diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2021-06-13 13:04:00 -0700 |
---|---|---|
committer | Richard Henderson <richard.henderson@linaro.org> | 2021-06-29 10:04:57 -0700 |
commit | 0b76ff8f1b63733f3cae78e4a0aba332e994f8d8 (patch) | |
tree | 334e0782b2b6713242e662fe2fcce6e880fb4369 /tcg/optimize.c | |
parent | 0d57d36af5de88f86e4ec1e1abc716209f791f8f (diff) | |
download | qemu-0b76ff8f1b63733f3cae78e4a0aba332e994f8d8.zip qemu-0b76ff8f1b63733f3cae78e4a0aba332e994f8d8.tar.gz qemu-0b76ff8f1b63733f3cae78e4a0aba332e994f8d8.tar.bz2 |
tcg: Handle new bswap flags during optimize
Notice when the input is known to be zero-extended and force
the TCG_BSWAP_IZ flag on. Honor the TCG_BSWAP_OS bit during
constant folding. Propagate the input to the output mask.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'tcg/optimize.c')
-rw-r--r-- | tcg/optimize.c | 56 |
1 files changed, 51 insertions, 5 deletions
diff --git a/tcg/optimize.c b/tcg/optimize.c index 211a420..9876ac5 100644 --- a/tcg/optimize.c +++ b/tcg/optimize.c @@ -355,10 +355,12 @@ static uint64_t do_constant_folding_2(TCGOpcode op, uint64_t x, uint64_t y) return (uint16_t)x; CASE_OP_32_64(bswap16): - return bswap16(x); + x = bswap16(x); + return y & TCG_BSWAP_OS ? (int16_t)x : x; CASE_OP_32_64(bswap32): - return bswap32(x); + x = bswap32(x); + return y & TCG_BSWAP_OS ? (int32_t)x : x; case INDEX_op_bswap64_i64: return bswap64(x); @@ -1029,6 +1031,42 @@ void tcg_optimize(TCGContext *s) } break; + CASE_OP_32_64(bswap16): + mask = arg_info(op->args[1])->mask; + if (mask <= 0xffff) { + op->args[2] |= TCG_BSWAP_IZ; + } + mask = bswap16(mask); + switch (op->args[2] & (TCG_BSWAP_OZ | TCG_BSWAP_OS)) { + case TCG_BSWAP_OZ: + break; + case TCG_BSWAP_OS: + mask = (int16_t)mask; + break; + default: /* undefined high bits */ + mask |= MAKE_64BIT_MASK(16, 48); + break; + } + break; + + case INDEX_op_bswap32_i64: + mask = arg_info(op->args[1])->mask; + if (mask <= 0xffffffffu) { + op->args[2] |= TCG_BSWAP_IZ; + } + mask = bswap32(mask); + switch (op->args[2] & (TCG_BSWAP_OZ | TCG_BSWAP_OS)) { + case TCG_BSWAP_OZ: + break; + case TCG_BSWAP_OS: + mask = (int32_t)mask; + break; + default: /* undefined high bits */ + mask |= MAKE_64BIT_MASK(32, 32); + break; + } + break; + default: break; } @@ -1135,9 +1173,6 @@ void tcg_optimize(TCGContext *s) CASE_OP_32_64(ext16s): CASE_OP_32_64(ext16u): CASE_OP_32_64(ctpop): - CASE_OP_32_64(bswap16): - CASE_OP_32_64(bswap32): - case INDEX_op_bswap64_i64: case INDEX_op_ext32s_i64: case INDEX_op_ext32u_i64: case INDEX_op_ext_i32_i64: @@ -1151,6 +1186,17 @@ void tcg_optimize(TCGContext *s) } goto do_default; + CASE_OP_32_64(bswap16): + CASE_OP_32_64(bswap32): + case INDEX_op_bswap64_i64: + if (arg_is_const(op->args[1])) { + tmp = do_constant_folding(opc, arg_info(op->args[1])->val, + op->args[2]); + tcg_opt_gen_movi(s, &temps_used, op, op->args[0], tmp); + break; + } + goto do_default; + CASE_OP_32_64(add): CASE_OP_32_64(sub): CASE_OP_32_64(mul): |