mirror of
https://github.com/irmen/prog8.git
synced 2024-11-29 17:50:35 +00:00
Merge branch 'master' into next_compositetypes
This commit is contained in:
commit
c8b090a98b
@ -27,6 +27,7 @@ class CompilationOptions(val output: OutputType,
|
|||||||
var slabsHighBank: Int? = null,
|
var slabsHighBank: Int? = null,
|
||||||
var slabsGolden: Boolean = false,
|
var slabsGolden: Boolean = false,
|
||||||
var splitWordArrays: Boolean = false,
|
var splitWordArrays: Boolean = false,
|
||||||
|
var addMissingRts: Boolean = false, // deprecated, will likely go way in future version
|
||||||
var breakpointCpuInstruction: String? = null,
|
var breakpointCpuInstruction: String? = null,
|
||||||
var outputDir: Path = Path(""),
|
var outputDir: Path = Path(""),
|
||||||
var symbolDefs: Map<String, String> = emptyMap()
|
var symbolDefs: Map<String, String> = emptyMap()
|
||||||
|
@ -1040,7 +1040,7 @@ $repeatLabel""")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translate(ret: PtReturn, withRts: Boolean=true) {
|
private fun translate(ret: PtReturn) {
|
||||||
ret.value?.let { returnvalue ->
|
ret.value?.let { returnvalue ->
|
||||||
val sub = ret.definingSub()!!
|
val sub = ret.definingSub()!!
|
||||||
val returnReg = sub.returnRegister()!!
|
val returnReg = sub.returnRegister()!!
|
||||||
@ -1055,9 +1055,7 @@ $repeatLabel""")
|
|||||||
assignmentAsmGen.assignExpressionToRegister(addrofValue, returnReg.registerOrPair!!, false)
|
assignmentAsmGen.assignExpressionToRegister(addrofValue, returnReg.registerOrPair!!, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
out(" rts")
|
||||||
if(withRts)
|
|
||||||
out(" rts")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translate(asm: PtInlineAssembly) {
|
private fun translate(asm: PtInlineAssembly) {
|
||||||
|
@ -248,6 +248,7 @@ save_SCRATCH_ZPB1 .byte 0
|
|||||||
save_SCRATCH_ZPREG .byte 0
|
save_SCRATCH_ZPREG .byte 0
|
||||||
save_SCRATCH_ZPWORD1 .word 0
|
save_SCRATCH_ZPWORD1 .word 0
|
||||||
save_SCRATCH_ZPWORD2 .word 0
|
save_SCRATCH_ZPWORD2 .word 0
|
||||||
|
; !notreached!
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -461,6 +462,7 @@ cx16 {
|
|||||||
_cx16_vreg_storage
|
_cx16_vreg_storage
|
||||||
.word 0,0,0,0,0,0,0,0
|
.word 0,0,0,0,0,0,0,0
|
||||||
.word 0,0,0,0,0,0,0,0
|
.word 0,0,0,0,0,0,0,0
|
||||||
|
; !notreached!
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -453,6 +453,7 @@ save_SCRATCH_ZPB1 .byte 0
|
|||||||
save_SCRATCH_ZPREG .byte 0
|
save_SCRATCH_ZPREG .byte 0
|
||||||
save_SCRATCH_ZPWORD1 .word 0
|
save_SCRATCH_ZPWORD1 .word 0
|
||||||
save_SCRATCH_ZPWORD2 .word 0
|
save_SCRATCH_ZPWORD2 .word 0
|
||||||
|
; !notreached!
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -504,8 +505,6 @@ _modified
|
|||||||
tax
|
tax
|
||||||
pla
|
pla
|
||||||
rti
|
rti
|
||||||
|
|
||||||
_use_kernal .byte 0
|
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -978,6 +977,7 @@ cx16 {
|
|||||||
_cx16_vreg_storage
|
_cx16_vreg_storage
|
||||||
.word 0,0,0,0,0,0,0,0
|
.word 0,0,0,0,0,0,0,0
|
||||||
.word 0,0,0,0,0,0,0,0
|
.word 0,0,0,0,0,0,0,0
|
||||||
|
; !notreached!
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,6 +314,7 @@ _mod sta $ffff ; modified
|
|||||||
rts
|
rts
|
||||||
|
|
||||||
_screenrows .word cbm.Screen + range(0, 1000, 40)
|
_screenrows .word cbm.Screen + range(0, 1000, 40)
|
||||||
|
; !notreached!
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -357,6 +358,7 @@ _mod sta $ffff ; modified
|
|||||||
rts
|
rts
|
||||||
|
|
||||||
_colorrows .word $d800 + range(0, 1000, 40)
|
_colorrows .word $d800 + range(0, 1000, 40)
|
||||||
|
; !notreached!
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -386,6 +386,7 @@ _plot_y_values := p8c_BITMAP_ADDRESS + 320*(range(200)>>3) + (range(200) & 7)
|
|||||||
|
|
||||||
_y_lookup_lo .byte <_plot_y_values
|
_y_lookup_lo .byte <_plot_y_values
|
||||||
_y_lookup_hi .byte >_plot_y_values
|
_y_lookup_hi .byte >_plot_y_values
|
||||||
|
; !notreached!
|
||||||
|
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
@ -451,6 +451,7 @@ save_SCRATCH_ZPB1 .byte 0
|
|||||||
save_SCRATCH_ZPREG .byte 0
|
save_SCRATCH_ZPREG .byte 0
|
||||||
save_SCRATCH_ZPWORD1 .word 0
|
save_SCRATCH_ZPWORD1 .word 0
|
||||||
save_SCRATCH_ZPWORD2 .word 0
|
save_SCRATCH_ZPWORD2 .word 0
|
||||||
|
; !notreached!
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -975,6 +976,7 @@ cx16 {
|
|||||||
_cx16_vreg_storage
|
_cx16_vreg_storage
|
||||||
.word 0,0,0,0,0,0,0,0
|
.word 0,0,0,0,0,0,0,0
|
||||||
.word 0,0,0,0,0,0,0,0
|
.word 0,0,0,0,0,0,0,0
|
||||||
|
; !notreached!
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -317,6 +317,7 @@ _mod sta $ffff ; modified
|
|||||||
rts
|
rts
|
||||||
|
|
||||||
_screenrows .word cbm.Screen + range(0, 1000, 40)
|
_screenrows .word cbm.Screen + range(0, 1000, 40)
|
||||||
|
; !notreached!
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -360,6 +361,7 @@ _mod sta $ffff ; modified
|
|||||||
rts
|
rts
|
||||||
|
|
||||||
_colorrows .word $d800 + range(0, 1000, 40)
|
_colorrows .word $d800 + range(0, 1000, 40)
|
||||||
|
; !notreached!
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,6 +200,7 @@ _allzero lda #'0'
|
|||||||
sta string_out,x
|
sta string_out,x
|
||||||
inx
|
inx
|
||||||
bne _end
|
bne _end
|
||||||
|
; !notreached!
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -402,6 +403,7 @@ _digit
|
|||||||
bne _parse
|
bne _parse
|
||||||
; never reached
|
; never reached
|
||||||
_negative .byte 0
|
_negative .byte 0
|
||||||
|
; !notreached!
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -472,6 +474,7 @@ _try_iso
|
|||||||
bcs _stop
|
bcs _stop
|
||||||
and #63
|
and #63
|
||||||
bne _add_letter
|
bne _add_letter
|
||||||
|
; !notreached!
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -702,7 +705,7 @@ decHundreds .byte 0
|
|||||||
decTens .byte 0
|
decTens .byte 0
|
||||||
decOnes .byte 0
|
decOnes .byte 0
|
||||||
.byte 0 ; zero-terminate the decimal output string
|
.byte 0 ; zero-terminate the decimal output string
|
||||||
|
; !notreached!
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -736,6 +739,7 @@ asmsub internal_ubyte2hex (ubyte value @A) clobbers(X) -> ubyte @A, ubyte @Y
|
|||||||
rts
|
rts
|
||||||
|
|
||||||
_hex_digits .text "0123456789abcdef" ; can probably be reused for other stuff as well
|
_hex_digits .text "0123456789abcdef" ; can probably be reused for other stuff as well
|
||||||
|
; !notreached!
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -753,6 +757,7 @@ asmsub internal_uword2hex (uword value @AY) clobbers(A,Y) {
|
|||||||
sty output+3
|
sty output+3
|
||||||
rts
|
rts
|
||||||
output .text "0000", $00 ; 0-terminated output buffer (to make printing easier)
|
output .text "0000", $00 ; 0-terminated output buffer (to make printing easier)
|
||||||
|
; !notreached!
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,6 +186,7 @@ _borked
|
|||||||
+ jmp sys.exit
|
+ jmp sys.exit
|
||||||
|
|
||||||
_msg .text 13,"?rom 47+ required for val1",13,0
|
_msg .text 13,"?rom 47+ required for val1",13,0
|
||||||
|
; !notreached!
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -838,6 +838,7 @@ _large ora cx16.r2L
|
|||||||
+ lda #0
|
+ lda #0
|
||||||
rts
|
rts
|
||||||
_strides_lsb .byte 0,1,2,4,8,16,32,64,128,255,255,40,80,160,255,255
|
_strides_lsb .byte 0,1,2,4,8,16,32,64,128,255,255,40,80,160,255,255
|
||||||
|
; !notreached!
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -955,6 +956,7 @@ asmsub save_virtual_registers() clobbers(A,Y) {
|
|||||||
_cx16_vreg_storage
|
_cx16_vreg_storage
|
||||||
.word 0,0,0,0,0,0,0,0
|
.word 0,0,0,0,0,0,0,0
|
||||||
.word 0,0,0,0,0,0,0,0
|
.word 0,0,0,0,0,0,0,0
|
||||||
|
; !notreached!
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -993,6 +995,7 @@ asmsub save_vera_context() clobbers(A) {
|
|||||||
sta _vera_storage+6
|
sta _vera_storage+6
|
||||||
rts
|
rts
|
||||||
_vera_storage: .byte 0,0,0,0,0,0,0,0
|
_vera_storage: .byte 0,0,0,0,0,0,0,0
|
||||||
|
; !notreached!
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1315,6 +1318,7 @@ _continue iny
|
|||||||
bne _continue
|
bne _continue
|
||||||
+ pla
|
+ pla
|
||||||
sta $00
|
sta $00
|
||||||
|
rts
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1499,7 +1503,8 @@ asmsub restore_irq() clobbers(A) {
|
|||||||
cli
|
cli
|
||||||
rts
|
rts
|
||||||
_orig_irqvec .word 0
|
_orig_irqvec .word 0
|
||||||
}}
|
; !notreached!
|
||||||
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
asmsub set_rasterirq(uword handler @AY, uword rasterpos @R0) clobbers(A) {
|
asmsub set_rasterirq(uword handler @AY, uword rasterpos @R0) clobbers(A) {
|
||||||
@ -1775,6 +1780,7 @@ save_SCRATCH_ZPB1 .byte 0
|
|||||||
save_SCRATCH_ZPREG .byte 0
|
save_SCRATCH_ZPREG .byte 0
|
||||||
save_SCRATCH_ZPWORD1 .word 0
|
save_SCRATCH_ZPWORD1 .word 0
|
||||||
save_SCRATCH_ZPWORD2 .word 0
|
save_SCRATCH_ZPWORD2 .word 0
|
||||||
|
; !notreached!
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ math {
|
|||||||
lda _sinecos8u,y
|
lda _sinecos8u,y
|
||||||
rts
|
rts
|
||||||
_sinecos8u .byte trunc(128.0 + 127.5 * sin(range(256+64) * rad(360.0/256.0)))
|
_sinecos8u .byte trunc(128.0 + 127.5 * sin(range(256+64) * rad(360.0/256.0)))
|
||||||
|
; !notreached!
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,6 +31,7 @@ _sinecos8u .byte trunc(128.0 + 127.5 * sin(range(256+64) * rad(360.0/256.0)))
|
|||||||
lda _sinecos8,y
|
lda _sinecos8,y
|
||||||
rts
|
rts
|
||||||
_sinecos8 .char trunc(127.0 * sin(range(256+64) * rad(360.0/256.0)))
|
_sinecos8 .char trunc(127.0 * sin(range(256+64) * rad(360.0/256.0)))
|
||||||
|
; !notreached!
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,6 +49,7 @@ _sinecos8 .char trunc(127.0 * sin(range(256+64) * rad(360.0/256.0)))
|
|||||||
lda _sinecosR8u,y
|
lda _sinecosR8u,y
|
||||||
rts
|
rts
|
||||||
_sinecosR8u .byte trunc(128.0 + 127.5 * sin(range(180+45) * rad(360.0/180.0)))
|
_sinecosR8u .byte trunc(128.0 + 127.5 * sin(range(180+45) * rad(360.0/180.0)))
|
||||||
|
; !notreached!
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,6 +67,7 @@ _sinecosR8u .byte trunc(128.0 + 127.5 * sin(range(180+45) * rad(360.0/180.0)))
|
|||||||
lda _sinecosR8,y
|
lda _sinecosR8,y
|
||||||
rts
|
rts
|
||||||
_sinecosR8 .char trunc(127.0 * sin(range(180+45) * rad(360.0/180.0)))
|
_sinecosR8 .char trunc(127.0 * sin(range(180+45) * rad(360.0/180.0)))
|
||||||
|
; !notreached!
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,6 +135,7 @@ _sinecosR8 .char trunc(127.0 * sin(range(180+45) * rad(360.0/180.0)))
|
|||||||
rts
|
rts
|
||||||
+ lsr a
|
+ lsr a
|
||||||
bne -
|
bne -
|
||||||
|
; !notreached!
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -331,7 +336,7 @@ _quadrant_region_to_direction:
|
|||||||
.byte 8, 4,16,20
|
.byte 8, 4,16,20
|
||||||
.byte 7, 5,17,19
|
.byte 7, 5,17,19
|
||||||
.byte 6, 6,18,18
|
.byte 6, 6,18,18
|
||||||
|
; !notreached!
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -464,7 +469,7 @@ log2_tab
|
|||||||
.byte $fb,$fb,$fb,$fc,$fc,$fc,$fc,$fc
|
.byte $fb,$fb,$fb,$fc,$fc,$fc,$fc,$fc
|
||||||
.byte $fd,$fd,$fd,$fd,$fd,$fd,$fe,$fe
|
.byte $fd,$fd,$fd,$fd,$fd,$fd,$fe,$fe
|
||||||
.byte $fe,$fe,$fe,$ff,$ff,$ff,$ff,$ff
|
.byte $fe,$fe,$fe,$ff,$ff,$ff,$ff,$ff
|
||||||
|
; !notreached!
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -350,6 +350,7 @@ save_SCRATCH_ZPB1 .byte 0
|
|||||||
save_SCRATCH_ZPREG .byte 0
|
save_SCRATCH_ZPREG .byte 0
|
||||||
save_SCRATCH_ZPWORD1 .word 0
|
save_SCRATCH_ZPWORD1 .word 0
|
||||||
save_SCRATCH_ZPWORD2 .word 0
|
save_SCRATCH_ZPWORD2 .word 0
|
||||||
|
; !notreached!
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -564,6 +565,7 @@ cx16 {
|
|||||||
_cx16_vreg_storage
|
_cx16_vreg_storage
|
||||||
.word 0,0,0,0,0,0,0,0
|
.word 0,0,0,0,0,0,0,0
|
||||||
.word 0,0,0,0,0,0,0,0
|
.word 0,0,0,0,0,0,0,0
|
||||||
|
; !notreached!
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,6 +171,7 @@ _mod sta $ffff ; modified
|
|||||||
rts
|
rts
|
||||||
|
|
||||||
_screenrows .word cbm.Screen + range(0, 1000, 40)
|
_screenrows .word cbm.Screen + range(0, 1000, 40)
|
||||||
|
; !notreached!
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,6 +171,7 @@ _allzero lda #'0'
|
|||||||
eor P8ZP_SCRATCH_REG
|
eor P8ZP_SCRATCH_REG
|
||||||
rts
|
rts
|
||||||
_offsets .byte 128, 0, 64, 32, 64, 192, 128, 128
|
_offsets .byte 128, 0, 64, 32, 64, 192, 128, 128
|
||||||
|
; !notreached!
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,7 +178,7 @@ _found tya
|
|||||||
rts
|
rts
|
||||||
|
|
||||||
_str .word 0
|
_str .word 0
|
||||||
|
; !notreached!
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,6 +56,7 @@ private fun compileMain(args: Array<String>): Boolean {
|
|||||||
val outputDir by cli.option(ArgType.String, fullName = "out", description = "directory for output files instead of current directory").default(".")
|
val outputDir by cli.option(ArgType.String, fullName = "out", description = "directory for output files instead of current directory").default(".")
|
||||||
val quietAssembler by cli.option(ArgType.Boolean, fullName = "quietasm", description = "don't print assembler output results")
|
val quietAssembler by cli.option(ArgType.Boolean, fullName = "quietasm", description = "don't print assembler output results")
|
||||||
val warnSymbolShadowing by cli.option(ArgType.Boolean, fullName = "warnshadow", description="show assembler warnings about symbol shadowing")
|
val warnSymbolShadowing by cli.option(ArgType.Boolean, fullName = "warnshadow", description="show assembler warnings about symbol shadowing")
|
||||||
|
val addMissingRts by cli.option(ArgType.Boolean, fullName = "addmissingrts", description="enable old behavior that silently adds RTS to asmsubs that don't have one (deprecated, may go away in future version)")
|
||||||
val sourceDirs by cli.option(ArgType.String, fullName="srcdirs", description = "list of extra paths, separated with ${File.pathSeparator}, to search in for imported modules").multiple().delimiter(File.pathSeparator)
|
val sourceDirs by cli.option(ArgType.String, fullName="srcdirs", description = "list of extra paths, separated with ${File.pathSeparator}, to search in for imported modules").multiple().delimiter(File.pathSeparator)
|
||||||
val includeSourcelines by cli.option(ArgType.Boolean, fullName = "sourcelines", description = "include original Prog8 source lines in generated asm code")
|
val includeSourcelines by cli.option(ArgType.Boolean, fullName = "sourcelines", description = "include original Prog8 source lines in generated asm code")
|
||||||
val splitWordArrays by cli.option(ArgType.Boolean, fullName = "splitarrays", description = "treat all word arrays as tagged with @split to make them lsb/msb split in memory")
|
val splitWordArrays by cli.option(ArgType.Boolean, fullName = "splitarrays", description = "treat all word arrays as tagged with @split to make them lsb/msb split in memory")
|
||||||
@ -181,6 +182,7 @@ private fun compileMain(args: Array<String>): Boolean {
|
|||||||
slabsGolden == true,
|
slabsGolden == true,
|
||||||
compilationTarget!!,
|
compilationTarget!!,
|
||||||
splitWordArrays == true,
|
splitWordArrays == true,
|
||||||
|
addMissingRts == true,
|
||||||
breakpointCpuInstruction,
|
breakpointCpuInstruction,
|
||||||
printAst1 == true,
|
printAst1 == true,
|
||||||
printAst2 == true,
|
printAst2 == true,
|
||||||
@ -261,6 +263,7 @@ private fun compileMain(args: Array<String>): Boolean {
|
|||||||
slabsGolden == true,
|
slabsGolden == true,
|
||||||
compilationTarget!!,
|
compilationTarget!!,
|
||||||
splitWordArrays == true,
|
splitWordArrays == true,
|
||||||
|
addMissingRts == true,
|
||||||
breakpointCpuInstruction,
|
breakpointCpuInstruction,
|
||||||
printAst1 == true,
|
printAst1 == true,
|
||||||
printAst2 == true,
|
printAst2 == true,
|
||||||
|
@ -52,6 +52,7 @@ class CompilerArguments(val filepath: Path,
|
|||||||
val slabsGolden: Boolean,
|
val slabsGolden: Boolean,
|
||||||
val compilationTarget: String,
|
val compilationTarget: String,
|
||||||
val splitWordArrays: Boolean,
|
val splitWordArrays: Boolean,
|
||||||
|
val addMissingRts: Boolean,
|
||||||
val breakpointCpuInstruction: String?,
|
val breakpointCpuInstruction: String?,
|
||||||
val printAst1: Boolean,
|
val printAst1: Boolean,
|
||||||
val printAst2: Boolean,
|
val printAst2: Boolean,
|
||||||
@ -89,6 +90,7 @@ fun compileProgram(args: CompilerArguments): CompilationResult? {
|
|||||||
slabsHighBank = args.slabsHighBank
|
slabsHighBank = args.slabsHighBank
|
||||||
slabsGolden = args.slabsGolden
|
slabsGolden = args.slabsGolden
|
||||||
splitWordArrays = args.splitWordArrays
|
splitWordArrays = args.splitWordArrays
|
||||||
|
addMissingRts = args.addMissingRts
|
||||||
outputDir = args.outputDir.normalize()
|
outputDir = args.outputDir.normalize()
|
||||||
symbolDefs = args.symbolDefs
|
symbolDefs = args.symbolDefs
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ internal fun Program.checkValid(errors: IErrorReporter, compilerOptions: Compila
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal fun Program.processAstBeforeAsmGeneration(compilerOptions: CompilationOptions, errors: IErrorReporter) {
|
internal fun Program.processAstBeforeAsmGeneration(compilerOptions: CompilationOptions, errors: IErrorReporter) {
|
||||||
val fixer = BeforeAsmAstChanger(this, compilerOptions)
|
val fixer = BeforeAsmAstChanger(this, compilerOptions, errors)
|
||||||
fixer.visit(this)
|
fixer.visit(this)
|
||||||
while (errors.noErrors() && fixer.applyModifications() > 0) {
|
while (errors.noErrors() && fixer.applyModifications() > 0) {
|
||||||
fixer.visit(this)
|
fixer.visit(this)
|
||||||
@ -155,11 +155,29 @@ internal fun IdentifierReference.isSubroutineParameter(program: Program): Boolea
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun Subroutine.hasRtsInAsm(): Boolean {
|
internal fun Subroutine.hasRtsInAsm(checkOnlyLastInstruction: Boolean): Boolean {
|
||||||
return statements
|
val asms = statements
|
||||||
.asSequence()
|
.asSequence()
|
||||||
.filterIsInstance<InlineAssembly>()
|
.filterIsInstance<InlineAssembly>()
|
||||||
.any { it.hasReturnOrRts() }
|
if(checkOnlyLastInstruction) {
|
||||||
|
val lastAsm = asms.lastOrNull() ?: return false
|
||||||
|
val lastLine = lastAsm.assembly.lineSequence().map { it.trim() }.last {
|
||||||
|
it.isNotBlank() && (!it.startsWith(';') || it.contains("!notreached!"))
|
||||||
|
}
|
||||||
|
if(lastLine.contains("!notreached!"))
|
||||||
|
return true
|
||||||
|
val inlineAsm = InlineAssembly(" $lastLine", lastAsm.isIR, lastAsm.position)
|
||||||
|
return inlineAsm.hasReturnOrRts()
|
||||||
|
} else {
|
||||||
|
val allAsms = asms.toList()
|
||||||
|
val lastAsm = allAsms.lastOrNull() ?: return false
|
||||||
|
val lastLine = lastAsm.assembly.lineSequence().map { it.trim() }.last {
|
||||||
|
it.isNotBlank() && (!it.startsWith(';') || it.contains("!notreached!"))
|
||||||
|
}
|
||||||
|
if(lastLine.contains("!notreached!"))
|
||||||
|
return true
|
||||||
|
return allAsms.any { it.hasReturnOrRts() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun IdentifierReference.checkFunctionOrLabelExists(program: Program, statement: Statement, errors: IErrorReporter): Statement? {
|
internal fun IdentifierReference.checkFunctionOrLabelExists(program: Program, statement: Statement, errors: IErrorReporter): Statement? {
|
||||||
|
@ -11,7 +11,7 @@ import prog8.ast.walk.IAstModification
|
|||||||
import prog8.code.core.*
|
import prog8.code.core.*
|
||||||
import prog8.code.target.VMTarget
|
import prog8.code.target.VMTarget
|
||||||
|
|
||||||
internal class BeforeAsmAstChanger(val program: Program, private val options: CompilationOptions) : AstWalker() {
|
internal class BeforeAsmAstChanger(val program: Program, private val options: CompilationOptions, private val errors: IErrorReporter) : AstWalker() {
|
||||||
|
|
||||||
override fun before(breakStmt: Break, parent: Node): Iterable<IAstModification> {
|
override fun before(breakStmt: Break, parent: Node): Iterable<IAstModification> {
|
||||||
throw InternalCompilerException("break should have been replaced by goto $breakStmt")
|
throw InternalCompilerException("break should have been replaced by goto $breakStmt")
|
||||||
@ -81,13 +81,22 @@ internal class BeforeAsmAstChanger(val program: Program, private val options: Co
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!subroutine.inline) {
|
if (!subroutine.inline) {
|
||||||
if (subroutine.isAsmSubroutine && subroutine.asmAddress==null && !subroutine.hasRtsInAsm()) {
|
if (subroutine.isAsmSubroutine && subroutine.asmAddress==null) {
|
||||||
// make sure the NOT INLINED asm subroutine actually has a rts at the end
|
if(!options.addMissingRts && !subroutine.hasRtsInAsm(true)) {
|
||||||
// (non-asm routines get a Return statement as needed, above)
|
errors.err("asmsub seems to never return as it doesn't end with RTS/JMP/branch. If this is intended, add a '; !notreached!' comment at the end, or use -addmissingrts", subroutine.position)
|
||||||
mods += if(options.compTarget.name==VMTarget.NAME)
|
}
|
||||||
IAstModification.InsertLast(InlineAssembly(" return\n", true, Position.DUMMY), subroutine)
|
else if (!subroutine.hasRtsInAsm(false)) {
|
||||||
else
|
// make sure the NOT INLINED asm subroutine actually has a rts at the end
|
||||||
IAstModification.InsertLast(InlineAssembly(" rts\n", false, Position.DUMMY), subroutine)
|
// (non-asm routines get a Return statement as needed, above)
|
||||||
|
if(options.addMissingRts) {
|
||||||
|
errors.info("added missing RTS to asmsub", subroutine.position)
|
||||||
|
mods += if(options.compTarget.name==VMTarget.NAME)
|
||||||
|
IAstModification.InsertLast(InlineAssembly(" return\n", true, Position.DUMMY), subroutine)
|
||||||
|
else
|
||||||
|
IAstModification.InsertLast(InlineAssembly(" rts\n", false, Position.DUMMY), subroutine)
|
||||||
|
} else
|
||||||
|
errors.err("asmsub seems to never return as it doesn't end with RTS/JMP/branch. If this is intended, add a '; !notreached!' comment at the end, or use -addmissingrts", subroutine.position)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,6 +40,7 @@ private fun compileTheThing(filepath: Path, optimize: Boolean, target: ICompilat
|
|||||||
slabsGolden = false,
|
slabsGolden = false,
|
||||||
compilationTarget = target.name,
|
compilationTarget = target.name,
|
||||||
splitWordArrays = false,
|
splitWordArrays = false,
|
||||||
|
addMissingRts = false,
|
||||||
breakpointCpuInstruction = null,
|
breakpointCpuInstruction = null,
|
||||||
printAst1 = false,
|
printAst1 = false,
|
||||||
printAst2 = false,
|
printAst2 = false,
|
||||||
|
@ -38,6 +38,7 @@ class TestCompilerOptionSourcedirs: FunSpec({
|
|||||||
slabsGolden = false,
|
slabsGolden = false,
|
||||||
compilationTarget = Cx16Target.NAME,
|
compilationTarget = Cx16Target.NAME,
|
||||||
splitWordArrays = false,
|
splitWordArrays = false,
|
||||||
|
addMissingRts = false,
|
||||||
breakpointCpuInstruction = null,
|
breakpointCpuInstruction = null,
|
||||||
printAst1 = false,
|
printAst1 = false,
|
||||||
printAst2 = false,
|
printAst2 = false,
|
||||||
|
@ -57,6 +57,7 @@ main {
|
|||||||
asmsub baz() {
|
asmsub baz() {
|
||||||
%asm{{
|
%asm{{
|
||||||
jsr p8s_foo
|
jsr p8s_foo
|
||||||
|
jmp blah
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
asmsub bar() {
|
asmsub bar() {
|
||||||
|
@ -105,6 +105,9 @@ class TestSubroutines: FunSpec({
|
|||||||
}
|
}
|
||||||
|
|
||||||
asmsub asmfunc(str thing @AY) {
|
asmsub asmfunc(str thing @AY) {
|
||||||
|
%asm {{
|
||||||
|
rts
|
||||||
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub func(str thing) {
|
sub func(str thing) {
|
||||||
@ -125,7 +128,7 @@ class TestSubroutines: FunSpec({
|
|||||||
asmfunc.isAsmSubroutine shouldBe true
|
asmfunc.isAsmSubroutine shouldBe true
|
||||||
asmfunc.statements.single() shouldBe instanceOf<InlineAssembly>()
|
asmfunc.statements.single() shouldBe instanceOf<InlineAssembly>()
|
||||||
(asmfunc.statements.single() as InlineAssembly).assembly.trim() shouldBe "rts"
|
(asmfunc.statements.single() as InlineAssembly).assembly.trim() shouldBe "rts"
|
||||||
asmfunc.hasRtsInAsm() shouldBe true
|
asmfunc.hasRtsInAsm(false) shouldBe true
|
||||||
func.isAsmSubroutine shouldBe false
|
func.isAsmSubroutine shouldBe false
|
||||||
withClue("str param should have been changed to uword") {
|
withClue("str param should have been changed to uword") {
|
||||||
asmfunc.parameters.single().type shouldBe DataType.forDt(BaseDataType.UWORD)
|
asmfunc.parameters.single().type shouldBe DataType.forDt(BaseDataType.UWORD)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package prog8tests.codegeneration
|
package prog8tests.codegeneration
|
||||||
|
|
||||||
import io.kotest.core.spec.style.FunSpec
|
import io.kotest.core.spec.style.FunSpec
|
||||||
|
import io.kotest.matchers.collections.shouldContain
|
||||||
import io.kotest.matchers.ints.shouldBeGreaterThan
|
import io.kotest.matchers.ints.shouldBeGreaterThan
|
||||||
import io.kotest.matchers.shouldBe
|
import io.kotest.matchers.shouldBe
|
||||||
import io.kotest.matchers.shouldNotBe
|
import io.kotest.matchers.shouldNotBe
|
||||||
@ -467,4 +468,52 @@ main {
|
|||||||
}"""
|
}"""
|
||||||
compileText(Cx16Target(), false, src, writeAssembly = true) shouldNotBe null
|
compileText(Cx16Target(), false, src, writeAssembly = true) shouldNotBe null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test("missing rts in asmsub") {
|
||||||
|
val src="""
|
||||||
|
main {
|
||||||
|
sub start() {
|
||||||
|
test()
|
||||||
|
test2()
|
||||||
|
}
|
||||||
|
|
||||||
|
asmsub test() {
|
||||||
|
%asm {{
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline asmsub test2() {
|
||||||
|
%asm {{
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
}"""
|
||||||
|
|
||||||
|
val errors = ErrorReporterForTests()
|
||||||
|
compileText(C64Target(), false, src, writeAssembly = true, errors = errors) shouldBe null
|
||||||
|
errors.errors.size shouldBe 1
|
||||||
|
errors.errors[0] shouldContain "asmsub seems to never return"
|
||||||
|
}
|
||||||
|
|
||||||
|
test("missing rts in asmsub suppressed") {
|
||||||
|
val src="""
|
||||||
|
main {
|
||||||
|
sub start() {
|
||||||
|
test()
|
||||||
|
}
|
||||||
|
|
||||||
|
asmsub test() {
|
||||||
|
%asm {{
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
; !notreached!
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
}"""
|
||||||
|
|
||||||
|
compileText(C64Target(), false, src, writeAssembly = true) shouldNotBe null
|
||||||
|
}
|
||||||
})
|
})
|
@ -40,6 +40,7 @@ internal fun compileFile(
|
|||||||
outputDir = outputDir,
|
outputDir = outputDir,
|
||||||
errors = errors ?: ErrorReporterForTests(),
|
errors = errors ?: ErrorReporterForTests(),
|
||||||
splitWordArrays = false,
|
splitWordArrays = false,
|
||||||
|
addMissingRts = false,
|
||||||
breakpointCpuInstruction = null,
|
breakpointCpuInstruction = null,
|
||||||
printAst1 = false,
|
printAst1 = false,
|
||||||
printAst2 = false,
|
printAst2 = false,
|
||||||
|
@ -182,6 +182,12 @@ One or more .p8 module files
|
|||||||
interpret certain instructions differently and produce unexpected opcodes (like LDA X getting
|
interpret certain instructions differently and produce unexpected opcodes (like LDA X getting
|
||||||
turned into TXA, or not, depending on the symbol 'x' being defined in your own assembly code or not)
|
turned into TXA, or not, depending on the symbol 'x' being defined in your own assembly code or not)
|
||||||
|
|
||||||
|
``-addmissingrts``
|
||||||
|
Enables old compiler behavior that silently adds RTS to asmsubs that don't have one.
|
||||||
|
This was done to fix asmsubs so they return properly to the caller instead of crashing the program.
|
||||||
|
However the new compiler behavior is to not silently modify the code anymore and instead give an error message
|
||||||
|
that tells you how to fix the problem. This option may go away in future version.
|
||||||
|
|
||||||
``-quietasm``
|
``-quietasm``
|
||||||
Don't print assembler output results.
|
Don't print assembler output results.
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
TODO
|
TODO
|
||||||
====
|
====
|
||||||
|
|
||||||
|
- check benchmark score vs previous version
|
||||||
|
|
||||||
Improve register load order in subroutine call args assignments:
|
Improve register load order in subroutine call args assignments:
|
||||||
in certain situations, the "wrong" order of evaluation of function call arguments is done which results
|
in certain situations, the "wrong" order of evaluation of function call arguments is done which results
|
||||||
in overwriting registers that already got their value, which requires a lot of stack juggling (especially on plain 6502 cpu!)
|
in overwriting registers that already got their value, which requires a lot of stack juggling (especially on plain 6502 cpu!)
|
||||||
@ -11,7 +13,6 @@ Future Things and Ideas
|
|||||||
^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
- 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
|
- 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
|
||||||
- Can we support signed % (remainder) somehow?
|
- Can we support signed % (remainder) somehow?
|
||||||
- Don't add "random" rts to %asm blocks but instead give a warning about it? (but this breaks existing behavior that others already depend on... command line switch? block directive?)
|
|
||||||
- IR: implement missing operators in AssignmentGen (array shifts etc)
|
- IR: implement missing operators in AssignmentGen (array shifts etc)
|
||||||
- instead of copy-pasting inline asmsubs, make them into a 64tass macro and use that instead.
|
- instead of copy-pasting inline asmsubs, make them into a 64tass macro and use that instead.
|
||||||
that will allow them to be reused from custom user written assembly code as well.
|
that will allow them to be reused from custom user written assembly code as well.
|
||||||
|
@ -71,7 +71,7 @@ interrupts {
|
|||||||
; no other irqs in this example.
|
; no other irqs in this example.
|
||||||
}
|
}
|
||||||
|
|
||||||
asmsub wait() {
|
inline asmsub wait() {
|
||||||
%asm {{
|
%asm {{
|
||||||
wai
|
wai
|
||||||
}}
|
}}
|
||||||
|
@ -161,7 +161,7 @@ interrupts {
|
|||||||
|
|
||||||
bool aflow
|
bool aflow
|
||||||
|
|
||||||
asmsub wait() {
|
inline asmsub wait() {
|
||||||
%asm {{
|
%asm {{
|
||||||
wai
|
wai
|
||||||
}}
|
}}
|
||||||
@ -285,6 +285,7 @@ _lp2 lda $ffff,y
|
|||||||
inc _lp2+2
|
inc _lp2+2
|
||||||
dex
|
dex
|
||||||
bne _loop
|
bne _loop
|
||||||
|
; !notreached!
|
||||||
}}
|
}}
|
||||||
; original prog8 code:
|
; original prog8 code:
|
||||||
; uword @requirezp ptr = main.start.buffer
|
; uword @requirezp ptr = main.start.buffer
|
||||||
|
@ -327,7 +327,7 @@ interrupts {
|
|||||||
bool aflow
|
bool aflow
|
||||||
bool vsync
|
bool vsync
|
||||||
|
|
||||||
asmsub wait() {
|
inline asmsub wait() {
|
||||||
%asm {{
|
%asm {{
|
||||||
wai
|
wai
|
||||||
}}
|
}}
|
||||||
|
@ -4,46 +4,21 @@
|
|||||||
|
|
||||||
main {
|
main {
|
||||||
sub start() {
|
sub start() {
|
||||||
str @alignword @shared name1 = "abc123456789"
|
derp()
|
||||||
str @alignpage @shared name2 = "def123456789"
|
derp2()
|
||||||
str @alignword @shared @nozp name3 = "ghi123456789"
|
}
|
||||||
str @alignword @shared @nozp name4 = "jkl123456789"
|
|
||||||
ubyte[9] @alignword @shared array1
|
|
||||||
ubyte[9] @alignword @shared array2
|
|
||||||
ubyte[9] @alignpage @shared array3
|
|
||||||
ubyte[9] @alignword @shared array4
|
|
||||||
ubyte[9] @alignword @shared array5
|
|
||||||
ubyte[9] @alignword @shared array6
|
|
||||||
ubyte[9] @alignword @shared array7
|
|
||||||
ubyte[9] @alignword @shared array8
|
|
||||||
ubyte[] @alignword @shared array9 = [1,2,3]
|
|
||||||
ubyte[] @alignword @shared array10 = [1,2,3]
|
|
||||||
ubyte[] @alignpage @shared array11 = [1,2,3]
|
|
||||||
ubyte[] @alignpage @shared array12 = [1,2,3]
|
|
||||||
ubyte[] @alignword @shared array13 = [1,2,3]
|
|
||||||
ubyte[] @alignword @shared array14 = [1,2,3]
|
|
||||||
ubyte[] @alignpage @shared array15 = [1,2,3]
|
|
||||||
ubyte[] @alignpage @shared array16 = [1,2,3]
|
|
||||||
uword[3] @alignword @split @shared array17
|
|
||||||
uword[] @alignword @split @shared array18 = [1111,2222,3333]
|
|
||||||
|
|
||||||
array9[2]++
|
asmsub derp() {
|
||||||
array10[2]++
|
%asm {{
|
||||||
array11[2]++
|
nop
|
||||||
array12[2]++
|
nop
|
||||||
array13[2]++
|
}}
|
||||||
array14[2]++
|
}
|
||||||
array15[2]++
|
|
||||||
array16[2]++
|
|
||||||
array17[2]++
|
|
||||||
array18[2]++
|
|
||||||
name1[2]++
|
|
||||||
name2[2]++
|
|
||||||
name3[2]++
|
|
||||||
name4[2]++
|
|
||||||
|
|
||||||
%align 2
|
inline asmsub derp2() {
|
||||||
%align 3
|
%asm {{
|
||||||
%align 1000
|
nop
|
||||||
|
nop
|
||||||
|
}}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user