vm: more complete V-flag handling. somd doc and todo updates.

This commit is contained in:
Irmen de Jong
2025-05-23 18:58:14 +02:00
parent cc063124cf
commit 9da430ffeb
15 changed files with 35 additions and 24 deletions
@@ -19,7 +19,7 @@ class ConfigurableZeropage(
init {
if (options.floats) {
TODO("floats")
TODO("floats in configurable target zp")
}
if(SCRATCH_REG!=SCRATCH_B1+1u)
@@ -30,7 +30,7 @@ class ConfigurableZeropage(
ZeropageType.FULL -> fullsafe.forEach { free.addAll(it) }
ZeropageType.BASICSAFE -> basicsafe.forEach { free.addAll(it) }
ZeropageType.KERNALSAFE -> kernalsafe.forEach { free.addAll(it) }
ZeropageType.FLOATSAFE -> TODO("floatsafe")
ZeropageType.FLOATSAFE -> TODO("floatsafe in configurable target zp")
}
val distinctFree = free.distinct()
@@ -1046,7 +1046,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
}
private fun loadStatusAsBooleanResult(branchForTrue: Opcode, result: MutableList<IRCodeChunkBase>): Int {
// TODO this used to be a single instruction like SCC, SCS, SZ etc but those were problematic
// TODO this used to be a single instruction like SCC, SCS, SZ etc
val other = codeGen.createLabelName()
val after = codeGen.createLabelName()
val resultReg = codeGen.registers.next(IRDataType.BYTE)
@@ -1061,7 +1061,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
}
private fun compareRegisterAsBooleanResult(branchForTrue: Opcode, dt: IRDataType, reg1: Int, reg2: Int, result: MutableList<IRCodeChunkBase>): Int {
// TODO this used to be a single instruction like SCC, SCS, SZ etc but those were problematic
// TODO this used to be a single instruction like SCC, SCS, SZ etc
val other = codeGen.createLabelName()
val after = codeGen.createLabelName()
val resultReg = codeGen.registers.next(IRDataType.BYTE)
@@ -1966,7 +1966,7 @@ class IRCodeGen(
null -> when(registerOrFlag.statusflag) {
// TODO: do the statusflag argument as last
Statusflag.Pc -> chunk += IRInstruction(Opcode.LSR, paramDt, reg1=resultReg)
else -> throw AssemblyError("weird statusflag as param")
else -> throw AssemblyError("unsupported statusflag as param")
}
else -> throw AssemblyError("unsupported register arg")
}
+2 -3
View File
@@ -231,9 +231,8 @@ sys {
if_cs
cx16.r0L |= 1
; TODO: overflow flag not yet supported
; if_vs
; cx16.r0L |= %01000000
if_vs
cx16.r0L |= %01000000
return cx16.r0L
}
@@ -182,7 +182,7 @@ internal class AstChecker(private val program: Program,
val iterableDt = forLoop.iterable.inferType(program).getOrUndef()
if(iterableDt.isNumeric) TODO("iterable type should not be simple numeric!? "+forLoop.position)
if(iterableDt.isNumeric) TODO("iterable type should not be simple numeric "+forLoop.position)
if(forLoop.iterable is IFunctionCall) {
errors.err("can not loop over function call return value", forLoop.position)
@@ -196,7 +196,7 @@ internal class AstChecker(private val program: Program,
require(loopvar.datatype.isNumericOrBool)
when (loopvar.datatype.base) {
BaseDataType.UBYTE -> {
if(!iterableDt.isUnsignedByte && !iterableDt.isUnsignedByteArray && !iterableDt.isString) // TODO remove ubyte check?
if(!iterableDt.isUnsignedByte && !iterableDt.isUnsignedByteArray && !iterableDt.isString)
errors.err("ubyte loop variable can only loop over unsigned bytes or strings", forLoop.position)
checkUnsignedLoopDownto0(forLoop.iterable as? RangeExpression)
}
@@ -205,7 +205,7 @@ internal class AstChecker(private val program: Program,
errors.err("bool loop variable can only loop over boolean array", forLoop.position)
}
BaseDataType.UWORD -> {
if(!iterableDt.isUnsignedByte && !iterableDt.isUnsignedWord && !iterableDt.isString && // TODO remove byte and word check?
if(!iterableDt.isUnsignedByte && !iterableDt.isUnsignedWord && !iterableDt.isString &&
!iterableDt.isUnsignedByteArray && !iterableDt.isUnsignedWordArray &&
!iterableDt.isSplitWordArray)
errors.err("uword loop variable can only loop over unsigned bytes, words or strings", forLoop.position)
@@ -213,7 +213,7 @@ internal class AstChecker(private val program: Program,
checkUnsignedLoopDownto0(forLoop.iterable as? RangeExpression)
}
BaseDataType.BYTE -> {
if(!iterableDt.isSignedByte && !iterableDt.isSignedByteArray) // TODO remove byte check?
if(!iterableDt.isSignedByte && !iterableDt.isSignedByteArray)
errors.err("byte loop variable can only loop over bytes", forLoop.position)
}
BaseDataType.WORD -> {
@@ -1,5 +1,6 @@
Prog8 compiler v11.3.1 by Irmen de Jong (irmen@razorvine.net)
Prog8 compiler v12.0-SNAPSHOT by Irmen de Jong (irmen@razorvine.net)
Prerelease version from git commit cc063124 in branch master
This software is licensed under the GNU GPL 3.0, see https://www.gnu.org/licenses/gpl.html
Compiling program import-all-c128.p8
@@ -1,5 +1,6 @@
Prog8 compiler v11.3.1 by Irmen de Jong (irmen@razorvine.net)
Prog8 compiler v12.0-SNAPSHOT by Irmen de Jong (irmen@razorvine.net)
Prerelease version from git commit cc063124 in branch master
This software is licensed under the GNU GPL 3.0, see https://www.gnu.org/licenses/gpl.html
Compiling program import-all-c64.p8
@@ -1,5 +1,6 @@
Prog8 compiler v11.3.1 by Irmen de Jong (irmen@razorvine.net)
Prog8 compiler v12.0-SNAPSHOT by Irmen de Jong (irmen@razorvine.net)
Prerelease version from git commit cc063124 in branch master
This software is licensed under the GNU GPL 3.0, see https://www.gnu.org/licenses/gpl.html
Compiling program import-all-cx16.p8
@@ -530,6 +531,7 @@ LIBRARY MODULE NAME: monogfx
----------------------------
monogfx {
uword buffer_visible, buffer_back
const ubyte MODE_INVERT
const ubyte MODE_NORMAL
const ubyte MODE_STIPPLE
@@ -545,6 +547,7 @@ monogfx {
cs_innerloop640 (bool draw @A) -> clobbers (Y)
disc (uword xcenter, uword ycenter, ubyte radius, bool draw)
drawmode (ubyte dm)
enable_doublebuffer ()
fill (uword x, uword y, bool draw, ubyte stack_rambank)
fillrect (uword xx, uword yy, uword rwidth, uword rheight, bool draw)
hires ()
@@ -560,6 +563,7 @@ monogfx {
safe_disc (uword xcenter, uword ycenter, ubyte radius, bool draw)
safe_horizontal_line (uword xx, uword yy, uword length, bool draw)
safe_plot (uword xx, uword yy, bool draw)
swap_buffers (bool wait_for_vsync)
text (uword xx, uword yy, bool draw, str sctextptr)
text_charset (ubyte charset)
textmode ()
@@ -1093,6 +1097,8 @@ cx16 {
iso_cursor_char (ubyte character @X) -> clobbers (A,X,Y)
joystick_get (ubyte joynr @A) -> uword @AX, bool @Y = $ff56
joystick_scan () -> clobbers (A,X,Y) = $ff53
joysticks_detect () -> ubyte
joysticks_getall (bool also_keyboard_js) -> uword
kbdbuf_get_modifiers () -> ubyte @A = $fec0
kbdbuf_peek () -> ubyte @A, ubyte @X = $febd
kbdbuf_put (ubyte key @A) -> clobbers (X) = $fec3
@@ -1,5 +1,6 @@
Prog8 compiler v11.3.1 by Irmen de Jong (irmen@razorvine.net)
Prog8 compiler v12.0-SNAPSHOT by Irmen de Jong (irmen@razorvine.net)
Prerelease version from git commit cc063124 in branch master
This software is licensed under the GNU GPL 3.0, see https://www.gnu.org/licenses/gpl.html
Compiling program import-all-pet32.p8
@@ -1,5 +1,6 @@
Prog8 compiler v11.3.1 by Irmen de Jong (irmen@razorvine.net)
Prog8 compiler v12.0-SNAPSHOT by Irmen de Jong (irmen@razorvine.net)
Prerelease version from git commit cc063124 in branch master
This software is licensed under the GNU GPL 3.0, see https://www.gnu.org/licenses/gpl.html
Compiling program import-all-virtual.p8
+1
View File
@@ -13,6 +13,7 @@ Future Things and Ideas
- is "checkAssignmentCompatible" redundant (gets called just 1 time!) when we also have "checkValueTypeAndRange" ?
- enums?
- romable: should we have a way to explicitly set the memory address for the BSS area (instead of only the highram bank number on X16, allow a memory address too for the -varshigh option?)
- romable: fix remaining codegens (some for loops, see ForLoopsAsmGen)
- Kotlin: can we use inline value classes in certain spots?
- add float support to the configurable compiler targets
- Improve the SublimeText syntax file for prog8, you can also install this for 'bat': https://github.com/sharkdp/bat?tab=readme-ov-file#adding-new-syntaxes--language-definitions
@@ -128,8 +128,8 @@ class IRFileReader {
zeropage,
zpReserved,
zpAllowed,
false, // TODO always false?
false, // TODO always false?
false,
false,
romable,
target,
loadAddress,
@@ -1035,7 +1035,7 @@ data class IRInstruction(
if(opcode==Opcode.CONCAT)
return when(type) {
IRDataType.BYTE -> IRDataType.WORD
IRDataType.WORD -> TODO("concat.w from long type")
IRDataType.WORD -> TODO("concat.w into long type")
else -> null
}
if(opcode==Opcode.ASRNM || opcode==Opcode.LSRNM || opcode==Opcode.LSLNM || opcode==Opcode.SQRT)
@@ -385,7 +385,7 @@ class PtTypeCast(type: BaseDataType, position: Position) : PtExpression(DataType
if(children[0] is PtIdentifier) {
copy.add((children[0] as PtIdentifier).copy())
} else {
TODO("cannot copy node ${children[0]}")
TODO("copy node ${children[0]}")
}
return copy
}
@@ -400,7 +400,8 @@ class VirtualMachine(irProgram: IRProgram) {
status = status or 0b00000010u
if(statusCarry)
status = status or 0b00000001u
// TODO overflow not yet supported
if(statusOverflow)
status = status or 0b01000000u
valueStack.add(status)
nextPc()
}
@@ -410,7 +411,7 @@ class VirtualMachine(irProgram: IRProgram) {
statusNegative = status and 0b10000000 != 0
statusZero = status and 0b00000010 != 0
statusCarry = status and 0b00000001 != 0
// TODO overflow not yet supported
statusOverflow = status and 0b01000000 != 0
nextPc()
}
@@ -1385,7 +1386,7 @@ class VirtualMachine(irProgram: IRProgram) {
IRDataType.WORD -> statusNegative = (comparison and 0x8000)!=0
IRDataType.FLOAT -> { /* floats don't change the status bits */ }
}
// TODO statusOverflow
// TODO determine statusOverflow in comparison
}
private fun plusMinusMultAnyByte(operator: String, reg1: Int, reg2: Int) {