From 0e831d4b92ba73f1930932d122a5e814d4cda1b8 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Thu, 15 Sep 2022 23:08:41 +0200 Subject: [PATCH] fix superfluous usage of addressOf() --- .../codegen/experimental/AssignmentGen.kt | 60 ++++----- .../src/prog8/codegen/experimental/CodeGen.kt | 124 ++++++++++-------- .../codegen/experimental/ExpressionGen.kt | 107 +++++++-------- .../codegen/experimental/VmAssemblyProgram.kt | 12 +- .../prog8/codegen/virtual/AssemblyProgram.kt | 10 +- compiler/res/prog8lib/virtual/conv.p8 | 4 +- compiler/res/prog8lib/virtual/floats.p8 | 28 ++-- compiler/res/prog8lib/virtual/prog8_lib.p8 | 4 +- compiler/res/prog8lib/virtual/syslib.p8 | 16 +-- compiler/res/prog8lib/virtual/textio.p8 | 8 +- docs/source/todo.rst | 6 +- examples/test.p8 | 2 +- virtualmachine/src/prog8/vm/Assembler.kt | 23 ++-- 13 files changed, 211 insertions(+), 193 deletions(-) diff --git a/codeGenExperimental/src/prog8/codegen/experimental/AssignmentGen.kt b/codeGenExperimental/src/prog8/codegen/experimental/AssignmentGen.kt index 800f84ade..de8a4defa 100644 --- a/codeGenExperimental/src/prog8/codegen/experimental/AssignmentGen.kt +++ b/codeGenExperimental/src/prog8/codegen/experimental/AssignmentGen.kt @@ -28,8 +28,7 @@ internal class AssignmentGen(private val codeGen: CodeGen, private val expressio val array = assignment.target.array return if(ident!=null) { - val address = codeGen.addressOf(ident.targetName) - assignSelfInMemory(address, assignment.value, assignment) + assignSelfInMemory(ident.targetName.joinToString("."), assignment.value, assignment) } else if(memory != null) { if(memory.address is PtNumber) assignSelfInMemoryKnownAddress((memory.address as PtNumber).number.toInt(), assignment.value, assignment) @@ -73,7 +72,7 @@ internal class AssignmentGen(private val codeGen: CodeGen, private val expressio } private fun assignSelfInMemory( - addressOf: String, + symbol: String, value: PtExpression, origAssign: PtAssignment ): IRCodeChunk { @@ -82,12 +81,12 @@ internal class AssignmentGen(private val codeGen: CodeGen, private val expressio when(value) { is PtIdentifier -> return code // do nothing, x=x null assignment. is PtMachineRegister -> return code // do nothing, reg=reg null assignment - is PtPrefix -> return inplacePrefix(value.operator, vmDt, null, addressOf, value.position) - is PtBinaryExpression -> return inplaceBinexpr(value.operator, value.right, vmDt, value.type in SignedDatatypes, null, addressOf, origAssign) + is PtPrefix -> return inplacePrefix(value.operator, vmDt, null, symbol, value.position) + is PtBinaryExpression -> return inplaceBinexpr(value.operator, value.right, vmDt, value.type in SignedDatatypes, null, symbol, origAssign) is PtMemoryByte -> { val tempReg = codeGen.vmRegisters.nextFree() - code += IRCodeInstruction(Opcode.LOADM, vmDt, reg1 = tempReg, labelSymbol = addressOf) - code += IRCodeInstruction(Opcode.STOREM, vmDt, reg1 = tempReg, labelSymbol = addressOf) + code += IRCodeInstruction(Opcode.LOADM, vmDt, reg1 = tempReg, labelSymbol = symbol) + code += IRCodeInstruction(Opcode.STOREM, vmDt, reg1 = tempReg, labelSymbol = symbol) return code } else -> return fallbackAssign(origAssign) @@ -106,7 +105,7 @@ internal class AssignmentGen(private val codeGen: CodeGen, private val expressio vmDt: VmDataType, signed: Boolean, knownAddress: Int?, - addressOfSymbol: String?, + symbol: String?, origAssign: PtAssignment ): IRCodeChunk { if(knownAddress!=null) { @@ -123,17 +122,17 @@ internal class AssignmentGen(private val codeGen: CodeGen, private val expressio else -> {} } } else { - addressOfSymbol!! + symbol!! when (operator) { - "+" -> return expressionEval.operatorPlusInplace(null, addressOfSymbol, vmDt, operand) - "-" -> return expressionEval.operatorMinusInplace(null, addressOfSymbol, vmDt, operand) - "*" -> return expressionEval.operatorMultiplyInplace(null, addressOfSymbol, vmDt, operand) - "/" -> return expressionEval.operatorDivideInplace(null, addressOfSymbol, vmDt, signed, operand) - "|" -> return expressionEval.operatorOrInplace(null, addressOfSymbol, vmDt, operand) - "&" -> return expressionEval.operatorAndInplace(null, addressOfSymbol, vmDt, operand) - "^" -> return expressionEval.operatorXorInplace(null, addressOfSymbol, vmDt, operand) - "<<" -> return expressionEval.operatorShiftLeftInplace(null, addressOfSymbol, vmDt, operand) - ">>" -> return expressionEval.operatorShiftRightInplace(null, addressOfSymbol, vmDt, signed, operand) + "+" -> return expressionEval.operatorPlusInplace(null, symbol, vmDt, operand) + "-" -> return expressionEval.operatorMinusInplace(null, symbol, vmDt, operand) + "*" -> return expressionEval.operatorMultiplyInplace(null, symbol, vmDt, operand) + "/" -> return expressionEval.operatorDivideInplace(null, symbol, vmDt, signed, operand) + "|" -> return expressionEval.operatorOrInplace(null, symbol, vmDt, operand) + "&" -> return expressionEval.operatorAndInplace(null, symbol, vmDt, operand) + "^" -> return expressionEval.operatorXorInplace(null, symbol, vmDt, operand) + "<<" -> return expressionEval.operatorShiftLeftInplace(null, symbol, vmDt, operand) + ">>" -> return expressionEval.operatorShiftRightInplace(null, symbol, vmDt, signed, operand) else -> {} } } @@ -191,19 +190,18 @@ internal class AssignmentGen(private val codeGen: CodeGen, private val expressio } } if(ident!=null) { - val addressOf = codeGen.addressOf(ident.targetName) + val symbol = ident.targetName.joinToString(".") code += if(zero) { - IRCodeInstruction(Opcode.STOREZM, vmDt, labelSymbol = addressOf) + IRCodeInstruction(Opcode.STOREZM, vmDt, labelSymbol = symbol) } else { if (vmDt == VmDataType.FLOAT) - IRCodeInstruction(Opcode.STOREM, vmDt, fpReg1 = resultFpRegister, labelSymbol = addressOf) + IRCodeInstruction(Opcode.STOREM, vmDt, fpReg1 = resultFpRegister, labelSymbol = symbol) else - IRCodeInstruction(Opcode.STOREM, vmDt, reg1 = resultRegister, labelSymbol = addressOf) + IRCodeInstruction(Opcode.STOREM, vmDt, reg1 = resultRegister, labelSymbol = symbol) } } else if(array!=null) { - val variable = array.variable.targetName - var variableAddrOf = codeGen.addressOf(variable) + val variable = array.variable.targetName.joinToString(".") val itemsize = codeGen.program.memsizer.memorySize(array.type) if(array.variable.type==DataType.UWORD) { @@ -219,7 +217,7 @@ internal class AssignmentGen(private val codeGen: CodeGen, private val expressio resultRegister = codeGen.vmRegisters.nextFree() code += IRCodeInstruction(Opcode.LOAD, vmDt, reg1=resultRegister, value=0) } - code += IRCodeInstruction(Opcode.STOREIX, vmDt, reg1=resultRegister, reg2=idxReg, labelSymbol = variableAddrOf) + code += IRCodeInstruction(Opcode.STOREIX, vmDt, reg1=resultRegister, reg2=idxReg, labelSymbol = variable) return code } @@ -227,30 +225,30 @@ internal class AssignmentGen(private val codeGen: CodeGen, private val expressio if(zero) { if(fixedIndex!=null) { val offset = fixedIndex*itemsize - code += IRCodeInstruction(Opcode.STOREZM, vmDt, labelSymbol = "$variableAddrOf+$offset") + code += IRCodeInstruction(Opcode.STOREZM, vmDt, labelSymbol = "$variable+$offset") } else { val indexReg = codeGen.vmRegisters.nextFree() code += loadIndexReg(array, itemsize, indexReg, array.position) - code += IRCodeInstruction(Opcode.STOREZX, vmDt, reg1=indexReg, labelSymbol = variableAddrOf) + code += IRCodeInstruction(Opcode.STOREZX, vmDt, reg1=indexReg, labelSymbol = variable) } } else { if(vmDt== VmDataType.FLOAT) { if(fixedIndex!=null) { val offset = fixedIndex*itemsize - code += IRCodeInstruction(Opcode.STOREM, vmDt, fpReg1 = resultFpRegister, labelSymbol = "$variableAddrOf+$offset") + code += IRCodeInstruction(Opcode.STOREM, vmDt, fpReg1 = resultFpRegister, labelSymbol = "$variable+$offset") } else { val indexReg = codeGen.vmRegisters.nextFree() code += loadIndexReg(array, itemsize, indexReg, array.position) - code += IRCodeInstruction(Opcode.STOREX, vmDt, reg1 = resultRegister, reg2=indexReg, labelSymbol = variableAddrOf) + code += IRCodeInstruction(Opcode.STOREX, vmDt, reg1 = resultRegister, reg2=indexReg, labelSymbol = variable) } } else { if(fixedIndex!=null) { val offset = fixedIndex*itemsize - code += IRCodeInstruction(Opcode.STOREM, vmDt, reg1 = resultRegister, labelSymbol = "$variableAddrOf+$offset") + code += IRCodeInstruction(Opcode.STOREM, vmDt, reg1 = resultRegister, labelSymbol = "$variable+$offset") } else { val indexReg = codeGen.vmRegisters.nextFree() code += loadIndexReg(array, itemsize, indexReg, array.position) - code += IRCodeInstruction(Opcode.STOREX, vmDt, reg1 = resultRegister, reg2=indexReg, labelSymbol = variableAddrOf) + code += IRCodeInstruction(Opcode.STOREX, vmDt, reg1 = resultRegister, reg2=indexReg, labelSymbol = variable) } } } diff --git a/codeGenExperimental/src/prog8/codegen/experimental/CodeGen.kt b/codeGenExperimental/src/prog8/codegen/experimental/CodeGen.kt index 5c3c8e1f5..50ed6c1e8 100644 --- a/codeGenExperimental/src/prog8/codegen/experimental/CodeGen.kt +++ b/codeGenExperimental/src/prog8/codegen/experimental/CodeGen.kt @@ -314,9 +314,9 @@ class CodeGen(internal val program: PtProgram, code += translateForInNonConstantRange(forLoop, loopvar) } is PtIdentifier -> { - val arrayAddress = addressOf(iterable.targetName) + val symbol = iterable.targetName.joinToString(".") val iterableVar = symbolTable.lookup(iterable.targetName) as StStaticVariable - val loopvarAddress = addressOf(loopvar.scopedName) + val loopvarSymbol = loopvar.scopedName.joinToString(".") val indexReg = vmRegisters.nextFree() val tmpReg = vmRegisters.nextFree() val loopLabel = createLabelName() @@ -325,9 +325,9 @@ class CodeGen(internal val program: PtProgram, // iterate over a zero-terminated string code += IRCodeInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=indexReg, value=0) code += IRCodeLabel(loopLabel) - code += IRCodeInstruction(Opcode.LOADX, VmDataType.BYTE, reg1=tmpReg, reg2=indexReg, labelSymbol = arrayAddress) + code += IRCodeInstruction(Opcode.LOADX, VmDataType.BYTE, reg1=tmpReg, reg2=indexReg, labelSymbol = symbol) code += IRCodeInstruction(Opcode.BZ, VmDataType.BYTE, reg1=tmpReg, labelSymbol = endLabel) - code += IRCodeInstruction(Opcode.STOREM, VmDataType.BYTE, reg1=tmpReg, labelSymbol = loopvarAddress) + code += IRCodeInstruction(Opcode.STOREM, VmDataType.BYTE, reg1=tmpReg, labelSymbol = loopvarSymbol) code += translateNode(forLoop.statements) code += IRCodeInstruction(Opcode.INC, VmDataType.BYTE, reg1=indexReg) code += IRCodeInstruction(Opcode.JUMP, labelSymbol = loopLabel) @@ -342,16 +342,16 @@ class CodeGen(internal val program: PtProgram, code += IRCodeInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=indexReg, value=0) code += IRCodeInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=lengthReg, value=lengthBytes) code += IRCodeLabel(loopLabel) - code += IRCodeInstruction(Opcode.LOADX, vmType(elementDt), reg1=tmpReg, reg2=indexReg, labelSymbol=arrayAddress) - code += IRCodeInstruction(Opcode.STOREM, vmType(elementDt), reg1=tmpReg, labelSymbol = loopvarAddress) + code += IRCodeInstruction(Opcode.LOADX, vmType(elementDt), reg1=tmpReg, reg2=indexReg, labelSymbol=symbol) + code += IRCodeInstruction(Opcode.STOREM, vmType(elementDt), reg1=tmpReg, labelSymbol = loopvarSymbol) code += translateNode(forLoop.statements) code += addConstReg(VmDataType.BYTE, indexReg, elementSize, iterable.position) code += IRCodeInstruction(Opcode.BNE, VmDataType.BYTE, reg1=indexReg, reg2=lengthReg, labelSymbol = loopLabel) } else if(lengthBytes==256) { code += IRCodeInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=indexReg, value=0) code += IRCodeLabel(loopLabel) - code += IRCodeInstruction(Opcode.LOADX, vmType(elementDt), reg1=tmpReg, reg2=indexReg, labelSymbol=arrayAddress) - code += IRCodeInstruction(Opcode.STOREM, vmType(elementDt), reg1=tmpReg, labelSymbol = loopvarAddress) + code += IRCodeInstruction(Opcode.LOADX, vmType(elementDt), reg1=tmpReg, reg2=indexReg, labelSymbol=symbol) + code += IRCodeInstruction(Opcode.STOREM, vmType(elementDt), reg1=tmpReg, labelSymbol = loopvarSymbol) code += translateNode(forLoop.statements) code += addConstReg(VmDataType.BYTE, indexReg, elementSize, iterable.position) code += IRCodeInstruction(Opcode.BNZ, VmDataType.BYTE, reg1=indexReg, labelSymbol = loopLabel) @@ -365,8 +365,6 @@ class CodeGen(internal val program: PtProgram, return code } - internal inline fun addressOf(targetName: List): String = "&"+targetName.joinToString(".") - private fun translateForInNonConstantRange(forLoop: PtForLoop, loopvar: StStaticVariable): IRCodeChunk { val iterable = forLoop.iterable as PtRange val step = iterable.step.number.toInt() @@ -374,18 +372,18 @@ class CodeGen(internal val program: PtProgram, throw AssemblyError("step 0") val indexReg = vmRegisters.nextFree() val endvalueReg = vmRegisters.nextFree() - val loopvarAddress = addressOf(loopvar.scopedName) + val loopvarSymbol = loopvar.scopedName.joinToString(".") val loopvarDt = vmType(loopvar.dt) val loopLabel = createLabelName() val code = IRCodeChunk(forLoop.position) code += expressionEval.translateExpression(iterable.to, endvalueReg, -1) code += expressionEval.translateExpression(iterable.from, indexReg, -1) - code += IRCodeInstruction(Opcode.STOREM, loopvarDt, reg1=indexReg, labelSymbol=loopvarAddress) + code += IRCodeInstruction(Opcode.STOREM, loopvarDt, reg1=indexReg, labelSymbol=loopvarSymbol) code += IRCodeLabel(loopLabel) code += translateNode(forLoop.statements) - code += addConstMem(loopvarDt, loopvarAddress.toUInt(), step, iterable.position) - code += IRCodeInstruction(Opcode.LOADM, loopvarDt, reg1 = indexReg, labelSymbol = loopvarAddress) + code += addConstMem(loopvarDt, null, loopvarSymbol, step, iterable.position) + code += IRCodeInstruction(Opcode.LOADM, loopvarDt, reg1 = indexReg, labelSymbol = loopvarSymbol) val branchOpcode = if(loopvar.dt in SignedDatatypes) Opcode.BLES else Opcode.BLE code += IRCodeInstruction(branchOpcode, loopvarDt, reg1=indexReg, reg2=endvalueReg, labelSymbol=loopLabel) return code @@ -393,7 +391,7 @@ class CodeGen(internal val program: PtProgram, private fun translateForInConstantRange(forLoop: PtForLoop, loopvar: StStaticVariable): IRCodeChunk { val loopLabel = createLabelName() - val loopvarAddress = addressOf(loopvar.scopedName) + val loopvarSymbol = loopvar.scopedName.joinToString(".") val indexReg = vmRegisters.nextFree() val loopvarDt = vmType(loopvar.dt) val iterable = forLoop.iterable as PtRange @@ -414,11 +412,11 @@ class CodeGen(internal val program: PtProgram, endvalueReg = -1 // not used } code += IRCodeInstruction(Opcode.LOAD, loopvarDt, reg1=indexReg, value=rangeStart) - code += IRCodeInstruction(Opcode.STOREM, loopvarDt, reg1=indexReg, labelSymbol=loopvarAddress) + code += IRCodeInstruction(Opcode.STOREM, loopvarDt, reg1=indexReg, labelSymbol=loopvarSymbol) code += IRCodeLabel(loopLabel) code += translateNode(forLoop.statements) - code += addConstMem(loopvarDt, loopvarAddress.toUInt(), step, iterable.position) - code += IRCodeInstruction(Opcode.LOADM, loopvarDt, reg1 = indexReg, labelSymbol = loopvarAddress) + code += addConstMem(loopvarDt, null, loopvarSymbol, step, iterable.position) + code += IRCodeInstruction(Opcode.LOADM, loopvarDt, reg1 = indexReg, labelSymbol = loopvarSymbol) code += if(rangeEndWrapped==0) { IRCodeInstruction(Opcode.BNZ, loopvarDt, reg1 = indexReg, labelSymbol = loopLabel) } else { @@ -456,33 +454,55 @@ class CodeGen(internal val program: PtProgram, return code } - private fun addConstMem(dt: VmDataType, address: UInt, value: Int, position: Position): IRCodeChunk { + private fun addConstMem(dt: VmDataType, knownAddress: UInt?, symbol: String?, value: Int, position: Position): IRCodeChunk { val code = IRCodeChunk(position) when(value) { 0 -> { /* do nothing */ } 1 -> { - code += IRCodeInstruction(Opcode.INCM, dt, value=address.toInt()) + code += if(knownAddress!=null) + IRCodeInstruction(Opcode.INCM, dt, value=knownAddress.toInt()) + else + IRCodeInstruction(Opcode.INCM, dt, labelSymbol = symbol) } 2 -> { - code += IRCodeInstruction(Opcode.INCM, dt, value=address.toInt()) - code += IRCodeInstruction(Opcode.INCM, dt, value=address.toInt()) + if(knownAddress!=null) { + code += IRCodeInstruction(Opcode.INCM, dt, value = knownAddress.toInt()) + code += IRCodeInstruction(Opcode.INCM, dt, value = knownAddress.toInt()) + } else { + code += IRCodeInstruction(Opcode.INCM, dt, labelSymbol = symbol) + code += IRCodeInstruction(Opcode.INCM, dt, labelSymbol = symbol) + } } -1 -> { - code += IRCodeInstruction(Opcode.DECM, dt, value=address.toInt()) + code += if(knownAddress!=null) + IRCodeInstruction(Opcode.DECM, dt, value=knownAddress.toInt()) + else + IRCodeInstruction(Opcode.DECM, dt, labelSymbol = symbol) } -2 -> { - code += IRCodeInstruction(Opcode.DECM, dt, value=address.toInt()) - code += IRCodeInstruction(Opcode.DECM, dt, value=address.toInt()) + if(knownAddress!=null) { + code += IRCodeInstruction(Opcode.DECM, dt, value = knownAddress.toInt()) + code += IRCodeInstruction(Opcode.DECM, dt, value = knownAddress.toInt()) + } else { + code += IRCodeInstruction(Opcode.DECM, dt, labelSymbol = symbol) + code += IRCodeInstruction(Opcode.DECM, dt, labelSymbol = symbol) + } } else -> { val valueReg = vmRegisters.nextFree() if(value>0) { code += IRCodeInstruction(Opcode.LOAD, dt, reg1=valueReg, value=value) - code += IRCodeInstruction(Opcode.ADDM, dt, reg1=valueReg, value=address.toInt()) + code += if(knownAddress!=null) + IRCodeInstruction(Opcode.ADDM, dt, reg1=valueReg, value=knownAddress.toInt()) + else + IRCodeInstruction(Opcode.ADDM, dt, reg1=valueReg, labelSymbol = symbol) } else { code += IRCodeInstruction(Opcode.LOAD, dt, reg1=valueReg, value=-value) - code += IRCodeInstruction(Opcode.SUBM, dt, reg1=valueReg, value=address.toInt()) + code += if(knownAddress!=null) + IRCodeInstruction(Opcode.SUBM, dt, reg1=valueReg, value=knownAddress.toInt()) + else + IRCodeInstruction(Opcode.SUBM, dt, reg1=valueReg, labelSymbol = symbol) } } } @@ -501,7 +521,7 @@ class CodeGen(internal val program: PtProgram, return code } - internal fun multiplyByConstFloatInplace(knownAddress: Int?, addressOfSymbol: String?, factor: Float, position: Position): IRCodeChunk { + internal fun multiplyByConstFloatInplace(knownAddress: Int?, symbol: String?, factor: Float, position: Position): IRCodeChunk { val code = IRCodeChunk(position) if(factor==1f) return code @@ -509,14 +529,14 @@ class CodeGen(internal val program: PtProgram, code += if(knownAddress!=null) IRCodeInstruction(Opcode.STOREZM, VmDataType.FLOAT, value = knownAddress) else - IRCodeInstruction(Opcode.STOREZM, VmDataType.FLOAT, labelSymbol = addressOfSymbol) + IRCodeInstruction(Opcode.STOREZM, VmDataType.FLOAT, labelSymbol = symbol) } else { val factorReg = vmRegisters.nextFreeFloat() code += IRCodeInstruction(Opcode.LOAD, VmDataType.FLOAT, fpReg1=factorReg, fpValue = factor) code += if(knownAddress!=null) IRCodeInstruction(Opcode.MULM, VmDataType.FLOAT, fpReg1 = factorReg, value = knownAddress) else - IRCodeInstruction(Opcode.MULM, VmDataType.FLOAT, fpReg1 = factorReg, labelSymbol = addressOfSymbol) + IRCodeInstruction(Opcode.MULM, VmDataType.FLOAT, fpReg1 = factorReg, labelSymbol = symbol) } return code } @@ -547,7 +567,7 @@ class CodeGen(internal val program: PtProgram, return code } - internal fun multiplyByConstInplace(dt: VmDataType, knownAddress: Int?, addressOfSymbol: String?, factor: Int, position: Position): IRCodeChunk { + internal fun multiplyByConstInplace(dt: VmDataType, knownAddress: Int?, symbol: String?, factor: Int, position: Position): IRCodeChunk { val code = IRCodeChunk(position) if(factor==1) return code @@ -557,7 +577,7 @@ class CodeGen(internal val program: PtProgram, code += if(knownAddress!=null) IRCodeInstruction(Opcode.LSLM, dt, value = knownAddress) else - IRCodeInstruction(Opcode.LSLM, dt, labelSymbol = addressOfSymbol) + IRCodeInstruction(Opcode.LSLM, dt, labelSymbol = symbol) } else if(pow2>=1) { // just shift multiple bits @@ -566,13 +586,13 @@ class CodeGen(internal val program: PtProgram, code += if(knownAddress!=null) IRCodeInstruction(Opcode.LSLNM, dt, reg1=pow2reg, value=knownAddress) else - IRCodeInstruction(Opcode.LSLNM, dt, reg1=pow2reg, labelSymbol = addressOfSymbol) + IRCodeInstruction(Opcode.LSLNM, dt, reg1=pow2reg, labelSymbol = symbol) } else { if (factor == 0) { code += if(knownAddress!=null) IRCodeInstruction(Opcode.STOREZM, dt, value=knownAddress) else - IRCodeInstruction(Opcode.STOREZM, dt, labelSymbol = addressOfSymbol) + IRCodeInstruction(Opcode.STOREZM, dt, labelSymbol = symbol) } else { val factorReg = vmRegisters.nextFree() @@ -580,7 +600,7 @@ class CodeGen(internal val program: PtProgram, code += if(knownAddress!=null) IRCodeInstruction(Opcode.MULM, dt, reg1=factorReg, value = knownAddress) else - IRCodeInstruction(Opcode.MULM, dt, reg1=factorReg, labelSymbol = addressOfSymbol) + IRCodeInstruction(Opcode.MULM, dt, reg1=factorReg, labelSymbol = symbol) } } return code @@ -598,7 +618,7 @@ class CodeGen(internal val program: PtProgram, return code } - internal fun divideByConstFloatInplace(knownAddress: Int?, addressOfSymbol: String?, factor: Float, position: Position): IRCodeChunk { + internal fun divideByConstFloatInplace(knownAddress: Int?, symbol: String?, factor: Float, position: Position): IRCodeChunk { val code = IRCodeChunk(position) if(factor==1f) return code @@ -608,14 +628,14 @@ class CodeGen(internal val program: PtProgram, code += if(knownAddress!=null) IRCodeInstruction(Opcode.STOREM, VmDataType.FLOAT, fpReg1 = maxvalueReg, value=knownAddress) else - IRCodeInstruction(Opcode.STOREM, VmDataType.FLOAT, fpReg1 = maxvalueReg, labelSymbol = addressOfSymbol) + IRCodeInstruction(Opcode.STOREM, VmDataType.FLOAT, fpReg1 = maxvalueReg, labelSymbol = symbol) } else { val factorReg = vmRegisters.nextFreeFloat() code += IRCodeInstruction(Opcode.LOAD, VmDataType.FLOAT, fpReg1=factorReg, fpValue = factor) code += if(knownAddress!=null) IRCodeInstruction(Opcode.DIVSM, VmDataType.FLOAT, fpReg1 = factorReg, value=knownAddress) else - IRCodeInstruction(Opcode.DIVSM, VmDataType.FLOAT, fpReg1 = factorReg, labelSymbol = addressOfSymbol) + IRCodeInstruction(Opcode.DIVSM, VmDataType.FLOAT, fpReg1 = factorReg, labelSymbol = symbol) } return code } @@ -649,7 +669,7 @@ class CodeGen(internal val program: PtProgram, return code } - internal fun divideByConstInplace(dt: VmDataType, knownAddress: Int?, addressOfSymbol: String?, factor: Int, signed: Boolean, position: Position): IRCodeChunk { + internal fun divideByConstInplace(dt: VmDataType, knownAddress: Int?, symbol: String?, factor: Int, signed: Boolean, position: Position): IRCodeChunk { val code = IRCodeChunk(position) if(factor==1) return code @@ -659,7 +679,7 @@ class CodeGen(internal val program: PtProgram, code += if(knownAddress!=null) IRCodeInstruction(Opcode.LSRM, dt, value=knownAddress) else - IRCodeInstruction(Opcode.LSRM, dt, labelSymbol = addressOfSymbol) + IRCodeInstruction(Opcode.LSRM, dt, labelSymbol = symbol) } else if(pow2>=1 && !signed) { // just shift multiple bits @@ -669,13 +689,13 @@ class CodeGen(internal val program: PtProgram, if(knownAddress!=null) IRCodeInstruction(Opcode.ASRNM, dt, reg1 = pow2reg, value = knownAddress) else - IRCodeInstruction(Opcode.ASRNM, dt, reg1 = pow2reg, labelSymbol = addressOfSymbol) + IRCodeInstruction(Opcode.ASRNM, dt, reg1 = pow2reg, labelSymbol = symbol) } else { if(knownAddress!=null) IRCodeInstruction(Opcode.LSRNM, dt, reg1 = pow2reg, value = knownAddress) else - IRCodeInstruction(Opcode.LSRNM, dt, reg1 = pow2reg, labelSymbol = addressOfSymbol) + IRCodeInstruction(Opcode.LSRNM, dt, reg1 = pow2reg, labelSymbol = symbol) } } else { if (factor == 0) { @@ -684,7 +704,7 @@ class CodeGen(internal val program: PtProgram, code += if(knownAddress!=null) IRCodeInstruction(Opcode.STOREM, dt, reg1=reg, value=knownAddress) else - IRCodeInstruction(Opcode.STOREM, dt, reg1=reg, labelSymbol = addressOfSymbol) + IRCodeInstruction(Opcode.STOREM, dt, reg1=reg, labelSymbol = symbol) } else { val factorReg = vmRegisters.nextFree() @@ -693,13 +713,13 @@ class CodeGen(internal val program: PtProgram, if(knownAddress!=null) IRCodeInstruction(Opcode.DIVSM, dt, reg1 = factorReg, value = knownAddress) else - IRCodeInstruction(Opcode.DIVSM, dt, reg1 = factorReg, labelSymbol = addressOfSymbol) + IRCodeInstruction(Opcode.DIVSM, dt, reg1 = factorReg, labelSymbol = symbol) } else { if(knownAddress!=null) IRCodeInstruction(Opcode.DIVM, dt, reg1 = factorReg, value = knownAddress) else - IRCodeInstruction(Opcode.DIVM, dt, reg1 = factorReg, labelSymbol = addressOfSymbol) + IRCodeInstruction(Opcode.DIVM, dt, reg1 = factorReg, labelSymbol = symbol) } } } @@ -815,8 +835,7 @@ class CodeGen(internal val program: PtProgram, val array = postIncrDecr.target.array val vmDt = vmType(postIncrDecr.target.type) if(ident!=null) { - val address = addressOf(ident.targetName) - code += IRCodeInstruction(operationMem, vmDt, labelSymbol = address) + code += IRCodeInstruction(operationMem, vmDt, labelSymbol = ident.targetName.joinToString(".")) } else if(memory!=null) { if(memory.address is PtNumber) { val address = (memory.address as PtNumber).number.toInt() @@ -830,20 +849,19 @@ class CodeGen(internal val program: PtProgram, code += IRCodeInstruction(Opcode.STOREI, vmDt, reg1 = incReg, reg2 = addressReg) } } else if (array!=null) { - val variable = array.variable.targetName - var variableAddr = addressOf(variable) + val variable = array.variable.targetName.joinToString(".") val itemsize = program.memsizer.memorySize(array.type) val fixedIndex = constIntValue(array.index) if(fixedIndex!=null) { - variableAddr += fixedIndex*itemsize - code += IRCodeInstruction(operationMem, vmDt, labelSymbol=variableAddr) + val offset = fixedIndex*itemsize + code += IRCodeInstruction(operationMem, vmDt, labelSymbol="$variable+$offset") } else { val incReg = vmRegisters.nextFree() val indexReg = vmRegisters.nextFree() code += expressionEval.translateExpression(array.index, indexReg, -1) - code += IRCodeInstruction(Opcode.LOADX, vmDt, reg1=incReg, reg2=indexReg, labelSymbol=variableAddr) + code += IRCodeInstruction(Opcode.LOADX, vmDt, reg1=incReg, reg2=indexReg, labelSymbol=variable) code += IRCodeInstruction(operationRegister, vmDt, reg1=incReg) - code += IRCodeInstruction(Opcode.STOREX, vmDt, reg1=incReg, reg2=indexReg, labelSymbol=variableAddr) + code += IRCodeInstruction(Opcode.STOREX, vmDt, reg1=incReg, reg2=indexReg, labelSymbol=variable) } } else throw AssemblyError("weird assigntarget") diff --git a/codeGenExperimental/src/prog8/codegen/experimental/ExpressionGen.kt b/codeGenExperimental/src/prog8/codegen/experimental/ExpressionGen.kt index 9acd2acb3..4421ea150 100644 --- a/codeGenExperimental/src/prog8/codegen/experimental/ExpressionGen.kt +++ b/codeGenExperimental/src/prog8/codegen/experimental/ExpressionGen.kt @@ -30,21 +30,21 @@ internal class ExpressionGen(private val codeGen: CodeGen) { } is PtIdentifier -> { val vmDt = codeGen.vmType(expr.type) - val addrOf = codeGen.addressOf(expr.targetName) + val symbol = expr.targetName.joinToString(".") code += if (expr.type in PassByValueDatatypes) { if(vmDt==VmDataType.FLOAT) - IRCodeInstruction(Opcode.LOADM, vmDt, fpReg1 = resultFpRegister, labelSymbol = addrOf) + IRCodeInstruction(Opcode.LOADM, vmDt, fpReg1 = resultFpRegister, labelSymbol = symbol) else - IRCodeInstruction(Opcode.LOADM, vmDt, reg1 = resultRegister, labelSymbol = addrOf) + IRCodeInstruction(Opcode.LOADM, vmDt, reg1 = resultRegister, labelSymbol = symbol) } else { // for strings and arrays etc., load the *address* of the value instead - IRCodeInstruction(Opcode.LOAD, vmDt, reg1 = resultRegister, labelSymbol = addrOf) + IRCodeInstruction(Opcode.LOAD, vmDt, reg1 = resultRegister, labelSymbol = symbol) } } is PtAddressOf -> { val vmDt = codeGen.vmType(expr.type) - val addrOf = codeGen.addressOf(expr.identifier.targetName) - code += IRCodeInstruction(Opcode.LOAD, vmDt, reg1=resultRegister, labelSymbol = addrOf) + val symbol = expr.identifier.targetName.joinToString(".") + code += IRCodeInstruction(Opcode.LOAD, vmDt, reg1=resultRegister, labelSymbol = symbol) } is PtMemoryByte -> { if(expr.address is PtNumber) { @@ -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 arrayLocationExpr = codeGen.addressOf(arrayIx.variable.targetName) + val arrayVarSymbol = arrayIx.variable.targetName.joinToString(".") if(arrayIx.variable.type==DataType.UWORD) { // indexing a pointer var instead of a real array or string @@ -116,24 +116,24 @@ internal class ExpressionGen(private val codeGen: CodeGen) { if(arrayIx.index.type!=DataType.UBYTE) throw AssemblyError("non-array var indexing requires bytes index") code += translateExpression(arrayIx.index, idxReg, -1) - code += IRCodeInstruction(Opcode.LOADIX, vmDt, reg1=resultRegister, reg2=idxReg, labelSymbol = arrayLocationExpr) + code += IRCodeInstruction(Opcode.LOADIX, vmDt, reg1=resultRegister, reg2=idxReg, labelSymbol = arrayVarSymbol) return code } if(arrayIx.index is PtNumber) { val memOffset = ((arrayIx.index as PtNumber).number.toInt() * eltSize).toString() if(vmDt==VmDataType.FLOAT) - code += IRCodeInstruction(Opcode.LOADM, VmDataType.FLOAT, fpReg1=resultFpRegister, labelSymbol = "$arrayLocationExpr+$memOffset") + code += IRCodeInstruction(Opcode.LOADM, VmDataType.FLOAT, fpReg1=resultFpRegister, labelSymbol = "$arrayVarSymbol+$memOffset") else - code += IRCodeInstruction(Opcode.LOADM, vmDt, reg1=resultRegister, labelSymbol = "$arrayLocationExpr+$memOffset") + code += IRCodeInstruction(Opcode.LOADM, vmDt, reg1=resultRegister, labelSymbol = "$arrayVarSymbol+$memOffset") } else { code += translateExpression(arrayIx.index, idxReg, -1) if(eltSize>1) code += codeGen.multiplyByConst(VmDataType.BYTE, idxReg, eltSize, arrayIx.position) if(vmDt==VmDataType.FLOAT) - code += IRCodeInstruction(Opcode.LOADX, VmDataType.FLOAT, fpReg1 = resultFpRegister, reg1=idxReg, labelSymbol = arrayLocationExpr) + code += IRCodeInstruction(Opcode.LOADX, VmDataType.FLOAT, fpReg1 = resultFpRegister, reg1=idxReg, labelSymbol = arrayVarSymbol) else - code += IRCodeInstruction(Opcode.LOADX, vmDt, reg1=resultRegister, reg2=idxReg, labelSymbol = arrayLocationExpr) + code += IRCodeInstruction(Opcode.LOADX, vmDt, reg1=resultRegister, reg2=idxReg, labelSymbol = arrayVarSymbol) } return code } @@ -415,14 +415,14 @@ internal class ExpressionGen(private val codeGen: CodeGen) { return code } - internal fun operatorShiftRightInplace(knownAddress: Int?, addressOfSymbol: String?, vmDt: VmDataType, signed: Boolean, operand: PtExpression): IRCodeChunk { + internal fun operatorShiftRightInplace(knownAddress: Int?, symbol: String?, vmDt: VmDataType, signed: Boolean, operand: PtExpression): IRCodeChunk { val code = IRCodeChunk(operand.position) if(codeGen.isOne(operand)) { val opc = if (signed) Opcode.ASRM else Opcode.LSRM code += if(knownAddress!=null) IRCodeInstruction(opc, vmDt, value=knownAddress) else - IRCodeInstruction(opc, vmDt, labelSymbol = addressOfSymbol) + IRCodeInstruction(opc, vmDt, labelSymbol = symbol) } else { val operandReg = codeGen.vmRegisters.nextFree() code += translateExpression(operand, operandReg, -1) @@ -430,7 +430,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) { code += if(knownAddress!=null) IRCodeInstruction(opc, vmDt, reg1 = operandReg, value=knownAddress) else - IRCodeInstruction(opc, vmDt, reg1 = operandReg, labelSymbol = addressOfSymbol) + IRCodeInstruction(opc, vmDt, reg1 = operandReg, labelSymbol = symbol) } return code } @@ -449,20 +449,20 @@ internal class ExpressionGen(private val codeGen: CodeGen) { return code } - internal fun operatorShiftLeftInplace(knownAddress: Int?, addressOfSymbol: String?, vmDt: VmDataType, operand: PtExpression): IRCodeChunk { + internal fun operatorShiftLeftInplace(knownAddress: Int?, symbol: String?, vmDt: VmDataType, operand: PtExpression): IRCodeChunk { val code = IRCodeChunk(operand.position) if(codeGen.isOne(operand)){ code += if(knownAddress!=null) IRCodeInstruction(Opcode.LSLM, vmDt, value=knownAddress) else - IRCodeInstruction(Opcode.LSLM, vmDt, labelSymbol = addressOfSymbol) + IRCodeInstruction(Opcode.LSLM, vmDt, labelSymbol = symbol) } else { val operandReg = codeGen.vmRegisters.nextFree() code += translateExpression(operand, operandReg, -1) code += if(knownAddress!=null) IRCodeInstruction(Opcode.LSLNM, vmDt, reg1=operandReg, value=knownAddress) else - IRCodeInstruction(Opcode.LSLNM, vmDt, reg1=operandReg, labelSymbol = addressOfSymbol) + IRCodeInstruction(Opcode.LSLNM, vmDt, reg1=operandReg, labelSymbol = symbol) } return code } @@ -481,14 +481,14 @@ internal class ExpressionGen(private val codeGen: CodeGen) { return code } - internal fun operatorXorInplace(knownAddress: Int?, addressOfSymbol: String?, vmDt: VmDataType, operand: PtExpression): IRCodeChunk { + internal fun operatorXorInplace(knownAddress: Int?, symbol: String?, vmDt: VmDataType, operand: PtExpression): IRCodeChunk { val code = IRCodeChunk(operand.position) val operandReg = codeGen.vmRegisters.nextFree() code += translateExpression(operand, operandReg, -1) code += if(knownAddress!=null) IRCodeInstruction(Opcode.XORM, vmDt, reg1=operandReg, value = knownAddress) else - IRCodeInstruction(Opcode.XORM, vmDt, reg1=operandReg, labelSymbol = addressOfSymbol) + IRCodeInstruction(Opcode.XORM, vmDt, reg1=operandReg, labelSymbol = symbol) return code } @@ -506,14 +506,14 @@ internal class ExpressionGen(private val codeGen: CodeGen) { return code } - internal fun operatorAndInplace(knownAddress: Int?, addressOfSymbol: String?, vmDt: VmDataType, operand: PtExpression): IRCodeChunk { + internal fun operatorAndInplace(knownAddress: Int?, symbol: String?, vmDt: VmDataType, operand: PtExpression): IRCodeChunk { val code = IRCodeChunk(operand.position) val operandReg = codeGen.vmRegisters.nextFree() code += translateExpression(operand, operandReg, -1) code += if(knownAddress!=null) IRCodeInstruction(Opcode.ANDM, vmDt, reg1=operandReg, value=knownAddress) else - IRCodeInstruction(Opcode.ANDM, vmDt, reg1=operandReg, labelSymbol = addressOfSymbol) + IRCodeInstruction(Opcode.ANDM, vmDt, reg1=operandReg, labelSymbol = symbol) return code } @@ -531,14 +531,14 @@ internal class ExpressionGen(private val codeGen: CodeGen) { return code } - internal fun operatorOrInplace(knownAddress: Int?, addressOfSymbol: String?, vmDt: VmDataType, operand: PtExpression): IRCodeChunk { + internal fun operatorOrInplace(knownAddress: Int?, symbol: String?, vmDt: VmDataType, operand: PtExpression): IRCodeChunk { val code = IRCodeChunk(operand.position) val operandReg = codeGen.vmRegisters.nextFree() code += translateExpression(operand, operandReg, -1) code += if(knownAddress!=null) IRCodeInstruction(Opcode.ORM, vmDt, reg1=operandReg, value = knownAddress) else - IRCodeInstruction(Opcode.ORM, vmDt, reg1=operandReg, labelSymbol = addressOfSymbol) + IRCodeInstruction(Opcode.ORM, vmDt, reg1=operandReg, labelSymbol = symbol) return code } @@ -605,13 +605,13 @@ internal class ExpressionGen(private val codeGen: CodeGen) { return code } - internal fun operatorDivideInplace(knownAddress: Int?, addressOfSymbol: String?, vmDt: VmDataType, signed: Boolean, operand: PtExpression): IRCodeChunk { + internal fun operatorDivideInplace(knownAddress: Int?, symbol: String?, vmDt: VmDataType, signed: Boolean, operand: PtExpression): IRCodeChunk { val code = IRCodeChunk(operand.position) val constFactorRight = operand as? PtNumber if(vmDt==VmDataType.FLOAT) { if(constFactorRight!=null && constFactorRight.type!=DataType.FLOAT) { val factor = constFactorRight.number.toFloat() - code += codeGen.divideByConstFloatInplace(knownAddress, addressOfSymbol, factor, operand.position) + code += codeGen.divideByConstFloatInplace(knownAddress, symbol, factor, operand.position) } else { val operandFpReg = codeGen.vmRegisters.nextFreeFloat() code += translateExpression(operand, -1, operandFpReg) @@ -619,19 +619,19 @@ internal class ExpressionGen(private val codeGen: CodeGen) { if(knownAddress!=null) IRCodeInstruction(Opcode.DIVSM, vmDt, fpReg1 = operandFpReg, value = knownAddress) else - IRCodeInstruction(Opcode.DIVSM, vmDt, fpReg1 = operandFpReg, labelSymbol = addressOfSymbol) + IRCodeInstruction(Opcode.DIVSM, vmDt, fpReg1 = operandFpReg, labelSymbol = symbol) } else { if(knownAddress!=null) IRCodeInstruction(Opcode.DIVM, vmDt, fpReg1 = operandFpReg, value = knownAddress) else - IRCodeInstruction(Opcode.DIVM, vmDt, fpReg1 = operandFpReg, labelSymbol = addressOfSymbol) + IRCodeInstruction(Opcode.DIVM, vmDt, fpReg1 = operandFpReg, labelSymbol = symbol) } } } else { if(constFactorRight!=null && constFactorRight.type!=DataType.FLOAT) { val factor = constFactorRight.number.toInt() - code += codeGen.divideByConstInplace(vmDt, knownAddress, addressOfSymbol, factor, signed, operand.position) + code += codeGen.divideByConstInplace(vmDt, knownAddress, symbol, factor, signed, operand.position) } else { val operandReg = codeGen.vmRegisters.nextFree() code += translateExpression(operand, operandReg, -1) @@ -639,13 +639,13 @@ internal class ExpressionGen(private val codeGen: CodeGen) { if(knownAddress!=null) IRCodeInstruction(Opcode.DIVSM, vmDt, reg1 = operandReg, value = knownAddress) else - IRCodeInstruction(Opcode.DIVSM, vmDt, reg1 = operandReg, labelSymbol = addressOfSymbol) + IRCodeInstruction(Opcode.DIVSM, vmDt, reg1 = operandReg, labelSymbol = symbol) } else { if(knownAddress!=null) IRCodeInstruction(Opcode.DIVM, vmDt, reg1 = operandReg, value = knownAddress) else - IRCodeInstruction(Opcode.DIVM, vmDt, reg1 = operandReg, labelSymbol = addressOfSymbol) + IRCodeInstruction(Opcode.DIVM, vmDt, reg1 = operandReg, labelSymbol = symbol) } } } @@ -690,32 +690,32 @@ internal class ExpressionGen(private val codeGen: CodeGen) { return code } - internal fun operatorMultiplyInplace(knownAddress: Int?, addressOfSymbol: String?, vmDt: VmDataType, operand: PtExpression): IRCodeChunk { + internal fun operatorMultiplyInplace(knownAddress: Int?, symbol: String?, vmDt: VmDataType, operand: PtExpression): IRCodeChunk { val code = IRCodeChunk(operand.position) val constFactorRight = operand as? PtNumber if(vmDt==VmDataType.FLOAT) { if(constFactorRight!=null) { val factor = constFactorRight.number.toFloat() - code += codeGen.multiplyByConstFloatInplace(knownAddress, addressOfSymbol, factor, constFactorRight.position) + code += codeGen.multiplyByConstFloatInplace(knownAddress, symbol, factor, constFactorRight.position) } else { val operandFpReg = codeGen.vmRegisters.nextFreeFloat() code += translateExpression(operand, -1, operandFpReg) code += if(knownAddress!=null) IRCodeInstruction(Opcode.MULM, vmDt, fpReg1 = operandFpReg, value = knownAddress) else - IRCodeInstruction(Opcode.MULM, vmDt, fpReg1 = operandFpReg, labelSymbol = addressOfSymbol) + IRCodeInstruction(Opcode.MULM, vmDt, fpReg1 = operandFpReg, labelSymbol = symbol) } } else { if(constFactorRight!=null && constFactorRight.type!=DataType.FLOAT) { val factor = constFactorRight.number.toInt() - code += codeGen.multiplyByConstInplace(vmDt, knownAddress, addressOfSymbol, factor, constFactorRight.position) + code += codeGen.multiplyByConstInplace(vmDt, knownAddress, symbol, factor, constFactorRight.position) } else { val operandReg = codeGen.vmRegisters.nextFree() code += translateExpression(operand, operandReg, -1) code += if(knownAddress!=null) IRCodeInstruction(Opcode.MULM, vmDt, reg1=operandReg, value = knownAddress) else - IRCodeInstruction(Opcode.MULM, vmDt, reg1=operandReg, labelSymbol = addressOfSymbol) + IRCodeInstruction(Opcode.MULM, vmDt, reg1=operandReg, labelSymbol = symbol) } } return code @@ -759,14 +759,14 @@ internal class ExpressionGen(private val codeGen: CodeGen) { return code } - internal fun operatorMinusInplace(knownAddress: Int?, addressOfSymbol: String?, vmDt: VmDataType, operand: PtExpression): IRCodeChunk { + internal fun operatorMinusInplace(knownAddress: Int?, symbol: String?, vmDt: VmDataType, operand: PtExpression): IRCodeChunk { val code = IRCodeChunk(operand.position) if(vmDt==VmDataType.FLOAT) { if((operand as? PtNumber)?.number==1.0) { code += if(knownAddress!=null) IRCodeInstruction(Opcode.DECM, vmDt, value=knownAddress) else - IRCodeInstruction(Opcode.DECM, vmDt, labelSymbol = addressOfSymbol) + IRCodeInstruction(Opcode.DECM, vmDt, labelSymbol = symbol) } else { val operandFpReg = codeGen.vmRegisters.nextFreeFloat() @@ -774,14 +774,14 @@ internal class ExpressionGen(private val codeGen: CodeGen) { code += if(knownAddress!=null) IRCodeInstruction(Opcode.SUBM, vmDt, fpReg1=operandFpReg, value=knownAddress) else - IRCodeInstruction(Opcode.SUBM, vmDt, fpReg1=operandFpReg, labelSymbol = addressOfSymbol) + IRCodeInstruction(Opcode.SUBM, vmDt, fpReg1=operandFpReg, labelSymbol = symbol) } } else { if((operand as? PtNumber)?.number==1.0) { code += if(knownAddress!=null) IRCodeInstruction(Opcode.DECM, vmDt, value=knownAddress) else - IRCodeInstruction(Opcode.DECM, vmDt, labelSymbol = addressOfSymbol) + IRCodeInstruction(Opcode.DECM, vmDt, labelSymbol = symbol) } else { val operandReg = codeGen.vmRegisters.nextFree() @@ -789,7 +789,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) { code += if(knownAddress!=null) IRCodeInstruction(Opcode.SUBM, vmDt, reg1=operandReg, value = knownAddress) else - IRCodeInstruction(Opcode.SUBM, vmDt, reg1=operandReg, labelSymbol = addressOfSymbol) + IRCodeInstruction(Opcode.SUBM, vmDt, reg1=operandReg, labelSymbol = symbol) } } return code @@ -841,14 +841,14 @@ internal class ExpressionGen(private val codeGen: CodeGen) { return code } - internal fun operatorPlusInplace(knownAddress: Int?, addressOfSymbol: String?, vmDt: VmDataType, operand: PtExpression): IRCodeChunk { + internal fun operatorPlusInplace(knownAddress: Int?, symbol: String?, vmDt: VmDataType, operand: PtExpression): IRCodeChunk { val code = IRCodeChunk(operand.position) if(vmDt==VmDataType.FLOAT) { if((operand as? PtNumber)?.number==1.0) { code += if(knownAddress!=null) IRCodeInstruction(Opcode.INCM, vmDt, value = knownAddress) else - IRCodeInstruction(Opcode.INCM, vmDt, labelSymbol = addressOfSymbol) + IRCodeInstruction(Opcode.INCM, vmDt, labelSymbol = symbol) } else { val operandFpReg = codeGen.vmRegisters.nextFreeFloat() @@ -856,14 +856,14 @@ internal class ExpressionGen(private val codeGen: CodeGen) { code += if(knownAddress!=null) IRCodeInstruction(Opcode.ADDM, vmDt, fpReg1=operandFpReg, value = knownAddress) else - IRCodeInstruction(Opcode.ADDM, vmDt, fpReg1=operandFpReg, labelSymbol = addressOfSymbol) + IRCodeInstruction(Opcode.ADDM, vmDt, fpReg1=operandFpReg, labelSymbol = symbol) } } else { if((operand as? PtNumber)?.number==1.0) { code += if(knownAddress!=null) IRCodeInstruction(Opcode.INCM, vmDt, value = knownAddress) else - IRCodeInstruction(Opcode.INCM, vmDt, labelSymbol = addressOfSymbol) + IRCodeInstruction(Opcode.INCM, vmDt, labelSymbol = symbol) } else { val operandReg = codeGen.vmRegisters.nextFree() @@ -871,7 +871,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) { code += if(knownAddress!=null) IRCodeInstruction(Opcode.ADDM, vmDt, reg1=operandReg, value=knownAddress) else - IRCodeInstruction(Opcode.ADDM, vmDt, reg1=operandReg, labelSymbol = addressOfSymbol) + IRCodeInstruction(Opcode.ADDM, vmDt, reg1=operandReg, labelSymbol = symbol) } } return code @@ -883,25 +883,18 @@ internal class ExpressionGen(private val codeGen: CodeGen) { val code = IRCodeChunk(fcall.position) for ((arg, parameter) in fcall.args.zip(callTarget.parameters)) { val paramDt = codeGen.vmType(parameter.type) + val symbol = (fcall.functionName + parameter.name).joinToString(".") if(codeGen.isZero(arg)) { - if (paramDt == VmDataType.FLOAT) { - val addrOf = codeGen.addressOf(fcall.functionName + parameter.name) - code += IRCodeInstruction(Opcode.STOREZM, paramDt, labelSymbol = addrOf) - } else { - val mem = codeGen.addressOf(fcall.functionName + parameter.name) - code += IRCodeInstruction(Opcode.STOREZM, paramDt, labelSymbol = mem) - } + code += IRCodeInstruction(Opcode.STOREZM, paramDt, labelSymbol = symbol) } else { if (paramDt == VmDataType.FLOAT) { val argFpReg = codeGen.vmRegisters.nextFreeFloat() code += translateExpression(arg, -1, argFpReg) - val addrOf = codeGen.addressOf(fcall.functionName + parameter.name) - code += IRCodeInstruction(Opcode.STOREM, paramDt, fpReg1 = argFpReg, labelSymbol = addrOf) + code += IRCodeInstruction(Opcode.STOREM, paramDt, fpReg1 = argFpReg, labelSymbol = symbol) } else { val argReg = codeGen.vmRegisters.nextFree() code += translateExpression(arg, argReg, -1) - val addrOf = codeGen.addressOf(fcall.functionName + parameter.name) - code += IRCodeInstruction(Opcode.STOREM, paramDt, reg1 = argReg, labelSymbol = addrOf) + code += IRCodeInstruction(Opcode.STOREM, paramDt, reg1 = argReg, labelSymbol = symbol) } } } diff --git a/codeGenExperimental/src/prog8/codegen/experimental/VmAssemblyProgram.kt b/codeGenExperimental/src/prog8/codegen/experimental/VmAssemblyProgram.kt index 42f6ade69..37247f9a6 100644 --- a/codeGenExperimental/src/prog8/codegen/experimental/VmAssemblyProgram.kt +++ b/codeGenExperimental/src/prog8/codegen/experimental/VmAssemblyProgram.kt @@ -78,11 +78,13 @@ class VmAssemblyProgram(override val name: String, val irProgram: IRProgram): IA } private fun processInlinedAsm(asm: String, allocations: VmVariableAllocator): String { - // need to replace &X by address of X. TODO: this actually needs to be done by the vm assembler/loader. Then this can be omitted - return asm.replace("""&[a-zA-Z\d_\.]+""".toRegex()) { matchResult -> - // replace "&X" with the address of X - val name = matchResult.value.substring(1, matchResult.value.length).split('.') - allocations.get(name).toString() } + // TODO do we have to replace variable names by their allocated address??? + return asm +// // need to replace &X by address of X. TODO: this actually needs to be done by the vm assembler/loader. Then this can be omitted +// return asm.replace("""&[a-zA-Z\d_\.]+""".toRegex()) { matchResult -> +// // replace "&X" with the address of X +// val name = matchResult.value.substring(1, matchResult.value.length).split('.') +// allocations.get(name).toString() } } } diff --git a/codeGenVirtual/src/prog8/codegen/virtual/AssemblyProgram.kt b/codeGenVirtual/src/prog8/codegen/virtual/AssemblyProgram.kt index 2bc3e42e1..73615fdba 100644 --- a/codeGenVirtual/src/prog8/codegen/virtual/AssemblyProgram.kt +++ b/codeGenVirtual/src/prog8/codegen/virtual/AssemblyProgram.kt @@ -48,10 +48,12 @@ class AssemblyProgram(override val name: String, private val allocations: Variab } is VmCodeLabel -> write("_" + line.name.joinToString(".") + ":\n") is VmCodeInlineAsm -> { - val asm = line.assembly.replace("""&[a-zA-Z\d_\.]+""".toRegex()) { matchResult -> - // need to replace &X by address of X. TODO: this actually needs to be done by the vm assembler/loader. Then this can be omitted - val name = matchResult.value.substring(1, matchResult.value.length).split('.') - allocations.get(name).toString() } + // TODO do we have to replace variable names by their allocated address??? + val asm = line.assembly +// val asm = line.assembly.replace("""&[a-zA-Z\d_\.]+""".toRegex()) { matchResult -> +// // need to replace &X by address of X. TODO: this actually needs to be done by the vm assembler/loader. Then this can be omitted +// val name = matchResult.value.substring(1, matchResult.value.length).split('.') +// allocations.get(name).toString() } write(asm+"\n") } is VmCodeInlineBinary -> { diff --git a/compiler/res/prog8lib/virtual/conv.p8 b/compiler/res/prog8lib/virtual/conv.p8 index 3798a8f13..5f35a3b4e 100644 --- a/compiler/res/prog8lib/virtual/conv.p8 +++ b/compiler/res/prog8lib/virtual/conv.p8 @@ -196,7 +196,7 @@ sub str2uword(str string) -> uword { ; the number may NOT be preceded by a + sign and may NOT contain spaces ; (any non-digit character will terminate the number string that is parsed) %asm {{ - loadm.w r0,&conv.str2uword.string + loadm.w r0,conv.str2uword.string syscall 11 return }} @@ -207,7 +207,7 @@ sub str2word(str string) -> word { ; the number may be preceded by a + or - sign but may NOT contain spaces ; (any non-digit character will terminate the number string that is parsed) %asm {{ - loadm.w r0,&conv.str2word.string + loadm.w r0,conv.str2word.string syscall 12 return }} diff --git a/compiler/res/prog8lib/virtual/floats.p8 b/compiler/res/prog8lib/virtual/floats.p8 index 494c89a3b..9521bd3bb 100644 --- a/compiler/res/prog8lib/virtual/floats.p8 +++ b/compiler/res/prog8lib/virtual/floats.p8 @@ -10,7 +10,7 @@ floats { sub print_f(float value) { ; ---- prints the floating point value (without a newline). %asm {{ - loadm.f fr0,&floats.print_f.value + loadm.f fr0,floats.print_f.value syscall 25 return }} @@ -18,8 +18,8 @@ sub print_f(float value) { sub pow(float value, float power) -> float { %asm {{ - loadm.f fr0,&floats.pow.value - loadm.f fr1,&floats.pow.power + loadm.f fr0,floats.pow.value + loadm.f fr1,floats.pow.power fpow.f fr0,fr1 return }} @@ -27,7 +27,7 @@ sub pow(float value, float power) -> float { sub fabs(float value) -> float { %asm {{ - loadm.f fr0,&floats.fabs.value + loadm.f fr0,floats.fabs.value fabs.f fr0,fr0 return }} @@ -35,7 +35,7 @@ sub fabs(float value) -> float { sub sin(float angle) -> float { %asm {{ - loadm.f fr0,&floats.sin.angle + loadm.f fr0,floats.sin.angle fsin.f fr0,fr0 return }} @@ -43,7 +43,7 @@ sub sin(float angle) -> float { sub cos(float angle) -> float { %asm {{ - loadm.f fr0,&floats.cos.angle + loadm.f fr0,floats.cos.angle fcos.f fr0,fr0 return }} @@ -51,7 +51,7 @@ sub cos(float angle) -> float { sub tan(float value) -> float { %asm {{ - loadm.f fr0,&floats.tan.value + loadm.f fr0,floats.tan.value ftan.f fr0,fr0 return }} @@ -59,7 +59,7 @@ sub tan(float value) -> float { sub atan(float value) -> float { %asm {{ - loadm.f fr0,&floats.atan.value + loadm.f fr0,floats.atan.value fatan.f fr0,fr0 return }} @@ -67,7 +67,7 @@ sub atan(float value) -> float { sub ln(float value) -> float { %asm {{ - loadm.f fr0,&floats.ln.value + loadm.f fr0,floats.ln.value fln.f fr0,fr0 return }} @@ -75,7 +75,7 @@ sub ln(float value) -> float { sub log2(float value) -> float { %asm {{ - loadm.f fr0,&floats.log2.value + loadm.f fr0,floats.log2.value flog.f fr0,fr0 return }} @@ -83,7 +83,7 @@ sub log2(float value) -> float { sub sqrt(float value) -> float { %asm {{ - loadm.f fr0,&floats.sqrt.value + loadm.f fr0,floats.sqrt.value sqrt.f fr0,fr0 return }} @@ -101,7 +101,7 @@ sub deg(float angle) -> float { sub round(float value) -> float { %asm {{ - loadm.f fr0,&floats.round.value + loadm.f fr0,floats.round.value fround.f fr0,fr0 return }} @@ -109,7 +109,7 @@ sub round(float value) -> float { sub floor(float value) -> float { %asm {{ - loadm.f fr0,&floats.floor.value + loadm.f fr0,floats.floor.value ffloor.f fr0,fr0 return }} @@ -118,7 +118,7 @@ sub floor(float value) -> float { sub ceil(float value) -> float { ; -- ceil: tr = int(f); if tr==f -> return else return tr+1 %asm {{ - loadm.f fr0,&floats.ceil.value + loadm.f fr0,floats.ceil.value fceil.f fr0,fr0 return }} diff --git a/compiler/res/prog8lib/virtual/prog8_lib.p8 b/compiler/res/prog8lib/virtual/prog8_lib.p8 index 9936522df..da2f687ec 100644 --- a/compiler/res/prog8lib/virtual/prog8_lib.p8 +++ b/compiler/res/prog8lib/virtual/prog8_lib.p8 @@ -42,8 +42,8 @@ prog8_lib { ; Note that you can also directly compare strings and string values with eachother using ; comparison operators ==, < etcetera (it will use strcmp for you under water automatically). %asm {{ - loadm.w r0,&prog8_lib.string_compare.st1 - loadm.w r1,&prog8_lib.string_compare.st2 + loadm.w r0,prog8_lib.string_compare.st1 + loadm.w r1,prog8_lib.string_compare.st2 syscall 29 return }} diff --git a/compiler/res/prog8lib/virtual/syslib.p8 b/compiler/res/prog8lib/virtual/syslib.p8 index 5a0797615..6795969c3 100644 --- a/compiler/res/prog8lib/virtual/syslib.p8 +++ b/compiler/res/prog8lib/virtual/syslib.p8 @@ -15,7 +15,7 @@ sys { sub wait(uword jiffies) { ; --- wait approximately the given number of jiffies (1/60th seconds) %asm {{ - loadm.w r0,&sys.wait.jiffies + loadm.w r0,sys.wait.jiffies syscall 13 }} } @@ -62,7 +62,7 @@ sys { sub exit(ubyte returnvalue) { ; -- immediately exit the program with a return code in the A register %asm {{ - loadm.b r0,&sys.exit.returnvalue + loadm.b r0,sys.exit.returnvalue syscall 1 }} } @@ -82,24 +82,24 @@ sys { sub gfx_enable(ubyte mode) { %asm {{ - loadm.b r0,&sys.gfx_enable.mode + loadm.b r0,sys.gfx_enable.mode syscall 8 }} } sub gfx_plot(uword xx, uword yy, ubyte color) { %asm {{ - loadm.w r0,&sys.gfx_plot.xx - loadm.w r1,&sys.gfx_plot.yy - loadm.b r2,&sys.gfx_plot.color + loadm.w r0,sys.gfx_plot.xx + loadm.w r1,sys.gfx_plot.yy + loadm.b r2,sys.gfx_plot.color syscall 10 }} } sub gfx_getpixel(uword xx, uword yy) -> ubyte { %asm {{ - loadm.w r0,&sys.gfx_getpixel.xx - loadm.w r1,&sys.gfx_getpixel.yy + loadm.w r0,sys.gfx_getpixel.xx + loadm.w r1,sys.gfx_getpixel.yy syscall 30 return }} diff --git a/compiler/res/prog8lib/virtual/textio.p8 b/compiler/res/prog8lib/virtual/textio.p8 index 2e6cd4a86..67cb3a2ae 100644 --- a/compiler/res/prog8lib/virtual/textio.p8 +++ b/compiler/res/prog8lib/virtual/textio.p8 @@ -7,7 +7,7 @@ txt { sub clear_screen() { str @shared sequence = "\x1b[2J\x1B[H" %asm {{ - load.w r0,&txt.clear_screen.sequence + load.w r0,txt.clear_screen.sequence syscall 3 }} } @@ -30,14 +30,14 @@ sub uppercase() { sub chrout(ubyte char) { %asm {{ - loadm.b r0,&txt.chrout.char + loadm.b r0,txt.chrout.char syscall 2 }} } sub print (str text) { %asm {{ - loadm.w r0,&txt.print.text + loadm.w r0,txt.print.text syscall 3 }} } @@ -114,7 +114,7 @@ sub input_chars (uword buffer) -> ubyte { ; ---- Input a string (max. 80 chars) from the keyboard. Returns length of input. (string is terminated with a 0 byte as well) ; It assumes the keyboard is selected as I/O channel! %asm {{ - loadm.w r0,&txt.input_chars.buffer + loadm.w r0,txt.input_chars.buffer syscall 6 return }} diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 416270b57..484d64a18 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,10 +3,8 @@ TODO For next release ^^^^^^^^^^^^^^^^ -- IR: fix superfluous usage of addressOf() -- IR: addressOfSymbol -> just 'symbol' -- IR/VM: add address-of support (see CodeGen.addressOf()) syntax = &X -- IR/VM: add proper memory mapped variables support +- IR/VM: add proper memory mapped variables support - replace the symbol by the memory address in the IR code +- IR/VM: add support for incbin (!binary) - IR/VM: add proper memory slabs support ... diff --git a/examples/test.p8 b/examples/test.p8 index ee1676e23..1dff89fc2 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -24,7 +24,7 @@ main { %asm {{ nop - jump a_label + jump _a_label }} a_label: diff --git a/virtualmachine/src/prog8/vm/Assembler.kt b/virtualmachine/src/prog8/vm/Assembler.kt index 6b96c6ff0..6682d81dd 100644 --- a/virtualmachine/src/prog8/vm/Assembler.kt +++ b/virtualmachine/src/prog8/vm/Assembler.kt @@ -67,19 +67,26 @@ class Assembler { val program = mutableListOf() val instructionPattern = Regex("""([a-z]+)(\.b|\.w|\.f)?(.*)""", RegexOption.IGNORE_CASE) val labelPattern = Regex("""_([a-zA-Z\d\._]+):""") + val binaryPattern = Regex("""!binary (.+)""") for (line in source.lines()) { if(line.isBlank() || line.startsWith(';')) continue val match = instructionPattern.matchEntire(line.trim()) if(match==null) { - val labelmatch = labelPattern.matchEntire(line.trim()) - if(labelmatch==null) - throw IllegalArgumentException("invalid line $line at line ${program.size+1}") - else { - val label = labelmatch.groupValues[1] - if(label in labels) - throw IllegalArgumentException("label redefined $label") - labels[label] = program.size + val binarymatch = binaryPattern.matchEntire(line.trim()) + if(binarymatch!=null) { + val hex = binarymatch.groups[1]!!.value + TODO("binary ${hex}") + } else { + val labelmatch = labelPattern.matchEntire(line.trim()) + if (labelmatch == null) + throw IllegalArgumentException("invalid line $line at line ${program.size + 1}") + else { + val label = labelmatch.groupValues[1] + if (label in labels) + throw IllegalArgumentException("label redefined $label") + labels[label] = program.size + } } } else { val (_, instr, typestr, rest) = match.groupValues