mirror of
https://github.com/irmen/prog8.git
synced 2025-02-21 10:29:03 +00:00
ir: tweak register pool, prepare to register the types there uniquely
This commit is contained in:
parent
76b29aa629
commit
c8996418da
@ -139,7 +139,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
if(constAddress==null && memory!=null) {
|
||||
val register = codeGen.registers.nextFree()
|
||||
val register = codeGen.registers.next()
|
||||
val tr = expressionEval.translateExpression(memory.address)
|
||||
addToResult(result, tr, tr.resultReg, -1)
|
||||
when(operator) {
|
||||
@ -163,7 +163,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
"-" -> addInstr(result, IRInstruction(Opcode.NEGM, vmDt, address = constAddress, labelSymbol = symbol), null)
|
||||
"~" -> addInstr(result, IRInstruction(Opcode.INVM, vmDt, address = constAddress, labelSymbol = symbol), null)
|
||||
"not" -> {
|
||||
val regMask = codeGen.registers.nextFree()
|
||||
val regMask = codeGen.registers.next()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOAD, vmDt, reg1=regMask, immediate = 1)
|
||||
it += IRInstruction(Opcode.XORM, vmDt, reg1=regMask, address = constAddress, labelSymbol = symbol)
|
||||
@ -202,8 +202,8 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
addInstr(result, IRInstruction(Opcode.NEGM, IRDataType.BYTE, labelSymbol = array.variable.name+"_msb", symbolOffset = constIndex), skipCarryLabel)
|
||||
} else {
|
||||
val indexReg = loadIndex()
|
||||
val registerLsb = codeGen.registers.nextFree()
|
||||
val registerMsb = codeGen.registers.nextFree()
|
||||
val registerLsb = codeGen.registers.next()
|
||||
val registerMsb = codeGen.registers.next()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOADX, IRDataType.BYTE, reg1 = registerLsb, reg2 = indexReg, labelSymbol = array.variable.name+"_lsb")
|
||||
it += IRInstruction(Opcode.NEG, IRDataType.BYTE, reg1 = registerLsb)
|
||||
@ -225,7 +225,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
addInstr(result, IRInstruction(Opcode.INVM, IRDataType.BYTE, labelSymbol = array.variable.name+"_msb", symbolOffset = constIndex), null)
|
||||
} else {
|
||||
val indexReg = loadIndex()
|
||||
val register = codeGen.registers.nextFree()
|
||||
val register = codeGen.registers.next()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOADX, IRDataType.BYTE, reg1 = register, reg2 = indexReg, labelSymbol = array.variable.name+"_lsb")
|
||||
it += IRInstruction(Opcode.INV, IRDataType.BYTE, reg1 = register)
|
||||
@ -250,7 +250,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
addInstr(result, IRInstruction(Opcode.NEGM, vmDt, labelSymbol = array.variable.name, symbolOffset = constIndex*eltSize), null)
|
||||
} else {
|
||||
val indexReg = loadIndex()
|
||||
val register = codeGen.registers.nextFree()
|
||||
val register = codeGen.registers.next()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOADX, vmDt, reg1 = register, reg2 = indexReg, labelSymbol = array.variable.name)
|
||||
it += IRInstruction(Opcode.NEG, vmDt, reg1 = register)
|
||||
@ -263,7 +263,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
addInstr(result, IRInstruction(Opcode.INVM, vmDt, labelSymbol = array.variable.name, symbolOffset = constIndex*eltSize), null)
|
||||
} else {
|
||||
val indexReg = loadIndex()
|
||||
val register = codeGen.registers.nextFree()
|
||||
val register = codeGen.registers.next()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOADX, vmDt, reg1 = register, reg2 = indexReg, labelSymbol = array.variable.name)
|
||||
it += IRInstruction(Opcode.INV, vmDt, reg1 = register)
|
||||
@ -272,7 +272,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
}
|
||||
}
|
||||
"not" -> {
|
||||
val register = codeGen.registers.nextFree()
|
||||
val register = codeGen.registers.next()
|
||||
if(constIndex!=null) {
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOAD, vmDt, reg1=register, immediate = 1)
|
||||
@ -321,7 +321,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
if (assignment.value is PtIrRegister) {
|
||||
valueRegister = (assignment.value as PtIrRegister).register
|
||||
if(extendByteToWord) {
|
||||
valueRegister = codeGen.registers.nextFree()
|
||||
valueRegister = codeGen.registers.next()
|
||||
addInstr(result, IRInstruction(Opcode.EXT, IRDataType.BYTE, reg1=valueRegister, reg2=(assignment.value as PtIrRegister).register), null)
|
||||
}
|
||||
} else {
|
||||
@ -329,7 +329,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
valueRegister = tr.resultReg
|
||||
addToResult(result, tr, valueRegister, -1)
|
||||
if(extendByteToWord) {
|
||||
valueRegister = codeGen.registers.nextFree()
|
||||
valueRegister = codeGen.registers.next()
|
||||
val opcode = if(assignment.value.type.isSigned) Opcode.EXTS else Opcode.EXT
|
||||
addInstr(result, IRInstruction(opcode, IRDataType.BYTE, reg1=valueRegister, reg2=tr.resultReg), null)
|
||||
}
|
||||
@ -397,7 +397,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
if(fixedIndex!=null) {
|
||||
val chunk = IRCodeChunk(null, null).also {
|
||||
if(targetArray.splitWords) {
|
||||
val lsbmsbReg = codeGen.registers.nextFree()
|
||||
val lsbmsbReg = codeGen.registers.next()
|
||||
it += IRInstruction(Opcode.LSIG, IRDataType.BYTE, reg1 = lsbmsbReg, reg2 = valueRegister)
|
||||
it += IRInstruction(Opcode.STOREM, IRDataType.BYTE, reg1 = lsbmsbReg, immediate = arrayLength, labelSymbol = "${variable}_lsb", symbolOffset = fixedIndex)
|
||||
it += IRInstruction(Opcode.MSIG, IRDataType.BYTE, reg1 = lsbmsbReg, reg2 = valueRegister)
|
||||
@ -412,7 +412,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
result += code
|
||||
result += IRCodeChunk(null, null).also {
|
||||
if(targetArray.splitWords) {
|
||||
val lsbmsbReg = codeGen.registers.nextFree()
|
||||
val lsbmsbReg = codeGen.registers.next()
|
||||
it += IRInstruction(Opcode.LSIG, IRDataType.BYTE, reg1 = lsbmsbReg, reg2 = valueRegister)
|
||||
it += IRInstruction(Opcode.STOREX, IRDataType.BYTE, reg1 = lsbmsbReg, reg2=indexReg, immediate = arrayLength, labelSymbol = "${variable}_lsb")
|
||||
it += IRInstruction(Opcode.MSIG, IRDataType.BYTE, reg1 = lsbmsbReg, reg2 = valueRegister)
|
||||
@ -451,7 +451,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
if((ptrWithOffset.right as? PtNumber)?.number?.toInt() in 0..255) {
|
||||
// STOREIX only works with byte index.
|
||||
val ptrName = (ptrWithOffset.left as PtIdentifier).name
|
||||
val offsetReg = codeGen.registers.nextFree()
|
||||
val offsetReg = codeGen.registers.next()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=offsetReg, immediate = ptrWithOffset.right.asConstInteger())
|
||||
it += IRInstruction(Opcode.STOREIX, IRDataType.BYTE, reg1=valueRegister, reg2=offsetReg, labelSymbol = ptrName)
|
||||
@ -510,8 +510,8 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
val eltSize = codeGen.program.memsizer.memorySize(array.type, null)
|
||||
if(constIndex!=null && constValue!=null) {
|
||||
if(array.splitWords) {
|
||||
val valueRegLsb = codeGen.registers.nextFree()
|
||||
val valueRegMsb = codeGen.registers.nextFree()
|
||||
val valueRegLsb = codeGen.registers.next()
|
||||
val valueRegMsb = codeGen.registers.next()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOAD, vmDt, reg1=valueRegLsb, immediate=constValue and 255)
|
||||
it += IRInstruction(Opcode.LOAD, vmDt, reg1=valueRegMsb, immediate=constValue shr 8)
|
||||
@ -519,7 +519,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
it += IRInstruction(Opcode.ANDM, vmDt, reg1=valueRegMsb, labelSymbol = array.variable.name+"_msb", symbolOffset = constIndex)
|
||||
}
|
||||
} else {
|
||||
val valueReg = codeGen.registers.nextFree()
|
||||
val valueReg = codeGen.registers.next()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOAD, vmDt, reg1=valueReg, immediate=constValue)
|
||||
it += IRInstruction(Opcode.ANDM, vmDt, reg1=valueReg, labelSymbol = array.variable.name, symbolOffset = constIndex*eltSize)
|
||||
@ -550,8 +550,8 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
val eltSize = codeGen.program.memsizer.memorySize(array.type, null)
|
||||
if(constIndex!=null && constValue!=null) {
|
||||
if(array.splitWords) {
|
||||
val valueRegLsb = codeGen.registers.nextFree()
|
||||
val valueRegMsb = codeGen.registers.nextFree()
|
||||
val valueRegLsb = codeGen.registers.next()
|
||||
val valueRegMsb = codeGen.registers.next()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOAD, vmDt, reg1=valueRegLsb, immediate=constValue and 255)
|
||||
it += IRInstruction(Opcode.LOAD, vmDt, reg1=valueRegMsb, immediate=constValue shr 8)
|
||||
@ -559,7 +559,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
it += IRInstruction(Opcode.ANDM, vmDt, reg1=valueRegMsb, labelSymbol = array.variable.name+"_msb", symbolOffset = constIndex)
|
||||
}
|
||||
} else {
|
||||
val valueReg = codeGen.registers.nextFree()
|
||||
val valueReg = codeGen.registers.next()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOAD, vmDt, reg1=valueReg, immediate=constValue)
|
||||
it += IRInstruction(Opcode.ANDM, vmDt, reg1=valueReg, labelSymbol = array.variable.name, symbolOffset = constIndex*eltSize)
|
||||
@ -576,7 +576,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
val tr = expressionEval.translateExpression(operand)
|
||||
if(!operand.isSimple()) {
|
||||
// short-circuit LEFT and RIGHT --> if LEFT then RIGHT else LEFT (== if !LEFT then LEFT else RIGHT)
|
||||
val inplaceReg = codeGen.registers.nextFree()
|
||||
val inplaceReg = codeGen.registers.next()
|
||||
val shortcutLabel = codeGen.createLabelName()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += if(constAddress!=null)
|
||||
@ -610,8 +610,8 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
val eltSize = codeGen.program.memsizer.memorySize(array.type, null)
|
||||
if(constIndex!=null && constValue!=null) {
|
||||
if(array.splitWords) {
|
||||
val valueRegLsb = codeGen.registers.nextFree()
|
||||
val valueRegMsb = codeGen.registers.nextFree()
|
||||
val valueRegLsb = codeGen.registers.next()
|
||||
val valueRegMsb = codeGen.registers.next()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOAD, vmDt, reg1=valueRegLsb, immediate=constValue and 255)
|
||||
it += IRInstruction(Opcode.LOAD, vmDt, reg1=valueRegMsb, immediate=constValue shr 8)
|
||||
@ -619,7 +619,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
it += IRInstruction(Opcode.ORM, vmDt, reg1=valueRegMsb, labelSymbol = array.variable.name+"_msb", symbolOffset = constIndex)
|
||||
}
|
||||
} else {
|
||||
val valueReg = codeGen.registers.nextFree()
|
||||
val valueReg = codeGen.registers.next()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOAD, vmDt, reg1=valueReg, immediate=constValue)
|
||||
it += IRInstruction(Opcode.ORM, vmDt, reg1=valueReg, labelSymbol = array.variable.name, symbolOffset = constIndex*eltSize)
|
||||
@ -650,8 +650,8 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
val eltSize = codeGen.program.memsizer.memorySize(array.type, null)
|
||||
if(constIndex!=null && constValue!=null) {
|
||||
if(array.splitWords) {
|
||||
val valueRegLsb = codeGen.registers.nextFree()
|
||||
val valueRegMsb = codeGen.registers.nextFree()
|
||||
val valueRegLsb = codeGen.registers.next()
|
||||
val valueRegMsb = codeGen.registers.next()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOAD, vmDt, reg1=valueRegLsb, immediate=constValue and 255)
|
||||
it += IRInstruction(Opcode.LOAD, vmDt, reg1=valueRegMsb, immediate=constValue shr 8)
|
||||
@ -659,7 +659,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
it += IRInstruction(Opcode.ORM, vmDt, reg1=valueRegMsb, labelSymbol = array.variable.name+"_msb", symbolOffset = constIndex)
|
||||
}
|
||||
} else {
|
||||
val valueReg = codeGen.registers.nextFree()
|
||||
val valueReg = codeGen.registers.next()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOAD, vmDt, reg1=valueReg, immediate=constValue)
|
||||
it += IRInstruction(Opcode.ORM, vmDt, reg1=valueReg, labelSymbol = array.variable.name, symbolOffset = constIndex*eltSize)
|
||||
@ -676,7 +676,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
val tr = expressionEval.translateExpression(operand)
|
||||
if(!operand.isSimple()) {
|
||||
// short-circuit LEFT or RIGHT --> if LEFT then LEFT else RIGHT
|
||||
val inplaceReg = codeGen.registers.nextFree()
|
||||
val inplaceReg = codeGen.registers.next()
|
||||
val shortcutLabel = codeGen.createLabelName()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += if(constAddress!=null)
|
||||
@ -768,7 +768,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
val constValue = operand.asConstInteger()
|
||||
if(constIndex!=null && constValue!=null) {
|
||||
if(constValue!=1) {
|
||||
val valueReg=codeGen.registers.nextFree()
|
||||
val valueReg=codeGen.registers.next()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOAD, eltDt, reg1=valueReg, immediate = constValue)
|
||||
it += IRInstruction(Opcode.MULM, eltDt, reg1=valueReg, labelSymbol = array.variable.name, symbolOffset = constIndex*eltSize)
|
||||
@ -826,7 +826,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
if(constValue==1) {
|
||||
addInstr(result, IRInstruction(Opcode.DECM, eltDt, labelSymbol = array.variable.name, symbolOffset = constIndex*eltSize), null)
|
||||
} else {
|
||||
val valueReg=codeGen.registers.nextFree()
|
||||
val valueReg=codeGen.registers.next()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOAD, eltDt, reg1=valueReg, immediate = constValue)
|
||||
it += IRInstruction(Opcode.SUBM, eltDt, reg1=valueReg, labelSymbol = array.variable.name, symbolOffset = constIndex*eltSize)
|
||||
@ -889,7 +889,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
if(constIndex!=null) {
|
||||
val skip = codeGen.createLabelName()
|
||||
if(constValue==1) {
|
||||
val lsbReg = codeGen.registers.nextFree()
|
||||
val lsbReg = codeGen.registers.next()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = lsbReg, labelSymbol = array.variable.name+"_lsb", symbolOffset = constIndex)
|
||||
it += IRInstruction(Opcode.BSTNE, labelSymbol = skip)
|
||||
@ -919,7 +919,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
if(constValue==1) {
|
||||
addInstr(result, IRInstruction(Opcode.INCM, elementDt, labelSymbol = array.variable.name, symbolOffset = constIndex*eltSize), null)
|
||||
} else {
|
||||
val valueReg=codeGen.registers.nextFree()
|
||||
val valueReg=codeGen.registers.next()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOAD, elementDt, reg1=valueReg, immediate = constValue)
|
||||
it += IRInstruction(Opcode.ADDM, elementDt, reg1=valueReg, labelSymbol = array.variable.name, symbolOffset = constIndex*eltSize)
|
||||
@ -1054,8 +1054,8 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
val eltSize = codeGen.program.memsizer.memorySize(array.type, null)
|
||||
if(constIndex!=null && constValue!=null) {
|
||||
if(array.splitWords) {
|
||||
val valueRegLsb = codeGen.registers.nextFree()
|
||||
val valueRegMsb = codeGen.registers.nextFree()
|
||||
val valueRegLsb = codeGen.registers.next()
|
||||
val valueRegMsb = codeGen.registers.next()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOAD, vmDt, reg1=valueRegLsb, immediate=constValue and 255)
|
||||
it += IRInstruction(Opcode.LOAD, vmDt, reg1=valueRegMsb, immediate=constValue shr 8)
|
||||
@ -1063,7 +1063,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
it += IRInstruction(Opcode.XORM, vmDt, reg1=valueRegMsb, labelSymbol = array.variable.name+"_msb", symbolOffset = constIndex)
|
||||
}
|
||||
} else {
|
||||
val valueReg = codeGen.registers.nextFree()
|
||||
val valueReg = codeGen.registers.next()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOAD, vmDt, reg1=valueReg, immediate=constValue)
|
||||
it += IRInstruction(Opcode.XORM, vmDt, reg1=valueReg, labelSymbol = array.variable.name, symbolOffset = constIndex*eltSize)
|
||||
@ -1095,7 +1095,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
return null // TODO("optimized memory in-place %"")
|
||||
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
val resultReg = codeGen.registers.nextFree()
|
||||
val resultReg = codeGen.registers.next()
|
||||
if(operand is PtNumber) {
|
||||
val number = operand.number.toInt()
|
||||
if (constAddress != null) {
|
||||
|
@ -54,12 +54,12 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
val valueTr = exprGen.translateExpression(call.args[0])
|
||||
addToResult(result, valueTr, valueTr.resultReg, valueTr.resultFpReg)
|
||||
return if(resultType==IRDataType.FLOAT) {
|
||||
val resultFpReg = codeGen.registers.nextFreeFloat()
|
||||
val resultFpReg = codeGen.registers.next(IRDataType.FLOAT)
|
||||
addInstr(result, IRInstruction(Opcode.SQUARE, resultType, fpReg1 = resultFpReg, fpReg2 = valueTr.resultFpReg), null)
|
||||
ExpressionCodeResult(result, resultType, -1, resultFpReg)
|
||||
}
|
||||
else {
|
||||
val resultReg = codeGen.registers.nextFree()
|
||||
val resultReg = codeGen.registers.next()
|
||||
addInstr(result, IRInstruction(Opcode.SQUARE, resultType, reg1 = resultReg, reg2 = valueTr.resultReg), null)
|
||||
ExpressionCodeResult(result, resultType, resultReg, -1)
|
||||
}
|
||||
@ -73,7 +73,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
return if(call.void)
|
||||
ExpressionCodeResult(result, IRDataType.BYTE, -1, -1)
|
||||
else
|
||||
ExpressionCodeResult(result, IRDataType.WORD, codeGen.registers.nextFree(), -1) // TODO actually the result is returned in CPU registers AY...
|
||||
ExpressionCodeResult(result, IRDataType.WORD, codeGen.registers.next(), -1) // TODO actually the result is returned in CPU registers AY...
|
||||
}
|
||||
|
||||
private fun funcCallfar(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||
@ -123,7 +123,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
addToResult(result, tr, tr.resultReg, -1)
|
||||
addInstr(result, IRInstruction(Opcode.DIVMOD, type, reg1 = tr.resultReg, immediate = divident.number.toInt()), null)
|
||||
divisionReg = tr.resultReg
|
||||
remainderReg = codeGen.registers.nextFree()
|
||||
remainderReg = codeGen.registers.next()
|
||||
} else {
|
||||
val numTr = exprGen.translateExpression(number)
|
||||
addToResult(result, numTr, numTr.resultReg, -1)
|
||||
@ -148,7 +148,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
val right = exprGen.translateExpression(call.args[1])
|
||||
addToResult(result, left, left.resultReg, -1)
|
||||
addToResult(result, right, right.resultReg, -1)
|
||||
val resultReg = codeGen.registers.nextFree()
|
||||
val resultReg = codeGen.registers.next()
|
||||
result += codeGen.makeSyscall(IMSyscall.COMPARE_STRINGS, listOf(IRDataType.WORD to left.resultReg, IRDataType.WORD to right.resultReg), IRDataType.BYTE to resultReg)
|
||||
return ExpressionCodeResult(result, IRDataType.BYTE, resultReg, -1)
|
||||
}
|
||||
@ -177,7 +177,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
when (sourceDt.base) {
|
||||
BaseDataType.BYTE -> {
|
||||
val notNegativeLabel = codeGen.createLabelName()
|
||||
val compareReg = codeGen.registers.nextFree()
|
||||
val compareReg = codeGen.registers.next()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOADR, IRDataType.BYTE, reg1=compareReg, reg2=tr.resultReg)
|
||||
it += IRInstruction(Opcode.BSTPOS, labelSymbol = notNegativeLabel)
|
||||
@ -188,7 +188,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
}
|
||||
BaseDataType.WORD -> {
|
||||
val notNegativeLabel = codeGen.createLabelName()
|
||||
val compareReg = codeGen.registers.nextFree()
|
||||
val compareReg = codeGen.registers.next()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOADR, IRDataType.WORD, reg1=compareReg, reg2=tr.resultReg)
|
||||
it += IRInstruction(Opcode.BSTPOS, labelSymbol = notNegativeLabel)
|
||||
@ -198,7 +198,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
return ExpressionCodeResult(result, IRDataType.WORD, tr.resultReg, -1)
|
||||
}
|
||||
BaseDataType.FLOAT -> {
|
||||
val resultFpReg = codeGen.registers.nextFreeFloat()
|
||||
val resultFpReg = codeGen.registers.next(IRDataType.FLOAT)
|
||||
addInstr(result, IRInstruction(Opcode.FABS, IRDataType.FLOAT, fpReg1 = resultFpReg, fpReg2 = tr.resultFpReg), null)
|
||||
return ExpressionCodeResult(result, IRDataType.FLOAT, -1, resultFpReg)
|
||||
}
|
||||
@ -209,7 +209,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
private fun funcSgn(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
val tr = exprGen.translateExpression(call.args.single())
|
||||
val resultReg = codeGen.registers.nextFree()
|
||||
val resultReg = codeGen.registers.next()
|
||||
|
||||
if(tr.dt==IRDataType.FLOAT) {
|
||||
addToResult(result, tr, -1, tr.resultFpReg)
|
||||
@ -232,7 +232,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
when(dt.base) {
|
||||
BaseDataType.UBYTE -> {
|
||||
addToResult(result, tr, tr.resultReg, -1)
|
||||
val resultReg = codeGen.registers.nextFree()
|
||||
val resultReg = codeGen.registers.next()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.SQRT, IRDataType.BYTE, reg1=resultReg, reg2=tr.resultReg)
|
||||
}
|
||||
@ -240,7 +240,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
}
|
||||
BaseDataType.UWORD -> {
|
||||
addToResult(result, tr, tr.resultReg, -1)
|
||||
val resultReg = codeGen.registers.nextFree()
|
||||
val resultReg = codeGen.registers.next()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.SQRT, IRDataType.WORD, reg1=resultReg, reg2=tr.resultReg)
|
||||
}
|
||||
@ -248,7 +248,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
}
|
||||
BaseDataType.FLOAT -> {
|
||||
addToResult(result, tr, -1, tr.resultFpReg)
|
||||
val resultFpReg = codeGen.registers.nextFreeFloat()
|
||||
val resultFpReg = codeGen.registers.next(IRDataType.FLOAT)
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.SQRT, IRDataType.FLOAT, fpReg1 = resultFpReg, fpReg2 = tr.resultFpReg)
|
||||
}
|
||||
@ -260,7 +260,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
|
||||
private fun funcMkword(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
val resultReg = codeGen.registers.nextFree()
|
||||
val resultReg = codeGen.registers.next()
|
||||
if((call.args[0] as? PtNumber)?.number == 0.0) {
|
||||
// msb is 0, use EXT
|
||||
val lsbTr = exprGen.translateExpression(call.args[1])
|
||||
@ -405,7 +405,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
return if(dt==IRDataType.FLOAT) {
|
||||
if(call.args[0] is PtNumber) {
|
||||
val resultFpRegister = codeGen.registers.nextFreeFloat()
|
||||
val resultFpRegister = codeGen.registers.next(IRDataType.FLOAT)
|
||||
val address = (call.args[0] as PtNumber).number.toInt()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOADM, IRDataType.FLOAT, fpReg1 = resultFpRegister, address = address)
|
||||
@ -414,7 +414,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
} else {
|
||||
val tr = exprGen.translateExpression(call.args.single())
|
||||
addToResult(result, tr, tr.resultReg, -1)
|
||||
val resultFpReg = codeGen.registers.nextFreeFloat()
|
||||
val resultFpReg = codeGen.registers.next(IRDataType.FLOAT)
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOADI, IRDataType.FLOAT, reg1 = tr.resultReg, fpReg1 = resultFpReg)
|
||||
}
|
||||
@ -422,7 +422,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
}
|
||||
} else {
|
||||
if (call.args[0] is PtNumber) {
|
||||
val resultRegister = codeGen.registers.nextFree()
|
||||
val resultRegister = codeGen.registers.next()
|
||||
val address = (call.args[0] as PtNumber).number.toInt()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOADM, dt, reg1 = resultRegister, address = address)
|
||||
@ -431,7 +431,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
} else {
|
||||
val tr = exprGen.translateExpression(call.args.single())
|
||||
addToResult(result, tr, tr.resultReg, -1)
|
||||
val resultReg = codeGen.registers.nextFree()
|
||||
val resultReg = codeGen.registers.next()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOADI, dt, reg1 = resultReg, reg2 = tr.resultReg)
|
||||
}
|
||||
@ -473,7 +473,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
}
|
||||
|
||||
return if(address is PtNumber) {
|
||||
val resultRegister = codeGen.registers.nextFree()
|
||||
val resultRegister = codeGen.registers.next()
|
||||
val addressNum = address.number.toInt()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOADM, IRDataType.BYTE, reg1 = resultRegister, address = addressNum)
|
||||
@ -483,7 +483,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
} else {
|
||||
val addressTr = exprGen.translateExpression(address)
|
||||
addToResult(result, addressTr, addressTr.resultReg, -1)
|
||||
val resultReg = codeGen.registers.nextFree()
|
||||
val resultReg = codeGen.registers.next()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOADI, IRDataType.BYTE, reg1 = resultReg, reg2 = addressTr.resultReg)
|
||||
}
|
||||
@ -496,7 +496,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
private fun funcMemory(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||
val name = (call.args[0] as PtString).value
|
||||
val code = IRCodeChunk(null, null)
|
||||
val resultReg = codeGen.registers.nextFree()
|
||||
val resultReg = codeGen.registers.next()
|
||||
code += IRInstruction(Opcode.LOAD, IRDataType.WORD, reg1=resultReg, labelSymbol = "prog8_slabs.prog8_memoryslab_$name")
|
||||
return ExpressionCodeResult(code, IRDataType.BYTE, resultReg, -1)
|
||||
}
|
||||
@ -505,7 +505,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
val tr = exprGen.translateExpression(call.args.single())
|
||||
addToResult(result, tr, tr.resultReg, -1)
|
||||
val resultReg = codeGen.registers.nextFree()
|
||||
val resultReg = codeGen.registers.next()
|
||||
addInstr(result, IRInstruction(Opcode.LSIG, IRDataType.BYTE, reg1 = resultReg, reg2 = tr.resultReg), null)
|
||||
// note: if a word result is needed, the upper byte is cleared by the typecast that follows. No need to do it here.
|
||||
return ExpressionCodeResult(result, IRDataType.BYTE, resultReg, -1)
|
||||
@ -515,7 +515,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
val tr = exprGen.translateExpression(call.args.single())
|
||||
addToResult(result, tr, tr.resultReg, -1)
|
||||
val resultReg = codeGen.registers.nextFree()
|
||||
val resultReg = codeGen.registers.next()
|
||||
addInstr(result, IRInstruction(Opcode.MSIG, IRDataType.BYTE, reg1 = resultReg, reg2 = tr.resultReg), null)
|
||||
// note: if a word result is needed, the upper byte is cleared by the typecast that follows. No need to do it here.
|
||||
return ExpressionCodeResult(result, IRDataType.BYTE, resultReg, -1)
|
||||
@ -580,7 +580,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
is PtIdentifier -> {
|
||||
if(isConstZeroValue) {
|
||||
result += IRCodeChunk(null, null).also {
|
||||
val pointerReg = codeGen.registers.nextFree()
|
||||
val pointerReg = codeGen.registers.next()
|
||||
it += IRInstruction(Opcode.LOAD, IRDataType.WORD, reg1 = pointerReg, labelSymbol = target.name)
|
||||
if (msb)
|
||||
it += IRInstruction(Opcode.INC, IRDataType.WORD, reg1 = pointerReg)
|
||||
@ -590,7 +590,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
val valueTr = exprGen.translateExpression(call.args[1])
|
||||
addToResult(result, valueTr, valueTr.resultReg, -1)
|
||||
result += IRCodeChunk(null, null).also {
|
||||
val pointerReg = codeGen.registers.nextFree()
|
||||
val pointerReg = codeGen.registers.next()
|
||||
it += IRInstruction(Opcode.LOAD, IRDataType.WORD, reg1 = pointerReg, labelSymbol = target.name)
|
||||
if (msb)
|
||||
it += IRInstruction(Opcode.INC, IRDataType.WORD, reg1 = pointerReg)
|
||||
@ -605,7 +605,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
val varName = target.variable.name + if(msb) "_msb" else "_lsb"
|
||||
if(isConstZeroValue) {
|
||||
if(constIndex!=null) {
|
||||
val offsetReg = codeGen.registers.nextFree()
|
||||
val offsetReg = codeGen.registers.next()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=offsetReg, immediate = constIndex)
|
||||
it += IRInstruction(Opcode.STOREZX, IRDataType.BYTE, reg1=offsetReg, labelSymbol = varName)
|
||||
@ -621,7 +621,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
val valueTr = exprGen.translateExpression(call.args[1])
|
||||
addToResult(result, valueTr, valueTr.resultReg, -1)
|
||||
if(constIndex!=null) {
|
||||
val offsetReg = codeGen.registers.nextFree()
|
||||
val offsetReg = codeGen.registers.next()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=offsetReg, immediate = constIndex)
|
||||
it += IRInstruction(Opcode.STOREX, IRDataType.BYTE, reg1=valueTr.resultReg, reg2=offsetReg, labelSymbol = varName)
|
||||
@ -640,7 +640,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
val constIndex = target.index.asConstInteger()
|
||||
if(isConstZeroValue) {
|
||||
if(constIndex!=null) {
|
||||
val offsetReg = codeGen.registers.nextFree()
|
||||
val offsetReg = codeGen.registers.next()
|
||||
val offset = eltSize*constIndex + if(msb) 1 else 0
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=offsetReg, immediate = offset)
|
||||
@ -661,7 +661,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
val valueTr = exprGen.translateExpression(call.args[1])
|
||||
addToResult(result, valueTr, valueTr.resultReg, -1)
|
||||
if(constIndex!=null) {
|
||||
val offsetReg = codeGen.registers.nextFree()
|
||||
val offsetReg = codeGen.registers.next()
|
||||
val offset = eltSize*constIndex + if(msb) 1 else 0
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=offsetReg, immediate = offset)
|
||||
|
@ -33,7 +33,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
}
|
||||
is PtBool -> {
|
||||
val code = IRCodeChunk(null, null)
|
||||
val resultRegister = codeGen.registers.nextFree()
|
||||
val resultRegister = codeGen.registers.next()
|
||||
code += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = resultRegister, immediate = expr.asInt())
|
||||
ExpressionCodeResult(code, IRDataType.BYTE, resultRegister, -1)
|
||||
}
|
||||
@ -41,12 +41,12 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
val vmDt = irType(expr.type)
|
||||
val code = IRCodeChunk(null, null)
|
||||
if(vmDt==IRDataType.FLOAT) {
|
||||
val resultFpRegister = codeGen.registers.nextFreeFloat()
|
||||
val resultFpRegister = codeGen.registers.next(IRDataType.FLOAT)
|
||||
code += IRInstruction(Opcode.LOAD, vmDt, fpReg1 = resultFpRegister, immediateFp = expr.number)
|
||||
ExpressionCodeResult(code, vmDt,-1, resultFpRegister)
|
||||
}
|
||||
else {
|
||||
val resultRegister = codeGen.registers.nextFree()
|
||||
val resultRegister = codeGen.registers.next()
|
||||
code += IRInstruction(Opcode.LOAD, vmDt, reg1 = resultRegister, immediate = expr.number.toInt())
|
||||
ExpressionCodeResult(code, vmDt, resultRegister, -1)
|
||||
}
|
||||
@ -56,12 +56,12 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
if (expr.type.isPassByValue) {
|
||||
val vmDt = irType(expr.type)
|
||||
if(vmDt==IRDataType.FLOAT) {
|
||||
val resultFpRegister = codeGen.registers.nextFreeFloat()
|
||||
val resultFpRegister = codeGen.registers.next(IRDataType.FLOAT)
|
||||
code += IRInstruction(Opcode.LOADM, vmDt, fpReg1 = resultFpRegister, labelSymbol = expr.name)
|
||||
ExpressionCodeResult(code, vmDt, -1, resultFpRegister)
|
||||
}
|
||||
else {
|
||||
val resultRegister = codeGen.registers.nextFree()
|
||||
val resultRegister = codeGen.registers.next()
|
||||
code += IRInstruction(Opcode.LOADM, vmDt, reg1 = resultRegister, labelSymbol = expr.name)
|
||||
ExpressionCodeResult(code, vmDt, resultRegister, -1)
|
||||
}
|
||||
@ -69,7 +69,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
// for strings and arrays etc., load the *address* of the value instead
|
||||
// for arrays this could mean a split word array, in which case we take the address of the _lsb array which comes first
|
||||
val vmDt = if(expr.type.isUndefined) IRDataType.WORD else irType(expr.type)
|
||||
val resultRegister = codeGen.registers.nextFree()
|
||||
val resultRegister = codeGen.registers.next()
|
||||
val labelsymbol = if(expr.type.isSplitWordArray) expr.name+"_lsb" else expr.name
|
||||
code += IRInstruction(Opcode.LOAD, vmDt, reg1 = resultRegister, labelSymbol = labelsymbol)
|
||||
ExpressionCodeResult(code, vmDt, resultRegister, -1)
|
||||
@ -162,14 +162,14 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
val symbol = expr.identifier.name
|
||||
// note: LOAD <symbol> gets you the address of the symbol, whereas LOADM <symbol> would get you the value stored at that location
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
val resultRegister = codeGen.registers.nextFree()
|
||||
val resultRegister = codeGen.registers.next()
|
||||
if(expr.isFromArrayElement) {
|
||||
if(expr.identifier.type.isSplitWordArray)
|
||||
TODO("address of element of a split word array")
|
||||
addInstr(result, IRInstruction(Opcode.LOAD, vmDt, reg1 = resultRegister, labelSymbol = symbol), null)
|
||||
val indexTr2 = translateExpression(expr.arrayIndexExpr!!)
|
||||
addToResult(result, indexTr2, indexTr2.resultReg, -1)
|
||||
val indexWordReg = codeGen.registers.nextFree()
|
||||
val indexWordReg = codeGen.registers.next()
|
||||
addInstr(result, IRInstruction(Opcode.EXT, IRDataType.BYTE, reg1=indexWordReg, reg2=indexTr2.resultReg), null)
|
||||
if(expr.identifier.type.isUnsignedWord) {
|
||||
result += IRCodeChunk(null, null).also {
|
||||
@ -201,7 +201,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
|
||||
private fun translate(mem: PtMemoryByte): ExpressionCodeResult {
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
val resultRegister = codeGen.registers.nextFree()
|
||||
val resultRegister = codeGen.registers.next()
|
||||
|
||||
val constAddress = mem.address as? PtNumber
|
||||
if(constAddress!=null) {
|
||||
@ -214,7 +214,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
if((ptrWithOffset.right as? PtNumber)?.number?.toInt() in 0..255) {
|
||||
// LOADIX only works with byte index.
|
||||
val ptrName = (ptrWithOffset.left as PtIdentifier).name
|
||||
val offsetReg = codeGen.registers.nextFree()
|
||||
val offsetReg = codeGen.registers.next()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=offsetReg, immediate = ptrWithOffset.right.asConstInteger())
|
||||
it += IRInstruction(Opcode.LOADIX, IRDataType.BYTE, reg1=resultRegister, reg2=offsetReg, labelSymbol = ptrName)
|
||||
@ -259,7 +259,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
val endLabel = codeGen.createLabelName()
|
||||
val elementTr = translateExpression(check.needle)
|
||||
addToResult(result, elementTr, elementTr.resultReg, -1)
|
||||
val boolResultRegister = if(elementDt.isByteOrBool) elementTr.resultReg else codeGen.registers.nextFree()
|
||||
val boolResultRegister = if(elementDt.isByteOrBool) elementTr.resultReg else codeGen.registers.next()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
for(value in haystack){
|
||||
it += IRInstruction(Opcode.CMPI, irType(elementDt), elementTr.resultReg, immediate = value)
|
||||
@ -285,7 +285,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
addToResult(result, elementTr, elementTr.resultReg, -1)
|
||||
val iterableTr = translateExpression(haystackVar)
|
||||
addToResult(result, iterableTr, iterableTr.resultReg, -1)
|
||||
val resultReg = codeGen.registers.nextFree()
|
||||
val resultReg = codeGen.registers.next()
|
||||
result += codeGen.makeSyscall(IMSyscall.STRING_CONTAINS, listOf(IRDataType.BYTE to elementTr.resultReg, IRDataType.WORD to iterableTr.resultReg), IRDataType.BYTE to resultReg)
|
||||
addInstr(result, IRInstruction(Opcode.CMPI, IRDataType.BYTE, reg1=resultReg, immediate = 0), null)
|
||||
return ExpressionCodeResult(result, IRDataType.BYTE, resultReg, -1)
|
||||
@ -296,10 +296,10 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
addToResult(result, elementTr, elementTr.resultReg, -1)
|
||||
val iterableTr = translateExpression(haystackVar)
|
||||
addToResult(result, iterableTr, iterableTr.resultReg, -1)
|
||||
val lengthReg = codeGen.registers.nextFree()
|
||||
val lengthReg = codeGen.registers.next()
|
||||
val iterableLength = codeGen.symbolTable.getLength(haystackVar.name)
|
||||
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=lengthReg, immediate = iterableLength!!), null)
|
||||
val resultReg = codeGen.registers.nextFree()
|
||||
val resultReg = codeGen.registers.next()
|
||||
result += codeGen.makeSyscall(IMSyscall.BYTEARRAY_CONTAINS, listOf(IRDataType.BYTE to elementTr.resultReg, IRDataType.WORD to iterableTr.resultReg, IRDataType.BYTE to lengthReg), IRDataType.BYTE to resultReg)
|
||||
addInstr(result, IRInstruction(Opcode.CMPI, IRDataType.BYTE, reg1=resultReg, immediate = 0), null)
|
||||
return ExpressionCodeResult(result, IRDataType.BYTE, resultReg, -1)
|
||||
@ -310,10 +310,10 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
addToResult(result, elementTr, elementTr.resultReg, -1)
|
||||
val iterableTr = translateExpression(haystackVar)
|
||||
addToResult(result, iterableTr, iterableTr.resultReg, -1)
|
||||
val lengthReg = codeGen.registers.nextFree()
|
||||
val lengthReg = codeGen.registers.next()
|
||||
val iterableLength = codeGen.symbolTable.getLength(haystackVar.name)
|
||||
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=lengthReg, immediate = iterableLength!!), null)
|
||||
val resultReg = codeGen.registers.nextFree()
|
||||
val resultReg = codeGen.registers.next()
|
||||
result += codeGen.makeSyscall(IMSyscall.WORDARRAY_CONTAINS, listOf(IRDataType.WORD to elementTr.resultReg, IRDataType.WORD to iterableTr.resultReg, IRDataType.BYTE to lengthReg), IRDataType.BYTE to resultReg)
|
||||
addInstr(result, IRInstruction(Opcode.CMPI, IRDataType.BYTE, reg1=resultReg, immediate = 0), null)
|
||||
return ExpressionCodeResult(result, IRDataType.BYTE, resultReg, -1)
|
||||
@ -324,8 +324,8 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
addToResult(result, elementTr, -1, elementTr.resultFpReg)
|
||||
val iterableTr = translateExpression(haystackVar)
|
||||
addToResult(result, iterableTr, iterableTr.resultReg, -1)
|
||||
val lengthReg = codeGen.registers.nextFree()
|
||||
val resultReg = codeGen.registers.nextFree()
|
||||
val lengthReg = codeGen.registers.next()
|
||||
val resultReg = codeGen.registers.next()
|
||||
val iterableLength = codeGen.symbolTable.getLength(haystackVar.name)
|
||||
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=lengthReg, immediate = iterableLength!!), null)
|
||||
result += codeGen.makeSyscall(IMSyscall.FLOATARRAY_CONTAINS, listOf(IRDataType.FLOAT to elementTr.resultFpReg, IRDataType.WORD to iterableTr.resultReg, IRDataType.BYTE to lengthReg), IRDataType.BYTE to resultReg)
|
||||
@ -345,12 +345,12 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
|
||||
if(arrayIx.splitWords) {
|
||||
require(vmDt==IRDataType.WORD)
|
||||
resultRegister = codeGen.registers.nextFree()
|
||||
val finalResultReg = codeGen.registers.nextFree()
|
||||
resultRegister = codeGen.registers.next()
|
||||
val finalResultReg = codeGen.registers.next()
|
||||
if(arrayIx.index is PtNumber) {
|
||||
val memOffset = (arrayIx.index as PtNumber).number.toInt()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
val tmpRegMsb = codeGen.registers.nextFree()
|
||||
val tmpRegMsb = codeGen.registers.next()
|
||||
it += IRInstruction(Opcode.LOADM, IRDataType.BYTE, reg1=tmpRegMsb, labelSymbol= "${arrayVarSymbol}_msb", symbolOffset = memOffset)
|
||||
it += IRInstruction(Opcode.LOADM, IRDataType.BYTE, reg1=resultRegister, labelSymbol= "${arrayVarSymbol}_lsb", symbolOffset = memOffset)
|
||||
it += IRInstruction(Opcode.CONCAT, IRDataType.BYTE, reg1=finalResultReg, reg2=tmpRegMsb, reg3=resultRegister)
|
||||
@ -359,7 +359,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
val tr = translateExpression(arrayIx.index)
|
||||
addToResult(result, tr, tr.resultReg, -1)
|
||||
result += IRCodeChunk(null, null).also {
|
||||
val tmpRegMsb = codeGen.registers.nextFree()
|
||||
val tmpRegMsb = codeGen.registers.next()
|
||||
it += IRInstruction(Opcode.LOADX, IRDataType.BYTE, reg1=tmpRegMsb, reg2 = tr.resultReg, labelSymbol= "${arrayVarSymbol}_msb")
|
||||
it += IRInstruction(Opcode.LOADX, IRDataType.BYTE, reg1=resultRegister, reg2 = tr.resultReg, labelSymbol= "${arrayVarSymbol}_lsb")
|
||||
it += IRInstruction(Opcode.CONCAT, IRDataType.BYTE, reg1=finalResultReg, reg2=tmpRegMsb, reg3=resultRegister)
|
||||
@ -372,11 +372,11 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
if(arrayIx.index is PtNumber) {
|
||||
val memOffset = ((arrayIx.index as PtNumber).number.toInt() * eltSize)
|
||||
if(vmDt==IRDataType.FLOAT) {
|
||||
resultFpRegister = codeGen.registers.nextFreeFloat()
|
||||
resultFpRegister = codeGen.registers.next(IRDataType.FLOAT)
|
||||
addInstr(result, IRInstruction(Opcode.LOADM, IRDataType.FLOAT, fpReg1=resultFpRegister, labelSymbol = arrayVarSymbol, symbolOffset = memOffset), null)
|
||||
}
|
||||
else {
|
||||
resultRegister = codeGen.registers.nextFree()
|
||||
resultRegister = codeGen.registers.next()
|
||||
addInstr(result, IRInstruction(Opcode.LOADM, vmDt, reg1=resultRegister, labelSymbol = arrayVarSymbol, symbolOffset = memOffset), null)
|
||||
}
|
||||
} else {
|
||||
@ -385,11 +385,11 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
if(eltSize>1)
|
||||
result += codeGen.multiplyByConst(IRDataType.BYTE, tr.resultReg, eltSize)
|
||||
if(vmDt==IRDataType.FLOAT) {
|
||||
resultFpRegister = codeGen.registers.nextFreeFloat()
|
||||
resultFpRegister = codeGen.registers.next(IRDataType.FLOAT)
|
||||
addInstr(result, IRInstruction(Opcode.LOADX, IRDataType.FLOAT, fpReg1 = resultFpRegister, reg1=tr.resultReg, labelSymbol = arrayVarSymbol), null)
|
||||
}
|
||||
else {
|
||||
resultRegister = codeGen.registers.nextFree()
|
||||
resultRegister = codeGen.registers.next()
|
||||
addInstr(result, IRInstruction(Opcode.LOADX, vmDt, reg1=resultRegister, reg2=tr.resultReg, labelSymbol = arrayVarSymbol), null)
|
||||
}
|
||||
}
|
||||
@ -441,7 +441,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
actualResultReg2 =loadStatusAsBooleanResult(Opcode.BSTNE, result)
|
||||
}
|
||||
valueDt.isFloat -> {
|
||||
actualResultReg2 = codeGen.registers.nextFree()
|
||||
actualResultReg2 = codeGen.registers.next()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.SGN, IRDataType.FLOAT, reg1=actualResultReg2, fpReg1 = tr.resultFpReg)
|
||||
it += IRInstruction(Opcode.AND, IRDataType.BYTE, reg1=actualResultReg2, immediate = 1)
|
||||
@ -456,11 +456,11 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
actualResultReg2 = tr.resultReg
|
||||
}
|
||||
BaseDataType.UWORD, BaseDataType.WORD -> {
|
||||
actualResultReg2 = codeGen.registers.nextFree()
|
||||
actualResultReg2 = codeGen.registers.next()
|
||||
addInstr(result, IRInstruction(Opcode.LSIG, IRDataType.BYTE, reg1=actualResultReg2, reg2=tr.resultReg, immediate = 0), null)
|
||||
}
|
||||
BaseDataType.FLOAT -> {
|
||||
actualResultReg2 = codeGen.registers.nextFree()
|
||||
actualResultReg2 = codeGen.registers.next()
|
||||
addInstr(result, IRInstruction(Opcode.FTOUB, IRDataType.FLOAT, reg1=actualResultReg2, fpReg1 = tr.resultFpReg), null)
|
||||
}
|
||||
else -> throw AssemblyError("weird cast value type")
|
||||
@ -472,11 +472,11 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
actualResultReg2 = tr.resultReg
|
||||
}
|
||||
BaseDataType.UWORD, BaseDataType.WORD -> {
|
||||
actualResultReg2 = codeGen.registers.nextFree()
|
||||
actualResultReg2 = codeGen.registers.next()
|
||||
addInstr(result, IRInstruction(Opcode.LSIG, IRDataType.BYTE, reg1=actualResultReg2, reg2=tr.resultReg, immediate = 0), null)
|
||||
}
|
||||
BaseDataType.FLOAT -> {
|
||||
actualResultReg2 = codeGen.registers.nextFree()
|
||||
actualResultReg2 = codeGen.registers.next()
|
||||
addInstr(result, IRInstruction(Opcode.FTOSB, IRDataType.FLOAT, reg1=actualResultReg2, fpReg1 = tr.resultFpReg), null)
|
||||
}
|
||||
else -> throw AssemblyError("weird cast value type")
|
||||
@ -486,19 +486,19 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
when(valueDt.base) {
|
||||
BaseDataType.BYTE -> {
|
||||
// byte -> uword: sign extend
|
||||
actualResultReg2 = codeGen.registers.nextFree()
|
||||
actualResultReg2 = codeGen.registers.next()
|
||||
addInstr(result, IRInstruction(Opcode.EXTS, type = IRDataType.BYTE, reg1 = actualResultReg2, reg2 = tr.resultReg), null)
|
||||
}
|
||||
BaseDataType.BOOL, BaseDataType.UBYTE -> {
|
||||
// ubyte -> uword: sign extend
|
||||
actualResultReg2 = codeGen.registers.nextFree()
|
||||
actualResultReg2 = codeGen.registers.next()
|
||||
addInstr(result, IRInstruction(Opcode.EXT, type = IRDataType.BYTE, reg1 = actualResultReg2, reg2 = tr.resultReg), null)
|
||||
}
|
||||
BaseDataType.WORD -> {
|
||||
actualResultReg2 = tr.resultReg
|
||||
}
|
||||
BaseDataType.FLOAT -> {
|
||||
actualResultReg2 = codeGen.registers.nextFree()
|
||||
actualResultReg2 = codeGen.registers.next()
|
||||
addInstr(result, IRInstruction(Opcode.FTOUW, IRDataType.FLOAT, reg1=actualResultReg2, fpReg1 = tr.resultFpReg), null)
|
||||
}
|
||||
else -> throw AssemblyError("weird cast value type")
|
||||
@ -508,26 +508,26 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
when(valueDt.base) {
|
||||
BaseDataType.BYTE -> {
|
||||
// byte -> word: sign extend
|
||||
actualResultReg2 = codeGen.registers.nextFree()
|
||||
actualResultReg2 = codeGen.registers.next()
|
||||
addInstr(result, IRInstruction(Opcode.EXTS, type = IRDataType.BYTE, reg1 = actualResultReg2, reg2=tr.resultReg), null)
|
||||
}
|
||||
BaseDataType.BOOL, BaseDataType.UBYTE -> {
|
||||
// byte -> word: sign extend
|
||||
actualResultReg2 = codeGen.registers.nextFree()
|
||||
actualResultReg2 = codeGen.registers.next()
|
||||
addInstr(result, IRInstruction(Opcode.EXT, type = IRDataType.BYTE, reg1 = actualResultReg2, reg2=tr.resultReg), null)
|
||||
}
|
||||
BaseDataType.UWORD -> {
|
||||
actualResultReg2 = tr.resultReg
|
||||
}
|
||||
BaseDataType.FLOAT -> {
|
||||
actualResultReg2 = codeGen.registers.nextFree()
|
||||
actualResultReg2 = codeGen.registers.next()
|
||||
addInstr(result, IRInstruction(Opcode.FTOSW, IRDataType.FLOAT, reg1=actualResultReg2, fpReg1 = tr.resultFpReg), null)
|
||||
}
|
||||
else -> throw AssemblyError("weird cast value type")
|
||||
}
|
||||
}
|
||||
BaseDataType.FLOAT -> {
|
||||
actualResultFpReg2 = codeGen.registers.nextFreeFloat()
|
||||
actualResultFpReg2 = codeGen.registers.next(IRDataType.FLOAT)
|
||||
when(valueDt.base) {
|
||||
BaseDataType.BOOL, BaseDataType.UBYTE -> {
|
||||
addInstr(result, IRInstruction(Opcode.FFROMUB, IRDataType.FLOAT, reg1=tr.resultReg, fpReg1 = actualResultFpReg2), null)
|
||||
@ -636,9 +636,9 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
val returnRegSpec = if(fcall.void) null else {
|
||||
val returnIrType = irType(callTarget.returnType!!)
|
||||
if(returnIrType==IRDataType.FLOAT)
|
||||
FunctionCallArgs.RegSpec(returnIrType, codeGen.registers.nextFreeFloat(), null)
|
||||
FunctionCallArgs.RegSpec(returnIrType, codeGen.registers.next(IRDataType.FLOAT), null)
|
||||
else
|
||||
FunctionCallArgs.RegSpec(returnIrType, codeGen.registers.nextFree(), null)
|
||||
FunctionCallArgs.RegSpec(returnIrType, codeGen.registers.next(), null)
|
||||
}
|
||||
// create the call
|
||||
addInstr(result, IRInstruction(Opcode.CALL, labelSymbol = fcall.name,
|
||||
@ -695,9 +695,9 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
val returns = callTarget.returns[0]
|
||||
val returnIrType = irType(returns.type)
|
||||
if (returnIrType == IRDataType.FLOAT)
|
||||
FunctionCallArgs.RegSpec(returnIrType, codeGen.registers.nextFreeFloat(), returns.register)
|
||||
FunctionCallArgs.RegSpec(returnIrType, codeGen.registers.next(IRDataType.FLOAT), returns.register)
|
||||
else {
|
||||
val returnRegister = codeGen.registers.nextFree()
|
||||
val returnRegister = codeGen.registers.next()
|
||||
FunctionCallArgs.RegSpec(returnIrType, returnRegister, returns.register)
|
||||
}
|
||||
}
|
||||
@ -729,7 +729,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
// assign status flag bit to the return value register
|
||||
finalReturnRegister = returnRegSpec.registerNum
|
||||
if(finalReturnRegister<0)
|
||||
finalReturnRegister = codeGen.registers.nextFree()
|
||||
finalReturnRegister = codeGen.registers.next()
|
||||
when(statusFlagResult) {
|
||||
Statusflag.Pc -> {
|
||||
result += IRCodeChunk(null, null).also {
|
||||
@ -815,13 +815,13 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
}
|
||||
"sys.pop" -> {
|
||||
// pop byte
|
||||
val popReg = codeGen.registers.nextFree()
|
||||
val popReg = codeGen.registers.next()
|
||||
addInstr(chunk, IRInstruction(Opcode.POP, IRDataType.BYTE, reg1=popReg), null)
|
||||
return ExpressionCodeResult(chunk, IRDataType.BYTE, popReg, -1)
|
||||
}
|
||||
"sys.popw" -> {
|
||||
// pop word
|
||||
val popReg = codeGen.registers.nextFree()
|
||||
val popReg = codeGen.registers.next()
|
||||
addInstr(chunk, IRInstruction(Opcode.POP, IRDataType.WORD, reg1=popReg), null)
|
||||
return ExpressionCodeResult(chunk, IRDataType.WORD, popReg, -1)
|
||||
}
|
||||
@ -834,7 +834,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
}
|
||||
"floats.pop" -> {
|
||||
// pop float
|
||||
val popReg = codeGen.registers.nextFreeFloat()
|
||||
val popReg = codeGen.registers.next(IRDataType.FLOAT)
|
||||
addInstr(chunk, IRInstruction(Opcode.POP, IRDataType.FLOAT, fpReg1 = popReg), null)
|
||||
return ExpressionCodeResult(chunk, IRDataType.FLOAT, -1, resultFpReg = popReg)
|
||||
}
|
||||
@ -850,7 +850,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
): ExpressionCodeResult {
|
||||
// return multiple values
|
||||
val returnRegisters = callTarget.returns.map {
|
||||
val regnum = if(it.type.isFloat) codeGen.registers.nextFreeFloat() else codeGen.registers.nextFree()
|
||||
val regnum = if(it.type.isFloat) codeGen.registers.next(IRDataType.FLOAT) else codeGen.registers.next()
|
||||
FunctionCallArgs.RegSpec(irType(it.type), regnum, it.register)
|
||||
}
|
||||
// create the call
|
||||
@ -886,12 +886,12 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
addToResult(result, leftTr, -1, leftTr.resultFpReg)
|
||||
val rightTr = translateExpression(binExpr.right)
|
||||
addToResult(result, rightTr, -1, rightTr.resultFpReg)
|
||||
val resultRegister = codeGen.registers.nextFree()
|
||||
val resultRegister = codeGen.registers.next()
|
||||
addInstr(result, IRInstruction(Opcode.FCOMP, IRDataType.FLOAT, reg1=resultRegister, fpReg1 = leftTr.resultFpReg, fpReg2 = rightTr.resultFpReg), null)
|
||||
addInstr(result, IRInstruction(Opcode.CMPI, IRDataType.BYTE, reg1=resultRegister, immediate = 0), null)
|
||||
val other = codeGen.createLabelName()
|
||||
val after = codeGen.createLabelName()
|
||||
val resultReg = codeGen.registers.nextFree()
|
||||
val resultReg = codeGen.registers.next()
|
||||
// TODO can this be done more efficiently? also see operatorLessThan
|
||||
if(greaterEquals) {
|
||||
result += IRCodeChunk(null, null).also {
|
||||
@ -942,12 +942,12 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
addToResult(result, leftTr, -1, leftTr.resultFpReg)
|
||||
val rightTr = translateExpression(binExpr.right)
|
||||
addToResult(result, rightTr, -1, rightTr.resultFpReg)
|
||||
val resultRegister = codeGen.registers.nextFree()
|
||||
val resultRegister = codeGen.registers.next()
|
||||
addInstr(result, IRInstruction(Opcode.FCOMP, IRDataType.FLOAT, reg1=resultRegister, fpReg1 = leftTr.resultFpReg, fpReg2 = rightTr.resultFpReg), null)
|
||||
addInstr(result, IRInstruction(Opcode.CMPI, IRDataType.BYTE, reg1=resultRegister, immediate = 0), null)
|
||||
val other = codeGen.createLabelName()
|
||||
val after = codeGen.createLabelName()
|
||||
val resultReg = codeGen.registers.nextFree()
|
||||
val resultReg = codeGen.registers.next()
|
||||
// TODO can this be done more efficiently? also see operatorGreaterThan
|
||||
if(lessEquals) {
|
||||
result += IRCodeChunk(null, null).also {
|
||||
@ -993,8 +993,8 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
addToResult(result, leftTr, -1, leftTr.resultFpReg)
|
||||
val rightTr = translateExpression(binExpr.right)
|
||||
addToResult(result, rightTr, -1, rightTr.resultFpReg)
|
||||
val resultRegister = codeGen.registers.nextFree()
|
||||
val valueReg = codeGen.registers.nextFree()
|
||||
val resultRegister = codeGen.registers.next()
|
||||
val valueReg = codeGen.registers.next()
|
||||
val label = codeGen.createLabelName()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=resultRegister, immediate = 0)
|
||||
@ -1036,7 +1036,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
// TODO this used to be a single instruction like SCC, SCS, SZ etc but those were problematic
|
||||
val other = codeGen.createLabelName()
|
||||
val after = codeGen.createLabelName()
|
||||
val resultReg = codeGen.registers.nextFree()
|
||||
val resultReg = codeGen.registers.next()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(branchForTrue, labelSymbol = other)
|
||||
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = resultReg, immediate = 0)
|
||||
@ -1051,7 +1051,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
// TODO this used to be a single instruction like SCC, SCS, SZ etc but those were problematic
|
||||
val other = codeGen.createLabelName()
|
||||
val after = codeGen.createLabelName()
|
||||
val resultReg = codeGen.registers.nextFree()
|
||||
val resultReg = codeGen.registers.next()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(branchForTrue, dt, reg1=reg1, reg2=reg2, labelSymbol = other)
|
||||
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = resultReg, immediate = 0)
|
||||
|
@ -471,8 +471,8 @@ class IRCodeGen(
|
||||
require(forLoop.variable.name == loopvar.scopedName)
|
||||
val iterableLength = symbolTable.getLength(iterable.name)
|
||||
val loopvarSymbol = forLoop.variable.name
|
||||
val indexReg = registers.nextFree()
|
||||
val tmpReg = registers.nextFree()
|
||||
val indexReg = registers.next()
|
||||
val tmpReg = registers.next()
|
||||
val loopLabel = createLabelName()
|
||||
val endLabel = createLabelName()
|
||||
when {
|
||||
@ -498,9 +498,9 @@ class IRCodeGen(
|
||||
throw AssemblyError("weird dt")
|
||||
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=indexReg, immediate = 0), null)
|
||||
result += IRCodeChunk(loopLabel, null).also {
|
||||
val tmpRegLsb = registers.nextFree()
|
||||
val tmpRegMsb = registers.nextFree()
|
||||
val concatReg = registers.nextFree()
|
||||
val tmpRegLsb = registers.next()
|
||||
val tmpRegMsb = registers.next()
|
||||
val concatReg = registers.next()
|
||||
it += IRInstruction(Opcode.LOADX, IRDataType.BYTE, reg1=tmpRegMsb, reg2=indexReg, labelSymbol=iterable.name+"_msb")
|
||||
it += IRInstruction(Opcode.LOADX, IRDataType.BYTE, reg1=tmpRegLsb, reg2=indexReg, labelSymbol=iterable.name+"_lsb")
|
||||
it += IRInstruction(Opcode.CONCAT, IRDataType.BYTE, reg1=concatReg, reg2=tmpRegMsb, reg3=tmpRegLsb)
|
||||
@ -636,7 +636,7 @@ class IRCodeGen(
|
||||
val loopLabel = createLabelName()
|
||||
require(forLoop.variable.name == loopvar.scopedName)
|
||||
val loopvarSymbol = forLoop.variable.name
|
||||
val indexReg = registers.nextFree()
|
||||
val indexReg = registers.next()
|
||||
val loopvarDt = when(loopvar) {
|
||||
is StMemVar -> loopvar.dt
|
||||
is StStaticVariable -> loopvar.dt
|
||||
@ -744,7 +744,7 @@ class IRCodeGen(
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
val valueReg = registers.nextFree()
|
||||
val valueReg = registers.next()
|
||||
if(value>0) {
|
||||
code += IRInstruction(Opcode.LOAD, dt, reg1=valueReg, immediate = value)
|
||||
code += if(knownAddress!=null)
|
||||
@ -786,7 +786,7 @@ class IRCodeGen(
|
||||
else
|
||||
IRInstruction(Opcode.STOREZM, IRDataType.FLOAT, labelSymbol = symbol)
|
||||
} else {
|
||||
val factorReg = registers.nextFreeFloat()
|
||||
val factorReg = registers.next(IRDataType.FLOAT)
|
||||
code += IRInstruction(Opcode.LOAD, IRDataType.FLOAT, fpReg1=factorReg, immediateFp = factor)
|
||||
code += if(knownAddress!=null)
|
||||
IRInstruction(Opcode.MULM, IRDataType.FLOAT, fpReg1 = factorReg, address = knownAddress)
|
||||
@ -807,7 +807,7 @@ class IRCodeGen(
|
||||
}
|
||||
else if(pow2>=1) {
|
||||
// just shift multiple bits
|
||||
val pow2reg = registers.nextFree()
|
||||
val pow2reg = registers.next()
|
||||
code += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=pow2reg, immediate = pow2)
|
||||
code += IRInstruction(Opcode.LSLN, dt, reg1=reg, reg2=pow2reg)
|
||||
} else {
|
||||
@ -834,7 +834,7 @@ class IRCodeGen(
|
||||
}
|
||||
else if(pow2>=1) {
|
||||
// just shift multiple bits
|
||||
val pow2reg = registers.nextFree()
|
||||
val pow2reg = registers.next()
|
||||
code += IRInstruction(Opcode.LOAD, dt, reg1=pow2reg, immediate = pow2)
|
||||
code += if(knownAddress!=null)
|
||||
IRInstruction(Opcode.LSLNM, dt, reg1=pow2reg, address = knownAddress)
|
||||
@ -848,7 +848,7 @@ class IRCodeGen(
|
||||
IRInstruction(Opcode.STOREZM, dt, labelSymbol = symbol)
|
||||
}
|
||||
else {
|
||||
val factorReg = registers.nextFree()
|
||||
val factorReg = registers.next()
|
||||
code += IRInstruction(Opcode.LOAD, dt, reg1=factorReg, immediate = factor)
|
||||
code += if(knownAddress!=null)
|
||||
IRInstruction(Opcode.MULM, dt, reg1=factorReg, address = knownAddress)
|
||||
@ -876,14 +876,14 @@ class IRCodeGen(
|
||||
if(factor==1.0)
|
||||
return code
|
||||
if(factor==0.0) {
|
||||
val maxvalueReg = registers.nextFreeFloat()
|
||||
val maxvalueReg = registers.next(IRDataType.FLOAT)
|
||||
code += IRInstruction(Opcode.LOAD, IRDataType.FLOAT, fpReg1 = maxvalueReg, immediateFp = Double.MAX_VALUE)
|
||||
code += if(knownAddress!=null)
|
||||
IRInstruction(Opcode.STOREM, IRDataType.FLOAT, fpReg1 = maxvalueReg, address = knownAddress)
|
||||
else
|
||||
IRInstruction(Opcode.STOREM, IRDataType.FLOAT, fpReg1 = maxvalueReg, labelSymbol = symbol)
|
||||
} else {
|
||||
val factorReg = registers.nextFreeFloat()
|
||||
val factorReg = registers.next(IRDataType.FLOAT)
|
||||
code += IRInstruction(Opcode.LOAD, IRDataType.FLOAT, fpReg1=factorReg, immediateFp = factor)
|
||||
code += if(knownAddress!=null)
|
||||
IRInstruction(Opcode.DIVSM, IRDataType.FLOAT, fpReg1 = factorReg, address = knownAddress)
|
||||
@ -905,7 +905,7 @@ class IRCodeGen(
|
||||
code += IRInstruction(Opcode.ASR, dt, reg1=reg)
|
||||
} else {
|
||||
// just shift multiple bits (signed)
|
||||
val pow2reg = registers.nextFree()
|
||||
val pow2reg = registers.next()
|
||||
code += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=pow2reg, immediate = pow2)
|
||||
code += IRInstruction(Opcode.ASRN, dt, reg1=reg, reg2=pow2reg)
|
||||
}
|
||||
@ -915,7 +915,7 @@ class IRCodeGen(
|
||||
code += IRInstruction(Opcode.LSR, dt, reg1=reg)
|
||||
} else {
|
||||
// just shift multiple bits (unsigned)
|
||||
val pow2reg = registers.nextFree()
|
||||
val pow2reg = registers.next()
|
||||
code += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = pow2reg, immediate = pow2)
|
||||
code += IRInstruction(Opcode.LSRN, dt, reg1 = reg, reg2 = pow2reg)
|
||||
}
|
||||
@ -951,7 +951,7 @@ class IRCodeGen(
|
||||
IRInstruction(Opcode.ASRM, dt, labelSymbol = symbol)
|
||||
} else {
|
||||
// just shift multiple bits (signed)
|
||||
val pow2reg = registers.nextFree()
|
||||
val pow2reg = registers.next()
|
||||
code += IRInstruction(Opcode.LOAD, dt, reg1 = pow2reg, immediate = pow2)
|
||||
code += if (knownAddress != null)
|
||||
IRInstruction(Opcode.ASRNM, dt, reg1 = pow2reg, address = knownAddress)
|
||||
@ -968,7 +968,7 @@ class IRCodeGen(
|
||||
}
|
||||
else {
|
||||
// just shift multiple bits (unsigned)
|
||||
val pow2reg = registers.nextFree()
|
||||
val pow2reg = registers.next()
|
||||
code += IRInstruction(Opcode.LOAD, dt, reg1=pow2reg, immediate = pow2)
|
||||
code += if(knownAddress!=null)
|
||||
IRInstruction(Opcode.LSRNM, dt, reg1 = pow2reg, address = knownAddress)
|
||||
@ -982,7 +982,7 @@ class IRCodeGen(
|
||||
{
|
||||
// regular div
|
||||
if (factor == 0) {
|
||||
val reg = registers.nextFree()
|
||||
val reg = registers.next()
|
||||
code += IRInstruction(Opcode.LOAD, dt, reg1=reg, immediate = 0xffff)
|
||||
code += if(knownAddress!=null)
|
||||
IRInstruction(Opcode.STOREM, dt, reg1=reg, address = knownAddress)
|
||||
@ -990,7 +990,7 @@ class IRCodeGen(
|
||||
IRInstruction(Opcode.STOREM, dt, reg1=reg, labelSymbol = symbol)
|
||||
}
|
||||
else {
|
||||
val factorReg = registers.nextFree()
|
||||
val factorReg = registers.next()
|
||||
code += IRInstruction(Opcode.LOAD, dt, reg1=factorReg, immediate = factor)
|
||||
code += if(signed) {
|
||||
if(knownAddress!=null)
|
||||
@ -1036,7 +1036,7 @@ class IRCodeGen(
|
||||
addToResult(result, rightTr, -1, rightTr.resultFpReg)
|
||||
var afterIfLabel = ""
|
||||
result += IRCodeChunk(null, null).also {
|
||||
val compResultReg = registers.nextFree()
|
||||
val compResultReg = registers.next()
|
||||
it += IRInstruction(
|
||||
Opcode.FCOMP,
|
||||
IRDataType.FLOAT,
|
||||
@ -1398,7 +1398,7 @@ class IRCodeGen(
|
||||
addToResult(result, leftTr, -1, leftTr.resultFpReg)
|
||||
val rightTr = expressionEval.translateExpression(condition.right)
|
||||
addToResult(result, rightTr, -1, rightTr.resultFpReg)
|
||||
val compResultReg = registers.nextFree()
|
||||
val compResultReg = registers.next()
|
||||
addInstr(result, IRInstruction(Opcode.FCOMP, IRDataType.FLOAT, reg1 = compResultReg, fpReg1 = leftTr.resultFpReg, fpReg2 = rightTr.resultFpReg), null)
|
||||
val elseBranch: Opcode
|
||||
var useCmpi = false // for the branch opcodes that have been converted to CMPI + BSTxx form already
|
||||
@ -1690,7 +1690,7 @@ class IRCodeGen(
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
if(constRepeats==65536) {
|
||||
// make use of the word wrap around to count to 65536
|
||||
val resultRegister = registers.nextFree()
|
||||
val resultRegister = registers.next()
|
||||
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.WORD, reg1=resultRegister, immediate = 0), null)
|
||||
result += labelFirstChunk(translateNode(repeat.statements), repeatLabel)
|
||||
result += IRCodeChunk(null, null).also {
|
||||
|
@ -1,31 +1,32 @@
|
||||
package prog8.codegen.intermediate
|
||||
|
||||
import prog8.code.core.AssemblyError
|
||||
import prog8.intermediate.IRDataType
|
||||
|
||||
internal class RegisterPool {
|
||||
// reserve first 3 registers a subroutine return registers TODO is this still needed? how does returning values go in IR? Double types?
|
||||
private var firstFree: Int=3
|
||||
private var firstFreeFloat: Int=3
|
||||
|
||||
private var nextRegister: Int=1
|
||||
private val registerTypes: MutableMap<Int, IRDataType> = mutableMapOf()
|
||||
|
||||
// everything from 99000 onwards is reserved for special purposes:
|
||||
// 99000 - 99099 : WORD registers for syscall arguments and response value(s)
|
||||
// 99100 - 99199 : BYTE registers for syscall arguments and response value(s)
|
||||
|
||||
|
||||
fun nextFree(): Int {
|
||||
if(firstFree>=99000)
|
||||
fun next(): Int {
|
||||
if(nextRegister>=99000)
|
||||
throw AssemblyError("register pool depleted")
|
||||
val result = firstFree
|
||||
firstFree++
|
||||
val result = nextRegister
|
||||
// registerTypes[result] = type // TODO: make callers of this one supply the integer type they want as well and register it here
|
||||
nextRegister++
|
||||
return result
|
||||
}
|
||||
|
||||
fun nextFreeFloat(): Int {
|
||||
if(firstFreeFloat>=99000)
|
||||
throw AssemblyError("float register pool depleted")
|
||||
val result = firstFreeFloat
|
||||
firstFreeFloat++
|
||||
fun next(type: IRDataType): Int {
|
||||
if(nextRegister>=99000)
|
||||
throw AssemblyError("register pool depleted")
|
||||
val result = nextRegister
|
||||
nextRegister++
|
||||
registerTypes[result] = type
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
@ -3,4 +3,4 @@ org.gradle.console=rich
|
||||
org.gradle.parallel=true
|
||||
org.gradle.daemon=true
|
||||
kotlin.code.style=official
|
||||
version=11.0.1
|
||||
version=11.1-SNAPSHOT
|
||||
|
Loading…
x
Reference in New Issue
Block a user