i->Xin.FpI64.iregLo = iregLo;
return i;
}
+X86Instr* X86Instr_FpCMov ( X86CondCode cond, HReg src, HReg dst ) {
+ X86Instr* i = LibVEX_Alloc(sizeof(X86Instr));
+ i->tag = Xin_FpCMov;
+ i->Xin.FpCMov.cond = cond;
+ i->Xin.FpCMov.src = src;
+ i->Xin.FpCMov.dst = dst;
+ vassert(cond != Xcc_ALWAYS);
+ return i;
+}
void ppX86Instr ( X86Instr* i ) {
ppHRegX86(i->Xin.FpI64.freg);
}
return;
+ case Xin_FpCMov:
+ vex_printf("gcmov%s ", showX86CondCode(i->Xin.FpCMov.cond));
+ ppHRegX86(i->Xin.FpCMov.src);
+ vex_printf(",");
+ ppHRegX86(i->Xin.FpCMov.dst);
+ return;
default:
vpanic("ppX86Instr");
}
Xin_FpUnary, /* FP fake unary op */
Xin_FpBinary, /* FP fake binary op */
Xin_FpLdSt, /* FP fake load/store */
- Xin_FpI64 /* FP fake to/from 64-bit signed int */
+ Xin_FpI64, /* FP fake to/from 64-bit signed int */
+ Xin_FpCMov /* FP fake floating point conditional move */
}
X86InstrTag;
HReg iregHi;
HReg iregLo;
} FpI64;
- } Xin;
+ /* Mov src to dst on the given condition, which may not
+ be the bogus Xcc_ALWAYS. */
+ struct {
+ X86CondCode cond;
+ HReg src;
+ HReg dst;
+ } FpCMov;
+ } Xin;
}
X86Instr;
extern X86Instr* X86Instr_FpLdSt ( Bool isLoad, UChar sz, HReg reg, X86AMode* );
extern X86Instr* X86Instr_FpI64 ( Bool toInt, HReg freg,
HReg iregHi, HReg iregLo );
+extern X86Instr* X86Instr_FpCMov ( X86CondCode, HReg src, HReg dst );
extern void ppX86Instr ( X86Instr* );
break;
}
+ case Iex_GetI: {
+ /* First off, compute the index expression into an integer reg.
+ The referenced address will then be 0 + ebp + reg*1, that is,
+ an X86AMode_IRRS. */
+ HReg idx = iselIntExpr_R(env, e->Iex.GetI.offset);
+ HReg dst = newVRegI(env);
+ if (ty == Ity_I8) {
+ addInstr(env,
+ X86Instr_LoadEX(
+ 1, False,
+ X86AMode_IRRS(0, hregX86_EBP(), idx, 0),
+ dst ));
+ return dst;
+ }
+ }
+
/* --------- CCALL --------- */
case Iex_CCall: {
Addr64 helper;
static HReg iselDblExpr ( ISelEnv* env, IRExpr* e )
{
- // MatchInfo mi;
+ // MatchInfo mi;
+ IRType ty = typeOfIRExpr(env->type_env,e);
vassert(e);
- vassert(typeOfIRExpr(env->type_env,e) == Ity_F64);
+ vassert(ty == Ity_F64);
if (e->tag == Iex_Tmp) {
return lookupIRTemp(env, e->Iex.Tmp.tmp);
if (e->tag == Iex_GetI) {
/* First off, compute the index expression into an integer reg.
- The written address will then be 0 + ebp + reg*1, that is, an
- X86AMode_IRRS. */
+ The referenced address will then be 0 + ebp + reg*1, that is,
+ an X86AMode_IRRS. */
HReg idx = iselIntExpr_R(env, e->Iex.GetI.offset);
HReg res = newVRegF(env);
addInstr(env,
}
}
+ /* --------- MULTIPLEX --------- */
+ if (e->tag == Iex_Mux0X) {
+ if (ty == Ity_F64
+ && typeOfIRExpr(env->type_env,e->Iex.Mux0X.cond) == Ity_I8) {
+ HReg r8 = iselIntExpr_R(env, e->Iex.Mux0X.cond);
+ HReg rX = iselDblExpr(env, e->Iex.Mux0X.exprX);
+ HReg r0 = iselDblExpr(env, e->Iex.Mux0X.expr0);
+ HReg dst = newVRegF(env);
+ addInstr(env, X86Instr_FpCMov(Xcc_ALWAYS,rX,dst));
+ addInstr(env, X86Instr_Test32(X86RI_Imm(0xFF), X86RM_Reg(r8)));
+ addInstr(env, X86Instr_FpCMov(Xcc_Z,r0,dst));
+ return dst;
+ }
+ }
+
ppIRExpr(e);
vpanic("iselDblExpr");
}