| 2316 | } |
| 2317 | |
| 2318 | void EdGd(int instruction, struct Data* data, U8 prefix = 0, bool includeLock = false) { |
| 2319 | while (data->valid) { |
| 2320 | int ed; |
| 2321 | int gd; |
| 2322 | int rm; |
| 2323 | |
| 2324 | for (int setsFlags = 0; setsFlags < 3; setsFlags++) { |
| 2325 | for (ed = 0; ed < 8; ed++) { |
| 2326 | for (gd = 0; gd < 8; gd++) { |
| 2327 | Reg* e; |
| 2328 | Reg* g; |
| 2329 | |
| 2330 | if (ed == gd) |
| 2331 | continue; |
| 2332 | rm = ed | (gd << 3) | 0xC0; |
| 2333 | newInstructionWithRM(instruction, rm, data->flags, prefix); |
| 2334 | pushConstant(data); |
| 2335 | e = &cpu->reg[ed]; |
| 2336 | g = &cpu->reg[gd]; |
| 2337 | e->u32 = data->var1; |
| 2338 | g->u32 = data->var2; |
| 2339 | runTestCPU(); |
| 2340 | assertResult(data, cpu, instruction, e->u32, g->u32, -1, -1, 0, 0); |
| 2341 | |
| 2342 | if (setsFlags == 0) { |
| 2343 | pushCode8(0x39); |
| 2344 | pushCode8(0xc0); // cmp eax, eax: this will overwrite flags so the above code might take a different path in the dynamic cores that optimize away flag calculation |
| 2345 | } else if (setsFlags == 2) { |
| 2346 | if (ed != 0 && gd != 0) { |
| 2347 | // good test for JitCodeGen::getCF |
| 2348 | pushCode8(0x0f); // setc al |
| 2349 | pushCode8(0x92); |
| 2350 | pushCode8(0xc0); |
| 2351 | } |
| 2352 | // flags will be calculate in JIT |
| 2353 | U8 reg = 5; |
| 2354 | if (ed == 5 || gd == 5) { |
| 2355 | if (ed == 6 || gd == 6) { |
| 2356 | reg = 7; |
| 2357 | } else { |
| 2358 | reg = 6; |
| 2359 | } |
| 2360 | } |
| 2361 | if (ed == 4 || gd == 4) { |
| 2362 | continue; |
| 2363 | } |
| 2364 | pushCode8(0x9c); // push flags |
| 2365 | pushCode8(0x58 + reg); // pop reg |
| 2366 | } |
| 2367 | } |
| 2368 | } |
| 2369 | } |
| 2370 | |
| 2371 | for (int lock = 0; lock < 3; lock++) { |
| 2372 | for (gd = 0; gd < 8; gd++) { |
| 2373 | Reg* g; |
| 2374 | U32 result; |
| 2375 |
no test coverage detected