static UInt s390_decode_and_irgen(UChar *, UInt, DisResult *);
static void s390_irgen_xonc(IROp, IRTemp, IRTemp, IRTemp);
static void s390_irgen_CLC_EX(IRTemp, IRTemp, IRTemp);
-static IRExpr *convert_vex_fpcc_to_s390(IRTemp);
/*------------------------------------------------------------*/
}
+/*------------------------------------------------------------*/
+/*--- Condition code helpers ---*/
+/*------------------------------------------------------------*/
+
+/* The result of a Iop_CmpFxx operation is a condition code. It is
+ encoded using the values defined in type IRCmpFxxResult.
+ Before we can store the condition code into the guest state (or do
+ anything else with it for that matter) we need to convert it to
+ the encoding that s390 uses. This is what this function does.
+
+ s390 VEX b6 b2 b0 cc.1 cc.0
+ 0 0x40 EQ 1 0 0 0 0
+ 1 0x01 LT 0 0 1 0 1
+ 2 0x00 GT 0 0 0 1 0
+ 3 0x45 Unordered 1 1 1 1 1
+
+ The following bits from the VEX encoding are interesting:
+ b0, b2, b6 with b0 being the LSB. We observe:
+
+ cc.0 = b0;
+ cc.1 = b2 | (~b0 & ~b6)
+
+ with cc being the s390 condition code.
+*/
+static IRExpr *
+convert_vex_bfpcc_to_s390(IRTemp vex_cc)
+{
+ IRTemp cc0 = newTemp(Ity_I32);
+ IRTemp cc1 = newTemp(Ity_I32);
+ IRTemp b0 = newTemp(Ity_I32);
+ IRTemp b2 = newTemp(Ity_I32);
+ IRTemp b6 = newTemp(Ity_I32);
+
+ assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1)));
+ assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)),
+ mkU32(1)));
+ assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)),
+ mkU32(1)));
+
+ assign(cc0, mkexpr(b0));
+ assign(cc1, binop(Iop_Or32, mkexpr(b2),
+ binop(Iop_And32,
+ binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */
+ binop(Iop_Sub32, mkU32(1), mkexpr(b6)) /* ~b6 */
+ )));
+
+ return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1)));
+}
+
+
+/* The result of a Iop_CmpDxx operation is a condition code. It is
+ encoded using the values defined in type IRCmpDxxResult.
+ Before we can store the condition code into the guest state (or do
+ anything else with it for that matter) we need to convert it to
+ the encoding that s390 uses. This is what this function does. */
+static IRExpr *
+convert_vex_dfpcc_to_s390(IRTemp vex_cc)
+{
+ /* The VEX encodings for IRCmpDxxResult and IRCmpFxxResult are the
+ same. currently. */
+ return convert_vex_dfpcc_to_s390(vex_cc);
+}
+
+
/*------------------------------------------------------------*/
/*--- Build IR for formats ---*/
/*------------------------------------------------------------*/
assign(op2, get_dpr_dw0(r2));
assign(cc_vex, binop(Iop_CmpD64, mkexpr(op1), mkexpr(op2)));
- assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
+ assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
return "cdtr";
assign(op2, get_dpr_pair(r2));
assign(cc_vex, binop(Iop_CmpD128, mkexpr(op1), mkexpr(op2)));
- assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
+ assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
return "cxtr";
return "axbr";
}
-/* The result of a Iop_CmdFxx operation is a condition code. It is
- encoded using the values defined in type IRCmpFxxResult.
- Before we can store the condition code into the guest state (or do
- anything else with it for that matter) we need to convert it to
- the encoding that s390 uses. This is what this function does.
-
- s390 VEX b6 b2 b0 cc.1 cc.0
- 0 0x40 EQ 1 0 0 0 0
- 1 0x01 LT 0 0 1 0 1
- 2 0x00 GT 0 0 0 1 0
- 3 0x45 Unordered 1 1 1 1 1
-
- The following bits from the VEX encoding are interesting:
- b0, b2, b6 with b0 being the LSB. We observe:
-
- cc.0 = b0;
- cc.1 = b2 | (~b0 & ~b6)
-
- with cc being the s390 condition code.
-*/
-static IRExpr *
-convert_vex_fpcc_to_s390(IRTemp vex_cc)
-{
- IRTemp cc0 = newTemp(Ity_I32);
- IRTemp cc1 = newTemp(Ity_I32);
- IRTemp b0 = newTemp(Ity_I32);
- IRTemp b2 = newTemp(Ity_I32);
- IRTemp b6 = newTemp(Ity_I32);
-
- assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1)));
- assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)),
- mkU32(1)));
- assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)),
- mkU32(1)));
-
- assign(cc0, mkexpr(b0));
- assign(cc1, binop(Iop_Or32, mkexpr(b2),
- binop(Iop_And32,
- binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */
- binop(Iop_Sub32, mkU32(1), mkexpr(b6)) /* ~b6 */
- )));
-
- return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1)));
-}
-
static const HChar *
s390_irgen_CEBR(UChar r1, UChar r2)
{
assign(op2, get_fpr_w0(r2));
assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
- assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
+ assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
return "cebr";
assign(op2, get_fpr_dw0(r2));
assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
- assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
+ assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
return "cdbr";
assign(op2, get_fpr_pair(r2));
assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
- assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
+ assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
return "cxbr";
assign(op2, load(Ity_F32, mkexpr(op2addr)));
assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
- assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
+ assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
return "ceb";
assign(op2, load(Ity_F64, mkexpr(op2addr)));
assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
- assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
+ assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
return "cdb";
return S390_DFP_ROUND_PER_FPC_0;
}
+
+/*---------------------------------------------------------*/
+/*--- Condition code helper functions ---*/
+/*---------------------------------------------------------*/
+
/* CC_S390 holds the condition code in s390 encoding. Convert it to
- VEX encoding
+ VEX encoding (IRCmpFResult)
s390 VEX b6 b2 b0 cc.1 cc.0
0 0x40 EQ 1 0 0 0 0
VEX = b0 | (b2 << 2) | (b6 << 6);
*/
static HReg
-convert_s390_fpcc_to_vex(ISelEnv *env, HReg cc_s390)
+convert_s390_to_vex_bfpcc(ISelEnv *env, HReg cc_s390)
{
HReg cc0, cc1, b2, b6, cc_vex;
return cc_vex;
}
+/* CC_S390 holds the condition code in s390 encoding. Convert it to
+ VEX encoding (IRCmpDResult) */
+static HReg
+convert_s390_to_vex_dfpcc(ISelEnv *env, HReg cc_s390)
+{
+ /* The encodings for IRCmpFResult and IRCmpDResult are the same/ */
+ return convert_s390_to_vex_bfpcc(env, cc_s390);
+}
+
/*---------------------------------------------------------*/
/*--- ISEL: Integer expressions (128 bit) ---*/
addInstr(env, s390_insn_bfp_compare(size, cc_s390, h1, h2));
- return convert_s390_fpcc_to_vex(env, cc_s390);
+ return convert_s390_to_vex_bfpcc(env, cc_s390);
}
case Iop_CmpF128: {
res = newVRegI(env);
addInstr(env, s390_insn_bfp128_compare(16, cc_s390, f12, f14, f13, f15));
- return convert_s390_fpcc_to_vex(env, cc_s390);
+ return convert_s390_to_vex_bfpcc(env, cc_s390);
}
case Iop_CmpD64: {
addInstr(env, s390_insn_dfp_compare(size, cc_s390, h1, h2));
- return convert_s390_fpcc_to_vex(env, cc_s390);
+ return convert_s390_to_vex_dfpcc(env, cc_s390);
}
case Iop_CmpD128: {
res = newVRegI(env);
addInstr(env, s390_insn_dfp128_compare(16, cc_s390, f12, f14, f13, f15));
- return convert_s390_fpcc_to_vex(env, cc_s390);
+ return convert_s390_to_vex_dfpcc(env, cc_s390);
}
case Iop_Add8: