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

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [debugger/] [src/] [cpu_arm_plugin/] [srcproc/] [srcproc.cpp] - Blame information for rev 5

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 5 sergeykhbr
/*
2
 *  Copyright 2018 Sergey Khabarov, sergeykhbr@gmail.com
3
 *
4
 *  Licensed under the Apache License, Version 2.0 (the "License");
5
 *  you may not use this file except in compliance with the License.
6
 *  You may obtain a copy of the License at
7
 *
8
 *      http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 *  Unless required by applicable law or agreed to in writing, software
11
 *  distributed under the License is distributed on an "AS IS" BASIS,
12
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 *  See the License for the specific language governing permissions and
14
 *  limitations under the License.
15
 */
16
 
17
#include "../arm-isa.h"
18
#include "srcproc.h"
19
#include <iostream>
20
 
21
namespace debugger {
22
 
23
/** Class registration in the Core */
24
enum ESymbInfo {
25
    SymbInfo_Name,
26
    SymbInfo_Address,
27
    SymbInfo_Total,
28
};
29
 
30
const char *const *RN = IREGS_NAMES;
31
 
32
 
33
ArmSourceService::ArmSourceService(const char *name) : IService(name) {
34
    registerInterface(static_cast<ISourceCode *>(this));
35
 
36
    brList_.make_list(0);
37
    symbolListSortByName_.make_list(0);
38
    symbolListSortByAddr_.make_list(0);
39
    registerAttribute("Endianess", &endianess_);
40
}
41
 
42
ArmSourceService::~ArmSourceService() {
43
}
44
 
45
void ArmSourceService::postinitService() {
46
}
47
 
48
void ArmSourceService::addFileSymbol(const char *name, uint64_t addr,
49
                                       int sz) {
50
    AttributeType symb(Attr_List);
51
    symb.make_list(Symbol_Total);
52
    symb[Symbol_Name].make_string(name);
53
    symb[Symbol_Addr].make_uint64(addr);
54
    symb[Symbol_Size].make_int64(sz);
55
 
56
    symbolListSortByName_.add_to_list(&symb);
57
    symbolListSortByName_.sort(Symbol_Name);
58
 
59
    symbolListSortByAddr_.add_to_list(&symb);
60
    symbolListSortByAddr_.sort(Symbol_Addr);
61
}
62
 
63
void ArmSourceService::addFunctionSymbol(const char *name,
64
                                      uint64_t addr, int sz) {
65
    addFileSymbol(name, addr, sz);
66
}
67
 
68
void ArmSourceService::addDataSymbol(const char *name, uint64_t addr,
69
                                       int sz) {
70
    addFileSymbol(name, addr, sz);
71
}
72
 
73
void ArmSourceService::clearSymbols() {
74
    symbolListSortByName_.make_list(0);
75
    symbolListSortByAddr_.make_list(0);
76
}
77
 
78
void ArmSourceService::addSymbols(AttributeType *list) {
79
    for (unsigned i = 0; i < list->size(); i++) {
80
        AttributeType &item = (*list)[i];
81
        symbolListSortByName_.add_to_list(&item);
82
        symbolListSortByAddr_.add_to_list(&item);
83
    }
84
    symbolListSortByName_.sort(Symbol_Name);
85
    symbolListSortByAddr_.sort(Symbol_Addr);
86
}
87
 
88
void ArmSourceService::addressToSymbol(uint64_t addr, AttributeType *info) {
89
    uint64_t sadr, send;
90
    int sz = static_cast<int>(symbolListSortByAddr_.size());
91
 
92
    info->make_list(SymbInfo_Total);
93
    (*info)[SymbInfo_Name].make_string("");
94
    (*info)[SymbInfo_Address].make_uint64(0);
95
    if (sz == 0) {
96
        return;
97
    }
98
    sadr = symbolListSortByAddr_[0u][Symbol_Addr].to_uint64();
99
    if (addr < sadr) {
100
        return;
101
    }
102
 
103
    bool search = true;
104
    int dist, pos = sz / 2;
105
    dist = pos;
106
    while (search) {
107
        AttributeType &symb = symbolListSortByAddr_[pos];
108
        sadr = symb[Symbol_Addr].to_uint64();
109
        if (pos < static_cast<int>(symbolListSortByAddr_.size()) - 1) {
110
            send = symbolListSortByAddr_[pos + 1][Symbol_Addr].to_uint64();
111
        } else {
112
            send = sadr + symb[Symbol_Size].to_uint64();
113
        }
114
        if (sadr <= addr && addr < send) {
115
            (*info)[SymbInfo_Name] = symb[Symbol_Name];
116
            (*info)[SymbInfo_Address].make_uint64(addr - sadr);
117
            return;
118
        }
119
 
120
        if (addr < sadr) {
121
            if (dist == 0 || pos == 0) {
122
                search = false;
123
            } else if (dist == 1) {
124
                dist = 0;
125
                pos--;
126
            } else {
127
                int incr = dist / 2;
128
                pos -= incr;
129
                dist = (dist / 2) + (dist & 0x1);
130
                if (pos < 0) {
131
                    pos = 0;
132
                }
133
            }
134
        } else {
135
            if (dist == 0 || pos == (sz - 1)) {
136
                search = false;
137
            } else if (dist == 1) {
138
                dist = 0;
139
                pos++;
140
            } else {
141
                int incr = dist / 2;
142
                pos += incr;
143
                dist = (dist / 2) + (dist & 0x1);
144
                if (pos >= sz) {
145
                    pos = sz - 1;
146
                }
147
            }
148
        }
149
    }
150
}
151
 
152
int ArmSourceService::symbol2Address(const char *name, uint64_t *addr) {
153
    for (unsigned i = 0; i < symbolListSortByName_.size(); i++) {
154
        AttributeType &item = symbolListSortByName_[i];
155
        if (item[Symbol_Name].is_equal(name)) {
156
            *addr = item[Symbol_Addr].to_uint64();
157
            return 0;
158
        }
159
    }
160
    return -1;
161
}
162
 
163
void ArmSourceService::registerBreakpoint(uint64_t addr, uint64_t flags,
164
                                       uint64_t instr) {
165
    AttributeType item;
166
    item.make_list(BrkList_Total);
167
    item[BrkList_address].make_uint64(addr);
168
    item[BrkList_flags].make_uint64(flags);
169
    //item[BrkList_instr].make_uint64(instr);
170
 
171
    bool not_found = true;
172
    for (unsigned i = 0; i < brList_.size(); i++) {
173
        AttributeType &br = brList_[i];
174
        if (addr == br[BrkList_address].to_uint64()) {
175
            not_found = false;
176
        }
177
    }
178
    if (not_found) {
179
        brList_.add_to_list(&item);
180
    }
181
}
182
 
183
int ArmSourceService::unregisterBreakpoint(uint64_t addr, uint64_t *flags,
184
                                       uint64_t *instr) {
185
    for (unsigned i = 0; i < brList_.size(); i++) {
186
        AttributeType &br = brList_[i];
187
        if (addr == br[BrkList_address].to_uint64()) {
188
            *flags = br[BrkList_flags].to_uint64();
189
            //*instr = br[BrkList_instr].to_uint64();
190
            brList_.remove_from_list(i);
191
            return 0;
192
        }
193
    }
194
    return 1;
195
}
196
 
197
void ArmSourceService::getBreakpointList(AttributeType *list) {
198
    if (!list->is_list() || list->size() != brList_.size()) {
199
        list->make_list(brList_.size());
200
    }
201
 
202
    for (unsigned i = 0; i < brList_.size(); i++) {
203
        AttributeType &item = (*list)[i];
204
        AttributeType &br = brList_[i];
205
        if (!item.is_list() || item.size() != 3) {
206
            item.make_list(BrkList_Total);
207
        }
208
        item[BrkList_address] = br[BrkList_address];
209
        item[BrkList_flags] = br[BrkList_flags];
210
        item[BrkList_instr] = br[BrkList_instr];
211
    }
212
}
213
 
214
bool ArmSourceService::isBreakpoint(uint64_t addr, AttributeType *outbr) {
215
    for (unsigned i = 0; i < brList_.size(); i++) {
216
        uint64_t bradr = brList_[i][BrkList_address].to_uint64();
217
        if (addr == bradr) {
218
            *outbr = brList_[i];
219
            return true;
220
        }
221
    }
222
    return false;
223
}
224
 
225
int ArmSourceService::disasm(uint64_t pc,
226
                       uint8_t *data,
227
                       int offset,
228
                       AttributeType *mnemonic,
229
                       AttributeType *comment) {
230
    uint32_t instr;
231
    memcpy(&instr, &data[offset], 4);
232
    if ((instr & 0x0FB00000) == 0x03000000) {
233
        return parseUndefinedInstruction(pc, instr, mnemonic, comment);
234
    } else if ((instr & 0x0F0000F0) == 0x9
235
        && (((instr >> 22) & 0x3F) == 0 || ((instr >> 23) & 0x1F) == 1)) {
236
        return parseMultiply(pc, instr, mnemonic, comment);
237
    } else if (((instr >> 4) & 0x00FFFFFF) == 0x12FFF1) {
238
        return parseBranchExchange(pc, instr, mnemonic, comment);
239
    } else if ((instr & 0x0F0000F0) == 0x06000070) {
240
        // ARM V6 operation: uxtab, uxtb, uxah, uxth..
241
        return parseBytesExtending(pc, instr, mnemonic, comment);
242
    } else if (((instr >> 26) & 0x3) == 0x1) {
243
        return parseSingleDataTransfer(pc, instr, mnemonic, comment);
244
    } else if (((instr >> 25) & 0x7) == 0x4) {
245
        return parseBlockDataTransfer(pc, instr, mnemonic, comment);
246
    } else if (((instr >> 24) & 0xF) == 0xE && (instr & 0x10)) {
247
        return parseCoprocRegTransfer(pc, instr, mnemonic, comment);
248
    } else if (((instr >> 26) & 0x3) == 0x0) {
249
        return parseDataProcessing(pc, instr, mnemonic, comment);
250
    } else if (((instr >> 25) & 0x7) == 0x5) {
251
        return parseBranch(pc, instr, mnemonic, comment);
252
    }
253
    mnemonic->make_string("unimpl");
254
    comment->make_string("");
255
    return 4;
256
}
257
 
258
void ArmSourceService::disasm(uint64_t pc,
259
                          AttributeType *idata,
260
                          AttributeType *asmlist) {
261
    asmlist->make_list(0);
262
    if (!idata->is_data()) {
263
        return;
264
    }
265
    uint8_t *data = idata->data();
266
 
267
    AttributeType asm_item, symb_item, info, brpoint;
268
    asm_item.make_list(ASM_Total);
269
    symb_item.make_list(3);
270
    asm_item[ASM_list_type].make_int64(AsmList_disasm);
271
    symb_item[ASM_list_type].make_int64(AsmList_symbol);
272
    uint64_t off = 0;
273
    Reg64Type code;
274
    int codesz;
275
 
276
    while (static_cast<unsigned>(off) < idata->size()) {
277
        code.val = *reinterpret_cast<uint32_t*>(&data[off]);
278
 
279
        addressToSymbol(pc + off, &info);
280
        if (info[SymbInfo_Name].size() != 0 &&
281
            info[SymbInfo_Address].to_int() == 0) {
282
            symb_item[1].make_uint64(pc + off);
283
            symb_item[2].make_string(info[SymbInfo_Name].to_string());
284
            asmlist->add_to_list(&symb_item);
285
        }
286
        asm_item[ASM_addrline].make_uint64(pc + off);
287
        asm_item[ASM_breakpoint].make_boolean(false);
288
        asm_item[ASM_label].make_string("");
289
 
290
        if (isBreakpoint(pc + off, &brpoint)) {
291
            asm_item[ASM_breakpoint].make_boolean(true);
292
            //if (!(brpoint[BrkList_flags].to_uint64() & BreakFlag_HW)) {
293
            //    code.val = brpoint[BrkList_instr].to_uint32();
294
            //}
295
        }
296
        codesz = disasm(pc + off,
297
                        code.buf,
298
                        0,
299
                        &asm_item[ASM_mnemonic],
300
                        &asm_item[ASM_comment]);
301
 
302
        uint64_t swap = code.val;
303
        if (codesz == 2) {
304
            swap = code.buf16[0];
305
        }
306
        if (endianess_.to_int() == 1) {
307
            swap = 0;
308
            for (int i = 0; i < codesz; i++) {
309
                swap = (swap << 8) | code.buf[i];
310
            }
311
        }
312
        asm_item[ASM_code].make_uint64(swap);
313
        asm_item[ASM_codesize].make_uint64(codesz);
314
        asmlist->add_to_list(&asm_item);
315
        off += codesz;
316
    }
317
}
318
 
319
int ArmSourceService::parseUndefinedInstruction(uint64_t pc, uint32_t instr,
320
                                                AttributeType *mnemonic,
321
                                                AttributeType *comment) {
322
    char tstr[64];
323
    if (((instr >> 20) & 0xFF) == 0x34) {
324
        uint32_t imm16 = instr & 0xFFF;
325
        imm16 |= ((instr & 0xF0000) >> 12);
326
        RISCV_sprintf(tstr, sizeof(tstr), "movt     %s,#%04x",
327
            IREGS_NAMES[(instr >> 12) & 0xf], imm16);
328
    } else {
329
        mnemonic->make_string("unimpl");
330
        comment->make_string("");
331
    }
332
    return 4;
333
}
334
 
335
 
336
int ArmSourceService::parseSingleDataTransfer(uint64_t pc, uint32_t instr,
337
                                              AttributeType *mnemonic,
338
                                              AttributeType *comment) {
339
    char tstr[64];
340
    SingleDataTransferType u;
341
    const char *strdown[2] = {"-", ""};
342
    u.value = instr;
343
    if (u.imm_bits.L) {
344
        if (!u.imm_bits.I) {
345
            if (u.imm_bits.rd == Reg_pc && u.imm_bits.rn == Reg_pc
346
                && (u.imm_bits.imm & 0x1)) {
347
                if (u.imm_bits.imm == 0x4F) {
348
                    RISCV_sprintf(tstr, sizeof(tstr), "%s", "dsb");
349
                } else if (u.imm_bits.imm == 0x6F) {
350
                    RISCV_sprintf(tstr, sizeof(tstr), "%s", "isb");
351
                } else {
352
                    RISCV_sprintf(tstr, sizeof(tstr), "%s", "?sb");
353
                }
354
            } else {
355
                RISCV_sprintf(tstr, sizeof(tstr), "ldr      %s,[%s,#%s%d]",
356
                    IREGS_NAMES[u.imm_bits.rd],
357
                    IREGS_NAMES[u.imm_bits.rn],
358
                    strdown[u.imm_bits.U],
359
                    u.imm_bits.imm
360
                    );
361
            }
362
        } else {
363
            RISCV_sprintf(tstr, sizeof(tstr), "ldr      %s,[%s,%s,LSL#%d]",
364
                IREGS_NAMES[u.reg_bits.rd],
365
                IREGS_NAMES[u.reg_bits.rn],
366
                IREGS_NAMES[u.reg_bits.rm],
367
                u.reg_bits.sh_sel
368
                );
369
        }
370
    } else {
371
        const char *instrname[2] = {"str     ", "strb    "};
372
        if (!u.imm_bits.I) {
373
                RISCV_sprintf(tstr, sizeof(tstr), "%s %s,[%s,#%s%d]",
374
                    instrname[u.imm_bits.B],
375
                    IREGS_NAMES[u.imm_bits.rd],
376
                    IREGS_NAMES[u.imm_bits.rn],
377
                    strdown[u.imm_bits.U],
378
                    u.imm_bits.imm
379
                    );
380
        } else {
381
            RISCV_sprintf(tstr, sizeof(tstr), "%s %s,[%s,%s,LSL#%d]",
382
                instrname[u.imm_bits.B],
383
                IREGS_NAMES[u.reg_bits.rd],
384
                IREGS_NAMES[u.reg_bits.rn],
385
                IREGS_NAMES[u.reg_bits.rm],
386
                u.reg_bits.sh_sel
387
                );
388
        }
389
    }
390
    mnemonic->make_string(tstr);
391
    return 4;
392
}
393
 
394
int ArmSourceService::parseBlockDataTransfer(uint64_t pc, uint32_t instr,
395
                                             AttributeType *mnemonic,
396
                                             AttributeType *comment) {
397
    BlockDataTransferType u;
398
    const char *instrname[2] = {"stm     ", "ldm     "};
399
    const char *spname[2] =    {"push    ", "pop     "};
400
    const char *sflag[2] = {"", "^"};
401
    char rnames[512] = "";
402
    char tstr[512];
403
    int sz = 0;
404
    u.value = instr;
405
    for (int i = 0; i < 16; i++) {
406
        if ((instr & (1 << i )) == 0) {
407
            continue;
408
        }
409
        if (sz) {
410
            sz = RISCV_sprintf(&rnames[sz], sizeof(rnames) - sz,
411
                                ",%s", IREGS_NAMES[i]);
412
        } else {
413
            sz = RISCV_sprintf(&rnames[sz], sizeof(rnames) - sz,
414
                                "%s", IREGS_NAMES[i]);
415
        }
416
    }
417
 
418
    if (u.bits.rn == Reg_sp) {
419
        RISCV_sprintf(tstr, sizeof(tstr), "%s {%s}%s",
420
            spname[u.bits.L],
421
            rnames,
422
            sflag[u.bits.S]
423
            );
424
    } else {
425
        RISCV_sprintf(tstr, sizeof(tstr), "%s %s,{%s}%s",
426
            instrname[u.bits.L],
427
            IREGS_NAMES[u.bits.rn],
428
            rnames,
429
            sflag[u.bits.S]
430
            );
431
    }
432
    mnemonic->make_string(tstr);
433
    return 4;
434
}
435
 
436
 
437
int ArmSourceService::parseDataProcessing(uint64_t pc, uint32_t instr,
438
                                          AttributeType *mnemonic,
439
                                          AttributeType *comment) {
440
    char tstr[64];
441
    char op2[32];
442
    DataProcessingType u;
443
    u.value = instr;
444
    const char instr_name[][16] = {
445
        "and     ", "eor     ", "sub     ", "rsb     ",
446
        "add     ", "adc     ", "sbc     ", "rsc     ",
447
        "tst     ", "teq     ", "cmp     ", "cmn     ",
448
        "orr     ", "mov     ", "bic     ", "mvn     "
449
 
450
    };
451
    const char psrname[2][16] = {"CPSR", "SPSR"};
452
    // N Z C V
453
    const char flagmask[][16] = {
454
    "",    "v",    "c",   "cv",
455
    "z",  "zv",   "zc",  "zcv",
456
    "n",  "nv",   "nc",  "ncv",
457
    "nz", "nzv", "nzc", "nzcv"
458
    };
459
 
460
    if (u.imm_bits.I) {
461
        uint32_t rsh = 2*u.imm_bits.rotate;
462
        uint32_t imm = (u.imm_bits.imm >> rsh)
463
                     | (u.imm_bits.imm << (32 - rsh));
464
        RISCV_sprintf(op2, sizeof(op2), "#%d", imm);
465
    } else {
466
        if (u.reg_bits.shift) {
467
            RISCV_sprintf(op2, sizeof(op2), "%s{,%d}",
468
                IREGS_NAMES[u.reg_bits.rm],
469
                u.reg_bits.shift);
470
        } else {
471
            RISCV_sprintf(op2, sizeof(op2), "%s",
472
                IREGS_NAMES[u.reg_bits.rm],
473
                u.reg_bits.shift);
474
        }
475
    }
476
    if (instr == 0xe320f000) {
477
        RISCV_sprintf(tstr, sizeof(tstr), "nop      {%d}", 0);
478
    } else if (u.mrs_bits.b27_23 == 0x2 && u.mrs_bits.b21_20 == 0
479
        && u.mrs_bits.mask == 0xF && u.mrs_bits.zero12 == 0) {
480
        RISCV_sprintf(tstr, sizeof(tstr), "mrs      %s,%s",
481
            IREGS_NAMES[u.mrs_bits.rd],
482
            psrname[u.mrs_bits.ps]);
483
    } else if ((u.mrs_bits.b27_23 == 0x2 || u.mrs_bits.b27_23 == 0x6)
484
        && u.mrs_bits.b21_20 == 0x2
485
        && u.mrs_bits.rd == 0xf) {
486
        RISCV_sprintf(tstr, sizeof(tstr), "msr      %s_%s,%s",
487
            psrname[u.mrs_bits.ps],
488
            flagmask[u.mrs_bits.mask+1],
489
            op2
490
            );
491
    } else if (u.imm_bits.opcode == 13 || u.imm_bits.opcode == 15) {
492
        // MOV, MVN
493
        RISCV_sprintf(tstr, sizeof(tstr), "%s %s,%s",
494
            instr_name[u.imm_bits.opcode],
495
            IREGS_NAMES[u.imm_bits.rd],
496
            op2);
497
    } else if (u.imm_bits.opcode == 8 || u.imm_bits.opcode == 9
498
        || u.imm_bits.opcode == 10 || u.imm_bits.opcode == 11) {
499
        // CMP, CMN, TEQ, TST
500
        RISCV_sprintf(tstr, sizeof(tstr), "%s %s,%s",
501
            instr_name[u.imm_bits.opcode],
502
            IREGS_NAMES[u.imm_bits.rn],
503
            op2);
504
    } else {
505
        RISCV_sprintf(tstr, sizeof(tstr), "%s %s,%s,%s",
506
            instr_name[u.imm_bits.opcode],
507
            IREGS_NAMES[u.imm_bits.rd],
508
            IREGS_NAMES[u.imm_bits.rn],
509
            op2);
510
    }
511
    mnemonic->make_string(tstr);
512
    return 4;
513
}
514
 
515
int ArmSourceService::parseMultiply(uint64_t pc, uint32_t instr,
516
                                    AttributeType *mnemonic,
517
                                    AttributeType *comment) {
518
    char tstr[64] = "unimpl";
519
    instr &= 0x0FFFFFFF;
520
    if ((instr >> 23) == 0) {
521
        MulType u;
522
        u.value = instr;
523
        if (u.bits.A) {
524
            RISCV_sprintf(tstr, sizeof(tstr), "mla      %s,%s,%s,%s",
525
                IREGS_NAMES[u.bits.rd],
526
                IREGS_NAMES[u.bits.rm],
527
                IREGS_NAMES[u.bits.rs],
528
                IREGS_NAMES[u.bits.rn]);
529
        } else {
530
            RISCV_sprintf(tstr, sizeof(tstr), "mul      %s,%s,%s",
531
                IREGS_NAMES[u.bits.rd],
532
                IREGS_NAMES[u.bits.rm],
533
                IREGS_NAMES[u.bits.rs]);
534
        }
535
    } else if ((instr >> 23) == 1) {
536
        const char *str_s[2] = {"u", "s"};
537
        const char *str_instr[2] = {"mull    ", "mlal    "};
538
        MulLongType u;
539
        u.value = instr;
540
        RISCV_sprintf(tstr, sizeof(tstr), "%s%s %s,%s,%s,%s",
541
            str_s[u.bits.S],
542
            str_instr[u.bits.A],
543
            IREGS_NAMES[u.bits.rdhi],
544
            IREGS_NAMES[u.bits.rdlo],
545
            IREGS_NAMES[u.bits.rm],
546
            IREGS_NAMES[u.bits.rs]);
547
    }
548
    mnemonic->make_string(tstr);
549
    return 4;
550
}
551
 
552
int ArmSourceService::parseBytesExtending(uint64_t pc, uint32_t instr,
553
                                          AttributeType *mnemonic,
554
                                          AttributeType *comment) {
555
    char tstr[64] = "unimpl";
556
    SignExtendType u;
557
    u.value = instr;
558
    if (u.bits.rn == 0xF) {
559
        if (u.bits.b27_20 == 0x6E) {
560
            RISCV_sprintf(tstr, sizeof(tstr), "uxtb     %s,%s,sh#%d",
561
                IREGS_NAMES[u.bits.rd],
562
                IREGS_NAMES[u.bits.rm],
563
                8*u.bits.rotate);
564
        } else if (u.bits.b27_20 == 0x6C) {
565
            RISCV_sprintf(tstr, sizeof(tstr), "uxtb16   %s,%s,sh#%d",
566
                IREGS_NAMES[u.bits.rd],
567
                IREGS_NAMES[u.bits.rm],
568
                8*u.bits.rotate);
569
        } else if (u.bits.b27_20 == 0x6F) {
570
            RISCV_sprintf(tstr, sizeof(tstr), "uxth     %s,%s,sh#%d",
571
                IREGS_NAMES[u.bits.rd],
572
                IREGS_NAMES[u.bits.rm],
573
                8*u.bits.rotate);
574
        }
575
    } else {
576
        if (u.bits.b27_20 == 0x6E) {
577
            RISCV_sprintf(tstr, sizeof(tstr), "uxtab    %s,%s,%s,sh#%d",
578
                IREGS_NAMES[u.bits.rd],
579
                IREGS_NAMES[u.bits.rn],
580
                IREGS_NAMES[u.bits.rm],
581
                8*u.bits.rotate);
582
        } else if (u.bits.b27_20 == 0x6C) {
583
            RISCV_sprintf(tstr, sizeof(tstr), "uxtab16  %s,%s,%s,sh#%d",
584
                IREGS_NAMES[u.bits.rd],
585
                IREGS_NAMES[u.bits.rn],
586
                IREGS_NAMES[u.bits.rm],
587
                8*u.bits.rotate);
588
        } else if (u.bits.b27_20 == 0x6F) {
589
            RISCV_sprintf(tstr, sizeof(tstr), "uxtah    %s,%s,%s,sh#%d",
590
                IREGS_NAMES[u.bits.rd],
591
                IREGS_NAMES[u.bits.rn],
592
                IREGS_NAMES[u.bits.rm],
593
                8*u.bits.rotate);
594
        }
595
    }
596
    mnemonic->make_string(tstr);
597
    return 4;
598
}
599
 
600
 
601
int ArmSourceService::parseCoprocRegTransfer(uint64_t pc, uint32_t instr,
602
                                             AttributeType *mnemonic,
603
                                             AttributeType *comment) {
604
    char tstr[64] = "unimpl";
605
    CoprocessorTransferType u;
606
    u.value = instr;
607
    const char instr_name[2][16] = {"mcr     ", "mrc     "};
608
    RISCV_sprintf(tstr, sizeof(tstr), "%s p%d,%d,%s,c%d,c%d,%d",
609
        instr_name[u.bits.L],
610
        u.bits.cp_num,
611
        u.bits.mode,
612
        IREGS_NAMES[u.bits.rd],
613
        u.bits.crn,
614
        u.bits.crm,
615
        u.bits.cp_nfo
616
        );
617
    mnemonic->make_string(tstr);
618
    return 4;
619
}
620
 
621
int ArmSourceService::parseBranch(uint64_t pc, uint32_t instr,
622
                                  AttributeType *mnemonic,
623
                                  AttributeType *comment) {
624
    char tstr[64];
625
    BranchType u;
626
    u.value = instr;
627
    const char *flags[16] = {
628
        "eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
629
        "hi", "ls", "ge", "lt", "gt", "le", "", ""
630
    };
631
 
632
    uint32_t off = u.bits.offset;
633
    if ((u.value >> 23) & 0x1) {
634
        off |= 0xFF000000;
635
    }
636
    off = static_cast<uint32_t>(pc + (off << 2) + 8);
637
 
638
    if (u.bits.L) {
639
        RISCV_sprintf(tstr, sizeof(tstr), "bl       %x",
640
            off);
641
    } else {
642
        RISCV_sprintf(tstr, sizeof(tstr), "b%2s      %x",
643
            flags[u.bits.cond],
644
            off);
645
    }
646
    mnemonic->make_string(tstr);
647
    return 4;
648
}
649
 
650
int ArmSourceService::parseBranchExchange(uint64_t pc, uint32_t instr,
651
                                          AttributeType *mnemonic,
652
                                          AttributeType *comment) {
653
    char tstr[64];
654
    BranchType u;
655
    u.value = instr;
656
 
657
    RISCV_sprintf(tstr, sizeof(tstr), "bx       %s",
658
            IREGS_NAMES[u.bits.offset & 0xF]);
659
    mnemonic->make_string(tstr);
660
    return 4;
661
}
662
 
663
}  // namespace debugger

powered by: WebSVN 2.1.0

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