v6m virtual machine
Import programemu812
mbed LPC812 emulator pre-alpha version
Import programemu1114
mbed LPC1114 emulator pre-alpha version
BaseV6M.h
- Committer:
- va009039
- Date:
- 2016-04-01
- Revision:
- 5:65d77b2e6bc7
- Parent:
- 4:1c7b72bcfc4d
File content as of revision 5:65d77b2e6bc7:
// BaseV6M.h 2015/8/27 #pragma once #include <stdint.h> #define _SP 13 #define _LR 14 #define _PC 15 #define _xPSR 16 #define _IM 17 #define _NL 18 class BaseV6M { public: BaseV6M(); void fetch(); void execute(); void reset(); void run(int step); protected: virtual void poke32(uint32_t a, uint32_t d) = 0; virtual uint32_t peek32(uint32_t a) = 0; virtual void poke8(uint32_t a, uint8_t d) = 0; virtual uint8_t peek8(uint32_t a) = 0; virtual void poke16(uint32_t a, uint16_t w) { poke8(a, w & 0xff); poke8(a+1, w>>8); } virtual uint16_t peek16(uint32_t a) { return peek8(a) | peek8(a+1)<<8; } const char* GetRegName(uint32_t* pR); int GetRegIndex(uint32_t* pR); const char* StrRegLists() { return "todo"; } uint32_t R[16+1+2]; uint32_t* Rd; uint32_t* Rn; uint32_t* Rm; uint32_t code, code2nd; uint32_t cycle; uint32_t N(); uint32_t Z(); uint32_t C(); uint32_t V(); private: template<class T> void poke(uint32_t addr, T data) { switch(sizeof(T)) { case 4: poke32(addr, data); break; case 2: poke16(addr, data); break; case 1: poke8(addr, data); break; } /* NOTREACHED */ } template<class T> T peek(uint32_t addr) { switch(sizeof(T)) { case 4: return peek32(addr); case 2: return peek16(addr); case 1: return peek8(addr); } /* NOTREACHED */ } uint32_t op; uint32_t reg_list; bool cache; void Cin(uint32_t c); void NZupdate(uint32_t d); void NZCVupdate(uint32_t d, uint32_t n, uint32_t m); void jump(uint32_t addr); void exception_entry(uint32_t num); void exception_return(); void push(uint32_t d); uint32_t pop(); void d_Rn_Rd(uint32_t code); // decode leaf void d_Op_H_Rm(uint32_t code); // BX Rm / BLX Rm void d_imm3_Rn_Rd(uint32_t code); // ADD Rd,Rn,#imm3 void d_Rd_imm8(uint32_t code); // <Op> Rd,#imm8 / LDR rd,[pc,#imm8] void d_Rn_imm8(uint32_t code); // <Op> Rn,#imm8 void d_imm5_Rn_Rd(uint32_t code); // LSL Rd,Rn,#imm5 / LDR Rd,[Rn,#imm5] void d_Op_Rm_Rd(uint32_t code); // <Op> Rd,Rm void d_Op_imm7(uint32_t code); // ADD|SUB sp,sp,#imm7 void d_D_M_Rm_Rd(uint32_t code); // ADD|CMP|MOV Rd,Rm void d_Rm_Rn_Rd(uint32_t code); // LDR Rd,[Rn,Rm] void d_reg_list(uint32_t code); // PUSH / POP void d_Rn_reg_list(uint32_t code); // LDM / STM void d32_Rd_SYSm(uint32_t code, uint32_t code2nd); // MRS void d32_Rn_SYSm(uint32_t code, uint32_t code2nd); // MSR void e_adc(); // ADC Rd,Rn,Rm|imm void e_sbc(); // SBC Rd,Rn,Rm|imm void e_add(); // ADD Rd,Rn,Rm|imm void e_sub(); // SUB Rd,Rn,Rm|imm void e_cmp(); // CMP Rn,Rm|imm void e_cmn(); // CMN Rn,Rm|imm void e_and(); // AND Rd,Rn,Rm|imm void e_tst(); // TST Rn,Rm|imm void e_lsl(); // LSL Rd,Rn,Rm|imm void e_lsr(); // LSR Rd,Rn,Rm|imm void e_asr(); // ASR Rd,Rn,Rm|imm void e_ror(); // ROR Rd,Rn,Rm|imm void e_orr(); // ORR Rd,Rn,Rm|imm void e_eor(); // EOR Rd,Rn,Rm|imm void e_mul(); // MUL Rd,Rn,Rm void e_bic(); // BIC Rd,Rn,Rm|imm void e_mov(); // MOV Rd,Rm|imm void e_neg(); // NEG void e_mvn(); // MVN void c_beq(uint32_t code); // BEQ #0xd000-0xd0ff void c_bne(uint32_t code); // BNE 0xd100-0xd1ff void c_bcs(uint32_t code); // BCS #0xd200-0xd2ff void c_bcc(uint32_t code); // BCC #0xd300-0xd3ff void c_bmi(uint32_t code); // BMI 0xd400-0xd4ff void c_bpl(uint32_t code); // BMI 0xd500-0xd5ff void c_bvs(uint32_t code); // BVS 0xd600-0xd6ff void c_bvc(uint32_t code); // BVC 0xd700-0xd7ff void c_bhi(uint32_t code); // BHI 0xd800-0xd8ff void c_bls(uint32_t code); // BLS 0xd900-0xd9ff void c_bge(uint32_t code); // BGE 0xda00-0xdaff void c_blt(uint32_t code); // BLT 0xdb00-0xdbff void c_bgt(uint32_t code); // BGT 0xdc00-0xdcff void c_ble(uint32_t code); // BLE 0xdd00-0xddff void c_b_forward(uint32_t code); // B 0xe000-0xe3ff void c_b_backward(uint32_t code); // B 0xe400-0xe7ff void c32_bl_forward(uint32_t code); // BL 0xf000-0xf2ff void c32_bl_forward3(uint32_t code); // BL 0xf300-0xf3ff void c32_mrs(uint32_t code, uint32_t code2nd); void c32_msr(uint32_t code, uint32_t code2nd); void c32_dsb_dmb_isb(uint32_t code, uint32_t code2nd); void c32_bl_backward(uint32_t code); // BL 0xf400-0xf7ff void c_bx(uint32_t code); // BX BLX 0x4770 void c_add(uint32_t code); // ADDS Rd,Rn,Rm 0x1800-0x19ff void c_sub(uint32_t code); // SUBS Rd,Rn,Rm 0x1a00-0x1bff void c_add1(uint32_t code); // ADD Rd,Rn,#imm3 / MOV Rd,Rn 0x1c00-0x1dff void c_sub1(uint32_t code); // SUB Rd,Rn,#imm3 0x1e00-1fff void c_add2(uint32_t code); // ADD Rd,#imm8 0x3000-0x37ff void c_sub2(uint32_t code); // SUB Rd,#imm8 0x3800-0x3fff void c_mov(uint32_t code); // MOVS Rd,#imm8 0x2000-0x27ff void c_cmp(uint32_t code); // CMP Rn,#imm8 0x2800-0x2fff void c_lsl(uint32_t code); // LSLS Rd,Rn,#imm5 0x0000-0x07ff void c_lsr(uint32_t code); // LSRS Rd,Rn,#imm5 0x0800-0x0fff void c_asr(uint32_t code); // ASRS Rd,Rn,#imm5 0x1000-0x17ff void c_and_eor_lsl_lsr(uint32_t code); // ANDS|EORS|LSLS|LSRS Rd,Rm 0x4000-0x40ff void c_asr_adc_sbc_ror(uint32_t code); // ASRS|ADCS|SBCS|RORS Rd,Rm 0x4100-0x41ff void c_tst_neg_cmp_cmn(uint32_t code); // TST|NEGS|CMP|CMN Rd,Rm 0x4200-0x42ff void c_orr_mul_bic_mvn(uint32_t code); // ORRS|MULS|BICS|MVNS Rd,Rm 0x4300-0x43ff void c_add_hr(uint32_t code); // ADD Rd,Rm (high reg) 0x4400-0x44ff void c_cmp_hr(uint32_t code); // CMP Rd,Rm (high reg) 0x4500-0x45ff void c_mov_hr(uint32_t code); // MOV Rd,Rm (high reg) 0x4600-0x46ff void c_add_r_pc(uint32_t code); // ADD Rd,pc,#imm8 0xa000-0xa7ff void c_add_r_sp(uint32_t code); // ADD Rd,sp,#imm8 0xa800-0xafff void c_add_sp(uint32_t code); // ADD|SUB sp,sp,#imm 0xb000-0xb0ff template<class T> void e_ldr(bool immed = false) { if (immed) { R[_IM] *= sizeof(T); } *Rd = peek<T>(*Rn + *Rm); } template<class T> void e_str(bool immed = false) { if (immed) { R[_IM] *= sizeof(T); } poke<T>(*Rn + *Rm, *Rd); } void c_ldr1(uint32_t code); // LDR Rd,[Rn,#imm5] 0x6800-0x6fff void c_str1(uint32_t code); // STR Rd,[Rn,#imm5] 0x6000-0x67ff void c_ldrb(uint32_t code); // LDRB Rd,[Rn,#imm5] 0x7800-0x7fff void c_strb(uint32_t code); // STRB Rd,[Rn,#imm5] 0x7000-0x77ff void c_ldrh(uint32_t code); // LDRH Rd,[Rn,#imm5] 0x8800-0x8fff void c_strh(uint32_t code); // STRH Rd,[Rn,#imm5] 0x8000-0x87ff void c_ldr2(uint32_t code); // LDR Rd,[Rn,Rm] 0x5800-0x59ff void c_str2(uint32_t code); // STR Rd,[Rn,Rm] 0x5000-0x51ff void c_ldrh2(uint32_t code); // LDRH Rd,[Rn,Rm] 0x5a00-0x5bff void c_strh2(uint32_t code); // STRH Rd,[Rn,Rm] 0x5200-0x53ff void c_ldrsh(uint32_t code); // LDRSH Rd,[Rn,Rm] 0x5e00-0x5fff void c_ldrb2(uint32_t code); // LDRB Rd,[Rn,Rm] 0x5c00-0x5dff void c_strb2(uint32_t code); // STRB Rd,[Rn,Rm] 0x5400-0x55ff void c_ldrsb(uint32_t code); // LDRSB Rd,[Rn,Rm] 0x5600-0x57ff void c_ldr_pc(uint32_t code); // LDR Rd,[pc,#imm8] 0x4800-0x4fff void c_ldr_sp(uint32_t code); // LDR Rd,[sp,#imm8] 0x9800-0x9fff void c_str_sp(uint32_t code); // STR Rd,[sp,#imm8] 0x9000-0x97ff void e_ldm(); // LDM / POP void e_stm(); // STM void e_push(); // PUSH void c_ldm(uint32_t code); // LDM Rn!,{reg_list} 0xc800-0xcfff void c_stm(uint32_t code); // STM Rn!,{reg_list} 0xc000-0xc7ff void c_pop(uint32_t code); // POP {reg_list} 0xbc00-0xbcff void c_pop_pc(uint32_t code); // POP {reg_list,pc} 0xbd00-0xbdff void c_push(uint32_t code); // PUSH {reg_list} 0xb400-0xb4ff void c_push_lr(uint32_t code); // PUSH {reg_list,lr} 0xb500-0xb5ff void c_uxt(uint32_t code); // UXTH|UXTB Rd,Rm 0xb200-0xb2ff void c_rev(uint32_t code); // REV|REV16|REVSH Rd,Rm 0xba00-0xba3f void c_nop(uint32_t code); // NOP 0xbf00 void c_bkpt(uint32_t code); // BKPT #imm8 0xbe00-0xbeff void c_swi(uint32_t code); // SWI #imm8 0xdf00-0xdfff void c_cps(uint32_t code); // CPSIE|CPSID A|I|F 0xb6c0-0xb6e7 void c_todo(uint32_t code); // undefined code };