summaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2026-09-11 09:15:50 -1000
committerRichard Henderson <richard.henderson@linaro.org>2026-09-11 09:15:50 -1000
commitc7d073cf3682a9a18cd0a0342a2340d7f33dcec4 (patch)
treee5422ab3bd3dccded591452becafaa7ded36bd14 /target
parent7332db732ec713d74885048f64748ae6e033a0fc (diff)
parent8acc03787bd602dec74c0169cf8cf232356eedbd (diff)
downloadqemu-master.tar.gz
qemu-master.zip
Merge tag 'pull-hex-20260911' of https://github.com/qualcomm/qemu into stagingHEADmaster
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.inc3
-rw-r--r--target/hexagon/cpu-qom.h6
-rw-r--r--target/hexagon/cpu.c14
-rw-r--r--target/hexagon/cpu.h4
-rw-r--r--target/hexagon/cpu_helper.c15
-rw-r--r--target/hexagon/genptr.c8
-rw-r--r--target/hexagon/hex_interrupts.c141
-rw-r--r--target/hexagon/hex_regs.h42
-rw-r--r--target/hexagon/imported/encode_pp.def21
-rw-r--r--target/hexagon/imported/ldst.idef21
-rw-r--r--target/hexagon/imported/system.idef7
-rw-r--r--target/hexagon/op_helper.c58
-rw-r--r--target/hexagon/reg_fields_def.h.inc10
-rw-r--r--target/hexagon/sys_macros.h11
-rw-r--r--target/hexagon/tag_rev_info.c.inc30
-rw-r--r--target/hexagon/translate.c8
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]);