mirror of
https://github.com/irmen/prog8.git
synced 2025-02-25 04:29:36 +00:00
various regression fixes
This commit is contained in:
parent
ee906ba82c
commit
5f2bf2b375
@ -259,7 +259,7 @@ _numlen
|
||||
- lda (c64.SCRATCH_ZPWORD1),y
|
||||
cmp #'0'
|
||||
bmi +
|
||||
cmp #'9'
|
||||
cmp #':' ; one after '9'
|
||||
bpl +
|
||||
iny
|
||||
bne -
|
||||
|
@ -14,6 +14,12 @@ class StatementReorderer(private val namespace: INameScope, private val heap: He
|
||||
// - the 'start' subroutine in the 'main' block will be moved to the top immediately following the directives.
|
||||
// - all other subroutines will be moved to the end of their block.
|
||||
|
||||
|
||||
// @todo sort the VariableInitializations and normal assignments: as long as the values are constants and they follow eachother without other stmts inbetween. something like this:
|
||||
// // sort by datatype and value, so multiple initializations with the same value can be optimized (to load the value just once)
|
||||
// val sortedInits = varinits.sortedWith(compareBy({it.value.resultingDatatype(namespace, heap)}, {it.value.constValue(namespace, heap)?.asNumericValue?.toDouble()}))
|
||||
|
||||
|
||||
private val directivesToMove = setOf("%output", "%launcher", "%zeropage", "%zpreserved", "%address", "%option")
|
||||
private val vardeclsToAdd = mutableMapOf<INameScope, MutableList<VarDecl>>()
|
||||
|
||||
|
@ -183,10 +183,8 @@ private class StatementTranslator(private val prog: IntermediateProgram,
|
||||
prog.instr(Opcode.START_PROCDEF)
|
||||
prog.line(subroutine.position)
|
||||
// note: the caller has already written the arguments into the subroutine's parameter variables.
|
||||
val (varinits, others) = subroutine.statements.partition { it is VariableInitializationAssignment }
|
||||
val varInits: List<VariableInitializationAssignment> = varinits as List<VariableInitializationAssignment>
|
||||
translateVarInits(varInits)
|
||||
translate(others)
|
||||
// note2: don't separate normal and VariableInitializationAssignment here, because the order strictly matters
|
||||
translate(subroutine.statements)
|
||||
val r= super.process(subroutine)
|
||||
prog.instr(Opcode.END_PROCDEF)
|
||||
return r
|
||||
@ -200,13 +198,6 @@ private class StatementTranslator(private val prog: IntermediateProgram,
|
||||
}
|
||||
}
|
||||
|
||||
private fun translateVarInits(varinits: List<VariableInitializationAssignment>) {
|
||||
// sort by datatype and value, so multiple initializations with the same value can be optimized (to load the value just once)
|
||||
val sortedInits = varinits.sortedWith(compareBy({it.value.resultingDatatype(namespace, heap)}, {it.value.constValue(namespace, heap)?.asNumericValue?.toDouble()}))
|
||||
for (vi in sortedInits)
|
||||
translate(vi)
|
||||
}
|
||||
|
||||
private fun translate(statements: List<IStatement>) {
|
||||
for (stmt: IStatement in statements) {
|
||||
generatedLabelSequenceNumber++
|
||||
@ -935,13 +926,13 @@ private class StatementTranslator(private val prog: IntermediateProgram,
|
||||
private fun translateSubroutineCall(subroutine: Subroutine, arguments: List<IExpression>, callPosition: Position) {
|
||||
// evaluate the arguments and assign them into the subroutine's argument variables.
|
||||
var restoreX = Register.X in subroutine.asmClobbers
|
||||
if(restoreX)
|
||||
prog.instr(Opcode.RSAVEX)
|
||||
|
||||
if(subroutine.isAsmSubroutine) {
|
||||
if(subroutine.parameters.size!=subroutine.asmParameterRegisters.size)
|
||||
throw CompilerException("no support for mix of register and non-register subroutine arguments")
|
||||
|
||||
if(restoreX)
|
||||
prog.instr(Opcode.RSAVEX)
|
||||
|
||||
// only register arguments (or status-flag bits)
|
||||
var carryParam: Boolean? = null
|
||||
for(arg in arguments.zip(subroutine.asmParameterRegisters)) {
|
||||
|
@ -43,7 +43,7 @@ class IntermediateProgram(val name: String, var loadAddress: Int, val heap: Heap
|
||||
optimizeVariableCopying()
|
||||
optimizeMultipleSequentialLineInstrs()
|
||||
optimizeCallReturnIntoJump()
|
||||
optimizeRestoreXYSaveXYIntoRestoreXY()
|
||||
optimizeRestoreXSaveXIntoRepopX()
|
||||
// todo: add more optimizations to stackvm code
|
||||
|
||||
optimizeRemoveNops() // must be done as the last step
|
||||
@ -57,16 +57,14 @@ class IntermediateProgram(val name: String, var loadAddress: Int, val heap: Heap
|
||||
blk.instructions.removeIf { it.opcode== Opcode.NOP && it !is LabelInstr }
|
||||
}
|
||||
|
||||
private fun optimizeRestoreXYSaveXYIntoRestoreXY() {
|
||||
// replace rrestorex/y+rsavex/y combo by only rrestorex/y
|
||||
private fun optimizeRestoreXSaveXIntoRepopX() {
|
||||
// replace rrestorex+rsavex combo by only repopX
|
||||
for(blk in blocks) {
|
||||
val instructionsToReplace = mutableMapOf<Int, Instruction>()
|
||||
|
||||
blk.instructions.asSequence().withIndex().filter {it.value.opcode!=Opcode.LINE}.windowed(2).toList().forEach {
|
||||
if(it[0].value.opcode==Opcode.RRESTOREX && it[1].value.opcode==Opcode.RSAVEX) {
|
||||
instructionsToReplace[it[1].index] = Instruction(Opcode.NOP)
|
||||
}
|
||||
else if(it[0].value.opcode==Opcode.RRESTOREY && it[1].value.opcode==Opcode.RSAVEY) {
|
||||
instructionsToReplace[it[0].index] = Instruction(Opcode.REPOPX)
|
||||
instructionsToReplace[it[1].index] = Instruction(Opcode.NOP)
|
||||
}
|
||||
}
|
||||
|
@ -259,10 +259,9 @@ enum class Opcode {
|
||||
CLI, // clear irq-disable status flag
|
||||
RSAVE, // save all internal registers and status flags
|
||||
RSAVEX, // save just X (the evaluation stack pointer)
|
||||
RSAVEY, // save just Y (used in for loops for instance)
|
||||
RRESTORE, // restore all internal registers and status flags
|
||||
RRESTOREX, // restore just X (the evaluation stack pointer)
|
||||
RRESTOREY, // restore just Y (used in for loops for instance)
|
||||
REPOPX, // restore just X (the evaluation stack pointer) but store it again too (essentially not erasing the value that's saved on the stack)
|
||||
|
||||
NOP, // do nothing
|
||||
BREAKPOINT, // breakpoint
|
||||
|
@ -479,10 +479,9 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
// restore all registers and cpu status flag
|
||||
" pla | tay | pla | tax | pla | plp"
|
||||
}
|
||||
Opcode.RSAVEX -> " txa | pha"
|
||||
Opcode.RRESTOREX -> " pla | tax"
|
||||
Opcode.RSAVEY -> " tya | pha"
|
||||
Opcode.RRESTOREY -> " pla | tay"
|
||||
Opcode.RSAVEX -> " sta ${C64Zeropage.SCRATCH_REG} | txa | pha | lda ${C64Zeropage.SCRATCH_REG}"
|
||||
Opcode.RRESTOREX -> " sta ${C64Zeropage.SCRATCH_REG} | pla | tax | lda ${C64Zeropage.SCRATCH_REG}"
|
||||
Opcode.REPOPX -> " sta ${C64Zeropage.SCRATCH_REG} | pla | tax | pha | lda ${C64Zeropage.SCRATCH_REG}"
|
||||
Opcode.DISCARD_BYTE -> " inx"
|
||||
Opcode.DISCARD_WORD -> " inx"
|
||||
Opcode.DISCARD_FLOAT -> " inx | inx | inx"
|
||||
|
@ -1486,9 +1486,8 @@ class StackVm(private var traceOutputFile: String?) {
|
||||
P_irqd = evalstack.pop().asBooleanValue
|
||||
}
|
||||
Opcode.RSAVEX -> evalstack.push(variables["X"])
|
||||
Opcode.RSAVEY -> evalstack.push(variables["Y"])
|
||||
Opcode.RRESTOREX -> variables["X"] = evalstack.pop()
|
||||
Opcode.RRESTOREY -> variables["Y"] = evalstack.pop()
|
||||
Opcode.REPOPX -> variables["X"] = evalstack.peek()
|
||||
Opcode.INLINE_ASSEMBLY -> throw VmExecutionException("stackVm doesn't support executing inline assembly code")
|
||||
Opcode.PUSH_ADDR_HEAPVAR -> {
|
||||
val heapId = variables[ins.callLabel]!!.heapId
|
||||
|
@ -8,11 +8,6 @@
|
||||
; It's less readable I think, but produces a smaller program.
|
||||
|
||||
|
||||
|
||||
; @todo doesn't work correctly any longer and locks up at the end. Something seems broken in the if statements comparing the numbers.
|
||||
|
||||
|
||||
|
||||
~ main {
|
||||
sub start() {
|
||||
str name = "????????????????????????????????????????"
|
||||
@ -39,9 +34,10 @@
|
||||
c64flt.FADDH() ; add 0.5..
|
||||
c64flt.FADDH() ; and again, so +1 total
|
||||
A, Y = c64flt.GETADRAY()
|
||||
secretnumber = A ; secret number = rnd()*100+1
|
||||
secretnumber = A ; secret number = rnd()*100+1
|
||||
|
||||
ask_guess:
|
||||
|
||||
c64.STROUT("\nYou have ")
|
||||
c64scr.print_ub(attempts_left)
|
||||
c64.STROUT(" guess")
|
||||
|
@ -33,7 +33,7 @@
|
||||
return ending(true)
|
||||
} else {
|
||||
c64scr.print("\n\nThat is too ")
|
||||
if guess<secretnumber ; @todo not correct anymore, entering '19' says too low while the number is 18
|
||||
if guess<secretnumber
|
||||
c64scr.print("low!\n")
|
||||
else
|
||||
c64scr.print("high!\n")
|
||||
|
@ -5,36 +5,59 @@
|
||||
|
||||
sub start() {
|
||||
|
||||
; c64scr.print_ub(c64utils.str2ubyte("1"))
|
||||
; c64.CHROUT('\n')
|
||||
; c64scr.print_ub(c64utils.str2ubyte("12"))
|
||||
; c64.CHROUT('\n')
|
||||
; c64scr.print_ub(c64utils.str2ubyte("123"))
|
||||
; c64.CHROUT('\n')
|
||||
; c64scr.print_ub(c64utils.str2ubyte("1234"))
|
||||
; c64.CHROUT('\n')
|
||||
; c64scr.print_ub(c64utils.str2ubyte("12xyz"))
|
||||
; c64.CHROUT('\n')
|
||||
; c64.CHROUT('\n')
|
||||
;
|
||||
; c64scr.print_ub(c64utils.str2ubyte("19"))
|
||||
; c64.CHROUT('\n')
|
||||
; c64scr.print_ub(c64utils.str2ubyte("199"))
|
||||
; c64.CHROUT('\n')
|
||||
; c64scr.print_ub(c64utils.str2ubyte("29"))
|
||||
; c64.CHROUT('\n')
|
||||
; c64scr.print_ub(c64utils.str2ubyte("99xyz"))
|
||||
; c64.CHROUT('\n')
|
||||
; c64scr.print_ub(c64utils.str2ubyte("199xyz"))
|
||||
; c64.CHROUT('\n')
|
||||
; c64.CHROUT('\n')
|
||||
|
||||
c64scr.print_ub(c64utils.str2ubyte("1"))
|
||||
c64scr.print_b(c64utils.str2byte("1"))
|
||||
c64.CHROUT('\n')
|
||||
c64scr.print_ub(c64utils.str2ubyte("12"))
|
||||
c64scr.print_b(c64utils.str2byte("12"))
|
||||
c64.CHROUT('\n')
|
||||
c64scr.print_ub(c64utils.str2ubyte("123"))
|
||||
c64scr.print_b(c64utils.str2byte("123"))
|
||||
c64.CHROUT('\n')
|
||||
c64scr.print_ub(c64utils.str2ubyte("1234"))
|
||||
c64scr.print_b(c64utils.str2byte("1234"))
|
||||
c64.CHROUT('\n')
|
||||
c64scr.print_ub(c64utils.str2ubyte("12xyz"))
|
||||
c64scr.print_b(c64utils.str2ubyte("12xyz"))
|
||||
c64.CHROUT('\n')
|
||||
c64.CHROUT('\n')
|
||||
|
||||
c64scr.print_ub(c64utils.str2byte("1"))
|
||||
c64.CHROUT('\n')
|
||||
c64scr.print_ub(c64utils.str2byte("12"))
|
||||
c64.CHROUT('\n')
|
||||
c64scr.print_ub(c64utils.str2byte("123"))
|
||||
c64.CHROUT('\n')
|
||||
c64scr.print_ub(c64utils.str2byte("1234"))
|
||||
c64.CHROUT('\n')
|
||||
c64scr.print_ub(c64utils.str2ubyte("12xyz"))
|
||||
c64.CHROUT('\n')
|
||||
c64.CHROUT('\n')
|
||||
c64scr.print_b(c64utils.str2byte("19"))
|
||||
c64.CHROUT('\n')
|
||||
c64scr.print_b(c64utils.str2byte("29"))
|
||||
c64.CHROUT('\n')
|
||||
c64scr.print_b(c64utils.str2byte("199"))
|
||||
c64.CHROUT('\n')
|
||||
c64scr.print_b(c64utils.str2byte("299"))
|
||||
c64.CHROUT('\n')
|
||||
c64scr.print_b(c64utils.str2ubyte("99zzxyz"))
|
||||
c64.CHROUT('\n')
|
||||
c64.CHROUT('\n')
|
||||
|
||||
c64scr.print_b(c64utils.str2byte("-1"))
|
||||
c64scr.print_b(c64utils.str2byte("-9"))
|
||||
c64.CHROUT('\n')
|
||||
c64scr.print_b(c64utils.str2byte("-12"))
|
||||
c64scr.print_b(c64utils.str2byte("-99"))
|
||||
c64.CHROUT('\n')
|
||||
c64scr.print_b(c64utils.str2byte("-123"))
|
||||
c64scr.print_b(c64utils.str2byte("-199"))
|
||||
c64.CHROUT('\n')
|
||||
c64scr.print_b(c64utils.str2byte("-1111"))
|
||||
c64.CHROUT('\n')
|
||||
@ -42,5 +65,10 @@
|
||||
c64.CHROUT('\n')
|
||||
|
||||
}
|
||||
|
||||
sub foo(ubyte param1, ubyte param2) {
|
||||
ubyte local1
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user