mirror of
https://github.com/irmen/prog8.git
synced 2024-12-23 09:32:43 +00:00
ifelse more
This commit is contained in:
parent
c77cd0da39
commit
e1a133c2c0
@ -156,26 +156,8 @@ internal class IfElseAsmGen(private val program: PtProgram,
|
||||
translateIfElseBodies("bcs", stmt)
|
||||
}
|
||||
}
|
||||
"<=" -> {
|
||||
fallbackTranslate(stmt, true)
|
||||
// asmgen.assignExpressionToRegister(condition.left, RegisterOrPair.A, signed)
|
||||
// cmpAwithByteValue(condition.right)
|
||||
// if(signed) {
|
||||
// TODO("byte if <=")
|
||||
// } else {
|
||||
// TODO("ubyte if <=")
|
||||
// }
|
||||
}
|
||||
">" -> {
|
||||
fallbackTranslate(stmt, true)
|
||||
// asmgen.assignExpressionToRegister(condition.left, RegisterOrPair.A, signed)
|
||||
// cmpAwithByteValue(condition.right)
|
||||
// return if(signed) {
|
||||
// TODO("byte if >")
|
||||
// } else {
|
||||
// TODO("ubyte if >")
|
||||
// }
|
||||
}
|
||||
"<=" -> translateByteLessEqual(stmt, signed, jumpAfterIf)
|
||||
">" -> translateByteGreater(stmt, signed, jumpAfterIf)
|
||||
">=" -> {
|
||||
asmgen.assignExpressionToRegister(condition.left, RegisterOrPair.A, signed)
|
||||
cmpAwithByteValue(condition.right)
|
||||
@ -240,66 +222,544 @@ internal class IfElseAsmGen(private val program: PtProgram,
|
||||
}
|
||||
}
|
||||
|
||||
private fun translateByteLessEqual(stmt: PtIfElse, signed: Boolean, jumpAfterIf: PtJump?) {
|
||||
|
||||
fun bodies(greaterBranches: Pair<String, String>, stmt: PtIfElse) {
|
||||
// comparison value is already in A
|
||||
val afterIfLabel = asmgen.makeLabel("afterif")
|
||||
if(stmt.hasElse()) {
|
||||
// if and else blocks
|
||||
val elseLabel = asmgen.makeLabel("else")
|
||||
asmgen.out("""
|
||||
${greaterBranches.first} +
|
||||
${greaterBranches.second} $elseLabel
|
||||
+""")
|
||||
asmgen.translate(stmt.ifScope)
|
||||
asmgen.jmp(afterIfLabel, false)
|
||||
asmgen.out(elseLabel)
|
||||
asmgen.translate(stmt.elseScope)
|
||||
} else {
|
||||
// no else block
|
||||
asmgen.out("""
|
||||
${greaterBranches.first} +
|
||||
${greaterBranches.second} $afterIfLabel
|
||||
+""")
|
||||
asmgen.translate(stmt.ifScope)
|
||||
}
|
||||
asmgen.out(afterIfLabel)
|
||||
}
|
||||
|
||||
fun bodies(
|
||||
branches: Pair<String, String>,
|
||||
greaterBranches: Pair<String, String>,
|
||||
jump: PtJump,
|
||||
elseBlock: PtNodeGroup
|
||||
) {
|
||||
// comparison value is already in A
|
||||
val (asmLabel, indirect) = asmgen.getJumpTarget(jump)
|
||||
if(indirect) {
|
||||
asmgen.out("""
|
||||
${greaterBranches.first} +
|
||||
${greaterBranches.second} ++
|
||||
+ jmp ($asmLabel)
|
||||
+""")
|
||||
} else {
|
||||
asmgen.out(" ${branches.first} $asmLabel | ${branches.second} $asmLabel")
|
||||
}
|
||||
asmgen.translate(elseBlock)
|
||||
}
|
||||
|
||||
val condition = stmt.condition as PtBinaryExpression
|
||||
asmgen.assignExpressionToRegister(condition.left, RegisterOrPair.A, signed)
|
||||
cmpAwithByteValue(condition.right)
|
||||
if(signed) {
|
||||
if(jumpAfterIf!=null) {
|
||||
bodies("bmi" to "beq", "beq" to "bpl", jumpAfterIf, stmt.elseScope)
|
||||
} else {
|
||||
bodies("beq" to "bpl", stmt)
|
||||
}
|
||||
} else {
|
||||
if(jumpAfterIf!=null) {
|
||||
bodies("bcc" to "beq", "beq" to "bcs", jumpAfterIf, stmt.elseScope)
|
||||
} else {
|
||||
bodies("beq" to "bcs", stmt)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun translateByteGreater(stmt: PtIfElse, signed: Boolean, jumpAfterIf: PtJump?) {
|
||||
|
||||
fun bodies(lessEqBranches: Pair<String, String>, stmt: PtIfElse) {
|
||||
// comparison value is already in A
|
||||
val afterIfLabel = asmgen.makeLabel("afterif")
|
||||
if(stmt.hasElse()) {
|
||||
// if and else blocks
|
||||
val elseLabel = asmgen.makeLabel("else")
|
||||
asmgen.out(" ${lessEqBranches.first} $elseLabel | ${lessEqBranches.second} $elseLabel")
|
||||
asmgen.translate(stmt.ifScope)
|
||||
asmgen.jmp(afterIfLabel, false)
|
||||
asmgen.out(elseLabel)
|
||||
asmgen.translate(stmt.elseScope)
|
||||
} else {
|
||||
// no else block
|
||||
asmgen.out(" ${lessEqBranches.first} $afterIfLabel | ${lessEqBranches.second} $afterIfLabel")
|
||||
asmgen.translate(stmt.ifScope)
|
||||
}
|
||||
asmgen.out(afterIfLabel)
|
||||
}
|
||||
|
||||
fun bodies(
|
||||
branches: Pair<String, String>,
|
||||
lessEqBranches: Pair<String, String>,
|
||||
jump: PtJump,
|
||||
elseBlock: PtNodeGroup
|
||||
) {
|
||||
// comparison value is already in A
|
||||
val (asmLabel, indirect) = asmgen.getJumpTarget(jump)
|
||||
if(indirect) {
|
||||
asmgen.out("""
|
||||
${lessEqBranches.first} +
|
||||
${lessEqBranches.second} +
|
||||
jmp ($asmLabel)
|
||||
+""")
|
||||
} else {
|
||||
asmgen.out("""
|
||||
${branches.first} +
|
||||
${branches.second} $asmLabel
|
||||
+""")
|
||||
}
|
||||
asmgen.translate(elseBlock)
|
||||
}
|
||||
|
||||
val condition = stmt.condition as PtBinaryExpression
|
||||
asmgen.assignExpressionToRegister(condition.left, RegisterOrPair.A, signed)
|
||||
cmpAwithByteValue(condition.right)
|
||||
if(signed) {
|
||||
if(jumpAfterIf!=null) {
|
||||
bodies("beq" to "bpl", "bmi" to "beq", jumpAfterIf, stmt.elseScope)
|
||||
} else {
|
||||
bodies("bmi" to "beq", stmt)
|
||||
}
|
||||
} else {
|
||||
if(jumpAfterIf!=null) {
|
||||
bodies("beq" to "bcs", "bcc" to "beq", jumpAfterIf, stmt.elseScope)
|
||||
} else {
|
||||
bodies("bcc" to "beq", stmt)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun translateIfWord(stmt: PtIfElse, condition: PtBinaryExpression, jumpAfterIf: PtJump?) {
|
||||
val signed = condition.left.type in SignedDatatypes
|
||||
val constValue = condition.right.asConstInteger()
|
||||
if(constValue==0) {
|
||||
if(condition.operator=="==") {
|
||||
// if X==0
|
||||
// TODO even more optimized code by comparing lsb and msb separately
|
||||
asmgen.assignExpressionToRegister(condition.left, RegisterOrPair.AY, signed)
|
||||
asmgen.out(" sty P8ZP_SCRATCH_REG | ora P8ZP_SCRATCH_REG")
|
||||
return if(jumpAfterIf!=null)
|
||||
translateJumpElseBodies("beq", "bne", jumpAfterIf, stmt.elseScope)
|
||||
else
|
||||
translateIfElseBodies("bne", stmt)
|
||||
} else if(condition.operator=="!=") {
|
||||
// if X!=0
|
||||
// TODO even more optimized code by comparing lsb and msb separately
|
||||
asmgen.assignExpressionToRegister(condition.left, RegisterOrPair.AY, signed)
|
||||
asmgen.out(" sty P8ZP_SCRATCH_REG | ora P8ZP_SCRATCH_REG")
|
||||
return if(jumpAfterIf!=null)
|
||||
translateJumpElseBodies("bne", "beq", jumpAfterIf, stmt.elseScope)
|
||||
else
|
||||
translateIfElseBodies("beq", stmt)
|
||||
// optimized comparisons with zero
|
||||
when (condition.operator) {
|
||||
"==" -> return wordEqualsZero(condition.left, false, signed, jumpAfterIf, stmt)
|
||||
"!=" -> return wordEqualsZero(condition.left, true, signed, jumpAfterIf, stmt)
|
||||
"<" -> return wordLessZero(condition.left, signed, jumpAfterIf, stmt)
|
||||
"<=" -> return wordLessEqualsZero(condition.left, signed, jumpAfterIf, stmt)
|
||||
">" -> return wordGreaterZero(condition.left, signed, jumpAfterIf, stmt)
|
||||
">=" -> return wordGreaterEqualsZero(condition.left, signed, jumpAfterIf, stmt)
|
||||
}
|
||||
}
|
||||
|
||||
// non-zero comparisons
|
||||
when(condition.operator) {
|
||||
"==" -> {
|
||||
// TODO
|
||||
println("word if ==")
|
||||
fallbackTranslate(stmt)
|
||||
}
|
||||
"!=" -> {
|
||||
// TODO
|
||||
println("word if !=")
|
||||
fallbackTranslate(stmt)
|
||||
}
|
||||
"<" -> {
|
||||
// TODO()
|
||||
println("word if <")
|
||||
fallbackTranslate(stmt)
|
||||
}
|
||||
"<=" -> {
|
||||
// TODO()
|
||||
println("word if <=")
|
||||
fallbackTranslate(stmt)
|
||||
}
|
||||
">" -> {
|
||||
// TODO()
|
||||
println("word if >")
|
||||
fallbackTranslate(stmt)
|
||||
}
|
||||
">=" -> {
|
||||
// TODO()
|
||||
println("word if >=")
|
||||
fallbackTranslate(stmt)
|
||||
}
|
||||
"==" -> wordEqualsValue(condition.left, condition.right, false, signed, jumpAfterIf, stmt)
|
||||
"!=" -> wordEqualsValue(condition.left, condition.right, true, signed, jumpAfterIf, stmt)
|
||||
"<" -> wordLessValue(condition.left, condition.right, signed, jumpAfterIf, stmt)
|
||||
"<=" -> wordLessEqualsValue(condition.left, condition.right, signed, jumpAfterIf, stmt)
|
||||
">" -> wordGreaterValue(condition.left, condition.right, signed, jumpAfterIf, stmt)
|
||||
">=" -> wordGreaterEqualsValue(condition.left, condition.right, signed, jumpAfterIf, stmt)
|
||||
else -> fallbackTranslate(stmt, false)
|
||||
}
|
||||
}
|
||||
|
||||
private fun wordGreaterEqualsZero(value: PtExpression, signed: Boolean, jump: PtJump?, stmt: PtIfElse) {
|
||||
// special case for word>=0
|
||||
if(signed) {
|
||||
loadAndCmp0MSB(value)
|
||||
if (jump != null)
|
||||
translateJumpElseBodies("bpl", "bmi", jump, stmt.elseScope)
|
||||
else
|
||||
translateIfElseBodies("bmi", stmt)
|
||||
} else {
|
||||
asmgen.translate(stmt.ifScope)
|
||||
}
|
||||
}
|
||||
|
||||
private fun wordLessZero(value: PtExpression, signed: Boolean, jump: PtJump?, stmt: PtIfElse) {
|
||||
if(signed) {
|
||||
loadAndCmp0MSB(value)
|
||||
if (jump != null)
|
||||
translateJumpElseBodies("bmi", "bpl", jump, stmt.elseScope)
|
||||
else
|
||||
translateIfElseBodies("bpl", stmt)
|
||||
} else {
|
||||
asmgen.translate(stmt.elseScope)
|
||||
}
|
||||
}
|
||||
|
||||
private fun wordLessValue(left: PtExpression, right: PtExpression, signed: Boolean, jump: PtJump?, stmt: PtIfElse) {
|
||||
println("word if <") // TODO
|
||||
fallbackTranslate(stmt)
|
||||
}
|
||||
|
||||
private fun wordGreaterValue(left: PtExpression, right: PtExpression, signed: Boolean, jump: PtJump?, stmt: PtIfElse) {
|
||||
println("word if >") // TODO
|
||||
fallbackTranslate(stmt)
|
||||
}
|
||||
|
||||
private fun wordLessEqualsValue(left: PtExpression, right: PtExpression, signed: Boolean, jump: PtJump?, stmt: PtIfElse) {
|
||||
println("word if <=") // TODO
|
||||
fallbackTranslate(stmt)
|
||||
}
|
||||
|
||||
private fun wordGreaterEqualsValue(left: PtExpression, right: PtExpression, signed: Boolean, jump: PtJump?, stmt: PtIfElse) {
|
||||
println("word if >=") // TODO
|
||||
fallbackTranslate(stmt)
|
||||
}
|
||||
|
||||
private fun loadAndCmp0MSB(value: PtExpression) {
|
||||
when(value) {
|
||||
is PtArrayIndexer -> {
|
||||
val varname = asmgen.asmVariableName(value.variable)
|
||||
asmgen.loadScaledArrayIndexIntoRegister(value, CpuRegister.Y)
|
||||
asmgen.out(" lda $varname+1,y")
|
||||
}
|
||||
is PtIdentifier -> {
|
||||
val varname = asmgen.asmVariableName(value)
|
||||
asmgen.out(" lda $varname+1")
|
||||
}
|
||||
else -> {
|
||||
asmgen.assignExpressionToRegister(value, RegisterOrPair.AY, true)
|
||||
asmgen.out(" cmp #0")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun wordLessEqualsZero(value: PtExpression, signed: Boolean, jump: PtJump?, stmt: PtIfElse) {
|
||||
return if(signed) {
|
||||
asmgen.assignExpressionToRegister(value, RegisterOrPair.AY, true) // TODO optimize this even further by doing MSB/LSB separately
|
||||
if(jump!=null) {
|
||||
val (asmLabel, indirect) = asmgen.getJumpTarget(jump)
|
||||
if(indirect) {
|
||||
asmgen.out("""
|
||||
cpy #0
|
||||
bmi +
|
||||
bne ++
|
||||
cmp #0
|
||||
bne ++
|
||||
+ jmp ($asmLabel)
|
||||
+""")
|
||||
} else {
|
||||
asmgen.out("""
|
||||
cpy #0
|
||||
bmi $asmLabel
|
||||
bne +
|
||||
cmp #0
|
||||
beq $asmLabel
|
||||
+""")
|
||||
}
|
||||
asmgen.translate(stmt.elseScope)
|
||||
} else {
|
||||
val afterIfLabel = asmgen.makeLabel("afterif")
|
||||
if(stmt.hasElse()) {
|
||||
// if and else blocks
|
||||
val elseLabel = asmgen.makeLabel("else")
|
||||
asmgen.out("""
|
||||
cpy #0
|
||||
bmi +
|
||||
bne $elseLabel
|
||||
cmp #0
|
||||
bne $elseLabel
|
||||
+""")
|
||||
asmgen.translate(stmt.ifScope)
|
||||
asmgen.jmp(afterIfLabel, false)
|
||||
asmgen.out(elseLabel)
|
||||
asmgen.translate(stmt.elseScope)
|
||||
} else {
|
||||
// no else block
|
||||
asmgen.out("""
|
||||
cpy #0
|
||||
bmi +
|
||||
bne $afterIfLabel
|
||||
cmp #0
|
||||
bne $afterIfLabel
|
||||
+""")
|
||||
asmgen.translate(stmt.ifScope)
|
||||
}
|
||||
asmgen.out(afterIfLabel)
|
||||
}
|
||||
} else {
|
||||
wordEqualsZero(value, true, false, jump, stmt)
|
||||
}
|
||||
}
|
||||
|
||||
private fun wordGreaterZero(value: PtExpression, signed: Boolean, jump: PtJump?, stmt: PtIfElse) {
|
||||
if(signed) {
|
||||
asmgen.assignExpressionToRegister(value, RegisterOrPair.AY, true) // TODO optimize this even further by doing MSB/LSB separately
|
||||
if(jump!=null) {
|
||||
val (asmLabel, indirect) = asmgen.getJumpTarget(jump)
|
||||
if(indirect) {
|
||||
asmgen.out("""
|
||||
cpy #0
|
||||
bmi ++
|
||||
bne +
|
||||
cmp #0
|
||||
beq ++
|
||||
+ jmp ($asmLabel)
|
||||
+""")
|
||||
} else {
|
||||
asmgen.out("""
|
||||
cpy #0
|
||||
bmi +
|
||||
bne $asmLabel
|
||||
cmp #0
|
||||
bne $asmLabel
|
||||
+""")
|
||||
}
|
||||
asmgen.translate(stmt.elseScope)
|
||||
} else {
|
||||
val afterIfLabel = asmgen.makeLabel("afterif")
|
||||
if(stmt.hasElse()) {
|
||||
// if and else blocks
|
||||
val elseLabel = asmgen.makeLabel("else")
|
||||
asmgen.out("""
|
||||
cpy #0
|
||||
bmi $elseLabel
|
||||
bne +
|
||||
cmp #0
|
||||
beq $elseLabel
|
||||
+""")
|
||||
asmgen.translate(stmt.ifScope)
|
||||
asmgen.jmp(afterIfLabel, false)
|
||||
asmgen.out(elseLabel)
|
||||
asmgen.translate(stmt.elseScope)
|
||||
} else {
|
||||
// no else block
|
||||
asmgen.out("""
|
||||
cpy #0
|
||||
bmi $afterIfLabel
|
||||
bne +
|
||||
cmp #0
|
||||
beq $afterIfLabel
|
||||
+""")
|
||||
asmgen.translate(stmt.ifScope)
|
||||
}
|
||||
asmgen.out(afterIfLabel)
|
||||
}
|
||||
} else {
|
||||
wordEqualsZero(value, true, false, jump, stmt)
|
||||
}
|
||||
}
|
||||
|
||||
private fun wordEqualsZero(value: PtExpression, notEquals: Boolean, signed: Boolean, jump: PtJump?, stmt: PtIfElse) {
|
||||
|
||||
fun viaScratchReg(branchInstr: String, falseBranch: String) {
|
||||
asmgen.assignExpressionToRegister(value, RegisterOrPair.AY, signed)
|
||||
asmgen.out(" sty P8ZP_SCRATCH_REG | ora P8ZP_SCRATCH_REG")
|
||||
if(jump!=null)
|
||||
translateJumpElseBodies(branchInstr, falseBranch, jump, stmt.elseScope)
|
||||
else
|
||||
translateIfElseBodies(falseBranch, stmt)
|
||||
}
|
||||
|
||||
fun translateLoadFromVar(variable: String, branch: String, falseBranch: String) {
|
||||
asmgen.out(" lda $variable | ora $variable+1")
|
||||
return if(jump!=null)
|
||||
translateJumpElseBodies(branch, falseBranch, jump, stmt.elseScope)
|
||||
else
|
||||
translateIfElseBodies(falseBranch, stmt)
|
||||
}
|
||||
|
||||
if(notEquals) {
|
||||
when(value) {
|
||||
is PtArrayIndexer -> {
|
||||
val constIndex = value.index.asConstInteger()
|
||||
if(constIndex!=null) {
|
||||
val offset = constIndex * program.memsizer.memorySize(value.type)
|
||||
if(offset<256) {
|
||||
val varName = asmgen.asmVariableName(value.variable)
|
||||
return translateLoadFromVar("$varName+$offset", "bne", "beq")
|
||||
}
|
||||
}
|
||||
viaScratchReg("bne", "beq")
|
||||
}
|
||||
is PtIdentifier -> {
|
||||
return translateLoadFromVar(asmgen.asmVariableName(value), "bne", "beq")
|
||||
}
|
||||
else -> viaScratchReg("bne", "beq")
|
||||
}
|
||||
} else {
|
||||
when (value) {
|
||||
is PtArrayIndexer -> {
|
||||
val constIndex = value.index.asConstInteger()
|
||||
if(constIndex!=null) {
|
||||
val offset = constIndex * program.memsizer.memorySize(value.type)
|
||||
if(offset<256) {
|
||||
val varName = asmgen.asmVariableName(value.variable)
|
||||
return translateLoadFromVar("$varName+$offset", "beq", "bne")
|
||||
}
|
||||
}
|
||||
viaScratchReg("beq", "bne")
|
||||
}
|
||||
is PtIdentifier -> {
|
||||
return translateLoadFromVar(asmgen.asmVariableName(value), "beq", "bne")
|
||||
}
|
||||
else -> viaScratchReg("beq", "bne")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun wordEqualsValue(
|
||||
left: PtExpression,
|
||||
right: PtExpression,
|
||||
notEquals: Boolean,
|
||||
signed: Boolean,
|
||||
jump: PtJump?,
|
||||
stmt: PtIfElse
|
||||
) {
|
||||
|
||||
fun translateLoadFromVarNotEquals(varname: String) {
|
||||
if(jump!=null) {
|
||||
val (asmLabel, indirect) = asmgen.getJumpTarget(jump)
|
||||
if(indirect) {
|
||||
asmgen.out("""
|
||||
cmp $varname
|
||||
bne +
|
||||
cpy $varname+1
|
||||
beq ++
|
||||
+ jmp ($asmLabel)
|
||||
+""")
|
||||
} else {
|
||||
asmgen.out("""
|
||||
cmp $varname
|
||||
bne $asmLabel
|
||||
cpy $varname+1
|
||||
bne $asmLabel""")
|
||||
}
|
||||
asmgen.translate(stmt.elseScope)
|
||||
} else {
|
||||
val afterIfLabel = asmgen.makeLabel("afterif")
|
||||
if(stmt.hasElse()) {
|
||||
// if and else blocks
|
||||
val elseLabel = asmgen.makeLabel("else")
|
||||
asmgen.out("""
|
||||
cmp $varname
|
||||
bne +
|
||||
cpy $varname+1
|
||||
beq $elseLabel
|
||||
+""")
|
||||
asmgen.translate(stmt.ifScope)
|
||||
asmgen.jmp(afterIfLabel, false)
|
||||
asmgen.out(elseLabel)
|
||||
asmgen.translate(stmt.elseScope)
|
||||
} else {
|
||||
// no else block
|
||||
asmgen.out("""
|
||||
cmp $varname
|
||||
bne +
|
||||
cpy $varname+1
|
||||
beq $afterIfLabel
|
||||
+""")
|
||||
asmgen.translate(stmt.ifScope)
|
||||
}
|
||||
asmgen.out(afterIfLabel)
|
||||
}
|
||||
}
|
||||
|
||||
fun translateLoadFromVarEquals(varname: String) {
|
||||
return if(jump!=null) {
|
||||
val (asmLabel, indirect) = asmgen.getJumpTarget(jump)
|
||||
if(indirect) {
|
||||
asmgen.out("""
|
||||
cmp $varname
|
||||
bne +
|
||||
cpy $varname+1
|
||||
bne +
|
||||
jmp ($asmLabel)
|
||||
+""")
|
||||
} else {
|
||||
asmgen.out("""
|
||||
cmp $varname
|
||||
bne +
|
||||
cpy $varname+1
|
||||
beq $asmLabel
|
||||
+""")
|
||||
}
|
||||
asmgen.translate(stmt.elseScope)
|
||||
} else {
|
||||
val afterIfLabel = asmgen.makeLabel("afterif")
|
||||
if(stmt.hasElse()) {
|
||||
// if and else blocks
|
||||
val elseLabel = asmgen.makeLabel("else")
|
||||
asmgen.out("""
|
||||
cmp $varname
|
||||
bne $elseLabel
|
||||
cpy $varname+1
|
||||
bne $elseLabel""")
|
||||
asmgen.translate(stmt.ifScope)
|
||||
asmgen.jmp(afterIfLabel, false)
|
||||
asmgen.out(elseLabel)
|
||||
asmgen.translate(stmt.elseScope)
|
||||
} else {
|
||||
// no else block
|
||||
asmgen.out("""
|
||||
cmp $varname
|
||||
bne $afterIfLabel
|
||||
cpy $varname+1
|
||||
bne $afterIfLabel""")
|
||||
asmgen.translate(stmt.ifScope)
|
||||
}
|
||||
asmgen.out(afterIfLabel)
|
||||
}
|
||||
}
|
||||
|
||||
if(notEquals) {
|
||||
when(left) {
|
||||
is PtArrayIndexer -> {
|
||||
asmgen.assignExpressionToRegister(right, RegisterOrPair.AY, signed)
|
||||
val constIndex = left.index.asConstInteger()
|
||||
if(constIndex!=null) {
|
||||
val offset = constIndex * program.memsizer.memorySize(left.type)
|
||||
if(offset<256) {
|
||||
val varName = asmgen.asmVariableName(left.variable)
|
||||
return translateLoadFromVarNotEquals("$varName+$offset")
|
||||
}
|
||||
}
|
||||
fallbackTranslate(stmt, false)
|
||||
}
|
||||
is PtIdentifier -> {
|
||||
asmgen.assignExpressionToRegister(right, RegisterOrPair.AY, signed)
|
||||
return translateLoadFromVarNotEquals(asmgen.asmVariableName(left))
|
||||
}
|
||||
else -> fallbackTranslate(stmt, false)
|
||||
}
|
||||
} else {
|
||||
when(left) {
|
||||
is PtArrayIndexer -> {
|
||||
asmgen.assignExpressionToRegister(right, RegisterOrPair.AY, signed)
|
||||
val constIndex = left.index.asConstInteger()
|
||||
if(constIndex!=null) {
|
||||
val offset = constIndex * program.memsizer.memorySize(left.type)
|
||||
if(offset<256) {
|
||||
val varName = asmgen.asmVariableName(left.variable)
|
||||
return translateLoadFromVarEquals("$varName+$offset")
|
||||
}
|
||||
}
|
||||
fallbackTranslate(stmt, false)
|
||||
}
|
||||
is PtIdentifier -> {
|
||||
asmgen.assignExpressionToRegister(right, RegisterOrPair.AY, signed)
|
||||
return translateLoadFromVarEquals(asmgen.asmVariableName(left))
|
||||
}
|
||||
else -> fallbackTranslate(stmt, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun translateIfFloat(stmt: PtIfElse, condition: PtBinaryExpression, jumpAfterIf: PtJump?) {
|
||||
val constValue = (condition.right as? PtNumber)?.number
|
||||
if(constValue==0.0) {
|
||||
|
@ -2091,7 +2091,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
throw AssemblyError("can't store word into memory byte")
|
||||
}
|
||||
TargetStorageKind.ARRAY -> {
|
||||
asmgen.out(" lda #<$sourceName | ldy #>$sourceName")
|
||||
asmgen.out(" lda #<$sourceName | ldy #>$sourceName")
|
||||
assignRegisterpairWord(target, RegisterOrPair.AY)
|
||||
}
|
||||
TargetStorageKind.REGISTER -> {
|
||||
|
@ -1,6 +1,12 @@
|
||||
TODO
|
||||
====
|
||||
|
||||
examples/primes is larger than on 10.1
|
||||
examples/maze is larger than on 10.1
|
||||
examples/textelite is larger than on 10.1
|
||||
|
||||
|
||||
|
||||
===== ====== =======
|
||||
VM 6502 what
|
||||
===== ====== =======
|
||||
@ -44,6 +50,9 @@ 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.
|
||||
|
110
examples/test.p8
110
examples/test.p8
@ -6,8 +6,98 @@
|
||||
main {
|
||||
bool @shared staticbool1 = true
|
||||
bool @shared staticbool2
|
||||
word[4] words
|
||||
|
||||
byte @shared sbb
|
||||
|
||||
sub start() {
|
||||
|
||||
while cx16.r0s < 1234
|
||||
cx16.r0L++
|
||||
loop:
|
||||
if cx16.r0s >= 1234
|
||||
goto skip
|
||||
cx16.r0L++
|
||||
goto loop
|
||||
skip:
|
||||
|
||||
; TODO all this for uwords
|
||||
|
||||
; if sbb<0
|
||||
; cx16.r0L++
|
||||
; if sbb>0
|
||||
; cx16.r0L++
|
||||
; if sbb<=0
|
||||
; cx16.r0L++
|
||||
; if sbb>=0
|
||||
; cx16.r0L++
|
||||
; if cx16.r0s<0
|
||||
; cx16.r0L++
|
||||
; if cx16.r0s>0
|
||||
; cx16.r0L++
|
||||
; if cx16.r0s>0
|
||||
; goto start
|
||||
; if cx16.r0s>0
|
||||
; goto cx16.r0
|
||||
; if cx16.r0s<=0
|
||||
; cx16.r0L++
|
||||
; else
|
||||
; cx16.r0L++
|
||||
; if cx16.r0s>=0
|
||||
; cx16.r0L++
|
||||
; if words[2]<0
|
||||
; cx16.r0L++
|
||||
; if words[2]>0
|
||||
; cx16.r0L++
|
||||
; if words[2]<=0
|
||||
; cx16.r0L++
|
||||
; if words[2]>=0
|
||||
; cx16.r0L++
|
||||
; if words[cx16.r0L]<0
|
||||
; cx16.r0L++
|
||||
; if words[cx16.r0L]>0
|
||||
; cx16.r0L++
|
||||
; if words[cx16.r0L]<=0
|
||||
; cx16.r0L++
|
||||
; if words[cx16.r0L]>=0
|
||||
; cx16.r0L++
|
||||
|
||||
; staticbool2 = sbb < 0
|
||||
; staticbool2 = sbb > 0
|
||||
; staticbool1 = sbb <= 0
|
||||
; staticbool1 = sbb >= 0
|
||||
; staticbool2 = cx16.r0s <0
|
||||
; staticbool2 = cx16.r0s >0
|
||||
; staticbool1 = cx16.r0s <=0
|
||||
; staticbool1 = cx16.r0s >=0
|
||||
; staticbool2 = words[2]<0
|
||||
; staticbool2 = words[2]>0
|
||||
; staticbool1 = words[2]<=0
|
||||
; staticbool1 = words[2]>=0
|
||||
; staticbool2 = words[cx16.r0L]<0
|
||||
; staticbool2 = words[cx16.r0L]>0
|
||||
; staticbool1 = words[cx16.r0L]<=0
|
||||
; staticbool1 = words[cx16.r0L]>=0
|
||||
|
||||
|
||||
; if cx16.r0 > 1234
|
||||
; cx16.r0L++
|
||||
; if cx16.r0s > 1234
|
||||
; cx16.r0L++
|
||||
; if cx16.r0 < 1234
|
||||
; cx16.r0L++
|
||||
; if cx16.r0s < 1234
|
||||
; cx16.r0L++
|
||||
; if cx16.r0 >= 1234
|
||||
; cx16.r0L++
|
||||
; if cx16.r0s >= 1234
|
||||
; cx16.r0L++
|
||||
; if cx16.r0 <= 1234
|
||||
; cx16.r0L++
|
||||
; if cx16.r0s <= 1234
|
||||
; cx16.r0L++
|
||||
|
||||
|
||||
; boolean_const_and_var(true)
|
||||
; staticbool1 = boolean_arrays_and_return()
|
||||
; txt.print_ub(staticbool1 as ubyte)
|
||||
@ -27,7 +117,7 @@ main {
|
||||
; efficient_compare_99()
|
||||
; efficient_compare_var()
|
||||
; efficient_assign_cmp_0()
|
||||
efficient_assign_cmp_99()
|
||||
; efficient_assign_cmp_99()
|
||||
; efficient_assign_cmp_var()
|
||||
; if_gotos()
|
||||
; if_code()
|
||||
@ -472,6 +562,7 @@ main {
|
||||
|
||||
sub if_code() {
|
||||
ubyte @shared ub
|
||||
byte @shared sb
|
||||
bool @shared bb
|
||||
if ub==0
|
||||
cx16.r0L++
|
||||
@ -498,6 +589,23 @@ main {
|
||||
cx16.r0L++
|
||||
else
|
||||
cx16.r0--
|
||||
|
||||
if ub>10
|
||||
cx16.r0++
|
||||
if ub>=10
|
||||
cx16.r0++
|
||||
if ub<10
|
||||
cx16.r0++
|
||||
if ub<=10
|
||||
cx16.r0++
|
||||
if sb>10
|
||||
cx16.r0++
|
||||
if sb>=10
|
||||
cx16.r0++
|
||||
if sb<10
|
||||
cx16.r0++
|
||||
if sb<=10
|
||||
cx16.r0++
|
||||
}
|
||||
|
||||
sub intfunc() -> ubyte {
|
||||
|
Loading…
Reference in New Issue
Block a user