OpenCores
URL https://opencores.org/ocsvn/lxp32/lxp32/trunk

Subversion Repositories lxp32

[/] [lxp32/] [trunk/] [tools/] [src/] [lxp32dump/] [disassembler.cpp] - Blame information for rev 9

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 9 ring0_mipt
/*
2
 * Copyright (c) 2016 by Alex I. Kuznetsov.
3
 *
4
 * Part of the LXP32 CPU IP core.
5
 *
6
 * This module implements members of the Disassembler class.
7
 */
8
 
9
#include "disassembler.h"
10
 
11
#include <stdexcept>
12
 
13
/*
14
 * Disassembler::Operand class members
15
 */
16
 
17
Disassembler::Operand::Operand(Type t,int value):
18
        _type(t),_value(value) {}
19
 
20
Disassembler::Operand::Type Disassembler::Operand::type() const {
21
        return _type;
22
}
23
 
24
int Disassembler::Operand::value() const {
25
        return _value;
26
}
27
 
28
/*
29
 * Disassembler class members
30
 */
31
 
32
Disassembler::Disassembler(std::istream &is,std::ostream &os):
33
        _is(is),_os(os),_fmt(Bin),_preferAliases(true),_lineNumber(0),_pos(0) {}
34
 
35
void Disassembler::setFormat(Format fmt) {
36
        _fmt=fmt;
37
}
38
 
39
void Disassembler::setBase(Word base) {
40
        _pos=base;
41
}
42
 
43
void Disassembler::setPreferAliases(bool b) {
44
        _preferAliases=b;
45
}
46
 
47
void Disassembler::dump() {
48
        Word word;
49
 
50
        for(;;) {
51
                auto offset=_pos;
52
                if(!getWord(word)) break;
53
                auto opcode=word>>26;
54
 
55
                std::string instruction;
56
 
57
                bool lcValid=false;
58
                Word lcOperand;
59
 
60
                switch(opcode) {
61
                case 0x10:
62
                        instruction=decodeAdd(word);
63
                        break;
64
                case 0x18:
65
                        instruction=decodeAnd(word);
66
                        break;
67
                case 0x21:
68
                        instruction=decodeCall(word);
69
                        break;
70
                case 0x15:
71
                        instruction=decodeDivs(word);
72
                        break;
73
                case 0x14:
74
                        instruction=decodeDivu(word);
75
                        break;
76
                case 0x02:
77
                        instruction=decodeHlt(word);
78
                        break;
79
                case 0x20:
80
                        instruction=decodeJmp(word);
81
                        break;
82
                case 0x01:
83
                        instruction=decodeLc(word,lcValid,lcOperand);
84
                        break;
85
                case 0x0B:
86
                        instruction=decodeLsb(word);
87
                        break;
88
                case 0x0A:
89
                        instruction=decodeLub(word);
90
                        break;
91
                case 0x08:
92
                        instruction=decodeLw(word);
93
                        break;
94
                case 0x17:
95
                        instruction=decodeMods(word);
96
                        break;
97
                case 0x16:
98
                        instruction=decodeModu(word);
99
                        break;
100
                case 0x12:
101
                        instruction=decodeMul(word);
102
                        break;
103
                case 0x00:
104
                        instruction=decodeNop(word);
105
                        break;
106
                case 0x19:
107
                        instruction=decodeOr(word);
108
                        break;
109
                case 0x0E:
110
                        instruction=decodeSb(word);
111
                        break;
112
                case 0x1C:
113
                        instruction=decodeSl(word);
114
                        break;
115
                case 0x1F:
116
                        instruction=decodeSrs(word);
117
                        break;
118
                case 0x1E:
119
                        instruction=decodeSru(word);
120
                        break;
121
                case 0x11:
122
                        instruction=decodeSub(word);
123
                        break;
124
                case 0x0C:
125
                        instruction=decodeSw(word);
126
                        break;
127
                case 0x1A:
128
                        instruction=decodeXor(word);
129
                        break;
130
                default:
131
                        if((opcode>>4)==0x03) instruction=decodeCjmpxx(word);
132
                        else if((opcode>>3)==0x05) instruction=decodeLcs(word);
133
                        else instruction=decodeWord(word);
134
                }
135
 
136
                auto size=instruction.size();
137
                std::size_t padding=0;
138
                if(size<32) padding=32-size;
139
 
140
                _os<<'\t'<<instruction<<std::string(padding,' ')<<"// ";
141
                _os<<hex(offset)<<": "<<hex(word);
142
                if(lcValid) _os<<' '<<hex(lcOperand);
143
                _os<<std::endl;
144
        }
145
}
146
 
