v6m virtual machine

Dependents:  

Import programemu812

mbed LPC812 emulator pre-alpha version

Import programemu1114

mbed LPC1114 emulator pre-alpha version

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
+
+};
+
+