Add decode and translation for trap2 and the vallocframe and
vdeallocframe instruction forms introduced with v83.  Model vector stack
overflow as a precise exception and report it to linux-user as SIGSEGV.

Signed-off-by: Brian Cain <[email protected]>
---
 target/hexagon/cpu_bits.h               |  1 +
 target/hexagon/gen_tcg.h                | 51 +++++++++++++++++++++++++
 target/hexagon/hex_regs.h               |  2 +
 target/hexagon/translate.h              |  1 +
 linux-user/hexagon/cpu_loop.c           |  4 ++
 target/hexagon/cpu.c                    |  2 +-
 target/hexagon/hexswi.c                 |  5 +++
 target/hexagon/translate.c              |  2 +-
 target/hexagon/tag_rev_info.c.inc       | 10 +++++
 target/hexagon/gen_idef_parser_funcs.py |  2 +-
 target/hexagon/gen_tcg_funcs.py         |  4 +-
 target/hexagon/imported/encode_pp.def   |  5 +++
 target/hexagon/imported/system.idef     |  8 ++++
 13 files changed, 93 insertions(+), 4 deletions(-)

diff --git a/target/hexagon/cpu_bits.h b/target/hexagon/cpu_bits.h
index a8fba4aa188..02ab05b326a 100644
--- a/target/hexagon/cpu_bits.h
+++ b/target/hexagon/cpu_bits.h
@@ -77,6 +77,7 @@ enum hex_cause {
     HEX_CAUSE_NO_COPROC2_ENABLE = 0x018,
     HEX_CAUSE_PRIV_USER_NO_GINSN = 0x01a,
     HEX_CAUSE_PRIV_USER_NO_SINSN = 0x01b,
+    HEX_CAUSE_VECTOR_STACK_OVERFLOW = 0x01c,
     HEX_CAUSE_REG_WRITE_CONFLICT = 0x01d,
     HEX_CAUSE_PC_NOT_ALIGNED = 0x01e,
     HEX_CAUSE_MISALIGNED_LOAD = 0x020,
diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h
index 38d8558c97a..114199aaaac 100644
--- a/target/hexagon/gen_tcg.h
+++ b/target/hexagon/gen_tcg.h
@@ -1405,6 +1405,57 @@
         RtV = RtV; \
     } while (0)
 
+#ifdef CONFIG_USER_ONLY
+#define fGEN_TCG_V2_CHECK_AND_WRITE_VSP(VSP) \
+    do { \
+        TCGLabel *write_vsp = gen_new_label(); \
+        tcg_gen_brcond_tl(TCG_COND_GEU, VSP, \
+                          hex_gpr[HEX_REG_VFRAMELIMIT], write_vsp); \
+        gen_precise_exception(HEX_CAUSE_VECTOR_STACK_OVERFLOW, ctx->pkt.pc); \
+        gen_set_label(write_vsp); \
+        tcg_gen_mov_tl(hex_gpr[HEX_REG_VSP], VSP); \
+    } while (0)
+#else
+#define fGEN_TCG_V2_CHECK_AND_WRITE_VSP(VSP) \
+    do { \
+        TCGLabel *write_vsp = gen_new_label(); \
+        TCGv mode = tcg_temp_new(); \
+        tcg_gen_andi_tl(mode, hex_t_sreg[HEX_SREG_SSR], \
+                        1 << reg_field_info[SSR_EX].offset); \
+        tcg_gen_brcondi_tl(TCG_COND_NE, mode, 0, write_vsp); \
+        tcg_gen_andi_tl(mode, hex_t_sreg[HEX_SREG_SSR], \
+                        1 << reg_field_info[SSR_UM].offset); \
+        tcg_gen_brcondi_tl(TCG_COND_EQ, mode, 0, write_vsp); \
+        tcg_gen_brcond_tl(TCG_COND_GEU, VSP, \
+                          hex_gpr[HEX_REG_VFRAMELIMIT], write_vsp); \
+        gen_precise_exception(HEX_CAUSE_VECTOR_STACK_OVERFLOW, ctx->pkt.pc); \
+        gen_set_label(write_vsp); \
+        tcg_gen_mov_tl(hex_gpr[HEX_REG_VSP], VSP); \
+    } while (0)
+#endif
+#define fGEN_TCG_V2_vallocframe_imm(SHORTCODE) \
+    do { \
+        TCGv vsp = tcg_temp_new(); \
+        tcg_gen_subi_tl(vsp, hex_gpr[HEX_REG_VSP], uiV << 11); \
+        fGEN_TCG_V2_CHECK_AND_WRITE_VSP(vsp); \
+    } while (0)
+#define fGEN_TCG_V2_vallocframe_reg(SHORTCODE) \
+    do { \
+        TCGv size = tcg_temp_new(); \
+        TCGv vsp = tcg_temp_new(); \
+        tcg_gen_shli_tl(size, RsV, 11); \
+        tcg_gen_sub_tl(vsp, hex_gpr[HEX_REG_VSP], size); \
+        fGEN_TCG_V2_CHECK_AND_WRITE_VSP(vsp); \
+    } while (0)
+#define fGEN_TCG_V2_vdeallocframe_imm(SHORTCODE) \
+    tcg_gen_addi_tl(hex_gpr[HEX_REG_VSP], hex_gpr[HEX_REG_VSP], uiV << 11)
+#define fGEN_TCG_V2_vdeallocframe_reg(SHORTCODE) \
+    do { \
+        TCGv size = tcg_temp_new(); \
+        tcg_gen_shli_tl(size, RsV, 11); \
+        tcg_gen_add_tl(hex_gpr[HEX_REG_VSP], hex_gpr[HEX_REG_VSP], size); \
+    } while (0)
+
 #define fGEN_TCG_L2_loadw_aq(SHORTCODE)                 SHORTCODE
 #define fGEN_TCG_L4_loadd_aq(SHORTCODE)                 SHORTCODE
 
diff --git a/target/hexagon/hex_regs.h b/target/hexagon/hex_regs.h
index 1f6bf9f88a0..03feca477b6 100644
--- a/target/hexagon/hex_regs.h
+++ b/target/hexagon/hex_regs.h
@@ -77,6 +77,8 @@ enum {
     HEX_REG_QEMU_PKT_CNT      = 52,
     HEX_REG_QEMU_INSN_CNT     = 53,
     HEX_REG_QEMU_HVX_CNT      = 54,
+    HEX_REG_VFRAMELIMIT       = 60,
+    HEX_REG_VSP               = 61,
     HEX_REG_UTIMERLO          = 62,
     HEX_REG_UTIMERHI          = 63,
 };
diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h
index 2d1ed5208b7..a4fc9d0c6f1 100644
--- a/target/hexagon/translate.h
+++ b/target/hexagon/translate.h
@@ -365,6 +365,7 @@ extern TCGv_i64 hex_llsc_val_i64;
 extern TCGv hex_vstore_addr[VSTORES_MAX];
 extern TCGv hex_vstore_size[VSTORES_MAX];
 extern TCGv hex_vstore_pending[VSTORES_MAX];
+void gen_precise_exception(int cause, uint32_t pc);
 #ifdef CONFIG_USER_ONLY
 #define hex_hvx_ptr tcg_env
 #define HEX_HVX_OFFSET(member) offsetof(CPUHexagonState, hvx_ctx.member)
diff --git a/linux-user/hexagon/cpu_loop.c b/linux-user/hexagon/cpu_loop.c
index e6bb3b62a9f..2e66b4d9ac8 100644
--- a/linux-user/hexagon/cpu_loop.c
+++ b/linux-user/hexagon/cpu_loop.c
@@ -73,6 +73,10 @@ void cpu_loop(CPUHexagonState *env)
                 force_sig_fault(TARGET_SIGSEGV, TARGET_SEGV_MAPERR,
                                 env->gpr[HEX_REG_PC]);
                 break;
+            case HEX_CAUSE_VECTOR_STACK_OVERFLOW:
+                force_sig_fault(TARGET_SIGSEGV, TARGET_SEGV_BNDERR,
+                                env->gpr[HEX_REG_PC]);
+                break;
             case HEX_CAUSE_PRIV_USER_NO_GINSN:
             case HEX_CAUSE_PRIV_USER_NO_SINSN:
             case HEX_CAUSE_INVALID_PACKET:
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
index f7303c07abd..6adeee9d57f 100644
--- a/target/hexagon/cpu.c
+++ b/target/hexagon/cpu.c
@@ -87,7 +87,7 @@ const char * const hexagon_regnames[TOTAL_PER_THREAD_REGS] = {
   "sa0", "lc0", "sa1", "lc1", "p3_0", "c5",  "m0",  "m1",
   "usr", "pc",  "ugp", "gp",  "cs0",  "cs1", "c14", "c15",
   "c16", "c17", "c18", "c19", "pkt_cnt",  "insn_cnt", "hvx_cnt", "c23",
-  "c24", "c25", "c26", "c27", "c28",  "c29", "c30", "c31",
+  "c24", "c25", "c26", "c27", "vframelimit", "vsp", "c30", "c31",
 };
 
 #ifndef CONFIG_USER_ONLY
diff --git a/target/hexagon/hexswi.c b/target/hexagon/hexswi.c
index ef1d558dfc4..73949720ccf 100644
--- a/target/hexagon/hexswi.c
+++ b/target/hexagon/hexswi.c
@@ -366,6 +366,10 @@ static void coredump(CPUHexagonState *env)
         fprintf(f, "0x%x, Stack limit check error",
                 HEX_CAUSE_STACK_LIMIT);
         break;
+    case HEX_CAUSE_VECTOR_STACK_OVERFLOW:
+        fprintf(f, "0x%x, Vector stack overflow",
+                HEX_CAUSE_VECTOR_STACK_OVERFLOW);
+        break;
     case HEX_CAUSE_FPTRAP_CAUSE_BADFLOAT:
         fprintf(f, "0x%x, Floating-Point: Execution of Floating-Point "
                 "instruction resulted in exception",
@@ -905,6 +909,7 @@ void hexagon_cpu_do_interrupt(CPUState *cs)
         case HEX_CAUSE_NO_COPROC_ENABLE:
         case HEX_CAUSE_NO_COPROC2_ENABLE:
         case HEX_CAUSE_UNSUPPORTED_HVX_64B:
+        case HEX_CAUSE_VECTOR_STACK_OVERFLOW:
         case HEX_CAUSE_REG_WRITE_CONFLICT:
         case HEX_CAUSE_VWCTRL_WINDOW_MISS:
             hexagon_ssr_set_cause(env, env->cause_code);
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
index cd1abdf1461..665791db4fb 100644
--- a/target/hexagon/translate.c
+++ b/target/hexagon/translate.c
@@ -137,7 +137,7 @@ intptr_t ctx_tmp_vreg_off(DisasContext *ctx, int regnum,
     return offset;
 }
 
-static void gen_precise_exception(int cause, uint32_t PC)
+void gen_precise_exception(int cause, uint32_t PC)
 {
     tcg_gen_movi_i32(hex_cause_code, cause);
     gen_helper_raise_exception(tcg_env, tcg_constant_i32(HEX_EVENT_PRECISE),
diff --git a/target/hexagon/tag_rev_info.c.inc 
b/target/hexagon/tag_rev_info.c.inc
index a1b7b50cbf2..c2d4886a846 100644
--- a/target/hexagon/tag_rev_info.c.inc
+++ b/target/hexagon/tag_rev_info.c.inc
@@ -699,6 +699,16 @@ static const struct tag_rev_info 
tag_rev_info[XX_LAST_OPCODE] = {
     },
     [V6_vconv_bf_qf32] = { .introduced = HEX_VER_V81, .removed = HEX_VER_NONE 
},
 
+    [V2_vallocframe_imm] = { .introduced = HEX_VER_V83,
+                             .removed = HEX_VER_NONE },
+    [V2_vallocframe_reg] = { .introduced = HEX_VER_V83,
+                             .removed = HEX_VER_NONE },
+    [V2_vdeallocframe_imm] = { .introduced = HEX_VER_V83,
+                               .removed = HEX_VER_NONE },
+    [V2_vdeallocframe_reg] = { .introduced = HEX_VER_V83,
+                               .removed = HEX_VER_NONE },
+    [J2_trap2] = { .introduced = HEX_VER_V83, .removed = HEX_VER_NONE },
+
     [Y4_dcfetch_multi] = { .introduced = HEX_VER_V85,
                             .removed = HEX_VER_NONE },
     [AM_addw_aq] = { .introduced = HEX_VER_V85, .removed = HEX_VER_NONE },
diff --git a/target/hexagon/gen_idef_parser_funcs.py 
b/target/hexagon/gen_idef_parser_funcs.py
index 7151a4f6713..9293be4c398 100644
--- a/target/hexagon/gen_idef_parser_funcs.py
+++ b/target/hexagon/gen_idef_parser_funcs.py
@@ -77,7 +77,7 @@ def main():
             if tag in {"S4_vrcrotate_acc", "S4_vrcrotate"}:
                 continue
             ## Skip trap instructions
-            if tag in {"J2_trap0", "J2_trap1"}:
+            if tag in {"J2_trap0", "J2_trap1", "J2_trap2"}:
                 continue
             ## Skip 128-bit instructions
             if tag in {"A7_croundd_ri", "A7_croundd_rr"}:
diff --git a/target/hexagon/gen_tcg_funcs.py b/target/hexagon/gen_tcg_funcs.py
index b09ce7c285f..bdc3fa0fe04 100755
--- a/target/hexagon/gen_tcg_funcs.py
+++ b/target/hexagon/gen_tcg_funcs.py
@@ -86,7 +86,9 @@ def gen_tcg_func(f, tag, regs, imms):
     if "A_HVX_IEEE_FP" in hex_common.attribdict[tag]:
         gen_disabled_ieee_insn(f, tag, regs)
 
-    if hex_common.is_idef_parser_enabled(tag):
+    if (hex_common.is_idef_parser_enabled(tag) and tag not in {
+            "V2_vallocframe_imm", "V2_vallocframe_reg",
+            "V2_vdeallocframe_imm", "V2_vdeallocframe_reg"}):
         gpr_operands = [
             hex_common.get_register(tag, regtype, regid)
             for regtype, regid in regs
diff --git a/target/hexagon/imported/encode_pp.def 
b/target/hexagon/imported/encode_pp.def
index c590ed4f959..ed1de09a40c 100644
--- a/target/hexagon/imported/encode_pp.def
+++ b/target/hexagon/imported/encode_pp.def
@@ -409,6 +409,11 @@ DEF_EXT_SPACE(EXTRACTW,   ICLASS_LD" 001 0 000 iiiii 
PP0iiiii 001iiiii")
 DEF_ENC32(Y2_dcfetchbo,   "10010100000sssssPP000iiiiiiiiiii")
 DEF_ENC32(Y4_dcfetch_multi,"10010100000sssssPP001ttttt------")
 DEF_ENC32(Y2_dcfetchbo_nt,"10010100000sssssPP10-iiiiiiiiiii")
+DEF_ENC32(V2_vallocframe_imm,"01100000100-----PP001----iiiiiii")
+DEF_ENC32(V2_vallocframe_reg,"01100000100sssssPP010-----------")
+DEF_ENC32(V2_vdeallocframe_imm,"01101010100-----PP001----iiiiiii")
+DEF_ENC32(V2_vdeallocframe_reg,"01101001010sssssPP010-----------")
+DEF_ENC32(J2_trap2,"0101010011------PP-iiiii---iii--")
 
 
 
diff --git a/target/hexagon/imported/system.idef 
b/target/hexagon/imported/system.idef
index 9c4897a2eee..ff208b1a1f0 100644
--- a/target/hexagon/imported/system.idef
+++ b/target/hexagon/imported/system.idef
@@ -48,6 +48,9 @@ 
Q6INSN(J2_trap1,"trap1(Rx32,#u8)",ATTRIBS(A_COF,A_NOTE_NOPACKET,A_RESTRICT_NOPAC
                fVIRTINSN_SPSWAP(uiV,RxV);
        })
 
+Q6INSN(J2_trap2,"trap2(#u8)",ATTRIBS(A_COF,A_RESTRICT_NOPACKET),
+       "Trap to Operating System", { fTRAP(2,uiV); })
+
 
Q6INSN(J2_pause,"pause(#u8)",ATTRIBS(A_COF,A_NOTE_NOPACKET,A_RESTRICT_NOPACKET),
 "Enter low-power state for #u8 cycles",{fPAUSE(uiV);})
 
@@ -241,6 +244,11 @@ 
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(V2_vallocframe_imm,"vallocframe(#u7:0)",ATTRIBS(A_RESTRICT_NOPACKET),"Allocate
 vector stack frame",{})
+Q6INSN(V2_vallocframe_reg,"vallocframe(Rs32)",ATTRIBS(A_RESTRICT_NOPACKET),"Allocate
 vector stack frame",{})
+Q6INSN(V2_vdeallocframe_imm,"vdeallocframe(#u7:0)",ATTRIBS(A_RESTRICT_NOPACKET),"Deallocate
 vector stack frame",{})
+Q6INSN(V2_vdeallocframe_reg,"vdeallocframe(Rs32)",ATTRIBS(A_RESTRICT_NOPACKET),"Deallocate
 vector stack frame",{})
 
Q6INSN(Y4_dcfetch_multi,"dcfetch_multi(Rs32,Rt32)",ATTRIBS(A_RESTRICT_PREFERSLOT0,A_DCFETCH,A_RESTRICT_NOSLOT1_STORE),"Data
 Cache Prefetch",{fEA_REG(RsV); fDCFETCH_MULTI(EA,fEXTRACTU_BITS(RtV,10,0));})
 
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();})
 
-- 
2.34.1

Reply via email to