mirror of
https://github.com/irmen/prog8.git
synced 2025-01-26 19:30:59 +00:00
refactor IR returnregs 4
This commit is contained in:
parent
54dd3a00df
commit
451e527b7c
@ -141,17 +141,16 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
if(!zero) {
|
||||
// calculate the assignment value
|
||||
if (vmDt == IRDataType.FLOAT) {
|
||||
resultFpRegister = codeGen.registers.nextFreeFloat()
|
||||
val tr = expressionEval.translateExpression(assignment.value)
|
||||
addToResult(result, tr, -1, resultFpRegister)
|
||||
resultFpRegister = tr.resultFpReg
|
||||
addToResult(result, tr, -1, tr.resultFpReg)
|
||||
} else {
|
||||
resultRegister = if (assignment.value is PtMachineRegister) {
|
||||
(assignment.value as PtMachineRegister).register
|
||||
} else {
|
||||
val reg = codeGen.registers.nextFree()
|
||||
val tr = expressionEval.translateExpression(assignment.value)
|
||||
addToResult(result, tr, reg, -1)
|
||||
reg
|
||||
addToResult(result, tr, tr.resultReg, -1)
|
||||
tr.resultReg
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,118 +10,56 @@ import prog8.intermediate.*
|
||||
internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGen: ExpressionGen) {
|
||||
|
||||
fun translate(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||
when(call.name) {
|
||||
"any" -> {
|
||||
val resultRegister = codeGen.registers.nextFree()
|
||||
return ExpressionCodeResult(funcAny(call, resultRegister), IRDataType.BYTE, resultRegister, -1)
|
||||
}
|
||||
"all" -> {
|
||||
val resultRegister = codeGen.registers.nextFree()
|
||||
return ExpressionCodeResult(funcAll(call, resultRegister), IRDataType.BYTE, resultRegister, -1)
|
||||
}
|
||||
"abs" -> {
|
||||
val resultRegister = codeGen.registers.nextFree()
|
||||
return ExpressionCodeResult(funcAbs(call, resultRegister), codeGen.irType(call.args[0].type), resultRegister, -1)
|
||||
}
|
||||
"cmp" -> {
|
||||
return ExpressionCodeResult(funcCmp(call), codeGen.irType(call.args[0].type), -1, -1)
|
||||
}
|
||||
"sgn" -> {
|
||||
val resultRegister = codeGen.registers.nextFree()
|
||||
return ExpressionCodeResult(funcSgn(call, resultRegister), codeGen.irType(call.type), resultRegister, -1)
|
||||
}
|
||||
"sqrt16" -> {
|
||||
val resultRegister = codeGen.registers.nextFree()
|
||||
return ExpressionCodeResult(funcSqrt16(call, resultRegister), IRDataType.WORD, resultRegister, -1)
|
||||
}
|
||||
"pop" -> {
|
||||
return ExpressionCodeResult(funcPop(call), IRDataType.BYTE, -1, -1)
|
||||
}
|
||||
"popw" -> {
|
||||
return ExpressionCodeResult(funcPopw(call), IRDataType.WORD, -1, -1)
|
||||
}
|
||||
"push" -> {
|
||||
return ExpressionCodeResult(funcPush(call), IRDataType.BYTE, -1, -1)
|
||||
}
|
||||
"pushw" -> {
|
||||
return ExpressionCodeResult(funcPushw(call), IRDataType.BYTE,-1, -1)
|
||||
}
|
||||
return when(call.name) {
|
||||
"any" -> funcAny(call)
|
||||
"all" -> funcAll(call)
|
||||
"abs" -> funcAbs(call)
|
||||
"cmp" -> funcCmp(call)
|
||||
"sgn" -> funcSgn(call)
|
||||
"sqrt16" -> funcSqrt16(call)
|
||||
"pop" -> funcPop(call)
|
||||
"popw" -> funcPopw(call)
|
||||
"push" -> funcPush(call)
|
||||
"pushw" -> funcPushw(call)
|
||||
"rsave",
|
||||
"rsavex",
|
||||
"rrestore",
|
||||
"rrestorex" -> {
|
||||
return ExpressionCodeResult.EMPTY // vm doesn't have registers to save/restore
|
||||
}
|
||||
"rrestorex" -> ExpressionCodeResult.EMPTY // vm doesn't have registers to save/restore
|
||||
"callfar" -> throw AssemblyError("callfar() is for cx16 target only")
|
||||
"msb" -> return funcMsb(call)
|
||||
"lsb" -> return funcLsb(call)
|
||||
"memory" -> {
|
||||
val resultRegister = codeGen.registers.nextFree()
|
||||
return ExpressionCodeResult(funcMemory(call, resultRegister), IRDataType.WORD, resultRegister, -1)
|
||||
}
|
||||
"peek" -> {
|
||||
val resultRegister = codeGen.registers.nextFree()
|
||||
return ExpressionCodeResult(funcPeek(call, resultRegister), IRDataType.BYTE, resultRegister, -1)
|
||||
}
|
||||
"peekw" -> {
|
||||
val resultRegister = codeGen.registers.nextFree()
|
||||
return ExpressionCodeResult(funcPeekW(call, resultRegister), IRDataType.WORD, resultRegister, -1)
|
||||
}
|
||||
"poke" -> {
|
||||
return ExpressionCodeResult(funcPoke(call), IRDataType.BYTE, -1, -1)
|
||||
}
|
||||
"pokew" -> {
|
||||
return ExpressionCodeResult(funcPokeW(call), IRDataType.BYTE,-1, -1)
|
||||
}
|
||||
"pokemon" -> {
|
||||
return ExpressionCodeResult(emptyList(), IRDataType.BYTE, -1, -1)
|
||||
}
|
||||
"mkword" -> {
|
||||
val resultRegister = codeGen.registers.nextFree()
|
||||
return ExpressionCodeResult(funcMkword(call, resultRegister), IRDataType.WORD, resultRegister, -1)
|
||||
}
|
||||
"sort" -> {
|
||||
return ExpressionCodeResult(funcSort(call), IRDataType.BYTE, -1, -1)
|
||||
}
|
||||
"reverse" -> {
|
||||
return ExpressionCodeResult(funcReverse(call), IRDataType.BYTE, -1, -1)
|
||||
}
|
||||
"rol" -> {
|
||||
val resultRegister = codeGen.registers.nextFree()
|
||||
return ExpressionCodeResult(funcRolRor(Opcode.ROXL, call, resultRegister), codeGen.irType(call.args[0].type), resultRegister, -1)
|
||||
}
|
||||
"ror" -> {
|
||||
val resultRegister = codeGen.registers.nextFree()
|
||||
return ExpressionCodeResult(funcRolRor(Opcode.ROXR, call, resultRegister), codeGen.irType(call.args[0].type), resultRegister, -1)
|
||||
}
|
||||
"rol2" -> {
|
||||
val resultRegister = codeGen.registers.nextFree()
|
||||
return ExpressionCodeResult(funcRolRor(Opcode.ROL, call, resultRegister), codeGen.irType(call.args[0].type), resultRegister, -1)
|
||||
}
|
||||
"ror2" -> {
|
||||
val resultRegister = codeGen.registers.nextFree()
|
||||
return ExpressionCodeResult(funcRolRor(Opcode.ROR, call, resultRegister), codeGen.irType(call.args[0].type), resultRegister, -1)
|
||||
}
|
||||
"msb" -> funcMsb(call)
|
||||
"lsb" -> funcLsb(call)
|
||||
"memory" -> funcMemory(call)
|
||||
"peek" -> funcPeek(call)
|
||||
"peekw" -> funcPeekW(call)
|
||||
"poke" -> funcPoke(call)
|
||||
"pokew" -> funcPokeW(call)
|
||||
"pokemon" -> ExpressionCodeResult.EMPTY // easter egg function
|
||||
"mkword" -> funcMkword(call)
|
||||
"sort" -> funcSort(call)
|
||||
"reverse" -> funcReverse(call)
|
||||
"rol" -> funcRolRor(Opcode.ROXL, call)
|
||||
"ror" -> funcRolRor(Opcode.ROXR, call)
|
||||
"rol2" -> funcRolRor(Opcode.ROL, call)
|
||||
"ror2" -> funcRolRor(Opcode.ROR, call)
|
||||
else -> throw AssemblyError("missing builtinfunc for ${call.name}")
|
||||
}
|
||||
}
|
||||
|
||||
// TODO let all funcs return ExpressionCodeResult as well
|
||||
|
||||
private fun funcCmp(call: PtBuiltinFunctionCall): IRCodeChunks {
|
||||
private fun funcCmp(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
val leftTr = exprGen.translateExpression(call.args[0])
|
||||
addToResult(result, leftTr, leftTr.resultReg, -1)
|
||||
val rightTr = exprGen.translateExpression(call.args[1])
|
||||
require(leftTr.resultReg!=rightTr.resultReg)
|
||||
addToResult(result, rightTr, rightTr.resultReg, -1)
|
||||
val dt = codeGen.irType(call.args[0].type)
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.CMP, codeGen.irType(call.args[0].type), reg1=leftTr.resultReg, reg2=rightTr.resultReg)
|
||||
it += IRInstruction(Opcode.CMP, dt, reg1=leftTr.resultReg, reg2=rightTr.resultReg)
|
||||
}
|
||||
return result
|
||||
return ExpressionCodeResult(result, dt, leftTr.resultReg, -1)
|
||||
}
|
||||
|
||||
private fun funcAny(call: PtBuiltinFunctionCall, resultRegister: Int): IRCodeChunks {
|
||||
private fun funcAny(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||
val arrayName = call.args[0] as PtIdentifier
|
||||
val array = codeGen.symbolTable.flat.getValue(arrayName.name) as StStaticVariable
|
||||
val syscall =
|
||||
@ -139,13 +77,14 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = SyscallRegisterBase+1, value = array.length)
|
||||
it += IRInstruction(Opcode.SYSCALL, value = syscall.number)
|
||||
if(resultRegister!=0)
|
||||
it += IRInstruction(Opcode.LOADR, IRDataType.BYTE, reg1 = resultRegister, reg2 = 0)
|
||||
// SysCall call convention: return value in register r0
|
||||
if(tr.resultReg!=0)
|
||||
it += IRInstruction(Opcode.LOADR, IRDataType.BYTE, reg1 = tr.resultReg, reg2 = 0)
|
||||
}
|
||||
return result
|
||||
return ExpressionCodeResult(result, IRDataType.BYTE, tr.resultReg, -1)
|
||||
}
|
||||
|
||||
private fun funcAll(call: PtBuiltinFunctionCall, resultRegister: Int): IRCodeChunks {
|
||||
private fun funcAll(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||
val arrayName = call.args[0] as PtIdentifier
|
||||
val array = codeGen.symbolTable.flat.getValue(arrayName.name) as StStaticVariable
|
||||
val syscall =
|
||||
@ -163,94 +102,97 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = SyscallRegisterBase+1, value = array.length)
|
||||
it += IRInstruction(Opcode.SYSCALL, value = syscall.number)
|
||||
if(resultRegister!=0)
|
||||
it += IRInstruction(Opcode.LOADR, IRDataType.BYTE, reg1 = resultRegister, reg2 = 0)
|
||||
// SysCall call convention: return value in register r0
|
||||
if(tr.resultReg!=0)
|
||||
it += IRInstruction(Opcode.LOADR, IRDataType.BYTE, reg1 = tr.resultReg, reg2 = 0)
|
||||
}
|
||||
return result
|
||||
return ExpressionCodeResult(result, IRDataType.BYTE, tr.resultReg, -1)
|
||||
}
|
||||
|
||||
private fun funcAbs(call: PtBuiltinFunctionCall, resultRegister: Int): IRCodeChunks {
|
||||
private fun funcAbs(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||
val sourceDt = call.args.single().type
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
if(sourceDt!=DataType.UWORD) {
|
||||
val tr = exprGen.translateExpression(call.args[0])
|
||||
addToResult(result, tr, resultRegister, -1)
|
||||
when (sourceDt) {
|
||||
DataType.UBYTE -> {
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.EXT, IRDataType.BYTE, reg1 = resultRegister)
|
||||
}
|
||||
if(sourceDt==DataType.UWORD)
|
||||
return ExpressionCodeResult.EMPTY
|
||||
|
||||
val tr = exprGen.translateExpression(call.args[0])
|
||||
addToResult(result, tr, tr.resultReg, -1)
|
||||
when (sourceDt) {
|
||||
DataType.UBYTE -> {
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.EXT, IRDataType.BYTE, reg1 = tr.resultReg)
|
||||
}
|
||||
DataType.BYTE -> {
|
||||
val notNegativeLabel = codeGen.createLabelName()
|
||||
val compareReg = codeGen.registers.nextFree()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOADR, IRDataType.BYTE, reg1=compareReg, reg2=resultRegister)
|
||||
it += IRInstruction(Opcode.AND, IRDataType.BYTE, reg1=compareReg, value=0x80)
|
||||
it += IRInstruction(Opcode.BZ, IRDataType.BYTE, reg1=compareReg, labelSymbol = notNegativeLabel)
|
||||
it += IRInstruction(Opcode.NEG, IRDataType.BYTE, reg1=resultRegister)
|
||||
it += IRInstruction(Opcode.EXT, IRDataType.BYTE, reg1=resultRegister)
|
||||
}
|
||||
result += IRCodeChunk(notNegativeLabel, null)
|
||||
}
|
||||
DataType.WORD -> {
|
||||
val notNegativeLabel = codeGen.createLabelName()
|
||||
val compareReg = codeGen.registers.nextFree()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOADR, IRDataType.WORD, reg1=compareReg, reg2=resultRegister)
|
||||
it += IRInstruction(Opcode.AND, IRDataType.WORD, reg1=compareReg, value=0x8000)
|
||||
it += IRInstruction(Opcode.BZ, IRDataType.WORD, reg1=compareReg, labelSymbol = notNegativeLabel)
|
||||
it += IRInstruction(Opcode.NEG, IRDataType.WORD, reg1=resultRegister)
|
||||
}
|
||||
result += IRCodeChunk(notNegativeLabel, null)
|
||||
}
|
||||
else -> throw AssemblyError("weird type")
|
||||
return ExpressionCodeResult(result, IRDataType.BYTE, tr.resultReg, -1)
|
||||
}
|
||||
DataType.BYTE -> {
|
||||
val notNegativeLabel = codeGen.createLabelName()
|
||||
val compareReg = codeGen.registers.nextFree()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOADR, IRDataType.BYTE, reg1=compareReg, reg2=tr.resultReg)
|
||||
it += IRInstruction(Opcode.AND, IRDataType.BYTE, reg1=compareReg, value=0x80)
|
||||
it += IRInstruction(Opcode.BZ, IRDataType.BYTE, reg1=compareReg, labelSymbol = notNegativeLabel)
|
||||
it += IRInstruction(Opcode.NEG, IRDataType.BYTE, reg1=tr.resultReg)
|
||||
it += IRInstruction(Opcode.EXT, IRDataType.BYTE, reg1=tr.resultReg)
|
||||
}
|
||||
result += IRCodeChunk(notNegativeLabel, null)
|
||||
return ExpressionCodeResult(result, IRDataType.BYTE, tr.resultReg, -1)
|
||||
}
|
||||
DataType.WORD -> {
|
||||
val notNegativeLabel = codeGen.createLabelName()
|
||||
val compareReg = codeGen.registers.nextFree()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOADR, IRDataType.WORD, reg1=compareReg, reg2=tr.resultReg)
|
||||
it += IRInstruction(Opcode.AND, IRDataType.WORD, reg1=compareReg, value=0x8000)
|
||||
it += IRInstruction(Opcode.BZ, IRDataType.WORD, reg1=compareReg, labelSymbol = notNegativeLabel)
|
||||
it += IRInstruction(Opcode.NEG, IRDataType.WORD, reg1=tr.resultReg)
|
||||
}
|
||||
result += IRCodeChunk(notNegativeLabel, null)
|
||||
return ExpressionCodeResult(result, IRDataType.WORD, tr.resultReg, -1)
|
||||
}
|
||||
else -> throw AssemblyError("weird type")
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private fun funcSgn(call: PtBuiltinFunctionCall, resultRegister: Int): IRCodeChunks {
|
||||
val reg = codeGen.registers.nextFree()
|
||||
private fun funcSgn(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
val vmDt = codeGen.irType(call.type)
|
||||
val tr = exprGen.translateExpression(call.args.single())
|
||||
addToResult(result, tr, tr.resultReg, -1)
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.SGN, vmDt, reg1 = tr.resultReg, reg2 = tr.resultReg)
|
||||
}
|
||||
return ExpressionCodeResult(result, vmDt, tr.resultReg, -1)
|
||||
}
|
||||
|
||||
private fun funcSqrt16(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
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.SGN, codeGen.irType(call.type), reg1 = resultRegister, reg2 = reg)
|
||||
it += IRInstruction(Opcode.SQRT, IRDataType.WORD, reg1=tr.resultReg, reg2=tr.resultReg)
|
||||
}
|
||||
return result
|
||||
return ExpressionCodeResult(result, IRDataType.WORD, tr.resultReg, -1)
|
||||
}
|
||||
|
||||
private fun funcSqrt16(call: PtBuiltinFunctionCall, resultRegister: Int): IRCodeChunks {
|
||||
val reg = codeGen.registers.nextFree()
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
val tr = exprGen.translateExpression(call.args.single())
|
||||
addToResult(result, tr, reg, -1)
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.SQRT, IRDataType.WORD, reg1=resultRegister, reg2=reg)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private fun funcPop(call: PtBuiltinFunctionCall): IRCodeChunks {
|
||||
private fun funcPop(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||
val code = IRCodeChunk(null, null)
|
||||
val reg = codeGen.registers.nextFree()
|
||||
code += IRInstruction(Opcode.POP, IRDataType.BYTE, reg1=reg)
|
||||
val result = mutableListOf<IRCodeChunkBase>(code)
|
||||
result += assignRegisterTo(call.args.single(), reg)
|
||||
return result
|
||||
return ExpressionCodeResult(result, IRDataType.BYTE, reg, -1)
|
||||
}
|
||||
|
||||
private fun funcPopw(call: PtBuiltinFunctionCall): IRCodeChunks {
|
||||
private fun funcPopw(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||
val code = IRCodeChunk(null, null)
|
||||
val reg = codeGen.registers.nextFree()
|
||||
code += IRInstruction(Opcode.POP, IRDataType.WORD, reg1=reg)
|
||||
val result = mutableListOf<IRCodeChunkBase>(code)
|
||||
result += assignRegisterTo(call.args.single(), reg)
|
||||
return result
|
||||
return ExpressionCodeResult(result, IRDataType.WORD, reg, -1)
|
||||
}
|
||||
|
||||
private fun funcPush(call: PtBuiltinFunctionCall): IRCodeChunks {
|
||||
private fun funcPush(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
val reg = codeGen.registers.nextFree()
|
||||
val tr = exprGen.translateExpression(call.args.single())
|
||||
@ -258,10 +200,10 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.PUSH, IRDataType.BYTE, reg1=reg)
|
||||
}
|
||||
return result
|
||||
return ExpressionCodeResult(result, IRDataType.BYTE, -1, -1)
|
||||
}
|
||||
|
||||
private fun funcPushw(call: PtBuiltinFunctionCall): IRCodeChunks {
|
||||
private fun funcPushw(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
val reg = codeGen.registers.nextFree()
|
||||
val tr = exprGen.translateExpression(call.args.single())
|
||||
@ -269,10 +211,10 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.PUSH, IRDataType.WORD, reg1 = reg)
|
||||
}
|
||||
return result
|
||||
return ExpressionCodeResult(result, IRDataType.BYTE, -1, -1)
|
||||
}
|
||||
|
||||
private fun funcReverse(call: PtBuiltinFunctionCall): IRCodeChunks {
|
||||
private fun funcReverse(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||
val arrayName = call.args[0] as PtIdentifier
|
||||
val array = codeGen.symbolTable.flat.getValue(arrayName.name) as StStaticVariable
|
||||
val syscall =
|
||||
@ -289,10 +231,10 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = SyscallRegisterBase+1, value = array.length)
|
||||
it += IRInstruction(Opcode.SYSCALL, value = syscall.number)
|
||||
}
|
||||
return result
|
||||
return ExpressionCodeResult(result, IRDataType.BYTE, -1, -1)
|
||||
}
|
||||
|
||||
private fun funcSort(call: PtBuiltinFunctionCall): IRCodeChunks {
|
||||
private fun funcSort(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||
val arrayName = call.args[0] as PtIdentifier
|
||||
val array = codeGen.symbolTable.flat.getValue(arrayName.name) as StStaticVariable
|
||||
val syscall =
|
||||
@ -312,23 +254,23 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = SyscallRegisterBase+1, value = array.length)
|
||||
it += IRInstruction(Opcode.SYSCALL, value = syscall.number)
|
||||
}
|
||||
return result
|
||||
return ExpressionCodeResult(result, IRDataType.BYTE, -1, -1)
|
||||
}
|
||||
|
||||
private fun funcMkword(call: PtBuiltinFunctionCall, resultRegister: Int): IRCodeChunks {
|
||||
private fun funcMkword(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
val msbTr = exprGen.translateExpression(call.args[0])
|
||||
addToResult(result, msbTr, msbTr.resultReg, -1)
|
||||
val lsbTr = exprGen.translateExpression(call.args[1])
|
||||
require(lsbTr.resultReg!=msbTr.resultReg)
|
||||
addToResult(result, lsbTr, resultRegister, -1)
|
||||
addToResult(result, lsbTr, lsbTr.resultReg, -1)
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.CONCAT, IRDataType.BYTE, reg1 = resultRegister, reg2 = msbTr.resultReg)
|
||||
it += IRInstruction(Opcode.CONCAT, IRDataType.BYTE, reg1 = lsbTr.resultReg, reg2 = msbTr.resultReg)
|
||||
}
|
||||
return result
|
||||
return ExpressionCodeResult(result, IRDataType.WORD, lsbTr.resultReg, -1)
|
||||
}
|
||||
|
||||
private fun funcPokeW(call: PtBuiltinFunctionCall): IRCodeChunks {
|
||||
private fun funcPokeW(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
if(codeGen.isZero(call.args[1])) {
|
||||
if (call.args[0] is PtNumber) {
|
||||
@ -364,10 +306,10 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
return ExpressionCodeResult(result, IRDataType.BYTE, -1, -1)
|
||||
}
|
||||
|
||||
private fun funcPoke(call: PtBuiltinFunctionCall): IRCodeChunks {
|
||||
private fun funcPoke(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
if(codeGen.isZero(call.args[1])) {
|
||||
if (call.args[0] is PtNumber) {
|
||||
@ -403,50 +345,53 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
return ExpressionCodeResult(result, IRDataType.BYTE, -1, -1)
|
||||
}
|
||||
|
||||
private fun funcPeekW(call: PtBuiltinFunctionCall, resultRegister: Int): IRCodeChunks {
|
||||
private fun funcPeekW(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
if(call.args[0] is PtNumber) {
|
||||
return if(call.args[0] is PtNumber) {
|
||||
val resultRegister = codeGen.registers.nextFree()
|
||||
val address = (call.args[0] as PtNumber).number.toInt()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOADM, IRDataType.WORD, reg1 = resultRegister, value = address)
|
||||
}
|
||||
ExpressionCodeResult(result, IRDataType.BYTE, resultRegister, -1)
|
||||
} else {
|
||||
val addressReg = codeGen.registers.nextFree()
|
||||
val tr = exprGen.translateExpression(call.args.single())
|
||||
addToResult(result, tr, addressReg, -1)
|
||||
addToResult(result, tr, tr.resultReg, -1)
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOADI, IRDataType.WORD, reg1 = resultRegister, reg2 = addressReg)
|
||||
it += IRInstruction(Opcode.LOADI, IRDataType.WORD, reg1 = tr.resultReg, reg2 = tr.resultReg)
|
||||
}
|
||||
ExpressionCodeResult(result, IRDataType.WORD, tr.resultReg, -1)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private fun funcPeek(call: PtBuiltinFunctionCall, resultRegister: Int): IRCodeChunks {
|
||||
private fun funcPeek(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
if(call.args[0] is PtNumber) {
|
||||
return if(call.args[0] is PtNumber) {
|
||||
val resultRegister = codeGen.registers.nextFree()
|
||||
val address = (call.args[0] as PtNumber).number.toInt()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOADM, IRDataType.BYTE, reg1 = resultRegister, value = address)
|
||||
}
|
||||
ExpressionCodeResult(result, IRDataType.BYTE, resultRegister, -1)
|
||||
} else {
|
||||
val addressReg = codeGen.registers.nextFree()
|
||||
val tr = exprGen.translateExpression(call.args.single())
|
||||
addToResult(result, tr, addressReg, -1)
|
||||
addToResult(result, tr, tr.resultReg, -1)
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOADI, IRDataType.BYTE, reg1 = resultRegister, reg2 = addressReg)
|
||||
it += IRInstruction(Opcode.LOADI, IRDataType.BYTE, reg1 = tr.resultReg, reg2 = tr.resultReg)
|
||||
}
|
||||
ExpressionCodeResult(result, IRDataType.BYTE, tr.resultReg, -1)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private fun funcMemory(call: PtBuiltinFunctionCall, resultRegister: Int): IRCodeChunks {
|
||||
private fun funcMemory(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||
val name = (call.args[0] as PtString).value
|
||||
val code = IRCodeChunk(null, null)
|
||||
code += IRInstruction(Opcode.LOAD, IRDataType.WORD, reg1=resultRegister, labelSymbol = "prog8_slabs.prog8_memoryslab_$name")
|
||||
return listOf(code)
|
||||
val resultReg = codeGen.registers.nextFree()
|
||||
code += IRInstruction(Opcode.LOAD, IRDataType.WORD, reg1=resultReg, labelSymbol = "prog8_slabs.prog8_memoryslab_$name")
|
||||
return ExpressionCodeResult(code, IRDataType.BYTE, resultReg, -1)
|
||||
}
|
||||
|
||||
private fun funcLsb(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||
@ -466,16 +411,16 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
return ExpressionCodeResult(result, IRDataType.BYTE, resultRegister, -1)
|
||||
}
|
||||
|
||||
private fun funcRolRor(opcode: Opcode, call: PtBuiltinFunctionCall, resultRegister: Int): IRCodeChunks {
|
||||
private fun funcRolRor(opcode: Opcode, call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||
val vmDt = codeGen.irType(call.args[0].type)
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
val tr = exprGen.translateExpression(call.args[0])
|
||||
addToResult(result, tr, resultRegister, -1)
|
||||
addToResult(result, tr, tr.resultReg, -1)
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(opcode, vmDt, reg1 = resultRegister)
|
||||
it += IRInstruction(opcode, vmDt, reg1 = tr.resultReg)
|
||||
}
|
||||
result += assignRegisterTo(call.args[0], resultRegister)
|
||||
return result
|
||||
result += assignRegisterTo(call.args[0], tr.resultReg)
|
||||
return ExpressionCodeResult(result, vmDt, -1, -1)
|
||||
}
|
||||
|
||||
private fun assignRegisterTo(target: PtExpression, register: Int): IRCodeChunks {
|
||||
|
@ -459,7 +459,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
addInstr(result, IRInstruction(ins, IRDataType.BYTE, reg1 = resultRegister, reg2 = zeroRegister), null)
|
||||
} else {
|
||||
if(binExpr.left.type==DataType.STR && binExpr.right.type==DataType.STR) {
|
||||
val leftTr = translateExpression(binExpr.right)
|
||||
val leftTr = translateExpression(binExpr.left)
|
||||
addToResult(result, leftTr, SyscallRegisterBase, -1)
|
||||
val rightTr = translateExpression(binExpr.right)
|
||||
require(rightTr.resultReg!=leftTr.resultReg)
|
||||
@ -475,7 +475,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
IRInstruction(Opcode.SGTS, IRDataType.BYTE, reg1 = resultRegister, reg2 = 1)
|
||||
}
|
||||
} else {
|
||||
val leftTr = translateExpression(binExpr.right)
|
||||
val leftTr = translateExpression(binExpr.left)
|
||||
addToResult(result, leftTr, resultRegister, -1)
|
||||
val rightTr = translateExpression(binExpr.right)
|
||||
require(rightTr.resultReg!=leftTr.resultReg)
|
||||
@ -516,7 +516,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
addInstr(result, IRInstruction(ins, IRDataType.BYTE, reg1 = resultRegister, reg2 = zeroRegister), null)
|
||||
} else {
|
||||
if(binExpr.left.type==DataType.STR && binExpr.right.type==DataType.STR) {
|
||||
val leftTr = translateExpression(binExpr.right)
|
||||
val leftTr = translateExpression(binExpr.left)
|
||||
addToResult(result, leftTr, SyscallRegisterBase, -1)
|
||||
val rightTr = translateExpression(binExpr.right)
|
||||
require(rightTr.resultReg!=leftTr.resultReg)
|
||||
@ -532,7 +532,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
IRInstruction(Opcode.SLTS, IRDataType.BYTE, reg1 = resultRegister, reg2 = 1)
|
||||
}
|
||||
} else {
|
||||
val leftTr = translateExpression(binExpr.right)
|
||||
val leftTr = translateExpression(binExpr.left)
|
||||
addToResult(result, leftTr, resultRegister, -1)
|
||||
val rightTr = translateExpression(binExpr.right)
|
||||
require(rightTr.resultReg!=leftTr.resultReg)
|
||||
@ -589,7 +589,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
val opcode = if (notEquals) Opcode.SNZ else Opcode.SZ
|
||||
addInstr(result, IRInstruction(opcode, vmDt, reg1 = resultRegister, reg2 = resultRegister), null)
|
||||
} else {
|
||||
val leftTr = translateExpression(binExpr.right)
|
||||
val leftTr = translateExpression(binExpr.left)
|
||||
addToResult(result, leftTr, resultRegister, -1)
|
||||
val rightTr = translateExpression(binExpr.right)
|
||||
require(rightTr.resultReg!=leftTr.resultReg)
|
||||
@ -610,7 +610,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
val opc = if (signed) Opcode.ASR else Opcode.LSR
|
||||
addInstr(result, IRInstruction(opc, vmDt, reg1 = resultRegister), null)
|
||||
} else {
|
||||
val leftTr = translateExpression(binExpr.right)
|
||||
val leftTr = translateExpression(binExpr.left)
|
||||
addToResult(result, leftTr, resultRegister, -1)
|
||||
val rightTr = translateExpression(binExpr.right)
|
||||
require(rightTr.resultReg!=leftTr.resultReg)
|
||||
@ -650,7 +650,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
addToResult(result, tr, resultRegister, -1)
|
||||
addInstr(result, IRInstruction(Opcode.LSL, vmDt, reg1=resultRegister), null)
|
||||
} else {
|
||||
val leftTr = translateExpression(binExpr.right)
|
||||
val leftTr = translateExpression(binExpr.left)
|
||||
addToResult(result, leftTr, resultRegister, -1)
|
||||
val rightTr = translateExpression(binExpr.right)
|
||||
require(rightTr.resultReg!=leftTr.resultReg)
|
||||
@ -687,7 +687,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
addToResult(result, tr, resultRegister, -1)
|
||||
addInstr(result, IRInstruction(Opcode.XOR, vmDt, reg1 = resultRegister, value=(binExpr.right as PtNumber).number.toInt()), null)
|
||||
} else {
|
||||
val leftTr = translateExpression(binExpr.right)
|
||||
val leftTr = translateExpression(binExpr.left)
|
||||
addToResult(result, leftTr, resultRegister, -1)
|
||||
val rightTr = translateExpression(binExpr.right)
|
||||
require(rightTr.resultReg!=leftTr.resultReg)
|
||||
@ -775,7 +775,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
addToResult(result, tr, resultRegister, -1)
|
||||
addInstr(result, IRInstruction(Opcode.MOD, vmDt, reg1 = resultRegister, value=(binExpr.right as PtNumber).number.toInt()), null)
|
||||
} else {
|
||||
val leftTr = translateExpression(binExpr.right)
|
||||
val leftTr = translateExpression(binExpr.left)
|
||||
addToResult(result, leftTr, resultRegister, -1)
|
||||
val rightTr = translateExpression(binExpr.right)
|
||||
require(rightTr.resultReg!=leftTr.resultReg)
|
||||
@ -907,7 +907,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
val factor = constFactorRight.number.toFloat()
|
||||
result += codeGen.multiplyByConstFloat(resultFpRegister, factor)
|
||||
} else {
|
||||
val leftTr = translateExpression(binExpr.right)
|
||||
val leftTr = translateExpression(binExpr.left)
|
||||
addToResult(result, leftTr, -1, resultFpRegister)
|
||||
val rightTr = translateExpression(binExpr.right)
|
||||
require(rightTr.resultFpReg!=leftTr.resultFpReg)
|
||||
@ -926,7 +926,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
val factor = constFactorRight.number.toInt()
|
||||
result += codeGen.multiplyByConst(vmDt, resultRegister, factor)
|
||||
} else {
|
||||
val leftTr = translateExpression(binExpr.right)
|
||||
val leftTr = translateExpression(binExpr.left)
|
||||
addToResult(result, leftTr, resultRegister, -1)
|
||||
val rightTr = translateExpression(binExpr.right)
|
||||
require(rightTr.resultReg!=leftTr.resultReg)
|
||||
@ -984,7 +984,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
addToResult(result, tr, -1, resultFpRegister)
|
||||
addInstr(result, IRInstruction(Opcode.SUB, vmDt, fpReg1 = resultFpRegister, fpValue = (binExpr.right as PtNumber).number.toFloat()), null)
|
||||
} else {
|
||||
val leftTr = translateExpression(binExpr.right)
|
||||
val leftTr = translateExpression(binExpr.left)
|
||||
addToResult(result, leftTr, -1, resultFpRegister)
|
||||
val rightTr = translateExpression(binExpr.right)
|
||||
require(rightTr.resultFpReg!=leftTr.resultFpReg)
|
||||
@ -1004,7 +1004,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
addToResult(result, tr, resultRegister, -1)
|
||||
addInstr(result, IRInstruction(Opcode.SUB, vmDt, reg1 = resultRegister, value = (binExpr.right as PtNumber).number.toInt()), null)
|
||||
} else {
|
||||
val leftTr = translateExpression(binExpr.right)
|
||||
val leftTr = translateExpression(binExpr.left)
|
||||
addToResult(result, leftTr, resultRegister, -1)
|
||||
val rightTr = translateExpression(binExpr.right)
|
||||
require(rightTr.resultReg!=leftTr.resultReg)
|
||||
@ -1075,7 +1075,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
addToResult(result, tr, -1, resultFpRegister)
|
||||
addInstr(result, IRInstruction(Opcode.ADD, vmDt, fpReg1 = resultFpRegister, fpValue = (binExpr.right as PtNumber).number.toFloat()), null)
|
||||
} else {
|
||||
val leftTr = translateExpression(binExpr.right)
|
||||
val leftTr = translateExpression(binExpr.left)
|
||||
addToResult(result, leftTr, -1, resultFpRegister)
|
||||
val rightTr = translateExpression(binExpr.right)
|
||||
require(rightTr.resultFpReg!=leftTr.resultFpReg)
|
||||
@ -1100,7 +1100,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
addToResult(result, tr, resultRegister, -1)
|
||||
addInstr(result, IRInstruction(Opcode.ADD, vmDt, reg1 = resultRegister, value=(binExpr.right as PtNumber).number.toInt()), null)
|
||||
} else {
|
||||
val leftTr = translateExpression(binExpr.right)
|
||||
val leftTr = translateExpression(binExpr.left)
|
||||
addToResult(result, leftTr, resultRegister, -1)
|
||||
val rightTr = translateExpression(binExpr.right)
|
||||
require(rightTr.resultReg!=leftTr.resultReg)
|
||||
|
@ -999,14 +999,13 @@ class IRCodeGen(
|
||||
val branchDt: IRDataType
|
||||
if(irDtLeft==IRDataType.FLOAT) {
|
||||
branchDt = IRDataType.BYTE
|
||||
val leftFpReg = registers.nextFreeFloat()
|
||||
val rightFpReg = registers.nextFreeFloat()
|
||||
compResultReg = registers.nextFree()
|
||||
val tr = expressionEval.translateExpression(ifElse.condition.left)
|
||||
addToResult(result, tr, -1, leftFpReg)
|
||||
val leftTr = expressionEval.translateExpression(ifElse.condition.left)
|
||||
addToResult(result, leftTr, -1, leftTr.resultFpReg)
|
||||
result += IRCodeChunk(null, null).also {
|
||||
val rightFpReg = registers.nextFreeFloat()
|
||||
it += IRInstruction(Opcode.LOAD, IRDataType.FLOAT, fpReg1 = rightFpReg, fpValue = 0f)
|
||||
it += IRInstruction(Opcode.FCOMP, IRDataType.FLOAT, reg1=compResultReg, fpReg1 = leftFpReg, fpReg2 = rightFpReg)
|
||||
it += IRInstruction(Opcode.FCOMP, IRDataType.FLOAT, reg1=compResultReg, fpReg1 = leftTr.resultFpReg, fpReg2 = rightFpReg)
|
||||
}
|
||||
elseBranch = when (ifElse.condition.operator) {
|
||||
"==" -> Opcode.BNZ
|
||||
@ -1279,16 +1278,14 @@ class IRCodeGen(
|
||||
addInstr(result, IRInstruction(Opcode.RETURN), null)
|
||||
} else {
|
||||
if(value.type==DataType.FLOAT) {
|
||||
val reg = registers.nextFreeFloat()
|
||||
val tr = expressionEval.translateExpression(value)
|
||||
addToResult(result, tr, -1, reg)
|
||||
addInstr(result, IRInstruction(Opcode.RETURNREG, IRDataType.FLOAT, fpReg1 = reg), null)
|
||||
addToResult(result, tr, -1, tr.resultFpReg)
|
||||
addInstr(result, IRInstruction(Opcode.RETURNREG, IRDataType.FLOAT, fpReg1 = tr.resultFpReg), null)
|
||||
}
|
||||
else {
|
||||
val reg = registers.nextFree()
|
||||
val tr = expressionEval.translateExpression(value)
|
||||
addToResult(result, tr, reg, -1)
|
||||
addInstr(result, IRInstruction(Opcode.RETURNREG, irType(value.type) , reg1=reg), null)
|
||||
addToResult(result, tr, tr.resultReg, -1)
|
||||
addInstr(result, IRInstruction(Opcode.RETURNREG, irType(value.type) , reg1=tr.resultReg), null)
|
||||
}
|
||||
}
|
||||
return result
|
||||
|
@ -3,7 +3,6 @@ TODO
|
||||
|
||||
For next minor release
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
- fix VM bsieve not printing the last number and string correctly
|
||||
- fix IR/VM crashing in bouncegfx and textelite
|
||||
- reduce the usage of register.nextFree() in IR codegen
|
||||
- get rid of ResultRegister in IR codegen? as the calls now encode this into the new opcodes...
|
||||
|
Loading…
x
Reference in New Issue
Block a user