147
bool Disassembler::getWord(Word &w) {
148
        if(_fmt==Bin) {
149
                char buf[sizeof(Word)] {}; // zero-initialize
150
                _is.read(buf,sizeof(Word));
151
 
152
                auto n=static_cast<std::size_t>(_is.gcount());
153
                if(n==0) return false;
154
                if(n<sizeof(Word)) std::cerr<<"Warning: last word is truncated"<<std::endl;
155
 
156
                w=(static_cast<unsigned char>(buf[3])<<24)|(static_cast<unsigned char>(buf[2])<<16)|
157
                        (static_cast<unsigned char>(buf[1])<<8)|static_cast<unsigned char>(buf[0]);
158
        }
159
        else {
160
                try {
161
                        std::string line;
162
                        if(!std::getline(_is,line)) return false;
163
                        _lineNumber++;
164
 
165
                        if(_fmt==Textio) w=std::stoul(line,nullptr,2);
166
                        else if(_fmt==Dec) w=std::stoul(line,nullptr,10);
167
                        else if(_fmt==Hex) w=std::stoul(line,nullptr,16);
168
                        else return false;
169
                }
170
                catch(std::exception &) {
171
                        throw std::runtime_error("Bad literal at line "+std::to_string(_lineNumber));
172
                }
173
        }
174
        _pos+=sizeof(Word);
175
        return true;
176
}
177
 
178
std::string Disassembler::str(const Operand &op) {
179
        if(op.type()==Operand::Register) {
180
                if(!_preferAliases) return "r"+std::to_string(op.value());
181
                else if(op.value()>=240&&op.value()<=247) return "iv"+std::to_string(op.value()-240);
182
                else if(op.value()==252) return "cr";
183
                else if(op.value()==253) return "irp";
184
                else if(op.value()==254) return "rp";
185
                else if(op.value()==255) return "sp";
186
                else return "r"+std::to_string(op.value());
187
        }
188
        else return std::to_string(op.value());
189
}
190
 
191
Disassembler::Operand Disassembler::decodeRd1Operand(Word w) {
192
        int value=(w>>8)&0xFF;
193
        if(w&0x02000000) return Operand(Operand::Register,value);
194
        else {
195
                if(value>127) value-=256;
196
                return Operand(Operand::Direct,value);
197
        }
198
}
199
 
200
Disassembler::Operand Disassembler::decodeRd2Operand(Word w) {
201
        int value=w&0xFF;
202
        if(w&0x01000000) return Operand(Operand::Register,value);
203
        else {
204
                if(value>127) value-=256;
205
                return Operand(Operand::Direct,value);
206
        }
207
}
208
 
209
Disassembler::Operand Disassembler::decodeDstOperand(Word w) {
210
        int value=(w>>16)&0xFF;
211
        return Operand(Operand::Register,value);
212
}
213
 
214
std::string Disassembler::decodeSimpleInstruction(const std::string &op,Word w) {
215
        auto dst=decodeDstOperand(w);
216
        auto rd1=decodeRd1Operand(w);
217
        auto rd2=decodeRd2Operand(w);
218
        return op+' '+str(dst)+", "+str(rd1)+", "+str(rd2);
219
}
220
 
221
std::string Disassembler::decodeAdd(Word w) {
222
        auto dst=decodeDstOperand(w);
223
        auto rd1=decodeRd1Operand(w);
224
        auto rd2=decodeRd2Operand(w);
225
 
226
        if(rd2.type()==Operand::Direct&&rd2.value()==0&&_preferAliases)
227
                return "mov "+str(dst)+", "+str(rd1);
228
        else
229
                return "add "+str(dst)+", "+str(rd1)+", "+str(rd2);
230
}
231
 
232
std::string Disassembler::decodeAnd(Word w) {
233
        return decodeSimpleInstruction("and",w);
234
}
235
 
236
std::string Disassembler::decodeCall(Word w) {
237
        auto dst=decodeDstOperand(w);
238
        auto rd1=decodeRd1Operand(w);
239
        auto rd2=decodeRd2Operand(w);
240
 
241
        if(dst.value()!=0xFE) return decodeWord(w);
242
        if(rd1.type()!=Operand::Register) return decodeWord(w);
243
        if(rd2.type()!=Operand::Direct||rd2.value()!=0) return decodeWord(w);
244
 
245
        return "call "+str(rd1);
246
}
247
 
