This commit is contained in:
Irmen de Jong 2019-08-17 18:38:28 +02:00
parent 80113f9208
commit 59f8b91e25
5 changed files with 35 additions and 36 deletions

View File

@ -1 +1 @@
1.52
1.53-dev

View File

@ -21,37 +21,39 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
is NumericLiteralValue -> translateExpression(expression)
is RegisterExpr -> translateExpression(expression)
is IdentifierReference -> translateExpression(expression)
is FunctionCall -> {
val functionName = expression.target.nameInSource.last()
val builtinFunc = BuiltinFunctions[functionName]
if(builtinFunc!=null) {
asmgen.translateFunctioncallExpression(expression, builtinFunc)
} else {
asmgen.translateFunctionCall(expression)
val sub = expression.target.targetSubroutine(program.namespace)!!
val returns = sub.returntypes.zip(sub.asmReturnvaluesRegisters)
for((_, reg) in returns) {
if(!reg.stack) {
// result value in cpu or status registers, put it on the stack
if(reg.registerOrPair!=null) {
when(reg.registerOrPair) {
RegisterOrPair.A -> asmgen.out(" sta ${MachineDefinition.ESTACK_LO_HEX},x | dex")
RegisterOrPair.Y -> asmgen.out(" tya | sta ${MachineDefinition.ESTACK_LO_HEX},x | dex")
RegisterOrPair.AY -> asmgen.out(" sta ${MachineDefinition.ESTACK_LO_HEX},x | tya | sta ${MachineDefinition.ESTACK_HI_HEX},x | dex")
RegisterOrPair.X, RegisterOrPair.AX, RegisterOrPair.XY -> throw AssemblyError("can't push X register - use a variable")
}
}
// return value from a statusregister is not put on the stack, it should be acted on via a conditional branch such as if_cc
}
}
}
}
is FunctionCall -> translateExpression(expression)
is ArrayLiteralValue, is StringLiteralValue -> TODO("string/array/struct assignment?")
is StructLiteralValue -> throw AssemblyError("struct literal value assignment should have been flattened")
is RangeExpr -> throw AssemblyError("range expression should have been changed into array values")
}
}
private fun translateExpression(expression: FunctionCall) {
val functionName = expression.target.nameInSource.last()
val builtinFunc = BuiltinFunctions[functionName]
if (builtinFunc != null) {
asmgen.translateFunctioncallExpression(expression, builtinFunc)
} else {
asmgen.translateFunctionCall(expression)
val sub = expression.target.targetSubroutine(program.namespace)!!
val returns = sub.returntypes.zip(sub.asmReturnvaluesRegisters)
for ((_, reg) in returns) {
if (!reg.stack) {
// result value in cpu or status registers, put it on the stack
if (reg.registerOrPair != null) {
when (reg.registerOrPair) {
RegisterOrPair.A -> asmgen.out(" sta ${MachineDefinition.ESTACK_LO_HEX},x | dex")
RegisterOrPair.Y -> asmgen.out(" tya | sta ${MachineDefinition.ESTACK_LO_HEX},x | dex")
RegisterOrPair.AY -> asmgen.out(" sta ${MachineDefinition.ESTACK_LO_HEX},x | tya | sta ${MachineDefinition.ESTACK_HI_HEX},x | dex")
RegisterOrPair.X, RegisterOrPair.AX, RegisterOrPair.XY -> throw AssemblyError("can't push X register - use a variable")
}
}
// return value from a statusregister is not put on the stack, it should be acted on via a conditional branch such as if_cc
}
}
}
}
private fun translateExpression(expr: TypecastExpression) {
translateExpression(expr.expression)
when(expr.expression.inferType(program).typeOrElse(DataType.STRUCT)) {
@ -175,7 +177,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
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 val powersOfTwo = setOf(0,1,2,4,8,16,32,64,128,256)
private fun translateExpression(expr: BinaryExpression) {
val leftIDt = expr.left.inferType(program)
@ -215,7 +217,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
if(value!=null) {
if(rightDt in IntegerDatatypes) {
val amount = value.number.toInt()
if(amount in powerOfTwos)
if(amount in powersOfTwo)
printWarning("${expr.right.position} multiplication by power of 2 should have been optimized into a left shift instruction: $amount")
when(rightDt) {
DataType.UBYTE -> {
@ -312,7 +314,6 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
}
}
private fun translatePushFromArray(arrayExpr: ArrayIndexedExpression) {
// assume *reading* from an array
val index = arrayExpr.arrayspec.index

View File

@ -608,8 +608,8 @@ internal class SimplifyExpressions(private val program: Program) : IAstModifying
}
private val powersOfTwo = (1 .. 16).map { (2.0).pow(it) }
private val negativePowersOfTwo = powersOfTwo.map { -it }
private val powersOfTwo = (1 .. 16).map { (2.0).pow(it) }.toSet()
private val negativePowersOfTwo = powersOfTwo.map { -it }.toSet()
private fun optimizeDivision(expr: BinaryExpression, leftVal: NumericLiteralValue?, rightVal: NumericLiteralValue?): Expression {
if(leftVal==null && rightVal==null)
@ -712,7 +712,7 @@ internal class SimplifyExpressions(private val program: Program) : IAstModifying
optimizationsDone++
return expr.left
}
2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0, 512.0, 1024.0, 2048.0, 4096.0, 8192.0, 16384.0, 32768.0, 65536.0 -> {
in powersOfTwo -> {
if(leftValue.inferType(program).typeOrElse(DataType.STRUCT) in IntegerDatatypes) {
// times a power of two => shift left
optimizationsDone++
@ -720,7 +720,7 @@ internal class SimplifyExpressions(private val program: Program) : IAstModifying
return BinaryExpression(expr.left, "<<", NumericLiteralValue.optimalInteger(numshifts, expr.position), expr.position)
}
}
-2.0, -4.0, -8.0, -16.0, -32.0, -64.0, -128.0, -256.0, -512.0, -1024.0, -2048.0, -4096.0, -8192.0, -16384.0, -32768.0, -65536.0 -> {
in negativePowersOfTwo -> {
if(leftValue.inferType(program).typeOrElse(DataType.STRUCT) in IntegerDatatypes) {
// times a negative power of two => negate, then shift left
optimizationsDone++

View File

@ -1,8 +1,6 @@
%import c64lib
%import c64utils
; TODO: some optimizer breaks this.. runs fine without optimization
spritedata $2000 {
; this memory block contains the sprite data
; it must start on an address aligned to 64 bytes.

View File

@ -2,7 +2,7 @@
%zeropage basicsafe
%option enable_floats
; TODO complete codegeneration for all lines in this
; TODO complete asm code generation for all lines in this