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

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [debugger/] [src/] [cpu_arm_plugin/] [arm7tdmi.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 "api_utils.h"
18
#include "arm-isa.h"
19
#include "cpu_arm7_func.h"
20
 
21
namespace debugger {
22
 
23
static const uint64_t PREFETCH_OFFSET[InstrModes_Total] = {
24
    8,
25
    4
26
};
27
 
28
/** Data processing default behaviour can be re-implemeted: */
29
int ArmDataProcessingInstruction::exec_checked(Reg64Type *payload) {
30
    DataProcessingType u;
31
    u.value = payload->buf32[0];
32
    uint32_t A = static_cast<uint32_t>(R[u.reg_bits.rn]);
33
    uint32_t M;
34
    uint32_t Res;
35
    if (u.imm_bits.I) {
36
        M = imm12(u.imm_bits);
37
    } else {
38
        M = static_cast<uint32_t>(R[u.reg_bits.rm]);
39
        M = shift12(u.reg_bits, M, R[u.reg_bits.shift >> 1]);
40
    }
41
    if (do_operation(A, M, &Res)) {
42
        R[u.reg_bits.rd] = Res;
43
    }
44
    if (is_flags_changed(u)) {
45
        set_flags(A, M, Res);
46
    }
47
    return 4;
48
}
49
 
50
bool ArmDataProcessingInstruction::is_flags_changed(DataProcessingType u) {
51
    return u.reg_bits.S && u.reg_bits.rd != Reg_pc;
52
}
53
 
54
void ArmDataProcessingInstruction::set_flags(uint32_t A, uint32_t M,
55
                                             uint32_t Res) {
56
    icpu_->setC(0);
57
    icpu_->setZ(Res == 0);
58
    icpu_->setN(Res >> 31);
59
}
60
 
61
/** @brief Subtruct specific instruction set
62
 
63
 Specific flags computation with subtraction
64
 */
65
class ArmSubInstruction : public ArmDataProcessingInstruction {
66
 public:
67
    ArmSubInstruction(CpuCortex_Functional *icpu, const char *name,
68
        const char *bits) : ArmDataProcessingInstruction(icpu, name, bits) {}
69
 protected:
70
    virtual bool is_inverted() = 0;
71
    virtual bool with_carry() = 0;
72
    virtual EOperationResult op_result() = 0;
73
 
74
    virtual EOperationResult do_operation(uint32_t A, uint32_t M,
75
                                          uint32_t *pRes) {
76
        if (!is_inverted()) {
77
            *pRes = A - M;
78
        } else {
79
            *pRes = M - A;
80
        }
81
        if (with_carry()) {
82
            *pRes += (icpu_->getC() - 1);
83
        }
84
        return op_result();
85
    }
86
 
87
    virtual void set_flags(uint32_t A, uint32_t M, uint32_t Res) {
88
        if (is_inverted()) {
89
            uint32_t t1 = A;
90
            A = M;
91
            M = t1;
92
        }
93
        uint32_t C = !(((~A & M) | (M & Res) | (Res & ~A)) >> 31);
94
        uint32_t V = ((A & ~M & ~Res) | (~A & M & Res)) >> 31;
95
        icpu_->setC(C);
96
        icpu_->setV(V);
97
        icpu_->setZ(Res == 0);
98
        icpu_->setN(Res >> 31);
99
    }
100
};
101
 
102
/** @brief addictive specific instruction set
103
 
104
 Specific flags computation with addition
105
 */
106
class ArmAddInstruction : public ArmDataProcessingInstruction {
107
 public:
108
    ArmAddInstruction(CpuCortex_Functional *icpu, const char *name,
109
        const char *bits) : ArmDataProcessingInstruction(icpu, name, bits) {}
110
 protected:
111
    virtual EOperationResult op_result() = 0;
112
    virtual bool with_carry() = 0;
113
 
114
    virtual EOperationResult do_operation(uint32_t A, uint32_t M,
115
                                          uint32_t *pRes) {
116
        *pRes = A + M;
117
        if (with_carry()) {
118
            *pRes += icpu_->getC();
119
        }
120
        return op_result();
121
    }
122
 
123
    virtual void set_flags(uint32_t A, uint32_t M, uint32_t Res) {
124
        uint32_t C = ((A & M) | (M & ~Res) | (A & ~Res)) >> 31;
125
        uint32_t V = ((A & M & ~Res) | (~A & ~M & Res)) >> 31;
126
        icpu_->setC(C);
127
        icpu_->setV(V);
128
        icpu_->setZ(Res == 0);
129
        icpu_->setN(Res >> 31);
130
    }
131
};
132
 
133
/** Single memory transfer: LDR, STR
134
*/
135
class SingleDataTransferInstruction : public ArmInstruction {
136
 public:
137
    SingleDataTransferInstruction(CpuCortex_Functional *icpu, const char *name,
138
        const char *bits) : ArmInstruction(icpu, name, bits) {}
139
 
140
    virtual int exec_checked(Reg64Type *payload) {
141
        SingleDataTransferType u;
142
        u.value = payload->buf32[0];
143
        uint32_t opsz[2] = {4, 1};
144
        uint64_t off = R[u.imm_bits.rn];
145
 
146
        if (u.imm_bits.rn == Reg_pc) {
147
            off += PREFETCH_OFFSET[icpu_->getInstrMode()];
148
            if (u.imm_bits.rd == Reg_pc && !u.imm_bits.I
149
                && (u.imm_bits.imm & 0x1)) {
150
                // DSB, ISB
151
                return 4;
152
            }
153
        }
154
 
155
        if (u.imm_bits.P) {
156
            off += get_increment(u);
157
            if (u.imm_bits.W) {
158
                R[u.imm_bits.rn] = off;
159
            }
160
        }
161
 
162
        trans_.addr = off;
163
        trans_.wstrb = 0;
164
        trans_.xsize = opsz[u.imm_bits.B];
165
        if (u.imm_bits.L) {
166
            trans_.action = MemAction_Read;
167
            trans_.rpayload.b64[0] = 0;
168
        } else {
169
            trans_.action = MemAction_Write;
170
            trans_.wstrb = (1 << trans_.xsize) - 1;
171
            trans_.wpayload.b64[0] = R[u.imm_bits.rd];
172
        }
173
        icpu_->dma_memop(&trans_);
174
 
175
        if (!u.imm_bits.P) {
176
            off += get_increment(u);
177
            R[u.imm_bits.rn] = off;
178
            if (u.imm_bits.W) {
179
            /** In the case of post-indexed addressing, the write back bit is
180
                redundant and must be set to zero, since the old base value can be
181
                retained by setting the offset to zero. Therefore post-indexed
182
                data transfers always write back the modified base. The only use of
183
                the W bit in a post-indexed data transfer is in privileged mode
184
                code, where setting the W bit forces non-privileged mode for the
185
                transfer, allowing the operating system to generate a user address
186
                in a system where the memory management hardware makes suitable
187
                use of this hardware.
188
            */
189
                RISCV_error("Post-index LDR,STR with W=1", 0);
190
            }
191
        }
192
        if (u.imm_bits.L) {
193
            R[u.imm_bits.rd] = trans_.rpayload.b32[0];
194
            if (u.imm_bits.rd == Reg_pc) {
195
                icpu_->setBranch(R[u.imm_bits.rd]);
196
            }
197
        }
198
        return 4;
199
    }
200
 
201
 protected:
202
    virtual uint64_t get_increment(SingleDataTransferType u) {
203
        uint64_t incr;
204
        if (!u.imm_bits.I) {
205
            incr = u.imm_bits.imm;
206
        } else {
207
            /**
208
             @warning The register specified shift amounts
209
                      are not available in this instruction class.
210
             */
211
            DataProcessingType u2;
212
            u2.value = u.value;
213
            incr = shift12(u2.reg_bits,
214
                           static_cast<uint32_t>(R[u.reg_bits.rm]),
215
                           0);  // !! not available
216
        }
217
        if (!u.reg_bits.U) {
218
            incr = (~incr) + 1;
219
        }
220
        return incr;
221
    }
222
};
223
 
224
/** Block memory transfer: LDM, STM
225
*/
226
class BlockDataTransferInstruction : public ArmInstruction {
227
 public:
228
    BlockDataTransferInstruction(CpuCortex_Functional *icpu, const char *name,
229
        const char *bits) : ArmInstruction(icpu, name, bits) {}
230
 
231
    virtual int exec_checked(Reg64Type *payload) {
232
        BlockDataTransferType u;
233
        uint64_t adrincr[2] = {static_cast<uint64_t>(-4), 4};
234
        u.value = payload->buf32[0];
235
        uint32_t R15 = (u.bits.reglist >> 15) & 0x1;
236
        int ridx;
237
        // @todo Mode switching depending R15 value!!!!
238
 
239
        trans_.addr = R[u.bits.rn];
240
        trans_.xsize = 4;
241
        trans_.wstrb = 0;
242
        for (int i = 0; i < 16; i++) {
243
            if (u.bits.L) {
244
                ridx = 15 - i;
245
            } else {
246
                ridx = i;
247
            }
248
            if ((u.bits.reglist & (0x1 << ridx)) == 0) {
249
                continue;
250
            }
251
            if (u.bits.L) {
252
                trans_.action = MemAction_Read;
253
                trans_.rpayload.b64[0] = 0;
254
            } else {
255
                trans_.action = MemAction_Write;
256
                trans_.wstrb = (1 << trans_.xsize) - 1;
257
                trans_.wpayload.b64[0] = R[ridx];
258
            }
259
            if (u.bits.P) {
260
                trans_.addr += adrincr[u.bits.U];
261
                if (u.bits.W) {
262
                    R[u.bits.rn] = trans_.addr;
263
                }
264
            }
265
 
266
            icpu_->dma_memop(&trans_);
267
 
268
            if (!u.bits.P) {
269
                trans_.addr += adrincr[u.bits.U];
270
                R[u.bits.rn] = trans_.addr;
271
            }
272
 
273
            if (u.bits.L) {
274
                R[ridx] = trans_.rpayload.b32[0];
275
                if (ridx == Reg_pc) {
276
                    icpu_->setBranch(R[ridx]);
277
                }
278
            }
279
        }
280
 
281
        if (!u.bits.P) {
282
            if (u.bits.W) {
283
                RISCV_error("Post-index LDM,STM with W=1", 0);
284
            }
285
        }
286
        if (u.bits.S) {
287
            // TODO: force user mode
288
        }
289
        return 4;
290
    }
291
};
292
 
293
 
294
/** Halfword and Signed Data Transfer: LDRH/STRH/LDRSB/LDRSH
295
*/
296
class HWordSignedDataTransferInstruction : public ArmInstruction {
297
 public:
298
    HWordSignedDataTransferInstruction(CpuCortex_Functional *icpu,
299
        const char *name, const char *bits)
300
        : ArmInstruction(icpu, name, bits) {}
301
 
302
    virtual int exec_checked(Reg64Type *payload) {
303
        HWordSignedDataTransferType u;
304
        u.value = payload->buf32[0];
305
        uint32_t opsz[2] = {1, 2};
306
        uint64_t off = R[u.bits.rn];
307
        if (u.bits.rn == Reg_pc) {
308
            off += PREFETCH_OFFSET[icpu_->getInstrMode()];
309
        }
310
 
311
        if (u.bits.P) {
312
            off += get_increment(u);
313
        }
314
 
315
        trans_.addr = off;
316
        trans_.xsize = opsz[u.bits.h];
317
        trans_.wstrb = 0;
318
        if (u.bits.L) {
319
            trans_.action = MemAction_Read;
320
            trans_.rpayload.b64[0] = 0;
321
        } else {
322
            trans_.action = MemAction_Write;
323
            trans_.wstrb = (1 << trans_.xsize) - 1;
324
            trans_.wpayload.b64[0] = R[u.bits.rd];
325
        }
326
        icpu_->dma_memop(&trans_);
327
 
328
        if (u.bits.W) {
329
            if (!u.bits.P) {
330
                off += get_increment(u);
331
            }
332
            R[u.bits.rn] = off;
333
        }
334
        if (u.bits.L) {
335
            if (u.bits.h) {
336
                R[u.bits.rd] = trans_.rpayload.b16[0];
337
                if (u.bits.s) {
338
                    R[u.bits.rd] |= EXT_SIGN_16;
339
                }
340
            } else {
341
                R[u.bits.rd] = trans_.rpayload.b8[0];
342
                if (u.bits.s) {
343
                    R[u.bits.rd] |= EXT_SIGN_8;
344
                }
345
            }
346
            if (u.bits.rd == Reg_pc) {
347
                icpu_->setBranch(R[u.bits.rd]);
348
            }
349
        }
350
        return 4;
351
    }
352
 
353
 protected:
354
    virtual uint64_t get_increment(HWordSignedDataTransferType u) {
355
        uint64_t incr;
356
        if (!u.bits.reg_imm) {
357
            incr = (u.bits.imm_h << 4) | u.bits.rm;
358
        } else {
359
            incr = R[u.bits.rm];
360
        }
361
        if (!u.bits.U) {
362
            incr = (~incr) + 1;
363
        }
364
        return incr;
365
    }
366
};
367
 
368
/** Multiply common */
369
class MultiplyInstruction : public ArmInstruction {
370
 public:
371
    MultiplyInstruction(CpuCortex_Functional *icpu, const char *name,
372
        const char *bits) : ArmInstruction(icpu, name, bits) {}
373
 
374
    virtual int exec_checked(Reg64Type *payload) {
375
        MulType u;
376
        u.value = payload->buf32[0];
377
        uint64_t res = R[u.bits.rm] * R[u.bits.rs];
378
        if (u.bits.A) {
379
            res += R[u.bits.rn];
380
        }
381
        R[u.bits.rd] = static_cast<uint32_t>(res);
382
        if (u.bits.S) {
383
            icpu_->setC(0); // set meaningless value
384
            icpu_->setZ(R[u.bits.rd] == 0);
385
            icpu_->setN(static_cast<uint32_t>(R[u.bits.rd]) >> 31);
386
        }
387
        return 4;
388
    }
389
};
390
 
391
/** Multiply Long common. */
392
class MultiplyLongInstruction : public ArmInstruction {
393
 public:
394
    MultiplyLongInstruction(CpuCortex_Functional *icpu, const char *name,
395
        const char *bits) : ArmInstruction(icpu, name, bits) {}
396
 
397
    virtual int exec_checked(Reg64Type *payload) {
398
        MulLongType u;
399
        u.value = payload->buf32[0];
400
        uint64_t res = 0;
401
        if (u.bits.A) {
402
            res = static_cast<uint64_t>(R[u.bits.rdhi]) << 32;
403
            res |= R[u.bits.rdlo];
404
        }
405
        if (u.bits.S) {
406
            int64_t a = static_cast<int32_t>(R[u.bits.rm]);
407
            int64_t b = static_cast<int32_t>(R[u.bits.rs]);
408
            res = static_cast<uint64_t>(static_cast<int64_t>(res) + a * b);
409
        } else {
410
            uint64_t a = R[u.bits.rm];
411
            uint64_t b = R[u.bits.rs];
412
            res = res + a * b;
413
        }
414
        R[u.bits.rdlo] = static_cast<uint32_t>(res);
415
        R[u.bits.rdhi] = static_cast<uint32_t>(res >> 32);
416
        if (u.bits.S) {
417
            icpu_->setC(0);     // set to meaningless value
418
            icpu_->setV(0);     // set to meaningless value
419
            icpu_->setZ(res == 0);
420
            icpu_->setN(static_cast<uint32_t>(res >> 63));
421
        }
422
        return 4;
423
    }
424
};
425
 
426
 
427
/**
428
 * @brief AND.
429
 */
430
static const char *AND_OPCODES[2] = {
431
    "????0000000?????????????????????",
432
    "????0010000?????????????????????"
433
};
434
 
435
class AND : public ArmDataProcessingInstruction {
436
 public:
437
    AND(CpuCortex_Functional *icpu, int opidx) :
438
        ArmDataProcessingInstruction(icpu, "AND", AND_OPCODES[opidx]) {}
439
 protected:
440
    virtual EOperationResult do_operation(uint32_t A, uint32_t M,
441
                                          uint32_t *pRes) {
442
        *pRes = A & M;
443
        return OP_Write;
444
    }
445
};
446
 
447
/**
448
 * @brief EOR.
449
 */
450
static const char *EOR_OPCODES[2] = {
451
    "????0000001?????????????????????",
452
    "????0010001?????????????????????"
453
};
454
 
455
class EOR : public ArmDataProcessingInstruction {
456
 public:
457
    EOR(CpuCortex_Functional *icpu, int opidx) :
458
        ArmDataProcessingInstruction(icpu, "EOR", EOR_OPCODES[opidx]) {}
459
 protected:
460
    virtual EOperationResult do_operation(uint32_t A, uint32_t M,
461
                                          uint32_t *pRes) {
462
        *pRes = A ^ M;
463
        return OP_Write;
464
    }
465
};
466
 
467
/**
468
 * @brief Subtruct.
469
 */
470
static const char *SUB_OPCODES[2] = {
471
    "????0000010?????????????????????",
472
    "????0010010?????????????????????"
473
};
474
 
475
class SUB : public ArmSubInstruction {
476
 public:
477
    SUB(CpuCortex_Functional *icpu, int opidx) :
478
        ArmSubInstruction(icpu, "SUB", SUB_OPCODES[opidx]) {}
479
 protected:
480
    virtual bool is_inverted() { return false; }
481
    virtual bool with_carry() { return false; }
482
    virtual EOperationResult op_result() { return OP_Write; }
483
};
484
 
485
/**
486
 * @brief Subtruct right.
487
 */
488
static const char *RSB_OPCODES[2] = {
489
    "????0000011?????????????????????",
490
    "????0010011?????????????????????"
491
};
492
 
493
class RSB : public ArmSubInstruction {
494
 public:
495
    RSB(CpuCortex_Functional *icpu, int opidx) :
496
        ArmSubInstruction(icpu, "RSB", RSB_OPCODES[opidx]) {}
497
 protected:
498
    virtual bool is_inverted() { return true; }
499
    virtual bool with_carry() { return false; }
500
    virtual EOperationResult op_result() { return OP_Write; }
501
};
502
 
503
/**
504
 * @brief Addition.
505
 */
506
static const char *ADD_OPCODES[2] = {
507
    "????0000100?????????????????????",
508
    "????0010100?????????????????????"
509
};
510
 
511
class ADD : public ArmAddInstruction {
512
 public:
513
    ADD(CpuCortex_Functional *icpu, int opidx) :
514
        ArmAddInstruction(icpu, "ADD", ADD_OPCODES[opidx]) {}
515
 protected:
516
    virtual EOperationResult op_result() { return OP_Write; }
517
    virtual bool with_carry() { return false; }
518
};
519
 
520
/**
521
 * @brief Addition with carry bit.
522
 */
523
static const char *ADC_OPCODES[2] = {
524
    "????0000101?????????????????????",
525
    "????0010101?????????????????????"
526
};
527
 
528
class ADC : public ArmAddInstruction {
529
 public:
530
    ADC(CpuCortex_Functional *icpu, int opidx) :
531
        ArmAddInstruction(icpu, "ADC", ADC_OPCODES[opidx]) {}
532
 protected:
533
    virtual EOperationResult op_result() { return OP_Write; }
534
    virtual bool with_carry() { return true; }
535
};
536
 
537
/**
538
 * @brief Subtruct with carry bit: Op1 - Op2 + C - 1 !!!!!!.
539
 */
540
static const char *SBC_OPCODES[2] = {
541
    "????0000110?????????????????????",
542
    "????0010110?????????????????????"
543
};
544
 
545
class SBC : public ArmSubInstruction {
546
 public:
547
    SBC(CpuCortex_Functional *icpu, int opidx) :
548
        ArmSubInstruction(icpu, "SBC", SBC_OPCODES[opidx]) {}
549
 protected:
550
    virtual bool is_inverted() { return false; }
551
    virtual bool with_carry() { return true; }
552
    virtual EOperationResult op_result() { return OP_Write; }
553
};
554
 
555
/**
556
 * @brief Subtruct right with carry bit: Op2 - Op1 + C - 1 !!!!.
557
 */
558
static const char *RSC_OPCODES[2] = {
559
    "????0000111?????????????????????",
560
    "????0010111?????????????????????"
561
};
562
 
563
class RSC : public ArmSubInstruction {
564
 public:
565
    RSC(CpuCortex_Functional *icpu, int opidx) :
566
        ArmSubInstruction(icpu, "RSC", RSC_OPCODES[opidx]) {}
567
 protected:
568
    virtual bool is_inverted() { return true; }
569
    virtual bool with_carry() { return true; }
570
    virtual EOperationResult op_result() { return OP_Write; }
571
};
572
 
573
/**
574
 * @brief Set condition codes on Op1 AND Op2.
575
 * S-flag must be set otherwise it can be MOVW instruction
576
 */
577
 static const char *TST_OPCODES[2] = {
578
    "????00010001????????????????????",
579
    "????00110001????????????????????"
580
};
581
 
582
class TST : public ArmDataProcessingInstruction {
583
 public:
584
    TST(CpuCortex_Functional *icpu, int opidx) :
585
        ArmDataProcessingInstruction(icpu, "TST", TST_OPCODES[opidx]) {}
586
 protected:
587
    virtual EOperationResult do_operation(uint32_t A, uint32_t M,
588
                                          uint32_t *pRes) {
589
        *pRes = A & M;
590
        return OP_Drop;
591
    }
592
};
593
 
594
/**
595
 * @brief Set condition codes on Op1 EOR Op2.
596
 */
597
static const char *TEQ_OPCODES[2] = {
598
    "????0001001?????????????????????",
599
    "????0011001?????????????????????"
600
};
601
 
602
class TEQ : public ArmDataProcessingInstruction {
603
 public:
604
    TEQ(CpuCortex_Functional *icpu, int opidx) :
605
        ArmDataProcessingInstruction(icpu, "TEQ", TEQ_OPCODES[opidx]) {}
606
 protected:
607
    virtual EOperationResult do_operation(uint32_t A, uint32_t M,
608
                                          uint32_t *pRes) {
609
        *pRes = A ^ M;
610
        return OP_Drop;
611
    }
612
};
613
 
614
/**
615
 * @brief Set condition codes on Op1 - Op2.
616
 */
617
static const char *CMP_OPCODES[2] = {
618
    "????0001010?????????????????????",
619
    "????0011010?????????????????????"
620
};
621
 
622
class CMP : public ArmSubInstruction {
623
 public:
624
    CMP(CpuCortex_Functional *icpu, int opidx) :
625
        ArmSubInstruction(icpu, "CMP", CMP_OPCODES[opidx]) {}
626
 protected:
627
    virtual bool is_inverted() { return false; }
628
    virtual bool with_carry() { return false; }
629
    virtual EOperationResult op_result() { return OP_Drop; }
630
};
631
 
632
/**
633
 * @brief Set condition codes on Op1 + Op2.
634
 */
635
static const char *CMN_OPCODES[2] = {
636
    "????0001011?????????????????????",
637
    "????0011011?????????????????????"
638
};
639
 
640
class CMN : public ArmAddInstruction {
641
 public:
642
    CMN(CpuCortex_Functional *icpu, int opidx) :
643
        ArmAddInstruction(icpu, "CMN", CMN_OPCODES[opidx]) {}
644
 protected:
645
    virtual bool with_carry() { return false; }
646
    virtual EOperationResult op_result() { return OP_Drop; }
647
};
648
 
649
/**
650
 * @brief OR
651
 */
652
static const char *ORR_OPCODES[2] = {
653
    "????0001100?????????????????????",
654
    "????0011100?????????????????????"
655
};
656
 
657
class ORR : public ArmDataProcessingInstruction {
658
 public:
659
    ORR(CpuCortex_Functional *icpu, int opidx) :
660
        ArmDataProcessingInstruction(icpu, "ORR", ORR_OPCODES[opidx]) {}
661
 protected:
662
    virtual EOperationResult do_operation(uint32_t A, uint32_t M,
663
                                          uint32_t *pRes) {
664
        *pRes = A | M;
665
        return OP_Write;
666
    }
667
};
668
 
669
/**
670
 * @brief Move data: Rd = Op2
671
 */
672
static const char *MOV_OPCODES[2] = {
673
    "????0001101?????????????????????",
674
    "????0011101?????????????????????"
675
};
676
 
677
class MOV : public ArmDataProcessingInstruction {
678
 public:
679
    MOV(CpuCortex_Functional *icpu, int opidx) :
680
        ArmDataProcessingInstruction(icpu, "MOV", MOV_OPCODES[opidx]) {}
681
 protected:
682
    virtual EOperationResult do_operation(uint32_t A, uint32_t M,
683
                                          uint32_t *pRes) {
684
        *pRes = M;
685
        return OP_Write;
686
    }
687
};
688
 
689
/** Move Top writes an immediate value to the top halfword of the destination
690
    register. It does not affect the contents of the bottom halfword. */
691
class MOVT : public ArmInstruction {
692
 public:
693
    MOVT(CpuCortex_Functional *icpu) :
694
        ArmInstruction(icpu, "MOVT", "????00110100????????????????????") {}
695
 protected:
696
    virtual int exec_checked(Reg64Type *payload) {
697
        DataProcessingType u;
698
        u.value = payload->buf32[0];
699
        uint32_t imm16 = (u.mov_bits.imm4 << 12) | u.mov_bits.imm12;
700
        R[u.mov_bits.rd] &= ~0xFFFF0000;
701
        R[u.mov_bits.rd] |= (imm16 << 16);
702
        return 4;
703
    }
704
};
705
 
706
/** This new variant of MOV (immediate) writes a 16-bit immediate
707
    value to the destination register */
708
class MOVW : public ArmInstruction {
709
 public:
710
    MOVW(CpuCortex_Functional *icpu) :
711
        ArmInstruction(icpu, "MOVW", "????00110000????????????????????") {}
712
 protected:
713
    virtual int exec_checked(Reg64Type *payload) {
714
        DataProcessingType u;
715
        u.value = payload->buf32[0];
716
        uint32_t imm16 = (u.mov_bits.imm4 << 12) | u.mov_bits.imm12;
717
        R[u.mov_bits.rd] &= ~0xFFFF;
718
        R[u.mov_bits.rd] |= imm16;
719
        return 4;
720
    }
721
};
722
 
723
/** Rd:=Rm*Rs. */
724
class MUL : public MultiplyInstruction {
725
 public:
726
    MUL(CpuCortex_Functional *icpu) : MultiplyInstruction(icpu,
727
        "MUL", "????0000000?????????????1001????") {}
728
};
729
 
730
/** Multiply and accumulate:  Rd:=Rm*Rs+Rn */
731
class MLA : public MultiplyInstruction {
732
 public:
733
    MLA(CpuCortex_Functional *icpu) : MultiplyInstruction(icpu,
734
        "MLA", "????0000001?????????????1001????") {}
735
};
736
 
737
/** Unsigned Multiply Long */
738
class UMULL : public MultiplyLongInstruction {
739
 public:
740
    UMULL(CpuCortex_Functional *icpu) : MultiplyLongInstruction(icpu,
741
        "UMULL", "????0000100?????????????1001????") {}
742
};
743
 
744
/** Unsigned Multiply ^ Accumulate Long */
745
class UMLAL : public MultiplyLongInstruction {
746
 public:
747
    UMLAL(CpuCortex_Functional *icpu) : MultiplyLongInstruction(icpu,
748
        "UMLAL", "????0000101?????????????1001????") {}
749
};
750
 
751
/** Signed Multiply Long */
752
class SMULL : public MultiplyLongInstruction {
753
 public:
754
    SMULL(CpuCortex_Functional *icpu) : MultiplyLongInstruction(icpu,
755
        "SMULL", "????0000110?????????????1001????") {}
756
};
757
 
758
/** Signed Multiply ^ Accumulate Long */
759
class SMLAL : public MultiplyLongInstruction {
760
 public:
761
    SMLAL(CpuCortex_Functional *icpu) : MultiplyLongInstruction(icpu,
762
        "SMLAL", "????0000111?????????????1001????") {}
763
};
764
 
765
/**
766
 * @brief Bit clear: AND NOT
767
 */
768
static const char *BIC_OPCODES[2] = {
769
    "????0001110?????????????????????",
770
    "????0011110?????????????????????"
771
};
772
 
773
class BIC : public ArmDataProcessingInstruction {
774
 public:
775
    BIC(CpuCortex_Functional *icpu, int opidx) :
776
        ArmDataProcessingInstruction(icpu, "BIC", BIC_OPCODES[opidx]) {}
777
 protected:
778
    virtual EOperationResult do_operation(uint32_t A, uint32_t M,
779
                                          uint32_t *pRes) {
780
        *pRes = A & ~M;
781
        return OP_Write;
782
    }
783
};
784
 
785
/**
786
 * @brief Move inverted data: Rd = NOT Op2
787
 */
788
static const char *MVN_OPCODES[2] = {
789
    "????0001111?????????????????????",
790
    "????0011111?????????????????????"
791
};
792
 
793
class MVN : public ArmDataProcessingInstruction {
794
 public:
795
    MVN(CpuCortex_Functional *icpu, int opidx) :
796
        ArmDataProcessingInstruction(icpu, "MVN", MVN_OPCODES[opidx]) {}
797
 protected:
798
    virtual EOperationResult do_operation(uint32_t A, uint32_t M,
799
                                          uint32_t *pRes) {
800
        *pRes = ~M;
801
        return OP_Write;
802
    }
803
};
804
 
805
/** Branch */
806
class B : public ArmInstruction {
807
public:
808
    B(CpuCortex_Functional *icpu) :
809
        ArmInstruction(icpu, "B", "????1010????????????????????????") {}
810
 
811
    virtual int exec_checked(Reg64Type *payload) {
812
        BranchType u;
813
        u.value = payload->buf32[0];
814
        uint32_t off = u.bits.offset;
815
        if ((u.value >> 23) & 0x1) {
816
            off |= 0xFF000000;
817
        }
818
        off = static_cast<uint32_t>(
819
            R[Reg_pc] + (off << 2) + PREFETCH_OFFSET[icpu_->getInstrMode()]);
820
        R[Reg_pc] = off;
821
        icpu_->setBranch(off);
822
        return 4;
823
    }
824
};
825
 
826
/** Branch with Link */
827
class BL : public ArmInstruction {
828
public:
829
    BL(CpuCortex_Functional *icpu) :
830
        ArmInstruction(icpu, "BL", "????1011????????????????????????") {}
831
 
832
    virtual int exec_checked(Reg64Type *payload) {
833
        BranchType u;
834
        u.value = payload->buf32[0];
835
        R[Reg_lr] = R[Reg_pc] + 4;
836
        uint32_t off = u.bits.offset;
837
        if ((u.value >> 23) & 0x1) {
838
            off |= 0xFF000000;
839
        }
840
        off = static_cast<uint32_t>(
841
            R[Reg_pc] + (off << 2) + PREFETCH_OFFSET[icpu_->getInstrMode()]);
842
        R[Reg_pc] = off;
843
        icpu_->setBranch(off);
844
        return 4;
845
    }
846
};
847
 
848
/** Branch and Exchange */
849
class BX : public ArmInstruction {
850
public:
851
    BX(CpuCortex_Functional *icpu) :
852
        ArmInstruction(icpu, "BX", "????000100101111111111110001????") {}
853
 
854
    virtual int exec_checked(Reg64Type *payload) {
855
        BranchType u;
856
        u.value = payload->buf32[0];
857
        uint32_t off = static_cast<uint32_t>(R[u.bits.offset & 0xf]);
858
        if (off & 0x1) {
859
            icpu_->setInstrMode(THUMB_mode);
860
        } else {
861
            icpu_->setInstrMode(ARM_mode);
862
        }
863
        R[Reg_pc] = off;
864
        icpu_->setBranch(off);
865
        return 4;
866
    }
867
};
868
 
869
/** Load word pre-adding immediate offset to base register */
870
static const char *LDR_OPCODES[4] = {
871
    "????0100???1????????????????????", // immedaiate, post incr
872
    "????0101???1????????????????????", // immedaiate, pre incr
873
    "????0110???1????????????????????", // shift reg, post incr
874
    "????0111???1????????????????????", // shift reg, pre incr
875
};
876
 
877
class LDR : public SingleDataTransferInstruction {
878
public:
879
    LDR(CpuCortex_Functional *icpu, int opidx) :
880
        SingleDataTransferInstruction(icpu, "LDR", LDR_OPCODES[opidx]) {}
881
};
882
 
883
/** Load Signed Byte */
884
static const char *LDRSB_OPCODES[4] = {
885
    "????0000???1????????????1101????", // post incr
886
    "????0001???1????????????1101????", // pre incr
887
};
888
 
889
class LDRSB : public HWordSignedDataTransferInstruction {
890
public:
891
    LDRSB(CpuCortex_Functional *icpu, int opidx) :
892
        HWordSignedDataTransferInstruction(icpu, "LDRSB", LDRSB_OPCODES[opidx])
893
        {}
894
};
895
 
896
/** Load Unsigned Half-Word */
897
static const char *LDRH_OPCODES[4] = {
898
    "????0000???1????????????1011????", // post incr
899
    "????0001???1????????????1011????", // pre incr
900
};
901
 
902
class LDRH : public HWordSignedDataTransferInstruction {
903
public:
904
    LDRH(CpuCortex_Functional *icpu, int opidx) :
905
        HWordSignedDataTransferInstruction(icpu, "LDRH", LDRH_OPCODES[opidx])
906
        {}
907
};
908
 
909
/** Load Signed Half-word */
910
static const char *LDRSH_OPCODES[4] = {
911
    "????0000???1????????????1111????", // post incr
912
    "????0001???1????????????1111????", // pre incr
913
};
914
 
915
class LDRSH : public HWordSignedDataTransferInstruction {
916
public:
917
    LDRSH(CpuCortex_Functional *icpu, int opidx) :
918
        HWordSignedDataTransferInstruction(icpu, "LDRSH", LDRSB_OPCODES[opidx])
919
        {}
920
};
921
 
922
/** Load Block data */
923
static const char *LDM_OPCODES[4] = {
924
    "????1000???1????????????????????", // post incr
925
    "????1001???1????????????????????", // pre incr
926
};
927
 
928
class LDM : public BlockDataTransferInstruction {
929
 public:
930
    LDM(CpuCortex_Functional *icpu, int opidx) :
931
        BlockDataTransferInstruction(icpu, "LDM", LDM_OPCODES[opidx]) {}
932
};
933
 
934
 
935
 
936
/** Store word */
937
static const char *STR_OPCODES[4] = {
938
    "????0100?0?0????????????????????", // immedaiate, post incr
939
    "????0101?0?0????????????????????", // immedaiate, pre incr
940
    "????0110?0?0????????????????????", // shift reg, post incr
941
    "????0111?0?0????????????????????", // shift reg, pre incr
942
};
943
 
944
class STR : public SingleDataTransferInstruction {
945
public:
946
    STR(CpuCortex_Functional *icpu, int opidx) :
947
        SingleDataTransferInstruction(icpu, "STR", STR_OPCODES[opidx]) {}
948
};
949
 
950
/** Store Byte */
951
static const char *STRB_OPCODES[4] = {
952
    "????0100?1?0????????????????????", // immedaiate, post incr
953
    "????0101?1?0????????????????????", // immedaiate, pre incr
954
    "????0110?1?0????????????????????", // shift reg, post incr
955
    "????0111?1?0????????????????????", // shift reg, pre incr
956
};
957
 
958
class STRB : public SingleDataTransferInstruction {
959
public:
960
    STRB(CpuCortex_Functional *icpu, int opidx) :
961
        SingleDataTransferInstruction(icpu, "STRB", STRB_OPCODES[opidx]) {}
962
};
963
 
964
/** Store Half-Word */
965
static const char *STRH_OPCODES[4] = {
966
    "????0000???0????????????1?11????", // post incr
967
    "????0001???0????????????1?11????", // pre incr
968
};
969
 
970
class STRH : public HWordSignedDataTransferInstruction {
971
public:
972
    STRH(CpuCortex_Functional *icpu, int opidx) :
973
        HWordSignedDataTransferInstruction(icpu, "STRH", STRH_OPCODES[opidx])
974
        {}
975
};
976
 
977
/** Store Block data */
978
static const char *STM_OPCODES[4] = {
979
    "????1000???0????????????????????", // post incr
980
    "????1001???0????????????????????", // pre incr
981
};
982
 
983
class STM : public BlockDataTransferInstruction {
984
 public:
985
    STM(CpuCortex_Functional *icpu, int opidx) :
986
        BlockDataTransferInstruction(icpu, "STM", STM_OPCODES[opidx]) {}
987
};
988
 
989
/** Move from coprocessor to ARM7TDMI-S register (L=1) */
990
class MRC : public ArmInstruction {
991
 public:
992
    MRC(CpuCortex_Functional *icpu) :
993
        ArmInstruction(icpu, "MRC", "????1110???1???????????????1????") {}
994
 
995
    virtual int exec_checked(Reg64Type *payload) {
996
        CoprocessorTransferType u;
997
        u.value = payload->buf32[0];
998
        return 4;
999
    }
1000
};
1001
 
1002
/** Move from ARM7TDMI-S register to coprocessor (L=0) */
1003
class MCR : public ArmInstruction {
1004
 public:
1005
    MCR(CpuCortex_Functional *icpu) :
1006
        ArmInstruction(icpu, "MRC", "????1110???0???????????????1????") {}
1007
 
1008
    virtual int exec_checked(Reg64Type *payload) {
1009
        CoprocessorTransferType u;
1010
        u.value = payload->buf32[0];
1011
        return 4;
1012
    }
1013
};
1014
 
1015
/**
1016
 * @brief Transfer register to PSR flags.
1017
 */
1018
static const char *MSR_OPCODES[2] = {
1019
    "????00010?10????1111????????????",
1020
    "????00110?10????1111????????????"
1021
};
1022
 
1023
class MSR : public ArmInstruction {
1024
public:
1025
    MSR(CpuCortex_Functional *icpu, int opidx) :
1026
        ArmInstruction(icpu, "MSR", MSR_OPCODES[opidx]) {}
1027
 
1028
    virtual int exec_checked(Reg64Type *payload) {
1029
        PsrTransferType u;
1030
        u.value = payload->buf32[0];
1031
        return 4;
1032
    }
1033
};
1034
 
1035
class MRS : public ArmInstruction {
1036
public:
1037
    MRS(CpuCortex_Functional *icpu) :
1038
        ArmInstruction(icpu, "MRS", "????00010?001111????000000000000") {}
1039
 
1040
    virtual int exec_checked(Reg64Type *payload) {
1041
        PsrTransferType u;
1042
        u.value = payload->buf32[0];
1043
        return 4;
1044
    }
1045
};
1046
 
1047
class NOP : public ArmInstruction {
1048
public:
1049
    NOP(CpuCortex_Functional *icpu) :
1050
        ArmInstruction(icpu, "NOP", "????0011001000001111000000000000") {}
1051
 
1052
    virtual int exec_checked(Reg64Type *payload) {
1053
        return 4;
1054
    }
1055
};
1056
 
1057
/** Bytes zero-extending
1058
 UXTB extracts an 8-bit value from a register and zero extends it to 32 bits.
1059
 You can specify a rotation by 0, 8, 16, or 24 bits before extracting
1060
 the 8-bit value.
1061
 */
1062
class UXTB : public ArmInstruction {
1063
public:
1064
    UXTB(CpuCortex_Functional *icpu) :
1065
        ArmInstruction(icpu, "UXTB", "????011011101111????????0111????") {}
1066
 
1067
    virtual int exec_checked(Reg64Type *payload) {
1068
        SignExtendType u;
1069
        u.value = payload->buf32[0];
1070
        uint64_t t1 = (R[u.bits.rm] & 0xFFFFFFFF) >> (8*u.bits.rotate);
1071
        t1 = (R[u.bits.rm] << (32 - 8*u.bits.rotate)) | t1;
1072
        t1 &= 0xFF;
1073
        R[u.bits.rd] = static_cast<uint32_t>(t1);
1074
        return 4;
1075
    }
1076
};
1077
 
1078
/** */
1079
class UXTAB : public ArmInstruction {
1080
public:
1081
    UXTAB(CpuCortex_Functional *icpu) :
1082
        ArmInstruction(icpu, "UXTAB", "????01101110????????????0111????") {}
1083
 
1084
    virtual int exec_checked(Reg64Type *payload) {
1085
        SignExtendType u;
1086
        u.value = payload->buf32[0];
1087
        uint64_t t1 = (R[u.bits.rm] & 0xFFFFFFFF) >> (8*u.bits.rotate);
1088
        t1 = (R[u.bits.rm] << (32 - 8*u.bits.rotate)) | t1;
1089
        t1 &= 0xFF;
1090
        R[u.bits.rd] = R[u.bits.rn] + static_cast<uint32_t>(t1);
1091
        return 4;
1092
    }
1093
};
1094
 
1095
/** UXTB16 extracts two 8-bit values from a register and zero extends them
1096
  to 16 bits each. You can specify a rotation by 0, 8, 16, or 24 bits before
1097
  extracting the 8-bit values.
1098
 */
1099
class UXTB16 : public ArmInstruction {
1100
public:
1101
    UXTB16(CpuCortex_Functional *icpu) :
1102
        ArmInstruction(icpu, "UXTB16", "????011011001111????????0111????") {}
1103
 
1104
    virtual int exec_checked(Reg64Type *payload) {
1105
        SignExtendType u;
1106
        u.value = payload->buf32[0];
1107
        uint64_t t1 = (R[u.bits.rm] & 0xFFFFFFFF) >> (8*u.bits.rotate);
1108
        t1 = (R[u.bits.rm] << (32 - 8*u.bits.rotate)) | t1;
1109
        t1 &= 0x00FF00FF;
1110
        R[u.bits.rd] = static_cast<uint32_t>(t1);
1111
        return 4;
1112
    }
1113
};
1114
 
1115
/** UXTAB16 extracts two 8-bit values from a register, zero extends them
1116
 to 16 bits each, and adds the results to the two values from another
1117
 register. You can specify a rotation by 0, 8, 16, or 24 bits before
1118
 extracting the 8-bit values.
1119
 */
1120
class UXTAB16 : public ArmInstruction {
1121
public:
1122
    UXTAB16(CpuCortex_Functional *icpu) :
1123
        ArmInstruction(icpu, "UXTAB16", "????01101100????????????0111????") {}
1124
 
1125
    virtual int exec_checked(Reg64Type *payload) {
1126
        SignExtendType u;
1127
        u.value = payload->buf32[0];
1128
        uint64_t t1 = (R[u.bits.rm] & 0xFFFFFFFF) >> (8*u.bits.rotate);
1129
        t1 = (R[u.bits.rm] << (32 - 8*u.bits.rotate)) | t1;
1130
        uint32_t a = (R[u.bits.rd] & 0xFFFF) + (t1 & 0xFF);
1131
        uint32_t b = ((R[u.bits.rd] >> 16) & 0xFFFF) + ((t1 >> 16) & 0xFF);
1132
        R[u.bits.rd] = (b << 16) | a;
1133
        return 4;
1134
    }
1135
};
1136
 
1137
 
1138
/** UXTH extracts a 16-bit value from a register and zero extends it
1139
 to 32 bits. You can specify a rotation by 0, 8, 16, or 24 bits before
1140
 extracting the 16-bit value.
1141
 */
1142
class UXTH : public ArmInstruction {
1143
public:
1144
    UXTH(CpuCortex_Functional *icpu) :
1145
        ArmInstruction(icpu, "UXTH", "????011011111111????????0111????") {}
1146
 
1147
    virtual int exec_checked(Reg64Type *payload) {
1148
        SignExtendType u;
1149
        u.value = payload->buf32[0];
1150
        uint64_t t1 = (R[u.bits.rm] & 0xFFFFFFFF) >> (8*u.bits.rotate);
1151
        t1 = (R[u.bits.rm] << (32 - 8*u.bits.rotate)) | t1;
1152
        t1 &= 0xFFFF;
1153
        R[u.bits.rd] = static_cast<uint32_t>(t1);
1154
        return 4;
1155
    }
1156
};
1157
 
1158
/** UXTAH extracts a 16-bit value from a register, zero extends it to 32 bits,
1159
 and adds the result to a value in another register. You can specify a
1160
 rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
1161
 */
1162
class UXTAH : public ArmInstruction {
1163
public:
1164
    UXTAH(CpuCortex_Functional *icpu) :
1165
        ArmInstruction(icpu, "UXTAH", "????01101111????????????0111????") {}
1166
 
1167
    virtual int exec_checked(Reg64Type *payload) {
1168
        SignExtendType u;
1169
        u.value = payload->buf32[0];
1170
        uint64_t t1 = (R[u.bits.rm] & 0xFFFFFFFF) >> (8*u.bits.rotate);
1171
        t1 = (R[u.bits.rm] << (32 - 8*u.bits.rotate)) | t1;
1172
        t1 &= 0xFFFF;
1173
        R[u.bits.rd] = R[u.bits.rn] + static_cast<uint32_t>(t1);
1174
        return 4;
1175
    }
1176
};
1177
 
1178
 
1179
/**
1180
 * @brief SWI (software breakpoint instruction)
1181
 *
1182
 */
1183
class SWI : public ArmInstruction {
1184
 public:
1185
    SWI(CpuCortex_Functional *icpu) :
1186
        ArmInstruction(icpu, "SWI", "????1110???1???????????????1????") {}
1187
 
1188
    virtual int exec_checked(Reg64Type *payload) {
1189
        icpu_->raiseSoftwareIrq();
1190
        return 4;
1191
    }
1192
};
1193
 
1194
 
1195
 
1196
void CpuCortex_Functional::addArm7tmdiIsa() {
1197
 
1198
    // Arm V6 instructions:
1199
    //      CPS, SRS, RFE
1200
    //      REV, REV16, REVSH
1201
    //      SETEND
1202
    //      LDREX, STREX
1203
    //      SXTB, SXTH, UXTB, UXTH
1204
    addSupportedInstruction(new UXTB(this));    // same opcode as STRB
1205
    addSupportedInstruction(new UXTAB(this));
1206
    addSupportedInstruction(new UXTB16(this));  // rn=1111b
1207
    addSupportedInstruction(new UXTAB16(this));  // rn=????b
1208
    addSupportedInstruction(new UXTH(this));    // rn=1111b
1209
    addSupportedInstruction(new UXTAH(this));   // rn=????
1210
 
1211
    // use the same as opcodes TEQ, TST, CMN and CMP without S-flag
1212
    // and must be registered first.
1213
    addSupportedInstruction(new BX(this));  // use TST,MSR opcode
1214
    addSupportedInstruction(new NOP(this)); // use MSR opcode
1215
    addSupportedInstruction(new MOVT(this));
1216
    addSupportedInstruction(new MOVW(this));
1217
    addSupportedInstruction(new MUL(this));
1218
    addSupportedInstruction(new MLA(this));
1219
    addSupportedInstruction(new UMULL(this));
1220
    addSupportedInstruction(new UMLAL(this));
1221
    addSupportedInstruction(new SMULL(this));
1222
    addSupportedInstruction(new SMLAL(this));
1223
    addSupportedInstruction(new MRS(this));
1224
    addSupportedInstruction(new MSR(this, 0));
1225
    addSupportedInstruction(new MSR(this, 1));
1226
 
1227
    addSupportedInstruction(new AND(this, 0));
1228
    addSupportedInstruction(new AND(this, 1));
1229
    addSupportedInstruction(new EOR(this, 0));
1230
    addSupportedInstruction(new EOR(this, 1));
1231
    addSupportedInstruction(new SUB(this, 0));
1232
    addSupportedInstruction(new SUB(this, 1));
1233
    addSupportedInstruction(new RSB(this, 0));
1234
    addSupportedInstruction(new RSB(this, 1));
1235
    addSupportedInstruction(new ADD(this, 0));
1236
    addSupportedInstruction(new ADD(this, 1));
1237
    addSupportedInstruction(new ADC(this, 0));
1238
    addSupportedInstruction(new ADC(this, 1));
1239
    addSupportedInstruction(new SBC(this, 0));
1240
    addSupportedInstruction(new SBC(this, 1));
1241
    addSupportedInstruction(new RSC(this, 0));
1242
    addSupportedInstruction(new RSC(this, 1));
1243
    addSupportedInstruction(new TST(this, 0));
1244
    addSupportedInstruction(new TST(this, 1));
1245
    addSupportedInstruction(new TEQ(this, 0));
1246
    addSupportedInstruction(new TEQ(this, 1));
1247
    addSupportedInstruction(new CMP(this, 0));
1248
    addSupportedInstruction(new CMP(this, 1));
1249
    addSupportedInstruction(new CMN(this, 0));
1250
    addSupportedInstruction(new CMN(this, 1));
1251
    addSupportedInstruction(new ORR(this, 0));
1252
    addSupportedInstruction(new ORR(this, 1));
1253
    addSupportedInstruction(new MOV(this, 0));
1254
    addSupportedInstruction(new MOV(this, 1));
1255
    addSupportedInstruction(new BIC(this, 0));
1256
    addSupportedInstruction(new BIC(this, 1));
1257
    addSupportedInstruction(new MVN(this, 0));
1258
    addSupportedInstruction(new MVN(this, 1));
1259
    addSupportedInstruction(new B(this));
1260
    addSupportedInstruction(new BL(this));
1261
    addSupportedInstruction(new LDR(this, 0));
1262
    addSupportedInstruction(new LDR(this, 1));
1263
    addSupportedInstruction(new LDR(this, 2));
1264
    addSupportedInstruction(new LDR(this, 3));
1265
    addSupportedInstruction(new LDRSB(this, 0));
1266
    addSupportedInstruction(new LDRSB(this, 1));
1267
    addSupportedInstruction(new LDRH(this, 0));
1268
    addSupportedInstruction(new LDRH(this, 1));
1269
    addSupportedInstruction(new LDRSH(this, 0));
1270
    addSupportedInstruction(new LDRSH(this, 1));
1271
    addSupportedInstruction(new LDM(this, 0));
1272
    addSupportedInstruction(new LDM(this, 1));
1273
    addSupportedInstruction(new STR(this, 0));
1274
    addSupportedInstruction(new STR(this, 1));
1275
    addSupportedInstruction(new STR(this, 2));
1276
    addSupportedInstruction(new STR(this, 3));
1277
    addSupportedInstruction(new STRB(this, 0));
1278
    addSupportedInstruction(new STRB(this, 1));
1279
    addSupportedInstruction(new STRB(this, 2));
1280
    addSupportedInstruction(new STRB(this, 3));
1281
    addSupportedInstruction(new STRH(this, 0));
1282
    addSupportedInstruction(new STRH(this, 1));
1283
    addSupportedInstruction(new STM(this, 0));
1284
    addSupportedInstruction(new STM(this, 1));
1285
    addSupportedInstruction(new MCR(this));
1286
    addSupportedInstruction(new MRC(this));
1287
    addSupportedInstruction(new SWI(this));
1288
}
1289
 
1290
}  // namespace debugger

powered by: WebSVN 2.1.0

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