mirror of
https://github.com/irmen/prog8.git
synced 2025-11-23 14:17:51 +00:00
implement missing long typecasts
This commit is contained in:
@@ -1620,7 +1620,17 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||
else -> throw AssemblyError("invalid reg")
|
||||
}
|
||||
} else {
|
||||
TODO("msw(expression) ${fcall.position} - use a temporary variable for now")
|
||||
asmgen.assignExpressionToRegister(arg, RegisterOrPair.R0R1_32, true)
|
||||
when(resultRegister) {
|
||||
RegisterOrPair.AX -> asmgen.out(" lda cx16.r1 | ldx cx16.r1+1")
|
||||
null, RegisterOrPair.AY -> asmgen.out(" lda cx16.r1 | ldy cx16.r1+1")
|
||||
RegisterOrPair.XY -> asmgen.out(" ldx cx16.r1 | ldy cx16.r1+1")
|
||||
in Cx16VirtualRegisters -> {
|
||||
val regname = resultRegister.name.lowercase()
|
||||
asmgen.out(" lda cx16.r1 | sta cx16.$regname | lda cx16.r1+1 | sta cx16.$regname+1")
|
||||
}
|
||||
else -> throw AssemblyError("invalid reg")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1643,7 +1653,19 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||
else -> throw AssemblyError("invalid reg")
|
||||
}
|
||||
} else {
|
||||
TODO("lsw(expression) ${fcall.position} - use a temporary variable for now")
|
||||
asmgen.assignExpressionToRegister(arg, RegisterOrPair.R0R1_32, true)
|
||||
when(resultRegister) {
|
||||
RegisterOrPair.AX -> asmgen.out(" lda cx16.r0 | ldx cx16.r0+1")
|
||||
null, RegisterOrPair.AY -> asmgen.out(" lda cx16.r0 | ldy cx16.r0+1")
|
||||
RegisterOrPair.XY -> asmgen.out(" ldx cx16.r0 | ldy cx16.r0+1")
|
||||
in Cx16VirtualRegisters -> {
|
||||
if(resultRegister!=RegisterOrPair.R0) {
|
||||
val regname = resultRegister.name.lowercase()
|
||||
asmgen.out(" lda cx16.r0 | sta cx16.$regname | lda cx16.r0+1 | sta cx16.$regname+1")
|
||||
}
|
||||
}
|
||||
else -> throw AssemblyError("invalid reg")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2455,7 +2455,7 @@ $endLabel""")
|
||||
is PtArrayIndexer -> {
|
||||
if(targetDt.isByte && valueDt.isWord) {
|
||||
// just assign the lsb from the array value
|
||||
return assignCastViaLsbFunc(value, target)
|
||||
return assignCastWordViaLsbFunc(value, target)
|
||||
} else if(targetDt.isBool && valueDt.isWord) {
|
||||
return assignWordToBool(value, target)
|
||||
}
|
||||
@@ -2513,7 +2513,7 @@ $endLabel""")
|
||||
if(parentTc!=null && parentTc.type.isUnsignedWord) {
|
||||
// typecast a word value to ubyte and directly back to uword
|
||||
// generate code for lsb(value) here instead of the ubyte typecast
|
||||
return assignCastViaLsbFunc(value, target)
|
||||
return assignCastWordViaLsbFunc(value, target)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2545,7 +2545,7 @@ $endLabel""")
|
||||
else
|
||||
// cast an uword to a byte register, do this via lsb(value)
|
||||
// generate code for lsb(value) here instead of the ubyte typecast
|
||||
assignCastViaLsbFunc(value, target)
|
||||
assignCastWordViaLsbFunc(value, target)
|
||||
}
|
||||
RegisterOrPair.AX,
|
||||
RegisterOrPair.AY,
|
||||
@@ -2569,7 +2569,7 @@ $endLabel""")
|
||||
if(!(valueDt isAssignableTo targetDt)) {
|
||||
return if(valueDt.isWord && targetDt.isByte) {
|
||||
// word to byte, just take the lsb
|
||||
assignCastViaLsbFunc(value, target)
|
||||
assignCastWordViaLsbFunc(value, target)
|
||||
} else if(valueDt.isWord && targetDt.isBool) {
|
||||
// word to bool
|
||||
assignWordToBool(value, target)
|
||||
@@ -2582,6 +2582,12 @@ $endLabel""")
|
||||
} else if(valueDt.isByteOrBool && targetDt.isWord) {
|
||||
// byte to word, just assign
|
||||
assignExpressionToRegister(value, target.register!!, valueDt.isSigned)
|
||||
} else if(valueDt.isLong && targetDt.isByte) {
|
||||
// long to byte, just take the lsb
|
||||
assignCastLongToByte(value, target)
|
||||
} else if(valueDt.isLong && targetDt.isWord) {
|
||||
// long to word, just take the lsw
|
||||
assignCastViaLswFunc(value, target)
|
||||
} else
|
||||
throw AssemblyError("can't cast $valueDt to $targetDt, this should have been checked in the astchecker")
|
||||
}
|
||||
@@ -2664,7 +2670,24 @@ $endLabel""")
|
||||
asmgen.assignExpressionTo(origTypeCastExpression, target)
|
||||
}
|
||||
|
||||
private fun assignCastViaLsbFunc(value: PtExpression, target: AsmAssignTarget) {
|
||||
private fun assignCastLongToByte(value: PtExpression, target: AsmAssignTarget) {
|
||||
// long to byte, can't use lsb() because that only works on words
|
||||
when(value) {
|
||||
is PtIdentifier -> {
|
||||
val longvar = asmgen.asmVariableName(value)
|
||||
asmgen.out(" lda $longvar")
|
||||
assignRegisterByte(target, CpuRegister.A, true, false)
|
||||
}
|
||||
is PtNumber -> throw AssemblyError("casting a long number to byte should have been const-folded away ${value.position}")
|
||||
else -> {
|
||||
assignExpressionToRegister(value, RegisterOrPair.R0R1_32, true)
|
||||
asmgen.out(" lda cx16.r0")
|
||||
assignRegisterByte(target, CpuRegister.A, true, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun assignCastWordViaLsbFunc(value: PtExpression, target: AsmAssignTarget) {
|
||||
val lsb = PtBuiltinFunctionCall("lsb", false, true, DataType.UBYTE, value.position)
|
||||
lsb.parent = value.parent
|
||||
lsb.add(value)
|
||||
@@ -2673,6 +2696,15 @@ $endLabel""")
|
||||
translateNormalAssignment(assign, value.definingISub())
|
||||
}
|
||||
|
||||
private fun assignCastViaLswFunc(value: PtExpression, target: AsmAssignTarget) {
|
||||
val lsb = PtBuiltinFunctionCall("lsw", false, true, DataType.UWORD, value.position)
|
||||
lsb.parent = value.parent
|
||||
lsb.add(value)
|
||||
val src = AsmAssignSource(SourceStorageKind.EXPRESSION, program, asmgen, DataType.UWORD, expression = lsb)
|
||||
val assign = AsmAssignment(src, listOf(target), program.memsizer, value.position)
|
||||
translateNormalAssignment(assign, value.definingISub())
|
||||
}
|
||||
|
||||
private fun assignWordToBool(value: PtExpression, target: AsmAssignTarget) {
|
||||
assignExpressionToRegister(value, RegisterOrPair.AY, false)
|
||||
asmgen.out("""
|
||||
|
||||
Reference in New Issue
Block a user