Add special handlers for shift instructions.
This commit is contained in:
parent
9358c3a6be
commit
8e2d686b5c
8 changed files with 84 additions and 62 deletions
|
@ -93,14 +93,17 @@ object Ops {
|
|||
def or( rd: Int, rs1: Int, imm: Int) = ArithImm(Reg(rd), Reg(rs1), Imm(imm), OR)
|
||||
def xor( rd: Int, rs1: Int, imm: Int) = ArithImm(Reg(rd), Reg(rs1), Imm(imm), XOR)
|
||||
def and( rd: Int, rs1: Int, imm: Int) = ArithImm(Reg(rd), Reg(rs1), Imm(imm), AND)
|
||||
def sll( rd: Int, rs1: Int, imm: Int) = ArithImm(Reg(rd), Reg(rs1), Imm(imm), SLL)
|
||||
def srl( rd: Int, rs1: Int, imm: Int) = ArithImm(Reg(rd), Reg(rs1), Imm(imm), SRL)
|
||||
def sra( rd: Int, rs1: Int, imm: Int) = ArithImm(Reg(rd), Reg(rs1), Imm(imm), SRA)
|
||||
def slt( rd: Int, rs1: Int, imm: Int) = ArithImm(Reg(rd), Reg(rs1), Imm(imm), SLT)
|
||||
def sltu(rd: Int, rs1: Int, imm: Int) = ArithImm(Reg(rd), Reg(rs1), Imm(imm), SLTU)
|
||||
def nop = add(0, 0, 0)
|
||||
}
|
||||
|
||||
case class ArithImmShift(imm11: Imm, rd: Reg, rs1: Reg, shamt: Imm, op: ArithOp) extends Op with IType
|
||||
object ArithImmShift {
|
||||
def sll( rd: Int, rs1: Int, imm: Int) = ArithImmShift(Imm(0), Reg(rd), Reg(rs1), Imm(imm), SLL)
|
||||
def srl( rd: Int, rs1: Int, imm: Int) = ArithImmShift(Imm(0), Reg(rd), Reg(rs1), Imm(imm), SRL)
|
||||
def sra( rd: Int, rs1: Int, imm: Int) = ArithImmShift(Imm(32), Reg(rd), Reg(rs1), Imm(imm), SRA)
|
||||
}
|
||||
|
||||
case class LUI(rd: Reg, imm: Imm) extends Op with UType
|
||||
case class AUIPC(rd: Reg, imm: Imm) extends Op with UType
|
||||
|
|
|
@ -84,9 +84,9 @@ object Parser {
|
|||
stringWs("xori") ~> arithImm.mapN{ArithImm.xor},
|
||||
stringWs("andi") ~> arithImm.mapN{ArithImm.and},
|
||||
|
||||
stringWs("slli") ~> arithImm.mapN{ArithImm.sll},
|
||||
stringWs("srli") ~> arithImm.mapN{ArithImm.srl},
|
||||
stringWs("srai") ~> arithImm.mapN{ArithImm.sra},
|
||||
stringWs("slli") ~> arithImm.mapN{ArithImmShift.sll},
|
||||
stringWs("srli") ~> arithImm.mapN{ArithImmShift.srl},
|
||||
stringWs("srai") ~> arithImm.mapN{ArithImmShift.sra},
|
||||
|
||||
stringWs("slti") ~> arithImm.mapN{ArithImm.slt},
|
||||
stringWs("sltiu") ~> arithImm.mapN{ArithImm.sltu},
|
||||
|
@ -160,16 +160,16 @@ object Parser {
|
|||
SW(placeHolder, 0, 2048),
|
||||
LW(placeHolder, rs1.value, (offset & 0xFFFFFF1C)),
|
||||
LW(rd.value, rs1.value, (offset & 0xFFFFFF1C) + 4),
|
||||
ArithImm.sra(placeHolder, placeHolder, 24),
|
||||
ArithImm.sll(rd.value, rd.value, 24),
|
||||
ArithImm.sra(rd.value, rd.value, 16),
|
||||
ArithImmShift.sra(placeHolder, placeHolder, 24),
|
||||
ArithImmShift.sll(rd.value, rd.value, 24),
|
||||
ArithImmShift.sra(rd.value, rd.value, 16),
|
||||
Arith.add(rd, rd, placeHolder),
|
||||
LW(placeHolder, 0, 2048)).reverse
|
||||
}
|
||||
case (rd, offset, rs1) if (offset % 4 == 2) => {
|
||||
List(
|
||||
LW(rd, rs1, (offset & 0xFFFFFF1C)),
|
||||
ArithImm.sra(rd, rd, 16)
|
||||
ArithImmShift.sra(rd, rd, 16)
|
||||
).reverse
|
||||
}
|
||||
|
||||
|
@ -177,8 +177,8 @@ object Parser {
|
|||
val leftShift = if((offset % 4) == 0) 16 else 8
|
||||
List(
|
||||
LW(rd, rs1, (offset & 0xFFFFFF1C)),
|
||||
ArithImm.sll(rd, rd, leftShift),
|
||||
ArithImm.sra(rd, rd, 16),
|
||||
ArithImmShift.sll(rd, rd, leftShift),
|
||||
ArithImmShift.sra(rd, rd, 16),
|
||||
).reverse
|
||||
}
|
||||
}.map(_.widen[Op]),
|
||||
|
|
|
@ -23,16 +23,17 @@ case class VM(
|
|||
def stepInstruction: Either[Finished, ExecutionTrace[VM]] = {
|
||||
if (pc.value == 0xEB1CEB1C) Left(Success)
|
||||
else getOp flatMap {
|
||||
case op: Branch => executeBranch(op)
|
||||
case op: Arith => executeArith(op)
|
||||
case op: ArithImm => executeArithImm(op)
|
||||
case op: AUIPC => executeAUIPC(op)
|
||||
case op: LUI => executeLUI(op)
|
||||
case op: JALR => executeJALR(op)
|
||||
case op: JAL => executeJAL(op)
|
||||
case op: LW => executeLW(op)
|
||||
case op: SW => executeSW(op)
|
||||
case DONE => Left(Success)
|
||||
case op: Branch => executeBranch(op)
|
||||
case op: Arith => executeArith(op)
|
||||
case op: ArithImm => executeArithImm(op)
|
||||
case op: ArithImmShift => executeArithImmShift(op)
|
||||
case op: AUIPC => executeAUIPC(op)
|
||||
case op: LUI => executeLUI(op)
|
||||
case op: JALR => executeJALR(op)
|
||||
case op: JAL => executeJAL(op)
|
||||
case op: LW => executeLW(op)
|
||||
case op: SW => executeSW(op)
|
||||
case DONE => Left(Success)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,6 +76,13 @@ case class VM(
|
|||
}
|
||||
|
||||
|
||||
private def executeArithImmShift(op: ArithImmShift) = {
|
||||
val (regUpdate, nextRegs) = regs.arithImm(op.rd, op.rs1, op.shamt, op.op.run)
|
||||
val nextVM = this.copy(regs = nextRegs)
|
||||
Right(step(nextVM, regUpdate.toList:_*))
|
||||
}
|
||||
|
||||
|
||||
private def executeLUI(op: LUI) = {
|
||||
val (regUpdate, nextRegs) = regs + (op.rd -> (op.imm.value << 12))
|
||||
val nextVM = this.copy(regs = nextRegs)
|
||||
|
|
|
@ -125,12 +125,17 @@ object assembler {
|
|||
}
|
||||
|
||||
/**
|
||||
* Currently not used, thus we allow too larg shifts.
|
||||
* Used by SRI, SRAI, SLLI
|
||||
*/
|
||||
def setShiftTypeImmediate(instruction: Int, immediate: Int): Int = {
|
||||
val points = List((24, 5))
|
||||
val withField = applyImmediate(5, immediate, points)(instruction)
|
||||
withField
|
||||
def setShiftTypeImmediate(funct7: Int, shamt: Int, addr: Addr): Int => InstructionFragment = {
|
||||
val shamtPoints = List((24, 5))
|
||||
val funct7Points = List((31, 6))
|
||||
|
||||
base => {
|
||||
val withF7 = applyImmediateU(funct7, funct7Points, addr)(base)
|
||||
val withShamt = withF7.flatMap(base2 => applyImmediateU(shamt, shamtPoints, addr)(base2))
|
||||
withShamt
|
||||
}
|
||||
}
|
||||
|
||||
def setOpCode(opcode: Int): Int => Int = setField(0, 7, opcode)
|
||||
|
@ -142,16 +147,17 @@ object assembler {
|
|||
|
||||
|
||||
def setOpCode(op: Op): Int => Int = op match {
|
||||
case x: Branch => setOpCode("1100011".binary)
|
||||
case x: Arith => setOpCode("0110011".binary)
|
||||
case x: ArithImm => setOpCode("0010011".binary)
|
||||
case x: LW => setOpCode("0000011".binary)
|
||||
case x: SW => setOpCode("0100011".binary)
|
||||
case x: JALR => setOpCode("1100111".binary)
|
||||
case x: JAL => setOpCode("1101111".binary)
|
||||
case x: AUIPC => setOpCode("0110111".binary)
|
||||
case x: LUI => setOpCode("0010111".binary)
|
||||
case DONE => setOpCode("0010011".binary) // done is turned into a NOP in the assembler.
|
||||
case x: Branch => setOpCode("1100011".binary)
|
||||
case x: Arith => setOpCode("0110011".binary)
|
||||
case x: ArithImm => setOpCode("0010011".binary)
|
||||
case x: ArithImmShift => setOpCode("0010011".binary)
|
||||
case x: LW => setOpCode("0000011".binary)
|
||||
case x: SW => setOpCode("0100011".binary)
|
||||
case x: JALR => setOpCode("1100111".binary)
|
||||
case x: JAL => setOpCode("1101111".binary)
|
||||
case x: AUIPC => setOpCode("0110111".binary)
|
||||
case x: LUI => setOpCode("0010111".binary)
|
||||
case DONE => setOpCode("0010011".binary) // done is turned into a NOP in the assembler.
|
||||
}
|
||||
|
||||
def setComparisonFunct(cmp: Comparison): Int => Int = cmp match {
|
||||
|
@ -195,7 +201,6 @@ object assembler {
|
|||
setRs1(op.rs1.value)
|
||||
|
||||
def assembleSType(op: SType): Int => Int = {
|
||||
// say("stype")
|
||||
instruction =>
|
||||
(setRs1(op.rs1.value) andThen
|
||||
setRs2(op.rs2.value))(instruction)
|
||||
|
@ -214,16 +219,17 @@ object assembler {
|
|||
|
||||
|
||||
def assembleImmediate(op: Op, addr: Addr, labelMap: Map[Label, Addr]): Int => Either[(String, Addr), Int] = op match {
|
||||
case DONE => instruction => Right(instruction)
|
||||
case op: Arith => instruction => Right(instruction)
|
||||
case op: ArithImm => setItypeImmediate(op.imm.value, addr)
|
||||
case op: Branch => setBranchDestination(labelMap, op, addr)
|
||||
case op: JALR => instruction => labelMap.lift(op.dst).toRight(s"label ${op.dst} not found", addr).flatMap(addr => setItypeImmediate(addr.value, addr)(instruction))
|
||||
case op: AUIPC => setUtypeImmediate(op.imm.value, addr)
|
||||
case op: LUI => setUtypeImmediate(op.imm.value, addr)
|
||||
case op: LW => setItypeImmediate(op.offset.value, addr)
|
||||
case op: SW => setStypeImmediate(op.offset.value, addr)
|
||||
case op: JAL => instruction => {
|
||||
case DONE => instruction => Right(instruction)
|
||||
case op: Arith => instruction => Right(instruction)
|
||||
case op: ArithImm => setItypeImmediate(op.imm.value, addr)
|
||||
case op: ArithImmShift => setShiftTypeImmediate(op.imm11.value, op.shamt.value, addr)
|
||||
case op: Branch => setBranchDestination(labelMap, op, addr)
|
||||
case op: JALR => instruction => labelMap.lift(op.dst).toRight(s"label ${op.dst} not found", addr).flatMap(addr => setItypeImmediate(addr.value, addr)(instruction))
|
||||
case op: AUIPC => setUtypeImmediate(op.imm.value, addr)
|
||||
case op: LUI => setUtypeImmediate(op.imm.value, addr)
|
||||
case op: LW => setItypeImmediate(op.offset.value, addr)
|
||||
case op: SW => setStypeImmediate(op.offset.value, addr)
|
||||
case op: JAL => instruction => {
|
||||
val addressDistance = labelMap
|
||||
.lift(op.dst).toRight(s"label ${op.dst} not found", addr)
|
||||
.map(absoluteAddr => absoluteAddr - addr)
|
||||
|
|
|
@ -81,16 +81,17 @@ object PrintUtils {
|
|||
val UNKNOWN = "UNKNOWN"
|
||||
|
||||
def printInstruction(op: Ops.Op, labelMap: Map[Label, Addr]): fansi.Str = op match {
|
||||
case op: Branch => fansi.Color.Red(s"B${op.comp}\t${op.rs1.show}, ${op.rs2.show}, ${op.dst.show}\t[${labelMap.lift(op.dst).getOrElse(UNKNOWN)}]")
|
||||
case op: Arith => s"${op.op}\t${op.rd.show}, ${op.rs1.show}, ${op.rs2.show}"
|
||||
case op: ArithImm => s"${op.op}I\t${op.rd.show}, ${op.rs1.show}, ${op.imm.show}"
|
||||
case op: JALR => fansi.Color.Green(s"JALR\t${op.rd.show}, ${op.rs1.show}, ${op.dst.show}\t[${labelMap.lift(op.dst).getOrElse(UNKNOWN)}]")
|
||||
case op: JAL => fansi.Color.Magenta(s"JAL\t${op.rd.show}, ${op.dst.show} [${labelMap.lift(op.dst).getOrElse(UNKNOWN)}]")
|
||||
case op: LW => s"LW\t${op.rd.show}, ${op.offset.show}(${op.rs1.show})"
|
||||
case op: SW => s"SW\t${op.rs2.show}, ${op.offset.show}(${op.rs1.show})"
|
||||
case op: LUI => s"LUI\t${op.rd.show}, ${op.imm.show}"
|
||||
case op: AUIPC => s"AUIPC\t${op.rd.show}, ${op.imm.show}"
|
||||
case DONE => s"DONE"
|
||||
case op: Branch => fansi.Color.Red(s"B${op.comp}\t${op.rs1.show}, ${op.rs2.show}, ${op.dst.show}\t[${labelMap.lift(op.dst).getOrElse(UNKNOWN)}]")
|
||||
case op: Arith => s"${op.op}\t${op.rd.show}, ${op.rs1.show}, ${op.rs2.show}"
|
||||
case op: ArithImm => s"${op.op}I\t${op.rd.show}, ${op.rs1.show}, ${op.imm.show}"
|
||||
case op: ArithImmShift => s"${op.op}I\t${op.rd.show}, ${op.rs1.show}, ${op.shamt.show}"
|
||||
case op: JALR => fansi.Color.Green(s"JALR\t${op.rd.show}, ${op.rs1.show}, ${op.dst.show}\t[${labelMap.lift(op.dst).getOrElse(UNKNOWN)}]")
|
||||
case op: JAL => fansi.Color.Magenta(s"JAL\t${op.rd.show}, ${op.dst.show} [${labelMap.lift(op.dst).getOrElse(UNKNOWN)}]")
|
||||
case op: LW => s"LW\t${op.rd.show}, ${op.offset.show}(${op.rs1.show})"
|
||||
case op: SW => s"SW\t${op.rs2.show}, ${op.offset.show}(${op.rs1.show})"
|
||||
case op: LUI => s"LUI\t${op.rd.show}, ${op.imm.show}"
|
||||
case op: AUIPC => s"AUIPC\t${op.rd.show}, ${op.imm.show}"
|
||||
case DONE => s"DONE"
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -136,9 +136,9 @@ object TestUtils {
|
|||
(s"ori ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(imm).show}", ArithImm.or(rd, rs1, imm)),
|
||||
(s"xori ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(imm).show}", ArithImm.xor(rd, rs1, imm)),
|
||||
(s"andi ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(imm).show}", ArithImm.and(rd, rs1, imm)),
|
||||
(s"slli ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(shift).show}", ArithImm.sll(rd, rs1, shift)),
|
||||
(s"srli ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(shift).show}", ArithImm.srl(rd, rs1, shift)),
|
||||
(s"srai ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(shift).show}", ArithImm.sra(rd, rs1, shift)),
|
||||
(s"slli ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(shift).show}", ArithImmShift.sll(rd, rs1, shift % 32)),
|
||||
(s"srli ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(shift).show}", ArithImmShift.srl(rd, rs1, shift % 32)),
|
||||
(s"srai ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(shift).show}", ArithImmShift.sra(rd, rs1, shift % 32)),
|
||||
(s"slti ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(imm).show}", ArithImm.slt(rd, rs1, imm)),
|
||||
(s"sltiu ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(imm).show}", ArithImm.sltu(rd, rs1, imm)))
|
||||
(rd, choices.shuffle(r).head)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue