vm: implement rest of float instructions

This commit is contained in:
Irmen de Jong 2022-05-04 22:31:45 +02:00
parent da01a5b4dc
commit b1a49e5f29
4 changed files with 116 additions and 34 deletions

View File

@ -25,28 +25,28 @@ sub print_f(float value) {
sub pow(float value, float power) -> float { sub pow(float value, float power) -> float {
%asm {{ %asm {{
phx stx P8ZP_SCRATCH_W1
phy sty P8ZP_SCRATCH_W1+1
lda #<value lda #<value
ldy #>value ldy #>value
jsr floats.CONUPK jsr floats.CONUPK
lda #<power lda #<power
ldy #>power ldy #>power
jsr floats.FPWR jsr floats.FPWR
ply ldx P8ZP_SCRATCH_W1
plx ldy P8ZP_SCRATCH_W1+1
rts rts
}} }}
} }
sub fabs(float value) -> float { sub fabs(float value) -> float {
%asm {{ %asm {{
phx stx P8ZP_SCRATCH_REG
lda #<value lda #<value
ldy #>value ldy #>value
jsr MOVFM jsr MOVFM
jsr ABS jsr ABS
plx ldx P8ZP_SCRATCH_REG
rts rts
}} }}
} }

View File

@ -3,7 +3,6 @@ TODO
For next release For next release
^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^
- vm: implement rest of float instructions
- vm: get rid of intermediate floats.xxx() functions somehow, instead generate the float instructions directly? - vm: get rid of intermediate floats.xxx() functions somehow, instead generate the float instructions directly?
- pipe operator: allow non-unary function calls in the pipe that specify the other argument(s) in the calls. - pipe operator: allow non-unary function calls in the pipe that specify the other argument(s) in the calls.
- allow "xxx" * constexpr (where constexpr is not a number literal), now gives expression error not same type - allow "xxx" * constexpr (where constexpr is not a number literal), now gives expression error not same type

View File

@ -8,19 +8,31 @@
main { main {
sub start() { sub start() {
float fl = 42.123 float fl = -4.55
float[] farray = [0.0, 0.0, 1.11, 2.22, 42.123, 0.0, -99.99] floats.print_f(floats.fabs(fl))
ubyte ix
for ix in 0 to len(farray)-1 {
floats.print_f(farray[ix])
txt.spc()
}
txt.nl() txt.nl()
reverse(farray) floats.print_f(floats.sin(fl))
for ix in 0 to len(farray)-1 { txt.nl()
floats.print_f(farray[ix]) floats.print_f(floats.cos(fl))
txt.spc() txt.nl()
} floats.print_f(floats.tan(fl))
txt.nl()
floats.print_f(floats.atan(fl))
txt.nl()
floats.print_f(floats.round(fl))
txt.nl()
floats.print_f(floats.floor(fl))
txt.nl()
floats.print_f(floats.ceil(fl))
txt.nl()
fl = 4.55
floats.print_f(floats.ln(fl))
txt.nl()
floats.print_f(floats.log2(fl))
txt.nl()
floats.print_f(floats.sqrt(fl))
txt.nl()
floats.print_f(floats.pow(fl, 2.2)) ; TODO fix illegal quantity error
txt.nl() txt.nl()
sys.exit(42) sys.exit(42)
; floats.print_f(-42.42) ; floats.print_f(-42.42)

View File

@ -3,9 +3,7 @@ package prog8.vm
import prog8.code.target.virtual.IVirtualMachineRunner import prog8.code.target.virtual.IVirtualMachineRunner
import java.awt.Toolkit import java.awt.Toolkit
import java.util.* import java.util.*
import kotlin.math.roundToInt import kotlin.math.*
import kotlin.math.sign
import kotlin.math.sqrt
import kotlin.random.Random import kotlin.random.Random
@ -181,18 +179,18 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
Opcode.FTOSB -> InsFTOSB(ins) Opcode.FTOSB -> InsFTOSB(ins)
Opcode.FTOUW -> InsFTOUW(ins) Opcode.FTOUW -> InsFTOUW(ins)
Opcode.FTOSW -> InsFTOSW(ins) Opcode.FTOSW -> InsFTOSW(ins)
Opcode.FPOW -> TODO() Opcode.FPOW -> InsFPOW(ins)
Opcode.FABS -> TODO() Opcode.FABS -> InsFABS(ins)
Opcode.FSIN -> TODO() Opcode.FSIN -> InsFSIN(ins)
Opcode.FCOS -> TODO() Opcode.FCOS -> InsFCOS(ins)
Opcode.FTAN -> TODO() Opcode.FTAN -> InsFTAN(ins)
Opcode.FATAN -> TODO() Opcode.FATAN -> InsFATAN(ins)
Opcode.FLN -> TODO() Opcode.FLN -> InsFLN(ins)
Opcode.FLOG -> TODO() Opcode.FLOG -> InsFLOG(ins)
Opcode.FSQRT -> TODO() Opcode.FSQRT -> InsFSQRT(ins)
Opcode.FROUND -> TODO() Opcode.FROUND -> InsFROUND(ins)
Opcode.FFLOOR -> TODO() Opcode.FFLOOR -> InsFFLOOR(ins)
Opcode.FCEIL -> TODO() Opcode.FCEIL -> InsFCEIL(ins)
else -> throw IllegalArgumentException("invalid opcode ${ins.opcode}") else -> throw IllegalArgumentException("invalid opcode ${ins.opcode}")
} }
} }
@ -1102,6 +1100,79 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
pc++ pc++
} }
private fun InsFPOW(i: Instruction) {
val value = registers.getFloat(i.fpReg2!!)
val exponent = registers.getFloat(i.fpReg3!!)
registers.setFloat(i.fpReg1!!, value.pow(exponent))
pc++
}
private fun InsFSIN(i: Instruction) {
val angle = registers.getFloat(i.fpReg2!!)
registers.setFloat(i.fpReg1!!, sin(angle))
pc++
}
private fun InsFCOS(i: Instruction) {
val angle = registers.getFloat(i.fpReg2!!)
registers.setFloat(i.fpReg1!!, cos(angle))
pc++
}
private fun InsFTAN(i: Instruction) {
val angle = registers.getFloat(i.fpReg2!!)
registers.setFloat(i.fpReg1!!, tan(angle))
pc++
}
private fun InsFATAN(i: Instruction) {
val angle = registers.getFloat(i.fpReg2!!)
registers.setFloat(i.fpReg1!!, atan(angle))
pc++
}
private fun InsFABS(i: Instruction) {
val value = registers.getFloat(i.fpReg2!!)
registers.setFloat(i.fpReg1!!, abs(value))
pc++
}
private fun InsFLN(i: Instruction) {
val value = registers.getFloat(i.fpReg2!!)
registers.setFloat(i.fpReg1!!, ln(value))
pc++
}
private fun InsFLOG(i: Instruction) {
val value = registers.getFloat(i.fpReg2!!)
registers.setFloat(i.fpReg1!!, log2(value))
pc++
}
private fun InsFROUND(i: Instruction) {
val value = registers.getFloat(i.fpReg2!!)
registers.setFloat(i.fpReg1!!, round(value))
pc++
}
private fun InsFFLOOR(i: Instruction) {
val value = registers.getFloat(i.fpReg2!!)
registers.setFloat(i.fpReg1!!, floor(value))
pc++
}
private fun InsFCEIL(i: Instruction) {
val value = registers.getFloat(i.fpReg2!!)
registers.setFloat(i.fpReg1!!, ceil(value))
pc++
}
private fun InsFSQRT(i: Instruction) {
val value = registers.getFloat(i.fpReg2!!)
registers.setFloat(i.fpReg1!!, sqrt(value))
pc++
}
private fun getBranchOperands(i: Instruction): Pair<Int, Int> { private fun getBranchOperands(i: Instruction): Pair<Int, Int> {
return when(i.type) { return when(i.type) {
VmDataType.BYTE -> Pair(registers.getSB(i.reg1!!).toInt(), registers.getSB(i.reg2!!).toInt()) VmDataType.BYTE -> Pair(registers.getSB(i.reg1!!).toInt(), registers.getSB(i.reg2!!).toInt())