diff options
author | Claudio Fontana <claudio.fontana@huawei.com> | 2013-06-12 16:20:22 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2013-06-12 16:20:22 +0100 |
commit | 7deea126b24508e8ffa7aa4aecfa6fa97eddc384 (patch) | |
tree | 69ff97339cd71283322da082dc53e91cf10432cc /tcg | |
parent | 36fac14a6416fe1f8f6f23bfac5f9e662be78d2b (diff) |
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>
Diffstat (limited to 'tcg')
-rw-r--r-- | tcg/aarch64/tcg-target.c | 34 |
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 } */ |