vm: implement float to integer cast, any, all, reverse

This commit is contained in:
Irmen de Jong 2022-05-04 20:47:48 +02:00
parent 3f9cdd9b56
commit da01a5b4dc
11 changed files with 136 additions and 159 deletions

View File

@ -328,8 +328,6 @@ internal class AssignmentAsmGen(private val program: Program,
val variable = (containment.iterable as? IdentifierReference)?.targetVarDecl(program)
?: throw AssemblyError("invalid containment iterable type")
if(elementDt istype DataType.FLOAT)
throw AssemblyError("containment check of floats not supported")
if(variable.origin!=VarDeclOrigin.USERCODE) {
when(variable.datatype) {
DataType.STR -> {
@ -388,7 +386,9 @@ internal class AssignmentAsmGen(private val program: Program,
asmgen.out(" jsr prog8_lib.containment_bytearray")
return
}
DataType.ARRAY_F -> throw AssemblyError("containment check of floats not supported")
DataType.ARRAY_F -> {
throw AssemblyError("containment check of floats not supported")
}
DataType.ARRAY_B, DataType.ARRAY_UB -> {
val arrayVal = variable.value as ArrayLiteral
assignExpressionToRegister(containment.element, RegisterOrPair.A, elementDt istype DataType.BYTE)

View File

@ -64,36 +64,34 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen:
private fun funcAny(call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk {
val arrayName = call.args[0] as PtIdentifier
val array = codeGen.symbolTable.flat.getValue(arrayName.targetName) as StStaticVariable
val elementDt: VmDataType = codeGen.vmType(ArrayToElementTypes.getValue(array.dt))
val code = VmCodeChunk()
val syscall =
when(array.dt) {
when (array.dt) {
DataType.ARRAY_UB,
DataType.ARRAY_B -> Syscall.ANY_BYTE
DataType.ARRAY_UW,
DataType.ARRAY_W -> Syscall.ANY_WORD
DataType.ARRAY_F -> TODO("float any")
DataType.ARRAY_F -> Syscall.ANY_FLOAT
else -> throw IllegalArgumentException("weird type")
}
val code = VmCodeChunk()
code += exprGen.translateExpression(call.args[0], 0, -1)
code += VmCodeInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=1, value=array.length)
code += VmCodeInstruction(Opcode.SYSCALL, value=syscall.ordinal)
if(resultRegister!=0)
code += VmCodeInstruction(Opcode.LOADR, elementDt, reg1=resultRegister, reg2=0)
code += VmCodeInstruction(Opcode.LOAD, VmDataType.BYTE, reg1 = 1, value = array.length)
code += VmCodeInstruction(Opcode.SYSCALL, value = syscall.ordinal)
if (resultRegister != 0)
code += VmCodeInstruction(Opcode.LOADR, VmDataType.BYTE, reg1 = resultRegister, reg2 = 0)
return code
}
private fun funcAll(call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk {
val arrayName = call.args[0] as PtIdentifier
val array = codeGen.symbolTable.flat.getValue(arrayName.targetName) as StStaticVariable
val elementDt: VmDataType = codeGen.vmType(ArrayToElementTypes.getValue(array.dt))
val syscall =
when(array.dt) {
DataType.ARRAY_UB,
DataType.ARRAY_B -> Syscall.ALL_BYTE
DataType.ARRAY_UW,
DataType.ARRAY_W -> Syscall.ALL_WORD
DataType.ARRAY_F -> TODO("float all")
DataType.ARRAY_F -> Syscall.ALL_FLOAT
else -> throw IllegalArgumentException("weird type")
}
val code = VmCodeChunk()
@ -101,7 +99,7 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen:
code += VmCodeInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=1, value=array.length)
code += VmCodeInstruction(Opcode.SYSCALL, value=syscall.ordinal)
if(resultRegister!=0)
code += VmCodeInstruction(Opcode.LOADR, elementDt, reg1=resultRegister, reg2=0)
code += VmCodeInstruction(Opcode.LOADR, VmDataType.BYTE, reg1=resultRegister, reg2=0)
return code
}
@ -201,7 +199,7 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen:
when(array.dt) {
DataType.ARRAY_UB, DataType.ARRAY_B, DataType.STR -> Syscall.REVERSE_BYTES
DataType.ARRAY_UW, DataType.ARRAY_W -> Syscall.REVERSE_WORDS
DataType.ARRAY_F -> TODO("float reverse")
DataType.ARRAY_F -> Syscall.REVERSE_FLOATS
else -> throw IllegalArgumentException("weird type to reverse")
}
val code = VmCodeChunk()
@ -220,8 +218,8 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen:
DataType.ARRAY_B -> Syscall.SORT_BYTE
DataType.ARRAY_UW -> Syscall.SORT_UWORD
DataType.ARRAY_W -> Syscall.SORT_WORD
DataType.ARRAY_F -> TODO("float sort")
DataType.STR -> Syscall.SORT_UBYTE
DataType.ARRAY_F -> throw java.lang.IllegalArgumentException("sorting a floating point array is not supported")
else -> throw IllegalArgumentException("weird type to sort")
}
val code = VmCodeChunk()

View File

@ -62,7 +62,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
}
is PtTypeCast -> code += translate(expr, resultRegister, resultFpRegister)
is PtPrefix -> code += translate(expr, resultRegister)
is PtArrayIndexer -> code += translate(expr, resultRegister)
is PtArrayIndexer -> code += translate(expr, resultRegister, resultFpRegister)
is PtBinaryExpression -> code += translate(expr, resultRegister, resultFpRegister)
is PtBuiltinFunctionCall -> code += codeGen.translateBuiltinFunc(expr, resultRegister)
is PtFunctionCall -> code += translate(expr, resultRegister, resultFpRegister)
@ -139,13 +139,13 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
call.children.add(PtNumber(DataType.UBYTE, iterable.length!!.toDouble(), iterable.position))
code += translate(call, resultRegister, resultFpRegister)
}
DataType.ARRAY_F -> TODO("containment check in float-array")
DataType.ARRAY_F -> throw AssemblyError("containment check in float-array not supported")
else -> throw AssemblyError("weird iterable dt ${iterable.dt} for ${check.iterable.targetName}")
}
return code
}
private fun translate(arrayIx: PtArrayIndexer, resultRegister: Int): VmCodeChunk {
private fun translate(arrayIx: PtArrayIndexer, resultRegister: Int, resultFpRegister: Int): VmCodeChunk {
val eltSize = codeGen.program.memsizer.memorySize(arrayIx.type)
val vmDt = codeGen.vmType(arrayIx.type)
val code = VmCodeChunk()
@ -154,12 +154,18 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
if(arrayIx.index is PtNumber) {
// optimized code when index is known - just calculate the memory address here
val memOffset = (arrayIx.index as PtNumber).number.toInt() * eltSize
code += VmCodeInstruction(Opcode.LOADM, vmDt, reg1=resultRegister, value=arrayLocation+memOffset)
if(vmDt==VmDataType.FLOAT)
code += VmCodeInstruction(Opcode.LOADM, VmDataType.FLOAT, fpReg1=resultFpRegister, value=arrayLocation+memOffset)
else
code += VmCodeInstruction(Opcode.LOADM, vmDt, reg1=resultRegister, value=arrayLocation+memOffset)
} else {
code += translateExpression(arrayIx.index, idxReg, -1)
if(eltSize>1)
code += codeGen.multiplyByConst(VmDataType.BYTE, idxReg, eltSize)
code += VmCodeInstruction(Opcode.LOADX, vmDt, reg1=resultRegister, reg2=idxReg, value = arrayLocation)
if(vmDt==VmDataType.FLOAT)
code += VmCodeInstruction(Opcode.LOADX, VmDataType.FLOAT, fpReg1 = resultFpRegister, reg1=idxReg, value = arrayLocation)
else
code += VmCodeInstruction(Opcode.LOADX, vmDt, reg1=resultRegister, reg2=idxReg, value = arrayLocation)
}
return code
}
@ -193,29 +199,30 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
return code
}
private fun translate(cast: PtTypeCast, resultRegister: Int, predefinedResultFpRegister: Int): VmCodeChunk {
private fun translate(cast: PtTypeCast, predefinedResultRegister: Int, predefinedResultFpRegister: Int): VmCodeChunk {
val code = VmCodeChunk()
if(cast.type==cast.value.type)
return code
val actualResultFpReg = if(predefinedResultFpRegister>=0) predefinedResultFpRegister else codeGen.vmRegisters.nextFreeFloat()
val actualResultReg = if(predefinedResultRegister>=0) predefinedResultRegister else codeGen.vmRegisters.nextFree()
if(cast.value.type==DataType.FLOAT) {
// a cast from float to integer, so evaluate the value into a float register first
code += translateExpression(cast.value, -1, actualResultFpReg)
}
else
code += translateExpression(cast.value, resultRegister, -1)
code += translateExpression(cast.value, actualResultReg, -1)
when(cast.type) {
DataType.UBYTE -> {
when(cast.value.type) {
DataType.BYTE, DataType.UWORD, DataType.WORD -> { /* just keep the LSB as it is */ }
DataType.FLOAT -> code += VmCodeInstruction(Opcode.FTOUB, VmDataType.FLOAT, reg1=resultRegister, fpReg1 = actualResultFpReg)
DataType.FLOAT -> code += VmCodeInstruction(Opcode.FTOUB, VmDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg)
else -> throw AssemblyError("weird cast value type")
}
}
DataType.BYTE -> {
when(cast.value.type) {
DataType.UBYTE, DataType.UWORD, DataType.WORD -> { /* just keep the LSB as it is */ }
DataType.FLOAT -> code += VmCodeInstruction(Opcode.FTOSB, VmDataType.FLOAT, reg1=resultRegister, fpReg1 = actualResultFpReg)
DataType.FLOAT -> code += VmCodeInstruction(Opcode.FTOSB, VmDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg)
else -> throw AssemblyError("weird cast value type")
}
}
@ -223,15 +230,15 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
when(cast.value.type) {
DataType.BYTE -> {
// byte -> uword: sign extend
code += VmCodeInstruction(Opcode.EXTS, type = VmDataType.BYTE, reg1 = resultRegister)
code += VmCodeInstruction(Opcode.EXTS, type = VmDataType.BYTE, reg1 = actualResultReg)
}
DataType.UBYTE -> {
// ubyte -> uword: sign extend
code += VmCodeInstruction(Opcode.EXT, type = VmDataType.BYTE, reg1 = resultRegister)
code += VmCodeInstruction(Opcode.EXT, type = VmDataType.BYTE, reg1 = actualResultReg)
}
DataType.WORD -> { }
DataType.FLOAT -> {
code += VmCodeInstruction(Opcode.FTOUW, VmDataType.FLOAT, reg1=resultRegister, fpReg1 = actualResultFpReg)
code += VmCodeInstruction(Opcode.FTOUW, VmDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg)
}
else -> throw AssemblyError("weird cast value type")
}
@ -240,32 +247,35 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
when(cast.value.type) {
DataType.BYTE -> {
// byte -> word: sign extend
code += VmCodeInstruction(Opcode.EXTS, type = VmDataType.BYTE, reg1 = resultRegister)
code += VmCodeInstruction(Opcode.EXTS, type = VmDataType.BYTE, reg1 = actualResultReg)
}
DataType.UBYTE -> {
// byte -> word: sign extend
code += VmCodeInstruction(Opcode.EXT, type = VmDataType.BYTE, reg1 = resultRegister)
code += VmCodeInstruction(Opcode.EXT, type = VmDataType.BYTE, reg1 = actualResultReg)
}
DataType.UWORD -> { }
DataType.FLOAT -> {
code += VmCodeInstruction(Opcode.FTOSW, VmDataType.FLOAT, reg1=resultRegister, fpReg1 = actualResultFpReg)
code += VmCodeInstruction(Opcode.FTOSW, VmDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg)
}
else -> throw AssemblyError("weird cast value type")
}
}
DataType.FLOAT -> {
TODO("floating point to integer cast not yet supported")
// when(cast.value.type) {
// DataType.BYTE -> {
// }
// DataType.UBYTE -> {
// }
// DataType.WORD -> {
// }
// DataType.UWORD -> {
// }
// else -> throw AssemblyError("weird cast value type")
// }
when(cast.value.type) {
DataType.UBYTE -> {
code += VmCodeInstruction(Opcode.FFROMUB, VmDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg)
}
DataType.BYTE -> {
code += VmCodeInstruction(Opcode.FFROMSB, VmDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg)
}
DataType.UWORD -> {
code += VmCodeInstruction(Opcode.FFROMUW, VmDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg)
}
DataType.WORD -> {
code += VmCodeInstruction(Opcode.FFROMSW, VmDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg)
}
else -> throw AssemblyError("weird cast value type")
}
}
else -> throw AssemblyError("weird cast type")
}

View File

@ -13,7 +13,7 @@ sub print_f(float value) {
; ---- prints the floating point value (without a newline).
%asm {{
loadm.f fr0,{floats.print_f.value}
syscall 35
syscall 25
return
}}
}

View File

@ -3,7 +3,7 @@ TODO
For next release
^^^^^^^^^^^^^^^^
- vm: implement float any, all, reverse, sort
- vm: implement rest of float instructions
- 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.
- allow "xxx" * constexpr (where constexpr is not a number literal), now gives expression error not same type
@ -63,7 +63,8 @@ Libraries:
- add modes 2 and 3 to gfx2 (lowres 4 color and 16 color)?
- add a flood fill routine to gfx2?
- add a diskio.f_seek() routine for the Cx16 that uses its seek dos api? (only if that's stable)
- use cx16 MACPTR() to load stuff faster?
- diskio: use cx16 MACPTR() to load stuff faster? (see it's use in X16edit to fast load blocks)
note that it might fail on non sdcard files so have to make graceful degradation
Expressions:

View File

@ -9,15 +9,19 @@
main {
sub start() {
float fl = 42.123
float fl2 = fl / 1.0
txt.print("rad 180 = ")
floats.print_f(floats.rad(180.0))
txt.print("\nrad 360 = ")
floats.print_f(floats.rad(360.0))
txt.print("\ndeg 2 = ")
floats.print_f(floats.deg(2.0))
txt.print("\ndeg pi = ")
floats.print_f(floats.deg(floats.PI))
float[] farray = [0.0, 0.0, 1.11, 2.22, 42.123, 0.0, -99.99]
ubyte ix
for ix in 0 to len(farray)-1 {
floats.print_f(farray[ix])
txt.spc()
}
txt.nl()
reverse(farray)
for ix in 0 to len(farray)-1 {
floats.print_f(farray[ix])
txt.spc()
}
txt.nl()
sys.exit(42)
; floats.print_f(-42.42)
; float f1 = 1.2345

View File

@ -14,7 +14,7 @@
<keywords keywords="&amp;;-&gt;;@;\$;and;as;asmsub;break;clobbers;do;downto;else;false;for;goto;if;if_cc;if_cs;if_eq;if_mi;if_ne;if_neg;if_nz;if_pl;if_pos;if_vc;if_vs;if_z;in;inline;not;or;repeat;return;romsub;step;sub;to;true;until;when;while;xor;~" ignore_case="false" />
<keywords2 keywords="%address;%asm;%asmbinary;%asminclude;%breakpoint;%import;%launcher;%option;%output;%zeropage;%zpreserved;iso:;petscii:;sc:" />
<keywords3 keywords="@requirezp;@shared;@zp;byte;const;float;str;ubyte;uword;void;word" />
<keywords4 keywords="abs;all;any;avg;callfar;callrom;cmp;len;lsb;max;memory;min;mkword;msb;peek;peekw;poke;pokew;pop;popw;push;pushw;reverse;rnd;rndw;rol;rol2;ror;ror2;rrestore;rrestorex;rsave;rsavex;sgn;sizeof;sort;sqrt16;sum;swap;|&gt;" />
<keywords4 keywords="abs;all;any;avg;callfar;callrom;cmp;len;lsb;memory;mkword;msb;peek;peekw;poke;pokew;pop;popw;push;pushw;reverse;rnd;rndw;rol;rol2;ror;ror2;rrestore;rrestorex;rsave;rsavex;sgn;sizeof;sort;sqrt16;swap;|&gt;" />
</highlighting>
<extensionMap>
<mapping ext="p8" />

View File

@ -27,7 +27,7 @@
<Keywords name="Keywords1">void const&#x000D;&#x000A;str&#x000D;&#x000A;byte ubyte&#x000D;&#x000A;word uword&#x000D;&#x000A;float&#x000D;&#x000A;zp shared requirezp</Keywords>
<Keywords name="Keywords2">%address&#x000D;&#x000A;%asm&#x000D;&#x000A;%asmbinary&#x000D;&#x000A;%asminclude&#x000D;&#x000A;%breakpoint&#x000D;&#x000A;%import&#x000D;&#x000A;%launcher&#x000D;&#x000A;%option&#x000D;&#x000A;%output&#x000D;&#x000A;%zeropage&#x000D;&#x000A;%zpreserved</Keywords>
<Keywords name="Keywords3">inline sub asmsub romsub&#x000D;&#x000A;clobbers&#x000D;&#x000A;asm&#x000D;&#x000A;if&#x000D;&#x000A;when else&#x000D;&#x000A;if_cc if_cs if_eq if_mi if_neg if_nz if_pl if_pos if_vc if_vs if_z&#x000D;&#x000A;for in step do while repeat&#x000D;&#x000A;break return goto</Keywords>
<Keywords name="Keywords4">abs all any avg callfar callrom cmp len lsb lsl lsr max memory min mkword msb peek peekw poke pokew push pushw pop popw rsave rsavex rrestore rrestorex reverse rnd rndw rol rol2 ror ror2 sgn sizeof sort sqrt16 sum swap</Keywords>
<Keywords name="Keywords4">abs all any avg callfar callrom cmp len lsb lsl lsr memory mkword msb peek peekw poke pokew push pushw pop popw rsave rsavex rrestore rrestorex reverse rnd rndw rol rol2 ror ror2 sgn sizeof sort sqrt16 swap</Keywords>
<Keywords name="Keywords5">true false&#x000D;&#x000A;not and or xor&#x000D;&#x000A;as to downto |&gt;</Keywords>
<Keywords name="Keywords6"></Keywords>
<Keywords name="Keywords7"></Keywords>

View File

@ -10,7 +10,7 @@
syn keyword prog8BuiltInFunc sgn sqrt16
" Array functions
syn keyword prog8BuiltInFunc any all len max min reverse sum sort
syn keyword prog8BuiltInFunc any all len reverse sort
" Miscellaneous functions
syn keyword prog8BuiltInFunc cmp lsb msb mkword peek peekw poke pokew rnd rndw push pushw pop popw rsave rsavex rrestore rrestorex

View File

@ -24,23 +24,16 @@ SYSCALLS:
16 = sort_byte array
17 = sort_uword array
18 = sort_word array
19 = max_ubyte array
20 = max_byte array
21 = max_uword array
22 = max_word array
23 = min_ubyte array
24 = min_byte array
25 = min_uword array
26 = min_word array
27 = sum_byte array
28 = sum_word array
29 = any_byte array
30 = any_word array
31 = all_byte array
32 = all_word array
33 = reverse_bytes array
34 = reverse_words array
35 = print_f (floating point value in fpReg0)
19 = any_byte array
20 = any_word array
21 = any_float array
22 = all_byte array
23 = all_word array
24 = all_float array
25 = print_f (floating point value in fp reg 0)
26 = reverse_bytes array
27 = reverse_words array
28 = reverse_floats array
*/
enum class Syscall {
@ -63,23 +56,16 @@ enum class Syscall {
SORT_BYTE,
SORT_UWORD,
SORT_WORD,
MAX_UBYTE,
MAX_BYTE,
MAX_UWORD,
MAX_WORD,
MIN_UBYTE,
MIN_BYTE,
MIN_UWORD,
MIN_WORD,
SUM_BYTE,
SUM_WORD,
ANY_BYTE,
ANY_WORD,
ANY_FLOAT,
ALL_BYTE,
ALL_WORD,
ALL_FLOAT,
PRINT_F,
REVERSE_BYTES,
REVERSE_WORDS,
PRINT_F
REVERSE_FLOATS,
}
object SysCalls {
@ -191,75 +177,15 @@ object SysCalls {
vm.memory.setUW(address+index*2, value)
}
}
Syscall.MAX_UBYTE -> {
Syscall.REVERSE_FLOATS -> {
val address = vm.registers.getUW(0).toInt()
val length = vm.registers.getUB(1).toInt()
val addresses = IntProgression.fromClosedRange(address, address+length*2-2, 2)
val value = addresses.map { vm.memory.getUB(it) }.maxOf { it }
vm.registers.setUB(0, value)
}
Syscall.MAX_BYTE -> {
val address = vm.registers.getUW(0).toInt()
val length = vm.registers.getUB(1).toInt()
val addresses = IntProgression.fromClosedRange(address, address+length*2-2, 2)
val value = addresses.map { vm.memory.getSB(it) }.maxOf { it }
vm.registers.setSB(0, value)
}
Syscall.MAX_UWORD -> {
val address = vm.registers.getUW(0).toInt()
val length = vm.registers.getUB(1).toInt()
val addresses = IntProgression.fromClosedRange(address, address+length*2-2, 2)
val value = addresses.map { vm.memory.getUW(it) }.maxOf { it }
vm.registers.setUW(0, value)
}
Syscall.MAX_WORD -> {
val address = vm.registers.getUW(0).toInt()
val length = vm.registers.getUB(1).toInt()
val addresses = IntProgression.fromClosedRange(address, address+length*2-2, 2)
val value = addresses.map { vm.memory.getSW(it) }.maxOf { it }
vm.registers.setSW(0, value)
}
Syscall.MIN_UBYTE -> {
val address = vm.registers.getUW(0).toInt()
val length = vm.registers.getUB(1).toInt()
val addresses = IntProgression.fromClosedRange(address, address+length*2-2, 2)
val value = addresses.map { vm.memory.getUB(it) }.minOf { it }
vm.registers.setUB(0, value)
}
Syscall.MIN_BYTE -> {
val address = vm.registers.getUW(0).toInt()
val length = vm.registers.getUB(1).toInt()
val addresses = IntProgression.fromClosedRange(address, address+length*2-2, 2)
val value = addresses.map { vm.memory.getSB(it) }.minOf { it }
vm.registers.setSB(0, value)
}
Syscall.MIN_UWORD -> {
val address = vm.registers.getUW(0).toInt()
val length = vm.registers.getUB(1).toInt()
val addresses = IntProgression.fromClosedRange(address, address+length*2-2, 2)
val value = addresses.map { vm.memory.getUW(it) }.minOf { it }
vm.registers.setUW(0, value)
}
Syscall.MIN_WORD -> {
val address = vm.registers.getUW(0).toInt()
val length = vm.registers.getUB(1).toInt()
val addresses = IntProgression.fromClosedRange(address, address+length*2-2, 2)
val value = addresses.map { vm.memory.getSW(it) }.minOf { it }
vm.registers.setSW(0, value)
}
Syscall.SUM_BYTE -> {
val address = vm.registers.getUW(0).toInt()
val length = vm.registers.getUB(1).toInt()
val addresses = IntProgression.fromClosedRange(address, address+length*2-2, 2)
val value = addresses.map { vm.memory.getUB(it) }.sum()
vm.registers.setUB(0, value.toUByte())
}
Syscall.SUM_WORD -> {
val address = vm.registers.getUW(0).toInt()
val length = vm.registers.getUB(1).toInt()
val addresses = IntProgression.fromClosedRange(address, address+length*2-2, 2)
val value = addresses.map { vm.memory.getUW(it) }.sum()
vm.registers.setUW(0, value.toUShort())
val array = IntProgression.fromClosedRange(address, address+length*4-2, 4).map {
vm.memory.getFloat(it)
}.reversed()
array.withIndex().forEach { (index, value)->
vm.memory.setFloat(address+index*4, value)
}
}
Syscall.ANY_BYTE -> {
val address = vm.registers.getUW(0).toInt()
@ -279,6 +205,15 @@ object SysCalls {
else
vm.registers.setUB(0, 0u)
}
Syscall.ANY_FLOAT -> {
val address = vm.registers.getUW(0).toInt()
val length = vm.registers.getUB(1).toInt()
val addresses = IntProgression.fromClosedRange(address, address+length*4-2, 4)
if(addresses.any { vm.memory.getFloat(it).toInt()!=0 })
vm.registers.setUB(0, 1u)
else
vm.registers.setUB(0, 0u)
}
Syscall.ALL_BYTE -> {
val address = vm.registers.getUW(0).toInt()
val length = vm.registers.getUB(1).toInt()
@ -297,6 +232,15 @@ object SysCalls {
else
vm.registers.setUB(0, 0u)
}
Syscall.ALL_FLOAT -> {
val address = vm.registers.getUW(0).toInt()
val length = vm.registers.getUB(1).toInt()
val addresses = IntProgression.fromClosedRange(address, address+length*4-2, 4)
if(addresses.all { vm.memory.getFloat(it).toInt()!=0 })
vm.registers.setUB(0, 1u)
else
vm.registers.setUB(0, 0u)
}
Syscall.PRINT_F -> {
val value = vm.registers.getFloat(0)
print(value)

View File

@ -173,10 +173,10 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
Opcode.CLC -> { statusCarry = false; pc++ }
Opcode.SEC -> { statusCarry = true; pc++ }
Opcode.FFROMUB -> TODO()
Opcode.FFROMSB -> TODO()
Opcode.FFROMUW -> TODO()
Opcode.FFROMSW -> TODO()
Opcode.FFROMUB -> InsFFROMUB(ins)
Opcode.FFROMSB -> InsFFROMSB(ins)
Opcode.FFROMUW -> InsFFROMUW(ins)
Opcode.FFROMSW -> InsFFROMSW(ins)
Opcode.FTOUB -> InsFTOUB(ins)
Opcode.FTOSB -> InsFTOSB(ins)
Opcode.FTOUW -> InsFTOUW(ins)
@ -276,7 +276,7 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
when(i.type!!) {
VmDataType.BYTE -> registers.setUB(i.reg1!!, memory.getUB(registers.getUW(i.reg2!!).toInt()))
VmDataType.WORD -> registers.setUW(i.reg1!!, memory.getUW(registers.getUW(i.reg2!!).toInt()))
VmDataType.FLOAT -> registers.setFloat(i.fpReg1!!, memory.getFloat(registers.getUW(i.reg2!!).toInt()))
VmDataType.FLOAT -> registers.setFloat(i.fpReg1!!, memory.getFloat(registers.getUW(i.reg1!!).toInt()))
}
pc++
}
@ -285,7 +285,7 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
when (i.type!!) {
VmDataType.BYTE -> registers.setUB(i.reg1!!, memory.getUB(i.value!! + registers.getUW(i.reg2!!).toInt()))
VmDataType.WORD -> registers.setUW(i.reg1!!, memory.getUW(i.value!! + registers.getUW(i.reg2!!).toInt()))
VmDataType.FLOAT -> registers.setFloat(i.fpReg1!!, memory.getFloat(i.value!! + registers.getUW(i.reg2!!).toInt()))
VmDataType.FLOAT -> registers.setFloat(i.fpReg1!!, memory.getFloat(i.value!! + registers.getUW(i.reg1!!).toInt()))
}
pc++
}
@ -1062,6 +1062,26 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
pc++
}
private fun InsFFROMUB(i: Instruction) {
registers.setFloat(i.fpReg1!!, registers.getUB(i.reg1!!).toFloat())
pc++
}
private fun InsFFROMSB(i: Instruction) {
registers.setFloat(i.fpReg1!!, registers.getSB(i.reg1!!).toFloat())
pc++
}
private fun InsFFROMUW(i: Instruction) {
registers.setFloat(i.fpReg1!!, registers.getUW(i.reg1!!).toFloat())
pc++
}
private fun InsFFROMSW(i: Instruction) {
registers.setFloat(i.fpReg1!!, registers.getSW(i.reg1!!).toFloat())
pc++
}
private fun InsFTOUB(i: Instruction) {
registers.setUB(i.reg1!!, registers.getFloat(i.fpReg1!!).toInt().toUByte())
pc++