/* $Id: despasm.cc,v 1.1 2003/01/02 20:53:20 batonik Exp $ */ #include "despasm.h" #include const char *rozkazy[] = { "add", "addx", "addcc", "addxcc", "sub", "subx", "subcc", "subxcc", "and", "andcc", "andn", "andncc", "or", "orcc", "orn", "orncc", "xor", "xorcc", "xorn", "xorncc", "sll", "srl", "sra", "jmpl", "save", "restore", "ld", "ldub", "lduh", "ldd", "ldsb", "ldsh", "st", "stb", "sth", "std", "ldstub", "swap", "bn", "be", "ble", "bl", "bleu", "bcs", "bneg", "bvs", "ba", "bne", "bg", "bge", "bgu", "bcc", "bpos", "bvc", "sethi", "call" }; unsigned long rozwinZnak(unsigned long dsp, int num) { if (dsp & ( 1UL << num)) dsp |= (0xFFFFFFFF << num); return(dsp); } string rejestr ( int num, int typ ) { string temp("%"); char buff[3]; if (!typ) { sprintf(buff, "%-d", num & 0x1F); temp += (string) "r" + (string) buff; } else { if (num == 30) temp += "fp"; else if (num == 14) temp += "sp"; else { if (num < 8) temp += "g"; else if (num < 16) { temp += "o"; num -= 8; } else if (num < 24) { temp += "l"; num -= 16; } else { temp += "i"; num -= 24; } } sprintf(buff, "%-d", num & 0x1F); temp += buff; } return(temp); } despasm::despasm ( vector spasm_code, int typ_reg) { instr_word rozkaz; string linia; char *bufor; long adres; bufor = new char[DEASM_BUFOR]; decoded.clear(); for (unsigned long i = 0; i < spasm_code.size(); i++) { adres = i * 4; rozkaz = bit_word(spasm_code[i]); memset(bufor, 0, DEASM_BUFOR); sprintf(bufor, INSTR_FORMAT, rozkazy[rozkaz.instr]); linia = bufor; switch (rozkaz.format) { case (instr_word::call_format): sprintf(bufor, ADRES_FORMAT, adres + 4 * rozwinZnak(rozkaz.dsp30, 30)); linia += bufor; break; case (instr_word::sethi_format): sprintf(bufor, SETHI_FORMAT, (int) rozwinZnak(rozkaz.imm22, 22)); linia += (string) bufor + ", " + rejestr(rozkaz.dst, typ_reg); break; case (instr_word::branch_format): sprintf(bufor, ADRES_FORMAT, adres + 4 * rozwinZnak(rozkaz.dsp22, 22)); linia += bufor; break; case (instr_word::primary_reg): linia += rejestr(rozkaz.src1, typ_reg) + ", " + rejestr(rozkaz.src2, typ_reg) + ", " + rejestr(rozkaz.dst, typ_reg); break; case (instr_word::primary_imm): sprintf(bufor, IMM_FORMAT, (int) rozwinZnak(rozkaz.imm13, 13)); linia += rejestr(rozkaz.src1, typ_reg) + ", " + bufor + ", " + rejestr(rozkaz.dst, typ_reg); break; } decoded.push_back(linia); } delete bufor; } string despasm::getline (unsigned long num) { return(this->decoded[num]); }