#![allow(warnings, unused)]
pub fn instruction_decoder(instr: Vec<&str>) {
let opcode_slice = &instr[25..]; let opcode_slice_joined = opcode_slice.join("");
println!("--------------------------------");
match opcode_slice_joined.as_str() {
"0000011" => { let funct3_slice = &instr[17..20];
let funct3_slice_joined = funct3_slice.join("");
let rd_slice = &instr[20..25];
let rd_slice_joined = rd_slice.join("");
let rs1_slice = &instr[12..17];
let rs1_slice_joined = rs1_slice.join("");
let mut imm_slice = &instr[0..12];
let mut imm_slice_joined = imm_slice.join("");
let rd_bits = i32::from_str_radix(&rd_slice_joined, 2).unwrap();
let rs1_bits = i32::from_str_radix(&rs1_slice_joined, 2).unwrap();
let mut imm_bits = i32::from_str_radix(&imm_slice_joined, 2).unwrap();
if imm_slice[0] == "1" {
let mut x = 1;
loop {
let mut twos = i32::pow(2, x);
if (imm_bits as f32)/(twos as f32) < 1.0 {
imm_bits = imm_bits - twos;
break;
}
else {
x = x + 1;
}
}
}
match funct3_slice_joined.as_str() {
"000" => { println!("Load Byte (LB) instruction decoded");
println!("Destination Register address: x{}", rd_bits);
println!("Register One address: x{}", rs1_bits);
println!("Immediate value: {}", imm_bits);
println!("LB x{}, {}(x{})", rd_bits, imm_bits, rs1_bits);
println!("--------------------------------");
}
"001" => { println!("Load Half-word (LH) instruction decoded");
println!("Destination Register address: x{}", rd_bits);
println!("Register One address: x{}", rs1_bits);
println!("Immediate value: {}", imm_bits);
println!("LH x{}, {}(x{})", rd_bits, imm_bits, rs1_bits);
println!("--------------------------------");
}
"010" => { println!("Load Word (LW) instruction decoded");
println!("Destination Register address: x{}", rd_bits);
println!("Register One address: x{}", rs1_bits);
println!("Immediate value: {}", imm_bits);
println!("LW x{}, {}(x{})", rd_bits, imm_bits, rs1_bits);
println!("--------------------------------");
}
"100" => { println!("Load Byte Unsigned (LBU) instruction decoded");
println!("Destination Register address: x{}", rd_bits);
println!("Register One address: x{}", rs1_bits);
println!("Immediate value: {}", imm_bits);
println!("LBU x{}, {}(x{})", rd_bits, imm_bits, rs1_bits);
println!("--------------------------------");
}
"101" => { println!("Load Half-word Unsigned (LHU) instruction decoded");
println!("Destination Register address: x{}", rd_bits);
println!("Register One address: x{}", rs1_bits);
println!("Immediate value: {}", imm_bits);
println!("LHU x{}, {}(x{})", rd_bits, imm_bits, rs1_bits);
println!("--------------------------------");
}
default => {
panic!("Instruction format error!");
}
&_ => todo!()
}
}
"0100011" => { let funct3_slice = &instr[17..20];
let funct3_slice_joined = funct3_slice.join("");
let rs2_slice = &instr[7..12];
let rs2_slice_joined = rs2_slice.join("");
let rs1_slice = &instr[12..17];
let rs1_slice_joined = rs1_slice.join("");
let mut imm_slice = &instr[0..7];
let mut imm_slice_joined = imm_slice.join("");
let imm2_slice = &instr[20..25];
let imm2_slice_joined = imm2_slice.join("");
imm_slice_joined = imm_slice_joined + &imm2_slice_joined;
let rs1_bits = i32::from_str_radix(&rs1_slice_joined, 2).unwrap();
let rs2_bits = i32::from_str_radix(&rs2_slice_joined, 2).unwrap();
let mut imm_bits = i32::from_str_radix(&imm_slice_joined, 2).unwrap();
if imm_slice[0] == "1" {
let mut x = 1;
loop {
let mut twos = i32::pow(2, x);
if (imm_bits as f32)/(twos as f32) < 1.0 {
imm_bits = imm_bits - twos;
break;
}
else {
x = x + 1;
}
}
}
match funct3_slice_joined.as_str() {
"000" => { println!("Store Byte (SB) instruction decoded");
println!("Register One address: x{}", rs1_bits);
println!("Register Two address: x{}", rs2_bits);
println!("Immediate value: {}", imm_bits);
println!("SB x{}, {}(x{})", rs2_bits, imm_bits, rs1_bits);
println!("--------------------------------");
}
"001" => { println!("Store Half-word (SH) instruction decoded");
println!("Register One address: x{}", rs1_bits);
println!("Register Two address: x{}", rs2_bits);
println!("Immediate value: {}", imm_bits);
println!("SH x{}, {}(x{})", rs2_bits, imm_bits, rs1_bits);
println!("--------------------------------");
}
"010" => { println!("Store Word (SW) instruction decoded");
println!("Register One address: x{}", rs1_bits);
println!("Register Two address: x{}", rs2_bits);
println!("Immediate value: {}", imm_bits);
println!("SW x{}, {}(x{})", rs2_bits, imm_bits, rs1_bits);
println!("--------------------------------");
}
default => {
panic!("Instruction format error!");
}
&_ => todo!()
}
}
"0010011" => { let funct3_slice = &instr[17..20];
let funct3_slice_joined = funct3_slice.join("");
let rd_slice = &instr[20..25];
let rd_slice_joined = rd_slice.join("");
let rs1_slice = &instr[12..17];
let rs1_slice_joined = rs1_slice.join("");
let imm_slice = &instr[0..12];
let mut imm_slice_joined = imm_slice.join("");
let rd_bits = i32::from_str_radix(&rd_slice_joined, 2).unwrap();
let rs1_bits = i32::from_str_radix(&rs1_slice_joined, 2).unwrap();
let mut imm_bits = i32::from_str_radix(&imm_slice_joined, 2).unwrap();
if imm_slice[0] == "1" {
let mut x = 1;
loop {
let mut twos = i32::pow(2, x);
if (imm_bits as f32)/(twos as f32) < 1.0 {
imm_bits = imm_bits - twos;
break;
}
else {
x = x + 1;
}
}
}
match funct3_slice_joined.as_str() {
"000" => { println!("Add Immediate (ADDI) instruction decoded");
println!("Destination Register address: x{}", rd_bits);
println!("Register One address: x{}", rs1_bits);
println!("Immediate value: {}", imm_bits);
println!("ADDI x{}, x{}, {}", rd_bits, rs1_bits, imm_bits);
println!("--------------------------------");
}
"010" => { println!("Set less than Immediate (SLTI) instruction decoded");
println!("Destination Register address: x{}", rd_bits);
println!("Register One address: x{}", rs1_bits);
println!("Immediate value: {}", imm_bits);
println!("SLTI x{}, x{}, {}", rd_bits, rs1_bits, imm_bits);
println!("--------------------------------");
}
"011" => { println!("Set less than Immediate unsigned (SLTIU) instruction decoded");
println!("Destination Register address: x{}", rd_bits);
println!("Register One address: x{}", rs1_bits);
println!("Immediate value: {}", imm_bits);
println!("SLTIU x{}, x{}, {}", rd_bits, rs1_bits, imm_bits);
println!("--------------------------------");
}
"100" => { println!("XOR Immediate (XORI) instruction decoded");
println!("Destination Register address: x{}", rd_bits);
println!("Register One address: x{}", rs1_bits);
println!("Immediate value: {}", imm_bits);
println!("XORI x{}, x{}, {}", rd_bits, rs1_bits, imm_bits);
println!("--------------------------------");
}
"110" => { println!("OR Immediate (ORI) instruction decoded");
println!("Destination Register address: x{}", rd_bits);
println!("Register One address: x{}", rs1_bits);
println!("Immediate value: {}", imm_bits);
println!("ORI x{}, x{}, {}", rd_bits, rs1_bits, imm_bits);
println!("--------------------------------");
}
"111" => { println!("AND Immediate (ANDI) instruction decoded");
println!("Destination Register address: x{}", rd_bits);
println!("Register One address: x{}", rs1_bits);
println!("Immediate value: {}", imm_bits);
println!("ANDI x{}, x{}, {}", rd_bits, rs1_bits, imm_bits);
println!("--------------------------------");
}
default => {
panic!("Instruction format error!");
}
&_ => todo!()
}
}
"0110111" => { let rd_slice = &instr[20..25];
let rd_slice_joined = rd_slice.join("");
let imm_slice = &instr[0..20];
let imm_slice_joined = imm_slice.join("");
let rd_bits = i32::from_str_radix(&rd_slice_joined, 2).unwrap();
let mut imm_bits = i32::from_str_radix(&imm_slice_joined, 2).unwrap();
if imm_slice[0] == "1" {
let mut x = 1;
loop {
let mut twos = i32::pow(2, x);
if (imm_bits as f32)/(twos as f32) < 1.0 {
imm_bits = imm_bits - twos;
break;
}
else {
x = x + 1;
}
}
}
println!("Load Upper Immediate (LUI) instruction decoded");
println!("Destination Register address: x{}", rd_bits);
println!("Immediate address: x{}", imm_bits);
println!("LUI x{}, {}", rd_bits, imm_bits);
println!("--------------------------------");
}
"0010111" => { let rd_slice = &instr[20..25];
let rd_slice_joined = rd_slice.join("");
let imm_slice = &instr[0..20];
let imm_slice_joined = imm_slice.join("");
let rd_bits = i32::from_str_radix(&rd_slice_joined, 2).unwrap();
let mut imm_bits = i32::from_str_radix(&imm_slice_joined, 2).unwrap();
if imm_slice[0] == "1" {
let mut x = 1;
loop {
let mut twos = i32::pow(2, x);
if (imm_bits as f32)/(twos as f32) < 1.0 {
imm_bits = imm_bits - twos;
break;
}
else {
x = x + 1;
}
}
}
println!("Add upper immediate with PC (AUIPC) instruction decoded");
println!("Destination Register address: x{}", rd_bits);
println!("Immediate address: x{}", imm_bits);
println!("AUIPC x{}, {}", rd_bits, imm_bits);
println!("--------------------------------");
}
"1101111" => { let rd_slice = &instr[20..25];
let rd_slice_joined = rd_slice.join("");
let imm_slice = &instr[0..20];
let imm_slice_joined = imm_slice.join("");
let imm_slice_1 = imm_slice[0].to_string(); let imm_slice_2 = &imm_slice[1..10]; let imm_slice_2_joined = imm_slice_2.join("");
let imm_slice_3 = imm_slice[10].to_string(); let imm_slice_4 = &imm_slice[11..20]; let imm_slice_4_joined = imm_slice_4.join("");
let mut imm_final = imm_slice_2_joined + &imm_slice_3 + &imm_slice_4_joined + &imm_slice_1;
let rd_bits = u32::from_str_radix(&rd_slice_joined, 2).unwrap();
let mut imm_bits = i32::from_str_radix(&imm_final, 2).unwrap();
println!("Jump and Link (JAL) instruction decoded");
println!("Destination Register address: x{}", rd_bits);
println!("Immediate address: x{}", imm_bits);
println!("JAL x{}, {}", rd_bits, imm_bits);
println!("--------------------------------");
}
"1100111" => { let rd_slice = &instr[20..25];
let rd_slice_joined = rd_slice.join("");
let imm_slice = &instr[0..12];
let imm_slice_joined = imm_slice.join("");
let rs1_slice = &instr[12..17];
let rs1_slice_joined = rs1_slice.join("");
let rd_bits = i32::from_str_radix(&rd_slice_joined, 2).unwrap();
let rs1_bits = i32::from_str_radix(&rs1_slice_joined, 2).unwrap();
let mut imm_bits = i32::from_str_radix(&imm_slice_joined, 2).unwrap();
if imm_slice[0] == "1" {
let mut x = 1;
loop {
let mut twos = i32::pow(2, x);
if (imm_bits as f32)/(twos as f32) < 1.0 {
imm_bits = imm_bits - twos;
break;
}
else {
x = x + 1;
}
}
}
println!("Jump and Link to register (JALR) instruction decoded");
println!("Destination Register address: x{}", rd_bits);
println!("Register one address: x{}", rs1_bits);
println!("Immediate value: {}", imm_bits);
println!("JALR x{}, x{}, {}", rd_bits, rs1_bits, imm_bits);
println!("--------------------------------");
}
"0110011" => { let funct3_slice = &instr[17..20];
let funct3_slice_joined = funct3_slice.join("");
let funct7_slice = &instr[0..7];
let funct7_slice_joined = funct7_slice.join("");
let rs2_slice = &instr[7..12];
let rs2_slice_joined = rs2_slice.join("");
let rs1_slice = &instr[12..17];
let rs1_slice_joined = rs1_slice.join("");
let rd_slice = &instr[20..25];
let rd_slice_joined = rd_slice.join("");
let rs1_bits = i32::from_str_radix(&rs1_slice_joined, 2).unwrap();
let rs2_bits = i32::from_str_radix(&rs2_slice_joined, 2).unwrap();
let mut rd_bits = i32::from_str_radix(&rd_slice_joined, 2).unwrap();
match funct3_slice_joined.as_str() {
"000" => {
match funct7_slice_joined.as_str() {
"0000000" => { println!("Addition (ADD) instruction decoded");
println!("Destination Register address: x{}", rd_bits);
println!("Register One address: x{}", rs1_bits);
println!("Register Two value: {}", rs2_bits);
println!("ADD x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
println!("--------------------------------");
}
"0100000" => { println!("Subtraction (SUB) instruction decoded");
println!("Destination Register address: x{}", rd_bits);
println!("Register One address: x{}", rs1_bits);
println!("Register Two value: {}", rs2_bits);
println!("SUB x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
println!("--------------------------------");
}
"0000001" => { println!("Multiplication (MUL) instruction decoded");
println!("Destination Register address: x{}", rd_bits);
println!("Register One address: x{}", rs1_bits);
println!("Register Two value: {}", rs2_bits);
println!("MUL x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
println!("--------------------------------");
}
&_ => todo!()
}
}
"001" => {
match funct7_slice_joined.as_str() {
"0000000" => { println!("Shift Left Logical (SLL) instruction decoded");
println!("Destination Register address: x{}", rd_bits);
println!("Register One address: x{}", rs1_bits);
println!("Register Two value: {}", rs2_bits);
println!("SLL x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
println!("--------------------------------");
}
"0000001" => { println!("Multiply High Signed (MULH) instruction decoded");
println!("Destination Register address: x{}", rd_bits);
println!("Register One address: x{}", rs1_bits);
println!("Register Two value: {}", rs2_bits);
println!("MULH x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
println!("--------------------------------");
}
&_ => todo!()
}
}
"010" => {
match funct7_slice_joined.as_str() {
"0000000" => { println!("Set less than (SLT) instruction decoded");
println!("Destination Register address: x{}", rd_bits);
println!("Register One address: x{}", rs1_bits);
println!("Register Two value: {}", rs2_bits);
println!("SLT x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
println!("--------------------------------");
}
"0000001" => { println!("Multiply High Unsigned with signed (MULHSU) instruction decoded");
println!("Destination Register address: x{}", rd_bits);
println!("Register One address: x{}", rs1_bits);
println!("Register Two value: {}", rs2_bits);
println!("MULHSU x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
println!("--------------------------------");
}
&_ => todo!()
}
}
"011" => {
match funct7_slice_joined.as_str() {
"0000000" => { println!("Set less than unsigned (SLTU) instruction decoded");
println!("Destination Register address: x{}", rd_bits);
println!("Register One address: x{}", rs1_bits);
println!("Register Two value: {}", rs2_bits);
println!("SLTU x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
println!("--------------------------------");
}
"0000001" => { println!("Multiply High Unsigned (MULHU) instruction decoded");
println!("Destination Register address: x{}", rd_bits);
println!("Register One address: x{}", rs1_bits);
println!("Register Two value: {}", rs2_bits);
println!("MULHU x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
println!("--------------------------------");
}
&_ => todo!()
}
}
"100" => {
match funct7_slice_joined.as_str() {
"0000000" => { println!("XOR instruction decoded");
println!("Destination Register address: x{}", rd_bits);
println!("Register One address: x{}", rs1_bits);
println!("Register Two value: {}", rs2_bits);
println!("XOR x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
println!("--------------------------------");
}
"0000001" => { println!("Divide Signed (DIV) instruction decoded");
println!("Destination Register address: x{}", rd_bits);
println!("Register One address: x{}", rs1_bits);
println!("Register Two address: x{}", rs2_bits);
println!("DIV x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
println!("--------------------------------");
}
&_ => todo!()
}
}
"101" => { match funct7_slice_joined.as_str() {
"0000000" => { println!("Shift Right Logical (SRL) instruction decoded");
println!("Destination Register address: x{}", rd_bits);
println!("Register One address: x{}", rs1_bits);
println!("Register Two value: {}", rs2_bits);
println!("SRL x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
println!("--------------------------------");
}
"0000001" => { println!("Divide Unsigned (DIVU) instruction decoded");
println!("Destination Register address: x{}", rd_bits);
println!("Register One address: x{}", rs1_bits);
println!("Register Two address: x{}", rs2_bits);
println!("DIVU x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
println!("--------------------------------");
}
"0100000" => { println!("Shift Right Arithmetic (SRA) instruction decoded");
println!("Destination Register address: x{}", rd_bits);
println!("Register One address: x{}", rs1_bits);
println!("Register Two value: {}", rs2_bits);
println!("SRA x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
println!("--------------------------------");
}
&_ => todo!()
}
}
"110" => {
match funct7_slice_joined.as_str() {
"0000000" => { println!("OR instruction decoded");
println!("Destination Register address: x{}", rd_bits);
println!("Register One address: x{}", rs1_bits);
println!("Register Two value: {}", rs2_bits);
println!("OR x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
println!("--------------------------------");
}
"0000001" => { println!("Remainder Signed (REM) instruction decoded");
println!("Destination Register address: x{}", rd_bits);
println!("Register One address: x{}", rs1_bits);
println!("Register Two address: x{}", rs2_bits);
println!("REM x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
println!("--------------------------------");
}
&_ => todo!()
}
}
"111" => {
match funct7_slice_joined.as_str() {
"0000000" => { println!("AND instruction decoded");
println!("Destination Register address: x{}", rd_bits);
println!("Register One address: x{}", rs1_bits);
println!("Register Two value: {}", rs2_bits);
println!("AND x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
println!("--------------------------------");
}
"0000001" => { println!("Remainder Unsigned (REMU) instruction decoded");
println!("Destination Register address: x{}", rd_bits);
println!("Register One address: x{}", rs1_bits);
println!("Register Two address: x{}", rs2_bits);
println!("REMU x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
println!("--------------------------------");
}
&_ => todo!()
}
}
&_ => todo!()
}
}
default => {
panic!("Opcode not found!");
}
&_ => todo!()
}
}