ir: tweak register pool, prepare to register the types there uniquely

This commit is contained in:
Irmen de Jong 2024-12-28 02:17:04 +01:00
parent 76b29aa629
commit c8996418da
6 changed files with 155 additions and 154 deletions

View File

@ -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) {

View File

@ -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)

View File

@ -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)

View File

@ -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 {

View File

@ -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
}
}

View File

@ -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