xref: /aosp_15_r20/external/mesa3d/src/etnaviv/isa/assembler.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright © 2024 Igalia S.L.
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 <fcntl.h>
7*61046927SAndroid Build Coastguard Worker #include <getopt.h>
8*61046927SAndroid Build Coastguard Worker #include <stdio.h>
9*61046927SAndroid Build Coastguard Worker #include <unistd.h>
10*61046927SAndroid Build Coastguard Worker 
11*61046927SAndroid Build Coastguard Worker #include "asm.h"
12*61046927SAndroid Build Coastguard Worker #include "isa.h"
13*61046927SAndroid Build Coastguard Worker 
14*61046927SAndroid Build Coastguard Worker #include "util/u_dynarray.h"
15*61046927SAndroid Build Coastguard Worker 
16*61046927SAndroid Build Coastguard Worker #include <etnaviv/isa/etnaviv-isa.h>
17*61046927SAndroid Build Coastguard Worker 
18*61046927SAndroid Build Coastguard Worker struct encoded_instr {
19*61046927SAndroid Build Coastguard Worker    uint32_t word[4];
20*61046927SAndroid Build Coastguard Worker };
21*61046927SAndroid Build Coastguard Worker 
22*61046927SAndroid Build Coastguard Worker static void
pre_instr_cb(void * d,unsigned n,void * instr)23*61046927SAndroid Build Coastguard Worker pre_instr_cb(void *d, unsigned n, void *instr)
24*61046927SAndroid Build Coastguard Worker {
25*61046927SAndroid Build Coastguard Worker    uint32_t *dwords = (uint32_t *)instr;
26*61046927SAndroid Build Coastguard Worker    printf("%03d [%08x %08x %08x %08x] ", n, dwords[0], dwords[1], dwords[2], dwords[3]);
27*61046927SAndroid Build Coastguard Worker }
28*61046927SAndroid Build Coastguard Worker 
29*61046927SAndroid Build Coastguard Worker static void
store(const char * filename,void * data,unsigned size)30*61046927SAndroid Build Coastguard Worker store(const char *filename, void *data, unsigned size)
31*61046927SAndroid Build Coastguard Worker {
32*61046927SAndroid Build Coastguard Worker    int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644);
33*61046927SAndroid Build Coastguard Worker    if (fd == -1) {
34*61046927SAndroid Build Coastguard Worker       fprintf(stderr, "Error opening file (%s)", filename);
35*61046927SAndroid Build Coastguard Worker       return;
36*61046927SAndroid Build Coastguard Worker    }
37*61046927SAndroid Build Coastguard Worker 
38*61046927SAndroid Build Coastguard Worker    ssize_t bytes_written = write(fd, data, size);
39*61046927SAndroid Build Coastguard Worker    if (bytes_written == -1) {
40*61046927SAndroid Build Coastguard Worker       fprintf(stderr, "Error writing to file");
41*61046927SAndroid Build Coastguard Worker       close(fd);
42*61046927SAndroid Build Coastguard Worker       return;
43*61046927SAndroid Build Coastguard Worker    }
44*61046927SAndroid Build Coastguard Worker 
45*61046927SAndroid Build Coastguard Worker    close(fd);
46*61046927SAndroid Build Coastguard Worker }
47*61046927SAndroid Build Coastguard Worker 
48*61046927SAndroid Build Coastguard Worker static void
print_usage()49*61046927SAndroid Build Coastguard Worker print_usage()
50*61046927SAndroid Build Coastguard Worker {
51*61046927SAndroid Build Coastguard Worker    printf("Usage: etnaviv-assembler -i FILE -o FILE -s\n");
52*61046927SAndroid Build Coastguard Worker }
53*61046927SAndroid Build Coastguard Worker 
54*61046927SAndroid Build Coastguard Worker int
main(int argc,char * argv[])55*61046927SAndroid Build Coastguard Worker main(int argc, char *argv[])
56*61046927SAndroid Build Coastguard Worker {
57*61046927SAndroid Build Coastguard Worker    bool show_disasm = false;
58*61046927SAndroid Build Coastguard Worker    bool dual_16_mode = false;
59*61046927SAndroid Build Coastguard Worker    const char *in = NULL;
60*61046927SAndroid Build Coastguard Worker    const char *out = NULL;
61*61046927SAndroid Build Coastguard Worker 
62*61046927SAndroid Build Coastguard Worker    int opt = 0;
63*61046927SAndroid Build Coastguard Worker    while ((opt = getopt(argc, argv, "i:o:sd")) != -1) {
64*61046927SAndroid Build Coastguard Worker       switch (opt) {
65*61046927SAndroid Build Coastguard Worker       case 'i':
66*61046927SAndroid Build Coastguard Worker          in = optarg;
67*61046927SAndroid Build Coastguard Worker          break;
68*61046927SAndroid Build Coastguard Worker       case 'o':
69*61046927SAndroid Build Coastguard Worker          out = optarg;
70*61046927SAndroid Build Coastguard Worker          break;
71*61046927SAndroid Build Coastguard Worker       case 's':
72*61046927SAndroid Build Coastguard Worker          show_disasm = true;
73*61046927SAndroid Build Coastguard Worker          break;
74*61046927SAndroid Build Coastguard Worker       case 'd':
75*61046927SAndroid Build Coastguard Worker          dual_16_mode = true;
76*61046927SAndroid Build Coastguard Worker          break;
77*61046927SAndroid Build Coastguard Worker       default:
78*61046927SAndroid Build Coastguard Worker          print_usage();
79*61046927SAndroid Build Coastguard Worker          exit(EXIT_FAILURE);
80*61046927SAndroid Build Coastguard Worker       }
81*61046927SAndroid Build Coastguard Worker    }
82*61046927SAndroid Build Coastguard Worker 
83*61046927SAndroid Build Coastguard Worker    if (!in || !out) {
84*61046927SAndroid Build Coastguard Worker       print_usage();
85*61046927SAndroid Build Coastguard Worker 
86*61046927SAndroid Build Coastguard Worker       return EXIT_FAILURE;
87*61046927SAndroid Build Coastguard Worker    }
88*61046927SAndroid Build Coastguard Worker 
89*61046927SAndroid Build Coastguard Worker    struct etna_asm_result *result = isa_parse_file(in, dual_16_mode);
90*61046927SAndroid Build Coastguard Worker 
91*61046927SAndroid Build Coastguard Worker    if (!result->success) {
92*61046927SAndroid Build Coastguard Worker       fprintf(stderr, "Failed to parse %s\n%s\n", in, result->error);
93*61046927SAndroid Build Coastguard Worker       isa_asm_result_destroy(result);
94*61046927SAndroid Build Coastguard Worker 
95*61046927SAndroid Build Coastguard Worker       return EXIT_FAILURE;
96*61046927SAndroid Build Coastguard Worker    }
97*61046927SAndroid Build Coastguard Worker 
98*61046927SAndroid Build Coastguard Worker    struct util_dynarray bin;
99*61046927SAndroid Build Coastguard Worker    util_dynarray_init(&bin, NULL);
100*61046927SAndroid Build Coastguard Worker 
101*61046927SAndroid Build Coastguard Worker    for (unsigned int i = 0; i < result->num_instr; i++) {
102*61046927SAndroid Build Coastguard Worker       struct encoded_instr encoded;
103*61046927SAndroid Build Coastguard Worker 
104*61046927SAndroid Build Coastguard Worker       isa_assemble_instruction(encoded.word, &result->instr[i]);
105*61046927SAndroid Build Coastguard Worker       util_dynarray_append(&bin, struct encoded_instr, encoded);
106*61046927SAndroid Build Coastguard Worker    }
107*61046927SAndroid Build Coastguard Worker 
108*61046927SAndroid Build Coastguard Worker    unsigned int num = util_dynarray_num_elements(&bin, struct encoded_instr);
109*61046927SAndroid Build Coastguard Worker    unsigned int size = num * sizeof(struct encoded_instr);
110*61046927SAndroid Build Coastguard Worker    void *data = util_dynarray_begin(&bin);
111*61046927SAndroid Build Coastguard Worker 
112*61046927SAndroid Build Coastguard Worker    store(out, data, size);
113*61046927SAndroid Build Coastguard Worker 
114*61046927SAndroid Build Coastguard Worker    if (show_disasm) {
115*61046927SAndroid Build Coastguard Worker       static struct isa_decode_options options = {
116*61046927SAndroid Build Coastguard Worker          .show_errors = true,
117*61046927SAndroid Build Coastguard Worker          .branch_labels = true,
118*61046927SAndroid Build Coastguard Worker          .pre_instr_cb = pre_instr_cb,
119*61046927SAndroid Build Coastguard Worker       };
120*61046927SAndroid Build Coastguard Worker 
121*61046927SAndroid Build Coastguard Worker       etnaviv_isa_disasm(data, size, stdout, &options);
122*61046927SAndroid Build Coastguard Worker    }
123*61046927SAndroid Build Coastguard Worker 
124*61046927SAndroid Build Coastguard Worker    util_dynarray_fini(&bin);
125*61046927SAndroid Build Coastguard Worker 
126*61046927SAndroid Build Coastguard Worker    return EXIT_SUCCESS;
127*61046927SAndroid Build Coastguard Worker }
128