Skip to content

Modeler extension #52

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 28 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
e978aec
Modeler: change addiw to use AND instead of SLL+SRL
CAS-ual-TY Jan 18, 2023
79283ff
Modeler: implement addw
CAS-ual-TY Jan 18, 2023
c40e817
Modeler: implement subw
CAS-ual-TY Jan 18, 2023
a7b9e7b
Modeler: improve/simplify slliw
CAS-ual-TY Jan 25, 2023
fd96e2c
Modeler: improve/simplify srliw
CAS-ual-TY Jan 25, 2023
badb5c9
Modeler: improve/simplify sraiw
CAS-ual-TY Jan 25, 2023
59f5105
Modeler: Mark rem and remw as unreachable
CAS-ual-TY Jan 25, 2023
b2a7ed3
Modeler: Improve and wrappers for 32-bit
CAS-ual-TY Jan 25, 2023
2205801
Modeler: Mark slti as unreachable
CAS-ual-TY Jan 28, 2023
22d52a2
Modeler: mark new instructions available
CAS-ual-TY Jan 28, 2023
d35deea
Emulator + Modeler: implement lwu
CAS-ual-TY Jan 28, 2023
7615560
Emulator: Implement slti
CAS-ual-TY Jan 28, 2023
4ff264d
Emulator: Implement rem
CAS-ual-TY Jan 28, 2023
c96655f
Emulator: Implement divw
CAS-ual-TY Jan 28, 2023
982750d
Emulator: Implement remw
CAS-ual-TY Jan 28, 2023
ff31f94
Modeler: Implement sllw
CAS-ual-TY Jan 28, 2023
ebb0173
Modeler: Rename some variables
CAS-ual-TY Jan 28, 2023
940f3b2
Revert: Modeler: Implement sllw
CAS-ual-TY Jan 28, 2023
5a0e186
Revert "Modeler: mark new instructions available"
CAS-ual-TY Jan 28, 2023
63ed28e
Revert "Modeler: Mark rem and remw as unreachable"
CAS-ual-TY Jan 28, 2023
4037071
Merge remote-tracking branch 'upstream/main' into modeler-extension
CAS-ual-TY Jan 28, 2023
8a91fc1
Emulator: Implement xor
CAS-ual-TY Jan 28, 2023
65fe137
Modeler: Implement srlw
CAS-ual-TY Jan 28, 2023
aaf2b3f
Modeler: Implement sraw
CAS-ual-TY Jan 28, 2023
d20d13c
Modeler: Implement divuw
CAS-ual-TY Jan 28, 2023
50c447a
Modeler: Implement remuw
CAS-ual-TY Jan 28, 2023
53633a3
Modeler: Reorder instructions list to match emulator
CAS-ual-TY Jan 29, 2023
1d34637
Modeler: Rename some variables for clarity
CAS-ual-TY Jan 29, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 87 additions & 0 deletions src/emulate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,11 +246,13 @@ fn execute(state: &mut EmulatorState, instr: Instruction) {
Instruction::Ld(itype) => exec_ld(state, itype),
Instruction::Lbu(itype) => exec_lbu(state, itype),
Instruction::Lhu(itype) => exec_lhu(state, itype),
Instruction::Lwu(itype) => exec_lwu(state, itype),
Instruction::Sb(stype) => exec_sb(state, stype),
Instruction::Sh(stype) => exec_sh(state, stype),
Instruction::Sw(stype) => exec_sw(state, stype),
Instruction::Sd(stype) => exec_sd(state, stype),
Instruction::Addi(itype) => exec_addi(state, itype),
Instruction::Slti(itype) => exec_slti(state, itype),
Instruction::Sltiu(itype) => exec_sltiu(state, itype),
Instruction::Xori(itype) => exec_xori(state, itype),
Instruction::Ori(itype) => exec_ori(state, itype),
Expand All @@ -267,6 +269,7 @@ fn execute(state: &mut EmulatorState, instr: Instruction) {
Instruction::Sll(rtype) => exec_sll(state, rtype),
Instruction::Slt(rtype) => exec_slt(state, rtype),
Instruction::Sltu(rtype) => exec_sltu(state, rtype),
Instruction::Xor(rtype) => exec_xor(state, rtype),
Instruction::Srl(rtype) => exec_srl(state, rtype),
Instruction::Sra(rtype) => exec_sra(state, rtype),
Instruction::Or(rtype) => exec_or(state, rtype),
Expand All @@ -279,9 +282,13 @@ fn execute(state: &mut EmulatorState, instr: Instruction) {
Instruction::Addw(rtype) => exec_addw(state, rtype),
Instruction::Subw(rtype) => exec_subw(state, rtype),
Instruction::Sllw(rtype) => exec_sllw(state, rtype),
Instruction::Srlw(rtype) => exec_srlw(state, rtype),
Instruction::Sraw(rtype) => exec_sraw(state, rtype),
Instruction::Mulw(rtype) => exec_mulw(state, rtype),
Instruction::Divw(rtype) => exec_divw(state, rtype),
Instruction::Divuw(rtype) => exec_divuw(state, rtype),
Instruction::Remw(rtype) => exec_remw(state, rtype),
Instruction::Remuw(rtype) => exec_remuw(state, rtype),
Instruction::Ecall(_itype) => exec_ecall(state),
// TODO: Cover all needed instructions here.
_ => unimplemented!("not implemented: {:?}", instr),
Expand Down Expand Up @@ -485,6 +492,17 @@ fn exec_lw(state: &mut EmulatorState, itype: IType) {
state.pc_next();
}

// rd = z64(mem32[rs1 + u64(imm{12})])
// pc = pc + 4
fn exec_lwu(state: &mut EmulatorState, itype: IType) {
let rs1_value = state.get_reg(itype.rs1());
let address = rs1_value.wrapping_add(itype.imm() as u64);
let rd_value = state.get_mem_typed::<u32>(address) as u64;
trace_itype(state, "lwu", itype, rd_value);
state.set_reg(itype.rd(), rd_value);
state.pc_next();
}

// rd = mem[rs1 + s64(imm{12})]
// pc = pc + 4
fn exec_ld(state: &mut EmulatorState, itype: IType) {
Expand Down Expand Up @@ -560,6 +578,18 @@ fn exec_addiw(state: &mut EmulatorState, itype: IType) {
state.pc_next();
}

// rd = 1 ||| if (rs1 <s s64(imm{12}))
// rd = 0 ||| otherwise
// pc = pc + 4
fn exec_slti(state: &mut EmulatorState, itype: IType) {
let rs1_value = state.get_reg(itype.rs1());
let condition = (rs1_value as i64) < itype.imm();
let rd_value = EmulatorValue::from(condition);
trace_itype(state, "slti", itype, rd_value);
state.set_reg(itype.rd(), rd_value);
state.pc_next();
}

// rd = 1 ||| if (rs1 <u s64(imm{12}))
// rd = 0 ||| otherwise
// pc = pc + 4
Expand All @@ -572,6 +602,17 @@ fn exec_sltiu(state: &mut EmulatorState, itype: IType) {
state.pc_next();
}

// rd = rs1 ^ rs2
// pc = pc + 4
fn exec_xor(state: &mut EmulatorState, rtype: RType) {
let rs1_value = state.get_reg(rtype.rs1());
let rs2_value = state.get_reg(rtype.rs2());
let rd_value = rs1_value ^ rs2_value;
trace_rtype(state, "xor", rtype, rd_value);
state.set_reg(rtype.rd(), rd_value);
state.pc_next();
}

// rd = rs1 ^ s64(imm{12})
// pc = pc + 4
fn exec_xori(state: &mut EmulatorState, itype: IType) {
Expand Down Expand Up @@ -728,6 +769,28 @@ fn exec_sllw(state: &mut EmulatorState, rtype: RType) {
state.pc_next();
}

// rd = s64(rs1{32} >>u z32(rs2{6}))
// pc = pc + 4
fn exec_srlw(state: &mut EmulatorState, rtype: RType) {
let rs1_value = state.get_reg(rtype.rs1());
let rs2_value = state.get_reg(rtype.rs2());
let rd_value = (rs1_value as u32).wrapping_shr(rs2_value as u32) as u64;
trace_rtype(state, "srlw", rtype, rd_value);
state.set_reg(rtype.rd(), rd_value);
state.pc_next();
}

// rd = s64(rs1{32} >>s z32(rs2{6}))
// pc = pc + 4
fn exec_sraw(state: &mut EmulatorState, rtype: RType) {
let rs1_value = state.get_reg(rtype.rs1());
let rs2_value = state.get_reg(rtype.rs2());
let rd_value = (rs1_value as i32).wrapping_shr(rs2_value as u32) as u64;
trace_rtype(state, "sraw", rtype, rd_value);
state.set_reg(rtype.rd(), rd_value);
state.pc_next();
}

// rd = rs1 >>u z32(rs2{6})
// pc = pc + 4
fn exec_srl(state: &mut EmulatorState, rtype: RType) {
Expand Down Expand Up @@ -856,6 +919,18 @@ fn exec_divu(state: &mut EmulatorState, rtype: RType) {
state.pc_next();
}

// rd = s64(rs1{32} /u rs2{32})
// pc = pc + 4
fn exec_divuw(state: &mut EmulatorState, rtype: RType) {
let rs1_value = state.get_reg(rtype.rs1());
let rs2_value = state.get_reg(rtype.rs2());
assert!((rs2_value as u32) != 0, "check for non-zero divisor");
let rd_value = (rs1_value as u32).wrapping_div(rs2_value as u32) as u64;
trace_rtype(state, "divuw", rtype, rd_value);
state.set_reg(rtype.rd(), rd_value);
state.pc_next();
}

// rd = rs1 %s rs2
// pc = pc + 4
fn exec_rem(state: &mut EmulatorState, rtype: RType) {
Expand Down Expand Up @@ -892,6 +967,18 @@ fn exec_remu(state: &mut EmulatorState, rtype: RType) {
state.pc_next();
}

// rd = s64(rs1{32} %u rs2{32})
// pc = pc + 4
fn exec_remuw(state: &mut EmulatorState, rtype: RType) {
let rs1_value = state.get_reg(rtype.rs1());
let rs2_value = state.get_reg(rtype.rs2());
assert!((rs2_value as u32) != 0, "check for non-zero divisor");
let rd_value = (rs1_value as u32).wrapping_rem(rs2_value as u32) as u64;
trace_rtype(state, "remuw", rtype, rd_value);
state.set_reg(rtype.rd(), rd_value);
state.pc_next();
}

fn exec_ecall(state: &mut EmulatorState) {
let a7_value = state.get_reg(Register::A7);
if a7_value == SyscallId::Exit as u64 {
Expand Down
Loading