use crate::decode::*; use crate::print::*; // doit disparaitre const MEM_SIZE : usize= 4096; pub struct Machine { pub pc : u32, pub int_reg : [u32 ; 32], pub instructions : [u32 ; 100], pub main_memory : [u8 ; MEM_SIZE] // 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 } impl Machine { pub fn _init_machine() -> Machine { Machine { pc : 0, instructions : [0 ; 100], int_reg : [0 ; 32], main_memory : [0 ; MEM_SIZE] } } pub fn one_instruction(mut machine : Machine) -> Machine { let mut unsigned_reg1 : u64 = 0; let mut unsigned_reg2 : u64 = 0; if machine.instructions.len() <= machine.pc as usize { println!("ERROR : number max of instructions rushed"); return machine; } let inst : Instruction = decode(machine.instructions[machine.pc as usize]); machine.pc += 4; match inst.opcode { RISCV_LUI => { machine.int_reg[inst.rd as usize] = inst.imm31_12; }, //****************************************************************************************** // Treatment for: OPI INSTRUCTIONS RISCV_OPI => { match inst.funct3 { RISCV_OPI_ADDI => { machine.int_reg[inst.rd as usize] = machine.int_reg[inst.rs1 as usize] + inst.imm12_I_signed as u32; }, RISCV_OPI_SLTI => { machine.int_reg[inst.rd as usize] = if machine.int_reg[inst.rs1 as usize] < inst.imm12_I_signed as u32 { 1 } else { 0 }; }, RISCV_OPI_XORI => { machine.int_reg[inst.rd as usize] = machine.int_reg[inst.rs1 as usize] ^ inst.imm12_I_signed as u32; }, RISCV_OPI_ORI => { machine.int_reg[inst.rd as usize] = machine.int_reg[inst.rs1 as usize] | inst.imm12_I_signed as u32; }, RISCV_OPI_ANDI => { machine.int_reg[inst.rd as usize] = machine.int_reg[inst.rs1 as usize] & inst.imm12_I_signed as u32; }, RISCV_OPI_SLLI => { machine.int_reg[inst.rd as usize] = machine.int_reg[inst.rs1 as usize] << inst.shamt; } _ => { println!("{} inconnu", inst.funct3); } } }, RISCV_JAL => { machine.int_reg[inst.rd as usize] = machine.pc; machine.pc = machine.pc - 4 + (inst.imm21_1_signed as u32); }, RISCV_OP => { match inst.funct3 { RISCV_OP_ADD => { // RISCV_OP_ADD_ADD inaccessible /*if (inst.funct7 == RISCV_OP_ADD_ADD) { machine.int_reg[inst.rd as usize] = machine.int_reg[inst.rs1 as usize] + machine.int_reg[inst.rs2 as usize];*/ machine.int_reg[inst.rd as usize] = machine.int_reg[inst.rs1 as usize] - machine.int_reg[inst.rs2 as usize]; //} }, RISCV_OP_SLL => { machine.int_reg[inst.rd as usize] = machine.int_reg[inst.rs1 as usize] << (machine.int_reg[inst.rs2 as usize] & 0x3f); }, RISCV_OP_SLT => { if machine.int_reg[inst.rs1 as usize] < machine.int_reg[inst.rs2 as usize] { machine.int_reg[inst.rd as usize] = 1; } else { machine.int_reg[inst.rd as usize] = 0; } }, RISCV_OP_SLTU => { unsigned_reg1 = machine.int_reg[inst.rs1 as usize] as u64; unsigned_reg2 = machine.int_reg[inst.rs2 as usize] as u64; if unsigned_reg1 < unsigned_reg2 { machine.int_reg[inst.rd as usize] = 1; } else { machine.int_reg[inst.rd as usize] = 0; } }, RISCV_OP_XOR => { machine.int_reg[inst.rd as usize] = machine.int_reg[inst.rs1 as usize] ^ machine.int_reg[inst.rs2 as usize]; }, RISCV_OP_SR => { // RISCV_OP_SR_SRL inaccessible machine.int_reg[inst.rd as usize] = machine.int_reg[inst.rs1 as usize] >> (machine.int_reg[inst.rs2 as usize] & 0x3f); }, RISCV_OP_OR => { machine.int_reg[inst.rd as usize] = machine.int_reg[inst.rs1 as usize] | machine.int_reg[inst.rs2 as usize]; }, RISCV_OP_AND => { machine.int_reg[inst.rd as usize] = machine.int_reg[inst.rs1 as usize] & machine.int_reg[inst.rs2 as usize]; }, _ => { println!("RISCV_OP undefined case\n"); } } } _ => { println!("{} opcode non géré", inst.opcode)}, } machine } } #[cfg(test)] mod test { use super::Machine; }