
#ifndef riscv_h__
#define riscv_h__

#include "stdint.h"



/*

每个指令长度为32bit，分为6个类型
|--------------+------------+-----------+-------------+--------------+---------------|
|  [31-25]     |  [24-20]   |  [19-15]  |  [14-12]    |  [11-7]      |     [6-0]     |
|--------------+------------+-----------+-------------+--------------+---------------|
|    funct7    |     rs2    |    rs1    |   funct3    |     rd       |     opcode    | R-type 计算指令
|--------------+------------+-----------+-------------+--------------+---------------|
|         imm[11:0]         |    rs1    |   funct3    |     rd       |     opcode    | I-type 加载指令
|--------------+------------+-----------+-------------+--------------+---------------|
|   imm[11:5]  |     rs2    |    rs1    |   funct3    | imm[4:0]     |     opcode    | S-type 存储指令
|--------------+------------+-----------+-------------+--------------+---------------|
|imm[12] [10:5]|     rs2    |    rs1    |   funct3    | imm[4:1][11] |     opcode    | B-type 分支指令
|--------------+------------+-----------+-------------+--------------+---------------|
|                      imm[31:12]                     |     rd       |     opcode    | U-type 立即数指令
|-----------------------------------------------------+--------------+---------------|
|            imm[20] [10:1] [11] [19:12]              |     rd       |     opcode    | J-type 跳转指令
|-----------------------------------------------------+--------------+---------------|

*/

// 定义opcode
#define opcode_lui   0x37  // U-type
#define opcode_auipc 0x17  // U-type
#define opcode_jal   0x6f  // J-type
#define opcode_jalr  0x67  // I-type

// B-type
#define opcode_beq  0x63
#define opcode_bne  0x63
#define opcode_blt  0x63
#define opcode_bge  0x63
#define opcode_bltu 0x63
#define opcode_bgeu 0x63

// I-type
#define opcode_lb   0x03
#define opcode_lh   0x03
#define opcode_lw   0x03
#define opcode_lbu  0x03
#define opcode_lhu  0x03

// S-type
#define opcode_sb   0x23
#define opcode_sh   0x23
#define opcode_sw   0x23

// I-type
#define opcode_addi 0x13
#define opcode_slti 0x13
#define opcode_sltiu 0x13
#define opcode_xori 0x13
#define opcode_ori  0x13
#define opcode_andi 0x13
#define opcode_slli 0x13
#define opcode_srli 0x13
#define opcode_srai 0x13

// R-type
#define opcode_add  0x33
#define opcode_sub  0x33
#define opcode_sll  0x33
#define opcode_slt  0x33
#define opcode_sltu 0x33
#define opcode_xor  0x33
#define opcode_srl  0x33
#define opcode_sra  0x33
#define opcode_or   0x33
#define opcode_and  0x33

#define opcode_fence 0x0f
#define opcode_fence_i 0x0f

// 系统调用
#define opcode_ecall 0x73
#define opcode_ebreak 0x73
#define opcode_csrrw 0x73
#define opcode_csrrs 0x73
#define opcode_csrrc 0x73
#define opcode_csrrwi 0x73
#define opcode_csrrsi 0x73
#define opcode_csrrci 0x73


#define MEM_SIZE 1024*1024
#define MEM_ADDR_BASE 0x10000000

#define zero reg[0]
#define ra   reg[1]
#define sp   reg[2]
#define gp   reg[3]
#define tp   reg[4]
#define t0   reg[5]
#define t1   reg[6]
#define t2   reg[7]
#define s0   reg[8]
#define s1   reg[9]
#define a0   reg[10]
#define a1   reg[11]
#define a2   reg[12]
#define a3   reg[13]
#define a4   reg[14]
#define a5   reg[15]
#define a6   reg[16]
#define a7   reg[17]
#define s2   reg[18]
#define s3   reg[19]
#define s4   reg[20]
#define s5   reg[21]
#define s6   reg[22]
#define s7   reg[23]
#define s8   reg[24]
#define s9   reg[25]
#define s10  reg[26]
#define s11  reg[27]
#define t3   reg[28]
#define t4   reg[29]
#define t5   reg[30]
#define t6   reg[31]

#define fp   reg[8]



// 不需要做符号扩展
#define imm_u_type(_ins,_imm) {\
  _imm = (_ins >> 12) << 12;\
}

// 20位符号扩展
#define imm_j_type(_ins,_imm) {\
  _imm = ((_ins >> 21) & 0x3ff) << 1;\
  _imm |= ((_ins >> 20) & 1) << 11;\
  _imm |= ((_ins >> 12) & 0xff) << 12;\
  _imm |= ((_ins >> 31) & 1) << 20;\
  if(_imm&(1<<20)){\
    _imm|=0xfff00000;\
  }\
}

// 12位符号扩展
#define imm_i_type(_ins,_imm) {\
  _imm = (_ins >> 20) & 0xfff;\
  if(_imm&(1<<11)){\
    _imm|=0xfffff000;\
  }\
}

// 13位符号扩展
#define imm_b_type(_ins,_imm) {\
  _imm = ((_ins >> 31) & 1) << 12;\
  _imm |= ((_ins >> 7) & 0x1) << 11;\
  _imm |= ((_ins >> 8) & 0xf) << 1;\
  _imm |= ((_ins >> 25) & 0x3f) << 5;\
  if(_imm&(1<<12)){\
    _imm|=0xfffff000;\
  }\
}

// 12位符号扩展
#define imm_s_type(_ins,_imm) {\
  _imm = ((_ins >> 7) & 0x1f);\
  _imm |= (_ins >> 25) << 5;\
  if(_imm&(1<<11)){\
    _imm|=0xfffff000;\
  }\
}

#define imm_csr(_ins,_imm) {\
  _imm = (_ins >> 20) & 0xfff;\
}


#define DEVICE_MAX_NUM 16


struct riscv_t;
typedef struct device_t{
  uint32_t addr;
  uint32_t size;
  uint32_t (*read)(uint32_t addr);
  void (*write)(uint32_t addr, uint32_t data);
  void (*run)(struct riscv_t *riscv,const struct device_t* device);
  void (*init)(const struct device_t* device);
}device_t;

typedef struct riscv_t{
  uint32_t mem[MEM_SIZE];
  const device_t* device_list[DEVICE_MAX_NUM];
  uint32_t device_num;
  uint32_t* rom;
  uint32_t rom_size;
  uint32_t rom_addr_base;
  uint32_t pc;
  uint32_t pc_modify;// pc 指针已经被修改 不要自动递增
  int32_t exc_code;
  uint32_t reg[32];
  uint32_t csrs[4096];
}riscv_t;

#define mem_wr(addr) riscv->mem[(addr-MEM_ADDR_BASE) >> 2]
#define mem_wrb(addr) ((uint8_t *)riscv->mem)[(addr-MEM_ADDR_BASE)]
#define mem_wrh(addr) ((uint16_t *)riscv->mem)[(addr-MEM_ADDR_BASE) >> 1]

#define rom_wr(addr) riscv->rom[(addr-riscv->rom_addr_base) >> 2]
#define rom_wrb(addr) ((uint8_t *)(riscv->rom))[(addr-riscv->rom_addr_base)]
#define rom_wrh(addr) ((uint16_t *)(riscv->rom))[(addr-riscv->rom_addr_base) >> 1]


// trap 相关定义
#define mstatus     csrs[0x300]   // 机器状态寄存器
#define misa        csrs[0x301]   // ISA扩展
#define medeleg     csrs[0x302]   // 异常委托寄存器
#define mideleg     csrs[0x303]   // 中断委托寄存器
#define mie         csrs[0x304]   // 中断使能寄存器
#define mtvec       csrs[0x305]   // 异常向量寄存器
#define mcounteren  csrs[0x306]   // 统计计数器使能寄存器
#define mstatush    csrs[0x310]   // 添加的状态寄存器高

#define mscratch    csrs[0x340]   // 存储器 软件中可用于暂时存放一个字大小的数据
#define mepc        csrs[0x341]   // 异常程序计数器 指向发生异常的指令
#define mcause      csrs[0x342]   // 异常原因寄存器
#define mtval       csrs[0x343]   // 异常值寄存器 地址例外出错的地址 非法指令本身
#define mip         csrs[0x344]   // 中断请求寄存器 它列出正在准备处理的中断
#define mtinst      csrs[0x34a]   // 存储器指令寄存器 当发生异常时，它包含异常指令
#define mtval2      csrs[0x34b]   // 坏的物理地址
#define mcycle      csrs[0xc00]   // 循环计数器
#define minstret    csrs[0xc02]   // 执行指令计数器


// 只有机器模式的cpu只有这两个位起作用 清除这两个位表示禁用全局中断
#define MSTATUS_MIE         0x00000008 // 中断使能位
#define MSTATUS_MPIE        0x00000080 // 进异常时会自动清除MIE MPIE是清除之前的状态


#define MIP_MSIP            (1 << IRQ_M_SOFT)
#define MIP_MTIP            (1 << IRQ_M_TIMER)
#define MIP_MEIP            (1 << IRQ_M_EXT)
#define IRQ_M_SOFT   3
#define IRQ_M_TIMER  7
#define IRQ_M_EXT    11



int riscv_register_device(riscv_t* riscv, const device_t* device);
int riscv_init(riscv_t* riscv, uint32_t* rom, uint32_t rom_addr_base, uint32_t rom_size);
int riscv_device_init(riscv_t* riscv);
int riscv_run(riscv_t* riscv);


#endif