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: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26771>
This commit is contained in:
Connor Abbott 2023-12-18 17:28:02 -05:00 committed by Marge Bot
parent a5db8e9c1f
commit d860b2eca5
5 changed files with 29 additions and 7 deletions

View file

@ -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);

View file

@ -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)

View file

@ -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");

View file

@ -99,6 +99,7 @@ extern YYSTYPE yylval;
".align" return TOKEN(T_ALIGN);
".jumptbl" return TOKEN(T_JUMPTBL);
".section" return TOKEN(T_SECTION);
"," return ',';
"[" return '[';

View file

@ -175,6 +175,7 @@ label(const char *str)
%token <tok> T_ALIGN
%token <tok> T_JUMPTBL
%token <tok> T_SECTION
%type <num> reg
%type <num> 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; }