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.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
