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

Subversion Repositories lxp32

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

Go to most recent revision | Details | Compare with Previous | View Log

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