| 10179 | } |
| 10180 | |
| 10181 | void test32BitMemoryAccess() { |
| 10182 | U32 reg1, reg2; |
| 10183 | |
| 10184 | // Mod 00 |
| 10185 | // [DS:EAX] |
| 10186 | initMem32(); EAX = 0; runLeaGd(0, 0, 0, 0, 0, 0, 0, DS); |
| 10187 | initMem32(); EAX = 0x10000; runLeaGd(1 << 3, 0, 0, 0, 0, 0, 0x10000, DS); |
| 10188 | |
| 10189 | // [DS:ECX] |
| 10190 | initMem32(); ECX = 0; runLeaGd(0 | 1, 0, 0, 0, 0, 0, 0, DS); |
| 10191 | initMem32(); ECX = 0x10000; runLeaGd(1 << 3 | 1, 0, 0, 0, 0, 0, 0x10000, DS); |
| 10192 | |
| 10193 | // [DS:EDX] |
| 10194 | initMem32(); EDX = 0; runLeaGd(0 | 2, 0, 0, 0, 0, 0, 0, DS); |
| 10195 | initMem32(); EDX = 0x10000; runLeaGd(1 << 3 | 2, 0, 0, 0, 0, 0, 0x10000, DS); |
| 10196 | |
| 10197 | // [DS:EBX] |
| 10198 | initMem32(); EBX = 0; runLeaGd(0 | 3, 0, 0, 0, 0, 0, 0, DS); |
| 10199 | initMem32(); EBX = 0x10000; runLeaGd(1 << 3 | 3, 0, 0, 0, 0, 0, 0x10000, DS); |
| 10200 | |
| 10201 | // SIB0 |
| 10202 | // [DS:reg1+reg2<<0] |
| 10203 | for (reg1 = 0; reg1 < 8; reg1++) { |
| 10204 | for (reg2 = 0; reg2 < 8; reg2++) { |
| 10205 | U32 seg = DS; |
| 10206 | if (reg1 == 4) { |
| 10207 | seg = SS; |
| 10208 | } |
| 10209 | if (reg1 == 5) { // reg1==5 means reg1 is replaced with disp32 |
| 10210 | if (reg2 == 4) { // reg2==4 means reg2 is not used |
| 10211 | initMem32(); runLeaGd(0 | 4, 1, (reg2 << 3) | reg1, 0, 1, 0, 0, seg); |
| 10212 | initMem32(); runLeaGd(1 << 3 | 4, 1, (reg2 << 3) | reg1, 0, 1, 0x10000, 0x10000, seg); |
| 10213 | |
| 10214 | // shift should have no effect |
| 10215 | initMem32(); runLeaGd(1 << 3 | 4, 1, (reg2 << 3) | reg1 | 1 << 6, 0, 1, 0x10000, 0x10000, seg); |
| 10216 | initMem32(); runLeaGd(1 << 3 | 4, 1, (reg2 << 3) | reg1 | 2 << 6, 0, 1, 0x10000, 0x10000, seg); |
| 10217 | initMem32(); runLeaGd(1 << 3 | 4, 1, (reg2 << 3) | reg1 | 3 << 6, 0, 1, 0x10000, 0x10000, seg); |
| 10218 | } else { |
| 10219 | initMem32(); cpu->reg[reg2].u32 = 0; runLeaGd(0 | 4, 1, (reg2 << 3) | reg1, 0, 1, 0, 0, seg); |
| 10220 | initMem32(); cpu->reg[reg2].u32 = 0x10000; runLeaGd(1 << 3 | 4, 1, (reg2 << 3) | reg1, 0, 1, 0, 0x10000, seg); |
| 10221 | initMem32(); cpu->reg[reg2].u32 = 0; runLeaGd(2 << 3 | 4, 1, (reg2 << 3) | reg1, 0, 1, 0x10000, 0x10000, seg); |
| 10222 | initMem32(); cpu->reg[reg2].u32 = 0x1000; runLeaGd(3 << 3 | 4, 1, (reg2 << 3) | reg1, 0, 1, 0x0F000, 0x10000, seg); |
| 10223 | initMem32(); cpu->reg[reg2].u32 = -(0x2000); runLeaGd(4 << 3 | 4, 1, (reg2 << 3) | reg1, 0, 1, 0x11000, 0x0F000, seg); |
| 10224 | initMem32(); cpu->reg[reg2].u32 = 0x11000; runLeaGd(4 << 3 | 4, 1, (reg2 << 3) | reg1, 0, 1, -(0x2000), 0x0F000, seg); |
| 10225 | |
| 10226 | initMem32(); cpu->reg[reg2].u32 = 0; runLeaGd(0 | 4, 1, (reg2 << 3) | reg1 | 1 << 6, 0, 1, 0, 0, seg); |
| 10227 | initMem32(); cpu->reg[reg2].u32 = 0x08000; runLeaGd(1 << 3 | 4, 1, (reg2 << 3) | reg1 | 1 << 6, 0, 1, 0, 0x10000, seg); |
| 10228 | |
| 10229 | initMem32(); cpu->reg[reg2].u32 = 0; runLeaGd(0 | 4, 1, (reg2 << 3) | reg1 | 2 << 6, 0, 1, 0, 0, seg); |
| 10230 | initMem32(); cpu->reg[reg2].u32 = 0x04000; runLeaGd(1 << 3 | 4, 1, (reg2 << 3) | reg1 | 2 << 6, 0, 1, 0, 0x10000, seg); |
| 10231 | |
| 10232 | initMem32(); cpu->reg[reg2].u32 = 0; runLeaGd(0 | 4, 1, (reg2 << 3) | reg1 | 3 << 6, 0, 1, 0, 0, seg); |
| 10233 | initMem32(); cpu->reg[reg2].u32 = 0x02000; runLeaGd(1 << 3 | 4, 1, (reg2 << 3) | reg1 | 3 << 6, 0, 1, 0, 0x10000, seg); |
| 10234 | } |
| 10235 | } else { |
| 10236 | if (reg2 == 4) { // reg2==4 means reg2 is not used |
| 10237 | initMem32(); cpu->reg[reg1].u32 = 0; runLeaGd(0 | 4, 1, (reg2 << 3) | reg1, 0, 0, 0, 0, seg); |
| 10238 | initMem32(); cpu->reg[reg1].u32 = 0x10000; runLeaGd(1 << 3 | 4, 1, (reg2 << 3) | reg1, 0, 0, 0, 0x10000, seg); |