tcg/ppc: Fold the ext{8,16,32}[us] cases into {s}extract

Accept byte and word extensions with the extract opcodes.
This is preparatory to removing the specialized extracts.

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2024-12-25 21:44:35 -08:00
parent 791d03047b
commit 94d593941b
2 changed files with 44 additions and 2 deletions

View File

@ -39,7 +39,7 @@
#define TCG_TARGET_HAS_ctpop_i32 have_isa_2_06 #define TCG_TARGET_HAS_ctpop_i32 have_isa_2_06
#define TCG_TARGET_HAS_deposit_i32 1 #define TCG_TARGET_HAS_deposit_i32 1
#define TCG_TARGET_HAS_extract_i32 1 #define TCG_TARGET_HAS_extract_i32 1
#define TCG_TARGET_HAS_sextract_i32 0 #define TCG_TARGET_HAS_sextract_i32 1
#define TCG_TARGET_HAS_extract2_i32 0 #define TCG_TARGET_HAS_extract2_i32 0
#define TCG_TARGET_HAS_negsetcond_i32 1 #define TCG_TARGET_HAS_negsetcond_i32 1
#define TCG_TARGET_HAS_mulu2_i32 0 #define TCG_TARGET_HAS_mulu2_i32 0
@ -75,7 +75,7 @@
#define TCG_TARGET_HAS_ctpop_i64 have_isa_2_06 #define TCG_TARGET_HAS_ctpop_i64 have_isa_2_06
#define TCG_TARGET_HAS_deposit_i64 1 #define TCG_TARGET_HAS_deposit_i64 1
#define TCG_TARGET_HAS_extract_i64 1 #define TCG_TARGET_HAS_extract_i64 1
#define TCG_TARGET_HAS_sextract_i64 0 #define TCG_TARGET_HAS_sextract_i64 1
#define TCG_TARGET_HAS_extract2_i64 0 #define TCG_TARGET_HAS_extract2_i64 0
#define TCG_TARGET_HAS_negsetcond_i64 1 #define TCG_TARGET_HAS_negsetcond_i64 1
#define TCG_TARGET_HAS_add2_i64 1 #define TCG_TARGET_HAS_add2_i64 1
@ -121,4 +121,16 @@
#define TCG_TARGET_HAS_cmpsel_vec 1 #define TCG_TARGET_HAS_cmpsel_vec 1
#define TCG_TARGET_HAS_tst_vec 0 #define TCG_TARGET_HAS_tst_vec 0
#define TCG_TARGET_extract_valid(type, ofs, len) 1
static inline bool
tcg_target_sextract_valid(TCGType type, unsigned ofs, unsigned len)
{
if (type == TCG_TYPE_I64 && ofs + len == 32) {
return true;
}
return ofs == 0 && (len == 8 || len == 16);
}
#define TCG_TARGET_sextract_valid tcg_target_sextract_valid
#endif #endif

View File

@ -3430,13 +3430,41 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
break; break;
case INDEX_op_extract_i32: case INDEX_op_extract_i32:
if (args[2] == 0 && args[3] <= 16) {
tcg_out32(s, ANDI | SAI(args[1], args[0], (1 << args[3]) - 1));
break;
}
tcg_out_rlw(s, RLWINM, args[0], args[1], tcg_out_rlw(s, RLWINM, args[0], args[1],
32 - args[2], 32 - args[3], 31); 32 - args[2], 32 - args[3], 31);
break; break;
case INDEX_op_extract_i64: case INDEX_op_extract_i64:
if (args[2] == 0 && args[3] <= 16) {
tcg_out32(s, ANDI | SAI(args[1], args[0], (1 << args[3]) - 1));
break;
}
tcg_out_rld(s, RLDICL, args[0], args[1], 64 - args[2], 64 - args[3]); tcg_out_rld(s, RLDICL, args[0], args[1], 64 - args[2], 64 - args[3]);
break; break;
case INDEX_op_sextract_i64:
if (args[2] + args[3] == 32) {
if (args[2] == 0) {
tcg_out_ext32s(s, args[0], args[1]);
} else {
tcg_out_sari32(s, args[0], args[1], args[2]);
}
break;
}
/* FALLTHRU */
case INDEX_op_sextract_i32:
if (args[2] == 0 && args[3] == 8) {
tcg_out_ext8s(s, TCG_TYPE_I32, args[0], args[1]);
} else if (args[2] == 0 && args[3] == 16) {
tcg_out_ext16s(s, TCG_TYPE_I32, args[0], args[1]);
} else {
g_assert_not_reached();
}
break;
case INDEX_op_movcond_i32: case INDEX_op_movcond_i32:
tcg_out_movcond(s, TCG_TYPE_I32, args[5], args[0], args[1], args[2], tcg_out_movcond(s, TCG_TYPE_I32, args[5], args[0], args[1], args[2],
args[3], args[4], const_args[2]); args[3], args[4], const_args[2]);
@ -4160,6 +4188,7 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
case INDEX_op_bswap16_i32: case INDEX_op_bswap16_i32:
case INDEX_op_bswap32_i32: case INDEX_op_bswap32_i32:
case INDEX_op_extract_i32: case INDEX_op_extract_i32:
case INDEX_op_sextract_i32:
case INDEX_op_ld8u_i64: case INDEX_op_ld8u_i64:
case INDEX_op_ld8s_i64: case INDEX_op_ld8s_i64:
case INDEX_op_ld16u_i64: case INDEX_op_ld16u_i64:
@ -4179,6 +4208,7 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
case INDEX_op_bswap32_i64: case INDEX_op_bswap32_i64:
case INDEX_op_bswap64_i64: case INDEX_op_bswap64_i64:
case INDEX_op_extract_i64: case INDEX_op_extract_i64:
case INDEX_op_sextract_i64:
return C_O1_I1(r, r); return C_O1_I1(r, r);
case INDEX_op_st8_i32: case INDEX_op_st8_i32: