diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2024-12-29 20:52:12 -0800 |
---|---|---|
committer | Richard Henderson <richard.henderson@linaro.org> | 2025-01-16 20:57:17 -0800 |
commit | fa65f13555e121566c9105f252c72a3b63f1ecea (patch) | |
tree | 6e6fe34c6cd8850170cd13f9a1e89a7c2ea428f5 | |
parent | 841e2c5257102c738e8578eb0ce38d3de830ea4c (diff) | |
download | qemu-fa65f13555e121566c9105f252c72a3b63f1ecea.zip qemu-fa65f13555e121566c9105f252c72a3b63f1ecea.tar.gz qemu-fa65f13555e121566c9105f252c72a3b63f1ecea.tar.bz2 |
tcg/riscv: Use SRAIW, SRLIW for {s}extract_i64
Extracts which abut bit 32 may use 32-bit shifts.
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
-rw-r--r-- | tcg/riscv/tcg-target-has.h | 24 | ||||
-rw-r--r-- | tcg/riscv/tcg-target.c.inc | 16 |
2 files changed, 19 insertions, 21 deletions
diff --git a/tcg/riscv/tcg-target-has.h b/tcg/riscv/tcg-target-has.h index 5bf62c7..e890546 100644 --- a/tcg/riscv/tcg-target-has.h +++ b/tcg/riscv/tcg-target-has.h @@ -112,31 +112,21 @@ static inline bool tcg_target_extract_valid(TCGType type, unsigned ofs, unsigned len) { - if (ofs == 0) { - switch (len) { - case 16: - return cpuinfo & CPUINFO_ZBB; - case 32: - return (cpuinfo & CPUINFO_ZBA) && type == TCG_TYPE_I64; - } + if (type == TCG_TYPE_I64 && ofs + len == 32) { + /* ofs > 0 uses SRLIW; ofs == 0 uses add.uw. */ + return ofs || (cpuinfo & CPUINFO_ZBA); } - return false; + return (cpuinfo & CPUINFO_ZBB) && ofs == 0 && len == 16; } #define TCG_TARGET_extract_valid tcg_target_extract_valid static inline bool tcg_target_sextract_valid(TCGType type, unsigned ofs, unsigned len) { - if (ofs == 0) { - switch (len) { - case 8: - case 16: - return cpuinfo & CPUINFO_ZBB; - case 32: - return type == TCG_TYPE_I64; - } + if (type == TCG_TYPE_I64 && ofs + len == 32) { + return true; } - return false; + return (cpuinfo & CPUINFO_ZBB) && ofs == 0 && (len == 8 || len == 16); } #define TCG_TARGET_sextract_valid tcg_target_sextract_valid diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc index fc93900..4f6e18f 100644 --- a/tcg/riscv/tcg-target.c.inc +++ b/tcg/riscv/tcg-target.c.inc @@ -2344,8 +2344,12 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type, break; case INDEX_op_extract_i64: - if (a2 == 0 && args[3] == 32) { - tcg_out_ext32u(s, a0, a1); + if (a2 + args[3] == 32) { + if (a2 == 0) { + tcg_out_ext32u(s, a0, a1); + } else { + tcg_out_opc_imm(s, OPC_SRLIW, a0, a1, a2); + } break; } /* FALLTHRU */ @@ -2358,8 +2362,12 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type, break; case INDEX_op_sextract_i64: - if (a2 == 0 && args[3] == 32) { - tcg_out_ext32s(s, a0, a1); + if (a2 + args[3] == 32) { + if (a2 == 0) { + tcg_out_ext32s(s, a0, a1); + } else { + tcg_out_opc_imm(s, OPC_SRAIW, a0, a1, a2); + } break; } /* FALLTHRU */ |