From d860b2eca52cea968f09570649849cbff503e149 Mon Sep 17 00:00:00 2001 From: Connor Abbott Date: Mon, 18 Dec 2023 17:28:02 -0500 Subject: [PATCH] freedreno/afuc: Add support for multiple sections when assembling Sections have names that are currently unused but we will need to use them on a750 for relocations. Part-of: --- src/freedreno/afuc/asm.c | 30 +++++++++++++++++++++++------- src/freedreno/afuc/asm.h | 1 + src/freedreno/afuc/disasm.c | 2 ++ src/freedreno/afuc/lexer.l | 1 + src/freedreno/afuc/parser.y | 2 ++ 5 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/freedreno/afuc/asm.c b/src/freedreno/afuc/asm.c index 92bac423846..8895715470e 100644 --- a/src/freedreno/afuc/asm.c +++ b/src/freedreno/afuc/asm.c @@ -93,11 +93,14 @@ static unsigned instr_offset; static struct asm_label labels[0x512]; static unsigned num_labels; +static int outfd; + struct afuc_instr * next_instr(afuc_opc opc) { struct afuc_instr *ai = &instructions[num_instructions++]; assert(num_instructions < ARRAY_SIZE(instructions)); + memset(ai, 0, sizeof(*ai)); instr_offset++; ai->opc = opc; return ai; @@ -181,12 +184,6 @@ emit_instructions(int outfd) .gen = gpuver, }; - /* there is an extra 0x00000000 which kernel strips off.. we could - * perhaps use it for versioning. - */ - i = 0; - write(outfd, &i, 4); - /* Expand some meta opcodes, and resolve branch targets */ for (i = 0; i < num_instructions; i++) { struct afuc_instr *ai = &instructions[i]; @@ -247,6 +244,19 @@ emit_instructions(int outfd) } } +void next_section(void) +{ + /* Sections must be aligned to 32 bytes */ + align_instr(32); + + emit_instructions(outfd); + + num_instructions = 0; + instr_offset = 0; + num_labels = 0; +} + + unsigned parse_control_reg(const char *name) { @@ -275,7 +285,7 @@ main(int argc, char **argv) { FILE *in; char *file, *outfile; - int c, ret, outfd; + int c, ret; /* Argument parsing: */ while ((c = getopt(argc, argv, "g:")) != -1) { @@ -326,6 +336,12 @@ main(int argc, char **argv) usage(); } + /* there is an extra 0x00000000 which kernel strips off.. we could + * perhaps use it for versioning. + */ + uint32_t zero = 0; + write(outfd, &zero, 4); + ret = yyparse(); if (ret) { fprintf(stderr, "parse failed: %d\n", ret); diff --git a/src/freedreno/afuc/asm.h b/src/freedreno/afuc/asm.h index d7d1d9a3b30..d97ca0d4b5a 100644 --- a/src/freedreno/afuc/asm.h +++ b/src/freedreno/afuc/asm.h @@ -39,6 +39,7 @@ struct afuc_instr *next_instr(afuc_opc opc); void decl_label(const char *str); void decl_jumptbl(void); void align_instr(unsigned alignment); +void next_section(void); static inline uint32_t parse_reg(const char *str) diff --git a/src/freedreno/afuc/disasm.c b/src/freedreno/afuc/disasm.c index 799d4cad438..e200569a3da 100644 --- a/src/freedreno/afuc/disasm.c +++ b/src/freedreno/afuc/disasm.c @@ -353,6 +353,7 @@ disasm(struct emu *emu) } if (bv_offset) { + printf("\n.section BV\n"); printf(";\n"); printf("; BV microcode:\n"); printf(";\n"); @@ -390,6 +391,7 @@ disasm(struct emu *emu) } if (lpac_offset) { + printf("\n.section LPAC\n"); printf(";\n"); printf("; LPAC microcode:\n"); printf(";\n"); diff --git a/src/freedreno/afuc/lexer.l b/src/freedreno/afuc/lexer.l index 6856443aa0e..25be4590f95 100644 --- a/src/freedreno/afuc/lexer.l +++ b/src/freedreno/afuc/lexer.l @@ -99,6 +99,7 @@ extern YYSTYPE yylval; ".align" return TOKEN(T_ALIGN); ".jumptbl" return TOKEN(T_JUMPTBL); +".section" return TOKEN(T_SECTION); "," return ','; "[" return '['; diff --git a/src/freedreno/afuc/parser.y b/src/freedreno/afuc/parser.y index 18c7b3a3e16..0e3f7d73e41 100644 --- a/src/freedreno/afuc/parser.y +++ b/src/freedreno/afuc/parser.y @@ -175,6 +175,7 @@ label(const char *str) %token T_ALIGN %token T_JUMPTBL +%token T_SECTION %type reg %type immediate @@ -197,6 +198,7 @@ instr_or_label: instr_r | T_IDENTIFIER ':' { decl_label($1); } | T_ALIGN immediate { align_instr($2); } | T_JUMPTBL { decl_jumptbl(); } +| T_SECTION T_IDENTIFIER { next_section(); } xmov: T_XMOV { $$ = $1; } | { $$ = 0; }