- Add TCGOP_TYPE, TCGOP_FLAGS.
   - Pass type and flags to tcg_op_supported, tcg_target_op_def.
   - Split out tcg-target-has.h and unexport from tcg.h.
   - Reorg constraint processing; constify TCGOpDef.
   - Make extract, sextract, deposit opcodes mandatory.
   - Merge ext{8,16,32}{s,u} opcodes into {s}extract.
 tcg/mips: Expand bswap unconditionally
 tcg/riscv: Use SRAIW, SRLIW for {s}extract_i64
 tcg/riscv: Use BEXTI for single-bit extractions
 tcg/sparc64: Use SRA, SRL for {s}extract_i64
 
 disas/riscv: Guard dec->cfg dereference for host disassemble
 util/cpuinfo-riscv: Detect Zbs
 accel/tcg: Call tcg_tb_insert() for one-insn TBs
 linux-user: Add missing /proc/cpuinfo fields for sparc
 -----BEGIN PGP SIGNATURE-----
 
 iQFRBAABCgA7FiEEekgeeIaLTbaoWgXAZN846K9+IV8FAmeKnzUdHHJpY2hhcmQu
 aGVuZGVyc29uQGxpbmFyby5vcmcACgkQZN846K9+IV+Kvgf+LG9UjXlWF9GK923E
 TllBL2rLf1OOdtTXWO15VcvGMoWDwB3tVBdhihdvXmnWju+WbfMk6mct5NhzsKn9
 LmuugMIZs+hMROj+bgMK8x47jRIh5N2rDYxcEgmyfIpYb2o9qvyqKecGVRlSJTCE
 bmt5UFbvPThBb8upoMfq3F6evuMx0szBP7wrOwSR/VGpmzIr20UTEWo6I1ALp4uj
 paFaysYol4em3dIhkiuV9cL7E0EIObaNa7l9RUci/BmTq+JaVxUnW1Y2i0PEwKwG
 FJSfYTJk3wBgAVxC2zC2g3ZM7uKuecSXMpiFopTiuyQLp7Q61i9kCNvEq0qY5tdb
 DaqR/g==
 =cv4O
 -----END PGP SIGNATURE-----

Merge tag 'pull-tcg-20250117' of https://gitlab.com/rth7680/qemu into staging

tcg:
  - Add TCGOP_TYPE, TCGOP_FLAGS.
  - Pass type and flags to tcg_op_supported, tcg_target_op_def.
  - Split out tcg-target-has.h and unexport from tcg.h.
  - Reorg constraint processing; constify TCGOpDef.
  - Make extract, sextract, deposit opcodes mandatory.
  - Merge ext{8,16,32}{s,u} opcodes into {s}extract.
tcg/mips: Expand bswap unconditionally
tcg/riscv: Use SRAIW, SRLIW for {s}extract_i64
tcg/riscv: Use BEXTI for single-bit extractions
tcg/sparc64: Use SRA, SRL for {s}extract_i64

disas/riscv: Guard dec->cfg dereference for host disassemble
util/cpuinfo-riscv: Detect Zbs
accel/tcg: Call tcg_tb_insert() for one-insn TBs
linux-user: Add missing /proc/cpuinfo fields for sparc

# -----BEGIN PGP SIGNATURE-----
#
# iQFRBAABCgA7FiEEekgeeIaLTbaoWgXAZN846K9+IV8FAmeKnzUdHHJpY2hhcmQu
# aGVuZGVyc29uQGxpbmFyby5vcmcACgkQZN846K9+IV+Kvgf+LG9UjXlWF9GK923E
# TllBL2rLf1OOdtTXWO15VcvGMoWDwB3tVBdhihdvXmnWju+WbfMk6mct5NhzsKn9
# LmuugMIZs+hMROj+bgMK8x47jRIh5N2rDYxcEgmyfIpYb2o9qvyqKecGVRlSJTCE
# bmt5UFbvPThBb8upoMfq3F6evuMx0szBP7wrOwSR/VGpmzIr20UTEWo6I1ALp4uj
# paFaysYol4em3dIhkiuV9cL7E0EIObaNa7l9RUci/BmTq+JaVxUnW1Y2i0PEwKwG
# FJSfYTJk3wBgAVxC2zC2g3ZM7uKuecSXMpiFopTiuyQLp7Q61i9kCNvEq0qY5tdb
# DaqR/g==
# =cv4O
# -----END PGP SIGNATURE-----
# gpg: Signature made Fri 17 Jan 2025 13:19:33 EST
# 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

* tag 'pull-tcg-20250117' of https://gitlab.com/rth7680/qemu: (68 commits)
  softfloat: Constify helpers returning float_status field
  accel/tcg: Call tcg_tb_insert() for one-insn TBs
  tcg: Document tb_lookup() and tcg_tb_lookup()
  linux-user: Add missing /proc/cpuinfo fields for sparc
  tcg/riscv: Use BEXTI for single-bit extractions
  util/cpuinfo-riscv: Detect Zbs
  tcg: Remove TCG_TARGET_HAS_deposit_{i32,i64}
  tcg: Remove TCG_TARGET_HAS_{s}extract_{i32,i64}
  tcg/tci: Remove assertions for deposit and extract
  tcg/tci: Provide TCG_TARGET_{s}extract_valid
  tcg/sparc64: Use SRA, SRL for {s}extract_i64
  tcg/s390x: Fold the ext{8,16,32}[us] cases into {s}extract
  tcg/riscv: Use SRAIW, SRLIW for {s}extract_i64
  tcg/riscv64: Fold the ext{8,16,32}[us] cases into {s}extract
  tcg/ppc: Fold the ext{8,16,32}[us] cases into {s}extract
  tcg/mips: Fold the ext{8,16,32}[us] cases into {s}extract
  tcg/loongarch64: Fold the ext{8,16,32}[us] cases into {s}extract
  tcg/arm: Add full [US]XT[BH] into {s}extract
  tcg/aarch64: Expand extract with offset 0 with andi
  tcg/aarch64: Provide TCG_TARGET_{s}extract_valid
  ...

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
Stefan Hajnoczi 2025-01-21 08:27:20 -05:00
commit 32a97c5d05
78 changed files with 2856 additions and 2269 deletions

View file

@ -249,7 +249,20 @@ static TranslationBlock *tb_htable_lookup(CPUState *cpu, vaddr pc,
return qht_lookup_custom(&tb_ctx.htable, &desc, h, tb_lookup_cmp);
}
/* Might cause an exception, so have a longjmp destination ready */
/**
* tb_lookup:
* @cpu: CPU that will execute the returned translation block
* @pc: guest PC
* @cs_base: arch-specific value associated with translation block
* @flags: arch-specific translation block flags
* @cflags: CF_* flags
*
* Look up a translation block inside the QHT using @pc, @cs_base, @flags and
* @cflags. Uses @cpu's tb_jmp_cache. Might cause an exception, so have a
* longjmp destination ready.
*
* Returns: an existing translation block or NULL.
*/
static inline TranslationBlock *tb_lookup(CPUState *cpu, vaddr pc,
uint64_t cs_base, uint32_t flags,
uint32_t cflags)

View file

@ -12,6 +12,7 @@
#include "exec/exec-all.h"
#include "exec/translation-block.h"
#include "tb-internal.h"
#include "tcg-target-mo.h"
/*
* Access to the various translations structures need to be serialised

View file

@ -531,16 +531,6 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
tb_reset_jump(tb, 1);
}
/*
* If the TB is not associated with a physical RAM page then it must be
* a temporary one-insn TB, and we have nothing left to do. Return early
* before attempting to link to other TBs or add to the lookup table.
*/
if (tb_page_addr0(tb) == -1) {
assert_no_pages_locked();
return tb;
}
/*
* Insert TB into the corresponding region tree before publishing it
* through QHT. Otherwise rewinding happened in the TB might fail to
@ -548,6 +538,25 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
*/
tcg_tb_insert(tb);
/*
* If the TB is not associated with a physical RAM page then it must be
* a temporary one-insn TB.
*
* Such TBs must be added to region trees in order to make sure that
* restore_state_to_opc() - which on some architectures is not limited to
* rewinding, but also affects exception handling! - is called when such a
* TB causes an exception.
*
* At the same time, temporary one-insn TBs must be executed at most once,
* because subsequent reads from, e.g., I/O memory may return different
* values. So return early before attempting to link to other TBs or add
* to the QHT.
*/
if (tb_page_addr0(tb) == -1) {
assert_no_pages_locked();
return tb;
}
/*
* No explicit memory barrier is required -- tb_link_page() makes the
* TB visible in a consistent state.

View file

@ -2611,7 +2611,7 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
break;
case 2: op = rv_op_c_li; break;
case 3:
if (dec->cfg->ext_zcmop) {
if (dec->cfg && dec->cfg->ext_zcmop) {
if ((((inst >> 2) & 0b111111) == 0b100000) &&
(((inst >> 11) & 0b11) == 0b0)) {
unsigned int cmop_code = 0;
@ -2712,7 +2712,7 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
op = rv_op_c_sqsp;
} else {
op = rv_op_c_fsdsp;
if (dec->cfg->ext_zcmp && ((inst >> 12) & 0b01)) {
if (dec->cfg && dec->cfg->ext_zcmp && ((inst >> 12) & 0b01)) {
switch ((inst >> 8) & 0b01111) {
case 8:
if (((inst >> 4) & 0b01111) >= 4) {
@ -2738,7 +2738,7 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
} else {
switch ((inst >> 10) & 0b011) {
case 0:
if (!dec->cfg->ext_zcmt) {
if (dec->cfg && !dec->cfg->ext_zcmt) {
break;
}
if (((inst >> 2) & 0xFF) >= 32) {
@ -2748,7 +2748,7 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
}
break;
case 3:
if (!dec->cfg->ext_zcmp) {
if (dec->cfg && !dec->cfg->ext_zcmp) {
break;
}
switch ((inst >> 5) & 0b011) {
@ -2956,7 +2956,7 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
break;
case 5:
op = rv_op_auipc;
if (dec->cfg->ext_zicfilp &&
if (dec->cfg && dec->cfg->ext_zicfilp &&
(((inst >> 7) & 0b11111) == 0b00000)) {
op = rv_op_lpad;
}
@ -4058,7 +4058,7 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
case 2: op = rv_op_csrrs; break;
case 3: op = rv_op_csrrc; break;
case 4:
if (dec->cfg->ext_zimop) {
if (dec->cfg && dec->cfg->ext_zimop) {
int imm_mop5, imm_mop3, reg_num;
if ((extract32(inst, 22, 10) & 0b1011001111)
== 0b1000000111) {
@ -5112,28 +5112,28 @@ static GString *format_inst(size_t tab, rv_decode *dec)
g_string_append(buf, rv_ireg_name_sym[dec->rs2]);
break;
case '3':
if (dec->cfg->ext_zfinx) {
if (dec->cfg && dec->cfg->ext_zfinx) {
g_string_append(buf, rv_ireg_name_sym[dec->rd]);
} else {
g_string_append(buf, rv_freg_name_sym[dec->rd]);
}
break;
case '4':
if (dec->cfg->ext_zfinx) {
if (dec->cfg && dec->cfg->ext_zfinx) {
g_string_append(buf, rv_ireg_name_sym[dec->rs1]);
} else {
g_string_append(buf, rv_freg_name_sym[dec->rs1]);
}
break;
case '5':
if (dec->cfg->ext_zfinx) {
if (dec->cfg && dec->cfg->ext_zfinx) {
g_string_append(buf, rv_ireg_name_sym[dec->rs2]);
} else {
g_string_append(buf, rv_freg_name_sym[dec->rs2]);
}
break;
case '6':
if (dec->cfg->ext_zfinx) {
if (dec->cfg && dec->cfg->ext_zfinx) {
g_string_append(buf, rv_ireg_name_sym[dec->rs3]);
} else {
g_string_append(buf, rv_freg_name_sym[dec->rs3]);
@ -5439,7 +5439,8 @@ static GString *disasm_inst(rv_isa isa, uint64_t pc, rv_inst inst,
const rv_opcode_data *opcode_data = decoders[i].opcode_data;
void (*decode_func)(rv_decode *, rv_isa) = decoders[i].decode_func;
if (guard_func(cfg)) {
/* always_true_p don't dereference cfg */
if (((i == 0) || cfg) && guard_func(cfg)) {
dec.opcode_data = opcode_data;
decode_func(&dec, isa);
if (dec.op != rv_op_illegal)

View file

@ -712,10 +712,9 @@ QEMU specific operations
Host vector operations
----------------------
All of the vector ops have two parameters, ``TCGOP_VECL`` & ``TCGOP_VECE``.
The former specifies the length of the vector in log2 64-bit units; the
latter specifies the length of the element (if applicable) in log2 8-bit units.
E.g. VECL = 1 -> 64 << 1 -> v128, and VECE = 2 -> 1 << 2 -> i32.
All of the vector ops have two parameters, ``TCGOP_TYPE`` & ``TCGOP_VECE``.
The former specifies the length of the vector as a TCGType; the latter
specifies the length of the element (if applicable) in log2 8-bit units.
.. list-table::
@ -729,7 +728,7 @@ E.g. VECL = 1 -> 64 << 1 -> v128, and VECE = 2 -> 1 << 2 -> i32.
* - dup_vec *v0*, *r1*
- | Duplicate the low N bits of *r1* into VECL/VECE copies across *v0*.
- | Duplicate the low N bits of *r1* into TYPE/VECE copies across *v0*.
* - dupi_vec *v0*, *c*
@ -738,7 +737,7 @@ E.g. VECL = 1 -> 64 << 1 -> v128, and VECE = 2 -> 1 << 2 -> i32.
* - dup2_vec *v0*, *r1*, *r2*
- | Duplicate *r2*:*r1* into VECL/64 copies across *v0*. This opcode is
- | Duplicate *r2*:*r1* into TYPE/64 copies across *v0*. This opcode is
only present for 32-bit hosts.
* - add_vec *v0*, *v1*, *v2*
@ -810,7 +809,7 @@ E.g. VECL = 1 -> 64 << 1 -> v128, and VECE = 2 -> 1 << 2 -> i32.
.. code-block:: c
for (i = 0; i < VECL/VECE; ++i) {
for (i = 0; i < TYPE/VECE; ++i) {
v0[i] = v1[i] << s2;
}
@ -832,7 +831,7 @@ E.g. VECL = 1 -> 64 << 1 -> v128, and VECE = 2 -> 1 << 2 -> i32.
.. code-block:: c
for (i = 0; i < VECL/VECE; ++i) {
for (i = 0; i < TYPE/VECE; ++i) {
v0[i] = v1[i] << v2[i];
}

View file

@ -9,8 +9,9 @@
#define CPUINFO_ALWAYS (1u << 0) /* so cpuinfo is nonzero */
#define CPUINFO_ZBA (1u << 1)
#define CPUINFO_ZBB (1u << 2)
#define CPUINFO_ZICOND (1u << 3)
#define CPUINFO_ZVE64X (1u << 4)
#define CPUINFO_ZBS (1u << 3)
#define CPUINFO_ZICOND (1u << 4)
#define CPUINFO_ZVE64X (1u << 5)
/* Initialized with a constructor. */
extern unsigned cpuinfo;

View file

@ -124,58 +124,61 @@ static inline void set_no_signaling_nans(bool val, float_status *status)
status->no_signaling_nans = val;
}
static inline bool get_float_detect_tininess(float_status *status)
static inline bool get_float_detect_tininess(const float_status *status)
{
return status->tininess_before_rounding;
}
static inline FloatRoundMode get_float_rounding_mode(float_status *status)
static inline FloatRoundMode get_float_rounding_mode(const float_status *status)
{
return status->float_rounding_mode;
}
static inline int get_float_exception_flags(float_status *status)
static inline int get_float_exception_flags(const float_status *status)
{
return status->float_exception_flags;
}
static inline FloatX80RoundPrec
get_floatx80_rounding_precision(float_status *status)
get_floatx80_rounding_precision(const float_status *status)
{
return status->floatx80_rounding_precision;
}
static inline Float2NaNPropRule get_float_2nan_prop_rule(float_status *status)
static inline Float2NaNPropRule
get_float_2nan_prop_rule(const float_status *status)
{
return status->float_2nan_prop_rule;
}
static inline Float3NaNPropRule get_float_3nan_prop_rule(float_status *status)
static inline Float3NaNPropRule
get_float_3nan_prop_rule(const float_status *status)
{
return status->float_3nan_prop_rule;
}
static inline FloatInfZeroNaNRule get_float_infzeronan_rule(float_status *status)
static inline FloatInfZeroNaNRule
get_float_infzeronan_rule(const float_status *status)
{
return status->float_infzeronan_rule;
}
static inline uint8_t get_float_default_nan_pattern(float_status *status)
static inline uint8_t get_float_default_nan_pattern(const float_status *status)
{
return status->default_nan_pattern;
}
static inline bool get_flush_to_zero(float_status *status)
static inline bool get_flush_to_zero(const float_status *status)
{
return status->flush_to_zero;
}
static inline bool get_flush_inputs_to_zero(float_status *status)
static inline bool get_flush_inputs_to_zero(const float_status *status)
{
return status->flush_inputs_to_zero;
}
static inline bool get_default_nan_mode(float_status *status)
static inline bool get_default_nan_mode(const float_status *status)
{
return status->default_nan_mode;
}

View file

@ -33,20 +33,13 @@ DEF(set_label, 0, 0, 1, TCG_OPF_BB_END | TCG_OPF_NOT_PRESENT)
/* variable number of parameters */
DEF(call, 0, 0, 3, TCG_OPF_CALL_CLOBBER | TCG_OPF_NOT_PRESENT)
DEF(br, 0, 0, 1, TCG_OPF_BB_END)
DEF(br, 0, 0, 1, TCG_OPF_BB_END | TCG_OPF_NOT_PRESENT)
#define IMPL(X) (__builtin_constant_p(X) && (X) <= 0 ? TCG_OPF_NOT_PRESENT : 0)
#if TCG_TARGET_REG_BITS == 32
# define IMPL64 TCG_OPF_64BIT | TCG_OPF_NOT_PRESENT
#else
# define IMPL64 TCG_OPF_64BIT
#endif
DEF(mb, 0, 0, 1, 0)
DEF(mb, 0, 0, 1, TCG_OPF_NOT_PRESENT)
DEF(mov_i32, 1, 1, 0, TCG_OPF_NOT_PRESENT)
DEF(setcond_i32, 1, 2, 1, 0)
DEF(negsetcond_i32, 1, 2, 1, IMPL(TCG_TARGET_HAS_negsetcond_i32))
DEF(negsetcond_i32, 1, 2, 1, 0)
DEF(movcond_i32, 1, 4, 1, 0)
/* load/store */
DEF(ld8u_i32, 1, 1, 1, 0)
@ -61,12 +54,12 @@ DEF(st_i32, 0, 2, 1, 0)
DEF(add_i32, 1, 2, 0, 0)
DEF(sub_i32, 1, 2, 0, 0)
DEF(mul_i32, 1, 2, 0, 0)
DEF(div_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_div_i32))
DEF(divu_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_div_i32))
DEF(rem_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_rem_i32))
DEF(remu_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_rem_i32))
DEF(div2_i32, 2, 3, 0, IMPL(TCG_TARGET_HAS_div2_i32))
DEF(divu2_i32, 2, 3, 0, IMPL(TCG_TARGET_HAS_div2_i32))
DEF(div_i32, 1, 2, 0, 0)
DEF(divu_i32, 1, 2, 0, 0)
DEF(rem_i32, 1, 2, 0, 0)
DEF(remu_i32, 1, 2, 0, 0)
DEF(div2_i32, 2, 3, 0, 0)
DEF(divu2_i32, 2, 3, 0, 0)
DEF(and_i32, 1, 2, 0, 0)
DEF(or_i32, 1, 2, 0, 0)
DEF(xor_i32, 1, 2, 0, 0)
@ -74,127 +67,122 @@ DEF(xor_i32, 1, 2, 0, 0)
DEF(shl_i32, 1, 2, 0, 0)
DEF(shr_i32, 1, 2, 0, 0)
DEF(sar_i32, 1, 2, 0, 0)
DEF(rotl_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_rot_i32))
DEF(rotr_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_rot_i32))
DEF(deposit_i32, 1, 2, 2, IMPL(TCG_TARGET_HAS_deposit_i32))
DEF(extract_i32, 1, 1, 2, IMPL(TCG_TARGET_HAS_extract_i32))
DEF(sextract_i32, 1, 1, 2, IMPL(TCG_TARGET_HAS_sextract_i32))
DEF(extract2_i32, 1, 2, 1, IMPL(TCG_TARGET_HAS_extract2_i32))
DEF(rotl_i32, 1, 2, 0, 0)
DEF(rotr_i32, 1, 2, 0, 0)
DEF(deposit_i32, 1, 2, 2, 0)
DEF(extract_i32, 1, 1, 2, 0)
DEF(sextract_i32, 1, 1, 2, 0)
DEF(extract2_i32, 1, 2, 1, 0)
DEF(brcond_i32, 0, 2, 2, TCG_OPF_BB_END | TCG_OPF_COND_BRANCH)
DEF(add2_i32, 2, 4, 0, IMPL(TCG_TARGET_HAS_add2_i32))
DEF(sub2_i32, 2, 4, 0, IMPL(TCG_TARGET_HAS_sub2_i32))
DEF(mulu2_i32, 2, 2, 0, IMPL(TCG_TARGET_HAS_mulu2_i32))
DEF(muls2_i32, 2, 2, 0, IMPL(TCG_TARGET_HAS_muls2_i32))
DEF(muluh_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_muluh_i32))
DEF(mulsh_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_mulsh_i32))
DEF(brcond2_i32, 0, 4, 2,
TCG_OPF_BB_END | TCG_OPF_COND_BRANCH | IMPL(TCG_TARGET_REG_BITS == 32))
DEF(setcond2_i32, 1, 4, 1, IMPL(TCG_TARGET_REG_BITS == 32))
DEF(add2_i32, 2, 4, 0, 0)
DEF(sub2_i32, 2, 4, 0, 0)
DEF(mulu2_i32, 2, 2, 0, 0)
DEF(muls2_i32, 2, 2, 0, 0)
DEF(muluh_i32, 1, 2, 0, 0)
DEF(mulsh_i32, 1, 2, 0, 0)
DEF(brcond2_i32, 0, 4, 2, TCG_OPF_BB_END | TCG_OPF_COND_BRANCH)
DEF(setcond2_i32, 1, 4, 1, 0)
DEF(ext8s_i32, 1, 1, 0, IMPL(TCG_TARGET_HAS_ext8s_i32))
DEF(ext16s_i32, 1, 1, 0, IMPL(TCG_TARGET_HAS_ext16s_i32))
DEF(ext8u_i32, 1, 1, 0, IMPL(TCG_TARGET_HAS_ext8u_i32))
DEF(ext16u_i32, 1, 1, 0, IMPL(TCG_TARGET_HAS_ext16u_i32))
DEF(bswap16_i32, 1, 1, 1, IMPL(TCG_TARGET_HAS_bswap16_i32))
DEF(bswap32_i32, 1, 1, 1, IMPL(TCG_TARGET_HAS_bswap32_i32))
DEF(not_i32, 1, 1, 0, IMPL(TCG_TARGET_HAS_not_i32))
DEF(ext8s_i32, 1, 1, 0, 0)
DEF(ext16s_i32, 1, 1, 0, 0)
DEF(ext8u_i32, 1, 1, 0, 0)
DEF(ext16u_i32, 1, 1, 0, 0)
DEF(bswap16_i32, 1, 1, 1, 0)
DEF(bswap32_i32, 1, 1, 1, 0)
DEF(not_i32, 1, 1, 0, 0)
DEF(neg_i32, 1, 1, 0, 0)
DEF(andc_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_andc_i32))
DEF(orc_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_orc_i32))
DEF(eqv_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_eqv_i32))
DEF(nand_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_nand_i32))
DEF(nor_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_nor_i32))
DEF(clz_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_clz_i32))
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(andc_i32, 1, 2, 0, 0)
DEF(orc_i32, 1, 2, 0, 0)
DEF(eqv_i32, 1, 2, 0, 0)
DEF(nand_i32, 1, 2, 0, 0)
DEF(nor_i32, 1, 2, 0, 0)
DEF(clz_i32, 1, 2, 0, 0)
DEF(ctz_i32, 1, 2, 0, 0)
DEF(ctpop_i32, 1, 1, 0, 0)
DEF(mov_i64, 1, 1, 0, TCG_OPF_64BIT | TCG_OPF_NOT_PRESENT)
DEF(setcond_i64, 1, 2, 1, IMPL64)
DEF(negsetcond_i64, 1, 2, 1, IMPL64 | IMPL(TCG_TARGET_HAS_negsetcond_i64))
DEF(movcond_i64, 1, 4, 1, IMPL64)
DEF(mov_i64, 1, 1, 0, TCG_OPF_NOT_PRESENT)
DEF(setcond_i64, 1, 2, 1, 0)
DEF(negsetcond_i64, 1, 2, 1, 0)
DEF(movcond_i64, 1, 4, 1, 0)
/* load/store */
DEF(ld8u_i64, 1, 1, 1, IMPL64)
DEF(ld8s_i64, 1, 1, 1, IMPL64)
DEF(ld16u_i64, 1, 1, 1, IMPL64)
DEF(ld16s_i64, 1, 1, 1, IMPL64)
DEF(ld32u_i64, 1, 1, 1, IMPL64)
DEF(ld32s_i64, 1, 1, 1, IMPL64)
DEF(ld_i64, 1, 1, 1, IMPL64)
DEF(st8_i64, 0, 2, 1, IMPL64)
DEF(st16_i64, 0, 2, 1, IMPL64)
DEF(st32_i64, 0, 2, 1, IMPL64)
DEF(st_i64, 0, 2, 1, IMPL64)
DEF(ld8u_i64, 1, 1, 1, 0)
DEF(ld8s_i64, 1, 1, 1, 0)
DEF(ld16u_i64, 1, 1, 1, 0)
DEF(ld16s_i64, 1, 1, 1, 0)
DEF(ld32u_i64, 1, 1, 1, 0)
DEF(ld32s_i64, 1, 1, 1, 0)
DEF(ld_i64, 1, 1, 1, 0)
DEF(st8_i64, 0, 2, 1, 0)
DEF(st16_i64, 0, 2, 1, 0)
DEF(st32_i64, 0, 2, 1, 0)
DEF(st_i64, 0, 2, 1, 0)
/* arith */
DEF(add_i64, 1, 2, 0, IMPL64)
DEF(sub_i64, 1, 2, 0, IMPL64)
DEF(mul_i64, 1, 2, 0, IMPL64)
DEF(div_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_div_i64))
DEF(divu_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_div_i64))
DEF(rem_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_rem_i64))
DEF(remu_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_rem_i64))
DEF(div2_i64, 2, 3, 0, IMPL64 | IMPL(TCG_TARGET_HAS_div2_i64))
DEF(divu2_i64, 2, 3, 0, IMPL64 | IMPL(TCG_TARGET_HAS_div2_i64))
DEF(and_i64, 1, 2, 0, IMPL64)
DEF(or_i64, 1, 2, 0, IMPL64)
DEF(xor_i64, 1, 2, 0, IMPL64)
DEF(add_i64, 1, 2, 0, 0)
DEF(sub_i64, 1, 2, 0, 0)
DEF(mul_i64, 1, 2, 0, 0)
DEF(div_i64, 1, 2, 0, 0)
DEF(divu_i64, 1, 2, 0, 0)
DEF(rem_i64, 1, 2, 0, 0)
DEF(remu_i64, 1, 2, 0, 0)
DEF(div2_i64, 2, 3, 0, 0)
DEF(divu2_i64, 2, 3, 0, 0)
DEF(and_i64, 1, 2, 0, 0)
DEF(or_i64, 1, 2, 0, 0)
DEF(xor_i64, 1, 2, 0, 0)
/* shifts/rotates */
DEF(shl_i64, 1, 2, 0, IMPL64)
DEF(shr_i64, 1, 2, 0, IMPL64)
DEF(sar_i64, 1, 2, 0, IMPL64)
DEF(rotl_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_rot_i64))
DEF(rotr_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_rot_i64))
DEF(deposit_i64, 1, 2, 2, IMPL64 | IMPL(TCG_TARGET_HAS_deposit_i64))
DEF(extract_i64, 1, 1, 2, IMPL64 | IMPL(TCG_TARGET_HAS_extract_i64))
DEF(sextract_i64, 1, 1, 2, IMPL64 | IMPL(TCG_TARGET_HAS_sextract_i64))
DEF(extract2_i64, 1, 2, 1, IMPL64 | IMPL(TCG_TARGET_HAS_extract2_i64))
DEF(shl_i64, 1, 2, 0, 0)
DEF(shr_i64, 1, 2, 0, 0)
DEF(sar_i64, 1, 2, 0, 0)
DEF(rotl_i64, 1, 2, 0, 0)
DEF(rotr_i64, 1, 2, 0, 0)
DEF(deposit_i64, 1, 2, 2, 0)
DEF(extract_i64, 1, 1, 2, 0)
DEF(sextract_i64, 1, 1, 2, 0)
DEF(extract2_i64, 1, 2, 1, 0)
/* size changing ops */
DEF(ext_i32_i64, 1, 1, 0, IMPL64)
DEF(extu_i32_i64, 1, 1, 0, IMPL64)
DEF(extrl_i64_i32, 1, 1, 0,
IMPL(TCG_TARGET_HAS_extr_i64_i32)
| (TCG_TARGET_REG_BITS == 32 ? TCG_OPF_NOT_PRESENT : 0))
DEF(extrh_i64_i32, 1, 1, 0,
IMPL(TCG_TARGET_HAS_extr_i64_i32)
| (TCG_TARGET_REG_BITS == 32 ? TCG_OPF_NOT_PRESENT : 0))
DEF(ext_i32_i64, 1, 1, 0, 0)
DEF(extu_i32_i64, 1, 1, 0, 0)
DEF(extrl_i64_i32, 1, 1, 0, 0)
DEF(extrh_i64_i32, 1, 1, 0, 0)
DEF(brcond_i64, 0, 2, 2, TCG_OPF_BB_END | TCG_OPF_COND_BRANCH | IMPL64)
DEF(ext8s_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_ext8s_i64))
DEF(ext16s_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_ext16s_i64))
DEF(ext32s_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_ext32s_i64))
DEF(ext8u_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_ext8u_i64))
DEF(ext16u_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_ext16u_i64))
DEF(ext32u_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_ext32u_i64))
DEF(bswap16_i64, 1, 1, 1, IMPL64 | IMPL(TCG_TARGET_HAS_bswap16_i64))
DEF(bswap32_i64, 1, 1, 1, IMPL64 | IMPL(TCG_TARGET_HAS_bswap32_i64))
DEF(bswap64_i64, 1, 1, 1, IMPL64 | IMPL(TCG_TARGET_HAS_bswap64_i64))
DEF(not_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_not_i64))
DEF(neg_i64, 1, 1, 0, IMPL64)
DEF(andc_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_andc_i64))
DEF(orc_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_orc_i64))
DEF(eqv_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_eqv_i64))
DEF(nand_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_nand_i64))
DEF(nor_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_nor_i64))
DEF(clz_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_clz_i64))
DEF(ctz_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_ctz_i64))
DEF(ctpop_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_ctpop_i64))
DEF(brcond_i64, 0, 2, 2, TCG_OPF_BB_END | TCG_OPF_COND_BRANCH)
DEF(ext8s_i64, 1, 1, 0, 0)
DEF(ext16s_i64, 1, 1, 0, 0)
DEF(ext32s_i64, 1, 1, 0, 0)
DEF(ext8u_i64, 1, 1, 0, 0)
DEF(ext16u_i64, 1, 1, 0, 0)
DEF(ext32u_i64, 1, 1, 0, 0)
DEF(bswap16_i64, 1, 1, 1, 0)
DEF(bswap32_i64, 1, 1, 1, 0)
DEF(bswap64_i64, 1, 1, 1, 0)
DEF(not_i64, 1, 1, 0, 0)
DEF(neg_i64, 1, 1, 0, 0)
DEF(andc_i64, 1, 2, 0, 0)
DEF(orc_i64, 1, 2, 0, 0)
DEF(eqv_i64, 1, 2, 0, 0)
DEF(nand_i64, 1, 2, 0, 0)
DEF(nor_i64, 1, 2, 0, 0)
DEF(clz_i64, 1, 2, 0, 0)
DEF(ctz_i64, 1, 2, 0, 0)
DEF(ctpop_i64, 1, 1, 0, 0)
DEF(add2_i64, 2, 4, 0, IMPL64 | IMPL(TCG_TARGET_HAS_add2_i64))
DEF(sub2_i64, 2, 4, 0, IMPL64 | IMPL(TCG_TARGET_HAS_sub2_i64))
DEF(mulu2_i64, 2, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_mulu2_i64))
DEF(muls2_i64, 2, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_muls2_i64))
DEF(muluh_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_muluh_i64))
DEF(mulsh_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_mulsh_i64))
DEF(add2_i64, 2, 4, 0, 0)
DEF(sub2_i64, 2, 4, 0, 0)
DEF(mulu2_i64, 2, 2, 0, 0)
DEF(muls2_i64, 2, 2, 0, 0)
DEF(muluh_i64, 1, 2, 0, 0)
DEF(mulsh_i64, 1, 2, 0, 0)
#define DATA64_ARGS (TCG_TARGET_REG_BITS == 64 ? 1 : 2)
/* There are tcg_ctx->insn_start_words here, not just one. */
DEF(insn_start, 0, 0, DATA64_ARGS, TCG_OPF_NOT_PRESENT)
DEF(exit_tb, 0, 0, 1, TCG_OPF_BB_EXIT | TCG_OPF_BB_END)
DEF(goto_tb, 0, 0, 1, TCG_OPF_BB_EXIT | TCG_OPF_BB_END)
DEF(exit_tb, 0, 0, 1, TCG_OPF_BB_EXIT | TCG_OPF_BB_END | TCG_OPF_NOT_PRESENT)
DEF(goto_tb, 0, 0, 1, TCG_OPF_BB_EXIT | TCG_OPF_BB_END | TCG_OPF_NOT_PRESENT)
DEF(goto_ptr, 0, 1, 0, TCG_OPF_BB_EXIT | TCG_OPF_BB_END)
DEF(plugin_cb, 0, 0, 1, TCG_OPF_NOT_PRESENT)
@ -206,113 +194,90 @@ DEF(qemu_ld_a32_i32, 1, 1, 1,
DEF(qemu_st_a32_i32, 0, 1 + 1, 1,
TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
DEF(qemu_ld_a32_i64, DATA64_ARGS, 1, 1,
TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS | TCG_OPF_64BIT)
TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
DEF(qemu_st_a32_i64, 0, DATA64_ARGS + 1, 1,
TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS | TCG_OPF_64BIT)
TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
DEF(qemu_ld_a64_i32, 1, DATA64_ARGS, 1,
TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
DEF(qemu_st_a64_i32, 0, 1 + DATA64_ARGS, 1,
TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
DEF(qemu_ld_a64_i64, DATA64_ARGS, DATA64_ARGS, 1,
TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS | TCG_OPF_64BIT)
TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
DEF(qemu_st_a64_i64, 0, DATA64_ARGS + DATA64_ARGS, 1,
TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS | TCG_OPF_64BIT)
TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
/* Only used by i386 to cope with stupid register constraints. */
DEF(qemu_st8_a32_i32, 0, 1 + 1, 1,
TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS |
IMPL(TCG_TARGET_HAS_qemu_st8_i32))
TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
DEF(qemu_st8_a64_i32, 0, 1 + DATA64_ARGS, 1,
TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS |
IMPL(TCG_TARGET_HAS_qemu_st8_i32))
TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
/* Only for 64-bit hosts at the moment. */
DEF(qemu_ld_a32_i128, 2, 1, 1,
TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS | TCG_OPF_64BIT |
IMPL(TCG_TARGET_HAS_qemu_ldst_i128))
DEF(qemu_ld_a64_i128, 2, 1, 1,
TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS | TCG_OPF_64BIT |
IMPL(TCG_TARGET_HAS_qemu_ldst_i128))
DEF(qemu_st_a32_i128, 0, 3, 1,
TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS | TCG_OPF_64BIT |
IMPL(TCG_TARGET_HAS_qemu_ldst_i128))
DEF(qemu_st_a64_i128, 0, 3, 1,
TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS | TCG_OPF_64BIT |
IMPL(TCG_TARGET_HAS_qemu_ldst_i128))
DEF(qemu_ld_a32_i128, 2, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
DEF(qemu_ld_a64_i128, 2, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
DEF(qemu_st_a32_i128, 0, 3, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
DEF(qemu_st_a64_i128, 0, 3, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
/* Host vector support. */
#define IMPLVEC TCG_OPF_VECTOR | IMPL(TCG_TARGET_MAYBE_vec)
DEF(mov_vec, 1, 1, 0, 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))
DEF(dup_vec, 1, 1, 0, TCG_OPF_VECTOR)
DEF(dup2_vec, 1, 2, 0, TCG_OPF_VECTOR)
DEF(ld_vec, 1, 1, 1, IMPLVEC)
DEF(st_vec, 0, 2, 1, IMPLVEC)
DEF(dupm_vec, 1, 1, 1, IMPLVEC)
DEF(ld_vec, 1, 1, 1, TCG_OPF_VECTOR)
DEF(st_vec, 0, 2, 1, TCG_OPF_VECTOR)
DEF(dupm_vec, 1, 1, 1, TCG_OPF_VECTOR)
DEF(add_vec, 1, 2, 0, IMPLVEC)
DEF(sub_vec, 1, 2, 0, IMPLVEC)
DEF(mul_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_mul_vec))
DEF(neg_vec, 1, 1, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_neg_vec))
DEF(abs_vec, 1, 1, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_abs_vec))
DEF(ssadd_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_sat_vec))
DEF(usadd_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_sat_vec))
DEF(sssub_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_sat_vec))
DEF(ussub_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_sat_vec))
DEF(smin_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_minmax_vec))
DEF(umin_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_minmax_vec))
DEF(smax_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_minmax_vec))
DEF(umax_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_minmax_vec))
DEF(add_vec, 1, 2, 0, TCG_OPF_VECTOR)
DEF(sub_vec, 1, 2, 0, TCG_OPF_VECTOR)
DEF(mul_vec, 1, 2, 0, TCG_OPF_VECTOR)
DEF(neg_vec, 1, 1, 0, TCG_OPF_VECTOR)
DEF(abs_vec, 1, 1, 0, TCG_OPF_VECTOR)
DEF(ssadd_vec, 1, 2, 0, TCG_OPF_VECTOR)
DEF(usadd_vec, 1, 2, 0, TCG_OPF_VECTOR)
DEF(sssub_vec, 1, 2, 0, TCG_OPF_VECTOR)
DEF(ussub_vec, 1, 2, 0, TCG_OPF_VECTOR)
DEF(smin_vec, 1, 2, 0, TCG_OPF_VECTOR)
DEF(umin_vec, 1, 2, 0, TCG_OPF_VECTOR)
DEF(smax_vec, 1, 2, 0, TCG_OPF_VECTOR)
DEF(umax_vec, 1, 2, 0, TCG_OPF_VECTOR)
DEF(and_vec, 1, 2, 0, IMPLVEC)
DEF(or_vec, 1, 2, 0, IMPLVEC)
DEF(xor_vec, 1, 2, 0, IMPLVEC)
DEF(andc_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_andc_vec))
DEF(orc_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_orc_vec))
DEF(nand_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_nand_vec))
DEF(nor_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_nor_vec))
DEF(eqv_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_eqv_vec))
DEF(not_vec, 1, 1, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_not_vec))
DEF(and_vec, 1, 2, 0, TCG_OPF_VECTOR)
DEF(or_vec, 1, 2, 0, TCG_OPF_VECTOR)
DEF(xor_vec, 1, 2, 0, TCG_OPF_VECTOR)
DEF(andc_vec, 1, 2, 0, TCG_OPF_VECTOR)
DEF(orc_vec, 1, 2, 0, TCG_OPF_VECTOR)
DEF(nand_vec, 1, 2, 0, TCG_OPF_VECTOR)
DEF(nor_vec, 1, 2, 0, TCG_OPF_VECTOR)
DEF(eqv_vec, 1, 2, 0, TCG_OPF_VECTOR)
DEF(not_vec, 1, 1, 0, TCG_OPF_VECTOR)
DEF(shli_vec, 1, 1, 1, IMPLVEC | IMPL(TCG_TARGET_HAS_shi_vec))
DEF(shri_vec, 1, 1, 1, IMPLVEC | IMPL(TCG_TARGET_HAS_shi_vec))
DEF(sari_vec, 1, 1, 1, IMPLVEC | IMPL(TCG_TARGET_HAS_shi_vec))
DEF(rotli_vec, 1, 1, 1, IMPLVEC | IMPL(TCG_TARGET_HAS_roti_vec))
DEF(shli_vec, 1, 1, 1, TCG_OPF_VECTOR)
DEF(shri_vec, 1, 1, 1, TCG_OPF_VECTOR)
DEF(sari_vec, 1, 1, 1, TCG_OPF_VECTOR)
DEF(rotli_vec, 1, 1, 1, TCG_OPF_VECTOR)
DEF(shls_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_shs_vec))
DEF(shrs_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_shs_vec))
DEF(sars_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_shs_vec))
DEF(rotls_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_rots_vec))
DEF(shls_vec, 1, 2, 0, TCG_OPF_VECTOR)
DEF(shrs_vec, 1, 2, 0, TCG_OPF_VECTOR)
DEF(sars_vec, 1, 2, 0, TCG_OPF_VECTOR)
DEF(rotls_vec, 1, 2, 0, TCG_OPF_VECTOR)
DEF(shlv_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_shv_vec))
DEF(shrv_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_shv_vec))
DEF(sarv_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_shv_vec))
DEF(rotlv_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_rotv_vec))
DEF(rotrv_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_rotv_vec))
DEF(shlv_vec, 1, 2, 0, TCG_OPF_VECTOR)
DEF(shrv_vec, 1, 2, 0, TCG_OPF_VECTOR)
DEF(sarv_vec, 1, 2, 0, TCG_OPF_VECTOR)
DEF(rotlv_vec, 1, 2, 0, TCG_OPF_VECTOR)
DEF(rotrv_vec, 1, 2, 0, TCG_OPF_VECTOR)
DEF(cmp_vec, 1, 2, 1, IMPLVEC)
DEF(cmp_vec, 1, 2, 1, TCG_OPF_VECTOR)
DEF(bitsel_vec, 1, 3, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_bitsel_vec))
DEF(cmpsel_vec, 1, 4, 1, IMPLVEC | IMPL(TCG_TARGET_HAS_cmpsel_vec))
DEF(bitsel_vec, 1, 3, 0, TCG_OPF_VECTOR)
DEF(cmpsel_vec, 1, 4, 1, TCG_OPF_VECTOR)
DEF(last_generic, 0, 0, 0, TCG_OPF_NOT_PRESENT)
#if TCG_TARGET_MAYBE_vec
#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, 1, 0, 1, TCG_OPF_NOT_PRESENT)
DEF(tci_movl, 1, 0, 1, TCG_OPF_NOT_PRESENT)
#endif
#include "tcg-target-opc.h.inc"
#undef DATA64_ARGS
#undef IMPL
#undef IMPL64
#undef IMPLVEC
#undef DEF

