25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: bintrans_i386.c,v 1.76 2005/06/22 10:12:25 debug Exp $ |
* $Id: bintrans_i386.c,v 1.83 2005/07/31 08:47:57 debug Exp $ |
29 |
* |
* |
30 |
* i386 specific code for dynamic binary translation. |
* i386 specific code for dynamic binary translation. |
31 |
* See bintrans.c for more information. Included from bintrans.c. |
* See bintrans.c for more information. Included from bintrans.c. |
64 |
#define ofs_tabl0 (((size_t)&dummy_cpu.cd.mips.vaddr_to_hostaddr_table0) - ((size_t)&dummy_cpu)) |
#define ofs_tabl0 (((size_t)&dummy_cpu.cd.mips.vaddr_to_hostaddr_table0) - ((size_t)&dummy_cpu)) |
65 |
#define ofs_chunks ((size_t)&dummy_vth32_table.bintrans_chunks[0] - (size_t)&dummy_vth32_table) |
#define ofs_chunks ((size_t)&dummy_vth32_table.bintrans_chunks[0] - (size_t)&dummy_vth32_table) |
66 |
#define ofs_chunkbase ((size_t)&dummy_cpu.cd.mips.chunk_base_address - (size_t)&dummy_cpu) |
#define ofs_chunkbase ((size_t)&dummy_cpu.cd.mips.chunk_base_address - (size_t)&dummy_cpu) |
67 |
|
#define ofs_h_l (((size_t)&dummy_cpu.cd.mips.host_load) - ((size_t)&dummy_cpu)) |
68 |
|
#define ofs_h_s (((size_t)&dummy_cpu.cd.mips.host_store) - ((size_t)&dummy_cpu)) |
69 |
|
|
70 |
|
|
71 |
static void (*bintrans_runchunk)(struct cpu *, unsigned char *); |
static void (*bintrans_runchunk)(struct cpu *, unsigned char *); |
425 |
/* |
/* |
426 |
* bintrans_write_instruction__addiu_etc(): |
* bintrans_write_instruction__addiu_etc(): |
427 |
*/ |
*/ |
428 |
static int bintrans_write_instruction__addiu_etc(unsigned char **addrp, |
static int bintrans_write_instruction__addiu_etc( |
429 |
|
struct memory *mem, unsigned char **addrp, |
430 |
int rt, int rs, int imm, int instruction_type) |
int rt, int rs, int imm, int instruction_type) |
431 |
{ |
{ |
432 |
unsigned char *a; |
unsigned char *a; |
460 |
goto rt0; |
goto rt0; |
461 |
} |
} |
462 |
|
|
463 |
#if 0 |
if (mem->bintrans_32bit_only) |
|
if (bintrans_32bit_only) |
|
464 |
load_into_eax_and_sign_extend_into_edx(&a, &dummy_cpu.cd.mips.gpr[rs]); |
load_into_eax_and_sign_extend_into_edx(&a, &dummy_cpu.cd.mips.gpr[rs]); |
465 |
else |
else |
|
#endif |
|
466 |
load_into_eax_edx(&a, &dummy_cpu.cd.mips.gpr[rs]); |
load_into_eax_edx(&a, &dummy_cpu.cd.mips.gpr[rs]); |
467 |
|
|
468 |
switch (instruction_type) { |
switch (instruction_type) { |
697 |
/* |
/* |
698 |
* bintrans_write_instruction__addu_etc(): |
* bintrans_write_instruction__addu_etc(): |
699 |
*/ |
*/ |
700 |
static int bintrans_write_instruction__addu_etc(unsigned char **addrp, |
static int bintrans_write_instruction__addu_etc( |
701 |
|
struct memory *mem, unsigned char **addrp, |
702 |
int rd, int rs, int rt, int sa, int instruction_type) |
int rd, int rs, int rt, int sa, int instruction_type) |
703 |
{ |
{ |
704 |
unsigned char *a; |
unsigned char *a; |
723 |
case SPECIAL_MOVN: |
case SPECIAL_MOVN: |
724 |
bintrans_write_chunkreturn_fail(addrp); |
bintrans_write_chunkreturn_fail(addrp); |
725 |
return 0; |
return 0; |
726 |
|
case SPECIAL_SLT: |
727 |
|
case SPECIAL_SLTU: |
728 |
|
if (!mem->bintrans_32bit_only) { |
729 |
|
bintrans_write_chunkreturn_fail(addrp); |
730 |
|
return 0; |
731 |
|
} |
732 |
|
break; |
733 |
} |
} |
734 |
|
|
735 |
switch (instruction_type) { |
switch (instruction_type) { |
745 |
case SPECIAL_DSLL32: |
case SPECIAL_DSLL32: |
746 |
case SPECIAL_DSRL32: |
case SPECIAL_DSRL32: |
747 |
case SPECIAL_DSRA32: |
case SPECIAL_DSRA32: |
|
case SPECIAL_SLT: |
|
|
case SPECIAL_SLTU: |
|
748 |
load64 = 1; |
load64 = 1; |
749 |
} |
} |
750 |
|
|
773 |
} |
} |
774 |
|
|
775 |
/* edx:eax = rs, ecx:ebx = rt */ |
/* edx:eax = rs, ecx:ebx = rt */ |
776 |
if (load64) { |
if (load64 && !mem->bintrans_32bit_only) { |
777 |
load_into_eax_edx(&a, &dummy_cpu.cd.mips.gpr[rt]); |
load_into_eax_edx(&a, &dummy_cpu.cd.mips.gpr[rt]); |
778 |
/* 89 c3 mov %eax,%ebx */ |
/* 89 c3 mov %eax,%ebx */ |
779 |
/* 89 d1 mov %edx,%ecx */ |
/* 89 d1 mov %edx,%ecx */ |
877 |
*a++ = 0x99; |
*a++ = 0x99; |
878 |
break; |
break; |
879 |
case SPECIAL_SLTU: |
case SPECIAL_SLTU: |
880 |
/* set if less than, unsigned. (compare edx:eax to ecx:ebx) */ |
/* NOTE: 32-bit ONLY! */ |
881 |
/* if edx <= ecx and eax < ebx then 1, else 0. */ |
/* set if less than, unsigned. (compare eax to ebx) */ |
|
/* 39 ca cmp %ecx,%edx */ |
|
|
/* 77 0b ja <ret0> */ |
|
882 |
/* 39 d8 cmp %ebx,%eax */ |
/* 39 d8 cmp %ebx,%eax */ |
883 |
/* 73 07 jae 58 <ret0> */ |
/* 73 07 jae 58 <ret0> */ |
|
*a++ = 0x39; *a++ = 0xca; |
|
|
*a++ = 0x77; *a++ = 0x0b; |
|
884 |
*a++ = 0x39; *a++ = 0xd8; |
*a++ = 0x39; *a++ = 0xd8; |
885 |
*a++ = 0x73; *a++ = 0x07; |
*a++ = 0x73; *a++ = 0x07; |
886 |
|
|
898 |
*a++ = 0x99; |
*a++ = 0x99; |
899 |
break; |
break; |
900 |
case SPECIAL_SLT: |
case SPECIAL_SLT: |
901 |
/* set if less than, signed. (compare edx:eax to ecx:ebx) */ |
/* NOTE: 32-bit ONLY! */ |
902 |
/* if edx > ecx then 0. */ |
/* set if less than, signed. (compare eax to ebx) */ |
|
/* if edx < ecx then 1. */ |
|
|
/* if eax < ebx then 1, else 0. */ |
|
|
/* 39 ca cmp %ecx,%edx */ |
|
|
/* 7c 0a jl <ret1> */ |
|
|
/* 7f 04 jg <ret0> */ |
|
903 |
/* 39 d8 cmp %ebx,%eax */ |
/* 39 d8 cmp %ebx,%eax */ |
904 |
/* 7c 04 jl <ret1> */ |
/* 7c 04 jl <ret1> */ |
|
*a++ = 0x39; *a++ = 0xca; |
|
|
*a++ = 0x7c; *a++ = 0x0a; |
|
|
*a++ = 0x7f; *a++ = 0x04; |
|
905 |
*a++ = 0x39; *a++ = 0xd8; |
*a++ = 0x39; *a++ = 0xd8; |
906 |
*a++ = 0x7c; *a++ = 0x04; |
*a++ = 0x7c; *a++ = 0x04; |
907 |
|
|
1757 |
*/ |
*/ |
1758 |
static int bintrans_write_instruction__loadstore(struct memory *mem, |
static int bintrans_write_instruction__loadstore(struct memory *mem, |
1759 |
unsigned char **addrp, int rt, int imm, int rs, |
unsigned char **addrp, int rt, int imm, int rs, |
1760 |
int instruction_type, int bigendian) |
int instruction_type, int bigendian, int do_alignment_check) |
1761 |
{ |
{ |
1762 |
unsigned char *a, *retfail, *generic64bit, *doloadstore, |
unsigned char *a, *retfail, *generic64bit, *doloadstore, |
1763 |
*okret0, *okret1, *okret2, *skip; |
*okret0, *okret1, *okret2, *skip; |
1767 |
if (instruction_type == HI6_LQ_MDMX || instruction_type == HI6_SQ) |
if (instruction_type == HI6_LQ_MDMX || instruction_type == HI6_SQ) |
1768 |
return 0; |
return 0; |
1769 |
|
|
|
/* TODO: Not yet: */ |
|
|
if (bigendian) |
|
|
return 0; |
|
|
|
|
1770 |
switch (instruction_type) { |
switch (instruction_type) { |
1771 |
case HI6_LQ_MDMX: |
case HI6_LQ_MDMX: |
1772 |
case HI6_LDL: |
case HI6_LDL: |
1797 |
unaligned = 1; |
unaligned = 1; |
1798 |
} |
} |
1799 |
|
|
1800 |
|
/* TODO: Not yet: */ |
1801 |
|
if (bigendian && unaligned) |
1802 |
|
return 0; |
1803 |
|
|
1804 |
a = *addrp; |
a = *addrp; |
1805 |
|
|
1806 |
if (mem->bintrans_32bit_only) |
if (mem->bintrans_32bit_only) |
1808 |
else |
else |
1809 |
load_into_eax_edx(&a, &dummy_cpu.cd.mips.gpr[rs]); |
load_into_eax_edx(&a, &dummy_cpu.cd.mips.gpr[rs]); |
1810 |
|
|
1811 |
if (imm & 0x8000) { |
if (imm != 0) { |
1812 |
/* 05 34 f2 ff ff add $0xfffff234,%eax */ |
if (imm & 0x8000) { |
1813 |
/* 83 d2 ff adc $0xffffffff,%edx */ |
/* 05 34 f2 ff ff add $0xfffff234,%eax */ |
1814 |
*a++ = 5; |
/* 83 d2 ff adc $0xffffffff,%edx */ |
1815 |
*a++ = imm; *a++ = imm >> 8; *a++ = 0xff; *a++ = 0xff; |
*a++ = 5; |
1816 |
if (!mem->bintrans_32bit_only) { |
*a++ = imm; *a++ = imm >> 8; *a++ = 0xff; *a++ = 0xff; |
1817 |
*a++ = 0x83; *a++ = 0xd2; *a++ = 0xff; |
if (!mem->bintrans_32bit_only) { |
1818 |
} |
*a++ = 0x83; *a++ = 0xd2; *a++ = 0xff; |
1819 |
} else { |
} |
1820 |
/* 05 34 12 00 00 add $0x1234,%eax */ |
} else { |
1821 |
/* 83 d2 00 adc $0x0,%edx */ |
/* 05 34 12 00 00 add $0x1234,%eax */ |
1822 |
*a++ = 5; |
/* 83 d2 00 adc $0x0,%edx */ |
1823 |
*a++ = imm; *a++ = imm >> 8; *a++ = 0; *a++ = 0; |
*a++ = 5; |
1824 |
if (!mem->bintrans_32bit_only) { |
*a++ = imm; *a++ = imm >> 8; *a++ = 0; *a++ = 0; |
1825 |
*a++ = 0x83; *a++ = 0xd2; *a++ = 0; |
if (!mem->bintrans_32bit_only) { |
1826 |
|
*a++ = 0x83; *a++ = 0xd2; *a++ = 0; |
1827 |
|
} |
1828 |
} |
} |
1829 |
} |
} |
1830 |
|
|
1866 |
* 83 e0 fc and $0xfffffffc,%eax |
* 83 e0 fc and $0xfffffffc,%eax |
1867 |
*/ |
*/ |
1868 |
*a++ = 0x83; *a++ = 0xe0; *a++ = 0xff - alignment; |
*a++ = 0x83; *a++ = 0xe0; *a++ = 0xff - alignment; |
1869 |
} else if (alignment > 0) { |
} else if (alignment > 0 && do_alignment_check) { |
1870 |
unsigned char *alignskip; |
unsigned char *alignskip; |
1871 |
/* |
/* |
1872 |
* Check alignment: |
* Check alignment: |
1887 |
/* Here, edx:eax = vaddr */ |
/* Here, edx:eax = vaddr */ |
1888 |
|
|
1889 |
if (mem->bintrans_32bit_only) { |
if (mem->bintrans_32bit_only) { |
1890 |
/* Call the quick lookup routine: */ |
/* ebx = vaddr >> 12; */ |
1891 |
if (load) |
*a++ = 0x89; *a++ = 0xc3; /* mov %eax, %ebx */ |
1892 |
ofs = (size_t)bintrans_load_32bit; |
*a++ = 0xc1; *a++ = 0xeb; *a++ = 0x0c; /* shr $12, %ebx */ |
1893 |
else |
|
1894 |
ofs = (size_t)bintrans_store_32bit; |
if (load) { |
1895 |
ofs = ofs - ((size_t)a + 5); |
/* ecx = cpu->cd.mips.host_load */ |
1896 |
*a++ = 0xe8; *a++ = ofs; *a++ = ofs >> 8; |
*a++ = 0x8b; *a++ = 0x8e; *a++ = ofs_h_l & 255; |
1897 |
*a++ = ofs >> 16; *a++ = ofs >> 24; |
*a++ = (ofs_h_l >> 8) & 255; |
1898 |
|
*a++ = (ofs_h_l >> 16) & 255; *a++ = (ofs_h_l >> 24) & 255; |
1899 |
|
} else { |
1900 |
|
/* ecx = cpu->cd.mips.host_store */ |
1901 |
|
*a++ = 0x8b; *a++ = 0x8e; *a++ = ofs_h_s & 255; |
1902 |
|
*a++ = (ofs_h_s >> 8) & 255; |
1903 |
|
*a++ = (ofs_h_s >> 16) & 255; *a++ = (ofs_h_s >> 24) & 255; |
1904 |
|
} |
1905 |
|
|
1906 |
|
/* ecx = host_load[a] (or host_store[a]) */ |
1907 |
|
*a++ = 0x8b; *a++ = 0x0c; *a++ = 0x99; /* mov (%ecx,%ebx,4),%ecx */ |
1908 |
|
|
1909 |
/* |
/* |
1910 |
* ecx = NULL? Then return with failure. |
* ecx = NULL? Then return with failure. |
1919 |
|
|
1920 |
/* |
/* |
1921 |
* eax = offset within page = vaddr & 0xfff |
* eax = offset within page = vaddr & 0xfff |
|
* |
|
|
* 25 ff 0f 00 00 and $0xfff,%eax |
|
|
*/ |
|
|
*a++ = 0x25; *a++ = 0xff; *a++ = 0x0f; *a++ = 0; *a++ = 0; |
|
|
|
|
|
/* |
|
1922 |
* ecx = host address ( = host page + offset) |
* ecx = host address ( = host page + offset) |
1923 |
* |
* |
1924 |
* 83 e1 fe and $0xfffffffe,%ecx clear the lowest bit |
* 25 ff 0f 00 00 and $0xfff,%eax |
1925 |
* 01 c1 add %eax,%ecx |
* 01 c1 add %eax,%ecx |
1926 |
*/ |
*/ |
1927 |
*a++ = 0x83; *a++ = 0xe1; *a++ = 0xfe; |
*a++ = 0x25; *a++ = 0xff; *a++ = 0x0f; *a++ = 0; *a++ = 0; |
1928 |
*a++ = 0x01; *a++ = 0xc1; |
*a++ = 0x01; *a++ = 0xc1; |
1929 |
} else { |
} else { |
1930 |
/* |
/* |
1967 |
|
|
1968 |
/* |
/* |
1969 |
* eax = offset within page = vaddr & 0xfff |
* eax = offset within page = vaddr & 0xfff |
|
* |
|
|
* 25 ff 0f 00 00 and $0xfff,%eax |
|
|
*/ |
|
|
*a++ = 0x25; *a++ = 0xff; *a++ = 0x0f; *a++ = 0; *a++ = 0; |
|
|
|
|
|
/* |
|
1970 |
* ecx = host address ( = host page + offset) |
* ecx = host address ( = host page + offset) |
1971 |
* |
* |
1972 |
* 83 e1 fe and $0xfffffffe,%ecx clear the lowest bit |
* 25 ff 0f 00 00 and $0xfff,%eax |
1973 |
* 01 c1 add %eax,%ecx |
* 01 c1 add %eax,%ecx |
1974 |
*/ |
*/ |
1975 |
*a++ = 0x83; *a++ = 0xe1; *a++ = 0xfe; |
*a++ = 0x25; *a++ = 0xff; *a++ = 0x0f; *a++ = 0; *a++ = 0; |
1976 |
*a++ = 0x01; *a++ = 0xc1; |
*a++ = 0x01; *a++ = 0xc1; |
1977 |
|
|
1978 |
*a++ = 0xeb; doloadstore = a; *a++ = 0x01; |
*a++ = 0xeb; doloadstore = a; *a++ = 0x01; |
2025 |
|
|
2026 |
|
|
2027 |
if (!load) { |
if (!load) { |
2028 |
if (alignment >= 7) |
if (rt == MIPS_GPR_ZERO) { |
2029 |
load_into_eax_edx(&a, &dummy_cpu.cd.mips.gpr[rt]); |
switch (alignment) { |
2030 |
else |
case 7: *a++ = 0x31; *a++ = 0xd2; /* edx = 0 */ |
2031 |
load_into_eax_dont_care_about_edx(&a, &dummy_cpu.cd.mips.gpr[rt]); |
case 3: |
2032 |
|
case 1: *a++ = 0x31; *a++ = 0xc0; break; /* eax = 0 */ |
2033 |
|
case 0: *a++ = 0xb0; *a++ = 0x00; break; /* al = 0 */ |
2034 |
|
default:fatal("todo: zero\n"); exit(1); |
2035 |
|
} |
2036 |
|
} else { |
2037 |
|
if (alignment >= 7) |
2038 |
|
load_into_eax_edx(&a, &dummy_cpu.cd.mips.gpr[rt]); |
2039 |
|
else |
2040 |
|
load_into_eax_dont_care_about_edx(&a, &dummy_cpu.cd.mips.gpr[rt]); |
2041 |
|
} |
2042 |
} |
} |
2043 |
|
|
2044 |
switch (instruction_type) { |
switch (instruction_type) { |
2045 |
case HI6_LD: |
case HI6_LD: |
2046 |
/* 8b 01 mov (%ecx),%eax */ |
if (bigendian) { |
2047 |
/* 8b 51 04 mov 0x4(%ecx),%edx */ |
/* 8b 11 mov (%ecx),%edx */ |
2048 |
*a++ = 0x8b; *a++ = 0x01; |
/* 8b 41 04 mov 0x4(%ecx),%eax */ |
2049 |
*a++ = 0x8b; *a++ = 0x51; *a++ = 0x04; |
/* 0f c8 bswap %eax */ |
2050 |
|
/* 0f ca bswap %edx */ |
2051 |
|
*a++ = 0x8b; *a++ = 0x11; |
2052 |
|
*a++ = 0x8b; *a++ = 0x41; *a++ = 0x04; |
2053 |
|
*a++ = 0x0f; *a++ = 0xc8; |
2054 |
|
*a++ = 0x0f; *a++ = 0xca; |
2055 |
|
} else { |
2056 |
|
/* 8b 01 mov (%ecx),%eax */ |
2057 |
|
/* 8b 51 04 mov 0x4(%ecx),%edx */ |
2058 |
|
*a++ = 0x8b; *a++ = 0x01; |
2059 |
|
*a++ = 0x8b; *a++ = 0x51; *a++ = 0x04; |
2060 |
|
} |
2061 |
break; |
break; |
2062 |
case HI6_LWU: |
case HI6_LWU: |
2063 |
/* 8b 01 mov (%ecx),%eax */ |
/* 8b 01 mov (%ecx),%eax */ |
2064 |
|
/* 0f c8 bswap %eax (big endian) */ |
2065 |
/* 31 d2 xor %edx,%edx */ |
/* 31 d2 xor %edx,%edx */ |
2066 |
*a++ = 0x8b; *a++ = 0x01; |
*a++ = 0x8b; *a++ = 0x01; |
2067 |
|
if (bigendian) { |
2068 |
|
*a++ = 0x0f; *a++ = 0xc8; |
2069 |
|
} |
2070 |
*a++ = 0x31; *a++ = 0xd2; |
*a++ = 0x31; *a++ = 0xd2; |
2071 |
break; |
break; |
2072 |
case HI6_LW: |
case HI6_LW: |
2073 |
/* 8b 01 mov (%ecx),%eax */ |
/* 8b 01 mov (%ecx),%eax */ |
2074 |
|
/* 0f c8 bswap %eax (big endian) */ |
2075 |
/* 99 cltd */ |
/* 99 cltd */ |
2076 |
*a++ = 0x8b; *a++ = 0x01; |
*a++ = 0x8b; *a++ = 0x01; |
2077 |
|
if (bigendian) { |
2078 |
|
*a++ = 0x0f; *a++ = 0xc8; |
2079 |
|
} |
2080 |
*a++ = 0x99; |
*a++ = 0x99; |
2081 |
break; |
break; |
2082 |
case HI6_LHU: |
case HI6_LHU: |
2083 |
/* 31 c0 xor %eax,%eax */ |
/* 31 c0 xor %eax,%eax */ |
2084 |
/* 66 8b 01 mov (%ecx),%ax */ |
/* 66 8b 01 mov (%ecx),%ax */ |
2085 |
|
/* 86 c4 xchg %al,%ah (big endian) */ |
2086 |
/* 99 cltd */ |
/* 99 cltd */ |
2087 |
*a++ = 0x31; *a++ = 0xc0; |
*a++ = 0x31; *a++ = 0xc0; |
2088 |
*a++ = 0x66; *a++ = 0x8b; *a++ = 0x01; |
*a++ = 0x66; *a++ = 0x8b; *a++ = 0x01; |
2089 |
|
if (bigendian) { |
2090 |
|
*a++ = 0x86; *a++ = 0xc4; |
2091 |
|
} |
2092 |
*a++ = 0x99; |
*a++ = 0x99; |
2093 |
break; |
break; |
2094 |
case HI6_LH: |
case HI6_LH: |
2095 |
/* 66 8b 01 mov (%ecx),%ax */ |
/* 66 8b 01 mov (%ecx),%ax */ |
2096 |
|
/* 86 c4 xchg %al,%ah (big endian) */ |
2097 |
/* 98 cwtl */ |
/* 98 cwtl */ |
2098 |
/* 99 cltd */ |
/* 99 cltd */ |
2099 |
*a++ = 0x66; *a++ = 0x8b; *a++ = 0x01; |
*a++ = 0x66; *a++ = 0x8b; *a++ = 0x01; |
2100 |
|
if (bigendian) { |
2101 |
|
*a++ = 0x86; *a++ = 0xc4; |
2102 |
|
} |
2103 |
*a++ = 0x98; |
*a++ = 0x98; |
2104 |
*a++ = 0x99; |
*a++ = 0x99; |
2105 |
break; |
break; |
2321 |
break; |
break; |
2322 |
|
|
2323 |
case HI6_SD: |
case HI6_SD: |
2324 |
/* 89 01 mov %eax,(%ecx) */ |
if (bigendian) { |
2325 |
/* 89 51 04 mov %edx,0x4(%ecx) */ |
/* 0f c8 bswap %eax */ |
2326 |
*a++ = 0x89; *a++ = 0x01; |
/* 0f ca bswap %edx */ |
2327 |
*a++ = 0x89; *a++ = 0x51; *a++ = 0x04; |
/* 89 11 mov %edx,(%ecx) */ |
2328 |
|
/* 89 41 04 mov %eax,0x4(%ecx) */ |
2329 |
|
*a++ = 0x0f; *a++ = 0xc8; |
2330 |
|
*a++ = 0x0f; *a++ = 0xca; |
2331 |
|
*a++ = 0x89; *a++ = 0x11; |
2332 |
|
*a++ = 0x89; *a++ = 0x41; *a++ = 0x04; |
2333 |
|
} else { |
2334 |
|
/* 89 01 mov %eax,(%ecx) */ |
2335 |
|
/* 89 51 04 mov %edx,0x4(%ecx) */ |
2336 |
|
*a++ = 0x89; *a++ = 0x01; |
2337 |
|
*a++ = 0x89; *a++ = 0x51; *a++ = 0x04; |
2338 |
|
} |
2339 |
break; |
break; |
2340 |
case HI6_SW: |
case HI6_SW: |
2341 |
|
/* 0f c8 bswap %eax (big endian) */ |
2342 |
|
if (bigendian) { |
2343 |
|
*a++ = 0x0f; *a++ = 0xc8; |
2344 |
|
} |
2345 |
/* 89 01 mov %eax,(%ecx) */ |
/* 89 01 mov %eax,(%ecx) */ |
2346 |
*a++ = 0x89; *a++ = 0x01; |
*a++ = 0x89; *a++ = 0x01; |
2347 |
break; |
break; |
2348 |
case HI6_SH: |
case HI6_SH: |
2349 |
|
/* 86 c4 xchg %al,%ah (big endian) */ |
2350 |
|
if (bigendian) { |
2351 |
|
*a++ = 0x86; *a++ = 0xc4; |
2352 |
|
} |
2353 |
/* 66 89 01 mov %ax,(%ecx) */ |
/* 66 89 01 mov %ax,(%ecx) */ |
2354 |
*a++ = 0x66; *a++ = 0x89; *a++ = 0x01; |
*a++ = 0x66; *a++ = 0x89; *a++ = 0x01; |
2355 |
break; |
break; |
2893 |
|
|
2894 |
bintrans_load_32bit = (void *)p; |
bintrans_load_32bit = (void *)p; |
2895 |
|
|
2896 |
/* |
/* ebx = vaddr >> 12; */ |
2897 |
* ebx = ((vaddr >> 22) & 1023) * sizeof(void *) |
*p++ = 0x89; *p++ = 0xc3; /* mov %eax, %ebx */ |
2898 |
* |
*p++ = 0xc1; *p++ = 0xeb; *p++ = 0x0c; /* shr $12, %ebx */ |
2899 |
* 89 c3 mov %eax,%ebx |
|
2900 |
* c1 eb 14 shr $20,%ebx |
/* ecx = cpu->cd.mips.host_load */ |
2901 |
* 81 e3 fc 0f 00 00 and $0xffc,%ebx |
*p++ = 0x8b; *p++ = 0x8e; *p++ = ofs_h_l & 255; |
2902 |
*/ |
*p++ = (ofs_h_l >> 8) & 255; |
2903 |
*p++ = 0x89; *p++ = 0xc3; |
*p++ = (ofs_h_l >> 16) & 255; *p++ = (ofs_h_l >> 24) & 255; |
|
*p++ = 0xc1; *p++ = 0xeb; *p++ = 0x14; |
|
|
*p++ = 0x81; *p++ = 0xe3; *p++ = 0xfc; *p++ = 0x0f; *p++ = 0; *p++ = 0; |
|
|
|
|
|
/* |
|
|
* ecx = vaddr_to_hostaddr_table0 |
|
|
* |
|
|
* 8b 8e 34 12 00 00 mov 0x1234(%esi),%ecx |
|
|
*/ |
|
|
*p++ = 0x8b; *p++ = 0x8e; *p++ = ofs_tabl0 & 255; |
|
|
*p++ = (ofs_tabl0 >> 8) & 255; |
|
|
*p++ = (ofs_tabl0 >> 16) & 255; *p++ = (ofs_tabl0 >> 24) & 255; |
|
|
|
|
|
/* |
|
|
* ecx = vaddr_to_hostaddr_table0[a] |
|
|
* |
|
|
* 8b 0c 19 mov (%ecx,%ebx),%ecx |
|
|
*/ |
|
|
*p++ = 0x8b; *p++ = 0x0c; *p++ = 0x19; |
|
|
|
|
|
/* |
|
|
* ebx = ((vaddr >> 12) & 1023) * sizeof(void *) |
|
|
* |
|
|
* 89 c3 mov %eax,%ebx |
|
|
* c1 eb 0a shr $10,%ebx |
|
|
* 81 e3 fc 0f 00 00 and $0xffc,%ebx |
|
|
*/ |
|
|
*p++ = 0x89; *p++ = 0xc3; |
|
|
*p++ = 0xc1; *p++ = 0xeb; *p++ = 0x0a; |
|
|
*p++ = 0x81; *p++ = 0xe3; *p++ = 0xfc; *p++ = 0x0f; *p++ = 0; *p++ = 0; |
|
2904 |
|
|
2905 |
/* |
/* ecx = host_load[a] */ |
2906 |
* ecx = vaddr_to_hostaddr_table0[a][b*2] |
*p++ = 0x8b; *p++ = 0x0c; *p++ = 0x99; /* mov (%ecx,%ebx,4),%ecx */ |
|
* |
|
|
* 8b 0c 59 mov 0(%ecx,%ebx,2),%ecx |
|
|
*/ |
|
|
*p++ = 0x8b; *p++ = 0x0c; *p++ = 0x59; |
|
2907 |
|
|
2908 |
/* ret */ |
/* ret */ |
2909 |
*p++ = 0xc3; |
*p++ = 0xc3; |
2927 |
|
|
2928 |
bintrans_store_32bit = (void *)p; |
bintrans_store_32bit = (void *)p; |
2929 |
|
|
2930 |
/* |
/* ebx = vaddr >> 12; */ |
2931 |
* ebx = ((vaddr >> 22) & 1023) * sizeof(void *) |
*p++ = 0x89; *p++ = 0xc3; /* mov %eax, %ebx */ |
2932 |
* |
*p++ = 0xc1; *p++ = 0xeb; *p++ = 0x0c; /* shr $12, %ebx */ |
2933 |
* 89 c3 mov %eax,%ebx |
|
2934 |
* c1 eb 14 shr $20,%ebx |
/* ecx = cpu->cd.mips.host_store */ |
2935 |
* 81 e3 fc 0f 00 00 and $0xffc,%ebx |
*p++ = 0x8b; *p++ = 0x8e; *p++ = ofs_h_s & 255; |
2936 |
*/ |
*p++ = (ofs_h_s >> 8) & 255; |
2937 |
*p++ = 0x89; *p++ = 0xc3; |
*p++ = (ofs_h_s >> 16) & 255; *p++ = (ofs_h_s >> 24) & 255; |
|
*p++ = 0xc1; *p++ = 0xeb; *p++ = 0x14; |
|
|
*p++ = 0x81; *p++ = 0xe3; *p++ = 0xfc; *p++ = 0x0f; *p++ = 0; *p++ = 0; |
|
|
|
|
|
/* |
|
|
* ecx = vaddr_to_hostaddr_table0 |
|
|
* |
|
|
* 8b 8e 34 12 00 00 mov 0x1234(%esi),%ecx |
|
|
*/ |
|
|
*p++ = 0x8b; *p++ = 0x8e; *p++ = ofs_tabl0 & 255; |
|
|
*p++ = (ofs_tabl0 >> 8) & 255; |
|
|
*p++ = (ofs_tabl0 >> 16) & 255; *p++ = (ofs_tabl0 >> 24) & 255; |
|
|
|
|
|
/* |
|
|
* ecx = vaddr_to_hostaddr_table0[a] |
|
|
* |
|
|
* 8b 0c 19 mov (%ecx,%ebx),%ecx |
|
|
*/ |
|
|
*p++ = 0x8b; *p++ = 0x0c; *p++ = 0x19; |
|
2938 |
|
|
2939 |
/* |
/* ecx = host_store[a] */ |
2940 |
* ebx = ((vaddr >> 12) & 1023) * sizeof(void *) |
*p++ = 0x8b; *p++ = 0x0c; *p++ = 0x99; /* mov (%ecx,%ebx,4),%ecx */ |
|
* |
|
|
* 89 c3 mov %eax,%ebx |
|
|
* c1 eb 0a shr $10,%ebx |
|
|
* 81 e3 fc 0f 00 00 and $0xffc,%ebx |
|
|
*/ |
|
|
*p++ = 0x89; *p++ = 0xc3; |
|
|
*p++ = 0xc1; *p++ = 0xeb; *p++ = 0x0a; |
|
|
*p++ = 0x81; *p++ = 0xe3; *p++ = 0xfc; *p++ = 0x0f; *p++ = 0; *p++ = 0; |
|
|
|
|
|
/* |
|
|
* ecx = vaddr_to_hostaddr_table0[a][b*2] |
|
|
* |
|
|
* 8b 4c 59 04 mov 4(%ecx,%ebx,2),%ecx |
|
|
*/ |
|
|
*p++ = 0x8b; *p++ = 0x4c; *p++ = 0x59; *p++ = 0x04; |
|
2941 |
|
|
2942 |
/* ret */ |
/* ret */ |
2943 |
*p++ = 0xc3; |
*p++ = 0xc3; |