Add RISCV pseudoinstructions
PiperOrigin-RevId: 562871328
diff --git a/sim/kelvin_base.bin_fmt b/sim/kelvin_base.bin_fmt
index 22dca32..e567af8 100644
--- a/sim/kelvin_base.bin_fmt
+++ b/sim/kelvin_base.bin_fmt
@@ -7,7 +7,8 @@
jal : JType : rd != 0, opcode == 0b110'1111;
j : JType : rd == 0, opcode == 0b110'1111;
jalr : IType : rd != 0, func3 == 0b000, opcode == 0b110'0111;
- jr : IType : rd == 0, func3 == 0b000, opcode == 0b110'0111;
+ jr : IType : rd == 0, rs1 != 1, func3 == 0b000, opcode == 0b110'0111;
+ ret : IType : rd == 0, rs1 == 1, imm12 == 0, func3 == 0b000, opcode == 0b110'0111;
beq : BType : func3 == 0b000, opcode == 0b110'0011;
bne : BType : func3 == 0b001, opcode == 0b110'0011;
blt : BType : func3 == 0b100, opcode == 0b110'0011;
@@ -16,13 +17,16 @@
bgeu : BType : func3 == 0b111, opcode == 0b110'0011;
lb : BType : func3 == 0b000, opcode == 0b000'0011;
lh : BType : func3 == 0b001, opcode == 0b000'0011;
+ li : IType : rd != 0, rs1 == 0, func3 == 0b000, opcode == 0b001'0011;
lw : BType : func3 == 0b010, opcode == 0b000'0011;
lbu : BType : func3 == 0b100, opcode == 0b000'0011;
lhu : BType : func3 == 0b101, opcode == 0b000'0011;
+ mv : IType : rs1 != 0, imm12 == 0, func3 == 0b000, opcode == 0b001'0011;
+ nop : IType : rd == 0, rs1 == 0, imm12 == 0, func3 == 0b000, opcode == 0b001'0011;
sb : SType : func3 == 0b000, opcode == 0b010'0011;
sh : SType : func3 == 0b001, opcode == 0b010'0011;
sw : SType : func3 == 0b010, opcode == 0b010'0011;
- addi : IType : func3 == 0b000, opcode == 0b001'0011;
+ addi : IType : rs1 != 0, imm12 != 0, func3 == 0b000, opcode == 0b001'0011;
slti : IType : func3 == 0b010, opcode == 0b001'0011;
sltiu : IType : func3 == 0b011, opcode == 0b001'0011;
xori : IType : func3 == 0b100, opcode == 0b001'0011;
diff --git a/sim/kelvin_base.isa b/sim/kelvin_base.isa
index 2809371..49e7736 100644
--- a/sim/kelvin_base.isa
+++ b/sim/kelvin_base.isa
@@ -18,6 +18,14 @@
resources: TwoOp,
disasm: "addi", "%rd, %rs1, %I_imm12",
semfunc: "&mpact::sim::riscv::RV32::RiscVIAdd";
+ li{: rs1, I_imm12 : rd},
+ resources: TwoOp,
+ disasm: "li", "%rd, %I_imm12",
+ semfunc: "&mpact::sim::riscv::RV32::RiscVIAdd";
+ mv{: rs1, I_imm12 : rd},
+ resources: TwoOp,
+ disasm: "mv", "%rd, %rs1",
+ semfunc: "&mpact::sim::riscv::RV32::RiscVIAdd";
slti{: rs1, I_imm12 : rd},
resources: TwoOp,
disasm: "slti", "%rd, %rs1, %I_imm12",
@@ -120,6 +128,10 @@
resources: { next_pc, rs1 : next_pc[0..], rd[0..]},
disasm: "jr", "%rs1, %J_imm12",
semfunc: "&mpact::sim::riscv::RV32::RiscVIJalr";
+ ret{: rs1, J_imm12 : next_pc, rd},
+ resources: { next_pc, rs1 : next_pc[0..], rd[0..]},
+ disasm: "ret",
+ semfunc: "&mpact::sim::riscv::RV32::RiscVIJalr";
beq{: rs1, rs2, B_imm12 : next_pc},
resources: { next_pc, rs1, rs2 : next_pc[0..]},
disasm: "beq", "%rs1, %rs2, %(@+B_imm12:08x)",
diff --git a/sim/test/kelvin_encoding_test.cc b/sim/test/kelvin_encoding_test.cc
index 8dad336..96c4500 100644
--- a/sim/test/kelvin_encoding_test.cc
+++ b/sim/test/kelvin_encoding_test.cc
@@ -167,6 +167,10 @@
EXPECT_EQ(enc_->GetOpcode(SlotEnum::kKelvin, 0), OpcodeEnum::kAuipc);
enc_->ParseInstruction(SetRd(kJal, kRdValue));
EXPECT_EQ(enc_->GetOpcode(SlotEnum::kKelvin, 0), OpcodeEnum::kJal);
+ enc_->ParseInstruction(SetRs1(kJalr, kRdValue));
+ EXPECT_EQ(enc_->GetOpcode(SlotEnum::kKelvin, 0), OpcodeEnum::kRet);
+ enc_->ParseInstruction(SetRs1(kJalr, 0x2));
+ EXPECT_EQ(enc_->GetOpcode(SlotEnum::kKelvin, 0), OpcodeEnum::kJr);
enc_->ParseInstruction(SetRd(kJalr, kRdValue));
EXPECT_EQ(enc_->GetOpcode(SlotEnum::kKelvin, 0), OpcodeEnum::kJalr);
enc_->ParseInstruction(kBeq);
@@ -197,7 +201,14 @@
EXPECT_EQ(enc_->GetOpcode(SlotEnum::kKelvin, 0), OpcodeEnum::kSh);
enc_->ParseInstruction(SetRd(kSw, kRdValue));
EXPECT_EQ(enc_->GetOpcode(SlotEnum::kKelvin, 0), OpcodeEnum::kSw);
+ enc_->ParseInstruction(kAddi);
+ EXPECT_EQ(enc_->GetOpcode(SlotEnum::kKelvin, 0), OpcodeEnum::kNop);
enc_->ParseInstruction(SetRd(kAddi, kRdValue));
+ EXPECT_EQ(enc_->GetOpcode(SlotEnum::kKelvin, 0), OpcodeEnum::kLi);
+ enc_->ParseInstruction(SetRs1(SetRd(kAddi, kRdValue), 0x2));
+ EXPECT_EQ(enc_->GetOpcode(SlotEnum::kKelvin, 0), OpcodeEnum::kMv);
+ enc_->ParseInstruction(SetRs1(SetRd(kAddi, kRdValue), 0x2) |
+ (0b1 << 20 /*imm12*/));
EXPECT_EQ(enc_->GetOpcode(SlotEnum::kKelvin, 0), OpcodeEnum::kAddi);
enc_->ParseInstruction(SetRd(kSlti, kRdValue));
EXPECT_EQ(enc_->GetOpcode(SlotEnum::kKelvin, 0), OpcodeEnum::kSlti);