⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 isel.c

📁 The Valgrind distribution has multiple tools. The most popular is the memory checking tool (called M
💻 C
📖 第 1 页 / 共 5 页
字号:
         addInstr(env, X86Instr_Alu32R(                          Xalu_MOV,                           X86RMI_Mem(X86AMode_IR(e->Iex.Get.offset,                                                 hregX86_EBP())),                          dst));         return dst;      }      if (ty == Ity_I8 || ty == Ity_I16) {         HReg dst = newVRegI(env);         addInstr(env, X86Instr_LoadEX(                          toUChar(ty==Ity_I8 ? 1 : 2),                          False,                          X86AMode_IR(e->Iex.Get.offset,hregX86_EBP()),                          dst));         return dst;      }      break;   }   case Iex_GetI: {      X86AMode* am          = genGuestArrayOffset(              env, e->Iex.GetI.descr,                    e->Iex.GetI.ix, e->Iex.GetI.bias );      HReg dst = newVRegI(env);      if (ty == Ity_I8) {         addInstr(env, X86Instr_LoadEX( 1, False, am, dst ));         return dst;      }      if (ty == Ity_I32) {         addInstr(env, X86Instr_Alu32R(Xalu_MOV, X86RMI_Mem(am), dst));         return dst;      }      break;   }   /* --------- CCALL --------- */   case Iex_CCall: {      HReg    dst = newVRegI(env);      vassert(ty == e->Iex.CCall.retty);      /* be very restrictive for now.  Only 32/64-bit ints allowed         for args, and 32 bits for return type. */      if (e->Iex.CCall.retty != Ity_I32)         goto irreducible;      /* Marshal args, do the call, clear stack. */      doHelperCall( env, False, NULL, e->Iex.CCall.cee, e->Iex.CCall.args );      addInstr(env, mk_iMOVsd_RR(hregX86_EAX(), dst));      return dst;   }   /* --------- LITERAL --------- */   /* 32/16/8-bit literals */   case Iex_Const: {      X86RMI* rmi = iselIntExpr_RMI ( env, e );      HReg    r   = newVRegI(env);      addInstr(env, X86Instr_Alu32R(Xalu_MOV, rmi, r));      return r;   }   /* --------- MULTIPLEX --------- */   case Iex_Mux0X: {     if ((ty == Ity_I32 || ty == Ity_I16 || ty == Ity_I8)         && typeOfIRExpr(env->type_env,e->Iex.Mux0X.cond) == Ity_I8) {        HReg r8;        HReg rX   = iselIntExpr_R(env, e->Iex.Mux0X.exprX);        X86RM* r0 = iselIntExpr_RM(env, e->Iex.Mux0X.expr0);        HReg dst = newVRegI(env);        addInstr(env, mk_iMOVsd_RR(rX,dst));        r8 = iselIntExpr_R(env, e->Iex.Mux0X.cond);        addInstr(env, X86Instr_Test32(0xFF, r8));        addInstr(env, X86Instr_CMov32(Xcc_Z,r0,dst));        return dst;      }      break;   }   default:    break;   } /* switch (e->tag) */   /* We get here if no pattern matched. */  irreducible:   ppIRExpr(e);   vpanic("iselIntExpr_R: cannot reduce tree");}/*---------------------------------------------------------*//*--- ISEL: Integer expression auxiliaries              ---*//*---------------------------------------------------------*//* --------------------- AMODEs --------------------- *//* Return an AMode which computes the value of the specified   expression, possibly also adding insns to the code list as a   result.  The expression may only be a 32-bit one.*/static Bool sane_AMode ( X86AMode* am ){   switch (am->tag) {      case Xam_IR:         return             toBool( hregClass(am->Xam.IR.reg) == HRcInt32                    && (hregIsVirtual(am->Xam.IR.reg)                        || am->Xam.IR.reg == hregX86_EBP()) );      case Xam_IRRS:         return             toBool( hregClass(am->Xam.IRRS.base) == HRcInt32                    && hregIsVirtual(am->Xam.IRRS.base)                    && hregClass(am->Xam.IRRS.index) == HRcInt32                    && hregIsVirtual(am->Xam.IRRS.index) );      default:        vpanic("sane_AMode: unknown x86 amode tag");   }}static X86AMode* iselIntExpr_AMode ( ISelEnv* env, IRExpr* e ){   X86AMode* am = iselIntExpr_AMode_wrk(env, e);   vassert(sane_AMode(am));   return am;}/* DO NOT CALL THIS DIRECTLY ! */static X86AMode* iselIntExpr_AMode_wrk ( ISelEnv* env, IRExpr* e ){   IRType ty = typeOfIRExpr(env->type_env,e);   vassert(ty == Ity_I32);   /* Add32(expr1, Shl32(expr2, imm)) */   if (e->tag == Iex_Binop       && e->Iex.Binop.op == Iop_Add32       && e->Iex.Binop.arg2->tag == Iex_Binop       && e->Iex.Binop.arg2->Iex.Binop.op == Iop_Shl32       && e->Iex.Binop.arg2->Iex.Binop.arg2->tag == Iex_Const       && e->Iex.Binop.arg2->Iex.Binop.arg2->Iex.Const.con->tag == Ico_U8) {      UInt shift = e->Iex.Binop.arg2->Iex.Binop.arg2->Iex.Const.con->Ico.U8;      if (shift == 1 || shift == 2 || shift == 3) {         HReg r1 = iselIntExpr_R(env, e->Iex.Binop.arg1);         HReg r2 = iselIntExpr_R(env, e->Iex.Binop.arg2->Iex.Binop.arg1 );         return X86AMode_IRRS(0, r1, r2, shift);      }   }   /* Add32(expr,i) */   if (e->tag == Iex_Binop        && e->Iex.Binop.op == Iop_Add32       && e->Iex.Binop.arg2->tag == Iex_Const       && e->Iex.Binop.arg2->Iex.Const.con->tag == Ico_U32) {      HReg r1 = iselIntExpr_R(env,  e->Iex.Binop.arg1);      return X86AMode_IR(e->Iex.Binop.arg2->Iex.Const.con->Ico.U32, r1);   }   /* Doesn't match anything in particular.  Generate it into      a register and use that. */   {      HReg r1 = iselIntExpr_R(env, e);      return X86AMode_IR(0, r1);   }}/* --------------------- RMIs --------------------- *//* Similarly, calculate an expression into an X86RMI operand.  As with   iselIntExpr_R, the expression can have type 32, 16 or 8 bits.  */static X86RMI* iselIntExpr_RMI ( ISelEnv* env, IRExpr* e ){   X86RMI* rmi = iselIntExpr_RMI_wrk(env, e);   /* sanity checks ... */   switch (rmi->tag) {      case Xrmi_Imm:         return rmi;      case Xrmi_Reg:         vassert(hregClass(rmi->Xrmi.Reg.reg) == HRcInt32);         vassert(hregIsVirtual(rmi->Xrmi.Reg.reg));         return rmi;      case Xrmi_Mem:         vassert(sane_AMode(rmi->Xrmi.Mem.am));         return rmi;      default:         vpanic("iselIntExpr_RMI: unknown x86 RMI tag");   }}/* DO NOT CALL THIS DIRECTLY ! */static X86RMI* iselIntExpr_RMI_wrk ( ISelEnv* env, IRExpr* e ){   IRType ty = typeOfIRExpr(env->type_env,e);   vassert(ty == Ity_I32 || ty == Ity_I16 || ty == Ity_I8);   /* special case: immediate */   if (e->tag == Iex_Const) {      UInt u;      switch (e->Iex.Const.con->tag) {         case Ico_U32: u = e->Iex.Const.con->Ico.U32; break;         case Ico_U16: u = 0xFFFF & (e->Iex.Const.con->Ico.U16); break;         case Ico_U8:  u = 0xFF   & (e->Iex.Const.con->Ico.U8); break;         default: vpanic("iselIntExpr_RMI.Iex_Const(x86h)");      }      return X86RMI_Imm(u);   }   /* special case: 32-bit GET */   if (e->tag == Iex_Get && ty == Ity_I32) {      return X86RMI_Mem(X86AMode_IR(e->Iex.Get.offset,                                    hregX86_EBP()));   }   /* special case: 32-bit load from memory */   if (e->tag == Iex_Load && ty == Ity_I32 && e->Iex.Load.end == Iend_LE) {      X86AMode* am = iselIntExpr_AMode(env, e->Iex.Load.addr);      return X86RMI_Mem(am);   }   /* default case: calculate into a register and return that */   {      HReg r = iselIntExpr_R ( env, e );      return X86RMI_Reg(r);   }}/* --------------------- RIs --------------------- *//* Calculate an expression into an X86RI operand.  As with   iselIntExpr_R, the expression can have type 32, 16 or 8 bits. */static X86RI* iselIntExpr_RI ( ISelEnv* env, IRExpr* e ){   X86RI* ri = iselIntExpr_RI_wrk(env, e);   /* sanity checks ... */   switch (ri->tag) {      case Xri_Imm:         return ri;      case Xrmi_Reg:         vassert(hregClass(ri->Xri.Reg.reg) == HRcInt32);         vassert(hregIsVirtual(ri->Xri.Reg.reg));         return ri;      default:         vpanic("iselIntExpr_RI: unknown x86 RI tag");   }}/* DO NOT CALL THIS DIRECTLY ! */static X86RI* iselIntExpr_RI_wrk ( ISelEnv* env, IRExpr* e ){   IRType ty = typeOfIRExpr(env->type_env,e);   vassert(ty == Ity_I32 || ty == Ity_I16 || ty == Ity_I8);   /* special case: immediate */   if (e->tag == Iex_Const) {      UInt u;      switch (e->Iex.Const.con->tag) {         case Ico_U32: u = e->Iex.Const.con->Ico.U32; break;         case Ico_U16: u = 0xFFFF & (e->Iex.Const.con->Ico.U16); break;         case Ico_U8:  u = 0xFF   & (e->Iex.Const.con->Ico.U8); break;         default: vpanic("iselIntExpr_RMI.Iex_Const(x86h)");      }      return X86RI_Imm(u);   }   /* default case: calculate into a register and return that */   {      HReg r = iselIntExpr_R ( env, e );      return X86RI_Reg(r);   }}/* --------------------- RMs --------------------- *//* Similarly, calculate an expression into an X86RM operand.  As with   iselIntExpr_R, the expression can have type 32, 16 or 8 bits.  */static X86RM* iselIntExpr_RM ( ISelEnv* env, IRExpr* e ){   X86RM* rm = iselIntExpr_RM_wrk(env, e);   /* sanity checks ... */   switch (rm->tag) {      case Xrm_Reg:         vassert(hregClass(rm->Xrm.Reg.reg) == HRcInt32);         vassert(hregIsVirtual(rm->Xrm.Reg.reg));         return rm;      case Xrm_Mem:         vassert(sane_AMode(rm->Xrm.Mem.am));         return rm;      default:         vpanic("iselIntExpr_RM: unknown x86 RM tag");   }}/* DO NOT CALL THIS DIRECTLY ! */static X86RM* iselIntExpr_RM_wrk ( ISelEnv* env, IRExpr* e ){   IRType ty = typeOfIRExpr(env->type_env,e);   vassert(ty == Ity_I32 || ty == Ity_I16 || ty == Ity_I8);   /* special case: 32-bit GET */   if (e->tag == Iex_Get && ty == Ity_I32) {      return X86RM_Mem(X86AMode_IR(e->Iex.Get.offset,                                   hregX86_EBP()));   }   /* special case: load from memory */   /* default case: calculate into a register and return that */   {      HReg r = iselIntExpr_R ( env, e );      return X86RM_Reg(r);   }}/* --------------------- CONDCODE --------------------- *//* Generate code to evaluated a bit-typed expression, returning the   condition code which would correspond when the expression would   notionally have returned 1. */static X86CondCode iselCondCode ( ISelEnv* env, IRExpr* e ){   /* Uh, there's nothing we can sanity check here, unfortunately. */   return iselCondCode_wrk(env,e);}/* DO NOT CALL THIS DIRECTLY ! */static X86CondCode iselCondCode_wrk ( ISelEnv* env, IRExpr* e ){   MatchInfo mi;   DECLARE_PATTERN(p_32to1);   DECLARE_PATTERN(p_1Uto32_then_32to1);   DECLARE_PATTERN(p_1Sto32_then_32to1);   vassert(e);   vassert(typeOfIRExpr(env->type_env,e) == Ity_I1);   /* var */   if (e->tag == Iex_Tmp) {      HReg r32 = lookupIRTemp(env, e->Iex.Tmp.tmp);      /* Test32 doesn't modify r32; so this is OK. */      addInstr(env, X86Instr_Test32(1,r32));      return Xcc_NZ;   }   /* Constant 1:Bit */   if (e->tag == Iex_Const) {      HReg r;      vassert(e->Iex.Const.con->tag == Ico_U1);      vassert(e->Iex.Const.con->Ico.U1 == True               || e->Iex.Const.con->Ico.U1 == False);      r = newVRegI(env);      addInstr(env, X86Instr_Alu32R(Xalu_MOV,X86RMI_Imm(0),r));      addInstr(env, X86Instr_Alu32R(Xalu_XOR,X86RMI_Reg(r),r));      return e->Iex.Const.con->Ico.U1 ? Xcc_Z : Xcc_NZ;   }   /* Not1(e) */   if (e->tag == Iex_Unop && e->Iex.Unop.op == Iop_Not1) {      /* Generate code for the arg, and negate the test condition */      return 1 ^ iselCondCode(env, e->Iex.Unop.arg);   }   /* --- patterns rooted at: 32to1 --- */   /* 32to1(1Uto32(e)) ==> e */   DEFINE_PATTERN(p_1Uto32_then_32to1,                  unop(Iop_32to1,unop(Iop_1Uto32,bind(0))));   if (matchIRExpr(&mi,p_1Uto32_then_32to1,e)) {      IRExpr* expr1 = mi.bindee[0];      return iselCondCode(env, expr1);   }   /* 32to1(1Sto32(e)) ==> e */   DEFINE_PATTERN(p_1Sto32_then_32to1,                  unop(Iop_32to1,unop(Iop_1Sto32,bind(0))));   if (matchIRExpr(&mi,p_1Sto32_then_32to1,e)) {      IRExpr* expr1 = mi.bindee[0];      return iselCondCode(env, expr1);   }   /* 32to1(expr32) */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -