summaryrefslogtreecommitdiffstats
path: root/tcg/ppc64
diff options
context:
space:
mode:
authorRichard Henderson <rth@twiddle.net>2013-01-31 15:52:49 -0800
committerRichard Henderson <rth@twiddle.net>2013-04-15 19:52:04 +0200
commit421233a1469123cc51ddd19849f7db4b6bd380e7 (patch)
treeeb9bcb211cb00a7e518c009e8617754ab41c2be2 /tcg/ppc64
parent752c1fdb6d3e7cc03157af213837f3b081b03858 (diff)
downloadhqemu-421233a1469123cc51ddd19849f7db4b6bd380e7.zip
hqemu-421233a1469123cc51ddd19849f7db4b6bd380e7.tar.gz
tcg-ppc64: Cleanup tcg_out_movi
The test for using movi32 was sub-optimal for TCG_TYPE_I32, comparing a signed 32-bit quantity against an unsigned 32-bit quantity. When possible, use addi+oris for 32-bit unsigned constants. Otherwise, standardize on addi+oris+ori instead of addis+ori+rldicl. Reviewed-by: Aurelien Jarno <aurelien@aurel32.net> Signed-off-by: Richard Henderson <rth@twiddle.net>
Diffstat (limited to 'tcg/ppc64')
-rw-r--r--tcg/ppc64/tcg-target.c41
1 files changed, 17 insertions, 24 deletions
diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c
index 822eb07..c6ff75b 100644
--- a/tcg/ppc64/tcg-target.c
+++ b/tcg/ppc64/tcg-target.c
@@ -480,32 +480,25 @@ static void tcg_out_movi32(TCGContext *s, TCGReg ret, int32_t arg)
}
}
-static void tcg_out_movi (TCGContext *s, TCGType type,
- TCGReg ret, tcg_target_long arg)
+static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg ret,
+ tcg_target_long arg)
{
- int32_t arg32 = arg;
- arg = type == TCG_TYPE_I32 ? arg & 0xffffffff : arg;
-
- if (arg == arg32) {
- tcg_out_movi32 (s, ret, arg32);
- }
- else {
- if ((uint64_t) arg >> 32) {
- uint16_t h16 = arg >> 16;
- uint16_t l16 = arg;
-
- tcg_out_movi32(s, ret, arg >> 32);
+ if (type == TCG_TYPE_I32 || arg == (int32_t)arg) {
+ tcg_out_movi32(s, ret, arg);
+ } else if (arg == (uint32_t)arg && !(arg & 0x8000)) {
+ tcg_out32(s, ADDI | TAI(ret, 0, arg));
+ tcg_out32(s, ORIS | SAI(ret, ret, arg >> 16));
+ } else {
+ int32_t high = arg >> 32;
+ tcg_out_movi32(s, ret, high);
+ if (high) {
tcg_out_shli64(s, ret, ret, 32);
- if (h16) {
- tcg_out32(s, ORIS | SAI(ret, ret, h16));
- }
- if (l16) {
- tcg_out32(s, ORI | SAI(ret, ret, l16));
- }
- } else {
- tcg_out_movi32 (s, ret, arg32);
- if (arg32 < 0)
- tcg_out_ext32u(s, ret, ret);
+ }
+ if (arg & 0xffff0000) {
+ tcg_out32(s, ORIS | SAI(ret, ret, arg >> 16));
+ }
+ if (arg & 0xffff) {
+ tcg_out32(s, ORI | SAI(ret, ret, arg));
}
}
}
OpenPOWER on IntegriCloud