mirror of
https://github.com/irmen/prog8.git
synced 2026-04-22 08:16:49 +00:00
optimize certain word multiplication with bit shifting if it's a power of 2
This commit is contained in:
@@ -5,6 +5,7 @@ import prog8.code.ast.*
|
||||
import prog8.code.core.*
|
||||
import prog8.codegen.cpu6502.AsmGen6502Internal
|
||||
import prog8.codegen.cpu6502.VariableAllocator
|
||||
import kotlin.math.log2
|
||||
|
||||
|
||||
internal class AssignmentAsmGen(
|
||||
@@ -1145,6 +1146,14 @@ internal class AssignmentAsmGen(
|
||||
assignExpressionToRegister(expr.left, RegisterOrPair.A, expr.type.isSigned)
|
||||
if (value in asmgen.optimizedByteMultiplications)
|
||||
asmgen.out(" jsr prog8_math.mul_byte_${value}")
|
||||
else if(value in powersOfTwoInt) {
|
||||
val shifts = log2(value.toDouble()).toInt()
|
||||
if(shifts>=8) {
|
||||
asmgen.out(" lda #0")
|
||||
} else {
|
||||
repeat(shifts) { asmgen.out(" asl a") }
|
||||
}
|
||||
}
|
||||
else
|
||||
asmgen.out(" ldy #$value | jsr prog8_math.multiply_bytes")
|
||||
assignRegisterByte(target, CpuRegister.A, false, true)
|
||||
@@ -1155,7 +1164,26 @@ internal class AssignmentAsmGen(
|
||||
assignExpressionToRegister(expr.left, RegisterOrPair.AY, expr.type.isSigned)
|
||||
asmgen.out(" jsr prog8_math.mul_word_${value}")
|
||||
}
|
||||
else if(value in powersOfTwoInt) {
|
||||
val shifts = log2(value.toDouble()).toInt()
|
||||
if(shifts>=16) {
|
||||
assignExpressionToRegister(expr.left, RegisterOrPair.AY, expr.type.isSigned)
|
||||
asmgen.out(" lda #0 | ldy #0")
|
||||
} else {
|
||||
if(target.kind==TargetStorageKind.VARIABLE && target.datatype.isWord) {
|
||||
assignExpressionToVariable(expr.left, target.asmVarname, target.datatype)
|
||||
repeat(shifts) { asmgen.out(" asl ${target.asmVarname} | rol ${target.asmVarname}+1") }
|
||||
return true
|
||||
} else {
|
||||
assignExpressionToRegister(expr.left, RegisterOrPair.AY, expr.type.isSigned)
|
||||
asmgen.out(" sty P8ZP_SCRATCH_REG")
|
||||
repeat(shifts) { asmgen.out(" asl a | rol P8ZP_SCRATCH_REG") }
|
||||
asmgen.out(" ldy P8ZP_SCRATCH_REG")
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
assignExpressionToRegister(expr.left, RegisterOrPair.AY, expr.type.isSigned)
|
||||
if(expr.definingBlock()!!.options.veraFxMuls){
|
||||
// cx16 verafx hardware mul
|
||||
asmgen.assignWordOperandsToAYAndVar(expr.right, expr.left, "cx16.r1")
|
||||
|
||||
@@ -58,18 +58,15 @@ and for example the below code omits line 5::
|
||||
STRUCTS and TYPED POINTERS
|
||||
--------------------------
|
||||
|
||||
- the type of struct initializer arrays should not be uword[] but ^^struct[] ?
|
||||
- implement the remaining TODO's in PointerAssignmentsGen.
|
||||
- optimize deref in PointerAssignmentsGen: optimize 'forceTemporary' to only use a temporary when the offset is >0
|
||||
- optimize addUnsignedByteOrWordToAY in PointerAssignmentsGen a bit more
|
||||
- optimize the float copying in assignIndexedPointer() (also word?)
|
||||
- implement even more struct instance assignments (via memcopy) in CodeDesugarer (see the TODO) (add to documentation as well, paragraph 'Structs')
|
||||
- try to optimize pointer arithmetic used in peek/poke a bit more so the routines in sorting module can use typed pointers without increasing code size, see test.p8 in commit d394dc1e
|
||||
- should @(wordpointer) be equivalent to wordpointer^^ (that would require a LOT of code rewrite that now knows that @() is strictly byte based) ?
|
||||
or do an implicit cast @(wpointer as ubyte^^) ? And/or add a warning about that?
|
||||
- optimize addUnsignedByteOrWordToAY in PointerAssignmentsGen a bit more
|
||||
- support for typed function pointers? (&routine could be typed by default as well then)
|
||||
- support @nosplit pointer arrays?
|
||||
- support pointer to pointer?
|
||||
- the type of struct initializer arrays should not be uword[] but ^^struct[]
|
||||
- support for typed function pointers? (&routine could be typed by default as well then)
|
||||
- really fixing the pointer dereferencing issues (cursed hybrid beween IdentifierReference, PtrDereferece and PtrIndexedDereference) may require getting rid of scoped identifiers altogether and treat '.' as a "scope or pointer following operator"
|
||||
- (later, nasty parser problem:) support chaining pointer dereference on function calls that return a pointer. (type checking now fails on stuff like func().field and func().next.field)
|
||||
|
||||
|
||||
+25
-54
@@ -1,63 +1,34 @@
|
||||
%import textio
|
||||
%zeropage basicsafe
|
||||
|
||||
main {
|
||||
word bignum
|
||||
|
||||
struct Node {
|
||||
ubyte id
|
||||
str name
|
||||
bool flag
|
||||
word counter
|
||||
}
|
||||
|
||||
sub start() {
|
||||
^^Node test = []
|
||||
bignum = 11111
|
||||
test.counter = 22222
|
||||
^^uword @shared ptr
|
||||
|
||||
txt.print_w(bignum)
|
||||
txt.spc()
|
||||
bignum++
|
||||
add1()
|
||||
add2()
|
||||
sub1()
|
||||
sub2()
|
||||
|
||||
txt.print_w(bignum)
|
||||
txt.spc()
|
||||
bignum--
|
||||
sub add1() {
|
||||
ptr += 5
|
||||
cx16.r0 = ptr + 5
|
||||
cx16.r0 = peekw(ptr + 5)
|
||||
}
|
||||
|
||||
txt.print_w(bignum)
|
||||
txt.nl()
|
||||
sub add2() {
|
||||
ptr += cx16.r0L
|
||||
cx16.r0 = ptr + cx16.r0L
|
||||
cx16.r0 = peekw(ptr + cx16.r0L)
|
||||
}
|
||||
|
||||
txt.print_w(test.counter)
|
||||
txt.spc()
|
||||
test.counter ++
|
||||
sub sub1() {
|
||||
ptr -= 5
|
||||
cx16.r0 = ptr - 5
|
||||
cx16.r0 = peekw(ptr - 5)
|
||||
}
|
||||
|
||||
txt.print_w(test.counter)
|
||||
txt.spc()
|
||||
test.counter --
|
||||
|
||||
txt.print_w(test.counter)
|
||||
txt.nl()
|
||||
|
||||
txt.print_w(bignum)
|
||||
txt.spc()
|
||||
bignum+=5555
|
||||
|
||||
txt.print_w(bignum)
|
||||
txt.spc()
|
||||
bignum-=5555
|
||||
|
||||
txt.print_w(bignum)
|
||||
txt.nl()
|
||||
|
||||
txt.print_w(test.counter)
|
||||
txt.spc()
|
||||
test.counter += 5555
|
||||
|
||||
txt.print_w(test.counter)
|
||||
txt.spc()
|
||||
test.counter -= 5555
|
||||
|
||||
txt.print_w(test.counter)
|
||||
txt.nl()
|
||||
sub sub2() {
|
||||
ptr -= cx16.r0L
|
||||
cx16.r0 = ptr - cx16.r0L
|
||||
cx16.r0 = peekw(ptr - cx16.r0L)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user