const RegisterAllocator::State RegisterAllocator::capture() { State state; if(!minimalRestore) { spillAll(); return state; // Empty state } for(int i = 0; i < 8; i++) { // Prevent optimizations markModified(OperandREG32(i)); markModified(OperandMMREG(i)); markModified(OperandXMMREG(i)); } for(int i = 0; i < 8; i++) { state.GPR[i] = GPR[i]; state.MMX[i] = MMX[i]; state.XMM[i] = XMM[i]; } return state; }
void RegisterAllocator::restore(const State &state) { if(!minimalRestore) { spillAll(); return; } for(int i = 0; i < 8; i++) { if(GPR[i].reference != state.GPR[i].reference) { spill32(i); } if(MMX[i].reference != state.MMX[i].reference) { spill64(i); } if(XMM[i].reference != state.XMM[i].reference) { spill128(i); } } for(int i = 0; i < 8; i++) { if(GPR[i].reference != state.GPR[i].reference && state.GPR[i].reference != 0) { allocate32(i, state.GPR[i].reference, true, state.GPR[i].partial); } if(MMX[i].reference != state.MMX[i].reference && state.MMX[i].reference != 0) { allocate64(i, state.MMX[i].reference, true); } if(XMM[i].reference != state.XMM[i].reference && state.XMM[i].reference != 0) { allocate128(i, state.XMM[i].reference, true, state.XMM[i].partial != 0); } } for(int i = 0; i < 8; i++) { // Prevent optimizations markModified(OperandREG32(i)); markModified(OperandMMREG(i)); markModified(OperandXMMREG(i)); } }
StressTest(int seed, int tests, int level, bool copyProp, bool loadElim, bool spillElim) : CodeGenerator(false) { if(copyProp) enableCopyPropagation(); else disableCopyPropagation(); if(loadElim) enableLoadElimination(); else disableLoadElimination(); if(spillElim) enableSpillElimination(); else disableSpillElimination(); #if 0 Int a; Int b; Int c; pushad(); prologue(1024); freeAll(); for(int i = 0; i < 3; i++) { add(r32(&x[2 * i + 0]), r32(&x[2 * i + 1])); } nop(); a = (a + b) * c; nop(); for(int i = 2; i >= 1; i--) { add(r32(&x[2 * i + 0]), r32(&x[2 * i + 1])); } nop(); spillAll(); epilogue(); popad(); ret(); return; #else // ------------------------------------------------- srand(seed); for(int i = 0; i < 16; i++) { w[i] = rand(); } for(int i = 0; i < 16; i++) { x[i] = w[i]; } if(level & 0x01) for(int i = 0; i < tests; i++) { x[q()] = x[q()]; if(i % 3 == 0 && rand() < RAND_MAX / 2) { int a = q(); int b = q(); x[b] += x[a]; } } if(level & 0x02) for(int i = 0; i < tests; i++) { int a = q(); int b = q(); x[b] += x[a]; if(i % 3 == 0 && rand() < RAND_MAX / 2) { x[q()] = x[q()]; } } if(level & 0x04) for(int i = 0; i < tests; i++) { int a = q(); int b = q(); x[b] += x[a]; if(i % 3 == 0 && rand() < RAND_MAX / 2) { x[q()]; // spill(reg) } } if(level & 0x08) for(int i = 0; i < tests; i++) { if(q() < q() / 2) {int a = q(); int b = q(); x[b] += x[a];} // add(r(), r()); if(q() < q() / 2) {x[q()] = x[q()];} // mov(r(), r()); if(q() < q() / 2) q(); // spill(r()); } for(int i = 0; i < 16; i++) { y[i] = x[i]; } // ------------------------------------------------- srand(seed); for(int i = 0; i < 16; i++) { w[i] = rand(); } pushad(); for(int i = 0; i < 16; i++) { mov(eax, dword_ptr [&w[i]]); mov(dword_ptr [&x[i]], eax); } freeAll(); nop(); if(level & 0x01) for(int i = 0; i < tests; i++) { mov(r(), r()); if(i % 3 == 0 && rand() < RAND_MAX / 2) { add(r(), r()); } } if(level & 0x02) for(int i = 0; i < tests; i++) { add(r(), r()); if(i % 3 == 0 && rand() < RAND_MAX / 2) { mov(r(), r()); } } if(level & 0x04) for(int i = 0; i < tests; i++) { add(r(), r()); if(i % 3 == 0 && rand() < RAND_MAX / 2) { spill(r()); } } if(level & 0x08) for(int i = 0; i < tests; i++) { if(q() < q() / 2) add(r(), r()); if(q() < q() / 2) mov(r(), r()); if(q() < q() / 2) spill(r()); } nop(); spillAll(); nop(); for(int i = 0; i < 16; i++) { mov(eax, dword_ptr [&x[i]]); mov(dword_ptr [&z[i]], eax); } popad(); ret(); #endif }