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