v6m virtual machine

Dependents:  

Import programemu812

mbed LPC812 emulator pre-alpha version

Import programemu1114

mbed LPC1114 emulator pre-alpha version

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?

UserRevisionLine numberNew 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