mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-24 02:20:11 +01:00
etnaviv: isa: Add cli assembler
Nothing too fancy. Signed-off-by: Christian Gmeiner <cgmeiner@igalia.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28869>
This commit is contained in:
parent
6db922c0bf
commit
858d42bee9
2 changed files with 134 additions and 0 deletions
127
src/etnaviv/isa/assembler.c
Normal file
127
src/etnaviv/isa/assembler.c
Normal file
|
|
@ -0,0 +1,127 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2024 Igalia S.L.
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "asm.h"
|
||||||
|
#include "isa.h"
|
||||||
|
|
||||||
|
#include "util/u_dynarray.h"
|
||||||
|
|
||||||
|
#include <etnaviv/isa/etnaviv-isa.h>
|
||||||
|
|
||||||
|
struct encoded_instr {
|
||||||
|
uint32_t word[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
pre_instr_cb(void *d, unsigned n, void *instr)
|
||||||
|
{
|
||||||
|
uint32_t *dwords = (uint32_t *)instr;
|
||||||
|
printf("%03d [%08x %08x %08x %08x] ", n, dwords[0], dwords[1], dwords[2], dwords[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
store(const char *filename, void *data, unsigned size)
|
||||||
|
{
|
||||||
|
int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
||||||
|
if (fd == -1) {
|
||||||
|
fprintf(stderr, "Error opening file (%s)", filename);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t bytes_written = write(fd, data, size);
|
||||||
|
if (bytes_written == -1) {
|
||||||
|
fprintf(stderr, "Error writing to file");
|
||||||
|
close(fd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_usage()
|
||||||
|
{
|
||||||
|
printf("Usage: etnaviv-assembler -i FILE -o FILE -s\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
bool show_disasm = false;
|
||||||
|
bool dual_16_mode = false;
|
||||||
|
const char *in = NULL;
|
||||||
|
const char *out = NULL;
|
||||||
|
|
||||||
|
int opt = 0;
|
||||||
|
while ((opt = getopt(argc, argv, "i:o:sd")) != -1) {
|
||||||
|
switch (opt) {
|
||||||
|
case 'i':
|
||||||
|
in = optarg;
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
out = optarg;
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
show_disasm = true;
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
dual_16_mode = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
print_usage();
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!in || !out) {
|
||||||
|
print_usage();
|
||||||
|
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct etna_asm_result *result = isa_parse_file(in, dual_16_mode);
|
||||||
|
|
||||||
|
if (!result->success) {
|
||||||
|
fprintf(stderr, "Failed to parse %s\n%s\n", in, result->error);
|
||||||
|
isa_asm_result_destroy(result);
|
||||||
|
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct util_dynarray bin;
|
||||||
|
util_dynarray_init(&bin, NULL);
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < result->num_instr; i++) {
|
||||||
|
struct encoded_instr encoded;
|
||||||
|
|
||||||
|
isa_assemble_instruction(encoded.word, &result->instr[i]);
|
||||||
|
util_dynarray_append(&bin, struct encoded_instr, encoded);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int num = util_dynarray_num_elements(&bin, struct encoded_instr);
|
||||||
|
unsigned int size = num * sizeof(struct encoded_instr);
|
||||||
|
void *data = util_dynarray_begin(&bin);
|
||||||
|
|
||||||
|
store(out, data, size);
|
||||||
|
|
||||||
|
if (show_disasm) {
|
||||||
|
static struct isa_decode_options options = {
|
||||||
|
.show_errors = true,
|
||||||
|
.branch_labels = true,
|
||||||
|
.pre_instr_cb = pre_instr_cb,
|
||||||
|
};
|
||||||
|
|
||||||
|
etnaviv_isa_disasm(data, size, stdout, &options);
|
||||||
|
}
|
||||||
|
|
||||||
|
util_dynarray_fini(&bin);
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
@ -173,6 +173,13 @@ if with_tools.contains('etnaviv')
|
||||||
link_with: [_libetnaviv_isa_bindings_gen, _libetnaviv_isa_proc_rs],
|
link_with: [_libetnaviv_isa_bindings_gen, _libetnaviv_isa_proc_rs],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
etnaviv_assembler = executable(
|
||||||
|
'etnaviv-assembler',
|
||||||
|
['assembler.c'],
|
||||||
|
gnu_symbol_visibility: 'hidden',
|
||||||
|
dependencies: [ idep_libetnaviv_decode ],
|
||||||
|
link_with: [libetnaviv_encode, libetnaviv_isa_rs],
|
||||||
|
)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
subdir('tests')
|
subdir('tests')
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue