spl

systems programming language
git clone http://frotz.net/git/spl.git
Log | Files | Refs | README | LICENSE

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 }