+++ /dev/null
-/*******************************************************************************
-*
-* File: dasm.c
-* Description: Disassembler for TUMBL binary code.
-* Syntax: mb-dasm [binFilename]
-* if no binFilename specified, defaults to imem.bin in local
-* directory.
-*
-* Author: Huib Lincklaen Arriens
-* Date: August 2010
-*
-* Note: No checks, e.g. on inputfile being a multiple of 4 bytes
-*
-********************************************************************************/
-
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <iostream>
-#include <fstream>
-#include <iomanip>
-
-
-// TUMBL Opcodes to be handled explicitely
-#define OP_CMP 0x05
-
-#define OP_MUL 0x10
-#define OP_BS 0x11
-#define OP_IDIV 0x12
-#define OP_FSL 0x13
-#define OP_FP 0x16
-#define OP_MULI 0x18
-#define OP_BSI 0x19
-#define OP_FSLD 0x1B
-
-#define OP_SEXT 0x24
-#define OP_SPR 0x25
-#define OP_BR 0x26 // for br brd brld bra brad brald brk
-#define OP_BRC 0x27 // for beq bne blt ble bgt bge
-#define OP_IMM 0x2C
-#define OP_RTBD 0x2D
-#define OP_BRI 0x2E // for bri brid brlid brai braid
-#define OP_BRCI 0x2F // for beqi bnei blti blei bgti bgei
-
-
-using namespace std;
-
-static const int MAXMEM = 65536;
-
-static const char *opc_Tbl[] =
- { "add ", "rsub ", "addc ", "rsubc ", "addk ", "x_cmp ", "addkc ", "rsubkc ",
- "addi ", "rsubi ", "addic ", "rsubic ", "addik ", "rsubik ", "addikc ", "rsubikc ",
- "mul ", "bs ", "idiv ", "FSLd ", "-- ", "-- ", "FPI ", "-- ",
- "muli ", "bsi ", "-- ", "FSL ", "-- ", "-- ", "-- ", "-- ",
- "or ", "and ", "xor ", "andn ", "sext ", "SPR ", "br ", "brc ",
- "ori ", "andi ", "xori ", "andni ", "imm ", "rtbd ", "bri ", "brci ",
- "lbu ", "lhu ", "lw ", "-- ", "sb ", "sh ", "sw ", "-- ",
- "lbui ", "lhui ", "lwi ", "-- ", "sbi ", "shi ", "swi ", "-- " };
-
-static const char *brc_Tbl[] =
- { "beq", "bne", "blt", "ble", "bgt", "bge" };
-
-
-char s1str[80] = "";
-char s2str[25] = "";
-const char spc_str[17] = " ";
-unsigned int imem[MAXMEM];
-unsigned int mem_size;
-
-
-void print_Usage (char *cmd_name)
-{
- fprintf( stderr, "Usage: %s [binFilename]\n", cmd_name);
- fprintf( stderr, "where the optional binFilename references a binary (Little Endian) code file.\n");
- fprintf( stderr, "If not specified binFilename tries to read imem.bin in the local directory.\n");
-}
-
-void read_bin (char *binFilename, unsigned int *imem, unsigned int *mem_size)
-{
- ifstream binFile( binFilename, ios::in | ios::binary );
- // the next type should be "char" because the iostream needs it like that ....
- char bin_bytes[MAXMEM]; // 4 Bytes in a Word
- int isize;
- int i, j;
-
- cout << "Reading " << binFilename << " ..." << endl << endl;
- if ( binFile.fail() ) {cout << "Cannot open " << binFilename << " ..." << endl; exit (1);}
- // get length of file:
- binFile.seekg (0, ios::end);
- isize = binFile.tellg();
- if (isize > sizeof(bin_bytes)) {
- cout << binFilename << " larger than " << MAXMEM/1024 << " kBytes ("
- << MAXMEM/4096 << " kWords) ..." << endl << endl;
- exit (1);
- }
- *mem_size = isize/4;
- binFile.seekg (0, ios::beg);
- // read data as a block:
- binFile.read (bin_bytes, isize);
- if ( binFile.fail() ) {cout << "Read error ..." << endl; exit (2);}
- binFile.close();
- for (i = 0, j = 0; i < isize; i += 4, j++ ) {
- // remember iostream only read signed chars ...
- imem[j] = ((unsigned char)bin_bytes[i] << 24) +
- ((unsigned char)bin_bytes[i+1] << 16) +
- ((unsigned char)bin_bytes[i+2] << 8) +
- (unsigned char)bin_bytes[i+3];
- }
-}
-
-void disasm (unsigned int pci)
-{
- unsigned int pcb, ins;
- unsigned int opc;
- unsigned int rd, ra, rb, imm;
- int s_imm;
- unsigned int s1len;
- bool a, l, d, b;
- bool xpand, valid_code;
-
- pcb = 4*pci;
- ins = imem[pci];
- // decode the current instruction
- opc = (ins >> 26) & 0x3F;
- ra = (ins >> 16) & 0x1F;
- rd = (ins >> 21) & 0x1F;
- if (!(opc & 0x08)) {
- rb = (ins >> 11) & 0x1F;
- imm = ins & 0x07FF; // not really imm!!
- sprintf (s2str, "r%d, r%d, r%d", rd, ra, rb);
- }
- else {
- imm = ins & 0xFFFF;
- // 32 bit extension of a 16 bit or an 8 bit number
- s_imm = imm & 0x8000 ? 0xffff0000 | imm : imm;
- sprintf (s2str, "r%d, r%d, 0x%0x", rd, ra, imm);
- }
-
- if (ins == 0)
- sprintf (s1str, "nop");
- else {
- xpand = 1;
- switch (opc)
- {
- case OP_BR: // BR / BRA / BRD / BRAD / BRLD / BRALD
- if ((ra & 0x1F) == 0x0C) // BRK
- {
- printf ("BRK"); //// ??????
- }
- l = ra & 0x04;
- a = ra & 0x08;
- d = ra & 0x10;
- b = (ra & 0x1F) == 0x0C;
- if (b) sprintf (s1str, "brk r%d, r%d", rd, rb);
- else
- if (!l) {
- s1len = sprintf (s1str, "br%s%s", a ? "a" : "", d ? "d" : "");
- sprintf (s1str, "%s r%d", strncat(s1str," ",6-s1len), rb);
- } else {
- s1len = sprintf (s1str, "br%sl%s", a ? "a" : "", d ? "d" : "");
- sprintf (s1str, "%s r%d, r%d", strncat(s1str," ",6-s1len), rd, rb);
- }
- break;
- case OP_BRC:
- if ((rd & 0xf) <= 0x5)
- sprintf (s1str, "%s%s r%d, 0x%x", brc_Tbl[rd & 0xf], rd & 0x10 ? "d" : " ", ra, rb);
- else
- sprintf (s1str, "brc (opcode 0x27) has some errors, please check\n");
- break;
- case OP_BRI: // BRI / BRAI / BRID / BRAID / BRLID / BRAILD
- if ((ra & 0x1F) == 0x0C) // BRK
- printf ("BRK"); //// ??????
- l = ra & 0x04;
- a = ra & 0x08;
- d = ra & 0x10;
- b = (ra & 0x1F) == 0x0C;
- if (b) sprintf (s1str, "brki r%d, 0x%x", rd, imm);
- else {
- if (!l) {
- s1len = sprintf (s1str, "bri%s%s", a ? "a" : "", d ? "d" : "" );
- s1len = sprintf (s1str, "%s %d", strncat(s1str," ",6-s1len), s_imm);
- } else {
- s1len = sprintf (s1str, "bri%sl%s", a ? "a" : "", d ? "d" : "");
- s1len = sprintf (s1str, "%s r%d, %d", strncat(s1str," ",6-s1len), rd, s_imm);
- }
- if (a)
- sprintf (s1str, "%s// 0x%x", strncat(s1str,spc_str,25-s1len), imm);
- else
- sprintf (s1str, "%s// 0x%x", strncat(s1str,spc_str,25-s1len), pcb + s_imm);
- }
- break;
- case OP_BRCI:
- if ((rd & 0xf) <= 0x5) {
- s1len = sprintf (s1str, "%si%s r%d, %d", brc_Tbl[rd & 0xf], rd & 0x10 ? "d" : " ", ra, s_imm);
- sprintf (s1str, "%s// 0x%x", strncat(s1str,spc_str,25-s1len), pcb + s_imm);
- } else
- sprintf (s1str, "brci (opcode 0x2f) has some errors, please check\n");
- break;
- case OP_BSI:
- sprintf (s2str, "r%d, r%d, 0x%0x", rd, ra, imm & 0x1F);
- // !! no break
- case OP_BS:
- if (imm & 0x400) // left shift
- s1len = sprintf (s1str, "bsll%s %s", opc & 0x08 ? "i" : " ", s2str);
- else
- s1len = sprintf (s1str, "bsr%s%s %s",
- imm & 0x200 ? "a" : "l", opc & 0x08 ? "i" : " ", s2str);
- break;
- case OP_CMP: // or RSUBK
- if (imm & 1)
- sprintf (s1str, "cmp%s %s", imm & 2 ? "u" : " ", s2str);
- else
- sprintf (s1str, "rsubk %s", s2str);
- break;
- case OP_FP:
- sprintf (s1str, "Floating Point Instruction NOT IMPLEMENTED IN TUMBL");
- break;
- case OP_FSL:
- case OP_FSLD:
- sprintf (s1str, "FSL Instruction NOT IMPLEMENTED IN TUMBL");
- break;
- case OP_IDIV:
- s1len = sprintf (s1str, "idiv%s %s", imm & 0x02 ? "u" : " ", s2str);
- sprintf (s1str, "%s NOT IMPLEMENTED IN TUMBL", strncat(s1str,spc_str,25-s1len));
- break;
- case OP_IMM:
- sprintf (s1str, "imm 0x%04x // %d", imm, s_imm);
- break;
- case OP_MUL:
- case OP_MULI:
- s1len = sprintf (s1str, "%s%s", opc_Tbl[opc], s2str);
- break;
- case OP_RTBD:
- valid_code = 1;
- switch(rd) {
- case 0x12: sprintf (s2str, "rtbd"); break; // RTBD
- case 0x11: sprintf (s2str, "rtid"); break; // RTID
- case 0x14: sprintf (s2str, "rted"); break; // RTED
- case 0x10: sprintf (s2str, "rtsd"); break; // RTSD
- default:
- sprintf (s1str, "Illegal subopcode in OP_RTBD");
- valid_code = 0;
- }
- if (valid_code)
- sprintf (s1str, "%s r%d, 0x%x", s2str, ra, imm);
- break;
- case OP_SEXT:
- valid_code = 1;
- switch (imm) {
- case 0x61: sprintf (s2str, "sext16"); break; // SEXT16
- case 0x60: sprintf (s2str, "sext8 "); break; // SEXT8
- case 0x01: sprintf (s2str, "sra "); break; // SRA
- case 0x21: sprintf (s2str, "src "); break; // SRC
- case 0x41: sprintf (s2str, "srl "); break; // SRL
- default :
- sprintf (s1str, "OP_SEXT has some errors, please check" );
- valid_code = 0;
- }
- if (valid_code)
- sprintf (s1str, "%s r%d, r%d", s2str, rd, ra);
- break;
- case OP_SPR:
- sprintf (s1str, "SP-Reg Instruction NOT IMPLEMENTED IN TUMBL");
- break;
- default:
- xpand = 0;
- } // switch (opc)
-
- if (!xpand) {
- if (strncmp(opc_Tbl[opc],"--",2))
- sprintf (s1str, "%s%s", opc_Tbl[opc], s2str);
- else
- sprintf (s1str, "Unknown instruction / possibly data ?");
- }
- }
- printf ("%6x: %08x %s\n", pcb, ins, s1str);
-}
-
-
-int main(int argc, char *argv[])
-{
- char binFilename[132];
-
- // note: strncmp == 0 if the parts of the strings are equal
- if ((argc > 2) || ((argc == 2) && !strncmp(argv[1],"-",1))) {
- print_Usage( argv[0]);
- return (1);
- }
-
- if (argc == 2)
- sprintf( binFilename, argv[1]);
- else
- sprintf( binFilename, "imem.bin");
- read_bin (binFilename, imem, &mem_size);
- for (int pci = 0; pci < mem_size; pci++)
- disasm (pci);
-}
-