diff options
author | Richard Henderson <rth@twiddle.net> | 2013-08-31 06:13:49 -0700 |
---|---|---|
committer | Richard Henderson <rth@twiddle.net> | 2013-09-25 07:46:32 -0700 |
commit | d40f3cb1128208d901b6224b52ff36ff05680d28 (patch) | |
tree | ad3ed1aa531c28554a1fcc88d50ca13963ad39cb | |
parent | ad94e1a9db52de4ddfd9940324249518e0265902 (diff) |
tcg-ppc64: Fold constant call address into descriptor load
Eliminates one insn per call:
: lis r2,4165
-: ori r2,r2,59616
-: ld r0,0(r2)
+: ld r0,-5920(r2)
: mtctr r0
-: ld r2,8(r2)
+: ld r2,-5912(r2)
: bctrl
Signed-off-by: Richard Henderson <rth@twiddle.net>
-rw-r--r-- | tcg/ppc64/tcg-target.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c index 5ac62bf40d..8eb04060e6 100644 --- a/tcg/ppc64/tcg-target.c +++ b/tcg/ppc64/tcg-target.c @@ -713,16 +713,24 @@ static void tcg_out_call(TCGContext *s, tcg_target_long arg, int const_arg) tcg_out32(s, BCLR | BO_ALWAYS | LK); } #else - int reg = arg; + TCGReg reg = arg; + int ofs = 0; if (const_arg) { + /* Fold the low bits of the constant into the addresses below. */ + ofs = (int16_t)arg; + if (ofs + 8 < 0x8000) { + arg -= ofs; + } else { + ofs = 0; + } reg = TCG_REG_R2; tcg_out_movi(s, TCG_TYPE_I64, reg, arg); } - tcg_out32(s, LD | TAI(TCG_REG_R0, reg, 0)); + tcg_out32(s, LD | TAI(TCG_REG_R0, reg, ofs)); tcg_out32(s, MTSPR | RA(TCG_REG_R0) | CTR); - tcg_out32(s, LD | TAI(TCG_REG_R2, reg, 8)); + tcg_out32(s, LD | TAI(TCG_REG_R2, reg, ofs + 8)); tcg_out32(s, BCCTR | BO_ALWAYS | LK); #endif } |