|
From: <sv...@va...> - 2012-08-06 13:35:45
|
florian 2012-08-06 14:35:33 +0100 (Mon, 06 Aug 2012)
New Revision: 2462
Log:
The arguments in a helper call need to be sign/zero-extended
to 64 bit. Fix helper calls accordingly. And because I keep forgetting
this, add checking machinery in the insn selector so it won't happen again.
Diagnosed by Christian Borntraeger.
Modified files:
trunk/priv/guest_s390_toIR.c
trunk/priv/host_s390_isel.c
Modified: trunk/priv/guest_s390_toIR.c (+13 -11)
===================================================================
--- trunk/priv/guest_s390_toIR.c 2012-08-06 01:07:54 +01:00 (rev 2461)
+++ trunk/priv/guest_s390_toIR.c 2012-08-06 14:35:33 +01:00 (rev 2462)
@@ -10685,7 +10685,7 @@
static HChar *
s390_irgen_CVD(UChar r1, IRTemp op2addr)
{
- store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
+ store(mkexpr(op2addr), s390_call_cvd(unop(Iop_32Uto64, get_gpr_w1(r1))));
return "cvd";
}
@@ -11212,7 +11212,8 @@
/* Call the helper */
IRTemp retval = newTemp(Ity_I64);
- assign(retval, s390_call_cu21(mkexpr(srcval), mkexpr(low_surrogate)));
+ assign(retval, s390_call_cu21(unop(Iop_32Uto64, mkexpr(srcval)),
+ unop(Iop_32Uto64, mkexpr(low_surrogate))));
/* Before we can test whether the 1st operand is exhausted we need to
test for an invalid low surrogate. Because cc=2 outranks cc=1. */
@@ -11339,7 +11340,8 @@
/* Call the helper */
IRTemp retval = newTemp(Ity_I64);
- assign(retval, s390_call_cu24(mkexpr(srcval), mkexpr(low_surrogate)));
+ assign(retval, s390_call_cu24(unop(Iop_32Uto64, mkexpr(srcval)),
+ unop(Iop_32Uto64, mkexpr(low_surrogate))));
/* Before we can test whether the 1st operand is exhausted we need to
test for an invalid low surrogate. Because cc=2 outranks cc=1. */
@@ -11416,7 +11418,7 @@
/* Call the helper */
IRTemp retval = newTemp(Ity_I64);
- assign(retval, s390_call_cu42(mkexpr(srcval)));
+ assign(retval, s390_call_cu42(unop(Iop_32Uto64, mkexpr(srcval))));
/* If the UTF-32 character was invalid, set cc=2 and we're done.
cc=2 outranks cc=1 (1st operand exhausted) */
@@ -11510,7 +11512,7 @@
/* Call the helper */
IRTemp retval = newTemp(Ity_I64);
- assign(retval, s390_call_cu41(mkexpr(srcval)));
+ assign(retval, s390_call_cu41(unop(Iop_32Uto64, mkexpr(srcval))));
/* If the UTF-32 character was invalid, set cc=2 and we're done.
cc=2 outranks cc=1 (1st operand exhausted) */
@@ -11628,13 +11630,13 @@
next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1)));
/* There is at least one byte there. Read it. */
- IRTemp byte1 = newTemp(Ity_I32);
- assign(byte1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(addr2))));
+ IRTemp byte1 = newTemp(Ity_I64);
+ assign(byte1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(addr2))));
/* Call the helper to get number of bytes and invalid byte indicator */
IRTemp retval1 = newTemp(Ity_I64);
assign(retval1, s390_call_cu12_cu14_helper1(mkexpr(byte1),
- mkU32(extended_checking)));
+ mkU64(extended_checking)));
/* Check for invalid 1st byte */
IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1));
@@ -11654,13 +11656,13 @@
cond = binop(Iop_CmpLE64U, mkU64(2), mkexpr(num_src_bytes));
addr = binop(Iop_Add64, mkexpr(addr2), mkU64(1));
- byte2 = mkite(cond, unop(Iop_8Uto32, load(Ity_I8, addr)), mkU32(0));
+ byte2 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
cond = binop(Iop_CmpLE64U, mkU64(3), mkexpr(num_src_bytes));
addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
- byte3 = mkite(cond, unop(Iop_8Uto32, load(Ity_I8, addr)), mkU32(0));
+ byte3 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
cond = binop(Iop_CmpLE64U, mkU64(4), mkexpr(num_src_bytes));
addr = binop(Iop_Add64, mkexpr(addr2), mkU64(3));
- byte4 = mkite(cond, unop(Iop_8Uto32, load(Ity_I8, addr)), mkU32(0));
+ byte4 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
/* Call the helper to get the converted value and invalid byte indicator.
We can pass at most 5 arguments; therefore some encoding is needed
Modified: trunk/priv/host_s390_isel.c (+19 -0)
===================================================================
--- trunk/priv/host_s390_isel.c 2012-08-06 01:07:54 +01:00 (rev 2461)
+++ trunk/priv/host_s390_isel.c 2012-08-06 14:35:33 +01:00 (rev 2462)
@@ -465,6 +465,25 @@
vpanic("doHelperCall: too many arguments");
}
+ /* All arguments must have Ity_I64. For two reasons:
+ (1) We do not handle floating point arguments.
+ (2) The ABI requires that integer values are sign- or zero-extended
+ to 64 bit.
+ */
+ Int arg_errors = 0;
+ for (i = 0; i < n_args; ++i) {
+ IRType type = typeOfIRExpr(env->type_env, args[i]);
+ if (type != Ity_I64) {
+ ++arg_errors;
+ vex_printf("calling %s: argument #%d has type ", callee->name, i);
+ ppIRType(type);
+ vex_printf("; Ity_I64 is required\n");
+ }
+ }
+
+ if (arg_errors)
+ vpanic("cannot continue due to errors in argument passing");
+
argreg = 0;
/* If we need the guest state pointer put it in a temporary arg reg */
|