248
std::string Disassembler::decodeCjmpxx(Word w) {
249
        auto jumpType=(w>>26)&0x0F;
250
        std::string op;
251
 
252
        switch(jumpType) {
253
        case 0x8:
254
                op="cjmpe";
255
                break;
256
        case 0x4:
257
                op="cjmpne";
258
                break;
259
        case 0x2:
260
                op="cjmpug";
261
                break;
262
        case 0xA:
263
                op="cjmpuge";
264
                break;
265
        case 0x1:
266
                op="cjmpsg";
267
                break;
268
        case 0x9:
269
                op="cjmpsge";
270
                break;
271
        default:
272
                return decodeWord(w);
273
        }
274
 
275
        return decodeSimpleInstruction(op,w);
276
}
277
 
278
std::string Disassembler::decodeDivs(Word w) {
279
        auto rd2=decodeRd2Operand(w);
280
        if(rd2.type()==Operand::Direct&&rd2.value()==0) return decodeWord(w);
281
        return decodeSimpleInstruction("divs",w);
282
}
283
 
284
std::string Disassembler::decodeDivu(Word w) {
285
        auto rd2=decodeRd2Operand(w);
286
        if(rd2.type()==Operand::Direct&&rd2.value()==0) return decodeWord(w);
287
        return decodeSimpleInstruction("divu",w);
288
}
289
 
290
std::string Disassembler::decodeHlt(Word w) {
291
        if(w!=0x08000000) return decodeWord(w);
292
        return "hlt";
293
}
294
 
295
std::string Disassembler::decodeJmp(Word w) {
296
        auto dst=decodeDstOperand(w);
297
        auto rd1=decodeRd1Operand(w);
298
        auto rd2=decodeRd2Operand(w);
299
 
300
        if(dst.value()!=0) return decodeWord(w);
301
        if(rd1.type()!=Operand::Register) return decodeWord(w);
302
        if(rd2.type()!=Operand::Direct||rd2.value()!=0) return decodeWord(w);
303
 
304
        if(rd1.value()==253&&_preferAliases) return "iret";
305
        if(rd1.value()==254&&_preferAliases) return "ret";
306
        return "jmp "+str(rd1);
307
}
308
 
309
std::string Disassembler::decodeLc(Word w,bool &valid,Word &operand) {
310
        auto dst=decodeDstOperand(w);
311
        auto rd1=decodeRd1Operand(w);
312
        auto rd2=decodeRd2Operand(w);
313
 
314
        valid=false;
315
 
316
        if(rd1.type()!=Operand::Direct||rd1.value()!=0) return decodeWord(w);
317
        if(rd2.type()!=Operand::Direct||rd2.value()!=0) return decodeWord(w);
318
 
319
        bool b=getWord(operand);
320
        if(!b) return decodeWord(w);
321
 
322
        valid=true;
323
        return "lc "+str(dst)+", 0x"+hex(operand);
324
}
325
 
326
std::string Disassembler::decodeLcs(Word w) {
327
        auto dst=decodeDstOperand(w);
328
        auto operand=w&0xFFFF;
329
        operand|=(w>>8)&0x001F0000;
330
        if(operand&0x00100000) operand|=0xFFE00000;
331
        return "lcs "+str(dst)+", 0x"+hex(operand);
332
}
333
 
334
std::string Disassembler::decodeLsb(Word w) {
335
        auto dst=decodeDstOperand(w);
336
        auto rd1=decodeRd1Operand(w);
337
        auto rd2=decodeRd2Operand(w);
338
 
339
        if(rd1.type()!=Operand::Register) return decodeWord(w);
340
        if(rd2.type()!=Operand::Direct||rd2.value()!=0) return decodeWord(w);
341
 
342
        return "lsb "+str(dst)+", "+str(rd1);
343
}
344
 
345
std::string Disassembler::decodeLub(Word w) {
346
        auto dst=decodeDstOperand(w);
347
        auto rd1=decodeRd1Operand(w);
348
        auto rd2=decodeRd2Operand(w);
349
 
350
        if(rd1.type()!=Operand::Register) return decodeWord(w);
351
        if(rd2.type()!=Operand::Direct||rd2.value()!=0) return decodeWord(w);
352
 
353
        return "lub "+str(dst)+", "+str(rd1);
354
}
355
 
