📄 hdefs.c
字号:
return; case Pin_AvCMov: addHRegUse(u, HRmModify, i->Pin.AvCMov.dst); addHRegUse(u, HRmRead, i->Pin.AvCMov.src); return; case Pin_AvLdVSCR: addHRegUse(u, HRmRead, i->Pin.AvLdVSCR.src); return; default: ppPPC32Instr(i); vpanic("getRegUsage_PPC32Instr"); }}/* local helper */static void mapReg(HRegRemap* m, HReg* r){ *r = lookupHRegRemap(m, *r);}void mapRegs_PPC32Instr (HRegRemap* m, PPC32Instr* i){ switch (i->tag) { case Pin_LI32: mapReg(m, &i->Pin.LI32.dst); return; case Pin_Alu32: mapReg(m, &i->Pin.Alu32.dst); mapReg(m, &i->Pin.Alu32.srcL); mapRegs_PPC32RH(m, i->Pin.Alu32.srcR); return; case Pin_Cmp32: mapReg(m, &i->Pin.Cmp32.srcL); mapRegs_PPC32RH(m, i->Pin.Cmp32.srcR); return; case Pin_Unary32: mapReg(m, &i->Pin.Unary32.dst); mapReg(m, &i->Pin.Unary32.src); return; case Pin_MulL: mapReg(m, &i->Pin.MulL.dst); mapReg(m, &i->Pin.MulL.srcL); mapReg(m, &i->Pin.MulL.srcR); return; case Pin_Div: mapReg(m, &i->Pin.Div.dst); mapReg(m, &i->Pin.Div.srcL); mapReg(m, &i->Pin.Div.srcR); return; case Pin_Call: return; case Pin_Goto: mapRegs_PPC32RI(m, i->Pin.Goto.dst); return; case Pin_CMov32: mapRegs_PPC32RI(m, i->Pin.CMov32.src); mapReg(m, &i->Pin.CMov32.dst); return; case Pin_Load: mapRegs_PPC32AMode(m, i->Pin.Load.src); mapReg(m, &i->Pin.Load.dst); return; case Pin_Store: mapReg(m, &i->Pin.Store.src); mapRegs_PPC32AMode(m, i->Pin.Store.dst); return; case Pin_Set32: mapReg(m, &i->Pin.Set32.dst); return; case Pin_MfCR: mapReg(m, &i->Pin.MfCR.dst); return; case Pin_MFence: return; case Pin_FpUnary: mapReg(m, &i->Pin.FpUnary.dst); mapReg(m, &i->Pin.FpUnary.src); return; case Pin_FpBinary: mapReg(m, &i->Pin.FpBinary.dst); mapReg(m, &i->Pin.FpBinary.srcL); mapReg(m, &i->Pin.FpBinary.srcR); return; case Pin_FpLdSt: mapReg(m, &i->Pin.FpLdSt.reg); mapRegs_PPC32AMode(m, i->Pin.FpLdSt.addr); return; case Pin_FpF64toF32: mapReg(m, &i->Pin.FpF64toF32.dst); mapReg(m, &i->Pin.FpF64toF32.src); return; case Pin_FpF64toI32: mapReg(m, &i->Pin.FpF64toI32.dst); mapReg(m, &i->Pin.FpF64toI32.src); return; case Pin_FpCMov: mapReg(m, &i->Pin.FpCMov.dst); mapReg(m, &i->Pin.FpCMov.src); return; case Pin_FpLdFPSCR: mapReg(m, &i->Pin.FpLdFPSCR.src); return; case Pin_FpCmp: mapReg(m, &i->Pin.FpCmp.dst); mapReg(m, &i->Pin.FpCmp.srcL); mapReg(m, &i->Pin.FpCmp.srcR); return; case Pin_RdWrLR: mapReg(m, &i->Pin.RdWrLR.gpr); return; case Pin_AvLdSt: mapReg(m, &i->Pin.AvLdSt.reg); mapRegs_PPC32AMode(m, i->Pin.AvLdSt.addr); return; case Pin_AvUnary: mapReg(m, &i->Pin.AvUnary.dst); mapReg(m, &i->Pin.AvUnary.src); return; case Pin_AvBinary: mapReg(m, &i->Pin.AvBinary.dst); mapReg(m, &i->Pin.AvBinary.srcL); mapReg(m, &i->Pin.AvBinary.srcR); return; case Pin_AvBin8x16: mapReg(m, &i->Pin.AvBin8x16.dst); mapReg(m, &i->Pin.AvBin8x16.srcL); mapReg(m, &i->Pin.AvBin8x16.srcR); return; case Pin_AvBin16x8: mapReg(m, &i->Pin.AvBin16x8.dst); mapReg(m, &i->Pin.AvBin16x8.srcL); mapReg(m, &i->Pin.AvBin16x8.srcR); return; case Pin_AvBin32x4: mapReg(m, &i->Pin.AvBin32x4.dst); mapReg(m, &i->Pin.AvBin32x4.srcL); mapReg(m, &i->Pin.AvBin32x4.srcR); return; case Pin_AvBin32Fx4: mapReg(m, &i->Pin.AvBin32Fx4.dst); mapReg(m, &i->Pin.AvBin32Fx4.srcL); mapReg(m, &i->Pin.AvBin32Fx4.srcR); return; case Pin_AvPerm: mapReg(m, &i->Pin.AvPerm.dst); mapReg(m, &i->Pin.AvPerm.srcL); mapReg(m, &i->Pin.AvPerm.srcR); mapReg(m, &i->Pin.AvPerm.ctl); return; case Pin_AvSel: mapReg(m, &i->Pin.AvSel.dst); mapReg(m, &i->Pin.AvSel.srcL); mapReg(m, &i->Pin.AvSel.srcR); mapReg(m, &i->Pin.AvSel.ctl); return; case Pin_AvShlDbl: mapReg(m, &i->Pin.AvShlDbl.dst); mapReg(m, &i->Pin.AvShlDbl.srcL); mapReg(m, &i->Pin.AvShlDbl.srcR); return; case Pin_AvSplat: mapReg(m, &i->Pin.AvSplat.dst); mapRegs_PPC32RI(m, i->Pin.AvSplat.src); return; case Pin_AvCMov: mapReg(m, &i->Pin.AvCMov.dst); mapReg(m, &i->Pin.AvCMov.src); return; case Pin_AvLdVSCR: mapReg(m, &i->Pin.AvLdVSCR.src); return; default: ppPPC32Instr(i); vpanic("mapRegs_PPC32Instr"); }}/* Figure out if i represents a reg-reg move, and if so assign the source and destination to *src and *dst. If in doubt say No. Used by the register allocator to do move coalescing. */Bool isMove_PPC32Instr ( PPC32Instr* i, HReg* src, HReg* dst ){ /* Moves between integer regs */ if (i->tag == Pin_Alu32) { // or Rd,Rs,Rs == mr Rd,Rs if (i->Pin.Alu32.op != Palu_OR) return False; if (i->Pin.Alu32.srcR->tag != Prh_Reg) return False; if (i->Pin.Alu32.srcR->Prh.Reg.reg != i->Pin.Alu32.srcL) return False; *src = i->Pin.Alu32.srcL; *dst = i->Pin.Alu32.dst; return True; } /* Moves between FP regs */ if (i->tag == Pin_FpUnary) { if (i->Pin.FpUnary.op != Pfp_MOV) return False; *src = i->Pin.FpUnary.src; *dst = i->Pin.FpUnary.dst; return True; } return False;}/* Generate ppc32 spill/reload instructions under the direction of the register allocator. Note it's critical these don't write the condition codes. */PPC32Instr* genSpill_PPC32 ( HReg rreg, UShort offsetB ){ PPC32AMode* am; vassert(!hregIsVirtual(rreg)); am = PPC32AMode_IR(offsetB, GuestStatePtr); switch (hregClass(rreg)) { case HRcInt32: return PPC32Instr_Store( 4, am, rreg); case HRcFlt64: return PPC32Instr_FpLdSt ( False/*store*/, 8, rreg, am ); case HRcVec128: // XXX: GPR30 used as spill register to kludge AltiVec AMode_IR return PPC32Instr_AvLdSt ( False/*store*/, 16, rreg, am ); default: ppHRegClass(hregClass(rreg)); vpanic("genSpill_PPC32: unimplemented regclass"); }}PPC32Instr* genReload_PPC32 ( HReg rreg, UShort offsetB ){ PPC32AMode* am; vassert(!hregIsVirtual(rreg)); am = PPC32AMode_IR(offsetB, GuestStatePtr); switch (hregClass(rreg)) { case HRcInt32: return PPC32Instr_Load( 4, False, rreg, am ); case HRcFlt64: return PPC32Instr_FpLdSt ( True/*load*/, 8, rreg, am ); case HRcVec128: // XXX: GPR30 used as spill register to kludge AltiVec AMode_IR return PPC32Instr_AvLdSt ( True/*load*/, 16, rreg, am ); default: ppHRegClass(hregClass(rreg)); vpanic("genReload_PPC32: unimplemented regclass"); }}/* --------- The ppc32 assembler (bleh.) --------- */static UInt iregNo ( HReg r ){ UInt n; vassert(hregClass(r) == HRcInt32); vassert(!hregIsVirtual(r)); n = hregNumber(r); vassert(n <= 32); return n;}static UInt fregNo ( HReg fr ){ UInt n; vassert(hregClass(fr) == HRcFlt64); vassert(!hregIsVirtual(fr)); n = hregNumber(fr); vassert(n <= 32); return n;}static UInt vregNo ( HReg v ){ UInt n; vassert(hregClass(v) == HRcVec128); vassert(!hregIsVirtual(v)); n = hregNumber(v); vassert(n <= 32); return n;}/* Emit 32bit instruction big-endianly */static UChar* emit32 ( UChar* p, UInt w32 ){ *p++ = toUChar((w32 >> 24) & 0x000000FF); *p++ = toUChar((w32 >> 16) & 0x000000FF); *p++ = toUChar((w32 >> 8) & 0x000000FF); *p++ = toUChar((w32) & 0x000000FF); return p;}/* The following mkForm[...] functions refer to PPC32 instruction forms as per PPC32 p576 */static UChar* mkFormD ( UChar* p, UInt opc1, UInt r1, UInt r2, UInt imm ){ UInt theInstr; vassert(opc1 < 0x40); vassert(r1 < 0x20); vassert(r2 < 0x20); imm = imm & 0xFFFF; theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) | (imm)); return emit32(p, theInstr);}static UChar* mkFormX ( UChar* p, UInt opc1, UInt r1, UInt r2, UInt r3, UInt opc2, UInt b0 ){ UInt theInstr; vassert(opc1 < 0x40); vassert(r1 < 0x20); vassert(r2 < 0x20); vassert(r3 < 0x20); vassert(opc2 < 0x400); vassert(b0 < 0x2); theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) | (r3<<11) | (opc2<<1) | (b0)); return emit32(p, theInstr);}static UChar* mkFormXO ( UChar* p, UInt opc1, UInt r1, UInt r2, UInt r3, UInt b10, UInt opc2, UInt b0 ){ UInt theInstr; vassert(opc1 < 0x40); vassert(r1 < 0x20); vassert(r2 < 0x20); vassert(r3 < 0x20); vassert(b10 < 0x2); vassert(opc2 < 0x200); vassert(b0 < 0x2); theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) | (r3<<11) | (b10 << 10) | (opc2<<1) | (b0)); return emit32(p, theInstr);}static UChar* mkFormXL ( UChar* p, UInt opc1, UInt f1, UInt f2, UInt f3, UInt opc2, UInt b0 ){ UInt theInstr; vassert(opc1 < 0x40); vassert(f1 < 0x20); vassert(f2 < 0x20); vassert(f3 < 0x20); vassert(opc2 < 0x400); vassert(b0 < 0x2); theInstr = ((opc1<<26) | (f1<<21) | (f2<<16) | (f3<<11) | (opc2<<1) | (b0)); return emit32(p, theInstr);}// Note: for split field ops, give mnemonic argstatic UChar* mkFormXFX ( UChar* p, UInt r1, UInt f2, UInt opc2 ){ UInt theInstr; vassert(r1 < 0x20); vassert(f2 < 0x20); vassert(opc2 < 0x400); switch (opc2) { case 144: // mtcrf vassert(f2 < 0x100); f2 = f2 << 1; break; case 339: // mfspr case 371: // mftb case 467: // mtspr vassert(f2 < 0x400); f2 = ((f2>>5) & 0x1F) | ((f2 & 0x1F)<<5); // re-arrange split field break; default: vpanic("mkFormXFX(PPC32)"); } theInstr = ((31<<26) | (r1<<21) | (f2<<11) | (opc2<<1)); return emit32(p, theInstr);}// Only used by mtfsfstatic UChar* mkFormXFL ( UChar* p, UInt FM, UInt freg ){ UInt theInstr; vassert(FM < 0x100); vassert(freg < 0x20); theInstr = ((63<<26) | (FM<<17) | (freg<<11) | (711<<1)); return emit32(p, theInstr);}#if 0// 'b'static UChar* mkFormI ( UChar* p, UInt LI, UInt AA, UInt LK ){ UInt the
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -