Teach the IDEF parser about VSP and vector frame checks. Describe the
vallocframe and vdeallocframe instruction semantics in system.idef, and
move the vector stack overflow check into a shared TCG generator helper.

Signed-off-by: Brian Cain <[email protected]>
---
 target/hexagon/gen_tcg.h                    | 51 ---------------------
 target/hexagon/genptr.h                     |  1 +
 target/hexagon/idef-parser/parser-helpers.h |  1 +
 target/hexagon/genptr.c                     | 21 +++++++++
 target/hexagon/idef-parser/parser-helpers.c | 14 ++++++
 target/hexagon/gen_tcg_funcs.py             |  4 +-
 target/hexagon/idef-parser/idef-parser.lex  |  8 ++++
 target/hexagon/idef-parser/idef-parser.y    |  9 +++-
 target/hexagon/imported/system.idef         |  8 ++--
 9 files changed, 58 insertions(+), 59 deletions(-)

diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h
index 114199aaaac..38d8558c97a 100644
--- a/target/hexagon/gen_tcg.h
+++ b/target/hexagon/gen_tcg.h
@@ -1405,57 +1405,6 @@
         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/genptr.h b/target/hexagon/genptr.h
index 7c0e90e93aa..270375251f8 100644
--- a/target/hexagon/genptr.h
+++ b/target/hexagon/genptr.h
@@ -69,6 +69,7 @@ typedef enum {
 void gen_atomic4(DisasContext *ctx, TCGv dest, TCGv vaddr, TCGv src,
                  HexAtomicOp operation);
 void gen_atomic8(DisasContext *ctx, TCGv_i64 dest, TCGv vaddr, TCGv_i64 src);
+void gen_vframecheck(DisasContext *ctx, TCGv vsp);
 void probe_noshuf_load(TCGv va, int s, int mi);
 void gen_gvec_sabsdiff_var(unsigned vece, TCGv_ptr dbase, uint32_t dofs,
                            TCGv_ptr abase, uint32_t aofs,
diff --git a/target/hexagon/idef-parser/parser-helpers.h 
b/target/hexagon/idef-parser/parser-helpers.h
index d3dfcec5690..0c9ddc0727e 100644
--- a/target/hexagon/idef-parser/parser-helpers.h
+++ b/target/hexagon/idef-parser/parser-helpers.h
@@ -296,6 +296,7 @@ void gen_cancel(Context *c, YYLTYPE *locp);
 void gen_load_cancel(Context *c, YYLTYPE *locp);
 
 void gen_framecheck(Context *c, YYLTYPE *locp, HexValue *addr, HexValue *ea);
+void gen_vframecheck(Context *c, YYLTYPE *locp, HexValue *addr);
 
 void gen_load(Context *c, YYLTYPE *locp, HexValue *size,
               HexSignedness signedness, HexValue *ea, HexValue *dst);
diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index 46ef5bd704d..f264bb9d0a0 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -700,6 +700,27 @@ void gen_atomic8(DisasContext *ctx, TCGv_i64 dest, TCGv 
vaddr, TCGv_i64 src)
                             MO_LE | MO_64 | MO_ALIGN);
 }
 
+void gen_vframecheck(DisasContext *ctx, TCGv vsp)
+{
+    TCGLabel *write_vsp = gen_new_label();
+
+#ifndef CONFIG_USER_ONLY
+    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);
+#endif
+    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);
+}
+
 #ifndef CONFIG_HEXAGON_IDEF_PARSER
 static TCGv gen_slotval(DisasContext *ctx)
 {
diff --git a/target/hexagon/idef-parser/parser-helpers.c 
b/target/hexagon/idef-parser/parser-helpers.c
index 49cc11fddd8..104f935a21e 100644
--- a/target/hexagon/idef-parser/parser-helpers.c
+++ b/target/hexagon/idef-parser/parser-helpers.c
@@ -25,6 +25,7 @@
 #include <string.h>
 #include <unistd.h>
 
+#include "hex_regs.h"
 #include "idef-parser.h"
 #include "parser-helpers.h"
 #include "idef-parser.tab.h"
@@ -1313,6 +1314,11 @@ void gen_write_reg(Context *c, YYLTYPE *locp, HexValue 
*reg, HexValue *value)
     yyassert(c, locp, reg->type == REGISTER, "reg must be a register!");
     value_m = gen_rvalue_truncate(c, locp, &value_m);
     value_m = rvalue_materialize(c, locp, &value_m);
+    if (reg->reg.id == HEX_REG_VSP) {
+        OUT(c, locp, "tcg_gen_mov_tl(hex_gpr[HEX_REG_VSP], ", &value_m,
+            ");\n");
+        return;
+    }
     OUT(c,
         locp,
         "tcg_gen_mov_tl(get_result_gpr(ctx, ", &reg->reg.id, "), ",
@@ -1740,6 +1746,14 @@ void gen_framecheck(Context *c, YYLTYPE *locp, HexValue 
*addr, HexValue *ea)
     OUT(c, locp, "gen_framecheck(ctx, ", &addr_m, ", ", &ea_m, ");\n");
 }
 
+void gen_vframecheck(Context *c, YYLTYPE *locp, HexValue *addr)
+{
+    HexValue addr_m = rvalue_materialize(c, locp, addr);
+
+    addr_m = gen_rvalue_truncate(c, locp, &addr_m);
+    OUT(c, locp, "gen_vframecheck(ctx, ", &addr_m, ");\n");
+}
+
 void gen_load(Context *c, YYLTYPE *locp, HexValue *width,
               HexSignedness signedness, HexValue *ea, HexValue *dst)
 {
diff --git a/target/hexagon/gen_tcg_funcs.py b/target/hexagon/gen_tcg_funcs.py
index bdc3fa0fe04..b09ce7c285f 100755
--- a/target/hexagon/gen_tcg_funcs.py
+++ b/target/hexagon/gen_tcg_funcs.py
@@ -86,9 +86,7 @@ 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) and tag not in {
-            "V2_vallocframe_imm", "V2_vallocframe_reg",
-            "V2_vdeallocframe_imm", "V2_vdeallocframe_reg"}):
+    if hex_common.is_idef_parser_enabled(tag):
         gpr_operands = [
             hex_common.get_register(tag, regtype, regid)
             for regtype, regid in regs
diff --git a/target/hexagon/idef-parser/idef-parser.lex 
b/target/hexagon/idef-parser/idef-parser.lex
index cd5958ec904..c2fc10dccce 100644
--- a/target/hexagon/idef-parser/idef-parser.lex
+++ b/target/hexagon/idef-parser/idef-parser.lex
@@ -161,6 +161,7 @@ STRING_LIT               \"(\\.|[^"\\])*\"
 "fFRAME_SCRAMBLE"        |
 "fFRAME_UNSCRAMBLE"      { return FSCR; }
 "fFRAMECHECK"            { return FCHK; }
+"fVFRAMECHECK"           { return VFCHK; }
 "Constant_extended"      { return CONSTEXT; }
 "fCL1_"{DIGIT}           { return LOCNT; }
 "fbrev"                  { return BREV; }
@@ -329,6 +330,13 @@ STRING_LIT               \"(\\.|[^"\\])*\"
                            yylval->rvalue.bit_width = 32;
                            yylval->rvalue.signedness = UNSIGNED;
                            return REG; }
+"VSP"                    { yylval->rvalue.type = REGISTER;
+                           yylval->rvalue.reg.type = GENERAL_PURPOSE;
+                           yylval->rvalue.reg.id = HEX_REG_VSP;
+                           yylval->rvalue.reg.bit_width = 32;
+                           yylval->rvalue.bit_width = 32;
+                           yylval->rvalue.signedness = UNSIGNED;
+                           return REG; }
 "fREAD_FP()"             |
 "FP"                     { yylval->rvalue.type = REGISTER;
                            yylval->rvalue.reg.type = GENERAL_PURPOSE;
diff --git a/target/hexagon/idef-parser/idef-parser.y 
b/target/hexagon/idef-parser/idef-parser.y
index 3cffafa5b76..b846cf24d01 100644
--- a/target/hexagon/idef-parser/idef-parser.y
+++ b/target/hexagon/idef-parser/idef-parser.y
@@ -51,7 +51,7 @@
 
 %token IN INAME VAR
 %token ABS CROUND ROUND CIRCADD COUNTONES INC DEC ANDA ORA XORA PLUSPLUS ASL
-%token ASR LSR EQ NEQ LTE GTE MIN MAX ANDL FOR ICIRC IF MUN FSCR FCHK SXT
+%token ASR LSR EQ NEQ LTE GTE MIN MAX ANDL FOR ICIRC IF MUN FSCR FCHK VFCHK SXT
 %token ZXT CONSTEXT LOCNT BREV SIGN LOAD STORE PC LPCFG
 %token LOAD_CANCEL STORE_CANCEL CANCEL IDENTITY ROTL INSBITS SETBITS EXTRANGE
 %token CAST4_8U FAIL CARRY_FROM_ADD ADDSAT64 LSBNEW
@@ -398,6 +398,7 @@ assign_statement : lvalue '=' rvalue
                  ;
 
 control_statement : frame_check
+                  | vframe_check
                   | cancel_statement
                   | if_statement
                   | for_statement
@@ -409,6 +410,12 @@ frame_check : FCHK '(' rvalue ',' rvalue ')' ';'
               }
             ;
 
+vframe_check : VFCHK '(' rvalue ',' rvalue ')' ';'
+               {
+                   gen_vframecheck(c, &@1, &$3);
+               }
+             ;
+
 cancel_statement : LOAD_CANCEL
                    {
                        gen_load_cancel(c, &@1);
diff --git a/target/hexagon/imported/system.idef 
b/target/hexagon/imported/system.idef
index ff208b1a1f0..80fa0cd5618 100644
--- a/target/hexagon/imported/system.idef
+++ b/target/hexagon/imported/system.idef
@@ -245,10 +245,10 @@ 
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(V2_vallocframe_imm,"vallocframe(#u7:0)",ATTRIBS(A_RESTRICT_NOPACKET),"Allocate
 vector stack frame",{ fVFRAMECHECK(VSP - (uiV << 11), VSP); })
+Q6INSN(V2_vallocframe_reg,"vallocframe(Rs32)",ATTRIBS(A_RESTRICT_NOPACKET),"Allocate
 vector stack frame",{ fVFRAMECHECK(VSP - (RsV << 11), VSP); })
+Q6INSN(V2_vdeallocframe_imm,"vdeallocframe(#u7:0)",ATTRIBS(A_RESTRICT_NOPACKET),"Deallocate
 vector stack frame",{ VSP = VSP + (uiV << 11); })
+Q6INSN(V2_vdeallocframe_reg,"vdeallocframe(Rs32)",ATTRIBS(A_RESTRICT_NOPACKET),"Deallocate
 vector stack frame",{ VSP = VSP + (RsV << 11); })
 
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