All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [RFC 01/14] tcg-aarch64: Allow immediate operands to add and sub
  2013-08-12 18:44 [Qemu-devel] [RFC 00/14] tcg aarch64 improvements Richard Henderson
@ 2013-08-12 18:44 ` Richard Henderson
  0 siblings, 0 replies; 3+ messages in thread
From: Richard Henderson @ 2013-08-12 18:44 UTC (permalink / raw)
  To: qemu-devel; +Cc: claudio.fontana, Richard Henderson

Use signed 25-bit operands, because two 12-bit operations is
smaller than movz+movk+add.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 tcg/aarch64/tcg-target.c | 107 +++++++++++++++++++++++++++--------------------
 1 file changed, 61 insertions(+), 46 deletions(-)

diff --git a/tcg/aarch64/tcg-target.c b/tcg/aarch64/tcg-target.c
index 41a17f8..ed32f64 100644
--- a/tcg/aarch64/tcg-target.c
+++ b/tcg/aarch64/tcg-target.c
@@ -106,6 +106,8 @@ static inline void patch_reloc(uint8_t *code_ptr, int type,
     }
 }
 
+#define TCG_CT_CONST_S25  0x100
+
 /* parse target specific constraints */
 static int target_parse_constraint(TCGArgConstraint *ct,
                                    const char **pct_str)
@@ -129,6 +131,9 @@ static int target_parse_constraint(TCGArgConstraint *ct,
         tcg_regset_reset_reg(ct->u.regs, TCG_REG_X3);
 #endif
         break;
+    case 'A': /* 25-bit signed, to be added or subtracted.  */
+        ct->ct |= TCG_CT_CONST_S25;
+        break;
     default:
         return -1;
     }
@@ -146,6 +151,9 @@ static inline int tcg_target_const_match(tcg_target_long val,
     if (ct & TCG_CT_CONST) {
         return 1;
     }
+    if ((ct & TCG_CT_CONST_S25) && sextract32(val, 0, 25) == val) {
+        return 1;
+    }
 
     return 0;
 }
@@ -200,12 +208,14 @@ enum aarch64_ldst_op_type { /* type of operation */
 };
 
 enum aarch64_arith_opc {
-    ARITH_AND = 0x0a,
-    ARITH_ADD = 0x0b,
-    ARITH_OR = 0x2a,
+    ARITH_AND  = 0x0a,
+    ARITH_ADD  = 0x0b,
+    ARITH_ADDI = 0x11,
+    ARITH_OR   = 0x2a,
     ARITH_ADDS = 0x2b,
-    ARITH_XOR = 0x4a,
-    ARITH_SUB = 0x4b,
+    ARITH_XOR  = 0x4a,
+    ARITH_SUB  = 0x4b,
+    ARITH_SUBI = 0x51,
     ARITH_ANDS = 0x6a,
     ARITH_SUBS = 0x6b,
 };
@@ -453,6 +463,20 @@ static inline void tcg_out_arith(TCGContext *s, enum aarch64_arith_opc opc,
     tcg_out32(s, base | rm << 16 | shift | rn << 5 | rd);
 }
 
+static inline void tcg_out_aimm(TCGContext *s, enum aarch64_arith_opc opc,
+                                int ext, TCGReg rd, TCGReg rn, uint64_t aimm)
+{
+    unsigned int base = (ext ? 0x80 | opc : opc) << 24;
+
+    if (aimm > 0xfff) {
+        assert((aimm & 0xfff) == 0);
+        aimm >>= 12;
+        base |= 1 << 22; /* apply LSL 12 */
+        assert(aimm <= 0xfff);
+    }
+    tcg_out32(s, base | (aimm << 10) | (rn << 5) | rd);
+}
+
 static inline void tcg_out_mul(TCGContext *s, int ext,
                                TCGReg rd, TCGReg rn, TCGReg rm)
 {
@@ -732,44 +756,27 @@ static inline void tcg_out_uxt(TCGContext *s, int s_bits,
     tcg_out_ubfm(s, 0, rd, rn, 0, bits);
 }
 
-static inline void tcg_out_addi(TCGContext *s, int ext,
-                                TCGReg rd, TCGReg rn, unsigned int aimm)
+static void tcg_out_addi(TCGContext *s, int ext, TCGReg rd, TCGReg rn,
+                         tcg_target_long aimm)
 {
-    /* add immediate aimm unsigned 12bit value (with LSL 0 or 12) */
-    /* using ADD 0x11000000 | (ext) | (aimm << 10) | (rn << 5) | rd */
-    unsigned int base = ext ? 0x91000000 : 0x11000000;
+    enum aarch64_arith_opc opc = ARITH_ADDI;
+    tcg_target_long lo, hi;
 
-    if (aimm <= 0xfff) {
-        aimm <<= 10;
-    } else {
-        /* we can only shift left by 12, on assert we cannot represent */
-        assert(!(aimm & 0xfff));
-        assert(aimm <= 0xfff000);
-        base |= 1 << 22; /* apply LSL 12 */
-        aimm >>= 2;
+    if (aimm < 0) {
+        aimm = -aimm;
+        opc = ARITH_SUBI;
     }
+    hi = aimm & 0xfff000;
+    lo = aimm & 0xfff;
+    assert(aimm == hi + lo);
 
-    tcg_out32(s, base | aimm | (rn << 5) | rd);
-}
-
-static inline void tcg_out_subi(TCGContext *s, int ext,
-                                TCGReg rd, TCGReg rn, unsigned int aimm)
-{
-    /* sub immediate aimm unsigned 12bit value (with LSL 0 or 12) */
-    /* using SUB 0x51000000 | (ext) | (aimm << 10) | (rn << 5) | rd */
-    unsigned int base = ext ? 0xd1000000 : 0x51000000;
-
-    if (aimm <= 0xfff) {
-        aimm <<= 10;
-    } else {
-        /* we can only shift left by 12, on assert we cannot represent */
-        assert(!(aimm & 0xfff));
-        assert(aimm <= 0xfff000);
-        base |= 1 << 22; /* apply LSL 12 */
-        aimm >>= 2;
+    if (hi != 0) {
+        tcg_out_aimm(s, opc, ext, rd, rn, hi);
+        rn = rd;
+    }
+    if (lo != 0 || rd != rn) {
+        tcg_out_aimm(s, opc, ext, rd, rn, lo);
     }
-
-    tcg_out32(s, base | aimm | (rn << 5) | rd);
 }
 
 static inline void tcg_out_nop(TCGContext *s)
@@ -1180,13 +1187,21 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
     case INDEX_op_add_i64:
         ext = 1; /* fall through */
     case INDEX_op_add_i32:
-        tcg_out_arith(s, ARITH_ADD, ext, args[0], args[1], args[2], 0);
+        if (const_args[2]) {
+            tcg_out_addi(s, ext, args[0], args[1], args[2]);
+        } else {
+            tcg_out_arith(s, ARITH_ADD, ext, args[0], args[1], args[2], 0);
+        }
         break;
 
     case INDEX_op_sub_i64:
         ext = 1; /* fall through */
     case INDEX_op_sub_i32:
-        tcg_out_arith(s, ARITH_SUB, ext, args[0], args[1], args[2], 0);
+        if (const_args[2]) {
+            tcg_out_addi(s, ext, args[0], args[1], -args[2]);
+        } else {
+            tcg_out_arith(s, ARITH_SUB, ext, args[0], args[1], args[2], 0);
+        }
         break;
 
     case INDEX_op_and_i64:
@@ -1391,10 +1406,10 @@ static const TCGTargetOpDef aarch64_op_defs[] = {
     { INDEX_op_st32_i64, { "r", "r" } },
     { INDEX_op_st_i64, { "r", "r" } },
 
-    { INDEX_op_add_i32, { "r", "r", "r" } },
-    { INDEX_op_add_i64, { "r", "r", "r" } },
-    { INDEX_op_sub_i32, { "r", "r", "r" } },
-    { INDEX_op_sub_i64, { "r", "r", "r" } },
+    { INDEX_op_add_i32, { "r", "r", "rA" } },
+    { INDEX_op_add_i64, { "r", "r", "rA" } },
+    { INDEX_op_sub_i32, { "r", "r", "rA" } },
+    { INDEX_op_sub_i64, { "r", "r", "rA" } },
     { INDEX_op_mul_i32, { "r", "r", "r" } },
     { INDEX_op_mul_i64, { "r", "r", "r" } },
     { INDEX_op_and_i32, { "r", "r", "r" } },
@@ -1518,8 +1533,8 @@ static void tcg_target_qemu_prologue(TCGContext *s)
     }
 
     /* make stack space for TCG locals */
-    tcg_out_subi(s, 1, TCG_REG_SP, TCG_REG_SP,
-                 frame_size_tcg_locals * TCG_TARGET_STACK_ALIGN);
+    tcg_out_addi(s, 1, TCG_REG_SP, TCG_REG_SP,
+                 -frame_size_tcg_locals * TCG_TARGET_STACK_ALIGN);
     /* inform TCG about how to find TCG locals with register, offset, size */
     tcg_set_frame(s, TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE,
                   CPU_TEMP_BUF_NLONGS * sizeof(long));
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [Qemu-devel] [RFC 01/14] tcg-aarch64: Allow immediate operands to add and sub
@ 2013-08-13  8:57 Jay Foad
  2013-08-13 16:08 ` Richard Henderson
  0 siblings, 1 reply; 3+ messages in thread
