fix IR codegen for the RETURN 4,5,6,7

added cx16.EXTAPI_memory_decompress_from_func for cx16
This commit is contained in:
Irmen de Jong 2025-01-22 02:31:21 +01:00
parent 277a1a32b2
commit 0191acb2b3
11 changed files with 48 additions and 40 deletions

View File

@ -59,7 +59,7 @@ sealed interface IPtAssignment {
get() = children.size>2
}
class PtAssignment(position: Position) : PtNode(position), IPtAssignment
class PtAssignment(position: Position, val isVarInitializer: Boolean=false) : PtNode(position), IPtAssignment
class PtAugmentedAssign(val operator: String, position: Position) : PtNode(position), IPtAssignment

View File

@ -21,6 +21,8 @@ internal class AssignmentAsmGen(
private val augmentableAsmGen = AugmentableAssignmentAsmGen(program, this, asmgen, allocator)
fun translate(assignment: PtAssignment) {
// if(assignment.isVarInitializer)
// println("VARINIT ${assignment.target} ${assignment.value}")
val target = AsmAssignTarget.fromAstAssignment(assignment.target, assignment.definingISub(), asmgen)
val source = AsmAssignSource.fromAstSource(assignment.value, program, asmgen).adjustSignedUnsigned(target)
val pos = if(assignment.position !== Position.DUMMY) assignment.position else if(assignment.target.position !== Position.DUMMY) assignment.target.position else assignment.value.position

View File

@ -46,7 +46,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
normalsub.returns.zip(assignmentTargets).zip(registersReverseOrder).forEach {
val target = it.first.second as PtAssignTarget
if(!target.void) {
val assignSingle = PtAssignment(assignment.position)
val assignSingle = PtAssignment(assignment.position, assignment.isVarInitializer)
assignSingle.add(target)
assignSingle.add(PtIdentifier("cx16.${it.second.toString().lowercase()}", it.first.first, assignment.position))
result += translateRegularAssign(assignSingle)

View File

@ -1764,11 +1764,9 @@ class IRCodeGen(
for ((value, register) in ret.children.zip(registersReverseOrder)) {
val tr = expressionEval.translateExpression(value as PtExpression)
addToResult(result, tr, tr.resultReg, -1)
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.STOREM, tr.dt, reg1=tr.resultReg, labelSymbol = "cx16.${register.toString().lowercase()}")
it += IRInstruction(Opcode.RETURN)
}
addInstr(result, IRInstruction(Opcode.STOREM, tr.dt, reg1=tr.resultReg, labelSymbol = "cx16.${register.toString().lowercase()}"), null)
}
addInstr(result, IRInstruction(Opcode.RETURN), null)
return result
}

View File

@ -585,7 +585,7 @@ _setup_raster_irq
ora #%10000000
sta c64.SCROLY ; set most significant bit of raster position
+ lda #%00000001
sta c64.IREQMASK ;enable raster interrupt signals from vic
sta c64.IREQMASK ; enable raster interrupt signals from vic
rts
}}
}

View File

@ -600,7 +600,7 @@ _setup_raster_irq
ora #%10000000
sta c64.SCROLY ; set most significant bit of raster position
+ lda #%00000001
sta c64.IREQMASK ;enable raster interrupt signals from vic
sta c64.IREQMASK ; enable raster interrupt signals from vic
rts
}}
}

View File

@ -557,6 +557,7 @@ const ubyte EXTAPI_led_update = $0B
const ubyte EXTAPI_mouse_set_position = $0C
const ubyte EXTAPI_scnsiz = $0D
const ubyte EXTAPI_kbd_leds = $0E
const ubyte EXTAPI_memory_decompress_from_func = $0F
; extapi16 call numbers
const ubyte EXTAPI16_test = $00

View File

