disassemble-sr32.c (1723B)
1 // Copyright 2025, Brian Swetland <swetland@frotz.net> 2 // Licensed under the Apache License, Version 2.0. 3 4 #include <string.h> 5 #include <stdio.h> 6 7 #include "sr32.h" 8 9 static char *append_str(char *buf, const char *s) { 10 while (*s) *buf++ = *s++; 11 return buf; 12 } 13 static char *append_i32(char *buf, int32_t n) { 14 return buf + sprintf(buf, "%d", n); 15 } 16 static char *append_u32(char *buf, int32_t n) { 17 return buf + sprintf(buf, "0x%x", n); 18 } 19 20 static const char* regname[32] = { 21 "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", 22 "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", 23 "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23", 24 "x24", "x25", "x26", "x27", "x28", "x29", "x30", "x31", 25 }; 26 27 typedef struct { 28 uint32_t mask; 29 uint32_t bits; 30 const char* fmt; 31 } sr32ins_t; 32 33 static sr32ins_t instab[] = { 34 #include <instab.h> 35 }; 36 37 void sr32dis(uint32_t pc, uint32_t ins, char *out) { 38 unsigned n = 0; 39 while ((ins & instab[n].mask) != instab[n].bits) n++; 40 const char* fmt = instab[n].fmt; 41 char c; 42 while ((c = *fmt++) != 0) { 43 if (c != '%') { 44 *out++ = c; 45 continue; 46 } 47 switch (*fmt++) { 48 case 'a': out = append_str(out, regname[get_ra(ins)]); break; 49 case 'b': out = append_str(out, regname[get_rb(ins)]); break; 50 case 't': out = append_str(out, regname[get_rt(ins)]); break; 51 case 'i': out = append_i32(out, get_i16(ins)); break; 52 case 'u': out = append_u32(out, get_i16(ins)); break; 53 case 'j': out = append_i32(out, get_i21(ins)); break; 54 case 's': out = append_i32(out, get_rb(ins)); break; 55 case 'J': out = append_u32(out, pc + 4 + get_i21(ins)); break; 56 case 'B': out = append_u32(out, pc + 4 + get_i16(ins)); break; 57 case 'U': out = append_u32(out, get_i16(ins) << 16); break; 58 } 59 } 60 *out = 0; 61 }