mirror of
https://github.com/irmen/prog8.git
synced 2024-11-25 19:31:36 +00:00
refactor IR returnregs 5
This commit is contained in:
parent
451e527b7c
commit
db4619a9d9
@ -176,16 +176,15 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
throw AssemblyError("non-array var indexing requires bytes dt")
|
||||
if(array.index.type!=DataType.UBYTE)
|
||||
throw AssemblyError("non-array var indexing requires bytes index")
|
||||
val idxReg = codeGen.registers.nextFree()
|
||||
val tr = expressionEval.translateExpression(array.index)
|
||||
addToResult(result, tr, idxReg, -1)
|
||||
val idxTr = expressionEval.translateExpression(array.index)
|
||||
addToResult(result, idxTr, idxTr.resultReg, -1)
|
||||
val code = IRCodeChunk(null, null)
|
||||
if(zero) {
|
||||
// there's no STOREZIX instruction
|
||||
resultRegister = codeGen.registers.nextFree()
|
||||
code += IRInstruction(Opcode.LOAD, vmDt, reg1=resultRegister, value=0)
|
||||
}
|
||||
code += IRInstruction(Opcode.STOREIX, vmDt, reg1=resultRegister, reg2=idxReg, labelSymbol = variable)
|
||||
code += IRInstruction(Opcode.STOREIX, vmDt, reg1=resultRegister, reg2=idxTr.resultReg, labelSymbol = variable)
|
||||
result += code
|
||||
return result
|
||||
}
|
||||
@ -233,20 +232,18 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
val chunk = IRCodeChunk(null, null).also { it += IRInstruction(Opcode.STOREZM, vmDt, value=(memory.address as PtNumber).number.toInt()) }
|
||||
result += chunk
|
||||
} else {
|
||||
val addressReg = codeGen.registers.nextFree()
|
||||
val tr = expressionEval.translateExpression(memory.address)
|
||||
addToResult(result, tr, addressReg, -1)
|
||||
result += IRCodeChunk(null, null).also { it += IRInstruction(Opcode.STOREZI, vmDt, reg1=addressReg) }
|
||||
addToResult(result, tr, tr.resultReg, -1)
|
||||
result += IRCodeChunk(null, null).also { it += IRInstruction(Opcode.STOREZI, vmDt, reg1=tr.resultReg) }
|
||||
}
|
||||
} else {
|
||||
if(memory.address is PtNumber) {
|
||||
val chunk = IRCodeChunk(null, null).also { it += IRInstruction(Opcode.STOREM, vmDt, reg1=resultRegister, value=(memory.address as PtNumber).number.toInt()) }
|
||||
result += chunk
|
||||
} else {
|
||||
val addressReg = codeGen.registers.nextFree()
|
||||
val tr = expressionEval.translateExpression(memory.address)
|
||||
addToResult(result, tr, addressReg, -1)
|
||||
result += IRCodeChunk(null, null).also { it += IRInstruction(Opcode.STOREI, vmDt, reg1=resultRegister, reg2=addressReg) }
|
||||
addToResult(result, tr, tr.resultReg, -1)
|
||||
result += IRCodeChunk(null, null).also { it += IRInstruction(Opcode.STOREI, vmDt, reg1=resultRegister, reg2=tr.resultReg) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -194,22 +194,20 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
|
||||
private fun funcPush(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
val reg = codeGen.registers.nextFree()
|
||||
val tr = exprGen.translateExpression(call.args.single())
|
||||
addToResult(result, tr, reg, -1)
|
||||
addToResult(result, tr, tr.resultReg, -1)
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.PUSH, IRDataType.BYTE, reg1=reg)
|
||||
it += IRInstruction(Opcode.PUSH, IRDataType.BYTE, reg1=tr.resultReg)
|
||||
}
|
||||
return ExpressionCodeResult(result, IRDataType.BYTE, -1, -1)
|
||||
}
|
||||
|
||||
private fun funcPushw(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
val reg = codeGen.registers.nextFree()
|
||||
val tr = exprGen.translateExpression(call.args.single())
|
||||
addToResult(result, tr, reg, -1)
|
||||
addToResult(result, tr, tr.resultReg, -1)
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.PUSH, IRDataType.WORD, reg1 = reg)
|
||||
it += IRInstruction(Opcode.PUSH, IRDataType.WORD, reg1 = tr.resultReg)
|
||||
}
|
||||
return ExpressionCodeResult(result, IRDataType.BYTE, -1, -1)
|
||||
}
|
||||
@ -279,30 +277,28 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
it += IRInstruction(Opcode.STOREZM, IRDataType.WORD, value = address)
|
||||
}
|
||||
} else {
|
||||
val addressReg = codeGen.registers.nextFree()
|
||||
val tr = exprGen.translateExpression(call.args[0])
|
||||
addToResult(result, tr, addressReg, -1)
|
||||
addToResult(result, tr, tr.resultReg, -1)
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.STOREZI, IRDataType.WORD, reg1 = addressReg)
|
||||
it += IRInstruction(Opcode.STOREZI, IRDataType.WORD, reg1 = tr.resultReg)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
val valueReg = codeGen.registers.nextFree()
|
||||
if (call.args[0] is PtNumber) {
|
||||
val address = (call.args[0] as PtNumber).number.toInt()
|
||||
val tr = exprGen.translateExpression(call.args[1])
|
||||
addToResult(result, tr, valueReg, -1)
|
||||
addToResult(result, tr, tr.resultReg, -1)
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.STOREM, IRDataType.WORD, reg1 = valueReg, value = address)
|
||||
it += IRInstruction(Opcode.STOREM, IRDataType.WORD, reg1 = tr.resultReg, value = address)
|
||||
}
|
||||
} else {
|
||||
val addressTr = exprGen.translateExpression(call.args[0])
|
||||
addToResult(result, addressTr, addressTr.resultReg, -1)
|
||||
val valueTr = exprGen.translateExpression(call.args[1])
|
||||
require(valueTr.resultReg!=addressTr.resultReg)
|
||||
addToResult(result, valueTr, valueReg, -1)
|
||||
addToResult(result, valueTr, valueTr.resultReg, -1)
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.STOREI, IRDataType.WORD, reg1 = valueReg, reg2 = addressTr.resultReg)
|
||||
it += IRInstruction(Opcode.STOREI, IRDataType.WORD, reg1 = valueTr.resultReg, reg2 = addressTr.resultReg)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -318,30 +314,28 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
it += IRInstruction(Opcode.STOREZM, IRDataType.BYTE, value = address)
|
||||
}
|
||||
} else {
|
||||
val addressReg = codeGen.registers.nextFree()
|
||||
val tr = exprGen.translateExpression(call.args[0])
|
||||
addToResult(result, tr, addressReg, -1)
|
||||
addToResult(result, tr, tr.resultReg, -1)
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.STOREZI, IRDataType.BYTE, reg1 = addressReg)
|
||||
it += IRInstruction(Opcode.STOREZI, IRDataType.BYTE, reg1 = tr.resultReg)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
val valueReg = codeGen.registers.nextFree()
|
||||
if (call.args[0] is PtNumber) {
|
||||
val address = (call.args[0] as PtNumber).number.toInt()
|
||||
val tr = exprGen.translateExpression(call.args[1])
|
||||
addToResult(result, tr, valueReg, -1)
|
||||
addToResult(result, tr, tr.resultReg, -1)
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.STOREM, IRDataType.BYTE, reg1 = valueReg, value = address)
|
||||
it += IRInstruction(Opcode.STOREM, IRDataType.BYTE, reg1 = tr.resultReg, value = address)
|
||||
}
|
||||
} else {
|
||||
val addressTr = exprGen.translateExpression(call.args[0])
|
||||
addToResult(result, addressTr, addressTr.resultReg, -1)
|
||||
val valueTr = exprGen.translateExpression(call.args[1])
|
||||
require(valueTr.resultReg!=addressTr.resultReg)
|
||||
addToResult(result, valueTr, valueReg, -1)
|
||||
addToResult(result, valueTr, valueTr.resultReg, -1)
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.STOREI, IRDataType.BYTE, reg1 = valueReg, reg2 = addressTr.resultReg)
|
||||
it += IRInstruction(Opcode.STOREI, IRDataType.BYTE, reg1 = valueTr.resultReg, reg2 = addressTr.resultReg)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -401,14 +395,13 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
|
||||
private fun funcMsb(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
val resultRegister = codeGen.registers.nextFree()
|
||||
val tr = exprGen.translateExpression(call.args.single())
|
||||
addToResult(result, tr, resultRegister, -1)
|
||||
addToResult(result, tr, tr.resultReg, -1)
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.MSIG, IRDataType.BYTE, reg1 = resultRegister, reg2 = resultRegister)
|
||||
it += IRInstruction(Opcode.MSIG, IRDataType.BYTE, reg1 = tr.resultReg, reg2 = tr.resultReg)
|
||||
}
|
||||
// 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, resultRegister, -1)
|
||||
return ExpressionCodeResult(result, IRDataType.BYTE, tr.resultReg, -1)
|
||||
}
|
||||
|
||||
private fun funcRolRor(opcode: Opcode, call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||
|
@ -1171,11 +1171,9 @@ internal fun addToResult(
|
||||
if(requiredResultFpReg!=-1) require(requiredResultReg==-1)
|
||||
|
||||
if(requiredResultReg>=0 && requiredResultReg!=codeResult.resultReg) {
|
||||
println("RESULT REG DIFFERENCE: GOT ${codeResult.resultReg} WANTED $requiredResultReg ${codeResult.dt}")
|
||||
codeResult.chunks.last().instructions += IRInstruction(Opcode.LOADR, codeResult.dt, reg1=requiredResultReg, reg2=codeResult.resultReg)
|
||||
}
|
||||
if(requiredResultFpReg>=0 && requiredResultFpReg!=codeResult.resultFpReg) {
|
||||
println("RESULT FPREG DIFFERENCE: GOT ${codeResult.resultFpReg} WANTED $requiredResultFpReg ${codeResult.dt}")
|
||||
codeResult.chunks.last().instructions += IRInstruction(Opcode.LOADR, IRDataType.FLOAT, fpReg1 = requiredResultFpReg, fpReg2 = codeResult.resultFpReg)
|
||||
}
|
||||
result += codeResult.chunks
|
||||
|
@ -401,11 +401,9 @@ class IRCodeGen(
|
||||
if(whenStmt.choices.children.isEmpty())
|
||||
return emptyList()
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
val valueReg = registers.nextFree()
|
||||
val choiceReg = registers.nextFree()
|
||||
val valueDt = irType(whenStmt.value.type)
|
||||
val tr = expressionEval.translateExpression(whenStmt.value)
|
||||
addToResult(result, tr, valueReg, -1)
|
||||
val valueTr = expressionEval.translateExpression(whenStmt.value)
|
||||
addToResult(result, valueTr, valueTr.resultReg, -1)
|
||||
val choices = whenStmt.choices.children.map {it as PtWhenChoice }
|
||||
val endLabel = createLabelName()
|
||||
for (choice in choices) {
|
||||
@ -414,10 +412,11 @@ class IRCodeGen(
|
||||
} else {
|
||||
val skipLabel = createLabelName()
|
||||
val values = choice.values.children.map {it as PtNumber}
|
||||
val choiceReg = registers.nextFree()
|
||||
if(values.size==1) {
|
||||
val chunk = IRCodeChunk(null, null)
|
||||
chunk += IRInstruction(Opcode.LOAD, valueDt, reg1=choiceReg, value=values[0].number.toInt())
|
||||
chunk += IRInstruction(Opcode.BNE, valueDt, reg1=valueReg, reg2=choiceReg, labelSymbol = skipLabel)
|
||||
chunk += IRInstruction(Opcode.BNE, valueDt, reg1=valueTr.resultReg, reg2=choiceReg, labelSymbol = skipLabel)
|
||||
result += chunk
|
||||
result += translateNode(choice.statements)
|
||||
if(choice.statements.children.last() !is PtReturn)
|
||||
@ -427,7 +426,7 @@ class IRCodeGen(
|
||||
val chunk = IRCodeChunk(null, null)
|
||||
for (value in values) {
|
||||
chunk += IRInstruction(Opcode.LOAD, valueDt, reg1=choiceReg, value=value.number.toInt())
|
||||
chunk += IRInstruction(Opcode.BEQ, valueDt, reg1=valueReg, reg2=choiceReg, labelSymbol = matchLabel)
|
||||
chunk += IRInstruction(Opcode.BEQ, valueDt, reg1=valueTr.resultReg, reg2=choiceReg, labelSymbol = matchLabel)
|
||||
}
|
||||
chunk += IRInstruction(Opcode.JUMP, labelSymbol = skipLabel)
|
||||
result += chunk
|
||||
@ -1019,9 +1018,9 @@ class IRCodeGen(
|
||||
} else {
|
||||
// integer comparisons
|
||||
branchDt = irDtLeft
|
||||
compResultReg = registers.nextFree()
|
||||
val tr = expressionEval.translateExpression(ifElse.condition.left)
|
||||
addToResult(result, tr, compResultReg, -1)
|
||||
compResultReg = tr.resultReg
|
||||
addToResult(result, tr, tr.resultReg, -1)
|
||||
elseBranch = when (ifElse.condition.operator) {
|
||||
"==" -> Opcode.BNZ
|
||||
"!=" -> Opcode.BZ
|
||||
@ -1188,14 +1187,13 @@ class IRCodeGen(
|
||||
val address = (memory.address as PtNumber).number.toInt()
|
||||
addInstr(result, IRInstruction(operationMem, irDt, value = address), null)
|
||||
} else {
|
||||
val incReg = registers.nextFree()
|
||||
val addressReg = registers.nextFree()
|
||||
val tr = expressionEval.translateExpression(memory.address,)
|
||||
addToResult(result, tr, addressReg, -1)
|
||||
val tr = expressionEval.translateExpression(memory.address)
|
||||
addToResult(result, tr, tr.resultReg, -1)
|
||||
val chunk = IRCodeChunk(null, null)
|
||||
chunk += IRInstruction(Opcode.LOADI, irDt, reg1 = incReg, reg2 = addressReg)
|
||||
val incReg = registers.nextFree()
|
||||
chunk += IRInstruction(Opcode.LOADI, irDt, reg1 = incReg, reg2 = tr.resultReg)
|
||||
chunk += IRInstruction(operationRegister, irDt, reg1 = incReg)
|
||||
chunk += IRInstruction(Opcode.STOREI, irDt, reg1 = incReg, reg2 = addressReg)
|
||||
chunk += IRInstruction(Opcode.STOREI, irDt, reg1 = incReg, reg2 = tr.resultReg)
|
||||
result += chunk
|
||||
}
|
||||
} else if (array!=null) {
|
||||
@ -1206,14 +1204,13 @@ class IRCodeGen(
|
||||
val offset = fixedIndex*itemsize
|
||||
addInstr(result, IRInstruction(operationMem, irDt, labelSymbol="$variable+$offset"), null)
|
||||
} else {
|
||||
val incReg = registers.nextFree()
|
||||
val indexReg = registers.nextFree()
|
||||
val tr = expressionEval.translateExpression(array.index)
|
||||
addToResult(result, tr, indexReg, -1)
|
||||
val indexTr = expressionEval.translateExpression(array.index)
|
||||
addToResult(result, indexTr, indexTr.resultReg, -1)
|
||||
val chunk = IRCodeChunk(null, null)
|
||||
chunk += IRInstruction(Opcode.LOADX, irDt, reg1=incReg, reg2=indexReg, labelSymbol=variable)
|
||||
val incReg = registers.nextFree()
|
||||
chunk += IRInstruction(Opcode.LOADX, irDt, reg1=incReg, reg2=indexTr.resultReg, labelSymbol=variable)
|
||||
chunk += IRInstruction(operationRegister, irDt, reg1=incReg)
|
||||
chunk += IRInstruction(Opcode.STOREX, irDt, reg1=incReg, reg2=indexReg, labelSymbol=variable)
|
||||
chunk += IRInstruction(Opcode.STOREX, irDt, reg1=incReg, reg2=indexTr.resultReg, labelSymbol=variable)
|
||||
result += chunk
|
||||
}
|
||||
} else
|
||||
@ -1234,16 +1231,15 @@ class IRCodeGen(
|
||||
|
||||
val repeatLabel = createLabelName()
|
||||
val skipRepeatLabel = createLabelName()
|
||||
val counterReg = registers.nextFree()
|
||||
val irDt = irType(repeat.count.type)
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
val tr = expressionEval.translateExpression(repeat.count)
|
||||
addToResult(result, tr, counterReg, -1)
|
||||
addInstr(result, IRInstruction(Opcode.BZ, irDt, reg1=counterReg, labelSymbol = skipRepeatLabel), null)
|
||||
val countTr = expressionEval.translateExpression(repeat.count)
|
||||
addToResult(result, countTr, countTr.resultReg, -1)
|
||||
addInstr(result, IRInstruction(Opcode.BZ, irDt, reg1=countTr.resultReg, labelSymbol = skipRepeatLabel), null)
|
||||
result += labelFirstChunk(translateNode(repeat.statements), repeatLabel)
|
||||
val chunk = IRCodeChunk(null, null)
|
||||
chunk += IRInstruction(Opcode.DEC, irDt, reg1=counterReg)
|
||||
chunk += IRInstruction(Opcode.BNZ, irDt, reg1=counterReg, labelSymbol = repeatLabel)
|
||||
chunk += IRInstruction(Opcode.DEC, irDt, reg1=countTr.resultReg)
|
||||
chunk += IRInstruction(Opcode.BNZ, irDt, reg1=countTr.resultReg, labelSymbol = repeatLabel)
|
||||
result += chunk
|
||||
result += IRCodeChunk(skipRepeatLabel, null)
|
||||
return result
|
||||
|
Loading…
Reference in New Issue
Block a user