use crate::types::*;
use crate::Register;
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum Instruction {
Lui(UType),
Jal(JType),
Jalr(IType),
Beq(BType),
Ld(IType),
Sd(SType),
Addi(IType),
Add(RType),
Sub(RType),
Sltu(RType),
Mul(RType),
Divu(RType),
Remu(RType),
Ecall(IType),
}
const OP_LD: u32 = 3; const OP_IMM: u32 = 19; const OP_SD: u32 = 35; const OP_OP: u32 = 51; const OP_LUI: u32 = 55; const OP_BRANCH: u32 = 99; const OP_JALR: u32 = 103; const OP_JAL: u32 = 111; const OP_SYSTEM: u32 = 115;
const F3_ADDI: u32 = 0; const F3_ADD: u32 = 0; const F3_SUB: u32 = 0; const F3_MUL: u32 = 0; const F3_DIVU: u32 = 5; const F3_REMU: u32 = 7; const F3_SLTU: u32 = 3; const F3_LD: u32 = 3; const F3_SD: u32 = 3; const F3_BEQ: u32 = 0; const F3_JALR: u32 = 0; const F3_ECALL: u32 = 0;
const F7_ADD: u32 = 0; const F7_MUL: u32 = 1; const F7_SUB: u32 = 32; const F7_DIVU: u32 = 1; const F7_REMU: u32 = 1; const F7_SLTU: u32 = 0;
impl Instruction {
pub fn new_nop() -> Instruction {
Self::new_addi(Register::Zero, Register::Zero, 0)
}
pub fn new_add(rd: Register, rs1: Register, rs2: Register) -> Instruction {
Instruction::Add(RType::new(F7_ADD, F3_ADD, OP_OP, rs1, rs2, rd))
}
pub fn new_sub(rd: Register, rs1: Register, rs2: Register) -> Instruction {
Instruction::Sub(RType::new(F7_SUB, F3_SUB, OP_OP, rs1, rs2, rd))
}
pub fn new_mul(rd: Register, rs1: Register, rs2: Register) -> Instruction {
Instruction::Mul(RType::new(F7_MUL, F3_MUL, OP_OP, rs1, rs2, rd))
}
pub fn new_divu(rd: Register, rs1: Register, rs2: Register) -> Instruction {
Instruction::Divu(RType::new(F7_DIVU, F3_DIVU, OP_OP, rs1, rs2, rd))
}
pub fn new_remu(rd: Register, rs1: Register, rs2: Register) -> Instruction {
Instruction::Remu(RType::new(F7_REMU, F3_REMU, OP_OP, rs1, rs2, rd))
}
pub fn new_sltu(rd: Register, rs1: Register, rs2: Register) -> Instruction {
Instruction::Sltu(RType::new(F7_SLTU, F3_SLTU, OP_OP, rs1, rs2, rd))
}
pub fn new_addi(rd: Register, rs1: Register, immediate: i32) -> Instruction {
Instruction::Addi(IType::new(immediate, F3_ADDI, OP_IMM, rd, rs1))
}
pub fn new_ld(rd: Register, rs1: Register, immediate: i32) -> Instruction {
Instruction::Ld(IType::new(immediate, F3_LD, OP_LD, rd, rs1))
}
pub fn new_ecall() -> Instruction {
Instruction::Ecall(IType::new(
0,
F3_ECALL,
OP_SYSTEM,
Register::Zero,
Register::Zero,
))
}
pub fn new_jalr(rd: Register, rs1: Register, immediate: i32) -> Instruction {
Instruction::Jalr(IType::new(immediate, F3_JALR, OP_JALR, rd, rs1))
}
pub fn new_sd(rs1: Register, rs2: Register, immediate: i32) -> Instruction {
Instruction::Sd(SType::new(immediate, F3_SD, OP_SD, rs1, rs2))
}
pub fn new_beq(rs1: Register, rs2: Register, immediate: i32) -> Instruction {
Instruction::Beq(BType::new(immediate, F3_BEQ, OP_BRANCH, rs1, rs2))
}
pub fn new_jal(rd: Register, immediate: i32) -> Instruction {
Instruction::Jal(JType::new(immediate, OP_JAL, rd))
}
pub fn new_lui(rd: Register, immediate: i32) -> Instruction {
Instruction::Lui(UType::new(immediate, OP_LUI, rd))
}
}