View file

@ -64,111 +64,6 @@ typedef uint64_t TCGRegSet;
#error unsupported
#endif
#if TCG_TARGET_REG_BITS == 32
/* Turn some undef macros into false macros. */
#define TCG_TARGET_HAS_extr_i64_i32 0
#define TCG_TARGET_HAS_div_i64 0
#define TCG_TARGET_HAS_rem_i64 0
#define TCG_TARGET_HAS_div2_i64 0
#define TCG_TARGET_HAS_rot_i64 0
#define TCG_TARGET_HAS_ext8s_i64 0
#define TCG_TARGET_HAS_ext16s_i64 0
#define TCG_TARGET_HAS_ext32s_i64 0
#define TCG_TARGET_HAS_ext8u_i64 0
#define TCG_TARGET_HAS_ext16u_i64 0
#define TCG_TARGET_HAS_ext32u_i64 0
#define TCG_TARGET_HAS_bswap16_i64 0
#define TCG_TARGET_HAS_bswap32_i64 0
#define TCG_TARGET_HAS_bswap64_i64 0
#define TCG_TARGET_HAS_not_i64 0
#define TCG_TARGET_HAS_andc_i64 0
#define TCG_TARGET_HAS_orc_i64 0
#define TCG_TARGET_HAS_eqv_i64 0
#define TCG_TARGET_HAS_nand_i64 0
#define TCG_TARGET_HAS_nor_i64 0
#define TCG_TARGET_HAS_clz_i64 0
#define TCG_TARGET_HAS_ctz_i64 0
#define TCG_TARGET_HAS_ctpop_i64 0
#define TCG_TARGET_HAS_deposit_i64 0
#define TCG_TARGET_HAS_extract_i64 0
#define TCG_TARGET_HAS_sextract_i64 0
#define TCG_TARGET_HAS_extract2_i64 0
#define TCG_TARGET_HAS_negsetcond_i64 0
#define TCG_TARGET_HAS_add2_i64 0
#define TCG_TARGET_HAS_sub2_i64 0
#define TCG_TARGET_HAS_mulu2_i64 0
#define TCG_TARGET_HAS_muls2_i64 0
#define TCG_TARGET_HAS_muluh_i64 0
#define TCG_TARGET_HAS_mulsh_i64 0
/* Turn some undef macros into true macros. */
#define TCG_TARGET_HAS_add2_i32 1
#define TCG_TARGET_HAS_sub2_i32 1
#endif
#ifndef TCG_TARGET_deposit_i32_valid
#define TCG_TARGET_deposit_i32_valid(ofs, len) 1
#endif
#ifndef TCG_TARGET_deposit_i64_valid
#define TCG_TARGET_deposit_i64_valid(ofs, len) 1
#endif
#ifndef TCG_TARGET_extract_i32_valid
#define TCG_TARGET_extract_i32_valid(ofs, len) 1
#endif
#ifndef TCG_TARGET_extract_i64_valid
#define TCG_TARGET_extract_i64_valid(ofs, len) 1
#endif
/* Only one of DIV or DIV2 should be defined. */
#if defined(TCG_TARGET_HAS_div_i32)
#define TCG_TARGET_HAS_div2_i32 0
#elif defined(TCG_TARGET_HAS_div2_i32)
#define TCG_TARGET_HAS_div_i32 0
#define TCG_TARGET_HAS_rem_i32 0
#endif
#if defined(TCG_TARGET_HAS_div_i64)
#define TCG_TARGET_HAS_div2_i64 0
#elif defined(TCG_TARGET_HAS_div2_i64)
#define TCG_TARGET_HAS_div_i64 0
#define TCG_TARGET_HAS_rem_i64 0
#endif
#if !defined(TCG_TARGET_HAS_v64) \
&& !defined(TCG_TARGET_HAS_v128) \
&& !defined(TCG_TARGET_HAS_v256)
#define TCG_TARGET_MAYBE_vec 0
#define TCG_TARGET_HAS_abs_vec 0
#define TCG_TARGET_HAS_neg_vec 0
#define TCG_TARGET_HAS_not_vec 0
#define TCG_TARGET_HAS_andc_vec 0
#define TCG_TARGET_HAS_orc_vec 0
#define TCG_TARGET_HAS_nand_vec 0
#define TCG_TARGET_HAS_nor_vec 0
#define TCG_TARGET_HAS_eqv_vec 0
#define TCG_TARGET_HAS_roti_vec 0
#define TCG_TARGET_HAS_rots_vec 0
#define TCG_TARGET_HAS_rotv_vec 0
#define TCG_TARGET_HAS_shi_vec 0
#define TCG_TARGET_HAS_shs_vec 0
#define TCG_TARGET_HAS_shv_vec 0
#define TCG_TARGET_HAS_mul_vec 0
#define TCG_TARGET_HAS_sat_vec 0
#define TCG_TARGET_HAS_minmax_vec 0
#define TCG_TARGET_HAS_bitsel_vec 0
#define TCG_TARGET_HAS_cmpsel_vec 0
#define TCG_TARGET_HAS_tst_vec 0
#else
#define TCG_TARGET_MAYBE_vec 1
#endif
#ifndef TCG_TARGET_HAS_v64
#define TCG_TARGET_HAS_v64 0
#endif
#ifndef TCG_TARGET_HAS_v128
#define TCG_TARGET_HAS_v128 0
#endif
#ifndef TCG_TARGET_HAS_v256
#define TCG_TARGET_HAS_v256 0
#endif
typedef enum TCGOpcode {
#define DEF(name, oargs, iargs, cargs, flags) INDEX_op_ ## name,
#include "tcg/tcg-opc.h"
@ -439,7 +334,8 @@ struct TCGOp {
#define TCGOP_CALLI(X) (X)->param1
#define TCGOP_CALLO(X) (X)->param2
#define TCGOP_VECL(X) (X)->param1
#define TCGOP_TYPE(X) (X)->param1
#define TCGOP_FLAGS(X) (X)->param2
#define TCGOP_VECE(X) (X)->param2
/* Make sure operands fit in the bitfields above. */
@ -497,12 +393,8 @@ struct TCGContext {
CPUState *cpu; /* *_trans */
/* These structures are private to tcg-target.c.inc. */
#ifdef TCG_TARGET_NEED_LDST_LABELS
QSIMPLEQ_HEAD(, TCGLabelQemuLdst) ldst_labels;
#endif
#ifdef TCG_TARGET_NEED_POOL_LABELS
struct TCGLabelPoolData *pool_labels;
#endif
TCGLabel *exitreq_label;
@ -746,10 +638,51 @@ void tcg_region_reset_all(void);
size_t tcg_code_size(void);
size_t tcg_code_capacity(void);
/**
* tcg_tb_insert:
* @tb: translation block to insert
*
* Insert @tb into the region trees.
*/
void tcg_tb_insert(TranslationBlock *tb);
/**
* tcg_tb_remove:
* @tb: translation block to remove
*
* Remove @tb from the region trees.
*/
void tcg_tb_remove(TranslationBlock *tb);
/**
* tcg_tb_lookup:
* @tc_ptr: host PC to look up
*
* Look up a translation block inside the region trees by @tc_ptr. This is
* useful for exception handling, but must not be used for the purposes of
* executing the returned translation block. See struct tb_tc for more
* information.
*
* Returns: a translation block previously inserted into the region trees,
* such that @tc_ptr points anywhere inside the code generated for it, or
* NULL.
*/
TranslationBlock *tcg_tb_lookup(uintptr_t tc_ptr);
/**
* tcg_tb_foreach:
* @func: callback
* @user_data: opaque value to pass to @callback
*
* Call @func for each translation block inserted into the region trees.
*/
void tcg_tb_foreach(GTraverseFunc func, gpointer user_data);
/**
* tcg_nb_tbs:
*
* Returns: the number of translation blocks inserted into the region trees.
*/
size_t tcg_nb_tbs(void);
/* user-mode: Called with mmap_lock held. */
@ -807,8 +740,6 @@ enum {
/* Instruction has side effects: it cannot be removed if its outputs
are not used, and might trigger exceptions. */
TCG_OPF_SIDE_EFFECTS = 0x08,
/* Instruction operands are 64-bits (otherwise 32-bits). */
TCG_OPF_64BIT = 0x10,
/* Instruction is optional and not implemented by the host, or insn
is generic and should not be implemented by the host. */
TCG_OPF_NOT_PRESENT = 0x20,
@ -822,18 +753,23 @@ typedef struct TCGOpDef {
const char *name;
uint8_t nb_oargs, nb_iargs, nb_cargs, nb_args;
uint8_t flags;
TCGArgConstraint *args_ct;
} TCGOpDef;
extern TCGOpDef tcg_op_defs[];
extern const TCGOpDef tcg_op_defs[];
extern const size_t tcg_op_defs_max;
typedef struct TCGTargetOpDef {
TCGOpcode op;
const char *args_ct_str[TCG_MAX_OP_ARGS];
} TCGTargetOpDef;
bool tcg_op_supported(TCGOpcode op);
/*
* tcg_op_supported:
* Query if @op, for @type and @flags, is supported by the host
* on which we are currently executing.
*/
bool tcg_op_supported(TCGOpcode op, TCGType type, unsigned flags);
/*
* tcg_op_deposit_valid:
* Query if a deposit into (ofs, len) is supported for @type by
* the host on which we are currently executing.
*/
bool tcg_op_deposit_valid(TCGType type, unsigned ofs, unsigned len);
void tcg_gen_call0(void *func, TCGHelperInfo *, TCGTemp *ret);
void tcg_gen_call1(void *func, TCGHelperInfo *, TCGTemp *ret, TCGTemp *);
@ -854,10 +790,6 @@ void tcg_gen_call7(void *func, TCGHelperInfo *, TCGTemp *ret,
TCGOp *tcg_emit_op(TCGOpcode opc, unsigned nargs);
void tcg_op_remove(TCGContext *s, TCGOp *op);
TCGOp *tcg_op_insert_before(TCGContext *s, TCGOp *op,
TCGOpcode opc, unsigned nargs);
TCGOp *tcg_op_insert_after(TCGContext *s, TCGOp *op,
TCGOpcode opc, unsigned nargs);
/**
* tcg_remove_ops_after:
@ -1016,17 +948,10 @@ extern tcg_prologue_fn *tcg_qemu_tb_exec;
void tcg_register_jit(const void *buf, size_t buf_size);
#if TCG_TARGET_MAYBE_vec
/* Return zero if the tuple (opc, type, vece) is unsupportable;
return > 0 if it is directly supportable;
return < 0 if we must call tcg_expand_vec_op. */
int tcg_can_emit_vec_op(TCGOpcode, TCGType, unsigned);
#else
static inline int tcg_can_emit_vec_op(TCGOpcode o, TCGType t, unsigned ve)
{
return 0;
}
#endif
/* Expand the tuple (opc, type, vece) on the given arguments. */
void tcg_expand_vec_op(TCGOpcode, TCGType, unsigned, TCGArg, ...);

View file

@ -8,7 +8,25 @@
static int open_cpuinfo(CPUArchState *cpu_env, int fd)
{
dprintf(fd, "type\t\t: sun4u\n");
int i, num_cpus;
const char *cpu_type;
num_cpus = sysconf(_SC_NPROCESSORS_ONLN);
if (cpu_env->def.features & CPU_FEATURE_HYPV) {
cpu_type = "sun4v";
} else {
cpu_type = "sun4u";
}
dprintf(fd, "cpu\t\t: %s (QEMU)\n", cpu_env->def.name);
dprintf(fd, "type\t\t: %s\n", cpu_type);
dprintf(fd, "ncpus probed\t: %d\n", num_cpus);
dprintf(fd, "ncpus active\t: %d\n", num_cpus);
dprintf(fd, "State:\n");
for (i = 0; i < num_cpus; i++) {
dprintf(fd, "CPU%d:\t\t: online\n", i);
}
return 0;
}
#define HAVE_ARCH_PROC_CPUINFO

View file

@ -8219,6 +8219,7 @@ static bool trans_CCMP(DisasContext *s, arg_CCMP *a)
TCGv_i64 tcg_rn, tcg_y;
DisasCompare c;
unsigned nzcv;
bool has_andc;
/* Set T0 = !COND. */
arm_test_cc(&c, a->cond);
@ -8249,17 +8250,18 @@ static bool trans_CCMP(DisasContext *s, arg_CCMP *a)
tcg_gen_subi_i32(tcg_t2, tcg_t0, 1);
nzcv = a->nzcv;
has_andc = tcg_op_supported(INDEX_op_andc_i32, TCG_TYPE_I32, 0);
if (nzcv & 8) { /* N */
tcg_gen_or_i32(cpu_NF, cpu_NF, tcg_t1);
} else {
if (TCG_TARGET_HAS_andc_i32) {
if (has_andc) {
tcg_gen_andc_i32(cpu_NF, cpu_NF, tcg_t1);
} else {
tcg_gen_and_i32(cpu_NF, cpu_NF, tcg_t2);
}
}
if (nzcv & 4) { /* Z */
if (TCG_TARGET_HAS_andc_i32) {
if (has_andc) {
tcg_gen_andc_i32(cpu_ZF, cpu_ZF, tcg_t1);
} else {
tcg_gen_and_i32(cpu_ZF, cpu_ZF, tcg_t2);
@ -8270,7 +8272,7 @@ static bool trans_CCMP(DisasContext *s, arg_CCMP *a)
if (nzcv & 2) { /* C */
tcg_gen_or_i32(cpu_CF, cpu_CF, tcg_t0);
} else {
if (TCG_TARGET_HAS_andc_i32) {
if (has_andc) {
tcg_gen_andc_i32(cpu_CF, cpu_CF, tcg_t1);
} else {
tcg_gen_and_i32(cpu_CF, cpu_CF, tcg_t2);
@ -8279,7 +8281,7 @@ static bool trans_CCMP(DisasContext *s, arg_CCMP *a)
if (nzcv & 1) { /* V */
tcg_gen_or_i32(cpu_VF, cpu_VF, tcg_t1);
} else {
if (TCG_TARGET_HAS_andc_i32) {
if (has_andc) {
tcg_gen_andc_i32(cpu_VF, cpu_VF, tcg_t1);
} else {
tcg_gen_and_i32(cpu_VF, cpu_VF, tcg_t2);

View file

@ -596,14 +596,8 @@ static void gen_bsl1n_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, TCGv_i64 k)
static void gen_bsl1n_vec(unsigned vece, TCGv_vec d, TCGv_vec n,
TCGv_vec m, TCGv_vec k)
{
if (TCG_TARGET_HAS_bitsel_vec) {
tcg_gen_not_vec(vece, n, n);
tcg_gen_bitsel_vec(vece, d, k, n, m);
} else {
tcg_gen_andc_vec(vece, n, k, n);
tcg_gen_andc_vec(vece, m, m, k);
tcg_gen_or_vec(vece, d, n, m);
}
}
static void gen_bsl1n(unsigned vece, uint32_t d, uint32_t n, uint32_t m,
@ -628,7 +622,7 @@ static void gen_bsl2n_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, TCGv_i64 k)
* = | ~(m | k)
*/
tcg_gen_and_i64(n, n, k);
if (TCG_TARGET_HAS_orc_i64) {
if (tcg_op_supported(INDEX_op_orc_i64, TCG_TYPE_I64, 0)) {
tcg_gen_or_i64(m, m, k);
tcg_gen_orc_i64(d, n, m);
} else {
@ -640,14 +634,8 @@ static void gen_bsl2n_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, TCGv_i64 k)
static void gen_bsl2n_vec(unsigned vece, TCGv_vec d, TCGv_vec n,
TCGv_vec m, TCGv_vec k)
{
if (TCG_TARGET_HAS_bitsel_vec) {
tcg_gen_not_vec(vece, m, m);
tcg_gen_bitsel_vec(vece, d, k, n, m);
} else {
tcg_gen_and_vec(vece, n, n, k);
tcg_gen_or_vec(vece, m, m, k);
tcg_gen_orc_vec(vece, d, n, m);
}
}
static void gen_bsl2n(unsigned vece, uint32_t d, uint32_t n, uint32_t m,

View file

@ -493,7 +493,7 @@ static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
{
TCGv_i32 tmp = tcg_temp_new_i32();
if (TCG_TARGET_HAS_add2_i32) {
if (tcg_op_supported(INDEX_op_add2_i32, TCG_TYPE_I32, 0)) {
tcg_gen_movi_i32(tmp, 0);
tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);

View file

@ -24,13 +24,9 @@
* The exact opcode to check depends on 32- vs. 64-bit.
*/
#ifdef TARGET_X86_64
#define TCG_TARGET_HAS_extract2_tl TCG_TARGET_HAS_extract2_i64
#define TCG_TARGET_deposit_tl_valid TCG_TARGET_deposit_i64_valid
#define TCG_TARGET_extract_tl_valid TCG_TARGET_extract_i64_valid
#define INDEX_op_extract2_tl INDEX_op_extract2_i64
#else
#define TCG_TARGET_HAS_extract2_tl TCG_TARGET_HAS_extract2_i32
#define TCG_TARGET_deposit_tl_valid TCG_TARGET_deposit_i32_valid
#define TCG_TARGET_extract_tl_valid TCG_TARGET_extract_i32_valid
#define INDEX_op_extract2_tl INDEX_op_extract2_i32
#endif
#define MMX_OFFSET(reg) \
@ -3018,7 +3014,7 @@ static void gen_PMOVMSKB(DisasContext *s, X86DecodedInsn *decode)
tcg_gen_ld8u_tl(s->T0, tcg_env, offsetof(CPUX86State, xmm_t0.ZMM_B(vec_len - 1)));
while (vec_len > 8) {
vec_len -= 8;
if (TCG_TARGET_HAS_extract2_tl) {
if (tcg_op_supported(INDEX_op_extract2_tl, TCG_TYPE_TL, 0)) {
/*
* Load the next byte of the result into the high byte of T.
* TCG does a similar expansion of deposit to shl+extract2; by
@ -3472,7 +3468,7 @@ static void gen_RCL(DisasContext *s, X86DecodedInsn *decode)
}
/* Compute high part, including incoming carry. */
if (!have_1bit_cin || TCG_TARGET_deposit_tl_valid(1, TARGET_LONG_BITS - 1)) {
if (!have_1bit_cin || tcg_op_deposit_valid(TCG_TYPE_TL, 1, TARGET_LONG_BITS - 1)) {
/* high = (T0 << 1) | cin */
TCGv cin = have_1bit_cin ? decode->cc_dst : decode->cc_src;
tcg_gen_deposit_tl(high, cin, s->T0, 1, TARGET_LONG_BITS - 1);
@ -3524,7 +3520,7 @@ static void gen_RCR(DisasContext *s, X86DecodedInsn *decode)
}
/* Save incoming carry into high, it will be shifted later. */
if (!have_1bit_cin || TCG_TARGET_deposit_tl_valid(1, TARGET_LONG_BITS - 1)) {
if (!have_1bit_cin || tcg_op_deposit_valid(TCG_TYPE_TL, 1, TARGET_LONG_BITS - 1)) {
TCGv cin = have_1bit_cin ? decode->cc_dst : decode->cc_src;
tcg_gen_deposit_tl(high, cin, s->T0, 1, TARGET_LONG_BITS - 1);
} else {

View file

@ -3980,7 +3980,7 @@ static void decode_bit_andacc(DisasContext *ctx)
pos1, pos2, &tcg_gen_andc_tl, &tcg_gen_and_tl);
break;
case OPC2_32_BIT_AND_NOR_T:
if (TCG_TARGET_HAS_andc_i32) {
if (tcg_op_supported(INDEX_op_andc_i32, TCG_TYPE_I32, 0)) {
gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
pos1, pos2, &tcg_gen_or_tl, &tcg_gen_andc_tl);
} else {
@ -4113,7 +4113,7 @@ static void decode_bit_orand(DisasContext *ctx)
pos1, pos2, &tcg_gen_andc_tl, &tcg_gen_or_tl);
break;
case OPC2_32_BIT_OR_NOR_T:
if (TCG_TARGET_HAS_orc_i32) {
if (tcg_op_supported(INDEX_op_orc_i32, TCG_TYPE_I32, 0)) {
gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
pos1, pos2, &tcg_gen_or_tl, &tcg_gen_orc_tl);
} else {

View file

@ -0,0 +1,117 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Define target-specific opcode support
* Copyright (c) 2013 Huawei Technologies Duesseldorf GmbH
*/
#ifndef TCG_TARGET_HAS_H
#define TCG_TARGET_HAS_H
#include "host/cpuinfo.h"
#define have_lse (cpuinfo & CPUINFO_LSE)
#define have_lse2 (cpuinfo & CPUINFO_LSE2)
/* optional instructions */
#define TCG_TARGET_HAS_div_i32 1
#define TCG_TARGET_HAS_rem_i32 1
#define TCG_TARGET_HAS_ext8s_i32 1
#define TCG_TARGET_HAS_ext16s_i32 1
#define TCG_TARGET_HAS_ext8u_i32 1
#define TCG_TARGET_HAS_ext16u_i32 1
#define TCG_TARGET_HAS_bswap16_i32 1
#define TCG_TARGET_HAS_bswap32_i32 1
#define TCG_TARGET_HAS_not_i32 1
#define TCG_TARGET_HAS_rot_i32 1
#define TCG_TARGET_HAS_andc_i32 1
#define TCG_TARGET_HAS_orc_i32 1
#define TCG_TARGET_HAS_eqv_i32 1
#define TCG_TARGET_HAS_nand_i32 0
#define TCG_TARGET_HAS_nor_i32 0
#define TCG_TARGET_HAS_clz_i32 1
#define TCG_TARGET_HAS_ctz_i32 1
#define TCG_TARGET_HAS_ctpop_i32 0
#define TCG_TARGET_HAS_extract2_i32 1
#define TCG_TARGET_HAS_negsetcond_i32 1
#define TCG_TARGET_HAS_add2_i32 1
#define TCG_TARGET_HAS_sub2_i32 1
#define TCG_TARGET_HAS_mulu2_i32 0
#define TCG_TARGET_HAS_muls2_i32 0
#define TCG_TARGET_HAS_muluh_i32 0
#define TCG_TARGET_HAS_mulsh_i32 0
#define TCG_TARGET_HAS_extr_i64_i32 0
#define TCG_TARGET_HAS_qemu_st8_i32 0
#define TCG_TARGET_HAS_div_i64 1
#define TCG_TARGET_HAS_rem_i64 1
#define TCG_TARGET_HAS_ext8s_i64 1
#define TCG_TARGET_HAS_ext16s_i64 1
#define TCG_TARGET_HAS_ext32s_i64 1
#define TCG_TARGET_HAS_ext8u_i64 1
#define TCG_TARGET_HAS_ext16u_i64 1
#define TCG_TARGET_HAS_ext32u_i64 1
#define TCG_TARGET_HAS_bswap16_i64 1
#define TCG_TARGET_HAS_bswap32_i64 1
#define TCG_TARGET_HAS_bswap64_i64 1
#define TCG_TARGET_HAS_not_i64 1
#define TCG_TARGET_HAS_rot_i64 1
#define TCG_TARGET_HAS_andc_i64 1
#define TCG_TARGET_HAS_orc_i64 1
#define TCG_TARGET_HAS_eqv_i64 1
#define TCG_TARGET_HAS_nand_i64 0
#define TCG_TARGET_HAS_nor_i64 0
#define TCG_TARGET_HAS_clz_i64 1
#define TCG_TARGET_HAS_ctz_i64 1
#define TCG_TARGET_HAS_ctpop_i64 0
#define TCG_TARGET_HAS_extract2_i64 1
#define TCG_TARGET_HAS_negsetcond_i64 1
#define TCG_TARGET_HAS_add2_i64 1
#define TCG_TARGET_HAS_sub2_i64 1
#define TCG_TARGET_HAS_mulu2_i64 0
#define TCG_TARGET_HAS_muls2_i64 0
#define TCG_TARGET_HAS_muluh_i64 1
#define TCG_TARGET_HAS_mulsh_i64 1
/*
* Without FEAT_LSE2, we must use LDXP+STXP to implement atomic 128-bit load,
* which requires writable pages. We must defer to the helper for user-only,
* but in system mode all ram is writable for the host.
*/
#ifdef CONFIG_USER_ONLY
#define TCG_TARGET_HAS_qemu_ldst_i128 have_lse2
#else
#define TCG_TARGET_HAS_qemu_ldst_i128 1
#endif
#define TCG_TARGET_HAS_tst 1
#define TCG_TARGET_HAS_v64 1
#define TCG_TARGET_HAS_v128 1
#define TCG_TARGET_HAS_v256 0
#define TCG_TARGET_HAS_andc_vec 1
#define TCG_TARGET_HAS_orc_vec 1
#define TCG_TARGET_HAS_nand_vec 0
#define TCG_TARGET_HAS_nor_vec 0
#define TCG_TARGET_HAS_eqv_vec 0
#define TCG_TARGET_HAS_not_vec 1
#define TCG_TARGET_HAS_neg_vec 1
#define TCG_TARGET_HAS_abs_vec 1
#define TCG_TARGET_HAS_roti_vec 0
#define TCG_TARGET_HAS_rots_vec 0
#define TCG_TARGET_HAS_rotv_vec 0
#define TCG_TARGET_HAS_shi_vec 1
#define TCG_TARGET_HAS_shs_vec 0
#define TCG_TARGET_HAS_shv_vec 1
#define TCG_TARGET_HAS_mul_vec 1
#define TCG_TARGET_HAS_sat_vec 1
#define TCG_TARGET_HAS_minmax_vec 1
#define TCG_TARGET_HAS_bitsel_vec 1
#define TCG_TARGET_HAS_cmpsel_vec 0
#define TCG_TARGET_HAS_tst_vec 1
#define TCG_TARGET_extract_valid(type, ofs, len) 1
#define TCG_TARGET_sextract_valid(type, ofs, len) 1
#define TCG_TARGET_deposit_valid(type, ofs, len) 1
#endif

View file

@ -0,0 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Define target-specific memory model
* Copyright (c) 2013 Huawei Technologies Duesseldorf GmbH
*/
#ifndef TCG_TARGET_MO_H
#define TCG_TARGET_MO_H
#define TCG_TARGET_DEFAULT_MO 0
#endif

View file

@ -11,5 +11,5 @@
* consider these to be UNSPEC with names.
*/
DEF(aa64_sshl_vec, 1, 2, 0, IMPLVEC)
DEF(aa64_sli_vec, 1, 2, 1, IMPLVEC)
DEF(aa64_sshl_vec, 1, 2, 0, TCG_OPF_VECTOR)
DEF(aa64_sli_vec, 1, 2, 1, TCG_OPF_VECTOR)

View file

@ -10,10 +10,21 @@
* See the COPYING file in the top-level directory for details.
*/
#include "../tcg-ldst.c.inc"
#include "../tcg-pool.c.inc"
#include "qemu/bitops.h"
/* Used for function call generation. */
#define TCG_REG_CALL_STACK TCG_REG_SP
#define TCG_TARGET_STACK_ALIGN 16
#define TCG_TARGET_CALL_STACK_OFFSET 0
#define TCG_TARGET_CALL_ARG_I32 TCG_CALL_ARG_NORMAL
#define TCG_TARGET_CALL_ARG_I64 TCG_CALL_ARG_NORMAL
#ifdef CONFIG_DARWIN
# define TCG_TARGET_CALL_ARG_I128 TCG_CALL_ARG_NORMAL
#else
# define TCG_TARGET_CALL_ARG_I128 TCG_CALL_ARG_EVEN
#endif
#define TCG_TARGET_CALL_RET_I128 TCG_CALL_RET_NORMAL
/* We're going to re-use TCGType in setting of the SF bit, which controls
the size of the operation performed. If we know the values match, it
makes things much cleaner. */
@ -2104,14 +2115,10 @@ void tb_target_set_jmp_target(const TranslationBlock *tb, int n,
flush_idcache_range(jmp_rx, jmp_rw, 4);
}
static void tcg_out_op(TCGContext *s, TCGOpcode opc,
static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType ext,
const TCGArg args[TCG_MAX_OP_ARGS],
const int const_args[TCG_MAX_OP_ARGS])
{
/* 99% of the time, we can signal the use of extension registers
by looking to see if the opcode handles 64-bit data. */
TCGType ext = (tcg_op_defs[opc].flags & TCG_OPF_64BIT) != 0;
/* Hoist the loads of the most common arguments. */
TCGArg a0 = args[0];
TCGArg a1 = args[1];
@ -2443,7 +2450,12 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
case INDEX_op_extract_i64:
case INDEX_op_extract_i32:
if (a2 == 0) {
uint64_t mask = MAKE_64BIT_MASK(0, args[3]);
tcg_out_logicali(s, I3404_ANDI, ext, a0, a1, mask);
} else {
tcg_out_ubfm(s, ext, a0, a1, a2, a2 + args[3] - 1);
}
break;
case INDEX_op_sextract_i64:
@ -2951,7 +2963,8 @@ void tcg_expand_vec_op(TCGOpcode opc, TCGType type, unsigned vece,
}
}
static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
static TCGConstraintSetIndex
tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
{
switch (op) {
case INDEX_op_goto_ptr:
@ -3147,7 +3160,7 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
return C_O1_I2(w, 0, w);
default:
g_assert_not_reached();
return C_NotImplemented;
}
}

View file

@ -13,8 +13,6 @@
#ifndef AARCH64_TCG_TARGET_H
#define AARCH64_TCG_TARGET_H
#include "host/cpuinfo.h"
#define TCG_TARGET_INSN_UNIT_SIZE 4
#define MAX_CODE_GEN_BUFFER_SIZE ((size_t)-1)
@ -49,128 +47,4 @@ typedef enum {
#define TCG_TARGET_NB_REGS 64
/* used for function call generation */
#define TCG_REG_CALL_STACK TCG_REG_SP
#define TCG_TARGET_STACK_ALIGN 16
#define TCG_TARGET_CALL_STACK_OFFSET 0
#define TCG_TARGET_CALL_ARG_I32 TCG_CALL_ARG_NORMAL
#define TCG_TARGET_CALL_ARG_I64 TCG_CALL_ARG_NORMAL
#ifdef CONFIG_DARWIN
# define TCG_TARGET_CALL_ARG_I128 TCG_CALL_ARG_NORMAL
#else
# define TCG_TARGET_CALL_ARG_I128 TCG_CALL_ARG_EVEN
#endif
#define TCG_TARGET_CALL_RET_I128 TCG_CALL_RET_NORMAL
#define have_lse (cpuinfo & CPUINFO_LSE)
#define have_lse2 (cpuinfo & CPUINFO_LSE2)
/* optional instructions */
#define TCG_TARGET_HAS_div_i32 1
#define TCG_TARGET_HAS_rem_i32 1
#define TCG_TARGET_HAS_ext8s_i32 1
#define TCG_TARGET_HAS_ext16s_i32 1
#define TCG_TARGET_HAS_ext8u_i32 1
#define TCG_TARGET_HAS_ext16u_i32 1
#define TCG_TARGET_HAS_bswap16_i32 1
#define TCG_TARGET_HAS_bswap32_i32 1
#define TCG_TARGET_HAS_not_i32 1
#define TCG_TARGET_HAS_rot_i32 1
#define TCG_TARGET_HAS_andc_i32 1
#define TCG_TARGET_HAS_orc_i32 1
#define TCG_TARGET_HAS_eqv_i32 1
#define TCG_TARGET_HAS_nand_i32 0
#define TCG_TARGET_HAS_nor_i32 0
#define TCG_TARGET_HAS_clz_i32 1
#define TCG_TARGET_HAS_ctz_i32 1
#define TCG_TARGET_HAS_ctpop_i32 0
#define TCG_TARGET_HAS_deposit_i32 1
#define TCG_TARGET_HAS_extract_i32 1
#define TCG_TARGET_HAS_sextract_i32 1
#define TCG_TARGET_HAS_extract2_i32 1
#define TCG_TARGET_HAS_negsetcond_i32 1
#define TCG_TARGET_HAS_add2_i32 1
#define TCG_TARGET_HAS_sub2_i32 1
#define TCG_TARGET_HAS_mulu2_i32 0
#define TCG_TARGET_HAS_muls2_i32 0
#define TCG_TARGET_HAS_muluh_i32 0
#define TCG_TARGET_HAS_mulsh_i32 0
#define TCG_TARGET_HAS_extr_i64_i32 0
#define TCG_TARGET_HAS_qemu_st8_i32 0
#define TCG_TARGET_HAS_div_i64 1
#define TCG_TARGET_HAS_rem_i64 1
#define TCG_TARGET_HAS_ext8s_i64 1
#define TCG_TARGET_HAS_ext16s_i64 1
#define TCG_TARGET_HAS_ext32s_i64 1
#define TCG_TARGET_HAS_ext8u_i64 1
#define TCG_TARGET_HAS_ext16u_i64 1
#define TCG_TARGET_HAS_ext32u_i64 1
#define TCG_TARGET_HAS_bswap16_i64 1
#define TCG_TARGET_HAS_bswap32_i64 1
#define TCG_TARGET_HAS_bswap64_i64 1
#define TCG_TARGET_HAS_not_i64 1
#define TCG_TARGET_HAS_rot_i64 1
#define TCG_TARGET_HAS_andc_i64 1
#define TCG_TARGET_HAS_orc_i64 1
#define TCG_TARGET_HAS_eqv_i64 1
#define TCG_TARGET_HAS_nand_i64 0
#define TCG_TARGET_HAS_nor_i64 0
#define TCG_TARGET_HAS_clz_i64 1
#define TCG_TARGET_HAS_ctz_i64 1
#define TCG_TARGET_HAS_ctpop_i64 0
#define TCG_TARGET_HAS_deposit_i64 1
#define TCG_TARGET_HAS_extract_i64 1
#define TCG_TARGET_HAS_sextract_i64 1
#define TCG_TARGET_HAS_extract2_i64 1
#define TCG_TARGET_HAS_negsetcond_i64 1
#define TCG_TARGET_HAS_add2_i64 1
#define TCG_TARGET_HAS_sub2_i64 1
#define TCG_TARGET_HAS_mulu2_i64 0
#define TCG_TARGET_HAS_muls2_i64 0
#define TCG_TARGET_HAS_muluh_i64 1
#define TCG_TARGET_HAS_mulsh_i64 1
/*
* Without FEAT_LSE2, we must use LDXP+STXP to implement atomic 128-bit load,
* which requires writable pages. We must defer to the helper for user-only,
* but in system mode all ram is writable for the host.
*/
#ifdef CONFIG_USER_ONLY
#define TCG_TARGET_HAS_qemu_ldst_i128 have_lse2
#else
#define TCG_TARGET_HAS_qemu_ldst_i128 1
#endif
#define TCG_TARGET_HAS_tst 1
#define TCG_TARGET_HAS_v64 1
#define TCG_TARGET_HAS_v128 1
#define TCG_TARGET_HAS_v256 0
#define TCG_TARGET_HAS_andc_vec 1
#define TCG_TARGET_HAS_orc_vec 1
#define TCG_TARGET_HAS_nand_vec 0
#define TCG_TARGET_HAS_nor_vec 0
#define TCG_TARGET_HAS_eqv_vec 0
#define TCG_TARGET_HAS_not_vec 1
#define TCG_TARGET_HAS_neg_vec 1
#define TCG_TARGET_HAS_abs_vec 1
#define TCG_TARGET_HAS_roti_vec 0
#define TCG_TARGET_HAS_rots_vec 0
#define TCG_TARGET_HAS_rotv_vec 0
#define TCG_TARGET_HAS_shi_vec 1
#define TCG_TARGET_HAS_shs_vec 0
#define TCG_TARGET_HAS_shv_vec 1
#define TCG_TARGET_HAS_mul_vec 1
#define TCG_TARGET_HAS_sat_vec 1
#define TCG_TARGET_HAS_minmax_vec 1
#define TCG_TARGET_HAS_bitsel_vec 1
#define TCG_TARGET_HAS_cmpsel_vec 0
#define TCG_TARGET_HAS_tst_vec 1
#define TCG_TARGET_DEFAULT_MO (0)
#define TCG_TARGET_NEED_LDST_LABELS
#define TCG_TARGET_NEED_POOL_LABELS
#endif /* AARCH64_TCG_TARGET_H */

100
tcg/arm/tcg-target-has.h Normal file
View file

@ -0,0 +1,100 @@
/* SPDX-License-Identifier: MIT */
/*
* Define target-specific opcode support
* Copyright (c) 2008 Fabrice Bellard
* Copyright (c) 2008 Andrzej Zaborowski
*/
#ifndef TCG_TARGET_HAS_H
#define TCG_TARGET_HAS_H
extern int arm_arch;
#define use_armv7_instructions (__ARM_ARCH >= 7 || arm_arch >= 7)
#ifdef __ARM_ARCH_EXT_IDIV__
#define use_idiv_instructions 1
#else
extern bool use_idiv_instructions;
#endif
#ifdef __ARM_NEON__
#define use_neon_instructions 1
#else
extern bool use_neon_instructions;
#endif
/* optional instructions */
#define TCG_TARGET_HAS_ext8s_i32 1
#define TCG_TARGET_HAS_ext16s_i32 1
#define TCG_TARGET_HAS_ext8u_i32 0 /* and r0, r1, #0xff */
#define TCG_TARGET_HAS_ext16u_i32 1
#define TCG_TARGET_HAS_bswap16_i32 1
#define TCG_TARGET_HAS_bswap32_i32 1
#define TCG_TARGET_HAS_not_i32 1
#define TCG_TARGET_HAS_rot_i32 1
#define TCG_TARGET_HAS_andc_i32 1
#define TCG_TARGET_HAS_orc_i32 0
#define TCG_TARGET_HAS_eqv_i32 0
#define TCG_TARGET_HAS_nand_i32 0
#define TCG_TARGET_HAS_nor_i32 0
#define TCG_TARGET_HAS_clz_i32 1
#define TCG_TARGET_HAS_ctz_i32 use_armv7_instructions
#define TCG_TARGET_HAS_ctpop_i32 0
#define TCG_TARGET_HAS_extract2_i32 1
#define TCG_TARGET_HAS_negsetcond_i32 1
#define TCG_TARGET_HAS_mulu2_i32 1
#define TCG_TARGET_HAS_muls2_i32 1
#define TCG_TARGET_HAS_muluh_i32 0
#define TCG_TARGET_HAS_mulsh_i32 0
#define TCG_TARGET_HAS_div_i32 use_idiv_instructions
#define TCG_TARGET_HAS_rem_i32 0
#define TCG_TARGET_HAS_qemu_st8_i32 0
#define TCG_TARGET_HAS_qemu_ldst_i128 0
#define TCG_TARGET_HAS_tst 1
#define TCG_TARGET_HAS_v64 use_neon_instructions
#define TCG_TARGET_HAS_v128 use_neon_instructions
#define TCG_TARGET_HAS_v256 0
#define TCG_TARGET_HAS_andc_vec 1
#define TCG_TARGET_HAS_orc_vec 1
#define TCG_TARGET_HAS_nand_vec 0
#define TCG_TARGET_HAS_nor_vec 0
#define TCG_TARGET_HAS_eqv_vec 0
#define TCG_TARGET_HAS_not_vec 1
#define TCG_TARGET_HAS_neg_vec 1
#define TCG_TARGET_HAS_abs_vec 1
#define TCG_TARGET_HAS_roti_vec 0
#define TCG_TARGET_HAS_rots_vec 0
#define TCG_TARGET_HAS_rotv_vec 0
#define TCG_TARGET_HAS_shi_vec 1
#define TCG_TARGET_HAS_shs_vec 0
#define TCG_TARGET_HAS_shv_vec 0
#define TCG_TARGET_HAS_mul_vec 1
#define TCG_TARGET_HAS_sat_vec 1
#define TCG_TARGET_HAS_minmax_vec 1
#define TCG_TARGET_HAS_bitsel_vec 1
#define TCG_TARGET_HAS_cmpsel_vec 0
#define TCG_TARGET_HAS_tst_vec 1
static inline bool
tcg_target_extract_valid(TCGType type, unsigned ofs, unsigned len)
{
if (use_armv7_instructions) {
return true; /* SBFX or UBFX */
}
switch (len) {
case 8: /* SXTB or UXTB */
case 16: /* SXTH or UXTH */
return (ofs % 8) == 0;
}
return false;
}
#define TCG_TARGET_extract_valid tcg_target_extract_valid
#define TCG_TARGET_sextract_valid tcg_target_extract_valid
#define TCG_TARGET_deposit_valid(type, ofs, len) use_armv7_instructions
#endif

13
tcg/arm/tcg-target-mo.h Normal file
View file

@ -0,0 +1,13 @@
/* SPDX-License-Identifier: MIT */
/*
* Define target-specific memory model
* Copyright (c) 2008 Fabrice Bellard
* Copyright (c) 2008 Andrzej Zaborowski
*/
#ifndef TCG_TARGET_MO_H
#define TCG_TARGET_MO_H
#define TCG_TARGET_DEFAULT_MO 0
#endif

View file

@ -11,6 +11,6 @@
* consider these to be UNSPEC with names.
*/
DEF(arm_sli_vec, 1, 2, 1, IMPLVEC)
DEF(arm_sshl_vec, 1, 2, 0, IMPLVEC)
DEF(arm_ushl_vec, 1, 2, 0, IMPLVEC)
DEF(arm_sli_vec, 1, 2, 1, TCG_OPF_VECTOR)
DEF(arm_sshl_vec, 1, 2, 0, TCG_OPF_VECTOR)
DEF(arm_ushl_vec, 1, 2, 0, TCG_OPF_VECTOR)

View file

@ -23,8 +23,6 @@
*/
#include "elf.h"
#include "../tcg-ldst.c.inc"
#include "../tcg-pool.c.inc"
int arm_arch = __ARM_ARCH;
@ -35,6 +33,14 @@ bool use_idiv_instructions;
bool use_neon_instructions;
#endif
/* Used for function call generation. */
#define TCG_TARGET_STACK_ALIGN 8
#define TCG_TARGET_CALL_STACK_OFFSET 0
#define TCG_TARGET_CALL_ARG_I32 TCG_CALL_ARG_NORMAL
#define TCG_TARGET_CALL_ARG_I64 TCG_CALL_ARG_EVEN
#define TCG_TARGET_CALL_ARG_I128 TCG_CALL_ARG_EVEN
#define TCG_TARGET_CALL_RET_I128 TCG_CALL_RET_BY_REF
#ifdef CONFIG_DEBUG_TCG
static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
"%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
@ -1030,19 +1036,61 @@ static void tcg_out_deposit(TCGContext *s, ARMCond cond, TCGReg rd,
static void tcg_out_extract(TCGContext *s, ARMCond cond, TCGReg rd,
TCGReg rn, int ofs, int len)
{
/* According to gcc, AND can be faster. */
if (ofs == 0 && len <= 8) {
tcg_out_dat_imm(s, cond, ARITH_AND, rd, rn,
encode_imm_nofail((1 << len) - 1));
return;
}
if (use_armv7_instructions) {
/* ubfx */
tcg_out32(s, 0x07e00050 | (cond << 28) | (rd << 12) | rn
| (ofs << 7) | ((len - 1) << 16));
return;
}
assert(ofs % 8 == 0);
switch (len) {
case 8:
/* uxtb */
tcg_out32(s, 0x06ef0070 | (cond << 28) | (rd << 12) | (ofs << 7) | rn);
break;
case 16:
/* uxth */
tcg_out32(s, 0x06ff0070 | (cond << 28) | (rd << 12) | (ofs << 7) | rn);
break;
default:
g_assert_not_reached();
}
}
static void tcg_out_sextract(TCGContext *s, ARMCond cond, TCGReg rd,
TCGReg rn, int ofs, int len)
{
if (use_armv7_instructions) {
/* sbfx */
tcg_out32(s, 0x07a00050 | (cond << 28) | (rd << 12) | rn
| (ofs << 7) | ((len - 1) << 16));
return;
}
assert(ofs % 8 == 0);
switch (len) {
case 8:
/* sxtb */
tcg_out32(s, 0x06af0070 | (cond << 28) | (rd << 12) | (ofs << 7) | rn);
break;
case 16:
/* sxth */
tcg_out32(s, 0x06bf0070 | (cond << 28) | (rd << 12) | (ofs << 7) | rn);
break;
default:
g_assert_not_reached();
}
}
static void tcg_out_ld32u(TCGContext *s, ARMCond cond,
TCGReg rd, TCGReg rn, int32_t offset)
{
@ -1799,7 +1847,7 @@ void tb_target_set_jmp_target(const TranslationBlock *tb, int n,
flush_idcache_range(jmp_rx, jmp_rw, 4);
}
static void tcg_out_op(TCGContext *s, TCGOpcode opc,
static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
const TCGArg args[TCG_MAX_OP_ARGS],
const int const_args[TCG_MAX_OP_ARGS])
{
@ -2118,7 +2166,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
}
}
static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
static TCGConstraintSetIndex
tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
{
switch (op) {
case INDEX_op_goto_ptr:
@ -2254,7 +2303,7 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
case INDEX_op_bitsel_vec:
return C_O1_I3(w, w, w, w);
default:
g_assert_not_reached();
return C_NotImplemented;
}
}

View file

@ -26,10 +26,6 @@
#ifndef ARM_TCG_TARGET_H
#define ARM_TCG_TARGET_H
extern int arm_arch;
#define use_armv7_instructions (__ARM_ARCH >= 7 || arm_arch >= 7)
#define TCG_TARGET_INSN_UNIT_SIZE 4
#define MAX_CODE_GEN_BUFFER_SIZE UINT32_MAX
@ -74,86 +70,4 @@ typedef enum {
#define TCG_TARGET_NB_REGS 32
#ifdef __ARM_ARCH_EXT_IDIV__
#define use_idiv_instructions 1
#else
extern bool use_idiv_instructions;
#endif
#ifdef __ARM_NEON__
#define use_neon_instructions 1
#else
extern bool use_neon_instructions;
#endif
/* used for function call generation */
#define TCG_TARGET_STACK_ALIGN 8
#define TCG_TARGET_CALL_STACK_OFFSET 0
#define TCG_TARGET_CALL_ARG_I32 TCG_CALL_ARG_NORMAL
#define TCG_TARGET_CALL_ARG_I64 TCG_CALL_ARG_EVEN
#define TCG_TARGET_CALL_ARG_I128 TCG_CALL_ARG_EVEN
#define TCG_TARGET_CALL_RET_I128 TCG_CALL_RET_BY_REF
/* optional instructions */
#define TCG_TARGET_HAS_ext8s_i32 1
#define TCG_TARGET_HAS_ext16s_i32 1
#define TCG_TARGET_HAS_ext8u_i32 0 /* and r0, r1, #0xff */
#define TCG_TARGET_HAS_ext16u_i32 1
#define TCG_TARGET_HAS_bswap16_i32 1
#define TCG_TARGET_HAS_bswap32_i32 1
#define TCG_TARGET_HAS_not_i32 1
#define TCG_TARGET_HAS_rot_i32 1
#define TCG_TARGET_HAS_andc_i32 1
#define TCG_TARGET_HAS_orc_i32 0
#define TCG_TARGET_HAS_eqv_i32 0
#define TCG_TARGET_HAS_nand_i32 0
#define TCG_TARGET_HAS_nor_i32 0
#define TCG_TARGET_HAS_clz_i32 1
#define TCG_TARGET_HAS_ctz_i32 use_armv7_instructions
#define TCG_TARGET_HAS_ctpop_i32 0
#define TCG_TARGET_HAS_deposit_i32 use_armv7_instructions
#define TCG_TARGET_HAS_extract_i32 use_armv7_instructions
#define TCG_TARGET_HAS_sextract_i32 use_armv7_instructions
#define TCG_TARGET_HAS_extract2_i32 1
#define TCG_TARGET_HAS_negsetcond_i32 1
#define TCG_TARGET_HAS_mulu2_i32 1
#define TCG_TARGET_HAS_muls2_i32 1
#define TCG_TARGET_HAS_muluh_i32 0
#define TCG_TARGET_HAS_mulsh_i32 0
#define TCG_TARGET_HAS_div_i32 use_idiv_instructions
#define TCG_TARGET_HAS_rem_i32 0
#define TCG_TARGET_HAS_qemu_st8_i32 0
#define TCG_TARGET_HAS_qemu_ldst_i128 0
#define TCG_TARGET_HAS_tst 1
#define TCG_TARGET_HAS_v64 use_neon_instructions
#define TCG_TARGET_HAS_v128 use_neon_instructions
#define TCG_TARGET_HAS_v256 0
#define TCG_TARGET_HAS_andc_vec 1
#define TCG_TARGET_HAS_orc_vec 1
#define TCG_TARGET_HAS_nand_vec 0
#define TCG_TARGET_HAS_nor_vec 0
#define TCG_TARGET_HAS_eqv_vec 0
#define TCG_TARGET_HAS_not_vec 1
#define TCG_TARGET_HAS_neg_vec 1
#define TCG_TARGET_HAS_abs_vec 1
#define TCG_TARGET_HAS_roti_vec 0
#define TCG_TARGET_HAS_rots_vec 0
#define TCG_TARGET_HAS_rotv_vec 0
#define TCG_TARGET_HAS_shi_vec 1
#define TCG_TARGET_HAS_shs_vec 0
#define TCG_TARGET_HAS_shv_vec 0
#define TCG_TARGET_HAS_mul_vec 1
#define TCG_TARGET_HAS_sat_vec 1
#define TCG_TARGET_HAS_minmax_vec 1
#define TCG_TARGET_HAS_bitsel_vec 1
#define TCG_TARGET_HAS_cmpsel_vec 0
#define TCG_TARGET_HAS_tst_vec 1
#define TCG_TARGET_DEFAULT_MO (0)
#define TCG_TARGET_NEED_LDST_LABELS
#define TCG_TARGET_NEED_POOL_LABELS
#endif

169
tcg/i386/tcg-target-has.h Normal file
View file

@ -0,0 +1,169 @@
/* SPDX-License-Identifier: MIT */
/*
* Define target-specific opcode support
* Copyright (c) 2008 Fabrice Bellard
*/
#ifndef TCG_TARGET_HAS_H
#define TCG_TARGET_HAS_H
#include "host/cpuinfo.h"
#define have_bmi1 (cpuinfo & CPUINFO_BMI1)
#define have_popcnt (cpuinfo & CPUINFO_POPCNT)
#define have_avx1 (cpuinfo & CPUINFO_AVX1)
#define have_avx2 (cpuinfo & CPUINFO_AVX2)
#define have_movbe (cpuinfo & CPUINFO_MOVBE)
/*
* There are interesting instructions in AVX512, so long as we have AVX512VL,
* which indicates support for EVEX on sizes smaller than 512 bits.
*/
#define have_avx512vl ((cpuinfo & CPUINFO_AVX512VL) && \
(cpuinfo & CPUINFO_AVX512F))
#define have_avx512bw ((cpuinfo & CPUINFO_AVX512BW) && have_avx512vl)
#define have_avx512dq ((cpuinfo & CPUINFO_AVX512DQ) && have_avx512vl)
#define have_avx512vbmi2 ((cpuinfo & CPUINFO_AVX512VBMI2) && have_avx512vl)
/* optional instructions */
#define TCG_TARGET_HAS_div2_i32 1
#define TCG_TARGET_HAS_rot_i32 1
#define TCG_TARGET_HAS_ext8s_i32 1
#define TCG_TARGET_HAS_ext16s_i32 1
#define TCG_TARGET_HAS_ext8u_i32 1
#define TCG_TARGET_HAS_ext16u_i32 1
#define TCG_TARGET_HAS_bswap16_i32 1
#define TCG_TARGET_HAS_bswap32_i32 1
#define TCG_TARGET_HAS_not_i32 1
#define TCG_TARGET_HAS_andc_i32 have_bmi1
#define TCG_TARGET_HAS_orc_i32 0
#define TCG_TARGET_HAS_eqv_i32 0
#define TCG_TARGET_HAS_nand_i32 0
#define TCG_TARGET_HAS_nor_i32 0
#define TCG_TARGET_HAS_clz_i32 1
#define TCG_TARGET_HAS_ctz_i32 1
#define TCG_TARGET_HAS_ctpop_i32 have_popcnt
#define TCG_TARGET_HAS_extract2_i32 1
#define TCG_TARGET_HAS_negsetcond_i32 1
#define TCG_TARGET_HAS_add2_i32 1
#define TCG_TARGET_HAS_sub2_i32 1
#define TCG_TARGET_HAS_mulu2_i32 1
#define TCG_TARGET_HAS_muls2_i32 1
#define TCG_TARGET_HAS_muluh_i32 0
#define TCG_TARGET_HAS_mulsh_i32 0
#if TCG_TARGET_REG_BITS == 64
/* Keep 32-bit values zero-extended in a register. */
#define TCG_TARGET_HAS_extr_i64_i32 1
#define TCG_TARGET_HAS_div2_i64 1
#define TCG_TARGET_HAS_rot_i64 1
#define TCG_TARGET_HAS_ext8s_i64 1
#define TCG_TARGET_HAS_ext16s_i64 1
#define TCG_TARGET_HAS_ext32s_i64 1
#define TCG_TARGET_HAS_ext8u_i64 1
#define TCG_TARGET_HAS_ext16u_i64 1
#define TCG_TARGET_HAS_ext32u_i64 1
#define TCG_TARGET_HAS_bswap16_i64 1
#define TCG_TARGET_HAS_bswap32_i64 1
#define TCG_TARGET_HAS_bswap64_i64 1
#define TCG_TARGET_HAS_not_i64 1
#define TCG_TARGET_HAS_andc_i64 have_bmi1
#define TCG_TARGET_HAS_orc_i64 0
#define TCG_TARGET_HAS_eqv_i64 0
#define TCG_TARGET_HAS_nand_i64 0
#define TCG_TARGET_HAS_nor_i64 0
#define TCG_TARGET_HAS_clz_i64 1
#define TCG_TARGET_HAS_ctz_i64 1
#define TCG_TARGET_HAS_ctpop_i64 have_popcnt
#define TCG_TARGET_HAS_extract2_i64 1
#define TCG_TARGET_HAS_negsetcond_i64 1
#define TCG_TARGET_HAS_add2_i64 1
#define TCG_TARGET_HAS_sub2_i64 1
#define TCG_TARGET_HAS_mulu2_i64 1
#define TCG_TARGET_HAS_muls2_i64 1
#define TCG_TARGET_HAS_muluh_i64 0
#define TCG_TARGET_HAS_mulsh_i64 0
#define TCG_TARGET_HAS_qemu_st8_i32 0
#else
#define TCG_TARGET_HAS_qemu_st8_i32 1
#endif
#define TCG_TARGET_HAS_qemu_ldst_i128 \
(TCG_TARGET_REG_BITS == 64 && (cpuinfo & CPUINFO_ATOMIC_VMOVDQA))
#define TCG_TARGET_HAS_tst 1
/* We do not support older SSE systems, only beginning with AVX1. */
#define TCG_TARGET_HAS_v64 have_avx1
#define TCG_TARGET_HAS_v128 have_avx1
#define TCG_TARGET_HAS_v256 have_avx2
#define TCG_TARGET_HAS_andc_vec 1
#define TCG_TARGET_HAS_orc_vec have_avx512vl
#define TCG_TARGET_HAS_nand_vec have_avx512vl
#define TCG_TARGET_HAS_nor_vec have_avx512vl
#define TCG_TARGET_HAS_eqv_vec have_avx512vl
#define TCG_TARGET_HAS_not_vec have_avx512vl
#define TCG_TARGET_HAS_neg_vec 0
#define TCG_TARGET_HAS_abs_vec 1
#define TCG_TARGET_HAS_roti_vec have_avx512vl
#define TCG_TARGET_HAS_rots_vec 0
#define TCG_TARGET_HAS_rotv_vec have_avx512vl
#define TCG_TARGET_HAS_shi_vec 1
#define TCG_TARGET_HAS_shs_vec 1
#define TCG_TARGET_HAS_shv_vec have_avx2
#define TCG_TARGET_HAS_mul_vec 1
#define TCG_TARGET_HAS_sat_vec 1
#define TCG_TARGET_HAS_minmax_vec 1
#define TCG_TARGET_HAS_bitsel_vec have_avx512vl
#define TCG_TARGET_HAS_cmpsel_vec 1
#define TCG_TARGET_HAS_tst_vec have_avx512bw
#define TCG_TARGET_deposit_valid(type, ofs, len) \
(((ofs) == 0 && ((len) == 8 || (len) == 16)) || \
(TCG_TARGET_REG_BITS == 32 && (ofs) == 8 && (len) == 8))
/*
* Check for the possibility of low byte/word extraction, high-byte extraction
* and zero-extending 32-bit right-shift.
*
* We cannot sign-extend from high byte to 64-bits without using the
* REX prefix that explicitly excludes access to the high-byte registers.
*/
static inline bool
tcg_target_sextract_valid(TCGType type, unsigned ofs, unsigned len)
{
switch (ofs) {
case 0:
switch (len) {
case 8:
case 16:
return true;
case 32:
return type == TCG_TYPE_I64;
}
return false;
case 8:
return len == 8 && type == TCG_TYPE_I32;
}
return false;
}
#define TCG_TARGET_sextract_valid tcg_target_sextract_valid
static inline bool
tcg_target_extract_valid(TCGType type, unsigned ofs, unsigned len)
{
if (type == TCG_TYPE_I64 && ofs + len == 32) {
return true;
}
switch (ofs) {
case 0:
return len == 8 || len == 16;
case 8:
return len == 8;
}
return false;
}
#define TCG_TARGET_extract_valid tcg_target_extract_valid
#endif

19
tcg/i386/tcg-target-mo.h Normal file
View file

@ -0,0 +1,19 @@
/* SPDX-License-Identifier: MIT */
/*
* Define target-specific memory model
* Copyright (c) 2008 Fabrice Bellard
*/
#ifndef TCG_TARGET_MO_H
#define TCG_TARGET_MO_H
/*
* This defines the natural memory order supported by this architecture
* before guarantees made by various barrier instructions.
*
* The x86 has a pretty strong memory ordering which only really
* allows for some stores to be re-ordered after loads.
*/
#define TCG_TARGET_DEFAULT_MO (TCG_MO_ALL & ~TCG_MO_ST_LD)
#endif

View file

@ -24,14 +24,14 @@
* consider these to be UNSPEC with names.
*/
DEF(x86_shufps_vec, 1, 2, 1, IMPLVEC)
DEF(x86_blend_vec, 1, 2, 1, IMPLVEC)
DEF(x86_packss_vec, 1, 2, 0, IMPLVEC)
DEF(x86_packus_vec, 1, 2, 0, IMPLVEC)
DEF(x86_psrldq_vec, 1, 1, 1, IMPLVEC)
DEF(x86_vperm2i128_vec, 1, 2, 1, IMPLVEC)
DEF(x86_punpckl_vec, 1, 2, 0, IMPLVEC)
DEF(x86_punpckh_vec, 1, 2, 0, IMPLVEC)
DEF(x86_vpshldi_vec, 1, 2, 1, IMPLVEC)
DEF(x86_vpshldv_vec, 1, 3, 0, IMPLVEC)
DEF(x86_vpshrdv_vec, 1, 3, 0, IMPLVEC)
DEF(x86_shufps_vec, 1, 2, 1, TCG_OPF_VECTOR)
DEF(x86_blend_vec, 1, 2, 1, TCG_OPF_VECTOR)
DEF(x86_packss_vec, 1, 2, 0, TCG_OPF_VECTOR)
DEF(x86_packus_vec, 1, 2, 0, TCG_OPF_VECTOR)
DEF(x86_psrldq_vec, 1, 1, 1, TCG_OPF_VECTOR)
DEF(x86_vperm2i128_vec, 1, 2, 1, TCG_OPF_VECTOR)
DEF(x86_punpckl_vec, 1, 2, 0, TCG_OPF_VECTOR)
DEF(x86_punpckh_vec, 1, 2, 0, TCG_OPF_VECTOR)
DEF(x86_vpshldi_vec, 1, 2, 1, TCG_OPF_VECTOR)
DEF(x86_vpshldv_vec, 1, 3, 0, TCG_OPF_VECTOR)
DEF(x86_vpshrdv_vec, 1, 3, 0, TCG_OPF_VECTOR)

View file

@ -22,8 +22,25 @@
* THE SOFTWARE.
*/
#include "../tcg-ldst.c.inc"
#include "../tcg-pool.c.inc"
/* Used for function call generation. */
#define TCG_TARGET_STACK_ALIGN 16
#if defined(_WIN64)
#define TCG_TARGET_CALL_STACK_OFFSET 32
#else
#define TCG_TARGET_CALL_STACK_OFFSET 0
#endif
#define TCG_TARGET_CALL_ARG_I32 TCG_CALL_ARG_NORMAL
#define TCG_TARGET_CALL_ARG_I64 TCG_CALL_ARG_NORMAL
#if defined(_WIN64)
# define TCG_TARGET_CALL_ARG_I128 TCG_CALL_ARG_BY_REF
# define TCG_TARGET_CALL_RET_I128 TCG_CALL_RET_BY_VEC
#elif TCG_TARGET_REG_BITS == 64
# define TCG_TARGET_CALL_ARG_I128 TCG_CALL_ARG_NORMAL
# define TCG_TARGET_CALL_RET_I128 TCG_CALL_RET_NORMAL
#else
# define TCG_TARGET_CALL_ARG_I128 TCG_CALL_ARG_NORMAL
# define TCG_TARGET_CALL_RET_I128 TCG_CALL_RET_BY_REF
#endif
#ifdef CONFIG_DEBUG_TCG
static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
@ -1312,16 +1329,31 @@ static inline void tcg_out_rolw_8(TCGContext *s, int reg)
static void tcg_out_ext8u(TCGContext *s, TCGReg dest, TCGReg src)
{
/* movzbl */
tcg_debug_assert(src < 4 || TCG_TARGET_REG_BITS == 64);
if (TCG_TARGET_REG_BITS == 32 && src >= 4) {
tcg_out_mov(s, TCG_TYPE_I32, dest, src);
if (dest >= 4) {
tcg_out_modrm(s, OPC_ARITH_EvIz, ARITH_AND, dest);
tcg_out32(s, 0xff);
return;
}
src = dest;
}
tcg_out_modrm(s, OPC_MOVZBL + P_REXB_RM, dest, src);
}
static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
{
int rexw = type == TCG_TYPE_I32 ? 0 : P_REXW;
/* movsbl */
tcg_debug_assert(src < 4 || TCG_TARGET_REG_BITS == 64);
if (TCG_TARGET_REG_BITS == 32 && src >= 4) {
tcg_out_mov(s, TCG_TYPE_I32, dest, src);
if (dest >= 4) {
tcg_out_shifti(s, SHIFT_SHL, dest, 24);
tcg_out_shifti(s, SHIFT_SAR, dest, 24);
return;
}
src = dest;
}
tcg_out_modrm(s, OPC_MOVSBL + P_REXB_RM + rexw, dest, src);
}
@ -2595,17 +2627,16 @@ void tb_target_set_jmp_target(const TranslationBlock *tb, int n,
/* no need to flush icache explicitly */
}
static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
const TCGArg args[TCG_MAX_OP_ARGS],
const int const_args[TCG_MAX_OP_ARGS])
{
TCGArg a0, a1, a2;
int c, const_a2, vexop, rexw = 0;
int c, const_a2, vexop, rexw;
#if TCG_TARGET_REG_BITS == 64
# define OP_32_64(x) \
case glue(glue(INDEX_op_, x), _i64): \
rexw = P_REXW; /* FALLTHRU */ \
case glue(glue(INDEX_op_, x), _i32)
#else
# define OP_32_64(x) \
@ -2617,6 +2648,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
a1 = args[1];
a2 = args[2];
const_a2 = const_args[2];
rexw = type == TCG_TYPE_I32 ? 0 : P_REXW;
switch (opc) {
case INDEX_op_goto_ptr:
@ -3003,6 +3035,10 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
case INDEX_op_extract_i64:
if (a2 + args[3] == 32) {
if (a2 == 0) {
tcg_out_ext32u(s, a0, a1);
break;
}
/* This is a 32-bit zero-extending right shift. */
tcg_out_mov(s, TCG_TYPE_I32, a0, a1);
tcg_out_shifti(s, SHIFT_SHR, a0, a2);
@ -3010,29 +3046,54 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
}
/* FALLTHRU */
case INDEX_op_extract_i32:
/* On the off-chance that we can use the high-byte registers.
Otherwise we emit the same ext16 + shift pattern that we
would have gotten from the normal tcg-op.c expansion. */
tcg_debug_assert(a2 == 8 && args[3] == 8);
if (a2 == 0 && args[3] == 8) {
tcg_out_ext8u(s, a0, a1);
} else if (a2 == 0 && args[3] == 16) {
tcg_out_ext16u(s, a0, a1);
} else if (a2 == 8 && args[3] == 8) {
/*
* On the off-chance that we can use the high-byte registers.
* Otherwise we emit the same ext16 + shift pattern that we
* would have gotten from the normal tcg-op.c expansion.
*/
if (a1 < 4 && a0 < 8) {
tcg_out_modrm(s, OPC_MOVZBL, a0, a1 + 4);
} else {
tcg_out_ext16u(s, a0, a1);
tcg_out_shifti(s, SHIFT_SHR, a0, 8);
}
} else {
g_assert_not_reached();
}
break;
case INDEX_op_sextract_i64:
if (a2 == 0 && args[3] == 8) {
tcg_out_ext8s(s, TCG_TYPE_I64, a0, a1);
} else if (a2 == 0 && args[3] == 16) {
tcg_out_ext16s(s, TCG_TYPE_I64, a0, a1);
} else if (a2 == 0 && args[3] == 32) {
tcg_out_ext32s(s, a0, a1);
} else {
g_assert_not_reached();
}
break;
case INDEX_op_sextract_i32:
/* We don't implement sextract_i64, as we cannot sign-extend to
64-bits without using the REX prefix that explicitly excludes
access to the high-byte registers. */
tcg_debug_assert(a2 == 8 && args[3] == 8);
if (a2 == 0 && args[3] == 8) {
tcg_out_ext8s(s, TCG_TYPE_I32, a0, a1);
} else if (a2 == 0 && args[3] == 16) {
tcg_out_ext16s(s, TCG_TYPE_I32, a0, a1);
} else if (a2 == 8 && args[3] == 8) {
if (a1 < 4 && a0 < 8) {
tcg_out_modrm(s, OPC_MOVSBL, a0, a1 + 4);
} else {
tcg_out_ext16s(s, TCG_TYPE_I32, a0, a1);
tcg_out_shifti(s, SHIFT_SAR, a0, 8);
}
} else {
g_assert_not_reached();
}
break;
OP_32_64(extract2):
@ -3610,7 +3671,8 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
}
}
static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
static TCGConstraintSetIndex
tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
{
switch (op) {
case INDEX_op_goto_ptr:
@ -3713,6 +3775,7 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
case INDEX_op_extract_i32:
case INDEX_op_extract_i64:
case INDEX_op_sextract_i32:
case INDEX_op_sextract_i64:
case INDEX_op_ctpop_i32:
case INDEX_op_ctpop_i64:
return C_O1_I1(r, r);
@ -3868,7 +3931,7 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
return C_O1_I4(x, x, x, xO, x);
default:
g_assert_not_reached();
return C_NotImplemented;
}
}

View file

@ -25,8 +25,6 @@
#ifndef I386_TCG_TARGET_H
#define I386_TCG_TARGET_H
#include "host/cpuinfo.h"
#define TCG_TARGET_INSN_UNIT_SIZE 1
#ifdef __x86_64__
@ -90,164 +88,4 @@ typedef enum {
TCG_REG_CALL_STACK = TCG_REG_ESP
} TCGReg;
/* used for function call generation */
#define TCG_TARGET_STACK_ALIGN 16
#if defined(_WIN64)
#define TCG_TARGET_CALL_STACK_OFFSET 32
#else
#define TCG_TARGET_CALL_STACK_OFFSET 0
#endif
#define TCG_TARGET_CALL_ARG_I32 TCG_CALL_ARG_NORMAL
#define TCG_TARGET_CALL_ARG_I64 TCG_CALL_ARG_NORMAL
#if defined(_WIN64)
# define TCG_TARGET_CALL_ARG_I128 TCG_CALL_ARG_BY_REF
# define TCG_TARGET_CALL_RET_I128 TCG_CALL_RET_BY_VEC
#elif TCG_TARGET_REG_BITS == 64
# define TCG_TARGET_CALL_ARG_I128 TCG_CALL_ARG_NORMAL
# define TCG_TARGET_CALL_RET_I128 TCG_CALL_RET_NORMAL
#else
# define TCG_TARGET_CALL_ARG_I128 TCG_CALL_ARG_NORMAL
# define TCG_TARGET_CALL_RET_I128 TCG_CALL_RET_BY_REF
#endif
#define have_bmi1 (cpuinfo & CPUINFO_BMI1)
#define have_popcnt (cpuinfo & CPUINFO_POPCNT)
#define have_avx1 (cpuinfo & CPUINFO_AVX1)
#define have_avx2 (cpuinfo & CPUINFO_AVX2)
#define have_movbe (cpuinfo & CPUINFO_MOVBE)
/*
* There are interesting instructions in AVX512, so long as we have AVX512VL,
* which indicates support for EVEX on sizes smaller than 512 bits.
*/
#define have_avx512vl ((cpuinfo & CPUINFO_AVX512VL) && \
(cpuinfo & CPUINFO_AVX512F))
#define have_avx512bw ((cpuinfo & CPUINFO_AVX512BW) && have_avx512vl)
#define have_avx512dq ((cpuinfo & CPUINFO_AVX512DQ) && have_avx512vl)
#define have_avx512vbmi2 ((cpuinfo & CPUINFO_AVX512VBMI2) && have_avx512vl)
/* optional instructions */
#define TCG_TARGET_HAS_div2_i32 1
#define TCG_TARGET_HAS_rot_i32 1
#define TCG_TARGET_HAS_ext8s_i32 1
#define TCG_TARGET_HAS_ext16s_i32 1
#define TCG_TARGET_HAS_ext8u_i32 1
#define TCG_TARGET_HAS_ext16u_i32 1
#define TCG_TARGET_HAS_bswap16_i32 1
#define TCG_TARGET_HAS_bswap32_i32 1
#define TCG_TARGET_HAS_not_i32 1
#define TCG_TARGET_HAS_andc_i32 have_bmi1
#define TCG_TARGET_HAS_orc_i32 0
#define TCG_TARGET_HAS_eqv_i32 0
#define TCG_TARGET_HAS_nand_i32 0
#define TCG_TARGET_HAS_nor_i32 0
#define TCG_TARGET_HAS_clz_i32 1
#define TCG_TARGET_HAS_ctz_i32 1
#define TCG_TARGET_HAS_ctpop_i32 have_popcnt
#define TCG_TARGET_HAS_deposit_i32 1
#define TCG_TARGET_HAS_extract_i32 1
#define TCG_TARGET_HAS_sextract_i32 1
#define TCG_TARGET_HAS_extract2_i32 1
#define TCG_TARGET_HAS_negsetcond_i32 1
#define TCG_TARGET_HAS_add2_i32 1
#define TCG_TARGET_HAS_sub2_i32 1
#define TCG_TARGET_HAS_mulu2_i32 1
#define TCG_TARGET_HAS_muls2_i32 1
#define TCG_TARGET_HAS_muluh_i32 0
#define TCG_TARGET_HAS_mulsh_i32 0
#if TCG_TARGET_REG_BITS == 64
/* Keep 32-bit values zero-extended in a register. */
#define TCG_TARGET_HAS_extr_i64_i32 1
#define TCG_TARGET_HAS_div2_i64 1
#define TCG_TARGET_HAS_rot_i64 1
#define TCG_TARGET_HAS_ext8s_i64 1
#define TCG_TARGET_HAS_ext16s_i64 1
#define TCG_TARGET_HAS_ext32s_i64 1
#define TCG_TARGET_HAS_ext8u_i64 1
#define TCG_TARGET_HAS_ext16u_i64 1
#define TCG_TARGET_HAS_ext32u_i64 1
#define TCG_TARGET_HAS_bswap16_i64 1
#define TCG_TARGET_HAS_bswap32_i64 1
#define TCG_TARGET_HAS_bswap64_i64 1
#define TCG_TARGET_HAS_not_i64 1
#define TCG_TARGET_HAS_andc_i64 have_bmi1
#define TCG_TARGET_HAS_orc_i64 0
#define TCG_TARGET_HAS_eqv_i64 0
#define TCG_TARGET_HAS_nand_i64 0
#define TCG_TARGET_HAS_nor_i64 0
#define TCG_TARGET_HAS_clz_i64 1
#define TCG_TARGET_HAS_ctz_i64 1
#define TCG_TARGET_HAS_ctpop_i64 have_popcnt
#define TCG_TARGET_HAS_deposit_i64 1
#define TCG_TARGET_HAS_extract_i64 1
#define TCG_TARGET_HAS_sextract_i64 0
#define TCG_TARGET_HAS_extract2_i64 1
#define TCG_TARGET_HAS_negsetcond_i64 1
#define TCG_TARGET_HAS_add2_i64 1
#define TCG_TARGET_HAS_sub2_i64 1
#define TCG_TARGET_HAS_mulu2_i64 1
#define TCG_TARGET_HAS_muls2_i64 1
#define TCG_TARGET_HAS_muluh_i64 0
#define TCG_TARGET_HAS_mulsh_i64 0
#define TCG_TARGET_HAS_qemu_st8_i32 0
#else
#define TCG_TARGET_HAS_qemu_st8_i32 1
#endif
#define TCG_TARGET_HAS_qemu_ldst_i128 \
(TCG_TARGET_REG_BITS == 64 && (cpuinfo & CPUINFO_ATOMIC_VMOVDQA))
#define TCG_TARGET_HAS_tst 1
/* We do not support older SSE systems, only beginning with AVX1. */
#define TCG_TARGET_HAS_v64 have_avx1
#define TCG_TARGET_HAS_v128 have_avx1
#define TCG_TARGET_HAS_v256 have_avx2
#define TCG_TARGET_HAS_andc_vec 1
#define TCG_TARGET_HAS_orc_vec have_avx512vl
#define TCG_TARGET_HAS_nand_vec have_avx512vl
#define TCG_TARGET_HAS_nor_vec have_avx512vl
#define TCG_TARGET_HAS_eqv_vec have_avx512vl
#define TCG_TARGET_HAS_not_vec have_avx512vl
#define TCG_TARGET_HAS_neg_vec 0
#define TCG_TARGET_HAS_abs_vec 1
#define TCG_TARGET_HAS_roti_vec have_avx512vl
#define TCG_TARGET_HAS_rots_vec 0
#define TCG_TARGET_HAS_rotv_vec have_avx512vl
#define TCG_TARGET_HAS_shi_vec 1
#define TCG_TARGET_HAS_shs_vec 1
#define TCG_TARGET_HAS_shv_vec have_avx2
#define TCG_TARGET_HAS_mul_vec 1
#define TCG_TARGET_HAS_sat_vec 1
#define TCG_TARGET_HAS_minmax_vec 1
#define TCG_TARGET_HAS_bitsel_vec have_avx512vl
#define TCG_TARGET_HAS_cmpsel_vec 1
#define TCG_TARGET_HAS_tst_vec have_avx512bw
#define TCG_TARGET_deposit_i32_valid(ofs, len) \
(((ofs) == 0 && ((len) == 8 || (len) == 16)) || \
(TCG_TARGET_REG_BITS == 32 && (ofs) == 8 && (len) == 8))
#define TCG_TARGET_deposit_i64_valid TCG_TARGET_deposit_i32_valid
/* Check for the possibility of high-byte extraction and, for 64-bit,
zero-extending 32-bit right-shift. */
#define TCG_TARGET_extract_i32_valid(ofs, len) ((ofs) == 8 && (len) == 8)
#define TCG_TARGET_extract_i64_valid(ofs, len) \
(((ofs) == 8 && (len) == 8) || ((ofs) + (len)) == 32)
/* This defines the natural memory order supported by this
* architecture before guarantees made by various barrier
* instructions.
*
* The x86 has a pretty strong memory ordering which only really
* allows for some stores to be re-ordered after loads.
*/
#include "tcg/tcg-mo.h"
#define TCG_TARGET_DEFAULT_MO (TCG_MO_ALL & ~TCG_MO_ST_LD)
#define TCG_TARGET_NEED_LDST_LABELS
#define TCG_TARGET_NEED_POOL_LABELS
#endif

View file

@ -0,0 +1,119 @@
/* SPDX-License-Identifier: MIT */
/*
* Define target-specific opcode support
* Copyright (c) 2021 WANG Xuerui <git@xen0n.name>
*/
#ifndef TCG_TARGET_HAS_H
#define TCG_TARGET_HAS_H
#include "host/cpuinfo.h"
/* optional instructions */
#define TCG_TARGET_HAS_negsetcond_i32 0
#define TCG_TARGET_HAS_div_i32 1
#define TCG_TARGET_HAS_rem_i32 1
#define TCG_TARGET_HAS_div2_i32 0
#define TCG_TARGET_HAS_rot_i32 1
#define TCG_TARGET_HAS_extract2_i32 0
#define TCG_TARGET_HAS_add2_i32 0
#define TCG_TARGET_HAS_sub2_i32 0
#define TCG_TARGET_HAS_mulu2_i32 0
#define TCG_TARGET_HAS_muls2_i32 0
#define TCG_TARGET_HAS_muluh_i32 1
#define TCG_TARGET_HAS_mulsh_i32 1
#define TCG_TARGET_HAS_ext8s_i32 1
#define TCG_TARGET_HAS_ext16s_i32 1
#define TCG_TARGET_HAS_ext8u_i32 1
#define TCG_TARGET_HAS_ext16u_i32 1
#define TCG_TARGET_HAS_bswap16_i32 1
#define TCG_TARGET_HAS_bswap32_i32 1
#define TCG_TARGET_HAS_not_i32 1
#define TCG_TARGET_HAS_andc_i32 1
#define TCG_TARGET_HAS_orc_i32 1
#define TCG_TARGET_HAS_eqv_i32 0
#define TCG_TARGET_HAS_nand_i32 0
#define TCG_TARGET_HAS_nor_i32 1
#define TCG_TARGET_HAS_clz_i32 1
#define TCG_TARGET_HAS_ctz_i32 1
#define TCG_TARGET_HAS_ctpop_i32 0
#define TCG_TARGET_HAS_brcond2 0
#define TCG_TARGET_HAS_setcond2 0
#define TCG_TARGET_HAS_qemu_st8_i32 0
/* 64-bit operations */
#define TCG_TARGET_HAS_negsetcond_i64 0
#define TCG_TARGET_HAS_div_i64 1
#define TCG_TARGET_HAS_rem_i64 1
#define TCG_TARGET_HAS_div2_i64 0
#define TCG_TARGET_HAS_rot_i64 1
#define TCG_TARGET_HAS_extract2_i64 0
#define TCG_TARGET_HAS_extr_i64_i32 1
#define TCG_TARGET_HAS_ext8s_i64 1
#define TCG_TARGET_HAS_ext16s_i64 1
#define TCG_TARGET_HAS_ext32s_i64 1
#define TCG_TARGET_HAS_ext8u_i64 1
#define TCG_TARGET_HAS_ext16u_i64 1
#define TCG_TARGET_HAS_ext32u_i64 1
#define TCG_TARGET_HAS_bswap16_i64 1
#define TCG_TARGET_HAS_bswap32_i64 1
#define TCG_TARGET_HAS_bswap64_i64 1
#define TCG_TARGET_HAS_not_i64 1
#define TCG_TARGET_HAS_andc_i64 1
#define TCG_TARGET_HAS_orc_i64 1
#define TCG_TARGET_HAS_eqv_i64 0
#define TCG_TARGET_HAS_nand_i64 0
#define TCG_TARGET_HAS_nor_i64 1
#define TCG_TARGET_HAS_clz_i64 1
#define TCG_TARGET_HAS_ctz_i64 1
#define TCG_TARGET_HAS_ctpop_i64 0
#define TCG_TARGET_HAS_add2_i64 0
#define TCG_TARGET_HAS_sub2_i64 0
#define TCG_TARGET_HAS_mulu2_i64 0
#define TCG_TARGET_HAS_muls2_i64 0
#define TCG_TARGET_HAS_muluh_i64 1
#define TCG_TARGET_HAS_mulsh_i64 1
#define TCG_TARGET_HAS_qemu_ldst_i128 (cpuinfo & CPUINFO_LSX)
#define TCG_TARGET_HAS_tst 0
#define TCG_TARGET_HAS_v64 (cpuinfo & CPUINFO_LSX)
#define TCG_TARGET_HAS_v128 (cpuinfo & CPUINFO_LSX)
#define TCG_TARGET_HAS_v256 (cpuinfo & CPUINFO_LASX)
#define TCG_TARGET_HAS_not_vec 1
#define TCG_TARGET_HAS_neg_vec 1
#define TCG_TARGET_HAS_abs_vec 0
#define TCG_TARGET_HAS_andc_vec 1
#define TCG_TARGET_HAS_orc_vec 1
#define TCG_TARGET_HAS_nand_vec 0
#define TCG_TARGET_HAS_nor_vec 1
#define TCG_TARGET_HAS_eqv_vec 0
#define TCG_TARGET_HAS_mul_vec 1
#define TCG_TARGET_HAS_shi_vec 1
#define TCG_TARGET_HAS_shs_vec 0
#define TCG_TARGET_HAS_shv_vec 1
#define TCG_TARGET_HAS_roti_vec 1
#define TCG_TARGET_HAS_rots_vec 0
#define TCG_TARGET_HAS_rotv_vec 1
#define TCG_TARGET_HAS_sat_vec 1
#define TCG_TARGET_HAS_minmax_vec 1
#define TCG_TARGET_HAS_bitsel_vec 1
#define TCG_TARGET_HAS_cmpsel_vec 0
#define TCG_TARGET_HAS_tst_vec 0
#define TCG_TARGET_extract_valid(type, ofs, len) 1
#define TCG_TARGET_deposit_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

View file

@ -0,0 +1,12 @@
/* SPDX-License-Identifier: MIT */
/*
* Define target-specific memory model
* Copyright (c) 2021 WANG Xuerui <git@xen0n.name>
*/
#ifndef TCG_TARGET_MO_H
#define TCG_TARGET_MO_H
#define TCG_TARGET_DEFAULT_MO 0
#endif

View file

@ -29,9 +29,17 @@
* THE SOFTWARE.
*/
#include "../tcg-ldst.c.inc"
#include <asm/hwcap.h>
/* used for function call generation */
#define TCG_REG_CALL_STACK TCG_REG_SP
#define TCG_TARGET_STACK_ALIGN 16
#define TCG_TARGET_CALL_STACK_OFFSET 0
#define TCG_TARGET_CALL_ARG_I32 TCG_CALL_ARG_NORMAL
#define TCG_TARGET_CALL_ARG_I64 TCG_CALL_ARG_NORMAL
#define TCG_TARGET_CALL_ARG_I128 TCG_CALL_ARG_NORMAL
#define TCG_TARGET_CALL_RET_I128 TCG_CALL_RET_NORMAL
#ifdef CONFIG_DEBUG_TCG
static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
"zero",
@ -1270,7 +1278,7 @@ void tb_target_set_jmp_target(const TranslationBlock *tb, int n,
flush_idcache_range(jmp_rx, jmp_rw, 4);
}
static void tcg_out_op(TCGContext *s, TCGOpcode opc,
static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
const TCGArg args[TCG_MAX_OP_ARGS],
const int const_args[TCG_MAX_OP_ARGS])
{
@ -1367,10 +1375,38 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
break;
case INDEX_op_extract_i32:
if (a2 == 0 && args[3] <= 12) {
tcg_out_opc_andi(s, a0, a1, (1 << args[3]) - 1);
} else {
tcg_out_opc_bstrpick_w(s, a0, a1, a2, a2 + args[3] - 1);
}
break;
case INDEX_op_extract_i64:
if (a2 == 0 && args[3] <= 12) {
tcg_out_opc_andi(s, a0, a1, (1 << args[3]) - 1);
} else {
tcg_out_opc_bstrpick_d(s, a0, a1, a2, a2 + args[3] - 1);
}
break;
case INDEX_op_sextract_i64:
if (a2 + args[3] == 32) {
if (a2 == 0) {
tcg_out_ext32s(s, a0, a1);
} else {
tcg_out_opc_srai_w(s, a0, a1, a2);
}
break;
}
/* FALLTHRU */
case INDEX_op_sextract_i32:
if (a2 == 0 && args[3] == 8) {
tcg_out_ext8s(s, TCG_TYPE_REG, a0, a1);
} else if (a2 == 0 && args[3] == 16) {
tcg_out_ext16s(s, TCG_TYPE_REG, a0, a1);
} else {
g_assert_not_reached();
}
break;
case INDEX_op_deposit_i32:
@ -2183,7 +2219,8 @@ void tcg_expand_vec_op(TCGOpcode opc, TCGType type, unsigned vece,
g_assert_not_reached();
}
static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
static TCGConstraintSetIndex
tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
{
switch (op) {
case INDEX_op_goto_ptr:
@ -2234,6 +2271,8 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
case INDEX_op_not_i64:
case INDEX_op_extract_i32:
case INDEX_op_extract_i64:
case INDEX_op_sextract_i32:
case INDEX_op_sextract_i64:
case INDEX_op_bswap16_i32:
case INDEX_op_bswap16_i64:
case INDEX_op_bswap32_i32:
@ -2383,7 +2422,7 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
return C_O1_I3(w, w, w, w);
default:
g_assert_not_reached();
return C_NotImplemented;
}
}
@ -2456,6 +2495,14 @@ static void tcg_out_tb_start(TCGContext *s)
/* nothing to do */
}
static void tcg_out_nop_fill(tcg_insn_unit *p, int count)
{
for (int i = 0; i < count; ++i) {
/* Canonical nop is andi r0,r0,0 */
p[i] = OPC_ANDI;
}
}
static void tcg_target_init(TCGContext *s)
{
unsigned long hwcap = qemu_getauxval(AT_HWCAP);

View file

@ -29,8 +29,6 @@
#ifndef LOONGARCH_TCG_TARGET_H
#define LOONGARCH_TCG_TARGET_H
#include "host/cpuinfo.h"
#define TCG_TARGET_INSN_UNIT_SIZE 4
#define TCG_TARGET_NB_REGS 64
@ -87,117 +85,4 @@ typedef enum {
TCG_VEC_TMP0 = TCG_REG_V23,
} TCGReg;
/* used for function call generation */
#define TCG_REG_CALL_STACK TCG_REG_SP
#define TCG_TARGET_STACK_ALIGN 16
#define TCG_TARGET_CALL_STACK_OFFSET 0
#define TCG_TARGET_CALL_ARG_I32 TCG_CALL_ARG_NORMAL
#define TCG_TARGET_CALL_ARG_I64 TCG_CALL_ARG_NORMAL
#define TCG_TARGET_CALL_ARG_I128 TCG_CALL_ARG_NORMAL
#define TCG_TARGET_CALL_RET_I128 TCG_CALL_RET_NORMAL
/* optional instructions */
#define TCG_TARGET_HAS_negsetcond_i32 0
#define TCG_TARGET_HAS_div_i32 1
#define TCG_TARGET_HAS_rem_i32 1
#define TCG_TARGET_HAS_div2_i32 0
#define TCG_TARGET_HAS_rot_i32 1
#define TCG_TARGET_HAS_deposit_i32 1
#define TCG_TARGET_HAS_extract_i32 1
#define TCG_TARGET_HAS_sextract_i32 0
#define TCG_TARGET_HAS_extract2_i32 0
#define TCG_TARGET_HAS_add2_i32 0
#define TCG_TARGET_HAS_sub2_i32 0
#define TCG_TARGET_HAS_mulu2_i32 0
#define TCG_TARGET_HAS_muls2_i32 0
#define TCG_TARGET_HAS_muluh_i32 1
#define TCG_TARGET_HAS_mulsh_i32 1
#define TCG_TARGET_HAS_ext8s_i32 1
#define TCG_TARGET_HAS_ext16s_i32 1
#define TCG_TARGET_HAS_ext8u_i32 1
#define TCG_TARGET_HAS_ext16u_i32 1
#define TCG_TARGET_HAS_bswap16_i32 1
#define TCG_TARGET_HAS_bswap32_i32 1
#define TCG_TARGET_HAS_not_i32 1
#define TCG_TARGET_HAS_andc_i32 1
#define TCG_TARGET_HAS_orc_i32 1
#define TCG_TARGET_HAS_eqv_i32 0
#define TCG_TARGET_HAS_nand_i32 0
#define TCG_TARGET_HAS_nor_i32 1
#define TCG_TARGET_HAS_clz_i32 1
#define TCG_TARGET_HAS_ctz_i32 1
#define TCG_TARGET_HAS_ctpop_i32 0
#define TCG_TARGET_HAS_brcond2 0
#define TCG_TARGET_HAS_setcond2 0
#define TCG_TARGET_HAS_qemu_st8_i32 0
/* 64-bit operations */
#define TCG_TARGET_HAS_negsetcond_i64 0
#define TCG_TARGET_HAS_div_i64 1
#define TCG_TARGET_HAS_rem_i64 1
#define TCG_TARGET_HAS_div2_i64 0
#define TCG_TARGET_HAS_rot_i64 1
#define TCG_TARGET_HAS_deposit_i64 1
#define TCG_TARGET_HAS_extract_i64 1
#define TCG_TARGET_HAS_sextract_i64 0
#define TCG_TARGET_HAS_extract2_i64 0
#define TCG_TARGET_HAS_extr_i64_i32 1
#define TCG_TARGET_HAS_ext8s_i64 1
#define TCG_TARGET_HAS_ext16s_i64 1
#define TCG_TARGET_HAS_ext32s_i64 1
#define TCG_TARGET_HAS_ext8u_i64 1
#define TCG_TARGET_HAS_ext16u_i64 1
#define TCG_TARGET_HAS_ext32u_i64 1
#define TCG_TARGET_HAS_bswap16_i64 1
#define TCG_TARGET_HAS_bswap32_i64 1
#define TCG_TARGET_HAS_bswap64_i64 1
#define TCG_TARGET_HAS_not_i64 1
#define TCG_TARGET_HAS_andc_i64 1
#define TCG_TARGET_HAS_orc_i64 1
#define TCG_TARGET_HAS_eqv_i64 0
#define TCG_TARGET_HAS_nand_i64 0
#define TCG_TARGET_HAS_nor_i64 1
#define TCG_TARGET_HAS_clz_i64 1
#define TCG_TARGET_HAS_ctz_i64 1
#define TCG_TARGET_HAS_ctpop_i64 0
#define TCG_TARGET_HAS_add2_i64 0
#define TCG_TARGET_HAS_sub2_i64 0
#define TCG_TARGET_HAS_mulu2_i64 0
#define TCG_TARGET_HAS_muls2_i64 0
#define TCG_TARGET_HAS_muluh_i64 1
#define TCG_TARGET_HAS_mulsh_i64 1
#define TCG_TARGET_HAS_qemu_ldst_i128 (cpuinfo & CPUINFO_LSX)
#define TCG_TARGET_HAS_tst 0
#define TCG_TARGET_HAS_v64 (cpuinfo & CPUINFO_LSX)
#define TCG_TARGET_HAS_v128 (cpuinfo & CPUINFO_LSX)
#define TCG_TARGET_HAS_v256 (cpuinfo & CPUINFO_LASX)
#define TCG_TARGET_HAS_not_vec 1
#define TCG_TARGET_HAS_neg_vec 1
#define TCG_TARGET_HAS_abs_vec 0
#define TCG_TARGET_HAS_andc_vec 1
#define TCG_TARGET_HAS_orc_vec 1
#define TCG_TARGET_HAS_nand_vec 0
#define TCG_TARGET_HAS_nor_vec 1
#define TCG_TARGET_HAS_eqv_vec 0
#define TCG_TARGET_HAS_mul_vec 1
#define TCG_TARGET_HAS_shi_vec 1
#define TCG_TARGET_HAS_shs_vec 0
#define TCG_TARGET_HAS_shv_vec 1
#define TCG_TARGET_HAS_roti_vec 1
#define TCG_TARGET_HAS_rots_vec 0
#define TCG_TARGET_HAS_rotv_vec 1
#define TCG_TARGET_HAS_sat_vec 1
#define TCG_TARGET_HAS_minmax_vec 1
#define TCG_TARGET_HAS_bitsel_vec 1
#define TCG_TARGET_HAS_cmpsel_vec 0
#define TCG_TARGET_HAS_tst_vec 0
#define TCG_TARGET_DEFAULT_MO (0)
#define TCG_TARGET_NEED_LDST_LABELS
#endif /* LOONGARCH_TCG_TARGET_H */

135
tcg/mips/tcg-target-has.h Normal file
View file

@ -0,0 +1,135 @@
/* SPDX-License-Identifier: MIT */
/*
* Define target-specific opcode support
* Copyright (c) 2008-2009 Arnaud Patard <arnaud.patard@rtp-net.org>
* Copyright (c) 2009 Aurelien Jarno <aurelien@aurel32.net>
*/
#ifndef TCG_TARGET_HAS_H
#define TCG_TARGET_HAS_H
/* MOVN/MOVZ instructions detection */
#if (defined(__mips_isa_rev) && (__mips_isa_rev >= 1)) || \
defined(_MIPS_ARCH_LOONGSON2E) || defined(_MIPS_ARCH_LOONGSON2F) || \
defined(_MIPS_ARCH_MIPS4)
#define use_movnz_instructions 1
#else
extern bool use_movnz_instructions;
#endif
/* MIPS32 instruction set detection */
#if defined(__mips_isa_rev) && (__mips_isa_rev >= 1)
#define use_mips32_instructions 1
#else
extern bool use_mips32_instructions;
#endif
/* MIPS32R2 instruction set detection */
#if defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
#define use_mips32r2_instructions 1
#else
extern bool use_mips32r2_instructions;
#endif
/* MIPS32R6 instruction set detection */
#if defined(__mips_isa_rev) && (__mips_isa_rev >= 6)
#define use_mips32r6_instructions 1
#else
#define use_mips32r6_instructions 0
#endif
/* optional instructions */
#define TCG_TARGET_HAS_div_i32 1
#define TCG_TARGET_HAS_rem_i32 1
#define TCG_TARGET_HAS_not_i32 1
#define TCG_TARGET_HAS_nor_i32 1
#define TCG_TARGET_HAS_andc_i32 0
#define TCG_TARGET_HAS_orc_i32 0
#define TCG_TARGET_HAS_eqv_i32 0
#define TCG_TARGET_HAS_nand_i32 0
#define TCG_TARGET_HAS_mulu2_i32 (!use_mips32r6_instructions)
#define TCG_TARGET_HAS_muls2_i32 (!use_mips32r6_instructions)
#define TCG_TARGET_HAS_muluh_i32 1
#define TCG_TARGET_HAS_mulsh_i32 1
#define TCG_TARGET_HAS_bswap16_i32 1
#define TCG_TARGET_HAS_bswap32_i32 1
#define TCG_TARGET_HAS_negsetcond_i32 0
#if TCG_TARGET_REG_BITS == 64
#define TCG_TARGET_HAS_add2_i32 0
#define TCG_TARGET_HAS_sub2_i32 0
#define TCG_TARGET_HAS_extr_i64_i32 1
#define TCG_TARGET_HAS_div_i64 1
#define TCG_TARGET_HAS_rem_i64 1
#define TCG_TARGET_HAS_not_i64 1
#define TCG_TARGET_HAS_nor_i64 1
#define TCG_TARGET_HAS_andc_i64 0
#define TCG_TARGET_HAS_orc_i64 0
#define TCG_TARGET_HAS_eqv_i64 0
#define TCG_TARGET_HAS_nand_i64 0
#define TCG_TARGET_HAS_add2_i64 0
#define TCG_TARGET_HAS_sub2_i64 0
#define TCG_TARGET_HAS_mulu2_i64 (!use_mips32r6_instructions)
#define TCG_TARGET_HAS_muls2_i64 (!use_mips32r6_instructions)
#define TCG_TARGET_HAS_muluh_i64 1
#define TCG_TARGET_HAS_mulsh_i64 1
#define TCG_TARGET_HAS_ext32s_i64 1
#define TCG_TARGET_HAS_ext32u_i64 1
#define TCG_TARGET_HAS_negsetcond_i64 0
#endif
/* optional instructions detected at runtime */
#define TCG_TARGET_HAS_extract2_i32 0
#define TCG_TARGET_HAS_ext8s_i32 use_mips32r2_instructions
#define TCG_TARGET_HAS_ext16s_i32 use_mips32r2_instructions
#define TCG_TARGET_HAS_rot_i32 use_mips32r2_instructions
#define TCG_TARGET_HAS_clz_i32 use_mips32r2_instructions
#define TCG_TARGET_HAS_ctz_i32 0
#define TCG_TARGET_HAS_ctpop_i32 0
#define TCG_TARGET_HAS_qemu_st8_i32 0
#if TCG_TARGET_REG_BITS == 64
#define TCG_TARGET_HAS_bswap16_i64 1
#define TCG_TARGET_HAS_bswap32_i64 1
#define TCG_TARGET_HAS_bswap64_i64 1
#define TCG_TARGET_HAS_extract2_i64 0
#define TCG_TARGET_HAS_ext8s_i64 use_mips32r2_instructions
#define TCG_TARGET_HAS_ext16s_i64 use_mips32r2_instructions
#define TCG_TARGET_HAS_rot_i64 use_mips32r2_instructions
#define TCG_TARGET_HAS_clz_i64 use_mips32r2_instructions
#define TCG_TARGET_HAS_ctz_i64 0
#define TCG_TARGET_HAS_ctpop_i64 0
#endif
/* optional instructions automatically implemented */
#define TCG_TARGET_HAS_ext8u_i32 0 /* andi rt, rs, 0xff */
#define TCG_TARGET_HAS_ext16u_i32 0 /* andi rt, rs, 0xffff */
#if TCG_TARGET_REG_BITS == 64
#define TCG_TARGET_HAS_ext8u_i64 0 /* andi rt, rs, 0xff */
#define TCG_TARGET_HAS_ext16u_i64 0 /* andi rt, rs, 0xffff */
#endif
#define TCG_TARGET_HAS_qemu_ldst_i128 0
#define TCG_TARGET_HAS_tst 0
#define TCG_TARGET_extract_valid(type, ofs, len) use_mips32r2_instructions
#define TCG_TARGET_deposit_valid(type, ofs, len) use_mips32r2_instructions
static inline bool
tcg_target_sextract_valid(TCGType type, unsigned ofs, unsigned len)
{
if (ofs == 0) {
switch (len) {
case 8:
case 16:
return use_mips32r2_instructions;
case 32:
return type == TCG_TYPE_I64;
}
}
return false;
}
#define TCG_TARGET_sextract_valid tcg_target_sextract_valid
#endif

13
tcg/mips/tcg-target-mo.h Normal file
View file

@ -0,0 +1,13 @@
/* SPDX-License-Identifier: MIT */
/*
* Define target-specific memory model
* Copyright (c) 2008-2009 Arnaud Patard <arnaud.patard@rtp-net.org>
* Copyright (c) 2009 Aurelien Jarno <aurelien@aurel32.net>
*/
#ifndef TCG_TARGET_MO_H
#define TCG_TARGET_MO_H
#define TCG_TARGET_DEFAULT_MO 0
#endif

View file

@ -0,0 +1 @@
/* No target specific opcodes. */

View file

@ -24,8 +24,19 @@
* THE SOFTWARE.
*/
#include "../tcg-ldst.c.inc"
#include "../tcg-pool.c.inc"
/* used for function call generation */
#define TCG_TARGET_STACK_ALIGN 16
#if _MIPS_SIM == _ABIO32
# define TCG_TARGET_CALL_STACK_OFFSET 16
# define TCG_TARGET_CALL_ARG_I64 TCG_CALL_ARG_EVEN
# define TCG_TARGET_CALL_RET_I128 TCG_CALL_RET_BY_REF
#else
# define TCG_TARGET_CALL_STACK_OFFSET 0
# define TCG_TARGET_CALL_ARG_I64 TCG_CALL_ARG_NORMAL
# define TCG_TARGET_CALL_RET_I128 TCG_CALL_RET_NORMAL
#endif
#define TCG_TARGET_CALL_ARG_I32 TCG_CALL_ARG_NORMAL
#define TCG_TARGET_CALL_ARG_I128 TCG_CALL_ARG_EVEN
#if TCG_TARGET_REG_BITS == 32
# define LO_OFF (HOST_BIG_ENDIAN * 4)
@ -1667,7 +1678,7 @@ void tb_target_set_jmp_target(const TranslationBlock *tb, int n,
/* Always indirect, nothing to do */
}
static void tcg_out_op(TCGContext *s, TCGOpcode opc,
static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
const TCGArg args[TCG_MAX_OP_ARGS],
const int const_args[TCG_MAX_OP_ARGS])
{
@ -2030,12 +2041,37 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
tcg_out_opc_bf64(s, OPC_DINS, OPC_DINSM, OPC_DINSU, a0, a2,
args[3] + args[4] - 1, args[3]);
break;
case INDEX_op_extract_i32:
if (a2 == 0 && args[3] <= 16) {
tcg_out_opc_imm(s, OPC_ANDI, a0, a1, (1 << args[3]) - 1);
} else {
tcg_out_opc_bf(s, OPC_EXT, a0, a1, args[3] - 1, a2);
}
break;
case INDEX_op_extract_i64:
tcg_out_opc_bf64(s, OPC_DEXT, OPC_DEXTM, OPC_DEXTU, a0, a1,
args[3] - 1, a2);
if (a2 == 0 && args[3] <= 16) {
tcg_out_opc_imm(s, OPC_ANDI, a0, a1, (1 << args[3]) - 1);
} else {
tcg_out_opc_bf64(s, OPC_DEXT, OPC_DEXTM, OPC_DEXTU,
a0, a1, args[3] - 1, a2);
}
break;
case INDEX_op_sextract_i64:
if (a2 == 0 && args[3] == 32) {
tcg_out_ext32s(s, a0, a1);
break;
}
/* FALLTHRU */
case INDEX_op_sextract_i32:
if (a2 == 0 && args[3] == 8) {
tcg_out_ext8s(s, TCG_TYPE_REG, a0, a1);
} else if (a2 == 0 && args[3] == 16) {
tcg_out_ext16s(s, TCG_TYPE_REG, a0, a1);
} else {
g_assert_not_reached();
}
break;
case INDEX_op_brcond_i32:
@ -2140,7 +2176,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
}
}
static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
static TCGConstraintSetIndex
tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
{
switch (op) {
case INDEX_op_goto_ptr:
@ -2158,6 +2195,7 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
case INDEX_op_ext8s_i32:
case INDEX_op_ext16s_i32:
case INDEX_op_extract_i32:
case INDEX_op_sextract_i32:
case INDEX_op_ld8u_i64:
case INDEX_op_ld8s_i64:
case INDEX_op_ld16u_i64:
@ -2179,6 +2217,7 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
case INDEX_op_extrl_i64_i32:
case INDEX_op_extrh_i64_i32:
case INDEX_op_extract_i64:
case INDEX_op_sextract_i64:
return C_O1_I1(r, r);
case INDEX_op_st8_i32:
@ -2281,7 +2320,7 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
: C_O0_I4(rZ, rZ, r, r));
default:
g_assert_not_reached();
return C_NotImplemented;
}
}

View file

@ -70,134 +70,4 @@ typedef enum {
TCG_AREG0 = TCG_REG_S8,
} TCGReg;
/* used for function call generation */
#define TCG_TARGET_STACK_ALIGN 16
#if _MIPS_SIM == _ABIO32
# define TCG_TARGET_CALL_STACK_OFFSET 16
# define TCG_TARGET_CALL_ARG_I64 TCG_CALL_ARG_EVEN
# define TCG_TARGET_CALL_RET_I128 TCG_CALL_RET_BY_REF
#else
# define TCG_TARGET_CALL_STACK_OFFSET 0
# define TCG_TARGET_CALL_ARG_I64 TCG_CALL_ARG_NORMAL
# define TCG_TARGET_CALL_RET_I128 TCG_CALL_RET_NORMAL
#endif
#define TCG_TARGET_CALL_ARG_I32 TCG_CALL_ARG_NORMAL
#define TCG_TARGET_CALL_ARG_I128 TCG_CALL_ARG_EVEN
/* MOVN/MOVZ instructions detection */
#if (defined(__mips_isa_rev) && (__mips_isa_rev >= 1)) || \
defined(_MIPS_ARCH_LOONGSON2E) || defined(_MIPS_ARCH_LOONGSON2F) || \
defined(_MIPS_ARCH_MIPS4)
#define use_movnz_instructions 1
#else
extern bool use_movnz_instructions;
#endif
/* MIPS32 instruction set detection */
#if defined(__mips_isa_rev) && (__mips_isa_rev >= 1)
#define use_mips32_instructions 1
#else
extern bool use_mips32_instructions;
#endif
/* MIPS32R2 instruction set detection */
#if defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
#define use_mips32r2_instructions 1
#else
extern bool use_mips32r2_instructions;
#endif
/* MIPS32R6 instruction set detection */
#if defined(__mips_isa_rev) && (__mips_isa_rev >= 6)
#define use_mips32r6_instructions 1
#else
#define use_mips32r6_instructions 0
#endif
/* optional instructions */
#define TCG_TARGET_HAS_div_i32 1
#define TCG_TARGET_HAS_rem_i32 1
#define TCG_TARGET_HAS_not_i32 1
#define TCG_TARGET_HAS_nor_i32 1
#define TCG_TARGET_HAS_andc_i32 0
#define TCG_TARGET_HAS_orc_i32 0
#define TCG_TARGET_HAS_eqv_i32 0
#define TCG_TARGET_HAS_nand_i32 0
#define TCG_TARGET_HAS_mulu2_i32 (!use_mips32r6_instructions)
#define TCG_TARGET_HAS_muls2_i32 (!use_mips32r6_instructions)
#define TCG_TARGET_HAS_muluh_i32 1
#define TCG_TARGET_HAS_mulsh_i32 1
#define TCG_TARGET_HAS_bswap32_i32 1
#define TCG_TARGET_HAS_negsetcond_i32 0
#if TCG_TARGET_REG_BITS == 64
#define TCG_TARGET_HAS_add2_i32 0
#define TCG_TARGET_HAS_sub2_i32 0
#define TCG_TARGET_HAS_extr_i64_i32 1
#define TCG_TARGET_HAS_div_i64 1
#define TCG_TARGET_HAS_rem_i64 1
#define TCG_TARGET_HAS_not_i64 1
#define TCG_TARGET_HAS_nor_i64 1
#define TCG_TARGET_HAS_andc_i64 0
#define TCG_TARGET_HAS_orc_i64 0
#define TCG_TARGET_HAS_eqv_i64 0
#define TCG_TARGET_HAS_nand_i64 0
#define TCG_TARGET_HAS_add2_i64 0
#define TCG_TARGET_HAS_sub2_i64 0
#define TCG_TARGET_HAS_mulu2_i64 (!use_mips32r6_instructions)
#define TCG_TARGET_HAS_muls2_i64 (!use_mips32r6_instructions)
#define TCG_TARGET_HAS_muluh_i64 1
#define TCG_TARGET_HAS_mulsh_i64 1
#define TCG_TARGET_HAS_ext32s_i64 1
#define TCG_TARGET_HAS_ext32u_i64 1
#define TCG_TARGET_HAS_negsetcond_i64 0
#endif
/* optional instructions detected at runtime */
#define TCG_TARGET_HAS_bswap16_i32 use_mips32r2_instructions
#define TCG_TARGET_HAS_deposit_i32 use_mips32r2_instructions
#define TCG_TARGET_HAS_extract_i32 use_mips32r2_instructions
#define TCG_TARGET_HAS_sextract_i32 0
#define TCG_TARGET_HAS_extract2_i32 0
#define TCG_TARGET_HAS_ext8s_i32 use_mips32r2_instructions
#define TCG_TARGET_HAS_ext16s_i32 use_mips32r2_instructions
#define TCG_TARGET_HAS_rot_i32 use_mips32r2_instructions
#define TCG_TARGET_HAS_clz_i32 use_mips32r2_instructions
#define TCG_TARGET_HAS_ctz_i32 0
#define TCG_TARGET_HAS_ctpop_i32 0
#define TCG_TARGET_HAS_qemu_st8_i32 0
#if TCG_TARGET_REG_BITS == 64
#define TCG_TARGET_HAS_bswap16_i64 use_mips32r2_instructions
#define TCG_TARGET_HAS_bswap32_i64 use_mips32r2_instructions
#define TCG_TARGET_HAS_bswap64_i64 use_mips32r2_instructions
#define TCG_TARGET_HAS_deposit_i64 use_mips32r2_instructions
#define TCG_TARGET_HAS_extract_i64 use_mips32r2_instructions
#define TCG_TARGET_HAS_sextract_i64 0
#define TCG_TARGET_HAS_extract2_i64 0
#define TCG_TARGET_HAS_ext8s_i64 use_mips32r2_instructions
#define TCG_TARGET_HAS_ext16s_i64 use_mips32r2_instructions
#define TCG_TARGET_HAS_rot_i64 use_mips32r2_instructions
#define TCG_TARGET_HAS_clz_i64 use_mips32r2_instructions
#define TCG_TARGET_HAS_ctz_i64 0
#define TCG_TARGET_HAS_ctpop_i64 0
#endif
/* optional instructions automatically implemented */
#define TCG_TARGET_HAS_ext8u_i32 0 /* andi rt, rs, 0xff */
#define TCG_TARGET_HAS_ext16u_i32 0 /* andi rt, rs, 0xffff */
#if TCG_TARGET_REG_BITS == 64
#define TCG_TARGET_HAS_ext8u_i64 0 /* andi rt, rs, 0xff */
#define TCG_TARGET_HAS_ext16u_i64 0 /* andi rt, rs, 0xffff */
#endif
#define TCG_TARGET_HAS_qemu_ldst_i128 0
#define TCG_TARGET_HAS_tst 0
#define TCG_TARGET_DEFAULT_MO 0
#define TCG_TARGET_NEED_LDST_LABELS
#define TCG_TARGET_NEED_POOL_LABELS
#endif

View file

@ -28,6 +28,7 @@
#include "qemu/interval-tree.h"
#include "tcg/tcg-op-common.h"
#include "tcg-internal.h"
#include "tcg-has.h"
#define CASE_OP_32_64(x) \
glue(glue(case INDEX_op_, x), _i32): \
@ -370,7 +371,7 @@ static bool tcg_opt_gen_mov(OptContext *ctx, TCGOp *op, TCGArg dst, TCGArg src)
case TCG_TYPE_V64:
case TCG_TYPE_V128:
case TCG_TYPE_V256:
/* TCGOP_VECL and TCGOP_VECE remain unchanged. */
/* TCGOP_TYPE and TCGOP_VECE remain unchanged. */
new_op = INDEX_op_mov_vec;
break;
default:
@ -2361,9 +2362,11 @@ static void fold_setcond_tst_pow2(OptContext *ctx, TCGOp *op, bool neg)
xor_opc = INDEX_op_xor_i32;
shr_opc = INDEX_op_shr_i32;
neg_opc = INDEX_op_neg_i32;
if (TCG_TARGET_extract_i32_valid(sh, 1)) {
uext_opc = TCG_TARGET_HAS_extract_i32 ? INDEX_op_extract_i32 : 0;
sext_opc = TCG_TARGET_HAS_sextract_i32 ? INDEX_op_sextract_i32 : 0;
if (TCG_TARGET_extract_valid(TCG_TYPE_I32, sh, 1)) {
uext_opc = INDEX_op_extract_i32;
}
if (TCG_TARGET_sextract_valid(TCG_TYPE_I32, sh, 1)) {
sext_opc = INDEX_op_sextract_i32;
}
break;
case TCG_TYPE_I64:
@ -2372,9 +2375,11 @@ static void fold_setcond_tst_pow2(OptContext *ctx, TCGOp *op, bool neg)
xor_opc = INDEX_op_xor_i64;
shr_opc = INDEX_op_shr_i64;
neg_opc = INDEX_op_neg_i64;
if (TCG_TARGET_extract_i64_valid(sh, 1)) {
uext_opc = TCG_TARGET_HAS_extract_i64 ? INDEX_op_extract_i64 : 0;
sext_opc = TCG_TARGET_HAS_sextract_i64 ? INDEX_op_sextract_i64 : 0;
if (TCG_TARGET_extract_valid(TCG_TYPE_I64, sh, 1)) {
uext_opc = INDEX_op_extract_i64;
}
if (TCG_TARGET_sextract_valid(TCG_TYPE_I64, sh, 1)) {
sext_opc = INDEX_op_sextract_i64;
}
break;
default:
@ -2866,13 +2871,7 @@ void tcg_optimize(TCGContext *s)
copy_propagate(&ctx, op, def->nb_oargs, def->nb_iargs);
/* Pre-compute the type of the operation. */
if (def->flags & TCG_OPF_VECTOR) {
ctx.type = TCG_TYPE_V64 + TCGOP_VECL(op);
} else if (def->flags & TCG_OPF_64BIT) {
ctx.type = TCG_TYPE_I64;
} else {
ctx.type = TCG_TYPE_I32;
}
ctx.type = TCGOP_TYPE(op);
/*
* Process each opcode.

131
tcg/ppc/tcg-target-has.h Normal file
View file

@ -0,0 +1,131 @@
/* SPDX-License-Identifier: MIT */
/*
* Define target-specific opcode support
* Copyright (c) 2008 Fabrice Bellard
*/
#ifndef TCG_TARGET_HAS_H
#define TCG_TARGET_HAS_H
#include "host/cpuinfo.h"
#define have_isa_2_06 (cpuinfo & CPUINFO_V2_06)
#define have_isa_2_07 (cpuinfo & CPUINFO_V2_07)
#define have_isa_3_00 (cpuinfo & CPUINFO_V3_0)
#define have_isa_3_10 (cpuinfo & CPUINFO_V3_1)
#define have_altivec (cpuinfo & CPUINFO_ALTIVEC)
#define have_vsx (cpuinfo & CPUINFO_VSX)
/* optional instructions automatically implemented */
#define TCG_TARGET_HAS_ext8u_i32 0 /* andi */
#define TCG_TARGET_HAS_ext16u_i32 0
/* optional instructions */
#define TCG_TARGET_HAS_div_i32 1
#define TCG_TARGET_HAS_rem_i32 have_isa_3_00
#define TCG_TARGET_HAS_rot_i32 1
#define TCG_TARGET_HAS_ext8s_i32 1
#define TCG_TARGET_HAS_ext16s_i32 1
#define TCG_TARGET_HAS_bswap16_i32 1
#define TCG_TARGET_HAS_bswap32_i32 1
#define TCG_TARGET_HAS_not_i32 1
#define TCG_TARGET_HAS_andc_i32 1
#define TCG_TARGET_HAS_orc_i32 1
#define TCG_TARGET_HAS_eqv_i32 1
#define TCG_TARGET_HAS_nand_i32 1
#define TCG_TARGET_HAS_nor_i32 1
#define TCG_TARGET_HAS_clz_i32 1
#define TCG_TARGET_HAS_ctz_i32 have_isa_3_00
#define TCG_TARGET_HAS_ctpop_i32 have_isa_2_06
#define TCG_TARGET_HAS_extract2_i32 0
#define TCG_TARGET_HAS_negsetcond_i32 1
#define TCG_TARGET_HAS_mulu2_i32 0
#define TCG_TARGET_HAS_muls2_i32 0
#define TCG_TARGET_HAS_muluh_i32 1
#define TCG_TARGET_HAS_mulsh_i32 1
#define TCG_TARGET_HAS_qemu_st8_i32 0
#if TCG_TARGET_REG_BITS == 64
#define TCG_TARGET_HAS_add2_i32 0
#define TCG_TARGET_HAS_sub2_i32 0
#define TCG_TARGET_HAS_extr_i64_i32 0
#define TCG_TARGET_HAS_div_i64 1
#define TCG_TARGET_HAS_rem_i64 have_isa_3_00
#define TCG_TARGET_HAS_rot_i64 1
#define TCG_TARGET_HAS_ext8s_i64 1
#define TCG_TARGET_HAS_ext16s_i64 1
#define TCG_TARGET_HAS_ext32s_i64 1
#define TCG_TARGET_HAS_ext8u_i64 0
#define TCG_TARGET_HAS_ext16u_i64 0
#define TCG_TARGET_HAS_ext32u_i64 0
#define TCG_TARGET_HAS_bswap16_i64 1
#define TCG_TARGET_HAS_bswap32_i64 1
#define TCG_TARGET_HAS_bswap64_i64 1
#define TCG_TARGET_HAS_not_i64 1
#define TCG_TARGET_HAS_andc_i64 1
#define TCG_TARGET_HAS_orc_i64 1
#define TCG_TARGET_HAS_eqv_i64 1
#define TCG_TARGET_HAS_nand_i64 1
#define TCG_TARGET_HAS_nor_i64 1
#define TCG_TARGET_HAS_clz_i64 1
#define TCG_TARGET_HAS_ctz_i64 have_isa_3_00
#define TCG_TARGET_HAS_ctpop_i64 have_isa_2_06
#define TCG_TARGET_HAS_extract2_i64 0
#define TCG_TARGET_HAS_negsetcond_i64 1
#define TCG_TARGET_HAS_add2_i64 1
#define TCG_TARGET_HAS_sub2_i64 1
#define TCG_TARGET_HAS_mulu2_i64 0
#define TCG_TARGET_HAS_muls2_i64 0
#define TCG_TARGET_HAS_muluh_i64 1
#define TCG_TARGET_HAS_mulsh_i64 1
#endif
#define TCG_TARGET_HAS_qemu_ldst_i128 \
(TCG_TARGET_REG_BITS == 64 && have_isa_2_07)
#define TCG_TARGET_HAS_tst 1
/*
* While technically Altivec could support V64, it has no 64-bit store
* instruction and substituting two 32-bit stores makes the generated
* code quite large.
*/
#define TCG_TARGET_HAS_v64 have_vsx
#define TCG_TARGET_HAS_v128 have_altivec
#define TCG_TARGET_HAS_v256 0
#define TCG_TARGET_HAS_andc_vec 1
#define TCG_TARGET_HAS_orc_vec have_isa_2_07
#define TCG_TARGET_HAS_nand_vec have_isa_2_07
#define TCG_TARGET_HAS_nor_vec 1
#define TCG_TARGET_HAS_eqv_vec have_isa_2_07
#define TCG_TARGET_HAS_not_vec 1
#define TCG_TARGET_HAS_neg_vec have_isa_3_00
#define TCG_TARGET_HAS_abs_vec 0
#define TCG_TARGET_HAS_roti_vec 0
#define TCG_TARGET_HAS_rots_vec 0
#define TCG_TARGET_HAS_rotv_vec 1
#define TCG_TARGET_HAS_shi_vec 0
#define TCG_TARGET_HAS_shs_vec 0
#define TCG_TARGET_HAS_shv_vec 1
#define TCG_TARGET_HAS_mul_vec 1
#define TCG_TARGET_HAS_sat_vec 1
#define TCG_TARGET_HAS_minmax_vec 1
#define TCG_TARGET_HAS_bitsel_vec have_vsx
#define TCG_TARGET_HAS_cmpsel_vec 1
#define TCG_TARGET_HAS_tst_vec 0
#define TCG_TARGET_extract_valid(type, ofs, len) 1
#define TCG_TARGET_deposit_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

12
tcg/ppc/tcg-target-mo.h Normal file
View file

@ -0,0 +1,12 @@
/* SPDX-License-Identifier: MIT */
/*
* Define target-specific memory model
* Copyright (c) 2008 Fabrice Bellard
*/
#ifndef TCG_TARGET_MO_H
#define TCG_TARGET_MO_H
#define TCG_TARGET_DEFAULT_MO 0
#endif

View file

@ -24,9 +24,9 @@
* consider these to be UNSPEC with names.
*/
DEF(ppc_mrgh_vec, 1, 2, 0, IMPLVEC)
DEF(ppc_mrgl_vec, 1, 2, 0, IMPLVEC)
DEF(ppc_msum_vec, 1, 3, 0, IMPLVEC)
DEF(ppc_muleu_vec, 1, 2, 0, IMPLVEC)
DEF(ppc_mulou_vec, 1, 2, 0, IMPLVEC)
DEF(ppc_pkum_vec, 1, 2, 0, IMPLVEC)
DEF(ppc_mrgh_vec, 1, 2, 0, TCG_OPF_VECTOR)
DEF(ppc_mrgl_vec, 1, 2, 0, TCG_OPF_VECTOR)
DEF(ppc_msum_vec, 1, 3, 0, TCG_OPF_VECTOR)
DEF(ppc_muleu_vec, 1, 2, 0, TCG_OPF_VECTOR)
DEF(ppc_mulou_vec, 1, 2, 0, TCG_OPF_VECTOR)
DEF(ppc_pkum_vec, 1, 2, 0, TCG_OPF_VECTOR)

View file

@ -23,8 +23,6 @@
*/
#include "elf.h"
#include "../tcg-pool.c.inc"
#include "../tcg-ldst.c.inc"
/*
* Standardize on the _CALL_FOO symbols used by GCC:
@ -2942,7 +2940,7 @@ void tb_target_set_jmp_target(const TranslationBlock *tb, int n,
flush_idcache_range(jmp_rx, jmp_rw, 4);
}
static void tcg_out_op(TCGContext *s, TCGOpcode opc,
static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
const TCGArg args[TCG_MAX_OP_ARGS],
const int const_args[TCG_MAX_OP_ARGS])
{
@ -3432,13 +3430,41 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
break;
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],
32 - args[2], 32 - args[3], 31);
break;
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]);
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:
tcg_out_movcond(s, TCG_TYPE_I32, args[5], args[0], args[1], args[2],
args[3], args[4], const_args[2]);
@ -4142,7 +4168,8 @@ void tcg_expand_vec_op(TCGOpcode opc, TCGType type, unsigned vece,
va_end(va);
}
static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
static TCGConstraintSetIndex
tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
{
switch (op) {
case INDEX_op_goto_ptr:
@ -4161,6 +4188,7 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
case INDEX_op_bswap16_i32:
case INDEX_op_bswap32_i32:
case INDEX_op_extract_i32:
case INDEX_op_sextract_i32:
case INDEX_op_ld8u_i64:
case INDEX_op_ld8s_i64:
case INDEX_op_ld16u_i64:
@ -4180,6 +4208,7 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
case INDEX_op_bswap32_i64:
case INDEX_op_bswap64_i64:
case INDEX_op_extract_i64:
case INDEX_op_sextract_i64:
return C_O1_I1(r, r);
case INDEX_op_st8_i32:
@ -4356,7 +4385,7 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
return C_O1_I4(v, v, v, vZM, v);
default:
g_assert_not_reached();
return C_NotImplemented;
}
}

View file

@ -25,8 +25,6 @@
#ifndef PPC_TCG_TARGET_H
#define PPC_TCG_TARGET_H
#include "host/cpuinfo.h"
#define MAX_CODE_GEN_BUFFER_SIZE ((size_t)-1)
#define TCG_TARGET_NB_REGS 64
@ -55,128 +53,4 @@ typedef enum {
TCG_AREG0 = TCG_REG_R27
} TCGReg;
typedef enum {
tcg_isa_base,
tcg_isa_2_06,
tcg_isa_2_07,
tcg_isa_3_00,
tcg_isa_3_10,
} TCGPowerISA;
#define have_isa_2_06 (cpuinfo & CPUINFO_V2_06)
#define have_isa_2_07 (cpuinfo & CPUINFO_V2_07)
#define have_isa_3_00 (cpuinfo & CPUINFO_V3_0)
#define have_isa_3_10 (cpuinfo & CPUINFO_V3_1)
#define have_altivec (cpuinfo & CPUINFO_ALTIVEC)
#define have_vsx (cpuinfo & CPUINFO_VSX)
/* optional instructions automatically implemented */
#define TCG_TARGET_HAS_ext8u_i32 0 /* andi */
#define TCG_TARGET_HAS_ext16u_i32 0
/* optional instructions */
#define TCG_TARGET_HAS_div_i32 1
#define TCG_TARGET_HAS_rem_i32 have_isa_3_00
#define TCG_TARGET_HAS_rot_i32 1
#define TCG_TARGET_HAS_ext8s_i32 1
#define TCG_TARGET_HAS_ext16s_i32 1
#define TCG_TARGET_HAS_bswap16_i32 1
#define TCG_TARGET_HAS_bswap32_i32 1
#define TCG_TARGET_HAS_not_i32 1
#define TCG_TARGET_HAS_andc_i32 1
#define TCG_TARGET_HAS_orc_i32 1
#define TCG_TARGET_HAS_eqv_i32 1
#define TCG_TARGET_HAS_nand_i32 1
#define TCG_TARGET_HAS_nor_i32 1
#define TCG_TARGET_HAS_clz_i32 1
#define TCG_TARGET_HAS_ctz_i32 have_isa_3_00
#define TCG_TARGET_HAS_ctpop_i32 have_isa_2_06
#define TCG_TARGET_HAS_deposit_i32 1
#define TCG_TARGET_HAS_extract_i32 1
#define TCG_TARGET_HAS_sextract_i32 0
#define TCG_TARGET_HAS_extract2_i32 0
#define TCG_TARGET_HAS_negsetcond_i32 1
#define TCG_TARGET_HAS_mulu2_i32 0
#define TCG_TARGET_HAS_muls2_i32 0
#define TCG_TARGET_HAS_muluh_i32 1
#define TCG_TARGET_HAS_mulsh_i32 1
#define TCG_TARGET_HAS_qemu_st8_i32 0
#if TCG_TARGET_REG_BITS == 64
#define TCG_TARGET_HAS_add2_i32 0
#define TCG_TARGET_HAS_sub2_i32 0
#define TCG_TARGET_HAS_extr_i64_i32 0
#define TCG_TARGET_HAS_div_i64 1
#define TCG_TARGET_HAS_rem_i64 have_isa_3_00
#define TCG_TARGET_HAS_rot_i64 1
#define TCG_TARGET_HAS_ext8s_i64 1
#define TCG_TARGET_HAS_ext16s_i64 1
#define TCG_TARGET_HAS_ext32s_i64 1
#define TCG_TARGET_HAS_ext8u_i64 0
#define TCG_TARGET_HAS_ext16u_i64 0
#define TCG_TARGET_HAS_ext32u_i64 0
#define TCG_TARGET_HAS_bswap16_i64 1
#define TCG_TARGET_HAS_bswap32_i64 1
#define TCG_TARGET_HAS_bswap64_i64 1
#define TCG_TARGET_HAS_not_i64 1
#define TCG_TARGET_HAS_andc_i64 1
#define TCG_TARGET_HAS_orc_i64 1
#define TCG_TARGET_HAS_eqv_i64 1
#define TCG_TARGET_HAS_nand_i64 1
#define TCG_TARGET_HAS_nor_i64 1
#define TCG_TARGET_HAS_clz_i64 1
#define TCG_TARGET_HAS_ctz_i64 have_isa_3_00
#define TCG_TARGET_HAS_ctpop_i64 have_isa_2_06
#define TCG_TARGET_HAS_deposit_i64 1
#define TCG_TARGET_HAS_extract_i64 1
#define TCG_TARGET_HAS_sextract_i64 0
#define TCG_TARGET_HAS_extract2_i64 0
#define TCG_TARGET_HAS_negsetcond_i64 1
#define TCG_TARGET_HAS_add2_i64 1
#define TCG_TARGET_HAS_sub2_i64 1
#define TCG_TARGET_HAS_mulu2_i64 0
#define TCG_TARGET_HAS_muls2_i64 0
#define TCG_TARGET_HAS_muluh_i64 1
#define TCG_TARGET_HAS_mulsh_i64 1
#endif
#define TCG_TARGET_HAS_qemu_ldst_i128 \
(TCG_TARGET_REG_BITS == 64 && have_isa_2_07)
#define TCG_TARGET_HAS_tst 1
/*
* While technically Altivec could support V64, it has no 64-bit store
* instruction and substituting two 32-bit stores makes the generated
* code quite large.
*/
#define TCG_TARGET_HAS_v64 have_vsx
#define TCG_TARGET_HAS_v128 have_altivec
#define TCG_TARGET_HAS_v256 0
#define TCG_TARGET_HAS_andc_vec 1
#define TCG_TARGET_HAS_orc_vec have_isa_2_07
#define TCG_TARGET_HAS_nand_vec have_isa_2_07
#define TCG_TARGET_HAS_nor_vec 1
#define TCG_TARGET_HAS_eqv_vec have_isa_2_07
#define TCG_TARGET_HAS_not_vec 1
#define TCG_TARGET_HAS_neg_vec have_isa_3_00
#define TCG_TARGET_HAS_abs_vec 0
#define TCG_TARGET_HAS_roti_vec 0
#define TCG_TARGET_HAS_rots_vec 0
#define TCG_TARGET_HAS_rotv_vec 1
#define TCG_TARGET_HAS_shi_vec 0
#define TCG_TARGET_HAS_shs_vec 0
#define TCG_TARGET_HAS_shv_vec 1
#define TCG_TARGET_HAS_mul_vec 1
#define TCG_TARGET_HAS_sat_vec 1
#define TCG_TARGET_HAS_minmax_vec 1
#define TCG_TARGET_HAS_bitsel_vec have_vsx
#define TCG_TARGET_HAS_cmpsel_vec 1
#define TCG_TARGET_HAS_tst_vec 0
#define TCG_TARGET_DEFAULT_MO (0)
#define TCG_TARGET_NEED_LDST_LABELS
#define TCG_TARGET_NEED_POOL_LABELS
#endif

135
tcg/riscv/tcg-target-has.h Normal file
View file

@ -0,0 +1,135 @@
/* SPDX-License-Identifier: MIT */
/*
* Define target-specific opcode support
* Copyright (c) 2018 SiFive, Inc
*/
#ifndef TCG_TARGET_HAS_H
#define TCG_TARGET_HAS_H
#include "host/cpuinfo.h"
/* optional instructions */
#define TCG_TARGET_HAS_negsetcond_i32 1
#define TCG_TARGET_HAS_div_i32 1
#define TCG_TARGET_HAS_rem_i32 1
#define TCG_TARGET_HAS_div2_i32 0
#define TCG_TARGET_HAS_rot_i32 (cpuinfo & CPUINFO_ZBB)
#define TCG_TARGET_HAS_extract2_i32 0
#define TCG_TARGET_HAS_add2_i32 1
#define TCG_TARGET_HAS_sub2_i32 1
#define TCG_TARGET_HAS_mulu2_i32 0
#define TCG_TARGET_HAS_muls2_i32 0
#define TCG_TARGET_HAS_muluh_i32 0
#define TCG_TARGET_HAS_mulsh_i32 0
#define TCG_TARGET_HAS_ext8s_i32 1
#define TCG_TARGET_HAS_ext16s_i32 1
#define TCG_TARGET_HAS_ext8u_i32 1
#define TCG_TARGET_HAS_ext16u_i32 1
#define TCG_TARGET_HAS_bswap16_i32 (cpuinfo & CPUINFO_ZBB)
#define TCG_TARGET_HAS_bswap32_i32 (cpuinfo & CPUINFO_ZBB)
#define TCG_TARGET_HAS_not_i32 1
#define TCG_TARGET_HAS_andc_i32 (cpuinfo & CPUINFO_ZBB)
#define TCG_TARGET_HAS_orc_i32 (cpuinfo & CPUINFO_ZBB)
#define TCG_TARGET_HAS_eqv_i32 (cpuinfo & CPUINFO_ZBB)
#define TCG_TARGET_HAS_nand_i32 0
#define TCG_TARGET_HAS_nor_i32 0
#define TCG_TARGET_HAS_clz_i32 (cpuinfo & CPUINFO_ZBB)
#define TCG_TARGET_HAS_ctz_i32 (cpuinfo & CPUINFO_ZBB)
#define TCG_TARGET_HAS_ctpop_i32 (cpuinfo & CPUINFO_ZBB)
#define TCG_TARGET_HAS_brcond2 1
#define TCG_TARGET_HAS_setcond2 1
#define TCG_TARGET_HAS_qemu_st8_i32 0
#define TCG_TARGET_HAS_negsetcond_i64 1
#define TCG_TARGET_HAS_div_i64 1
#define TCG_TARGET_HAS_rem_i64 1
#define TCG_TARGET_HAS_div2_i64 0
#define TCG_TARGET_HAS_rot_i64 (cpuinfo & CPUINFO_ZBB)
#define TCG_TARGET_HAS_extract2_i64 0
#define TCG_TARGET_HAS_extr_i64_i32 1
#define TCG_TARGET_HAS_ext8s_i64 1
#define TCG_TARGET_HAS_ext16s_i64 1
#define TCG_TARGET_HAS_ext32s_i64 1
#define TCG_TARGET_HAS_ext8u_i64 1
#define TCG_TARGET_HAS_ext16u_i64 1
#define TCG_TARGET_HAS_ext32u_i64 1
#define TCG_TARGET_HAS_bswap16_i64 (cpuinfo & CPUINFO_ZBB)
#define TCG_TARGET_HAS_bswap32_i64 (cpuinfo & CPUINFO_ZBB)
#define TCG_TARGET_HAS_bswap64_i64 (cpuinfo & CPUINFO_ZBB)
#define TCG_TARGET_HAS_not_i64 1
#define TCG_TARGET_HAS_andc_i64 (cpuinfo & CPUINFO_ZBB)
#define TCG_TARGET_HAS_orc_i64 (cpuinfo & CPUINFO_ZBB)
#define TCG_TARGET_HAS_eqv_i64 (cpuinfo & CPUINFO_ZBB)
#define TCG_TARGET_HAS_nand_i64 0
#define TCG_TARGET_HAS_nor_i64 0
#define TCG_TARGET_HAS_clz_i64 (cpuinfo & CPUINFO_ZBB)
#define TCG_TARGET_HAS_ctz_i64 (cpuinfo & CPUINFO_ZBB)
#define TCG_TARGET_HAS_ctpop_i64 (cpuinfo & CPUINFO_ZBB)
#define TCG_TARGET_HAS_add2_i64 1
#define TCG_TARGET_HAS_sub2_i64 1
#define TCG_TARGET_HAS_mulu2_i64 0
#define TCG_TARGET_HAS_muls2_i64 0
#define TCG_TARGET_HAS_muluh_i64 1
#define TCG_TARGET_HAS_mulsh_i64 1
#define TCG_TARGET_HAS_qemu_ldst_i128 0
#define TCG_TARGET_HAS_tst 0
/* vector instructions */
#define TCG_TARGET_HAS_v64 (cpuinfo & CPUINFO_ZVE64X)
#define TCG_TARGET_HAS_v128 (cpuinfo & CPUINFO_ZVE64X)
#define TCG_TARGET_HAS_v256 (cpuinfo & CPUINFO_ZVE64X)
#define TCG_TARGET_HAS_andc_vec 0
#define TCG_TARGET_HAS_orc_vec 0
#define TCG_TARGET_HAS_nand_vec 0
#define TCG_TARGET_HAS_nor_vec 0
#define TCG_TARGET_HAS_eqv_vec 0
#define TCG_TARGET_HAS_not_vec 1
#define TCG_TARGET_HAS_neg_vec 1
#define TCG_TARGET_HAS_abs_vec 0
#define TCG_TARGET_HAS_roti_vec 1
#define TCG_TARGET_HAS_rots_vec 1
#define TCG_TARGET_HAS_rotv_vec 1
#define TCG_TARGET_HAS_shi_vec 1
#define TCG_TARGET_HAS_shs_vec 1
#define TCG_TARGET_HAS_shv_vec 1
#define TCG_TARGET_HAS_mul_vec 1
#define TCG_TARGET_HAS_sat_vec 1
#define TCG_TARGET_HAS_minmax_vec 1
#define TCG_TARGET_HAS_bitsel_vec 0
#define TCG_TARGET_HAS_cmpsel_vec 1
#define TCG_TARGET_HAS_tst_vec 0
static inline bool
tcg_target_extract_valid(TCGType type, unsigned ofs, unsigned len)
{
if (type == TCG_TYPE_I64 && ofs + len == 32) {
/* ofs > 0 uses SRLIW; ofs == 0 uses add.uw. */
return ofs || (cpuinfo & CPUINFO_ZBA);
}
switch (len) {
case 1:
return (cpuinfo & CPUINFO_ZBS) && ofs != 0;
case 16:
return (cpuinfo & CPUINFO_ZBB) && ofs == 0;
}
return false;
}
#define TCG_TARGET_extract_valid tcg_target_extract_valid
static inline bool
tcg_target_sextract_valid(TCGType type, unsigned ofs, unsigned len)
{
if (type == TCG_TYPE_I64 && ofs + len == 32) {
return true;
}
return (cpuinfo & CPUINFO_ZBB) && ofs == 0 && (len == 8 || len == 16);
}
#define TCG_TARGET_sextract_valid tcg_target_sextract_valid
#define TCG_TARGET_deposit_valid(type, ofs, len) 0
#endif

12
tcg/riscv/tcg-target-mo.h Normal file
View file

@ -0,0 +1,12 @@
/* SPDX-License-Identifier: MIT */
/*
* Define target-specific memory model
* Copyright (c) 2018 SiFive, Inc
*/
#ifndef TCG_TARGET_MO_H
#define TCG_TARGET_MO_H
#define TCG_TARGET_DEFAULT_MO 0
#endif

View file

@ -27,8 +27,14 @@
* THE SOFTWARE.
*/
#include "../tcg-ldst.c.inc"
#include "../tcg-pool.c.inc"
/* Used for function call generation. */
#define TCG_REG_CALL_STACK TCG_REG_SP
#define TCG_TARGET_STACK_ALIGN 16
#define TCG_TARGET_CALL_STACK_OFFSET 0
#define TCG_TARGET_CALL_ARG_I32 TCG_CALL_ARG_NORMAL
#define TCG_TARGET_CALL_ARG_I64 TCG_CALL_ARG_NORMAL
#define TCG_TARGET_CALL_ARG_I128 TCG_CALL_ARG_NORMAL
#define TCG_TARGET_CALL_RET_I128 TCG_CALL_RET_NORMAL
#ifdef CONFIG_DEBUG_TCG
static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
@ -157,6 +163,7 @@ typedef enum {
OPC_ANDI = 0x7013,
OPC_AUIPC = 0x17,
OPC_BEQ = 0x63,
OPC_BEXTI = 0x48005013,
OPC_BGE = 0x5063,
OPC_BGEU = 0x7063,
OPC_BLT = 0x4063,
@ -1954,7 +1961,7 @@ void tb_target_set_jmp_target(const TranslationBlock *tb, int n,
flush_idcache_range(jmp_rx, jmp_rw, 4);
}
static void tcg_out_op(TCGContext *s, TCGOpcode opc,
static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
const TCGArg args[TCG_MAX_OP_ARGS],
const int const_args[TCG_MAX_OP_ARGS])
{
@ -2337,6 +2344,50 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
tcg_out_mb(s, a0);
break;
case INDEX_op_extract_i64:
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 */
case INDEX_op_extract_i32:
switch (args[3]) {
case 1:
tcg_out_opc_imm(s, OPC_BEXTI, a0, a1, a2);
break;
case 16:
tcg_debug_assert(a2 == 0);
tcg_out_ext16u(s, a0, a1);
break;
default:
g_assert_not_reached();
}
break;
case INDEX_op_sextract_i64:
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 */
case INDEX_op_sextract_i32:
if (a2 == 0 && args[3] == 8) {
tcg_out_ext8s(s, TCG_TYPE_REG, a0, a1);
} else if (a2 == 0 && args[3] == 16) {
tcg_out_ext16s(s, TCG_TYPE_REG, a0, a1);
} else {
g_assert_not_reached();
}
break;
case INDEX_op_mov_i32: /* Always emitted via tcg_out_mov. */
case INDEX_op_mov_i64:
case INDEX_op_call: /* Always emitted via tcg_out_call. */
@ -2577,7 +2628,8 @@ int tcg_can_emit_vec_op(TCGOpcode opc, TCGType type, unsigned vece)
}
}
static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
static TCGConstraintSetIndex
tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
{
switch (op) {
case INDEX_op_goto_ptr:
@ -2613,6 +2665,10 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
case INDEX_op_extrl_i64_i32:
case INDEX_op_extrh_i64_i32:
case INDEX_op_ext_i32_i64:
case INDEX_op_extract_i32:
case INDEX_op_extract_i64:
case INDEX_op_sextract_i32:
case INDEX_op_sextract_i64:
case INDEX_op_bswap16_i32:
case INDEX_op_bswap32_i32:
case INDEX_op_bswap16_i64:
@ -2761,7 +2817,7 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
case INDEX_op_cmpsel_vec:
return C_O1_I4(v, v, vL, vK, vK);
default:
g_assert_not_reached();
return C_NotImplemented;
}
}

View file

@ -25,8 +25,6 @@
#ifndef RISCV_TCG_TARGET_H
#define RISCV_TCG_TARGET_H
#include "host/cpuinfo.h"
#define TCG_TARGET_INSN_UNIT_SIZE 4
#define TCG_TARGET_NB_REGS 64
#define MAX_CODE_GEN_BUFFER_SIZE ((size_t)-1)
@ -59,118 +57,4 @@ typedef enum {
TCG_REG_TMP2 = TCG_REG_T4,
} TCGReg;
/* used for function call generation */
#define TCG_REG_CALL_STACK TCG_REG_SP
#define TCG_TARGET_STACK_ALIGN 16
#define TCG_TARGET_CALL_STACK_OFFSET 0
#define TCG_TARGET_CALL_ARG_I32 TCG_CALL_ARG_NORMAL
#define TCG_TARGET_CALL_ARG_I64 TCG_CALL_ARG_NORMAL
#define TCG_TARGET_CALL_ARG_I128 TCG_CALL_ARG_NORMAL
#define TCG_TARGET_CALL_RET_I128 TCG_CALL_RET_NORMAL
/* optional instructions */
#define TCG_TARGET_HAS_negsetcond_i32 1
#define TCG_TARGET_HAS_div_i32 1
#define TCG_TARGET_HAS_rem_i32 1
#define TCG_TARGET_HAS_div2_i32 0
#define TCG_TARGET_HAS_rot_i32 (cpuinfo & CPUINFO_ZBB)
#define TCG_TARGET_HAS_deposit_i32 0
#define TCG_TARGET_HAS_extract_i32 0
#define TCG_TARGET_HAS_sextract_i32 0
#define TCG_TARGET_HAS_extract2_i32 0
#define TCG_TARGET_HAS_add2_i32 1
#define TCG_TARGET_HAS_sub2_i32 1
#define TCG_TARGET_HAS_mulu2_i32 0
#define TCG_TARGET_HAS_muls2_i32 0
#define TCG_TARGET_HAS_muluh_i32 0
#define TCG_TARGET_HAS_mulsh_i32 0
#define TCG_TARGET_HAS_ext8s_i32 1
#define TCG_TARGET_HAS_ext16s_i32 1
#define TCG_TARGET_HAS_ext8u_i32 1
#define TCG_TARGET_HAS_ext16u_i32 1
#define TCG_TARGET_HAS_bswap16_i32 (cpuinfo & CPUINFO_ZBB)
#define TCG_TARGET_HAS_bswap32_i32 (cpuinfo & CPUINFO_ZBB)
#define TCG_TARGET_HAS_not_i32 1
#define TCG_TARGET_HAS_andc_i32 (cpuinfo & CPUINFO_ZBB)
#define TCG_TARGET_HAS_orc_i32 (cpuinfo & CPUINFO_ZBB)
#define TCG_TARGET_HAS_eqv_i32 (cpuinfo & CPUINFO_ZBB)
#define TCG_TARGET_HAS_nand_i32 0
#define TCG_TARGET_HAS_nor_i32 0
#define TCG_TARGET_HAS_clz_i32 (cpuinfo & CPUINFO_ZBB)
#define TCG_TARGET_HAS_ctz_i32 (cpuinfo & CPUINFO_ZBB)
#define TCG_TARGET_HAS_ctpop_i32 (cpuinfo & CPUINFO_ZBB)
#define TCG_TARGET_HAS_brcond2 1
#define TCG_TARGET_HAS_setcond2 1
#define TCG_TARGET_HAS_qemu_st8_i32 0
#define TCG_TARGET_HAS_negsetcond_i64 1
#define TCG_TARGET_HAS_div_i64 1
#define TCG_TARGET_HAS_rem_i64 1
#define TCG_TARGET_HAS_div2_i64 0
#define TCG_TARGET_HAS_rot_i64 (cpuinfo & CPUINFO_ZBB)
#define TCG_TARGET_HAS_deposit_i64 0
#define TCG_TARGET_HAS_extract_i64 0
#define TCG_TARGET_HAS_sextract_i64 0
#define TCG_TARGET_HAS_extract2_i64 0
#define TCG_TARGET_HAS_extr_i64_i32 1
#define TCG_TARGET_HAS_ext8s_i64 1
#define TCG_TARGET_HAS_ext16s_i64 1
#define TCG_TARGET_HAS_ext32s_i64 1
#define TCG_TARGET_HAS_ext8u_i64 1
#define TCG_TARGET_HAS_ext16u_i64 1
#define TCG_TARGET_HAS_ext32u_i64 1
#define TCG_TARGET_HAS_bswap16_i64 (cpuinfo & CPUINFO_ZBB)
#define TCG_TARGET_HAS_bswap32_i64 (cpuinfo & CPUINFO_ZBB)
#define TCG_TARGET_HAS_bswap64_i64 (cpuinfo & CPUINFO_ZBB)
#define TCG_TARGET_HAS_not_i64 1
#define TCG_TARGET_HAS_andc_i64 (cpuinfo & CPUINFO_ZBB)
#define TCG_TARGET_HAS_orc_i64 (cpuinfo & CPUINFO_ZBB)
#define TCG_TARGET_HAS_eqv_i64 (cpuinfo & CPUINFO_ZBB)
#define TCG_TARGET_HAS_nand_i64 0
#define TCG_TARGET_HAS_nor_i64 0
#define TCG_TARGET_HAS_clz_i64 (cpuinfo & CPUINFO_ZBB)
#define TCG_TARGET_HAS_ctz_i64 (cpuinfo & CPUINFO_ZBB)
#define TCG_TARGET_HAS_ctpop_i64 (cpuinfo & CPUINFO_ZBB)
#define TCG_TARGET_HAS_add2_i64 1
#define TCG_TARGET_HAS_sub2_i64 1
#define TCG_TARGET_HAS_mulu2_i64 0
#define TCG_TARGET_HAS_muls2_i64 0
#define TCG_TARGET_HAS_muluh_i64 1
#define TCG_TARGET_HAS_mulsh_i64 1
#define TCG_TARGET_HAS_qemu_ldst_i128 0
#define TCG_TARGET_HAS_tst 0
/* vector instructions */
#define TCG_TARGET_HAS_v64 (cpuinfo & CPUINFO_ZVE64X)
#define TCG_TARGET_HAS_v128 (cpuinfo & CPUINFO_ZVE64X)
#define TCG_TARGET_HAS_v256 (cpuinfo & CPUINFO_ZVE64X)
#define TCG_TARGET_HAS_andc_vec 0
#define TCG_TARGET_HAS_orc_vec 0
#define TCG_TARGET_HAS_nand_vec 0
#define TCG_TARGET_HAS_nor_vec 0
#define TCG_TARGET_HAS_eqv_vec 0
#define TCG_TARGET_HAS_not_vec 1
#define TCG_TARGET_HAS_neg_vec 1
#define TCG_TARGET_HAS_abs_vec 0
#define TCG_TARGET_HAS_roti_vec 1
#define TCG_TARGET_HAS_rots_vec 1
#define TCG_TARGET_HAS_rotv_vec 1
#define TCG_TARGET_HAS_shi_vec 1
#define TCG_TARGET_HAS_shs_vec 1
#define TCG_TARGET_HAS_shv_vec 1
#define TCG_TARGET_HAS_mul_vec 1
#define TCG_TARGET_HAS_sat_vec 1
#define TCG_TARGET_HAS_minmax_vec 1
#define TCG_TARGET_HAS_bitsel_vec 0
#define TCG_TARGET_HAS_cmpsel_vec 1
#define TCG_TARGET_HAS_tst_vec 0
#define TCG_TARGET_DEFAULT_MO (0)
#define TCG_TARGET_NEED_LDST_LABELS
#define TCG_TARGET_NEED_POOL_LABELS
#endif

137
tcg/s390x/tcg-target-has.h Normal file
View file

@ -0,0 +1,137 @@
/* SPDX-License-Identifier: MIT */
/*
* Define target-specific opcode support
* Copyright (c) 2009 Ulrich Hecht <uli@suse.de>
*/
#ifndef TCG_TARGET_HAS_H
#define TCG_TARGET_HAS_H
/* Facilities required for proper operation; checked at startup. */
#define FACILITY_ZARCH_ACTIVE 2
#define FACILITY_LONG_DISP 18
#define FACILITY_EXT_IMM 21
#define FACILITY_GEN_INST_EXT 34
#define FACILITY_45 45
/* Facilities that are checked at runtime. */
#define FACILITY_LOAD_ON_COND2 53
#define FACILITY_MISC_INSN_EXT2 58
#define FACILITY_MISC_INSN_EXT3 61
#define FACILITY_VECTOR 129
#define FACILITY_VECTOR_ENH1 135
extern uint64_t s390_facilities[3];
#define HAVE_FACILITY(X) \
((s390_facilities[FACILITY_##X / 64] >> (63 - FACILITY_##X % 64)) & 1)
/* optional instructions */
#define TCG_TARGET_HAS_div2_i32 1
#define TCG_TARGET_HAS_rot_i32 1
#define TCG_TARGET_HAS_ext8s_i32 1
#define TCG_TARGET_HAS_ext16s_i32 1
#define TCG_TARGET_HAS_ext8u_i32 1
#define TCG_TARGET_HAS_ext16u_i32 1
#define TCG_TARGET_HAS_bswap16_i32 1
#define TCG_TARGET_HAS_bswap32_i32 1
#define TCG_TARGET_HAS_not_i32 HAVE_FACILITY(MISC_INSN_EXT3)
#define TCG_TARGET_HAS_andc_i32 HAVE_FACILITY(MISC_INSN_EXT3)
#define TCG_TARGET_HAS_orc_i32 HAVE_FACILITY(MISC_INSN_EXT3)
#define TCG_TARGET_HAS_eqv_i32 HAVE_FACILITY(MISC_INSN_EXT3)
#define TCG_TARGET_HAS_nand_i32 HAVE_FACILITY(MISC_INSN_EXT3)
#define TCG_TARGET_HAS_nor_i32 HAVE_FACILITY(MISC_INSN_EXT3)
#define TCG_TARGET_HAS_clz_i32 0
#define TCG_TARGET_HAS_ctz_i32 0
#define TCG_TARGET_HAS_ctpop_i32 1
#define TCG_TARGET_HAS_extract2_i32 0
#define TCG_TARGET_HAS_negsetcond_i32 1
#define TCG_TARGET_HAS_add2_i32 1
#define TCG_TARGET_HAS_sub2_i32 1
#define TCG_TARGET_HAS_mulu2_i32 0
#define TCG_TARGET_HAS_muls2_i32 0
#define TCG_TARGET_HAS_muluh_i32 0
#define TCG_TARGET_HAS_mulsh_i32 0
#define TCG_TARGET_HAS_extr_i64_i32 0
#define TCG_TARGET_HAS_qemu_st8_i32 0
#define TCG_TARGET_HAS_div2_i64 1
#define TCG_TARGET_HAS_rot_i64 1
#define TCG_TARGET_HAS_ext8s_i64 1
#define TCG_TARGET_HAS_ext16s_i64 1
#define TCG_TARGET_HAS_ext32s_i64 1
#define TCG_TARGET_HAS_ext8u_i64 1
#define TCG_TARGET_HAS_ext16u_i64 1
#define TCG_TARGET_HAS_ext32u_i64 1
#define TCG_TARGET_HAS_bswap16_i64 1
#define TCG_TARGET_HAS_bswap32_i64 1
#define TCG_TARGET_HAS_bswap64_i64 1
#define TCG_TARGET_HAS_not_i64 HAVE_FACILITY(MISC_INSN_EXT3)
#define TCG_TARGET_HAS_andc_i64 HAVE_FACILITY(MISC_INSN_EXT3)
#define TCG_TARGET_HAS_orc_i64 HAVE_FACILITY(MISC_INSN_EXT3)
#define TCG_TARGET_HAS_eqv_i64 HAVE_FACILITY(MISC_INSN_EXT3)
#define TCG_TARGET_HAS_nand_i64 HAVE_FACILITY(MISC_INSN_EXT3)
#define TCG_TARGET_HAS_nor_i64 HAVE_FACILITY(MISC_INSN_EXT3)
#define TCG_TARGET_HAS_clz_i64 1
#define TCG_TARGET_HAS_ctz_i64 0
#define TCG_TARGET_HAS_ctpop_i64 1
#define TCG_TARGET_HAS_extract2_i64 0
#define TCG_TARGET_HAS_negsetcond_i64 1
#define TCG_TARGET_HAS_add2_i64 1
#define TCG_TARGET_HAS_sub2_i64 1
#define TCG_TARGET_HAS_mulu2_i64 1
#define TCG_TARGET_HAS_muls2_i64 HAVE_FACILITY(MISC_INSN_EXT2)
#define TCG_TARGET_HAS_muluh_i64 0
#define TCG_TARGET_HAS_mulsh_i64 0
#define TCG_TARGET_HAS_qemu_ldst_i128 1
#define TCG_TARGET_HAS_tst 1
#define TCG_TARGET_HAS_v64 HAVE_FACILITY(VECTOR)
#define TCG_TARGET_HAS_v128 HAVE_FACILITY(VECTOR)
#define TCG_TARGET_HAS_v256 0
#define TCG_TARGET_HAS_andc_vec 1
#define TCG_TARGET_HAS_orc_vec HAVE_FACILITY(VECTOR_ENH1)
#define TCG_TARGET_HAS_nand_vec HAVE_FACILITY(VECTOR_ENH1)
#define TCG_TARGET_HAS_nor_vec 1
#define TCG_TARGET_HAS_eqv_vec HAVE_FACILITY(VECTOR_ENH1)
#define TCG_TARGET_HAS_not_vec 1
#define TCG_TARGET_HAS_neg_vec 1
#define TCG_TARGET_HAS_abs_vec 1
#define TCG_TARGET_HAS_roti_vec 1
#define TCG_TARGET_HAS_rots_vec 1
#define TCG_TARGET_HAS_rotv_vec 1
#define TCG_TARGET_HAS_shi_vec 1
#define TCG_TARGET_HAS_shs_vec 1
#define TCG_TARGET_HAS_shv_vec 1
#define TCG_TARGET_HAS_mul_vec 1
#define TCG_TARGET_HAS_sat_vec 0
#define TCG_TARGET_HAS_minmax_vec 1
#define TCG_TARGET_HAS_bitsel_vec 1
#define TCG_TARGET_HAS_cmpsel_vec 1
#define TCG_TARGET_HAS_tst_vec 0
#define TCG_TARGET_extract_valid(type, ofs, len) 1
#define TCG_TARGET_deposit_valid(type, ofs, len) 1
static inline bool
tcg_target_sextract_valid(TCGType type, unsigned ofs, unsigned len)
{
if (ofs == 0) {
switch (len) {
case 8:
case 16:
return true;
case 32:
return type == TCG_TYPE_I64;
}
}
return false;
}
#define TCG_TARGET_sextract_valid tcg_target_sextract_valid
#endif

12
tcg/s390x/tcg-target-mo.h Normal file
View file

@ -0,0 +1,12 @@
/* SPDX-License-Identifier: MIT */
/*
* Define target-specific memory model
* Copyright (c) 2009 Ulrich Hecht <uli@suse.de>
*/
#ifndef TCG_TARGET_MO_H
#define TCG_TARGET_MO_H
#define TCG_TARGET_DEFAULT_MO (TCG_MO_ALL & ~TCG_MO_ST_LD)
#endif

View file

@ -10,6 +10,6 @@
* emitted by tcg_expand_vec_op. For those familiar with GCC internals,
* consider these to be UNSPEC with names.
*/
DEF(s390_vuph_vec, 1, 1, 0, IMPLVEC)
DEF(s390_vupl_vec, 1, 1, 0, IMPLVEC)
DEF(s390_vpks_vec, 1, 2, 0, IMPLVEC)
DEF(s390_vuph_vec, 1, 1, 0, TCG_OPF_VECTOR)
DEF(s390_vupl_vec, 1, 1, 0, TCG_OPF_VECTOR)
DEF(s390_vpks_vec, 1, 2, 0, TCG_OPF_VECTOR)

View file

@ -24,10 +24,16 @@
* THE SOFTWARE.
*/
#include "../tcg-ldst.c.inc"
#include "../tcg-pool.c.inc"
#include "elf.h"
/* Used for function call generation. */
#define TCG_TARGET_STACK_ALIGN 8
#define TCG_TARGET_CALL_STACK_OFFSET 160
#define TCG_TARGET_CALL_ARG_I32 TCG_CALL_ARG_EXTEND
#define TCG_TARGET_CALL_ARG_I64 TCG_CALL_ARG_NORMAL
#define TCG_TARGET_CALL_ARG_I128 TCG_CALL_ARG_BY_REF
#define TCG_TARGET_CALL_RET_I128 TCG_CALL_RET_BY_REF
#define TCG_CT_CONST_S16 (1 << 8)
#define TCG_CT_CONST_S32 (1 << 9)
#define TCG_CT_CONST_U32 (1 << 10)
@ -1566,9 +1572,41 @@ static void tgen_deposit(TCGContext *s, TCGReg dest, TCGReg src,
static void tgen_extract(TCGContext *s, TCGReg dest, TCGReg src,
int ofs, int len)
{
if (ofs == 0) {
switch (len) {
case 8:
tcg_out_ext8u(s, dest, src);
return;
case 16:
tcg_out_ext16u(s, dest, src);
return;
case 32:
tcg_out_ext32u(s, dest, src);
return;
}
}
tcg_out_risbg(s, dest, src, 64 - len, 63, 64 - ofs, 1);
}
static void tgen_sextract(TCGContext *s, TCGReg dest, TCGReg src,
int ofs, int len)
{
if (ofs == 0) {
switch (len) {
case 8:
tcg_out_ext8s(s, TCG_TYPE_REG, dest, src);
return;
case 16:
tcg_out_ext16s(s, TCG_TYPE_REG, dest, src);
return;
case 32:
tcg_out_ext32s(s, dest, src);
return;
}
}
g_assert_not_reached();
}
static void tgen_gotoi(TCGContext *s, int cc, const tcg_insn_unit *dest)
{
ptrdiff_t off = tcg_pcrel_diff(s, dest) >> 1;
@ -2111,7 +2149,7 @@ void tb_target_set_jmp_target(const TranslationBlock *tb, int n,
case glue(glue(INDEX_op_,x),_i32): \
case glue(glue(INDEX_op_,x),_i64)
static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
const TCGArg args[TCG_MAX_OP_ARGS],
const int const_args[TCG_MAX_OP_ARGS])
{
@ -2707,7 +2745,6 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
/* Since we can't support "0Z" as a constraint, we allow a1 in
any register. Fix things up as if a matching constraint. */
if (a0 != a1) {
TCGType type = (opc == INDEX_op_deposit_i64);
if (a0 == a2) {
tcg_out_mov(s, type, TCG_TMP0, a2);
a2 = TCG_TMP0;
@ -2721,6 +2758,9 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
OP_32_64(extract):
tgen_extract(s, args[0], args[1], args[2], args[3]);
break;
OP_32_64(sextract):
tgen_sextract(s, args[0], args[1], args[2], args[3]);
break;
case INDEX_op_clz_i64:
tgen_clz(s, args[0], args[1], args[2], const_args[2]);
@ -3201,7 +3241,8 @@ void tcg_expand_vec_op(TCGOpcode opc, TCGType type, unsigned vece,
va_end(va);
}
static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
static TCGConstraintSetIndex
tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
{
switch (op) {
case INDEX_op_goto_ptr:
@ -3319,6 +3360,8 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
case INDEX_op_extu_i32_i64:
case INDEX_op_extract_i32:
case INDEX_op_extract_i64:
case INDEX_op_sextract_i32:
case INDEX_op_sextract_i64:
case INDEX_op_ctpop_i32:
case INDEX_op_ctpop_i64:
return C_O1_I1(r, r);
@ -3421,7 +3464,7 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
: C_O1_I4(v, v, v, vZ, v));
default:
g_assert_not_reached();
return C_NotImplemented;
}
}

View file

@ -51,130 +51,4 @@ typedef enum TCGReg {
#define TCG_TARGET_NB_REGS 64
/* Facilities required for proper operation; checked at startup. */
#define FACILITY_ZARCH_ACTIVE 2
#define FACILITY_LONG_DISP 18
#define FACILITY_EXT_IMM 21
#define FACILITY_GEN_INST_EXT 34
#define FACILITY_45 45
/* Facilities that are checked at runtime. */
#define FACILITY_LOAD_ON_COND2 53
#define FACILITY_MISC_INSN_EXT2 58
#define FACILITY_MISC_INSN_EXT3 61
#define FACILITY_VECTOR 129
#define FACILITY_VECTOR_ENH1 135
extern uint64_t s390_facilities[3];
#define HAVE_FACILITY(X) \
((s390_facilities[FACILITY_##X / 64] >> (63 - FACILITY_##X % 64)) & 1)
/* optional instructions */
#define TCG_TARGET_HAS_div2_i32 1
#define TCG_TARGET_HAS_rot_i32 1
#define TCG_TARGET_HAS_ext8s_i32 1
#define TCG_TARGET_HAS_ext16s_i32 1
#define TCG_TARGET_HAS_ext8u_i32 1
#define TCG_TARGET_HAS_ext16u_i32 1
#define TCG_TARGET_HAS_bswap16_i32 1
#define TCG_TARGET_HAS_bswap32_i32 1
#define TCG_TARGET_HAS_not_i32 HAVE_FACILITY(MISC_INSN_EXT3)
#define TCG_TARGET_HAS_andc_i32 HAVE_FACILITY(MISC_INSN_EXT3)
#define TCG_TARGET_HAS_orc_i32 HAVE_FACILITY(MISC_INSN_EXT3)
#define TCG_TARGET_HAS_eqv_i32 HAVE_FACILITY(MISC_INSN_EXT3)
#define TCG_TARGET_HAS_nand_i32 HAVE_FACILITY(MISC_INSN_EXT3)
#define TCG_TARGET_HAS_nor_i32 HAVE_FACILITY(MISC_INSN_EXT3)
#define TCG_TARGET_HAS_clz_i32 0
#define TCG_TARGET_HAS_ctz_i32 0
#define TCG_TARGET_HAS_ctpop_i32 1
#define TCG_TARGET_HAS_deposit_i32 1
#define TCG_TARGET_HAS_extract_i32 1
#define TCG_TARGET_HAS_sextract_i32 0
#define TCG_TARGET_HAS_extract2_i32 0
#define TCG_TARGET_HAS_negsetcond_i32 1
#define TCG_TARGET_HAS_add2_i32 1
#define TCG_TARGET_HAS_sub2_i32 1
#define TCG_TARGET_HAS_mulu2_i32 0
#define TCG_TARGET_HAS_muls2_i32 0
#define TCG_TARGET_HAS_muluh_i32 0
#define TCG_TARGET_HAS_mulsh_i32 0
#define TCG_TARGET_HAS_extr_i64_i32 0
#define TCG_TARGET_HAS_qemu_st8_i32 0
#define TCG_TARGET_HAS_div2_i64 1
#define TCG_TARGET_HAS_rot_i64 1
#define TCG_TARGET_HAS_ext8s_i64 1
#define TCG_TARGET_HAS_ext16s_i64 1
#define TCG_TARGET_HAS_ext32s_i64 1
#define TCG_TARGET_HAS_ext8u_i64 1
#define TCG_TARGET_HAS_ext16u_i64 1
#define TCG_TARGET_HAS_ext32u_i64 1
#define TCG_TARGET_HAS_bswap16_i64 1
#define TCG_TARGET_HAS_bswap32_i64 1
#define TCG_TARGET_HAS_bswap64_i64 1
#define TCG_TARGET_HAS_not_i64 HAVE_FACILITY(MISC_INSN_EXT3)
#define TCG_TARGET_HAS_andc_i64 HAVE_FACILITY(MISC_INSN_EXT3)
#define TCG_TARGET_HAS_orc_i64 HAVE_FACILITY(MISC_INSN_EXT3)
#define TCG_TARGET_HAS_eqv_i64 HAVE_FACILITY(MISC_INSN_EXT3)
#define TCG_TARGET_HAS_nand_i64 HAVE_FACILITY(MISC_INSN_EXT3)
#define TCG_TARGET_HAS_nor_i64 HAVE_FACILITY(MISC_INSN_EXT3)
#define TCG_TARGET_HAS_clz_i64 1
#define TCG_TARGET_HAS_ctz_i64 0
#define TCG_TARGET_HAS_ctpop_i64 1
#define TCG_TARGET_HAS_deposit_i64 1
#define TCG_TARGET_HAS_extract_i64 1
#define TCG_TARGET_HAS_sextract_i64 0
#define TCG_TARGET_HAS_extract2_i64 0
#define TCG_TARGET_HAS_negsetcond_i64 1
#define TCG_TARGET_HAS_add2_i64 1
#define TCG_TARGET_HAS_sub2_i64 1
#define TCG_TARGET_HAS_mulu2_i64 1
#define TCG_TARGET_HAS_muls2_i64 HAVE_FACILITY(MISC_INSN_EXT2)
#define TCG_TARGET_HAS_muluh_i64 0
#define TCG_TARGET_HAS_mulsh_i64 0
#define TCG_TARGET_HAS_qemu_ldst_i128 1
#define TCG_TARGET_HAS_tst 1
#define TCG_TARGET_HAS_v64 HAVE_FACILITY(VECTOR)
#define TCG_TARGET_HAS_v128 HAVE_FACILITY(VECTOR)
#define TCG_TARGET_HAS_v256 0
#define TCG_TARGET_HAS_andc_vec 1
#define TCG_TARGET_HAS_orc_vec HAVE_FACILITY(VECTOR_ENH1)
#define TCG_TARGET_HAS_nand_vec HAVE_FACILITY(VECTOR_ENH1)
#define TCG_TARGET_HAS_nor_vec 1
#define TCG_TARGET_HAS_eqv_vec HAVE_FACILITY(VECTOR_ENH1)
#define TCG_TARGET_HAS_not_vec 1
#define TCG_TARGET_HAS_neg_vec 1
#define TCG_TARGET_HAS_abs_vec 1
#define TCG_TARGET_HAS_roti_vec 1
#define TCG_TARGET_HAS_rots_vec 1
#define TCG_TARGET_HAS_rotv_vec 1
#define TCG_TARGET_HAS_shi_vec 1
#define TCG_TARGET_HAS_shs_vec 1
#define TCG_TARGET_HAS_shv_vec 1
#define TCG_TARGET_HAS_mul_vec 1
#define TCG_TARGET_HAS_sat_vec 0
#define TCG_TARGET_HAS_minmax_vec 1
#define TCG_TARGET_HAS_bitsel_vec 1
#define TCG_TARGET_HAS_cmpsel_vec 1
#define TCG_TARGET_HAS_tst_vec 0
/* used for function call generation */
#define TCG_TARGET_STACK_ALIGN 8
#define TCG_TARGET_CALL_STACK_OFFSET 160
#define TCG_TARGET_CALL_ARG_I32 TCG_CALL_ARG_EXTEND
#define TCG_TARGET_CALL_ARG_I64 TCG_CALL_ARG_NORMAL
#define TCG_TARGET_CALL_ARG_I128 TCG_CALL_ARG_BY_REF
#define TCG_TARGET_CALL_RET_I128 TCG_CALL_RET_BY_REF
#define TCG_TARGET_DEFAULT_MO (TCG_MO_ALL & ~TCG_MO_ST_LD)
#define TCG_TARGET_NEED_LDST_LABELS
#define TCG_TARGET_NEED_POOL_LABELS
#endif

View file

@ -0,0 +1,87 @@
/* SPDX-License-Identifier: MIT */
/*
* Define target-specific opcode support
* Copyright (c) 2008 Fabrice Bellard
*/
#ifndef TCG_TARGET_HAS_H
#define TCG_TARGET_HAS_H
#if defined(__VIS__) && __VIS__ >= 0x300
#define use_vis3_instructions 1
#else
extern bool use_vis3_instructions;
#endif
/* optional instructions */
#define TCG_TARGET_HAS_div_i32 1
#define TCG_TARGET_HAS_rem_i32 0
#define TCG_TARGET_HAS_rot_i32 0
#define TCG_TARGET_HAS_ext8s_i32 0
#define TCG_TARGET_HAS_ext16s_i32 0
#define TCG_TARGET_HAS_ext8u_i32 0
#define TCG_TARGET_HAS_ext16u_i32 0
#define TCG_TARGET_HAS_bswap16_i32 0
#define TCG_TARGET_HAS_bswap32_i32 0
#define TCG_TARGET_HAS_not_i32 1
#define TCG_TARGET_HAS_andc_i32 1
#define TCG_TARGET_HAS_orc_i32 1
#define TCG_TARGET_HAS_eqv_i32 0
#define TCG_TARGET_HAS_nand_i32 0
#define TCG_TARGET_HAS_nor_i32 0
#define TCG_TARGET_HAS_clz_i32 0
#define TCG_TARGET_HAS_ctz_i32 0
#define TCG_TARGET_HAS_ctpop_i32 0
#define TCG_TARGET_HAS_extract2_i32 0
#define TCG_TARGET_HAS_negsetcond_i32 1
#define TCG_TARGET_HAS_add2_i32 1
#define TCG_TARGET_HAS_sub2_i32 1
#define TCG_TARGET_HAS_mulu2_i32 1
#define TCG_TARGET_HAS_muls2_i32 1
#define TCG_TARGET_HAS_muluh_i32 0
#define TCG_TARGET_HAS_mulsh_i32 0
#define TCG_TARGET_HAS_qemu_st8_i32 0
#define TCG_TARGET_HAS_extr_i64_i32 0
#define TCG_TARGET_HAS_div_i64 1
#define TCG_TARGET_HAS_rem_i64 0
#define TCG_TARGET_HAS_rot_i64 0
#define TCG_TARGET_HAS_ext8s_i64 0
#define TCG_TARGET_HAS_ext16s_i64 0
#define TCG_TARGET_HAS_ext32s_i64 1
#define TCG_TARGET_HAS_ext8u_i64 0
#define TCG_TARGET_HAS_ext16u_i64 0
#define TCG_TARGET_HAS_ext32u_i64 1
#define TCG_TARGET_HAS_bswap16_i64 0
#define TCG_TARGET_HAS_bswap32_i64 0
#define TCG_TARGET_HAS_bswap64_i64 0
#define TCG_TARGET_HAS_not_i64 1
#define TCG_TARGET_HAS_andc_i64 1
#define TCG_TARGET_HAS_orc_i64 1
#define TCG_TARGET_HAS_eqv_i64 0
#define TCG_TARGET_HAS_nand_i64 0
#define TCG_TARGET_HAS_nor_i64 0
#define TCG_TARGET_HAS_clz_i64 0
#define TCG_TARGET_HAS_ctz_i64 0
#define TCG_TARGET_HAS_ctpop_i64 0
#define TCG_TARGET_HAS_extract2_i64 0
#define TCG_TARGET_HAS_negsetcond_i64 1
#define TCG_TARGET_HAS_add2_i64 1
#define TCG_TARGET_HAS_sub2_i64 1
#define TCG_TARGET_HAS_mulu2_i64 0
#define TCG_TARGET_HAS_muls2_i64 0
#define TCG_TARGET_HAS_muluh_i64 use_vis3_instructions
#define TCG_TARGET_HAS_mulsh_i64 0
#define TCG_TARGET_HAS_qemu_ldst_i128 0
#define TCG_TARGET_HAS_tst 1
#define TCG_TARGET_extract_valid(type, ofs, len) \
((type) == TCG_TYPE_I64 && (ofs) + (len) == 32)
#define TCG_TARGET_sextract_valid TCG_TARGET_extract_valid
#define TCG_TARGET_deposit_valid(type, ofs, len) 0
#endif

View file

@ -0,0 +1,12 @@
/* SPDX-License-Identifier: MIT */
/*
* Define target-specific memory model
* Copyright (c) 2008 Fabrice Bellard
*/
#ifndef TCG_TARGET_MO_H
#define TCG_TARGET_MO_H
#define TCG_TARGET_DEFAULT_MO 0
#endif

View file

@ -0,0 +1 @@
/* No target specific opcodes. */

View file

@ -27,8 +27,15 @@
#error "unsupported code generation mode"
#endif
#include "../tcg-ldst.c.inc"
#include "../tcg-pool.c.inc"
/* Used for function call generation. */
#define TCG_REG_CALL_STACK TCG_REG_O6
#define TCG_TARGET_STACK_BIAS 2047
#define TCG_TARGET_STACK_ALIGN 16
#define TCG_TARGET_CALL_STACK_OFFSET (128 + 6 * 8 + TCG_TARGET_STACK_BIAS)
#define TCG_TARGET_CALL_ARG_I32 TCG_CALL_ARG_EXTEND
#define TCG_TARGET_CALL_ARG_I64 TCG_CALL_ARG_NORMAL
#define TCG_TARGET_CALL_ARG_I128 TCG_CALL_ARG_NORMAL
#define TCG_TARGET_CALL_RET_I128 TCG_CALL_RET_NORMAL
#ifdef CONFIG_DEBUG_TCG
static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
@ -1281,7 +1288,7 @@ void tb_target_set_jmp_target(const TranslationBlock *tb, int n,
{
}
static void tcg_out_op(TCGContext *s, TCGOpcode opc,
static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
const TCGArg args[TCG_MAX_OP_ARGS],
const int const_args[TCG_MAX_OP_ARGS])
{
@ -1503,6 +1510,15 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
tcg_out_mb(s, a0);
break;
case INDEX_op_extract_i64:
tcg_debug_assert(a2 + args[3] == 32);
tcg_out_arithi(s, a0, a1, a2, SHIFT_SRL);
break;
case INDEX_op_sextract_i64:
tcg_debug_assert(a2 + args[3] == 32);
tcg_out_arithi(s, a0, a1, a2, SHIFT_SRA);
break;
case INDEX_op_mov_i32: /* Always emitted via tcg_out_mov. */
case INDEX_op_mov_i64:
case INDEX_op_call: /* Always emitted via tcg_out_call. */
@ -1525,7 +1541,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
}
}
static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
static TCGConstraintSetIndex
tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
{
switch (op) {
case INDEX_op_goto_ptr:
@ -1551,6 +1568,8 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
case INDEX_op_ext32u_i64:
case INDEX_op_ext_i32_i64:
case INDEX_op_extu_i32_i64:
case INDEX_op_extract_i64:
case INDEX_op_sextract_i64:
case INDEX_op_qemu_ld_a32_i32:
case INDEX_op_qemu_ld_a64_i32:
case INDEX_op_qemu_ld_a32_i64:
@ -1620,7 +1639,7 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
return C_O1_I2(r, r, r);
default:
g_assert_not_reached();
return C_NotImplemented;
}
}

View file

@ -64,97 +64,6 @@ typedef enum {
TCG_REG_I7,
} TCGReg;
/* used for function call generation */
#define TCG_REG_CALL_STACK TCG_REG_O6
#define TCG_TARGET_STACK_BIAS 2047
#define TCG_TARGET_STACK_ALIGN 16
#define TCG_TARGET_CALL_STACK_OFFSET (128 + 6*8 + TCG_TARGET_STACK_BIAS)
#define TCG_TARGET_CALL_ARG_I32 TCG_CALL_ARG_EXTEND
#define TCG_TARGET_CALL_ARG_I64 TCG_CALL_ARG_NORMAL
#define TCG_TARGET_CALL_ARG_I128 TCG_CALL_ARG_NORMAL
#define TCG_TARGET_CALL_RET_I128 TCG_CALL_RET_NORMAL
#if defined(__VIS__) && __VIS__ >= 0x300
#define use_vis3_instructions 1
#else
extern bool use_vis3_instructions;
#endif
/* optional instructions */
#define TCG_TARGET_HAS_div_i32 1
#define TCG_TARGET_HAS_rem_i32 0
#define TCG_TARGET_HAS_rot_i32 0
#define TCG_TARGET_HAS_ext8s_i32 0
#define TCG_TARGET_HAS_ext16s_i32 0
#define TCG_TARGET_HAS_ext8u_i32 0
#define TCG_TARGET_HAS_ext16u_i32 0
#define TCG_TARGET_HAS_bswap16_i32 0
#define TCG_TARGET_HAS_bswap32_i32 0
#define TCG_TARGET_HAS_not_i32 1
#define TCG_TARGET_HAS_andc_i32 1
#define TCG_TARGET_HAS_orc_i32 1
#define TCG_TARGET_HAS_eqv_i32 0
#define TCG_TARGET_HAS_nand_i32 0
#define TCG_TARGET_HAS_nor_i32 0
#define TCG_TARGET_HAS_clz_i32 0
#define TCG_TARGET_HAS_ctz_i32 0
#define TCG_TARGET_HAS_ctpop_i32 0
#define TCG_TARGET_HAS_deposit_i32 0
#define TCG_TARGET_HAS_extract_i32 0
#define TCG_TARGET_HAS_sextract_i32 0
#define TCG_TARGET_HAS_extract2_i32 0
#define TCG_TARGET_HAS_negsetcond_i32 1
#define TCG_TARGET_HAS_add2_i32 1
#define TCG_TARGET_HAS_sub2_i32 1
#define TCG_TARGET_HAS_mulu2_i32 1
#define TCG_TARGET_HAS_muls2_i32 1
#define TCG_TARGET_HAS_muluh_i32 0
#define TCG_TARGET_HAS_mulsh_i32 0
#define TCG_TARGET_HAS_qemu_st8_i32 0
#define TCG_TARGET_HAS_extr_i64_i32 0
#define TCG_TARGET_HAS_div_i64 1
#define TCG_TARGET_HAS_rem_i64 0
#define TCG_TARGET_HAS_rot_i64 0
#define TCG_TARGET_HAS_ext8s_i64 0
#define TCG_TARGET_HAS_ext16s_i64 0
#define TCG_TARGET_HAS_ext32s_i64 1
#define TCG_TARGET_HAS_ext8u_i64 0
#define TCG_TARGET_HAS_ext16u_i64 0
#define TCG_TARGET_HAS_ext32u_i64 1
#define TCG_TARGET_HAS_bswap16_i64 0
#define TCG_TARGET_HAS_bswap32_i64 0
#define TCG_TARGET_HAS_bswap64_i64 0
#define TCG_TARGET_HAS_not_i64 1
#define TCG_TARGET_HAS_andc_i64 1
#define TCG_TARGET_HAS_orc_i64 1
#define TCG_TARGET_HAS_eqv_i64 0
#define TCG_TARGET_HAS_nand_i64 0
#define TCG_TARGET_HAS_nor_i64 0
#define TCG_TARGET_HAS_clz_i64 0
#define TCG_TARGET_HAS_ctz_i64 0
#define TCG_TARGET_HAS_ctpop_i64 0
#define TCG_TARGET_HAS_deposit_i64 0
#define TCG_TARGET_HAS_extract_i64 0
#define TCG_TARGET_HAS_sextract_i64 0
#define TCG_TARGET_HAS_extract2_i64 0
#define TCG_TARGET_HAS_negsetcond_i64 1
#define TCG_TARGET_HAS_add2_i64 1
#define TCG_TARGET_HAS_sub2_i64 1
#define TCG_TARGET_HAS_mulu2_i64 0
#define TCG_TARGET_HAS_muls2_i64 0
#define TCG_TARGET_HAS_muluh_i64 use_vis3_instructions
#define TCG_TARGET_HAS_mulsh_i64 0
#define TCG_TARGET_HAS_qemu_ldst_i128 0
#define TCG_TARGET_HAS_tst 1
#define TCG_AREG0 TCG_REG_I0
#define TCG_TARGET_DEFAULT_MO (0)
#define TCG_TARGET_NEED_LDST_LABELS
#define TCG_TARGET_NEED_POOL_LABELS
#endif

View file

@ -24,10 +24,11 @@
#include "qemu/osdep.h"
#include "tcg/tcg.h"
#include "tcg-has.h"
TCGOpDef tcg_op_defs[] = {
const TCGOpDef tcg_op_defs[] = {
#define DEF(s, oargs, iargs, cargs, flags) \
{ #s, oargs, iargs, cargs, iargs + oargs + cargs, flags, NULL },
{ #s, oargs, iargs, cargs, iargs + oargs + cargs, flags },
#include "tcg/tcg-opc.h"
#undef DEF
};

101
tcg/tcg-has.h Normal file
View file

@ -0,0 +1,101 @@
/* SPDX-License-Identifier: MIT */
/*
* Define target-specific opcode support
* Copyright (c) 2024 Linaro, Ltd.
*/
#ifndef TCG_HAS_H
#define TCG_HAS_H
#include "tcg-target-has.h"
#if TCG_TARGET_REG_BITS == 32
/* Turn some undef macros into false macros. */
#define TCG_TARGET_HAS_extr_i64_i32 0
#define TCG_TARGET_HAS_div_i64 0
#define TCG_TARGET_HAS_rem_i64 0
#define TCG_TARGET_HAS_div2_i64 0
#define TCG_TARGET_HAS_rot_i64 0
#define TCG_TARGET_HAS_ext8s_i64 0
#define TCG_TARGET_HAS_ext16s_i64 0
#define TCG_TARGET_HAS_ext32s_i64 0
#define TCG_TARGET_HAS_ext8u_i64 0
#define TCG_TARGET_HAS_ext16u_i64 0
#define TCG_TARGET_HAS_ext32u_i64 0
#define TCG_TARGET_HAS_bswap16_i64 0
#define TCG_TARGET_HAS_bswap32_i64 0
#define TCG_TARGET_HAS_bswap64_i64 0
#define TCG_TARGET_HAS_not_i64 0
#define TCG_TARGET_HAS_andc_i64 0
#define TCG_TARGET_HAS_orc_i64 0
#define TCG_TARGET_HAS_eqv_i64 0
#define TCG_TARGET_HAS_nand_i64 0
#define TCG_TARGET_HAS_nor_i64 0
#define TCG_TARGET_HAS_clz_i64 0
#define TCG_TARGET_HAS_ctz_i64 0
#define TCG_TARGET_HAS_ctpop_i64 0
#define TCG_TARGET_HAS_extract2_i64 0
#define TCG_TARGET_HAS_negsetcond_i64 0
#define TCG_TARGET_HAS_add2_i64 0
#define TCG_TARGET_HAS_sub2_i64 0
#define TCG_TARGET_HAS_mulu2_i64 0
#define TCG_TARGET_HAS_muls2_i64 0
#define TCG_TARGET_HAS_muluh_i64 0
#define TCG_TARGET_HAS_mulsh_i64 0
/* Turn some undef macros into true macros. */
#define TCG_TARGET_HAS_add2_i32 1
#define TCG_TARGET_HAS_sub2_i32 1
#endif
/* Only one of DIV or DIV2 should be defined. */
#if defined(TCG_TARGET_HAS_div_i32)
#define TCG_TARGET_HAS_div2_i32 0
#elif defined(TCG_TARGET_HAS_div2_i32)
#define TCG_TARGET_HAS_div_i32 0
#define TCG_TARGET_HAS_rem_i32 0
#endif
#if defined(TCG_TARGET_HAS_div_i64)
#define TCG_TARGET_HAS_div2_i64 0
#elif defined(TCG_TARGET_HAS_div2_i64)
#define TCG_TARGET_HAS_div_i64 0
#define TCG_TARGET_HAS_rem_i64 0
#endif
#if !defined(TCG_TARGET_HAS_v64) \
&& !defined(TCG_TARGET_HAS_v128) \
&& !defined(TCG_TARGET_HAS_v256)
#define TCG_TARGET_MAYBE_vec 0
#define TCG_TARGET_HAS_abs_vec 0
#define TCG_TARGET_HAS_neg_vec 0
#define TCG_TARGET_HAS_not_vec 0
#define TCG_TARGET_HAS_andc_vec 0
#define TCG_TARGET_HAS_orc_vec 0
#define TCG_TARGET_HAS_nand_vec 0
#define TCG_TARGET_HAS_nor_vec 0
#define TCG_TARGET_HAS_eqv_vec 0
#define TCG_TARGET_HAS_roti_vec 0
#define TCG_TARGET_HAS_rots_vec 0
#define TCG_TARGET_HAS_rotv_vec 0
#define TCG_TARGET_HAS_shi_vec 0
#define TCG_TARGET_HAS_shs_vec 0
#define TCG_TARGET_HAS_shv_vec 0
#define TCG_TARGET_HAS_mul_vec 0
#define TCG_TARGET_HAS_sat_vec 0
#define TCG_TARGET_HAS_minmax_vec 0
#define TCG_TARGET_HAS_bitsel_vec 0
#define TCG_TARGET_HAS_cmpsel_vec 0
#define TCG_TARGET_HAS_tst_vec 0
#else
#define TCG_TARGET_MAYBE_vec 1
#endif
#ifndef TCG_TARGET_HAS_v64
#define TCG_TARGET_HAS_v64 0
#endif
#ifndef TCG_TARGET_HAS_v128
#define TCG_TARGET_HAS_v128 0
#endif
#ifndef TCG_TARGET_HAS_v256
#define TCG_TARGET_HAS_v256 0
#endif
#endif

View file

@ -92,12 +92,13 @@ TCGTemp *tcg_temp_new_internal(TCGType type, TCGTempKind kind);
*/
TCGTemp *tcg_constant_internal(TCGType type, int64_t val);
TCGOp *tcg_gen_op1(TCGOpcode, TCGArg);
TCGOp *tcg_gen_op2(TCGOpcode, TCGArg, TCGArg);
TCGOp *tcg_gen_op3(TCGOpcode, TCGArg, TCGArg, TCGArg);
TCGOp *tcg_gen_op4(TCGOpcode, TCGArg, TCGArg, TCGArg, TCGArg);
TCGOp *tcg_gen_op5(TCGOpcode, TCGArg, TCGArg, TCGArg, TCGArg, TCGArg);
TCGOp *tcg_gen_op6(TCGOpcode, TCGArg, TCGArg, TCGArg, TCGArg, TCGArg, TCGArg);
TCGOp *tcg_gen_op1(TCGOpcode, TCGType, TCGArg);
TCGOp *tcg_gen_op2(TCGOpcode, TCGType, TCGArg, TCGArg);
TCGOp *tcg_gen_op3(TCGOpcode, TCGType, TCGArg, TCGArg, TCGArg);
TCGOp *tcg_gen_op4(TCGOpcode, TCGType, TCGArg, TCGArg, TCGArg, TCGArg);
TCGOp *tcg_gen_op5(TCGOpcode, TCGType, TCGArg, TCGArg, TCGArg, TCGArg, TCGArg);
TCGOp *tcg_gen_op6(TCGOpcode, TCGType, TCGArg, TCGArg,
TCGArg, TCGArg, TCGArg, TCGArg);
void vec_gen_2(TCGOpcode, TCGType, unsigned, TCGArg, TCGArg);
void vec_gen_3(TCGOpcode, TCGType, unsigned, TCGArg, TCGArg, TCGArg);
@ -105,4 +106,9 @@ void vec_gen_4(TCGOpcode, TCGType, unsigned, TCGArg, TCGArg, TCGArg, TCGArg);
void vec_gen_6(TCGOpcode opc, TCGType type, unsigned vece, TCGArg r,
TCGArg a, TCGArg b, TCGArg c, TCGArg d, TCGArg e);
TCGOp *tcg_op_insert_before(TCGContext *s, TCGOp *op,
TCGOpcode opc, unsigned nargs);
TCGOp *tcg_op_insert_after(TCGContext *s, TCGOp *op,
TCGOpcode opc, unsigned nargs);
#endif /* TCG_INTERNAL_H */

View file

@ -1,65 +0,0 @@
/*
* TCG Backend Data: load-store optimization only.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/*
* Generate TB finalization at the end of block
*/
static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l);
static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l);
static int tcg_out_ldst_finalize(TCGContext *s)
{
TCGLabelQemuLdst *lb;
/* qemu_ld/st slow paths */
QSIMPLEQ_FOREACH(lb, &s->ldst_labels, next) {
if (lb->is_ld
? !tcg_out_qemu_ld_slow_path(s, lb)
: !tcg_out_qemu_st_slow_path(s, lb)) {
return -2;
}
/* Test for (pending) buffer overflow. The assumption is that any
one operation beginning below the high water mark cannot overrun
the buffer completely. Thus we can test for overflow after
generating code without having to check during generation. */
if (unlikely((void *)s->code_ptr > s->code_gen_highwater)) {
return -1;
}
}
return 0;
}
/*
* Allocate a new TCGLabelQemuLdst entry.
*/
static inline TCGLabelQemuLdst *new_ldst_label(TCGContext *s)
{
TCGLabelQemuLdst *l = tcg_malloc(sizeof(*l));
memset(l, 0, sizeof(*l));
QSIMPLEQ_INSERT_TAIL(&s->ldst_labels, l, next);
return l;
}

View file

@ -23,6 +23,7 @@
#include "tcg/tcg-op-common.h"
#include "tcg/tcg-op-gvec-common.h"
#include "tcg/tcg-gvec-desc.h"
#include "tcg-has.h"
#define MAX_UNROLL 4

View file

@ -30,7 +30,8 @@
#include "exec/translation-block.h"
#include "exec/plugin-gen.h"
#include "tcg-internal.h"
#include "tcg-has.h"
#include "tcg-target-mo.h"
static void check_max_alignment(unsigned a_bits)
{
@ -87,14 +88,15 @@ static MemOp tcg_canonicalize_memop(MemOp op, bool is64, bool st)
return op;
}
static void gen_ldst(TCGOpcode opc, TCGTemp *vl, TCGTemp *vh,
static void gen_ldst(TCGOpcode opc, TCGType type, TCGTemp *vl, TCGTemp *vh,
TCGTemp *addr, MemOpIdx oi)
{
if (TCG_TARGET_REG_BITS == 64 || tcg_ctx->addr_type == TCG_TYPE_I32) {
if (vh) {
tcg_gen_op4(opc, temp_arg(vl), temp_arg(vh), temp_arg(addr), oi);
tcg_gen_op4(opc, type, temp_arg(vl), temp_arg(vh),
temp_arg(addr), oi);
} else {
tcg_gen_op3(opc, temp_arg(vl), temp_arg(addr), oi);
tcg_gen_op3(opc, type, temp_arg(vl), temp_arg(addr), oi);
}
} else {
/* See TCGV_LOW/HIGH. */
@ -102,10 +104,11 @@ static void gen_ldst(TCGOpcode opc, TCGTemp *vl, TCGTemp *vh,
TCGTemp *ah = addr + !HOST_BIG_ENDIAN;
if (vh) {
tcg_gen_op5(opc, temp_arg(vl), temp_arg(vh),
tcg_gen_op5(opc, type, temp_arg(vl), temp_arg(vh),
temp_arg(al), temp_arg(ah), oi);
} else {
tcg_gen_op4(opc, temp_arg(vl), temp_arg(al), temp_arg(ah), oi);
tcg_gen_op4(opc, type, temp_arg(vl),
temp_arg(al), temp_arg(ah), oi);
}
}
}
@ -115,9 +118,9 @@ static void gen_ldst_i64(TCGOpcode opc, TCGv_i64 v, TCGTemp *addr, MemOpIdx oi)
if (TCG_TARGET_REG_BITS == 32) {
TCGTemp *vl = tcgv_i32_temp(TCGV_LOW(v));
TCGTemp *vh = tcgv_i32_temp(TCGV_HIGH(v));
gen_ldst(opc, vl, vh, addr, oi);
gen_ldst(opc, TCG_TYPE_I64, vl, vh, addr, oi);
} else {
gen_ldst(opc, tcgv_i64_temp(v), NULL, addr, oi);
gen_ldst(opc, TCG_TYPE_I64, tcgv_i64_temp(v), NULL, addr, oi);
}
}
@ -250,7 +253,7 @@ static void tcg_gen_qemu_ld_i32_int(TCGv_i32 val, TCGTemp *addr,
} else {
opc = INDEX_op_qemu_ld_a64_i32;
}
gen_ldst(opc, tcgv_i32_temp(val), NULL, addr, oi);
gen_ldst(opc, TCG_TYPE_I32, tcgv_i32_temp(val), NULL, addr, oi);
plugin_gen_mem_callbacks_i32(val, copy_addr, addr, orig_oi,
QEMU_PLUGIN_MEM_R);
@ -319,7 +322,7 @@ static void tcg_gen_qemu_st_i32_int(TCGv_i32 val, TCGTemp *addr,
opc = INDEX_op_qemu_st_a64_i32;
}
}
gen_ldst(opc, tcgv_i32_temp(val), NULL, addr, oi);
gen_ldst(opc, TCG_TYPE_I32, tcgv_i32_temp(val), NULL, addr, oi);
plugin_gen_mem_callbacks_i32(val, NULL, addr, orig_oi, QEMU_PLUGIN_MEM_W);
if (swap) {
@ -590,7 +593,8 @@ static void tcg_gen_qemu_ld_i128_int(TCGv_i128 val, TCGTemp *addr,
} else {
opc = INDEX_op_qemu_ld_a64_i128;
}
gen_ldst(opc, tcgv_i64_temp(lo), tcgv_i64_temp(hi), addr, oi);
gen_ldst(opc, TCG_TYPE_I128, tcgv_i64_temp(lo),
tcgv_i64_temp(hi), addr, oi);
if (need_bswap) {
tcg_gen_bswap64_i64(lo, lo);
@ -710,7 +714,8 @@ static void tcg_gen_qemu_st_i128_int(TCGv_i128 val, TCGTemp *addr,
} else {
opc = INDEX_op_qemu_st_a64_i128;
}
gen_ldst(opc, tcgv_i64_temp(lo), tcgv_i64_temp(hi), addr, oi);
gen_ldst(opc, TCG_TYPE_I128, tcgv_i64_temp(lo),
tcgv_i64_temp(hi), addr, oi);
if (need_bswap) {
tcg_temp_free_i64(lo);

View file

@ -23,6 +23,7 @@
#include "tcg/tcg-op-common.h"
#include "tcg/tcg-mo.h"
#include "tcg-internal.h"
#include "tcg-has.h"
/*
* Vector optional opcode tracking.
@ -143,7 +144,7 @@ bool tcg_can_emit_vecop_list(const TCGOpcode *list,
void vec_gen_2(TCGOpcode opc, TCGType type, unsigned vece, TCGArg r, TCGArg a)
{
TCGOp *op = tcg_emit_op(opc, 2);
TCGOP_VECL(op) = type - TCG_TYPE_V64;
TCGOP_TYPE(op) = type;
TCGOP_VECE(op) = vece;
op->args[0] = r;
op->args[1] = a;
@ -153,7 +154,7 @@ void vec_gen_3(TCGOpcode opc, TCGType type, unsigned vece,
TCGArg r, TCGArg a, TCGArg b)
{
TCGOp *op = tcg_emit_op(opc, 3);
TCGOP_VECL(op) = type - TCG_TYPE_V64;
TCGOP_TYPE(op) = type;
TCGOP_VECE(op) = vece;
op->args[0] = r;
op->args[1] = a;
@ -164,7 +165,7 @@ void vec_gen_4(TCGOpcode opc, TCGType type, unsigned vece,
TCGArg r, TCGArg a, TCGArg b, TCGArg c)
{
TCGOp *op = tcg_emit_op(opc, 4);
TCGOP_VECL(op) = type - TCG_TYPE_V64;
TCGOP_TYPE(op) = type;
TCGOP_VECE(op) = vece;
op->args[0] = r;
op->args[1] = a;
@ -176,7 +177,7 @@ void vec_gen_6(TCGOpcode opc, TCGType type, unsigned vece, TCGArg r,
TCGArg a, TCGArg b, TCGArg c, TCGArg d, TCGArg e)
{
TCGOp *op = tcg_emit_op(opc, 6);
TCGOP_VECL(op) = type - TCG_TYPE_V64;
TCGOP_TYPE(op) = type;
TCGOP_VECE(op) = vece;
op->args[0] = r;
op->args[1] = a;

View file

@ -29,7 +29,7 @@
#include "exec/translation-block.h"
#include "exec/plugin-gen.h"
#include "tcg-internal.h"
#include "tcg-has.h"
/*
* Encourage the compiler to tail-call to a function, rather than inlining.
@ -37,34 +37,39 @@
*/
#define NI __attribute__((noinline))
TCGOp * NI tcg_gen_op1(TCGOpcode opc, TCGArg a1)
TCGOp * NI tcg_gen_op1(TCGOpcode opc, TCGType type, TCGArg a1)
{
TCGOp *op = tcg_emit_op(opc, 1);
TCGOP_TYPE(op) = type;
op->args[0] = a1;
return op;
}
TCGOp * NI tcg_gen_op2(TCGOpcode opc, TCGArg a1, TCGArg a2)
TCGOp * NI tcg_gen_op2(TCGOpcode opc, TCGType type, TCGArg a1, TCGArg a2)
{
TCGOp *op = tcg_emit_op(opc, 2);
TCGOP_TYPE(op) = type;
op->args[0] = a1;
op->args[1] = a2;
return op;
}
TCGOp * NI tcg_gen_op3(TCGOpcode opc, TCGArg a1, TCGArg a2, TCGArg a3)
TCGOp * NI tcg_gen_op3(TCGOpcode opc, TCGType type, TCGArg a1,
TCGArg a2, TCGArg a3)
{
TCGOp *op = tcg_emit_op(opc, 3);
TCGOP_TYPE(op) = type;
op->args[0] = a1;
op->args[1] = a2;
op->args[2] = a3;
return op;
}
TCGOp * NI tcg_gen_op4(TCGOpcode opc, TCGArg a1, TCGArg a2,
TCGOp * NI tcg_gen_op4(TCGOpcode opc, TCGType type, TCGArg a1, TCGArg a2,
TCGArg a3, TCGArg a4)
{
TCGOp *op = tcg_emit_op(opc, 4);
TCGOP_TYPE(op) = type;
op->args[0] = a1;
op->args[1] = a2;
op->args[2] = a3;
@ -72,10 +77,11 @@ TCGOp * NI tcg_gen_op4(TCGOpcode opc, TCGArg a1, TCGArg a2,
return op;
}
TCGOp * NI tcg_gen_op5(TCGOpcode opc, TCGArg a1, TCGArg a2,
TCGOp * NI tcg_gen_op5(TCGOpcode opc, TCGType type, TCGArg a1, TCGArg a2,
TCGArg a3, TCGArg a4, TCGArg a5)
{
TCGOp *op = tcg_emit_op(opc, 5);
TCGOP_TYPE(op) = type;
op->args[0] = a1;
op->args[1] = a2;
op->args[2] = a3;
@ -84,10 +90,11 @@ TCGOp * NI tcg_gen_op5(TCGOpcode opc, TCGArg a1, TCGArg a2,
return op;
}
TCGOp * NI tcg_gen_op6(TCGOpcode opc, TCGArg a1, TCGArg a2, TCGArg a3,
TCGArg a4, TCGArg a5, TCGArg a6)
TCGOp * NI tcg_gen_op6(TCGOpcode opc, TCGType type, TCGArg a1, TCGArg a2,
TCGArg a3, TCGArg a4, TCGArg a5, TCGArg a6)
{
TCGOp *op = tcg_emit_op(opc, 6);
TCGOP_TYPE(op) = type;
op->args[0] = a1;
op->args[1] = a2;
op->args[2] = a3;
@ -107,132 +114,138 @@ TCGOp * NI tcg_gen_op6(TCGOpcode opc, TCGArg a1, TCGArg a2, TCGArg a3,
# define DNI
#endif
static void DNI tcg_gen_op1_i32(TCGOpcode opc, TCGv_i32 a1)
static void DNI tcg_gen_op1_i32(TCGOpcode opc, TCGType type, TCGv_i32 a1)
{
tcg_gen_op1(opc, tcgv_i32_arg(a1));
tcg_gen_op1(opc, type, tcgv_i32_arg(a1));
}
static void DNI tcg_gen_op1_i64(TCGOpcode opc, TCGv_i64 a1)
static void DNI tcg_gen_op1_i64(TCGOpcode opc, TCGType type, TCGv_i64 a1)
{
tcg_gen_op1(opc, tcgv_i64_arg(a1));
tcg_gen_op1(opc, type, tcgv_i64_arg(a1));
}
static TCGOp * DNI tcg_gen_op1i(TCGOpcode opc, TCGArg a1)
static TCGOp * DNI tcg_gen_op1i(TCGOpcode opc, TCGType type, TCGArg a1)
{
return tcg_gen_op1(opc, a1);
return tcg_gen_op1(opc, type, a1);
}
static void DNI tcg_gen_op2_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2)
{
tcg_gen_op2(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2));
tcg_gen_op2(opc, TCG_TYPE_I32, tcgv_i32_arg(a1), tcgv_i32_arg(a2));
}
static void DNI tcg_gen_op2_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2)
{
tcg_gen_op2(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2));
tcg_gen_op2(opc, TCG_TYPE_I64, tcgv_i64_arg(a1), tcgv_i64_arg(a2));
}
static void DNI tcg_gen_op3_i32(TCGOpcode opc, TCGv_i32 a1,
TCGv_i32 a2, TCGv_i32 a3)
{
tcg_gen_op3(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2), tcgv_i32_arg(a3));
tcg_gen_op3(opc, TCG_TYPE_I32, tcgv_i32_arg(a1),
tcgv_i32_arg(a2), tcgv_i32_arg(a3));
}
static void DNI tcg_gen_op3_i64(TCGOpcode opc, TCGv_i64 a1,
TCGv_i64 a2, TCGv_i64 a3)
{
tcg_gen_op3(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2), tcgv_i64_arg(a3));
tcg_gen_op3(opc, TCG_TYPE_I64, tcgv_i64_arg(a1),
tcgv_i64_arg(a2), tcgv_i64_arg(a3));
}
static void DNI tcg_gen_op3i_i32(TCGOpcode opc, TCGv_i32 a1,
TCGv_i32 a2, TCGArg a3)
{
tcg_gen_op3(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2), a3);
tcg_gen_op3(opc, TCG_TYPE_I32, tcgv_i32_arg(a1), tcgv_i32_arg(a2), a3);
}
static void DNI tcg_gen_op3i_i64(TCGOpcode opc, TCGv_i64 a1,
TCGv_i64 a2, TCGArg a3)
{
tcg_gen_op3(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2), a3);
tcg_gen_op3(opc, TCG_TYPE_I64, tcgv_i64_arg(a1), tcgv_i64_arg(a2), a3);
}
static void DNI tcg_gen_ldst_op_i32(TCGOpcode opc, TCGv_i32 val,
TCGv_ptr base, TCGArg offset)
{
tcg_gen_op3(opc, tcgv_i32_arg(val), tcgv_ptr_arg(base), offset);
tcg_gen_op3(opc, TCG_TYPE_I32, tcgv_i32_arg(val),
tcgv_ptr_arg(base), offset);
}
static void DNI tcg_gen_ldst_op_i64(TCGOpcode opc, TCGv_i64 val,
TCGv_ptr base, TCGArg offset)
{
tcg_gen_op3(opc, tcgv_i64_arg(val), tcgv_ptr_arg(base), offset);
tcg_gen_op3(opc, TCG_TYPE_I64, tcgv_i64_arg(val),
tcgv_ptr_arg(base), offset);
}
static void DNI tcg_gen_op4_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
TCGv_i32 a3, TCGv_i32 a4)
{
tcg_gen_op4(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
tcg_gen_op4(opc, TCG_TYPE_I32, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
tcgv_i32_arg(a3), tcgv_i32_arg(a4));
}
static void DNI tcg_gen_op4_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2,
TCGv_i64 a3, TCGv_i64 a4)
{
tcg_gen_op4(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2),
tcg_gen_op4(opc, TCG_TYPE_I64, tcgv_i64_arg(a1), tcgv_i64_arg(a2),
tcgv_i64_arg(a3), tcgv_i64_arg(a4));
}
static void DNI tcg_gen_op4i_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
TCGv_i32 a3, TCGArg a4)
{
tcg_gen_op4(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
tcg_gen_op4(opc, TCG_TYPE_I32, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
tcgv_i32_arg(a3), a4);
}
static void DNI tcg_gen_op4i_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2,
TCGv_i64 a3, TCGArg a4)
{
tcg_gen_op4(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2),
tcg_gen_op4(opc, TCG_TYPE_I64, tcgv_i64_arg(a1), tcgv_i64_arg(a2),
tcgv_i64_arg(a3), a4);
}
static TCGOp * DNI tcg_gen_op4ii_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
TCGArg a3, TCGArg a4)
{
return tcg_gen_op4(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2), a3, a4);
return tcg_gen_op4(opc, TCG_TYPE_I32,
tcgv_i32_arg(a1), tcgv_i32_arg(a2), a3, a4);
}
static TCGOp * DNI tcg_gen_op4ii_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2,
TCGArg a3, TCGArg a4)
{
return tcg_gen_op4(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2), a3, a4);
return tcg_gen_op4(opc, TCG_TYPE_I64,
tcgv_i64_arg(a1), tcgv_i64_arg(a2), a3, a4);
}
static void DNI tcg_gen_op5_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
TCGv_i32 a3, TCGv_i32 a4, TCGv_i32 a5)
{
tcg_gen_op5(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
tcg_gen_op5(opc, TCG_TYPE_I32, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
tcgv_i32_arg(a3), tcgv_i32_arg(a4), tcgv_i32_arg(a5));
}
static void DNI tcg_gen_op5_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2,
TCGv_i64 a3, TCGv_i64 a4, TCGv_i64 a5)
{
tcg_gen_op5(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2),
tcg_gen_op5(opc, TCG_TYPE_I64, tcgv_i64_arg(a1), tcgv_i64_arg(a2),
tcgv_i64_arg(a3), tcgv_i64_arg(a4), tcgv_i64_arg(a5));
}
static void DNI tcg_gen_op5ii_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
TCGv_i32 a3, TCGArg a4, TCGArg a5)
{
tcg_gen_op5(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
tcg_gen_op5(opc, TCG_TYPE_I32, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
tcgv_i32_arg(a3), a4, a5);
}
static void DNI tcg_gen_op5ii_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2,
TCGv_i64 a3, TCGArg a4, TCGArg a5)
{
tcg_gen_op5(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2),
tcg_gen_op5(opc, TCG_TYPE_I64, tcgv_i64_arg(a1), tcgv_i64_arg(a2),
tcgv_i64_arg(a3), a4, a5);
}
@ -240,7 +253,7 @@ static void DNI tcg_gen_op6_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
TCGv_i32 a3, TCGv_i32 a4,
TCGv_i32 a5, TCGv_i32 a6)
{
tcg_gen_op6(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
tcg_gen_op6(opc, TCG_TYPE_I32, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
tcgv_i32_arg(a3), tcgv_i32_arg(a4), tcgv_i32_arg(a5),
tcgv_i32_arg(a6));
}
@ -249,7 +262,7 @@ static void DNI tcg_gen_op6_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2,
TCGv_i64 a3, TCGv_i64 a4,
TCGv_i64 a5, TCGv_i64 a6)
{
tcg_gen_op6(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2),
tcg_gen_op6(opc, TCG_TYPE_I64, tcgv_i64_arg(a1), tcgv_i64_arg(a2),
tcgv_i64_arg(a3), tcgv_i64_arg(a4), tcgv_i64_arg(a5),
tcgv_i64_arg(a6));
}
@ -258,7 +271,7 @@ static void DNI tcg_gen_op6i_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
TCGv_i32 a3, TCGv_i32 a4,
TCGv_i32 a5, TCGArg a6)
{
tcg_gen_op6(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
tcg_gen_op6(opc, TCG_TYPE_I32, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
tcgv_i32_arg(a3), tcgv_i32_arg(a4), tcgv_i32_arg(a5), a6);
}
@ -266,7 +279,7 @@ static void DNI tcg_gen_op6i_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2,
TCGv_i64 a3, TCGv_i64 a4,
TCGv_i64 a5, TCGArg a6)
{
tcg_gen_op6(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2),
tcg_gen_op6(opc, TCG_TYPE_I64, tcgv_i64_arg(a1), tcgv_i64_arg(a2),
tcgv_i64_arg(a3), tcgv_i64_arg(a4), tcgv_i64_arg(a5), a6);
}
@ -274,7 +287,7 @@ static TCGOp * DNI tcg_gen_op6ii_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
TCGv_i32 a3, TCGv_i32 a4,
TCGArg a5, TCGArg a6)
{
return tcg_gen_op6(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
return tcg_gen_op6(opc, TCG_TYPE_I32, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
tcgv_i32_arg(a3), tcgv_i32_arg(a4), a5, a6);
}
@ -283,7 +296,7 @@ static TCGOp * DNI tcg_gen_op6ii_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
void gen_set_label(TCGLabel *l)
{
l->present = 1;
tcg_gen_op1(INDEX_op_set_label, label_arg(l));
tcg_gen_op1(INDEX_op_set_label, 0, label_arg(l));
}
static void add_as_label_use(TCGLabel *l, TCGOp *op)
@ -296,7 +309,7 @@ static void add_as_label_use(TCGLabel *l, TCGOp *op)
void tcg_gen_br(TCGLabel *l)
{
add_as_label_use(l, tcg_gen_op1(INDEX_op_br, label_arg(l)));
add_as_label_use(l, tcg_gen_op1(INDEX_op_br, 0, label_arg(l)));
}
void tcg_gen_mb(TCGBar mb_type)
@ -314,25 +327,25 @@ void tcg_gen_mb(TCGBar mb_type)
#endif
if (parallel) {
tcg_gen_op1(INDEX_op_mb, mb_type);
tcg_gen_op1(INDEX_op_mb, 0, mb_type);
}
}
void tcg_gen_plugin_cb(unsigned from)
{
tcg_gen_op1(INDEX_op_plugin_cb, from);
tcg_gen_op1(INDEX_op_plugin_cb, 0, from);
}
void tcg_gen_plugin_mem_cb(TCGv_i64 addr, unsigned meminfo)
{
tcg_gen_op2(INDEX_op_plugin_mem_cb, tcgv_i64_arg(addr), meminfo);
tcg_gen_op2(INDEX_op_plugin_mem_cb, 0, tcgv_i64_arg(addr), meminfo);
}
/* 32 bit ops */
void tcg_gen_discard_i32(TCGv_i32 arg)
{
tcg_gen_op1_i32(INDEX_op_discard, arg);
tcg_gen_op1_i32(INDEX_op_discard, TCG_TYPE_I32, arg);
}
void tcg_gen_mov_i32(TCGv_i32 ret, TCGv_i32 arg)
@ -893,7 +906,7 @@ void tcg_gen_deposit_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2,
tcg_gen_mov_i32(ret, arg2);
return;
}
if (TCG_TARGET_HAS_deposit_i32 && TCG_TARGET_deposit_i32_valid(ofs, len)) {
if (TCG_TARGET_deposit_valid(TCG_TYPE_I32, ofs, len)) {
tcg_gen_op5ii_i32(INDEX_op_deposit_i32, ret, arg1, arg2, ofs, len);
return;
}
@ -938,8 +951,7 @@ void tcg_gen_deposit_z_i32(TCGv_i32 ret, TCGv_i32 arg,
tcg_gen_shli_i32(ret, arg, ofs);
} else if (ofs == 0) {
tcg_gen_andi_i32(ret, arg, (1u << len) - 1);
} else if (TCG_TARGET_HAS_deposit_i32
&& TCG_TARGET_deposit_i32_valid(ofs, len)) {
} else if (TCG_TARGET_deposit_valid(TCG_TYPE_I32, ofs, len)) {
TCGv_i32 zero = tcg_constant_i32(0);
tcg_gen_op5ii_i32(INDEX_op_deposit_i32, ret, zero, arg, ofs, len);
} else {
@ -1001,8 +1013,7 @@ void tcg_gen_extract_i32(TCGv_i32 ret, TCGv_i32 arg,
return;
}
if (TCG_TARGET_HAS_extract_i32
&& TCG_TARGET_extract_i32_valid(ofs, len)) {
if (TCG_TARGET_extract_valid(TCG_TYPE_I32, ofs, len)) {
tcg_gen_op4ii_i32(INDEX_op_extract_i32, ret, arg, ofs, len);
return;
}
@ -1064,8 +1075,7 @@ void tcg_gen_sextract_i32(TCGv_i32 ret, TCGv_i32 arg,
}
}
if (TCG_TARGET_HAS_sextract_i32
&& TCG_TARGET_extract_i32_valid(ofs, len)) {
if (TCG_TARGET_sextract_valid(TCG_TYPE_I32, ofs, len)) {
tcg_gen_op4ii_i32(INDEX_op_sextract_i32, ret, arg, ofs, len);
return;
}
@ -1467,7 +1477,7 @@ void tcg_gen_st_i32(TCGv_i32 arg1, TCGv_ptr arg2, tcg_target_long offset)
void tcg_gen_discard_i64(TCGv_i64 arg)
{
if (TCG_TARGET_REG_BITS == 64) {
tcg_gen_op1_i64(INDEX_op_discard, arg);
tcg_gen_op1_i64(INDEX_op_discard, TCG_TYPE_I64, arg);
} else {
tcg_gen_discard_i32(TCGV_LOW(arg));
tcg_gen_discard_i32(TCGV_HIGH(arg));
@ -2631,12 +2641,13 @@ void tcg_gen_deposit_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2,
tcg_gen_mov_i64(ret, arg2);
return;
}
if (TCG_TARGET_HAS_deposit_i64 && TCG_TARGET_deposit_i64_valid(ofs, len)) {
if (TCG_TARGET_REG_BITS == 64) {
if (TCG_TARGET_deposit_valid(TCG_TYPE_I64, ofs, len)) {
tcg_gen_op5ii_i64(INDEX_op_deposit_i64, ret, arg1, arg2, ofs, len);
return;
}
if (TCG_TARGET_REG_BITS == 32) {
} else {
if (ofs >= 32) {
tcg_gen_deposit_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1),
TCGV_LOW(arg2), ofs - 32, len);
@ -2691,8 +2702,8 @@ void tcg_gen_deposit_z_i64(TCGv_i64 ret, TCGv_i64 arg,
tcg_gen_shli_i64(ret, arg, ofs);
} else if (ofs == 0) {
tcg_gen_andi_i64(ret, arg, (1ull << len) - 1);
} else if (TCG_TARGET_HAS_deposit_i64
&& TCG_TARGET_deposit_i64_valid(ofs, len)) {
} else if (TCG_TARGET_REG_BITS == 64 &&
TCG_TARGET_deposit_valid(TCG_TYPE_I64, ofs, len)) {
TCGv_i64 zero = tcg_constant_i64(0);
tcg_gen_op5ii_i64(INDEX_op_deposit_i64, ret, zero, arg, ofs, len);
} else {
@ -2798,8 +2809,7 @@ void tcg_gen_extract_i64(TCGv_i64 ret, TCGv_i64 arg,
goto do_shift_and;
}
if (TCG_TARGET_HAS_extract_i64
&& TCG_TARGET_extract_i64_valid(ofs, len)) {
if (TCG_TARGET_extract_valid(TCG_TYPE_I64, ofs, len)) {
tcg_gen_op4ii_i64(INDEX_op_extract_i64, ret, arg, ofs, len);
return;
}
@ -2904,8 +2914,7 @@ void tcg_gen_sextract_i64(TCGv_i64 ret, TCGv_i64 arg,
return;
}
if (TCG_TARGET_HAS_sextract_i64
&& TCG_TARGET_extract_i64_valid(ofs, len)) {
if (TCG_TARGET_sextract_valid(TCG_TYPE_I64, ofs, len)) {
tcg_gen_op4ii_i64(INDEX_op_sextract_i64, ret, arg, ofs, len);
return;
}
@ -3156,7 +3165,7 @@ void tcg_gen_extrl_i64_i32(TCGv_i32 ret, TCGv_i64 arg)
if (TCG_TARGET_REG_BITS == 32) {
tcg_gen_mov_i32(ret, TCGV_LOW(arg));
} else if (TCG_TARGET_HAS_extr_i64_i32) {
tcg_gen_op2(INDEX_op_extrl_i64_i32,
tcg_gen_op2(INDEX_op_extrl_i64_i32, TCG_TYPE_I32,
tcgv_i32_arg(ret), tcgv_i64_arg(arg));
} else {
tcg_gen_mov_i32(ret, (TCGv_i32)arg);
@ -3168,7 +3177,7 @@ void tcg_gen_extrh_i64_i32(TCGv_i32 ret, TCGv_i64 arg)
if (TCG_TARGET_REG_BITS == 32) {
tcg_gen_mov_i32(ret, TCGV_HIGH(arg));
} else if (TCG_TARGET_HAS_extr_i64_i32) {
tcg_gen_op2(INDEX_op_extrh_i64_i32,
tcg_gen_op2(INDEX_op_extrh_i64_i32, TCG_TYPE_I32,
tcgv_i32_arg(ret), tcgv_i64_arg(arg));
} else {
TCGv_i64 t = tcg_temp_ebb_new_i64();
@ -3184,7 +3193,7 @@ void tcg_gen_extu_i32_i64(TCGv_i64 ret, TCGv_i32 arg)
tcg_gen_mov_i32(TCGV_LOW(ret), arg);
tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
} else {
tcg_gen_op2(INDEX_op_extu_i32_i64,
tcg_gen_op2(INDEX_op_extu_i32_i64, TCG_TYPE_I64,
tcgv_i64_arg(ret), tcgv_i32_arg(arg));
}
}
@ -3195,7 +3204,7 @@ void tcg_gen_ext_i32_i64(TCGv_i64 ret, TCGv_i32 arg)
tcg_gen_mov_i32(TCGV_LOW(ret), arg);
tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
} else {
tcg_gen_op2(INDEX_op_ext_i32_i64,
tcg_gen_op2(INDEX_op_ext_i32_i64, TCG_TYPE_I64,
tcgv_i64_arg(ret), tcgv_i32_arg(arg));
}
}
@ -3217,7 +3226,7 @@ void tcg_gen_concat_i32_i64(TCGv_i64 dest, TCGv_i32 low, TCGv_i32 high)
tcg_gen_extu_i32_i64(dest, low);
/* If deposit is available, use it. Otherwise use the extra
knowledge that we have of the zero-extensions above. */
if (TCG_TARGET_HAS_deposit_i64 && TCG_TARGET_deposit_i64_valid(32, 32)) {
if (TCG_TARGET_deposit_valid(TCG_TYPE_I64, 32, 32)) {
tcg_gen_deposit_i64(dest, dest, tmp, 32, 32);
} else {
tcg_gen_shli_i64(tmp, tmp, 32);
@ -3320,7 +3329,7 @@ void tcg_gen_exit_tb(const TranslationBlock *tb, unsigned idx)
tcg_debug_assert(idx == TB_EXIT_REQUESTED);
}
tcg_gen_op1i(INDEX_op_exit_tb, val);
tcg_gen_op1i(INDEX_op_exit_tb, 0, val);
}
void tcg_gen_goto_tb(unsigned idx)
@ -3335,7 +3344,7 @@ void tcg_gen_goto_tb(unsigned idx)
tcg_ctx->goto_tb_issue_mask |= 1 << idx;
#endif
plugin_gen_disable_mem_helpers();
tcg_gen_op1i(INDEX_op_goto_tb, idx);
tcg_gen_op1i(INDEX_op_goto_tb, 0, idx);
}
void tcg_gen_lookup_and_goto_ptr(void)
@ -3350,6 +3359,6 @@ void tcg_gen_lookup_and_goto_ptr(void)
plugin_gen_disable_mem_helpers();
ptr = tcg_temp_ebb_new_ptr();
gen_helper_lookup_tb_ptr(ptr, tcg_env);
tcg_gen_op1i(INDEX_op_goto_ptr, tcgv_ptr_arg(ptr));
tcg_gen_op1i(INDEX_op_goto_ptr, TCG_TYPE_PTR, tcgv_ptr_arg(ptr));
tcg_temp_free_ptr(ptr);
}

View file

@ -1,162 +0,0 @@
/*
* TCG Backend Data: constant pool.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
typedef struct TCGLabelPoolData {
struct TCGLabelPoolData *next;
tcg_insn_unit *label;
intptr_t addend;
int rtype;
unsigned nlong;
tcg_target_ulong data[];
} TCGLabelPoolData;
static TCGLabelPoolData *new_pool_alloc(TCGContext *s, int nlong, int rtype,
tcg_insn_unit *label, intptr_t addend)
{
TCGLabelPoolData *n = tcg_malloc(sizeof(TCGLabelPoolData)
+ sizeof(tcg_target_ulong) * nlong);
n->label = label;
n->addend = addend;
n->rtype = rtype;
n->nlong = nlong;
return n;
}
static void new_pool_insert(TCGContext *s, TCGLabelPoolData *n)
{
TCGLabelPoolData *i, **pp;
int nlong = n->nlong;
/* Insertion sort on the pool. */
for (pp = &s->pool_labels; (i = *pp) != NULL; pp = &i->next) {
if (nlong > i->nlong) {
break;
}
if (nlong < i->nlong) {
continue;
}
if (memcmp(n->data, i->data, sizeof(tcg_target_ulong) * nlong) >= 0) {
break;
}
}
n->next = *pp;
*pp = n;
}
/* The "usual" for generic integer code. */
static inline void new_pool_label(TCGContext *s, tcg_target_ulong d, int rtype,
tcg_insn_unit *label, intptr_t addend)
{
TCGLabelPoolData *n = new_pool_alloc(s, 1, rtype, label, addend);
n->data[0] = d;
new_pool_insert(s, n);
}
/* For v64 or v128, depending on the host. */
static inline void new_pool_l2(TCGContext *s, int rtype, tcg_insn_unit *label,
intptr_t addend, tcg_target_ulong d0,
tcg_target_ulong d1)
{
TCGLabelPoolData *n = new_pool_alloc(s, 2, rtype, label, addend);
n->data[0] = d0;
n->data[1] = d1;
new_pool_insert(s, n);
}
/* For v128 or v256, depending on the host. */
static inline void new_pool_l4(TCGContext *s, int rtype, tcg_insn_unit *label,
intptr_t addend, tcg_target_ulong d0,
tcg_target_ulong d1, tcg_target_ulong d2,
tcg_target_ulong d3)
{
TCGLabelPoolData *n = new_pool_alloc(s, 4, rtype, label, addend);
n->data[0] = d0;
n->data[1] = d1;
n->data[2] = d2;
n->data[3] = d3;
new_pool_insert(s, n);
}
/* For v256, for 32-bit host. */
static inline void new_pool_l8(TCGContext *s, int rtype, tcg_insn_unit *label,
intptr_t addend, tcg_target_ulong d0,
tcg_target_ulong d1, tcg_target_ulong d2,
tcg_target_ulong d3, tcg_target_ulong d4,
tcg_target_ulong d5, tcg_target_ulong d6,
tcg_target_ulong d7)
{
TCGLabelPoolData *n = new_pool_alloc(s, 8, rtype, label, addend);
n->data[0] = d0;
n->data[1] = d1;
n->data[2] = d2;
n->data[3] = d3;
n->data[4] = d4;
n->data[5] = d5;
n->data[6] = d6;
n->data[7] = d7;
new_pool_insert(s, n);
}
/* To be provided by cpu/tcg-target.c.inc. */
static void tcg_out_nop_fill(tcg_insn_unit *p, int count);
static int tcg_out_pool_finalize(TCGContext *s)
{
TCGLabelPoolData *p = s->pool_labels;
TCGLabelPoolData *l = NULL;
void *a;
if (p == NULL) {
return 0;
}
/* ??? Round up to qemu_icache_linesize, but then do not round
again when allocating the next TranslationBlock structure. */
a = (void *)ROUND_UP((uintptr_t)s->code_ptr,
sizeof(tcg_target_ulong) * p->nlong);
tcg_out_nop_fill(s->code_ptr, (tcg_insn_unit *)a - s->code_ptr);
s->data_gen_ptr = a;
for (; p != NULL; p = p->next) {
size_t size = sizeof(tcg_target_ulong) * p->nlong;
uintptr_t value;
if (!l || l->nlong != p->nlong || memcmp(l->data, p->data, size)) {
if (unlikely(a > s->code_gen_highwater)) {
return -1;
}
memcpy(a, p->data, size);
a += size;
l = p;
}
value = (uintptr_t)tcg_splitwx_to_rx(a) - size;
if (!patch_reloc(p->label, p->rtype, value, p->addend)) {
return -2;
}
}
s->code_ptr = a;
return 0;
}

643
tcg/tcg.c

File diff suppressed because it is too large Load diff

View file

@ -22,6 +22,7 @@
#include "tcg/helper-info.h"
#include "tcg/tcg-ldst.h"
#include "disas/dis-asm.h"
#include "tcg-has.h"
#include <ffi.h>
@ -650,24 +651,18 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
regs[r0] = ror32(regs[r1], regs[r2] & 31);
break;
#endif
#if TCG_TARGET_HAS_deposit_i32
case INDEX_op_deposit_i32:
tci_args_rrrbb(insn, &r0, &r1, &r2, &pos, &len);
regs[r0] = deposit32(regs[r1], pos, len, regs[r2]);
break;
#endif
#if TCG_TARGET_HAS_extract_i32
case INDEX_op_extract_i32:
tci_args_rrbb(insn, &r0, &r1, &pos, &len);
regs[r0] = extract32(regs[r1], pos, len);
break;
#endif
#if TCG_TARGET_HAS_sextract_i32
case INDEX_op_sextract_i32:
tci_args_rrbb(insn, &r0, &r1, &pos, &len);
regs[r0] = sextract32(regs[r1], pos, len);
break;
#endif
case INDEX_op_brcond_i32:
tci_args_rl(insn, tb_ptr, &r0, &ptr);
if ((uint32_t)regs[r0]) {
@ -861,24 +856,18 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
regs[r0] = ror64(regs[r1], regs[r2] & 63);
break;
#endif
#if TCG_TARGET_HAS_deposit_i64
case INDEX_op_deposit_i64:
tci_args_rrrbb(insn, &r0, &r1, &r2, &pos, &len);
regs[r0] = deposit64(regs[r1], pos, len, regs[r2]);
break;
#endif
#if TCG_TARGET_HAS_extract_i64
case INDEX_op_extract_i64:
tci_args_rrbb(insn, &r0, &r1, &pos, &len);
regs[r0] = extract64(regs[r1], pos, len);
break;
#endif
#if TCG_TARGET_HAS_sextract_i64
case INDEX_op_sextract_i64:
tci_args_rrbb(insn, &r0, &r1, &pos, &len);
regs[r0] = sextract64(regs[r1], pos, len);
break;
#endif
case INDEX_op_brcond_i64:
tci_args_rl(insn, tb_ptr, &r0, &ptr);
if (regs[r0]) {

81
tcg/tci/tcg-target-has.h Normal file
View file

@ -0,0 +1,81 @@
/* SPDX-License-Identifier: MIT */
/*
* Define target-specific opcode support
* Copyright (c) 2009, 2011 Stefan Weil
*/
#ifndef TCG_TARGET_HAS_H
#define TCG_TARGET_HAS_H
#define TCG_TARGET_HAS_bswap16_i32 1
#define TCG_TARGET_HAS_bswap32_i32 1
#define TCG_TARGET_HAS_div_i32 1
#define TCG_TARGET_HAS_rem_i32 1
#define TCG_TARGET_HAS_ext8s_i32 1
#define TCG_TARGET_HAS_ext16s_i32 1
#define TCG_TARGET_HAS_ext8u_i32 1
#define TCG_TARGET_HAS_ext16u_i32 1
#define TCG_TARGET_HAS_andc_i32 1
#define TCG_TARGET_HAS_extract2_i32 0
#define TCG_TARGET_HAS_eqv_i32 1
#define TCG_TARGET_HAS_nand_i32 1
#define TCG_TARGET_HAS_nor_i32 1
#define TCG_TARGET_HAS_clz_i32 1
#define TCG_TARGET_HAS_ctz_i32 1
#define TCG_TARGET_HAS_ctpop_i32 1
#define TCG_TARGET_HAS_not_i32 1
#define TCG_TARGET_HAS_orc_i32 1
#define TCG_TARGET_HAS_rot_i32 1
#define TCG_TARGET_HAS_negsetcond_i32 0
#define TCG_TARGET_HAS_muls2_i32 1
#define TCG_TARGET_HAS_muluh_i32 0
#define TCG_TARGET_HAS_mulsh_i32 0
#define TCG_TARGET_HAS_qemu_st8_i32 0
#if TCG_TARGET_REG_BITS == 64
#define TCG_TARGET_HAS_extr_i64_i32 0
#define TCG_TARGET_HAS_bswap16_i64 1
#define TCG_TARGET_HAS_bswap32_i64 1
#define TCG_TARGET_HAS_bswap64_i64 1
#define TCG_TARGET_HAS_extract2_i64 0
#define TCG_TARGET_HAS_div_i64 1
#define TCG_TARGET_HAS_rem_i64 1
#define TCG_TARGET_HAS_ext8s_i64 1
#define TCG_TARGET_HAS_ext16s_i64 1
#define TCG_TARGET_HAS_ext32s_i64 1
#define TCG_TARGET_HAS_ext8u_i64 1
#define TCG_TARGET_HAS_ext16u_i64 1
#define TCG_TARGET_HAS_ext32u_i64 1
#define TCG_TARGET_HAS_andc_i64 1
#define TCG_TARGET_HAS_eqv_i64 1
#define TCG_TARGET_HAS_nand_i64 1
#define TCG_TARGET_HAS_nor_i64 1
#define TCG_TARGET_HAS_clz_i64 1
#define TCG_TARGET_HAS_ctz_i64 1
#define TCG_TARGET_HAS_ctpop_i64 1
#define TCG_TARGET_HAS_not_i64 1
#define TCG_TARGET_HAS_orc_i64 1
#define TCG_TARGET_HAS_rot_i64 1
#define TCG_TARGET_HAS_negsetcond_i64 0
#define TCG_TARGET_HAS_muls2_i64 1
#define TCG_TARGET_HAS_add2_i32 1
#define TCG_TARGET_HAS_sub2_i32 1
#define TCG_TARGET_HAS_mulu2_i32 1
#define TCG_TARGET_HAS_add2_i64 1
#define TCG_TARGET_HAS_sub2_i64 1
#define TCG_TARGET_HAS_mulu2_i64 1
#define TCG_TARGET_HAS_muluh_i64 0
#define TCG_TARGET_HAS_mulsh_i64 0
#else
#define TCG_TARGET_HAS_mulu2_i32 1
#endif /* TCG_TARGET_REG_BITS == 64 */
#define TCG_TARGET_HAS_qemu_ldst_i128 0
#define TCG_TARGET_HAS_tst 1
#define TCG_TARGET_extract_valid(type, ofs, len) 1
#define TCG_TARGET_sextract_valid(type, ofs, len) 1
#define TCG_TARGET_deposit_valid(type, ofs, len) 1
#endif

17
tcg/tci/tcg-target-mo.h Normal file
View file

@ -0,0 +1,17 @@
/* SPDX-License-Identifier: MIT */
/*
* Define target-specific memory model
* Copyright (c) 2009, 2011 Stefan Weil
*/
#ifndef TCG_TARGET_MO_H
#define TCG_TARGET_MO_H
/*
* We could notice __i386__ or __s390x__ and reduce the barriers depending
* on the host. But if you want performance, you use the normal backend.
* We prefer consistency across hosts on this.
*/
#define TCG_TARGET_DEFAULT_MO 0
#endif

View file

@ -0,0 +1,4 @@
/* SPDX-License-Identifier: MIT */
/* These opcodes for use between the tci generator and interpreter. */
DEF(tci_movi, 1, 0, 1, TCG_OPF_NOT_PRESENT)
DEF(tci_movl, 1, 0, 1, TCG_OPF_NOT_PRESENT)

View file

@ -22,9 +22,22 @@
* THE SOFTWARE.
*/
#include "../tcg-pool.c.inc"
/* Used for function call generation. */
#define TCG_TARGET_CALL_STACK_OFFSET 0
#define TCG_TARGET_STACK_ALIGN 8
#if TCG_TARGET_REG_BITS == 32
# define TCG_TARGET_CALL_ARG_I32 TCG_CALL_ARG_EVEN
# define TCG_TARGET_CALL_ARG_I64 TCG_CALL_ARG_EVEN
# define TCG_TARGET_CALL_ARG_I128 TCG_CALL_ARG_EVEN
#else
# define TCG_TARGET_CALL_ARG_I32 TCG_CALL_ARG_NORMAL
# define TCG_TARGET_CALL_ARG_I64 TCG_CALL_ARG_NORMAL
# define TCG_TARGET_CALL_ARG_I128 TCG_CALL_ARG_NORMAL
#endif
#define TCG_TARGET_CALL_RET_I128 TCG_CALL_RET_NORMAL
static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
static TCGConstraintSetIndex
tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
{
switch (op) {
case INDEX_op_goto_ptr:
@ -174,7 +187,7 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
return TCG_TARGET_REG_BITS == 64 ? C_O0_I2(r, r) : C_O0_I4(r, r, r, r);
default:
g_assert_not_reached();
return C_NotImplemented;
}
}
@ -695,7 +708,7 @@ void tb_target_set_jmp_target(const TranslationBlock *tb, int n,
/* Always indirect, nothing to do */
}
static void tcg_out_op(TCGContext *s, TCGOpcode opc,
static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
const TCGArg args[TCG_MAX_OP_ARGS],
const int const_args[TCG_MAX_OP_ARGS])
{
@ -761,29 +774,13 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
tcg_out_op_rrr(s, opc, args[0], args[1], args[2]);
break;
CASE_32_64(deposit) /* Optional (TCG_TARGET_HAS_deposit_*). */
{
TCGArg pos = args[3], len = args[4];
TCGArg max = opc == INDEX_op_deposit_i32 ? 32 : 64;
tcg_debug_assert(pos < max);
tcg_debug_assert(pos + len <= max);
tcg_out_op_rrrbb(s, opc, args[0], args[1], args[2], pos, len);
}
CASE_32_64(deposit)
tcg_out_op_rrrbb(s, opc, args[0], args[1], args[2], args[3], args[4]);
break;
CASE_32_64(extract) /* Optional (TCG_TARGET_HAS_extract_*). */
CASE_32_64(sextract) /* Optional (TCG_TARGET_HAS_sextract_*). */
{
TCGArg pos = args[2], len = args[3];
TCGArg max = tcg_op_defs[opc].flags & TCG_OPF_64BIT ? 64 : 32;
tcg_debug_assert(pos < max);
tcg_debug_assert(pos + len <= max);
tcg_out_op_rrbb(s, opc, args[0], args[1], pos, len);
}
tcg_out_op_rrbb(s, opc, args[0], args[1], args[2], args[3]);
break;
CASE_32_64(brcond)
@ -965,3 +962,13 @@ bool tcg_target_has_memory_bswap(MemOp memop)
{
return true;
}
static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
{
g_assert_not_reached();
}
static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
{
g_assert_not_reached();
}

View file

@ -44,81 +44,6 @@
#define TCG_TARGET_INSN_UNIT_SIZE 4
#define MAX_CODE_GEN_BUFFER_SIZE ((size_t)-1)
/* Optional instructions. */
#define TCG_TARGET_HAS_bswap16_i32 1
#define TCG_TARGET_HAS_bswap32_i32 1
#define TCG_TARGET_HAS_div_i32 1
#define TCG_TARGET_HAS_rem_i32 1
#define TCG_TARGET_HAS_ext8s_i32 1
#define TCG_TARGET_HAS_ext16s_i32 1
#define TCG_TARGET_HAS_ext8u_i32 1
#define TCG_TARGET_HAS_ext16u_i32 1
#define TCG_TARGET_HAS_andc_i32 1
#define TCG_TARGET_HAS_deposit_i32 1
#define TCG_TARGET_HAS_extract_i32 1
#define TCG_TARGET_HAS_sextract_i32 1
#define TCG_TARGET_HAS_extract2_i32 0
#define TCG_TARGET_HAS_eqv_i32 1
#define TCG_TARGET_HAS_nand_i32 1
#define TCG_TARGET_HAS_nor_i32 1
#define TCG_TARGET_HAS_clz_i32 1
#define TCG_TARGET_HAS_ctz_i32 1
#define TCG_TARGET_HAS_ctpop_i32 1
#define TCG_TARGET_HAS_not_i32 1
#define TCG_TARGET_HAS_orc_i32 1
#define TCG_TARGET_HAS_rot_i32 1
#define TCG_TARGET_HAS_negsetcond_i32 0
#define TCG_TARGET_HAS_muls2_i32 1
#define TCG_TARGET_HAS_muluh_i32 0
#define TCG_TARGET_HAS_mulsh_i32 0
#define TCG_TARGET_HAS_qemu_st8_i32 0
#if TCG_TARGET_REG_BITS == 64
#define TCG_TARGET_HAS_extr_i64_i32 0
#define TCG_TARGET_HAS_bswap16_i64 1
#define TCG_TARGET_HAS_bswap32_i64 1
#define TCG_TARGET_HAS_bswap64_i64 1
#define TCG_TARGET_HAS_deposit_i64 1
#define TCG_TARGET_HAS_extract_i64 1
#define TCG_TARGET_HAS_sextract_i64 1
#define TCG_TARGET_HAS_extract2_i64 0
#define TCG_TARGET_HAS_div_i64 1
#define TCG_TARGET_HAS_rem_i64 1
#define TCG_TARGET_HAS_ext8s_i64 1
#define TCG_TARGET_HAS_ext16s_i64 1
#define TCG_TARGET_HAS_ext32s_i64 1
#define TCG_TARGET_HAS_ext8u_i64 1
#define TCG_TARGET_HAS_ext16u_i64 1
#define TCG_TARGET_HAS_ext32u_i64 1
#define TCG_TARGET_HAS_andc_i64 1
#define TCG_TARGET_HAS_eqv_i64 1
#define TCG_TARGET_HAS_nand_i64 1
#define TCG_TARGET_HAS_nor_i64 1
#define TCG_TARGET_HAS_clz_i64 1
#define TCG_TARGET_HAS_ctz_i64 1
#define TCG_TARGET_HAS_ctpop_i64 1
#define TCG_TARGET_HAS_not_i64 1
#define TCG_TARGET_HAS_orc_i64 1
#define TCG_TARGET_HAS_rot_i64 1
#define TCG_TARGET_HAS_negsetcond_i64 0
#define TCG_TARGET_HAS_muls2_i64 1
#define TCG_TARGET_HAS_add2_i32 1
#define TCG_TARGET_HAS_sub2_i32 1
#define TCG_TARGET_HAS_mulu2_i32 1
#define TCG_TARGET_HAS_add2_i64 1
#define TCG_TARGET_HAS_sub2_i64 1
#define TCG_TARGET_HAS_mulu2_i64 1
#define TCG_TARGET_HAS_muluh_i64 0
#define TCG_TARGET_HAS_mulsh_i64 0
#else
#define TCG_TARGET_HAS_mulu2_i32 1
#endif /* TCG_TARGET_REG_BITS == 64 */
#define TCG_TARGET_HAS_qemu_ldst_i128 0
#define TCG_TARGET_HAS_tst 1
/* Number of registers available. */
#define TCG_TARGET_NB_REGS 16
@ -146,26 +71,7 @@ typedef enum {
TCG_REG_CALL_STACK = TCG_REG_R15,
} TCGReg;
/* Used for function call generation. */
#define TCG_TARGET_CALL_STACK_OFFSET 0
#define TCG_TARGET_STACK_ALIGN 8
#if TCG_TARGET_REG_BITS == 32
# define TCG_TARGET_CALL_ARG_I32 TCG_CALL_ARG_EVEN
# define TCG_TARGET_CALL_ARG_I64 TCG_CALL_ARG_EVEN
# define TCG_TARGET_CALL_ARG_I128 TCG_CALL_ARG_EVEN
#else
# define TCG_TARGET_CALL_ARG_I32 TCG_CALL_ARG_NORMAL
# define TCG_TARGET_CALL_ARG_I64 TCG_CALL_ARG_NORMAL
# define TCG_TARGET_CALL_ARG_I128 TCG_CALL_ARG_NORMAL
#endif
#define TCG_TARGET_CALL_RET_I128 TCG_CALL_RET_NORMAL
#define HAVE_TCG_QEMU_TB_EXEC
#define TCG_TARGET_NEED_POOL_LABELS
/* We could notice __i386__ or __s390x__ and reduce the barriers depending
on the host. But if you want performance, you use the normal backend.
We prefer consistency across hosts on this. */
#define TCG_TARGET_DEFAULT_MO (0)
#endif /* TCG_TARGET_H */

View file

@ -36,7 +36,8 @@ static void sigill_handler(int signo, siginfo_t *si, void *data)
/* Called both as constructor and (possibly) via other constructors. */
unsigned __attribute__((constructor)) cpuinfo_init(void)
{
unsigned left = CPUINFO_ZBA | CPUINFO_ZBB | CPUINFO_ZICOND | CPUINFO_ZVE64X;
unsigned left = CPUINFO_ZBA | CPUINFO_ZBB | CPUINFO_ZBS
| CPUINFO_ZICOND | CPUINFO_ZVE64X;
unsigned info = cpuinfo;
if (info) {
@ -50,6 +51,9 @@ unsigned __attribute__((constructor)) cpuinfo_init(void)
#if defined(__riscv_arch_test) && defined(__riscv_zbb)
info |= CPUINFO_ZBB;
#endif
#if defined(__riscv_arch_test) && defined(__riscv_zbs)
info |= CPUINFO_ZBS;
#endif
#if defined(__riscv_arch_test) && defined(__riscv_zicond)
info |= CPUINFO_ZICOND;
#endif
@ -71,7 +75,8 @@ unsigned __attribute__((constructor)) cpuinfo_init(void)
&& pair.key >= 0) {
info |= pair.value & RISCV_HWPROBE_EXT_ZBA ? CPUINFO_ZBA : 0;
info |= pair.value & RISCV_HWPROBE_EXT_ZBB ? CPUINFO_ZBB : 0;
left &= ~(CPUINFO_ZBA | CPUINFO_ZBB);
info |= pair.value & RISCV_HWPROBE_EXT_ZBS ? CPUINFO_ZBS : 0;
left &= ~(CPUINFO_ZBA | CPUINFO_ZBB | CPUINFO_ZBS);
#ifdef RISCV_HWPROBE_EXT_ZICOND
info |= pair.value & RISCV_HWPROBE_EXT_ZICOND ? CPUINFO_ZICOND : 0;
left &= ~CPUINFO_ZICOND;
@ -117,6 +122,15 @@ unsigned __attribute__((constructor)) cpuinfo_init(void)
left &= ~CPUINFO_ZBB;
}
if (left & CPUINFO_ZBS) {
/* Probe for Zbs: bext zero,zero,zero. */
got_sigill = 0;
asm volatile(".insn r 0x33, 5, 0x24, zero, zero, zero"
: : : "memory");
info |= got_sigill ? 0 : CPUINFO_ZBS;
left &= ~CPUINFO_ZBS;
}
if (left & CPUINFO_ZICOND) {
/* Probe for Zicond: czero.eqz zero,zero,zero. */
got_sigill = 0;