Merge remote-tracking branch 'remotes/rth-gitlab/tags/pull-tcg-20210113' into staging

Improvements to tcg constant handling.
Force utf8 for decodetree.

# gpg: Signature made Thu 14 Jan 2021 02:15:42 GMT
# gpg:                using RSA key 7A481E78868B4DB6A85A05C064DF38E8AF7E215F
# gpg:                issuer "richard.henderson@linaro.org"
# gpg: Good signature from "Richard Henderson <richard.henderson@linaro.org>" [full]
# Primary key fingerprint: 7A48 1E78 868B 4DB6 A85A  05C0 64DF 38E8 AF7E 215F

* remotes/rth-gitlab/tags/pull-tcg-20210113: (24 commits)
  decodetree: Open files with encoding='utf-8'
  tcg/aarch64: Use tcg_constant_vec with tcg vec expanders
  tcg/ppc: Use tcg_constant_vec with tcg vec expanders
  tcg: Remove tcg_gen_dup{8,16,32,64}i_vec
  tcg/i386: Use tcg_constant_vec with tcg vec expanders
  tcg: Add tcg_reg_alloc_dup2
  tcg: Remove movi and dupi opcodes
  tcg/tci: Add special tci_movi_{i32,i64} opcodes
  tcg: Use tcg_constant_{i32,i64,vec} with gvec expanders
  tcg: Use tcg_constant_{i32,i64} with tcg plugins
  tcg: Use tcg_constant_{i32,i64} with tcg int expanders
  tcg: Use tcg_constant_i32 with icount expander
  tcg: Convert tcg_gen_dupi_vec to TCG_CONST
  tcg/optimize: Use tcg_constant_internal with constant folding
  tcg/optimize: Adjust TempOptInfo allocation
  tcg/optimize: Improve find_better_copy
  tcg: Introduce TYPE_CONST temporaries
  tcg: Expand TempOptInfo to 64-bits
  tcg: Rename struct tcg_temp_info to TempOptInfo
  tcg: Expand TCGTemp.val to 64-bits
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell
2021-01-14 09:54:29 +00:00
21 changed files with 890 additions and 669 deletions
+22 -27
View File
@@ -284,8 +284,8 @@ static TCGOp *copy_extu_i32_i64(TCGOp **begin_op, TCGOp *op)
if (TCG_TARGET_REG_BITS == 32) {
/* mov_i32 */
op = copy_op(begin_op, op, INDEX_op_mov_i32);
/* movi_i32 */
op = copy_op(begin_op, op, INDEX_op_movi_i32);
/* mov_i32 w/ $0 */
op = copy_op(begin_op, op, INDEX_op_mov_i32);
} else {
/* extu_i32_i64 */
op = copy_op(begin_op, op, INDEX_op_extu_i32_i64);
@@ -306,39 +306,34 @@ static TCGOp *copy_mov_i64(TCGOp **begin_op, TCGOp *op)
return op;
}
static TCGOp *copy_movi_i64(TCGOp **begin_op, TCGOp *op, uint64_t v)
{
if (TCG_TARGET_REG_BITS == 32) {
/* 2x movi_i32 */
op = copy_op(begin_op, op, INDEX_op_movi_i32);
op->args[1] = v;
op = copy_op(begin_op, op, INDEX_op_movi_i32);
op->args[1] = v >> 32;
} else {
/* movi_i64 */
op = copy_op(begin_op, op, INDEX_op_movi_i64);
op->args[1] = v;
}
return op;
}
static TCGOp *copy_const_ptr(TCGOp **begin_op, TCGOp *op, void *ptr)
{
if (UINTPTR_MAX == UINT32_MAX) {
/* movi_i32 */
op = copy_op(begin_op, op, INDEX_op_movi_i32);
op->args[1] = (uintptr_t)ptr;
/* mov_i32 */
op = copy_op(begin_op, op, INDEX_op_mov_i32);
op->args[1] = tcgv_i32_arg(tcg_constant_i32((uintptr_t)ptr));
} else {
/* movi_i64 */
op = copy_movi_i64(begin_op, op, (uint64_t)(uintptr_t)ptr);
/* mov_i64 */
op = copy_op(begin_op, op, INDEX_op_mov_i64);
op->args[1] = tcgv_i64_arg(tcg_constant_i64((uintptr_t)ptr));
}
return op;
}
static TCGOp *copy_const_i64(TCGOp **begin_op, TCGOp *op, uint64_t v)
{
return copy_movi_i64(begin_op, op, v);
if (TCG_TARGET_REG_BITS == 32) {
/* 2x mov_i32 */
op = copy_op(begin_op, op, INDEX_op_mov_i32);
op->args[1] = tcgv_i32_arg(tcg_constant_i32(v));
op = copy_op(begin_op, op, INDEX_op_mov_i32);
op->args[1] = tcgv_i32_arg(tcg_constant_i32(v >> 32));
} else {
/* mov_i64 */
op = copy_op(begin_op, op, INDEX_op_mov_i64);
op->args[1] = tcgv_i64_arg(tcg_constant_i64(v));
}
return op;
}
static TCGOp *copy_extu_tl_i64(TCGOp **begin_op, TCGOp *op)
@@ -486,8 +481,8 @@ static TCGOp *append_mem_cb(const struct qemu_plugin_dyn_cb *cb,
tcg_debug_assert(type == PLUGIN_GEN_CB_MEM);
/* const_i32 == movi_i32 ("info", so it remains as is) */
op = copy_op(&begin_op, op, INDEX_op_movi_i32);
/* const_i32 == mov_i32 ("info", so it remains as is) */
op = copy_op(&begin_op, op, INDEX_op_mov_i32);
/* const_ptr */
op = copy_const_ptr(&begin_op, op, cb->userp);
+13 -12
View File
@@ -34,7 +34,7 @@ static inline void gen_io_end(void)
static inline void gen_tb_start(const TranslationBlock *tb)
{
TCGv_i32 count, imm;
TCGv_i32 count;
tcg_ctx->exitreq_label = gen_new_label();
if (tb_cflags(tb) & CF_USE_ICOUNT) {
@@ -48,15 +48,13 @@ static inline void gen_tb_start(const TranslationBlock *tb)
offsetof(ArchCPU, env));
if (tb_cflags(tb) & CF_USE_ICOUNT) {
imm = tcg_temp_new_i32();
/* We emit a movi with a dummy immediate argument. Keep the insn index
* of the movi so that we later (when we know the actual insn count)
* can update the immediate argument with the actual insn count. */
tcg_gen_movi_i32(imm, 0xdeadbeef);
/*
* We emit a sub with a dummy immediate argument. Keep the insn index
* of the sub so that we later (when we know the actual insn count)
* can update the argument with the actual insn count.
*/
tcg_gen_sub_i32(count, count, tcg_constant_i32(0));
icount_start_insn = tcg_last_op();
tcg_gen_sub_i32(count, count, imm);
tcg_temp_free_i32(imm);
}
tcg_gen_brcondi_i32(TCG_COND_LT, count, 0, tcg_ctx->exitreq_label);
@@ -74,9 +72,12 @@ static inline void gen_tb_start(const TranslationBlock *tb)
static inline void gen_tb_end(const TranslationBlock *tb, int num_insns)
{
if (tb_cflags(tb) & CF_USE_ICOUNT) {
/* Update the num_insn immediate parameter now that we know
* the actual insn count. */
tcg_set_insn_param(icount_start_insn, 1, num_insns);
/*
* Update the num_insn immediate parameter now that we know
* the actual insn count.
*/
tcg_set_insn_param(icount_start_insn, 2,
tcgv_i32_arg(tcg_constant_i32(num_insns)));
}
gen_set_label(tcg_ctx->exitreq_label);
+2 -15
View File
@@ -271,6 +271,7 @@ void tcg_gen_mb(TCGBar);
/* 32 bit ops */
void tcg_gen_movi_i32(TCGv_i32 ret, int32_t arg);
void tcg_gen_addi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2);
void tcg_gen_subfi_i32(TCGv_i32 ret, int32_t arg1, TCGv_i32 arg2);
void tcg_gen_subi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2);
@@ -349,11 +350,6 @@ static inline void tcg_gen_mov_i32(TCGv_i32 ret, TCGv_i32 arg)
}
}
static inline void tcg_gen_movi_i32(TCGv_i32 ret, int32_t arg)
{
tcg_gen_op2i_i32(INDEX_op_movi_i32, ret, arg);
}
static inline void tcg_gen_ld8u_i32(TCGv_i32 ret, TCGv_ptr arg2,
tcg_target_long offset)
{
@@ -467,6 +463,7 @@ static inline void tcg_gen_not_i32(TCGv_i32 ret, TCGv_i32 arg)
/* 64 bit ops */
void tcg_gen_movi_i64(TCGv_i64 ret, int64_t arg);
void tcg_gen_addi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2);
void tcg_gen_subfi_i64(TCGv_i64 ret, int64_t arg1, TCGv_i64 arg2);
void tcg_gen_subi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2);
@@ -550,11 +547,6 @@ static inline void tcg_gen_mov_i64(TCGv_i64 ret, TCGv_i64 arg)
}
}
static inline void tcg_gen_movi_i64(TCGv_i64 ret, int64_t arg)
{
tcg_gen_op2i_i64(INDEX_op_movi_i64, ret, arg);
}
static inline void tcg_gen_ld8u_i64(TCGv_i64 ret, TCGv_ptr arg2,
tcg_target_long offset)
{
@@ -698,7 +690,6 @@ static inline void tcg_gen_sub_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
void tcg_gen_discard_i64(TCGv_i64 arg);
void tcg_gen_mov_i64(TCGv_i64 ret, TCGv_i64 arg);
void tcg_gen_movi_i64(TCGv_i64 ret, int64_t arg);
void tcg_gen_ld8u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset);
void tcg_gen_ld8s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset);
void tcg_gen_ld16u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset);
@@ -968,10 +959,6 @@ void tcg_gen_mov_vec(TCGv_vec, TCGv_vec);
void tcg_gen_dup_i32_vec(unsigned vece, TCGv_vec, TCGv_i32);
void tcg_gen_dup_i64_vec(unsigned vece, TCGv_vec, TCGv_i64);
void tcg_gen_dup_mem_vec(unsigned vece, TCGv_vec, TCGv_ptr, tcg_target_long);
void tcg_gen_dup8i_vec(TCGv_vec, uint32_t);
void tcg_gen_dup16i_vec(TCGv_vec, uint32_t);
void tcg_gen_dup32i_vec(TCGv_vec, uint32_t);
void tcg_gen_dup64i_vec(TCGv_vec, uint64_t);
void tcg_gen_dupi_vec(unsigned vece, TCGv_vec, uint64_t);
void tcg_gen_add_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
void tcg_gen_sub_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
+8 -3
View File
@@ -45,7 +45,6 @@ DEF(br, 0, 0, 1, TCG_OPF_BB_END)
DEF(mb, 0, 0, 1, 0)
DEF(mov_i32, 1, 1, 0, TCG_OPF_NOT_PRESENT)
DEF(movi_i32, 1, 0, 1, TCG_OPF_NOT_PRESENT)
DEF(setcond_i32, 1, 2, 1, 0)
DEF(movcond_i32, 1, 4, 1, IMPL(TCG_TARGET_HAS_movcond_i32))
/* load/store */
@@ -111,7 +110,6 @@ DEF(ctz_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_ctz_i32))
DEF(ctpop_i32, 1, 1, 0, IMPL(TCG_TARGET_HAS_ctpop_i32))
DEF(mov_i64, 1, 1, 0, TCG_OPF_64BIT | TCG_OPF_NOT_PRESENT)
DEF(movi_i64, 1, 0, 1, TCG_OPF_64BIT | TCG_OPF_NOT_PRESENT)
DEF(setcond_i64, 1, 2, 1, IMPL64)
DEF(movcond_i64, 1, 4, 1, IMPL64 | IMPL(TCG_TARGET_HAS_movcond_i64))
/* load/store */
@@ -221,7 +219,6 @@ DEF(qemu_st8_i32, 0, TLADDR_ARGS + 1, 1,
#define IMPLVEC TCG_OPF_VECTOR | IMPL(TCG_TARGET_MAYBE_vec)
DEF(mov_vec, 1, 1, 0, TCG_OPF_VECTOR | TCG_OPF_NOT_PRESENT)
DEF(dupi_vec, 1, 0, 1, TCG_OPF_VECTOR | TCG_OPF_NOT_PRESENT)
DEF(dup_vec, 1, 1, 0, IMPLVEC)
DEF(dup2_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_REG_BITS == 32))
@@ -278,6 +275,14 @@ DEF(last_generic, 0, 0, 0, TCG_OPF_NOT_PRESENT)
#include "tcg-target.opc.h"
#endif
#ifdef TCG_TARGET_INTERPRETER
/* These opcodes are only for use between the tci generator and interpreter. */
DEF(tci_movi_i32, 1, 0, 1, TCG_OPF_NOT_PRESENT)
#if TCG_TARGET_REG_BITS == 64
DEF(tci_movi_i64, 1, 0, 1, TCG_OPF_64BIT | TCG_OPF_NOT_PRESENT)
#endif
#endif
#undef TLADDR_ARGS
#undef DATA64_ARGS
#undef IMPL
+41 -9
View File
@@ -483,26 +483,32 @@ typedef enum TCGTempVal {
TEMP_VAL_CONST,
} TCGTempVal;
typedef enum TCGTempKind {
/* Temp is dead at the end of all basic blocks. */
TEMP_NORMAL,
/* Temp is saved across basic blocks but dead at the end of TBs. */
TEMP_LOCAL,
/* Temp is saved across both basic blocks and translation blocks. */
TEMP_GLOBAL,
/* Temp is in a fixed register. */
TEMP_FIXED,
/* Temp is a fixed constant. */
TEMP_CONST,
} TCGTempKind;
typedef struct TCGTemp {
TCGReg reg:8;
TCGTempVal val_type:8;
TCGType base_type:8;
TCGType type:8;
unsigned int fixed_reg:1;
TCGTempKind kind:3;
unsigned int indirect_reg:1;
unsigned int indirect_base:1;
unsigned int mem_coherent:1;
unsigned int mem_allocated:1;
/* If true, the temp is saved across both basic blocks and
translation blocks. */
unsigned int temp_global:1;
/* If true, the temp is saved across basic blocks but dead
at the end of translation blocks. If false, the temp is
dead at the end of basic blocks. */
unsigned int temp_local:1;
unsigned int temp_allocated:1;
tcg_target_long val;
int64_t val;
struct TCGTemp *mem_base;
intptr_t mem_offset;
const char *name;
@@ -661,6 +667,7 @@ struct TCGContext {
QSIMPLEQ_HEAD(, TCGOp) plugin_ops;
#endif
GHashTable *const_table[TCG_TYPE_COUNT];
TCGTempSet free_temps[TCG_TYPE_COUNT * 2];
TCGTemp temps[TCG_MAX_TEMPS]; /* globals first, temps after */
@@ -675,6 +682,11 @@ struct TCGContext {
target_ulong gen_insn_data[TCG_MAX_INSNS][TARGET_INSN_START_WORDS];
};
static inline bool temp_readonly(TCGTemp *ts)
{
return ts->kind >= TEMP_FIXED;
}
extern TCGContext tcg_init_ctx;
extern __thread TCGContext *tcg_ctx;
extern const void *tcg_code_gen_epilogue;
@@ -1070,6 +1082,7 @@ TCGOp *tcg_op_insert_after(TCGContext *s, TCGOp *op, TCGOpcode opc);
void tcg_optimize(TCGContext *s);
/* Allocate a new temporary and initialize it with a constant. */
TCGv_i32 tcg_const_i32(int32_t val);
TCGv_i64 tcg_const_i64(int64_t val);
TCGv_i32 tcg_const_local_i32(int32_t val);
@@ -1079,6 +1092,25 @@ TCGv_vec tcg_const_ones_vec(TCGType);
TCGv_vec tcg_const_zeros_vec_matching(TCGv_vec);
TCGv_vec tcg_const_ones_vec_matching(TCGv_vec);
/*
* Locate or create a read-only temporary that is a constant.
* This kind of temporary need not and should not be freed.
*/
TCGTemp *tcg_constant_internal(TCGType type, int64_t val);
static inline TCGv_i32 tcg_constant_i32(int32_t val)
{
return temp_tcgv_i32(tcg_constant_internal(TCG_TYPE_I32, val));
}
static inline TCGv_i64 tcg_constant_i64(int64_t val)
{
return temp_tcgv_i64(tcg_constant_internal(TCG_TYPE_I64, val));
}
TCGv_vec tcg_constant_vec(TCGType type, unsigned vece, int64_t val);
TCGv_vec tcg_constant_vec_matching(TCGv_vec match, unsigned vece, int64_t val);
#if UINTPTR_MAX == UINT32_MAX
# define tcg_const_ptr(x) ((TCGv_ptr)tcg_const_i32((intptr_t)(x)))
# define tcg_const_local_ptr(x) ((TCGv_ptr)tcg_const_local_i32((intptr_t)(x)))
+6 -3
View File
@@ -20,6 +20,7 @@
# See the syntax and semantics in docs/devel/decodetree.rst.
#
import io
import os
import re
import sys
@@ -1304,7 +1305,7 @@ def main():
for filename in args:
input_file = filename
f = open(filename, 'r')
f = open(filename, 'rt', encoding='utf-8')
parse_file(f, toppat)
f.close()
@@ -1324,9 +1325,11 @@ def main():
prop_size(stree)
if output_file:
output_fd = open(output_file, 'w')
output_fd = open(output_file, 'wt', encoding='utf-8')
else:
output_fd = sys.stdout
output_fd = io.TextIOWrapper(sys.stdout.buffer,
encoding=sys.stdout.encoding,
errors="ignore")
output_autogen()
for n in sorted(arguments.keys()):
+11 -21
View File
@@ -857,14 +857,14 @@ static void tcg_out_logicali(TCGContext *s, AArch64Insn insn, TCGType ext,
tcg_out_insn_3404(s, insn, ext, rd, rn, ext, r, c);
}
static void tcg_out_dupi_vec(TCGContext *s, TCGType type,
TCGReg rd, tcg_target_long v64)
static void tcg_out_dupi_vec(TCGContext *s, TCGType type, unsigned vece,
TCGReg rd, int64_t v64)
{
bool q = type == TCG_TYPE_V128;
int cmode, imm8, i;
/* Test all bytes equal first. */
if (v64 == dup_const(MO_8, v64)) {
if (vece == MO_8) {
imm8 = (uint8_t)v64;
tcg_out_insn(s, 3606, MOVI, q, rd, 0, 0xe, imm8);
return;
@@ -891,7 +891,7 @@ static void tcg_out_dupi_vec(TCGContext *s, TCGType type,
* cannot find an expansion there's no point checking a larger
* width because we already know by replication it cannot match.
*/
if (v64 == dup_const(MO_16, v64)) {
if (vece == MO_16) {
uint16_t v16 = v64;
if (is_shimm16(v16, &cmode, &imm8)) {
@@ -910,7 +910,7 @@ static void tcg_out_dupi_vec(TCGContext *s, TCGType type,
tcg_out_insn(s, 3606, MOVI, q, rd, 0, 0x8, v16 & 0xff);
tcg_out_insn(s, 3606, ORR, q, rd, 0, 0xa, v16 >> 8);
return;
} else if (v64 == dup_const(MO_32, v64)) {
} else if (vece == MO_32) {
uint32_t v32 = v64;
uint32_t n32 = ~v32;
@@ -1011,13 +1011,6 @@ static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg rd,
case TCG_TYPE_I64:
tcg_debug_assert(rd < 32);
break;
case TCG_TYPE_V64:
case TCG_TYPE_V128:
tcg_debug_assert(rd >= 32);
tcg_out_dupi_vec(s, type, rd, value);
return;
default:
g_assert_not_reached();
}
@@ -2264,8 +2257,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
case INDEX_op_mov_i32: /* Always emitted via tcg_out_mov. */
case INDEX_op_mov_i64:
case INDEX_op_movi_i32: /* Always emitted via tcg_out_movi. */
case INDEX_op_movi_i64:
case INDEX_op_call: /* Always emitted via tcg_out_call. */
default:
g_assert_not_reached();
@@ -2442,7 +2433,7 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
tcg_out_insn_3617(s, insn, is_q, vece, a0, a1);
break;
}
tcg_out_dupi_vec(s, type, TCG_VEC_TMP, 0);
tcg_out_dupi_vec(s, type, MO_8, TCG_VEC_TMP, 0);
a2 = TCG_VEC_TMP;
}
insn = cmp_insn[cond];
@@ -2473,7 +2464,6 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
break;
case INDEX_op_mov_vec: /* Always emitted via tcg_out_mov. */
case INDEX_op_dupi_vec: /* Always emitted via tcg_out_movi. */
case INDEX_op_dup_vec: /* Always emitted via tcg_out_dup_vec. */
default:
g_assert_not_reached();
@@ -2526,7 +2516,7 @@ void tcg_expand_vec_op(TCGOpcode opc, TCGType type, unsigned vece,
TCGArg a0, ...)
{
va_list va;
TCGv_vec v0, v1, v2, t1, t2;
TCGv_vec v0, v1, v2, t1, t2, c1;
TCGArg a2;
va_start(va, a0);
@@ -2558,8 +2548,8 @@ void tcg_expand_vec_op(TCGOpcode opc, TCGType type, unsigned vece,
case INDEX_op_rotlv_vec:
t1 = tcg_temp_new_vec(type);
tcg_gen_dupi_vec(vece, t1, 8 << vece);
tcg_gen_sub_vec(vece, t1, v2, t1);
c1 = tcg_constant_vec(type, vece, 8 << vece);
tcg_gen_sub_vec(vece, t1, v2, c1);
/* Right shifts are negative left shifts for AArch64. */
vec_gen_3(INDEX_op_shlv_vec, type, vece, tcgv_vec_arg(t1),
tcgv_vec_arg(v1), tcgv_vec_arg(t1));
@@ -2572,9 +2562,9 @@ void tcg_expand_vec_op(TCGOpcode opc, TCGType type, unsigned vece,
case INDEX_op_rotrv_vec:
t1 = tcg_temp_new_vec(type);
t2 = tcg_temp_new_vec(type);
c1 = tcg_constant_vec(type, vece, 8 << vece);
tcg_gen_neg_vec(vece, t1, v2);
tcg_gen_dupi_vec(vece, t2, 8 << vece);
tcg_gen_add_vec(vece, t2, t1, t2);
tcg_gen_sub_vec(vece, t2, c1, v2);
/* Right shifts are negative left shifts for AArch64. */
vec_gen_3(INDEX_op_shlv_vec, type, vece, tcgv_vec_arg(t1),
tcgv_vec_arg(v1), tcgv_vec_arg(t1));
-1
View File
@@ -2068,7 +2068,6 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
break;
case INDEX_op_mov_i32: /* Always emitted via tcg_out_mov. */
case INDEX_op_movi_i32: /* Always emitted via tcg_out_movi. */
case INDEX_op_call: /* Always emitted via tcg_out_call. */
default:
tcg_abort();
+67 -45
View File
@@ -942,8 +942,8 @@ static bool tcg_out_dupm_vec(TCGContext *s, TCGType type, unsigned vece,
return true;
}
static void tcg_out_dupi_vec(TCGContext *s, TCGType type,
TCGReg ret, tcg_target_long arg)
static void tcg_out_dupi_vec(TCGContext *s, TCGType type, unsigned vece,
TCGReg ret, int64_t arg)
{
int vex_l = (type == TCG_TYPE_V256 ? P_VEXL : 0);
@@ -956,7 +956,14 @@ static void tcg_out_dupi_vec(TCGContext *s, TCGType type,
return;
}
if (TCG_TARGET_REG_BITS == 64) {
if (TCG_TARGET_REG_BITS == 32 && vece < MO_64) {
if (have_avx2) {
tcg_out_vex_modrm_pool(s, OPC_VPBROADCASTD + vex_l, ret);
} else {
tcg_out_vex_modrm_pool(s, OPC_VBROADCASTSS, ret);
}
new_pool_label(s, arg, R_386_32, s->code_ptr - 4, 0);
} else {
if (type == TCG_TYPE_V64) {
tcg_out_vex_modrm_pool(s, OPC_MOVQ_VqWq, ret);
} else if (have_avx2) {
@@ -964,41 +971,40 @@ static void tcg_out_dupi_vec(TCGContext *s, TCGType type,
} else {
tcg_out_vex_modrm_pool(s, OPC_MOVDDUP, ret);
}
if (TCG_TARGET_REG_BITS == 64) {
new_pool_label(s, arg, R_386_PC32, s->code_ptr - 4, -4);
} else {
new_pool_l2(s, R_386_32, s->code_ptr - 4, 0, arg, arg >> 32);
}
}
}
static void tcg_out_movi_vec(TCGContext *s, TCGType type,
TCGReg ret, tcg_target_long arg)
{
if (arg == 0) {
tcg_out_vex_modrm(s, OPC_PXOR, ret, ret, ret);
return;
}
if (arg == -1) {
tcg_out_vex_modrm(s, OPC_PCMPEQB, ret, ret, ret);
return;
}
int rexw = (type == TCG_TYPE_I32 ? 0 : P_REXW);
tcg_out_vex_modrm_pool(s, OPC_MOVD_VyEy + rexw, ret);
if (TCG_TARGET_REG_BITS == 64) {
new_pool_label(s, arg, R_386_PC32, s->code_ptr - 4, -4);
} else {
if (have_avx2) {
tcg_out_vex_modrm_pool(s, OPC_VPBROADCASTD + vex_l, ret);
} else {
tcg_out_vex_modrm_pool(s, OPC_VBROADCASTSS, ret);
}
new_pool_label(s, arg, R_386_32, s->code_ptr - 4, 0);
}
}
static void tcg_out_movi(TCGContext *s, TCGType type,
TCGReg ret, tcg_target_long arg)
static void tcg_out_movi_int(TCGContext *s, TCGType type,
TCGReg ret, tcg_target_long arg)
{
tcg_target_long diff;
switch (type) {
case TCG_TYPE_I32:
#if TCG_TARGET_REG_BITS == 64
case TCG_TYPE_I64:
#endif
if (ret < 16) {
break;
}
/* fallthru */
case TCG_TYPE_V64:
case TCG_TYPE_V128:
case TCG_TYPE_V256:
tcg_debug_assert(ret >= 16);
tcg_out_dupi_vec(s, type, ret, arg);
return;
default:
g_assert_not_reached();
}
if (arg == 0) {
tgen_arithr(s, ARITH_XOR, ret, ret);
return;
@@ -1027,6 +1033,25 @@ static void tcg_out_movi(TCGContext *s, TCGType type,
tcg_out64(s, arg);
}
static void tcg_out_movi(TCGContext *s, TCGType type,
TCGReg ret, tcg_target_long arg)
{
switch (type) {
case TCG_TYPE_I32:
#if TCG_TARGET_REG_BITS == 64
case TCG_TYPE_I64:
#endif
if (ret < 16) {
tcg_out_movi_int(s, type, ret, arg);
} else {
tcg_out_movi_vec(s, type, ret, arg);
}
break;
default:
g_assert_not_reached();
}
}
static inline void tcg_out_pushi(TCGContext *s, tcg_target_long val)
{
if (val == (int8_t)val) {
@@ -2641,8 +2666,6 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
break;
case INDEX_op_mov_i32: /* Always emitted via tcg_out_mov. */
case INDEX_op_mov_i64:
case INDEX_op_movi_i32: /* Always emitted via tcg_out_movi. */
case INDEX_op_movi_i64:
case INDEX_op_call: /* Always emitted via tcg_out_call. */
default:
tcg_abort();
@@ -2928,7 +2951,6 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
break;
case INDEX_op_mov_vec: /* Always emitted via tcg_out_mov. */
case INDEX_op_dupi_vec: /* Always emitted via tcg_out_movi. */
case INDEX_op_dup_vec: /* Always emitted via tcg_out_dup_vec. */
default:
g_assert_not_reached();
@@ -3464,7 +3486,7 @@ static void expand_vec_rotv(TCGType type, unsigned vece, TCGv_vec v0,
static void expand_vec_mul(TCGType type, unsigned vece,
TCGv_vec v0, TCGv_vec v1, TCGv_vec v2)
{
TCGv_vec t1, t2, t3, t4;
TCGv_vec t1, t2, t3, t4, zero;
tcg_debug_assert(vece == MO_8);
@@ -3482,11 +3504,11 @@ static void expand_vec_mul(TCGType type, unsigned vece,
case TCG_TYPE_V64:
t1 = tcg_temp_new_vec(TCG_TYPE_V128);
t2 = tcg_temp_new_vec(TCG_TYPE_V128);
tcg_gen_dup16i_vec(t2, 0);
zero = tcg_constant_vec(TCG_TYPE_V128, MO_8, 0);
vec_gen_3(INDEX_op_x86_punpckl_vec, TCG_TYPE_V128, MO_8,
tcgv_vec_arg(t1), tcgv_vec_arg(v1), tcgv_vec_arg(t2));
tcgv_vec_arg(t1), tcgv_vec_arg(v1), tcgv_vec_arg(zero));
vec_gen_3(INDEX_op_x86_punpckl_vec, TCG_TYPE_V128, MO_8,
tcgv_vec_arg(t2), tcgv_vec_arg(t2), tcgv_vec_arg(v2));
tcgv_vec_arg(t2), tcgv_vec_arg(zero), tcgv_vec_arg(v2));
tcg_gen_mul_vec(MO_16, t1, t1, t2);
tcg_gen_shri_vec(MO_16, t1, t1, 8);
vec_gen_3(INDEX_op_x86_packus_vec, TCG_TYPE_V128, MO_8,
@@ -3501,15 +3523,15 @@ static void expand_vec_mul(TCGType type, unsigned vece,
t2 = tcg_temp_new_vec(type);
t3 = tcg_temp_new_vec(type);
t4 = tcg_temp_new_vec(type);
tcg_gen_dup16i_vec(t4, 0);
zero = tcg_constant_vec(TCG_TYPE_V128, MO_8, 0);
vec_gen_3(INDEX_op_x86_punpckl_vec, type, MO_8,
tcgv_vec_arg(t1), tcgv_vec_arg(v1), tcgv_vec_arg(t4));
tcgv_vec_arg(t1), tcgv_vec_arg(v1), tcgv_vec_arg(zero));
vec_gen_3(INDEX_op_x86_punpckl_vec, type, MO_8,
tcgv_vec_arg(t2), tcgv_vec_arg(t4), tcgv_vec_arg(v2));
tcgv_vec_arg(t2), tcgv_vec_arg(zero), tcgv_vec_arg(v2));
vec_gen_3(INDEX_op_x86_punpckh_vec, type, MO_8,
tcgv_vec_arg(t3), tcgv_vec_arg(v1), tcgv_vec_arg(t4));
tcgv_vec_arg(t3), tcgv_vec_arg(v1), tcgv_vec_arg(zero));
vec_gen_3(INDEX_op_x86_punpckh_vec, type, MO_8,
tcgv_vec_arg(t4), tcgv_vec_arg(t4), tcgv_vec_arg(v2));
tcgv_vec_arg(t4), tcgv_vec_arg(zero), tcgv_vec_arg(v2));
tcg_gen_mul_vec(MO_16, t1, t1, t2);
tcg_gen_mul_vec(MO_16, t3, t3, t4);
tcg_gen_shri_vec(MO_16, t1, t1, 8);
@@ -3537,7 +3559,7 @@ static bool expand_vec_cmp_noinv(TCGType type, unsigned vece, TCGv_vec v0,
NEED_UMIN = 8,
NEED_UMAX = 16,
};
TCGv_vec t1, t2;
TCGv_vec t1, t2, t3;
uint8_t fixup;
switch (cond) {
@@ -3608,9 +3630,9 @@ static bool expand_vec_cmp_noinv(TCGType type, unsigned vece, TCGv_vec v0,
} else if (fixup & NEED_BIAS) {
t1 = tcg_temp_new_vec(type);
t2 = tcg_temp_new_vec(type);
tcg_gen_dupi_vec(vece, t2, 1ull << ((8 << vece) - 1));
tcg_gen_sub_vec(vece, t1, v1, t2);
tcg_gen_sub_vec(vece, t2, v2, t2);
t3 = tcg_constant_vec(type, vece, 1ull << ((8 << vece) - 1));
tcg_gen_sub_vec(vece, t1, v1, t3);
tcg_gen_sub_vec(vece, t2, v2, t3);
v1 = t1;
v2 = t2;
cond = tcg_signed_cond(cond);
-2
View File
@@ -2141,8 +2141,6 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
break;
case INDEX_op_mov_i32: /* Always emitted via tcg_out_mov. */
case INDEX_op_mov_i64:
case INDEX_op_movi_i32: /* Always emitted via tcg_out_movi. */
case INDEX_op_movi_i64:
case INDEX_op_call: /* Always emitted via tcg_out_call. */
default:
tcg_abort();
+125 -124
View File
File diff suppressed because it is too large Load Diff
+51 -39
View File
@@ -912,31 +912,41 @@ static void tcg_out_movi_int(TCGContext *s, TCGType type, TCGReg ret,
}
}
static void tcg_out_dupi_vec(TCGContext *s, TCGType type, TCGReg ret,
tcg_target_long val)
static void tcg_out_dupi_vec(TCGContext *s, TCGType type, unsigned vece,
TCGReg ret, int64_t val)
{
uint32_t load_insn;
int rel, low;
intptr_t add;
low = (int8_t)val;
if (low >= -16 && low < 16) {
if (val == (tcg_target_long)dup_const(MO_8, low)) {
switch (vece) {
case MO_8:
low = (int8_t)val;
if (low >= -16 && low < 16) {
tcg_out32(s, VSPLTISB | VRT(ret) | ((val & 31) << 16));
return;
}
if (val == (tcg_target_long)dup_const(MO_16, low)) {
if (have_isa_3_00) {
tcg_out32(s, XXSPLTIB | VRT(ret) | ((val & 0xff) << 11));
return;
}
break;
case MO_16:
low = (int16_t)val;
if (low >= -16 && low < 16) {
tcg_out32(s, VSPLTISH | VRT(ret) | ((val & 31) << 16));
return;
}
if (val == (tcg_target_long)dup_const(MO_32, low)) {
break;
case MO_32:
low = (int32_t)val;
if (low >= -16 && low < 16) {
tcg_out32(s, VSPLTISW | VRT(ret) | ((val & 31) << 16));
return;
}
}
if (have_isa_3_00 && val == (tcg_target_long)dup_const(MO_8, val)) {
tcg_out32(s, XXSPLTIB | VRT(ret) | ((val & 0xff) << 11));
return;
break;
}
/*
@@ -956,14 +966,15 @@ static void tcg_out_dupi_vec(TCGContext *s, TCGType type, TCGReg ret,
if (TCG_TARGET_REG_BITS == 64) {
new_pool_label(s, val, rel, s->code_ptr, add);
} else {
new_pool_l2(s, rel, s->code_ptr, add, val, val);
new_pool_l2(s, rel, s->code_ptr, add, val >> 32, val);
}
} else {
load_insn = LVX | VRT(ret) | RB(TCG_REG_TMP1);
if (TCG_TARGET_REG_BITS == 64) {
new_pool_l2(s, rel, s->code_ptr, add, val, val);
} else {
new_pool_l4(s, rel, s->code_ptr, add, val, val, val, val);
new_pool_l4(s, rel, s->code_ptr, add,
val >> 32, val, val >> 32, val);
}
}
@@ -987,12 +998,6 @@ static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg ret,
tcg_out_movi_int(s, type, ret, arg, false);
break;
case TCG_TYPE_V64:
case TCG_TYPE_V128:
tcg_debug_assert(ret >= TCG_REG_V0);
tcg_out_dupi_vec(s, type, ret, arg);
break;
default:
g_assert_not_reached();
}
@@ -2972,8 +2977,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
case INDEX_op_mov_i32: /* Always emitted via tcg_out_mov. */
case INDEX_op_mov_i64:
case INDEX_op_movi_i32: /* Always emitted via tcg_out_movi. */
case INDEX_op_movi_i64:
case INDEX_op_call: /* Always emitted via tcg_out_call. */
default:
tcg_abort();
@@ -3321,7 +3324,6 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
return;
case INDEX_op_mov_vec: /* Always emitted via tcg_out_mov. */
case INDEX_op_dupi_vec: /* Always emitted via tcg_out_movi. */
case INDEX_op_dup_vec: /* Always emitted via tcg_out_dup_vec. */
default:
g_assert_not_reached();
@@ -3334,13 +3336,22 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
static void expand_vec_shi(TCGType type, unsigned vece, TCGv_vec v0,
TCGv_vec v1, TCGArg imm, TCGOpcode opci)
{
TCGv_vec t1 = tcg_temp_new_vec(type);
TCGv_vec t1;
/* Splat w/bytes for xxspltib. */
tcg_gen_dupi_vec(MO_8, t1, imm & ((8 << vece) - 1));
if (vece == MO_32) {
/*
* Only 5 bits are significant, and VSPLTISB can represent -16..15.
* So using negative numbers gets us the 4th bit easily.
*/
imm = sextract32(imm, 0, 5);
} else {
imm &= (8 << vece) - 1;
}
/* Splat w/bytes for xxspltib when 2.07 allows MO_64. */
t1 = tcg_constant_vec(type, MO_8, imm);
vec_gen_3(opci, type, vece, tcgv_vec_arg(v0),
tcgv_vec_arg(v1), tcgv_vec_arg(t1));
tcg_temp_free_vec(t1);
}
static void expand_vec_cmp(TCGType type, unsigned vece, TCGv_vec v0,
@@ -3398,7 +3409,7 @@ static void expand_vec_mul(TCGType type, unsigned vece, TCGv_vec v0,
{
TCGv_vec t1 = tcg_temp_new_vec(type);
TCGv_vec t2 = tcg_temp_new_vec(type);
TCGv_vec t3, t4;
TCGv_vec c0, c16;
switch (vece) {
case MO_8:
@@ -3417,21 +3428,22 @@ static void expand_vec_mul(TCGType type, unsigned vece, TCGv_vec v0,
case MO_32:
tcg_debug_assert(!have_isa_2_07);
t3 = tcg_temp_new_vec(type);
t4 = tcg_temp_new_vec(type);
tcg_gen_dupi_vec(MO_8, t4, -16);
/*
* Only 5 bits are significant, and VSPLTISB can represent -16..15.
* So using -16 is a quick way to represent 16.
*/
c16 = tcg_constant_vec(type, MO_8, -16);
c0 = tcg_constant_vec(type, MO_8, 0);
vec_gen_3(INDEX_op_rotlv_vec, type, MO_32, tcgv_vec_arg(t1),
tcgv_vec_arg(v2), tcgv_vec_arg(t4));
tcgv_vec_arg(v2), tcgv_vec_arg(c16));
vec_gen_3(INDEX_op_ppc_mulou_vec, type, MO_16, tcgv_vec_arg(t2),
tcgv_vec_arg(v1), tcgv_vec_arg(v2));
tcg_gen_dupi_vec(MO_8, t3, 0);
vec_gen_4(INDEX_op_ppc_msum_vec, type, MO_16, tcgv_vec_arg(t3),
tcgv_vec_arg(v1), tcgv_vec_arg(t1), tcgv_vec_arg(t3));
vec_gen_3(INDEX_op_shlv_vec, type, MO_32, tcgv_vec_arg(t3),
tcgv_vec_arg(t3), tcgv_vec_arg(t4));
tcg_gen_add_vec(MO_32, v0, t2, t3);
tcg_temp_free_vec(t3);
tcg_temp_free_vec(t4);
vec_gen_4(INDEX_op_ppc_msum_vec, type, MO_16, tcgv_vec_arg(t1),
tcgv_vec_arg(v1), tcgv_vec_arg(t1), tcgv_vec_arg(c0));
vec_gen_3(INDEX_op_shlv_vec, type, MO_32, tcgv_vec_arg(t1),
tcgv_vec_arg(t1), tcgv_vec_arg(c16));
tcg_gen_add_vec(MO_32, v0, t1, t2);
break;
default:
-2
View File
@@ -1563,8 +1563,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
case INDEX_op_mov_i32: /* Always emitted via tcg_out_mov. */
case INDEX_op_mov_i64:
case INDEX_op_movi_i32: /* Always emitted via tcg_out_movi. */
case INDEX_op_movi_i64:
case INDEX_op_call: /* Always emitted via tcg_out_call. */
default:
g_assert_not_reached();
-2
View File
@@ -2295,8 +2295,6 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
case INDEX_op_mov_i32: /* Always emitted via tcg_out_mov. */
case INDEX_op_mov_i64:
case INDEX_op_movi_i32: /* Always emitted via tcg_out_movi. */
case INDEX_op_movi_i64:
case INDEX_op_call: /* Always emitted via tcg_out_call. */
default:
tcg_abort();
-2
View File
@@ -1586,8 +1586,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
case INDEX_op_mov_i32: /* Always emitted via tcg_out_mov. */
case INDEX_op_mov_i64:
case INDEX_op_movi_i32: /* Always emitted via tcg_out_movi. */
case INDEX_op_movi_i64:
case INDEX_op_call: /* Always emitted via tcg_out_call. */
default:
tcg_abort();
+51 -78
View File
@@ -115,7 +115,7 @@ void tcg_gen_gvec_2_ool(uint32_t dofs, uint32_t aofs,
gen_helper_gvec_2 *fn)
{
TCGv_ptr a0, a1;
TCGv_i32 desc = tcg_const_i32(simd_desc(oprsz, maxsz, data));
TCGv_i32 desc = tcg_constant_i32(simd_desc(oprsz, maxsz, data));
a0 = tcg_temp_new_ptr();
a1 = tcg_temp_new_ptr();
@@ -127,7 +127,6 @@ void tcg_gen_gvec_2_ool(uint32_t dofs, uint32_t aofs,
tcg_temp_free_ptr(a0);
tcg_temp_free_ptr(a1);
tcg_temp_free_i32(desc);
}
/* Generate a call to a gvec-style helper with two vector operands
@@ -137,7 +136,7 @@ void tcg_gen_gvec_2i_ool(uint32_t dofs, uint32_t aofs, TCGv_i64 c,
gen_helper_gvec_2i *fn)
{
TCGv_ptr a0, a1;
TCGv_i32 desc = tcg_const_i32(simd_desc(oprsz, maxsz, data));
TCGv_i32 desc = tcg_constant_i32(simd_desc(oprsz, maxsz, data));
a0 = tcg_temp_new_ptr();
a1 = tcg_temp_new_ptr();
@@ -149,7 +148,6 @@ void tcg_gen_gvec_2i_ool(uint32_t dofs, uint32_t aofs, TCGv_i64 c,
tcg_temp_free_ptr(a0);
tcg_temp_free_ptr(a1);
tcg_temp_free_i32(desc);
}
/* Generate a call to a gvec-style helper with three vector operands. */
@@ -158,7 +156,7 @@ void tcg_gen_gvec_3_ool(uint32_t dofs, uint32_t aofs, uint32_t bofs,
gen_helper_gvec_3 *fn)
{
TCGv_ptr a0, a1, a2;
TCGv_i32 desc = tcg_const_i32(simd_desc(oprsz, maxsz, data));
TCGv_i32 desc = tcg_constant_i32(simd_desc(oprsz, maxsz, data));
a0 = tcg_temp_new_ptr();
a1 = tcg_temp_new_ptr();
@@ -173,7 +171,6 @@ void tcg_gen_gvec_3_ool(uint32_t dofs, uint32_t aofs, uint32_t bofs,
tcg_temp_free_ptr(a0);
tcg_temp_free_ptr(a1);
tcg_temp_free_ptr(a2);
tcg_temp_free_i32(desc);
}
/* Generate a call to a gvec-style helper with four vector operands. */
@@ -182,7 +179,7 @@ void tcg_gen_gvec_4_ool(uint32_t dofs, uint32_t aofs, uint32_t bofs,
int32_t data, gen_helper_gvec_4 *fn)
{
TCGv_ptr a0, a1, a2, a3;
TCGv_i32 desc = tcg_const_i32(simd_desc(oprsz, maxsz, data));
TCGv_i32 desc = tcg_constant_i32(simd_desc(oprsz, maxsz, data));
a0 = tcg_temp_new_ptr();
a1 = tcg_temp_new_ptr();
@@ -200,7 +197,6 @@ void tcg_gen_gvec_4_ool(uint32_t dofs, uint32_t aofs, uint32_t bofs,
tcg_temp_free_ptr(a1);
tcg_temp_free_ptr(a2);
tcg_temp_free_ptr(a3);
tcg_temp_free_i32(desc);
}
/* Generate a call to a gvec-style helper with five vector operands. */
@@ -209,7 +205,7 @@ void tcg_gen_gvec_5_ool(uint32_t dofs, uint32_t aofs, uint32_t bofs,
uint32_t maxsz, int32_t data, gen_helper_gvec_5 *fn)
{
TCGv_ptr a0, a1, a2, a3, a4;
TCGv_i32 desc = tcg_const_i32(simd_desc(oprsz, maxsz, data));
TCGv_i32 desc = tcg_constant_i32(simd_desc(oprsz, maxsz, data));
a0 = tcg_temp_new_ptr();
a1 = tcg_temp_new_ptr();
@@ -230,7 +226,6 @@ void tcg_gen_gvec_5_ool(uint32_t dofs, uint32_t aofs, uint32_t bofs,
tcg_temp_free_ptr(a2);
tcg_temp_free_ptr(a3);
tcg_temp_free_ptr(a4);
tcg_temp_free_i32(desc);
}
/* Generate a call to a gvec-style helper with three vector operands
@@ -240,7 +235,7 @@ void tcg_gen_gvec_2_ptr(uint32_t dofs, uint32_t aofs,
int32_t data, gen_helper_gvec_2_ptr *fn)
{
TCGv_ptr a0, a1;
TCGv_i32 desc = tcg_const_i32(simd_desc(oprsz, maxsz, data));
TCGv_i32 desc = tcg_constant_i32(simd_desc(oprsz, maxsz, data));
a0 = tcg_temp_new_ptr();
a1 = tcg_temp_new_ptr();
@@ -252,7 +247,6 @@ void tcg_gen_gvec_2_ptr(uint32_t dofs, uint32_t aofs,
tcg_temp_free_ptr(a0);
tcg_temp_free_ptr(a1);
tcg_temp_free_i32(desc);
}
/* Generate a call to a gvec-style helper with three vector operands
@@ -262,7 +256,7 @@ void tcg_gen_gvec_3_ptr(uint32_t dofs, uint32_t aofs, uint32_t bofs,
int32_t data, gen_helper_gvec_3_ptr *fn)
{
TCGv_ptr a0, a1, a2;
TCGv_i32 desc = tcg_const_i32(simd_desc(oprsz, maxsz, data));
TCGv_i32 desc = tcg_constant_i32(simd_desc(oprsz, maxsz, data));
a0 = tcg_temp_new_ptr();
a1 = tcg_temp_new_ptr();
@@ -277,7 +271,6 @@ void tcg_gen_gvec_3_ptr(uint32_t dofs, uint32_t aofs, uint32_t bofs,
tcg_temp_free_ptr(a0);
tcg_temp_free_ptr(a1);
tcg_temp_free_ptr(a2);
tcg_temp_free_i32(desc);
}
/* Generate a call to a gvec-style helper with four vector operands
@@ -288,7 +281,7 @@ void tcg_gen_gvec_4_ptr(uint32_t dofs, uint32_t aofs, uint32_t bofs,
gen_helper_gvec_4_ptr *fn)
{
TCGv_ptr a0, a1, a2, a3;
TCGv_i32 desc = tcg_const_i32(simd_desc(oprsz, maxsz, data));
TCGv_i32 desc = tcg_constant_i32(simd_desc(oprsz, maxsz, data));
a0 = tcg_temp_new_ptr();
a1 = tcg_temp_new_ptr();
@@ -306,7 +299,6 @@ void tcg_gen_gvec_4_ptr(uint32_t dofs, uint32_t aofs, uint32_t bofs,
tcg_temp_free_ptr(a1);
tcg_temp_free_ptr(a2);
tcg_temp_free_ptr(a3);
tcg_temp_free_i32(desc);
}
/* Generate a call to a gvec-style helper with five vector operands
@@ -317,7 +309,7 @@ void tcg_gen_gvec_5_ptr(uint32_t dofs, uint32_t aofs, uint32_t bofs,
gen_helper_gvec_5_ptr *fn)
{
TCGv_ptr a0, a1, a2, a3, a4;
TCGv_i32 desc = tcg_const_i32(simd_desc(oprsz, maxsz, data));
TCGv_i32 desc = tcg_constant_i32(simd_desc(oprsz, maxsz, data));
a0 = tcg_temp_new_ptr();
a1 = tcg_temp_new_ptr();
@@ -338,7 +330,6 @@ void tcg_gen_gvec_5_ptr(uint32_t dofs, uint32_t aofs, uint32_t bofs,
tcg_temp_free_ptr(a2);
tcg_temp_free_ptr(a3);
tcg_temp_free_ptr(a4);
tcg_temp_free_i32(desc);
}
/* Return true if we want to implement something of OPRSZ bytes
@@ -605,9 +596,9 @@ static void do_dup(unsigned vece, uint32_t dofs, uint32_t oprsz,
|| (TCG_TARGET_REG_BITS == 64
&& (in_c == 0 || in_c == -1
|| !check_size_impl(oprsz, 4)))) {
t_64 = tcg_const_i64(in_c);
t_64 = tcg_constant_i64(in_c);
} else {
t_32 = tcg_const_i32(in_c);
t_32 = tcg_constant_i32(in_c);
}
}
@@ -648,11 +639,11 @@ static void do_dup(unsigned vece, uint32_t dofs, uint32_t oprsz,
t_val = tcg_temp_new_i32();
tcg_gen_extrl_i64_i32(t_val, in_64);
} else {
t_val = tcg_const_i32(in_c);
t_val = tcg_constant_i32(in_c);
}
gen_helper_memset(t_ptr, t_ptr, t_val, t_size);
if (!in_32) {
if (in_64) {
tcg_temp_free_i32(t_val);
}
tcg_temp_free_ptr(t_size);
@@ -660,15 +651,14 @@ static void do_dup(unsigned vece, uint32_t dofs, uint32_t oprsz,
return;
}
t_desc = tcg_const_i32(simd_desc(oprsz, maxsz, 0));
t_desc = tcg_constant_i32(simd_desc(oprsz, maxsz, 0));
if (vece == MO_64) {
if (in_64) {
gen_helper_gvec_dup64(t_ptr, t_desc, in_64);
} else {
t_64 = tcg_const_i64(in_c);
t_64 = tcg_constant_i64(in_c);
gen_helper_gvec_dup64(t_ptr, t_desc, t_64);
tcg_temp_free_i64(t_64);
}
} else {
typedef void dup_fn(TCGv_ptr, TCGv_i32, TCGv_i32);
@@ -680,24 +670,23 @@ static void do_dup(unsigned vece, uint32_t dofs, uint32_t oprsz,
if (in_32) {
fns[vece](t_ptr, t_desc, in_32);
} else {
} else if (in_64) {
t_32 = tcg_temp_new_i32();
if (in_64) {
tcg_gen_extrl_i64_i32(t_32, in_64);
} else if (vece == MO_8) {
tcg_gen_movi_i32(t_32, in_c & 0xff);
} else if (vece == MO_16) {
tcg_gen_movi_i32(t_32, in_c & 0xffff);
} else {
tcg_gen_movi_i32(t_32, in_c);
}
tcg_gen_extrl_i64_i32(t_32, in_64);
fns[vece](t_ptr, t_desc, t_32);
tcg_temp_free_i32(t_32);
} else {
if (vece == MO_8) {
in_c &= 0xff;
} else if (vece == MO_16) {
in_c &= 0xffff;
}
t_32 = tcg_constant_i32(in_c);
fns[vece](t_ptr, t_desc, t_32);
}
}
tcg_temp_free_ptr(t_ptr);
tcg_temp_free_i32(t_desc);
return;
done:
@@ -1247,10 +1236,9 @@ void tcg_gen_gvec_2i(uint32_t dofs, uint32_t aofs, uint32_t oprsz,
if (g->fno) {
tcg_gen_gvec_2_ool(dofs, aofs, oprsz, maxsz, c, g->fno);
} else {
TCGv_i64 tcg_c = tcg_const_i64(c);
TCGv_i64 tcg_c = tcg_constant_i64(c);
tcg_gen_gvec_2i_ool(dofs, aofs, tcg_c, oprsz,
maxsz, c, g->fnoi);
tcg_temp_free_i64(tcg_c);
}
oprsz = maxsz;
}
@@ -1744,16 +1732,14 @@ static void gen_addv_mask(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b, TCGv_i64 m)
void tcg_gen_vec_add8_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
{
TCGv_i64 m = tcg_const_i64(dup_const(MO_8, 0x80));
TCGv_i64 m = tcg_constant_i64(dup_const(MO_8, 0x80));
gen_addv_mask(d, a, b, m);
tcg_temp_free_i64(m);
}
void tcg_gen_vec_add16_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
{
TCGv_i64 m = tcg_const_i64(dup_const(MO_16, 0x8000));
TCGv_i64 m = tcg_constant_i64(dup_const(MO_16, 0x8000));
gen_addv_mask(d, a, b, m);
tcg_temp_free_i64(m);
}
void tcg_gen_vec_add32_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
@@ -1837,9 +1823,8 @@ void tcg_gen_gvec_adds(unsigned vece, uint32_t dofs, uint32_t aofs,
void tcg_gen_gvec_addi(unsigned vece, uint32_t dofs, uint32_t aofs,
int64_t c, uint32_t oprsz, uint32_t maxsz)
{
TCGv_i64 tmp = tcg_const_i64(c);
TCGv_i64 tmp = tcg_constant_i64(c);
tcg_gen_gvec_adds(vece, dofs, aofs, tmp, oprsz, maxsz);
tcg_temp_free_i64(tmp);
}
static const TCGOpcode vecop_list_sub[] = { INDEX_op_sub_vec, 0 };
@@ -1897,16 +1882,14 @@ static void gen_subv_mask(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b, TCGv_i64 m)
void tcg_gen_vec_sub8_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
{
TCGv_i64 m = tcg_const_i64(dup_const(MO_8, 0x80));
TCGv_i64 m = tcg_constant_i64(dup_const(MO_8, 0x80));
gen_subv_mask(d, a, b, m);
tcg_temp_free_i64(m);
}
void tcg_gen_vec_sub16_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
{
TCGv_i64 m = tcg_const_i64(dup_const(MO_16, 0x8000));
TCGv_i64 m = tcg_constant_i64(dup_const(MO_16, 0x8000));
gen_subv_mask(d, a, b, m);
tcg_temp_free_i64(m);
}
void tcg_gen_vec_sub32_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
@@ -2017,9 +2000,8 @@ void tcg_gen_gvec_muls(unsigned vece, uint32_t dofs, uint32_t aofs,
void tcg_gen_gvec_muli(unsigned vece, uint32_t dofs, uint32_t aofs,
int64_t c, uint32_t oprsz, uint32_t maxsz)
{
TCGv_i64 tmp = tcg_const_i64(c);
TCGv_i64 tmp = tcg_constant_i64(c);
tcg_gen_gvec_muls(vece, dofs, aofs, tmp, oprsz, maxsz);
tcg_temp_free_i64(tmp);
}
void tcg_gen_gvec_ssadd(unsigned vece, uint32_t dofs, uint32_t aofs,
@@ -2076,18 +2058,16 @@ void tcg_gen_gvec_sssub(unsigned vece, uint32_t dofs, uint32_t aofs,
static void tcg_gen_usadd_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
{
TCGv_i32 max = tcg_const_i32(-1);
TCGv_i32 max = tcg_constant_i32(-1);
tcg_gen_add_i32(d, a, b);
tcg_gen_movcond_i32(TCG_COND_LTU, d, d, a, max, d);
tcg_temp_free_i32(max);
}
static void tcg_gen_usadd_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
{
TCGv_i64 max = tcg_const_i64(-1);
TCGv_i64 max = tcg_constant_i64(-1);
tcg_gen_add_i64(d, a, b);
tcg_gen_movcond_i64(TCG_COND_LTU, d, d, a, max, d);
tcg_temp_free_i64(max);
}
void tcg_gen_gvec_usadd(unsigned vece, uint32_t dofs, uint32_t aofs,
@@ -2120,18 +2100,16 @@ void tcg_gen_gvec_usadd(unsigned vece, uint32_t dofs, uint32_t aofs,
static void tcg_gen_ussub_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
{
TCGv_i32 min = tcg_const_i32(0);
TCGv_i32 min = tcg_constant_i32(0);
tcg_gen_sub_i32(d, a, b);
tcg_gen_movcond_i32(TCG_COND_LTU, d, a, b, min, d);
tcg_temp_free_i32(min);
}
static void tcg_gen_ussub_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
{
TCGv_i64 min = tcg_const_i64(0);
TCGv_i64 min = tcg_constant_i64(0);
tcg_gen_sub_i64(d, a, b);
tcg_gen_movcond_i64(TCG_COND_LTU, d, a, b, min, d);
tcg_temp_free_i64(min);
}
void tcg_gen_gvec_ussub(unsigned vece, uint32_t dofs, uint32_t aofs,
@@ -2292,16 +2270,14 @@ static void gen_negv_mask(TCGv_i64 d, TCGv_i64 b, TCGv_i64 m)
void tcg_gen_vec_neg8_i64(TCGv_i64 d, TCGv_i64 b)
{
TCGv_i64 m = tcg_const_i64(dup_const(MO_8, 0x80));
TCGv_i64 m = tcg_constant_i64(dup_const(MO_8, 0x80));
gen_negv_mask(d, b, m);
tcg_temp_free_i64(m);
}
void tcg_gen_vec_neg16_i64(TCGv_i64 d, TCGv_i64 b)
{
TCGv_i64 m = tcg_const_i64(dup_const(MO_16, 0x8000));
TCGv_i64 m = tcg_constant_i64(dup_const(MO_16, 0x8000));
gen_negv_mask(d, b, m);
tcg_temp_free_i64(m);
}
void tcg_gen_vec_neg32_i64(TCGv_i64 d, TCGv_i64 b)
@@ -2570,9 +2546,8 @@ void tcg_gen_gvec_ands(unsigned vece, uint32_t dofs, uint32_t aofs,
void tcg_gen_gvec_andi(unsigned vece, uint32_t dofs, uint32_t aofs,
int64_t c, uint32_t oprsz, uint32_t maxsz)
{
TCGv_i64 tmp = tcg_const_i64(dup_const(vece, c));
TCGv_i64 tmp = tcg_constant_i64(dup_const(vece, c));
tcg_gen_gvec_2s(dofs, aofs, oprsz, maxsz, tmp, &gop_ands);
tcg_temp_free_i64(tmp);
}
static const GVecGen2s gop_xors = {
@@ -2595,9 +2570,8 @@ void tcg_gen_gvec_xors(unsigned vece, uint32_t dofs, uint32_t aofs,
void tcg_gen_gvec_xori(unsigned vece, uint32_t dofs, uint32_t aofs,
int64_t c, uint32_t oprsz, uint32_t maxsz)
{
TCGv_i64 tmp = tcg_const_i64(dup_const(vece, c));
TCGv_i64 tmp = tcg_constant_i64(dup_const(vece, c));
tcg_gen_gvec_2s(dofs, aofs, oprsz, maxsz, tmp, &gop_xors);
tcg_temp_free_i64(tmp);
}
static const GVecGen2s gop_ors = {
@@ -2620,9 +2594,8 @@ void tcg_gen_gvec_ors(unsigned vece, uint32_t dofs, uint32_t aofs,
void tcg_gen_gvec_ori(unsigned vece, uint32_t dofs, uint32_t aofs,
int64_t c, uint32_t oprsz, uint32_t maxsz)
{
TCGv_i64 tmp = tcg_const_i64(dup_const(vece, c));
TCGv_i64 tmp = tcg_constant_i64(dup_const(vece, c));
tcg_gen_gvec_2s(dofs, aofs, oprsz, maxsz, tmp, &gop_ors);
tcg_temp_free_i64(tmp);
}
void tcg_gen_vec_shl8i_i64(TCGv_i64 d, TCGv_i64 a, int64_t c)
@@ -3110,9 +3083,9 @@ static void tcg_gen_shlv_mod_vec(unsigned vece, TCGv_vec d,
TCGv_vec a, TCGv_vec b)
{
TCGv_vec t = tcg_temp_new_vec_matching(d);
TCGv_vec m = tcg_constant_vec_matching(d, vece, (8 << vece) - 1);
tcg_gen_dupi_vec(vece, t, (8 << vece) - 1);
tcg_gen_and_vec(vece, t, t, b);
tcg_gen_and_vec(vece, t, b, m);
tcg_gen_shlv_vec(vece, d, a, t);
tcg_temp_free_vec(t);
}
@@ -3173,9 +3146,9 @@ static void tcg_gen_shrv_mod_vec(unsigned vece, TCGv_vec d,
TCGv_vec a, TCGv_vec b)
{
TCGv_vec t = tcg_temp_new_vec_matching(d);
TCGv_vec m = tcg_constant_vec_matching(d, vece, (8 << vece) - 1);
tcg_gen_dupi_vec(vece, t, (8 << vece) - 1);
tcg_gen_and_vec(vece, t, t, b);
tcg_gen_and_vec(vece, t, b, m);
tcg_gen_shrv_vec(vece, d, a, t);
tcg_temp_free_vec(t);
}
@@ -3236,9 +3209,9 @@ static void tcg_gen_sarv_mod_vec(unsigned vece, TCGv_vec d,
TCGv_vec a, TCGv_vec b)
{
TCGv_vec t = tcg_temp_new_vec_matching(d);
TCGv_vec m = tcg_constant_vec_matching(d, vece, (8 << vece) - 1);
tcg_gen_dupi_vec(vece, t, (8 << vece) - 1);
tcg_gen_and_vec(vece, t, t, b);
tcg_gen_and_vec(vece, t, b, m);
tcg_gen_sarv_vec(vece, d, a, t);
tcg_temp_free_vec(t);
}
@@ -3299,9 +3272,9 @@ static void tcg_gen_rotlv_mod_vec(unsigned vece, TCGv_vec d,
TCGv_vec a, TCGv_vec b)
{
TCGv_vec t = tcg_temp_new_vec_matching(d);
TCGv_vec m = tcg_constant_vec_matching(d, vece, (8 << vece) - 1);
tcg_gen_dupi_vec(vece, t, (8 << vece) - 1);
tcg_gen_and_vec(vece, t, t, b);
tcg_gen_and_vec(vece, t, b, m);
tcg_gen_rotlv_vec(vece, d, a, t);
tcg_temp_free_vec(t);
}
@@ -3358,9 +3331,9 @@ static void tcg_gen_rotrv_mod_vec(unsigned vece, TCGv_vec d,
TCGv_vec a, TCGv_vec b)
{
TCGv_vec t = tcg_temp_new_vec_matching(d);
TCGv_vec m = tcg_constant_vec_matching(d, vece, (8 << vece) - 1);
tcg_gen_dupi_vec(vece, t, (8 << vece) - 1);
tcg_gen_and_vec(vece, t, t, b);
tcg_gen_and_vec(vece, t, b, m);
tcg_gen_rotrv_vec(vece, d, a, t);
tcg_temp_free_vec(t);
}
+6 -46
View File
@@ -83,7 +83,6 @@ bool tcg_can_emit_vecop_list(const TCGOpcode *list,
case INDEX_op_xor_vec:
case INDEX_op_mov_vec:
case INDEX_op_dup_vec:
case INDEX_op_dupi_vec:
case INDEX_op_dup2_vec:
case INDEX_op_ld_vec:
case INDEX_op_st_vec:
@@ -216,25 +215,17 @@ void tcg_gen_mov_vec(TCGv_vec r, TCGv_vec a)
}
}
#define MO_REG (TCG_TARGET_REG_BITS == 64 ? MO_64 : MO_32)
static void do_dupi_vec(TCGv_vec r, unsigned vece, TCGArg a)
{
TCGTemp *rt = tcgv_vec_temp(r);
vec_gen_2(INDEX_op_dupi_vec, rt->base_type, vece, temp_arg(rt), a);
}
TCGv_vec tcg_const_zeros_vec(TCGType type)
{
TCGv_vec ret = tcg_temp_new_vec(type);
do_dupi_vec(ret, MO_REG, 0);
tcg_gen_dupi_vec(MO_64, ret, 0);
return ret;
}
TCGv_vec tcg_const_ones_vec(TCGType type)
{
TCGv_vec ret = tcg_temp_new_vec(type);
do_dupi_vec(ret, MO_REG, -1);
tcg_gen_dupi_vec(MO_64, ret, -1);
return ret;
}
@@ -250,41 +241,10 @@ TCGv_vec tcg_const_ones_vec_matching(TCGv_vec m)
return tcg_const_ones_vec(t->base_type);
}
void tcg_gen_dup64i_vec(TCGv_vec r, uint64_t a)
{
if (TCG_TARGET_REG_BITS == 64) {
do_dupi_vec(r, MO_64, a);
} else if (a == dup_const(MO_32, a)) {
do_dupi_vec(r, MO_32, a);
} else {
TCGv_i64 c = tcg_const_i64(a);
tcg_gen_dup_i64_vec(MO_64, r, c);
tcg_temp_free_i64(c);
}
}
void tcg_gen_dup32i_vec(TCGv_vec r, uint32_t a)
{
do_dupi_vec(r, MO_REG, dup_const(MO_32, a));
}
void tcg_gen_dup16i_vec(TCGv_vec r, uint32_t a)
{
do_dupi_vec(r, MO_REG, dup_const(MO_16, a));
}
void tcg_gen_dup8i_vec(TCGv_vec r, uint32_t a)
{
do_dupi_vec(r, MO_REG, dup_const(MO_8, a));
}
void tcg_gen_dupi_vec(unsigned vece, TCGv_vec r, uint64_t a)
{
if (vece == MO_64) {
tcg_gen_dup64i_vec(r, a);
} else {
do_dupi_vec(r, MO_REG, dup_const(vece, a));
}
TCGTemp *rt = tcgv_vec_temp(r);
tcg_gen_mov_vec(r, tcg_constant_vec(rt->base_type, vece, a));
}
void tcg_gen_dup_i64_vec(unsigned vece, TCGv_vec r, TCGv_i64 a)
@@ -489,8 +449,8 @@ void tcg_gen_abs_vec(unsigned vece, TCGv_vec r, TCGv_vec a)
if (tcg_can_emit_vec_op(INDEX_op_sari_vec, type, vece) > 0) {
tcg_gen_sari_vec(vece, t, a, (8 << vece) - 1);
} else {
do_dupi_vec(t, MO_REG, 0);
tcg_gen_cmp_vec(TCG_COND_LT, vece, t, a, t);
tcg_gen_cmp_vec(TCG_COND_LT, vece, t, a,
tcg_constant_vec(type, vece, 0));
}
tcg_gen_xor_vec(vece, r, a, t);
tcg_gen_sub_vec(vece, r, r, t);
+107 -120
View File
File diff suppressed because it is too large Load Diff
+376 -112
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -593,7 +593,7 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
t1 = tci_read_r32(regs, &tb_ptr);
tci_write_reg32(regs, t0, t1);
break;
case INDEX_op_movi_i32:
case INDEX_op_tci_movi_i32:
t0 = *tb_ptr++;
t1 = tci_read_i32(&tb_ptr);
tci_write_reg32(regs, t0, t1);
@@ -864,7 +864,7 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
t1 = tci_read_r64(regs, &tb_ptr);
tci_write_reg64(regs, t0, t1);
break;
case INDEX_op_movi_i64:
case INDEX_op_tci_movi_i64:
t0 = *tb_ptr++;
t1 = tci_read_i64(&tb_ptr);
tci_write_reg64(regs, t0, t1);

Some files were not shown because too many files have changed in this diff Show More