mirror of
https://github.com/irmen/prog8.git
synced 2024-11-26 11:49:22 +00:00
avoid using temp var even more
This commit is contained in:
parent
04959dbd8b
commit
3b786c819d
@ -707,11 +707,8 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
||||
}
|
||||
|
||||
private fun inplacemodificationByteVariableWithValue(name: String, dt: DataType, operator: String, value: PtExpression) {
|
||||
// TODO optimize: don't use scratch var if possible
|
||||
val tmpVar = if(name!="P8ZP_SCRATCH_B1") "P8ZP_SCRATCH_B1" else "P8ZP_SCRATCH_REG"
|
||||
asmgen.assignExpressionToVariable(value, tmpVar, value.type)
|
||||
asmgen.out(" lda $name")
|
||||
inplacemodificationRegisterAwithVariable(operator, tmpVar, dt in SignedDatatypes)
|
||||
asmgen.assignExpressionToRegister(value, RegisterOrPair.A, dt in SignedDatatypes)
|
||||
inplacemodificationRegisterAwithVariableWithSwappedOperands(operator, name, dt in SignedDatatypes)
|
||||
asmgen.out(" sta $name")
|
||||
}
|
||||
|
||||
@ -722,15 +719,16 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
||||
}
|
||||
|
||||
private fun inplacemodificationRegisterAwithVariable(operator: String, variable: String, signed: Boolean) {
|
||||
// A = A <operator> variable
|
||||
when (operator) {
|
||||
"+" -> asmgen.out(" clc | adc $variable")
|
||||
"-" -> asmgen.out(" sec | sbc $variable")
|
||||
"*" -> asmgen.out(" ldy $variable | jsr math.multiply_bytes")
|
||||
"/" -> {
|
||||
if(signed)
|
||||
asmgen.out(" ldy $variable | jsr math.divmod_b_asm | tya")
|
||||
asmgen.out(" ldy $variable | jsr math.divmod_b_asm | tya")
|
||||
else
|
||||
asmgen.out(" ldy $variable | jsr math.divmod_ub_asm | tya")
|
||||
asmgen.out(" ldy $variable | jsr math.divmod_ub_asm | tya")
|
||||
}
|
||||
"%" -> {
|
||||
if(signed)
|
||||
@ -881,6 +879,164 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
||||
}
|
||||
}
|
||||
|
||||
private fun inplacemodificationRegisterAwithVariableWithSwappedOperands(operator: String, variable: String, signed: Boolean) {
|
||||
// A = variable <operator> A
|
||||
|
||||
if(operator in AssociativeOperators)
|
||||
return inplacemodificationRegisterAwithVariable(operator, variable, signed) // just reuse existing code for associative operators
|
||||
|
||||
// now implement the non-assiciative operators...
|
||||
when (operator) {
|
||||
"-" -> {
|
||||
// TODO optimize: don't use scratch var
|
||||
val tmpVar = if(variable!="P8ZP_SCRATCH_B1") "P8ZP_SCRATCH_B1" else "P8ZP_SCRATCH_REG"
|
||||
asmgen.out(" sta $tmpVar | lda $variable | sec | sbc $tmpVar")
|
||||
}
|
||||
"/" -> {
|
||||
if(signed)
|
||||
asmgen.out(" tay | lda $variable | jsr math.divmod_b_asm | tya")
|
||||
else
|
||||
asmgen.out(" tay | lda $variable | jsr math.divmod_ub_asm | tya")
|
||||
}
|
||||
"%" -> {
|
||||
if(signed)
|
||||
throw AssemblyError("remainder of signed integers is not properly defined/implemented, use unsigned instead")
|
||||
asmgen.out(" tay | lda $variable | jsr math.divmod_ub_asm")
|
||||
}
|
||||
"<<" -> {
|
||||
asmgen.out("""
|
||||
tay
|
||||
beq +
|
||||
lda $variable
|
||||
- asl a
|
||||
dey
|
||||
bne -
|
||||
+""")
|
||||
}
|
||||
">>" -> {
|
||||
if(!signed) {
|
||||
asmgen.out("""
|
||||
tay
|
||||
beq +
|
||||
lda $variable
|
||||
- lsr a
|
||||
dey
|
||||
bne -
|
||||
+""")
|
||||
} else {
|
||||
asmgen.out("""
|
||||
tay
|
||||
beq +
|
||||
lda $variable
|
||||
sta P8ZP_SCRATCH_B1
|
||||
- asl a
|
||||
ror P8ZP_SCRATCH_B1
|
||||
lda P8ZP_SCRATCH_B1
|
||||
dey
|
||||
bne -
|
||||
+""")
|
||||
}
|
||||
}
|
||||
"<" -> {
|
||||
if(!signed) {
|
||||
TODO("swap operand order")
|
||||
asmgen.out("""
|
||||
tay
|
||||
lda #0
|
||||
cpy $variable
|
||||
rol a
|
||||
eor #1""")
|
||||
}
|
||||
else {
|
||||
TODO("swap operand order")
|
||||
// see http://www.6502.org/tutorials/compare_beyond.html
|
||||
asmgen.out("""
|
||||
sec
|
||||
sbc $variable
|
||||
bvc +
|
||||
eor #$80
|
||||
+ bmi +
|
||||
lda #0
|
||||
beq ++
|
||||
+ lda #1
|
||||
+""")
|
||||
}
|
||||
}
|
||||
"<=" -> {
|
||||
if(!signed) {
|
||||
TODO("swap operand order")
|
||||
asmgen.out("""
|
||||
tay
|
||||
lda #0
|
||||
ldy $variable
|
||||
rol a""")
|
||||
} else {
|
||||
TODO("swap operand order")
|
||||
// see http://www.6502.org/tutorials/compare_beyond.html
|
||||
asmgen.out("""
|
||||
clc
|
||||
sbc $variable
|
||||
bvc +
|
||||
eor #$80
|
||||
+ bmi +
|
||||
lda #0
|
||||
beq ++
|
||||
+ lda #1
|
||||
+""")
|
||||
}
|
||||
}
|
||||
">" -> {
|
||||
if(!signed) {
|
||||
TODO("swap operand order")
|
||||
asmgen.out("""
|
||||
tay
|
||||
lda #0
|
||||
cpy $variable
|
||||
beq +
|
||||
rol a
|
||||
+""")
|
||||
} else {
|
||||
TODO("swap operand order")
|
||||
// see http://www.6502.org/tutorials/compare_beyond.html
|
||||
asmgen.out("""
|
||||
clc
|
||||
sbc $variable
|
||||
bvc +
|
||||
eor #$80
|
||||
+ bpl +
|
||||
lda #0
|
||||
beq ++
|
||||
+ lda #1
|
||||
+""")
|
||||
}
|
||||
}
|
||||
">=" -> {
|
||||
if(!signed) {
|
||||
TODO("swap operand order")
|
||||
asmgen.out("""
|
||||
tay
|
||||
lda #0
|
||||
cpy $variable
|
||||
rol a""")
|
||||
} else {
|
||||
TODO("swap operand order")
|
||||
// see http://www.6502.org/tutorials/compare_beyond.html
|
||||
asmgen.out("""
|
||||
sec
|
||||
sbc $variable
|
||||
bvc +
|
||||
eor #$80
|
||||
+ bpl +
|
||||
lda #0
|
||||
beq ++
|
||||
+ lda #1
|
||||
+""")
|
||||
}
|
||||
}
|
||||
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
||||
}
|
||||
}
|
||||
|
||||
private fun inplacemodificationByteVariableWithLiteralval(name: String, dt: DataType, operator: String, value: Int) {
|
||||
// note: this contains special optimized cases because we know the exact value. Don't replace this with another routine.
|
||||
when (operator) {
|
||||
|
@ -58,6 +58,7 @@ multiply_words .proc
|
||||
; -- multiply two 16-bit words into a 32-bit result (signed and unsigned)
|
||||
; input: A/Y = first 16-bit number, cx16.R0 = second 16-bit number
|
||||
; output: multiply_words.result == cx16.R0:R1, 4-bytes/32-bits product, LSB order (low-to-high) low 16 bits also in AY.
|
||||
; TODO: should not use R0 and R1 at all !!! result needs 4 consecutive bytes, so it can't be in zeropage at all...
|
||||
|
||||
; mult62.a
|
||||
; based on Dr Jefyll, http://forum.6502.org/viewtopic.php?f=9&t=689&start=0#p19958
|
||||
|
@ -1,6 +1,11 @@
|
||||
TODO
|
||||
====
|
||||
|
||||
- fix: amiga example with noopt draws wrong lines, caused by "2x faster word multiplication routine" because it trashes r0 and r1 now
|
||||
multiply_words in math.asm needs fixing.
|
||||
|
||||
- fix: test all other things with noopt once again! (examples/c64 are all ok)
|
||||
- fix: search for TODO("swap operand order")
|
||||
- optimize: search for TODO optimize: don't use scratch var
|
||||
- prefix prog8 subroutines with p8s_ instead of p8_ to not let them clash with variables in the asm?
|
||||
- allow 'chained' array indexing for expressions: value = ptrarray[0][0]
|
||||
|
@ -1,14 +1,17 @@
|
||||
%import textio
|
||||
%import math
|
||||
%zeropage basicsafe
|
||||
|
||||
main {
|
||||
sub start() {
|
||||
ubyte index
|
||||
ubyte index = 100
|
||||
ubyte[] t_index = [1,2,3,4,5]
|
||||
ubyte nibble = 0
|
||||
|
||||
index -= t_index[4]
|
||||
index += t_index[4]
|
||||
index += t_index[nibble]
|
||||
nibble++
|
||||
index -= t_index[3]
|
||||
index -= t_index[nibble]
|
||||
txt.print_ub(index) ; 100
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user