This commit is contained in:
Irmen de Jong 2020-08-23 23:28:25 +02:00
parent 1f17c22132
commit 6cd42ddafe
3 changed files with 127 additions and 34 deletions

View File

@ -695,9 +695,6 @@ internal class AsmGen(private val program: Program,
internal fun translateFunctionCall(functionCall: FunctionCall) = internal fun translateFunctionCall(functionCall: FunctionCall) =
functioncallAsmGen.translateFunctionCall(functionCall) functioncallAsmGen.translateFunctionCall(functionCall)
internal fun assignToRegister(reg: CpuRegister, value: Int?, identifier: IdentifierReference?) =
assignmentAsmGen.assignToRegister(reg, value, identifier)
private fun translateSubroutine(sub: Subroutine) { private fun translateSubroutine(sub: Subroutine) {
out("") out("")
outputSourceLine(sub) outputSourceLine(sub)

View File

@ -106,6 +106,7 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg
throw AssemblyError("argument type incompatible") throw AssemblyError("argument type incompatible")
val paramVar = parameter.value val paramVar = parameter.value
val scopedParamVar = (sub.scopedname+"."+paramVar.name).split(".") val scopedParamVar = (sub.scopedname+"."+paramVar.name).split(".")
val target = AssignTarget(IdentifierReference(scopedParamVar, sub.position), null, null, sub.position) val target = AssignTarget(IdentifierReference(scopedParamVar, sub.position), null, null, sub.position)
val assign = Assignment(target, value, value.position) val assign = Assignment(target, value, value.position)
@ -173,11 +174,12 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg
register!=null && register.name.length==1 -> { register!=null && register.name.length==1 -> {
when (value) { when (value) {
is NumericLiteralValue -> { is NumericLiteralValue -> {
asmgen.assignToRegister(CpuRegister.valueOf(register.name), value.number.toInt(), null) asmgen.out(" ld${register.name.toLowerCase()} #${value.number.toInt().toHex()}")
} }
is IdentifierReference -> { is IdentifierReference -> {
asmgen.assignToRegister(CpuRegister.valueOf(register.name), null, value) asmgen.out(" ld${register.name.toLowerCase()} ${asmgen.asmIdentifierName(value)}")
} }
// TODO more special cases to optimize argument passing in registers without intermediate stack usage
else -> { else -> {
asmgen.translateExpression(value) asmgen.translateExpression(value)
when(register) { when(register) {

View File

@ -141,15 +141,6 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
} }
} }
fun assignToRegister(reg: CpuRegister, value: Int?, identifier: IdentifierReference?) {
if(value!=null) {
asmgen.out(" ld${reg.toString().toLowerCase()} #${value.toHex()}")
} else if(identifier!=null) {
val name = asmgen.asmIdentifierName(identifier)
asmgen.out(" ld${reg.toString().toLowerCase()} $name")
}
}
private fun assignStackValue(target: AsmAssignTarget) { private fun assignStackValue(target: AsmAssignTarget) {
when(target.kind) { when(target.kind) {
TargetStorageKind.VARIABLE -> { TargetStorageKind.VARIABLE -> {
@ -244,8 +235,28 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
} }
} }
} }
TargetStorageKind.REGISTER -> TODO() TargetStorageKind.REGISTER -> {
TargetStorageKind.STACK -> TODO() when (target.datatype) {
DataType.UBYTE, DataType.BYTE -> {
when(target.register!!) {
RegisterOrPair.A -> asmgen.out(" inx | lda $ESTACK_LO_HEX,x")
RegisterOrPair.X -> throw AssemblyError("can't use X here")
RegisterOrPair.Y -> asmgen.out(" inx | ldy $ESTACK_LO_HEX,x")
else -> throw AssemblyError("can't assign byte to register pair word")
}
}
DataType.UWORD, DataType.WORD, in PassByReferenceDatatypes -> {
when(target.register!!) {
RegisterOrPair.AX -> throw AssemblyError("can't use X here")
RegisterOrPair.AY-> asmgen.out(" inx | lda $ESTACK_LO_HEX,x | ldy $ESTACK_HI_HEX,x")
RegisterOrPair.XY-> throw AssemblyError("can't use X here")
else -> throw AssemblyError("can't assign word to single byte register")
}
}
else -> throw AssemblyError("weird dt")
}
}
TargetStorageKind.STACK -> {}
} }
} }
@ -278,7 +289,14 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
TargetStorageKind.ARRAY -> { TargetStorageKind.ARRAY -> {
throw AssemblyError("no asm gen for assign address $sourceName to array ${target.asmVarname}") throw AssemblyError("no asm gen for assign address $sourceName to array ${target.asmVarname}")
} }
TargetStorageKind.REGISTER -> TODO() TargetStorageKind.REGISTER -> {
when(target.register!!) {
RegisterOrPair.AX -> asmgen.out(" lda #<$sourceName | ldx #>$sourceName")
RegisterOrPair.AY -> asmgen.out(" lda #<$sourceName | ldy #>$sourceName")
RegisterOrPair.XY -> asmgen.out(" ldx #<$sourceName | ldy #>$sourceName")
else -> throw AssemblyError("can't load address in a single 8-bit register")
}
}
TargetStorageKind.STACK -> TODO() TargetStorageKind.STACK -> TODO()
} }
} }
@ -368,7 +386,14 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
} }
} }
} }
TargetStorageKind.REGISTER -> TODO() TargetStorageKind.REGISTER -> {
when(target.register!!) {
RegisterOrPair.AX -> asmgen.out(" lda #$sourceName | ldx #$sourceName+1")
RegisterOrPair.AY -> asmgen.out(" lda #$sourceName | ldy #$sourceName+1")
RegisterOrPair.XY -> asmgen.out(" ldx #$sourceName | ldy #$sourceName+1")
else -> throw AssemblyError("can't load word in a single 8-bit register")
}
}
TargetStorageKind.STACK -> TODO() TargetStorageKind.STACK -> TODO()
} }
} }
@ -402,7 +427,9 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
asmgen.translateExpression(index) asmgen.translateExpression(index)
asmgen.out(" lda #<${target.asmVarname} | ldy #>${target.asmVarname} | jsr c64flt.pop_float_to_indexed_var") asmgen.out(" lda #<${target.asmVarname} | ldy #>${target.asmVarname} | jsr c64flt.pop_float_to_indexed_var")
} }
else -> throw AssemblyError("no asm gen for assign floatvar to $target") TargetStorageKind.MEMORY -> throw AssemblyError("can't assign float to mem byte")
TargetStorageKind.REGISTER -> throw AssemblyError("can't assign float to register")
TargetStorageKind.STACK -> TODO()
} }
} }
@ -437,7 +464,16 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
} }
} }
} }
TargetStorageKind.REGISTER -> TODO() TargetStorageKind.REGISTER -> {
when(target.register!!) {
RegisterOrPair.A -> asmgen.out(" lda $sourceName")
RegisterOrPair.X -> asmgen.out(" ldx $sourceName")
RegisterOrPair.Y -> asmgen.out(" ldy $sourceName")
RegisterOrPair.AX -> asmgen.out(" lda $sourceName | ldx #0")
RegisterOrPair.AY -> asmgen.out(" lda $sourceName | ldy #0")
RegisterOrPair.XY -> asmgen.out(" ldx $sourceName | ldy #0")
}
}
TargetStorageKind.STACK -> TODO() TargetStorageKind.STACK -> TODO()
} }
} }
@ -489,7 +525,28 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
} }
} }
} }
TargetStorageKind.REGISTER -> TODO() TargetStorageKind.REGISTER -> {
when(register) {
CpuRegister.A -> when(target.register!!) {
RegisterOrPair.A -> {}
RegisterOrPair.X -> { asmgen.out(" tax") }
RegisterOrPair.Y -> { asmgen.out(" tay") }
else -> throw AssemblyError("attempt to assign byte to register pair word")
}
CpuRegister.X -> when(target.register!!) {
RegisterOrPair.A -> { asmgen.out(" txa") }
RegisterOrPair.X -> { }
RegisterOrPair.Y -> { asmgen.out(" txy") }
else -> throw AssemblyError("attempt to assign byte to register pair word")
}
CpuRegister.Y -> when(target.register!!) {
RegisterOrPair.A -> { asmgen.out(" tya") }
RegisterOrPair.X -> { asmgen.out(" tyx") }
RegisterOrPair.Y -> { }
else -> throw AssemblyError("attempt to assign byte to register pair word")
}
}
}
TargetStorageKind.STACK -> TODO() TargetStorageKind.STACK -> TODO()
} }
} }
@ -536,7 +593,14 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
sta ${target.asmVarname}+1,y sta ${target.asmVarname}+1,y
""") """)
} }
TargetStorageKind.REGISTER -> TODO() TargetStorageKind.REGISTER -> {
when(target.register!!) {
RegisterOrPair.AX -> asmgen.out(" lda #<${word.toHex()} | ldx #>${word.toHex()}")
RegisterOrPair.AY -> asmgen.out(" lda #<${word.toHex()} | ldy #>${word.toHex()}")
RegisterOrPair.XY -> asmgen.out(" ldx #<${word.toHex()} | ldy #>${word.toHex()}")
else -> throw AssemblyError("can't assign word to single byte register")
}
}
TargetStorageKind.STACK -> TODO() TargetStorageKind.STACK -> TODO()
} }
} }
@ -571,7 +635,13 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
} }
} }
} }
else -> throw AssemblyError("no asm gen for assign byte $byte to $target") TargetStorageKind.REGISTER -> when(target.register!!) {
RegisterOrPair.A -> asmgen.out(" lda #${byte.toHex()}")
RegisterOrPair.X -> asmgen.out(" ldx #${byte.toHex()}")
RegisterOrPair.Y -> asmgen.out(" ldy #${byte.toHex()}")
else -> throw AssemblyError("can't assign byte to word register apir")
}
TargetStorageKind.STACK -> TODO()
} }
} }
@ -618,7 +688,9 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
""") """)
} }
} }
else -> throw AssemblyError("no asm gen for assign float 0.0 to $target") TargetStorageKind.MEMORY -> throw AssemblyError("can't assign float to memory byte")
TargetStorageKind.REGISTER -> throw AssemblyError("can't assign float to register")
TargetStorageKind.STACK -> TODO()
} }
} else { } else {
// non-zero value // non-zero value
@ -676,7 +748,9 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
""") """)
} }
} }
else -> throw AssemblyError("no asm gen for assign float $float to $target") TargetStorageKind.MEMORY -> throw AssemblyError("can't assign float to memory byte")
TargetStorageKind.REGISTER -> throw AssemblyError("can't assign float to register")
TargetStorageKind.STACK -> TODO()
} }
} }
} }
@ -696,7 +770,12 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
TargetStorageKind.ARRAY -> { TargetStorageKind.ARRAY -> {
throw AssemblyError("no asm gen for assign memory byte at $address to array ${target.asmVarname}") throw AssemblyError("no asm gen for assign memory byte at $address to array ${target.asmVarname}")
} }
TargetStorageKind.REGISTER -> TODO() TargetStorageKind.REGISTER -> when(target.register!!) {
RegisterOrPair.A -> asmgen.out(" lda ${address.toHex()}")
RegisterOrPair.X -> asmgen.out(" ldx ${address.toHex()}")
RegisterOrPair.Y -> asmgen.out(" ldy ${address.toHex()}")
else -> throw AssemblyError("can't assign byte to word register apir")
}
TargetStorageKind.STACK -> TODO() TargetStorageKind.STACK -> TODO()
} }
} else if (identifier != null) { } else if (identifier != null) {
@ -704,13 +783,13 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
when(target.kind) { when(target.kind) {
TargetStorageKind.VARIABLE -> { TargetStorageKind.VARIABLE -> {
asmgen.out(""" asmgen.out("""
lda $sourceName lda $sourceName
sta ${C64Zeropage.SCRATCH_W1} sta ${C64Zeropage.SCRATCH_W1}
lda $sourceName+1 lda $sourceName+1
sta ${C64Zeropage.SCRATCH_W1+1} sta ${C64Zeropage.SCRATCH_W1+1}
ldy #0 ldy #0
lda (${C64Zeropage.SCRATCH_W1}),y lda (${C64Zeropage.SCRATCH_W1}),y
sta ${target.asmVarname}""") sta ${target.asmVarname}""")
} }
TargetStorageKind.MEMORY -> { TargetStorageKind.MEMORY -> {
storeByteViaRegisterAInMemoryAddress(sourceName, target.memory!!) storeByteViaRegisterAInMemoryAddress(sourceName, target.memory!!)
@ -718,7 +797,22 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
TargetStorageKind.ARRAY -> { TargetStorageKind.ARRAY -> {
throw AssemblyError("no asm gen for assign memory byte $sourceName to array ${target.asmVarname} ") throw AssemblyError("no asm gen for assign memory byte $sourceName to array ${target.asmVarname} ")
} }
else -> throw AssemblyError("no asm gen for assign memory byte $target") TargetStorageKind.REGISTER -> {
asmgen.out("""
lda $sourceName
sta ${C64Zeropage.SCRATCH_W1}
lda $sourceName+1
sta ${C64Zeropage.SCRATCH_W1+1}
ldy #0
lda (${C64Zeropage.SCRATCH_W1}),y""")
when(target.register!!) {
RegisterOrPair.A -> {}
RegisterOrPair.X -> asmgen.out(" tax")
RegisterOrPair.Y -> asmgen.out(" tay")
else -> throw AssemblyError("can't assign byte to word register apir")
}
}
TargetStorageKind.STACK -> TODO()
} }
} }
} }