mirror of
https://github.com/irmen/prog8.git
synced 2024-11-26 11:49:22 +00:00
optimized codegen for some more simple expressions with +/-
This commit is contained in:
parent
3075578245
commit
0a65dfdd10
@ -318,7 +318,7 @@ internal class AssignmentAsmGen(private val program: Program,
|
|||||||
// no orig ast assign target so can't use the workaround, so fallback to stack eval
|
// no orig ast assign target so can't use the workaround, so fallback to stack eval
|
||||||
fallbackToStackEval(assign)
|
fallbackToStackEval(assign)
|
||||||
}
|
}
|
||||||
} else {
|
} else if(!attemptAssignOptimizedBinexpr(value, assign)) {
|
||||||
// All remaining binary expressions just evaluate via the stack for now.
|
// All remaining binary expressions just evaluate via the stack for now.
|
||||||
// (we can't use the assignment helper functions (assignExpressionTo...) to do it via registers here,
|
// (we can't use the assignment helper functions (assignExpressionTo...) to do it via registers here,
|
||||||
// because the code here is the implementation of exactly that...)
|
// because the code here is the implementation of exactly that...)
|
||||||
@ -329,6 +329,143 @@ internal class AssignmentAsmGen(private val program: Program,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun attemptAssignOptimizedBinexpr(expr: BinaryExpression, assign: AsmAssignment): Boolean {
|
||||||
|
if(!expr.inferType(program).isInteger)
|
||||||
|
return false
|
||||||
|
if(expr.operator!="+" && expr.operator!="-")
|
||||||
|
return false
|
||||||
|
|
||||||
|
val dt = expr.inferType(program).getOrElse { throw AssemblyError("invalid dt") }
|
||||||
|
val left = expr.left
|
||||||
|
val right = expr.right
|
||||||
|
if(dt in ByteDatatypes) {
|
||||||
|
when (right) {
|
||||||
|
is IdentifierReference -> {
|
||||||
|
assignExpressionToRegister(left, RegisterOrPair.A, dt==DataType.BYTE)
|
||||||
|
val symname = asmgen.asmVariableName(right)
|
||||||
|
if(expr.operator=="+")
|
||||||
|
asmgen.out(" clc | adc $symname")
|
||||||
|
else
|
||||||
|
asmgen.out(" sec | sbc $symname")
|
||||||
|
assignRegisterByte(assign.target, CpuRegister.A)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
is NumericLiteral -> {
|
||||||
|
assignExpressionToRegister(left, RegisterOrPair.A, dt==DataType.BYTE)
|
||||||
|
if(expr.operator=="+")
|
||||||
|
asmgen.out(" clc | adc #${right.number.toHex()}")
|
||||||
|
else
|
||||||
|
asmgen.out(" sec | sbc #${right.number.toHex()}")
|
||||||
|
assignRegisterByte(assign.target, CpuRegister.A)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
else -> return false
|
||||||
|
}
|
||||||
|
} else if(dt in WordDatatypes) {
|
||||||
|
when (right) {
|
||||||
|
is AddressOf -> {
|
||||||
|
assignExpressionToRegister(left, RegisterOrPair.AY, dt==DataType.WORD)
|
||||||
|
val symbol = asmgen.asmVariableName(right.identifier)
|
||||||
|
if(expr.operator=="+")
|
||||||
|
asmgen.out("""
|
||||||
|
clc
|
||||||
|
adc #<$symbol
|
||||||
|
pha
|
||||||
|
tya
|
||||||
|
adc #>$symbol
|
||||||
|
tay
|
||||||
|
pla""")
|
||||||
|
else
|
||||||
|
asmgen.out("""
|
||||||
|
sec
|
||||||
|
sbc #<$symbol
|
||||||
|
pha
|
||||||
|
tya
|
||||||
|
sbc #>$symbol
|
||||||
|
tay
|
||||||
|
pla""")
|
||||||
|
assignRegisterpairWord(assign.target, RegisterOrPair.AY)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
is IdentifierReference -> {
|
||||||
|
val symname = asmgen.asmVariableName(right)
|
||||||
|
assignExpressionToRegister(left, RegisterOrPair.AY, dt==DataType.WORD)
|
||||||
|
if(expr.operator=="+")
|
||||||
|
asmgen.out("""
|
||||||
|
clc
|
||||||
|
adc $symname
|
||||||
|
pha
|
||||||
|
tya
|
||||||
|
adc $symname+1
|
||||||
|
tay
|
||||||
|
pla""")
|
||||||
|
else
|
||||||
|
asmgen.out("""
|
||||||
|
sec
|
||||||
|
sbc $symname
|
||||||
|
pha
|
||||||
|
tya
|
||||||
|
sbc $symname+1
|
||||||
|
tay
|
||||||
|
pla""")
|
||||||
|
assignRegisterpairWord(assign.target, RegisterOrPair.AY)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
is NumericLiteral -> {
|
||||||
|
assignExpressionToRegister(left, RegisterOrPair.AY, dt==DataType.WORD)
|
||||||
|
if(expr.operator=="+") {
|
||||||
|
asmgen.out("""
|
||||||
|
clc
|
||||||
|
adc #<${right.number.toHex()}
|
||||||
|
pha
|
||||||
|
tya
|
||||||
|
adc #>${right.number.toHex()}
|
||||||
|
tay
|
||||||
|
pla""")
|
||||||
|
} else if(expr.operator=="-") {
|
||||||
|
asmgen.out("""
|
||||||
|
sec
|
||||||
|
sbc #<${right.number.toHex()}
|
||||||
|
pha
|
||||||
|
tya
|
||||||
|
sbc #>${right.number.toHex()}
|
||||||
|
tay
|
||||||
|
pla""")
|
||||||
|
}
|
||||||
|
assignRegisterpairWord(assign.target, RegisterOrPair.AY)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
is TypecastExpression -> {
|
||||||
|
val castedValue = right.expression
|
||||||
|
if(right.type in WordDatatypes && castedValue.inferType(program).isBytes) {
|
||||||
|
if(castedValue is IdentifierReference) {
|
||||||
|
val castedSymname = asmgen.asmVariableName(castedValue)
|
||||||
|
assignExpressionToRegister(left, RegisterOrPair.AY, dt==DataType.WORD)
|
||||||
|
if(expr.operator=="+")
|
||||||
|
asmgen.out("""
|
||||||
|
clc
|
||||||
|
adc $castedSymname
|
||||||
|
bcc +
|
||||||
|
iny
|
||||||
|
+""")
|
||||||
|
else
|
||||||
|
asmgen.out("""
|
||||||
|
sec
|
||||||
|
sbc $castedSymname
|
||||||
|
bcs +
|
||||||
|
dey
|
||||||
|
+""")
|
||||||
|
assignRegisterpairWord(assign.target, RegisterOrPair.AY)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
private fun fallbackToStackEval(assign: AsmAssignment) {
|
private fun fallbackToStackEval(assign: AsmAssignment) {
|
||||||
// TODO DON'T STACK-EVAL... perhaps by using a temp var? so that it becomes augmentable assignment expression?
|
// TODO DON'T STACK-EVAL... perhaps by using a temp var? so that it becomes augmentable assignment expression?
|
||||||
// or don't try to solve it here in this one case and rather rewrite the whole stack based value evaluation.
|
// or don't try to solve it here in this one case and rather rewrite the whole stack based value evaluation.
|
||||||
|
@ -33,64 +33,22 @@ main {
|
|||||||
; mcCarthy()
|
; mcCarthy()
|
||||||
;test_stack.test()
|
;test_stack.test()
|
||||||
|
|
||||||
ubyte value = 0
|
|
||||||
ubyte one = 1
|
ubyte one = 1
|
||||||
ubyte two = 2
|
ubyte two = 2
|
||||||
ubyte[10] data = [11,22,33,4,5,6,7,8,9,10]
|
uword onew = 1
|
||||||
|
uword twow = 2
|
||||||
|
ubyte[10] data = [1,2,3,4,5,6,7,8,9,10]
|
||||||
uword bitmapbuf = &data
|
uword bitmapbuf = &data
|
||||||
|
|
||||||
; 11 22 33
|
; @(bitmapbuf+onew) = 90+one
|
||||||
txt.print_ub(bitmapbuf[0])
|
; @(bitmapbuf+twow) = 90+two
|
||||||
txt.spc()
|
bitmapbuf += 5
|
||||||
txt.print_ub(bitmapbuf[1])
|
; @(bitmapbuf-1) = 90+one
|
||||||
txt.spc()
|
; @(bitmapbuf-2) = 90+two
|
||||||
txt.print_ub(bitmapbuf[2])
|
@(bitmapbuf-onew) = 90+one
|
||||||
txt.nl()
|
@(bitmapbuf-twow) = 90+two
|
||||||
rol(bitmapbuf[0])
|
|
||||||
rol(bitmapbuf[0])
|
|
||||||
txt.print_ub(bitmapbuf[0]) ; 44
|
|
||||||
txt.spc()
|
|
||||||
ror(bitmapbuf[0])
|
|
||||||
ror(bitmapbuf[0])
|
|
||||||
txt.print_ub(bitmapbuf[0]) ; 11
|
|
||||||
txt.nl()
|
|
||||||
|
|
||||||
; 22 44 66
|
|
||||||
txt.print_ub(bitmapbuf[0]*2)
|
|
||||||
txt.spc()
|
|
||||||
txt.print_ub(bitmapbuf[1]*2)
|
|
||||||
txt.spc()
|
|
||||||
txt.print_ub(bitmapbuf[2]*2)
|
|
||||||
txt.nl()
|
|
||||||
|
|
||||||
value = one+one+one+one+one
|
|
||||||
txt.print_ub(value) ; 5
|
|
||||||
txt.nl()
|
|
||||||
|
|
||||||
bitmapbuf[0] = one+one+one
|
|
||||||
bitmapbuf[0] = one+one+one
|
|
||||||
bitmapbuf[0] = one+one+one
|
|
||||||
bitmapbuf[1] = one+one
|
|
||||||
bitmapbuf[1] = one+one
|
|
||||||
bitmapbuf[1] = one+one
|
|
||||||
bitmapbuf[2] = one
|
|
||||||
bitmapbuf[2] = one
|
|
||||||
bitmapbuf[2] = one
|
|
||||||
bitmapbuf[3] = 42
|
|
||||||
bitmapbuf[2] += 100
|
|
||||||
bitmapbuf[2] -= 1
|
|
||||||
bitmapbuf[2] -= 1
|
|
||||||
bitmapbuf[2] -= 1
|
|
||||||
bitmapbuf[2] -= 1
|
|
||||||
|
|
||||||
; 3 2 97
|
|
||||||
txt.print_ub(bitmapbuf[0])
|
|
||||||
txt.spc()
|
|
||||||
txt.print_ub(bitmapbuf[1])
|
|
||||||
txt.spc()
|
|
||||||
txt.print_ub(bitmapbuf[2])
|
|
||||||
txt.nl()
|
|
||||||
|
|
||||||
|
ubyte value
|
||||||
for value in data {
|
for value in data {
|
||||||
txt.print_ub(value) ; 3 2 97 42 5 6 7 8 9 10
|
txt.print_ub(value) ; 3 2 97 42 5 6 7 8 9 10
|
||||||
txt.spc()
|
txt.spc()
|
||||||
|
Loading…
Reference in New Issue
Block a user