mirror of
https://github.com/irmen/prog8.git
synced 2025-01-14 01: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
|
val array = assignment.target.array
|
||||||
|
|
||||||
return if(ident!=null) {
|
return if(ident!=null) {
|
||||||
val address = codeGen.allocations.get(ident.targetName)
|
val address = codeGen.addressOf(ident.targetName)
|
||||||
assignSelfInMemory(address, assignment.value, assignment)
|
assignSelfInMemory(address, assignment.value, assignment)
|
||||||
} else if(memory != null) {
|
} else if(memory != null) {
|
||||||
if(memory.address is PtNumber)
|
if(memory.address is PtNumber)
|
||||||
@ -147,7 +147,7 @@ internal class AssignmentGen(private val codeGen: CodeGen, private val expressio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(ident!=null) {
|
if(ident!=null) {
|
||||||
val address = codeGen.allocations.get(ident.targetName)
|
val address = codeGen.addressOf(ident.targetName)
|
||||||
code += if(zero) {
|
code += if(zero) {
|
||||||
IRCodeInstruction(Opcode.STOREZM, vmDt, value = address)
|
IRCodeInstruction(Opcode.STOREZM, vmDt, value = address)
|
||||||
} else {
|
} else {
|
||||||
@ -159,7 +159,7 @@ internal class AssignmentGen(private val codeGen: CodeGen, private val expressio
|
|||||||
}
|
}
|
||||||
else if(array!=null) {
|
else if(array!=null) {
|
||||||
val variable = array.variable.targetName
|
val variable = array.variable.targetName
|
||||||
var variableAddr = codeGen.allocations.get(variable)
|
var variableAddr = codeGen.addressOf(variable)
|
||||||
val itemsize = codeGen.program.memsizer.memorySize(array.type)
|
val itemsize = codeGen.program.memsizer.memorySize(array.type)
|
||||||
|
|
||||||
if(array.variable.type==DataType.UWORD) {
|
if(array.variable.type==DataType.UWORD) {
|
||||||
|
@ -40,7 +40,6 @@ class CodeGen(internal val program: PtProgram,
|
|||||||
internal val errors: IErrorReporter
|
internal val errors: IErrorReporter
|
||||||
): IAssemblyGenerator {
|
): IAssemblyGenerator {
|
||||||
|
|
||||||
internal val allocations = VariableAllocator(symbolTable, program.encoding, program.memsizer)
|
|
||||||
private val expressionEval = ExpressionGen(this)
|
private val expressionEval = ExpressionGen(this)
|
||||||
private val builtinFuncGen = BuiltinFuncGen(this, expressionEval)
|
private val builtinFuncGen = BuiltinFuncGen(this, expressionEval)
|
||||||
private val assignmentGen = AssignmentGen(this, expressionEval)
|
private val assignmentGen = AssignmentGen(this, expressionEval)
|
||||||
@ -301,9 +300,9 @@ class CodeGen(internal val program: PtProgram,
|
|||||||
code += translateForInNonConstantRange(forLoop, loopvar)
|
code += translateForInNonConstantRange(forLoop, loopvar)
|
||||||
}
|
}
|
||||||
is PtIdentifier -> {
|
is PtIdentifier -> {
|
||||||
val arrayAddress = allocations.get(iterable.targetName)
|
val arrayAddress = addressOf(iterable.targetName)
|
||||||
val iterableVar = symbolTable.lookup(iterable.targetName) as StStaticVariable
|
val iterableVar = symbolTable.lookup(iterable.targetName) as StStaticVariable
|
||||||
val loopvarAddress = allocations.get(loopvar.scopedName)
|
val loopvarAddress = addressOf(loopvar.scopedName)
|
||||||
val indexReg = vmRegisters.nextFree()
|
val indexReg = vmRegisters.nextFree()
|
||||||
val tmpReg = vmRegisters.nextFree()
|
val tmpReg = vmRegisters.nextFree()
|
||||||
val loopLabel = createLabelName()
|
val loopLabel = createLabelName()
|
||||||
@ -352,6 +351,11 @@ class CodeGen(internal val program: PtProgram,
|
|||||||
return code
|
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 {
|
private fun translateForInNonConstantRange(forLoop: PtForLoop, loopvar: StStaticVariable): IRCodeChunk {
|
||||||
val iterable = forLoop.iterable as PtRange
|
val iterable = forLoop.iterable as PtRange
|
||||||
val step = iterable.step.number.toInt()
|
val step = iterable.step.number.toInt()
|
||||||
@ -359,7 +363,7 @@ class CodeGen(internal val program: PtProgram,
|
|||||||
throw AssemblyError("step 0")
|
throw AssemblyError("step 0")
|
||||||
val indexReg = vmRegisters.nextFree()
|
val indexReg = vmRegisters.nextFree()
|
||||||
val endvalueReg = vmRegisters.nextFree()
|
val endvalueReg = vmRegisters.nextFree()
|
||||||
val loopvarAddress = allocations.get(loopvar.scopedName)
|
val loopvarAddress = addressOf(loopvar.scopedName)
|
||||||
val loopvarDt = vmType(loopvar.dt)
|
val loopvarDt = vmType(loopvar.dt)
|
||||||
val loopLabel = createLabelName()
|
val loopLabel = createLabelName()
|
||||||
val code = IRCodeChunk(forLoop.position)
|
val code = IRCodeChunk(forLoop.position)
|
||||||
@ -378,7 +382,7 @@ class CodeGen(internal val program: PtProgram,
|
|||||||
|
|
||||||
private fun translateForInConstantRange(forLoop: PtForLoop, loopvar: StStaticVariable): IRCodeChunk {
|
private fun translateForInConstantRange(forLoop: PtForLoop, loopvar: StStaticVariable): IRCodeChunk {
|
||||||
val loopLabel = createLabelName()
|
val loopLabel = createLabelName()
|
||||||
val loopvarAddress = allocations.get(loopvar.scopedName)
|
val loopvarAddress = addressOf(loopvar.scopedName)
|
||||||
val indexReg = vmRegisters.nextFree()
|
val indexReg = vmRegisters.nextFree()
|
||||||
val loopvarDt = vmType(loopvar.dt)
|
val loopvarDt = vmType(loopvar.dt)
|
||||||
val iterable = forLoop.iterable as PtRange
|
val iterable = forLoop.iterable as PtRange
|
||||||
@ -753,7 +757,7 @@ class CodeGen(internal val program: PtProgram,
|
|||||||
val array = postIncrDecr.target.array
|
val array = postIncrDecr.target.array
|
||||||
val vmDt = vmType(postIncrDecr.target.type)
|
val vmDt = vmType(postIncrDecr.target.type)
|
||||||
if(ident!=null) {
|
if(ident!=null) {
|
||||||
val address = allocations.get(ident.targetName)
|
val address = addressOf(ident.targetName)
|
||||||
code += IRCodeInstruction(operationMem, vmDt, value = address)
|
code += IRCodeInstruction(operationMem, vmDt, value = address)
|
||||||
} else if(memory!=null) {
|
} else if(memory!=null) {
|
||||||
if(memory.address is PtNumber) {
|
if(memory.address is PtNumber) {
|
||||||
@ -769,7 +773,7 @@ class CodeGen(internal val program: PtProgram,
|
|||||||
}
|
}
|
||||||
} else if (array!=null) {
|
} else if (array!=null) {
|
||||||
val variable = array.variable.targetName
|
val variable = array.variable.targetName
|
||||||
var variableAddr = allocations.get(variable)
|
var variableAddr = addressOf(variable)
|
||||||
val itemsize = program.memsizer.memorySize(array.type)
|
val itemsize = program.memsizer.memorySize(array.type)
|
||||||
val fixedIndex = constIntValue(array.index)
|
val fixedIndex = constIntValue(array.index)
|
||||||
if(fixedIndex!=null) {
|
if(fixedIndex!=null) {
|
||||||
|
@ -30,7 +30,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
|
|||||||
}
|
}
|
||||||
is PtIdentifier -> {
|
is PtIdentifier -> {
|
||||||
val vmDt = codeGen.vmType(expr.type)
|
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) {
|
code += if (expr.type in PassByValueDatatypes) {
|
||||||
if(vmDt==VmDataType.FLOAT)
|
if(vmDt==VmDataType.FLOAT)
|
||||||
IRCodeInstruction(Opcode.LOADM, vmDt, fpReg1 = resultFpRegister, value = mem)
|
IRCodeInstruction(Opcode.LOADM, vmDt, fpReg1 = resultFpRegister, value = mem)
|
||||||
@ -43,7 +43,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
|
|||||||
}
|
}
|
||||||
is PtAddressOf -> {
|
is PtAddressOf -> {
|
||||||
val vmDt = codeGen.vmType(expr.type)
|
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)
|
code += IRCodeInstruction(Opcode.LOAD, vmDt, reg1=resultRegister, value=mem)
|
||||||
}
|
}
|
||||||
is PtMemoryByte -> {
|
is PtMemoryByte -> {
|
||||||
@ -107,7 +107,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
|
|||||||
val vmDt = codeGen.vmType(arrayIx.type)
|
val vmDt = codeGen.vmType(arrayIx.type)
|
||||||
val code = IRCodeChunk(arrayIx.position)
|
val code = IRCodeChunk(arrayIx.position)
|
||||||
val idxReg = codeGen.vmRegisters.nextFree()
|
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) {
|
if(arrayIx.variable.type==DataType.UWORD) {
|
||||||
// indexing a pointer var instead of a real array or string
|
// 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)
|
val paramDt = codeGen.vmType(parameter.type)
|
||||||
if(codeGen.isZero(arg)) {
|
if(codeGen.isZero(arg)) {
|
||||||
if (paramDt == VmDataType.FLOAT) {
|
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)
|
code += IRCodeInstruction(Opcode.STOREZM, paramDt, value = mem)
|
||||||
} else {
|
} 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)
|
code += IRCodeInstruction(Opcode.STOREZM, paramDt, value = mem)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (paramDt == VmDataType.FLOAT) {
|
if (paramDt == VmDataType.FLOAT) {
|
||||||
val argFpReg = codeGen.vmRegisters.nextFreeFloat()
|
val argFpReg = codeGen.vmRegisters.nextFreeFloat()
|
||||||
code += translateExpression(arg, -1, argFpReg)
|
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)
|
code += IRCodeInstruction(Opcode.STOREM, paramDt, fpReg1 = argFpReg, value = mem)
|
||||||
} else {
|
} else {
|
||||||
val argReg = codeGen.vmRegisters.nextFree()
|
val argReg = codeGen.vmRegisters.nextFree()
|
||||||
code += translateExpression(arg, argReg, -1)
|
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)
|
code += IRCodeInstruction(Opcode.STOREM, paramDt, reg1 = argReg, value = mem)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,11 +3,9 @@ TODO
|
|||||||
|
|
||||||
For next release
|
For next release
|
||||||
^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^
|
||||||
- vm: intermediate code: don't flatten everything. Instead, as a new intermediary step,
|
- IR/VM: add address-of support (see CodeGen.addrssOf())
|
||||||
convert the new Ast into *structured* intermediary code.
|
- IR/VM: add proper memory mapped variables support
|
||||||
Basically keep the blocks and subroutines structure, including full subroutine signature information,
|
- IR/VM: add proper memory slabs support
|
||||||
don't do variable and zeropage allocations yet.
|
|
||||||
|
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
||||||
|
@ -25,14 +25,16 @@ main {
|
|||||||
nop
|
nop
|
||||||
}}
|
}}
|
||||||
|
|
||||||
; TODO should generate address
|
; TODO add proper memory SLAB support to IR+VM
|
||||||
uword @shared slab1 = memory("slab 1", 2000, 0)
|
; uword @shared slab1 = memory("slab 1", 2000, 0)
|
||||||
uword @shared slab2 = memory("slab 1", 2000, 0)
|
; uword @shared slab2 = memory("slab 1", 2000, 0)
|
||||||
uword @shared slab3 = memory("other # slab", 2000, 64)
|
; uword @shared slab3 = memory("other # slab", 2000, 64)
|
||||||
|
|
||||||
&uword mapped = $c000
|
&uword mapped = $c000
|
||||||
&ubyte[20] mappedarray = $c100
|
&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 qq = zz
|
||||||
uword @shared @zp qq2 = &zz
|
uword @shared @zp qq2 = &zz
|
||||||
|
@ -412,7 +412,7 @@ class IRFileReader(outputDir: Path, programName: String) {
|
|||||||
else {
|
else {
|
||||||
if(operand.startsWith('_')) {
|
if(operand.startsWith('_')) {
|
||||||
// it's a label.
|
// 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
|
value = null
|
||||||
} else {
|
} else {
|
||||||
value = parseValue(operand)
|
value = parseValue(operand)
|
||||||
@ -423,7 +423,7 @@ class IRFileReader(outputDir: Path, programName: String) {
|
|||||||
operand = operands.removeFirst().trim()
|
operand = operands.removeFirst().trim()
|
||||||
if(operand.startsWith('_')) {
|
if(operand.startsWith('_')) {
|
||||||
// it's a label.
|
// 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
|
value = null
|
||||||
} else {
|
} else {
|
||||||
value = parseValue(operand)
|
value = parseValue(operand)
|
||||||
|
@ -143,6 +143,10 @@ class IRCodeInstruction(
|
|||||||
VmDataType.FLOAT, null -> {}
|
VmDataType.FLOAT, null -> {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(labelSymbol?.first()?.startsWith('_')==true) {
|
||||||
|
throw IllegalArgumentException("label/symbol should not start with underscore $labelSymbol")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user