Browse Source

Add rest of RV32C instructions

pull/23/head
Andrew Waterman 11 years ago
parent
commit
56701b2308
  1. 1
      riscv/decode.h
  2. 2
      riscv/encoding.h
  3. 9
      riscv/insns/c_addiw.h
  4. 10
      riscv/insns/c_ldsp.h
  5. 39
      riscv/insns/c_sd.h
  6. 8
      riscv/insns/c_sdsp.h
  7. 16
      riscv/insns/c_slliw.h

1
riscv/decode.h

@ -85,6 +85,7 @@ public:
int64_t rvc_ld_imm() { return (x(10, 3) << 3) + (x(5, 2) << 6); }
int64_t rvc_j_imm() { return (x(3, 4) << 1) + (x(2, 1) << 5) + (xs(7, 6) << 6); }
int64_t rvc_b_imm() { return (x(3, 4) << 1) + (x(2, 1) << 5) + (xs(10, 3) << 6); }
int64_t rvc_simm3() { return x(10, 3); }
uint64_t rvc_rd() { return rd(); }
uint64_t rvc_rs1() { return rd(); }
uint64_t rvc_rs2() { return x(2, 5); }

2
riscv/encoding.h

@ -266,7 +266,7 @@
#define MATCH_C_SLLI 0x1
#define MASK_C_SLLI 0xe003
#define MATCH_C_SLLIW 0x8001
#define MASK_C_SLLIW 0xf003
#define MASK_C_SLLIW 0xe003
#define MATCH_C_SRAI 0x2000
#define MASK_C_SRAI 0xe003
#define MATCH_C_SRLI 0x2001

9
riscv/insns/c_addiw.h

@ -1,4 +1,7 @@
require_extension('C');
require_rv64;
require(insn.rvc_rd() != 0);
WRITE_RD(sext32(RVC_RS1 + insn.rvc_imm()));
if (xlen == 32) {
WRITE_RD(RVC_RS1 & insn.rvc_imm()); // c.andi
} else {
require(insn.rvc_rd() != 0);
WRITE_RD(sext32(RVC_RS1 + insn.rvc_imm()));
}

10
riscv/insns/c_ldsp.h

@ -1,4 +1,8 @@
require_extension('C');
require_rv64;
require(insn.rvc_rd() != 0);
WRITE_RD(MMU.load_int64(RVC_SP + insn.rvc_ldsp_imm()));
if (xlen == 32) {
if (sreg_t(RVC_RS1S) >= 0) // c.bgez
set_pc(pc + insn.rvc_b_imm());
} else {
require(insn.rvc_rd() != 0);
WRITE_RD(MMU.load_int64(RVC_SP + insn.rvc_ldsp_imm()));
}

39
riscv/insns/c_sd.h

@ -1,3 +1,38 @@
require_extension('C');
require_rv64;
MMU.store_uint64(RVC_RS1S + insn.rvc_ld_imm(), RVC_RS2S);
if (xlen == 32) {
int32_t res;
switch ((insn.bits() >> 10) & 7) {
case 0:
switch ((insn.bits() >> 5) & 3) {
case 0: res = RVC_RS1S ^ RVC_RS2S; // c.xor
case 1: res = int32_t(RVC_RS1S) >> (RVC_RS2S & 0x1f); // c.sra
default: require(0);
}
WRITE_RVC_RS1S(res);
break;
case 1:
switch ((insn.bits() >> 5) & 3) {
case 0: res = RVC_RS1S << (RVC_RS2S & 0x1f); // c.sll
case 1: res = uint32_t(RVC_RS1S) >> (RVC_RS2S & 0x1f); // c.srl
case 2: res = int32_t(RVC_RS1S) < int32_t(RVC_RS2S); // c.slt
case 3: res = uint32_t(RVC_RS1S) < uint32_t(RVC_RS2S); // c.sltu
}
WRITE_RVC_RS1S(res);
break;
case 3:
switch ((insn.bits() >> 5) & 3) {
case 0: res = RVC_RS1S << (RVC_RS2S & 0x1f); // c.sllr
case 1: res = uint32_t(RVC_RS1S) >> (RVC_RS2S & 0x1f); // c.srlr
case 2: res = int32_t(RVC_RS1S) < int32_t(RVC_RS2S); // c.sltr
case 3: res = uint32_t(RVC_RS1S) < uint32_t(RVC_RS2S); // c.sltur
}
WRITE_RVC_RS2S(res);
break;
default: require(0);
}
} else {
MMU.store_uint64(RVC_RS1S + insn.rvc_ld_imm(), RVC_RS2S);
}

8
riscv/insns/c_sdsp.h

@ -1,3 +1,7 @@
require_extension('C');
require_rv64;
MMU.store_uint64(RVC_SP + insn.rvc_sdsp_imm(), RVC_RS2);
if (xlen == 32) {
if (sreg_t(RVC_RS1S) < 0) // c.bltz
set_pc(pc + insn.rvc_b_imm());
} else {
MMU.store_uint64(RVC_SP + insn.rvc_sdsp_imm(), RVC_RS2);
}

16
riscv/insns/c_slliw.h

@ -1,5 +1,13 @@
require_extension('C');
require_rv64;
require(insn.rvc_rd() != 0);
require(insn.rvc_imm() < 32);
WRITE_RD(sext32(RVC_RS1 << insn.rvc_imm()));
if (xlen == 32) {
switch ((insn.bits() >> 5) & 3) {
case 0: WRITE_RVC_RS2S(sext_xlen(RVC_RS1S + insn.rvc_simm3())); // c.addin
case 1: WRITE_RVC_RS2S(sext_xlen(RVC_RS1S ^ insn.rvc_simm3())); // c.xorin
case 2: WRITE_RVC_RS2S(sext_xlen(RVC_RS1S | insn.rvc_simm3())); // c.orin
case 3: WRITE_RVC_RS2S(sext_xlen(RVC_RS1S & insn.rvc_simm3())); // c.andin
}
} else {
require(insn.rvc_rd() != 0);
require(insn.rvc_imm() < 32);
WRITE_RD(sext32(RVC_RS1 << insn.rvc_imm()));
}

Loading…
Cancel
Save