mirror of
https://github.com/irmen/prog8.git
synced 2025-11-23 14:17:51 +00:00
fix long if-expressions temp register usage
This commit is contained in:
@@ -15,40 +15,27 @@ internal class IfExpressionAsmGen(private val asmgen: AsmGen6502Internal, privat
|
||||
val falseLabel = asmgen.makeLabel("ifexpr_false")
|
||||
val endLabel = asmgen.makeLabel("ifexpr_end")
|
||||
evalIfExpressionConditonAndBranchWhenFalse(expr.condition, falseLabel)
|
||||
when {
|
||||
expr.type.isByteOrBool -> {
|
||||
|
||||
if(expr.type.isByteOrBool) {
|
||||
asmgen.assignExpressionToRegister(expr.truevalue, RegisterOrPair.A)
|
||||
asmgen.jmp(endLabel)
|
||||
asmgen.out(falseLabel)
|
||||
asmgen.assignExpressionToRegister(expr.falsevalue, RegisterOrPair.A)
|
||||
asmgen.out(endLabel)
|
||||
assignmentAsmGen.assignRegisterByte(target, CpuRegister.A, false, false)
|
||||
}
|
||||
expr.type.isWord || expr.type.isString -> {
|
||||
asmgen.assignExpressionToRegister(expr.truevalue, RegisterOrPair.AY)
|
||||
asmgen.jmp(endLabel)
|
||||
asmgen.out(falseLabel)
|
||||
asmgen.assignExpressionToRegister(expr.falsevalue, RegisterOrPair.AY)
|
||||
asmgen.out(endLabel)
|
||||
assignmentAsmGen.assignRegisterpairWord(target, RegisterOrPair.AY)
|
||||
}
|
||||
expr.type.isLong -> {
|
||||
asmgen.assignExpressionToRegister(expr.truevalue, RegisterOrPair.R0R1_32, true)
|
||||
asmgen.jmp(endLabel)
|
||||
asmgen.out(falseLabel)
|
||||
asmgen.assignExpressionToRegister(expr.falsevalue, RegisterOrPair.R0R1_32, true)
|
||||
asmgen.out(endLabel)
|
||||
assignmentAsmGen.assignRegisterLong(target, RegisterOrPair.R0R1_32)
|
||||
}
|
||||
expr.type.isFloat -> {
|
||||
} else if(expr.type.isFloat) {
|
||||
asmgen.assignExpressionToRegister(expr.truevalue, RegisterOrPair.FAC1, true)
|
||||
asmgen.jmp(endLabel)
|
||||
asmgen.out(falseLabel)
|
||||
asmgen.assignExpressionToRegister(expr.falsevalue, RegisterOrPair.FAC1, true)
|
||||
asmgen.out(endLabel)
|
||||
asmgen.assignRegister(RegisterOrPair.FAC1, target)
|
||||
}
|
||||
else -> throw AssemblyError("weird dt")
|
||||
} else {
|
||||
asmgen.assignExpressionTo(expr.truevalue, target)
|
||||
asmgen.jmp(endLabel)
|
||||
asmgen.out(falseLabel)
|
||||
asmgen.assignExpressionTo(expr.falsevalue, target)
|
||||
asmgen.out(endLabel)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -398,18 +385,19 @@ internal class IfExpressionAsmGen(private val asmgen: AsmGen6502Internal, privat
|
||||
cmp #$${hex.take(2)}
|
||||
bne $falseLabel""")
|
||||
} else {
|
||||
asmgen.assignExpressionToRegister(expr, RegisterOrPair.R0R1_32)
|
||||
// TODO cannot easily preserve R14:R15 on stack because we need the status flags of the comparison in between...
|
||||
asmgen.assignExpressionToRegister(expr, RegisterOrPair.R14R15_32)
|
||||
asmgen.out("""
|
||||
lda cx16.r0
|
||||
lda cx16.r14
|
||||
cmp #$${hex.substring(6, 8)}
|
||||
bne $falseLabel
|
||||
lda cx16.r0+1
|
||||
lda cx16.r14+1
|
||||
cmp #$${hex.substring(4, 6)}
|
||||
bne $falseLabel
|
||||
lda cx16.r0+2
|
||||
lda cx16.r14+2
|
||||
cmp #$${hex.substring(2, 4)}
|
||||
bne $falseLabel
|
||||
lda cx16.r0+3
|
||||
lda cx16.r14+3
|
||||
cmp #$${hex.take(2)}
|
||||
bne $falseLabel""")
|
||||
}
|
||||
@@ -435,18 +423,19 @@ internal class IfExpressionAsmGen(private val asmgen: AsmGen6502Internal, privat
|
||||
cmp $varname2+3
|
||||
bne $falseLabel""")
|
||||
} else {
|
||||
asmgen.assignExpressionToRegister(expr, RegisterOrPair.R0R1_32)
|
||||
// TODO cannot easily preserve R14:R15 on stack because we need the status flags of the comparison in between...
|
||||
asmgen.assignExpressionToRegister(expr, RegisterOrPair.R14R15_32)
|
||||
asmgen.out("""
|
||||
lda cx16.r0
|
||||
lda cx16.r14
|
||||
cmp $varname2
|
||||
bne $falseLabel
|
||||
lda cx16.r0+1
|
||||
lda cx16.r14+1
|
||||
cmp $varname2+1
|
||||
bne $falseLabel
|
||||
lda cx16.r0+2
|
||||
lda cx16.r14+2
|
||||
cmp $varname2+2
|
||||
bne $falseLabel
|
||||
lda cx16.r0+3
|
||||
lda cx16.r14+3
|
||||
cmp $varname2+3
|
||||
bne $falseLabel""")
|
||||
}
|
||||
@@ -503,13 +492,16 @@ internal class IfExpressionAsmGen(private val asmgen: AsmGen6502Internal, privat
|
||||
ora $varname+3
|
||||
bne $falseLabel""")
|
||||
} else {
|
||||
asmgen.assignExpressionToRegister(expr, RegisterOrPair.R0R1_32)
|
||||
asmgen.pushLongRegisters(RegisterOrPair.R14R15_32, 1)
|
||||
asmgen.assignExpressionToRegister(expr, RegisterOrPair.R14R15_32)
|
||||
asmgen.out("""
|
||||
lda cx16.r0
|
||||
ora cx16.r0+1
|
||||
ora cx16.r0+2
|
||||
ora cx16.r0+3
|
||||
bne $falseLabel""")
|
||||
lda cx16.r14
|
||||
ora cx16.r14+1
|
||||
ora cx16.r14+2
|
||||
ora cx16.r14+3
|
||||
sta P8ZP_SCRATCH_REG""")
|
||||
asmgen.popLongRegisters(RegisterOrPair.R14R15_32, 1)
|
||||
asmgen.out(" lda P8ZP_SCRATCH_REG | bne $falseLabel")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -525,13 +517,16 @@ internal class IfExpressionAsmGen(private val asmgen: AsmGen6502Internal, privat
|
||||
ora $varname+3
|
||||
beq $falseLabel""")
|
||||
} else {
|
||||
asmgen.assignExpressionToRegister(expr, RegisterOrPair.R0R1_32)
|
||||
asmgen.pushLongRegisters(RegisterOrPair.R14R15_32, 1)
|
||||
asmgen.assignExpressionToRegister(expr, RegisterOrPair.R14R15_32)
|
||||
asmgen.out("""
|
||||
lda cx16.r0
|
||||
ora cx16.r0+1
|
||||
ora cx16.r0+2
|
||||
ora cx16.r0+3
|
||||
beq $falseLabel""")
|
||||
lda cx16.r14
|
||||
ora cx16.r14+1
|
||||
ora cx16.r14+2
|
||||
ora cx16.r14+3
|
||||
sta P8ZP_SCRATCH_REG""")
|
||||
asmgen.popLongRegisters(RegisterOrPair.R14R15_32, 1)
|
||||
asmgen.out(" lda P8ZP_SCRATCH_REG | beq $falseLabel")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,14 +2,6 @@ TODO
|
||||
====
|
||||
|
||||
- optimizedBitwiseExpr(): use R14:R15 instead to save copying/stack manipulation?
|
||||
|
||||
- use R12-R15 as temp registers with longs instead of R0-R3 (much less chance on clobbering)
|
||||
check usages of R0R1_32, because all usages of R2R3_32 have already been corrected
|
||||
update/remove the warning in the docs about this
|
||||
maybe reduce problem even further by storing/retrieveing the previous value of those registers? we NEED this anyway because expressions can be nested...
|
||||
|
||||
- (not needed anymore if everything is saved on the stack?:) can the compiler give a warning if you use R0/R1 (or whatever the temp storage is) in expressions and/or statements together with long integers? (because R0/R1 are likely to be clobbered as temporary storage)
|
||||
|
||||
- implement inplaceLongAdd/Sub in PointerAssignmentGen
|
||||
|
||||
|
||||
|
||||
@@ -250,13 +250,12 @@ to be done on word values, and don't want to explicitly have to cast everything
|
||||
a lot will be much slower than when you restrict yourself to 8 or 16 bit values. Use long values sparingly.
|
||||
|
||||
.. danger::
|
||||
**longs and cx16.R0,R1,R2,R3**:
|
||||
**Many operations on long values require the use of the R0 and R1 virtual register as temporary storage**
|
||||
and several even R2 and R3 as well. So if you are working with long values, you should assume that the contents of R0 and R1
|
||||
(and probably R2 and R3 as well) are destroyed.
|
||||
**Using R0,R1,R2,R3 in expressions that work with longs, will probably give a corrupted result, without
|
||||
a warning of the compiler!** It is strongly advised to *not* use R0,R1,R2,R3 at all when dealing with longs.
|
||||
*Note: this may change in the future to maybe R12-R15 instead, to reduce the chance of overwriting registers that are already used*
|
||||
**longs and cx16.R12,R13,R14,R15**:
|
||||
**Some operations on long values require the use of the R12-R15 virtual register as temporary storage**
|
||||
So if you are working with long values, you should assume that the contents of R12-R15 could be destroyed.
|
||||
()Many operations preserve the values, but not all because of reasons)
|
||||
**Using R12,R13,R14,R15 in expressions that work with longs, will sometimes give a corrupted result, without
|
||||
a warning of the compiler!** It is strongly advised to *not* use R12-R15 at all when dealing with longs.
|
||||
|
||||
|
||||
Booleans
|
||||
|
||||
@@ -7,11 +7,18 @@ main {
|
||||
sub start() {
|
||||
long @shared lv, lv2
|
||||
|
||||
if lv==lv2+2
|
||||
cx16.r0++
|
||||
cx16.r0L = if lv==9999 then 99 else 42
|
||||
txt.print_ub(cx16.r0L)
|
||||
txt.nl()
|
||||
|
||||
lv2 = if lv==9999 then 999999 else 424242
|
||||
txt.print_l(lv2)
|
||||
txt.nl()
|
||||
lv=9999
|
||||
lv2 = if lv==9999 then 999999 else 424242
|
||||
txt.print_l(lv2)
|
||||
txt.nl()
|
||||
|
||||
if lv!=lv2+2
|
||||
cx16.r0++
|
||||
|
||||
; long @shared lv1 = $12345678
|
||||
;
|
||||
|
||||
Reference in New Issue
Block a user