aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@twiddle.net>2013-08-31 06:13:49 -0700
committerRichard Henderson <rth@twiddle.net>2013-09-25 07:46:32 -0700
commitd40f3cb1128208d901b6224b52ff36ff05680d28 (patch)
treead3ed1aa531c28554a1fcc88d50ca13963ad39cb
parentad94e1a9db52de4ddfd9940324249518e0265902 (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.c14
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
}