/* * Copyright (c) 1999, 2000, 2002 Seth Kingsley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgment: * This product includes software developed by Seth Kingsley and * contributors. * 4. Neither the author's name, nor any of the contributors names may be * used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #include #include #include #ifndef lint static const char rcsid[] = "$Id$"; #endif /* !lint */ #define EXT(n) ((n & 0x8000) ? (n | 0xffff0000) : n) int main(int ac, char *av[]) { struct { const char *o_name; enum { UKWN, JMP, STA, SA, BRCH, TSX, TSIM, TIM, TMEM, RTYP, NONE, BRAK, S, SD, D, ST, DST, DTSH, DTS, CO } o_fmt; } ops[] = { {NULL, RTYP}, {NULL, BRCH}, {"j", JMP}, {"jal", JMP}, {"beq", STA}, {"bne", STA}, {"blez", SA}, {"bgtz", SA}, {"addi", TSX}, {"addiu", TSX}, {"slti", TSX}, {"sltiu", TSX}, {"andi", TSIM}, {"ori", TSIM}, {"xori", TSIM}, {"lui", TIM}, {"cop0", CO}, {"cop1", CO}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {"lb", TMEM}, {NULL, UKWN}, {NULL, UKWN}, {"lw", TMEM}, {"lbu", TMEM}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {"sb", TMEM}, {NULL, UKWN}, {NULL, UKWN}, {"sw", TMEM}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {"lwc1", TMEM}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {"swc1", TMEM}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN} }, fns[] = { {"sll", DTSH}, {NULL, UKWN}, {"srl", DTSH}, {"sra", DTSH}, {"sllv", DTS}, {NULL, UKWN}, {"srlv", DTS}, {"srav", DTS}, {"jr", S}, {"jalr", SD}, {NULL, UKWN}, {NULL, UKWN}, {"syscall", NONE}, {"break", BRAK}, {NULL, UKWN}, {NULL, UKWN}, {"mfhi", D}, {"mthi", S}, {"mflo", D}, {"mtlo", S}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {"mult", ST}, {"multu", ST}, {"div", ST}, {"divu", ST}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {"add", DST}, {"addu", DST}, {"sub", DST}, {"subu", DST}, {"and", DST}, {"or", DST}, {"xor", DST}, {"nor", DST}, {NULL, UKWN}, {NULL, UKWN}, {"slt", DST}, {"sltu", DST}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, }, tops[] = { {"bltz", SA}, {"bgez", SA}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {"bltzal", SA}, {"bgezal", SA}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN}, {NULL, UKWN} }, o; u_int pc = 0x400000; /* from SPIM */ union { u_int u_uint; struct { u_int r_func : 6, r_shift : 5, r_rd : 5, r_rt : 5, r_rs : 5, r_op : 6; } u_r; #define r_func u_r.r_func #define r_shift u_r.r_shift #define r_rd u_r.r_rd #define r_rt u_r.r_rt #define r_rs u_r.r_rs #define r_op u_r.r_op struct { u_int i_imm : 16, i_rt : 5, i_rs : 5, i_op : 6; } u_i; #define i_imm u_i.i_imm #define i_rt u_i.i_rt #define i_rs u_i.i_rs #define i_op u_i.i_op struct { u_int j_jmp : 26, j_op : 6; } u_j; #define j_jmp u_j.j_jmp #define j_op u_j.j_op } i; puts(" PC HEX INST\t TAL instruction\n"); while (fread(&i, 4, 1, stdin)) { i.u_uint = ntohl(i.u_uint); printf("%08x %08x\t", pc, i.u_uint); pc+= 4; if (ops[i.r_op].o_fmt == RTYP) o = fns[i.r_func]; else if (ops[i.r_op].o_fmt == BRCH) o = tops[i.r_rt]; else o = ops[i.r_op]; if (o.o_name) printf((o.o_fmt != NONE) ? "%s\t" : "%s\n", o.o_name); switch (o.o_fmt) { case JMP: printf("%#.8x\n", i.j_jmp << 2); break; case STA: printf("$%d, $%d, %#.8x\n", i.i_rs, i.i_rt, pc + (EXT(i.i_imm) << 2)); break; case SA: printf("$%d, %#.8x\n", i.i_rs, pc + (EXT(i.i_imm) << 2)); break; case TSX: printf("$%d, $%d, %d\n", i.i_rt, i.i_rs, EXT(i.i_imm)); break; case TSIM: printf("$%d, $%d, %#x\n", i.i_rt, i.i_rs, i.i_imm); break; case TIM: printf("$%d, %#04x\n", i.i_rt, i.i_imm); break; case TMEM: printf("$%d, %d($%d)\n", i.i_rt, i.i_imm, i.i_rs); break; case NONE: break; case BRAK: printf("%#x\n", i.j_jmp); break; case S: printf("$%d\n", i.r_rs); break; case SD: printf("$%d, $%d\n", i.r_rs, i.r_rd); break; case D: printf("$%d\n", i.r_rd); break; case ST: printf("$%d, $%d\n", i.r_rs, i.r_rt); break; case DST: printf("$%d, $%d, $%d\n", i.r_rd, i.r_rs, i.r_rt); break; case DTSH: printf("$%d, $%d, %d\n", i.r_rd, i.r_rt, i.r_shift); break; case DTS: printf("$%d, $%d, $%d\n", i.r_rd, i.r_rt, i.r_rs); break; case CO: puts("coprocessor instruction"); break; case UKWN: default: puts("** Unknown instruction **"); } } return EX_OK; }