diff --git a/src/machine.rs b/src/machine.rs index 2bb70f7..58f66a5 100644 --- a/src/machine.rs +++ b/src/machine.rs @@ -9,7 +9,8 @@ pub struct Machine { pub pc : u32, pub int_reg : [u32 ; 32], pub instructions : [u32 ; 100], - pub main_memory : [u8 ; MEM_SIZE] + pub main_memory : [u8 ; MEM_SIZE], + pub shiftmask : [u32 ; 32] // futur taille à calculer int memSize = g_cfg->NumPhysPages * g_cfg->PageSize; //creer une struct cfg(configuration) qui s'initialise avec valeur dans un fichier cfg } @@ -18,12 +19,21 @@ pub struct Machine { impl Machine { pub fn _init_machine() -> Machine { + let mut shiftmask : [u32 ; 32] = [0 ; 32]; + let mut value : u32 = 0xffff; + + value = (value << 16) + value; + for i in 0..32 { + shiftmask[i] = value; + value = value >> 1; + } Machine { pc : 0, instructions : [0 ; 100], int_reg : [0 ; 32], - main_memory : [0 ; MEM_SIZE] + main_memory : [0 ; MEM_SIZE], + shiftmask : shiftmask } } @@ -68,6 +78,13 @@ impl Machine { }, RISCV_OPI_SLLI => { machine.int_reg[inst.rd as usize] = machine.int_reg[inst.rs1 as usize] << inst.shamt; + }, + RISCV_OPI_SRI => { + if inst.funct7_smaller == RISCV_OPI_SRI_SRLI { + machine.int_reg[inst.rd as usize] = (machine.int_reg[inst.rs1 as usize] >> inst.shamt) & machine.shiftmask[inst.shamt as usize]; + } else { // SRAI + machine.int_reg[inst.rd as usize] = (machine.int_reg[inst.rs1 as usize] >> inst.shamt); + } } _ => { println!("{} inconnu", inst.funct3); } } @@ -123,6 +140,65 @@ impl Machine { println!("RISCV_OP undefined case\n"); } } + }, + //****************************************************************************************** + // Treatment for: OPW INSTRUCTIONS + RISCV_OPW => { + if inst.funct7 == 1 { + let localDataa = machine.int_reg[inst.rs1 as usize] & 0xffffffff; + let localDatab = machine.int_reg[inst.rs2 as usize] & 0xffffffff; + let localDataaUnsigned = machine.int_reg[inst.rs1 as usize] & 0xffffffff; + let localDatabUnsigned = machine.int_reg[inst.rs2 as usize] & 0xffffffff; + + // Match case for multiplication operations (in standard extension RV32M) + match inst.funct3 { + RISCV_OPW_M_MULW => { + machine.int_reg[inst.rd as usize] = localDataa * localDatab; + }, + RISCV_OPW_M_DIVW => { + machine.int_reg[inst.rd as usize] = localDataa / localDatab; + }, + RISCV_OPW_M_DIVUW => { + machine.int_reg[inst.rd as usize] = localDataaUnsigned / localDatabUnsigned; + }, + RISCV_OPW_M_REMW => { + machine.int_reg[inst.rd as usize] = localDataa % localDatab; + }, + RISCV_OPW_M_REMUW => { + machine.int_reg[inst.rd as usize] = localDataaUnsigned % localDatabUnsigned; + }, + _ => { + println!("this instruction ({}) doesn't exists", inst.value); + } + } + } else { + let localDataa = machine.int_reg[inst.rs1 as usize] & 0xffffffff; + let localDatab = machine.int_reg[inst.rs2 as usize] & 0xffffffff; + + // Match case for base OP operation + match inst.funct3 { + RISCV_OPW_ADDSUBW => { + if inst.funct7 == RISCV_OPW_ADDSUBW_ADDW { + machine.int_reg[inst.rd as usize] = localDataa + localDatab; + } else { // SUBW + machine.int_reg[inst.rd as usize] = localDataa - localDatab; + } + }, + RISCV_OPW_SLLW => { + machine.int_reg[inst.rd as usize] = localDataa << (localDatab & 0x1f); + }, + RISCV_OPW_SRW => { + if inst.funct7 == RISCV_OPW_SRW_SRLW { + machine.int_reg[inst.rd as usize] = localDataa >> (localDatab & 0x1f) & machine.shiftmask[32 + localDatab as usize]; + } else { // SRAW + machine.int_reg[inst.rd as usize] = localDataa >> (localDatab & 0x1f); + } + }, + _ => { + println!("this instruction ({}) doesn't exists", inst.value); + } + } + } } _ => { println!("{} opcode non géré", inst.opcode)}, } diff --git a/src/print.rs b/src/print.rs index 4aa70b0..788a6bd 100644 --- a/src/print.rs +++ b/src/print.rs @@ -130,6 +130,38 @@ pub const RISCV_FP_FCMP_FLE: u8 = 0; pub const RISCV_FP_FMVW: u8 = 0x78; +pub const RISCV_OP_M: u8 = 0x1; + +pub const RISCV_OP_M_MUL: u8 = 0x0; +pub const RISCV_OP_M_MULH: u8 = 0x1; +pub const RISCV_OP_M_MULHSU: u8 = 0x2; +pub const RISCV_OP_M_MULHU: u8 = 0x3; +pub const RISCV_OP_M_DIV: u8 = 0x4; +pub const RISCV_OP_M_DIVU: u8 = 0x5; +pub const RISCV_OP_M_REM: u8 = 0x6; +pub const RISCV_OP_M_REMU: u8 = 0x7; + +pub const RISCV_OPW_M_MULW: u8 = 0x0; +pub const RISCV_OPW_M_DIVW: u8 = 0x4; +pub const RISCV_OPW_M_DIVUW: u8 = 0x5; +pub const RISCV_OPW_M_REMW: u8 = 0x6; +pub const RISCV_OPW_M_REMUW: u8 = 0x7; + +pub const RISCV_FENCE: u8 = 0x0f; + +pub const RISCV_ATOM: u8 = 0x2f; +pub const RISCV_ATOM_LR: u8 = 0x2; +pub const RISCV_ATOM_SC: u8 = 0x3; +pub const RISCV_ATOM_SWAP: u8 = 0x1; +pub const RISCV_ATOM_ADD: u8 = 0; +pub const RISCV_ATOM_XOR: u8 = 0x4; +pub const RISCV_ATOM_AND: u8 = 0xc; +pub const RISCV_ATOM_OR: u8 = 0x8; +pub const RISCV_ATOM_MIN: u8 = 0x10; +pub const RISCV_ATOM_MAX: u8 = 0x14; +pub const RISCV_ATOM_MINU: u8 = 0x18; +pub const RISCV_ATOM_MAXU: u8 = 0x1c; + const names_op: [&str; 8] = ["add", "sll", "slt", "sltu", "xor", "sr", "or", "and"]; const names_opi: [&str; 8] = ["addi", "slli", "slti", "sltiu", "xori", "slri", "ori", "andi"];