mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-04 00:03:54 -06:00
Hexagon (target/hexagon) circular addressing
The following instructions are added L2_loadrub_pci Rd32 = memub(Rx32++#s4:0:circ(Mu2)) L2_loadrb_pci Rd32 = memb(Rx32++#s4:0:circ(Mu2)) L2_loadruh_pci Rd32 = memuh(Rx32++#s4:1:circ(Mu2)) L2_loadrh_pci Rd32 = memh(Rx32++#s4:1:circ(Mu2)) L2_loadri_pci Rd32 = memw(Rx32++#s4:2:circ(Mu2)) L2_loadrd_pci Rdd32 = memd(Rx32++#s4:3:circ(Mu2)) S2_storerb_pci memb(Rx32++#s4:0:circ(Mu2)) = Rt32 S2_storerh_pci memh(Rx32++#s4:1:circ(Mu2)) = Rt32 S2_storerf_pci memh(Rx32++#s4:1:circ(Mu2)) = Rt.H32 S2_storeri_pci memw(Rx32++#s4:2:circ(Mu2)) = Rt32 S2_storerd_pci memd(Rx32++#s4:3:circ(Mu2)) = Rtt32 S2_storerbnew_pci memb(Rx32++#s4:0:circ(Mu2)) = Nt8.new S2_storerhnew_pci memw(Rx32++#s4:1:circ(Mu2)) = Nt8.new S2_storerinew_pci memw(Rx32++#s4:2:circ(Mu2)) = Nt8.new L2_loadrub_pcr Rd32 = memub(Rx32++I:circ(Mu2)) L2_loadrb_pcr Rd32 = memb(Rx32++I:circ(Mu2)) L2_loadruh_pcr Rd32 = memuh(Rx32++I:circ(Mu2)) L2_loadrh_pcr Rd32 = memh(Rx32++I:circ(Mu2)) L2_loadri_pcr Rd32 = memw(Rx32++I:circ(Mu2)) L2_loadrd_pcr Rdd32 = memd(Rx32++I:circ(Mu2)) S2_storerb_pcr memb(Rx32++I:circ(Mu2)) = Rt32 S2_storerh_pcr memh(Rx32++I:circ(Mu2)) = Rt32 S2_storerf_pcr memh(Rx32++I:circ(Mu2)) = Rt32.H32 S2_storeri_pcr memw(Rx32++I:circ(Mu2)) = Rt32 S2_storerd_pcr memd(Rx32++I:circ(Mu2)) = Rtt32 S2_storerbnew_pcr memb(Rx32++I:circ(Mu2)) = Nt8.new S2_storerhnew_pcr memh(Rx32++I:circ(Mu2)) = Nt8.new S2_storerinew_pcr memw(Rx32++I:circ(Mu2)) = Nt8.new Test cases in tests/tcg/hexagon/circ.c Signed-off-by: Taylor Simpson <tsimpson@quicinc.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <1617930474-31979-23-git-send-email-tsimpson@quicinc.com> [rth: Squash <1619667142-29636-1-git-send-email-tsimpson@quicinc.com> removing gen_read_reg and gen_set_byte to avoid clang Werror.] Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
57d352ac29
commit
46ef47e2a7
9 changed files with 834 additions and 23 deletions
|
@ -133,6 +133,38 @@
|
|||
CHECK_NOSHUF; \
|
||||
tcg_gen_qemu_ld64(DST, VA, ctx->mem_idx); \
|
||||
} while (0)
|
||||
|
||||
#define MEM_STORE1_FUNC(X) \
|
||||
__builtin_choose_expr(TYPE_INT(X), \
|
||||
gen_store1i, \
|
||||
__builtin_choose_expr(TYPE_TCGV(X), \
|
||||
gen_store1, (void)0))
|
||||
#define MEM_STORE1(VA, DATA, SLOT) \
|
||||
MEM_STORE1_FUNC(DATA)(cpu_env, VA, DATA, ctx, SLOT)
|
||||
|
||||
#define MEM_STORE2_FUNC(X) \
|
||||
__builtin_choose_expr(TYPE_INT(X), \
|
||||
gen_store2i, \
|
||||
__builtin_choose_expr(TYPE_TCGV(X), \
|
||||
gen_store2, (void)0))
|
||||
#define MEM_STORE2(VA, DATA, SLOT) \
|
||||
MEM_STORE2_FUNC(DATA)(cpu_env, VA, DATA, ctx, SLOT)
|
||||
|
||||
#define MEM_STORE4_FUNC(X) \
|
||||
__builtin_choose_expr(TYPE_INT(X), \
|
||||
gen_store4i, \
|
||||
__builtin_choose_expr(TYPE_TCGV(X), \
|
||||
gen_store4, (void)0))
|
||||
#define MEM_STORE4(VA, DATA, SLOT) \
|
||||
MEM_STORE4_FUNC(DATA)(cpu_env, VA, DATA, ctx, SLOT)
|
||||
|
||||
#define MEM_STORE8_FUNC(X) \
|
||||
__builtin_choose_expr(TYPE_INT(X), \
|
||||
gen_store8i, \
|
||||
__builtin_choose_expr(TYPE_TCGV_I64(X), \
|
||||
gen_store8, (void)0))
|
||||
#define MEM_STORE8(VA, DATA, SLOT) \
|
||||
MEM_STORE8_FUNC(DATA)(cpu_env, VA, DATA, ctx, SLOT)
|
||||
#else
|
||||
#define MEM_LOAD1s(VA) ((int8_t)mem_load1(env, slot, VA))
|
||||
#define MEM_LOAD1u(VA) ((uint8_t)mem_load1(env, slot, VA))
|
||||
|
@ -285,6 +317,39 @@ static inline void gen_logical_not(TCGv dest, TCGv src)
|
|||
|
||||
#define fPCALIGN(IMM) IMM = (IMM & ~PCALIGN_MASK)
|
||||
|
||||
#ifdef QEMU_GENERATE
|
||||
static inline TCGv gen_read_ireg(TCGv result, TCGv val, int shift)
|
||||
{
|
||||
/*
|
||||
* Section 2.2.4 of the Hexagon V67 Programmer's Reference Manual
|
||||
*
|
||||
* The "I" value from a modifier register is divided into two pieces
|
||||
* LSB bits 23:17
|
||||
* MSB bits 31:28
|
||||
* The value is signed
|
||||
*
|
||||
* At the end we shift the result according to the shift argument
|
||||
*/
|
||||
TCGv msb = tcg_temp_new();
|
||||
TCGv lsb = tcg_temp_new();
|
||||
|
||||
tcg_gen_extract_tl(lsb, val, 17, 7);
|
||||
tcg_gen_sari_tl(msb, val, 21);
|
||||
tcg_gen_deposit_tl(result, msb, lsb, 0, 7);
|
||||
|
||||
tcg_gen_shli_tl(result, result, shift);
|
||||
|
||||
tcg_temp_free(msb);
|
||||
tcg_temp_free(lsb);
|
||||
|
||||
return result;
|
||||
}
|
||||
#define fREAD_IREG(VAL, SHIFT) gen_read_ireg(ireg, (VAL), (SHIFT))
|
||||
#else
|
||||
#define fREAD_IREG(VAL) \
|
||||
(fSXTN(11, 64, (((VAL) & 0xf0000000) >> 21) | ((VAL >> 17) & 0x7f)))
|
||||
#endif
|
||||
|
||||
#define fREAD_LR() (READ_REG(HEX_REG_LR))
|
||||
|
||||
#define fWRITE_LR(A) WRITE_RREG(HEX_REG_LR, A)
|
||||
|
@ -418,6 +483,13 @@ static inline void gen_logical_not(TCGv dest, TCGv src)
|
|||
#define fEA_REG(REG) tcg_gen_mov_tl(EA, REG)
|
||||
#define fPM_I(REG, IMM) tcg_gen_addi_tl(REG, REG, IMM)
|
||||
#define fPM_M(REG, MVAL) tcg_gen_add_tl(REG, REG, MVAL)
|
||||
#define fPM_CIRI(REG, IMM, MVAL) \
|
||||
do { \
|
||||
TCGv tcgv_siV = tcg_const_tl(siV); \
|
||||
gen_helper_fcircadd(REG, REG, tcgv_siV, MuV, \
|
||||
hex_gpr[HEX_REG_CS0 + MuN]); \
|
||||
tcg_temp_free(tcgv_siV); \
|
||||
} while (0)
|
||||
#else
|
||||
#define fEA_IMM(IMM) do { EA = (IMM); } while (0)
|
||||
#define fEA_REG(REG) do { EA = (REG); } while (0)
|
||||
|
@ -494,23 +566,43 @@ static inline void gen_logical_not(TCGv dest, TCGv src)
|
|||
gen_load_locked##SIZE##SIGN(DST, EA, ctx->mem_idx);
|
||||
#endif
|
||||
|
||||
#ifdef QEMU_GENERATE
|
||||
#define fSTORE(NUM, SIZE, EA, SRC) MEM_STORE##SIZE(EA, SRC, insn->slot)
|
||||
#else
|
||||
#define fSTORE(NUM, SIZE, EA, SRC) MEM_STORE##SIZE(EA, SRC, slot)
|
||||
#endif
|
||||
|
||||
#ifdef QEMU_GENERATE
|
||||
#define fSTORE_LOCKED(NUM, SIZE, EA, SRC, PRED) \
|
||||
gen_store_conditional##SIZE(env, ctx, PdN, PRED, EA, SRC);
|
||||
#endif
|
||||
|
||||
#ifdef QEMU_GENERATE
|
||||
#define GETBYTE_FUNC(X) \
|
||||
__builtin_choose_expr(TYPE_TCGV(X), \
|
||||
gen_get_byte, \
|
||||
__builtin_choose_expr(TYPE_TCGV_I64(X), \
|
||||
gen_get_byte_i64, (void)0))
|
||||
#define fGETBYTE(N, SRC) GETBYTE_FUNC(SRC)(BYTE, N, SRC, true)
|
||||
#define fGETUBYTE(N, SRC) GETBYTE_FUNC(SRC)(BYTE, N, SRC, false)
|
||||
#else
|
||||
#define fGETBYTE(N, SRC) ((int8_t)((SRC >> ((N) * 8)) & 0xff))
|
||||
#define fGETUBYTE(N, SRC) ((uint8_t)((SRC >> ((N) * 8)) & 0xff))
|
||||
#endif
|
||||
|
||||
#define fSETBYTE(N, DST, VAL) \
|
||||
do { \
|
||||
DST = (DST & ~(0x0ffLL << ((N) * 8))) | \
|
||||
(((uint64_t)((VAL) & 0x0ffLL)) << ((N) * 8)); \
|
||||
} while (0)
|
||||
|
||||
#ifdef QEMU_GENERATE
|
||||
#define fGETHALF(N, SRC) gen_get_half(HALF, N, SRC, true)
|
||||
#define fGETUHALF(N, SRC) gen_get_half(HALF, N, SRC, false)
|
||||
#else
|
||||
#define fGETHALF(N, SRC) ((int16_t)((SRC >> ((N) * 16)) & 0xffff))
|
||||
#define fGETUHALF(N, SRC) ((uint16_t)((SRC >> ((N) * 16)) & 0xffff))
|
||||
#endif
|
||||
#define fSETHALF(N, DST, VAL) \
|
||||
do { \
|
||||
DST = (DST & ~(0x0ffffLL << ((N) * 16))) | \
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue