compiler

Unnamed Compiled Systems Language Project
git clone http://frotz.net/git/compiler.git
Log | Files | Refs

risc5dis.c (2128B)


      1 // Copyright 2020, 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 "risc5.h"
      8 
      9 static char *append_str(char *buf, const char *s) {
     10 	while (*s) *buf++ = *s++;
     11 	return buf;
     12 }
     13 
     14 static char *append_i32(char *buf, int32_t n) {
     15 	return buf + sprintf(buf, "%d", n);
     16 }
     17 
     18 static char *append_u32(char *buf, int32_t n) {
     19 	return buf + sprintf(buf, "0x%x", n);
     20 }
     21 
     22 static const char* regname[16] = {
     23 	"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
     24 	"r8", "r9", "r10", "r11", "fp", "sb", "sp", "lr",
     25 };
     26 #define R(n) regname[(n) & 15]
     27 
     28 static const char* opname[16] = {
     29 	"mov", "lsl", "asr", "ror", "and", "ann", "ior", "xor",
     30 	"add", "sub", "mul", "div", "fad", "fsb", "fml", "fdv",
     31 };
     32 #define OP(n) opname[(n) & 15]
     33 
     34 static const char* ccname[16] = {
     35 	"mi", "eq", "cs", "vs", "ls", "lt", "le", "",
     36 	"pl", "ne", "cc", "vc", "hi", "ge", "gt", "nv",
     37 };
     38 #define CC(n) ccname[(n) & 15]
     39 
     40 typedef struct {
     41 	uint32_t mask;
     42 	uint32_t bits;
     43 	const char* fmt;
     44 } ins_t;
     45 
     46 static ins_t instab[] = {
     47 #include "../out/risc5ins.h"
     48 };
     49 
     50 void risc5dis(uint32_t pc, uint32_t ins, char *out) {
     51 	unsigned n = 0;
     52 	while ((ins & instab[n].mask) != instab[n].bits) n++;
     53 	const char* fmt = instab[n].fmt;
     54 	char x;
     55 
     56 	unsigned mo = ins & 0xFFFFF;
     57 	unsigned bo = ins & 0xFFFFFF;
     58 	if (mo & 0x80000) mo |= 0xFFF00000;
     59 	if (bo & 0x800000) bo |= 0xFF000000;
     60 
     61 	while ((x = *fmt++) != 0) {
     62 		if (x != '%') {
     63 			*out++ = x;
     64 			continue;
     65 		}
     66 		switch (*fmt++) {
     67 		case 'C': out = append_str(out, CC((ins >> 24) & 15)); break;
     68 		case 'a': out = append_str(out, R((ins >> 24) & 15)); break;
     69 		case 'b': out = append_str(out, R((ins >> 20) & 15)); break;
     70 		case 'o': out = append_str(out, OP((ins >> 16) & 15)); break;
     71 		case 'c': out = append_str(out, R(ins & 15)); break;
     72 		case 'n': out = append_i32(out, ins & 0xFFFF); break;
     73 		case 's': out = append_u32(out, (ins & 0xFFFF) | 0xFFFF0000); break;
     74 		case 'N': out = append_u32(out, (ins & 0xFFFF) << 16); break;
     75 		case 'm': out = append_i32(out, mo); break;
     76 		case 'B': out = append_u32(out, pc + 4 + (bo << 2)); break;
     77 		}
     78 	}
     79 	*out = 0;
     80 }