/* --------- PPCAMode: memory address expressions. --------- */
-PPC32AMode* PPC32AMode_IR ( UInt idx, HReg base ) {
+PPC32AMode* PPC32AMode_IR ( Int idx, HReg base ) {
PPC32AMode* am = LibVEX_Alloc(sizeof(PPC32AMode));
- vassert(idx < 0x10000);
+ vassert(idx >= -0x8000 && idx < 0x8000);
am->tag = Pam_IR;
am->Pam.IR.base = base;
am->Pam.IR.index = idx;
if (am->Pam.IR.index == 0)
vex_printf("0(");
else
- vex_printf("0x%x(", am->Pam.IR.index);
+ vex_printf("%d(", (Int)am->Pam.IR.index);
ppHRegPPC32(am->Pam.IR.base);
vex_printf(")");
return;
typedef
enum {
- Pam_IR, /* Immediate + Reg */
+ Pam_IR, /* Immediate (signed 16-bit) + Reg */
Pam_RR /* Reg1 + Reg2 */
}
PPC32AModeTag;
union {
struct {
HReg base;
- UInt index;
+ Int index;
} IR;
struct {
HReg base;
}
PPC32AMode;
-extern PPC32AMode* PPC32AMode_IR ( UInt, HReg );
+extern PPC32AMode* PPC32AMode_IR ( Int, HReg );
extern PPC32AMode* PPC32AMode_RR ( HReg, HReg );
extern PPC32AMode* dopyPPC32AMode ( PPC32AMode* );
result. The expression may only be a 32-bit one.
*/
+static Bool fits16bits ( UInt u )
+{
+ /* Is u the same as the sign-extend of its lower 16 bits? */
+ Int i = u & 0xFFFF;
+ i <<= 16;
+ i >>= 16;
+ return u == (UInt)i;
+}
+
static Bool sane_AMode ( PPC32AMode* am )
{
switch (am->tag) {
case Pam_IR:
return (hregClass(am->Pam.IR.base) == HRcInt32
&& hregIsVirtual(am->Pam.IR.base)
- && (am->Pam.IR.index < 0x10000));
+ && fits16bits(am->Pam.IR.index));
case Pam_RR:
return (hregClass(am->Pam.RR.base) == HRcInt32
&& hregIsVirtual(am->Pam.IR.base)
IRType ty = typeOfIRExpr(env->type_env,e);
vassert(ty == Ity_I32);
- /* Add32(expr,i), where i<0x10000 */
+ /* Add32(expr,i), where i == sign-extend of (i & 0xFFFF) */
if (e->tag == Iex_Binop
&& e->Iex.Binop.op == Iop_Add32
&& e->Iex.Binop.arg2->tag == Iex_Const
&& e->Iex.Binop.arg2->Iex.Const.con->tag == Ico_U32
- && e->Iex.Binop.arg2->Iex.Const.con->Ico.U32 < 0x10000) {
+ && fits16bits(e->Iex.Binop.arg2->Iex.Const.con->Ico.U32)) {
return PPC32AMode_IR(e->Iex.Binop.arg2->Iex.Const.con->Ico.U32,
- iselIntExpr_R(env, e->Iex.Binop.arg1));
+ iselIntExpr_R(env, e->Iex.Binop.arg1));
}
/* Add32(expr,expr) */