package projet.op

import chisel3._
import chisel3.util.switch
import projet.CUInterface
import projet.AluOpCode
import chisel3.util.is

object OpM {
    // Implements functions for instructions of the M extension of type R
    def opM(io: CUInterface) = {
        val funct3 = io.instruction(14, 12);
        // Meaning of Funct3 in the context of an OpM instruction
        object Funct3 extends ChiselEnum {
            val MUL = "b000".U
            val MULH = "b001".U
            val MULHSU = "b010".U
            val MULHU = "b011".U
            val DIV = "b100".U
            val DIVU = "b101".U
            val REM = "b110".U
            val REMU = "b111".U
        }

        io.reg_file_we := true.B // Write to regfile
        io.should_stall := true.B
        switch(funct3) {
            is(Funct3.MUL) {
                io.alu_opcode := AluOpCode.Mul
            }
            is(Funct3.MULH) {
                io.alu_opcode := AluOpCode.Mulh
            }
            is(Funct3.MULHSU) {
                io.alu_opcode := AluOpCode.Mulhsu
            }
            is(Funct3.MULHU) {
                io.alu_opcode := AluOpCode.Mulhu
            }
            is(Funct3.DIV) {
                io.alu_opcode := AluOpCode.Div
            }
            is(Funct3.DIVU) {
                io.alu_opcode := AluOpCode.Divu
            }
            is(Funct3.REM) {
                io.alu_opcode := AluOpCode.Rem
            }
            is(Funct3.REMU) {
                io.alu_opcode := AluOpCode.Remu
            }
        }
    }
}
