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

📄 isel.c

📁 The Valgrind distribution has multiple tools. The most popular is the memory checking tool (called M
💻 C
📖 第 1 页 / 共 5 页
字号:
      addInstr(env, PPCInstr_AvSplat(sz, dst, PPCVI5s_Reg(v_src)));      return dst;   }}/* for each lane of vSrc: lane == nan ? laneX = all 1's : all 0's */static HReg isNan ( ISelEnv* env, HReg vSrc ){   HReg zeros, msk_exp, msk_mnt, expt, mnts, vIsNan;    vassert(hregClass(vSrc) == HRcVec128);   zeros   = mk_AvDuplicateRI(env, mkU32(0));   msk_exp = mk_AvDuplicateRI(env, mkU32(0x7F800000));   msk_mnt = mk_AvDuplicateRI(env, mkU32(0x7FFFFF));   expt    = newVRegV(env);   mnts    = newVRegV(env);   vIsNan  = newVRegV(env);    /* 32bit float => sign(1) | exponent(8) | mantissa(23)      nan => exponent all ones, mantissa > 0 */   addInstr(env, PPCInstr_AvBinary(Pav_AND, expt, vSrc, msk_exp));   addInstr(env, PPCInstr_AvBin32x4(Pav_CMPEQU, expt, expt, msk_exp));   addInstr(env, PPCInstr_AvBinary(Pav_AND, mnts, vSrc, msk_mnt));   addInstr(env, PPCInstr_AvBin32x4(Pav_CMPGTU, mnts, mnts, zeros));   addInstr(env, PPCInstr_AvBinary(Pav_AND, vIsNan, expt, mnts));   return vIsNan;}/*---------------------------------------------------------*//*--- ISEL: Integer expressions (64/32/16/8 bit)        ---*//*---------------------------------------------------------*//* Select insns for an integer-typed expression, and add them to the   code list.  Return a reg holding the result.  This reg will be a   virtual register.  THE RETURNED REG MUST NOT BE MODIFIED.  If you   want to modify it, ask for a new vreg, copy it in there, and modify   the copy.  The register allocator will do its best to map both   vregs to the same real register, so the copies will often disappear   later in the game.   This should handle expressions of 64, 32, 16 and 8-bit type.   All results are returned in a (mode64 ? 64bit : 32bit) register.   For 16- and 8-bit expressions, the upper (32/48/56 : 16/24) bits   are arbitrary, so you should mask or sign extend partial values   if necessary.*/static HReg iselWordExpr_R ( ISelEnv* env, IRExpr* e ){   HReg r = iselWordExpr_R_wrk(env, e);   /* sanity checks ... */#  if 0   vex_printf("\n"); ppIRExpr(e); vex_printf("\n");#  endif   vassert(hregClass(r) == HRcGPR(env->mode64));   vassert(hregIsVirtual(r));   return r;}/* DO NOT CALL THIS DIRECTLY ! */static HReg iselWordExpr_R_wrk ( ISelEnv* env, IRExpr* e ){   Bool mode64 = env->mode64;   MatchInfo mi;   DECLARE_PATTERN(p_32to1_then_1Uto8);   IRType ty = typeOfIRExpr(env->type_env,e);   vassert(ty == Ity_I8 || ty == Ity_I16 ||           ty == Ity_I32 || ((ty == Ity_I64) && mode64));   switch (e->tag) {   /* --------- TEMP --------- */   case Iex_Tmp:      return lookupIRTemp(env, e->Iex.Tmp.tmp);   /* --------- LOAD --------- */   case Iex_Load: {      HReg        r_dst   = newVRegI(env);      PPCAMode* am_addr = iselWordExpr_AMode( env, e->Iex.Load.addr );      if (e->Iex.Load.end != Iend_BE)         goto irreducible;      addInstr(env, PPCInstr_Load( toUChar(sizeofIRType(ty)),                                    r_dst, am_addr, mode64 ));      return r_dst;      break;   }   /* --------- BINARY OP --------- */   case Iex_Binop: {      PPCAluOp  aluOp;      PPCShftOp shftOp;      /* Is it an addition or logical style op? */      switch (e->Iex.Binop.op) {      case Iop_Add8: case Iop_Add16: case Iop_Add32: case Iop_Add64:         aluOp = Palu_ADD; break;      case Iop_Sub8: case Iop_Sub16: case Iop_Sub32: case Iop_Sub64:         aluOp = Palu_SUB; break;      case Iop_And8: case Iop_And16: case Iop_And32: case Iop_And64:         aluOp = Palu_AND; break;      case Iop_Or8:  case Iop_Or16:  case Iop_Or32:  case Iop_Or64:         aluOp = Palu_OR; break;      case Iop_Xor8: case Iop_Xor16: case Iop_Xor32: case Iop_Xor64:         aluOp = Palu_XOR; break;      default:         aluOp = Palu_INVALID; break;      }      /* For commutative ops we assume any literal         values are on the second operand. */      if (aluOp != Palu_INVALID) {         HReg   r_dst   = newVRegI(env);         HReg   r_srcL  = iselWordExpr_R(env, e->Iex.Binop.arg1);         PPCRH* ri_srcR = NULL;         /* get right arg into an RH, in the appropriate way */         switch (aluOp) {         case Palu_ADD: case Palu_SUB:            ri_srcR = iselWordExpr_RH(env, True/*signed*/,                                       e->Iex.Binop.arg2);            break;         case Palu_AND: case Palu_OR: case Palu_XOR:            ri_srcR = iselWordExpr_RH(env, False/*signed*/,                                      e->Iex.Binop.arg2);            break;         default:            vpanic("iselWordExpr_R_wrk-aluOp-arg2");         }         addInstr(env, PPCInstr_Alu(aluOp, r_dst, r_srcL, ri_srcR));         return r_dst;      }      /* a shift? */      switch (e->Iex.Binop.op) {      case Iop_Shl8: case Iop_Shl16: case Iop_Shl32: case Iop_Shl64:         shftOp = Pshft_SHL; break;      case Iop_Shr8: case Iop_Shr16: case Iop_Shr32: case Iop_Shr64:         shftOp = Pshft_SHR; break;      case Iop_Sar8: case Iop_Sar16: case Iop_Sar32: case Iop_Sar64:         shftOp = Pshft_SAR; break;      default:         shftOp = Pshft_INVALID; break;      }      /* we assume any literal values are on the second operand. */      if (shftOp != Pshft_INVALID) {         HReg   r_dst   = newVRegI(env);         HReg   r_srcL  = iselWordExpr_R(env, e->Iex.Binop.arg1);         PPCRH* ri_srcR = NULL;         /* get right arg into an RH, in the appropriate way */         switch (shftOp) {         case Pshft_SHL: case Pshft_SHR: case Pshft_SAR:            if (!mode64)               ri_srcR = iselWordExpr_RH5u(env, e->Iex.Binop.arg2);            else               ri_srcR = iselWordExpr_RH6u(env, e->Iex.Binop.arg2);            break;         default:            vpanic("iselIntExpr_R_wrk-shftOp-arg2");         }         /* widen the left arg if needed */         if (shftOp == Pshft_SHR || shftOp == Pshft_SAR) {            if (ty == Ity_I8 || ty == Ity_I16) {               PPCRH* amt = PPCRH_Imm(False,                                      toUShort(ty == Ity_I8 ? 24 : 16));               HReg   tmp = newVRegI(env);               addInstr(env, PPCInstr_Shft(Pshft_SHL,                                           True/*32bit shift*/,                                           tmp, r_srcL, amt));               addInstr(env, PPCInstr_Shft(shftOp,                                           True/*32bit shift*/,                                           tmp, tmp,    amt));               r_srcL = tmp;               vassert(0); /* AWAITING TEST CASE */            }         }         /* Only 64 expressions need 64bit shifts,            32bit shifts are fine for all others */         if (ty == Ity_I64) {            vassert(mode64);            addInstr(env, PPCInstr_Shft(shftOp, False/*64bit shift*/,                                        r_dst, r_srcL, ri_srcR));         } else {            addInstr(env, PPCInstr_Shft(shftOp, True/*32bit shift*/,                                        r_dst, r_srcL, ri_srcR));         }         return r_dst;      }      /* How about a div? */      if (e->Iex.Binop.op == Iop_DivS32 ||           e->Iex.Binop.op == Iop_DivU32) {         Bool syned  = toBool(e->Iex.Binop.op == Iop_DivS32);         HReg r_dst  = newVRegI(env);         HReg r_srcL = iselWordExpr_R(env, e->Iex.Binop.arg1);         HReg r_srcR = iselWordExpr_R(env, e->Iex.Binop.arg2);         addInstr(env, PPCInstr_Div(syned, True/*32bit div*/,                                    r_dst, r_srcL, r_srcR));         return r_dst;      }      if (e->Iex.Binop.op == Iop_DivS64 ||           e->Iex.Binop.op == Iop_DivU64) {         Bool syned  = toBool(e->Iex.Binop.op == Iop_DivS64);         HReg r_dst  = newVRegI(env);         HReg r_srcL = iselWordExpr_R(env, e->Iex.Binop.arg1);         HReg r_srcR = iselWordExpr_R(env, e->Iex.Binop.arg2);         vassert(mode64);         addInstr(env, PPCInstr_Div(syned, False/*64bit div*/,                                    r_dst, r_srcL, r_srcR));         return r_dst;      }      /* No? Anyone for a mul? */      if (e->Iex.Binop.op == Iop_Mul32          || e->Iex.Binop.op == Iop_Mul64) {         Bool syned       = False;         Bool sz32        = (e->Iex.Binop.op != Iop_Mul64);         HReg r_dst       = newVRegI(env);         HReg r_srcL      = iselWordExpr_R(env, e->Iex.Binop.arg1);         HReg r_srcR      = iselWordExpr_R(env, e->Iex.Binop.arg2);         addInstr(env, PPCInstr_MulL(syned, False/*lo32*/, sz32,                                     r_dst, r_srcL, r_srcR));         return r_dst;      }            /* 32 x 32 -> 64 multiply */      if (mode64          && (e->Iex.Binop.op == Iop_MullU32              || e->Iex.Binop.op == Iop_MullS32)) {         HReg tLo    = newVRegI(env);         HReg tHi    = newVRegI(env);         HReg r_dst  = newVRegI(env);         Bool syned  = toBool(e->Iex.Binop.op == Iop_MullS32);         HReg r_srcL = iselWordExpr_R(env, e->Iex.Binop.arg1);         HReg r_srcR = iselWordExpr_R(env, e->Iex.Binop.arg2);         addInstr(env, PPCInstr_MulL(False/*signedness irrelevant*/,                                      False/*lo32*/, True/*32bit mul*/,                                     tLo, r_srcL, r_srcR));         addInstr(env, PPCInstr_MulL(syned,                                     True/*hi32*/, True/*32bit mul*/,                                     tHi, r_srcL, r_srcR));         addInstr(env, PPCInstr_Shft(Pshft_SHL, False/*64bit shift*/,                                     r_dst, tHi, PPCRH_Imm(False,32)));         addInstr(env, PPCInstr_Alu(Palu_OR,                                    r_dst, r_dst, PPCRH_Reg(tLo)));         return r_dst;      }      /* El-mutanto 3-way compare? */      if (e->Iex.Binop.op == Iop_CmpORD32S          || e->Iex.Binop.op == Iop_CmpORD32U) {         Bool   syned = toBool(e->Iex.Binop.op == Iop_CmpORD32S);         HReg   dst   = newVRegI(env);         HReg   srcL  = iselWordExpr_R(env, e->Iex.Binop.arg1);         PPCRH* srcR  = iselWordExpr_RH(env, syned, e->Iex.Binop.arg2);         addInstr(env, PPCInstr_Cmp(syned, True/*32bit cmp*/,                                    7/*cr*/, srcL, srcR));         addInstr(env, PPCInstr_MfCR(dst));         addInstr(env, PPCInstr_Alu(Palu_AND, dst, dst,                                    PPCRH_Imm(False,7<<1)));         return dst;      }      if (e->Iex.Binop.op == Iop_CmpORD64S          || e->Iex.Binop.op == Iop_CmpORD64U) {         Bool   syned = toBool(e->Iex.Binop.op == Iop_CmpORD64S);         HReg   dst   = newVRegI(env);         HReg   srcL  = iselWordExpr_R(env, e->Iex.Binop.arg1);         PPCRH* srcR  = iselWordExpr_RH(env, syned, e->Iex.Binop.arg2);         vassert(mode64);         addInstr(env, PPCInstr_Cmp(syned, False/*64bit cmp*/,                                    7/*cr*/, srcL, srcR));         addInstr(env, PPCInstr_MfCR(dst));         addInstr(env, PPCInstr_Alu(Palu_AND, dst, dst,                                    PPCRH_Imm(False,7<<1)));         return dst;      }      if (e->Iex.Binop.op == Iop_32HLto64) {         HReg   r_Hi  = iselWordExpr_R(env, e->Iex.Binop.arg1);         HReg   r_Lo  = iselWordExpr_R(env, e->Iex.Binop.arg2);         HReg   r_dst = newVRegI(env);         HReg   msk   = newVRegI(env);         vassert(mode64);         /* r_dst = OR( r_Hi<<32, r_Lo ) */         addInstr(env, PPCInstr_Shft(Pshft_SHL, False/*64bit shift*/,                                     r_dst, r_Hi, PPCRH_Imm(False,32)));         addInstr(env, PPCInstr_LI(msk, 0xFFFFFFFF, mode64));         addInstr(env, PPCInstr_Alu( Palu_AND, r_Lo, r_Lo,                                     PPCRH_Reg(msk) ));         addInstr(env, PPCInstr_Alu( Palu_OR, r_dst, r_dst,                                     PPCRH_Reg(r_Lo) ));         return r_dst;      }      if (e->Iex.Binop.op == Iop_CmpF64) {         HReg fr_srcL    = iselDblExpr(env, e->Iex.Binop.arg1);         HReg fr_srcR    = iselDblExpr(env, e->Iex.Binop.arg2);         HReg r_ccPPC   = newVRegI(env);         HReg r_ccIR    = newVRegI(env);         HReg r_ccIR_b0 = newVRegI(env);         HReg r_ccIR_b2 = newVRegI(env);         HReg r_ccIR_b6 = newVRegI(env);         addInstr(env, PPCInstr_FpCmp(r_ccPPC, fr_srcL, fr_srcR));         /* Map compare result from PPC to IR,            conforming to CmpF64 definition. */         /*           FP cmp result | PPC | IR           --------------------------           UN            | 0x1 | 0x45           EQ            | 0x2 | 0x40           GT            | 0x4 | 0x00           LT            | 0x8 | 0x01         */         // r_ccIR_b0 = r_ccPPC[0] | r_ccPPC[3]         addInstr(env, PPCInstr_Shft(Pshft_SHR, True/*32bit shift*/,                                     r_ccIR_b0, r_ccPPC,                                     PPCRH_Imm(False,0x3)));         addInstr(env, PPCInstr_Alu(Palu_OR,  r_ccIR_b0,                                    r_ccPPC,   PPCRH_Reg(r_ccIR_b0)));         addInstr(env, PPCInstr_Alu(Palu_AND, r_ccIR_b0,                                    r_ccIR_b0, PPCRH_Imm(False,0x1)));                  // r_ccIR_b2 = r_ccPPC[0]         addInstr(env, PPCInstr_Shft(Pshft_SHL, True/*32bit shift*/,                                     r_ccIR_b2, r_ccPPC,                                     PPCRH_Imm(False,0x2)));         addInstr(env, PPCInstr_Alu(Palu_AND, r_ccIR_b2,                                    r_ccIR_b2, PPCRH_Imm(False,0x4)));         // r_ccIR_b6 = r_ccPPC[0] | r_ccPPC[1]         addInstr(env, PPCInstr_Shft(Pshft_SHR, True/*32bit shift*/,                                     r_ccIR_b6, r_ccPPC,                                     PPCRH_Imm(False,0x1)));         addInstr(env, PPCInstr_Alu(Palu_OR,  r_ccIR_b6,                                    r_ccPPC, PPCRH_Reg(r_ccIR_b6)));         addInstr(env, PPCInstr_Shft(Pshft_SHL, True/*32bit shift*/,                                     r_ccIR_b6, r_ccIR_b6,                                     PPCRH_Imm(False,0x6)));         addInstr(env, PPCInstr_Alu(Palu_AND, r_ccIR_b6,                                    r_ccIR_b6, PPCRH_Imm(False,0x40)));         // r_ccIR = r_ccIR_b0 | r_ccIR_b2 | r_ccIR_b6         addInstr(env, PPCInstr_Alu(Palu_OR, r_ccIR,                                    r_ccIR_b0, PPCRH_Reg(r_ccIR_b2)));         addInstr(env, PPCInstr_Alu(Palu_OR, r_ccIR,                                    r_ccIR,    PPCRH_Reg(r_ccIR_b6)));         return r_ccIR;      }

⌨️ 快捷键说明

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