📄 toir.c
字号:
vassert(ty == Ity_I32 || ty == Ity_I64); return ( ty == Ity_I64 ? IRConst_U64(imm64) : IRConst_U32((UInt)imm64) );}/* Sign extend imm16 -> IRExpr* */static IRExpr* mkSzExtendS16 ( IRType ty, UInt imm16 ){ vassert(ty == Ity_I32 || ty == Ity_I64); return ( ty == Ity_I64 ? mkU64(extend_s_16to64(imm16)) : mkU32(extend_s_16to32(imm16)) );}/* Sign extend imm32 -> IRExpr* */static IRExpr* mkSzExtendS32 ( IRType ty, UInt imm32 ){ vassert(ty == Ity_I32 || ty == Ity_I64); return ( ty == Ity_I64 ? mkU64(extend_s_32to64(imm32)) : mkU32(imm32) );}/* IR narrows I32/I64 -> I8/I16/I32 */static IRExpr* mkSzNarrow8 ( IRType ty, IRExpr* src ){ vassert(ty == Ity_I32 || ty == Ity_I64); return ty == Ity_I64 ? unop(Iop_64to8, src) : unop(Iop_32to8, src);}static IRExpr* mkSzNarrow16 ( IRType ty, IRExpr* src ){ vassert(ty == Ity_I32 || ty == Ity_I64); return ty == Ity_I64 ? unop(Iop_64to16, src) : unop(Iop_32to16, src);}static IRExpr* mkSzNarrow32 ( IRType ty, IRExpr* src ){ vassert(ty == Ity_I32 || ty == Ity_I64); return ty == Ity_I64 ? unop(Iop_64to32, src) : src;}/* Signed/Unsigned IR widens I8/I16/I32 -> I32/I64 */static IRExpr* mkSzWiden8 ( IRType ty, IRExpr* src, Bool sined ){ IROp op; vassert(ty == Ity_I32 || ty == Ity_I64); if (sined) op = (ty==Ity_I32) ? Iop_8Sto32 : Iop_8Sto64; else op = (ty==Ity_I32) ? Iop_8Uto32 : Iop_8Uto64; return unop(op, src);}static IRExpr* mkSzWiden16 ( IRType ty, IRExpr* src, Bool sined ){ IROp op; vassert(ty == Ity_I32 || ty == Ity_I64); if (sined) op = (ty==Ity_I32) ? Iop_16Sto32 : Iop_16Sto64; else op = (ty==Ity_I32) ? Iop_16Uto32 : Iop_16Uto64; return unop(op, src);}static IRExpr* mkSzWiden32 ( IRType ty, IRExpr* src, Bool sined ){ vassert(ty == Ity_I32 || ty == Ity_I64); if (ty == Ity_I32) return src; return (sined) ? unop(Iop_32Sto64, src) : unop(Iop_32Uto64, src);}static Int integerGuestRegOffset ( UInt archreg ){ vassert(archreg < 32); // jrs: probably not necessary; only matters if we reference sub-parts // of the ppc registers, but that isn't the case // later: this might affect Altivec though? vassert(host_is_bigendian); switch (archreg) { case 0: return offsetofPPCGuestState(guest_GPR0); case 1: return offsetofPPCGuestState(guest_GPR1); case 2: return offsetofPPCGuestState(guest_GPR2); case 3: return offsetofPPCGuestState(guest_GPR3); case 4: return offsetofPPCGuestState(guest_GPR4); case 5: return offsetofPPCGuestState(guest_GPR5); case 6: return offsetofPPCGuestState(guest_GPR6); case 7: return offsetofPPCGuestState(guest_GPR7); case 8: return offsetofPPCGuestState(guest_GPR8); case 9: return offsetofPPCGuestState(guest_GPR9); case 10: return offsetofPPCGuestState(guest_GPR10); case 11: return offsetofPPCGuestState(guest_GPR11); case 12: return offsetofPPCGuestState(guest_GPR12); case 13: return offsetofPPCGuestState(guest_GPR13); case 14: return offsetofPPCGuestState(guest_GPR14); case 15: return offsetofPPCGuestState(guest_GPR15); case 16: return offsetofPPCGuestState(guest_GPR16); case 17: return offsetofPPCGuestState(guest_GPR17); case 18: return offsetofPPCGuestState(guest_GPR18); case 19: return offsetofPPCGuestState(guest_GPR19); case 20: return offsetofPPCGuestState(guest_GPR20); case 21: return offsetofPPCGuestState(guest_GPR21); case 22: return offsetofPPCGuestState(guest_GPR22); case 23: return offsetofPPCGuestState(guest_GPR23); case 24: return offsetofPPCGuestState(guest_GPR24); case 25: return offsetofPPCGuestState(guest_GPR25); case 26: return offsetofPPCGuestState(guest_GPR26); case 27: return offsetofPPCGuestState(guest_GPR27); case 28: return offsetofPPCGuestState(guest_GPR28); case 29: return offsetofPPCGuestState(guest_GPR29); case 30: return offsetofPPCGuestState(guest_GPR30); case 31: return offsetofPPCGuestState(guest_GPR31); default: break; } vpanic("integerGuestRegOffset(ppc,be)"); /*notreached*/}static IRExpr* getIReg ( UInt archreg ){ IRType ty = mode64 ? Ity_I64 : Ity_I32; vassert(archreg < 32); return IRExpr_Get( integerGuestRegOffset(archreg), ty );}/* Ditto, but write to a reg instead. */static void putIReg ( UInt archreg, IRExpr* e ){ IRType ty = mode64 ? Ity_I64 : Ity_I32; vassert(archreg < 32); vassert(typeOfIRExpr(irbb->tyenv, e) == ty ); stmt( IRStmt_Put(integerGuestRegOffset(archreg), e) );}static Int floatGuestRegOffset ( UInt archreg ){ vassert(archreg < 32); switch (archreg) { case 0: return offsetofPPCGuestState(guest_FPR0); case 1: return offsetofPPCGuestState(guest_FPR1); case 2: return offsetofPPCGuestState(guest_FPR2); case 3: return offsetofPPCGuestState(guest_FPR3); case 4: return offsetofPPCGuestState(guest_FPR4); case 5: return offsetofPPCGuestState(guest_FPR5); case 6: return offsetofPPCGuestState(guest_FPR6); case 7: return offsetofPPCGuestState(guest_FPR7); case 8: return offsetofPPCGuestState(guest_FPR8); case 9: return offsetofPPCGuestState(guest_FPR9); case 10: return offsetofPPCGuestState(guest_FPR10); case 11: return offsetofPPCGuestState(guest_FPR11); case 12: return offsetofPPCGuestState(guest_FPR12); case 13: return offsetofPPCGuestState(guest_FPR13); case 14: return offsetofPPCGuestState(guest_FPR14); case 15: return offsetofPPCGuestState(guest_FPR15); case 16: return offsetofPPCGuestState(guest_FPR16); case 17: return offsetofPPCGuestState(guest_FPR17); case 18: return offsetofPPCGuestState(guest_FPR18); case 19: return offsetofPPCGuestState(guest_FPR19); case 20: return offsetofPPCGuestState(guest_FPR20); case 21: return offsetofPPCGuestState(guest_FPR21); case 22: return offsetofPPCGuestState(guest_FPR22); case 23: return offsetofPPCGuestState(guest_FPR23); case 24: return offsetofPPCGuestState(guest_FPR24); case 25: return offsetofPPCGuestState(guest_FPR25); case 26: return offsetofPPCGuestState(guest_FPR26); case 27: return offsetofPPCGuestState(guest_FPR27); case 28: return offsetofPPCGuestState(guest_FPR28); case 29: return offsetofPPCGuestState(guest_FPR29); case 30: return offsetofPPCGuestState(guest_FPR30); case 31: return offsetofPPCGuestState(guest_FPR31); default: break; } vpanic("floatGuestRegOffset(ppc)"); /*notreached*/}static IRExpr* getFReg ( UInt archreg ){ vassert(archreg < 32); return IRExpr_Get( floatGuestRegOffset(archreg), Ity_F64 );}/* Ditto, but write to a reg instead. */static void putFReg ( UInt archreg, IRExpr* e ){ vassert(archreg < 32); vassert(typeOfIRExpr(irbb->tyenv, e) == Ity_F64); stmt( IRStmt_Put(floatGuestRegOffset(archreg), e) );}static Int vectorGuestRegOffset ( UInt archreg ){ vassert(archreg < 32); switch (archreg) { case 0: return offsetofPPCGuestState(guest_VR0); case 1: return offsetofPPCGuestState(guest_VR1); case 2: return offsetofPPCGuestState(guest_VR2); case 3: return offsetofPPCGuestState(guest_VR3); case 4: return offsetofPPCGuestState(guest_VR4); case 5: return offsetofPPCGuestState(guest_VR5); case 6: return offsetofPPCGuestState(guest_VR6); case 7: return offsetofPPCGuestState(guest_VR7); case 8: return offsetofPPCGuestState(guest_VR8); case 9: return offsetofPPCGuestState(guest_VR9); case 10: return offsetofPPCGuestState(guest_VR10); case 11: return offsetofPPCGuestState(guest_VR11); case 12: return offsetofPPCGuestState(guest_VR12); case 13: return offsetofPPCGuestState(guest_VR13); case 14: return offsetofPPCGuestState(guest_VR14); case 15: return offsetofPPCGuestState(guest_VR15); case 16: return offsetofPPCGuestState(guest_VR16); case 17: return offsetofPPCGuestState(guest_VR17); case 18: return offsetofPPCGuestState(guest_VR18); case 19: return offsetofPPCGuestState(guest_VR19); case 20: return offsetofPPCGuestState(guest_VR20); case 21: return offsetofPPCGuestState(guest_VR21); case 22: return offsetofPPCGuestState(guest_VR22); case 23: return offsetofPPCGuestState(guest_VR23); case 24: return offsetofPPCGuestState(guest_VR24); case 25: return offsetofPPCGuestState(guest_VR25); case 26: return offsetofPPCGuestState(guest_VR26); case 27: return offsetofPPCGuestState(guest_VR27); case 28: return offsetofPPCGuestState(guest_VR28); case 29: return offsetofPPCGuestState(guest_VR29); case 30: return offsetofPPCGuestState(guest_VR30); case 31: return offsetofPPCGuestState(guest_VR31); default: break; } vpanic("vextorGuestRegOffset(ppc)"); /*notreached*/}static IRExpr* getVReg ( UInt archreg ){ vassert(archreg < 32); return IRExpr_Get( vectorGuestRegOffset(archreg), Ity_V128 );}/* Ditto, but write to a reg instead. */static void putVReg ( UInt archreg, IRExpr* e ){ vassert(archreg < 32); vassert(typeOfIRExpr(irbb->tyenv, e) == Ity_V128); stmt( IRStmt_Put(vectorGuestRegOffset(archreg), e) );}static Int guestCR321offset ( UInt cr ){ switch (cr) { case 0: return offsetofPPCGuestState(guest_CR0_321 ); case 1: return offsetofPPCGuestState(guest_CR1_321 ); case 2: return offsetofPPCGuestState(guest_CR2_321 ); case 3: return offsetofPPCGuestState(guest_CR3_321 ); case 4: return offsetofPPCGuestState(guest_CR4_321 ); case 5: return offsetofPPCGuestState(guest_CR5_321 ); case 6: return offsetofPPCGuestState(guest_CR6_321 ); case 7: return offsetofPPCGuestState(guest_CR7_321 ); default: vpanic("guestCR321offset(ppc)"); }} static Int guestCR0offset ( UInt cr ){ switch (cr) { case 0: return offsetofPPCGuestState(guest_CR0_0 ); case 1: return offsetofPPCGuestState(guest_CR1_0 ); case 2: return offsetofPPCGuestState(guest_CR2_0 ); case 3: return offsetofPPCGuestState(guest_CR3_0 ); case 4: return offsetofPPCGuestState(guest_CR4_0 ); case 5: return offsetofPPCGuestState(guest_CR5_0 ); case 6: return offsetofPPCGuestState(guest_CR6_0 ); case 7: return offsetofPPCGuestState(guest_CR7_0 ); default: vpanic("guestCR3offset(ppc)"); }}// ROTL(src32/64, rot_amt5/6)static IRExpr* /* :: Ity_I32/64 */ ROTL ( IRExpr* src, IRExpr* rot_amt ){ IRExpr *mask, *rot; vassert(typeOfIRExpr(irbb->tyenv,rot_amt) == Ity_I8); if (typeOfIRExpr(irbb->tyenv,src) == Ity_I64) { // rot = (src << rot_amt) | (src >> (64-rot_amt)) mask = binop(Iop_And8, rot_amt, mkU8(63)); rot = binop(Iop_Or64, binop(Iop_Shl64, src, mask), binop(Iop_Shr64, src, binop(Iop_Sub8, mkU8(64), mask))); } else { // rot = (src << rot_amt) | (src >> (32-rot_amt)) mask = binop(Iop_And8, rot_amt, mkU8(31)); rot = binop(Iop_Or32, binop(Iop_Shl32, src, mask), binop(Iop_Shr32, src, binop(Iop_Sub8, mkU8(32), mask))); } /* Note: the MuxOX is not merely an optimisation; it's needed because otherwise the Shr is a shift by the word size when mask denotes zero. For rotates by immediates, a lot of this junk gets folded out. */ return IRExpr_Mux0X( mask, /* zero rotate */ src, /* non-zero rotate */ rot );}#if 0/* ROTL32_64(src64, rot_amt5) Weirdo 32bit rotl on ppc64: rot32 = ROTL(src_lo32,y); return (rot32|rot32);*/static IRExpr* /* :: Ity_I64 */ ROTL32_64 ( IRExpr* src64, IRExpr* rot_amt ){ IRExpr *mask, *rot32; vassert(mode64); // used only in 64bit mode vassert(typeOfIRExpr(irbb->tyenv,src64) == Ity_I64); vassert(typeOfIRExpr(irbb->tyenv,rot_amt) == Ity_I8); mask = binop(Iop_And8, rot_amt, mkU8(31)); rot32 = ROTL( unop(Iop_64to32, src64), rot_amt ); return binop(Iop_Or64, binop(Iop_Shl64, unop(Iop_32Uto64, rot32), mkU8(32)), unop(Iop_32Uto64, rot32));}#endif/* Standard effective address calc: (rA + rB) */static IRExpr* ea_rA_idxd ( UInt rA, UInt rB ){ IRType ty = mode64 ? Ity_I64 : Ity_I32; vassert(rA < 32); vassert(rB < 32); return binop(mkSzOp(ty, Iop_Add8), getIReg(rA), getIReg(rB));}/* Standard effective address calc: (rA + simm) */static IRExpr* ea_rA_simm ( UInt rA, UInt simm16 ){ IRType ty = mode64 ? Ity_I64 : Ity_I32; vassert(rA < 32); return binop(mkSzOp(ty, Iop_Add8), getIReg(rA), mkSzExtendS16(ty, simm16));}/* Standard effective address calc: (rA|0) */static IRExpr* ea_rAor0 ( UInt rA ){ IRType ty = mode64 ? Ity_I64 : Ity_I32; vassert(rA < 32); if (rA == 0) { return mkSzImm(ty, 0); } else { return getIReg(rA); }}/* Standard effective address calc: (rA|0) + rB */static IRExpr* ea_rAor0_idxd ( UInt rA, UInt rB ){ vassert(rA < 32); vassert(rB < 32); return (rA == 0) ? getIReg(rB) : ea_rA_idxd( rA, rB );}/* Standard effective address calc: (rA|0) + simm16 */static IRExpr* ea_rAor0_simm ( UInt rA, UInt simm16 ){ IRType ty = mode64 ? Ity_I64 : Ity_I32; vassert(rA < 32); if (rA == 0) { return mkSzExtendS16(ty, simm16); } else { return ea_rA_simm( rA, simm16 ); }}/* Align effective address */static IRExpr* addr_align( IRExpr* addr, UChar align ){ IRType ty = mode64 ? Ity_I64 : Ity_I32; Long mask; switch (align) { case 1: return addr; // byte aligned case 2: mask = ((Long)-1) << 1; break; // half-word aligned case 4: mask = ((Long)-1) << 2; break; // word aligned case 16: mask = ((Long)-1) << 4; break; // quad-word aligned default: vex_printf("addr_align: align = %u\n", align); vpanic("addr_align(ppc)"); } vassert(typeOfIRExpr(irbb->tyenv,addr) == ty); return binop( mkSzOp(ty, Iop_And8), addr, mkSzImm(ty, mask) );}/* Generate AbiHints which mark points at which the ELF ppc64 ABI says
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -