mirror of
https://github.com/irmen/prog8.git
synced 2024-08-10 14:29:06 +00:00
slightly optimize expression code for most common cases +/- 1 , */div 2
This commit is contained in:
parent
c0a5f8fef0
commit
c1ce0be451
@ -1223,6 +1223,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun translateExpression(expr: BinaryExpression) {
|
private fun translateExpression(expr: BinaryExpression) {
|
||||||
|
// TODO needs to use optimized assembly generation like the assignment instructions. But avoid code duplication.... rewrite all expressions into assignment form?
|
||||||
val leftIDt = expr.left.inferType(program)
|
val leftIDt = expr.left.inferType(program)
|
||||||
val rightIDt = expr.right.inferType(program)
|
val rightIDt = expr.right.inferType(program)
|
||||||
if(!leftIDt.isKnown || !rightIDt.isKnown)
|
if(!leftIDt.isKnown || !rightIDt.isKnown)
|
||||||
@ -1232,6 +1233,106 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
|
|||||||
val rightDt = rightIDt.typeOrElse(DataType.STRUCT)
|
val rightDt = rightIDt.typeOrElse(DataType.STRUCT)
|
||||||
// see if we can apply some optimized routines
|
// see if we can apply some optimized routines
|
||||||
when(expr.operator) {
|
when(expr.operator) {
|
||||||
|
"+" -> {
|
||||||
|
if(leftDt in IntegerDatatypes && rightDt in IntegerDatatypes) {
|
||||||
|
val leftVal = expr.left.constValue(program)?.number?.toInt()
|
||||||
|
val rightVal = expr.right.constValue(program)?.number?.toInt()
|
||||||
|
if (leftVal!=null && leftVal in -4..4) {
|
||||||
|
translateExpression(expr.right)
|
||||||
|
if(rightDt in ByteDatatypes) {
|
||||||
|
val incdec = if(leftVal<0) "dec" else "inc"
|
||||||
|
repeat(leftVal.absoluteValue) {
|
||||||
|
asmgen.out(" $incdec P8ESTACK_LO,x")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// word
|
||||||
|
if(leftVal<0) {
|
||||||
|
repeat(leftVal.absoluteValue) {
|
||||||
|
asmgen.out("""
|
||||||
|
lda P8ESTACK_LO+1,x
|
||||||
|
bne +
|
||||||
|
dec P8ESTACK_HI+1,x
|
||||||
|
+ dec P8ESTACK_LO+1,x""")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
repeat(leftVal) {
|
||||||
|
asmgen.out("""
|
||||||
|
inc P8ESTACK_LO+1,x
|
||||||
|
bne +
|
||||||
|
inc P8ESTACK_HI+1,x
|
||||||
|
+""")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
else if (rightVal!=null && rightVal in -4..4)
|
||||||
|
{
|
||||||
|
translateExpression(expr.left)
|
||||||
|
if(leftDt in ByteDatatypes) {
|
||||||
|
val incdec = if(rightVal<0) "dec" else "inc"
|
||||||
|
repeat(rightVal.absoluteValue) {
|
||||||
|
asmgen.out(" $incdec P8ESTACK_LO,x")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// word
|
||||||
|
if(rightVal<0) {
|
||||||
|
repeat(rightVal.absoluteValue) {
|
||||||
|
asmgen.out("""
|
||||||
|
lda P8ESTACK_LO+1,x
|
||||||
|
bne +
|
||||||
|
dec P8ESTACK_HI+1,x
|
||||||
|
+ dec P8ESTACK_LO+1,x""")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
repeat(rightVal) {
|
||||||
|
asmgen.out("""
|
||||||
|
inc P8ESTACK_LO+1,x
|
||||||
|
bne +
|
||||||
|
inc P8ESTACK_HI+1,x
|
||||||
|
+""")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"-" -> {
|
||||||
|
if(leftDt in IntegerDatatypes && rightDt in IntegerDatatypes) {
|
||||||
|
val rightVal = expr.right.constValue(program)?.number?.toInt()
|
||||||
|
if (rightVal!=null && rightVal in -4..4)
|
||||||
|
{
|
||||||
|
translateExpression(expr.left)
|
||||||
|
if(leftDt in ByteDatatypes) {
|
||||||
|
val incdec = if(rightVal<0) "inc" else "dec"
|
||||||
|
repeat(rightVal.absoluteValue) {
|
||||||
|
asmgen.out(" $incdec P8ESTACK_LO,x")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// word
|
||||||
|
if(rightVal>0) {
|
||||||
|
repeat(rightVal.absoluteValue) {
|
||||||
|
asmgen.out("""
|
||||||
|
lda P8ESTACK_LO+1,x
|
||||||
|
bne +
|
||||||
|
dec P8ESTACK_HI+1,x
|
||||||
|
+ dec P8ESTACK_LO+1,x""")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
repeat(rightVal) {
|
||||||
|
asmgen.out("""
|
||||||
|
inc P8ESTACK_LO+1,x
|
||||||
|
bne +
|
||||||
|
inc P8ESTACK_HI+1,x
|
||||||
|
+""")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
">>" -> {
|
">>" -> {
|
||||||
translateExpression(expr.left)
|
translateExpression(expr.left)
|
||||||
val amount = expr.right.constValue(program)?.number?.toInt()
|
val amount = expr.right.constValue(program)?.number?.toInt()
|
||||||
@ -1313,6 +1414,16 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
|
|||||||
if(value!=null) {
|
if(value!=null) {
|
||||||
if(rightDt in IntegerDatatypes) {
|
if(rightDt in IntegerDatatypes) {
|
||||||
val amount = value.number.toInt()
|
val amount = value.number.toInt()
|
||||||
|
if(amount==2) {
|
||||||
|
// optimize x*2 common case
|
||||||
|
translateExpression(expr.left)
|
||||||
|
if(leftDt in ByteDatatypes) {
|
||||||
|
asmgen.out(" asl P8ESTACK_LO,x")
|
||||||
|
} else {
|
||||||
|
asmgen.out(" asl P8ESTACK_LO,x | rol P8ESTACK_HI,x")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
when(rightDt) {
|
when(rightDt) {
|
||||||
DataType.UBYTE -> {
|
DataType.UBYTE -> {
|
||||||
if(amount in asmgen.optimizedByteMultiplications) {
|
if(amount in asmgen.optimizedByteMultiplications) {
|
||||||
@ -1357,15 +1468,31 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
"/" -> {
|
||||||
|
if(leftDt in IntegerDatatypes && rightDt in IntegerDatatypes) {
|
||||||
|
val rightVal = expr.right.constValue(program)?.number?.toInt()
|
||||||
|
if(rightVal!=null && rightVal==2) {
|
||||||
|
translateExpression(expr.left)
|
||||||
|
when(leftDt) {
|
||||||
|
DataType.UBYTE -> asmgen.out(" lsr P8ESTACK_LO+1,x")
|
||||||
|
DataType.BYTE -> asmgen.out(" asl P8ESTACK_LO+1,x | ror P8ESTACK_LO+1,x")
|
||||||
|
DataType.UWORD -> asmgen.out(" lsr P8ESTACK_HI+1,x | ror P8ESTACK_LO+1,x")
|
||||||
|
DataType.WORD -> asmgen.out(" asl P8ESTACK_HI+1,x | ror P8ESTACK_HI+1,x | ror P8ESTACK_LO+1,x")
|
||||||
|
else -> throw AssemblyError("wrong dt")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// the general, non-optimized cases
|
|
||||||
translateExpression(expr.left)
|
|
||||||
translateExpression(expr.right)
|
|
||||||
if((leftDt in ByteDatatypes && rightDt !in ByteDatatypes)
|
if((leftDt in ByteDatatypes && rightDt !in ByteDatatypes)
|
||||||
|| (leftDt in WordDatatypes && rightDt !in WordDatatypes))
|
|| (leftDt in WordDatatypes && rightDt !in WordDatatypes))
|
||||||
throw AssemblyError("binary operator ${expr.operator} left/right dt not identical")
|
throw AssemblyError("binary operator ${expr.operator} left/right dt not identical")
|
||||||
|
|
||||||
|
// the general, non-optimized cases TODO optimize more cases....
|
||||||
|
translateExpression(expr.left)
|
||||||
|
translateExpression(expr.right)
|
||||||
if(leftDt==DataType.STR && rightDt==DataType.STR && expr.operator in comparisonOperators) {
|
if(leftDt==DataType.STR && rightDt==DataType.STR && expr.operator in comparisonOperators) {
|
||||||
translateCompareStrings(expr.operator)
|
translateCompareStrings(expr.operator)
|
||||||
}
|
}
|
||||||
|
@ -668,7 +668,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
private fun inplaceModification_word_litval_to_variable(name: String, dt: DataType, operator: String, value: Int) {
|
private fun inplaceModification_word_litval_to_variable(name: String, dt: DataType, operator: String, value: Int) {
|
||||||
when (operator) {
|
when (operator) {
|
||||||
// note: ** (power) operator requires floats.
|
// note: ** (power) operator requires floats.
|
||||||
// TODO use these + and - optimizations in the expressionAsmGenerator as well. ****************************************
|
|
||||||
"+" -> {
|
"+" -> {
|
||||||
when {
|
when {
|
||||||
value==0 -> {}
|
value==0 -> {}
|
||||||
@ -683,6 +682,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
value==0x0100 -> asmgen.out(" inc $name+1")
|
value==0x0100 -> asmgen.out(" inc $name+1")
|
||||||
value==0x0200 -> asmgen.out(" inc $name+1 | inc $name+1")
|
value==0x0200 -> asmgen.out(" inc $name+1 | inc $name+1")
|
||||||
value==0x0300 -> asmgen.out(" inc $name+1 | inc $name+1 | inc $name+1")
|
value==0x0300 -> asmgen.out(" inc $name+1 | inc $name+1 | inc $name+1")
|
||||||
|
value==0x0400 -> asmgen.out(" inc $name+1 | inc $name+1 | inc $name+1 | inc $name+1")
|
||||||
value and 255==0 -> asmgen.out(" lda $name+1 | clc | adc #>$value | sta $name+1")
|
value and 255==0 -> asmgen.out(" lda $name+1 | clc | adc #>$value | sta $name+1")
|
||||||
else -> asmgen.out("""
|
else -> asmgen.out("""
|
||||||
lda $name
|
lda $name
|
||||||
@ -708,6 +708,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
value==0x0100 -> asmgen.out(" dec $name+1")
|
value==0x0100 -> asmgen.out(" dec $name+1")
|
||||||
value==0x0200 -> asmgen.out(" dec $name+1 | dec $name+1")
|
value==0x0200 -> asmgen.out(" dec $name+1 | dec $name+1")
|
||||||
value==0x0300 -> asmgen.out(" dec $name+1 | dec $name+1 | dec $name+1")
|
value==0x0300 -> asmgen.out(" dec $name+1 | dec $name+1 | dec $name+1")
|
||||||
|
value==0x0400 -> asmgen.out(" dec $name+1 | dec $name+1 | dec $name+1 | dec $name+1")
|
||||||
value and 255==0 -> asmgen.out(" lda $name+1 | sec | sbc #>$value | sta $name+1")
|
value and 255==0 -> asmgen.out(" lda $name+1 | sec | sbc #>$value | sta $name+1")
|
||||||
else -> asmgen.out("""
|
else -> asmgen.out("""
|
||||||
lda $name
|
lda $name
|
||||||
|
@ -7,18 +7,24 @@ main {
|
|||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
|
|
||||||
uword vv = 1111
|
uword vv = $1111
|
||||||
vv *= 23
|
uword vv2
|
||||||
txt.print_uw(vv)
|
vv2 = vv2+(vv/2)
|
||||||
|
vv2 = vv2+(vv - 1)
|
||||||
|
vv2 = vv2+(vv + $0200)
|
||||||
|
vv2 = vv2+(vv - $0400)
|
||||||
|
txt.print_uw(vv2)
|
||||||
txt.chrout('\n')
|
txt.chrout('\n')
|
||||||
|
|
||||||
word ww = -1111
|
word ww = -$1111
|
||||||
ww *= 23
|
word ww2 = 0
|
||||||
txt.print_w(ww)
|
ww2 = ww2 + ww + $0200
|
||||||
|
ww2 = ww2 +ww - $0400
|
||||||
|
txt.print_w(ww2)
|
||||||
txt.chrout('\n')
|
txt.chrout('\n')
|
||||||
ww = -1111
|
ww2= ww2 + ww + -$0200
|
||||||
ww *= -23
|
ww2= ww2 + ww - -$0400
|
||||||
txt.print_w(ww)
|
txt.print_w(ww2)
|
||||||
txt.chrout('\n')
|
txt.chrout('\n')
|
||||||
|
|
||||||
testX()
|
testX()
|
||||||
|
Loading…
Reference in New Issue
Block a user