v6m virtual machine
Import programemu812
mbed LPC812 emulator pre-alpha version
Import programemu1114
mbed LPC1114 emulator pre-alpha version
BaseV6M.h@5:65d77b2e6bc7, 2016-04-01 (annotated)
- Committer:
- va009039
- Date:
- Fri Apr 01 11:12:29 2016 +0900
- Revision:
- 5:65d77b2e6bc7
- Parent:
- 4:1c7b72bcfc4d
remove assert code.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
va009039 |
4:1c7b72bcfc4d | 1 | // BaseV6M.h 2015/8/27 |
va009039 |
1:5fa0120a6169 | 2 | #pragma once |
va009039 |
1:5fa0120a6169 | 3 | #include <stdint.h> |
va009039 |
1:5fa0120a6169 | 4 | |
va009039 |
1:5fa0120a6169 | 5 | #define _SP 13 |
va009039 |
1:5fa0120a6169 | 6 | #define _LR 14 |
va009039 |
1:5fa0120a6169 | 7 | #define _PC 15 |
va009039 |
1:5fa0120a6169 | 8 | #define _xPSR 16 |
va009039 |
1:5fa0120a6169 | 9 | #define _IM 17 |
va009039 |
1:5fa0120a6169 | 10 | #define _NL 18 |
va009039 |
1:5fa0120a6169 | 11 | |
va009039 |
1:5fa0120a6169 | 12 | class BaseV6M { |
va009039 |
1:5fa0120a6169 | 13 | public: |
va009039 |
1:5fa0120a6169 | 14 | BaseV6M(); |
va009039 |
1:5fa0120a6169 | 15 | void fetch(); |
va009039 |
1:5fa0120a6169 | 16 | void execute(); |
va009039 |
1:5fa0120a6169 | 17 | void reset(); |
va009039 |
1:5fa0120a6169 | 18 | void run(int step); |
va009039 |
1:5fa0120a6169 | 19 | |
va009039 |
1:5fa0120a6169 | 20 | protected: |
va009039 |
1:5fa0120a6169 | 21 | virtual void poke32(uint32_t a, uint32_t d) = 0; |
va009039 |
1:5fa0120a6169 | 22 | virtual uint32_t peek32(uint32_t a) = 0; |
va009039 |
1:5fa0120a6169 | 23 | virtual void poke8(uint32_t a, uint8_t d) = 0; |
va009039 |
1:5fa0120a6169 | 24 | virtual uint8_t peek8(uint32_t a) = 0; |
va009039 |
1:5fa0120a6169 | 25 | |
va009039 |
1:5fa0120a6169 | 26 | virtual void poke16(uint32_t a, uint16_t w) { |
va009039 |
1:5fa0120a6169 | 27 | poke8(a, w & 0xff); |
va009039 |
1:5fa0120a6169 | 28 | poke8(a+1, w>>8); |
va009039 |
1:5fa0120a6169 | 29 | } |
va009039 |
1:5fa0120a6169 | 30 | virtual uint16_t peek16(uint32_t a) { |
va009039 |
1:5fa0120a6169 | 31 | return peek8(a) | peek8(a+1)<<8; |
va009039 |
1:5fa0120a6169 | 32 | } |
va009039 |
1:5fa0120a6169 | 33 | |
va009039 |
1:5fa0120a6169 | 34 | const char* GetRegName(uint32_t* pR); |
va009039 |
1:5fa0120a6169 | 35 | int GetRegIndex(uint32_t* pR); |
va009039 |
1:5fa0120a6169 | 36 | const char* StrRegLists() { |
va009039 |
1:5fa0120a6169 | 37 | return "todo"; |
va009039 |
1:5fa0120a6169 | 38 | } |
va009039 |
1:5fa0120a6169 | 39 | uint32_t R[16+1+2]; |
va009039 |
1:5fa0120a6169 | 40 | uint32_t* Rd; |
va009039 |
1:5fa0120a6169 | 41 | uint32_t* Rn; |
va009039 |
1:5fa0120a6169 | 42 | uint32_t* Rm; |
va009039 |
1:5fa0120a6169 | 43 | uint32_t code, code2nd; |
va009039 |
1:5fa0120a6169 | 44 | uint32_t cycle; |
va009039 |
1:5fa0120a6169 | 45 | uint32_t N(); |
va009039 |
1:5fa0120a6169 | 46 | uint32_t Z(); |
va009039 |
1:5fa0120a6169 | 47 | uint32_t C(); |
va009039 |
1:5fa0120a6169 | 48 | uint32_t V(); |
va009039 |
1:5fa0120a6169 | 49 | |
va009039 |
1:5fa0120a6169 | 50 | private: |
va009039 |
1:5fa0120a6169 | 51 | template<class T> |
va009039 |
1:5fa0120a6169 | 52 | void poke(uint32_t addr, T data) { |
va009039 |
1:5fa0120a6169 | 53 | switch(sizeof(T)) { |
va009039 |
1:5fa0120a6169 | 54 | case 4: poke32(addr, data); break; |
va009039 |
1:5fa0120a6169 | 55 | case 2: poke16(addr, data); break; |
va009039 |
1:5fa0120a6169 | 56 | case 1: poke8(addr, data); break; |
va009039 |
1:5fa0120a6169 | 57 | } |
va009039 |
1:5fa0120a6169 | 58 | /* NOTREACHED */ |
va009039 |
1:5fa0120a6169 | 59 | } |
va009039 |
1:5fa0120a6169 | 60 | template<class T> |
va009039 |
1:5fa0120a6169 | 61 | T peek(uint32_t addr) { |
va009039 |
1:5fa0120a6169 | 62 | switch(sizeof(T)) { |
va009039 |
1:5fa0120a6169 | 63 | case 4: return peek32(addr); |
va009039 |
1:5fa0120a6169 | 64 | case 2: return peek16(addr); |
va009039 |
1:5fa0120a6169 | 65 | case 1: return peek8(addr); |
va009039 |
1:5fa0120a6169 | 66 | } |
va009039 |
1:5fa0120a6169 | 67 | /* NOTREACHED */ |
va009039 |
1:5fa0120a6169 | 68 | } |
va009039 |
1:5fa0120a6169 | 69 | uint32_t op; |
va009039 |
1:5fa0120a6169 | 70 | uint32_t reg_list; |
va009039 |
1:5fa0120a6169 | 71 | bool cache; |
va009039 |
1:5fa0120a6169 | 72 | void Cin(uint32_t c); |
va009039 |
1:5fa0120a6169 | 73 | void NZupdate(uint32_t d); |
va009039 |
1:5fa0120a6169 | 74 | void NZCVupdate(uint32_t d, uint32_t n, uint32_t m); |
va009039 |
1:5fa0120a6169 | 75 | void jump(uint32_t addr); |
va009039 |
1:5fa0120a6169 | 76 | void exception_entry(uint32_t num); |
va009039 |
1:5fa0120a6169 | 77 | void exception_return(); |
va009039 |
1:5fa0120a6169 | 78 | void push(uint32_t d); |
va009039 |
1:5fa0120a6169 | 79 | uint32_t pop(); |
va009039 |
1:5fa0120a6169 | 80 | |
va009039 |
1:5fa0120a6169 | 81 | void d_Rn_Rd(uint32_t code); // decode leaf |
va009039 |
1:5fa0120a6169 | 82 | void d_Op_H_Rm(uint32_t code); // BX Rm / BLX Rm |
va009039 |
1:5fa0120a6169 | 83 | void d_imm3_Rn_Rd(uint32_t code); // ADD Rd,Rn,#imm3 |
va009039 |
1:5fa0120a6169 | 84 | void d_Rd_imm8(uint32_t code); // <Op> Rd,#imm8 / LDR rd,[pc,#imm8] |
va009039 |
1:5fa0120a6169 | 85 | void d_Rn_imm8(uint32_t code); // <Op> Rn,#imm8 |
va009039 |
1:5fa0120a6169 | 86 | void d_imm5_Rn_Rd(uint32_t code); // LSL Rd,Rn,#imm5 / LDR Rd,[Rn,#imm5] |
va009039 |
1:5fa0120a6169 | 87 | void d_Op_Rm_Rd(uint32_t code); // <Op> Rd,Rm |
va009039 |
1:5fa0120a6169 | 88 | void d_Op_imm7(uint32_t code); // ADD|SUB sp,sp,#imm7 |
va009039 |
1:5fa0120a6169 | 89 | void d_D_M_Rm_Rd(uint32_t code); // ADD|CMP|MOV Rd,Rm |
va009039 |
1:5fa0120a6169 | 90 | void d_Rm_Rn_Rd(uint32_t code); // LDR Rd,[Rn,Rm] |
va009039 |
1:5fa0120a6169 | 91 | void d_reg_list(uint32_t code); // PUSH / POP |
va009039 |
1:5fa0120a6169 | 92 | void d_Rn_reg_list(uint32_t code); // LDM / STM |
va009039 |
4:1c7b72bcfc4d | 93 | void d32_Rd_SYSm(uint32_t code, uint32_t code2nd); // MRS |
va009039 |
4:1c7b72bcfc4d | 94 | void d32_Rn_SYSm(uint32_t code, uint32_t code2nd); // MSR |
va009039 |
1:5fa0120a6169 | 95 | void e_adc(); // ADC Rd,Rn,Rm|imm |
va009039 |
1:5fa0120a6169 | 96 | void e_sbc(); // SBC Rd,Rn,Rm|imm |
va009039 |
1:5fa0120a6169 | 97 | void e_add(); // ADD Rd,Rn,Rm|imm |
va009039 |
1:5fa0120a6169 | 98 | void e_sub(); // SUB Rd,Rn,Rm|imm |
va009039 |
1:5fa0120a6169 | 99 | void e_cmp(); // CMP Rn,Rm|imm |
va009039 |
1:5fa0120a6169 | 100 | void e_cmn(); // CMN Rn,Rm|imm |
va009039 |
1:5fa0120a6169 | 101 | void e_and(); // AND Rd,Rn,Rm|imm |
va009039 |
1:5fa0120a6169 | 102 | void e_tst(); // TST Rn,Rm|imm |
va009039 |
1:5fa0120a6169 | 103 | void e_lsl(); // LSL Rd,Rn,Rm|imm |
va009039 |
1:5fa0120a6169 | 104 | void e_lsr(); // LSR Rd,Rn,Rm|imm |
va009039 |
1:5fa0120a6169 | 105 | void e_asr(); // ASR Rd,Rn,Rm|imm |
va009039 |
1:5fa0120a6169 | 106 | void e_ror(); // ROR Rd,Rn,Rm|imm |
va009039 |
1:5fa0120a6169 | 107 | void e_orr(); // ORR Rd,Rn,Rm|imm |
va009039 |
1:5fa0120a6169 | 108 | void e_eor(); // EOR Rd,Rn,Rm|imm |
va009039 |
1:5fa0120a6169 | 109 | void e_mul(); // MUL Rd,Rn,Rm |
va009039 |
1:5fa0120a6169 | 110 | void e_bic(); // BIC Rd,Rn,Rm|imm |
va009039 |
1:5fa0120a6169 | 111 | void e_mov(); // MOV Rd,Rm|imm |
va009039 |
1:5fa0120a6169 | 112 | void e_neg(); // NEG |
va009039 |
1:5fa0120a6169 | 113 | void e_mvn(); // MVN |
va009039 |
1:5fa0120a6169 | 114 | void c_beq(uint32_t code); // BEQ #0xd000-0xd0ff |
va009039 |
1:5fa0120a6169 | 115 | void c_bne(uint32_t code); // BNE 0xd100-0xd1ff |
va009039 |
1:5fa0120a6169 | 116 | void c_bcs(uint32_t code); // BCS #0xd200-0xd2ff |
va009039 |
1:5fa0120a6169 | 117 | void c_bcc(uint32_t code); // BCC #0xd300-0xd3ff |
va009039 |
1:5fa0120a6169 | 118 | void c_bmi(uint32_t code); // BMI 0xd400-0xd4ff |
va009039 |
1:5fa0120a6169 | 119 | void c_bpl(uint32_t code); // BMI 0xd500-0xd5ff |
va009039 |
1:5fa0120a6169 | 120 | void c_bvs(uint32_t code); // BVS 0xd600-0xd6ff |
va009039 |
1:5fa0120a6169 | 121 | void c_bvc(uint32_t code); // BVC 0xd700-0xd7ff |
va009039 |
1:5fa0120a6169 | 122 | void c_bhi(uint32_t code); // BHI 0xd800-0xd8ff |
va009039 |
1:5fa0120a6169 | 123 | void c_bls(uint32_t code); // BLS 0xd900-0xd9ff |
va009039 |
1:5fa0120a6169 | 124 | void c_bge(uint32_t code); // BGE 0xda00-0xdaff |
va009039 |
1:5fa0120a6169 | 125 | void c_blt(uint32_t code); // BLT 0xdb00-0xdbff |
va009039 |
1:5fa0120a6169 | 126 | void c_bgt(uint32_t code); // BGT 0xdc00-0xdcff |
va009039 |
1:5fa0120a6169 | 127 | void c_ble(uint32_t code); // BLE 0xdd00-0xddff |
va009039 |
1:5fa0120a6169 | 128 | void c_b_forward(uint32_t code); // B 0xe000-0xe3ff |
va009039 |
1:5fa0120a6169 | 129 | void c_b_backward(uint32_t code); // B 0xe400-0xe7ff |
va009039 |
4:1c7b72bcfc4d | 130 | void c32_bl_forward(uint32_t code); // BL 0xf000-0xf2ff |
va009039 |
4:1c7b72bcfc4d | 131 | void c32_bl_forward3(uint32_t code); // BL 0xf300-0xf3ff |
va009039 |
4:1c7b72bcfc4d | 132 | void c32_mrs(uint32_t code, uint32_t code2nd); |
va009039 |
4:1c7b72bcfc4d | 133 | void c32_msr(uint32_t code, uint32_t code2nd); |
va009039 |
4:1c7b72bcfc4d | 134 | void c32_dsb_dmb_isb(uint32_t code, uint32_t code2nd); |
va009039 |
4:1c7b72bcfc4d | 135 | void c32_bl_backward(uint32_t code); // BL 0xf400-0xf7ff |
va009039 |
1:5fa0120a6169 | 136 | void c_bx(uint32_t code); // BX BLX 0x4770 |
va009039 |
1:5fa0120a6169 | 137 | void c_add(uint32_t code); // ADDS Rd,Rn,Rm 0x1800-0x19ff |
va009039 |
1:5fa0120a6169 | 138 | void c_sub(uint32_t code); // SUBS Rd,Rn,Rm 0x1a00-0x1bff |
va009039 |
1:5fa0120a6169 | 139 | void c_add1(uint32_t code); // ADD Rd,Rn,#imm3 / MOV Rd,Rn 0x1c00-0x1dff |
va009039 |
1:5fa0120a6169 | 140 | void c_sub1(uint32_t code); // SUB Rd,Rn,#imm3 0x1e00-1fff |
va009039 |
1:5fa0120a6169 | 141 | void c_add2(uint32_t code); // ADD Rd,#imm8 0x3000-0x37ff |
va009039 |
1:5fa0120a6169 | 142 | void c_sub2(uint32_t code); // SUB Rd,#imm8 0x3800-0x3fff |
va009039 |
1:5fa0120a6169 | 143 | void c_mov(uint32_t code); // MOVS Rd,#imm8 0x2000-0x27ff |
va009039 |
1:5fa0120a6169 | 144 | void c_cmp(uint32_t code); // CMP Rn,#imm8 0x2800-0x2fff |
va009039 |
1:5fa0120a6169 | 145 | void c_lsl(uint32_t code); // LSLS Rd,Rn,#imm5 0x0000-0x07ff |
va009039 |
1:5fa0120a6169 | 146 | void c_lsr(uint32_t code); // LSRS Rd,Rn,#imm5 0x0800-0x0fff |
va009039 |
1:5fa0120a6169 | 147 | void c_asr(uint32_t code); // ASRS Rd,Rn,#imm5 0x1000-0x17ff |
va009039 |
1:5fa0120a6169 | 148 | void c_and_eor_lsl_lsr(uint32_t code); // ANDS|EORS|LSLS|LSRS Rd,Rm 0x4000-0x40ff |
va009039 |
1:5fa0120a6169 | 149 | void c_asr_adc_sbc_ror(uint32_t code); // ASRS|ADCS|SBCS|RORS Rd,Rm 0x4100-0x41ff |
va009039 |
1:5fa0120a6169 | 150 | void c_tst_neg_cmp_cmn(uint32_t code); // TST|NEGS|CMP|CMN Rd,Rm 0x4200-0x42ff |
va009039 |
1:5fa0120a6169 | 151 | void c_orr_mul_bic_mvn(uint32_t code); // ORRS|MULS|BICS|MVNS Rd,Rm 0x4300-0x43ff |
va009039 |
1:5fa0120a6169 | 152 | void c_add_hr(uint32_t code); // ADD Rd,Rm (high reg) 0x4400-0x44ff |
va009039 |
1:5fa0120a6169 | 153 | void c_cmp_hr(uint32_t code); // CMP Rd,Rm (high reg) 0x4500-0x45ff |
va009039 |
1:5fa0120a6169 | 154 | void c_mov_hr(uint32_t code); // MOV Rd,Rm (high reg) 0x4600-0x46ff |
va009039 |
1:5fa0120a6169 | 155 | void c_add_r_pc(uint32_t code); // ADD Rd,pc,#imm8 0xa000-0xa7ff |
va009039 |
1:5fa0120a6169 | 156 | void c_add_r_sp(uint32_t code); // ADD Rd,sp,#imm8 0xa800-0xafff |
va009039 |
1:5fa0120a6169 | 157 | void c_add_sp(uint32_t code); // ADD|SUB sp,sp,#imm 0xb000-0xb0ff |
va009039 |
1:5fa0120a6169 | 158 | template<class T> |
va009039 |
1:5fa0120a6169 | 159 | void e_ldr(bool immed = false) { |
va009039 |
1:5fa0120a6169 | 160 | if (immed) { |
va009039 |
1:5fa0120a6169 | 161 | R[_IM] *= sizeof(T); |
va009039 |
1:5fa0120a6169 | 162 | } |
va009039 |
1:5fa0120a6169 | 163 | *Rd = peek<T>(*Rn + *Rm); |
va009039 |
1:5fa0120a6169 | 164 | } |
va009039 |
1:5fa0120a6169 | 165 | template<class T> |
va009039 |
1:5fa0120a6169 | 166 | void e_str(bool immed = false) { |
va009039 |
1:5fa0120a6169 | 167 | if (immed) { |
va009039 |
1:5fa0120a6169 | 168 | R[_IM] *= sizeof(T); |
va009039 |
1:5fa0120a6169 | 169 | } |
va009039 |
1:5fa0120a6169 | 170 | poke<T>(*Rn + *Rm, *Rd); |
va009039 |
1:5fa0120a6169 | 171 | } |
va009039 |
1:5fa0120a6169 | 172 | void c_ldr1(uint32_t code); // LDR Rd,[Rn,#imm5] 0x6800-0x6fff |
va009039 |
1:5fa0120a6169 | 173 | void c_str1(uint32_t code); // STR Rd,[Rn,#imm5] 0x6000-0x67ff |
va009039 |
1:5fa0120a6169 | 174 | void c_ldrb(uint32_t code); // LDRB Rd,[Rn,#imm5] 0x7800-0x7fff |
va009039 |
1:5fa0120a6169 | 175 | void c_strb(uint32_t code); // STRB Rd,[Rn,#imm5] 0x7000-0x77ff |
va009039 |
1:5fa0120a6169 | 176 | void c_ldrh(uint32_t code); // LDRH Rd,[Rn,#imm5] 0x8800-0x8fff |
va009039 |
1:5fa0120a6169 | 177 | void c_strh(uint32_t code); // STRH Rd,[Rn,#imm5] 0x8000-0x87ff |
va009039 |
1:5fa0120a6169 | 178 | void c_ldr2(uint32_t code); // LDR Rd,[Rn,Rm] 0x5800-0x59ff |
va009039 |
1:5fa0120a6169 | 179 | void c_str2(uint32_t code); // STR Rd,[Rn,Rm] 0x5000-0x51ff |
va009039 |
1:5fa0120a6169 | 180 | void c_ldrh2(uint32_t code); // LDRH Rd,[Rn,Rm] 0x5a00-0x5bff |
va009039 |
1:5fa0120a6169 | 181 | void c_strh2(uint32_t code); // STRH Rd,[Rn,Rm] 0x5200-0x53ff |
va009039 |
1:5fa0120a6169 | 182 | void c_ldrsh(uint32_t code); // LDRSH Rd,[Rn,Rm] 0x5e00-0x5fff |
va009039 |
1:5fa0120a6169 | 183 | void c_ldrb2(uint32_t code); // LDRB Rd,[Rn,Rm] 0x5c00-0x5dff |
va009039 |
1:5fa0120a6169 | 184 | void c_strb2(uint32_t code); // STRB Rd,[Rn,Rm] 0x5400-0x55ff |
va009039 |
1:5fa0120a6169 | 185 | void c_ldrsb(uint32_t code); // LDRSB Rd,[Rn,Rm] 0x5600-0x57ff |
va009039 |
1:5fa0120a6169 | 186 | void c_ldr_pc(uint32_t code); // LDR Rd,[pc,#imm8] 0x4800-0x4fff |
va009039 |
1:5fa0120a6169 | 187 | void c_ldr_sp(uint32_t code); // LDR Rd,[sp,#imm8] 0x9800-0x9fff |
va009039 |
1:5fa0120a6169 | 188 | void c_str_sp(uint32_t code); // STR Rd,[sp,#imm8] 0x9000-0x97ff |
va009039 |
1:5fa0120a6169 | 189 | void e_ldm(); // LDM / POP |
va009039 |
1:5fa0120a6169 | 190 | void e_stm(); // STM |
va009039 |
1:5fa0120a6169 | 191 | void e_push(); // PUSH |
va009039 |
1:5fa0120a6169 | 192 | void c_ldm(uint32_t code); // LDM Rn!,{reg_list} 0xc800-0xcfff |
va009039 |
1:5fa0120a6169 | 193 | void c_stm(uint32_t code); // STM Rn!,{reg_list} 0xc000-0xc7ff |
va009039 |
1:5fa0120a6169 | 194 | void c_pop(uint32_t code); // POP {reg_list} 0xbc00-0xbcff |
va009039 |
1:5fa0120a6169 | 195 | void c_pop_pc(uint32_t code); // POP {reg_list,pc} 0xbd00-0xbdff |
va009039 |
1:5fa0120a6169 | 196 | void c_push(uint32_t code); // PUSH {reg_list} 0xb400-0xb4ff |
va009039 |
1:5fa0120a6169 | 197 | void c_push_lr(uint32_t code); // PUSH {reg_list,lr} 0xb500-0xb5ff |
va009039 |
1:5fa0120a6169 | 198 | void c_uxt(uint32_t code); // UXTH|UXTB Rd,Rm 0xb200-0xb2ff |
va009039 |
1:5fa0120a6169 | 199 | void c_rev(uint32_t code); // REV|REV16|REVSH Rd,Rm 0xba00-0xba3f |
va009039 |
1:5fa0120a6169 | 200 | void c_nop(uint32_t code); // NOP 0xbf00 |
va009039 |
1:5fa0120a6169 | 201 | void c_bkpt(uint32_t code); // BKPT #imm8 0xbe00-0xbeff |
va009039 |
1:5fa0120a6169 | 202 | void c_swi(uint32_t code); // SWI #imm8 0xdf00-0xdfff |
va009039 |
1:5fa0120a6169 | 203 | void c_cps(uint32_t code); // CPSIE|CPSID A|I|F 0xb6c0-0xb6e7 |
va009039 |
1:5fa0120a6169 | 204 | void c_todo(uint32_t code); // undefined code |
va009039 |
1:5fa0120a6169 | 205 | }; |
va009039 |
1:5fa0120a6169 | 206 | |
va009039 |
1:5fa0120a6169 | 207 |