From: Cerion Armour-Brown Date: Thu, 10 Feb 2005 11:39:43 +0000 (+0000) Subject: Dealt with some cases where imm > 0xFFFF X-Git-Tag: svn/VALGRIND_3_0_1^2~454 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=794292cb440baaf3ddccd921c53a5942ec08ab0e;p=thirdparty%2Fvalgrind.git Dealt with some cases where imm > 0xFFFF git-svn-id: svn://svn.valgrind.org/vex/trunk@880 --- diff --git a/VEX/priv/host-ppc32/hdefs.c b/VEX/priv/host-ppc32/hdefs.c index d3cd5b77c1..69b1b33521 100644 --- a/VEX/priv/host-ppc32/hdefs.c +++ b/VEX/priv/host-ppc32/hdefs.c @@ -242,7 +242,7 @@ HChar* showPPC32CondCode ( PPC32CondCode cond ) /* --------- PPCAMode: memory address expressions. --------- */ PPC32AMode* PPC32AMode_IR ( UInt idx, HReg base ) { - // CAB: Rem assert immediate + vassert(idx < 0x10000); PPC32AMode* am = LibVEX_Alloc(sizeof(PPC32AMode)); am->tag = Pam_IR; am->Pam.IR.base = base; @@ -319,7 +319,6 @@ static void mapRegs_PPC32AMode ( HRegRemap* m, PPC32AMode* am ) { /* --------- Operand, which can be reg or immediate only. --------- */ PPC32RI* PPC32RI_Imm ( UInt imm32 ) { - // CAB: Rem assert immediate PPC32RI* op = LibVEX_Alloc(sizeof(PPC32RI)); op->tag = Pri_Imm; op->Pri.Imm.imm32 = imm32; @@ -665,7 +664,8 @@ void ppPPC32Instr ( PPC32Instr* i ) return; } if (i->Pin.Alu32.op == Palu_ADD && // add Rd,R0,Rs == li Rd,Rs - i->Pin.Alu32.src1 == hregPPC32_GPR0()) { + i->Pin.Alu32.src1 == hregPPC32_GPR0() && + i->Pin.Alu32.src2->tag == Pri_Imm) { vex_printf("li "); ppHRegPPC32(i->Pin.Alu32.dst); vex_printf(","); diff --git a/VEX/priv/host-ppc32/isel.c b/VEX/priv/host-ppc32/isel.c index a969903b19..caf417e8c4 100644 --- a/VEX/priv/host-ppc32/isel.c +++ b/VEX/priv/host-ppc32/isel.c @@ -288,15 +288,24 @@ static PPC32Instr* mk_iMOVds_RR ( HReg dst, HReg src ) return PPC32Instr_Alu32(Palu_OR, dst, src, PPC32RI_Reg(src)); } +/* Load an RI to a reg */ -/* Make an int reg<-ri move. */ - -static PPC32Instr* mk_iMOVds_RRI ( HReg dst, PPC32RI* src ) +static PPC32Instr* mk_iMOVds_RRI ( ISelEnv* env, HReg dst, PPC32RI* src ) { vassert(hregClass(dst) == HRcInt32); -// CAB: assert src... - HReg tmp = hregPPC32_GPR0(); // Gives value 0 in this context - return PPC32Instr_Alu32(Palu_ADD, dst, tmp, src); + // Note: In this context, GPR0 is NOT read -> just gives _value_ 0 + HReg zero = hregPPC32_GPR0(); + + if (src->tag == Pri_Imm && + src->Pri.Imm.imm32 > 0xFFFF) { + UInt imm = src->Pri.Imm.imm32; + // CAB: addis (aka lis) would be good... + addInstr(env, PPC32Instr_Alu32(Palu_ADD, dst, zero, PPC32RI_Imm(imm>>16))); + addInstr(env, PPC32Instr_Sh32(Psh_SHL, dst, dst, PPC32RI_Imm(16))); + return PPC32Instr_Alu32(Palu_ADD, dst, dst, PPC32RI_Imm(imm & 0xFFFF)); + } else { + return PPC32Instr_Alu32(Palu_ADD, dst, zero, src); + } } @@ -733,7 +742,7 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e ) IRType ty = typeOfIRExpr(env->type_env,e); vassert(ty == Ity_I32 || Ity_I16 || Ity_I8); - vex_printf("@iselIntExpr_R_wrk: tag=%d\n", e->tag); +// vex_printf("@iselIntExpr_R_wrk: tag=%d\n", e->tag); switch (e->tag) { @@ -1184,9 +1193,9 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e ) /* --------- LITERAL --------- */ /* 32/16/8-bit literals */ case Iex_Const: { - PPC32RI* ri = iselIntExpr_RI ( env, e ); HReg dst = newVRegI(env); - addInstr(env, mk_iMOVds_RRI(dst, ri)); + PPC32RI* ri = iselIntExpr_RI ( env, e ); + addInstr(env, mk_iMOVds_RRI(env, dst, ri)); return dst; } @@ -1235,7 +1244,8 @@ static Bool sane_AMode ( PPC32AMode* am ) switch (am->tag) { case Pam_IR: return (hregClass(am->Pam.IR.base) == HRcInt32 - && hregIsVirtual(am->Pam.IR.base)); + && hregIsVirtual(am->Pam.IR.base) + && (am->Pam.IR.index < 0x10000)); // CAB: This ok here? case Pam_RR: return (hregClass(am->Pam.RR.base) == HRcInt32 && hregIsVirtual(am->Pam.IR.base) @@ -1259,21 +1269,24 @@ static PPC32AMode* iselIntExpr_AMode_wrk ( ISelEnv* env, IRExpr* e ) IRType ty = typeOfIRExpr(env->type_env,e); vassert(ty == Ity_I32); - vex_printf("@iselIntExpr_AMode_wrk@\n"); - - // CAB: - // Can only make IR variant if - // e->Iex.Binop.arg2->Iex.Const.con->Ico.U32 - // is small enough... - // else an RR... +// vex_printf("@iselIntExpr_AMode_wrk\n"); - /* Add32(expr,i) */ + /* Add32(expr,i), where i<0x10000 */ 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) { - HReg r1 = iselIntExpr_R(env, e->Iex.Binop.arg1); - return PPC32AMode_IR(e->Iex.Binop.arg2->Iex.Const.con->Ico.U32, r1); + && e->Iex.Binop.arg2->Iex.Const.con->tag == Ico_U32 + && e->Iex.Binop.arg2->Iex.Const.con->Ico.U32 < 0x10000) { + return PPC32AMode_IR(e->Iex.Binop.arg2->Iex.Const.con->Ico.U32, + iselIntExpr_R(env, e->Iex.Binop.arg1)); + } + + /* Add32(expr,expr) */ + if (e->tag == Iex_Binop + && e->Iex.Binop.op == Iop_Add32) { + HReg r_base = iselIntExpr_R(env, e->Iex.Binop.arg1); + HReg r_idx = iselIntExpr_R(env, e->Iex.Binop.arg2); + return PPC32AMode_RR(r_idx, r_base); } /* Doesn't match anything in particular. Generate it into @@ -1312,7 +1325,7 @@ static PPC32RI* iselIntExpr_RI_wrk ( ISelEnv* env, IRExpr* e ) IRType ty = typeOfIRExpr(env->type_env,e); vassert(ty == Ity_I32 || ty == Ity_I16 || ty == Ity_I8); - vex_printf("@iselIntExpr_RI_wrk@\n"); +// vex_printf("@iselIntExpr_RI_wrk\n"); /* special case: immediate */ if (e->tag == Iex_Const) { @@ -1357,7 +1370,7 @@ static PPC32CondCode iselCondCode_wrk ( ISelEnv* env, IRExpr* e ) vassert(e); vassert(typeOfIRExpr(env->type_env,e) == Ity_I1); - vex_printf("@iselCondCode_wrk\n"); +// vex_printf("@iselCondCode_wrk\n"); //.. /* Constant 1:Bit */ //.. if (e->tag == Iex_Const && e->Iex.Const.con->Ico.U1 == True) { @@ -3032,7 +3045,7 @@ static void iselStmt ( ISelEnv* env, IRStmt* stmt ) vex_printf("\n"); } - vex_printf("@iselStmt: tag=%d\n", stmt->tag); +// vex_printf("@iselStmt: tag=%d\n", stmt->tag); switch (stmt->tag) {