refactoring

This commit is contained in:
Irmen de Jong 2020-08-23 18:20:57 +02:00
parent 1be139759c
commit 3991d23a69
7 changed files with 280 additions and 149 deletions

View File

@ -8,6 +8,7 @@ import prog8.ast.base.*
import prog8.ast.expressions.*
import prog8.ast.statements.*
import prog8.compiler.*
import prog8.compiler.target.CompilationTarget
import prog8.compiler.target.IAssemblyGenerator
import prog8.compiler.target.IAssemblyProgram
import prog8.compiler.target.c64.AssemblyProgram
@ -515,27 +516,6 @@ internal class AsmGen(private val program: Program,
internal fun fixNameSymbols(name: String) = name.replace("<", "prog8_").replace(">", "") // take care of the autogenerated invalid (anon) label names
internal fun readAndPushArrayvalueWithIndexA(elementDt: DataType, variable: IdentifierReference) {
val variablename = asmIdentifierName(variable)
when (elementDt) {
in ByteDatatypes ->
out(" tay | lda $variablename,y | sta $ESTACK_LO_HEX,x | dex")
in WordDatatypes ->
out(" asl a | tay | lda $variablename,y | sta $ESTACK_LO_HEX,x | lda $variablename+1,y | sta $ESTACK_HI_HEX,x | dex")
DataType.FLOAT ->
// index * 5 is done in the subroutine that's called
out("""
sta $ESTACK_LO_HEX,x
dex
lda #<$variablename
ldy #>$variablename
jsr c64flt.push_float_from_indexed_var
""")
else ->
throw AssemblyError("weird array elt type")
}
}
internal fun saveRegister(register: CpuRegister) {
when(register) {
CpuRegister.A -> out(" pha")
@ -603,9 +583,9 @@ internal class AsmGen(private val program: Program,
}
}
internal fun translateArrayIndexIntoA(expr: ArrayIndexedExpression) {
internal fun loadUnscaledArrayIndexIntoA(expr: ArrayIndexedExpression) {
when (val index = expr.arrayspec.index) {
is NumericLiteralValue -> throw AssemblyError("this should be optimized directly")
is NumericLiteralValue -> throw AssemblyError("constant array index should be optimized earlier")
is IdentifierReference -> {
val indexName = asmIdentifierName(index)
out(" lda $indexName")
@ -617,6 +597,100 @@ internal class AsmGen(private val program: Program,
}
}
internal fun loadScaledArrayIndexIntoRegister(expr: ArrayIndexedExpression,
elementDt: DataType,
register: CpuRegister,
addOneExtra: Boolean=false) {
val reg = register.toString().toLowerCase()
val index = expr.arrayspec.index
if(index is NumericLiteralValue) {
val indexValue = index.number.toInt() * elementDt.memorySize() + if(addOneExtra) 1 else 0
out(" ld$reg #$indexValue")
return
}
if(addOneExtra) {
// add 1 to the result
if (index is IdentifierReference) {
val indexName = asmIdentifierName(index)
when(elementDt) {
in ByteDatatypes -> {
out(" ldy $indexName | iny")
when(register) {
CpuRegister.A -> out(" tya")
CpuRegister.X -> out(" tyx")
CpuRegister.Y -> {}
}
}
in WordDatatypes -> {
out(" lda $indexName | sec | rol a")
when(register) {
CpuRegister.A -> {}
CpuRegister.X -> out(" tax")
CpuRegister.Y -> out(" tay")
}
}
DataType.FLOAT -> {
require(DataType.FLOAT.memorySize()==5)
out("""
lda $indexName
asl a
asl a
sec
adc $indexName""")
when(register) {
CpuRegister.A -> {}
CpuRegister.X -> out(" tax")
CpuRegister.Y -> out(" tay")
}
}
else -> throw AssemblyError("weird dt")
}
}
else {
TODO("+1")
}
} else {
if (index is IdentifierReference) {
val indexName = asmIdentifierName(index)
when(elementDt) {
in ByteDatatypes -> out(" ld$reg $indexName")
in WordDatatypes -> {
out(" lda $indexName | asl a")
when(register) {
CpuRegister.A -> {}
CpuRegister.X -> out(" tax")
CpuRegister.Y -> out(" tay")
}
}
DataType.FLOAT -> {
require(DataType.FLOAT.memorySize()==5)
out("""
lda $indexName
asl a
asl a
clc
adc $indexName""")
when(register) {
CpuRegister.A -> {}
CpuRegister.X -> out(" tax")
CpuRegister.Y -> out(" tay")
}
}
else -> throw AssemblyError("weird dt")
}
}
else {
expressionsAsmGen.translateExpression(index)
when(register) {
CpuRegister.A -> out(" inx | lda $ESTACK_LO_HEX,x")
CpuRegister.X -> throw AssemblyError("can't use X here")
CpuRegister.Y -> out(" inx | ldy $ESTACK_LO_HEX,x")
}
}
}
}
internal fun translateExpression(expression: Expression) =
expressionsAsmGen.translateExpression(expression)

View File

@ -20,7 +20,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
when(expression) {
is PrefixExpression -> translateExpression(expression)
is BinaryExpression -> translateExpression(expression)
is ArrayIndexedExpression -> translatePushFromArray(expression)
is ArrayIndexedExpression -> translateExpression(expression)
is TypecastExpression -> translateExpression(expression)
is AddressOf -> translateExpression(expression)
is DirectMemoryRead -> translateExpression(expression)
@ -384,8 +384,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
}
}
private fun translatePushFromArray(arrayExpr: ArrayIndexedExpression) {
// assume *reading* from an array
private fun translateExpression(arrayExpr: ArrayIndexedExpression) {
val index = arrayExpr.arrayspec.index
val elementDt = arrayExpr.inferType(program).typeOrElse(DataType.STRUCT)
val arrayVarName = asmgen.asmIdentifierName(arrayExpr.identifier)
@ -404,8 +403,28 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
else -> throw AssemblyError("weird element type")
}
} else {
asmgen.translateArrayIndexIntoA(arrayExpr)
asmgen.readAndPushArrayvalueWithIndexA(elementDt, arrayExpr.identifier)
when(elementDt) {
in ByteDatatypes -> {
asmgen.loadScaledArrayIndexIntoRegister(arrayExpr, elementDt, CpuRegister.Y)
asmgen.out(" lda $arrayVarName,y | sta $ESTACK_LO_HEX,x | dex")
}
in WordDatatypes -> {
asmgen.loadScaledArrayIndexIntoRegister(arrayExpr, elementDt, CpuRegister.Y)
asmgen.out(" lda $arrayVarName,y | sta $ESTACK_LO_HEX,x | lda $arrayVarName+1,y | sta $ESTACK_HI_HEX,x | dex")
}
DataType.FLOAT -> {
asmgen.loadScaledArrayIndexIntoRegister(arrayExpr, elementDt, CpuRegister.A)
asmgen.out("""
ldy #>$arrayVarName
clc
adc #<$arrayVarName
bcc +
iny
+ jsr c64flt.push_float""")
}
else -> throw AssemblyError("weird dt")
}
}
}

View File

@ -99,12 +99,14 @@ internal class PostIncrDecrAsmGen(private val program: Program, private val asmg
}
}
is IdentifierReference -> {
asmgen.translateArrayIndexIntoA(targetArrayIdx)
incrDecrArrayvalueWithIndexA(incr, elementDt, what)
// TODO rewrite using scaled?
asmgen.loadUnscaledArrayIndexIntoA(targetArrayIdx)
incrDecrArrayvalueWithIndexA(incr, elementDt, what) // TODO is this ok for word/float array?
}
else -> {
asmgen.translateArrayIndexIntoA(targetArrayIdx)
incrDecrArrayvalueWithIndexA(incr, elementDt, what)
// TODO rewrite using scaled?
asmgen.loadUnscaledArrayIndexIntoA(targetArrayIdx)
incrDecrArrayvalueWithIndexA(incr, elementDt, what)// TODO is this ok for word/float array?
}
}
}

