mirror of
https://github.com/irmen/prog8.git
synced 2024-05-29 01:41:32 +00:00
fix 6502 casting uword and float to bool
This commit is contained in:
parent
f5e332daf7
commit
37b346740b
|
@ -56,8 +56,8 @@ internal class IfElseAsmGen(private val program: PtProgram,
|
|||
is PtPrefix,
|
||||
is PtBinaryExpression -> { /* no cmp necessary the lda has been done just prior */ }
|
||||
is PtTypeCast -> {
|
||||
if(condition.value.type !in ByteDatatypes)
|
||||
asmgen.out(" cmp #0") // maybe can be eliminated altogether? depends on how the actual type cast is done...
|
||||
if(condition.value.type !in ByteDatatypes && condition.value.type !in WordDatatypes)
|
||||
asmgen.out(" cmp #0")
|
||||
}
|
||||
else -> asmgen.out(" cmp #0")
|
||||
}
|
||||
|
|
|
@ -1550,6 +1550,8 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||
if(targetDt in ByteDatatypes && valueDt in WordDatatypes) {
|
||||
// just assign the lsb from the array value
|
||||
return assignCastViaLsbFunc(value, target)
|
||||
} else if(targetDt==DataType.BOOL && valueDt in WordDatatypes) {
|
||||
return assignWordToBool(value, target)
|
||||
}
|
||||
}
|
||||
else -> {}
|
||||
|
@ -1629,9 +1631,12 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||
RegisterOrPair.A,
|
||||
RegisterOrPair.X,
|
||||
RegisterOrPair.Y -> {
|
||||
// cast an uword to a byte register, do this via lsb(value)
|
||||
// generate code for lsb(value) here instead of the ubyte typecast
|
||||
return assignCastViaLsbFunc(value, target)
|
||||
return if(targetDt==DataType.BOOL)
|
||||
assignWordToBool(value, target)
|
||||
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)
|
||||
}
|
||||
RegisterOrPair.AX,
|
||||
RegisterOrPair.AY,
|
||||
|
@ -1647,15 +1652,18 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||
if(target.kind==TargetStorageKind.REGISTER) {
|
||||
if(valueDt==DataType.FLOAT && target.datatype!=DataType.FLOAT) {
|
||||
// have to typecast the float number on the fly down to an integer
|
||||
assignExpressionToRegister(value, RegisterOrPair.FAC1, target.datatype in SignedDatatypes)
|
||||
assignTypeCastedFloatFAC1("P8ZP_SCRATCH_W1", target.datatype)
|
||||
assignVariableToRegister("P8ZP_SCRATCH_W1", target.register!!, target.datatype in SignedDatatypes, origTypeCastExpression.definingISub(), target.position)
|
||||
assignExpressionToRegister(value, RegisterOrPair.FAC1, targetDt in SignedDatatypes)
|
||||
assignTypeCastedFloatFAC1("P8ZP_SCRATCH_W1", targetDt)
|
||||
assignVariableToRegister("P8ZP_SCRATCH_W1", target.register!!, targetDt in SignedDatatypes, origTypeCastExpression.definingISub(), target.position)
|
||||
return
|
||||
} else {
|
||||
if(!(valueDt isAssignableTo targetDt)) {
|
||||
return if(valueDt in WordDatatypes && targetDt in ByteDatatypes) {
|
||||
// word to byte, just take the lsb
|
||||
assignCastViaLsbFunc(value, target)
|
||||
} else if(valueDt in WordDatatypes && targetDt==DataType.BOOL) {
|
||||
// word to bool
|
||||
assignWordToBool(value, target)
|
||||
} else if(valueDt in WordDatatypes && targetDt in WordDatatypes) {
|
||||
// word to word, just assign
|
||||
assignExpressionToRegister(value, target.register!!, valueDt in SignedDatatypes)
|
||||
|
@ -1742,12 +1750,24 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||
translateNormalAssignment(assign, value.definingISub())
|
||||
}
|
||||
|
||||
private fun assignWordToBool(value: PtExpression, target: AsmAssignTarget) {
|
||||
assignExpressionToRegister(value, RegisterOrPair.AY, false)
|
||||
asmgen.out("""
|
||||
sty P8ZP_SCRATCH_REG
|
||||
ora P8ZP_SCRATCH_REG
|
||||
beq +
|
||||
lda #1
|
||||
+""")
|
||||
assignRegisterByte(target, CpuRegister.A, false, false)
|
||||
}
|
||||
|
||||
private fun assignTypeCastedFloatFAC1(targetAsmVarName: String, targetDt: DataType) {
|
||||
|
||||
if(targetDt==DataType.FLOAT)
|
||||
throw AssemblyError("typecast to identical type")
|
||||
|
||||
when(targetDt) {
|
||||
DataType.BOOL -> asmgen.out(" jsr floats.cast_FAC1_as_bool_into_a | sta $targetAsmVarName")
|
||||
DataType.UBYTE -> asmgen.out(" jsr floats.cast_FAC1_as_uw_into_ya | sty $targetAsmVarName")
|
||||
DataType.BYTE -> asmgen.out(" jsr floats.cast_FAC1_as_w_into_ay | sta $targetAsmVarName")
|
||||
DataType.UWORD -> asmgen.out(" jsr floats.cast_FAC1_as_uw_into_ya | sty $targetAsmVarName | sta $targetAsmVarName+1")
|
||||
|
@ -1796,7 +1816,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||
}
|
||||
DataType.BYTE -> {
|
||||
when(targetDt) {
|
||||
DataType.UBYTE -> {
|
||||
DataType.UBYTE, DataType.BOOL -> {
|
||||
asmgen.out(" lda $sourceAsmVarName | sta $targetAsmVarName")
|
||||
}
|
||||
DataType.UWORD -> {
|
||||
|
@ -1823,6 +1843,14 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||
}
|
||||
DataType.UWORD -> {
|
||||
when(targetDt) {
|
||||
DataType.BOOL -> {
|
||||
asmgen.out("""
|
||||
lda $sourceAsmVarName
|
||||
ora $sourceAsmVarName+1
|
||||
beq +
|
||||
lda #1
|
||||
+ sta $targetAsmVarName""")
|
||||
}
|
||||
DataType.BYTE, DataType.UBYTE -> {
|
||||
asmgen.out(" lda $sourceAsmVarName | sta $targetAsmVarName")
|
||||
}
|
||||
|
@ -1844,6 +1872,14 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||
}
|
||||
DataType.WORD -> {
|
||||
when(targetDt) {
|
||||
DataType.BOOL -> {
|
||||
asmgen.out("""
|
||||
lda $sourceAsmVarName
|
||||
ora $sourceAsmVarName+1
|
||||
beq +
|
||||
lda #1
|
||||
+ sta $targetAsmVarName""")
|
||||
}
|
||||
DataType.BYTE, DataType.UBYTE -> {
|
||||
asmgen.out(" lda $sourceAsmVarName | sta $targetAsmVarName")
|
||||
}
|
||||
|
@ -1866,6 +1902,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||
DataType.FLOAT -> {
|
||||
asmgen.out(" lda #<$sourceAsmVarName | ldy #>$sourceAsmVarName")
|
||||
when(targetDt) {
|
||||
DataType.BOOL -> asmgen.out(" jsr floats.cast_as_bool_into_a | sta $targetAsmVarName")
|
||||
DataType.UBYTE -> asmgen.out(" jsr floats.cast_as_uw_into_ya | sty $targetAsmVarName")
|
||||
DataType.BYTE -> asmgen.out(" jsr floats.cast_as_w_into_ay | sta $targetAsmVarName")
|
||||
DataType.UWORD -> asmgen.out(" jsr floats.cast_as_uw_into_ya | sty $targetAsmVarName | sta $targetAsmVarName+1")
|
||||
|
|
|
@ -98,6 +98,21 @@ cast_as_w_into_ay .proc ; also used for float 2 b
|
|||
jmp cast_FAC1_as_w_into_ay
|
||||
.pend
|
||||
|
||||
cast_as_bool_into_a .proc
|
||||
; -- cast float at A/Y to bool into A
|
||||
; clobbers X
|
||||
jsr MOVFM
|
||||
jmp cast_FAC1_as_bool_into_a
|
||||
.pend
|
||||
|
||||
cast_FAC1_as_bool_into_a .proc
|
||||
; -- cast fac1 to bool into A
|
||||
; clobbers X
|
||||
jsr SIGN
|
||||
and #1
|
||||
rts
|
||||
.pend
|
||||
|
||||
cast_FAC1_as_uw_into_ya .proc ; also used for float 2 ub
|
||||
; -- cast fac1 to uword into Y/A
|
||||
; clobbers X
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
# generates various Prog8 files with a huge amount of number equality tests.
|
||||
# generates various Prog8 files with a large amount of number equality tests,
|
||||
# using various forms of the if statement (because these forms have their own code gen paths)
|
||||
|
||||
import sys
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
TODO
|
||||
====
|
||||
|
||||
fix 6502 casting uword to bool (don't take only the lsb!)
|
||||
retest all comparisons in if statements (byte, word, signed and unsigned) + all comparison assignments. Against 0 and something else as 0.
|
||||
with jump, indirect jump, no else block, and both if+else blocks.
|
||||
|
||||
fix "wordGreaterValue"
|
||||
|
||||
|
@ -64,9 +65,6 @@ ok . check program sizes vs. master branch
|
|||
===== ====== =======
|
||||
|
||||
|
||||
retest all comparisons in if statements (byte, word, signed and unsigned) + all comparison assignments. Against 0 and something else as 0.
|
||||
with jump, indirect jump, no else block, and both if+else blocks.
|
||||
|
||||
check that the flood fill routine in gfx2 and paint still works.
|
||||
re-allow typecast of const true/false back to ubytes 1 and 0?
|
||||
re-allow typecast of const ubyte 0/1 to false/true boolean?
|
||||
|
|
|
@ -6,15 +6,41 @@
|
|||
|
||||
main {
|
||||
sub start() {
|
||||
cx16.r0 = $2200
|
||||
float @shared fl = 1123.56
|
||||
|
||||
if cx16.r0L as bool
|
||||
cx16.r0L++
|
||||
if fl as bool
|
||||
txt.print("yep ")
|
||||
else
|
||||
txt.print("nope ")
|
||||
|
||||
bool @shared qq = fl as bool
|
||||
if qq
|
||||
txt.print("yep ")
|
||||
else
|
||||
txt.print("nope ")
|
||||
|
||||
if cx16.r0 as bool
|
||||
cx16.r0L++
|
||||
txt.print("yep ")
|
||||
else
|
||||
txt.print("nope ")
|
||||
|
||||
if @(cx16.r0) as bool
|
||||
cx16.r0L++
|
||||
qq = cx16.r0 as bool
|
||||
if qq
|
||||
txt.print("yep ")
|
||||
else
|
||||
txt.print("nope ")
|
||||
|
||||
if cx16.r0s as bool
|
||||
txt.print("yep ")
|
||||
else
|
||||
txt.print("nope ")
|
||||
|
||||
qq = cx16.r0s as bool
|
||||
if qq
|
||||
txt.print("yep ")
|
||||
else
|
||||
txt.print("nope ")
|
||||
|
||||
; test_stack.test()
|
||||
; broken_word_gt()
|
||||
|
|
Loading…
Reference in New Issue
Block a user