mirror of
https://github.com/irmen/prog8.git
synced 2024-12-25 23:29:55 +00:00
getting address-of into IR without allocations
This commit is contained in:
parent
3c315703c0
commit
502a665ffc
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
...
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -143,6 +143,10 @@ class IRCodeInstruction(
|
||||
VmDataType.FLOAT, null -> {}
|
||||
}
|
||||
}
|
||||
|
||||
if(labelSymbol?.first()?.startsWith('_')==true) {
|
||||
throw IllegalArgumentException("label/symbol should not start with underscore $labelSymbol")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user