tcg: Make use of bswap flags in tcg_gen_qemu_ld_*
We can perform any required sign-extension via TCG_BSWAP_OS. Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
2b836c2ac1
commit
359feba534
24
tcg/tcg-op.c
24
tcg/tcg-op.c
@ -2876,7 +2876,7 @@ void tcg_gen_qemu_ld_i32(TCGv_i32 val, TCGv addr, TCGArg idx, MemOp memop)
|
|||||||
orig_memop = memop;
|
orig_memop = memop;
|
||||||
if (!TCG_TARGET_HAS_MEMORY_BSWAP && (memop & MO_BSWAP)) {
|
if (!TCG_TARGET_HAS_MEMORY_BSWAP && (memop & MO_BSWAP)) {
|
||||||
memop &= ~MO_BSWAP;
|
memop &= ~MO_BSWAP;
|
||||||
/* The bswap primitive requires zero-extended input. */
|
/* The bswap primitive benefits from zero-extended input. */
|
||||||
if ((memop & MO_SSIZE) == MO_SW) {
|
if ((memop & MO_SSIZE) == MO_SW) {
|
||||||
memop &= ~MO_SIGN;
|
memop &= ~MO_SIGN;
|
||||||
}
|
}
|
||||||
@ -2889,10 +2889,9 @@ void tcg_gen_qemu_ld_i32(TCGv_i32 val, TCGv addr, TCGArg idx, MemOp memop)
|
|||||||
if ((orig_memop ^ memop) & MO_BSWAP) {
|
if ((orig_memop ^ memop) & MO_BSWAP) {
|
||||||
switch (orig_memop & MO_SIZE) {
|
switch (orig_memop & MO_SIZE) {
|
||||||
case MO_16:
|
case MO_16:
|
||||||
tcg_gen_bswap16_i32(val, val, TCG_BSWAP_IZ | TCG_BSWAP_OZ);
|
tcg_gen_bswap16_i32(val, val, (orig_memop & MO_SIGN
|
||||||
if (orig_memop & MO_SIGN) {
|
? TCG_BSWAP_IZ | TCG_BSWAP_OS
|
||||||
tcg_gen_ext16s_i32(val, val);
|
: TCG_BSWAP_IZ | TCG_BSWAP_OZ));
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case MO_32:
|
case MO_32:
|
||||||
tcg_gen_bswap32_i32(val, val);
|
tcg_gen_bswap32_i32(val, val);
|
||||||
@ -2965,7 +2964,7 @@ void tcg_gen_qemu_ld_i64(TCGv_i64 val, TCGv addr, TCGArg idx, MemOp memop)
|
|||||||
orig_memop = memop;
|
orig_memop = memop;
|
||||||
if (!TCG_TARGET_HAS_MEMORY_BSWAP && (memop & MO_BSWAP)) {
|
if (!TCG_TARGET_HAS_MEMORY_BSWAP && (memop & MO_BSWAP)) {
|
||||||
memop &= ~MO_BSWAP;
|
memop &= ~MO_BSWAP;
|
||||||
/* The bswap primitive requires zero-extended input. */
|
/* The bswap primitive benefits from zero-extended input. */
|
||||||
if ((memop & MO_SIGN) && (memop & MO_SIZE) < MO_64) {
|
if ((memop & MO_SIGN) && (memop & MO_SIZE) < MO_64) {
|
||||||
memop &= ~MO_SIGN;
|
memop &= ~MO_SIGN;
|
||||||
}
|
}
|
||||||
@ -2976,18 +2975,15 @@ void tcg_gen_qemu_ld_i64(TCGv_i64 val, TCGv addr, TCGArg idx, MemOp memop)
|
|||||||
plugin_gen_mem_callbacks(addr, info);
|
plugin_gen_mem_callbacks(addr, info);
|
||||||
|
|
||||||
if ((orig_memop ^ memop) & MO_BSWAP) {
|
if ((orig_memop ^ memop) & MO_BSWAP) {
|
||||||
|
int flags = (orig_memop & MO_SIGN
|
||||||
|
? TCG_BSWAP_IZ | TCG_BSWAP_OS
|
||||||
|
: TCG_BSWAP_IZ | TCG_BSWAP_OZ);
|
||||||
switch (orig_memop & MO_SIZE) {
|
switch (orig_memop & MO_SIZE) {
|
||||||
case MO_16:
|
case MO_16:
|
||||||
tcg_gen_bswap16_i64(val, val, TCG_BSWAP_IZ | TCG_BSWAP_OZ);
|
tcg_gen_bswap16_i64(val, val, flags);
|
||||||
if (orig_memop & MO_SIGN) {
|
|
||||||
tcg_gen_ext16s_i64(val, val);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case MO_32:
|
case MO_32:
|
||||||
tcg_gen_bswap32_i64(val, val, TCG_BSWAP_IZ | TCG_BSWAP_OZ);
|
tcg_gen_bswap32_i64(val, val, flags);
|
||||||
if (orig_memop & MO_SIGN) {
|
|
||||||
tcg_gen_ext32s_i64(val, val);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case MO_64:
|
case MO_64:
|
||||||
tcg_gen_bswap64_i64(val, val);
|
tcg_gen_bswap64_i64(val, val);
|
||||||
|
Loading…
Reference in New Issue
Block a user