View File

@ -42,7 +42,7 @@ internal class AsmAssignTarget(val kind: TargetStorageKind,
val constMemoryAddress by lazy { memory?.addressExpression?.constValue(program)?.number?.toInt() ?: 0}
val constArrayIndexValue by lazy { array?.arrayspec?.constIndex() }
val vardecl by lazy { variable?.targetVarDecl(program.namespace)!! }
val asmName by lazy {
val asmVarname by lazy {
if(variable!=null)
asmgen.asmIdentifierName(variable)
else

View File

@ -5,7 +5,6 @@ import prog8.ast.base.*
import prog8.ast.expressions.*
import prog8.ast.statements.*
import prog8.compiler.AssemblyError
import prog8.compiler.target.c64.C64MachineDefinition
import prog8.compiler.target.c64.C64MachineDefinition.C64Zeropage
import prog8.compiler.target.c64.C64MachineDefinition.ESTACK_HI_HEX
import prog8.compiler.target.c64.C64MachineDefinition.ESTACK_LO_HEX
@ -33,6 +32,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
}
val assign = AsmAssignment(source, target, assignment.isAugmentable, assignment.position)
target.origAssign = assign
if(assign.isAugmentable)
augmentableAsmGen.translate(assign)
@ -67,9 +67,9 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
val value = assign.source.array!!
val elementDt = assign.source.datatype
val index = value.arrayspec.index
val arrayVarName = asmgen.asmIdentifierName(value.identifier)
if (index is NumericLiteralValue) {
// constant array index value
val arrayVarName = asmgen.asmIdentifierName(value.identifier)
val indexValue = index.number.toInt() * elementDt.memorySize()
when (elementDt) {
in ByteDatatypes ->
@ -82,8 +82,9 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
throw AssemblyError("weird array type")
}
} else {
asmgen.translateArrayIndexIntoA(value)
asmgen.readAndPushArrayvalueWithIndexA(elementDt, value.identifier)
// TODO rewrite to use Scaled
asmgen.loadUnscaledArrayIndexIntoA(value)
readAndPushArrayvalueWithUnscaledIndexA(elementDt, arrayVarName)
}
assignStackValue(assign.target)
}
@ -137,21 +138,21 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
TargetStorageKind.VARIABLE -> {
when (target.datatype) {
DataType.UBYTE, DataType.BYTE -> {
asmgen.out(" inx | lda $ESTACK_LO_HEX,x | sta ${target.asmName}")
asmgen.out(" inx | lda $ESTACK_LO_HEX,x | sta ${target.asmVarname}")
}
DataType.UWORD, DataType.WORD -> {
asmgen.out("""
inx
lda $ESTACK_LO_HEX,x
sta ${target.asmName}
sta ${target.asmVarname}
lda $ESTACK_HI_HEX,x
sta ${target.asmName}+1
sta ${target.asmVarname}+1
""")
}
DataType.FLOAT -> {
asmgen.out("""
lda #<${target.asmName}
ldy #>${target.asmName}
lda #<${target.asmVarname}
ldy #>${target.asmVarname}
jsr c64flt.pop_float
""")
}
@ -164,10 +165,9 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
}
TargetStorageKind.ARRAY -> {
val targetArrayIdx = target.array!!
val arrayDt = targetArrayIdx.identifier.inferType(program).typeOrElse(DataType.STRUCT)
asmgen.translateExpression(targetArrayIdx.arrayspec.index)
asmgen.out(" inx | lda $ESTACK_LO_HEX,x")
popAndWriteArrayvalueWithIndexA(arrayDt, target.asmName)
popAndWriteArrayvalueWithUnscaledIndexA(target.datatype, target.asmVarname)
}
TargetStorageKind.REGISTER -> TODO()
TargetStorageKind.STACK -> TODO()
@ -193,8 +193,8 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
asmgen.out("""
lda #<$sourceName
ldy #>$sourceName
sta ${target.asmName}
sty ${target.asmName}+1
sta ${target.asmVarname}
sty ${target.asmVarname}+1
""")
}
TargetStorageKind.MEMORY -> {
@ -203,7 +203,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
TargetStorageKind.ARRAY -> {
val targetArrayIdx = target.array!!
val index = targetArrayIdx.arrayspec.index
throw AssemblyError("no asm gen for assign address $sourceName to array ${target.asmName} [ $index ]")
throw AssemblyError("no asm gen for assign address $sourceName to array ${target.asmVarname} [ $index ]")
}
TargetStorageKind.REGISTER -> TODO()
TargetStorageKind.STACK -> TODO()
@ -217,8 +217,8 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
asmgen.out("""
lda $sourceName
ldy $sourceName+1
sta ${target.asmName}
sty ${target.asmName}+1
sta ${target.asmVarname}
sty ${target.asmVarname}+1
""")
}
TargetStorageKind.MEMORY -> {
@ -230,8 +230,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
asmgen.out(" lda $sourceName | sta $ESTACK_LO_HEX,x | lda $sourceName+1 | sta $ESTACK_HI_HEX,x | dex")
asmgen.translateExpression(index)
asmgen.out(" inx | lda $ESTACK_LO_HEX,x")
val arrayDt = targetArrayIdx.identifier.inferType(program).typeOrElse(DataType.STRUCT)
popAndWriteArrayvalueWithIndexA(arrayDt, target.asmName)
popAndWriteArrayvalueWithUnscaledIndexA(target.datatype, target.asmVarname)
}
TargetStorageKind.REGISTER -> TODO()
TargetStorageKind.STACK -> TODO()
@ -244,15 +243,15 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
TargetStorageKind.VARIABLE -> {
asmgen.out("""
lda $sourceName
sta ${target.asmName}
sta ${target.asmVarname}
lda $sourceName+1
sta ${target.asmName}+1
sta ${target.asmVarname}+1
lda $sourceName+2
sta ${target.asmName}+2
sta ${target.asmVarname}+2
lda $sourceName+3
sta ${target.asmName}+3
sta ${target.asmVarname}+3
lda $sourceName+4
sta ${target.asmName}+4
sta ${target.asmVarname}+4
""")
}
TargetStorageKind.ARRAY -> {
@ -272,7 +271,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
TargetStorageKind.VARIABLE -> {
asmgen.out("""
lda $sourceName
sta ${target.asmName}
sta ${target.asmVarname}
""")
}
TargetStorageKind.MEMORY -> {
@ -281,11 +280,10 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
TargetStorageKind.ARRAY -> {
val targetArrayIdx = target.array!!
val index = targetArrayIdx.arrayspec.index
val arrayDt = targetArrayIdx.identifier.inferType(program).typeOrElse(DataType.STRUCT)
asmgen.out(" lda $sourceName | sta $ESTACK_LO_HEX,x | dex")
asmgen.translateExpression(index)
asmgen.out(" inx | lda $ESTACK_LO_HEX,x")
popAndWriteArrayvalueWithIndexA(arrayDt, target.asmName)
popAndWriteArrayvalueWithUnscaledIndexA(target.datatype, target.asmVarname)
}
TargetStorageKind.REGISTER -> TODO()
TargetStorageKind.STACK -> TODO()
@ -296,7 +294,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
require(target.datatype in ByteDatatypes)
when(target.kind) {
TargetStorageKind.VARIABLE -> {
asmgen.out(" st${register.name.toLowerCase()} ${target.asmName}")
asmgen.out(" st${register.name.toLowerCase()} ${target.asmVarname}")
}
TargetStorageKind.MEMORY -> {
storeRegisterInMemoryAddress(register, target.memory!!)
@ -308,9 +306,9 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
is NumericLiteralValue -> {
val memindex = index.number.toInt()
when (register) {
CpuRegister.A -> asmgen.out(" sta ${target.asmName}+$memindex")
CpuRegister.X -> asmgen.out(" stx ${target.asmName}+$memindex")
CpuRegister.Y -> asmgen.out(" sty ${target.asmName}+$memindex")
CpuRegister.A -> asmgen.out(" sta ${target.asmVarname}+$memindex")
CpuRegister.X -> asmgen.out(" stx ${target.asmVarname}+$memindex")
CpuRegister.Y -> asmgen.out(" sty ${target.asmVarname}+$memindex")
}
}
is IdentifierReference -> {
@ -323,7 +321,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
lda ${asmgen.asmIdentifierName(index)}
tay
lda ${C64Zeropage.SCRATCH_B1}
sta ${target.asmName},y
sta ${target.asmVarname},y
""")
}
else -> {
@ -340,7 +338,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
lda $ESTACK_LO_HEX,x
tay
lda ${C64Zeropage.SCRATCH_B1}
sta ${target.asmName},y
sta ${target.asmVarname},y
""")
}
}
@ -357,15 +355,15 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
// lsb=msb
asmgen.out("""
lda #${(word and 255).toHex()}
sta ${target.asmName}
sta ${target.asmName}+1
sta ${target.asmVarname}
sta ${target.asmVarname}+1
""")
} else {
asmgen.out("""
lda #<${word.toHex()}
ldy #>${word.toHex()}
sta ${target.asmName}
sty ${target.asmName}+1
sta ${target.asmVarname}
sty ${target.asmVarname}+1
""")
}
}
@ -395,7 +393,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
private fun assignConstantByte(target: AsmAssignTarget, byte: Short) {
when(target.kind) {
TargetStorageKind.VARIABLE -> {
asmgen.out(" lda #${byte.toHex()} | sta ${target.asmName} ")
asmgen.out(" lda #${byte.toHex()} | sta ${target.asmVarname} ")
}
TargetStorageKind.MEMORY -> {
storeByteViaRegisterAInMemoryAddress("#${byte.toHex()}", target.memory!!)
@ -422,31 +420,31 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
TargetStorageKind.VARIABLE -> {
asmgen.out("""
lda #0
sta ${target.asmName}
sta ${target.asmName}+1
sta ${target.asmName}+2
sta ${target.asmName}+3
sta ${target.asmName}+4
sta ${target.asmVarname}
sta ${target.asmVarname}+1
sta ${target.asmVarname}+2
sta ${target.asmVarname}+3
sta ${target.asmVarname}+4
""")
}
TargetStorageKind.ARRAY -> {
val index = target.array!!.arrayspec.index
if (index is NumericLiteralValue) {
val indexValue = index.number.toInt() * C64MachineDefinition.FLOAT_MEM_SIZE
val indexValue = index.number.toInt() * DataType.FLOAT.memorySize()
asmgen.out("""
lda #0
sta ${target.asmName}+$indexValue
sta ${target.asmName}+$indexValue+1
sta ${target.asmName}+$indexValue+2
sta ${target.asmName}+$indexValue+3
sta ${target.asmName}+$indexValue+4
sta ${target.asmVarname}+$indexValue
sta ${target.asmVarname}+$indexValue+1
sta ${target.asmVarname}+$indexValue+2
sta ${target.asmVarname}+$indexValue+3
sta ${target.asmVarname}+$indexValue+4
""")
} else {
asmgen.translateExpression(index)
asmgen.out("""
lda #<${target.asmName}
lda #<${target.asmVarname}
sta ${C64Zeropage.SCRATCH_W1}
lda #>${target.asmName}
lda #>${target.asmVarname}
sta ${C64Zeropage.SCRATCH_W1 + 1}
jsr c64flt.set_0_array_float
""")
@ -461,22 +459,22 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
TargetStorageKind.VARIABLE -> {
asmgen.out("""
lda $constFloat
sta ${target.asmName}
sta ${target.asmVarname}
lda $constFloat+1
sta ${target.asmName}+1
sta ${target.asmVarname}+1
lda $constFloat+2
sta ${target.asmName}+2
sta ${target.asmVarname}+2
lda $constFloat+3
sta ${target.asmName}+3
sta ${target.asmVarname}+3
lda $constFloat+4
sta ${target.asmName}+4
sta ${target.asmVarname}+4
""")
}
TargetStorageKind.ARRAY -> {
val index = target.array!!.arrayspec.index
val arrayVarName = asmgen.asmIdentifierName(target.array.identifier)
if (index is NumericLiteralValue) {
val indexValue = index.number.toInt() * C64MachineDefinition.FLOAT_MEM_SIZE
val indexValue = index.number.toInt() * DataType.FLOAT.memorySize()
asmgen.out("""
lda $constFloat
sta $arrayVarName+$indexValue
@ -515,7 +513,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
TargetStorageKind.VARIABLE -> {
asmgen.out("""
lda ${address.toHex()}
sta ${target.asmName}
sta ${target.asmVarname}
""")
}
TargetStorageKind.MEMORY -> {
@ -540,7 +538,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
sta ${C64Zeropage.SCRATCH_W1+1}
ldy #0
lda (${C64Zeropage.SCRATCH_W1}),y
sta ${target.asmName}""")
sta ${target.asmVarname}""")
}
TargetStorageKind.MEMORY -> {
storeByteViaRegisterAInMemoryAddress(sourceName, target.memory!!)
@ -628,23 +626,44 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
}
}
private fun popAndWriteArrayvalueWithIndexA(arrayDt: DataType, arrayvarname: String) {
when (arrayDt) {
DataType.STR, DataType.ARRAY_UB, DataType.ARRAY_B ->
asmgen.out(" tay | inx | lda $ESTACK_LO_HEX,x | sta $arrayvarname,y")
DataType.ARRAY_UW, DataType.ARRAY_W ->
asmgen.out(" asl a | tay | inx | lda $ESTACK_LO_HEX,x | sta $arrayvarname,y | lda $ESTACK_HI_HEX,x | sta $arrayvarname+1,y")
DataType.ARRAY_F ->
// index * 5 is done in the subroutine that's called
private fun popAndWriteArrayvalueWithUnscaledIndexA(elementDt: DataType, asmArrayvarname: String) {
when (elementDt) {
in ByteDatatypes ->
asmgen.out(" tay | inx | lda $ESTACK_LO_HEX,x | sta $asmArrayvarname,y")
in WordDatatypes ->
asmgen.out(" asl a | tay | inx | lda $ESTACK_LO_HEX,x | sta $asmArrayvarname,y | lda $ESTACK_HI_HEX,x | sta $asmArrayvarname+1,y")
DataType.FLOAT ->
// scaling * 5 is done in the subroutine that's called
asmgen.out("""
sta $ESTACK_LO_HEX,x
dex
lda #<$arrayvarname
ldy #>$arrayvarname
lda #<$asmArrayvarname
ldy #>$asmArrayvarname
jsr c64flt.pop_float_to_indexed_var
""")
else ->
throw AssemblyError("weird array type")
}
}
private fun readAndPushArrayvalueWithUnscaledIndexA(elementDt: DataType, asmVarname: String) {
// TODO this is only used once, remove this when that is rewritten using scaled
when (elementDt) {
in ByteDatatypes ->
asmgen.out(" tay | lda $asmVarname,y | sta $ESTACK_LO_HEX,x | dex")
in WordDatatypes ->
asmgen.out(" asl a | tay | lda $asmVarname,y | sta $ESTACK_LO_HEX,x | lda $asmVarname+1,y | sta $ESTACK_HI_HEX,x | dex")
DataType.FLOAT ->
// index * 5 is done in the subroutine that's called
asmgen.out("""
sta $ESTACK_LO_HEX,x
dex
lda #<$asmVarname
ldy #>$asmVarname
jsr c64flt.push_float_from_indexed_var
""")
else ->
throw AssemblyError("weird array elt type")
}
}
}

View File

@ -111,20 +111,20 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
when (target.datatype) {
in ByteDatatypes -> {
when {
valueLv != null -> inplaceModification_byte_litval_to_variable(target.asmName, target.datatype, operator, valueLv.toInt())
ident != null -> inplaceModification_byte_variable_to_variable(target.asmName, target.datatype, operator, ident)
valueLv != null -> inplaceModification_byte_litval_to_variable(target.asmVarname, target.datatype, operator, valueLv.toInt())
ident != null -> inplaceModification_byte_variable_to_variable(target.asmVarname, target.datatype, operator, ident)
// TODO more specialized code for types such as memory read etc.
value is TypecastExpression -> {
if (tryRemoveRedundantCast(value, target, operator)) return
inplaceModification_byte_value_to_variable(target.asmName, target.datatype, operator, value)
inplaceModification_byte_value_to_variable(target.asmVarname, target.datatype, operator, value)
}
else -> inplaceModification_byte_value_to_variable(target.asmName, target.datatype, operator, value)
else -> inplaceModification_byte_value_to_variable(target.asmVarname, target.datatype, operator, value)
}
}
in WordDatatypes -> {
when {
valueLv != null -> inplaceModification_word_litval_to_variable(target.asmName, target.datatype, operator, valueLv.toInt())
ident != null -> inplaceModification_word_variable_to_variable(target.asmName, target.datatype, operator, ident)
valueLv != null -> inplaceModification_word_litval_to_variable(target.asmVarname, target.datatype, operator, valueLv.toInt())
ident != null -> inplaceModification_word_variable_to_variable(target.asmVarname, target.datatype, operator, ident)
// TODO more specialized code for types such as memory read etc.
// value is DirectMemoryRead -> {
// println("warning: slow stack evaluation used (8): $name $operator= ${value::class.simpleName} at ${value.position}") // TODO
@ -140,21 +140,21 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
// }
value is TypecastExpression -> {
if (tryRemoveRedundantCast(value, target, operator)) return
inplaceModification_word_value_to_variable(target.asmName, target.datatype, operator, value)
inplaceModification_word_value_to_variable(target.asmVarname, target.datatype, operator, value)
}
else -> inplaceModification_word_value_to_variable(target.asmName, target.datatype, operator, value)
else -> inplaceModification_word_value_to_variable(target.asmVarname, target.datatype, operator, value)
}
}
DataType.FLOAT -> {
when {
valueLv != null -> inplaceModification_float_litval_to_variable(target.asmName, operator, valueLv.toDouble())
ident != null -> inplaceModification_float_variable_to_variable(target.asmName, operator, ident)
valueLv != null -> inplaceModification_float_litval_to_variable(target.asmVarname, operator, valueLv.toDouble())
ident != null -> inplaceModification_float_variable_to_variable(target.asmVarname, operator, ident)
// TODO more specialized code for types such as memory read etc.
value is TypecastExpression -> {
if (tryRemoveRedundantCast(value, target, operator)) return
inplaceModification_float_value_to_variable(target.asmName, operator, value)
inplaceModification_float_value_to_variable(target.asmVarname, operator, value)
}
else -> inplaceModification_float_value_to_variable(target.asmName, operator, value)
else -> inplaceModification_float_value_to_variable(target.asmVarname, operator, value)
}
}
else -> throw AssemblyError("weird type to do in-place modification on ${target.datatype}")
@ -1014,19 +1014,22 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
if (innerCastDt == null) {
// simple typecast where the value is the target
when (target.datatype) {
DataType.UBYTE, DataType.BYTE -> { /* byte target can't be casted to anything else at all */
}
DataType.UBYTE, DataType.BYTE -> { /* byte target can't be casted to anything else at all */ }
DataType.UWORD, DataType.WORD -> {
when (outerCastDt) {
DataType.UBYTE, DataType.BYTE -> {
if(target.kind== TargetStorageKind.VARIABLE) {
asmgen.out(" lda #0 | sta ${target.asmName}+1")
} else
throw AssemblyError("weird value")
when(target.kind) {
TargetStorageKind.VARIABLE -> asmgen.out(" lda #0 | sta ${target.asmVarname}+1")
TargetStorageKind.ARRAY -> {
asmgen.loadScaledArrayIndexIntoRegister(target.array!!, target.datatype, CpuRegister.Y, true)
asmgen.out(" lda #0 | sta ${target.asmVarname},y")
}
TargetStorageKind.STACK -> asmgen.out(" lda #0 | sta $ESTACK_HI_PLUS1_HEX,x")
else -> throw AssemblyError("weird target")
}
}
DataType.UWORD, DataType.WORD, in IterableDatatypes -> {
}
DataType.FLOAT -> throw AssemblyError("incompatible cast type")
DataType.UWORD, DataType.WORD, in IterableDatatypes -> {}
DataType.FLOAT -> throw AssemblyError("can't cast float in-place")
else -> throw AssemblyError("weird cast type")
}
}
@ -1052,11 +1055,11 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
when(target.kind) {
TargetStorageKind.VARIABLE -> {
asmgen.out("""
lda ${target.asmName}
lda ${target.asmVarname}
beq +
lda #1
+ eor #1
sta ${target.asmName}""")
sta ${target.asmVarname}""")
}
TargetStorageKind.MEMORY -> {
val mem = target.memory!!
@ -1108,14 +1111,14 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
when(target.kind) {
TargetStorageKind.VARIABLE -> {
asmgen.out("""
lda ${target.asmName}
ora ${target.asmName}+1
lda ${target.asmVarname}
ora ${target.asmVarname}+1
beq +
lda #1
+ eor #1
sta ${target.asmName}
sta ${target.asmVarname}
lsr a
sta ${target.asmName}+1""")
sta ${target.asmVarname}+1""")
}
TargetStorageKind.MEMORY -> throw AssemblyError("no asm gen for uword-memory not")
TargetStorageKind.ARRAY -> TODO("in-place not of uword array")
@ -1133,9 +1136,9 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
when(target.kind) {
TargetStorageKind.VARIABLE -> {
asmgen.out("""
lda ${target.asmName}
lda ${target.asmVarname}
eor #255
sta ${target.asmName}""")
sta ${target.asmVarname}""")
}
TargetStorageKind.MEMORY -> {
val memory = target.memory!!
@ -1181,12 +1184,12 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
when(target.kind) {
TargetStorageKind.VARIABLE -> {
asmgen.out("""
lda ${target.asmName}
lda ${target.asmVarname}
eor #255
sta ${target.asmName}
lda ${target.asmName}+1
sta ${target.asmVarname}
lda ${target.asmVarname}+1
eor #255
sta ${target.asmName}+1""")
sta ${target.asmVarname}+1""")
}
TargetStorageKind.MEMORY -> throw AssemblyError("no asm gen for uword-memory invert")
TargetStorageKind.ARRAY -> TODO("in-place invert uword array")
@ -1206,8 +1209,8 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
asmgen.out("""
lda #0
sec
sbc ${target.asmName}
sta ${target.asmName}""")
sbc ${target.asmVarname}
sta ${target.asmVarname}""")
}
TargetStorageKind.MEMORY -> throw AssemblyError("can't in-place negate memory ubyte")
TargetStorageKind.ARRAY -> TODO("in-place negate byte array")
@ -1221,11 +1224,11 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
asmgen.out("""
lda #0
sec
sbc ${target.asmName}
sta ${target.asmName}
sbc ${target.asmVarname}
sta ${target.asmVarname}
lda #0
sbc ${target.asmName}+1
sta ${target.asmName}+1""")
sbc ${target.asmVarname}+1
sta ${target.asmVarname}+1""")
}
TargetStorageKind.ARRAY -> TODO("in-place negate word array")
TargetStorageKind.MEMORY -> throw AssemblyError("no asm gen for word memory negate")
@ -1238,12 +1241,12 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
TargetStorageKind.VARIABLE -> {
asmgen.out("""
stx ${C64Zeropage.SCRATCH_REG_X}
lda #<${target.asmName}
ldy #>${target.asmName}
lda #<${target.asmVarname}
ldy #>${target.asmVarname}
jsr c64flt.MOVFM
jsr c64flt.NEGOP
ldx #<${target.asmName}
ldy #>${target.asmName}
ldx #<${target.asmVarname}
ldy #>${target.asmVarname}
jsr c64flt.MOVMF
ldx ${C64Zeropage.SCRATCH_REG_X}
""")

View File

@ -7,13 +7,27 @@ main {
sub start() {
&ubyte[256] foo= $c000
ubyte[] array=[1,2,3]
str string = "hello"
; uword[] array=[$1111 ,$2222,$3333]
; uword uw = $ee33
; ubyte i = 2
; array[1] = array[1] as ubyte
; array[i] = array[i] as ubyte
; c64scr.print_uwhex(array[0], 1)
; c64.CHROUT(',')
; c64scr.print_uwhex(array[1], 1)
; c64.CHROUT(',')
; c64scr.print_uwhex(array[2], 1)
; c64.CHROUT('\n')
c64scr.print_uwhex(foo, 1)
float[] farr = [1.111, 2.222, 3.333]
c64flt.print_f(farr[1])
c64.CHROUT('\n')
float ff
float ff2 = 0
ff = ff2 + farr[1] + 99
c64flt.print_f(ff)
c64.CHROUT('\n')
foo[100]=10
}
}