v6m virtual machine
Import programemu812
mbed LPC812 emulator pre-alpha version
Import programemu1114
mbed LPC1114 emulator pre-alpha version
Diff: BaseV6M.h
- Revision:
- 1:5fa0120a6169
- Parent:
- 0:c2ad7f15d6a8
- Child:
- 4:1c7b72bcfc4d
--- a/BaseV6M.h Mon Aug 10 13:02:02 2015 +0000 +++ b/BaseV6M.h Mon Aug 10 22:39:26 2015 +0900 @@ -0,0 +1,201 @@ +// BaseV6M.h 2015/8/9 +#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 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 c_bl(uint32_t code); // BL 0xf000-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 + +}; + +