diff --git a/codeGenExperimental/src/prog8/codegen/experimental/AssignmentGen.kt b/codeGenExperimental/src/prog8/codegen/experimental/AssignmentGen.kt index f0abe2559..15bfe41a6 100644 --- a/codeGenExperimental/src/prog8/codegen/experimental/AssignmentGen.kt +++ b/codeGenExperimental/src/prog8/codegen/experimental/AssignmentGen.kt @@ -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) { diff --git a/codeGenExperimental/src/prog8/codegen/experimental/CodeGen.kt b/codeGenExperimental/src/prog8/codegen/experimental/CodeGen.kt index e9ea700ae..0e78ea342 100644 --- a/codeGenExperimental/src/prog8/codegen/experimental/CodeGen.kt +++ b/codeGenExperimental/src/prog8/codegen/experimental/CodeGen.kt @@ -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): 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) { diff --git a/codeGenExperimental/src/prog8/codegen/experimental/ExpressionGen.kt b/codeGenExperimental/src/prog8/codegen/experimental/ExpressionGen.kt index 15b26c129..83f4e5a09 100644 --- a/codeGenExperimental/src/prog8/codegen/experimental/ExpressionGen.kt +++ b/codeGenExperimental/src/prog8/codegen/experimental/ExpressionGen.kt @@ -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) } } diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 21835dd49..ac63c7bf3 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -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 ... diff --git a/examples/test.p8 b/examples/test.p8 index ca202e5c4..5130067d8 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -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 diff --git a/intermediate/src/prog8/intermediate/IRFileReader.kt b/intermediate/src/prog8/intermediate/IRFileReader.kt index 067659678..ee6a9919b 100644 --- a/intermediate/src/prog8/intermediate/IRFileReader.kt +++ b/intermediate/src/prog8/intermediate/IRFileReader.kt @@ -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) diff --git a/intermediate/src/prog8/intermediate/IRProgram.kt b/intermediate/src/prog8/intermediate/IRProgram.kt index a527fb93e..1a4e3132e 100644 --- a/intermediate/src/prog8/intermediate/IRProgram.kt +++ b/intermediate/src/prog8/intermediate/IRProgram.kt @@ -143,6 +143,10 @@ class IRCodeInstruction( VmDataType.FLOAT, null -> {} } } + + if(labelSymbol?.first()?.startsWith('_')==true) { + throw IllegalArgumentException("label/symbol should not start with underscore $labelSymbol") + } } }