v6m virtual machine

Dependents:  

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