ir: replace RND opcode by syscalls

This commit is contained in:
Irmen de Jong 2022-10-22 17:16:36 +02:00
parent e94bf4c63c
commit 00afa1ce52
6 changed files with 18 additions and 21 deletions

View File

@ -126,7 +126,7 @@ sub ceil(float value) -> float {
sub rndf() -> float {
%ir {{
rnd.f fr0
syscall 35
return
}}
}

View File

@ -161,14 +161,14 @@ math {
sub rnd() -> ubyte {
%ir {{
rnd.b r0
syscall 33
return
}}
}
sub rndw() -> uword {
%ir {{
rnd.w r0
syscall 34
return
}}
}

View File

@ -3,8 +3,6 @@ TODO
For next release
^^^^^^^^^^^^^^^^
- ir: replace RND opcodes by syscalls
- optimizer: check that simple trampoline asmsub gets optimized away (such as math.rnd)
- ir: asmsub contents remains blank in IR file
...

View File

@ -126,7 +126,6 @@ mod reg1, value - remainder (modulo) of unsigned div
sqrt reg1, reg2 - reg1 is the square root of reg2
sgn reg1, reg2 - reg1 is the sign of reg2 (0, 1 or -1)
cmp reg1, reg2 - set processor status bits C, N, Z according to comparison of reg1 with reg2. (semantics taken from 6502/68000 CMP instruction)
rnd reg1 - get a random number (byte, word or float)
NOTE: because mul/div are constrained (truncated) to remain in 8 or 16 bits, there is NO NEED for separate signed/unsigned mul and div instructions. The result is identical.
@ -288,7 +287,6 @@ enum class Opcode {
SQRT,
SGN,
CMP,
RND,
EXT,
EXTS,
@ -588,7 +586,6 @@ val instructionFormats = mutableMapOf(
Opcode.DIVSM to InstructionFormat.from("BW,<r1,<v | F,<fr1,<v"),
Opcode.SQRT to InstructionFormat.from("BW,>r1,<r2 | F,>fr1,<fr2"),
Opcode.SGN to InstructionFormat.from("BW,>r1,<r2 | F,>fr1,<fr2"),
Opcode.RND to InstructionFormat.from("BW,>r1 | F,>fr1"),
Opcode.MODR to InstructionFormat.from("BW,<>r1,<r2"),
Opcode.MOD to InstructionFormat.from("BW,<>r1,<v"),
Opcode.CMP to InstructionFormat.from("BW,<r1,<r2"),

View File

@ -74,7 +74,10 @@ enum class Syscall {
COMPARE_STRINGS,
GFX_GETPIXEL,
RNDSEED,
RNDFSEED
RNDFSEED,
RND,
RNDW,
RNDF
}
object SysCalls {
@ -294,6 +297,15 @@ object SysCalls {
val seed2 = vm.registers.getUW(1)
vm.randomSeed(seed1, seed2)
}
Syscall.RND -> {
vm.registers.setUB(0, vm.randomGenerator.nextInt().toUByte())
}
Syscall.RNDW -> {
vm.registers.setUW(0, vm.randomGenerator.nextInt().toUShort())
}
Syscall.RNDF -> {
vm.registers.setFloat(0, vm.randomGeneratorFloats.nextFloat())
}
else -> throw AssemblyError("missing syscall ${call.name}")
}
}

View File

@ -41,8 +41,8 @@ class VirtualMachine(irProgram: IRProgram) {
var statusCarry = false
var statusZero = false
var statusNegative = false
private var randomGenerator = Random(0xa55a7653)
private var randomGeneratorFloats = Random(0xc0d3dbad)
internal var randomGenerator = Random(0xa55a7653)
internal var randomGeneratorFloats = Random(0xc0d3dbad)
private val cx16virtualregsBaseAddress: Int
init {
@ -181,7 +181,6 @@ class VirtualMachine(irProgram: IRProgram) {
Opcode.MOD -> InsMOD(ins)
Opcode.SGN -> InsSGN(ins)
Opcode.CMP -> InsCMP(ins)
Opcode.RND -> InsRND(ins)
Opcode.SQRT -> InsSQRT(ins)
Opcode.EXT -> InsEXT(ins)
Opcode.EXTS -> InsEXTS(ins)
@ -1061,15 +1060,6 @@ class VirtualMachine(irProgram: IRProgram) {
pc++
}
private fun InsRND(i: IRInstruction) {
when(i.type!!) {
IRDataType.BYTE -> registers.setUB(i.reg1!!, randomGenerator.nextInt().toUByte())
IRDataType.WORD -> registers.setUW(i.reg1!!, randomGenerator.nextInt().toUShort())
IRDataType.FLOAT -> registers.setFloat(i.fpReg1!!, randomGeneratorFloats.nextFloat())
}
pc++
}
private fun InsCMP(i: IRInstruction) {
val comparison: Int
when(i.type!!) {