exec.c 3.4 KB
Newer Older
P
Parallels 已提交
1 2 3 4
#include "cpu/exec.h"
#include "all-instr.h"

static make_EHelper(load) {
5 6 7 8 9
  static OpcodeEntry table [8] = {
    EXW(lds, 1), EXW(lds, 2), EXW(lds, 4), EXW(ld, 8), EXW(ld, 1), EXW(ld, 2), EXW(ld, 4), EMPTY
  };
  decinfo.width = table[decinfo.isa.instr.funct3].width;
  idex(pc, &table[decinfo.isa.instr.funct3]);
P
Parallels 已提交
10 11 12
}

static make_EHelper(store) {
13 14 15 16 17
  static OpcodeEntry table [8] = {
    EXW(st, 1), EXW(st, 2), EXW(st, 4), EXW(st, 8), EMPTY, EMPTY, EMPTY, EMPTY
  };
  decinfo.width = table[decinfo.isa.instr.funct3].width;
  idex(pc, &table[decinfo.isa.instr.funct3]);
P
Parallels 已提交
18 19 20
}

static make_EHelper(op_imm) {
21 22 23 24
  static OpcodeEntry table [8] = {
    EX(add), EX(sll), EX(slt), EX(sltu), EX(xor), EX(srl), EX(or), EX(and)
  };
  idex(pc, &table[decinfo.isa.instr.funct3]);
P
Parallels 已提交
25 26
}

27
static make_EHelper(op_imm32) {
28 29 30 31
  static OpcodeEntry table [8] = {
    EX(addw), EX(sllw), EMPTY, EMPTY, EMPTY, EX(srlw), EMPTY, EMPTY
  };
  idex(pc, &table[decinfo.isa.instr.funct3]);
P
Parallels 已提交
32 33 34
}

static make_EHelper(op) {
35 36 37 38 39 40 41 42 43 44
  static OpcodeEntry table [3][8] = {
    {EX(add), EX(sll), EX(slt), EX(sltu), EX(xor), EX(srl), EX(or), EX(and)},
    {EX(mul), EX(mulh), EX(mulhsu), EX(mulhu), EX(div), EX(divu), EX(rem), EX(remu)},
    {EX(sub), EMPTY, EMPTY, EMPTY, EMPTY, EX(sra), EMPTY, EMPTY},
  };

  uint32_t idx = decinfo.isa.instr.funct7;
  if (idx == 32) idx = 2;
  assert(idx <= 2);
  idex(pc, &table[idx][decinfo.isa.instr.funct3]);
P
Parallels 已提交
45 46
}

47
static make_EHelper(op32) {
48 49 50 51 52 53 54 55 56 57
  static OpcodeEntry table [3][8] = {
    {EX(addw), EX(sllw), EMPTY, EMPTY, EMPTY, EX(srlw), EMPTY, EMPTY},
    {EX(mulw), EMPTY, EMPTY, EMPTY, EX(divw), EX(divuw), EX(remw), EX(remuw)},
    {EX(subw), EMPTY, EMPTY, EMPTY, EMPTY, EX(sraw), EMPTY, EMPTY},
  };

  uint32_t idx = decinfo.isa.instr.funct7;
  if (idx == 32) idx = 2;
  assert(idx <= 2);
  idex(pc, &table[idx][decinfo.isa.instr.funct3]);
P
Parallels 已提交
58 59 60
}

static make_EHelper(system) {
61 62 63 64
  static OpcodeEntry table [8] = {
    EX(priv), IDEX(csr, csrrw), IDEX(csr, csrrs), EMPTY, EMPTY, EMPTY, EMPTY, EMPTY
  };
  idex(pc, &table[decinfo.isa.instr.funct3]);
P
Parallels 已提交
65 66 67
}

static OpcodeEntry opcode_table [32] = {
68 69
  /* b00 */ IDEX(ld, load), EMPTY, EMPTY, EMPTY, IDEX(I, op_imm), IDEX(U, auipc), IDEX(I, op_imm32), EMPTY,
  /* b01 */ IDEX(st, store), EMPTY, EMPTY, EMPTY, IDEX(R, op), IDEX(U, lui), IDEX(R, op32), EMPTY,
P
Parallels 已提交
70 71 72 73
  /* b10 */ EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
  /* b11 */ IDEX(B, branch), IDEX(I, jalr), EX(nemu_trap), IDEX(J, jal), EX(system), EMPTY, EMPTY, EMPTY,
};

74 75 76
// RVC

static make_EHelper(C_10_100) {
77
  static OpcodeEntry table [8] = {
Z
Zihao Yu 已提交
78
    EMPTY, EMPTY, EX(jalr), IDEX(C_MV, add), EMPTY, EMPTY, EMPTY, EMPTY,
79
  };
80 81 82 83
  int cond_c_simm12_not0 = (decinfo.isa.instr.c_simm12 != 0);
  int cond_c_rd_rs1_not0 = (decinfo.isa.instr.c_rd_rs1 != 0);
  int cond_c_rs2_not0 = (decinfo.isa.instr.c_rs2 != 0);
  int idx = (cond_c_simm12_not0 << 2) | (cond_c_rd_rs1_not0 << 1) | cond_c_rs2_not0;
84
  idex(pc, &table[idx]);
85 86 87 88
}

static OpcodeEntry rvc_table [3][8] = {
  {EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, },
Z
Zihao Yu 已提交
89 90
  {IDEX(CI, add), EMPTY, IDEX(C_LI, add), EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, },
  {EMPTY, EMPTY, EMPTY, EMPTY, IDEX(C_10_100, C_10_100), EMPTY, EMPTY, IDEX(C_SDSP, st), },
91 92
};

P
Parallels 已提交
93 94
void isa_exec(vaddr_t *pc) {
  decinfo.isa.instr.val = instr_fetch(pc, 4);
95 96 97 98 99 100 101
  if (decinfo.isa.instr.opcode1_0 == 0x3) {
    idex(pc, &opcode_table[decinfo.isa.instr.opcode6_2]);
  } else {
    // RVC instructions are only 2-byte
    *pc -= 2;
    idex(pc, &rvc_table[decinfo.isa.instr.opcode1_0][decinfo.isa.instr.c_funct3]);
  }
P
Parallels 已提交
102
}