From 0d4449208628ddb0fc5646da1ee0a4e347c440e2 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Tue, 26 Dec 2023 14:47:31 +0100 Subject: [PATCH] push,pushw,pop and popw are no longer built-in functions but regular routines in `sys` --- .../src/prog8/code/core/BuiltinFunctions.kt | 4 -- .../src/prog8/codegen/cpu6502/AsmGen.kt | 22 ++-------- .../codegen/cpu6502/BuiltinFunctionsAsmGen.kt | 18 -------- .../codegen/intermediate/BuiltinFuncGen.kt | 42 ------------------- compiler/res/prog8lib/atari/syslib.p8 | 28 +++++++++++++ compiler/res/prog8lib/c128/syslib.p8 | 28 +++++++++++++ compiler/res/prog8lib/c64/syslib.p8 | 27 ++++++++++++ compiler/res/prog8lib/cx16/psg.p8 | 16 +++---- compiler/res/prog8lib/cx16/syslib.p8 | 27 ++++++++++++ compiler/res/prog8lib/pet32/syslib.p8 | 28 +++++++++++++ compiler/res/prog8lib/virtual/syslib.p8 | 32 ++++++++++++++ .../compiler/astprocessing/AstChecker.kt | 13 ------ compiler/test/TestBuiltinFunctions.kt | 14 ------- compiler/test/TestTypecasts.kt | 6 +-- .../test/codegeneration/TestVariousCodeGen.kt | 21 ++++++++++ docs/source/libraries.rst | 14 +++++++ docs/source/programming.rst | 14 ------- examples/test.p8 | 21 +++++++--- syntax-files/IDEA/Prog8.xml | 6 +-- syntax-files/NotepadPlusPlus/Prog8.xml | 2 +- syntax-files/Vim/prog8_builtins.vim | 2 +- .../src/prog8/vm/VmProgramLoader.kt | 2 +- virtualmachine/test/TestVm.kt | 2 +- 23 files changed, 243 insertions(+), 146 deletions(-) diff --git a/codeCore/src/prog8/code/core/BuiltinFunctions.kt b/codeCore/src/prog8/code/core/BuiltinFunctions.kt index d5f75f5ed..2dfab89c8 100644 --- a/codeCore/src/prog8/code/core/BuiltinFunctions.kt +++ b/codeCore/src/prog8/code/core/BuiltinFunctions.kt @@ -125,10 +125,6 @@ val BuiltinFunctions: Map = mapOf( "pokew" to FSignature(false, listOf(FParam("address", arrayOf(DataType.UWORD)), FParam("value", arrayOf(DataType.UWORD))), null), "pokef" to FSignature(false, listOf(FParam("address", arrayOf(DataType.UWORD)), FParam("value", arrayOf(DataType.FLOAT))), null), "pokemon" to FSignature(false, listOf(FParam("address", arrayOf(DataType.UWORD)), FParam("value", arrayOf(DataType.UBYTE))), DataType.UBYTE), - "pop" to FSignature(false, listOf(FParam("target", ByteDatatypes)), null), - "popw" to FSignature(false, listOf(FParam("target", WordDatatypes)), null), - "push" to FSignature(false, listOf(FParam("value", ByteDatatypes)), null), - "pushw" to FSignature(false, listOf(FParam("value", WordDatatypes)), null), "rsave" to FSignature(false, emptyList(), null), "rrestore" to FSignature(false, emptyList(), null), "memory" to FSignature(true, listOf(FParam("name", arrayOf(DataType.STR)), FParam("size", arrayOf(DataType.UWORD)), FParam("alignment", arrayOf(DataType.UWORD))), DataType.UWORD), diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt index 352d94e90..0a3785867 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt @@ -3059,30 +3059,16 @@ $repeatLabel""") } } - internal fun popCpuStack(dt: DataType, target: IPtVariable, scope: IPtSubroutine?) { - // note: because A is pushed first so popped last, saving A is often not required here. - val targetAsmSub = (target as PtNode).definingAsmSub() - if(targetAsmSub != null) { - val parameter = targetAsmSub.parameters.first { it.second.name==target.name } - popCpuStack(targetAsmSub, parameter.second, parameter.first) - return - } - val scopedName = when(target) { - is PtConstant -> target.scopedName - is PtMemMapped -> target.scopedName - is PtVariable -> target.scopedName - else -> throw AssemblyError("weird target var") - } - val tgt = AsmAssignTarget(TargetStorageKind.VARIABLE, this, target.type, scope, target.position, variableAsmName = asmVariableName(scopedName)) + internal fun popCpuStack(dt: DataType) { if (dt in ByteDatatypes) { out(" pla") - assignRegister(RegisterOrPair.A, tgt) - } else { + } else if (dt in WordDatatypes) { if (isTargetCpu(CpuType.CPU65c02)) out(" ply | pla") else out(" pla | tay | pla") - assignRegister(RegisterOrPair.AY, tgt) + } else { + throw AssemblyError("can't pop type $dt") } } diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt index 312c069a4..234a62530 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt @@ -63,24 +63,6 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram, asmgen.out(" pla") } "poke" -> throw AssemblyError("poke() should have been replaced by @()") - "push" -> asmgen.pushCpuStack(DataType.UBYTE, fcall.args[0]) - "pushw" -> asmgen.pushCpuStack(DataType.UWORD, fcall.args[0]) - "pop" -> { - require(fcall.args[0] is PtIdentifier) { - "attempt to pop a value into a differently typed variable, or in something else that isn't supported ${fcall.position}" - } - val symbol = asmgen.symbolTable.lookup((fcall.args[0] as PtIdentifier).name) - val target = symbol!!.astNode as IPtVariable - asmgen.popCpuStack(DataType.UBYTE, target, fcall.definingISub()) - } - "popw" -> { - require(fcall.args[0] is PtIdentifier) { - "attempt to pop a value into a differently typed variable, or in something else that isn't supported ${fcall.position}" - } - val symbol = asmgen.symbolTable.lookup((fcall.args[0] as PtIdentifier).name) - val target = symbol!!.astNode as IPtVariable - asmgen.popCpuStack(DataType.UWORD, target, fcall.definingISub()) - } "rsave" -> funcRsave() "rrestore" -> funcRrestore() "cmp" -> funcCmp(fcall) diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/BuiltinFuncGen.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/BuiltinFuncGen.kt index 1364da84d..965885112 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/BuiltinFuncGen.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/BuiltinFuncGen.kt @@ -20,10 +20,6 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe "sqrt__ubyte", "sqrt__uword", "sqrt__float" -> funcSqrt(call) "divmod__ubyte" -> funcDivmod(call, IRDataType.BYTE) "divmod__uword" -> funcDivmod(call, IRDataType.WORD) - "pop" -> funcPop(call) - "popw" -> funcPopw(call) - "push" -> funcPush(call) - "pushw" -> funcPushw(call) "rsave", "rrestore" -> ExpressionCodeResult.EMPTY // vm doesn't have registers to save/restore "callfar" -> funcCallfar(call) "call" -> funcCall(call) @@ -278,44 +274,6 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe } } - private fun funcPop(call: PtBuiltinFunctionCall): ExpressionCodeResult { - val code = IRCodeChunk(null, null) - val reg = codeGen.registers.nextFree() - code += IRInstruction(Opcode.POP, IRDataType.BYTE, reg1=reg) - val result = mutableListOf(code) - result += assignRegisterTo(call.args.single(), reg) - return ExpressionCodeResult(result, IRDataType.BYTE, reg, -1) - } - - private fun funcPopw(call: PtBuiltinFunctionCall): ExpressionCodeResult { - val code = IRCodeChunk(null, null) - val reg = codeGen.registers.nextFree() - code += IRInstruction(Opcode.POP, IRDataType.WORD, reg1=reg) - val result = mutableListOf(code) - result += assignRegisterTo(call.args.single(), reg) - return ExpressionCodeResult(result, IRDataType.WORD, reg, -1) - } - - private fun funcPush(call: PtBuiltinFunctionCall): ExpressionCodeResult { - val result = mutableListOf() - val tr = exprGen.translateExpression(call.args.single()) - addToResult(result, tr, tr.resultReg, -1) - result += IRCodeChunk(null, null).also { - it += IRInstruction(Opcode.PUSH, IRDataType.BYTE, reg1=tr.resultReg) - } - return ExpressionCodeResult(result, IRDataType.BYTE, -1, -1) - } - - private fun funcPushw(call: PtBuiltinFunctionCall): ExpressionCodeResult { - val result = mutableListOf() - val tr = exprGen.translateExpression(call.args.single()) - addToResult(result, tr, tr.resultReg, -1) - result += IRCodeChunk(null, null).also { - it += IRInstruction(Opcode.PUSH, IRDataType.WORD, reg1 = tr.resultReg) - } - return ExpressionCodeResult(result, IRDataType.BYTE, -1, -1) - } - private fun funcReverse(call: PtBuiltinFunctionCall): ExpressionCodeResult { val arrayName = call.args[0] as PtIdentifier val arrayLength = codeGen.symbolTable.getLength(arrayName.name) diff --git a/compiler/res/prog8lib/atari/syslib.p8 b/compiler/res/prog8lib/atari/syslib.p8 index 277198202..79d318ef6 100644 --- a/compiler/res/prog8lib/atari/syslib.p8 +++ b/compiler/res/prog8lib/atari/syslib.p8 @@ -269,6 +269,34 @@ save_SCRATCH_ZPWORD2 .word 0 }} } + inline asmsub push(ubyte value @A) { + %asm {{ + pha + }} + } + + inline asmsub pushw(uword value @AY) { + %asm {{ + pha + tya + pha + }} + } + + inline asmsub pop() -> ubyte @A { + %asm {{ + pla + }} + } + + inline asmsub popw() -> uword @AY { + %asm {{ + pla + tay + pla + }} + } + } cx16 { diff --git a/compiler/res/prog8lib/c128/syslib.p8 b/compiler/res/prog8lib/c128/syslib.p8 index 2215a7c80..bf7237bc9 100644 --- a/compiler/res/prog8lib/c128/syslib.p8 +++ b/compiler/res/prog8lib/c128/syslib.p8 @@ -774,6 +774,34 @@ _longcopy }} } + inline asmsub push(ubyte value @A) { + %asm {{ + pha + }} + } + + inline asmsub pushw(uword value @AY) { + %asm {{ + pha + tya + pha + }} + } + + inline asmsub pop() -> ubyte @A { + %asm {{ + pla + }} + } + + inline asmsub popw() -> uword @AY { + %asm {{ + pla + tay + pla + }} + } + } cx16 { diff --git a/compiler/res/prog8lib/c64/syslib.p8 b/compiler/res/prog8lib/c64/syslib.p8 index 3901c7719..3c21576b8 100644 --- a/compiler/res/prog8lib/c64/syslib.p8 +++ b/compiler/res/prog8lib/c64/syslib.p8 @@ -772,6 +772,33 @@ _longcopy }} } + inline asmsub push(ubyte value @A) { + %asm {{ + pha + }} + } + + inline asmsub pushw(uword value @AY) { + %asm {{ + pha + tya + pha + }} + } + + inline asmsub pop() -> ubyte @A { + %asm {{ + pla + }} + } + + inline asmsub popw() -> uword @AY { + %asm {{ + pla + tay + pla + }} + } } cx16 { diff --git a/compiler/res/prog8lib/cx16/psg.p8 b/compiler/res/prog8lib/cx16/psg.p8 index 6652c84eb..7e3cb8d8a 100644 --- a/compiler/res/prog8lib/cx16/psg.p8 +++ b/compiler/res/prog8lib/cx16/psg.p8 @@ -114,10 +114,10 @@ psg { ; cx16.r0 = the volume word (volume scaled by 256) ; cx16.r1L = the voice number ; cx16.r2L = attack value - pushw(cx16.r0) - push(cx16.r1L) - push(cx16.r2L) - pushw(cx16.r9) + sys.pushw(cx16.r0) + sys.push(cx16.r1L) + sys.push(cx16.r2L) + sys.pushw(cx16.r9) ; calculate new volumes for cx16.r1L in 0 to 15 { when envelope_states[cx16.r1L] { @@ -166,10 +166,10 @@ psg { cx16.VERA_DATA0 = cx16.VERA_DATA1 & %11000000 | msb(envelope_volumes[cx16.r1L]) } cx16.restore_vera_context() - popw(cx16.r9) - pop(cx16.r2L) - pop(cx16.r1L) - popw(cx16.r0) + cx16.r9 = sys.popw() + cx16.r2L = sys.pop() + cx16.r1L = sys.pop() + cx16.r0 = sys.popw() return true ; run the system IRQ handler afterwards } diff --git a/compiler/res/prog8lib/cx16/syslib.p8 b/compiler/res/prog8lib/cx16/syslib.p8 index fdf825a31..408ef08a3 100644 --- a/compiler/res/prog8lib/cx16/syslib.p8 +++ b/compiler/res/prog8lib/cx16/syslib.p8 @@ -1615,4 +1615,31 @@ save_SCRATCH_ZPWORD2 .word 0 ldy #>prog8_program_end }} } + + inline asmsub push(ubyte value @A) { + %asm {{ + pha + }} + } + + inline asmsub pushw(uword value @AY) { + %asm {{ + pha + phy + }} + } + + inline asmsub pop() -> ubyte @A { + %asm {{ + pla + }} + } + + inline asmsub popw() -> uword @AY { + %asm {{ + ply + pla + }} + } + } diff --git a/compiler/res/prog8lib/pet32/syslib.p8 b/compiler/res/prog8lib/pet32/syslib.p8 index 4eaa08047..8cf327ca9 100644 --- a/compiler/res/prog8lib/pet32/syslib.p8 +++ b/compiler/res/prog8lib/pet32/syslib.p8 @@ -361,6 +361,34 @@ save_SCRATCH_ZPWORD2 .word 0 }} } + inline asmsub push(ubyte value @A) { + %asm {{ + pha + }} + } + + inline asmsub pushw(uword value @AY) { + %asm {{ + pha + tya + pha + }} + } + + inline asmsub pop() -> ubyte @A { + %asm {{ + pla + }} + } + + inline asmsub popw() -> uword @AY { + %asm {{ + pla + tay + pla + }} + } + } cx16 { diff --git a/compiler/res/prog8lib/virtual/syslib.p8 b/compiler/res/prog8lib/virtual/syslib.p8 index 1c4b3ca84..d1ff3af49 100644 --- a/compiler/res/prog8lib/virtual/syslib.p8 +++ b/compiler/res/prog8lib/virtual/syslib.p8 @@ -126,6 +126,38 @@ sys { returnr.b r0 }} } + + sub push(ubyte b) { + ; note: this *should* be inlined, however since the VM has separate program counter and value stacks, this also works + %ir {{ + loadm.b r65535,sys.push.b + push.b r65535 + }} + } + + sub pushw(uword w) { + ; note: this *should* be inlined, however since the VM has separate program counter and value stacks, this also works + %ir {{ + loadm.w r65535,sys.pushw.w + push.w r65535 + }} + } + + sub pop() -> ubyte { + ; note: this *should* be inlined, however since the VM has separate program counter and value stacks, this also works + %ir {{ + pop.b r65535 + returnr.b r65535 + }} + } + + sub popw() -> uword { + ; note: this *should* be inlined, however since the VM has separate program counter and value stacks, this also works + %ir {{ + pop.w r65535 + returnr.w r65535 + }} + } } cx16 { diff --git a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt index ba86d0a9e..9dd982796 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt @@ -1216,19 +1216,6 @@ internal class AstChecker(private val program: Program, errors.err("sorting a floating point array is not supported", functionCallStatement.args.first().position) } } - else if(funcName[0] in arrayOf("pop", "popw")) { - // can only pop into a variable, that has to have the correct type - val idref = functionCallStatement.args[0] - if(idref !is IdentifierReference) { - if(idref is TypecastExpression) { - val passByRef = idref.expression.inferType(program).isPassByReference - if(idref.type!=DataType.UWORD || !passByRef) - errors.err("invalid argument to pop, must be a variable with the correct type: ${functionCallStatement.args.first()}", functionCallStatement.args.first().position) - } else { - errors.err("invalid argument to pop, must be a variable with the correct type: ${functionCallStatement.args.first()}", functionCallStatement.args.first().position) - } - } - } else if(funcName[0].startsWith("divmod")) { if(functionCallStatement.args[2] is TypecastExpression || functionCallStatement.args[3] is TypecastExpression) { errors.err("arguments must be all ubyte or all uword", functionCallStatement.position) diff --git a/compiler/test/TestBuiltinFunctions.kt b/compiler/test/TestBuiltinFunctions.kt index ddebf14bf..6cc481bdc 100644 --- a/compiler/test/TestBuiltinFunctions.kt +++ b/compiler/test/TestBuiltinFunctions.kt @@ -2,7 +2,6 @@ package prog8tests import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.shouldBe -import io.kotest.matchers.shouldNotBe import prog8.ast.expressions.NumericLiteral import prog8.ast.statements.Assignment import prog8.ast.statements.FunctionCallStatement @@ -69,19 +68,6 @@ class TestBuiltinFunctions: FunSpec({ conv.returns.reg shouldBe null } - test("push pop") { - val src=""" - main { - sub start () { - pushw(cx16.r0) - push(cx16.r1L) - pop(cx16.r1L) - popw(cx16.r0) - } - }""" - compileText(Cx16Target(), false, src, writeAssembly = true) shouldNotBe null - } - test("certain builtin functions should be compile time evaluated") { val src=""" main { diff --git a/compiler/test/TestTypecasts.kt b/compiler/test/TestTypecasts.kt index b48a8af67..45f6ebbb7 100644 --- a/compiler/test/TestTypecasts.kt +++ b/compiler/test/TestTypecasts.kt @@ -693,9 +693,9 @@ main { sub start() { uword variable - pushw(variable) - pushw(handler) - pushw(&handler) + sys.pushw(variable) + sys.pushw(handler) + sys.pushw(&handler) handler(variable) handler(handler) handler(&handler) diff --git a/compiler/test/codegeneration/TestVariousCodeGen.kt b/compiler/test/codegeneration/TestVariousCodeGen.kt index 4ec652d5d..e5e055537 100644 --- a/compiler/test/codegeneration/TestVariousCodeGen.kt +++ b/compiler/test/codegeneration/TestVariousCodeGen.kt @@ -16,6 +16,7 @@ import prog8.code.target.Cx16Target import prog8.code.target.VMTarget import prog8tests.helpers.ErrorReporterForTests import prog8tests.helpers.compileText +import kotlin.io.path.readText class TestVariousCodeGen: FunSpec({ test("bool to byte cast in expression is correct") { @@ -358,4 +359,24 @@ main { compileText(VMTarget(), true, src, writeAssembly = false) shouldNotBe null compileText(Cx16Target(), true, src, writeAssembly = false) shouldNotBe null } + + test("push pop are inlined also with noopt") { + val text = """ +main { + sub start() { + sys.push(11) + sys.pushw(2222) + cx16.r2++ + cx16.r1 = sys.popw() + cx16.r0L = sys.pop() + } +}""" + val result = compileText(C64Target(), false, text, writeAssembly = true)!! + val assemblyFile = result.compilationOptions.outputDir.resolve(result.compilerAst.name + ".asm") + val assembly = assemblyFile.readText() + assembly shouldContain "inlined routine follows: push" + assembly shouldContain "inlined routine follows: pushw" + assembly shouldContain "inlined routine follows: pop" + assembly shouldContain "inlined routine follows: popw" + } }) \ No newline at end of file diff --git a/docs/source/libraries.rst b/docs/source/libraries.rst index 72579b28e..9653b1661 100644 --- a/docs/source/libraries.rst +++ b/docs/source/libraries.rst @@ -140,6 +140,20 @@ sys (part of syslib) It stores and restores the values of the internal prog8 variables. This allows other code to run that might clobber these values temporarily. +``push (value)`` + pushes a byte value on the CPU hardware stack. Low-level function that should normally not be used. + +``pushw (value)`` + pushes a 16-bit word value on the CPU hardware stack. Low-level function that should normally not be used. + +``pop ()`` + pops a byte value off the CPU hardware stack and returns it. + Low-level function that should normally not be used. + +``popw ()`` + pops a 16-bit word value off the CPU hardware stack and returns it. + Low-level function that should normally not be used. + conv ---- diff --git a/docs/source/programming.rst b/docs/source/programming.rst index 29a67a757..824162299 100644 --- a/docs/source/programming.rst +++ b/docs/source/programming.rst @@ -898,20 +898,6 @@ pokemon (address, value) Like poke(), but also returns the previous value in the given address. Also doesn't have anything to do with a certain video game. -push (value) - pushes a byte value on the CPU hardware stack. Low-level function that should normally not be used. - -pushw (value) - pushes a 16-bit word value on the CPU hardware stack. Low-level function that should normally not be used. - -pop (variable) - pops a byte value off the CPU hardware stack into the given variable. Only variables can be used. - Low-level function that should normally not be used. - -popw (value) - pops a 16-bit word value off the CPU hardware stack into the given variable. Only variables can be used. - Low-level function that should normally not be used. - rol (x) Rotate the bits in x (byte or word) one position to the left. This uses the CPU's rotate semantics: bit 0 will be set to the current value of the Carry flag, diff --git a/examples/test.p8 b/examples/test.p8 index eef353224..2332f5fe4 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,14 +1,25 @@ %import textio -%zeropage dontuse +;;%import floats +%zeropage basicsafe main { sub start() { - uword empty - uword block = memory("block", 500, 0) + sys.push(11) + sys.pushw(2222) + ;;floats.pushf(floats.π) + cx16.r2++ - txt.print_uwhex(&empty, true) + ;;float pi = floats.popf() + ;;floats.print_f(pi) + ;;txt.nl() + + cx16.r1 = sys.popw() + cx16.r0L = sys.pop() + + txt.print_ub(cx16.r0L) txt.nl() - txt.print_uwhex(block, true) + txt.print_uw(cx16.r1) txt.nl() + } } diff --git a/syntax-files/IDEA/Prog8.xml b/syntax-files/IDEA/Prog8.xml index a37c4f4f1..f0acf5a1e 100644 --- a/syntax-files/IDEA/Prog8.xml +++ b/syntax-files/IDEA/Prog8.xml @@ -1,4 +1,4 @@ - + - + \ No newline at end of file diff --git a/syntax-files/NotepadPlusPlus/Prog8.xml b/syntax-files/NotepadPlusPlus/Prog8.xml index f61b458dc..bc98d0acd 100644 --- a/syntax-files/NotepadPlusPlus/Prog8.xml +++ b/syntax-files/NotepadPlusPlus/Prog8.xml @@ -27,7 +27,7 @@ void const str byte ubyte bool word uword float zp shared split requirezp %address %asm %ir %asmbinary %asminclude %breakpoint %encoding %import %launcher %option %output %zeropage %zpreserved %zpallowed 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 unroll break continue return goto - abs all any call callfar clamp cmp divmod len lsb lsl lsr memory mkword min max msb peek peekw peekf poke pokew pokef push pushw pop popw rsave rsavex rrestore rrestorex reverse rnd rndw rol rol2 ror ror2 setlsb setmsb sgn sizeof sort sqrtw swap + abs all any call callfar clamp cmp divmod len lsb lsl lsr memory mkword min max msb peek peekw peekf poke pokew pokef rsave rsavex rrestore rrestorex reverse rnd rndw rol rol2 ror ror2 setlsb setmsb sgn sizeof sort sqrtw swap true false not and or xor as to downto |> diff --git a/syntax-files/Vim/prog8_builtins.vim b/syntax-files/Vim/prog8_builtins.vim index 9a1e8cc0b..3812de9fc 100644 --- a/syntax-files/Vim/prog8_builtins.vim +++ b/syntax-files/Vim/prog8_builtins.vim @@ -13,7 +13,7 @@ syn keyword prog8BuiltInFunc sgn sqrtw syn keyword prog8BuiltInFunc any all len reverse sort " Miscellaneous functions -syn keyword prog8BuiltInFunc cmp divmod lsb msb mkword min max peek peekw peekf poke pokew pokef push pushw pop popw rsave rsavex rrestore rrestorex +syn keyword prog8BuiltInFunc cmp divmod lsb msb mkword min max peek peekw peekf poke pokew pokef rsave rsavex rrestore rrestorex syn keyword prog8BuiltInFunc rol rol2 ror ror2 sizeof setlsb setmsb syn keyword prog8BuiltInFunc swap memory call callfar clamp diff --git a/virtualmachine/src/prog8/vm/VmProgramLoader.kt b/virtualmachine/src/prog8/vm/VmProgramLoader.kt index b887592c6..9317084f2 100644 --- a/virtualmachine/src/prog8/vm/VmProgramLoader.kt +++ b/virtualmachine/src/prog8/vm/VmProgramLoader.kt @@ -43,7 +43,7 @@ class VmProgramLoader { block.children.forEach { child -> when(child) { - is IRAsmSubroutine -> throw IRParseException("vm does not support asmsubs (use normal sub): ${child.label}") + is IRAsmSubroutine -> throw IRParseException("vm does not support non-inlined asmsubs (use normal sub): ${child.label}") is IRCodeChunk -> programChunks += child is IRInlineAsmChunk -> throw IRParseException("encountered unconverted inline assembly chunk") is IRInlineBinaryChunk -> throw IRParseException("inline binary data not yet supported in the VM") diff --git a/virtualmachine/test/TestVm.kt b/virtualmachine/test/TestVm.kt index fbeec40eb..eb848c971 100644 --- a/virtualmachine/test/TestVm.kt +++ b/virtualmachine/test/TestVm.kt @@ -85,7 +85,7 @@ class TestVm: FunSpec( { ) block += startSub program.addBlock(block) - shouldThrowWithMessage("vm does not support asmsubs (use normal sub): main.asmstart") { + shouldThrowWithMessage("vm does not support non-inlined asmsubs (use normal sub): main.asmstart") { VirtualMachine(program) } }