mirror of
https://github.com/irmen/prog8.git
synced 2025-01-11 13:29:45 +00:00
vm: implement float to integer cast, any, all, reverse
This commit is contained in:
parent
3f9cdd9b56
commit
da01a5b4dc
@ -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)
|
||||
|
@ -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()
|
||||
|
@ -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")
|
||||
}
|
||||
|
@ -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
|
||||
}}
|
||||
}
|
||||
|
@ -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:
|
||||
|
||||
|
@ -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
|
||||
|
@ -14,7 +14,7 @@
|
||||
<keywords keywords="&;->;@;\$;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;|>" />
|
||||
<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;|>" />
|
||||
</highlighting>
|
||||
<extensionMap>
|
||||
<mapping ext="p8" />
|
||||
|
@ -27,7 +27,7 @@
|
||||
<Keywords name="Keywords1">void const
str
byte ubyte
word uword
float
zp shared requirezp</Keywords>
|
||||
<Keywords name="Keywords2">%address
%asm
%asmbinary
%asminclude
%breakpoint
%import
%launcher
%option
%output
%zeropage
%zpreserved</Keywords>
|
||||
<Keywords name="Keywords3">inline sub asmsub romsub
clobbers
asm
if
when else
if_cc if_cs if_eq if_mi if_neg if_nz if_pl if_pos if_vc if_vs if_z
for in step do while repeat
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
not and or xor
as to downto |></Keywords>
|
||||
<Keywords name="Keywords6"></Keywords>
|
||||
<Keywords name="Keywords7"></Keywords>
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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++
|
||||
|
Loading…
x
Reference in New Issue
Block a user