mirror of
https://github.com/irmen/prog8.git
synced 2024-12-24 16:29:21 +00:00
added optimized multiplications to asmgen2
This commit is contained in:
parent
6544fcdc36
commit
5095d090cc
@ -300,9 +300,7 @@ internal class AsmGen2(val program: Program,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
DataType.ARRAY_F -> {
|
DataType.ARRAY_F -> {
|
||||||
val array = (decl.value as ReferenceLiteralValue).array
|
val array = (decl.value as ReferenceLiteralValue).array ?: throw AssemblyError("array should not be null?")
|
||||||
if(array==null)
|
|
||||||
TODO("fix this")
|
|
||||||
val floatFills = array.map {
|
val floatFills = array.map {
|
||||||
val number = (it as NumericLiteralValue).number
|
val number = (it as NumericLiteralValue).number
|
||||||
makeFloatFill(MachineDefinition.Mflpt5.fromNumber(number))
|
makeFloatFill(MachineDefinition.Mflpt5.fromNumber(number))
|
||||||
@ -367,9 +365,7 @@ internal class AsmGen2(val program: Program,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun makeArrayFillDataUnsigned(decl: VarDecl): List<String> {
|
private fun makeArrayFillDataUnsigned(decl: VarDecl): List<String> {
|
||||||
val array = (decl.value as ReferenceLiteralValue).array
|
val array = (decl.value as ReferenceLiteralValue).array ?: throw AssemblyError("array should not be null?")
|
||||||
if(array==null)
|
|
||||||
TODO("fix this")
|
|
||||||
return when {
|
return when {
|
||||||
decl.datatype == DataType.ARRAY_UB ->
|
decl.datatype == DataType.ARRAY_UB ->
|
||||||
// byte array can never contain pointer-to types, so treat values as all integers
|
// byte array can never contain pointer-to types, so treat values as all integers
|
||||||
@ -387,9 +383,7 @@ internal class AsmGen2(val program: Program,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun makeArrayFillDataSigned(decl: VarDecl): List<String> {
|
private fun makeArrayFillDataSigned(decl: VarDecl): List<String> {
|
||||||
val array = (decl.value as ReferenceLiteralValue).array
|
val array = (decl.value as ReferenceLiteralValue).array ?: throw AssemblyError("array should not be null?")
|
||||||
if(array==null)
|
|
||||||
TODO("fix this ${decl.value}")
|
|
||||||
|
|
||||||
return when {
|
return when {
|
||||||
decl.datatype == DataType.ARRAY_UB ->
|
decl.datatype == DataType.ARRAY_UB ->
|
||||||
@ -1865,9 +1859,15 @@ $endLabel""")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val optimizedByteMultiplications = setOf(3,5,6,7,9,10,11,12,13,14,15,20,25,40)
|
||||||
|
private val optimizedWordMultiplications = setOf(3,5,6,7,9,10,12,15,20,25,40)
|
||||||
|
private val powerOfTwos = setOf(0,1,2,4,8,16,32,64,128,256)
|
||||||
|
|
||||||
private fun translateExpression(expr: BinaryExpression) {
|
private fun translateExpression(expr: BinaryExpression) {
|
||||||
val leftDt = expr.left.inferType(program)!!
|
val leftDt = expr.left.inferType(program)!!
|
||||||
val rightDt = expr.right.inferType(program)!!
|
val rightDt = expr.right.inferType(program)!!
|
||||||
|
|
||||||
|
// see if we can apply some optimized routines
|
||||||
when(expr.operator) {
|
when(expr.operator) {
|
||||||
">>" -> {
|
">>" -> {
|
||||||
// bit-shifts are always by a constant number (for now)
|
// bit-shifts are always by a constant number (for now)
|
||||||
@ -1880,6 +1880,7 @@ $endLabel""")
|
|||||||
DataType.WORD -> repeat(amount) { out(" lda $ESTACK_HI_PLUS1_HEX,x | asl a | ror $ESTACK_HI_PLUS1_HEX,x | ror $ESTACK_LO_PLUS1_HEX,x") }
|
DataType.WORD -> repeat(amount) { out(" lda $ESTACK_HI_PLUS1_HEX,x | asl a | ror $ESTACK_HI_PLUS1_HEX,x | ror $ESTACK_LO_PLUS1_HEX,x") }
|
||||||
else -> throw AssemblyError("weird type")
|
else -> throw AssemblyError("weird type")
|
||||||
}
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
"<<" -> {
|
"<<" -> {
|
||||||
// bit-shifts are always by a constant number (for now)
|
// bit-shifts are always by a constant number (for now)
|
||||||
@ -1889,8 +1890,62 @@ $endLabel""")
|
|||||||
repeat(amount) { out(" asl $ESTACK_LO_PLUS1_HEX,x") }
|
repeat(amount) { out(" asl $ESTACK_LO_PLUS1_HEX,x") }
|
||||||
else
|
else
|
||||||
repeat(amount) { out(" asl $ESTACK_LO_PLUS1_HEX,x | rol $ESTACK_HI_PLUS1_HEX,x") }
|
repeat(amount) { out(" asl $ESTACK_LO_PLUS1_HEX,x | rol $ESTACK_HI_PLUS1_HEX,x") }
|
||||||
|
return
|
||||||
}
|
}
|
||||||
else -> {
|
"*" -> {
|
||||||
|
val value = expr.right.constValue(program)
|
||||||
|
if(value!=null) {
|
||||||
|
if(rightDt in IntegerDatatypes) {
|
||||||
|
val amount = value.number.toInt()
|
||||||
|
if(amount in powerOfTwos)
|
||||||
|
printWarning("${expr.right.position} multiplication by power of 2 should have been optimized into a left shift instruction: $amount")
|
||||||
|
when(rightDt) {
|
||||||
|
DataType.UBYTE -> {
|
||||||
|
if(amount in optimizedByteMultiplications) {
|
||||||
|
translateExpression(expr.left)
|
||||||
|
out(" jsr math.mul_byte_$amount")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DataType.BYTE -> {
|
||||||
|
if(amount in optimizedByteMultiplications) {
|
||||||
|
translateExpression(expr.left)
|
||||||
|
out(" jsr math.mul_byte_$amount")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if(amount.absoluteValue in optimizedByteMultiplications) {
|
||||||
|
translateExpression(expr.left)
|
||||||
|
out(" jsr prog8_lib.neg_b | jsr math.mul_byte_${amount.absoluteValue}")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DataType.UWORD -> {
|
||||||
|
if(amount in optimizedWordMultiplications) {
|
||||||
|
translateExpression(expr.left)
|
||||||
|
out(" jsr math.mul_word_$amount")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DataType.WORD -> {
|
||||||
|
if(amount in optimizedWordMultiplications) {
|
||||||
|
translateExpression(expr.left)
|
||||||
|
out(" jsr math.mul_word_$amount")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if(amount.absoluteValue in optimizedWordMultiplications) {
|
||||||
|
translateExpression(expr.left)
|
||||||
|
out(" jsr prog8_lib.neg_w | jsr math.mul_word_${amount.absoluteValue}")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// the general, non-optimized cases
|
||||||
translateExpression(expr.left)
|
translateExpression(expr.left)
|
||||||
translateExpression(expr.right)
|
translateExpression(expr.right)
|
||||||
if(leftDt!=rightDt)
|
if(leftDt!=rightDt)
|
||||||
@ -1902,8 +1957,6 @@ $endLabel""")
|
|||||||
else -> throw AssemblyError("non-numerical datatype")
|
else -> throw AssemblyError("non-numerical datatype")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun translateExpression(expr: PrefixExpression) {
|
private fun translateExpression(expr: PrefixExpression) {
|
||||||
translateExpression(expr.expression)
|
translateExpression(expr.expression)
|
||||||
|
@ -75,22 +75,28 @@ main {
|
|||||||
; plot the points of the 3d cube
|
; plot the points of the 3d cube
|
||||||
; first the points on the back, then the points on the front (painter algorithm)
|
; first the points on the back, then the points on the front (painter algorithm)
|
||||||
|
|
||||||
for ubyte i in 0 to len(xcoor)-1 {
|
ubyte i
|
||||||
word rz = rotatedz[i]
|
word rz
|
||||||
|
word persp
|
||||||
|
byte sx
|
||||||
|
byte sy
|
||||||
|
|
||||||
|
for i in 0 to len(xcoor)-1 {
|
||||||
|
rz = rotatedz[i]
|
||||||
if rz >= 10 {
|
if rz >= 10 {
|
||||||
word persp = (rz+200) / height
|
persp = (rz+200) / height
|
||||||
byte sx = rotatedx[i] / persp as byte + width/2
|
sx = rotatedx[i] / persp as byte + width/2
|
||||||
byte sy = rotatedy[i] / persp as byte + height/2
|
sy = rotatedy[i] / persp as byte + height/2
|
||||||
c64scr.setcc(sx as ubyte, sy as ubyte, 46, vertexcolors[(rz as byte >>5) + 3])
|
c64scr.setcc(sx as ubyte, sy as ubyte, 46, vertexcolors[(rz as byte >>5) + 3])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for ubyte i in 0 to len(xcoor)-1 {
|
for i in 0 to len(xcoor)-1 {
|
||||||
word rz = rotatedz[i]
|
rz = rotatedz[i]
|
||||||
if rz < 10 {
|
if rz < 10 {
|
||||||
word persp = (rz+200) / height
|
persp = (rz+200) / height
|
||||||
byte sx = rotatedx[i] / persp as byte + width/2
|
sx = rotatedx[i] / persp as byte + width/2
|
||||||
byte sy = rotatedy[i] / persp as byte + height/2
|
sy = rotatedy[i] / persp as byte + height/2
|
||||||
c64scr.setcc(sx as ubyte, sy as ubyte, 81, vertexcolors[(rz as byte >>5) + 3])
|
c64scr.setcc(sx as ubyte, sy as ubyte, 81, vertexcolors[(rz as byte >>5) + 3])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
135
examples/test.p8
135
examples/test.p8
@ -8,135 +8,20 @@ main {
|
|||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
|
|
||||||
c64scr.plot(0,24)
|
byte bb
|
||||||
|
ubyte ub
|
||||||
|
word ww
|
||||||
|
uword uw
|
||||||
|
float fl
|
||||||
|
|
||||||
ubyte ub=200
|
bb = 10*bb
|
||||||
byte bb=-100
|
ub = 12*ub
|
||||||
uword uw = 2000
|
ww = 15*ww
|
||||||
word ww = -1000
|
uw = 20*uw
|
||||||
float fl = 999.99
|
fl = 20*fl
|
||||||
ubyte[3] ubarr = 200
|
|
||||||
byte[3] barr = -100
|
|
||||||
uword[3] uwarr = 2000
|
|
||||||
word[3] warr = -1000
|
|
||||||
float[3] flarr = 999.99
|
|
||||||
|
|
||||||
c64scr.print("++\n")
|
|
||||||
ub++
|
|
||||||
bb++
|
|
||||||
uw++
|
|
||||||
ww++
|
|
||||||
fl++
|
|
||||||
ubarr[1]++
|
|
||||||
barr[1]++
|
|
||||||
uwarr[1]++
|
|
||||||
warr[1]++
|
|
||||||
flarr[1] ++
|
|
||||||
|
|
||||||
check_ub(ub, 201)
|
|
||||||
Y=100
|
|
||||||
Y++
|
|
||||||
check_ub(Y, 101)
|
|
||||||
check_fl(fl, 1000.99)
|
|
||||||
check_b(bb, -99)
|
|
||||||
check_uw(uw, 2001)
|
|
||||||
check_w(ww, -999)
|
|
||||||
check_ub(ubarr[0], 200)
|
|
||||||
check_fl(flarr[0], 999.99)
|
|
||||||
check_b(barr[0], -100)
|
|
||||||
check_uw(uwarr[0], 2000)
|
|
||||||
check_w(warr[0], -1000)
|
|
||||||
check_ub(ubarr[1], 201)
|
|
||||||
check_fl(flarr[1], 1000.99)
|
|
||||||
check_b(barr[1], -99)
|
|
||||||
check_uw(uwarr[1], 2001)
|
|
||||||
check_w(warr[1], -999)
|
|
||||||
|
|
||||||
c64scr.print("--\n")
|
|
||||||
ub--
|
|
||||||
bb--
|
|
||||||
uw--
|
|
||||||
ww--
|
|
||||||
fl--
|
|
||||||
ubarr[1]--
|
|
||||||
barr[1]--
|
|
||||||
uwarr[1]--
|
|
||||||
warr[1]--
|
|
||||||
flarr[1] --
|
|
||||||
check_ub(ub, 200)
|
|
||||||
Y=100
|
|
||||||
Y--
|
|
||||||
check_ub(Y, 99)
|
|
||||||
check_fl(fl, 999.99)
|
|
||||||
check_b(bb, -100)
|
|
||||||
check_uw(uw, 2000)
|
|
||||||
check_w(ww, -1000)
|
|
||||||
check_ub(ubarr[1], 200)
|
|
||||||
check_fl(flarr[1], 999.99)
|
|
||||||
check_b(barr[1], -100)
|
|
||||||
check_uw(uwarr[1], 2000)
|
|
||||||
check_w(warr[1], -1000)
|
|
||||||
|
|
||||||
@($0400+400-1) = X
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub check_ub(ubyte value, ubyte expected) {
|
|
||||||
if value==expected
|
|
||||||
c64scr.print(" ok ")
|
|
||||||
else
|
|
||||||
c64scr.print("err! ")
|
|
||||||
c64scr.print(" ubyte ")
|
|
||||||
c64scr.print_ub(value)
|
|
||||||
c64.CHROUT(',')
|
|
||||||
c64scr.print_ub(expected)
|
|
||||||
c64.CHROUT('\n')
|
|
||||||
}
|
|
||||||
|
|
||||||
sub check_b(byte value, byte expected) {
|
|
||||||
if value==expected
|
|
||||||
c64scr.print(" ok ")
|
|
||||||
else
|
|
||||||
c64scr.print("err! ")
|
|
||||||
c64scr.print(" byte ")
|
|
||||||
c64scr.print_b(value)
|
|
||||||
c64.CHROUT(',')
|
|
||||||
c64scr.print_b(expected)
|
|
||||||
c64.CHROUT('\n')
|
|
||||||
}
|
|
||||||
|
|
||||||
sub check_uw(uword value, uword expected) {
|
|
||||||
if value==expected
|
|
||||||
c64scr.print(" ok ")
|
|
||||||
else
|
|
||||||
c64scr.print("err! ")
|
|
||||||
c64scr.print(" uword ")
|
|
||||||
c64scr.print_uw(value)
|
|
||||||
c64.CHROUT(',')
|
|
||||||
c64scr.print_uw(expected)
|
|
||||||
c64.CHROUT('\n')
|
|
||||||
}
|
|
||||||
|
|
||||||
sub check_w(word value, word expected) {
|
|
||||||
if value==expected
|
|
||||||
c64scr.print(" ok ")
|
|
||||||
else
|
|
||||||
c64scr.print("err! ")
|
|
||||||
c64scr.print(" word ")
|
|
||||||
c64scr.print_w(value)
|
|
||||||
c64.CHROUT(',')
|
|
||||||
c64scr.print_w(expected)
|
|
||||||
c64.CHROUT('\n')
|
|
||||||
}
|
|
||||||
|
|
||||||
sub check_fl(float value, float expected) {
|
|
||||||
if value==expected
|
|
||||||
c64scr.print(" ok ")
|
|
||||||
else
|
|
||||||
c64scr.print("err! ")
|
|
||||||
c64scr.print(" float ")
|
|
||||||
c64flt.print_f(value)
|
|
||||||
c64.CHROUT(',')
|
|
||||||
c64flt.print_f(expected)
|
|
||||||
c64.CHROUT('\n')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user