From: Jay Foad @ 2013-08-13  8:57 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel

> -static inline void tcg_out_addi(TCGContext *s, int ext,
> -                                TCGReg rd, TCGReg rn, unsigned int aimm)
> +static void tcg_out_addi(TCGContext *s, int ext, TCGReg rd, TCGReg rn,
> +                         tcg_target_long aimm)
>  {
> -    /* add immediate aimm unsigned 12bit value (with LSL 0 or 12) */
> -    /* using ADD 0x11000000 | (ext) | (aimm << 10) | (rn << 5) | rd */
> -    unsigned int base = ext ? 0x91000000 : 0x11000000;
> +    enum aarch64_arith_opc opc = ARITH_ADDI;
> +    tcg_target_long lo, hi;
>
> -    if (aimm <= 0xfff) {
> -        aimm <<= 10;
> -    } else {
> -        /* we can only shift left by 12, on assert we cannot represent */
> -        assert(!(aimm & 0xfff));
> -        assert(aimm <= 0xfff000);
> -        base |= 1 << 22; /* apply LSL 12 */
> -        aimm >>= 2;
> +    if (aimm < 0) {
> +        aimm = -aimm;
> +        opc = ARITH_SUBI;
>      }
> +    hi = aimm & 0xfff000;
> +    lo = aimm & 0xfff;
> +    assert(aimm == hi + lo);

Won't this fail if aimm was -0x1000000 on entry?

Jay.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [Qemu-devel] [RFC 01/14] tcg-aarch64: Allow immediate operands to add and sub
  2013-08-13  8:57 [Qemu-devel] [RFC 01/14] tcg-aarch64: Allow immediate operands to add and sub Jay Foad
@ 2013-08-13 16:08 ` Richard Henderson
  0 siblings, 0 replies; 3+ messages in thread
From: Richard Henderson @ 2013-08-13 16:08 UTC (permalink / raw)
  To: Jay Foad; +Cc: qemu-devel

On 08/13/2013 01:57 AM, Jay Foad wrote:
>> -static inline void tcg_out_addi(TCGContext *s, int ext,
>> -                                TCGReg rd, TCGReg rn, unsigned int aimm)
>> +static void tcg_out_addi(TCGContext *s, int ext, TCGReg rd, TCGReg rn,
>> +                         tcg_target_long aimm)
>>  {
>> -    /* add immediate aimm unsigned 12bit value (with LSL 0 or 12) */
>> -    /* using ADD 0x11000000 | (ext) | (aimm << 10) | (rn << 5) | rd */
>> -    unsigned int base = ext ? 0x91000000 : 0x11000000;
>> +    enum aarch64_arith_opc opc = ARITH_ADDI;
>> +    tcg_target_long lo, hi;
>>
>> -    if (aimm <= 0xfff) {
>> -        aimm <<= 10;
>> -    } else {
>> -        /* we can only shift left by 12, on assert we cannot represent */
>> -        assert(!(aimm & 0xfff));
>> -        assert(aimm <= 0xfff000);
>> -        base |= 1 << 22; /* apply LSL 12 */
>> -        aimm >>= 2;
>> +    if (aimm < 0) {
>> +        aimm = -aimm;
>> +        opc = ARITH_SUBI;
>>      }
>> +    hi = aimm & 0xfff000;
>> +    lo = aimm & 0xfff;
>> +    assert(aimm == hi + lo);
> 
> Won't this fail if aimm was -0x1000000 on entry?

Yep, off-by-one thinko on the constraint test.
Should only allow -0xffffff <= x <= 0xffffff.


r~

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2013-08-13 16:09 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-08-13  8:57 [Qemu-devel] [RFC 01/14] tcg-aarch64: Allow immediate operands to add and sub Jay Foad
2013-08-13 16:08 ` Richard Henderson
  -- strict thread matches above, loose matches on Subject: below --
2013-08-12 18:44 [Qemu-devel] [RFC 00/14] tcg aarch64 improvements Richard Henderson
2013-08-12 18:44 ` [Qemu-devel] [RFC 01/14] tcg-aarch64: Allow immediate operands to add and sub Richard Henderson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.