356
std::string Disassembler::decodeLw(Word w) {
357
        auto dst=decodeDstOperand(w);
358
        auto rd1=decodeRd1Operand(w);
359
        auto rd2=decodeRd2Operand(w);
360
 
361
        if(rd1.type()!=Operand::Register) return decodeWord(w);
362
        if(rd2.type()!=Operand::Direct||rd2.value()!=0) return decodeWord(w);
363
 
364
        return "lw "+str(dst)+", "+str(rd1);
365
}
366
 
367
std::string Disassembler::decodeMods(Word w) {
368
        auto rd2=decodeRd2Operand(w);
369
        if(rd2.type()==Operand::Direct&&rd2.value()==0) return decodeWord(w);
370
        return decodeSimpleInstruction("mods",w);
371
}
372
 
373
std::string Disassembler::decodeModu(Word w) {
374
        auto rd2=decodeRd2Operand(w);
375
        if(rd2.type()==Operand::Direct&&rd2.value()==0) return decodeWord(w);
376
        return decodeSimpleInstruction("modu",w);
377
}
378
 
379
std::string Disassembler::decodeMul(Word w) {
380
        return decodeSimpleInstruction("mul",w);
381
}
382
 
383
std::string Disassembler::decodeNop(Word w) {
384
        if(w!=0) return decodeWord(w);
385
        return "nop";
386
}
387
 
388
std::string Disassembler::decodeOr(Word w) {
389
        return decodeSimpleInstruction("or",w);
390
}
391
 
392
std::string Disassembler::decodeSb(Word w) {
393
        auto dst=decodeDstOperand(w);
394
        auto rd1=decodeRd1Operand(w);
395
        auto rd2=decodeRd2Operand(w);
396
 
397
        if(dst.value()!=0) return decodeWord(w);
398
        if(rd1.type()!=Operand::Register) return decodeWord(w);
399
 
400
        return "sb "+str(rd1)+", "+str(rd2);
401
}
402
 
403
std::string Disassembler::decodeSl(Word w) {
404
        auto rd2=decodeRd2Operand(w);
405
        if(rd2.type()==Operand::Direct&&(rd2.value()<0||rd2.value()>31)) return decodeWord(w);
406
        return decodeSimpleInstruction("sl",w);
407
}
408
 
409
std::string Disassembler::decodeSrs(Word w) {
410
        auto rd2=decodeRd2Operand(w);
411
        if(rd2.type()==Operand::Direct&&(rd2.value()<0||rd2.value()>31)) return decodeWord(w);
412
        return decodeSimpleInstruction("srs",w);
413
}
414
 
415
std::string Disassembler::decodeSru(Word w) {
416
        auto rd2=decodeRd2Operand(w);
417
        if(rd2.type()==Operand::Direct&&(rd2.value()<0||rd2.value()>31)) return decodeWord(w);
418
        return decodeSimpleInstruction("sru",w);
419
}
420
 
421
std::string Disassembler::decodeSub(Word w) {
422
        auto dst=decodeDstOperand(w);
423
        auto rd1=decodeRd1Operand(w);
424
        auto rd2=decodeRd2Operand(w);
425
 
426
        if(rd1.type()==Operand::Direct&&rd1.value()==0&&_preferAliases)
427
                return "neg "+str(dst)+", "+str(rd2);
428
        else
429
                return "sub "+str(dst)+", "+str(rd1)+", "+str(rd2);
430
}
431
 
432
std::string Disassembler::decodeSw(Word w) {
433
        auto dst=decodeDstOperand(w);
434
        auto rd1=decodeRd1Operand(w);
435
        auto rd2=decodeRd2Operand(w);
436
 
437
        if(dst.value()!=0) return decodeWord(w);
438
        if(rd1.type()!=Operand::Register) return decodeWord(w);
439
 
440
        return "sw "+str(rd1)+", "+str(rd2);
441
}
442
 
443
std::string Disassembler::decodeXor(Word w) {
444
        auto dst=decodeDstOperand(w);
445
        auto rd1=decodeRd1Operand(w);
446
        auto rd2=decodeRd2Operand(w);
447
 
448
        if(rd2.type()==Operand::Direct&&rd2.value()==-1&&_preferAliases)
449
                return "not "+str(dst)+", "+str(rd1);
450
        else
451
                return "xor "+str(dst)+", "+str(rd1)+", "+str(rd2);
452
}
453
 
454
std::string Disassembler::decodeWord(Word w) {
455
        return ".word 0x"+hex(w);
456
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.