18% speedup from interrupt optimization
This commit is contained in:
@@ -19,14 +19,15 @@ fun main(args: Array<String>) {
|
|||||||
cpu.runState = CPU.RunState.RUNNING
|
cpu.runState = CPU.RunState.RUNNING
|
||||||
cpu.pc = 0x80u
|
cpu.pc = 0x80u
|
||||||
val start = System.nanoTime()
|
val start = System.nanoTime()
|
||||||
val ninsn = cpu.run()
|
val ninsn = cpu.run(50000000)
|
||||||
val end = System.nanoTime()
|
val end = System.nanoTime()
|
||||||
|
|
||||||
System.err.println("Halted at 0${cpu.pc.toString(8)}")
|
System.err.println("Halted at 0${cpu.pc.toString(8)}")
|
||||||
val time = (end-start).toDouble() / 1_000_000_000.0
|
val time = (end - start).toDouble() / 1_000_000_000.0
|
||||||
println("Executed ${ninsn} in ${time}s: ${ninsn/time} i/s")
|
println("Executed ${ninsn} in ${time}s: ${ninsn / time} i/s")
|
||||||
} finally {
|
} finally {
|
||||||
println("Exiting")
|
println("Exiting")
|
||||||
console.stop()
|
console.stop()
|
||||||
}
|
}
|
||||||
|
System.exit(0)
|
||||||
}
|
}
|
||||||
|
@@ -828,8 +828,9 @@ class CPU(val mbus: MemBus) {
|
|||||||
try {
|
try {
|
||||||
if (runState == RunState.HALTED) return
|
if (runState == RunState.HALTED) return
|
||||||
|
|
||||||
|
if (mbus.unibus.interruptPending) {
|
||||||
for (i in 7 downTo (psw_priority + 1)) {
|
for (i in 7 downTo (psw_priority + 1)) {
|
||||||
if (pirq bit 8+i) {
|
if (pirq bit 8 + i) {
|
||||||
logger.debug("PIRQ{} trap to 0xA0", i)
|
logger.debug("PIRQ{} trap to 0xA0", i)
|
||||||
trap(0xA0u)
|
trap(0xA0u)
|
||||||
break
|
break
|
||||||
@@ -845,6 +846,12 @@ class CPU(val mbus: MemBus) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
val pirqLvl = pirq.toInt() shr 1 and 7;
|
||||||
|
if (pirqLvl > psw_priority) {
|
||||||
|
trap(0xA0u)
|
||||||
|
}
|
||||||
|
}
|
||||||
if (runState == RunState.WAIT_FOR_INTERRUPT) {
|
if (runState == RunState.WAIT_FOR_INTERRUPT) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -867,6 +874,15 @@ class CPU(val mbus: MemBus) {
|
|||||||
fun run(): Long {
|
fun run(): Long {
|
||||||
var ninsn: Long = 0
|
var ninsn: Long = 0
|
||||||
while (runState == RunState.RUNNING) {
|
while (runState == RunState.RUNNING) {
|
||||||
|
ninsn += run(Long.MAX_VALUE)
|
||||||
|
step()
|
||||||
|
}
|
||||||
|
return ninsn
|
||||||
|
}
|
||||||
|
|
||||||
|
fun run(nstep: Long): Long {
|
||||||
|
var ninsn: Long = 0
|
||||||
|
while (runState == RunState.RUNNING && ninsn < nstep) {
|
||||||
ninsn++
|
ninsn++
|
||||||
step()
|
step()
|
||||||
}
|
}
|
||||||
|
@@ -77,6 +77,9 @@ class Unibus: PAddressSpace, Subregion(12, 6) {
|
|||||||
private val logger = LoggerFactory.getLogger(this.javaClass)
|
private val logger = LoggerFactory.getLogger(this.javaClass)
|
||||||
|
|
||||||
private val queue: Array<MutableList<InterruptSource>> = Array(8) { Vector(4) }
|
private val queue: Array<MutableList<InterruptSource>> = Array(8) { Vector(4) }
|
||||||
|
private var interruptCount: Int = 0
|
||||||
|
val interruptPending: Boolean
|
||||||
|
get() = interruptCount > 0
|
||||||
|
|
||||||
override fun map(address: UInt): PAddressSpace =
|
override fun map(address: UInt): PAddressSpace =
|
||||||
super.map(address) ?: throw BusTimeoutError(address)
|
super.map(address) ?: throw BusTimeoutError(address)
|
||||||
@@ -101,11 +104,17 @@ class Unibus: PAddressSpace, Subregion(12, 6) {
|
|||||||
/// to fetch the currently desired interrupt vector
|
/// to fetch the currently desired interrupt vector
|
||||||
fun assertInterrupt(priority: Int, device: InterruptSource) {
|
fun assertInterrupt(priority: Int, device: InterruptSource) {
|
||||||
val list = queue[priority]
|
val list = queue[priority]
|
||||||
|
if (list.isEmpty()) {
|
||||||
|
interruptCount++
|
||||||
|
}
|
||||||
if (!list.contains(device)) list.add(device)
|
if (!list.contains(device)) list.add(device)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun deassertInterrupt(priority: Int, device: InterruptSource) {
|
fun deassertInterrupt(priority: Int, device: InterruptSource) {
|
||||||
queue[priority].remove(device)
|
val lvlQueue = queue[priority]
|
||||||
|
if (lvlQueue.remove(device) && lvlQueue.isEmpty()) {
|
||||||
|
interruptCount--
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks for an interrupt. The handler receives (priority, device)
|
// Checks for an interrupt. The handler receives (priority, device)
|
||||||
|
Reference in New Issue
Block a user