diff options
| author | Richard Henderson <richard.henderson@linaro.org> | 2026-09-11 09:15:50 -1000 |
|---|---|---|
| committer | Richard Henderson <richard.henderson@linaro.org> | 2026-09-11 09:15:50 -1000 |
| commit | c7d073cf3682a9a18cd0a0342a2340d7f33dcec4 (patch) | |
| tree | e5422ab3bd3dccded591452becafaa7ded36bd14 /target | |
| parent | 7332db732ec713d74885048f64748ae6e033a0fc (diff) | |
| parent | 8acc03787bd602dec74c0169cf8cf232356eedbd (diff) | |
| download | qemu-master.tar.gz qemu-master.zip | |
Hexagon: v81 support
Initial support for v81, scalar only for now. HVX support
to follow.
Adds new machine definitions, v81 system architecture changes,
new scalar opcodes.
# -----BEGIN PGP SIGNATURE-----
#
# iQIzBAABCgAdFiEEPWaq5HRZSCTIjOD4GlSvuOVkbDIFAmqkJh0ACgkQGlSvuOVk
# bDJM1g//YHmUxStWUE+Sg2HXSTWMr+hqTFez1e70Xz429oQUTm86VyzrvIELUOD5
# kQDUlAkuTEuvheOjiA1ho4tXUEzaZTLmHX/V1jORN9AQV7c+2aiSJueAeh+zujMu
# Aa/4LtkBOb3xlmG7jAV3te1X1Cga0AQoR/VpfXOIR/ZdM+qCuENYvWG4Y/s5Wpvd
# 45MCO1CsROQW1uQIgbQbVUgmuF7sR3nkcMfFLCz5EnhNxSuUmpbHun/yWMWszj+n
# njldsowEEWH94uo8LN5U8sG1LgoreXUD6/vq7t6FKuPEqrwumksACJFWcbjiDc/0
# mtBByhC4jdleZ9LCx98Lle4h2RDxhjESGP3PTZWVNI6rzGghIEWJBI8EXKlmwCw3
# cC5C8H5v6xdpfqtzktZhOtT1/DHXLHgrPBZolpxnkAHEEnM7EZW8T0F53Tn+unDm
# dwUfQFCrYsno+Ez2owcv0BvIVHHT4TshQKgbRUHvisLYucyER/b9tZgkp8XeVecj
# eOwku4d68i6sQ1Rg8qC/hm426siP9FGwyWiiKvPjSx2GpDCYRMztP7/5NuKP7jxP
# ep7cNasDRzHkK3k7PpeWvNDU9YD4qReE9R0tsI6mfX/W5c38RY3Pt5vP1rIkgefH
# 7nP294Qhk8eJkUhlZvolTEIBT6YCL72peguMQ0TxqS1CaRa+Qu8=
# =Z7JW
# -----END PGP SIGNATURE-----
# gpg: Signature made Fri 11 Sep 2026 06:02:37 AM HST
# gpg: using RSA key 3D66AAE474594824C88CE0F81A54AFB8E5646C32
# gpg: Good signature from "Brian Cain (OSS Qualcomm) <brian.cain@oss.qualcomm.com>" [unknown]
# gpg: aka "Brian Cain (QUIC) <quic_bcain@quicinc.com>" [unknown]
# gpg: aka "Brian Cain <bcain@kernel.org>" [unknown]
# gpg: aka "Brian Cain (QuIC) <bcain@quicinc.com>" [unknown]
# gpg: aka "Brian Cain (CAF) <bcain@codeaurora.org>" [unknown]
# gpg: aka "bcain" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg: There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 6350 20F9 67A7 7164 79EF 49E0 175C 464E 541B 6D47
# Subkey fingerprint: 3D66 AAE4 7459 4824 C88C E0F8 1A54 AFB8 E564 6C32
* tag 'pull-hex-20260911' of https://github.com/qualcomm/qemu:
docs: Correct semihost spec URL
tests/functional: cover v81 system registers
target/hexagon: add v81 interrupt registers
target/hexagon: widen v81 CPU masks
hw/hexagon: move "sim" alias to "V81QA_1"
hw/hexagon: add the V81DGB_1 and V81QA_1 machines
target/hexagon: add Y2_tlbpp as unimplemented
target/hexagon: add the v79 instructions
target/hexagon: add the v73 J2_unpause scalar instruction
target/hexagon: add the v75, v79 and v81 CPU models
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'target')
| -rw-r--r-- | target/hexagon/attribs_def.h.inc | 3 | ||||
| -rw-r--r-- | target/hexagon/cpu-qom.h | 6 | ||||
| -rw-r--r-- | target/hexagon/cpu.c | 14 | ||||
| -rw-r--r-- | target/hexagon/cpu.h | 4 | ||||
| -rw-r--r-- | target/hexagon/cpu_helper.c | 15 | ||||
| -rw-r--r-- | target/hexagon/genptr.c | 8 | ||||
| -rw-r--r-- | target/hexagon/hex_interrupts.c | 141 | ||||
| -rw-r--r-- | target/hexagon/hex_regs.h | 42 | ||||
| -rw-r--r-- | target/hexagon/imported/encode_pp.def | 21 | ||||
| -rw-r--r-- | target/hexagon/imported/ldst.idef | 21 | ||||
| -rw-r--r-- | target/hexagon/imported/system.idef | 7 | ||||
| -rw-r--r-- | target/hexagon/op_helper.c | 58 | ||||
| -rw-r--r-- | target/hexagon/reg_fields_def.h.inc | 10 | ||||
| -rw-r--r-- | target/hexagon/sys_macros.h | 11 | ||||
| -rw-r--r-- | target/hexagon/tag_rev_info.c.inc | 30 | ||||
| -rw-r--r-- | target/hexagon/translate.c | 8 |
16 files changed, 317 insertions, 82 deletions
diff --git a/target/hexagon/attribs_def.h.inc b/target/hexagon/attribs_def.h.inc index d12f6ac4b1..5a98ea3313 100644 --- a/target/hexagon/attribs_def.h.inc +++ b/target/hexagon/attribs_def.h.inc @@ -21,8 +21,11 @@ DEF_ATTRIB(AA_DUMMY, "Dummy Zeroth Attribute", "", "") /* Misc */ DEF_ATTRIB(EXTENSION, "Extension instruction", "", "") +DEF_ATTRIB(NA_NT, "Non-Allocating Non-Temporal instruction", "", "") + DEF_ATTRIB(PRIV, "Not available in user or guest mode", "", "") DEF_ATTRIB(GUEST, "Not available in user mode", "", "") +DEF_ATTRIB(TLBPP_INSN, "Extended (64-bit VA) TLB probe instruction", "", "") DEF_ATTRIB(FPOP, "Floating Point Operation", "", "") diff --git a/target/hexagon/cpu-qom.h b/target/hexagon/cpu-qom.h index 6e1bb04070..2bfa4d5d0f 100644 --- a/target/hexagon/cpu-qom.h +++ b/target/hexagon/cpu-qom.h @@ -25,6 +25,9 @@ typedef enum { HEX_VER_V69 = 0x69, HEX_VER_V71 = 0x71, HEX_VER_V73 = 0x73, + HEX_VER_V75 = 0x75, + HEX_VER_V79 = 0x79, + HEX_VER_V81 = 0x81, HEX_VER_ANY = 0xff, } HexagonVersion; @@ -49,6 +52,9 @@ typedef struct { #define TYPE_HEXAGON_CPU_V69 HEXAGON_CPU_TYPE_NAME("v69") #define TYPE_HEXAGON_CPU_V71 HEXAGON_CPU_TYPE_NAME("v71") #define TYPE_HEXAGON_CPU_V73 HEXAGON_CPU_TYPE_NAME("v73") +#define TYPE_HEXAGON_CPU_V75 HEXAGON_CPU_TYPE_NAME("v75") +#define TYPE_HEXAGON_CPU_V79 HEXAGON_CPU_TYPE_NAME("v79") +#define TYPE_HEXAGON_CPU_V81 HEXAGON_CPU_TYPE_NAME("v81") OBJECT_DECLARE_CPU_TYPE(HexagonCPU, HexagonCPUClass, HEXAGON_CPU) diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c index 4a7b76e3bc..fad526ccfb 100644 --- a/target/hexagon/cpu.c +++ b/target/hexagon/cpu.c @@ -103,7 +103,16 @@ const char * const hexagon_sregnames[] = { "pmucnt5", "pmucnt6", "pmucnt7", "pmucnt0", "pmucnt1", "pmucnt2", "pmucnt3", "pmuevtcfg", "pmustid0", "pmuevtcfg1", "pmustid1", "timerlo", "timerhi", "pmucfg", "s59", - "s60", "s61", "s62", "s63", + "s60", "s61", "s62", "s63", "commit1t", + "commit2t", "commit3t", "commit4t", "commit5t", "commit6t", + "pcycle1t", "pcycle2t", "pcycle3t", "pcycle4t", "pcycle5t", + "pcycle6t", "stfinst", "isdbcmd", "isdbver", "brkptinfo", + "s80", "commit7t", "commit8t", "pcycle7t", "pcycle8t", + "commit9t", "commit10t", "commit11t", "commit12t", "commit13t", + "commit14t", "commit15t", "commit16t", "pcycle9t", "pcycle10t", + "pcycle11t", "pcycle12t", "pcycle13t", "pcycle14t", "pcycle15t", + "pcycle16t", "ipend", "iad", "isdbst1", "isdbst2", + "brkptinfo1", }; G_STATIC_ASSERT(NUM_SREGS == ARRAY_SIZE(hexagon_sregnames)); @@ -874,6 +883,9 @@ static const TypeInfo hexagon_cpu_type_infos[] = { DEFINE_CPU(TYPE_HEXAGON_CPU_V69, HEX_VER_V69), DEFINE_CPU(TYPE_HEXAGON_CPU_V71, HEX_VER_V71), DEFINE_CPU(TYPE_HEXAGON_CPU_V73, HEX_VER_V73), + DEFINE_CPU(TYPE_HEXAGON_CPU_V75, HEX_VER_V75), + DEFINE_CPU(TYPE_HEXAGON_CPU_V79, HEX_VER_V79), + DEFINE_CPU(TYPE_HEXAGON_CPU_V81, HEX_VER_V81), }; DEFINE_TYPES(hexagon_cpu_type_infos) diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h index 8a4a81dc26..b1533680bd 100644 --- a/target/hexagon/cpu.h +++ b/target/hexagon/cpu.h @@ -23,7 +23,7 @@ #ifndef CONFIG_USER_ONLY #define NUM_GREGS 32 #define GREG_WRITES_MAX 2 -#define NUM_SREGS 64 +#define NUM_SREGS 106 #define SREG_WRITES_MAX 2 #endif @@ -50,7 +50,7 @@ typedef struct HexagonGlobalRegState HexagonGlobalRegState; #define PRED_WRITES_MAX 5 /* 4 insns + endloop */ #define VSTORES_MAX 2 #define MAX_TLB_ENTRIES 1024 -#define THREADS_MAX 8 +#define THREADS_MAX 16 #define CPU_RESOLVING_TYPE TYPE_HEXAGON_CPU #ifndef CONFIG_USER_ONLY diff --git a/target/hexagon/cpu_helper.c b/target/hexagon/cpu_helper.c index 9ce260d744..eea5f60b46 100644 --- a/target/hexagon/cpu_helper.c +++ b/target/hexagon/cpu_helper.c @@ -333,10 +333,17 @@ int get_exe_mode(const CPUHexagonState *env) E_bit = thread_enabled_mask & (0x1 << env->threadId); thread_wait_mask = GET_FIELD(MODECTL_W, modectl); W_bit = thread_wait_mask & (0x1 << env->threadId); - isdbst = cpu->globalregs ? - hexagon_globalreg_read(cpu->globalregs, HEX_SREG_ISDBST, - env->threadId) : 0; - debugmode = GET_FIELD(ISDBST_DEBUGMODE, isdbst); + if (cpu->cfg.hex_def->hex_version >= HEX_VER_V81) { + isdbst = cpu->globalregs ? + hexagon_globalreg_read(cpu->globalregs, HEX_SREG_ISDBST2, + env->threadId) : 0; + debugmode = GET_FIELD(ISDBST2_DEBUGMODE, isdbst); + } else { + isdbst = cpu->globalregs ? + hexagon_globalreg_read(cpu->globalregs, HEX_SREG_ISDBST, + env->threadId) : 0; + debugmode = GET_FIELD(ISDBST_DEBUGMODE, isdbst); + } D_bit = debugmode & (0x1 << env->threadId); if (!D_bit && !W_bit && !E_bit) { diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c index 9f53fcb6b9..4e9a9670d5 100644 --- a/target/hexagon/genptr.c +++ b/target/hexagon/genptr.c @@ -269,14 +269,18 @@ static const uint32_t sreg_immut_masks[NUM_SREGS] = { [HEX_SREG_SSR] = 0x00008000, [HEX_SREG_CCR] = 0x10e0ff24, [HEX_SREG_HTID] = IMMUTABLE, - [HEX_SREG_IMASK] = 0xffff0000, [HEX_SREG_GEVB] = 0x000000ff, }; G_GNUC_UNUSED static void gen_log_sreg_write(DisasContext *ctx, int rnum, TCGv_i32 val) { - const uint32_t reg_mask = sreg_immut_masks[rnum]; + uint32_t reg_mask = sreg_immut_masks[rnum]; + + if (rnum == HEX_SREG_IMASK && + ctx->hex_def->hex_version < HEX_VER_V81) { + reg_mask = 0xffff0000; + } if (reg_mask != IMMUTABLE) { if (rnum < HEX_SREG_GLB_START) { diff --git a/target/hexagon/hex_interrupts.c b/target/hexagon/hex_interrupts.c index 2b2834af95..0b714b7383 100644 --- a/target/hexagon/hex_interrupts.c +++ b/target/hexagon/hex_interrupts.c @@ -21,7 +21,7 @@ static bool hex_is_qualified_for_int(CPUHexagonState *env, int int_num); static bool get_syscfg_gie(CPUHexagonState *env) { - HexagonCPU *cpu = env_archcpu(env); + const HexagonCPU *cpu = env_archcpu(env); uint32_t syscfg = hexagon_globalreg_read(cpu->globalregs, HEX_SREG_SYSCFG, env->threadId); @@ -52,85 +52,138 @@ static void set_ssr_ex_cause(CPUHexagonState *env, int ex, uint32_t cause) hexagon_modify_ssr(env, new, old); } -static bool get_iad_bit(CPUHexagonState *env, int int_num) +static bool has_split_ipend_iad(const CPUHexagonState *env) +{ + const HexagonCPU *cpu = env_archcpu(env); + + return cpu->cfg.hex_def->hex_version >= HEX_VER_V81; +} + +static uint32_t get_iad(CPUHexagonState *env) { HexagonCPU *cpu = env_archcpu(env); - uint32_t ipendad = - hexagon_globalreg_read(cpu->globalregs, HEX_SREG_IPENDAD, - env->threadId); - uint32_t iad = GET_FIELD(IPENDAD_IAD, ipendad); + + if (has_split_ipend_iad(env)) { + return hexagon_globalreg_read(cpu->globalregs, HEX_SREG_IAD, + env->threadId); + } + return GET_FIELD(IPENDAD_IAD, + hexagon_globalreg_read(cpu->globalregs, + HEX_SREG_IPENDAD, + env->threadId)); +} + +static void set_iad(CPUHexagonState *env, uint32_t iad) +{ + HexagonCPU *cpu = env_archcpu(env); + + if (has_split_ipend_iad(env)) { + hexagon_globalreg_write(cpu->globalregs, HEX_SREG_IAD, iad, + env->threadId); + } else { + uint32_t ipendad = + hexagon_globalreg_read(cpu->globalregs, HEX_SREG_IPENDAD, + env->threadId); + + fSET_FIELD(ipendad, IPENDAD_IAD, iad); + hexagon_globalreg_write(cpu->globalregs, HEX_SREG_IPENDAD, + ipendad, env->threadId); + } +} + +static bool get_iad_bit(CPUHexagonState *env, int int_num) +{ + uint32_t iad = get_iad(env); + return extract32(iad, int_num, 1); } static void set_iad_bit(CPUHexagonState *env, int int_num, int val) { - HexagonCPU *cpu = env_archcpu(env); - uint32_t ipendad = - hexagon_globalreg_read(cpu->globalregs, HEX_SREG_IPENDAD, - env->threadId); - uint32_t iad = GET_FIELD(IPENDAD_IAD, ipendad); + uint32_t iad = get_iad(env); + iad = deposit32(iad, int_num, 1, val); - fSET_FIELD(ipendad, IPENDAD_IAD, iad); - hexagon_globalreg_write(cpu->globalregs, HEX_SREG_IPENDAD, - ipendad, env->threadId); + set_iad(env, iad); } static uint32_t get_ipend(CPUHexagonState *env) { HexagonCPU *cpu = env_archcpu(env); - uint32_t ipendad = - hexagon_globalreg_read(cpu->globalregs, HEX_SREG_IPENDAD, - env->threadId); - return GET_FIELD(IPENDAD_IPEND, ipendad); + + if (has_split_ipend_iad(env)) { + return hexagon_globalreg_read(cpu->globalregs, HEX_SREG_IPEND, + env->threadId); + } + return GET_FIELD(IPENDAD_IPEND, + hexagon_globalreg_read(cpu->globalregs, + HEX_SREG_IPENDAD, + env->threadId)); } static inline bool get_ipend_bit(CPUHexagonState *env, int int_num) { - HexagonCPU *cpu = env_archcpu(env); - uint32_t ipendad = - hexagon_globalreg_read(cpu->globalregs, HEX_SREG_IPENDAD, - env->threadId); - uint32_t ipend = GET_FIELD(IPENDAD_IPEND, ipendad); + uint32_t ipend = get_ipend(env); return extract32(ipend, int_num, 1); } static void clear_ipend(CPUHexagonState *env, uint32_t mask) { HexagonCPU *cpu = env_archcpu(env); - uint32_t ipendad = - hexagon_globalreg_read(cpu->globalregs, HEX_SREG_IPENDAD, - env->threadId); - uint32_t ipend = GET_FIELD(IPENDAD_IPEND, ipendad); + uint32_t ipend = get_ipend(env); + ipend &= ~mask; - fSET_FIELD(ipendad, IPENDAD_IPEND, ipend); - hexagon_globalreg_write(cpu->globalregs, HEX_SREG_IPENDAD, - ipendad, env->threadId); + if (has_split_ipend_iad(env)) { + hexagon_globalreg_write(cpu->globalregs, HEX_SREG_IPEND, ipend, + env->threadId); + } else { + uint32_t ipendad = + hexagon_globalreg_read(cpu->globalregs, HEX_SREG_IPENDAD, + env->threadId); + + fSET_FIELD(ipendad, IPENDAD_IPEND, ipend); + hexagon_globalreg_write(cpu->globalregs, HEX_SREG_IPENDAD, + ipendad, env->threadId); + } } static void set_ipend(CPUHexagonState *env, uint32_t mask) { HexagonCPU *cpu = env_archcpu(env); - uint32_t ipendad = - hexagon_globalreg_read(cpu->globalregs, HEX_SREG_IPENDAD, - env->threadId); - uint32_t ipend = GET_FIELD(IPENDAD_IPEND, ipendad); + uint32_t ipend = get_ipend(env); + ipend |= mask; - fSET_FIELD(ipendad, IPENDAD_IPEND, ipend); - hexagon_globalreg_write(cpu->globalregs, HEX_SREG_IPENDAD, - ipendad, env->threadId); + if (has_split_ipend_iad(env)) { + hexagon_globalreg_write(cpu->globalregs, HEX_SREG_IPEND, ipend, + env->threadId); + } else { + uint32_t ipendad = + hexagon_globalreg_read(cpu->globalregs, HEX_SREG_IPENDAD, + env->threadId); + + fSET_FIELD(ipendad, IPENDAD_IPEND, ipend); + hexagon_globalreg_write(cpu->globalregs, HEX_SREG_IPENDAD, + ipendad, env->threadId); + } } static void set_ipend_bit(CPUHexagonState *env, int int_num, int val) { HexagonCPU *cpu = env_archcpu(env); - uint32_t ipendad = - hexagon_globalreg_read(cpu->globalregs, HEX_SREG_IPENDAD, - env->threadId); - uint32_t ipend = GET_FIELD(IPENDAD_IPEND, ipendad); + uint32_t ipend = get_ipend(env); + ipend = deposit32(ipend, int_num, 1, val); - fSET_FIELD(ipendad, IPENDAD_IPEND, ipend); - hexagon_globalreg_write(cpu->globalregs, HEX_SREG_IPENDAD, - ipendad, env->threadId); + if (has_split_ipend_iad(env)) { + hexagon_globalreg_write(cpu->globalregs, HEX_SREG_IPEND, ipend, + env->threadId); + } else { + uint32_t ipendad = + hexagon_globalreg_read(cpu->globalregs, HEX_SREG_IPENDAD, + env->threadId); + + fSET_FIELD(ipendad, IPENDAD_IPEND, ipend); + hexagon_globalreg_write(cpu->globalregs, HEX_SREG_IPENDAD, + ipendad, env->threadId); + } } static bool get_imask_bit(CPUHexagonState *env, int int_num) diff --git a/target/hexagon/hex_regs.h b/target/hexagon/hex_regs.h index 214b7b8fde..1f6bf9f88a 100644 --- a/target/hexagon/hex_regs.h +++ b/target/hexagon/hex_regs.h @@ -195,6 +195,48 @@ enum { HEX_SREG_S61 = 61, HEX_SREG_S62 = 62, HEX_SREG_S63 = 63, + HEX_SREG_COMMIT1T = 64, + HEX_SREG_COMMIT2T = 65, + HEX_SREG_COMMIT3T = 66, + HEX_SREG_COMMIT4T = 67, + HEX_SREG_COMMIT5T = 68, + HEX_SREG_COMMIT6T = 69, + HEX_SREG_PCYCLE1T = 70, + HEX_SREG_PCYCLE2T = 71, + HEX_SREG_PCYCLE3T = 72, + HEX_SREG_PCYCLE4T = 73, + HEX_SREG_PCYCLE5T = 74, + HEX_SREG_PCYCLE6T = 75, + HEX_SREG_STFINST = 76, + HEX_SREG_ISDBCMD = 77, + HEX_SREG_ISDBVER = 78, + HEX_SREG_BRKPTINFO = 79, + HEX_SREG_S80 = 80, + HEX_SREG_COMMIT7T = 81, + HEX_SREG_COMMIT8T = 82, + HEX_SREG_PCYCLE7T = 83, + HEX_SREG_PCYCLE8T = 84, + HEX_SREG_COMMIT9T = 85, + HEX_SREG_COMMIT10T = 86, + HEX_SREG_COMMIT11T = 87, + HEX_SREG_COMMIT12T = 88, + HEX_SREG_COMMIT13T = 89, + HEX_SREG_COMMIT14T = 90, + HEX_SREG_COMMIT15T = 91, + HEX_SREG_COMMIT16T = 92, + HEX_SREG_PCYCLE9T = 93, + HEX_SREG_PCYCLE10T = 94, + HEX_SREG_PCYCLE11T = 95, + HEX_SREG_PCYCLE12T = 96, + HEX_SREG_PCYCLE13T = 97, + HEX_SREG_PCYCLE14T = 98, + HEX_SREG_PCYCLE15T = 99, + HEX_SREG_PCYCLE16T = 100, + HEX_SREG_IPEND = 101, + HEX_SREG_IAD = 102, + HEX_SREG_ISDBST1 = 103, + HEX_SREG_ISDBST2 = 104, + HEX_SREG_BRKPTINFO1 = 105, }; #endif /* !CONFIG_USER_ONLY */ diff --git a/target/hexagon/imported/encode_pp.def b/target/hexagon/imported/encode_pp.def index d9e8ea2aeb..4b307b97b3 100644 --- a/target/hexagon/imported/encode_pp.def +++ b/target/hexagon/imported/encode_pp.def @@ -407,6 +407,7 @@ DEF_ENC32(R6_release_st_vi, ICLASS_ST" 000 01 11sssss PP0ttttt --1011dd") DEF_EXT_SPACE(EXTRACTW, ICLASS_LD" 001 0 000 iiiii PP0iiiii 001iiiii") DEF_ENC32(Y2_dcfetchbo, ICLASS_LD" 010 0 000 sssss PP0--iii iiiiiiii") +DEF_ENC32(Y2_dcfetchbo_nt,"10010100000sssssPP10-iiiiiiiiiii") @@ -473,6 +474,13 @@ STD_ST_ENC(rbnew, "1 101","00ttt") STD_ST_ENC(rhnew, "1 101","01ttt") STD_ST_ENC(rinew, "1 101","10ttt") +/* Non-temporal post-increment stores: the OPC nibble's high bit, always + * 1 above, is repurposed as the "nt" hint for this addressing mode only. */ +DEF_ENC32(S2_storerb_pi_nt,"10101010000xxxxxPP0ttttt0iiii-0-") +DEF_ENC32(S2_storerh_pi_nt,"10101010010xxxxxPP0ttttt0iiii-0-") +DEF_ENC32(S2_storeri_pi_nt,"10101010100xxxxxPP0ttttt0iiii-0-") +DEF_ENC32(S2_storerd_pi_nt,"10101010110xxxxxPP0ttttt0iiii-00") + STD_PST_ENC(rb, "1 000","ttttt") STD_PST_ENC(rh, "1 010","ttttt") STD_PST_ENC(rf, "1 011","ttttt") @@ -482,6 +490,16 @@ STD_PST_ENC(rbnew, "1 101","00ttt") STD_PST_ENC(rhnew, "1 101","01ttt") STD_PST_ENC(rinew, "1 101","10ttt") +/* Predicated forms of the non-temporal post-increment stores above. */ +DEF_ENC32(S2_pstorerbt_pi_nt,"10101010000xxxxxPP1ttttt0iiii0vv") +DEF_ENC32(S2_pstorerbf_pi_nt,"10101010000xxxxxPP1ttttt0iiii1vv") +DEF_ENC32(S2_pstorerht_pi_nt,"10101010010xxxxxPP1ttttt0iiii0vv") +DEF_ENC32(S2_pstorerhf_pi_nt,"10101010010xxxxxPP1ttttt0iiii1vv") +DEF_ENC32(S2_pstorerit_pi_nt,"10101010100xxxxxPP1ttttt0iiii0vv") +DEF_ENC32(S2_pstorerif_pi_nt,"10101010100xxxxxPP1ttttt0iiii1vv") +DEF_ENC32(S2_pstorerdt_pi_nt,"10101010110xxxxxPP1ttttt0iiii0vv") +DEF_ENC32(S2_pstorerdf_pi_nt,"10101010110xxxxxPP1ttttt0iiii1vv") + /* User */ @@ -492,6 +510,7 @@ STD_PST_ENC(rinew, "1 101","10ttt") DEF_ENC32(S2_allocframe, ICLASS_ST" 000 01 00xxxxx PP000iii iiiiiiii") DEF_ENC32(Y5_l2locka, ICLASS_ST" 000 01 11sssss PP1----- ------dd") DEF_ENC32(Y2_dczeroa, ICLASS_ST" 000 01 10sssss PP0----- --------") +DEF_ENC32(Y2_dczeroa_nt,"10100000110sssssPP1-------------") DEF_ENC32(Y2_barrier, ICLASS_ST" 100 00 00----- PP------ 000-----") @@ -585,6 +604,7 @@ DEF_FIELDROW_DESC32(ICLASS_J" 0100 -------- PP------ --------","[#4] (#u8) ") DEF_ENC32(J2_trap0, ICLASS_J" 0100 00------ PP-iiiii ---iii--") DEF_ENC32(J2_trap1, ICLASS_J" 0100 10-xxxxx PP-iiiii ---iii--") DEF_ENC32(J2_pause, ICLASS_J" 0100 01----ii PP-iiiii ---iii--") +DEF_ENC32(J2_unpause,"01010111111-----PP01----000-----") DEF_FIELDROW_DESC32(ICLASS_J" 0101 -------- PP------ --------","[#5] Rd=(Rs) ") DEF_ENC32(Y2_icdatar, ICLASS_J" 0101 101sssss PP------ ---ddddd") @@ -870,6 +890,7 @@ DEF_ENC32(Y2_tlbunlock,ICLASS_CR" 1100 001----- PP------ 010-----") DEF_ENC32(Y2_k0lock, ICLASS_CR" 1100 001----- PP------ 011-----") DEF_ENC32(Y2_k0unlock, ICLASS_CR" 1100 001----- PP------ 100-----") DEF_ENC32(Y2_tlbp, ICLASS_CR" 1100 100sssss PP------ ---ddddd") +DEF_ENC32(Y2_tlbpp,"01101100011sssssPP---------ddddd") DEF_ENC32(Y5_tlboc, ICLASS_CR" 1100 111sssss PP------ ---ddddd") DEF_ENC32(Y5_tlbasidi, ICLASS_CR" 1100 101sssss PP------ --------") DEF_ENC32(Y2_tlbr, ICLASS_CR" 1100 010sssss PP------ ---ddddd") diff --git a/target/hexagon/imported/ldst.idef b/target/hexagon/imported/ldst.idef index 4e1e5d5326..7106a0c572 100644 --- a/target/hexagon/imported/ldst.idef +++ b/target/hexagon/imported/ldst.idef @@ -118,6 +118,16 @@ STD_ST_AMODES(storerh, "Rt32", "memh","Store Half integer",ATTRIBS(A_REGWRSIZE_2 STD_ST_AMODES(storerf, "Rt.H32", "memh","Store Upper Half integer",ATTRIBS(A_REGWRSIZE_2B,A_MEMSIZE_2B,A_STORE),"1",fSTORE(1,2,EA,fGETHALF(1,RtV)),1) STD_ST_AMODES(storeri, "Rt32", "memw","Store Word",ATTRIBS(A_REGWRSIZE_4B,A_MEMSIZE_4B,A_STORE),"2",fSTORE(1,4,EA,RtV),2) STD_ST_AMODES(storerd, "Rtt32","memd","Store Double integer",ATTRIBS(A_REGWRSIZE_8B,A_MEMSIZE_8B,A_STORE),"3",fSTORE(1,8,EA,RttV),3) + +/* + * Non-temporal post-increment stores: same store, with a cache-locality + * hint that a normal-priority cache line is unlikely to be reused soon. + */ +Q6INSN(S2_storerb_pi_nt,"memb(Rx32++#s4:0):nt=Rt32",ATTRIBS(A_ARCHV2,A_MEMSIZE_1B,A_STORE,A_NA_NT),"Store Byte",{fEA_REG(RxV); fPM_I(RxV,siV); fSTORE(1,1,EA,fGETBYTE(0,RtV)); }) +Q6INSN(S2_storerh_pi_nt,"memh(Rx32++#s4:1):nt=Rt32",ATTRIBS(A_REGWRSIZE_2B,A_ARCHV2,A_MEMSIZE_2B,A_STORE,A_NA_NT),"Store Half integer",{fEA_REG(RxV); fPM_I(RxV,siV); fSTORE(1,2,EA,fGETHALF(0,RtV)); }) +Q6INSN(S2_storeri_pi_nt,"memw(Rx32++#s4:2):nt=Rt32",ATTRIBS(A_REGWRSIZE_4B,A_ARCHV2,A_MEMSIZE_4B,A_STORE,A_NA_NT),"Store Word",{fEA_REG(RxV); fPM_I(RxV,siV); fSTORE(1,4,EA,RtV); }) +Q6INSN(S2_storerd_pi_nt,"memd(Rx32++#s4:3):nt=Rtt32",ATTRIBS(A_REGWRSIZE_8B,A_ARCHV2,A_MEMSIZE_8B,A_STORE,A_NA_NT),"Store Double integer",{fEA_REG(RxV); fPM_I(RxV,siV); fSTORE(1,8,EA,RttV); }) + STD_ST_AMODES(storerinew, "Nt8.new", "memw","Store Word",ATTRIBS(A_REGWRSIZE_4B,A_NOTE_NEWVAL_SLOT0,A_NVSTORE,A_NOTE_NVSLOT0,A_MEMSIZE_4B,A_STORE,A_RESTRICT_NOSLOT1_STORE),"2",fSTORE(1,4,EA,fNEWREG_ST(NtN)),2) STD_ST_AMODES(storerbnew, "Nt8.new", "memb","Store Byte",ATTRIBS(A_NOTE_NEWVAL_SLOT0,A_NVSTORE,A_NOTE_NVSLOT0,A_MEMSIZE_1B,A_STORE,A_RESTRICT_NOSLOT1_STORE),"0",fSTORE(1,1,EA,fGETBYTE(0,fNEWREG_ST(NtN))),0) STD_ST_AMODES(storerhnew, "Nt8.new", "memh","Store Half integer",ATTRIBS(A_REGWRSIZE_2B,A_NOTE_NEWVAL_SLOT0,A_NVSTORE,A_NOTE_NVSLOT0,A_MEMSIZE_2B,A_STORE,A_RESTRICT_NOSLOT1_STORE),"1",fSTORE(1,2,EA,fGETHALF(0,fNEWREG_ST(NtN))),1) @@ -277,6 +287,17 @@ STD_PST_AMODES(storerh,"Rt32","memh","Store Half integer",ATTRIBS(A_REGWRSIZE_2B STD_PST_AMODES(storerf,"Rt.H32","memh","Store Upper Half integer",ATTRIBS(A_REGWRSIZE_2B,A_ARCHV2,A_MEMSIZE_2B,A_STORE),"1",1,fSTORE(1,2,EA,fGETHALF(1,RtV))) STD_PST_AMODES(storeri,"Rt32","memw","Store Word",ATTRIBS(A_REGWRSIZE_4B,A_ARCHV2,A_MEMSIZE_4B,A_STORE),"2",2,fSTORE(1,4,EA,RtV)) STD_PST_AMODES(storerd,"Rtt32","memd","Store Double integer",ATTRIBS(A_REGWRSIZE_8B,A_ARCHV2,A_MEMSIZE_8B,A_STORE),"3",3,fSTORE(1,8,EA,RttV)) + +/* Predicated forms of the non-temporal post-increment stores above. */ +Q6INSN(S2_pstorerbt_pi_nt,"if (Pv4) memb(Rx32++#s4:0):nt=Rt32",ATTRIBS(A_ARCHV2,A_MEMSIZE_1B,A_STORE,A_NA_NT),"Store Byte",{fEA_REG(RxV); if (fLSBOLD(PvV)){ fPM_I(RxV,siV); fSTORE(1,1,EA,fGETBYTE(0,RtV));} else {STORE_CANCEL(EA);}}) +Q6INSN(S2_pstorerbf_pi_nt,"if (!Pv4) memb(Rx32++#s4:0):nt=Rt32",ATTRIBS(A_ARCHV2,A_MEMSIZE_1B,A_STORE,A_NA_NT),"Store Byte",{fEA_REG(RxV); if (fLSBOLDNOT(PvV)){ fPM_I(RxV,siV); fSTORE(1,1,EA,fGETBYTE(0,RtV));} else {STORE_CANCEL(EA);}}) +Q6INSN(S2_pstorerht_pi_nt,"if (Pv4) memh(Rx32++#s4:1):nt=Rt32",ATTRIBS(A_REGWRSIZE_2B,A_ARCHV2,A_MEMSIZE_2B,A_STORE,A_NA_NT),"Store Half integer",{fEA_REG(RxV); if (fLSBOLD(PvV)){ fPM_I(RxV,siV); fSTORE(1,2,EA,fGETHALF(0,RtV));} else {STORE_CANCEL(EA);}}) +Q6INSN(S2_pstorerhf_pi_nt,"if (!Pv4) memh(Rx32++#s4:1):nt=Rt32",ATTRIBS(A_REGWRSIZE_2B,A_ARCHV2,A_MEMSIZE_2B,A_STORE,A_NA_NT),"Store Half integer",{fEA_REG(RxV); if (fLSBOLDNOT(PvV)){ fPM_I(RxV,siV); fSTORE(1,2,EA,fGETHALF(0,RtV));} else {STORE_CANCEL(EA);}}) +Q6INSN(S2_pstorerit_pi_nt,"if (Pv4) memw(Rx32++#s4:2):nt=Rt32",ATTRIBS(A_REGWRSIZE_4B,A_ARCHV2,A_MEMSIZE_4B,A_STORE,A_NA_NT),"Store Word",{fEA_REG(RxV); if (fLSBOLD(PvV)){ fPM_I(RxV,siV); fSTORE(1,4,EA,RtV);} else {STORE_CANCEL(EA);}}) +Q6INSN(S2_pstorerif_pi_nt,"if (!Pv4) memw(Rx32++#s4:2):nt=Rt32",ATTRIBS(A_REGWRSIZE_4B,A_ARCHV2,A_MEMSIZE_4B,A_STORE,A_NA_NT),"Store Word",{fEA_REG(RxV); if (fLSBOLDNOT(PvV)){ fPM_I(RxV,siV); fSTORE(1,4,EA,RtV);} else {STORE_CANCEL(EA);}}) +Q6INSN(S2_pstorerdt_pi_nt,"if (Pv4) memd(Rx32++#s4:3):nt=Rtt32",ATTRIBS(A_REGWRSIZE_8B,A_ARCHV2,A_MEMSIZE_8B,A_STORE,A_NA_NT),"Store Double integer",{fEA_REG(RxV); if (fLSBOLD(PvV)){ fPM_I(RxV,siV); fSTORE(1,8,EA,RttV);} else {STORE_CANCEL(EA);}}) +Q6INSN(S2_pstorerdf_pi_nt,"if (!Pv4) memd(Rx32++#s4:3):nt=Rtt32",ATTRIBS(A_REGWRSIZE_8B,A_ARCHV2,A_MEMSIZE_8B,A_STORE,A_NA_NT),"Store Double integer",{fEA_REG(RxV); if (fLSBOLDNOT(PvV)){ fPM_I(RxV,siV); fSTORE(1,8,EA,RttV);} else {STORE_CANCEL(EA);}}) + STD_PST_AMODES(storerinew,"Nt8.new","memw","Store Word",ATTRIBS(A_REGWRSIZE_4B,A_ARCHV2,A_NOTE_NEWVAL_SLOT0,A_NVSTORE,A_NOTE_NVSLOT0,A_MEMSIZE_4B,A_STORE,A_RESTRICT_NOSLOT1_STORE),"2",2,fSTORE(1,4,EA,fNEWREG_ST(NtN))) STD_PST_AMODES(storerbnew,"Nt8.new","memb","Store Byte",ATTRIBS(A_ARCHV2,A_NOTE_NEWVAL_SLOT0,A_NVSTORE,A_NOTE_NVSLOT0,A_MEMSIZE_1B,A_STORE,A_RESTRICT_NOSLOT1_STORE),"0",0,fSTORE(1,1,EA,fGETBYTE(0,fNEWREG_ST(NtN)))) STD_PST_AMODES(storerhnew,"Nt8.new","memh","Store Half integer",ATTRIBS(A_REGWRSIZE_2B,A_ARCHV2,A_NOTE_NEWVAL_SLOT0,A_NVSTORE,A_NOTE_NVSLOT0,A_MEMSIZE_2B,A_STORE,A_RESTRICT_NOSLOT1_STORE),"1",1,fSTORE(1,2,EA,fGETHALF(0,fNEWREG_ST(NtN)))) diff --git a/target/hexagon/imported/system.idef b/target/hexagon/imported/system.idef index 02aee8ce8e..a58da8f826 100644 --- a/target/hexagon/imported/system.idef +++ b/target/hexagon/imported/system.idef @@ -51,6 +51,9 @@ Q6INSN(J2_trap1,"trap1(Rx32,#u8)",ATTRIBS(A_COF,A_NOTE_NOPACKET,A_RESTRICT_NOPAC Q6INSN(J2_pause,"pause(#u8)",ATTRIBS(A_COF,A_NOTE_NOPACKET,A_RESTRICT_NOPACKET), "Enter low-power state for #u8 cycles",{fPAUSE(uiV);}) +Q6INSN(J2_unpause,"unpause",ATTRIBS(A_COF,A_NOTE_NOPACKET,A_RESTRICT_NOPACKET), +"Resume paused threads",{fUNPAUSE();}) + Q6INSN(J2_rte, "rte", ATTRIBS(A_PRIV,A_NOTE_PRIV,A_NO_TIMING_LOG), "Return from Exception", { @@ -115,6 +118,8 @@ Q6INSN(Y2_tlbr,"Rdd32=tlbr(Rs32)", ATTRIBS(A_PRIV,A_NOTE_PRIV,A_NOTE_NOPACKET,A_ Q6INSN(Y2_tlbp,"Rd32=tlbp(Rs32)", ATTRIBS(A_PRIV,A_NOTE_PRIV,A_NOTE_NOPACKET,A_RESTRICT_NOPACKET), "Probe TLB", {RdV=fTLBP(RsV);}) +Q6INSN(Y2_tlbpp,"Rd32=tlbp(Rss32)", ATTRIBS(A_PRIV,A_NOTE_PRIV,A_NOTE_NOPACKET,A_RESTRICT_NOPACKET,A_TLBPP_INSN), "Probe TLB64", {RdV=fTLBPP(RssV);}) + Q6INSN(Y5_tlbasidi,"tlbinvasid(Rs32)",ATTRIBS(A_PRIV,A_NOTE_PRIV,A_NOTE_NOPACKET,A_RESTRICT_NOPACKET), "Invalidate ASID", { fHIDE(int i;) @@ -235,10 +240,12 @@ Q6INSN(Y6_dmresume,"dmresume(Rs32)",ATTRIBS(A_NOTE_NOPACKET,A_RESTRICT_NOPACKET, Q6INSN(Y2_dcfetchbo,"dcfetch(Rs32+#u11:3)",ATTRIBS(A_RESTRICT_PREFERSLOT0,A_DCFETCH,A_RESTRICT_NOSLOT1_STORE),"Data Cache Prefetch",{fEA_RI(RsV,uiV); fDCFETCH(EA);}) +Q6INSN(Y2_dcfetchbo_nt,"dcfetch(Rs32+#u11:3):nt",ATTRIBS(A_NA_NT,A_RESTRICT_PREFERSLOT0,A_DCFETCH,A_RESTRICT_NOSLOT1_STORE),"Data Cache Prefetch",{fEA_RI(RsV,uiV); fDCFETCH(EA);}) Q6INSN(Y2_dckill,"dckill",ATTRIBS(A_PRIV,A_NOTE_PRIV,A_NOTE_NOPACKET,A_RESTRICT_SLOT0ONLY,A_RESTRICT_NOPACKET,A_CACHEOP,A_DCFLUSHOP),"Data Cache Invalidate",{fDCKILL();}) Q6INSN(Y2_dczeroa,"dczeroa(Rs32)",ATTRIBS(A_STORE,A_RESTRICT_SLOT1_AOK,A_NOTE_SLOT1_AOK,A_RESTRICT_SLOT0ONLY,A_CACHEOP,A_COPBYADDRESS,A_DCZEROA),"Zero an aligned 32-byte cacheline",{fEA_REG(RsV); fDCZEROA(EA);}) +Q6INSN(Y2_dczeroa_nt,"dczeroa(Rs32):nt",ATTRIBS(A_STORE,A_RESTRICT_SLOT1_AOK,A_NOTE_SLOT1_AOK,A_RESTRICT_SLOT0ONLY,A_CACHEOP,A_COPBYADDRESS,A_DCZEROA,A_NA_NT),"Zero an aligned 32-byte cacheline",{fEA_REG(RsV); fDCZEROA(EA);}) Q6INSN(Y2_dccleana,"dccleana(Rs32)",ATTRIBS(A_RESTRICT_SLOT1_AOK,A_NOTE_SLOT1_AOK,A_RESTRICT_SLOT0ONLY,A_CACHEOP,A_COPBYADDRESS,A_DCFLUSHOP),"Data Cache Clean Address",{fEA_REG(RsV); fDCCLEANA(EA);}) Q6INSN(Y2_dccleanidx,"dccleanidx(Rs32)",ATTRIBS(A_PRIV,A_NOTE_PRIV,A_RESTRICT_PACKET_AXOK,A_NOTE_AXOK,A_RESTRICT_SLOT0ONLY,A_CACHEOP,A_COPBYIDX,A_DCFLUSHOP),"Data Cache Clean Index",{fDCCLEANIDX(RsV);}) Q6INSN(Y2_dccleaninva,"dccleaninva(Rs32)",ATTRIBS(A_RESTRICT_SLOT1_AOK,A_NOTE_SLOT1_AOK,A_RESTRICT_SLOT0ONLY,A_CACHEOP,A_COPBYADDRESS,A_DCFLUSHOP),"Data Cache Clean and Invalidate Address",{fEA_REG(RsV); fDCCLEANINVA(EA);}) diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c index 7ad99ced7a..0d08ac7736 100644 --- a/target/hexagon/op_helper.c +++ b/target/hexagon/op_helper.c @@ -1600,38 +1600,53 @@ void HELPER(raise_stack_overflow)(CPUHexagonState *env, uint32_t slot, void HELPER(ciad)(CPUHexagonState *env, uint32_t mask) { - uint32_t ipendad; uint32_t iad; HexagonCPU *cpu; BQL_LOCK_GUARD(); cpu = env_archcpu(env); - ipendad = hexagon_globalreg_read(cpu->globalregs, HEX_SREG_IPENDAD, - env->threadId); - iad = fGET_FIELD(ipendad, IPENDAD_IAD); - fSET_FIELD(ipendad, IPENDAD_IAD, iad & ~(mask)); - hexagon_globalreg_write(cpu->globalregs, HEX_SREG_IPENDAD, - ipendad, env->threadId); + if (cpu->cfg.hex_def->hex_version >= HEX_VER_V81) { + iad = hexagon_globalreg_read(cpu->globalregs, HEX_SREG_IAD, + env->threadId) & ~mask; + hexagon_globalreg_write(cpu->globalregs, HEX_SREG_IAD, iad, + env->threadId); + } else { + uint32_t ipendad = + hexagon_globalreg_read(cpu->globalregs, HEX_SREG_IPENDAD, + env->threadId); + + fSET_FIELD(ipendad, IPENDAD_IAD, + fGET_FIELD(ipendad, IPENDAD_IAD) & ~mask); + hexagon_globalreg_write(cpu->globalregs, HEX_SREG_IPENDAD, + ipendad, env->threadId); + } l2vic_clear_interrupt(cpu->l2vic); hex_interrupt_update(env); } void HELPER(siad)(CPUHexagonState *env, uint32_t mask) { - uint32_t ipendad; uint32_t iad; HexagonCPU *cpu; BQL_LOCK_GUARD(); cpu = env_archcpu(env); - ipendad = cpu->globalregs ? - hexagon_globalreg_read(cpu->globalregs, HEX_SREG_IPENDAD, - env->threadId) : 0; - iad = fGET_FIELD(ipendad, IPENDAD_IAD); - fSET_FIELD(ipendad, IPENDAD_IAD, iad | mask); if (cpu->globalregs) { - hexagon_globalreg_write(cpu->globalregs, HEX_SREG_IPENDAD, - ipendad, env->threadId); + if (cpu->cfg.hex_def->hex_version >= HEX_VER_V81) { + iad = hexagon_globalreg_read(cpu->globalregs, HEX_SREG_IAD, + env->threadId) | mask; + hexagon_globalreg_write(cpu->globalregs, HEX_SREG_IAD, iad, + env->threadId); + } else { + uint32_t ipendad = + hexagon_globalreg_read(cpu->globalregs, HEX_SREG_IPENDAD, + env->threadId); + + fSET_FIELD(ipendad, IPENDAD_IAD, + fGET_FIELD(ipendad, IPENDAD_IAD) | mask); + hexagon_globalreg_write(cpu->globalregs, HEX_SREG_IPENDAD, + ipendad, env->threadId); + } } hex_interrupt_update(env); } @@ -1657,7 +1672,7 @@ void HELPER(iassignw)(CPUHexagonState *env, uint32_t src) CPU_FOREACH(cpu) { CPUHexagonState *thread_env = &(HEXAGON_CPU(cpu)->env); uint32_t imask = thread_env->t_sreg[HEX_SREG_IMASK]; - uint32_t intbitpos = (src >> 16) & 0xF; + uint32_t intbitpos = extract32(src, 16, 5); uint32_t val = (src >> thread_env->threadId) & 0x1; imask = deposit32(imask, intbitpos, 1, val); thread_env->t_sreg[HEX_SREG_IMASK] = imask; @@ -1677,7 +1692,7 @@ uint32_t HELPER(iassignr)(CPUHexagonState *env, uint32_t src) BQL_LOCK_GUARD(); /* src fields are in same position as modectl, but mean different things */ - intbitpos = GET_FIELD(MODECTL_W, src); + intbitpos = extract32(src, 16, 5); dest_reg = 0; CPU_FOREACH(cpu) { CPUHexagonState *thread_env = &(HEXAGON_CPU(cpu)->env); @@ -1896,10 +1911,17 @@ static inline QEMU_ALWAYS_INLINE uint32_t sreg_read(CPUHexagonState *env, } return env->t_sreg[HEX_SREG_BADVA0]; } + cpu = env_archcpu(env); + if (reg == HEX_SREG_IPENDAD && + cpu->cfg.hex_def->hex_version >= HEX_VER_V81) { + return (hexagon_globalreg_read(cpu->globalregs, HEX_SREG_IPEND, + env->threadId) & 0xffff) | + ((hexagon_globalreg_read(cpu->globalregs, HEX_SREG_IAD, + env->threadId) & 0xffff) << 16); + } if (reg < HEX_SREG_GLB_START) { return env->t_sreg[reg]; } - cpu = env_archcpu(env); return cpu->globalregs ? hexagon_globalreg_read(cpu->globalregs, reg, env->threadId) : 0; } diff --git a/target/hexagon/reg_fields_def.h.inc b/target/hexagon/reg_fields_def.h.inc index 29497fbcc4..c06e14fe24 100644 --- a/target/hexagon/reg_fields_def.h.inc +++ b/target/hexagon/reg_fields_def.h.inc @@ -44,7 +44,7 @@ DEF_REG_FIELD(IPENDAD_IAD, 16, 16) DEF_REG_FIELD(IPENDAD_IPEND, 0, 16) DEF_REG_FIELD(SCHEDCFG_EN, 8, 1) -DEF_REG_FIELD(SCHEDCFG_INTNO, 0, 4) +DEF_REG_FIELD(SCHEDCFG_INTNO, 0, 5) DEF_REG_FIELD(BESTWAIT_PRIO, 0, 9) @@ -109,14 +109,13 @@ DEF_REG_FIELD(SSR_SS, 30, 1) DEF_REG_FIELD(SSR_XE, 31, 1) /* misc registers */ -DEF_REG_FIELD(IMASK_MASK, 0, 16) +DEF_REG_FIELD(IMASK_MASK, 0, 32) DEF_REG_FIELD(STID_PRIO, 16, 8) DEF_REG_FIELD(STID_STID, 0, 8) -/* MODECTL fields */ -DEF_REG_FIELD(MODECTL_E, 0, 8) -DEF_REG_FIELD(MODECTL_W, 16, 8) +DEF_REG_FIELD(MODECTL_E, 0, 16) +DEF_REG_FIELD(MODECTL_W, 16, 16) DEF_REG_FIELD(CCR_L1ICP, 0, 2) DEF_REG_FIELD(CCR_L1DCP, 3, 2) @@ -153,3 +152,4 @@ DEF_REG_FIELD(ISDBST_PROCMODE, 3, 1) DEF_REG_FIELD(ISDBST_MBXINSTATUS, 2, 1) DEF_REG_FIELD(ISDBST_MBXOUTSTATUS, 1, 1) DEF_REG_FIELD(ISDBST_READY, 0, 1) +DEF_REG_FIELD(ISDBST2_DEBUGMODE, 16, 16) diff --git a/target/hexagon/sys_macros.h b/target/hexagon/sys_macros.h index a49c72715d..a5b9b7f259 100644 --- a/target/hexagon/sys_macros.h +++ b/target/hexagon/sys_macros.h @@ -177,14 +177,21 @@ fTLB_NONPOW2WRAP(fTLB_IDXMASK(INDEX))) #define fTLBP(TLBHI) \ hex_tlb_lookup(env, ((TLBHI) >> 12), ((TLBHI) << 12)) +#define fTLBPP(TLBHI) ({ \ + qemu_log_mask(LOG_UNIMP, "tlbpp is not implemented\n"); \ + 0; }) #define iic_flush_cache(p) #define fIN_DEBUG_MODE(TNUM) ({ \ HexagonCPU *_cpu = env_archcpu(env); \ + bool _is_v81 = _cpu->cfg.hex_def->hex_version >= HEX_VER_V81; \ uint32_t _isdbst = _cpu->globalregs ? \ hexagon_globalreg_read(_cpu->globalregs, \ - HEX_SREG_ISDBST, env->threadId) : 0; \ - (GET_FIELD(ISDBST_DEBUGMODE, _isdbst) \ + _is_v81 ? HEX_SREG_ISDBST2 : HEX_SREG_ISDBST, \ + env->threadId) : 0; \ + ((_is_v81 ? \ + GET_FIELD(ISDBST2_DEBUGMODE, _isdbst) : \ + GET_FIELD(ISDBST_DEBUGMODE, _isdbst)) \ & (0x1 << (TNUM))) != 0; }) #define fIN_DEBUG_MODE_NO_ISDB(TNUM) false diff --git a/target/hexagon/tag_rev_info.c.inc b/target/hexagon/tag_rev_info.c.inc index a91b91a23e..68be8cbafb 100644 --- a/target/hexagon/tag_rev_info.c.inc +++ b/target/hexagon/tag_rev_info.c.inc @@ -571,8 +571,9 @@ static const struct tag_rev_info tag_rev_info[XX_LAST_OPCODE] = { [F2_dfmpyhh] = { .introduced = HEX_VER_V67, .removed = HEX_VER_NONE }, [F2_dfmpylh] = { .introduced = HEX_VER_V67, .removed = HEX_VER_NONE }, [F2_dfmpyll] = { .introduced = HEX_VER_V67, .removed = HEX_VER_NONE }, - [J2_callrh] = { .introduced = 0x73, .removed = HEX_VER_NONE }, - [J2_jumprh] = { .introduced = 0x73, .removed = HEX_VER_NONE }, + [J2_callrh] = { .introduced = HEX_VER_V73, .removed = HEX_VER_NONE }, + [J2_jumprh] = { .introduced = HEX_VER_V73, .removed = HEX_VER_NONE }, + [J2_unpause] = { .introduced = HEX_VER_V73, .removed = HEX_VER_NONE }, [L2_loadw_aq] = { .introduced = HEX_VER_V68, .removed = HEX_VER_NONE }, [L4_loadd_aq] = { .introduced = HEX_VER_V68, .removed = HEX_VER_NONE }, [Y6_dmcfgrd] = { .introduced = HEX_VER_V68, .removed = HEX_VER_NONE }, @@ -618,6 +619,31 @@ static const struct tag_rev_info tag_rev_info[XX_LAST_OPCODE] = { [V6_vassign_tmp] = { .introduced = HEX_VER_V69, .removed = HEX_VER_NONE }, [V6_vcombine_tmp] = { .introduced = HEX_VER_V69, .removed = HEX_VER_NONE }, [V6_vmpyuhvs] = { .introduced = HEX_VER_V69, .removed = HEX_VER_NONE }, + + [S2_pstorerbf_pi_nt] = { .introduced = HEX_VER_V79, + .removed = HEX_VER_NONE }, + [S2_pstorerbt_pi_nt] = { .introduced = HEX_VER_V79, + .removed = HEX_VER_NONE }, + [S2_pstorerdf_pi_nt] = { .introduced = HEX_VER_V79, + .removed = HEX_VER_NONE }, + [S2_pstorerdt_pi_nt] = { .introduced = HEX_VER_V79, + .removed = HEX_VER_NONE }, + [S2_pstorerhf_pi_nt] = { .introduced = HEX_VER_V79, + .removed = HEX_VER_NONE }, + [S2_pstorerht_pi_nt] = { .introduced = HEX_VER_V79, + .removed = HEX_VER_NONE }, + [S2_pstorerif_pi_nt] = { .introduced = HEX_VER_V79, + .removed = HEX_VER_NONE }, + [S2_pstorerit_pi_nt] = { .introduced = HEX_VER_V79, + .removed = HEX_VER_NONE }, + [S2_storerb_pi_nt] = { .introduced = HEX_VER_V79, .removed = HEX_VER_NONE }, + [S2_storerd_pi_nt] = { .introduced = HEX_VER_V79, .removed = HEX_VER_NONE }, + [S2_storerh_pi_nt] = { .introduced = HEX_VER_V79, .removed = HEX_VER_NONE }, + [S2_storeri_pi_nt] = { .introduced = HEX_VER_V79, .removed = HEX_VER_NONE }, + [Y2_dcfetchbo_nt] = { .introduced = HEX_VER_V79, .removed = HEX_VER_NONE }, + [Y2_dczeroa_nt] = { .introduced = HEX_VER_V79, .removed = HEX_VER_NONE }, + + [Y2_tlbpp] = { .introduced = HEX_VER_V81, .removed = HEX_VER_NONE }, }; #endif /* HEXAGON_TAG_ARCH_TABLE_H */ diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c index 5d3d67e5d3..fd1de87405 100644 --- a/target/hexagon/translate.c +++ b/target/hexagon/translate.c @@ -319,6 +319,8 @@ static bool sreg_write_ends_tb(int reg_num) reg_num == HEX_SREG_STID || reg_num == HEX_SREG_IMASK || reg_num == HEX_SREG_IPENDAD || + reg_num == HEX_SREG_IPEND || + reg_num == HEX_SREG_IAD || reg_num == HEX_SREG_BESTWAIT || reg_num == HEX_SREG_SCHEDCFG; } @@ -830,8 +832,10 @@ static void gen_sreg_writes(DisasContext *ctx) gen_helper_modify_ssr(tcg_env, ctx->t_sreg_new_value[reg_num], old_reg); } else if ((reg_num == HEX_SREG_STID) || - (reg_num == HEX_SREG_IMASK) || - (reg_num == HEX_SREG_IPENDAD)) { + (reg_num == HEX_SREG_IMASK) || + (reg_num == HEX_SREG_IPENDAD) || + (reg_num == HEX_SREG_IPEND) || + (reg_num == HEX_SREG_IAD)) { if (ctx->need_commit && reg_num < HEX_SREG_GLB_START) { tcg_gen_mov_tl(hex_t_sreg[reg_num], ctx->t_sreg_new_value[reg_num]); |
