mirror of
https://github.com/irmen/prog8.git
synced 2024-12-27 20:33:39 +00:00
refactoring
This commit is contained in:
parent
1be139759c
commit
3991d23a69
@ -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)
|
||||
|
||||
|
@ -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")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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}
|
||||
""")
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user