getting address-of into IR without allocations

This commit is contained in:
Irmen de Jong 2022-09-04 23:18:35 +02:00
parent 3c315703c0
commit 502a665ffc
7 changed files with 37 additions and 29 deletions

View File

@ -28,7 +28,7 @@ internal class AssignmentGen(private val codeGen: CodeGen, private val expressio
val array = assignment.target.array
return if(ident!=null) {
val address = codeGen.allocations.get(ident.targetName)
val address = codeGen.addressOf(ident.targetName)
assignSelfInMemory(address, assignment.value, assignment)
} else if(memory != null) {
if(memory.address is PtNumber)
@ -147,7 +147,7 @@ internal class AssignmentGen(private val codeGen: CodeGen, private val expressio
}
}
if(ident!=null) {
val address = codeGen.allocations.get(ident.targetName)
val address = codeGen.addressOf(ident.targetName)
code += if(zero) {
IRCodeInstruction(Opcode.STOREZM, vmDt, value = address)
} else {
@ -159,7 +159,7 @@ internal class AssignmentGen(private val codeGen: CodeGen, private val expressio
}
else if(array!=null) {
val variable = array.variable.targetName
var variableAddr = codeGen.allocations.get(variable)
var variableAddr = codeGen.addressOf(variable)
val itemsize = codeGen.program.memsizer.memorySize(array.type)
if(array.variable.type==DataType.UWORD) {

View File

@ -40,7 +40,6 @@ class CodeGen(internal val program: PtProgram,
internal val errors: IErrorReporter
): IAssemblyGenerator {
internal val allocations = VariableAllocator(symbolTable, program.encoding, program.memsizer)
private val expressionEval = ExpressionGen(this)
private val builtinFuncGen = BuiltinFuncGen(this, expressionEval)
private val assignmentGen = AssignmentGen(this, expressionEval)
@ -301,9 +300,9 @@ class CodeGen(internal val program: PtProgram,
code += translateForInNonConstantRange(forLoop, loopvar)
}
is PtIdentifier -> {
val arrayAddress = allocations.get(iterable.targetName)
val arrayAddress = addressOf(iterable.targetName)
val iterableVar = symbolTable.lookup(iterable.targetName) as StStaticVariable
val loopvarAddress = allocations.get(loopvar.scopedName)
val loopvarAddress = addressOf(loopvar.scopedName)
val indexReg = vmRegisters.nextFree()
val tmpReg = vmRegisters.nextFree()
val loopLabel = createLabelName()
@ -352,6 +351,11 @@ class CodeGen(internal val program: PtProgram,
return code
}
internal fun addressOf(targetName: List<String>): Int {
println("TODO: IR SUPPORT FOR ADDRESS-OF $targetName") // TODO address-of
return 4242
}
private fun translateForInNonConstantRange(forLoop: PtForLoop, loopvar: StStaticVariable): IRCodeChunk {
val iterable = forLoop.iterable as PtRange
val step = iterable.step.number.toInt()
@ -359,7 +363,7 @@ class CodeGen(internal val program: PtProgram,
throw AssemblyError("step 0")
val indexReg = vmRegisters.nextFree()
val endvalueReg = vmRegisters.nextFree()
val loopvarAddress = allocations.get(loopvar.scopedName)
val loopvarAddress = addressOf(loopvar.scopedName)
val loopvarDt = vmType(loopvar.dt)
val loopLabel = createLabelName()
val code = IRCodeChunk(forLoop.position)
@ -378,7 +382,7 @@ class CodeGen(internal val program: PtProgram,
private fun translateForInConstantRange(forLoop: PtForLoop, loopvar: StStaticVariable): IRCodeChunk {
val loopLabel = createLabelName()
val loopvarAddress = allocations.get(loopvar.scopedName)
val loopvarAddress = addressOf(loopvar.scopedName)
val indexReg = vmRegisters.nextFree()
val loopvarDt = vmType(loopvar.dt)
val iterable = forLoop.iterable as PtRange
@ -753,7 +757,7 @@ class CodeGen(internal val program: PtProgram,
val array = postIncrDecr.target.array
val vmDt = vmType(postIncrDecr.target.type)
if(ident!=null) {
val address = allocations.get(ident.targetName)
val address = addressOf(ident.targetName)
code += IRCodeInstruction(operationMem, vmDt, value = address)
} else if(memory!=null) {
if(memory.address is PtNumber) {
@ -769,7 +773,7 @@ class CodeGen(internal val program: PtProgram,
}
} else if (array!=null) {
val variable = array.variable.targetName
var variableAddr = allocations.get(variable)
var variableAddr = addressOf(variable)
val itemsize = program.memsizer.memorySize(array.type)
val fixedIndex = constIntValue(array.index)
if(fixedIndex!=null) {

View File

@ -30,7 +30,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
}
is PtIdentifier -> {
val vmDt = codeGen.vmType(expr.type)
val mem = codeGen.allocations.get(expr.targetName)
val mem = codeGen.addressOf(expr.targetName)
code += if (expr.type in PassByValueDatatypes) {
if(vmDt==VmDataType.FLOAT)
IRCodeInstruction(Opcode.LOADM, vmDt, fpReg1 = resultFpRegister, value = mem)
@ -43,7 +43,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
}
is PtAddressOf -> {
val vmDt = codeGen.vmType(expr.type)
val mem = codeGen.allocations.get(expr.identifier.targetName)
val mem = codeGen.addressOf(expr.identifier.targetName)
code += IRCodeInstruction(Opcode.LOAD, vmDt, reg1=resultRegister, value=mem)
}
is PtMemoryByte -> {
@ -107,7 +107,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
val vmDt = codeGen.vmType(arrayIx.type)
val code = IRCodeChunk(arrayIx.position)
val idxReg = codeGen.vmRegisters.nextFree()
val arrayLocation = codeGen.allocations.get(arrayIx.variable.targetName)
val arrayLocation = codeGen.addressOf(arrayIx.variable.targetName)
if(arrayIx.variable.type==DataType.UWORD) {
// indexing a pointer var instead of a real array or string
@ -819,22 +819,22 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
val paramDt = codeGen.vmType(parameter.type)
if(codeGen.isZero(arg)) {
if (paramDt == VmDataType.FLOAT) {
val mem = codeGen.allocations.get(fcall.functionName + parameter.name)
val mem = codeGen.addressOf(fcall.functionName + parameter.name)
code += IRCodeInstruction(Opcode.STOREZM, paramDt, value = mem)
} else {
val mem = codeGen.allocations.get(fcall.functionName + parameter.name)
val mem = codeGen.addressOf(fcall.functionName + parameter.name)
code += IRCodeInstruction(Opcode.STOREZM, paramDt, value = mem)
}
} else {
if (paramDt == VmDataType.FLOAT) {
val argFpReg = codeGen.vmRegisters.nextFreeFloat()
code += translateExpression(arg, -1, argFpReg)
val mem = codeGen.allocations.get(fcall.functionName + parameter.name)
val mem = codeGen.addressOf(fcall.functionName + parameter.name)
code += IRCodeInstruction(Opcode.STOREM, paramDt, fpReg1 = argFpReg, value = mem)
} else {
val argReg = codeGen.vmRegisters.nextFree()
code += translateExpression(arg, argReg, -1)
val mem = codeGen.allocations.get(fcall.functionName + parameter.name)
val mem = codeGen.addressOf(fcall.functionName + parameter.name)
code += IRCodeInstruction(Opcode.STOREM, paramDt, reg1 = argReg, value = mem)
}
}

View File

@ -3,11 +3,9 @@ TODO
For next release
^^^^^^^^^^^^^^^^
- vm: intermediate code: don't flatten everything. Instead, as a new intermediary step,
convert the new Ast into *structured* intermediary code.
Basically keep the blocks and subroutines structure, including full subroutine signature information,
don't do variable and zeropage allocations yet.
- IR/VM: add address-of support (see CodeGen.addrssOf())
- IR/VM: add proper memory mapped variables support
- IR/VM: add proper memory slabs support
...

View File

@ -25,14 +25,16 @@ main {
nop
}}
; TODO should generate address
uword @shared slab1 = memory("slab 1", 2000, 0)
uword @shared slab2 = memory("slab 1", 2000, 0)
uword @shared slab3 = memory("other # slab", 2000, 64)
; TODO add proper memory SLAB support to IR+VM
; uword @shared slab1 = memory("slab 1", 2000, 0)
; uword @shared slab2 = memory("slab 1", 2000, 0)
; uword @shared slab3 = memory("other # slab", 2000, 64)
&uword mapped = $c000
&ubyte[20] mappedarray = $c100
uword @shared zz = slab1+slab2+slab3
uword @shared zz
; TODO zz = slab1+slab2+slab3
uword @shared @zp qq = zz
uword @shared @zp qq2 = &zz

View File

@ -412,7 +412,7 @@ class IRFileReader(outputDir: Path, programName: String) {
else {
if(operand.startsWith('_')) {
// it's a label.
labelSymbol = rest.split(",")[2].trim().split('.') // keep the original case
labelSymbol = rest.split(",")[2].trim().substring(1).split('.') // keep the original case
value = null
} else {
value = parseValue(operand)
@ -423,7 +423,7 @@ class IRFileReader(outputDir: Path, programName: String) {
operand = operands.removeFirst().trim()
if(operand.startsWith('_')) {
// it's a label.
labelSymbol = rest.split(",")[3].trim().split('.') // keep the original case
labelSymbol = rest.split(",")[3].trim().substring(1).split('.') // keep the original case
value = null
} else {
value = parseValue(operand)

View File

@ -143,6 +143,10 @@ class IRCodeInstruction(
VmDataType.FLOAT, null -> {}
}
}
if(labelSymbol?.first()?.startsWith('_')==true) {
throw IllegalArgumentException("label/symbol should not start with underscore $labelSymbol")
}
}
}