@ -164,7 +164,7 @@ class SimplifiedAstMaker(private val program: Program, private val errors: IErro
}
}
val assign = PtAssignment(srcAssign.position)
val assign = PtAssignment(srcAssign.position, srcAssign.origin==AssignmentOrigin.VARINIT)
val multi = srcAssign.target.multi
if(multi==null) {
assign.add(transform(srcAssign.target))

View File

@ -1,6 +1,13 @@
TODO
====
- Look if the =0 variable initializations can be reduced further. (most notably for multi-value variable initialization).
See canSkipInitializationWith0()?
Remove it if there is another normal assignment after the initialization assignment,
that does not use the variable itself somewhere in the value, and the value doesn't contain a functioncall.
Set the "initializer" boolean to true on the first assignment that remains.
- Make some of the target machine config externally configurable (for 1 new target, the existing ones should stay as they are for the time being)
- add paypal donation button as well?
@ -70,6 +77,7 @@ Libraries
---------
- Sorting module gnomesort_uw could be optimized more, rewrite in asm? Shellshort seems consistently faster even if most of the words are already sorted.
- Add split-word array sorting routines to sorting module?
- add even more general raster irq routines to build some sort of "copper list" , like Oscar64 has?
- pet32 target: make syslib more complete (missing kernal routines)?
- need help with: PET disk routines (OPEN, SETLFS etc are not exposed as kernal calls)
- fix the problems in atari target, and flesh out its libraries.
@ -80,7 +88,7 @@ Libraries
Optimizations
-------------
- Look if the =0 variable initializations can be reduced further. (most notably for multi-value variable initialization)
- Compare output of some Oscar64 samples to what prog8 does for the equivalent code (see https://github.com/drmortalwombat/OscarTutorials/tree/main and https://github.com/drmortalwombat/oscar64/tree/main/samples)
- Multi-value returns of normal subroutines: use cpu register A or AY for the first one and only start using virtual registers for the rest.
Can FAC then be used for floats as well again? Those are now not supported for multi-value returns.
- Optimize the IfExpression code generation to be more like regular if-else code. (both 6502 and IR) search for "TODO don't store condition as expression"

View File

@ -9,14 +9,8 @@ main {
ubyte @nozp @shared staticvar=51
sub start() {
ubyte a,b,c,d = multi4() ; TODO FIX IR CODEGEN
str shouldbestringarray = ["a", "b", "c"]
ubyte x = math.rnd()
ubyte a,b = multi1()
ubyte c,d = multi2()
x=irmen
txt.print_ub(a)
txt.spc()
txt.print_ub(b)
@ -27,19 +21,24 @@ main {
txt.nl()
}
sub single() -> ubyte {
return cx16.r0L+cx16.r1L
}
asmsub multi1() -> ubyte @A, ubyte @Y {
%asm {{
lda #1
ldy #2
rts
}}
}
; sub single() -> ubyte {
; return cx16.r0L+cx16.r1L
; }
; asmsub multi1() -> ubyte @A, ubyte @Y {
; %asm {{
; lda #1
; ldy #2
; rts
; }}
; }
;
; sub multi2() -> ubyte, ubyte {
; cx16.r0++
; return 3,4
; }
sub multi2() -> ubyte, ubyte {
sub multi4() -> ubyte, ubyte, ubyte, ubyte {
cx16.r0++
return 3,4
return 3,4,5,6
}
}

View File

@ -71,7 +71,7 @@ CONTROL FLOW
------------
jump location - continue running at instruction at 'location' (label/memory address)
jumpi reg1 - continue running at memory address in reg1 (indirect jump)
preparecall numparams - indicator that the next instructions are the param setup and function call/syscall with <numparams> parameters
preparecall numparams - indicator that the next instructions are the param setup and function call/syscall with <numparams> parameters, does nothing by itself
calli reg1 - calls a subroutine (without arguments and without return valus) at memory addres in reg1 (indirect jsr)
call label(argument register list) [: resultreg.type]
- calls a subroutine with the given arguments and return value (optional).
@ -109,21 +109,21 @@ bstvs address - branch to location if Status bit Overf
bgt reg1, value, address - jump to location in program given by location, if reg1 > immediate value (unsigned)
blt reg1, value, address - jump to location in program given by location, if reg1 < immediate value (unsigned)
bgtr reg1, reg2, address - jump to location in program given by location, if reg1 > reg2 (unsigned)
'bltr' reg1, reg2, address - jump to location in program given by location, if reg1 < reg2 (unsigned) ==> use bgtr with swapped operands
'bltr' reg1, reg2, address - jump to location in program given by location, if reg1 < reg2 (unsigned) ==> this opcode doesn't exist: use bgtr with swapped operands
bge reg1, value, address - jump to location in program given by location, if reg1 >= immediate value (unsigned)
ble reg1, value, address - jump to location in program given by location, if reg1 <= immediate value (unsigned)
bger reg1, reg2, address - jump to location in program given by location, if reg1 >= reg2 (unsigned)
'bler' reg1, reg2, address - jump to location in program given by location, if reg1 <= reg2 (unsigned) ==> use bger with swapped operands
'bler' reg1, reg2, address - jump to location in program given by location, if reg1 <= reg2 (unsigned) ==> this opcode doesn't exist: use bger with swapped operands
(signed comparison branches:)
bgts reg1, value, address - jump to location in program given by location, if reg1 > immediate value (signed)
blts reg1, value, address - jump to location in program given by location, if reg1 < immediate value (signed)
bgtsr reg1, reg2, address - jump to location in program given by location, if reg1 > reg2 (signed)
'bltsr' reg1, reg2, address - jump to location in program given by location, if reg1 < reg2 (signed) ==> use bgtsr with swapped operands
'bltsr' reg1, reg2, address - jump to location in program given by location, if reg1 < reg2 (signed) ==> this opcode doesn't exist: use bgtsr with swapped operands
bges reg1, value, address - jump to location in program given by location, if reg1 >= immediate value (signed)
bles reg1, value, address - jump to location in program given by location, if reg1 <= immediate value (signed)
bgesr reg1, reg2, address - jump to location in program given by location, if reg1 >= reg2 (signed)
'blesr' reg1, reg2, address - jump to location in program given by location, if reg1 <= reg2 (signed) ==> use bgesr with swapped operands
'blesr' reg1, reg2, address - jump to location in program given by location, if reg1 <= reg2 (signed) ==> this opcode doesn't exist: use bgesr with swapped operands
ARITHMETIC
@ -194,13 +194,13 @@ lsrm address - shift memory right by 1 bits + se
asrm address - shift memory right by 1 bits (signed) + set Carry to shifted bit
lslm address - shift memory left by 1 bits + set Carry to shifted bit
ror reg1 - rotate reg1 right by 1 bits, not using carry + set Carry to shifted bit
roxr reg1 - rotate reg1 right by 1 bits, using carry + set Carry to shifted bit
roxr reg1 - rotate reg1 right by 1 bits, using carry + set Carry to shifted bit (maps to 6502 CPU instruction ror)
rol reg1 - rotate reg1 left by 1 bits, not using carry + set Carry to shifted bit
roxl reg1 - rotate reg1 left by 1 bits, using carry, + set Carry to shifted bit
roxl reg1 - rotate reg1 left by 1 bits, using carry, + set Carry to shifted bit (maps to 6502 CPU instruction rol)
rorm address - rotate memory right by 1 bits, not using carry + set Carry to shifted bit
roxrm address - rotate memory right by 1 bits, using carry + set Carry to shifted bit
roxrm address - rotate memory right by 1 bits, using carry + set Carry to shifted bit (maps to 6502 CPU instruction ror)
rolm address - rotate memory left by 1 bits, not using carry + set Carry to shifted bit
roxlm address - rotate memory left by 1 bits, using carry, + set Carry to shifted bit
roxlm address - rotate memory left by 1 bits, using carry, + set Carry to shifted bit (maps to 6502 CPU instruction rol)
bit address - test bits in byte value at address, this is a special instruction available on other systems to optimize testing and branching on bits 7 and 6
@ -483,7 +483,7 @@ val OpcodesThatSetStatusbitsButNotCarry = arrayOf(
Opcode.OR,
Opcode.XORM,
Opcode.XORR,
Opcode.XOR,
Opcode.XOR
)
val OpcodesThatDependOnCarry = arrayOf(
@ -494,7 +494,7 @@ val OpcodesThatDependOnCarry = arrayOf(
Opcode.ROXL,
Opcode.ROXLM,
Opcode.ROXR,
Opcode.ROXRM,
Opcode.ROXRM
)
val OpcodesThatSetStatusbits = OpcodesThatSetStatusbitsButNotCarry + OpcodesThatSetStatusbitsIncludingCarry