Browse Source

Add special handlers for shift instructions.

master
peteraa 6 years ago
parent
commit
8e2d686b5c
8 changed files with 84 additions and 62 deletions
  1. +4
    -0
      .jvmopts
  2. +1
    -1
      src/main/scala/IF.scala
  3. +6
    -3
      src/test/scala/RISCV/Ops.scala
  4. +9
    -9
      src/test/scala/RISCV/Parser.scala
  5. +18
    -10
      src/test/scala/RISCV/VM.scala
  6. +32
    -26
      src/test/scala/RISCV/assembler.scala
  7. +11
    -10
      src/test/scala/RISCV/printUtils.scala
  8. +3
    -3
      src/test/scala/TestUtils.scala

+ 4
- 0
.jvmopts View File

@@ -0,0 +1,4 @@
-Xms512M
-Xmx4096M
-Xss32M
-XX:MaxMetaspaceSize=1024M

+ 1
- 1
src/main/scala/IF.scala View File

@@ -61,6 +61,6 @@ class InstructionFetch extends MultiIOModule {
when(testHarness.IMEMsetup.setup) { when(testHarness.IMEMsetup.setup) {
PC := 0.U PC := 0.U
// TODO: You should probably set the instruction to Instruction.NOP here. // TODO: You should probably set the instruction to Instruction.NOP here.
throw new Exception("Just making sure you're seeing the line above.\nYou can delete this exception now, it's found at line 64 at IF.scala")
// throw new Exception("Just making sure you're seeing the line above.\nYou can delete this exception now, it's found at line 64 at IF.scala")
} }
} }

+ 6
- 3
src/test/scala/RISCV/Ops.scala View File

@@ -93,14 +93,17 @@ object Ops {
def or( rd: Int, rs1: Int, imm: Int) = ArithImm(Reg(rd), Reg(rs1), Imm(imm), OR) 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 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 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 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 sltu(rd: Int, rs1: Int, imm: Int) = ArithImm(Reg(rd), Reg(rs1), Imm(imm), SLTU)
def nop = add(0, 0, 0) 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 LUI(rd: Reg, imm: Imm) extends Op with UType
case class AUIPC(rd: Reg, imm: Imm) extends Op with UType case class AUIPC(rd: Reg, imm: Imm) extends Op with UType


+ 9
- 9
src/test/scala/RISCV/Parser.scala View File

@@ -84,9 +84,9 @@ object Parser {
stringWs("xori") ~> arithImm.mapN{ArithImm.xor}, stringWs("xori") ~> arithImm.mapN{ArithImm.xor},
stringWs("andi") ~> arithImm.mapN{ArithImm.and}, 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("slti") ~> arithImm.mapN{ArithImm.slt},
stringWs("sltiu") ~> arithImm.mapN{ArithImm.sltu}, stringWs("sltiu") ~> arithImm.mapN{ArithImm.sltu},
@@ -160,16 +160,16 @@ object Parser {
SW(placeHolder, 0, 2048), SW(placeHolder, 0, 2048),
LW(placeHolder, rs1.value, (offset & 0xFFFFFF1C)), LW(placeHolder, rs1.value, (offset & 0xFFFFFF1C)),
LW(rd.value, rs1.value, (offset & 0xFFFFFF1C) + 4), 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), Arith.add(rd, rd, placeHolder),
LW(placeHolder, 0, 2048)).reverse LW(placeHolder, 0, 2048)).reverse
} }
case (rd, offset, rs1) if (offset % 4 == 2) => { case (rd, offset, rs1) if (offset % 4 == 2) => {
List( List(
LW(rd, rs1, (offset & 0xFFFFFF1C)), LW(rd, rs1, (offset & 0xFFFFFF1C)),
ArithImm.sra(rd, rd, 16)
ArithImmShift.sra(rd, rd, 16)
).reverse ).reverse
} }


@@ -177,8 +177,8 @@ object Parser {
val leftShift = if((offset % 4) == 0) 16 else 8 val leftShift = if((offset % 4) == 0) 16 else 8
List( List(
LW(rd, rs1, (offset & 0xFFFFFF1C)), 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 ).reverse
} }
}.map(_.widen[Op]), }.map(_.widen[Op]),


+ 18
- 10
src/test/scala/RISCV/VM.scala View File

@@ -23,16 +23,17 @@ case class VM(
def stepInstruction: Either[Finished, ExecutionTrace[VM]] = { def stepInstruction: Either[Finished, ExecutionTrace[VM]] = {
if (pc.value == 0xEB1CEB1C) Left(Success) if (pc.value == 0xEB1CEB1C) Left(Success)
else getOp flatMap { 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) = { private def executeLUI(op: LUI) = {
val (regUpdate, nextRegs) = regs + (op.rd -> (op.imm.value << 12)) val (regUpdate, nextRegs) = regs + (op.rd -> (op.imm.value << 12))
val nextVM = this.copy(regs = nextRegs) val nextVM = this.copy(regs = nextRegs)


+ 32
- 26
src/test/scala/RISCV/assembler.scala View File

@@ -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) def setOpCode(opcode: Int): Int => Int = setField(0, 7, opcode)
@@ -142,16 +147,17 @@ object assembler {




def setOpCode(op: Op): Int => Int = op match { 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 { def setComparisonFunct(cmp: Comparison): Int => Int = cmp match {
@@ -195,7 +201,6 @@ object assembler {
setRs1(op.rs1.value) setRs1(op.rs1.value)


def assembleSType(op: SType): Int => Int = { def assembleSType(op: SType): Int => Int = {
// say("stype")
instruction => instruction =>
(setRs1(op.rs1.value) andThen (setRs1(op.rs1.value) andThen
setRs2(op.rs2.value))(instruction) 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 { 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 val addressDistance = labelMap
.lift(op.dst).toRight(s"label ${op.dst} not found", addr) .lift(op.dst).toRight(s"label ${op.dst} not found", addr)
.map(absoluteAddr => absoluteAddr - addr) .map(absoluteAddr => absoluteAddr - addr)


+ 11
- 10
src/test/scala/RISCV/printUtils.scala View File

@@ -81,16 +81,17 @@ object PrintUtils {
val UNKNOWN = "UNKNOWN" val UNKNOWN = "UNKNOWN"


def printInstruction(op: Ops.Op, labelMap: Map[Label, Addr]): fansi.Str = op match { 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"
} }






+ 3
- 3
src/test/scala/TestUtils.scala View File

@@ -136,9 +136,9 @@ object TestUtils {
(s"ori ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(imm).show}", ArithImm.or(rd, rs1, imm)), (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"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"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"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))) (s"sltiu ${Reg(rd).show}, ${Reg(rs1).show}, ${Imm(imm).show}", ArithImm.sltu(rd, rs1, imm)))
(rd, choices.shuffle(r).head) (rd, choices.shuffle(r).head)


Loading…
Cancel
Save