xref: /aosp_15_r20/external/mesa3d/src/intel/compiler/brw_asm.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright © 2018 Intel Corporation
3*61046927SAndroid Build Coastguard Worker  * SPDX-License-Identifier: MIT
4*61046927SAndroid Build Coastguard Worker  */
5*61046927SAndroid Build Coastguard Worker 
6*61046927SAndroid Build Coastguard Worker #include "brw_asm.h"
7*61046927SAndroid Build Coastguard Worker #include "brw_asm_internal.h"
8*61046927SAndroid Build Coastguard Worker #include "brw_disasm_info.h"
9*61046927SAndroid Build Coastguard Worker 
10*61046927SAndroid Build Coastguard Worker /* TODO: Check if we can use bison/flex without globals. */
11*61046927SAndroid Build Coastguard Worker 
12*61046927SAndroid Build Coastguard Worker extern FILE *yyin;
13*61046927SAndroid Build Coastguard Worker struct list_head instr_labels;
14*61046927SAndroid Build Coastguard Worker struct list_head target_labels;
15*61046927SAndroid Build Coastguard Worker 
16*61046927SAndroid Build Coastguard Worker struct brw_codegen *p;
17*61046927SAndroid Build Coastguard Worker const char *input_filename;
18*61046927SAndroid Build Coastguard Worker int errors;
19*61046927SAndroid Build Coastguard Worker 
20*61046927SAndroid Build Coastguard Worker static bool
i965_postprocess_labels()21*61046927SAndroid Build Coastguard Worker i965_postprocess_labels()
22*61046927SAndroid Build Coastguard Worker {
23*61046927SAndroid Build Coastguard Worker    void *store = p->store;
24*61046927SAndroid Build Coastguard Worker 
25*61046927SAndroid Build Coastguard Worker    struct target_label *tlabel;
26*61046927SAndroid Build Coastguard Worker    struct instr_label *ilabel, *s;
27*61046927SAndroid Build Coastguard Worker 
28*61046927SAndroid Build Coastguard Worker    const unsigned to_bytes_scale = brw_jump_scale(p->devinfo);
29*61046927SAndroid Build Coastguard Worker 
30*61046927SAndroid Build Coastguard Worker    LIST_FOR_EACH_ENTRY(tlabel, &target_labels, link) {
31*61046927SAndroid Build Coastguard Worker       LIST_FOR_EACH_ENTRY_SAFE(ilabel, s, &instr_labels, link) {
32*61046927SAndroid Build Coastguard Worker          if (!strcmp(tlabel->name, ilabel->name)) {
33*61046927SAndroid Build Coastguard Worker             brw_inst *inst = store + ilabel->offset;
34*61046927SAndroid Build Coastguard Worker 
35*61046927SAndroid Build Coastguard Worker             int relative_offset = (tlabel->offset - ilabel->offset) / sizeof(brw_inst);
36*61046927SAndroid Build Coastguard Worker             relative_offset *= to_bytes_scale;
37*61046927SAndroid Build Coastguard Worker 
38*61046927SAndroid Build Coastguard Worker             unsigned opcode = brw_inst_opcode(p->isa, inst);
39*61046927SAndroid Build Coastguard Worker 
40*61046927SAndroid Build Coastguard Worker             if (ilabel->type == INSTR_LABEL_JIP) {
41*61046927SAndroid Build Coastguard Worker                switch (opcode) {
42*61046927SAndroid Build Coastguard Worker                case BRW_OPCODE_IF:
43*61046927SAndroid Build Coastguard Worker                case BRW_OPCODE_ELSE:
44*61046927SAndroid Build Coastguard Worker                case BRW_OPCODE_ENDIF:
45*61046927SAndroid Build Coastguard Worker                case BRW_OPCODE_WHILE:
46*61046927SAndroid Build Coastguard Worker                   brw_inst_set_jip(p->devinfo, inst, relative_offset);
47*61046927SAndroid Build Coastguard Worker                   break;
48*61046927SAndroid Build Coastguard Worker                case BRW_OPCODE_BREAK:
49*61046927SAndroid Build Coastguard Worker                case BRW_OPCODE_HALT:
50*61046927SAndroid Build Coastguard Worker                case BRW_OPCODE_CONTINUE:
51*61046927SAndroid Build Coastguard Worker                   brw_inst_set_jip(p->devinfo, inst, relative_offset);
52*61046927SAndroid Build Coastguard Worker                   break;
53*61046927SAndroid Build Coastguard Worker                default:
54*61046927SAndroid Build Coastguard Worker                   fprintf(stderr, "Unknown opcode %d with JIP label\n", opcode);
55*61046927SAndroid Build Coastguard Worker                   return false;
56*61046927SAndroid Build Coastguard Worker                }
57*61046927SAndroid Build Coastguard Worker             } else {
58*61046927SAndroid Build Coastguard Worker                switch (opcode) {
59*61046927SAndroid Build Coastguard Worker                case BRW_OPCODE_IF:
60*61046927SAndroid Build Coastguard Worker                case BRW_OPCODE_ELSE:
61*61046927SAndroid Build Coastguard Worker                   brw_inst_set_uip(p->devinfo, inst, relative_offset);
62*61046927SAndroid Build Coastguard Worker                   break;
63*61046927SAndroid Build Coastguard Worker                case BRW_OPCODE_WHILE:
64*61046927SAndroid Build Coastguard Worker                case BRW_OPCODE_ENDIF:
65*61046927SAndroid Build Coastguard Worker                   fprintf(stderr, "WHILE/ENDIF cannot have UIP offset\n");
66*61046927SAndroid Build Coastguard Worker                   return false;
67*61046927SAndroid Build Coastguard Worker                case BRW_OPCODE_BREAK:
68*61046927SAndroid Build Coastguard Worker                case BRW_OPCODE_CONTINUE:
69*61046927SAndroid Build Coastguard Worker                case BRW_OPCODE_HALT:
70*61046927SAndroid Build Coastguard Worker                   brw_inst_set_uip(p->devinfo, inst, relative_offset);
71*61046927SAndroid Build Coastguard Worker                   break;
72*61046927SAndroid Build Coastguard Worker                default:
73*61046927SAndroid Build Coastguard Worker                   fprintf(stderr, "Unknown opcode %d with UIP label\n", opcode);
74*61046927SAndroid Build Coastguard Worker                   return false;
75*61046927SAndroid Build Coastguard Worker                }
76*61046927SAndroid Build Coastguard Worker             }
77*61046927SAndroid Build Coastguard Worker 
78*61046927SAndroid Build Coastguard Worker             list_del(&ilabel->link);
79*61046927SAndroid Build Coastguard Worker          }
80*61046927SAndroid Build Coastguard Worker       }
81*61046927SAndroid Build Coastguard Worker    }
82*61046927SAndroid Build Coastguard Worker 
83*61046927SAndroid Build Coastguard Worker    LIST_FOR_EACH_ENTRY(ilabel, &instr_labels, link) {
84*61046927SAndroid Build Coastguard Worker       fprintf(stderr, "Unknown label '%s'\n", ilabel->name);
85*61046927SAndroid Build Coastguard Worker    }
86*61046927SAndroid Build Coastguard Worker 
87*61046927SAndroid Build Coastguard Worker    return list_is_empty(&instr_labels);
88*61046927SAndroid Build Coastguard Worker }
89*61046927SAndroid Build Coastguard Worker 
90*61046927SAndroid Build Coastguard Worker /* TODO: Would be nice to make this operate on string instead on a FILE. */
91*61046927SAndroid Build Coastguard Worker 
92*61046927SAndroid Build Coastguard Worker brw_assemble_result
brw_assemble(void * mem_ctx,const struct intel_device_info * devinfo,FILE * f,const char * filename,brw_assemble_flags flags)93*61046927SAndroid Build Coastguard Worker brw_assemble(void *mem_ctx, const struct intel_device_info *devinfo,
94*61046927SAndroid Build Coastguard Worker              FILE *f, const char *filename, brw_assemble_flags flags)
95*61046927SAndroid Build Coastguard Worker {
96*61046927SAndroid Build Coastguard Worker    brw_assemble_result result = {0};
97*61046927SAndroid Build Coastguard Worker 
98*61046927SAndroid Build Coastguard Worker    list_inithead(&instr_labels);
99*61046927SAndroid Build Coastguard Worker    list_inithead(&target_labels);
100*61046927SAndroid Build Coastguard Worker 
101*61046927SAndroid Build Coastguard Worker    struct brw_isa_info isa;
102*61046927SAndroid Build Coastguard Worker    brw_init_isa_info(&isa, devinfo);
103*61046927SAndroid Build Coastguard Worker 
104*61046927SAndroid Build Coastguard Worker    p = rzalloc(mem_ctx, struct brw_codegen);
105*61046927SAndroid Build Coastguard Worker    brw_init_codegen(&isa, p, p);
106*61046927SAndroid Build Coastguard Worker 
107*61046927SAndroid Build Coastguard Worker    yyin = f;
108*61046927SAndroid Build Coastguard Worker    input_filename = filename;
109*61046927SAndroid Build Coastguard Worker 
110*61046927SAndroid Build Coastguard Worker    int err = yyparse();
111*61046927SAndroid Build Coastguard Worker    if (err || errors)
112*61046927SAndroid Build Coastguard Worker       goto end;
113*61046927SAndroid Build Coastguard Worker 
114*61046927SAndroid Build Coastguard Worker    if (!i965_postprocess_labels())
115*61046927SAndroid Build Coastguard Worker       goto end;
116*61046927SAndroid Build Coastguard Worker 
117*61046927SAndroid Build Coastguard Worker    struct disasm_info *disasm_info = disasm_initialize(p->isa, NULL);
118*61046927SAndroid Build Coastguard Worker    if (!disasm_info) {
119*61046927SAndroid Build Coastguard Worker       ralloc_free(disasm_info);
120*61046927SAndroid Build Coastguard Worker       fprintf(stderr, "Unable to initialize disasm_info struct instance\n");
121*61046927SAndroid Build Coastguard Worker       goto end;
122*61046927SAndroid Build Coastguard Worker    }
123*61046927SAndroid Build Coastguard Worker 
124*61046927SAndroid Build Coastguard Worker    if (!brw_validate_instructions(p->isa, p->store, 0,
125*61046927SAndroid Build Coastguard Worker                                   p->next_insn_offset, disasm_info)) {
126*61046927SAndroid Build Coastguard Worker       ralloc_free(disasm_info);
127*61046927SAndroid Build Coastguard Worker       fprintf(stderr, "Invalid instructions\n");
128*61046927SAndroid Build Coastguard Worker       goto end;
129*61046927SAndroid Build Coastguard Worker    }
130*61046927SAndroid Build Coastguard Worker 
131*61046927SAndroid Build Coastguard Worker    result.bin = p->store;
132*61046927SAndroid Build Coastguard Worker    result.bin_size = p->next_insn_offset;
133*61046927SAndroid Build Coastguard Worker    result.inst_count = p->next_insn_offset / 16;
134*61046927SAndroid Build Coastguard Worker 
135*61046927SAndroid Build Coastguard Worker    if ((flags & BRW_ASSEMBLE_COMPACT) != 0) {
136*61046927SAndroid Build Coastguard Worker       brw_compact_instructions(p, 0, disasm_info);
137*61046927SAndroid Build Coastguard Worker 
138*61046927SAndroid Build Coastguard Worker       /* Adjust bin size to account for compacted instructions. */
139*61046927SAndroid Build Coastguard Worker       int compacted = 0;
140*61046927SAndroid Build Coastguard Worker       for (int i = 0; i < result.inst_count; i++) {
141*61046927SAndroid Build Coastguard Worker          const brw_inst *inst = result.bin + i;
142*61046927SAndroid Build Coastguard Worker          if (brw_inst_cmpt_control(devinfo, inst))
143*61046927SAndroid Build Coastguard Worker             compacted++;
144*61046927SAndroid Build Coastguard Worker       }
145*61046927SAndroid Build Coastguard Worker       result.bin_size -= compacted * 8;
146*61046927SAndroid Build Coastguard Worker    }
147*61046927SAndroid Build Coastguard Worker 
148*61046927SAndroid Build Coastguard Worker    ralloc_free(disasm_info);
149*61046927SAndroid Build Coastguard Worker 
150*61046927SAndroid Build Coastguard Worker end:
151*61046927SAndroid Build Coastguard Worker    /* Reset internal state. */
152*61046927SAndroid Build Coastguard Worker    yyin = NULL;
153*61046927SAndroid Build Coastguard Worker    input_filename = NULL;
154*61046927SAndroid Build Coastguard Worker    p = NULL;
155*61046927SAndroid Build Coastguard Worker    list_inithead(&instr_labels);
156*61046927SAndroid Build Coastguard Worker    list_inithead(&target_labels);
157*61046927SAndroid Build Coastguard Worker 
158*61046927SAndroid Build Coastguard Worker    return result;
159*61046927SAndroid Build Coastguard Worker }
160*61046927SAndroid Build Coastguard Worker 
161