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

📄 isel.c

📁 The Valgrind distribution has multiple tools. The most popular is the memory checking tool (called M
💻 C
📖 第 1 页 / 共 5 页
字号:
      if (e->Iex.Binop.op == Iop_F64toI32) {         /* This works in both mode64 and mode32. */         HReg      r1      = StackFramePtr(env->mode64);         PPCAMode* zero_r1 = PPCAMode_IR( 0, r1 );         HReg      fsrc    = iselDblExpr(env, e->Iex.Binop.arg2);         HReg      ftmp    = newVRegF(env);         HReg      idst    = newVRegI(env);         /* Set host rounding mode */         set_FPU_rounding_mode( env, e->Iex.Binop.arg1 );         sub_from_sp( env, 16 );         addInstr(env, PPCInstr_FpCftI(False/*F->I*/, True/*int32*/,                                        ftmp, fsrc));         addInstr(env, PPCInstr_FpSTFIW(r1, ftmp));         addInstr(env, PPCInstr_Load(4, idst, zero_r1, mode64));         /* in 64-bit mode we need to sign-widen idst. */         if (mode64)            addInstr(env, PPCInstr_Unary(Pun_EXTSW, idst, idst));         add_to_sp( env, 16 );         ///* Restore default FPU rounding. */         //set_FPU_rounding_default( env );         return idst;      }      if (e->Iex.Binop.op == Iop_F64toI64) {         if (mode64) {            HReg      r1      = StackFramePtr(env->mode64);            PPCAMode* zero_r1 = PPCAMode_IR( 0, r1 );            HReg      fsrc    = iselDblExpr(env, e->Iex.Binop.arg2);            HReg      idst    = newVRegI(env);                     HReg      ftmp    = newVRegF(env);            /* Set host rounding mode */            set_FPU_rounding_mode( env, e->Iex.Binop.arg1 );            sub_from_sp( env, 16 );            addInstr(env, PPCInstr_FpCftI(False/*F->I*/, False/*int64*/,                                          ftmp, fsrc));            addInstr(env, PPCInstr_FpLdSt(False/*store*/, 8, ftmp, zero_r1));            addInstr(env, PPCInstr_Load(8, idst, zero_r1, True/*mode64*/));            add_to_sp( env, 16 );            ///* Restore default FPU rounding. */            //set_FPU_rounding_default( env );            return idst;         }      }      break;   }   /* --------- UNARY OP --------- */   case Iex_Unop: {      IROp op_unop = e->Iex.Unop.op;      /* 1Uto8(32to1(expr32)) */      DEFINE_PATTERN(p_32to1_then_1Uto8,                     unop(Iop_1Uto8,unop(Iop_32to1,bind(0))));      if (matchIRExpr(&mi,p_32to1_then_1Uto8,e)) {         IRExpr* expr32 = mi.bindee[0];         HReg r_dst = newVRegI(env);         HReg r_src = iselWordExpr_R(env, expr32);         addInstr(env, PPCInstr_Alu(Palu_AND, r_dst,                                    r_src, PPCRH_Imm(False,1)));         return r_dst;      }      /* 16Uto32(LDbe:I16(expr32)) */      {         DECLARE_PATTERN(p_LDbe16_then_16Uto32);         DEFINE_PATTERN(p_LDbe16_then_16Uto32,                        unop(Iop_16Uto32,                             IRExpr_Load(Iend_BE,Ity_I16,bind(0))) );         if (matchIRExpr(&mi,p_LDbe16_then_16Uto32,e)) {            HReg r_dst = newVRegI(env);            PPCAMode* amode = iselWordExpr_AMode( env, mi.bindee[0] );            addInstr(env, PPCInstr_Load(2,r_dst,amode, mode64));            return r_dst;         }      }      switch (op_unop) {      case Iop_8Uto16:      case Iop_8Uto32:      case Iop_8Uto64:      case Iop_16Uto32:      case Iop_16Uto64: {         HReg   r_dst = newVRegI(env);         HReg   r_src = iselWordExpr_R(env, e->Iex.Unop.arg);         UShort mask  = toUShort(op_unop==Iop_16Uto64 ? 0xFFFF :                                 op_unop==Iop_16Uto32 ? 0xFFFF : 0xFF);         addInstr(env, PPCInstr_Alu(Palu_AND,r_dst,r_src,                                    PPCRH_Imm(False,mask)));         return r_dst;      }      case Iop_32Uto64: {         HReg r_dst = newVRegI(env);         HReg r_src = iselWordExpr_R(env, e->Iex.Unop.arg);         vassert(mode64);         addInstr(env,                  PPCInstr_Shft(Pshft_SHL, False/*64bit shift*/,                                r_dst, r_src, PPCRH_Imm(False,32)));         addInstr(env,                  PPCInstr_Shft(Pshft_SHR, False/*64bit shift*/,                                r_dst, r_dst, PPCRH_Imm(False,32)));         return r_dst;      }      case Iop_8Sto16:      case Iop_8Sto32:      case Iop_16Sto32: {         HReg   r_dst = newVRegI(env);         HReg   r_src = iselWordExpr_R(env, e->Iex.Unop.arg);         UShort amt   = toUShort(op_unop==Iop_16Sto32 ? 16 : 24);         addInstr(env,                  PPCInstr_Shft(Pshft_SHL, True/*32bit shift*/,                                r_dst, r_src, PPCRH_Imm(False,amt)));         addInstr(env,                  PPCInstr_Shft(Pshft_SAR, True/*32bit shift*/,                                r_dst, r_dst, PPCRH_Imm(False,amt)));         return r_dst;      }      case Iop_8Sto64:      case Iop_16Sto64:      case Iop_32Sto64: {         HReg   r_dst = newVRegI(env);         HReg   r_src = iselWordExpr_R(env, e->Iex.Unop.arg);         UShort amt   = toUShort(op_unop==Iop_8Sto64  ? 56 :                                 op_unop==Iop_16Sto64 ? 48 : 32);         vassert(mode64);         addInstr(env,                  PPCInstr_Shft(Pshft_SHL, False/*64bit shift*/,                                r_dst, r_src, PPCRH_Imm(False,amt)));         addInstr(env,                  PPCInstr_Shft(Pshft_SAR, False/*64bit shift*/,                                r_dst, r_dst, PPCRH_Imm(False,amt)));         return r_dst;      }      case Iop_Not8:      case Iop_Not16:      case Iop_Not32:      case Iop_Not64: {         HReg r_dst = newVRegI(env);         HReg r_src = iselWordExpr_R(env, e->Iex.Unop.arg);         addInstr(env, PPCInstr_Unary(Pun_NOT,r_dst,r_src));         return r_dst;      }      case Iop_64HIto32: {         if (!mode64) {            HReg rHi, rLo;            iselInt64Expr(&rHi,&rLo, env, e->Iex.Unop.arg);            return rHi; /* and abandon rLo .. poor wee thing :-) */         } else {            HReg   r_dst = newVRegI(env);            HReg   r_src = iselWordExpr_R(env, e->Iex.Unop.arg);            addInstr(env,                     PPCInstr_Shft(Pshft_SHR, False/*64bit shift*/,                                   r_dst, r_src, PPCRH_Imm(False,32)));            return r_dst;         }      }      case Iop_64to32: {         if (!mode64) {            HReg rHi, rLo;            iselInt64Expr(&rHi,&rLo, env, e->Iex.Unop.arg);            return rLo; /* similar stupid comment to the above ... */         } else {            /* This is a no-op. */            return iselWordExpr_R(env, e->Iex.Unop.arg);         }      }      case Iop_64to16: {         if (mode64) { /* This is a no-op. */            return iselWordExpr_R(env, e->Iex.Unop.arg);         }         break; /* evidently not used in 32-bit mode */      }      case Iop_16HIto8:      case Iop_32HIto16: {         HReg   r_dst = newVRegI(env);         HReg   r_src = iselWordExpr_R(env, e->Iex.Unop.arg);         UShort shift = toUShort(op_unop == Iop_16HIto8 ? 8 : 16);         addInstr(env,                  PPCInstr_Shft(Pshft_SHR, True/*32bit shift*/,                                r_dst, r_src, PPCRH_Imm(False,shift)));         return r_dst;      }      case Iop_128HIto64:          if (mode64) {            HReg rHi, rLo;            iselInt128Expr(&rHi,&rLo, env, e->Iex.Unop.arg);            return rHi; /* and abandon rLo .. poor wee thing :-) */         }         break;      case Iop_128to64:         if (mode64) {            HReg rHi, rLo;            iselInt128Expr(&rHi,&rLo, env, e->Iex.Unop.arg);            return rLo; /* similar stupid comment to the above ... */         }         break;      case Iop_1Uto32:      case Iop_1Uto8: {         HReg        r_dst = newVRegI(env);         PPCCondCode cond  = iselCondCode(env, e->Iex.Unop.arg);         addInstr(env, PPCInstr_Set(cond,r_dst));         return r_dst;      }      case Iop_1Sto8:      case Iop_1Sto16:      case Iop_1Sto32: {         /* could do better than this, but for now ... */         HReg        r_dst = newVRegI(env);         PPCCondCode cond  = iselCondCode(env, e->Iex.Unop.arg);         addInstr(env, PPCInstr_Set(cond,r_dst));         addInstr(env,                  PPCInstr_Shft(Pshft_SHL, True/*32bit shift*/,                                r_dst, r_dst, PPCRH_Imm(False,31)));         addInstr(env,                  PPCInstr_Shft(Pshft_SAR, True/*32bit shift*/,                                r_dst, r_dst, PPCRH_Imm(False,31)));         return r_dst;      }      case Iop_1Sto64:          if (mode64) {            /* could do better than this, but for now ... */            HReg        r_dst = newVRegI(env);            PPCCondCode cond  = iselCondCode(env, e->Iex.Unop.arg);            addInstr(env, PPCInstr_Set(cond,r_dst));            addInstr(env, PPCInstr_Shft(Pshft_SHL, False/*64bit shift*/,                                        r_dst, r_dst, PPCRH_Imm(False,63)));            addInstr(env, PPCInstr_Shft(Pshft_SAR, False/*64bit shift*/,                                        r_dst, r_dst, PPCRH_Imm(False,63)));            return r_dst;         }         break;      case Iop_Clz32:      case Iop_Clz64: {         HReg r_src, r_dst;         PPCUnaryOp op_clz = (op_unop == Iop_Clz32) ? Pun_CLZ32 :                                                      Pun_CLZ64;         if (op_unop == Iop_Clz64 && !mode64)            goto irreducible;         /* Count leading zeroes. */         r_dst = newVRegI(env);         r_src = iselWordExpr_R(env, e->Iex.Unop.arg);         addInstr(env, PPCInstr_Unary(op_clz,r_dst,r_src));         return r_dst;      }      case Iop_Neg8:      case Iop_Neg16:      case Iop_Neg32:      case Iop_Neg64: {         HReg r_dst = newVRegI(env);         HReg r_src = iselWordExpr_R(env, e->Iex.Unop.arg);         if (op_unop == Iop_Neg64 && !mode64)            goto irreducible;         addInstr(env, PPCInstr_Unary(Pun_NEG,r_dst,r_src));         return r_dst;      }      case Iop_V128to32: {         HReg        r_aligned16;         HReg        dst  = newVRegI(env);         HReg        vec  = iselVecExpr(env, e->Iex.Unop.arg);         PPCAMode *am_off0, *am_off12;         sub_from_sp( env, 32 );     // Move SP down 32 bytes         // get a quadword aligned address within our stack space         r_aligned16 = get_sp_aligned16( env );         am_off0  = PPCAMode_IR( 0, r_aligned16 );         am_off12 = PPCAMode_IR( 12,r_aligned16 );         // store vec, load low word to dst         addInstr(env,                  PPCInstr_AvLdSt( False/*store*/, 16, vec, am_off0 ));         addInstr(env,                  PPCInstr_Load( 4, dst, am_off12, mode64 ));         add_to_sp( env, 32 );       // Reset SP         return dst;      }      case Iop_V128to64:      case Iop_V128HIto64:          if (mode64) {            HReg     r_aligned16;            HReg     dst = newVRegI(env);            HReg     vec = iselVecExpr(env, e->Iex.Unop.arg);            PPCAMode *am_off0, *am_off8;            sub_from_sp( env, 32 );     // Move SP down 32 bytes            // get a quadword aligned address within our stack space            r_aligned16 = get_sp_aligned16( env );            am_off0 = PPCAMode_IR( 0, r_aligned16 );            am_off8 = PPCAMode_IR( 8 ,r_aligned16 );            // store vec, load low word (+8) or high (+0) to dst            addInstr(env,                     PPCInstr_AvLdSt( False/*store*/, 16, vec, am_off0 ));            addInstr(env,                     PPCInstr_Load(                         8, dst,                         op_unop == Iop_V128HIto64 ? am_off0 : am_off8,                         mode64 ));            add_to_sp( env, 32 );       // Reset SP            return dst;         }         break;      case Iop_16to8:      case Iop_32to8:      case Iop_32to16:      case Iop_64to8:         /* These are no-ops. */         if (op_unop == Iop_Neg64 && !mode64)            goto irreducible;         return iselWordExpr_R(env, e->Iex.Unop.arg);               /* ReinterpF64asI64(e) */      /* Given an IEEE754 double, produce an I64 with the same bit         pattern. */      case Iop_ReinterpF64asI64:          if (mode64) {            PPCAMode *am_addr;            HReg fr_src = iselDblExpr(env, e->Iex.Unop.arg);            HReg r_dst  = newVRegI(env);            sub_from_sp( env, 16 );     // Move SP down 16 bytes            am_addr = PPCAMode_IR( 0, StackFramePtr(mode64) );            // store as F64            addInstr(env, PPCInstr_FpLdSt( False/*store*/, 8,                                           fr_src, am_addr ));            // load as Ity_I64            addInstr(env, PPCInstr_Load( 8, r_dst, am_addr, mode64 ));            add_to_sp( env, 16 );       // Reset SP            return r_dst;         }         break;      default:          break;      }      break;   }   /* --------- GET --------- */   case Iex_Get: {      if (ty == Ity_I8 

⌨️ 快捷键说明

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