Line 24... |
Line 24... |
|
|
int Disassembler::Operand::value() const {
|
int Disassembler::Operand::value() const {
|
return _value;
|
return _value;
|
}
|
}
|
|
|
std::string Disassembler::Operand::str() const {
|
|
if(_type==Register) {
|
|
if(_value>=240&&_value<=247) return "iv"+std::to_string(_value-240);
|
|
else if(_value==252) return "cr";
|
|
else if(_value==253) return "irp";
|
|
else if(_value==254) return "rp";
|
|
else if(_value==255) return "sp";
|
|
else return "r"+std::to_string(_value);
|
|
}
|
|
else return std::to_string(_value);
|
|
}
|
|
|
|
/*
|
/*
|
* Disassembler class members
|
* Disassembler class members
|
*/
|
*/
|
|
|
Disassembler::Disassembler(std::istream &is,std::ostream &os):
|
Disassembler::Disassembler(std::istream &is,std::ostream &os):
|
_is(is),_os(os),_fmt(Bin),_lineNumber(0),_pos(0) {}
|
_is(is),_os(os),_fmt(Bin),_preferAliases(true),_lineNumber(0),_pos(0) {}
|
|
|
void Disassembler::setFormat(Format fmt) {
|
void Disassembler::setFormat(Format fmt) {
|
_fmt=fmt;
|
_fmt=fmt;
|
}
|
}
|
|
|
void Disassembler::setBase(Word base) {
|
void Disassembler::setBase(Word base) {
|
_pos=base;
|
_pos=base;
|
}
|
}
|
|
|
|
void Disassembler::setPreferAliases(bool b) {
|
|
_preferAliases=b;
|
|
}
|
|
|
void Disassembler::dump() {
|
void Disassembler::dump() {
|
Word word;
|
Word word;
|
|
|
for(;;) {
|
for(;;) {
|
auto offset=_pos;
|
auto offset=_pos;
|
Line 136... |
Line 128... |
case 0x1A:
|
case 0x1A:
|
instruction=decodeXor(word);
|
instruction=decodeXor(word);
|
break;
|
break;
|
default:
|
default:
|
if((opcode>>4)==0x03) instruction=decodeCjmpxx(word);
|
if((opcode>>4)==0x03) instruction=decodeCjmpxx(word);
|
|
else if((opcode>>3)==0x05) instruction=decodeLcs(word);
|
else instruction=decodeWord(word);
|
else instruction=decodeWord(word);
|
}
|
}
|
|
|
auto size=instruction.size();
|
auto size=instruction.size();
|
std::size_t padding=0;
|
std::size_t padding=0;
|
Line 181... |
Line 174... |
}
|
}
|
_pos+=sizeof(Word);
|
_pos+=sizeof(Word);
|
return true;
|
return true;
|
}
|
}
|
|
|
|
std::string Disassembler::str(const Operand &op) {
|
|
if(op.type()==Operand::Register) {
|
|
if(!_preferAliases) return "r"+std::to_string(op.value());
|
|
else if(op.value()>=240&&op.value()<=247) return "iv"+std::to_string(op.value()-240);
|
|
else if(op.value()==252) return "cr";
|
|
else if(op.value()==253) return "irp";
|
|
else if(op.value()==254) return "rp";
|
|
else if(op.value()==255) return "sp";
|
|
else return "r"+std::to_string(op.value());
|
|
}
|
|
else return std::to_string(op.value());
|
|
}
|
|
|
Disassembler::Operand Disassembler::decodeRd1Operand(Word w) {
|
Disassembler::Operand Disassembler::decodeRd1Operand(Word w) {
|
int value=(w>>8)&0xFF;
|
int value=(w>>8)&0xFF;
|
if(w&0x02000000) return Operand(Operand::Register,value);
|
if(w&0x02000000) return Operand(Operand::Register,value);
|
else {
|
else {
|
if(value>127) value-=256;
|
if(value>127) value-=256;
|
Line 209... |
Line 215... |
std::string Disassembler::decodeSimpleInstruction(const std::string &op,Word w) {
|
std::string Disassembler::decodeSimpleInstruction(const std::string &op,Word w) {
|
std::ostringstream oss;
|
std::ostringstream oss;
|
auto dst=decodeDstOperand(w);
|
auto dst=decodeDstOperand(w);
|
auto rd1=decodeRd1Operand(w);
|
auto rd1=decodeRd1Operand(w);
|
auto rd2=decodeRd2Operand(w);
|
auto rd2=decodeRd2Operand(w);
|
oss<<op<<' '<<dst.str()<<", "<<rd1.str()<<", "<<rd2.str();
|
oss<<op<<' '<<str(dst)<<", "<<str(rd1)<<", "<<str(rd2);
|
return oss.str();
|
return oss.str();
|
}
|
}
|
|
|
std::string Disassembler::decodeAdd(Word w) {
|
std::string Disassembler::decodeAdd(Word w) {
|
std::ostringstream oss;
|
std::ostringstream oss;
|
|
|
auto dst=decodeDstOperand(w);
|
auto dst=decodeDstOperand(w);
|
auto rd1=decodeRd1Operand(w);
|
auto rd1=decodeRd1Operand(w);
|
auto rd2=decodeRd2Operand(w);
|
auto rd2=decodeRd2Operand(w);
|
|
|
if(rd2.type()==Operand::Direct&&rd2.value()==0)
|
if(rd2.type()==Operand::Direct&&rd2.value()==0&&_preferAliases)
|
oss<<"mov "<<dst.str()<<", "<<rd1.str();
|
oss<<"mov "<<str(dst)<<", "<<str(rd1);
|
else
|
else
|
oss<<"add "<<dst.str()<<", "<<rd1.str()<<", "<<rd2.str();
|
oss<<"add "<<str(dst)<<", "<<str(rd1)<<", "<<str(rd2);
|
|
|
return oss.str();
|
return oss.str();
|
}
|
}
|
|
|
std::string Disassembler::decodeAnd(Word w) {
|
std::string Disassembler::decodeAnd(Word w) {
|
Line 241... |
Line 247... |
|
|
if(dst.value()!=0xFE) return decodeWord(w);
|
if(dst.value()!=0xFE) return decodeWord(w);
|
if(rd1.type()!=Operand::Register) return decodeWord(w);
|
if(rd1.type()!=Operand::Register) return decodeWord(w);
|
if(rd2.type()!=Operand::Direct||rd2.value()!=0) return decodeWord(w);
|
if(rd2.type()!=Operand::Direct||rd2.value()!=0) return decodeWord(w);
|
|
|
return "call "+rd1.str();
|
return "call "+str(rd1);
|
}
|
}
|
|
|
std::string Disassembler::decodeCjmpxx(Word w) {
|
std::string Disassembler::decodeCjmpxx(Word w) {
|
auto jumpType=(w>>26)&0x0F;
|
auto jumpType=(w>>26)&0x0F;
|
std::string op;
|
std::string op;
|
Line 300... |
Line 306... |
|
|
if(dst.value()!=0) return decodeWord(w);
|
if(dst.value()!=0) return decodeWord(w);
|
if(rd1.type()!=Operand::Register) return decodeWord(w);
|
if(rd1.type()!=Operand::Register) return decodeWord(w);
|
if(rd2.type()!=Operand::Direct||rd2.value()!=0) return decodeWord(w);
|
if(rd2.type()!=Operand::Direct||rd2.value()!=0) return decodeWord(w);
|
|
|
if(rd1.value()==253) return "iret";
|
if(rd1.value()==253&&_preferAliases) return "iret";
|
if(rd1.value()==254) return "ret";
|
if(rd1.value()==254&&_preferAliases) return "ret";
|
return "jmp "+rd1.str();
|
return "jmp "+str(rd1);
|
}
|
}
|
|
|
std::string Disassembler::decodeLc(Word w,bool &valid,Word &operand) {
|
std::string Disassembler::decodeLc(Word w,bool &valid,Word &operand) {
|
auto dst=decodeDstOperand(w);
|
auto dst=decodeDstOperand(w);
|
auto rd1=decodeRd1Operand(w);
|
auto rd1=decodeRd1Operand(w);
|
Line 319... |
Line 325... |
|
|
bool b=getWord(operand);
|
bool b=getWord(operand);
|
if(!b) return decodeWord(w);
|
if(!b) return decodeWord(w);
|
|
|
valid=true;
|
valid=true;
|
return "lc "+dst.str()+", 0x"+hex(operand);
|
return "lc "+str(dst)+", 0x"+hex(operand);
|
|
}
|
|
|
|
std::string Disassembler::decodeLcs(Word w) {
|
|
auto dst=decodeDstOperand(w);
|
|
auto operand=w&0xFFFF;
|
|
operand|=(w>>8)&0x001F0000;
|
|
if(operand&0x00100000) operand|=0xFFE00000;
|
|
return "lcs "+str(dst)+", 0x"+hex(operand);
|
}
|
}
|
|
|
std::string Disassembler::decodeLsb(Word w) {
|
std::string Disassembler::decodeLsb(Word w) {
|
std::ostringstream oss;
|
std::ostringstream oss;
|
|
|
Line 332... |
Line 346... |
auto rd2=decodeRd2Operand(w);
|
auto rd2=decodeRd2Operand(w);
|
|
|
if(rd1.type()!=Operand::Register) return decodeWord(w);
|
if(rd1.type()!=Operand::Register) return decodeWord(w);
|
if(rd2.type()!=Operand::Direct||rd2.value()!=0) return decodeWord(w);
|
if(rd2.type()!=Operand::Direct||rd2.value()!=0) return decodeWord(w);
|
|
|
return "lsb "+dst.str()+", "+rd1.str();
|
return "lsb "+str(dst)+", "+str(rd1);
|
}
|
}
|
|
|
std::string Disassembler::decodeLub(Word w) {
|
std::string Disassembler::decodeLub(Word w) {
|
std::ostringstream oss;
|
std::ostringstream oss;
|
|
|
Line 345... |
Line 359... |
auto rd2=decodeRd2Operand(w);
|
auto rd2=decodeRd2Operand(w);
|
|
|
if(rd1.type()!=Operand::Register) return decodeWord(w);
|
if(rd1.type()!=Operand::Register) return decodeWord(w);
|
if(rd2.type()!=Operand::Direct||rd2.value()!=0) return decodeWord(w);
|
if(rd2.type()!=Operand::Direct||rd2.value()!=0) return decodeWord(w);
|
|
|
return "lub "+dst.str()+", "+rd1.str();
|
return "lub "+str(dst)+", "+str(rd1);
|
}
|
}
|
|
|
std::string Disassembler::decodeLw(Word w) {
|
std::string Disassembler::decodeLw(Word w) {
|
std::ostringstream oss;
|
std::ostringstream oss;
|
|
|
Line 358... |
Line 372... |
auto rd2=decodeRd2Operand(w);
|
auto rd2=decodeRd2Operand(w);
|
|
|
if(rd1.type()!=Operand::Register) return decodeWord(w);
|
if(rd1.type()!=Operand::Register) return decodeWord(w);
|
if(rd2.type()!=Operand::Direct||rd2.value()!=0) return decodeWord(w);
|
if(rd2.type()!=Operand::Direct||rd2.value()!=0) return decodeWord(w);
|
|
|
return "lw "+dst.str()+", "+rd1.str();
|
return "lw "+str(dst)+", "+str(rd1);
|
}
|
}
|
|
|
std::string Disassembler::decodeMods(Word w) {
|
std::string Disassembler::decodeMods(Word w) {
|
auto rd2=decodeRd2Operand(w);
|
auto rd2=decodeRd2Operand(w);
|
if(rd2.type()==Operand::Direct&&rd2.value()==0) return decodeWord(w);
|
if(rd2.type()==Operand::Direct&&rd2.value()==0) return decodeWord(w);
|
Line 396... |
Line 410... |
auto rd2=decodeRd2Operand(w);
|
auto rd2=decodeRd2Operand(w);
|
|
|
if(dst.value()!=0) return decodeWord(w);
|
if(dst.value()!=0) return decodeWord(w);
|
if(rd1.type()!=Operand::Register) return decodeWord(w);
|
if(rd1.type()!=Operand::Register) return decodeWord(w);
|
|
|
return "sb "+rd1.str()+", "+rd2.str();
|
return "sb "+str(rd1)+", "+str(rd2);
|
}
|
}
|
|
|
std::string Disassembler::decodeSl(Word w) {
|
std::string Disassembler::decodeSl(Word w) {
|
auto rd2=decodeRd2Operand(w);
|
auto rd2=decodeRd2Operand(w);
|
if(rd2.type()==Operand::Direct&&(rd2.value()<0||rd2.value()>31)) return decodeWord(w);
|
if(rd2.type()==Operand::Direct&&(rd2.value()<0||rd2.value()>31)) return decodeWord(w);
|
Line 418... |
Line 432... |
if(rd2.type()==Operand::Direct&&(rd2.value()<0||rd2.value()>31)) return decodeWord(w);
|
if(rd2.type()==Operand::Direct&&(rd2.value()<0||rd2.value()>31)) return decodeWord(w);
|
return decodeSimpleInstruction("sru",w);
|
return decodeSimpleInstruction("sru",w);
|
}
|
}
|
|
|
std::string Disassembler::decodeSub(Word w) {
|
std::string Disassembler::decodeSub(Word w) {
|
return decodeSimpleInstruction("sub",w);
|
std::ostringstream oss;
|
|
|
|
auto dst=decodeDstOperand(w);
|
|
auto rd1=decodeRd1Operand(w);
|
|
auto rd2=decodeRd2Operand(w);
|
|
|
|
if(rd1.type()==Operand::Direct&&rd1.value()==0&&_preferAliases)
|
|
oss<<"neg "<<str(dst)<<", "<<str(rd2);
|
|
else
|
|
oss<<"sub "<<str(dst)<<", "<<str(rd1)<<", "<<str(rd2);
|
|
|
|
return oss.str();
|
}
|
}
|
|
|
std::string Disassembler::decodeSw(Word w) {
|
std::string Disassembler::decodeSw(Word w) {
|
std::ostringstream oss;
|
std::ostringstream oss;
|
|
|
Line 431... |
Line 456... |
auto rd2=decodeRd2Operand(w);
|
auto rd2=decodeRd2Operand(w);
|
|
|
if(dst.value()!=0) return decodeWord(w);
|
if(dst.value()!=0) return decodeWord(w);
|
if(rd1.type()!=Operand::Register) return decodeWord(w);
|
if(rd1.type()!=Operand::Register) return decodeWord(w);
|
|
|
return "sw "+rd1.str()+", "+rd2.str();
|
return "sw "+str(rd1)+", "+str(rd2);
|
}
|
}
|
|
|
std::string Disassembler::decodeXor(Word w) {
|
std::string Disassembler::decodeXor(Word w) {
|
std::ostringstream oss;
|
std::ostringstream oss;
|
|
|
auto dst=decodeDstOperand(w);
|
auto dst=decodeDstOperand(w);
|
auto rd1=decodeRd1Operand(w);
|
auto rd1=decodeRd1Operand(w);
|
auto rd2=decodeRd2Operand(w);
|
auto rd2=decodeRd2Operand(w);
|
|
|
if(rd2.type()==Operand::Direct&&rd2.value()==-1)
|
if(rd2.type()==Operand::Direct&&rd2.value()==-1&&_preferAliases)
|
oss<<"not "<<dst.str()<<", "<<rd1.str();
|
oss<<"not "<<str(dst)<<", "<<str(rd1);
|
else
|
else
|
oss<<"xor "<<dst.str()<<", "<<rd1.str()<<", "<<rd2.str();
|
oss<<"xor "<<str(dst)<<", "<<str(rd1)<<", "<<str(rd2);
|
|
|
return oss.str();
|
return oss.str();
|
}
|
}
|
|
|
std::string Disassembler::decodeWord(Word w) {
|
std::string Disassembler::decodeWord(Word w) {
|