goto can now accept any expression as address (instead of just a constant), and ofcourse a label name still.

This commit is contained in:
Irmen de Jong 2024-12-15 03:35:09 +01:00
parent cc59069876
commit 9e8cc8b54d
6 changed files with 238 additions and 145 deletions

View File

@ -608,8 +608,9 @@ class AsmGen6502Internal (
}
is PtAugmentedAssign -> assignmentAsmGen.translate(stmt)
is PtJump -> {
val (asmLabel, indirect) = getJumpTarget(stmt)
jmp(asmLabel, indirect)
val target = getJumpTarget(stmt)
require(!target.needsExpressionEvaluation)
jmp(target.asmLabel, target.indirect)
}
is PtLabel -> translate(stmt)
is PtConditionalBranch -> translate(stmt)
@ -1003,16 +1004,17 @@ $repeatLabel""")
if(jump!=null) {
// branch with only a jump (goto)
val instruction = branchInstruction(stmt.condition, false)
val (asmLabel, indirect) = getJumpTarget(jump)
if(indirect) {
val target = getJumpTarget(jump)
require(!target.needsExpressionEvaluation)
if(target.indirect) {
val complementedInstruction = branchInstruction(stmt.condition, true)
out("""
$complementedInstruction +
jmp ($asmLabel)
jmp (${target.asmLabel})
+""")
}
else {
out(" $instruction $asmLabel")
out(" $instruction ${target.asmLabel}")
}
translate(stmt.falseScope)
} else {
@ -1038,19 +1040,30 @@ $repeatLabel""")
}
}
internal fun getJumpTarget(jump: PtJump): Pair<String, Boolean> {
class JumpTarget(val asmLabel: String, val indirect: Boolean, val needsExpressionEvaluation: Boolean)
internal fun getJumpTarget(jump: PtJump, evaluateAddressExpression: Boolean = true): JumpTarget {
val ident = jump.target as? PtIdentifier
if(ident!=null) {
// can be a label, or a pointer variable
val symbol = symbolTable.lookup(ident.name)
return if(symbol?.type in arrayOf(StNodeType.STATICVAR, StNodeType.MEMVAR, StNodeType.CONSTANT))
Pair(asmSymbolName(ident), true) // indirect jump if the jump symbol is a variable
JumpTarget(asmSymbolName(ident), true, false) // indirect jump if the jump symbol is a variable
else
Pair(asmSymbolName(ident), false)
JumpTarget(asmSymbolName(ident), false, false)
}
val addr = jump.target.asConstInteger()
if(addr!=null) return Pair(addr.toHex(), false)
else TODO("GOTO TARGET ${jump.target}")
if(addr!=null)
return JumpTarget(addr.toHex(), false, false)
else {
if(evaluateAddressExpression) {
// we can do the address evaluation right now and just use a temporary pointer variable
assignExpressionToVariable(jump.target, "P8ZP_SCRATCH_W1", DataType.forDt(BaseDataType.UWORD))
return JumpTarget("P8ZP_SCRATCH_W1", true, false)
} else {
return JumpTarget("PROG8_JUMP_TARGET_IS_UNEVALUATED_ADDRESS_EXPRESSION", true, true)
}
}
}
private fun translate(ret: PtReturn) {

View File

@ -83,25 +83,27 @@ internal class IfElseAsmGen(private val program: PtProgram,
asmgen.out(" bit ${variable.name}")
if(testForBitSet) {
if(jumpAfterIf!=null) {
val (asmLabel, indirect) = asmgen.getJumpTarget(jumpAfterIf)
if(indirect)
val target = asmgen.getJumpTarget(jumpAfterIf)
require(!target.needsExpressionEvaluation)
if(target.indirect)
throw AssemblyError("cannot BIT to indirect label ${ifElse.position}")
if(ifElse.hasElse())
throw AssemblyError("didn't expect else part here ${ifElse.position}")
else
asmgen.out(" bmi $asmLabel")
asmgen.out(" bmi ${target.asmLabel}")
}
else
translateIfElseBodies("bpl", ifElse)
} else {
if(jumpAfterIf!=null) {
val (asmLabel, indirect) = asmgen.getJumpTarget(jumpAfterIf)
if(indirect)
val target = asmgen.getJumpTarget(jumpAfterIf)
require(!target.needsExpressionEvaluation)
if(target.indirect)
throw AssemblyError("cannot BIT to indirect label ${ifElse.position}")
if(ifElse.hasElse())
throw AssemblyError("didn't expect else part here ${ifElse.position}")
else
asmgen.out(" bpl $asmLabel")
asmgen.out(" bpl ${target.asmLabel}")
}
else
translateIfElseBodies("bmi", ifElse)
@ -113,25 +115,27 @@ internal class IfElseAsmGen(private val program: PtProgram,
asmgen.out(" bit ${variable.name}")
if(testForBitSet) {
if(jumpAfterIf!=null) {
val (asmLabel, indirect) = asmgen.getJumpTarget(jumpAfterIf)
if(indirect)
val target = asmgen.getJumpTarget(jumpAfterIf)
require(!target.needsExpressionEvaluation)
if(target.indirect)
throw AssemblyError("cannot BIT to indirect label ${ifElse.position}")
if(ifElse.hasElse())
throw AssemblyError("didn't expect else part here ${ifElse.position}")
else
asmgen.out(" bvs $asmLabel")
asmgen.out(" bvs ${target.asmLabel}")
}
else
translateIfElseBodies("bvc", ifElse)
} else {
if(jumpAfterIf!=null) {
val (asmLabel, indirect) = asmgen.getJumpTarget(jumpAfterIf)
if(indirect)
val target = asmgen.getJumpTarget(jumpAfterIf)
require(!target.needsExpressionEvaluation)
if(target.indirect)
throw AssemblyError("cannot BIT to indirect label ${ifElse.position}")
if(ifElse.hasElse())
throw AssemblyError("didn't expect else part here ${ifElse.position}")
else
asmgen.out(" bvc $asmLabel")
asmgen.out(" bvc ${target.asmLabel}")
}
else
translateIfElseBodies("bvs", ifElse)
@ -171,14 +175,17 @@ internal class IfElseAsmGen(private val program: PtProgram,
private fun translateJumpElseBodies(branchInstr: String, falseBranch: String, jump: PtJump, elseBlock: PtNodeGroup) {
// comparison value is already in A
val (asmLabel, indirect) = asmgen.getJumpTarget(jump)
if(indirect) {
var target = asmgen.getJumpTarget(jump, false)
if(target.indirect) {
asmgen.out(" $falseBranch +")
if(target.needsExpressionEvaluation)
target = asmgen.getJumpTarget(jump, true)
asmgen.out("""
$falseBranch +
jmp ($asmLabel)
jmp (${target.asmLabel})
+""")
} else {
asmgen.out(" $branchInstr $asmLabel")
require(!target.needsExpressionEvaluation)
asmgen.out(" $branchInstr ${target.asmLabel}")
}
asmgen.translate(elseBlock)
}
@ -283,17 +290,19 @@ internal class IfElseAsmGen(private val program: PtProgram,
">" -> {
if(signed) {
return if (jumpAfterIf != null) {
val (asmLabel, indirect) = asmgen.getJumpTarget(jumpAfterIf)
if(indirect) {
var target = asmgen.getJumpTarget(jumpAfterIf, false)
if(target.indirect) {
asmgen.out(" bmi + | beq +")
if(target.needsExpressionEvaluation)
target = asmgen.getJumpTarget(jumpAfterIf, true)
asmgen.out("""
bmi +
beq +
jmp ($asmLabel)
jmp (${target.asmLabel})
+""")
} else {
require(!target.needsExpressionEvaluation)
asmgen.out("""
beq +
bpl $asmLabel
bpl ${target.asmLabel}
+""")
}
asmgen.translate(stmt.elseScope)
@ -348,17 +357,19 @@ internal class IfElseAsmGen(private val program: PtProgram,
if(signed) {
// inverted '>'
return if (jumpAfterIf != null) {
val (asmLabel, indirect) = asmgen.getJumpTarget(jumpAfterIf)
if(indirect) {
var target = asmgen.getJumpTarget(jumpAfterIf, false)
if(target.indirect) {
asmgen.out(" bmi + | bne ++")
if(target.needsExpressionEvaluation)
target = asmgen.getJumpTarget(jumpAfterIf, true)
asmgen.out("""
bmi +
bne ++
+ jmp ($asmLabel)
+ jmp (${target.asmLabel})
+""")
} else {
require(!target.needsExpressionEvaluation)
asmgen.out("""
bmi $asmLabel
beq $asmLabel""")
bmi ${target.asmLabel}
beq ${target.asmLabel}""")
}
asmgen.translate(stmt.elseScope)
}
@ -427,17 +438,19 @@ internal class IfElseAsmGen(private val program: PtProgram,
asmgen.assignExpressionToRegister(condition.left, RegisterOrPair.A, false)
asmgen.cmpAwithByteValue(condition.right, false)
if(jumpAfterIf!=null) {
val (asmLabel, indirect) = asmgen.getJumpTarget(jumpAfterIf)
if(indirect) {
var target = asmgen.getJumpTarget(jumpAfterIf, false)
if(target.indirect) {
asmgen.out(" bcc + | beq +")
if(target.needsExpressionEvaluation)
target = asmgen.getJumpTarget(jumpAfterIf, true)
asmgen.out("""
bcc +
beq +
jmp ($asmLabel)
jmp (${target.asmLabel})
+""")
} else {
require(!target.needsExpressionEvaluation)
asmgen.out("""
beq +
bcs $asmLabel
bcs ${target.asmLabel}
+""")
}
asmgen.translate(stmt.elseScope)
@ -520,25 +533,29 @@ internal class IfElseAsmGen(private val program: PtProgram,
if(signed) {
// word < X
if(jump!=null) {
val (asmLabel, indirect) = asmgen.getJumpTarget(jump)
if(indirect) {
var target = asmgen.getJumpTarget(jump, false)
if(target.indirect) {
asmgen.out("""
cmp $valueLsb
tya
sbc $valueMsb
bvc +
eor #128
+ bpl +
jmp ($asmLabel)
+ bpl +""")
if(target.needsExpressionEvaluation)
target = asmgen.getJumpTarget(jump, true)
asmgen.out("""
jmp (${target.asmLabel})
+""")
} else {
require(!target.needsExpressionEvaluation)
asmgen.out("""
cmp $valueLsb
tya
sbc $valueMsb
bvc +
eor #128
+ bmi $asmLabel""")
+ bmi ${target.asmLabel}""")
}
} else {
val afterIfLabel = asmgen.makeLabel("afterif")
@ -572,23 +589,27 @@ internal class IfElseAsmGen(private val program: PtProgram,
} else {
// uword < X
if(jump!=null) {
val (asmLabel, indirect) = asmgen.getJumpTarget(jump)
if(indirect) {
var target = asmgen.getJumpTarget(jump, false)
if(target.indirect) {
asmgen.out("""
cpy $valueMsb
bcc _jump
+ bne +
cmp $valueLsb
bcs +
_jump jmp ($asmLabel)
bcs +""")
if(target.needsExpressionEvaluation)
target = asmgen.getJumpTarget(jump, true)
asmgen.out("""
_jump jmp (${target.asmLabel})
+""")
} else {
require(!target.needsExpressionEvaluation)
asmgen.out("""
cpy $valueMsb
bcc $asmLabel
bcc ${target.asmLabel}
bne +
cmp $valueLsb
bcc $asmLabel
bcc ${target.asmLabel}
+""")
}
} else {
@ -644,25 +665,29 @@ _jump jmp ($asmLabel)
if(signed) {
// word >= X
if(jump!=null) {
val (asmLabel, indirect) = asmgen.getJumpTarget(jump)
if(indirect) {
var target = asmgen.getJumpTarget(jump, false)
if(target.indirect) {
asmgen.out("""
cmp $valueLsb
tya
sbc $valueMsb
bvs +
eor #128
+ bpl +
jmp ($asmLabel)
+ bpl +""")
if(target.needsExpressionEvaluation)
target = asmgen.getJumpTarget(jump, true)
asmgen.out("""
jmp (${target.asmLabel})
+""")
} else {
require(!target.needsExpressionEvaluation)
asmgen.out("""
cmp $valueLsb
tya
sbc $valueMsb
bvs +
eor #128
+ bmi $asmLabel""")
+ bmi ${target.asmLabel}""")
}
} else {
val afterIfLabel = asmgen.makeLabel("afterif")
@ -696,21 +721,25 @@ _jump jmp ($asmLabel)
} else {
// uword >= X
if(jump!=null) {
val (asmLabel, indirect) = asmgen.getJumpTarget(jump)
if(indirect) {
var target = asmgen.getJumpTarget(jump, false)
if(target.indirect) {
asmgen.out("""
cmp $valueLsb
tya
sbc $valueMsb
bcc +
jmp ($asmLabel)
bcc +""")
if(target.needsExpressionEvaluation)
target = asmgen.getJumpTarget(jump, true)
asmgen.out("""
jmp (${target.asmLabel})
+""")
} else {
require(!target.needsExpressionEvaluation)
asmgen.out("""
cmp $valueLsb
tya
sbc $valueMsb
bcs $asmLabel""")
bcs ${target.asmLabel}""")
}
} else {
val afterIfLabel = asmgen.makeLabel("afterif")
@ -795,23 +824,27 @@ _jump jmp ($asmLabel)
fun compareLsbMsb(valueLsb: String, valueMsb: String) {
if(jump!=null) {
val (asmLabel, indirect) = asmgen.getJumpTarget(jump)
if(indirect) {
var target = asmgen.getJumpTarget(jump, false)
if(target.indirect) {
asmgen.out("""
lda $valueMsb
bmi +
bne ++
lda $valueLsb
bne ++
+ jmp ($asmLabel)
bne ++""")
if(target.needsExpressionEvaluation)
target = asmgen.getJumpTarget(jump, true)
asmgen.out("""
+ jmp (${target.asmLabel})
+""")
} else {
require(!target.needsExpressionEvaluation)
asmgen.out("""
lda $valueMsb
bmi $asmLabel
bmi ${target.asmLabel}
bne +
lda $valueLsb
beq $asmLabel
beq ${target.asmLabel}
+""")
}
asmgen.translate(stmt.elseScope)
@ -870,23 +903,27 @@ _jump jmp ($asmLabel)
asmgen.assignExpressionToRegister(value, RegisterOrPair.AY, true)
if(jump!=null) {
val (asmLabel, indirect) = asmgen.getJumpTarget(jump)
if(indirect) {
var target = asmgen.getJumpTarget(jump, false)
if(target.indirect) {
asmgen.out("""
cpy #0
bmi +
bne ++
cmp #0
bne ++
+ jmp ($asmLabel)
bne ++""")
if(target.needsExpressionEvaluation)
target = asmgen.getJumpTarget(jump, true)
asmgen.out("""
+ jmp (${target.asmLabel})
+""")
} else {
require(!target.needsExpressionEvaluation)
asmgen.out("""
cpy #0
bmi $asmLabel
bmi ${target.asmLabel}
bne +
cmp #0
beq $asmLabel
beq ${target.asmLabel}
+""")
}
asmgen.translate(stmt.elseScope)
@ -931,23 +968,27 @@ _jump jmp ($asmLabel)
fun compareLsbMsb(valueLsb: String, valueMsb: String) {
if(jump!=null) {
val (asmLabel, indirect) = asmgen.getJumpTarget(jump)
if(indirect) {
var target = asmgen.getJumpTarget(jump, false)
if(target.indirect) {
asmgen.out("""
lda $valueMsb
bmi ++
bne +
lda $valueLsb
beq ++
+ jmp ($asmLabel)
beq ++""")
if(target.needsExpressionEvaluation)
target = asmgen.getJumpTarget(jump, true)
asmgen.out("""
+ jmp (${target.asmLabel})
+""")
} else {
require(!target.needsExpressionEvaluation)
asmgen.out("""
lda $valueMsb
bmi +
bne $asmLabel
bne ${target.asmLabel}
lda $valueLsb
bne $asmLabel
bne ${target.asmLabel}
+""")
}
asmgen.translate(stmt.elseScope)
@ -1007,23 +1048,27 @@ _jump jmp ($asmLabel)
asmgen.assignExpressionToRegister(value, RegisterOrPair.AY, true)
if(jump!=null) {
val (asmLabel, indirect) = asmgen.getJumpTarget(jump)
if(indirect) {
var target = asmgen.getJumpTarget(jump, false)
if(target.indirect) {
asmgen.out("""
cpy #0
bmi ++
bne +
cmp #0
beq ++
+ jmp ($asmLabel)
cpy #0
bmi ++
bne +
cmp #0
beq ++""")
if(target.needsExpressionEvaluation)
target = asmgen.getJumpTarget(jump, true)
asmgen.out("""
+ jmp (${target.asmLabel})
+""")
} else {
require(!target.needsExpressionEvaluation)
asmgen.out("""
cpy #0
bmi +
bne $asmLabel
cmp #0
bne $asmLabel
cpy #0
bmi +
bne ${target.asmLabel}
cmp #0
bne ${target.asmLabel}
+""")
}
asmgen.translate(stmt.elseScope)
@ -1147,21 +1192,25 @@ _jump jmp ($asmLabel)
fun translateAYNotEquals(valueLsb: String, valueMsb: String) {
if(jump!=null) {
val (asmLabel, indirect) = asmgen.getJumpTarget(jump)
if(indirect) {
var target = asmgen.getJumpTarget(jump, false)
if(target.indirect) {
asmgen.out("""
cmp $valueLsb
bne +
cpy $valueMsb
beq ++
+ jmp ($asmLabel)
beq ++""")
if(target.needsExpressionEvaluation)
target = asmgen.getJumpTarget(jump, true)
asmgen.out("""
+ jmp (${target.asmLabel})
+""")
} else {
require(!target.needsExpressionEvaluation)
asmgen.out("""
cmp $valueLsb
bne $asmLabel
bne ${target.asmLabel}
cpy $valueMsb
bne $asmLabel""")
bne ${target.asmLabel}""")
}
asmgen.translate(stmt.elseScope)
} else {
@ -1195,21 +1244,25 @@ _jump jmp ($asmLabel)
fun translateAYEquals(valueLsb: String, valueMsb: String) {
if(jump!=null) {
val (asmLabel, indirect) = asmgen.getJumpTarget(jump)
if(indirect) {
var target = asmgen.getJumpTarget(jump, false)
if(target.indirect) {
asmgen.out("""
cmp $valueLsb
bne +
cpy $valueMsb
bne +
jmp ($asmLabel)
bne +""")
if(target.needsExpressionEvaluation)
target = asmgen.getJumpTarget(jump, true)
asmgen.out("""
jmp (${target.asmLabel})
+""")
} else {
require(!target.needsExpressionEvaluation)
asmgen.out("""
cmp $valueLsb
bne +
cpy $valueMsb
beq $asmLabel
beq ${target.asmLabel}
+""")
}
asmgen.translate(stmt.elseScope)
@ -1243,25 +1296,29 @@ _jump jmp ($asmLabel)
fun translateEqualsVarVar(left: PtIdentifier, right: PtIdentifier) {
if(notEquals) {
if(jump!=null) {
val (asmLabel, indirect) = asmgen.getJumpTarget(jump)
if(indirect) {
var target = asmgen.getJumpTarget(jump, false)
if(target.indirect) {
asmgen.out("""
lda ${left.name}
cmp ${right.name}
bne +
lda ${left.name}+1
cmp ${right.name}+1
beq ++
+ jmp ($asmLabel)
beq ++""")
if(target.needsExpressionEvaluation)
target = asmgen.getJumpTarget(jump, true)
asmgen.out("""
+ jmp (${target.asmLabel})
+""")
} else {
require(!target.needsExpressionEvaluation)
asmgen.out("""
lda ${left.name}
cmp ${right.name}
bne $asmLabel
bne ${target.asmLabel}
lda ${left.name}+1
cmp ${right.name}+1
bne $asmLabel""")
bne ${target.asmLabel}""")
}
asmgen.translate(stmt.elseScope)
} else {
@ -1298,25 +1355,29 @@ _jump jmp ($asmLabel)
} else {
// XXX translateAYEquals(right.name, right.name + "+1")
if(jump!=null) {
val (asmLabel, indirect) = asmgen.getJumpTarget(jump)
if(indirect) {
var target = asmgen.getJumpTarget(jump, false)
if(target.indirect) {
asmgen.out("""
lda ${left.name}
cmp ${right.name}
bne +
lda ${left.name}+1
cmp ${right.name}+1
bne +
jmp ($asmLabel)
bne +""")
if(target.needsExpressionEvaluation)
target = asmgen.getJumpTarget(jump, true)
asmgen.out("""
jmp (${target.asmLabel})
+""")
} else {
require(!target.needsExpressionEvaluation)
asmgen.out("""
lda ${left.name}
cmp ${right.name}
bne +
lda ${left.name}+1
cmp ${right.name}+1
beq $asmLabel
beq ${target.asmLabel}
+""")
}
asmgen.translate(stmt.elseScope)
@ -1356,25 +1417,29 @@ _jump jmp ($asmLabel)
val value = right.number.toInt()
if(notEquals) {
if(jump!=null) {
val (asmLabel, indirect) = asmgen.getJumpTarget(jump)
if(indirect) {
var target = asmgen.getJumpTarget(jump, false)
if(target.indirect) {
asmgen.out("""
lda ${left.name}
cmp #<$value
bne +
lda ${left.name}+1
cmp #>$value
beq ++
+ jmp ($asmLabel)
beq ++""")
if(target.needsExpressionEvaluation)
target = asmgen.getJumpTarget(jump, true)
asmgen.out("""
+ jmp (${target.asmLabel})
+""")
} else {
require(!target.needsExpressionEvaluation)
asmgen.out("""
lda ${left.name}
cmp #<$value
bne $asmLabel
bne ${target.asmLabel}
lda ${left.name}+1
cmp #>$value
bne $asmLabel""")
bne ${target.asmLabel}""")
}
asmgen.translate(stmt.elseScope)
} else {
@ -1410,25 +1475,29 @@ _jump jmp ($asmLabel)
}
} else {
if(jump!=null) {
val (asmLabel, indirect) = asmgen.getJumpTarget(jump)
if(indirect) {
var target = asmgen.getJumpTarget(jump, false)
if(target.indirect) {
asmgen.out("""
lda ${left.name}
cmp #<$value
bne +
lda ${left.name}+1
cmp #>$value
bne +
jmp ($asmLabel)
bne +""")
if(target.needsExpressionEvaluation)
target = asmgen.getJumpTarget(jump, true)
asmgen.out("""
jmp (${target.asmLabel})
+""")
} else {
require(!target.needsExpressionEvaluation)
asmgen.out("""
lda ${left.name}
cmp #<$value
bne +
lda ${left.name}+1
cmp #>$value
beq $asmLabel
beq ${target.asmLabel}
+""")
}
asmgen.translate(stmt.elseScope)

View File

@ -304,7 +304,7 @@ class IRCodeGen(
}
addInstr(result, branchIns, null)
} else {
TODO("GOTO TARGET ${goto.target}")
TODO("JUMP to expression address ${goto.target}")
}
if(branch.falseScope.children.isNotEmpty())
result += translateNode(branch.falseScope)
@ -1031,7 +1031,7 @@ class IRCodeGen(
if(identifier!=null) {
it += IRInstruction(Opcode.JUMPI, labelSymbol = identifier.name)
} else {
TODO("GOTO TARGET ${goto.target}")
TODO("JUMP to expression address ${goto.target}")
}
} else {
// normal jump, directly to target with branch opcode
@ -1057,7 +1057,7 @@ class IRCodeGen(
else if(goto.target is PtIdentifier)
IRInstruction(gotoOpcode, IRDataType.BYTE, reg1 = compResultReg, immediate = 0, labelSymbol = (goto.target as PtIdentifier).name)
else
TODO("GOTO TARGET ${goto.target}")
TODO("JUMP to expression address ${goto.target}")
}
}
}
@ -1076,7 +1076,7 @@ class IRCodeGen(
if(identifier!=null)
IRInstruction(branchOpcode, labelSymbol = identifier.name)
else
TODO("GOTO TARGET ${goto.target}")
TODO("JUMP to expression address ${goto.target}")
}
}
@ -1086,7 +1086,7 @@ class IRCodeGen(
val afterIfLabel = createLabelName()
val identifier = goto.target as? PtIdentifier
if(identifier==null) {
TODO("GOTO TARGET ${goto.target}")
TODO("JUMP to expression address ${goto.target}")
}
val gotoSymbol = identifier.name
@ -1257,7 +1257,7 @@ class IRCodeGen(
else if(goto.target is PtIdentifier)
addInstr(result, IRInstruction(opcode, irDt, reg1 = firstReg, immediate = number, labelSymbol = (goto.target as PtIdentifier).name), null)
else
TODO("GOTO TARGET ${goto.target}")
TODO("JUMP to expression address ${goto.target}")
}
}
} else {
@ -1316,7 +1316,7 @@ class IRCodeGen(
else if(goto.target is PtIdentifier)
addInstr(result, IRInstruction(opcode, irDt, reg1 = firstReg, reg2 = secondReg, labelSymbol = (goto.target as PtIdentifier).name), null)
else
TODO("GOTO TARGET ${goto.target}")
TODO("JUMP to expression address ${goto.target}")
}
}
}
@ -1660,7 +1660,7 @@ class IRCodeGen(
IRInstruction(Opcode.JUMP, labelSymbol = identifier.name)
}
} else {
TODO("GOTO TARGET ${jump.target}")
TODO("JUMP to expression address ${jump.target}")
}
}
result += chunk

View File

@ -760,12 +760,13 @@ using qualified "dotted names"::
uword address = $4000
goto address ; jump via address variable
goto address + idx ; jump to an adress that is the result of an expression
Notice that this is a valid way to end a subroutine (you can either ``return`` from it, or jump
to another piece of code that eventually returns).
If you jump to an address variable (uword), it is doing an 'indirect' jump: the jump will be done
to the address that's currently in the variable.
If you jump to an address variable or expression (uword), it is doing an 'indirect' jump: the jump will be done
to the address that's currently in the variable, or the result of the expression.
Assignments

View File

@ -1,8 +1,9 @@
TODO
====
goto can now accept any expression (instead of just a constant address or an identifier).
document this. + FIX code gen for the case where the target is a non-constant expression! See TODOs with "GOTO TARGET"
- make word arrays split by default (remove @split tag) and use new @nosplit tag to make an array use the old storage format? Also invert -splitarrays command line option.
- add &< and &> operators to get the address of the lsb-array and msb-array, respectively. Regular & will just return the start of the split array in memory whatever byte comes first.
- update Syntax files + Document all of this (also that word arrays can then have length 256 by default as well, and that @linear will reduce it to half.)
...
@ -10,7 +11,6 @@ document this. + FIX code gen for the case where the target is a non-constant e
Future Things and Ideas
^^^^^^^^^^^^^^^^^^^^^^^
- make word arrays split by default (remove @split tag) and use new @notsplit or @linear tag to make an array use the old storage format? Also remove -splitarrays command line option. Document this (also that word arrays can then have length 256 by default as well, and that @linear will reduce it to half.)
- a syntax to access specific bits in a variable, to avoid manually shifts&ands, something like variable[4:8] ? (or something else this may be too similar to regular array indexing)
- something to reduce the need to use fully qualified names all the time. 'with' ? Or 'using <prefix>'?
- Libraries: improve ability to create library files in prog8; for instance there's still stuff injected into the start of the start() routine AND there is separate setup logic going on before calling it.
@ -46,6 +46,7 @@ IR/VM
- fix call() return value handling
- fix float register parameters (FAC1,FAC2) for extsubs, search for TODO("floating point register parameters not supported")
- proper code gen for the CALLI instruction and that it (optionally) returns a word value that needs to be assigned to a reg
- make it possible to jump and branch to a computed address (expression), see TODO("JUMP to expression address
- idea: (but LLVM IR simply keeps the variables, so not a good idea then?...): replace all scalar variables by an allocated register. Keep a table of the variable to register mapping (including the datatype)
global initialization values are simply a list of LOAD instructions.
Variables replaced include all subroutine parameters! So the only variables that remain as variables are arrays and strings.

View File

@ -2,8 +2,17 @@ main {
sub start() {
goto $3000
goto labeltje
goto cx16.r0
goto cx16.r0+cx16.r1
if cx16.r0==0
goto cx16.r0+cx16.r1
if cx16.r0>2000
goto cx16.r0+cx16.r1
labeltje:
}
}