aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudio Fontana <claudio.fontana@huawei.com>2013-06-12 16:20:22 +0100
committerPeter Maydell <peter.maydell@linaro.org>2013-06-12 16:20:22 +0100
commit7deea126b24508e8ffa7aa4aecfa6fa97eddc384 (patch)
tree69ff97339cd71283322da082dc53e91cf10432cc
parent36fac14a6416fe1f8f6f23bfac5f9e662be78d2b (diff)
downloadqemu-arm-7deea126b24508e8ffa7aa4aecfa6fa97eddc384.tar.gz
tcg/aarch64: implement AND/TEST immediate pattern
add functions to AND/TEST registers with immediate patterns. Signed-off-by: Claudio Fontana <claudio.fontana@huawei.com> Reviewed-by: Richard Henderson <rth@twiddle.net> Message-id: 51AC9A0C.3090303@huawei.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--tcg/aarch64/tcg-target.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/tcg/aarch64/tcg-target.c b/tcg/aarch64/tcg-target.c
index 2aa9f75a25..bb59794046 100644
--- a/tcg/aarch64/tcg-target.c
+++ b/tcg/aarch64/tcg-target.c
@@ -580,6 +580,40 @@ static inline void tcg_out_call(TCGContext *s, tcg_target_long target)
}
}
+/* encode a logical immediate, mapping user parameter
+ M=set bits pattern length to S=M-1 */
+static inline unsigned int
+aarch64_limm(unsigned int m, unsigned int r)
+{
+ assert(m > 0);
+ return r << 16 | (m - 1) << 10;
+}
+
+/* test a register against an immediate bit pattern made of
+ M set bits rotated right by R.
+ Examples:
+ to test a 32/64 reg against 0x00000007, pass M = 3, R = 0.
+ to test a 32/64 reg against 0x000000ff, pass M = 8, R = 0.
+ to test a 32bit reg against 0xff000000, pass M = 8, R = 8.
+ to test a 32bit reg against 0xff0000ff, pass M = 16, R = 8.
+ */
+static inline void tcg_out_tst(TCGContext *s, int ext, TCGReg rn,
+ unsigned int m, unsigned int r)
+{
+ /* using TST alias of ANDS XZR, Xn,#bimm64 0x7200001f */
+ unsigned int base = ext ? 0xf240001f : 0x7200001f;
+ tcg_out32(s, base | aarch64_limm(m, r) | rn << 5);
+}
+
+/* and a register with a bit pattern, similarly to TST, no flags change */
+static inline void tcg_out_andi(TCGContext *s, int ext, TCGReg rd, TCGReg rn,
+ unsigned int m, unsigned int r)
+{
+ /* using AND 0x12000000 */
+ unsigned int base = ext ? 0x92400000 : 0x12000000;
+ tcg_out32(s, base | aarch64_limm(m, r) | rn << 5 | rd);
+}
+
static inline void tcg_out_ret(TCGContext *s)
{
/* emit RET { LR } */