mirror of
https://github.com/irmen/prog8.git
synced 2025-02-10 14:32:20 +00:00
fix IR codegen for the RETURN 4,5,6,7
added cx16.EXTAPI_memory_decompress_from_func for cx16
This commit is contained in:
parent
277a1a32b2
commit
0191acb2b3
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}}
|
||||
}
|
||||
|
@ -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
|
||||
}}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user