1 /*******************************************************************************
4 * Description: Disassembler for TUMBL binary code.
5 * Syntax: mb-dasm [binFilename]
6 * if no binFilename specified, defaults to imem.bin in local
9 * Author: Huib Lincklaen Arriens
12 * Note: No checks, e.g. on inputfile being a multiple of 4 bytes
14 ********************************************************************************/
25 // TUMBL Opcodes to be handled explicitely
39 #define OP_BR 0x26 // for br brd brld bra brad brald brk
40 #define OP_BRC 0x27 // for beq bne blt ble bgt bge
43 #define OP_BRI 0x2E // for bri brid brlid brai braid
44 #define OP_BRCI 0x2F // for beqi bnei blti blei bgti bgei
49 static const int MAXMEM = 65536;
51 static const char *opc_Tbl[] =
52 { "add ", "rsub ", "addc ", "rsubc ", "addk ", "x_cmp ", "addkc ", "rsubkc ",
53 "addi ", "rsubi ", "addic ", "rsubic ", "addik ", "rsubik ", "addikc ", "rsubikc ",
54 "mul ", "bs ", "idiv ", "FSLd ", "-- ", "-- ", "FPI ", "-- ",
55 "muli ", "bsi ", "-- ", "FSL ", "-- ", "-- ", "-- ", "-- ",
56 "or ", "and ", "xor ", "andn ", "sext ", "SPR ", "br ", "brc ",
57 "ori ", "andi ", "xori ", "andni ", "imm ", "rtbd ", "bri ", "brci ",
58 "lbu ", "lhu ", "lw ", "-- ", "sb ", "sh ", "sw ", "-- ",
59 "lbui ", "lhui ", "lwi ", "-- ", "sbi ", "shi ", "swi ", "-- " };
61 static const char *brc_Tbl[] =
62 { "beq", "bne", "blt", "ble", "bgt", "bge" };
67 const char spc_str[17] = " ";
68 unsigned int imem[MAXMEM];
69 unsigned int mem_size;
72 void print_Usage (char *cmd_name)
74 fprintf( stderr, "Usage: %s [binFilename]\n", cmd_name);
75 fprintf( stderr, "where the optional binFilename references a binary (Little Endian) code file.\n");
76 fprintf( stderr, "If not specified binFilename tries to read imem.bin in the local directory.\n");
79 void read_bin (char *binFilename, unsigned int *imem, unsigned int *mem_size)
81 ifstream binFile( binFilename, ios::in | ios::binary );
82 // the next type should be "char" because the iostream needs it like that ....
83 char bin_bytes[MAXMEM]; // 4 Bytes in a Word
87 cout << "Reading " << binFilename << " ..." << endl << endl;
88 if ( binFile.fail() ) {cout << "Cannot open " << binFilename << " ..." << endl; exit (1);}
89 // get length of file:
90 binFile.seekg (0, ios::end);
91 isize = binFile.tellg();
92 if (isize > sizeof(bin_bytes)) {
93 cout << binFilename << " larger than " << MAXMEM/1024 << " kBytes ("
94 << MAXMEM/4096 << " kWords) ..." << endl << endl;
98 binFile.seekg (0, ios::beg);
99 // read data as a block:
100 binFile.read (bin_bytes, isize);
101 if ( binFile.fail() ) {cout << "Read error ..." << endl; exit (2);}
103 for (i = 0, j = 0; i < isize; i += 4, j++ ) {
104 // remember iostream only read signed chars ...
105 imem[j] = ((unsigned char)bin_bytes[i] << 24) +
106 ((unsigned char)bin_bytes[i+1] << 16) +
107 ((unsigned char)bin_bytes[i+2] << 8) +
108 (unsigned char)bin_bytes[i+3];
112 void disasm (unsigned int pci)
114 unsigned int pcb, ins;
116 unsigned int rd, ra, rb, imm;
120 bool xpand, valid_code;
124 // decode the current instruction
125 opc = (ins >> 26) & 0x3F;
126 ra = (ins >> 16) & 0x1F;
127 rd = (ins >> 21) & 0x1F;
129 rb = (ins >> 11) & 0x1F;
130 imm = ins & 0x07FF; // not really imm!!
131 sprintf (s2str, "r%d, r%d, r%d", rd, ra, rb);
135 // 32 bit extension of a 16 bit or an 8 bit number
136 s_imm = imm & 0x8000 ? 0xffff0000 | imm : imm;
137 sprintf (s2str, "r%d, r%d, 0x%0x", rd, ra, imm);
141 sprintf (s1str, "nop");
146 case OP_BR: // BR / BRA / BRD / BRAD / BRLD / BRALD
147 if ((ra & 0x1F) == 0x0C) // BRK
149 printf ("BRK"); //// ??????
154 b = (ra & 0x1F) == 0x0C;
155 if (b) sprintf (s1str, "brk r%d, r%d", rd, rb);
158 s1len = sprintf (s1str, "br%s%s", a ? "a" : "", d ? "d" : "");
159 sprintf (s1str, "%s r%d", strncat(s1str," ",6-s1len), rb);
161 s1len = sprintf (s1str, "br%sl%s", a ? "a" : "", d ? "d" : "");
162 sprintf (s1str, "%s r%d, r%d", strncat(s1str," ",6-s1len), rd, rb);
166 if ((rd & 0xf) <= 0x5)
167 sprintf (s1str, "%s%s r%d, 0x%x", brc_Tbl[rd & 0xf], rd & 0x10 ? "d" : " ", ra, rb);
169 sprintf (s1str, "brc (opcode 0x27) has some errors, please check\n");
171 case OP_BRI: // BRI / BRAI / BRID / BRAID / BRLID / BRAILD
172 if ((ra & 0x1F) == 0x0C) // BRK
173 printf ("BRK"); //// ??????
177 b = (ra & 0x1F) == 0x0C;
178 if (b) sprintf (s1str, "brki r%d, 0x%x", rd, imm);
181 s1len = sprintf (s1str, "bri%s%s", a ? "a" : "", d ? "d" : "" );
182 s1len = sprintf (s1str, "%s %d", strncat(s1str," ",6-s1len), s_imm);
184 s1len = sprintf (s1str, "bri%sl%s", a ? "a" : "", d ? "d" : "");
185 s1len = sprintf (s1str, "%s r%d, %d", strncat(s1str," ",6-s1len), rd, s_imm);
188 sprintf (s1str, "%s// 0x%x", strncat(s1str,spc_str,25-s1len), imm);
190 sprintf (s1str, "%s// 0x%x", strncat(s1str,spc_str,25-s1len), pcb + s_imm);
194 if ((rd & 0xf) <= 0x5) {
195 s1len = sprintf (s1str, "%si%s r%d, %d", brc_Tbl[rd & 0xf], rd & 0x10 ? "d" : " ", ra, s_imm);
196 sprintf (s1str, "%s// 0x%x", strncat(s1str,spc_str,25-s1len), pcb + s_imm);
198 sprintf (s1str, "brci (opcode 0x2f) has some errors, please check\n");
201 sprintf (s2str, "r%d, r%d, 0x%0x", rd, ra, imm & 0x1F);
204 if (imm & 0x400) // left shift
205 s1len = sprintf (s1str, "bsll%s %s", opc & 0x08 ? "i" : " ", s2str);
207 s1len = sprintf (s1str, "bsr%s%s %s",
208 imm & 0x200 ? "a" : "l", opc & 0x08 ? "i" : " ", s2str);
210 case OP_CMP: // or RSUBK
212 sprintf (s1str, "cmp%s %s", imm & 2 ? "u" : " ", s2str);
214 sprintf (s1str, "rsubk %s", s2str);
217 sprintf (s1str, "Floating Point Instruction NOT IMPLEMENTED IN TUMBL");
221 sprintf (s1str, "FSL Instruction NOT IMPLEMENTED IN TUMBL");
224 s1len = sprintf (s1str, "idiv%s %s", imm & 0x02 ? "u" : " ", s2str);
225 sprintf (s1str, "%s NOT IMPLEMENTED IN TUMBL", strncat(s1str,spc_str,25-s1len));
228 sprintf (s1str, "imm 0x%04x // %d", imm, s_imm);
232 s1len = sprintf (s1str, "%s%s", opc_Tbl[opc], s2str);
237 case 0x12: sprintf (s2str, "rtbd"); break; // RTBD
238 case 0x11: sprintf (s2str, "rtid"); break; // RTID
239 case 0x14: sprintf (s2str, "rted"); break; // RTED
240 case 0x10: sprintf (s2str, "rtsd"); break; // RTSD
242 sprintf (s1str, "Illegal subopcode in OP_RTBD");
246 sprintf (s1str, "%s r%d, 0x%x", s2str, ra, imm);
251 case 0x61: sprintf (s2str, "sext16"); break; // SEXT16
252 case 0x60: sprintf (s2str, "sext8 "); break; // SEXT8
253 case 0x01: sprintf (s2str, "sra "); break; // SRA
254 case 0x21: sprintf (s2str, "src "); break; // SRC
255 case 0x41: sprintf (s2str, "srl "); break; // SRL
257 sprintf (s1str, "OP_SEXT has some errors, please check" );
261 sprintf (s1str, "%s r%d, r%d", s2str, rd, ra);
264 sprintf (s1str, "SP-Reg Instruction NOT IMPLEMENTED IN TUMBL");
271 if (strncmp(opc_Tbl[opc],"--",2))
272 sprintf (s1str, "%s%s", opc_Tbl[opc], s2str);
274 sprintf (s1str, "Unknown instruction / possibly data ?");
277 printf ("%6x: %08x %s\n", pcb, ins, s1str);
281 int main(int argc, char *argv[])
283 char binFilename[132];
285 // note: strncmp == 0 if the parts of the strings are equal
286 if ((argc > 2) || ((argc == 2) && !strncmp(argv[1],"-",1))) {
287 print_Usage( argv[0]);
292 sprintf( binFilename, argv[1]);
294 sprintf( binFilename, "imem.bin");
295 read_bin (binFilename, imem, &mem_size);
296 for (int pci = 0; pci < mem_size; pci++)