mirror of
https://github.com/irmen/prog8.git
synced 2024-09-07 03:54:27 +00:00
ir: remove position tracking from codechunk for now
This commit is contained in:
parent
e67c05c274
commit
e7408224ac
@ -3,7 +3,6 @@ package prog8.codegen.intermediate
|
|||||||
import prog8.code.ast.*
|
import prog8.code.ast.*
|
||||||
import prog8.code.core.AssemblyError
|
import prog8.code.core.AssemblyError
|
||||||
import prog8.code.core.DataType
|
import prog8.code.core.DataType
|
||||||
import prog8.code.core.Position
|
|
||||||
import prog8.code.core.SignedDatatypes
|
import prog8.code.core.SignedDatatypes
|
||||||
import prog8.intermediate.*
|
import prog8.intermediate.*
|
||||||
|
|
||||||
@ -50,7 +49,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
|||||||
when(value) {
|
when(value) {
|
||||||
is PtIdentifier -> return emptyList() // do nothing, x=x null assignment.
|
is PtIdentifier -> return emptyList() // do nothing, x=x null assignment.
|
||||||
is PtMachineRegister -> return emptyList() // do nothing, reg=reg null assignment
|
is PtMachineRegister -> return emptyList() // do nothing, reg=reg null assignment
|
||||||
is PtPrefix -> return inplacePrefix(value.operator, vmDt, address, null, value.position)
|
is PtPrefix -> return inplacePrefix(value.operator, vmDt, address, null)
|
||||||
is PtBinaryExpression -> return inplaceBinexpr(value.operator, value.right, vmDt, value.type in SignedDatatypes, address, null, origAssign)
|
is PtBinaryExpression -> return inplaceBinexpr(value.operator, value.right, vmDt, value.type in SignedDatatypes, address, null, origAssign)
|
||||||
is PtMemoryByte -> {
|
is PtMemoryByte -> {
|
||||||
return if (!codeGen.options.compTarget.machine.isIOAddress(address.toUInt()))
|
return if (!codeGen.options.compTarget.machine.isIOAddress(address.toUInt()))
|
||||||
@ -58,7 +57,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
|||||||
else {
|
else {
|
||||||
// read and write a (i/o) memory location to itself.
|
// read and write a (i/o) memory location to itself.
|
||||||
val tempReg = codeGen.registers.nextFree()
|
val tempReg = codeGen.registers.nextFree()
|
||||||
val code = IRCodeChunk(null, origAssign.position, null)
|
val code = IRCodeChunk(null, null)
|
||||||
code += IRInstruction(Opcode.LOADM, vmDt, reg1 = tempReg, value = address)
|
code += IRInstruction(Opcode.LOADM, vmDt, reg1 = tempReg, value = address)
|
||||||
code += IRInstruction(Opcode.STOREM, vmDt, reg1 = tempReg, value = address)
|
code += IRInstruction(Opcode.STOREM, vmDt, reg1 = tempReg, value = address)
|
||||||
listOf(code)
|
listOf(code)
|
||||||
@ -77,10 +76,10 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
|||||||
return when(value) {
|
return when(value) {
|
||||||
is PtIdentifier -> emptyList() // do nothing, x=x null assignment.
|
is PtIdentifier -> emptyList() // do nothing, x=x null assignment.
|
||||||
is PtMachineRegister -> emptyList() // do nothing, reg=reg null assignment
|
is PtMachineRegister -> emptyList() // do nothing, reg=reg null assignment
|
||||||
is PtPrefix -> inplacePrefix(value.operator, vmDt, null, symbol, value.position)
|
is PtPrefix -> inplacePrefix(value.operator, vmDt, null, symbol)
|
||||||
is PtBinaryExpression -> inplaceBinexpr(value.operator, value.right, vmDt, value.type in SignedDatatypes, null, symbol, origAssign)
|
is PtBinaryExpression -> inplaceBinexpr(value.operator, value.right, vmDt, value.type in SignedDatatypes, null, symbol, origAssign)
|
||||||
is PtMemoryByte -> {
|
is PtMemoryByte -> {
|
||||||
val code = IRCodeChunk(null, origAssign.position, null)
|
val code = IRCodeChunk(null, null)
|
||||||
val tempReg = codeGen.registers.nextFree()
|
val tempReg = codeGen.registers.nextFree()
|
||||||
code += IRInstruction(Opcode.LOADM, vmDt, reg1 = tempReg, labelSymbol = symbol)
|
code += IRInstruction(Opcode.LOADM, vmDt, reg1 = tempReg, labelSymbol = symbol)
|
||||||
code += IRInstruction(Opcode.STOREM, vmDt, reg1 = tempReg, labelSymbol = symbol)
|
code += IRInstruction(Opcode.STOREM, vmDt, reg1 = tempReg, labelSymbol = symbol)
|
||||||
@ -137,8 +136,8 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
|||||||
return fallbackAssign(origAssign)
|
return fallbackAssign(origAssign)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun inplacePrefix(operator: String, vmDt: IRDataType, knownAddress: Int?, addressSymbol: String?, position: Position): IRCodeChunks {
|
private fun inplacePrefix(operator: String, vmDt: IRDataType, knownAddress: Int?, addressSymbol: String?): IRCodeChunks {
|
||||||
val code= IRCodeChunk(null, position, null)
|
val code= IRCodeChunk(null, null)
|
||||||
when(operator) {
|
when(operator) {
|
||||||
"+" -> { }
|
"+" -> { }
|
||||||
"-" -> {
|
"-" -> {
|
||||||
@ -196,7 +195,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
|||||||
else
|
else
|
||||||
IRInstruction(Opcode.STOREM, vmDt, reg1 = resultRegister, labelSymbol = symbol)
|
IRInstruction(Opcode.STOREM, vmDt, reg1 = resultRegister, labelSymbol = symbol)
|
||||||
}
|
}
|
||||||
result += IRCodeChunk(null, ident.position, null).also { it += instruction }
|
result += IRCodeChunk(null, null).also { it += instruction }
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
else if(array!=null) {
|
else if(array!=null) {
|
||||||
@ -211,7 +210,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
|||||||
throw AssemblyError("non-array var indexing requires bytes index")
|
throw AssemblyError("non-array var indexing requires bytes index")
|
||||||
val idxReg = codeGen.registers.nextFree()
|
val idxReg = codeGen.registers.nextFree()
|
||||||
result += expressionEval.translateExpression(array.index, idxReg, -1)
|
result += expressionEval.translateExpression(array.index, idxReg, -1)
|
||||||
val code = IRCodeChunk(null, assignment.position, null)
|
val code = IRCodeChunk(null, null)
|
||||||
if(zero) {
|
if(zero) {
|
||||||
// there's no STOREZIX instruction
|
// there's no STOREZIX instruction
|
||||||
resultRegister = codeGen.registers.nextFree()
|
resultRegister = codeGen.registers.nextFree()
|
||||||
@ -226,33 +225,33 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
|||||||
if(zero) {
|
if(zero) {
|
||||||
if(fixedIndex!=null) {
|
if(fixedIndex!=null) {
|
||||||
val offset = fixedIndex*itemsize
|
val offset = fixedIndex*itemsize
|
||||||
val chunk = IRCodeChunk(null, assignment.position, null).also { it += IRInstruction(Opcode.STOREZM, vmDt, labelSymbol = "$variable+$offset") }
|
val chunk = IRCodeChunk(null, null).also { it += IRInstruction(Opcode.STOREZM, vmDt, labelSymbol = "$variable+$offset") }
|
||||||
result += chunk
|
result += chunk
|
||||||
} else {
|
} else {
|
||||||
val indexReg = codeGen.registers.nextFree()
|
val indexReg = codeGen.registers.nextFree()
|
||||||
result += loadIndexReg(array, itemsize, indexReg)
|
result += loadIndexReg(array, itemsize, indexReg)
|
||||||
result += IRCodeChunk(null, array.position, null).also { it += IRInstruction(Opcode.STOREZX, vmDt, reg1=indexReg, labelSymbol = variable) }
|
result += IRCodeChunk(null, null).also { it += IRInstruction(Opcode.STOREZX, vmDt, reg1=indexReg, labelSymbol = variable) }
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(vmDt== IRDataType.FLOAT) {
|
if(vmDt== IRDataType.FLOAT) {
|
||||||
if(fixedIndex!=null) {
|
if(fixedIndex!=null) {
|
||||||
val offset = fixedIndex*itemsize
|
val offset = fixedIndex*itemsize
|
||||||
val chunk = IRCodeChunk(null, assignment.position, null).also { it += IRInstruction(Opcode.STOREM, vmDt, fpReg1 = resultFpRegister, labelSymbol = "$variable+$offset") }
|
val chunk = IRCodeChunk(null, null).also { it += IRInstruction(Opcode.STOREM, vmDt, fpReg1 = resultFpRegister, labelSymbol = "$variable+$offset") }
|
||||||
result += chunk
|
result += chunk
|
||||||
} else {
|
} else {
|
||||||
val indexReg = codeGen.registers.nextFree()
|
val indexReg = codeGen.registers.nextFree()
|
||||||
result += loadIndexReg(array, itemsize, indexReg)
|
result += loadIndexReg(array, itemsize, indexReg)
|
||||||
result += IRCodeChunk(null, array.position, null).also { it += IRInstruction(Opcode.STOREX, vmDt, reg1 = indexReg, fpReg1 = resultFpRegister, labelSymbol = variable) }
|
result += IRCodeChunk(null, null).also { it += IRInstruction(Opcode.STOREX, vmDt, reg1 = indexReg, fpReg1 = resultFpRegister, labelSymbol = variable) }
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(fixedIndex!=null) {
|
if(fixedIndex!=null) {
|
||||||
val offset = fixedIndex*itemsize
|
val offset = fixedIndex*itemsize
|
||||||
val chunk = IRCodeChunk(null, assignment.position, null).also { it += IRInstruction(Opcode.STOREM, vmDt, reg1 = resultRegister, labelSymbol = "$variable+$offset") }
|
val chunk = IRCodeChunk(null, null).also { it += IRInstruction(Opcode.STOREM, vmDt, reg1 = resultRegister, labelSymbol = "$variable+$offset") }
|
||||||
result += chunk
|
result += chunk
|
||||||
} else {
|
} else {
|
||||||
val indexReg = codeGen.registers.nextFree()
|
val indexReg = codeGen.registers.nextFree()
|
||||||
result += loadIndexReg(array, itemsize, indexReg)
|
result += loadIndexReg(array, itemsize, indexReg)
|
||||||
result += IRCodeChunk(null, array.position, null).also { it += IRInstruction(Opcode.STOREX, vmDt, reg1 = resultRegister, reg2=indexReg, labelSymbol = variable) }
|
result += IRCodeChunk(null, null).also { it += IRInstruction(Opcode.STOREX, vmDt, reg1 = resultRegister, reg2=indexReg, labelSymbol = variable) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -262,21 +261,21 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
|||||||
require(vmDt== IRDataType.BYTE)
|
require(vmDt== IRDataType.BYTE)
|
||||||
if(zero) {
|
if(zero) {
|
||||||
if(memory.address is PtNumber) {
|
if(memory.address is PtNumber) {
|
||||||
val chunk = IRCodeChunk(null, assignment.position, null).also { it += IRInstruction(Opcode.STOREZM, vmDt, value=(memory.address as PtNumber).number.toInt()) }
|
val chunk = IRCodeChunk(null, null).also { it += IRInstruction(Opcode.STOREZM, vmDt, value=(memory.address as PtNumber).number.toInt()) }
|
||||||
result += chunk
|
result += chunk
|
||||||
} else {
|
} else {
|
||||||
val addressReg = codeGen.registers.nextFree()
|
val addressReg = codeGen.registers.nextFree()
|
||||||
result += expressionEval.translateExpression(memory.address, addressReg, -1)
|
result += expressionEval.translateExpression(memory.address, addressReg, -1)
|
||||||
result += IRCodeChunk(null, assignment.position, null).also { it += IRInstruction(Opcode.STOREZI, vmDt, reg1=addressReg) }
|
result += IRCodeChunk(null, null).also { it += IRInstruction(Opcode.STOREZI, vmDt, reg1=addressReg) }
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(memory.address is PtNumber) {
|
if(memory.address is PtNumber) {
|
||||||
val chunk = IRCodeChunk(null, assignment.position, null).also { it += IRInstruction(Opcode.STOREM, vmDt, reg1=resultRegister, value=(memory.address as PtNumber).number.toInt()) }
|
val chunk = IRCodeChunk(null, null).also { it += IRInstruction(Opcode.STOREM, vmDt, reg1=resultRegister, value=(memory.address as PtNumber).number.toInt()) }
|
||||||
result += chunk
|
result += chunk
|
||||||
} else {
|
} else {
|
||||||
val addressReg = codeGen.registers.nextFree()
|
val addressReg = codeGen.registers.nextFree()
|
||||||
result += expressionEval.translateExpression(memory.address, addressReg, -1)
|
result += expressionEval.translateExpression(memory.address, addressReg, -1)
|
||||||
result += IRCodeChunk(null, assignment.position, null).also { it += IRInstruction(Opcode.STOREI, vmDt, reg1=resultRegister, reg2=addressReg) }
|
result += IRCodeChunk(null, null).also { it += IRInstruction(Opcode.STOREI, vmDt, reg1=resultRegister, reg2=addressReg) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
|||||||
val result = mutableListOf<IRCodeChunkBase>()
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
result += exprGen.translateExpression(call.args[0], leftRegister, -1)
|
result += exprGen.translateExpression(call.args[0], leftRegister, -1)
|
||||||
result += exprGen.translateExpression(call.args[1], rightRegister, -1)
|
result += exprGen.translateExpression(call.args[1], rightRegister, -1)
|
||||||
result += IRCodeChunk(null, call.position, null).also {
|
result += IRCodeChunk(null, null).also {
|
||||||
it += IRInstruction(Opcode.CMP, codeGen.irType(call.args[0].type), reg1=leftRegister, reg2=rightRegister)
|
it += IRInstruction(Opcode.CMP, codeGen.irType(call.args[0].type), reg1=leftRegister, reg2=rightRegister)
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
@ -72,7 +72,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
|||||||
}
|
}
|
||||||
val result = mutableListOf<IRCodeChunkBase>()
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
result += exprGen.translateExpression(call.args[0], 0, -1)
|
result += exprGen.translateExpression(call.args[0], 0, -1)
|
||||||
result += IRCodeChunk(null, call.position, null).also {
|
result += IRCodeChunk(null, null).also {
|
||||||
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = 1, value = array.length)
|
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = 1, value = array.length)
|
||||||
it += IRInstruction(Opcode.SYSCALL, value = syscall.number)
|
it += IRInstruction(Opcode.SYSCALL, value = syscall.number)
|
||||||
if (resultRegister != 0)
|
if (resultRegister != 0)
|
||||||
@ -95,7 +95,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
|||||||
}
|
}
|
||||||
val result = mutableListOf<IRCodeChunkBase>()
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
result += exprGen.translateExpression(call.args[0], 0, -1)
|
result += exprGen.translateExpression(call.args[0], 0, -1)
|
||||||
result += IRCodeChunk(null, call.position, null).also {
|
result += IRCodeChunk(null, null).also {
|
||||||
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = 1, value = array.length)
|
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = 1, value = array.length)
|
||||||
it += IRInstruction(Opcode.SYSCALL, value = syscall.number)
|
it += IRInstruction(Opcode.SYSCALL, value = syscall.number)
|
||||||
if (resultRegister != 0)
|
if (resultRegister != 0)
|
||||||
@ -111,32 +111,32 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
|||||||
result += exprGen.translateExpression(call.args[0], resultRegister, -1)
|
result += exprGen.translateExpression(call.args[0], resultRegister, -1)
|
||||||
when (sourceDt) {
|
when (sourceDt) {
|
||||||
DataType.UBYTE -> {
|
DataType.UBYTE -> {
|
||||||
result += IRCodeChunk(null, call.position, null).also {
|
result += IRCodeChunk(null, null).also {
|
||||||
it += IRInstruction(Opcode.EXT, IRDataType.BYTE, reg1 = resultRegister)
|
it += IRInstruction(Opcode.EXT, IRDataType.BYTE, reg1 = resultRegister)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DataType.BYTE -> {
|
DataType.BYTE -> {
|
||||||
val notNegativeLabel = codeGen.createLabelName()
|
val notNegativeLabel = codeGen.createLabelName()
|
||||||
val compareReg = codeGen.registers.nextFree()
|
val compareReg = codeGen.registers.nextFree()
|
||||||
result += IRCodeChunk(null, call.position, null).also {
|
result += IRCodeChunk(null, null).also {
|
||||||
it += IRInstruction(Opcode.LOADR, IRDataType.BYTE, reg1=compareReg, reg2=resultRegister)
|
it += IRInstruction(Opcode.LOADR, IRDataType.BYTE, reg1=compareReg, reg2=resultRegister)
|
||||||
it += IRInstruction(Opcode.AND, IRDataType.BYTE, reg1=compareReg, value=0x80)
|
it += IRInstruction(Opcode.AND, IRDataType.BYTE, reg1=compareReg, value=0x80)
|
||||||
it += IRInstruction(Opcode.BZ, IRDataType.BYTE, reg1=compareReg, labelSymbol = notNegativeLabel)
|
it += IRInstruction(Opcode.BZ, IRDataType.BYTE, reg1=compareReg, labelSymbol = notNegativeLabel)
|
||||||
it += IRInstruction(Opcode.NEG, IRDataType.BYTE, reg1=resultRegister)
|
it += IRInstruction(Opcode.NEG, IRDataType.BYTE, reg1=resultRegister)
|
||||||
it += IRInstruction(Opcode.EXT, IRDataType.BYTE, reg1=resultRegister)
|
it += IRInstruction(Opcode.EXT, IRDataType.BYTE, reg1=resultRegister)
|
||||||
}
|
}
|
||||||
result += IRCodeChunk(notNegativeLabel, call.position, null)
|
result += IRCodeChunk(notNegativeLabel, null)
|
||||||
}
|
}
|
||||||
DataType.WORD -> {
|
DataType.WORD -> {
|
||||||
val notNegativeLabel = codeGen.createLabelName()
|
val notNegativeLabel = codeGen.createLabelName()
|
||||||
val compareReg = codeGen.registers.nextFree()
|
val compareReg = codeGen.registers.nextFree()
|
||||||
result += IRCodeChunk(null, call.position, null).also {
|
result += IRCodeChunk(null, null).also {
|
||||||
it += IRInstruction(Opcode.LOADR, IRDataType.WORD, reg1=compareReg, reg2=resultRegister)
|
it += IRInstruction(Opcode.LOADR, IRDataType.WORD, reg1=compareReg, reg2=resultRegister)
|
||||||
it += IRInstruction(Opcode.AND, IRDataType.WORD, reg1=compareReg, value=0x8000)
|
it += IRInstruction(Opcode.AND, IRDataType.WORD, reg1=compareReg, value=0x8000)
|
||||||
it += IRInstruction(Opcode.BZ, IRDataType.WORD, reg1=compareReg, labelSymbol = notNegativeLabel)
|
it += IRInstruction(Opcode.BZ, IRDataType.WORD, reg1=compareReg, labelSymbol = notNegativeLabel)
|
||||||
it += IRInstruction(Opcode.NEG, IRDataType.WORD, reg1=resultRegister)
|
it += IRInstruction(Opcode.NEG, IRDataType.WORD, reg1=resultRegister)
|
||||||
}
|
}
|
||||||
result += IRCodeChunk(notNegativeLabel, call.position, null)
|
result += IRCodeChunk(notNegativeLabel, null)
|
||||||
}
|
}
|
||||||
else -> throw AssemblyError("weird type")
|
else -> throw AssemblyError("weird type")
|
||||||
}
|
}
|
||||||
@ -148,7 +148,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
|||||||
val reg = codeGen.registers.nextFree()
|
val reg = codeGen.registers.nextFree()
|
||||||
val result = mutableListOf<IRCodeChunkBase>()
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
result += exprGen.translateExpression(call.args.single(), reg, -1)
|
result += exprGen.translateExpression(call.args.single(), reg, -1)
|
||||||
result += IRCodeChunk(null, call.position, null).also {
|
result += IRCodeChunk(null, null).also {
|
||||||
it += IRInstruction(Opcode.SGN, codeGen.irType(call.type), reg1 = resultRegister, reg2 = reg)
|
it += IRInstruction(Opcode.SGN, codeGen.irType(call.type), reg1 = resultRegister, reg2 = reg)
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
@ -158,14 +158,14 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
|||||||
val reg = codeGen.registers.nextFree()
|
val reg = codeGen.registers.nextFree()
|
||||||
val result = mutableListOf<IRCodeChunkBase>()
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
result += exprGen.translateExpression(call.args.single(), reg, -1)
|
result += exprGen.translateExpression(call.args.single(), reg, -1)
|
||||||
result += IRCodeChunk(null, call.position, null).also {
|
result += IRCodeChunk(null, null).also {
|
||||||
it += IRInstruction(Opcode.SQRT, IRDataType.WORD, reg1=resultRegister, reg2=reg)
|
it += IRInstruction(Opcode.SQRT, IRDataType.WORD, reg1=resultRegister, reg2=reg)
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun funcPop(call: PtBuiltinFunctionCall): IRCodeChunks {
|
private fun funcPop(call: PtBuiltinFunctionCall): IRCodeChunks {
|
||||||
val code = IRCodeChunk(null, call.position, null)
|
val code = IRCodeChunk(null, null)
|
||||||
val reg = codeGen.registers.nextFree()
|
val reg = codeGen.registers.nextFree()
|
||||||
code += IRInstruction(Opcode.POP, IRDataType.BYTE, reg1=reg)
|
code += IRInstruction(Opcode.POP, IRDataType.BYTE, reg1=reg)
|
||||||
val result = mutableListOf<IRCodeChunkBase>(code)
|
val result = mutableListOf<IRCodeChunkBase>(code)
|
||||||
@ -174,7 +174,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun funcPopw(call: PtBuiltinFunctionCall): IRCodeChunks {
|
private fun funcPopw(call: PtBuiltinFunctionCall): IRCodeChunks {
|
||||||
val code = IRCodeChunk(null, call.position, null)
|
val code = IRCodeChunk(null, null)
|
||||||
val reg = codeGen.registers.nextFree()
|
val reg = codeGen.registers.nextFree()
|
||||||
code += IRInstruction(Opcode.POP, IRDataType.WORD, reg1=reg)
|
code += IRInstruction(Opcode.POP, IRDataType.WORD, reg1=reg)
|
||||||
val result = mutableListOf<IRCodeChunkBase>(code)
|
val result = mutableListOf<IRCodeChunkBase>(code)
|
||||||
@ -186,7 +186,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
|||||||
val result = mutableListOf<IRCodeChunkBase>()
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
val reg = codeGen.registers.nextFree()
|
val reg = codeGen.registers.nextFree()
|
||||||
result += exprGen.translateExpression(call.args.single(), reg, -1)
|
result += exprGen.translateExpression(call.args.single(), reg, -1)
|
||||||
result += IRCodeChunk(null, call.position, null).also {
|
result += IRCodeChunk(null, null).also {
|
||||||
it += IRInstruction(Opcode.PUSH, IRDataType.BYTE, reg1=reg)
|
it += IRInstruction(Opcode.PUSH, IRDataType.BYTE, reg1=reg)
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
@ -196,7 +196,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
|||||||
val result = mutableListOf<IRCodeChunkBase>()
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
val reg = codeGen.registers.nextFree()
|
val reg = codeGen.registers.nextFree()
|
||||||
result += exprGen.translateExpression(call.args.single(), reg, -1)
|
result += exprGen.translateExpression(call.args.single(), reg, -1)
|
||||||
result += IRCodeChunk(null, call.position, null).also {
|
result += IRCodeChunk(null, null).also {
|
||||||
it += IRInstruction(Opcode.PUSH, IRDataType.WORD, reg1 = reg)
|
it += IRInstruction(Opcode.PUSH, IRDataType.WORD, reg1 = reg)
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
@ -214,7 +214,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
|||||||
}
|
}
|
||||||
val result = mutableListOf<IRCodeChunkBase>()
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
result += exprGen.translateExpression(call.args[0], 0, -1)
|
result += exprGen.translateExpression(call.args[0], 0, -1)
|
||||||
result += IRCodeChunk(null, call.position, null).also {
|
result += IRCodeChunk(null, null).also {
|
||||||
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = 1, value = array.length)
|
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = 1, value = array.length)
|
||||||
it += IRInstruction(Opcode.SYSCALL, value = syscall.number)
|
it += IRInstruction(Opcode.SYSCALL, value = syscall.number)
|
||||||
}
|
}
|
||||||
@ -236,7 +236,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
|||||||
}
|
}
|
||||||
val result = mutableListOf<IRCodeChunkBase>()
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
result += exprGen.translateExpression(call.args[0], 0, -1)
|
result += exprGen.translateExpression(call.args[0], 0, -1)
|
||||||
result += IRCodeChunk(null, call.position, null).also {
|
result += IRCodeChunk(null, null).also {
|
||||||
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = 1, value = array.length)
|
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = 1, value = array.length)
|
||||||
it += IRInstruction(Opcode.SYSCALL, value = syscall.number)
|
it += IRInstruction(Opcode.SYSCALL, value = syscall.number)
|
||||||
}
|
}
|
||||||
@ -248,7 +248,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
|||||||
val result = mutableListOf<IRCodeChunkBase>()
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
result += exprGen.translateExpression(call.args[0], msbReg, -1)
|
result += exprGen.translateExpression(call.args[0], msbReg, -1)
|
||||||
result += exprGen.translateExpression(call.args[1], resultRegister, -1)
|
result += exprGen.translateExpression(call.args[1], resultRegister, -1)
|
||||||
result += IRCodeChunk(null, call.position, null).also {
|
result += IRCodeChunk(null, null).also {
|
||||||
it += IRInstruction(Opcode.CONCAT, IRDataType.BYTE, reg1 = resultRegister, reg2 = msbReg)
|
it += IRInstruction(Opcode.CONCAT, IRDataType.BYTE, reg1 = resultRegister, reg2 = msbReg)
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
@ -259,13 +259,13 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
|||||||
if(codeGen.isZero(call.args[1])) {
|
if(codeGen.isZero(call.args[1])) {
|
||||||
if (call.args[0] is PtNumber) {
|
if (call.args[0] is PtNumber) {
|
||||||
val address = (call.args[0] as PtNumber).number.toInt()
|
val address = (call.args[0] as PtNumber).number.toInt()
|
||||||
result += IRCodeChunk(null, call.position, null).also {
|
result += IRCodeChunk(null, null).also {
|
||||||
it += IRInstruction(Opcode.STOREZM, IRDataType.WORD, value = address)
|
it += IRInstruction(Opcode.STOREZM, IRDataType.WORD, value = address)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val addressReg = codeGen.registers.nextFree()
|
val addressReg = codeGen.registers.nextFree()
|
||||||
result += exprGen.translateExpression(call.args[0], addressReg, -1)
|
result += exprGen.translateExpression(call.args[0], addressReg, -1)
|
||||||
result += IRCodeChunk(null, call.position, null).also {
|
result += IRCodeChunk(null, null).also {
|
||||||
it += IRInstruction(Opcode.STOREZI, IRDataType.WORD, reg2 = addressReg)
|
it += IRInstruction(Opcode.STOREZI, IRDataType.WORD, reg2 = addressReg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -274,14 +274,14 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
|||||||
if (call.args[0] is PtNumber) {
|
if (call.args[0] is PtNumber) {
|
||||||
val address = (call.args[0] as PtNumber).number.toInt()
|
val address = (call.args[0] as PtNumber).number.toInt()
|
||||||
result += exprGen.translateExpression(call.args[1], valueReg, -1)
|
result += exprGen.translateExpression(call.args[1], valueReg, -1)
|
||||||
result += IRCodeChunk(null, call.position, null).also {
|
result += IRCodeChunk(null, null).also {
|
||||||
it += IRInstruction(Opcode.STOREM, IRDataType.WORD, reg1 = valueReg, value = address)
|
it += IRInstruction(Opcode.STOREM, IRDataType.WORD, reg1 = valueReg, value = address)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val addressReg = codeGen.registers.nextFree()
|
val addressReg = codeGen.registers.nextFree()
|
||||||
result += exprGen.translateExpression(call.args[0], addressReg, -1)
|
result += exprGen.translateExpression(call.args[0], addressReg, -1)
|
||||||
result += exprGen.translateExpression(call.args[1], valueReg, -1)
|
result += exprGen.translateExpression(call.args[1], valueReg, -1)
|
||||||
result += IRCodeChunk(null, call.position, null).also {
|
result += IRCodeChunk(null, null).also {
|
||||||
it += IRInstruction(Opcode.STOREI, IRDataType.WORD, reg1 = valueReg, reg2 = addressReg)
|
it += IRInstruction(Opcode.STOREI, IRDataType.WORD, reg1 = valueReg, reg2 = addressReg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -294,13 +294,13 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
|||||||
if(codeGen.isZero(call.args[1])) {
|
if(codeGen.isZero(call.args[1])) {
|
||||||
if (call.args[0] is PtNumber) {
|
if (call.args[0] is PtNumber) {
|
||||||
val address = (call.args[0] as PtNumber).number.toInt()
|
val address = (call.args[0] as PtNumber).number.toInt()
|
||||||
result += IRCodeChunk(null, call.position, null).also {
|
result += IRCodeChunk(null, null).also {
|
||||||
it += IRInstruction(Opcode.STOREZM, IRDataType.BYTE, value = address)
|
it += IRInstruction(Opcode.STOREZM, IRDataType.BYTE, value = address)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val addressReg = codeGen.registers.nextFree()
|
val addressReg = codeGen.registers.nextFree()
|
||||||
result += exprGen.translateExpression(call.args[0], addressReg, -1)
|
result += exprGen.translateExpression(call.args[0], addressReg, -1)
|
||||||
result += IRCodeChunk(null, call.position, null).also {
|
result += IRCodeChunk(null, null).also {
|
||||||
it += IRInstruction(Opcode.STOREZI, IRDataType.BYTE, reg2 = addressReg)
|
it += IRInstruction(Opcode.STOREZI, IRDataType.BYTE, reg2 = addressReg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -309,14 +309,14 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
|||||||
if (call.args[0] is PtNumber) {
|
if (call.args[0] is PtNumber) {
|
||||||
val address = (call.args[0] as PtNumber).number.toInt()
|
val address = (call.args[0] as PtNumber).number.toInt()
|
||||||
result += exprGen.translateExpression(call.args[1], valueReg, -1)
|
result += exprGen.translateExpression(call.args[1], valueReg, -1)
|
||||||
result += IRCodeChunk(null, call.position, null).also {
|
result += IRCodeChunk(null, null).also {
|
||||||
it += IRInstruction(Opcode.STOREM, IRDataType.BYTE, reg1 = valueReg, value = address)
|
it += IRInstruction(Opcode.STOREM, IRDataType.BYTE, reg1 = valueReg, value = address)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val addressReg = codeGen.registers.nextFree()
|
val addressReg = codeGen.registers.nextFree()
|
||||||
result += exprGen.translateExpression(call.args[0], addressReg, -1)
|
result += exprGen.translateExpression(call.args[0], addressReg, -1)
|
||||||
result += exprGen.translateExpression(call.args[1], valueReg, -1)
|
result += exprGen.translateExpression(call.args[1], valueReg, -1)
|
||||||
result += IRCodeChunk(null, call.position, null).also {
|
result += IRCodeChunk(null, null).also {
|
||||||
it += IRInstruction(Opcode.STOREI, IRDataType.BYTE, reg1 = valueReg, reg2 = addressReg)
|
it += IRInstruction(Opcode.STOREI, IRDataType.BYTE, reg1 = valueReg, reg2 = addressReg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -328,13 +328,13 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
|||||||
val result = mutableListOf<IRCodeChunkBase>()
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
if(call.args[0] is PtNumber) {
|
if(call.args[0] is PtNumber) {
|
||||||
val address = (call.args[0] as PtNumber).number.toInt()
|
val address = (call.args[0] as PtNumber).number.toInt()
|
||||||
result += IRCodeChunk(null, call.position, null).also {
|
result += IRCodeChunk(null, null).also {
|
||||||
it += IRInstruction(Opcode.LOADM, IRDataType.WORD, reg1 = resultRegister, value = address)
|
it += IRInstruction(Opcode.LOADM, IRDataType.WORD, reg1 = resultRegister, value = address)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val addressReg = codeGen.registers.nextFree()
|
val addressReg = codeGen.registers.nextFree()
|
||||||
result += exprGen.translateExpression(call.args.single(), addressReg, -1)
|
result += exprGen.translateExpression(call.args.single(), addressReg, -1)
|
||||||
result += IRCodeChunk(null, call.position, null).also {
|
result += IRCodeChunk(null, null).also {
|
||||||
it += IRInstruction(Opcode.LOADI, IRDataType.WORD, reg1 = resultRegister, reg2 = addressReg)
|
it += IRInstruction(Opcode.LOADI, IRDataType.WORD, reg1 = resultRegister, reg2 = addressReg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -345,13 +345,13 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
|||||||
val result = mutableListOf<IRCodeChunkBase>()
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
if(call.args[0] is PtNumber) {
|
if(call.args[0] is PtNumber) {
|
||||||
val address = (call.args[0] as PtNumber).number.toInt()
|
val address = (call.args[0] as PtNumber).number.toInt()
|
||||||
result += IRCodeChunk(null, call.position, null).also {
|
result += IRCodeChunk(null, null).also {
|
||||||
it += IRInstruction(Opcode.LOADM, IRDataType.BYTE, reg1 = resultRegister, value = address)
|
it += IRInstruction(Opcode.LOADM, IRDataType.BYTE, reg1 = resultRegister, value = address)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val addressReg = codeGen.registers.nextFree()
|
val addressReg = codeGen.registers.nextFree()
|
||||||
result += exprGen.translateExpression(call.args.single(), addressReg, -1)
|
result += exprGen.translateExpression(call.args.single(), addressReg, -1)
|
||||||
result += IRCodeChunk(null, call.position, null).also {
|
result += IRCodeChunk(null, null).also {
|
||||||
it += IRInstruction(Opcode.LOADI, IRDataType.BYTE, reg1 = resultRegister, reg2 = addressReg)
|
it += IRInstruction(Opcode.LOADI, IRDataType.BYTE, reg1 = resultRegister, reg2 = addressReg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -360,7 +360,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
|||||||
|
|
||||||
private fun funcMemory(call: PtBuiltinFunctionCall, resultRegister: Int): IRCodeChunks {
|
private fun funcMemory(call: PtBuiltinFunctionCall, resultRegister: Int): IRCodeChunks {
|
||||||
val name = (call.args[0] as PtString).value
|
val name = (call.args[0] as PtString).value
|
||||||
val code = IRCodeChunk(null, call.position, null)
|
val code = IRCodeChunk(null, null)
|
||||||
code += IRInstruction(Opcode.LOAD, IRDataType.WORD, reg1=resultRegister, labelSymbol = "prog8_slabs.prog8_memoryslab_$name")
|
code += IRInstruction(Opcode.LOAD, IRDataType.WORD, reg1=resultRegister, labelSymbol = "prog8_slabs.prog8_memoryslab_$name")
|
||||||
return listOf(code)
|
return listOf(code)
|
||||||
}
|
}
|
||||||
@ -373,7 +373,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
|||||||
private fun funcMsb(call: PtBuiltinFunctionCall, resultRegister: Int): IRCodeChunks {
|
private fun funcMsb(call: PtBuiltinFunctionCall, resultRegister: Int): IRCodeChunks {
|
||||||
val result = mutableListOf<IRCodeChunkBase>()
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
result += exprGen.translateExpression(call.args.single(), resultRegister, -1)
|
result += exprGen.translateExpression(call.args.single(), resultRegister, -1)
|
||||||
result += IRCodeChunk(null, call.position, null).also {
|
result += IRCodeChunk(null, null).also {
|
||||||
it += IRInstruction(Opcode.MSIG, IRDataType.BYTE, reg1 = resultRegister, reg2 = resultRegister)
|
it += IRInstruction(Opcode.MSIG, IRDataType.BYTE, reg1 = resultRegister, reg2 = resultRegister)
|
||||||
}
|
}
|
||||||
// note: if a word result is needed, the upper byte is cleared by the typecast that follows. No need to do it here.
|
// note: if a word result is needed, the upper byte is cleared by the typecast that follows. No need to do it here.
|
||||||
@ -384,7 +384,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
|||||||
val vmDt = codeGen.irType(call.args[0].type)
|
val vmDt = codeGen.irType(call.args[0].type)
|
||||||
val result = mutableListOf<IRCodeChunkBase>()
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
result += exprGen.translateExpression(call.args[0], resultRegister, -1)
|
result += exprGen.translateExpression(call.args[0], resultRegister, -1)
|
||||||
result += IRCodeChunk(null, call.position, null).also {
|
result += IRCodeChunk(null, null).also {
|
||||||
it += IRInstruction(opcode, vmDt, reg1 = resultRegister)
|
it += IRInstruction(opcode, vmDt, reg1 = resultRegister)
|
||||||
}
|
}
|
||||||
result += assignRegisterTo(call.args[0], resultRegister)
|
result += assignRegisterTo(call.args[0], resultRegister)
|
||||||
|
@ -16,7 +16,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
is PtMachineRegister -> {
|
is PtMachineRegister -> {
|
||||||
if(resultRegister!=expr.register) {
|
if(resultRegister!=expr.register) {
|
||||||
val vmDt = codeGen.irType(expr.type)
|
val vmDt = codeGen.irType(expr.type)
|
||||||
val code = IRCodeChunk(null, expr.position, null)
|
val code = IRCodeChunk(null, null)
|
||||||
code += IRInstruction(Opcode.LOADR, vmDt, reg1=resultRegister, reg2=expr.register)
|
code += IRInstruction(Opcode.LOADR, vmDt, reg1=resultRegister, reg2=expr.register)
|
||||||
listOf(code)
|
listOf(code)
|
||||||
} else {
|
} else {
|
||||||
@ -25,7 +25,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
}
|
}
|
||||||
is PtNumber -> {
|
is PtNumber -> {
|
||||||
val vmDt = codeGen.irType(expr.type)
|
val vmDt = codeGen.irType(expr.type)
|
||||||
val code = IRCodeChunk(null, expr.position, null)
|
val code = IRCodeChunk(null, null)
|
||||||
code += if(vmDt==IRDataType.FLOAT)
|
code += if(vmDt==IRDataType.FLOAT)
|
||||||
IRInstruction(Opcode.LOAD, vmDt, fpReg1 = resultFpRegister, fpValue = expr.number.toFloat())
|
IRInstruction(Opcode.LOAD, vmDt, fpReg1 = resultFpRegister, fpValue = expr.number.toFloat())
|
||||||
else
|
else
|
||||||
@ -35,7 +35,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
is PtIdentifier -> {
|
is PtIdentifier -> {
|
||||||
val vmDt = codeGen.irType(expr.type)
|
val vmDt = codeGen.irType(expr.type)
|
||||||
val symbol = expr.targetName.joinToString(".")
|
val symbol = expr.targetName.joinToString(".")
|
||||||
val code = IRCodeChunk(null, expr.position, null)
|
val code = IRCodeChunk(null, null)
|
||||||
code += if (expr.type in PassByValueDatatypes) {
|
code += if (expr.type in PassByValueDatatypes) {
|
||||||
if(vmDt==IRDataType.FLOAT)
|
if(vmDt==IRDataType.FLOAT)
|
||||||
IRInstruction(Opcode.LOADM, vmDt, fpReg1 = resultFpRegister, labelSymbol = symbol)
|
IRInstruction(Opcode.LOADM, vmDt, fpReg1 = resultFpRegister, labelSymbol = symbol)
|
||||||
@ -51,7 +51,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
val vmDt = codeGen.irType(expr.type)
|
val vmDt = codeGen.irType(expr.type)
|
||||||
val symbol = expr.identifier.targetName.joinToString(".")
|
val symbol = expr.identifier.targetName.joinToString(".")
|
||||||
// note: LOAD <symbol> gets you the address of the symbol, whereas LOADM <symbol> would get you the value stored at that location
|
// note: LOAD <symbol> gets you the address of the symbol, whereas LOADM <symbol> would get you the value stored at that location
|
||||||
val code = IRCodeChunk(null, expr.position, null)
|
val code = IRCodeChunk(null, null)
|
||||||
code += IRInstruction(Opcode.LOAD, vmDt, reg1=resultRegister, labelSymbol = symbol)
|
code += IRInstruction(Opcode.LOAD, vmDt, reg1=resultRegister, labelSymbol = symbol)
|
||||||
listOf(code)
|
listOf(code)
|
||||||
}
|
}
|
||||||
@ -59,11 +59,11 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
val result = mutableListOf<IRCodeChunkBase>()
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
if(expr.address is PtNumber) {
|
if(expr.address is PtNumber) {
|
||||||
val address = (expr.address as PtNumber).number.toInt()
|
val address = (expr.address as PtNumber).number.toInt()
|
||||||
addInstr(result, IRInstruction(Opcode.LOADM, IRDataType.BYTE, reg1=resultRegister, value = address), null, expr.position)
|
addInstr(result, IRInstruction(Opcode.LOADM, IRDataType.BYTE, reg1=resultRegister, value = address), null)
|
||||||
} else {
|
} else {
|
||||||
val addressRegister = codeGen.registers.nextFree()
|
val addressRegister = codeGen.registers.nextFree()
|
||||||
result += translateExpression(expr.address, addressRegister, -1)
|
result += translateExpression(expr.address, addressRegister, -1)
|
||||||
addInstr(result, IRInstruction(Opcode.LOADI, IRDataType.BYTE, reg1=resultRegister, reg2=addressRegister), null, expr.position)
|
addInstr(result, IRInstruction(Opcode.LOADI, IRDataType.BYTE, reg1=resultRegister, reg2=addressRegister), null)
|
||||||
}
|
}
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
@ -140,24 +140,24 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
if(arrayIx.index.type!=DataType.UBYTE)
|
if(arrayIx.index.type!=DataType.UBYTE)
|
||||||
throw AssemblyError("non-array var indexing requires bytes index")
|
throw AssemblyError("non-array var indexing requires bytes index")
|
||||||
result += translateExpression(arrayIx.index, idxReg, -1)
|
result += translateExpression(arrayIx.index, idxReg, -1)
|
||||||
addInstr(result, IRInstruction(Opcode.LOADIX, vmDt, reg1=resultRegister, reg2=idxReg, labelSymbol = arrayVarSymbol), null, arrayIx.position)
|
addInstr(result, IRInstruction(Opcode.LOADIX, vmDt, reg1=resultRegister, reg2=idxReg, labelSymbol = arrayVarSymbol), null)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
if(arrayIx.index is PtNumber) {
|
if(arrayIx.index is PtNumber) {
|
||||||
val memOffset = ((arrayIx.index as PtNumber).number.toInt() * eltSize).toString()
|
val memOffset = ((arrayIx.index as PtNumber).number.toInt() * eltSize).toString()
|
||||||
if(vmDt==IRDataType.FLOAT)
|
if(vmDt==IRDataType.FLOAT)
|
||||||
addInstr(result, IRInstruction(Opcode.LOADM, IRDataType.FLOAT, fpReg1=resultFpRegister, labelSymbol = "$arrayVarSymbol+$memOffset"), null, arrayIx.position)
|
addInstr(result, IRInstruction(Opcode.LOADM, IRDataType.FLOAT, fpReg1=resultFpRegister, labelSymbol = "$arrayVarSymbol+$memOffset"), null)
|
||||||
else
|
else
|
||||||
addInstr(result, IRInstruction(Opcode.LOADM, vmDt, reg1=resultRegister, labelSymbol = "$arrayVarSymbol+$memOffset"), null, arrayIx.position)
|
addInstr(result, IRInstruction(Opcode.LOADM, vmDt, reg1=resultRegister, labelSymbol = "$arrayVarSymbol+$memOffset"), null)
|
||||||
} else {
|
} else {
|
||||||
result += translateExpression(arrayIx.index, idxReg, -1)
|
result += translateExpression(arrayIx.index, idxReg, -1)
|
||||||
if(eltSize>1)
|
if(eltSize>1)
|
||||||
result += codeGen.multiplyByConst(IRDataType.BYTE, idxReg, eltSize, arrayIx.position)
|
result += codeGen.multiplyByConst(IRDataType.BYTE, idxReg, eltSize)
|
||||||
if(vmDt==IRDataType.FLOAT)
|
if(vmDt==IRDataType.FLOAT)
|
||||||
addInstr(result, IRInstruction(Opcode.LOADX, IRDataType.FLOAT, fpReg1 = resultFpRegister, reg1=idxReg, labelSymbol = arrayVarSymbol), null, arrayIx.position)
|
addInstr(result, IRInstruction(Opcode.LOADX, IRDataType.FLOAT, fpReg1 = resultFpRegister, reg1=idxReg, labelSymbol = arrayVarSymbol), null)
|
||||||
else
|
else
|
||||||
addInstr(result, IRInstruction(Opcode.LOADX, vmDt, reg1=resultRegister, reg2=idxReg, labelSymbol = arrayVarSymbol), null, arrayIx.position)
|
addInstr(result, IRInstruction(Opcode.LOADX, vmDt, reg1=resultRegister, reg2=idxReg, labelSymbol = arrayVarSymbol), null)
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
@ -170,13 +170,13 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
"+" -> { }
|
"+" -> { }
|
||||||
"-" -> {
|
"-" -> {
|
||||||
if(vmDt==IRDataType.FLOAT)
|
if(vmDt==IRDataType.FLOAT)
|
||||||
addInstr(result, IRInstruction(Opcode.NEG, vmDt, fpReg1 = resultFpRegister), null, expr.position)
|
addInstr(result, IRInstruction(Opcode.NEG, vmDt, fpReg1 = resultFpRegister), null)
|
||||||
else
|
else
|
||||||
addInstr(result, IRInstruction(Opcode.NEG, vmDt, reg1 = resultRegister), null, expr.position)
|
addInstr(result, IRInstruction(Opcode.NEG, vmDt, reg1 = resultRegister), null)
|
||||||
}
|
}
|
||||||
"~" -> {
|
"~" -> {
|
||||||
val mask = if(vmDt==IRDataType.BYTE) 0x00ff else 0xffff
|
val mask = if(vmDt==IRDataType.BYTE) 0x00ff else 0xffff
|
||||||
addInstr(result, IRInstruction(Opcode.XOR, vmDt, reg1 = resultRegister, value = mask), null, expr.position)
|
addInstr(result, IRInstruction(Opcode.XOR, vmDt, reg1 = resultRegister, value = mask), null)
|
||||||
}
|
}
|
||||||
else -> throw AssemblyError("weird prefix operator")
|
else -> throw AssemblyError("weird prefix operator")
|
||||||
}
|
}
|
||||||
@ -199,14 +199,14 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
DataType.UBYTE -> {
|
DataType.UBYTE -> {
|
||||||
when(cast.value.type) {
|
when(cast.value.type) {
|
||||||
DataType.BYTE, DataType.UWORD, DataType.WORD -> { /* just keep the LSB as it is */ }
|
DataType.BYTE, DataType.UWORD, DataType.WORD -> { /* just keep the LSB as it is */ }
|
||||||
DataType.FLOAT -> addInstr(result, IRInstruction(Opcode.FTOUB, IRDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg), null, cast.position)
|
DataType.FLOAT -> addInstr(result, IRInstruction(Opcode.FTOUB, IRDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg), null)
|
||||||
else -> throw AssemblyError("weird cast value type")
|
else -> throw AssemblyError("weird cast value type")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DataType.BYTE -> {
|
DataType.BYTE -> {
|
||||||
when(cast.value.type) {
|
when(cast.value.type) {
|
||||||
DataType.UBYTE, DataType.UWORD, DataType.WORD -> { /* just keep the LSB as it is */ }
|
DataType.UBYTE, DataType.UWORD, DataType.WORD -> { /* just keep the LSB as it is */ }
|
||||||
DataType.FLOAT -> addInstr(result, IRInstruction(Opcode.FTOSB, IRDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg), null, cast.position)
|
DataType.FLOAT -> addInstr(result, IRInstruction(Opcode.FTOSB, IRDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg), null)
|
||||||
else -> throw AssemblyError("weird cast value type")
|
else -> throw AssemblyError("weird cast value type")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -214,15 +214,15 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
when(cast.value.type) {
|
when(cast.value.type) {
|
||||||
DataType.BYTE -> {
|
DataType.BYTE -> {
|
||||||
// byte -> uword: sign extend
|
// byte -> uword: sign extend
|
||||||
addInstr(result, IRInstruction(Opcode.EXTS, type = IRDataType.BYTE, reg1 = actualResultReg), null, cast.position)
|
addInstr(result, IRInstruction(Opcode.EXTS, type = IRDataType.BYTE, reg1 = actualResultReg), null)
|
||||||
}
|
}
|
||||||
DataType.UBYTE -> {
|
DataType.UBYTE -> {
|
||||||
// ubyte -> uword: sign extend
|
// ubyte -> uword: sign extend
|
||||||
addInstr(result, IRInstruction(Opcode.EXT, type = IRDataType.BYTE, reg1 = actualResultReg), null, cast.position)
|
addInstr(result, IRInstruction(Opcode.EXT, type = IRDataType.BYTE, reg1 = actualResultReg), null)
|
||||||
}
|
}
|
||||||
DataType.WORD -> { }
|
DataType.WORD -> { }
|
||||||
DataType.FLOAT -> {
|
DataType.FLOAT -> {
|
||||||
addInstr(result, IRInstruction(Opcode.FTOUW, IRDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg), null, cast.position)
|
addInstr(result, IRInstruction(Opcode.FTOUW, IRDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg), null)
|
||||||
}
|
}
|
||||||
else -> throw AssemblyError("weird cast value type")
|
else -> throw AssemblyError("weird cast value type")
|
||||||
}
|
}
|
||||||
@ -231,15 +231,15 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
when(cast.value.type) {
|
when(cast.value.type) {
|
||||||
DataType.BYTE -> {
|
DataType.BYTE -> {
|
||||||
// byte -> word: sign extend
|
// byte -> word: sign extend
|
||||||
addInstr(result, IRInstruction(Opcode.EXTS, type = IRDataType.BYTE, reg1 = actualResultReg), null, cast.position)
|
addInstr(result, IRInstruction(Opcode.EXTS, type = IRDataType.BYTE, reg1 = actualResultReg), null)
|
||||||
}
|
}
|
||||||
DataType.UBYTE -> {
|
DataType.UBYTE -> {
|
||||||
// byte -> word: sign extend
|
// byte -> word: sign extend
|
||||||
addInstr(result, IRInstruction(Opcode.EXT, type = IRDataType.BYTE, reg1 = actualResultReg), null, cast.position)
|
addInstr(result, IRInstruction(Opcode.EXT, type = IRDataType.BYTE, reg1 = actualResultReg), null)
|
||||||
}
|
}
|
||||||
DataType.UWORD -> { }
|
DataType.UWORD -> { }
|
||||||
DataType.FLOAT -> {
|
DataType.FLOAT -> {
|
||||||
addInstr(result, IRInstruction(Opcode.FTOSW, IRDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg), null, cast.position)
|
addInstr(result, IRInstruction(Opcode.FTOSW, IRDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg), null)
|
||||||
}
|
}
|
||||||
else -> throw AssemblyError("weird cast value type")
|
else -> throw AssemblyError("weird cast value type")
|
||||||
}
|
}
|
||||||
@ -252,7 +252,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
DataType.WORD -> IRInstruction(Opcode.FFROMSW, IRDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg)
|
DataType.WORD -> IRInstruction(Opcode.FFROMSW, IRDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg)
|
||||||
else -> throw AssemblyError("weird cast value type")
|
else -> throw AssemblyError("weird cast value type")
|
||||||
}
|
}
|
||||||
addInstr(result, instr, null, cast.position)
|
addInstr(result, instr, null)
|
||||||
}
|
}
|
||||||
else -> throw AssemblyError("weird cast type")
|
else -> throw AssemblyError("weird cast type")
|
||||||
}
|
}
|
||||||
@ -297,14 +297,14 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
val zeroRegister = codeGen.registers.nextFree()
|
val zeroRegister = codeGen.registers.nextFree()
|
||||||
result += translateExpression(binExpr.left, -1, leftFpReg)
|
result += translateExpression(binExpr.left, -1, leftFpReg)
|
||||||
result += translateExpression(binExpr.right, -1, rightFpReg)
|
result += translateExpression(binExpr.right, -1, rightFpReg)
|
||||||
addInstr(result, IRInstruction(Opcode.FCOMP, IRDataType.FLOAT, reg1=resultRegister, fpReg1 = leftFpReg, fpReg2 = rightFpReg), null, binExpr.position)
|
addInstr(result, IRInstruction(Opcode.FCOMP, IRDataType.FLOAT, reg1=resultRegister, fpReg1 = leftFpReg, fpReg2 = rightFpReg), null)
|
||||||
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=zeroRegister, value=0), null, binExpr.position)
|
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=zeroRegister, value=0), null)
|
||||||
val ins = if (signed) {
|
val ins = if (signed) {
|
||||||
if (greaterEquals) Opcode.SGES else Opcode.SGTS
|
if (greaterEquals) Opcode.SGES else Opcode.SGTS
|
||||||
} else {
|
} else {
|
||||||
if (greaterEquals) Opcode.SGE else Opcode.SGT
|
if (greaterEquals) Opcode.SGE else Opcode.SGT
|
||||||
}
|
}
|
||||||
addInstr(result, IRInstruction(ins, IRDataType.BYTE, reg1 = resultRegister, reg2 = zeroRegister), null, binExpr.position)
|
addInstr(result, IRInstruction(ins, IRDataType.BYTE, reg1 = resultRegister, reg2 = zeroRegister), null)
|
||||||
} else {
|
} else {
|
||||||
if(binExpr.left.type==DataType.STR && binExpr.right.type==DataType.STR) {
|
if(binExpr.left.type==DataType.STR && binExpr.right.type==DataType.STR) {
|
||||||
val comparisonCall = PtFunctionCall(listOf("prog8_lib", "string_compare"), false, DataType.BYTE, Position.DUMMY)
|
val comparisonCall = PtFunctionCall(listOf("prog8_lib", "string_compare"), false, DataType.BYTE, Position.DUMMY)
|
||||||
@ -312,12 +312,12 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
comparisonCall.children.add(binExpr.right)
|
comparisonCall.children.add(binExpr.right)
|
||||||
result += translate(comparisonCall, resultRegister, -1)
|
result += translate(comparisonCall, resultRegister, -1)
|
||||||
val zeroRegister = codeGen.registers.nextFree()
|
val zeroRegister = codeGen.registers.nextFree()
|
||||||
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=zeroRegister, value=0), null, binExpr.position)
|
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=zeroRegister, value=0), null)
|
||||||
val instr = if(greaterEquals)
|
val instr = if(greaterEquals)
|
||||||
IRInstruction(Opcode.SGES, IRDataType.BYTE, reg1=resultRegister, reg2=zeroRegister)
|
IRInstruction(Opcode.SGES, IRDataType.BYTE, reg1=resultRegister, reg2=zeroRegister)
|
||||||
else
|
else
|
||||||
IRInstruction(Opcode.SGTS, IRDataType.BYTE, reg1=resultRegister, reg2=zeroRegister)
|
IRInstruction(Opcode.SGTS, IRDataType.BYTE, reg1=resultRegister, reg2=zeroRegister)
|
||||||
addInstr(result, instr, null, binExpr.position)
|
addInstr(result, instr, null)
|
||||||
} else {
|
} else {
|
||||||
val rightResultReg = codeGen.registers.nextFree()
|
val rightResultReg = codeGen.registers.nextFree()
|
||||||
result += translateExpression(binExpr.left, resultRegister, -1)
|
result += translateExpression(binExpr.left, resultRegister, -1)
|
||||||
@ -327,7 +327,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
} else {
|
} else {
|
||||||
if (greaterEquals) Opcode.SGE else Opcode.SGT
|
if (greaterEquals) Opcode.SGE else Opcode.SGT
|
||||||
}
|
}
|
||||||
addInstr(result, IRInstruction(ins, vmDt, reg1 = resultRegister, reg2 = rightResultReg), null, binExpr.position)
|
addInstr(result, IRInstruction(ins, vmDt, reg1 = resultRegister, reg2 = rightResultReg), null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
@ -347,14 +347,14 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
val zeroRegister = codeGen.registers.nextFree()
|
val zeroRegister = codeGen.registers.nextFree()
|
||||||
result += translateExpression(binExpr.left, -1, leftFpReg)
|
result += translateExpression(binExpr.left, -1, leftFpReg)
|
||||||
result += translateExpression(binExpr.right, -1, rightFpReg)
|
result += translateExpression(binExpr.right, -1, rightFpReg)
|
||||||
addInstr(result, IRInstruction(Opcode.FCOMP, IRDataType.FLOAT, reg1=resultRegister, fpReg1 = leftFpReg, fpReg2 = rightFpReg), null, binExpr.position)
|
addInstr(result, IRInstruction(Opcode.FCOMP, IRDataType.FLOAT, reg1=resultRegister, fpReg1 = leftFpReg, fpReg2 = rightFpReg), null)
|
||||||
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=zeroRegister, value=0), null, binExpr.position)
|
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=zeroRegister, value=0), null)
|
||||||
val ins = if (signed) {
|
val ins = if (signed) {
|
||||||
if (lessEquals) Opcode.SLES else Opcode.SLTS
|
if (lessEquals) Opcode.SLES else Opcode.SLTS
|
||||||
} else {
|
} else {
|
||||||
if (lessEquals) Opcode.SLE else Opcode.SLT
|
if (lessEquals) Opcode.SLE else Opcode.SLT
|
||||||
}
|
}
|
||||||
addInstr(result, IRInstruction(ins, IRDataType.BYTE, reg1 = resultRegister, reg2 = zeroRegister), null, binExpr.position)
|
addInstr(result, IRInstruction(ins, IRDataType.BYTE, reg1 = resultRegister, reg2 = zeroRegister), null)
|
||||||
} else {
|
} else {
|
||||||
if(binExpr.left.type==DataType.STR && binExpr.right.type==DataType.STR) {
|
if(binExpr.left.type==DataType.STR && binExpr.right.type==DataType.STR) {
|
||||||
val comparisonCall = PtFunctionCall(listOf("prog8_lib", "string_compare"), false, DataType.BYTE, Position.DUMMY)
|
val comparisonCall = PtFunctionCall(listOf("prog8_lib", "string_compare"), false, DataType.BYTE, Position.DUMMY)
|
||||||
@ -362,12 +362,12 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
comparisonCall.children.add(binExpr.right)
|
comparisonCall.children.add(binExpr.right)
|
||||||
result += translate(comparisonCall, resultRegister, -1)
|
result += translate(comparisonCall, resultRegister, -1)
|
||||||
val zeroRegister = codeGen.registers.nextFree()
|
val zeroRegister = codeGen.registers.nextFree()
|
||||||
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=zeroRegister, value=0), null, binExpr.position)
|
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=zeroRegister, value=0), null)
|
||||||
val ins = if(lessEquals)
|
val ins = if(lessEquals)
|
||||||
IRInstruction(Opcode.SLES, IRDataType.BYTE, reg1=resultRegister, reg2=zeroRegister)
|
IRInstruction(Opcode.SLES, IRDataType.BYTE, reg1=resultRegister, reg2=zeroRegister)
|
||||||
else
|
else
|
||||||
IRInstruction(Opcode.SLTS, IRDataType.BYTE, reg1=resultRegister, reg2=zeroRegister)
|
IRInstruction(Opcode.SLTS, IRDataType.BYTE, reg1=resultRegister, reg2=zeroRegister)
|
||||||
addInstr(result, ins, null, binExpr.position)
|
addInstr(result, ins, null)
|
||||||
} else {
|
} else {
|
||||||
val rightResultReg = codeGen.registers.nextFree()
|
val rightResultReg = codeGen.registers.nextFree()
|
||||||
result += translateExpression(binExpr.left, resultRegister, -1)
|
result += translateExpression(binExpr.left, resultRegister, -1)
|
||||||
@ -377,7 +377,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
} else {
|
} else {
|
||||||
if (lessEquals) Opcode.SLE else Opcode.SLT
|
if (lessEquals) Opcode.SLE else Opcode.SLT
|
||||||
}
|
}
|
||||||
addInstr(result, IRInstruction(ins, vmDt, reg1 = resultRegister, reg2 = rightResultReg), null, binExpr.position)
|
addInstr(result, IRInstruction(ins, vmDt, reg1 = resultRegister, reg2 = rightResultReg), null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
@ -391,15 +391,15 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
result += translateExpression(binExpr.left, -1, leftFpReg)
|
result += translateExpression(binExpr.left, -1, leftFpReg)
|
||||||
result += translateExpression(binExpr.right, -1, rightFpReg)
|
result += translateExpression(binExpr.right, -1, rightFpReg)
|
||||||
if (notEquals) {
|
if (notEquals) {
|
||||||
addInstr(result, IRInstruction(Opcode.FCOMP, IRDataType.FLOAT, reg1=resultRegister, fpReg1 = leftFpReg, fpReg2 = rightFpReg), null, binExpr.position)
|
addInstr(result, IRInstruction(Opcode.FCOMP, IRDataType.FLOAT, reg1=resultRegister, fpReg1 = leftFpReg, fpReg2 = rightFpReg), null)
|
||||||
} else {
|
} else {
|
||||||
val label = codeGen.createLabelName()
|
val label = codeGen.createLabelName()
|
||||||
val valueReg = codeGen.registers.nextFree()
|
val valueReg = codeGen.registers.nextFree()
|
||||||
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=resultRegister, value=1), null, binExpr.position)
|
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=resultRegister, value=1), null)
|
||||||
addInstr(result, IRInstruction(Opcode.FCOMP, IRDataType.FLOAT, reg1=valueReg, fpReg1 = leftFpReg, fpReg2 = rightFpReg), null, binExpr.position)
|
addInstr(result, IRInstruction(Opcode.FCOMP, IRDataType.FLOAT, reg1=valueReg, fpReg1 = leftFpReg, fpReg2 = rightFpReg), null)
|
||||||
addInstr(result, IRInstruction(Opcode.BZ, IRDataType.BYTE, reg1=valueReg, labelSymbol = label), null, binExpr.position)
|
addInstr(result, IRInstruction(Opcode.BZ, IRDataType.BYTE, reg1=valueReg, labelSymbol = label), null)
|
||||||
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=resultRegister, value=0), null, binExpr.position)
|
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=resultRegister, value=0), null)
|
||||||
result += IRCodeChunk(label, binExpr.position, null)
|
result += IRCodeChunk(label, null)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(binExpr.left.type==DataType.STR && binExpr.right.type==DataType.STR) {
|
if(binExpr.left.type==DataType.STR && binExpr.right.type==DataType.STR) {
|
||||||
@ -408,14 +408,14 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
comparisonCall.children.add(binExpr.right)
|
comparisonCall.children.add(binExpr.right)
|
||||||
result += translate(comparisonCall, resultRegister, -1)
|
result += translate(comparisonCall, resultRegister, -1)
|
||||||
if(!notEquals)
|
if(!notEquals)
|
||||||
addInstr(result, IRInstruction(Opcode.INV, vmDt, reg1=resultRegister), null, binExpr.position)
|
addInstr(result, IRInstruction(Opcode.INV, vmDt, reg1=resultRegister), null)
|
||||||
addInstr(result, IRInstruction(Opcode.AND, vmDt, reg1=resultRegister, value=1), null, binExpr.position)
|
addInstr(result, IRInstruction(Opcode.AND, vmDt, reg1=resultRegister, value=1), null)
|
||||||
} else {
|
} else {
|
||||||
val rightResultReg = codeGen.registers.nextFree()
|
val rightResultReg = codeGen.registers.nextFree()
|
||||||
result += translateExpression(binExpr.left, resultRegister, -1)
|
result += translateExpression(binExpr.left, resultRegister, -1)
|
||||||
result += translateExpression(binExpr.right, rightResultReg, -1)
|
result += translateExpression(binExpr.right, rightResultReg, -1)
|
||||||
val opcode = if (notEquals) Opcode.SNE else Opcode.SEQ
|
val opcode = if (notEquals) Opcode.SNE else Opcode.SEQ
|
||||||
addInstr(result, IRInstruction(opcode, vmDt, reg1 = resultRegister, reg2 = rightResultReg), null, binExpr.position)
|
addInstr(result, IRInstruction(opcode, vmDt, reg1 = resultRegister, reg2 = rightResultReg), null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
@ -426,13 +426,13 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
if(codeGen.isOne(binExpr.right)) {
|
if(codeGen.isOne(binExpr.right)) {
|
||||||
result += translateExpression(binExpr.left, resultRegister, -1)
|
result += translateExpression(binExpr.left, resultRegister, -1)
|
||||||
val opc = if (signed) Opcode.ASR else Opcode.LSR
|
val opc = if (signed) Opcode.ASR else Opcode.LSR
|
||||||
addInstr(result, IRInstruction(opc, vmDt, reg1 = resultRegister), null, binExpr.position)
|
addInstr(result, IRInstruction(opc, vmDt, reg1 = resultRegister), null)
|
||||||
} else {
|
} else {
|
||||||
val rightResultReg = codeGen.registers.nextFree()
|
val rightResultReg = codeGen.registers.nextFree()
|
||||||
result += translateExpression(binExpr.left, resultRegister, -1)
|
result += translateExpression(binExpr.left, resultRegister, -1)
|
||||||
result += translateExpression(binExpr.right, rightResultReg, -1)
|
result += translateExpression(binExpr.right, rightResultReg, -1)
|
||||||
val opc = if (signed) Opcode.ASRN else Opcode.LSRN
|
val opc = if (signed) Opcode.ASRN else Opcode.LSRN
|
||||||
addInstr(result, IRInstruction(opc, vmDt, reg1 = resultRegister, reg2 = rightResultReg), null, binExpr.position)
|
addInstr(result, IRInstruction(opc, vmDt, reg1 = resultRegister, reg2 = rightResultReg), null)
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
@ -445,7 +445,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
IRInstruction(opc, vmDt, value=knownAddress)
|
IRInstruction(opc, vmDt, value=knownAddress)
|
||||||
else
|
else
|
||||||
IRInstruction(opc, vmDt, labelSymbol = symbol)
|
IRInstruction(opc, vmDt, labelSymbol = symbol)
|
||||||
addInstr(result, ins, null, operand.position)
|
addInstr(result, ins, null)
|
||||||
} else {
|
} else {
|
||||||
val operandReg = codeGen.registers.nextFree()
|
val operandReg = codeGen.registers.nextFree()
|
||||||
result += translateExpression(operand, operandReg, -1)
|
result += translateExpression(operand, operandReg, -1)
|
||||||
@ -454,7 +454,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
IRInstruction(opc, vmDt, reg1 = operandReg, value=knownAddress)
|
IRInstruction(opc, vmDt, reg1 = operandReg, value=knownAddress)
|
||||||
else
|
else
|
||||||
IRInstruction(opc, vmDt, reg1 = operandReg, labelSymbol = symbol)
|
IRInstruction(opc, vmDt, reg1 = operandReg, labelSymbol = symbol)
|
||||||
addInstr(result, ins, null, operand.position)
|
addInstr(result, ins, null)
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
@ -463,12 +463,12 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
val result = mutableListOf<IRCodeChunkBase>()
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
if(codeGen.isOne(binExpr.right)){
|
if(codeGen.isOne(binExpr.right)){
|
||||||
result += translateExpression(binExpr.left, resultRegister, -1)
|
result += translateExpression(binExpr.left, resultRegister, -1)
|
||||||
addInstr(result, IRInstruction(Opcode.LSL, vmDt, reg1=resultRegister), null, binExpr.position)
|
addInstr(result, IRInstruction(Opcode.LSL, vmDt, reg1=resultRegister), null)
|
||||||
} else {
|
} else {
|
||||||
val rightResultReg = codeGen.registers.nextFree()
|
val rightResultReg = codeGen.registers.nextFree()
|
||||||
result += translateExpression(binExpr.left, resultRegister, -1)
|
result += translateExpression(binExpr.left, resultRegister, -1)
|
||||||
result += translateExpression(binExpr.right, rightResultReg, -1)
|
result += translateExpression(binExpr.right, rightResultReg, -1)
|
||||||
addInstr(result, IRInstruction(Opcode.LSLN, vmDt, reg1=resultRegister, rightResultReg), null, binExpr.position)
|
addInstr(result, IRInstruction(Opcode.LSLN, vmDt, reg1=resultRegister, rightResultReg), null)
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
@ -480,7 +480,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
IRInstruction(Opcode.LSLM, vmDt, value=knownAddress)
|
IRInstruction(Opcode.LSLM, vmDt, value=knownAddress)
|
||||||
else
|
else
|
||||||
IRInstruction(Opcode.LSLM, vmDt, labelSymbol = symbol)
|
IRInstruction(Opcode.LSLM, vmDt, labelSymbol = symbol)
|
||||||
, null, operand.position)
|
, null)
|
||||||
} else {
|
} else {
|
||||||
val operandReg = codeGen.registers.nextFree()
|
val operandReg = codeGen.registers.nextFree()
|
||||||
result += translateExpression(operand, operandReg, -1)
|
result += translateExpression(operand, operandReg, -1)
|
||||||
@ -488,7 +488,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
IRInstruction(Opcode.LSLNM, vmDt, reg1=operandReg, value=knownAddress)
|
IRInstruction(Opcode.LSLNM, vmDt, reg1=operandReg, value=knownAddress)
|
||||||
else
|
else
|
||||||
IRInstruction(Opcode.LSLNM, vmDt, reg1=operandReg, labelSymbol = symbol)
|
IRInstruction(Opcode.LSLNM, vmDt, reg1=operandReg, labelSymbol = symbol)
|
||||||
,null, operand.position)
|
,null)
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
@ -497,12 +497,12 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
val result = mutableListOf<IRCodeChunkBase>()
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
if(binExpr.right is PtNumber) {
|
if(binExpr.right is PtNumber) {
|
||||||
result += translateExpression(binExpr.left, resultRegister, -1)
|
result += translateExpression(binExpr.left, resultRegister, -1)
|
||||||
addInstr(result, IRInstruction(Opcode.XOR, vmDt, reg1 = resultRegister, value=(binExpr.right as PtNumber).number.toInt()), null, binExpr.position)
|
addInstr(result, IRInstruction(Opcode.XOR, vmDt, reg1 = resultRegister, value=(binExpr.right as PtNumber).number.toInt()), null)
|
||||||
} else {
|
} else {
|
||||||
val rightResultReg = codeGen.registers.nextFree()
|
val rightResultReg = codeGen.registers.nextFree()
|
||||||
result += translateExpression(binExpr.left, resultRegister, -1)
|
result += translateExpression(binExpr.left, resultRegister, -1)
|
||||||
result += translateExpression(binExpr.right, rightResultReg, -1)
|
result += translateExpression(binExpr.right, rightResultReg, -1)
|
||||||
addInstr(result, IRInstruction(Opcode.XORR, vmDt, reg1 = resultRegister, reg2 = rightResultReg), null, binExpr.position)
|
addInstr(result, IRInstruction(Opcode.XORR, vmDt, reg1 = resultRegister, reg2 = rightResultReg), null)
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
@ -515,7 +515,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
IRInstruction(Opcode.XORM, vmDt, reg1=operandReg, value = knownAddress)
|
IRInstruction(Opcode.XORM, vmDt, reg1=operandReg, value = knownAddress)
|
||||||
else
|
else
|
||||||
IRInstruction(Opcode.XORM, vmDt, reg1=operandReg, labelSymbol = symbol)
|
IRInstruction(Opcode.XORM, vmDt, reg1=operandReg, labelSymbol = symbol)
|
||||||
,null, operand.position)
|
,null)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -523,12 +523,12 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
val result = mutableListOf<IRCodeChunkBase>()
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
if(binExpr.right is PtNumber) {
|
if(binExpr.right is PtNumber) {
|
||||||
result += translateExpression(binExpr.left, resultRegister, -1)
|
result += translateExpression(binExpr.left, resultRegister, -1)
|
||||||
addInstr(result, IRInstruction(Opcode.AND, vmDt, reg1 = resultRegister, value=(binExpr.right as PtNumber).number.toInt()), null, binExpr.position)
|
addInstr(result, IRInstruction(Opcode.AND, vmDt, reg1 = resultRegister, value=(binExpr.right as PtNumber).number.toInt()), null)
|
||||||
} else {
|
} else {
|
||||||
val rightResultReg = codeGen.registers.nextFree()
|
val rightResultReg = codeGen.registers.nextFree()
|
||||||
result += translateExpression(binExpr.left, resultRegister, -1)
|
result += translateExpression(binExpr.left, resultRegister, -1)
|
||||||
result += translateExpression(binExpr.right, rightResultReg, -1)
|
result += translateExpression(binExpr.right, rightResultReg, -1)
|
||||||
addInstr(result, IRInstruction(Opcode.ANDR, vmDt, reg1 = resultRegister, reg2 = rightResultReg), null, binExpr.position)
|
addInstr(result, IRInstruction(Opcode.ANDR, vmDt, reg1 = resultRegister, reg2 = rightResultReg), null)
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
@ -541,7 +541,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
IRInstruction(Opcode.ANDM, vmDt, reg1=operandReg, value=knownAddress)
|
IRInstruction(Opcode.ANDM, vmDt, reg1=operandReg, value=knownAddress)
|
||||||
else
|
else
|
||||||
IRInstruction(Opcode.ANDM, vmDt, reg1=operandReg, labelSymbol = symbol)
|
IRInstruction(Opcode.ANDM, vmDt, reg1=operandReg, labelSymbol = symbol)
|
||||||
,null, operand.position)
|
,null)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -549,12 +549,12 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
val result = mutableListOf<IRCodeChunkBase>()
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
if(binExpr.right is PtNumber) {
|
if(binExpr.right is PtNumber) {
|
||||||
result += translateExpression(binExpr.left, resultRegister, -1)
|
result += translateExpression(binExpr.left, resultRegister, -1)
|
||||||
addInstr(result, IRInstruction(Opcode.OR, vmDt, reg1 = resultRegister, value=(binExpr.right as PtNumber).number.toInt()), null, binExpr.position)
|
addInstr(result, IRInstruction(Opcode.OR, vmDt, reg1 = resultRegister, value=(binExpr.right as PtNumber).number.toInt()), null)
|
||||||
} else {
|
} else {
|
||||||
val rightResultReg = codeGen.registers.nextFree()
|
val rightResultReg = codeGen.registers.nextFree()
|
||||||
result += translateExpression(binExpr.left, resultRegister, -1)
|
result += translateExpression(binExpr.left, resultRegister, -1)
|
||||||
result += translateExpression(binExpr.right, rightResultReg, -1)
|
result += translateExpression(binExpr.right, rightResultReg, -1)
|
||||||
addInstr(result, IRInstruction(Opcode.ORR, vmDt, reg1 = resultRegister, reg2 = rightResultReg), null, binExpr.position)
|
addInstr(result, IRInstruction(Opcode.ORR, vmDt, reg1 = resultRegister, reg2 = rightResultReg), null)
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
@ -567,7 +567,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
IRInstruction(Opcode.ORM, vmDt, reg1=operandReg, value = knownAddress)
|
IRInstruction(Opcode.ORM, vmDt, reg1=operandReg, value = knownAddress)
|
||||||
else
|
else
|
||||||
IRInstruction(Opcode.ORM, vmDt, reg1=operandReg, labelSymbol = symbol)
|
IRInstruction(Opcode.ORM, vmDt, reg1=operandReg, labelSymbol = symbol)
|
||||||
, null, operand.position)
|
, null)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -577,11 +577,11 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
val rightResultReg = codeGen.registers.nextFree()
|
val rightResultReg = codeGen.registers.nextFree()
|
||||||
if(binExpr.right is PtNumber) {
|
if(binExpr.right is PtNumber) {
|
||||||
result += translateExpression(binExpr.left, resultRegister, -1)
|
result += translateExpression(binExpr.left, resultRegister, -1)
|
||||||
addInstr(result, IRInstruction(Opcode.MOD, vmDt, reg1 = resultRegister, value=(binExpr.right as PtNumber).number.toInt()), null, binExpr.position)
|
addInstr(result, IRInstruction(Opcode.MOD, vmDt, reg1 = resultRegister, value=(binExpr.right as PtNumber).number.toInt()), null)
|
||||||
} else {
|
} else {
|
||||||
result += translateExpression(binExpr.left, resultRegister, -1)
|
result += translateExpression(binExpr.left, resultRegister, -1)
|
||||||
result += translateExpression(binExpr.right, rightResultReg, -1)
|
result += translateExpression(binExpr.right, rightResultReg, -1)
|
||||||
addInstr(result, IRInstruction(Opcode.MODR, vmDt, reg1 = resultRegister, reg2 = rightResultReg), null, binExpr.position)
|
addInstr(result, IRInstruction(Opcode.MODR, vmDt, reg1 = resultRegister, reg2 = rightResultReg), null)
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
@ -606,7 +606,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
IRInstruction(Opcode.DIVSR, vmDt, fpReg1 = resultFpRegister, fpReg2=rightResultFpReg)
|
IRInstruction(Opcode.DIVSR, vmDt, fpReg1 = resultFpRegister, fpReg2=rightResultFpReg)
|
||||||
else
|
else
|
||||||
IRInstruction(Opcode.DIVR, vmDt, fpReg1 = resultFpRegister, fpReg2=rightResultFpReg)
|
IRInstruction(Opcode.DIVR, vmDt, fpReg1 = resultFpRegister, fpReg2=rightResultFpReg)
|
||||||
, null, binExpr.position)
|
, null)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(constFactorRight!=null && constFactorRight.type!=DataType.FLOAT) {
|
if(constFactorRight!=null && constFactorRight.type!=DataType.FLOAT) {
|
||||||
@ -621,7 +621,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
IRInstruction(Opcode.DIVS, vmDt, reg1 = resultRegister, value=(binExpr.right as PtNumber).number.toInt())
|
IRInstruction(Opcode.DIVS, vmDt, reg1 = resultRegister, value=(binExpr.right as PtNumber).number.toInt())
|
||||||
else
|
else
|
||||||
IRInstruction(Opcode.DIV, vmDt, reg1 = resultRegister, value=(binExpr.right as PtNumber).number.toInt())
|
IRInstruction(Opcode.DIV, vmDt, reg1 = resultRegister, value=(binExpr.right as PtNumber).number.toInt())
|
||||||
, null, binExpr.position)
|
, null)
|
||||||
} else {
|
} else {
|
||||||
result += translateExpression(binExpr.left, resultRegister, -1)
|
result += translateExpression(binExpr.left, resultRegister, -1)
|
||||||
result += translateExpression(binExpr.right, rightResultReg, -1)
|
result += translateExpression(binExpr.right, rightResultReg, -1)
|
||||||
@ -629,7 +629,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
IRInstruction(Opcode.DIVSR, vmDt, reg1 = resultRegister, reg2 = rightResultReg)
|
IRInstruction(Opcode.DIVSR, vmDt, reg1 = resultRegister, reg2 = rightResultReg)
|
||||||
else
|
else
|
||||||
IRInstruction(Opcode.DIVR, vmDt, reg1 = resultRegister, reg2 = rightResultReg)
|
IRInstruction(Opcode.DIVR, vmDt, reg1 = resultRegister, reg2 = rightResultReg)
|
||||||
, null, binExpr.position)
|
, null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -658,7 +658,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
else
|
else
|
||||||
IRInstruction(Opcode.DIVM, vmDt, fpReg1 = operandFpReg, labelSymbol = symbol)
|
IRInstruction(Opcode.DIVM, vmDt, fpReg1 = operandFpReg, labelSymbol = symbol)
|
||||||
}
|
}
|
||||||
addInstr(result, ins, null, operand.position)
|
addInstr(result, ins, null)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(constFactorRight!=null && constFactorRight.type!=DataType.FLOAT) {
|
if(constFactorRight!=null && constFactorRight.type!=DataType.FLOAT) {
|
||||||
@ -679,7 +679,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
else
|
else
|
||||||
IRInstruction(Opcode.DIVM, vmDt, reg1 = operandReg, labelSymbol = symbol)
|
IRInstruction(Opcode.DIVM, vmDt, reg1 = operandReg, labelSymbol = symbol)
|
||||||
}
|
}
|
||||||
addInstr(result, ins, null, operand.position)
|
addInstr(result, ins, null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
@ -693,31 +693,31 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
if(constFactorLeft!=null) {
|
if(constFactorLeft!=null) {
|
||||||
result += translateExpression(binExpr.right, -1, resultFpRegister)
|
result += translateExpression(binExpr.right, -1, resultFpRegister)
|
||||||
val factor = constFactorLeft.number.toFloat()
|
val factor = constFactorLeft.number.toFloat()
|
||||||
result += codeGen.multiplyByConstFloat(resultFpRegister, factor, constFactorLeft.position)
|
result += codeGen.multiplyByConstFloat(resultFpRegister, factor)
|
||||||
} else if(constFactorRight!=null) {
|
} else if(constFactorRight!=null) {
|
||||||
result += translateExpression(binExpr.left, -1, resultFpRegister)
|
result += translateExpression(binExpr.left, -1, resultFpRegister)
|
||||||
val factor = constFactorRight.number.toFloat()
|
val factor = constFactorRight.number.toFloat()
|
||||||
result += codeGen.multiplyByConstFloat(resultFpRegister, factor, constFactorRight.position)
|
result += codeGen.multiplyByConstFloat(resultFpRegister, factor)
|
||||||
} else {
|
} else {
|
||||||
val rightResultFpReg = codeGen.registers.nextFreeFloat()
|
val rightResultFpReg = codeGen.registers.nextFreeFloat()
|
||||||
result += translateExpression(binExpr.left, -1, resultFpRegister)
|
result += translateExpression(binExpr.left, -1, resultFpRegister)
|
||||||
result += translateExpression(binExpr.right, -1, rightResultFpReg)
|
result += translateExpression(binExpr.right, -1, rightResultFpReg)
|
||||||
addInstr(result, IRInstruction(Opcode.MULR, vmDt, fpReg1 = resultFpRegister, fpReg2 = rightResultFpReg), null, binExpr.position)
|
addInstr(result, IRInstruction(Opcode.MULR, vmDt, fpReg1 = resultFpRegister, fpReg2 = rightResultFpReg), null)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(constFactorLeft!=null && constFactorLeft.type!=DataType.FLOAT) {
|
if(constFactorLeft!=null && constFactorLeft.type!=DataType.FLOAT) {
|
||||||
result += translateExpression(binExpr.right, resultRegister, -1)
|
result += translateExpression(binExpr.right, resultRegister, -1)
|
||||||
val factor = constFactorLeft.number.toInt()
|
val factor = constFactorLeft.number.toInt()
|
||||||
result += codeGen.multiplyByConst(vmDt, resultRegister, factor, constFactorLeft.position)
|
result += codeGen.multiplyByConst(vmDt, resultRegister, factor)
|
||||||
} else if(constFactorRight!=null && constFactorRight.type!=DataType.FLOAT) {
|
} else if(constFactorRight!=null && constFactorRight.type!=DataType.FLOAT) {
|
||||||
result += translateExpression(binExpr.left, resultRegister, -1)
|
result += translateExpression(binExpr.left, resultRegister, -1)
|
||||||
val factor = constFactorRight.number.toInt()
|
val factor = constFactorRight.number.toInt()
|
||||||
result += codeGen.multiplyByConst(vmDt, resultRegister, factor, constFactorRight.position)
|
result += codeGen.multiplyByConst(vmDt, resultRegister, factor)
|
||||||
} else {
|
} else {
|
||||||
val rightResultReg = codeGen.registers.nextFree()
|
val rightResultReg = codeGen.registers.nextFree()
|
||||||
result += translateExpression(binExpr.left, resultRegister, -1)
|
result += translateExpression(binExpr.left, resultRegister, -1)
|
||||||
result += translateExpression(binExpr.right, rightResultReg, -1)
|
result += translateExpression(binExpr.right, rightResultReg, -1)
|
||||||
addInstr(result, IRInstruction(Opcode.MULR, vmDt, reg1 = resultRegister, reg2 = rightResultReg), null, binExpr.position)
|
addInstr(result, IRInstruction(Opcode.MULR, vmDt, reg1 = resultRegister, reg2 = rightResultReg), null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
@ -729,7 +729,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
if(vmDt==IRDataType.FLOAT) {
|
if(vmDt==IRDataType.FLOAT) {
|
||||||
if(constFactorRight!=null) {
|
if(constFactorRight!=null) {
|
||||||
val factor = constFactorRight.number.toFloat()
|
val factor = constFactorRight.number.toFloat()
|
||||||
result += codeGen.multiplyByConstFloatInplace(knownAddress, symbol, factor, constFactorRight.position)
|
result += codeGen.multiplyByConstFloatInplace(knownAddress, symbol, factor)
|
||||||
} else {
|
} else {
|
||||||
val operandFpReg = codeGen.registers.nextFreeFloat()
|
val operandFpReg = codeGen.registers.nextFreeFloat()
|
||||||
result += translateExpression(operand, -1, operandFpReg)
|
result += translateExpression(operand, -1, operandFpReg)
|
||||||
@ -737,7 +737,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
IRInstruction(Opcode.MULM, vmDt, fpReg1 = operandFpReg, value = knownAddress)
|
IRInstruction(Opcode.MULM, vmDt, fpReg1 = operandFpReg, value = knownAddress)
|
||||||
else
|
else
|
||||||
IRInstruction(Opcode.MULM, vmDt, fpReg1 = operandFpReg, labelSymbol = symbol)
|
IRInstruction(Opcode.MULM, vmDt, fpReg1 = operandFpReg, labelSymbol = symbol)
|
||||||
, null, operand.position)
|
, null)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(constFactorRight!=null && constFactorRight.type!=DataType.FLOAT) {
|
if(constFactorRight!=null && constFactorRight.type!=DataType.FLOAT) {
|
||||||
@ -750,7 +750,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
IRInstruction(Opcode.MULM, vmDt, reg1=operandReg, value = knownAddress)
|
IRInstruction(Opcode.MULM, vmDt, reg1=operandReg, value = knownAddress)
|
||||||
else
|
else
|
||||||
IRInstruction(Opcode.MULM, vmDt, reg1=operandReg, labelSymbol = symbol)
|
IRInstruction(Opcode.MULM, vmDt, reg1=operandReg, labelSymbol = symbol)
|
||||||
, null, operand.position)
|
, null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
@ -761,33 +761,33 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
if(vmDt==IRDataType.FLOAT) {
|
if(vmDt==IRDataType.FLOAT) {
|
||||||
if((binExpr.right as? PtNumber)?.number==1.0) {
|
if((binExpr.right as? PtNumber)?.number==1.0) {
|
||||||
result += translateExpression(binExpr.left, -1, resultFpRegister)
|
result += translateExpression(binExpr.left, -1, resultFpRegister)
|
||||||
addInstr(result, IRInstruction(Opcode.DEC, vmDt, fpReg1 = resultFpRegister), null, binExpr.position)
|
addInstr(result, IRInstruction(Opcode.DEC, vmDt, fpReg1 = resultFpRegister), null)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(binExpr.right is PtNumber) {
|
if(binExpr.right is PtNumber) {
|
||||||
result += translateExpression(binExpr.left, -1, resultFpRegister)
|
result += translateExpression(binExpr.left, -1, resultFpRegister)
|
||||||
addInstr(result, IRInstruction(Opcode.SUB, vmDt, fpReg1 = resultFpRegister, fpValue = (binExpr.right as PtNumber).number.toFloat()), null, binExpr.position)
|
addInstr(result, IRInstruction(Opcode.SUB, vmDt, fpReg1 = resultFpRegister, fpValue = (binExpr.right as PtNumber).number.toFloat()), null)
|
||||||
} else {
|
} else {
|
||||||
val rightResultFpReg = codeGen.registers.nextFreeFloat()
|
val rightResultFpReg = codeGen.registers.nextFreeFloat()
|
||||||
result += translateExpression(binExpr.left, -1, resultFpRegister)
|
result += translateExpression(binExpr.left, -1, resultFpRegister)
|
||||||
result += translateExpression(binExpr.right, -1, rightResultFpReg)
|
result += translateExpression(binExpr.right, -1, rightResultFpReg)
|
||||||
addInstr(result, IRInstruction(Opcode.SUBR, vmDt, fpReg1 = resultFpRegister, fpReg2 = rightResultFpReg), null, binExpr.position)
|
addInstr(result, IRInstruction(Opcode.SUBR, vmDt, fpReg1 = resultFpRegister, fpReg2 = rightResultFpReg), null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if((binExpr.right as? PtNumber)?.number==1.0) {
|
if((binExpr.right as? PtNumber)?.number==1.0) {
|
||||||
result += translateExpression(binExpr.left, resultRegister, -1)
|
result += translateExpression(binExpr.left, resultRegister, -1)
|
||||||
addInstr(result, IRInstruction(Opcode.DEC, vmDt, reg1=resultRegister), null, binExpr.position)
|
addInstr(result, IRInstruction(Opcode.DEC, vmDt, reg1=resultRegister), null)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(binExpr.right is PtNumber) {
|
if(binExpr.right is PtNumber) {
|
||||||
result += translateExpression(binExpr.left, resultRegister, -1)
|
result += translateExpression(binExpr.left, resultRegister, -1)
|
||||||
addInstr(result, IRInstruction(Opcode.SUB, vmDt, reg1 = resultRegister, value = (binExpr.right as PtNumber).number.toInt()), null, binExpr.position)
|
addInstr(result, IRInstruction(Opcode.SUB, vmDt, reg1 = resultRegister, value = (binExpr.right as PtNumber).number.toInt()), null)
|
||||||
} else {
|
} else {
|
||||||
val rightResultReg = codeGen.registers.nextFree()
|
val rightResultReg = codeGen.registers.nextFree()
|
||||||
result += translateExpression(binExpr.left, resultRegister, -1)
|
result += translateExpression(binExpr.left, resultRegister, -1)
|
||||||
result += translateExpression(binExpr.right, rightResultReg, -1)
|
result += translateExpression(binExpr.right, rightResultReg, -1)
|
||||||
addInstr(result, IRInstruction(Opcode.SUBR, vmDt, reg1 = resultRegister, reg2 = rightResultReg), null, binExpr.position)
|
addInstr(result, IRInstruction(Opcode.SUBR, vmDt, reg1 = resultRegister, reg2 = rightResultReg), null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -802,7 +802,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
IRInstruction(Opcode.DECM, vmDt, value=knownAddress)
|
IRInstruction(Opcode.DECM, vmDt, value=knownAddress)
|
||||||
else
|
else
|
||||||
IRInstruction(Opcode.DECM, vmDt, labelSymbol = symbol)
|
IRInstruction(Opcode.DECM, vmDt, labelSymbol = symbol)
|
||||||
, null, operand.position)
|
, null)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
val operandFpReg = codeGen.registers.nextFreeFloat()
|
val operandFpReg = codeGen.registers.nextFreeFloat()
|
||||||
@ -811,7 +811,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
IRInstruction(Opcode.SUBM, vmDt, fpReg1=operandFpReg, value=knownAddress)
|
IRInstruction(Opcode.SUBM, vmDt, fpReg1=operandFpReg, value=knownAddress)
|
||||||
else
|
else
|
||||||
IRInstruction(Opcode.SUBM, vmDt, fpReg1=operandFpReg, labelSymbol = symbol)
|
IRInstruction(Opcode.SUBM, vmDt, fpReg1=operandFpReg, labelSymbol = symbol)
|
||||||
, null, operand.position)
|
, null)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if((operand as? PtNumber)?.number==1.0) {
|
if((operand as? PtNumber)?.number==1.0) {
|
||||||
@ -819,7 +819,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
IRInstruction(Opcode.DECM, vmDt, value=knownAddress)
|
IRInstruction(Opcode.DECM, vmDt, value=knownAddress)
|
||||||
else
|
else
|
||||||
IRInstruction(Opcode.DECM, vmDt, labelSymbol = symbol)
|
IRInstruction(Opcode.DECM, vmDt, labelSymbol = symbol)
|
||||||
, null, operand.position)
|
, null)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
val operandReg = codeGen.registers.nextFree()
|
val operandReg = codeGen.registers.nextFree()
|
||||||
@ -828,7 +828,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
IRInstruction(Opcode.SUBM, vmDt, reg1=operandReg, value = knownAddress)
|
IRInstruction(Opcode.SUBM, vmDt, reg1=operandReg, value = knownAddress)
|
||||||
else
|
else
|
||||||
IRInstruction(Opcode.SUBM, vmDt, reg1=operandReg, labelSymbol = symbol)
|
IRInstruction(Opcode.SUBM, vmDt, reg1=operandReg, labelSymbol = symbol)
|
||||||
, null, operand.position)
|
, null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
@ -839,41 +839,41 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
if(vmDt==IRDataType.FLOAT) {
|
if(vmDt==IRDataType.FLOAT) {
|
||||||
if((binExpr.left as? PtNumber)?.number==1.0) {
|
if((binExpr.left as? PtNumber)?.number==1.0) {
|
||||||
result += translateExpression(binExpr.right, -1, resultFpRegister)
|
result += translateExpression(binExpr.right, -1, resultFpRegister)
|
||||||
addInstr(result, IRInstruction(Opcode.INC, vmDt, fpReg1=resultFpRegister), null, binExpr.position)
|
addInstr(result, IRInstruction(Opcode.INC, vmDt, fpReg1=resultFpRegister), null)
|
||||||
}
|
}
|
||||||
else if((binExpr.right as? PtNumber)?.number==1.0) {
|
else if((binExpr.right as? PtNumber)?.number==1.0) {
|
||||||
result += translateExpression(binExpr.left, -1, resultFpRegister)
|
result += translateExpression(binExpr.left, -1, resultFpRegister)
|
||||||
addInstr(result, IRInstruction(Opcode.INC, vmDt, fpReg1=resultFpRegister), null, binExpr.position)
|
addInstr(result, IRInstruction(Opcode.INC, vmDt, fpReg1=resultFpRegister), null)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(binExpr.right is PtNumber) {
|
if(binExpr.right is PtNumber) {
|
||||||
result += translateExpression(binExpr.left, -1, resultFpRegister)
|
result += translateExpression(binExpr.left, -1, resultFpRegister)
|
||||||
addInstr(result, IRInstruction(Opcode.ADD, vmDt, fpReg1 = resultFpRegister, fpValue = (binExpr.right as PtNumber).number.toFloat()), null, binExpr.position)
|
addInstr(result, IRInstruction(Opcode.ADD, vmDt, fpReg1 = resultFpRegister, fpValue = (binExpr.right as PtNumber).number.toFloat()), null)
|
||||||
} else {
|
} else {
|
||||||
val rightResultFpReg = codeGen.registers.nextFreeFloat()
|
val rightResultFpReg = codeGen.registers.nextFreeFloat()
|
||||||
result += translateExpression(binExpr.left, -1, resultFpRegister)
|
result += translateExpression(binExpr.left, -1, resultFpRegister)
|
||||||
result += translateExpression(binExpr.right, -1, rightResultFpReg)
|
result += translateExpression(binExpr.right, -1, rightResultFpReg)
|
||||||
addInstr(result, IRInstruction(Opcode.ADDR, vmDt, fpReg1 = resultFpRegister, fpReg2 = rightResultFpReg), null, binExpr.position)
|
addInstr(result, IRInstruction(Opcode.ADDR, vmDt, fpReg1 = resultFpRegister, fpReg2 = rightResultFpReg), null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if((binExpr.left as? PtNumber)?.number==1.0) {
|
if((binExpr.left as? PtNumber)?.number==1.0) {
|
||||||
result += translateExpression(binExpr.right, resultRegister, -1)
|
result += translateExpression(binExpr.right, resultRegister, -1)
|
||||||
addInstr(result, IRInstruction(Opcode.INC, vmDt, reg1=resultRegister), null, binExpr.position)
|
addInstr(result, IRInstruction(Opcode.INC, vmDt, reg1=resultRegister), null)
|
||||||
}
|
}
|
||||||
else if((binExpr.right as? PtNumber)?.number==1.0) {
|
else if((binExpr.right as? PtNumber)?.number==1.0) {
|
||||||
result += translateExpression(binExpr.left, resultRegister, -1)
|
result += translateExpression(binExpr.left, resultRegister, -1)
|
||||||
addInstr(result, IRInstruction(Opcode.INC, vmDt, reg1=resultRegister), null, binExpr.position)
|
addInstr(result, IRInstruction(Opcode.INC, vmDt, reg1=resultRegister), null)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(binExpr.right is PtNumber) {
|
if(binExpr.right is PtNumber) {
|
||||||
result += translateExpression(binExpr.left, resultRegister, -1)
|
result += translateExpression(binExpr.left, resultRegister, -1)
|
||||||
addInstr(result, IRInstruction(Opcode.ADD, vmDt, reg1 = resultRegister, value=(binExpr.right as PtNumber).number.toInt()), null, binExpr.position)
|
addInstr(result, IRInstruction(Opcode.ADD, vmDt, reg1 = resultRegister, value=(binExpr.right as PtNumber).number.toInt()), null)
|
||||||
} else {
|
} else {
|
||||||
val rightResultReg = codeGen.registers.nextFree()
|
val rightResultReg = codeGen.registers.nextFree()
|
||||||
result += translateExpression(binExpr.left, resultRegister, -1)
|
result += translateExpression(binExpr.left, resultRegister, -1)
|
||||||
result += translateExpression(binExpr.right, rightResultReg, -1)
|
result += translateExpression(binExpr.right, rightResultReg, -1)
|
||||||
addInstr(result, IRInstruction(Opcode.ADDR, vmDt, reg1 = resultRegister, reg2 = rightResultReg), null, binExpr.position)
|
addInstr(result, IRInstruction(Opcode.ADDR, vmDt, reg1 = resultRegister, reg2 = rightResultReg), null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -888,7 +888,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
IRInstruction(Opcode.INCM, vmDt, value = knownAddress)
|
IRInstruction(Opcode.INCM, vmDt, value = knownAddress)
|
||||||
else
|
else
|
||||||
IRInstruction(Opcode.INCM, vmDt, labelSymbol = symbol)
|
IRInstruction(Opcode.INCM, vmDt, labelSymbol = symbol)
|
||||||
, null, operand.position)
|
, null)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
val operandFpReg = codeGen.registers.nextFreeFloat()
|
val operandFpReg = codeGen.registers.nextFreeFloat()
|
||||||
@ -897,7 +897,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
IRInstruction(Opcode.ADDM, vmDt, fpReg1=operandFpReg, value = knownAddress)
|
IRInstruction(Opcode.ADDM, vmDt, fpReg1=operandFpReg, value = knownAddress)
|
||||||
else
|
else
|
||||||
IRInstruction(Opcode.ADDM, vmDt, fpReg1=operandFpReg, labelSymbol = symbol)
|
IRInstruction(Opcode.ADDM, vmDt, fpReg1=operandFpReg, labelSymbol = symbol)
|
||||||
, null, operand.position)
|
, null)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if((operand as? PtNumber)?.number==1.0) {
|
if((operand as? PtNumber)?.number==1.0) {
|
||||||
@ -905,7 +905,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
IRInstruction(Opcode.INCM, vmDt, value = knownAddress)
|
IRInstruction(Opcode.INCM, vmDt, value = knownAddress)
|
||||||
else
|
else
|
||||||
IRInstruction(Opcode.INCM, vmDt, labelSymbol = symbol)
|
IRInstruction(Opcode.INCM, vmDt, labelSymbol = symbol)
|
||||||
, null, operand.position)
|
, null)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
val operandReg = codeGen.registers.nextFree()
|
val operandReg = codeGen.registers.nextFree()
|
||||||
@ -914,7 +914,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
IRInstruction(Opcode.ADDM, vmDt, reg1=operandReg, value=knownAddress)
|
IRInstruction(Opcode.ADDM, vmDt, reg1=operandReg, value=knownAddress)
|
||||||
else
|
else
|
||||||
IRInstruction(Opcode.ADDM, vmDt, reg1=operandReg, labelSymbol = symbol)
|
IRInstruction(Opcode.ADDM, vmDt, reg1=operandReg, labelSymbol = symbol)
|
||||||
, null, operand.position)
|
, null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
@ -928,29 +928,29 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
val paramDt = codeGen.irType(parameter.type)
|
val paramDt = codeGen.irType(parameter.type)
|
||||||
val symbol = (fcall.functionName + parameter.name).joinToString(".")
|
val symbol = (fcall.functionName + parameter.name).joinToString(".")
|
||||||
if(codeGen.isZero(arg)) {
|
if(codeGen.isZero(arg)) {
|
||||||
addInstr(result, IRInstruction(Opcode.STOREZM, paramDt, labelSymbol = symbol), null, fcall.position)
|
addInstr(result, IRInstruction(Opcode.STOREZM, paramDt, labelSymbol = symbol), null)
|
||||||
} else {
|
} else {
|
||||||
if (paramDt == IRDataType.FLOAT) {
|
if (paramDt == IRDataType.FLOAT) {
|
||||||
val argFpReg = codeGen.registers.nextFreeFloat()
|
val argFpReg = codeGen.registers.nextFreeFloat()
|
||||||
result += translateExpression(arg, -1, argFpReg)
|
result += translateExpression(arg, -1, argFpReg)
|
||||||
addInstr(result, IRInstruction(Opcode.STOREM, paramDt, fpReg1 = argFpReg, labelSymbol = symbol), null, fcall.position)
|
addInstr(result, IRInstruction(Opcode.STOREM, paramDt, fpReg1 = argFpReg, labelSymbol = symbol), null)
|
||||||
} else {
|
} else {
|
||||||
val argReg = codeGen.registers.nextFree()
|
val argReg = codeGen.registers.nextFree()
|
||||||
result += translateExpression(arg, argReg, -1)
|
result += translateExpression(arg, argReg, -1)
|
||||||
addInstr(result, IRInstruction(Opcode.STOREM, paramDt, reg1 = argReg, labelSymbol = symbol), null, fcall.position)
|
addInstr(result, IRInstruction(Opcode.STOREM, paramDt, reg1 = argReg, labelSymbol = symbol), null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
addInstr(result, IRInstruction(Opcode.CALL, labelSymbol=fcall.functionName.joinToString(".")), null, fcall.position)
|
addInstr(result, IRInstruction(Opcode.CALL, labelSymbol=fcall.functionName.joinToString(".")), null)
|
||||||
if(fcall.type==DataType.FLOAT) {
|
if(fcall.type==DataType.FLOAT) {
|
||||||
if (!fcall.void && resultFpRegister != 0) {
|
if (!fcall.void && resultFpRegister != 0) {
|
||||||
// Call convention: result value is in fr0, so put it in the required register instead.
|
// Call convention: result value is in fr0, so put it in the required register instead.
|
||||||
addInstr(result, IRInstruction(Opcode.LOADR, IRDataType.FLOAT, fpReg1 = resultFpRegister, fpReg2 = 0), null, fcall.position)
|
addInstr(result, IRInstruction(Opcode.LOADR, IRDataType.FLOAT, fpReg1 = resultFpRegister, fpReg2 = 0), null)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!fcall.void && resultRegister != 0) {
|
if (!fcall.void && resultRegister != 0) {
|
||||||
// Call convention: result value is in r0, so put it in the required register instead.
|
// Call convention: result value is in r0, so put it in the required register instead.
|
||||||
addInstr(result, IRInstruction(Opcode.LOADR, codeGen.irType(fcall.type), reg1 = resultRegister, reg2 = 0), null, fcall.position)
|
addInstr(result, IRInstruction(Opcode.LOADR, codeGen.irType(fcall.type), reg1 = resultRegister, reg2 = 0), null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
@ -961,16 +961,16 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
val paramDt = codeGen.irType(parameter.type)
|
val paramDt = codeGen.irType(parameter.type)
|
||||||
val paramRegStr = if(parameter.register.registerOrPair!=null) parameter.register.registerOrPair.toString() else parameter.register.statusflag.toString()
|
val paramRegStr = if(parameter.register.registerOrPair!=null) parameter.register.registerOrPair.toString() else parameter.register.statusflag.toString()
|
||||||
if(codeGen.isZero(arg)) {
|
if(codeGen.isZero(arg)) {
|
||||||
addInstr(result, IRInstruction(Opcode.STOREZCPU, paramDt, labelSymbol = paramRegStr), null, fcall.position)
|
addInstr(result, IRInstruction(Opcode.STOREZCPU, paramDt, labelSymbol = paramRegStr), null)
|
||||||
} else {
|
} else {
|
||||||
if (paramDt == IRDataType.FLOAT)
|
if (paramDt == IRDataType.FLOAT)
|
||||||
throw AssemblyError("doesn't support float register argument in asm romsub")
|
throw AssemblyError("doesn't support float register argument in asm romsub")
|
||||||
val argReg = codeGen.registers.nextFree()
|
val argReg = codeGen.registers.nextFree()
|
||||||
result += translateExpression(arg, argReg, -1)
|
result += translateExpression(arg, argReg, -1)
|
||||||
addInstr(result, IRInstruction(Opcode.STORECPU, paramDt, reg1 = argReg, labelSymbol = paramRegStr), null, fcall.position)
|
addInstr(result, IRInstruction(Opcode.STORECPU, paramDt, reg1 = argReg, labelSymbol = paramRegStr), null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
addInstr(result, IRInstruction(Opcode.CALL, value=callTarget.address.toInt()), null, fcall.position)
|
addInstr(result, IRInstruction(Opcode.CALL, value=callTarget.address.toInt()), null)
|
||||||
if(!fcall.void) {
|
if(!fcall.void) {
|
||||||
if(callTarget.returns.size!=1)
|
if(callTarget.returns.size!=1)
|
||||||
throw AssemblyError("expect precisely 1 return value")
|
throw AssemblyError("expect precisely 1 return value")
|
||||||
@ -978,7 +978,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
throw AssemblyError("doesn't support float register result in asm romsub")
|
throw AssemblyError("doesn't support float register result in asm romsub")
|
||||||
val returns = callTarget.returns.single()
|
val returns = callTarget.returns.single()
|
||||||
val regStr = if(returns.registerOrPair!=null) returns.registerOrPair.toString() else returns.statusflag.toString()
|
val regStr = if(returns.registerOrPair!=null) returns.registerOrPair.toString() else returns.statusflag.toString()
|
||||||
addInstr(result, IRInstruction(Opcode.LOADCPU, codeGen.irType(fcall.type), reg1=resultRegister, labelSymbol = regStr), null, fcall.position)
|
addInstr(result, IRInstruction(Opcode.LOADCPU, codeGen.irType(fcall.type), reg1=resultRegister, labelSymbol = regStr), null)
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
@ -989,8 +989,8 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
internal fun addInstr(code: MutableList<IRCodeChunkBase>, instr: IRInstruction, label: String?, position: Position = Position.DUMMY) {
|
internal fun addInstr(code: MutableList<IRCodeChunkBase>, instr: IRInstruction, label: String?) {
|
||||||
code += IRCodeChunk(label, position, null).also {
|
code += IRCodeChunk(label, null).also {
|
||||||
it += instr
|
it += instr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ class IRCodeGen(
|
|||||||
if(block.inlineAssembly.isNotEmpty()) {
|
if(block.inlineAssembly.isNotEmpty()) {
|
||||||
val first = block.inlineAssembly.first()
|
val first = block.inlineAssembly.first()
|
||||||
if(first.label==null) {
|
if(first.label==null) {
|
||||||
val replacement = IRInlineAsmChunk(block.name, first.assembly, first.isIR, first.position, first.next)
|
val replacement = IRInlineAsmChunk(block.name, first.assembly, first.isIR, first.next)
|
||||||
block.inlineAssembly.removeAt(0)
|
block.inlineAssembly.removeAt(0)
|
||||||
block.inlineAssembly.add(0, replacement)
|
block.inlineAssembly.add(0, replacement)
|
||||||
} else if(first.label != block.name) {
|
} else if(first.label != block.name) {
|
||||||
@ -93,19 +93,19 @@ class IRCodeGen(
|
|||||||
if(first.label==null) {
|
if(first.label==null) {
|
||||||
val replacement = when(first) {
|
val replacement = when(first) {
|
||||||
is IRCodeChunk -> {
|
is IRCodeChunk -> {
|
||||||
val replacement = IRCodeChunk(sub.name, first.position, first.next)
|
val replacement = IRCodeChunk(sub.name, first.next)
|
||||||
replacement.instructions += first.instructions
|
replacement.instructions += first.instructions
|
||||||
replacement
|
replacement
|
||||||
}
|
}
|
||||||
is IRInlineAsmChunk -> IRInlineAsmChunk(sub.name, first.assembly, first.isIR, first.position, first.next)
|
is IRInlineAsmChunk -> IRInlineAsmChunk(sub.name, first.assembly, first.isIR, first.next)
|
||||||
is IRInlineBinaryChunk -> IRInlineBinaryChunk(sub.name, first.data, first.position, first.next)
|
is IRInlineBinaryChunk -> IRInlineBinaryChunk(sub.name, first.data, first.next)
|
||||||
else -> throw AssemblyError("invalid chunk")
|
else -> throw AssemblyError("invalid chunk")
|
||||||
}
|
}
|
||||||
sub.chunks.removeAt(0)
|
sub.chunks.removeAt(0)
|
||||||
sub.chunks.add(0, replacement)
|
sub.chunks.add(0, replacement)
|
||||||
} else if(first.label != sub.name) {
|
} else if(first.label != sub.name) {
|
||||||
val next = if(first is IRCodeChunk) first else null
|
val next = if(first is IRCodeChunk) first else null
|
||||||
sub.chunks.add(0, IRCodeChunk(sub.name, sub.position, next))
|
sub.chunks.add(0, IRCodeChunk(sub.name, next))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -282,19 +282,19 @@ class IRCodeGen(
|
|||||||
is PtIfElse -> translate(node)
|
is PtIfElse -> translate(node)
|
||||||
is PtPostIncrDecr -> translate(node)
|
is PtPostIncrDecr -> translate(node)
|
||||||
is PtRepeatLoop -> translate(node)
|
is PtRepeatLoop -> translate(node)
|
||||||
is PtLabel -> listOf(IRCodeChunk(node.name, node.position, null))
|
is PtLabel -> listOf(IRCodeChunk(node.name, null))
|
||||||
is PtBreakpoint -> {
|
is PtBreakpoint -> {
|
||||||
val chunk = IRCodeChunk(null, node.position, null)
|
val chunk = IRCodeChunk(null, null)
|
||||||
chunk += IRInstruction(Opcode.BREAKPOINT)
|
chunk += IRInstruction(Opcode.BREAKPOINT)
|
||||||
listOf(chunk)
|
listOf(chunk)
|
||||||
}
|
}
|
||||||
is PtConditionalBranch -> translate(node)
|
is PtConditionalBranch -> translate(node)
|
||||||
is PtInlineAssembly -> listOf(IRInlineAsmChunk(null, node.assembly, node.isIR, node.position, null))
|
is PtInlineAssembly -> listOf(IRInlineAsmChunk(null, node.assembly, node.isIR, null))
|
||||||
is PtIncludeBinary -> {
|
is PtIncludeBinary -> {
|
||||||
val data = node.file.readBytes()
|
val data = node.file.readBytes()
|
||||||
.drop(node.offset?.toInt() ?: 0)
|
.drop(node.offset?.toInt() ?: 0)
|
||||||
.take(node.length?.toInt() ?: Int.MAX_VALUE)
|
.take(node.length?.toInt() ?: Int.MAX_VALUE)
|
||||||
listOf(IRInlineBinaryChunk(null, data.map { it.toUByte() }, node.position, null))
|
listOf(IRInlineBinaryChunk(null, data.map { it.toUByte() }, null))
|
||||||
}
|
}
|
||||||
is PtAddressOf,
|
is PtAddressOf,
|
||||||
is PtContainmentCheck,
|
is PtContainmentCheck,
|
||||||
@ -340,16 +340,16 @@ class IRCodeGen(
|
|||||||
BranchCondition.VC -> IRInstruction(Opcode.BSTVC, labelSymbol = elseLabel)
|
BranchCondition.VC -> IRInstruction(Opcode.BSTVC, labelSymbol = elseLabel)
|
||||||
BranchCondition.VS -> IRInstruction(Opcode.BSTVS, labelSymbol = elseLabel)
|
BranchCondition.VS -> IRInstruction(Opcode.BSTVS, labelSymbol = elseLabel)
|
||||||
}
|
}
|
||||||
addInstr(result, branchIns, null, branch.position)
|
addInstr(result, branchIns, null)
|
||||||
result += translateNode(branch.trueScope)
|
result += translateNode(branch.trueScope)
|
||||||
if(branch.falseScope.children.isNotEmpty()) {
|
if(branch.falseScope.children.isNotEmpty()) {
|
||||||
val endLabel = createLabelName()
|
val endLabel = createLabelName()
|
||||||
addInstr(result, IRInstruction(Opcode.JUMP, labelSymbol = endLabel), null, branch.position)
|
addInstr(result, IRInstruction(Opcode.JUMP, labelSymbol = endLabel), null)
|
||||||
val chunks = translateNode(branch.falseScope)
|
val chunks = translateNode(branch.falseScope)
|
||||||
result += labelFirstChunk(chunks, elseLabel)
|
result += labelFirstChunk(chunks, elseLabel)
|
||||||
result += IRCodeChunk(endLabel, branch.position, null)
|
result += IRCodeChunk(endLabel, null)
|
||||||
} else {
|
} else {
|
||||||
result += IRCodeChunk(elseLabel, branch.position, null)
|
result += IRCodeChunk(elseLabel, null)
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
@ -360,20 +360,20 @@ class IRCodeGen(
|
|||||||
if(first.label!=null) {
|
if(first.label!=null) {
|
||||||
if(first.label==label)
|
if(first.label==label)
|
||||||
return chunks
|
return chunks
|
||||||
val newFirst = IRCodeChunk(label, first.position, first)
|
val newFirst = IRCodeChunk(label, first)
|
||||||
return listOf(newFirst) + chunks
|
return listOf(newFirst) + chunks
|
||||||
}
|
}
|
||||||
val labeledFirstChunk = when(first) {
|
val labeledFirstChunk = when(first) {
|
||||||
is IRCodeChunk -> {
|
is IRCodeChunk -> {
|
||||||
val newChunk = IRCodeChunk(label, first.position, first.next)
|
val newChunk = IRCodeChunk(label, first.next)
|
||||||
newChunk.instructions += first.instructions
|
newChunk.instructions += first.instructions
|
||||||
newChunk
|
newChunk
|
||||||
}
|
}
|
||||||
is IRInlineAsmChunk -> {
|
is IRInlineAsmChunk -> {
|
||||||
IRInlineAsmChunk(label, first.assembly, first.isIR, first.position, first.next)
|
IRInlineAsmChunk(label, first.assembly, first.isIR, first.next)
|
||||||
}
|
}
|
||||||
is IRInlineBinaryChunk -> {
|
is IRInlineBinaryChunk -> {
|
||||||
IRInlineBinaryChunk(label, first.data, first.position, first.next)
|
IRInlineBinaryChunk(label, first.data, first.next)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
throw AssemblyError("invalid chunk")
|
throw AssemblyError("invalid chunk")
|
||||||
@ -399,16 +399,16 @@ class IRCodeGen(
|
|||||||
val skipLabel = createLabelName()
|
val skipLabel = createLabelName()
|
||||||
val values = choice.values.children.map {it as PtNumber}
|
val values = choice.values.children.map {it as PtNumber}
|
||||||
if(values.size==1) {
|
if(values.size==1) {
|
||||||
val chunk = IRCodeChunk(null, whenStmt.position, null)
|
val chunk = IRCodeChunk(null, null)
|
||||||
chunk += IRInstruction(Opcode.LOAD, valueDt, reg1=choiceReg, value=values[0].number.toInt())
|
chunk += IRInstruction(Opcode.LOAD, valueDt, reg1=choiceReg, value=values[0].number.toInt())
|
||||||
chunk += IRInstruction(Opcode.BNE, valueDt, reg1=valueReg, reg2=choiceReg, labelSymbol = skipLabel)
|
chunk += IRInstruction(Opcode.BNE, valueDt, reg1=valueReg, reg2=choiceReg, labelSymbol = skipLabel)
|
||||||
result += chunk
|
result += chunk
|
||||||
result += translateNode(choice.statements)
|
result += translateNode(choice.statements)
|
||||||
if(choice.statements.children.last() !is PtReturn)
|
if(choice.statements.children.last() !is PtReturn)
|
||||||
addInstr(result, IRInstruction(Opcode.JUMP, labelSymbol = endLabel), null, whenStmt.position)
|
addInstr(result, IRInstruction(Opcode.JUMP, labelSymbol = endLabel), null)
|
||||||
} else {
|
} else {
|
||||||
val matchLabel = createLabelName()
|
val matchLabel = createLabelName()
|
||||||
val chunk = IRCodeChunk(null, whenStmt.position, null)
|
val chunk = IRCodeChunk(null, null)
|
||||||
for (value in values) {
|
for (value in values) {
|
||||||
chunk += IRInstruction(Opcode.LOAD, valueDt, reg1=choiceReg, value=value.number.toInt())
|
chunk += IRInstruction(Opcode.LOAD, valueDt, reg1=choiceReg, value=value.number.toInt())
|
||||||
chunk += IRInstruction(Opcode.BEQ, valueDt, reg1=valueReg, reg2=choiceReg, labelSymbol = matchLabel)
|
chunk += IRInstruction(Opcode.BEQ, valueDt, reg1=valueReg, reg2=choiceReg, labelSymbol = matchLabel)
|
||||||
@ -417,12 +417,12 @@ class IRCodeGen(
|
|||||||
result += chunk
|
result += chunk
|
||||||
result += labelFirstChunk(translateNode(choice.statements), matchLabel)
|
result += labelFirstChunk(translateNode(choice.statements), matchLabel)
|
||||||
if(choice.statements.children.last() !is PtReturn)
|
if(choice.statements.children.last() !is PtReturn)
|
||||||
addInstr(result, IRInstruction(Opcode.JUMP, labelSymbol = endLabel), null, whenStmt.position)
|
addInstr(result, IRInstruction(Opcode.JUMP, labelSymbol = endLabel), null)
|
||||||
}
|
}
|
||||||
result += IRCodeChunk(skipLabel, whenStmt.position, null)
|
result += IRCodeChunk(skipLabel, null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result += IRCodeChunk(endLabel, whenStmt.position, null)
|
result += IRCodeChunk(endLabel, null)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -447,18 +447,18 @@ class IRCodeGen(
|
|||||||
val endLabel = createLabelName()
|
val endLabel = createLabelName()
|
||||||
if(iterableVar.dt==DataType.STR) {
|
if(iterableVar.dt==DataType.STR) {
|
||||||
// iterate over a zero-terminated string
|
// iterate over a zero-terminated string
|
||||||
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=indexReg, value=0), null, forLoop.position)
|
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=indexReg, value=0), null)
|
||||||
val chunk = IRCodeChunk(loopLabel, forLoop.position, null)
|
val chunk = IRCodeChunk(loopLabel, null)
|
||||||
chunk += IRInstruction(Opcode.LOADX, IRDataType.BYTE, reg1=tmpReg, reg2=indexReg, labelSymbol = symbol)
|
chunk += IRInstruction(Opcode.LOADX, IRDataType.BYTE, reg1=tmpReg, reg2=indexReg, labelSymbol = symbol)
|
||||||
chunk += IRInstruction(Opcode.BZ, IRDataType.BYTE, reg1=tmpReg, labelSymbol = endLabel)
|
chunk += IRInstruction(Opcode.BZ, IRDataType.BYTE, reg1=tmpReg, labelSymbol = endLabel)
|
||||||
chunk += IRInstruction(Opcode.STOREM, IRDataType.BYTE, reg1=tmpReg, labelSymbol = loopvarSymbol)
|
chunk += IRInstruction(Opcode.STOREM, IRDataType.BYTE, reg1=tmpReg, labelSymbol = loopvarSymbol)
|
||||||
result += chunk
|
result += chunk
|
||||||
result += translateNode(forLoop.statements)
|
result += translateNode(forLoop.statements)
|
||||||
val jumpChunk = IRCodeChunk(null, forLoop.position, null)
|
val jumpChunk = IRCodeChunk(null, null)
|
||||||
jumpChunk += IRInstruction(Opcode.INC, IRDataType.BYTE, reg1=indexReg)
|
jumpChunk += IRInstruction(Opcode.INC, IRDataType.BYTE, reg1=indexReg)
|
||||||
jumpChunk += IRInstruction(Opcode.JUMP, labelSymbol = loopLabel)
|
jumpChunk += IRInstruction(Opcode.JUMP, labelSymbol = loopLabel)
|
||||||
result += jumpChunk
|
result += jumpChunk
|
||||||
result += IRCodeChunk(endLabel, forLoop.position, null)
|
result += IRCodeChunk(endLabel, null)
|
||||||
} else {
|
} else {
|
||||||
// iterate over array
|
// iterate over array
|
||||||
val elementDt = ArrayToElementTypes.getValue(iterable.type)
|
val elementDt = ArrayToElementTypes.getValue(iterable.type)
|
||||||
@ -466,26 +466,26 @@ class IRCodeGen(
|
|||||||
val lengthBytes = iterableVar.length!! * elementSize
|
val lengthBytes = iterableVar.length!! * elementSize
|
||||||
if(lengthBytes<256) {
|
if(lengthBytes<256) {
|
||||||
val lengthReg = registers.nextFree()
|
val lengthReg = registers.nextFree()
|
||||||
val chunk = IRCodeChunk(null, forLoop.position, null)
|
val chunk = IRCodeChunk(null, null)
|
||||||
chunk += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=indexReg, value=0)
|
chunk += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=indexReg, value=0)
|
||||||
chunk += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=lengthReg, value=lengthBytes)
|
chunk += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=lengthReg, value=lengthBytes)
|
||||||
result += chunk
|
result += chunk
|
||||||
val chunk2 = IRCodeChunk(loopLabel, forLoop.position, null)
|
val chunk2 = IRCodeChunk(loopLabel, null)
|
||||||
chunk2 += IRInstruction(Opcode.LOADX, irType(elementDt), reg1=tmpReg, reg2=indexReg, labelSymbol=symbol)
|
chunk2 += IRInstruction(Opcode.LOADX, irType(elementDt), reg1=tmpReg, reg2=indexReg, labelSymbol=symbol)
|
||||||
chunk2 += IRInstruction(Opcode.STOREM, irType(elementDt), reg1=tmpReg, labelSymbol = loopvarSymbol)
|
chunk2 += IRInstruction(Opcode.STOREM, irType(elementDt), reg1=tmpReg, labelSymbol = loopvarSymbol)
|
||||||
result += chunk2
|
result += chunk2
|
||||||
result += translateNode(forLoop.statements)
|
result += translateNode(forLoop.statements)
|
||||||
result += addConstReg(IRDataType.BYTE, indexReg, elementSize, iterable.position)
|
result += addConstReg(IRDataType.BYTE, indexReg, elementSize)
|
||||||
addInstr(result, IRInstruction(Opcode.BNE, IRDataType.BYTE, reg1=indexReg, reg2=lengthReg, labelSymbol = loopLabel), null, forLoop.position)
|
addInstr(result, IRInstruction(Opcode.BNE, IRDataType.BYTE, reg1=indexReg, reg2=lengthReg, labelSymbol = loopLabel), null)
|
||||||
} else if(lengthBytes==256) {
|
} else if(lengthBytes==256) {
|
||||||
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=indexReg, value=0), null, forLoop.position)
|
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=indexReg, value=0), null)
|
||||||
val chunk = IRCodeChunk(loopLabel, forLoop.position, null)
|
val chunk = IRCodeChunk(loopLabel, null)
|
||||||
chunk += IRInstruction(Opcode.LOADX, irType(elementDt), reg1=tmpReg, reg2=indexReg, labelSymbol=symbol)
|
chunk += IRInstruction(Opcode.LOADX, irType(elementDt), reg1=tmpReg, reg2=indexReg, labelSymbol=symbol)
|
||||||
chunk += IRInstruction(Opcode.STOREM, irType(elementDt), reg1=tmpReg, labelSymbol = loopvarSymbol)
|
chunk += IRInstruction(Opcode.STOREM, irType(elementDt), reg1=tmpReg, labelSymbol = loopvarSymbol)
|
||||||
result += chunk
|
result += chunk
|
||||||
result += translateNode(forLoop.statements)
|
result += translateNode(forLoop.statements)
|
||||||
result += addConstReg(IRDataType.BYTE, indexReg, elementSize, iterable.position)
|
result += addConstReg(IRDataType.BYTE, indexReg, elementSize)
|
||||||
addInstr(result, IRInstruction(Opcode.BNZ, IRDataType.BYTE, reg1=indexReg, labelSymbol = loopLabel), null, forLoop.position)
|
addInstr(result, IRInstruction(Opcode.BNZ, IRDataType.BYTE, reg1=indexReg, labelSymbol = loopLabel), null)
|
||||||
} else {
|
} else {
|
||||||
throw AssemblyError("iterator length should never exceed 256")
|
throw AssemblyError("iterator length should never exceed 256")
|
||||||
}
|
}
|
||||||
@ -515,12 +515,12 @@ class IRCodeGen(
|
|||||||
|
|
||||||
result += expressionEval.translateExpression(iterable.to, endvalueReg, -1)
|
result += expressionEval.translateExpression(iterable.to, endvalueReg, -1)
|
||||||
result += expressionEval.translateExpression(iterable.from, indexReg, -1)
|
result += expressionEval.translateExpression(iterable.from, indexReg, -1)
|
||||||
addInstr(result, IRInstruction(Opcode.STOREM, loopvarDtIr, reg1=indexReg, labelSymbol=loopvarSymbol), null, forLoop.position)
|
addInstr(result, IRInstruction(Opcode.STOREM, loopvarDtIr, reg1=indexReg, labelSymbol=loopvarSymbol), null)
|
||||||
result += labelFirstChunk(translateNode(forLoop.statements), loopLabel)
|
result += labelFirstChunk(translateNode(forLoop.statements), loopLabel)
|
||||||
result += addConstMem(loopvarDtIr, null, loopvarSymbol, step, iterable.position)
|
result += addConstMem(loopvarDtIr, null, loopvarSymbol, step)
|
||||||
addInstr(result, IRInstruction(Opcode.LOADM, loopvarDtIr, reg1 = indexReg, labelSymbol = loopvarSymbol), null, forLoop.position)
|
addInstr(result, IRInstruction(Opcode.LOADM, loopvarDtIr, reg1 = indexReg, labelSymbol = loopvarSymbol), null)
|
||||||
val branchOpcode = if(loopvarDt in SignedDatatypes) Opcode.BLES else Opcode.BLE
|
val branchOpcode = if(loopvarDt in SignedDatatypes) Opcode.BLES else Opcode.BLE
|
||||||
addInstr(result, IRInstruction(branchOpcode, loopvarDtIr, reg1=indexReg, reg2=endvalueReg, labelSymbol=loopLabel), null, forLoop.position)
|
addInstr(result, IRInstruction(branchOpcode, loopvarDtIr, reg1=indexReg, reg2=endvalueReg, labelSymbol=loopLabel), null)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -545,7 +545,7 @@ class IRCodeGen(
|
|||||||
val rangeEndWrapped = if(loopvarDtIr==IRDataType.BYTE) rangeEndUntyped and 255 else rangeEndUntyped and 65535
|
val rangeEndWrapped = if(loopvarDtIr==IRDataType.BYTE) rangeEndUntyped and 255 else rangeEndUntyped and 65535
|
||||||
val endvalueReg: Int
|
val endvalueReg: Int
|
||||||
val result = mutableListOf<IRCodeChunkBase>()
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
val chunk = IRCodeChunk(null, forLoop.position, null)
|
val chunk = IRCodeChunk(null, null)
|
||||||
if(rangeEndWrapped!=0) {
|
if(rangeEndWrapped!=0) {
|
||||||
endvalueReg = registers.nextFree()
|
endvalueReg = registers.nextFree()
|
||||||
chunk += IRInstruction(Opcode.LOAD, loopvarDtIr, reg1 = endvalueReg, value = rangeEndWrapped)
|
chunk += IRInstruction(Opcode.LOAD, loopvarDtIr, reg1 = endvalueReg, value = rangeEndWrapped)
|
||||||
@ -556,8 +556,8 @@ class IRCodeGen(
|
|||||||
chunk += IRInstruction(Opcode.STOREM, loopvarDtIr, reg1=indexReg, labelSymbol=loopvarSymbol)
|
chunk += IRInstruction(Opcode.STOREM, loopvarDtIr, reg1=indexReg, labelSymbol=loopvarSymbol)
|
||||||
result += chunk
|
result += chunk
|
||||||
result += labelFirstChunk(translateNode(forLoop.statements), loopLabel)
|
result += labelFirstChunk(translateNode(forLoop.statements), loopLabel)
|
||||||
result += addConstMem(loopvarDtIr, null, loopvarSymbol, step, iterable.position)
|
result += addConstMem(loopvarDtIr, null, loopvarSymbol, step)
|
||||||
val chunk2 = IRCodeChunk(null, forLoop.position, null)
|
val chunk2 = IRCodeChunk(null, null)
|
||||||
chunk2 += IRInstruction(Opcode.LOADM, loopvarDtIr, reg1 = indexReg, labelSymbol = loopvarSymbol)
|
chunk2 += IRInstruction(Opcode.LOADM, loopvarDtIr, reg1 = indexReg, labelSymbol = loopvarSymbol)
|
||||||
chunk2 += if(rangeEndWrapped==0) {
|
chunk2 += if(rangeEndWrapped==0) {
|
||||||
IRInstruction(Opcode.BNZ, loopvarDtIr, reg1 = indexReg, labelSymbol = loopLabel)
|
IRInstruction(Opcode.BNZ, loopvarDtIr, reg1 = indexReg, labelSymbol = loopLabel)
|
||||||
@ -568,8 +568,8 @@ class IRCodeGen(
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addConstReg(dt: IRDataType, reg: Int, value: Int, position: Position): IRCodeChunk {
|
private fun addConstReg(dt: IRDataType, reg: Int, value: Int): IRCodeChunk {
|
||||||
val code = IRCodeChunk(null, position, null)
|
val code = IRCodeChunk(null, null)
|
||||||
when(value) {
|
when(value) {
|
||||||
0 -> { /* do nothing */ }
|
0 -> { /* do nothing */ }
|
||||||
1 -> {
|
1 -> {
|
||||||
@ -597,8 +597,8 @@ class IRCodeGen(
|
|||||||
return code
|
return code
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addConstMem(dt: IRDataType, knownAddress: UInt?, symbol: String?, value: Int, position: Position): IRCodeChunk {
|
private fun addConstMem(dt: IRDataType, knownAddress: UInt?, symbol: String?, value: Int): IRCodeChunk {
|
||||||
val code = IRCodeChunk(null, position, null)
|
val code = IRCodeChunk(null, null)
|
||||||
when(value) {
|
when(value) {
|
||||||
0 -> { /* do nothing */ }
|
0 -> { /* do nothing */ }
|
||||||
1 -> {
|
1 -> {
|
||||||
@ -652,8 +652,8 @@ class IRCodeGen(
|
|||||||
return code
|
return code
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun multiplyByConstFloat(fpReg: Int, factor: Float, position: Position): IRCodeChunk {
|
internal fun multiplyByConstFloat(fpReg: Int, factor: Float): IRCodeChunk {
|
||||||
val code = IRCodeChunk(null, position, null)
|
val code = IRCodeChunk(null, null)
|
||||||
if(factor==1f)
|
if(factor==1f)
|
||||||
return code
|
return code
|
||||||
code += if(factor==0f) {
|
code += if(factor==0f) {
|
||||||
@ -664,8 +664,8 @@ class IRCodeGen(
|
|||||||
return code
|
return code
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun multiplyByConstFloatInplace(knownAddress: Int?, symbol: String?, factor: Float, position: Position): IRCodeChunk {
|
internal fun multiplyByConstFloatInplace(knownAddress: Int?, symbol: String?, factor: Float): IRCodeChunk {
|
||||||
val code = IRCodeChunk(null, position, null)
|
val code = IRCodeChunk(null, null)
|
||||||
if(factor==1f)
|
if(factor==1f)
|
||||||
return code
|
return code
|
||||||
if(factor==0f) {
|
if(factor==0f) {
|
||||||
@ -686,8 +686,8 @@ class IRCodeGen(
|
|||||||
|
|
||||||
internal val powersOfTwo = (0..16).map { 2.0.pow(it.toDouble()).toInt() }
|
internal val powersOfTwo = (0..16).map { 2.0.pow(it.toDouble()).toInt() }
|
||||||
|
|
||||||
internal fun multiplyByConst(dt: IRDataType, reg: Int, factor: Int, position: Position): IRCodeChunk {
|
internal fun multiplyByConst(dt: IRDataType, reg: Int, factor: Int): IRCodeChunk {
|
||||||
val code = IRCodeChunk(null, position, null)
|
val code = IRCodeChunk(null, null)
|
||||||
if(factor==1)
|
if(factor==1)
|
||||||
return code
|
return code
|
||||||
val pow2 = powersOfTwo.indexOf(factor)
|
val pow2 = powersOfTwo.indexOf(factor)
|
||||||
@ -711,7 +711,7 @@ class IRCodeGen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal fun multiplyByConstInplace(dt: IRDataType, knownAddress: Int?, symbol: String?, factor: Int, position: Position): IRCodeChunk {
|
internal fun multiplyByConstInplace(dt: IRDataType, knownAddress: Int?, symbol: String?, factor: Int, position: Position): IRCodeChunk {
|
||||||
val code = IRCodeChunk(null, position, null)
|
val code = IRCodeChunk(null, null)
|
||||||
if(factor==1)
|
if(factor==1)
|
||||||
return code
|
return code
|
||||||
val pow2 = powersOfTwo.indexOf(factor)
|
val pow2 = powersOfTwo.indexOf(factor)
|
||||||
@ -750,7 +750,7 @@ class IRCodeGen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal fun divideByConstFloat(fpReg: Int, factor: Float, position: Position): IRCodeChunk {
|
internal fun divideByConstFloat(fpReg: Int, factor: Float, position: Position): IRCodeChunk {
|
||||||
val code = IRCodeChunk(null, position, null)
|
val code = IRCodeChunk(null, null)
|
||||||
if(factor==1f)
|
if(factor==1f)
|
||||||
return code
|
return code
|
||||||
code += if(factor==0f) {
|
code += if(factor==0f) {
|
||||||
@ -762,7 +762,7 @@ class IRCodeGen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal fun divideByConstFloatInplace(knownAddress: Int?, symbol: String?, factor: Float, position: Position): IRCodeChunk {
|
internal fun divideByConstFloatInplace(knownAddress: Int?, symbol: String?, factor: Float, position: Position): IRCodeChunk {
|
||||||
val code = IRCodeChunk(null, position, null)
|
val code = IRCodeChunk(null, null)
|
||||||
if(factor==1f)
|
if(factor==1f)
|
||||||
return code
|
return code
|
||||||
if(factor==0f) {
|
if(factor==0f) {
|
||||||
@ -784,7 +784,7 @@ class IRCodeGen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal fun divideByConst(dt: IRDataType, reg: Int, factor: Int, signed: Boolean, position: Position): IRCodeChunk {
|
internal fun divideByConst(dt: IRDataType, reg: Int, factor: Int, signed: Boolean, position: Position): IRCodeChunk {
|
||||||
val code = IRCodeChunk(null, position, null)
|
val code = IRCodeChunk(null, null)
|
||||||
if(factor==1)
|
if(factor==1)
|
||||||
return code
|
return code
|
||||||
val pow2 = powersOfTwo.indexOf(factor)
|
val pow2 = powersOfTwo.indexOf(factor)
|
||||||
@ -813,7 +813,7 @@ class IRCodeGen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal fun divideByConstInplace(dt: IRDataType, knownAddress: Int?, symbol: String?, factor: Int, signed: Boolean, position: Position): IRCodeChunk {
|
internal fun divideByConstInplace(dt: IRDataType, knownAddress: Int?, symbol: String?, factor: Int, signed: Boolean, position: Position): IRCodeChunk {
|
||||||
val code = IRCodeChunk(null, position, null)
|
val code = IRCodeChunk(null, null)
|
||||||
if(factor==1)
|
if(factor==1)
|
||||||
return code
|
return code
|
||||||
val pow2 = powersOfTwo.indexOf(factor)
|
val pow2 = powersOfTwo.indexOf(factor)
|
||||||
@ -896,17 +896,17 @@ class IRCodeGen(
|
|||||||
// if and else parts
|
// if and else parts
|
||||||
val elseLabel = createLabelName()
|
val elseLabel = createLabelName()
|
||||||
val afterIfLabel = createLabelName()
|
val afterIfLabel = createLabelName()
|
||||||
addInstr(result, IRInstruction(elseBranch, irDt, reg1=leftReg, reg2=rightReg, labelSymbol = elseLabel), null, ifElse.position)
|
addInstr(result, IRInstruction(elseBranch, irDt, reg1=leftReg, reg2=rightReg, labelSymbol = elseLabel), null)
|
||||||
result += translateNode(ifElse.ifScope)
|
result += translateNode(ifElse.ifScope)
|
||||||
addInstr(result, IRInstruction(Opcode.JUMP, labelSymbol = afterIfLabel), null, ifElse.position)
|
addInstr(result, IRInstruction(Opcode.JUMP, labelSymbol = afterIfLabel), null)
|
||||||
result += labelFirstChunk(translateNode(ifElse.elseScope), elseLabel)
|
result += labelFirstChunk(translateNode(ifElse.elseScope), elseLabel)
|
||||||
result += IRCodeChunk(afterIfLabel, ifElse.position, null)
|
result += IRCodeChunk(afterIfLabel, null)
|
||||||
} else {
|
} else {
|
||||||
// only if part
|
// only if part
|
||||||
val afterIfLabel = createLabelName()
|
val afterIfLabel = createLabelName()
|
||||||
addInstr(result, IRInstruction(elseBranch, irDt, reg1=leftReg, reg2=rightReg, labelSymbol = afterIfLabel), null, ifElse.position)
|
addInstr(result, IRInstruction(elseBranch, irDt, reg1=leftReg, reg2=rightReg, labelSymbol = afterIfLabel), null)
|
||||||
result += translateNode(ifElse.ifScope)
|
result += translateNode(ifElse.ifScope)
|
||||||
result += IRCodeChunk(afterIfLabel, ifElse.position, null)
|
result += IRCodeChunk(afterIfLabel, null)
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
@ -920,17 +920,17 @@ class IRCodeGen(
|
|||||||
// if and else parts
|
// if and else parts
|
||||||
val elseLabel = createLabelName()
|
val elseLabel = createLabelName()
|
||||||
val afterIfLabel = createLabelName()
|
val afterIfLabel = createLabelName()
|
||||||
addInstr(result, IRInstruction(elseBranch, irDt, reg1=leftReg, labelSymbol = elseLabel), null, ifElse.position)
|
addInstr(result, IRInstruction(elseBranch, irDt, reg1=leftReg, labelSymbol = elseLabel), null)
|
||||||
result += translateNode(ifElse.ifScope)
|
result += translateNode(ifElse.ifScope)
|
||||||
addInstr(result, IRInstruction(Opcode.JUMP, labelSymbol = afterIfLabel), null, ifElse.position)
|
addInstr(result, IRInstruction(Opcode.JUMP, labelSymbol = afterIfLabel), null)
|
||||||
result += labelFirstChunk(translateNode(ifElse.elseScope), elseLabel)
|
result += labelFirstChunk(translateNode(ifElse.elseScope), elseLabel)
|
||||||
result += IRCodeChunk(afterIfLabel, ifElse.position, null)
|
result += IRCodeChunk(afterIfLabel, null)
|
||||||
} else {
|
} else {
|
||||||
// only if part
|
// only if part
|
||||||
val afterIfLabel = createLabelName()
|
val afterIfLabel = createLabelName()
|
||||||
addInstr(result, IRInstruction(elseBranch, irDt, reg1=leftReg, labelSymbol = afterIfLabel), null, ifElse.position)
|
addInstr(result, IRInstruction(elseBranch, irDt, reg1=leftReg, labelSymbol = afterIfLabel), null)
|
||||||
result += translateNode(ifElse.ifScope)
|
result += translateNode(ifElse.ifScope)
|
||||||
result += IRCodeChunk(afterIfLabel, ifElse.position, null)
|
result += IRCodeChunk(afterIfLabel, null)
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
@ -977,16 +977,16 @@ class IRCodeGen(
|
|||||||
val irDt = irType(postIncrDecr.target.type)
|
val irDt = irType(postIncrDecr.target.type)
|
||||||
val result = mutableListOf<IRCodeChunkBase>()
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
if(ident!=null) {
|
if(ident!=null) {
|
||||||
addInstr(result, IRInstruction(operationMem, irDt, labelSymbol = ident.targetName.joinToString(".")), null, postIncrDecr.position)
|
addInstr(result, IRInstruction(operationMem, irDt, labelSymbol = ident.targetName.joinToString(".")), null)
|
||||||
} else if(memory!=null) {
|
} else if(memory!=null) {
|
||||||
if(memory.address is PtNumber) {
|
if(memory.address is PtNumber) {
|
||||||
val address = (memory.address as PtNumber).number.toInt()
|
val address = (memory.address as PtNumber).number.toInt()
|
||||||
addInstr(result, IRInstruction(operationMem, irDt, value = address), null, postIncrDecr.position)
|
addInstr(result, IRInstruction(operationMem, irDt, value = address), null)
|
||||||
} else {
|
} else {
|
||||||
val incReg = registers.nextFree()
|
val incReg = registers.nextFree()
|
||||||
val addressReg = registers.nextFree()
|
val addressReg = registers.nextFree()
|
||||||
result += expressionEval.translateExpression(memory.address, addressReg, -1)
|
result += expressionEval.translateExpression(memory.address, addressReg, -1)
|
||||||
val chunk = IRCodeChunk(null, postIncrDecr.position, null)
|
val chunk = IRCodeChunk(null, null)
|
||||||
chunk += IRInstruction(Opcode.LOADI, irDt, reg1 = incReg, reg2 = addressReg)
|
chunk += IRInstruction(Opcode.LOADI, irDt, reg1 = incReg, reg2 = addressReg)
|
||||||
chunk += IRInstruction(operationRegister, irDt, reg1 = incReg)
|
chunk += IRInstruction(operationRegister, irDt, reg1 = incReg)
|
||||||
chunk += IRInstruction(Opcode.STOREI, irDt, reg1 = incReg, reg2 = addressReg)
|
chunk += IRInstruction(Opcode.STOREI, irDt, reg1 = incReg, reg2 = addressReg)
|
||||||
@ -998,12 +998,12 @@ class IRCodeGen(
|
|||||||
val fixedIndex = constIntValue(array.index)
|
val fixedIndex = constIntValue(array.index)
|
||||||
if(fixedIndex!=null) {
|
if(fixedIndex!=null) {
|
||||||
val offset = fixedIndex*itemsize
|
val offset = fixedIndex*itemsize
|
||||||
addInstr(result, IRInstruction(operationMem, irDt, labelSymbol="$variable+$offset"), null, postIncrDecr.position)
|
addInstr(result, IRInstruction(operationMem, irDt, labelSymbol="$variable+$offset"), null)
|
||||||
} else {
|
} else {
|
||||||
val incReg = registers.nextFree()
|
val incReg = registers.nextFree()
|
||||||
val indexReg = registers.nextFree()
|
val indexReg = registers.nextFree()
|
||||||
result += expressionEval.translateExpression(array.index, indexReg, -1)
|
result += expressionEval.translateExpression(array.index, indexReg, -1)
|
||||||
val chunk = IRCodeChunk(null, postIncrDecr.position, null)
|
val chunk = IRCodeChunk(null, null)
|
||||||
chunk += IRInstruction(Opcode.LOADX, irDt, reg1=incReg, reg2=indexReg, labelSymbol=variable)
|
chunk += IRInstruction(Opcode.LOADX, irDt, reg1=incReg, reg2=indexReg, labelSymbol=variable)
|
||||||
chunk += IRInstruction(operationRegister, irDt, reg1=incReg)
|
chunk += IRInstruction(operationRegister, irDt, reg1=incReg)
|
||||||
chunk += IRInstruction(Opcode.STOREX, irDt, reg1=incReg, reg2=indexReg, labelSymbol=variable)
|
chunk += IRInstruction(Opcode.STOREX, irDt, reg1=incReg, reg2=indexReg, labelSymbol=variable)
|
||||||
@ -1031,13 +1031,13 @@ class IRCodeGen(
|
|||||||
val irDt = irType(repeat.count.type)
|
val irDt = irType(repeat.count.type)
|
||||||
val result = mutableListOf<IRCodeChunkBase>()
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
result += expressionEval.translateExpression(repeat.count, counterReg, -1)
|
result += expressionEval.translateExpression(repeat.count, counterReg, -1)
|
||||||
addInstr(result, IRInstruction(Opcode.BZ, irDt, reg1=counterReg, labelSymbol = skipRepeatLabel), null, repeat.position)
|
addInstr(result, IRInstruction(Opcode.BZ, irDt, reg1=counterReg, labelSymbol = skipRepeatLabel), null)
|
||||||
result += labelFirstChunk(translateNode(repeat.statements), repeatLabel)
|
result += labelFirstChunk(translateNode(repeat.statements), repeatLabel)
|
||||||
val chunk = IRCodeChunk(null, repeat.position, null)
|
val chunk = IRCodeChunk(null, null)
|
||||||
chunk += IRInstruction(Opcode.DEC, irDt, reg1=counterReg)
|
chunk += IRInstruction(Opcode.DEC, irDt, reg1=counterReg)
|
||||||
chunk += IRInstruction(Opcode.BNZ, irDt, reg1=counterReg, labelSymbol = repeatLabel)
|
chunk += IRInstruction(Opcode.BNZ, irDt, reg1=counterReg, labelSymbol = repeatLabel)
|
||||||
result += chunk
|
result += chunk
|
||||||
result += IRCodeChunk(skipRepeatLabel, repeat.position, null)
|
result += IRCodeChunk(skipRepeatLabel, null)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1053,7 +1053,7 @@ class IRCodeGen(
|
|||||||
else
|
else
|
||||||
throw AssemblyError("weird jump")
|
throw AssemblyError("weird jump")
|
||||||
}
|
}
|
||||||
addInstr(result, instr, null, jump.position)
|
addInstr(result, instr, null)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1073,7 +1073,7 @@ class IRCodeGen(
|
|||||||
else
|
else
|
||||||
expressionEval.translateExpression(value, 0, -1)
|
expressionEval.translateExpression(value, 0, -1)
|
||||||
}
|
}
|
||||||
addInstr(result, IRInstruction(Opcode.RETURN), null, ret.position)
|
addInstr(result, IRInstruction(Opcode.RETURN), null)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1094,7 +1094,7 @@ class IRCodeGen(
|
|||||||
is PtAsmSub -> {
|
is PtAsmSub -> {
|
||||||
val assemblyChild = child.children.single() as PtInlineAssembly
|
val assemblyChild = child.children.single() as PtInlineAssembly
|
||||||
val asmChunk = IRInlineAsmChunk(
|
val asmChunk = IRInlineAsmChunk(
|
||||||
child.name, assemblyChild.assembly, assemblyChild.isIR, child.position, null
|
child.name, assemblyChild.assembly, assemblyChild.isIR, null
|
||||||
)
|
)
|
||||||
irBlock += IRAsmSubroutine(
|
irBlock += IRAsmSubroutine(
|
||||||
child.name,
|
child.name,
|
||||||
@ -1107,7 +1107,7 @@ class IRCodeGen(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
is PtInlineAssembly -> {
|
is PtInlineAssembly -> {
|
||||||
irBlock += IRInlineAsmChunk(null, child.assembly, child.isIR, child.position, null)
|
irBlock += IRInlineAsmChunk(null, child.assembly, child.isIR, null)
|
||||||
}
|
}
|
||||||
else -> TODO("weird child node $child")
|
else -> TODO("weird child node $child")
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package prog8.codegen.intermediate
|
package prog8.codegen.intermediate
|
||||||
|
|
||||||
|
import prog8.code.core.Position
|
||||||
import prog8.intermediate.*
|
import prog8.intermediate.*
|
||||||
|
|
||||||
internal class IRPeepholeOptimizer(private val irprog: IRProgram) {
|
internal class IRPeepholeOptimizer(private val irprog: IRProgram) {
|
||||||
@ -72,7 +73,7 @@ internal class IRPeepholeOptimizer(private val irprog: IRProgram) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
relabelChunks.forEach { (index, label) ->
|
relabelChunks.forEach { (index, label) ->
|
||||||
val chunk = IRCodeChunk(label, sub.chunks[index].position, null)
|
val chunk = IRCodeChunk(label, null)
|
||||||
chunk.instructions += sub.chunks[index].instructions
|
chunk.instructions += sub.chunks[index].instructions
|
||||||
sub.chunks[index] = chunk
|
sub.chunks[index] = chunk
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package prog8.codegen.intermediate
|
package prog8.codegen.intermediate
|
||||||
|
|
||||||
import prog8.code.core.IErrorReporter
|
import prog8.code.core.IErrorReporter
|
||||||
import prog8.code.core.SourceCode.Companion.libraryFilePrefix
|
import prog8.intermediate.IRCodeChunkBase
|
||||||
import prog8.intermediate.*
|
import prog8.intermediate.IRProgram
|
||||||
|
|
||||||
internal class IRUnusedCodeRemover(private val irprog: IRProgram, private val errors: IErrorReporter) {
|
internal class IRUnusedCodeRemover(private val irprog: IRProgram, private val errors: IErrorReporter) {
|
||||||
fun optimize(): Int {
|
fun optimize(): Int {
|
||||||
@ -25,8 +25,6 @@ internal class IRUnusedCodeRemover(private val irprog: IRProgram, private val er
|
|||||||
irprog.blocks.asSequence().flatMap { it.subroutines }.forEach { sub ->
|
irprog.blocks.asSequence().flatMap { it.subroutines }.forEach { sub ->
|
||||||
sub.chunks.reversed().forEach { chunk ->
|
sub.chunks.reversed().forEach { chunk ->
|
||||||
if(chunk !in linkedChunks) {
|
if(chunk !in linkedChunks) {
|
||||||
if(!chunk.position.file.startsWith(libraryFilePrefix))
|
|
||||||
errors.warn("unreachable code", chunk.position)
|
|
||||||
sub.chunks.remove(chunk)
|
sub.chunks.remove(chunk)
|
||||||
numRemoved++
|
numRemoved++
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ class TestIRPeepholeOpt: FunSpec({
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun makeIRProgram(instructions: List<IRInstruction>): IRProgram {
|
fun makeIRProgram(instructions: List<IRInstruction>): IRProgram {
|
||||||
val chunk = IRCodeChunk("main.start", Position.DUMMY, null)
|
val chunk = IRCodeChunk("main.start", null)
|
||||||
instructions.forEach { chunk += it }
|
instructions.forEach { chunk += it }
|
||||||
return makeIRProgram(listOf(chunk))
|
return makeIRProgram(listOf(chunk))
|
||||||
}
|
}
|
||||||
@ -51,15 +51,15 @@ class TestIRPeepholeOpt: FunSpec({
|
|||||||
}
|
}
|
||||||
|
|
||||||
test("remove jmp to label below") {
|
test("remove jmp to label below") {
|
||||||
val c1 = IRCodeChunk("main.start", Position.DUMMY, null)
|
val c1 = IRCodeChunk("main.start", null)
|
||||||
c1 += IRInstruction(Opcode.JUMP, labelSymbol = "label") // removed, but chunk stays because of label
|
c1 += IRInstruction(Opcode.JUMP, labelSymbol = "label") // removed, but chunk stays because of label
|
||||||
val c2 = IRCodeChunk("label", Position.DUMMY, null)
|
val c2 = IRCodeChunk("label", null)
|
||||||
c2 += IRInstruction(Opcode.JUMP, labelSymbol = "label2") // removed, but chunk stays because of label
|
c2 += IRInstruction(Opcode.JUMP, labelSymbol = "label2") // removed, but chunk stays because of label
|
||||||
c2 += IRInstruction(Opcode.NOP) // removed
|
c2 += IRInstruction(Opcode.NOP) // removed
|
||||||
val c3 = IRCodeChunk("label2", Position.DUMMY, null)
|
val c3 = IRCodeChunk("label2", null)
|
||||||
c3 += IRInstruction(Opcode.JUMP, labelSymbol = "label3")
|
c3 += IRInstruction(Opcode.JUMP, labelSymbol = "label3")
|
||||||
c3 += IRInstruction(Opcode.INC, IRDataType.BYTE, reg1=1)
|
c3 += IRInstruction(Opcode.INC, IRDataType.BYTE, reg1=1)
|
||||||
val c4 = IRCodeChunk("label3", Position.DUMMY, null)
|
val c4 = IRCodeChunk("label3", null)
|
||||||
val irProg = makeIRProgram(listOf(c1, c2, c3, c4))
|
val irProg = makeIRProgram(listOf(c1, c2, c3, c4))
|
||||||
|
|
||||||
irProg.chunks().size shouldBe 4
|
irProg.chunks().size shouldBe 4
|
||||||
|
@ -3,7 +3,6 @@ TODO
|
|||||||
|
|
||||||
For next release
|
For next release
|
||||||
^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^
|
||||||
- ir: position of chunk of text.print("abc") seems to point to the string arg instead of the call
|
|
||||||
- fix unused chunk remover that now causes code execution error (IRCodeGen should enable it)
|
- fix unused chunk remover that now causes code execution error (IRCodeGen should enable it)
|
||||||
- ir: improve dead code elimination by checking chunk linkage. Does this solve the next issue?:
|
- ir: improve dead code elimination by checking chunk linkage. Does this solve the next issue?:
|
||||||
- ir: how to remove all unused subroutines? (the 6502 assembly codegen relies on 64tass solve this for us)
|
- ir: how to remove all unused subroutines? (the 6502 assembly codegen relies on 64tass solve this for us)
|
||||||
|
@ -263,7 +263,7 @@ class IRFileReader {
|
|||||||
if(line!="<INITGLOBALS>")
|
if(line!="<INITGLOBALS>")
|
||||||
throw IRParseException("invalid INITGLOBALS")
|
throw IRParseException("invalid INITGLOBALS")
|
||||||
line = lines.next()
|
line = lines.next()
|
||||||
var chunk = IRCodeChunk(null, Position.DUMMY, null)
|
var chunk = IRCodeChunk(null, null)
|
||||||
if(line=="<C>") {
|
if(line=="<C>") {
|
||||||
chunk = parseCodeChunk(line, lines)!!
|
chunk = parseCodeChunk(line, lines)!!
|
||||||
line = lines.next()
|
line = lines.next()
|
||||||
@ -287,8 +287,8 @@ class IRFileReader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val blockPattern = Regex("<BLOCK NAME=(.+) ADDRESS=(.+) ALIGN=(.+) POS=(.+)>")
|
private val blockPattern = Regex("<BLOCK NAME=(.+) ADDRESS=(.+) ALIGN=(.+) POS=(.+)>")
|
||||||
private val inlineAsmPattern = Regex("<INLINEASM LABEL=(.*) IR=(.+) POS=(.+)>")
|
private val inlineAsmPattern = Regex("<INLINEASM LABEL=(.*) IR=(.+)>")
|
||||||
private val bytesPattern = Regex("<BYTES LABEL=(.*) POS=(.+)>")
|
private val bytesPattern = Regex("<BYTES LABEL=(.*)>")
|
||||||
private val asmsubPattern = Regex("<ASMSUB NAME=(.+) ADDRESS=(.+) CLOBBERS=(.*) RETURNS=(.*) POS=(.+)>")
|
private val asmsubPattern = Regex("<ASMSUB NAME=(.+) ADDRESS=(.+) CLOBBERS=(.*) RETURNS=(.*) POS=(.+)>")
|
||||||
private val subPattern = Regex("<SUB NAME=(.+) RETURNTYPE=(.+) POS=(.+)>")
|
private val subPattern = Regex("<SUB NAME=(.+) RETURNTYPE=(.+) POS=(.+)>")
|
||||||
private val posPattern = Regex("\\[(.+): line (.+) col (.+)-(.+)\\]")
|
private val posPattern = Regex("\\[(.+): line (.+) col (.+)-(.+)\\]")
|
||||||
@ -322,18 +322,17 @@ class IRFileReader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun parseInlineAssembly(startline: String, lines: Iterator<String>): IRInlineAsmChunk {
|
private fun parseInlineAssembly(startline: String, lines: Iterator<String>): IRInlineAsmChunk {
|
||||||
// <INLINEASM LABEL=optional-label IR=true POS=[examples/test.p8: line 8 col 6-9]>
|
// <INLINEASM LABEL=optional-label IR=true>
|
||||||
val match = inlineAsmPattern.matchEntire(startline) ?: throw IRParseException("invalid INLINEASM")
|
val match = inlineAsmPattern.matchEntire(startline) ?: throw IRParseException("invalid INLINEASM")
|
||||||
val label = match.groupValues[1]
|
val label = match.groupValues[1]
|
||||||
val isIr = match.groupValues[2].toBoolean()
|
val isIr = match.groupValues[2].toBoolean()
|
||||||
val pos = parsePosition(match.groupValues[3])
|
|
||||||
val asmlines = mutableListOf<String>()
|
val asmlines = mutableListOf<String>()
|
||||||
var line = lines.next()
|
var line = lines.next()
|
||||||
while(line!="</INLINEASM>") {
|
while(line!="</INLINEASM>") {
|
||||||
asmlines.add(line)
|
asmlines.add(line)
|
||||||
line = lines.next()
|
line = lines.next()
|
||||||
}
|
}
|
||||||
return IRInlineAsmChunk(label, asmlines.joinToString("\n"), isIr, pos, null)
|
return IRInlineAsmChunk(label, asmlines.joinToString("\n"), isIr, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun parseAsmSubroutine(startline: String, lines: Iterator<String>): IRAsmSubroutine {
|
private fun parseAsmSubroutine(startline: String, lines: Iterator<String>): IRAsmSubroutine {
|
||||||
@ -412,7 +411,6 @@ class IRFileReader {
|
|||||||
private fun parseBinaryBytes(startline: String, lines: Iterator<String>): IRInlineBinaryChunk {
|
private fun parseBinaryBytes(startline: String, lines: Iterator<String>): IRInlineBinaryChunk {
|
||||||
val match = bytesPattern.matchEntire(startline) ?: throw IRParseException("invalid BYTES")
|
val match = bytesPattern.matchEntire(startline) ?: throw IRParseException("invalid BYTES")
|
||||||
val label = match.groupValues[1]
|
val label = match.groupValues[1]
|
||||||
val pos = parsePosition(match.groupValues[2])
|
|
||||||
val bytes = mutableListOf<UByte>()
|
val bytes = mutableListOf<UByte>()
|
||||||
var line = lines.next()
|
var line = lines.next()
|
||||||
while(line!="</BYTES>") {
|
while(line!="</BYTES>") {
|
||||||
@ -421,7 +419,7 @@ class IRFileReader {
|
|||||||
}
|
}
|
||||||
line = lines.next()
|
line = lines.next()
|
||||||
}
|
}
|
||||||
return IRInlineBinaryChunk(label, bytes, pos, null)
|
return IRInlineBinaryChunk(label, bytes, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun parseParameters(lines: Iterator<String>): List<IRSubroutine.IRParam> {
|
private fun parseParameters(lines: Iterator<String>): List<IRSubroutine.IRParam> {
|
||||||
@ -451,7 +449,7 @@ class IRFileReader {
|
|||||||
firstline.split('=', limit = 2)[1].dropLast(1)
|
firstline.split('=', limit = 2)[1].dropLast(1)
|
||||||
else
|
else
|
||||||
null
|
null
|
||||||
val chunk = IRCodeChunk(label, Position.DUMMY, null)
|
val chunk = IRCodeChunk(label, null)
|
||||||
while(true) {
|
while(true) {
|
||||||
val line = lines.next()
|
val line = lines.next()
|
||||||
if (line == "</C>")
|
if (line == "</C>")
|
||||||
|
@ -102,7 +102,7 @@ class IRFileWriter(private val irProgram: IRProgram, outfileOverride: Path?) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun writeInlineBytes(chunk: IRInlineBinaryChunk) {
|
private fun writeInlineBytes(chunk: IRInlineBinaryChunk) {
|
||||||
out.write("<BYTES LABEL=${chunk.label ?: ""} POS=${chunk.position}>\n")
|
out.write("<BYTES LABEL=${chunk.label ?: ""}>\n")
|
||||||
chunk.data.withIndex().forEach {(index, byte) ->
|
chunk.data.withIndex().forEach {(index, byte) ->
|
||||||
out.write(byte.toString(16).padStart(2,'0'))
|
out.write(byte.toString(16).padStart(2,'0'))
|
||||||
if(index and 63 == 63 && index < chunk.data.size-1)
|
if(index and 63 == 63 && index < chunk.data.size-1)
|
||||||
@ -112,7 +112,7 @@ class IRFileWriter(private val irProgram: IRProgram, outfileOverride: Path?) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun writeInlineAsm(chunk: IRInlineAsmChunk) {
|
private fun writeInlineAsm(chunk: IRInlineAsmChunk) {
|
||||||
out.write("<INLINEASM LABEL=${chunk.label ?: ""} IR=${chunk.isIR} POS=${chunk.position}>\n")
|
out.write("<INLINEASM LABEL=${chunk.label ?: ""} IR=${chunk.isIR}>\n")
|
||||||
out.write(chunk.assembly)
|
out.write(chunk.assembly)
|
||||||
out.write("\n</INLINEASM>\n")
|
out.write("\n</INLINEASM>\n")
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ class IRProgram(val name: String,
|
|||||||
val encoding: IStringEncoding) {
|
val encoding: IStringEncoding) {
|
||||||
|
|
||||||
val asmSymbols = mutableMapOf<String, String>()
|
val asmSymbols = mutableMapOf<String, String>()
|
||||||
val globalInits = IRCodeChunk(null, Position.DUMMY, null)
|
val globalInits = IRCodeChunk(null, null)
|
||||||
val blocks = mutableListOf<IRBlock>()
|
val blocks = mutableListOf<IRBlock>()
|
||||||
|
|
||||||
fun addGlobalInits(chunk: IRCodeChunk) {
|
fun addGlobalInits(chunk: IRCodeChunk) {
|
||||||
@ -262,7 +262,7 @@ class IRAsmSubroutine(
|
|||||||
fun usedRegisters() = registersUsed
|
fun usedRegisters() = registersUsed
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class IRCodeChunkBase(val label: String?, val position: Position, var next: IRCodeChunkBase?) {
|
sealed class IRCodeChunkBase(val label: String?, var next: IRCodeChunkBase?) {
|
||||||
val instructions = mutableListOf<IRInstruction>()
|
val instructions = mutableListOf<IRInstruction>()
|
||||||
|
|
||||||
abstract fun isEmpty(): Boolean
|
abstract fun isEmpty(): Boolean
|
||||||
@ -270,7 +270,7 @@ sealed class IRCodeChunkBase(val label: String?, val position: Position, var nex
|
|||||||
abstract fun usedRegisters(): RegistersUsed
|
abstract fun usedRegisters(): RegistersUsed
|
||||||
}
|
}
|
||||||
|
|
||||||
class IRCodeChunk(label: String?, position: Position, next: IRCodeChunkBase?): IRCodeChunkBase(label, position, next) {
|
class IRCodeChunk(label: String?, next: IRCodeChunkBase?): IRCodeChunkBase(label, next) {
|
||||||
|
|
||||||
override fun isEmpty() = instructions.isEmpty()
|
override fun isEmpty() = instructions.isEmpty()
|
||||||
override fun isNotEmpty() = instructions.isNotEmpty()
|
override fun isNotEmpty() = instructions.isNotEmpty()
|
||||||
@ -295,8 +295,7 @@ class IRCodeChunk(label: String?, position: Position, next: IRCodeChunkBase?): I
|
|||||||
class IRInlineAsmChunk(label: String?,
|
class IRInlineAsmChunk(label: String?,
|
||||||
val assembly: String,
|
val assembly: String,
|
||||||
val isIR: Boolean,
|
val isIR: Boolean,
|
||||||
position: Position,
|
next: IRCodeChunkBase?): IRCodeChunkBase(label, next) {
|
||||||
next: IRCodeChunkBase?): IRCodeChunkBase(label, position, next) {
|
|
||||||
// note: no instructions, asm is in the property
|
// note: no instructions, asm is in the property
|
||||||
override fun isEmpty() = assembly.isBlank()
|
override fun isEmpty() = assembly.isBlank()
|
||||||
override fun isNotEmpty() = assembly.isNotBlank()
|
override fun isNotEmpty() = assembly.isNotBlank()
|
||||||
@ -312,8 +311,7 @@ class IRInlineAsmChunk(label: String?,
|
|||||||
|
|
||||||
class IRInlineBinaryChunk(label: String?,
|
class IRInlineBinaryChunk(label: String?,
|
||||||
val data: Collection<UByte>,
|
val data: Collection<UByte>,
|
||||||
position: Position,
|
next: IRCodeChunkBase?): IRCodeChunkBase(label, next) {
|
||||||
next: IRCodeChunkBase?): IRCodeChunkBase(label, position, next) {
|
|
||||||
// note: no instructions, data is in the property
|
// note: no instructions, data is in the property
|
||||||
override fun isEmpty() = data.isEmpty()
|
override fun isEmpty() = data.isEmpty()
|
||||||
override fun isNotEmpty() = data.isNotEmpty()
|
override fun isNotEmpty() = data.isNotEmpty()
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package prog8.vm
|
package prog8.vm
|
||||||
|
|
||||||
import prog8.code.StMemVar
|
import prog8.code.StMemVar
|
||||||
import prog8.code.core.Position
|
|
||||||
import prog8.code.target.virtual.IVirtualMachineRunner
|
import prog8.code.target.virtual.IVirtualMachineRunner
|
||||||
import prog8.intermediate.*
|
import prog8.intermediate.*
|
||||||
import java.awt.Color
|
import java.awt.Color
|
||||||
@ -51,7 +50,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
|||||||
program = VmProgramLoader().load(irProgram, memory)
|
program = VmProgramLoader().load(irProgram, memory)
|
||||||
require(irProgram.st.getAsmSymbols().isEmpty()) { "virtual machine can't yet process asmsymbols defined on command line" }
|
require(irProgram.st.getAsmSymbols().isEmpty()) { "virtual machine can't yet process asmsymbols defined on command line" }
|
||||||
cx16virtualregsBaseAddress = (irProgram.st.lookup("cx16.r0") as? StMemVar)?.address?.toInt() ?: 0xff02
|
cx16virtualregsBaseAddress = (irProgram.st.lookup("cx16.r0") as? StMemVar)?.address?.toInt() ?: 0xff02
|
||||||
pcChunk = program.firstOrNull() ?: IRCodeChunk(null, Position.DUMMY, null)
|
pcChunk = program.firstOrNull() ?: IRCodeChunk(null, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun run() {
|
fun run() {
|
||||||
@ -85,7 +84,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
|||||||
registers.reset()
|
registers.reset()
|
||||||
// memory.reset()
|
// memory.reset()
|
||||||
pcIndex = 0
|
pcIndex = 0
|
||||||
pcChunk = IRCodeChunk(null, Position.DUMMY, null)
|
pcChunk = IRCodeChunk(null, null)
|
||||||
stepCount = 0
|
stepCount = 0
|
||||||
callStack.clear()
|
callStack.clear()
|
||||||
statusCarry = false
|
statusCarry = false
|
||||||
|
@ -2,7 +2,6 @@ package prog8.vm
|
|||||||
|
|
||||||
import prog8.code.core.AssemblyError
|
import prog8.code.core.AssemblyError
|
||||||
import prog8.code.core.DataType
|
import prog8.code.core.DataType
|
||||||
import prog8.code.core.Position
|
|
||||||
import prog8.intermediate.*
|
import prog8.intermediate.*
|
||||||
|
|
||||||
class VmProgramLoader {
|
class VmProgramLoader {
|
||||||
@ -25,7 +24,7 @@ class VmProgramLoader {
|
|||||||
// make sure that if there is a "main.start" entrypoint, we jump to it
|
// make sure that if there is a "main.start" entrypoint, we jump to it
|
||||||
irProgram.blocks.firstOrNull()?.let {
|
irProgram.blocks.firstOrNull()?.let {
|
||||||
if(it.subroutines.any { sub -> sub.name=="main.start" }) {
|
if(it.subroutines.any { sub -> sub.name=="main.start" }) {
|
||||||
val chunk = IRCodeChunk(null, Position.DUMMY, null)
|
val chunk = IRCodeChunk(null, null)
|
||||||
placeholders[Pair(chunk, 0)] = "main.start"
|
placeholders[Pair(chunk, 0)] = "main.start"
|
||||||
chunk += IRInstruction(Opcode.JUMP, labelSymbol = "main.start")
|
chunk += IRInstruction(Opcode.JUMP, labelSymbol = "main.start")
|
||||||
programChunks += chunk
|
programChunks += chunk
|
||||||
@ -276,7 +275,7 @@ class VmProgramLoader {
|
|||||||
symbolAddresses: MutableMap<String, Int>,
|
symbolAddresses: MutableMap<String, Int>,
|
||||||
): Pair<IRCodeChunkBase, IRCodeChunk> {
|
): Pair<IRCodeChunkBase, IRCodeChunk> {
|
||||||
if(asmChunk.isIR) {
|
if(asmChunk.isIR) {
|
||||||
val chunk = IRCodeChunk(asmChunk.label, asmChunk.position, asmChunk.next)
|
val chunk = IRCodeChunk(asmChunk.label, asmChunk.next)
|
||||||
asmChunk.assembly.lineSequence().forEach {
|
asmChunk.assembly.lineSequence().forEach {
|
||||||
val parsed = parseIRCodeLine(it.trim(), Pair(chunk, chunk.instructions.size), placeholders)
|
val parsed = parseIRCodeLine(it.trim(), Pair(chunk, chunk.instructions.size), placeholders)
|
||||||
parsed.fold(
|
parsed.fold(
|
||||||
@ -287,7 +286,7 @@ class VmProgramLoader {
|
|||||||
chunks += chunk
|
chunks += chunk
|
||||||
return Pair(asmChunk, chunk)
|
return Pair(asmChunk, chunk)
|
||||||
} else {
|
} else {
|
||||||
throw IRParseException("vm currently does not support real inlined assembly (only IR): ${asmChunk.position}")
|
throw IRParseException("vm currently does not support real inlined assembly (only IR): ${asmChunk.label}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ class TestVm: FunSpec( {
|
|||||||
val program = IRProgram("test", IRSymbolTable(null), getTestOptions(), VMTarget())
|
val program = IRProgram("test", IRSymbolTable(null), getTestOptions(), VMTarget())
|
||||||
val block = IRBlock("testmain", null, IRBlock.BlockAlignment.NONE, Position.DUMMY)
|
val block = IRBlock("testmain", null, IRBlock.BlockAlignment.NONE, Position.DUMMY)
|
||||||
val startSub = IRSubroutine("testmain.testsub", emptyList(), null, Position.DUMMY)
|
val startSub = IRSubroutine("testmain.testsub", emptyList(), null, Position.DUMMY)
|
||||||
val code = IRCodeChunk(startSub.name, Position.DUMMY, null)
|
val code = IRCodeChunk(startSub.name, null)
|
||||||
code += IRInstruction(Opcode.NOP)
|
code += IRInstruction(Opcode.NOP)
|
||||||
code += IRInstruction(Opcode.LOAD, IRDataType.WORD, reg1=1, value=12345)
|
code += IRInstruction(Opcode.LOAD, IRDataType.WORD, reg1=1, value=12345)
|
||||||
code += IRInstruction(Opcode.STOREM, IRDataType.WORD, reg1=1, value=1000)
|
code += IRInstruction(Opcode.STOREM, IRDataType.WORD, reg1=1, value=1000)
|
||||||
@ -70,7 +70,7 @@ class TestVm: FunSpec( {
|
|||||||
val program = IRProgram("test", IRSymbolTable(null), getTestOptions(), VMTarget())
|
val program = IRProgram("test", IRSymbolTable(null), getTestOptions(), VMTarget())
|
||||||
val block = IRBlock("testmain", null, IRBlock.BlockAlignment.NONE, Position.DUMMY)
|
val block = IRBlock("testmain", null, IRBlock.BlockAlignment.NONE, Position.DUMMY)
|
||||||
val startSub = IRSubroutine("testmain.testsub", emptyList(), null, Position.DUMMY)
|
val startSub = IRSubroutine("testmain.testsub", emptyList(), null, Position.DUMMY)
|
||||||
val code = IRCodeChunk(startSub.name, Position.DUMMY, null)
|
val code = IRCodeChunk(startSub.name, null)
|
||||||
code += IRInstruction(Opcode.BINARYDATA, binaryData = listOf(1u,2u,3u))
|
code += IRInstruction(Opcode.BINARYDATA, binaryData = listOf(1u,2u,3u))
|
||||||
code += IRInstruction(Opcode.RETURN)
|
code += IRInstruction(Opcode.RETURN)
|
||||||
startSub += code
|
startSub += code
|
||||||
@ -91,7 +91,7 @@ class TestVm: FunSpec( {
|
|||||||
emptySet(),
|
emptySet(),
|
||||||
emptyList(),
|
emptyList(),
|
||||||
emptyList(),
|
emptyList(),
|
||||||
IRInlineAsmChunk("main.asmstart", "inlined asm here", false, Position.DUMMY, null),
|
IRInlineAsmChunk("main.asmstart", "inlined asm here", false, null),
|
||||||
Position.DUMMY
|
Position.DUMMY
|
||||||
)
|
)
|
||||||
block += startSub
|
block += startSub
|
||||||
@ -110,7 +110,7 @@ class TestVm: FunSpec( {
|
|||||||
emptySet(),
|
emptySet(),
|
||||||
emptyList(),
|
emptyList(),
|
||||||
emptyList(),
|
emptyList(),
|
||||||
IRInlineAsmChunk("main.start", "return", true, Position.DUMMY, null),
|
IRInlineAsmChunk("main.start", "return", true, null),
|
||||||
Position.DUMMY
|
Position.DUMMY
|
||||||
)
|
)
|
||||||
block += startSub
|
block += startSub
|
||||||
|
Loading…
Reference in New Issue
Block a user