mirror of
https://github.com/irmen/prog8.git
synced 2024-09-30 00:55:52 +00:00
vm syscall instruction no longer fixed to r0
This commit is contained in:
parent
5196443b26
commit
ac21e1be5c
@ -74,10 +74,9 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
|||||||
val left = exprGen.translateExpression(call.args[0])
|
val left = exprGen.translateExpression(call.args[0])
|
||||||
val right = exprGen.translateExpression(call.args[1])
|
val right = exprGen.translateExpression(call.args[1])
|
||||||
val targetReg = codeGen.registers.nextFree()
|
val targetReg = codeGen.registers.nextFree()
|
||||||
addToResult(result, left, 65500, -1)
|
addToResult(result, left, SyscallRegisterBase, -1)
|
||||||
addToResult(result, right, 65501, -1)
|
addToResult(result, right, SyscallRegisterBase+1, -1)
|
||||||
addInstr(result, IRInstruction(Opcode.SYSCALL, immediate = IMSyscall.COMPARE_STRINGS.number), null)
|
addInstr(result, IRInstruction(Opcode.SYSCALLR, IRDataType.BYTE, reg1=targetReg, immediate = IMSyscall.COMPARE_STRINGS.number), null)
|
||||||
addInstr(result, IRInstruction(Opcode.LOADR, IRDataType.BYTE, reg1=targetReg, reg2=0), null)
|
|
||||||
return ExpressionCodeResult(result, IRDataType.BYTE, targetReg, -1)
|
return ExpressionCodeResult(result, IRDataType.BYTE, targetReg, -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,10 +110,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
|||||||
addToResult(result, tr, SyscallRegisterBase, -1)
|
addToResult(result, tr, SyscallRegisterBase, -1)
|
||||||
result += IRCodeChunk(null, null).also {
|
result += IRCodeChunk(null, null).also {
|
||||||
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = SyscallRegisterBase+1, immediate = array.length)
|
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = SyscallRegisterBase+1, immediate = array.length)
|
||||||
it += IRInstruction(Opcode.SYSCALL, immediate = syscall.number)
|
it += IRInstruction(Opcode.SYSCALLR, IRDataType.BYTE, reg1=tr.resultReg, immediate = syscall.number)
|
||||||
// SysCall call convention: return value in register r0
|
|
||||||
if(tr.resultReg!=0)
|
|
||||||
it += IRInstruction(Opcode.LOADR, IRDataType.BYTE, reg1 = tr.resultReg, reg2 = 0)
|
|
||||||
}
|
}
|
||||||
return ExpressionCodeResult(result, IRDataType.BYTE, tr.resultReg, -1)
|
return ExpressionCodeResult(result, IRDataType.BYTE, tr.resultReg, -1)
|
||||||
}
|
}
|
||||||
@ -136,10 +132,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
|||||||
addToResult(result, tr, SyscallRegisterBase, -1)
|
addToResult(result, tr, SyscallRegisterBase, -1)
|
||||||
result += IRCodeChunk(null, null).also {
|
result += IRCodeChunk(null, null).also {
|
||||||
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = SyscallRegisterBase+1, immediate = array.length)
|
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = SyscallRegisterBase+1, immediate = array.length)
|
||||||
it += IRInstruction(Opcode.SYSCALL, immediate = syscall.number)
|
it += IRInstruction(Opcode.SYSCALLR, IRDataType.BYTE, reg1=tr.resultReg, immediate = syscall.number)
|
||||||
// SysCall call convention: return value in register r0
|
|
||||||
if(tr.resultReg!=0)
|
|
||||||
it += IRInstruction(Opcode.LOADR, IRDataType.BYTE, reg1 = tr.resultReg, reg2 = 0)
|
|
||||||
}
|
}
|
||||||
return ExpressionCodeResult(result, IRDataType.BYTE, tr.resultReg, -1)
|
return ExpressionCodeResult(result, IRDataType.BYTE, tr.resultReg, -1)
|
||||||
}
|
}
|
||||||
|
@ -116,8 +116,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
addToResult(result, tr, SyscallRegisterBase+1, -1)
|
addToResult(result, tr, SyscallRegisterBase+1, -1)
|
||||||
val resultReg = codeGen.registers.nextFree()
|
val resultReg = codeGen.registers.nextFree()
|
||||||
result += IRCodeChunk(null, null).also {
|
result += IRCodeChunk(null, null).also {
|
||||||
it += IRInstruction(Opcode.SYSCALL, immediate = IMSyscall.STRING_CONTAINS.number)
|
it += IRInstruction(Opcode.SYSCALLR, IRDataType.BYTE, reg1=resultReg, immediate = IMSyscall.STRING_CONTAINS.number)
|
||||||
it += IRInstruction(Opcode.LOADR, IRDataType.BYTE, reg1=resultReg, reg2=0)
|
|
||||||
}
|
}
|
||||||
return ExpressionCodeResult(result, IRDataType.BYTE, resultReg, -1)
|
return ExpressionCodeResult(result, IRDataType.BYTE, resultReg, -1)
|
||||||
}
|
}
|
||||||
@ -129,8 +128,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
val resultReg = codeGen.registers.nextFree()
|
val resultReg = codeGen.registers.nextFree()
|
||||||
result += IRCodeChunk(null, null).also {
|
result += IRCodeChunk(null, null).also {
|
||||||
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=SyscallRegisterBase+2, immediate = iterable.length!!)
|
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=SyscallRegisterBase+2, immediate = iterable.length!!)
|
||||||
it += IRInstruction(Opcode.SYSCALL, immediate = IMSyscall.BYTEARRAY_CONTAINS.number)
|
it += IRInstruction(Opcode.SYSCALLR, IRDataType.BYTE, reg1=resultReg, immediate = IMSyscall.BYTEARRAY_CONTAINS.number)
|
||||||
it += IRInstruction(Opcode.LOADR, IRDataType.BYTE, reg1=resultReg, reg2=0)
|
|
||||||
}
|
}
|
||||||
// SysCall call convention: return value in register r0
|
// SysCall call convention: return value in register r0
|
||||||
return ExpressionCodeResult(result, IRDataType.BYTE, resultReg, -1)
|
return ExpressionCodeResult(result, IRDataType.BYTE, resultReg, -1)
|
||||||
@ -143,8 +141,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
val resultReg = codeGen.registers.nextFree()
|
val resultReg = codeGen.registers.nextFree()
|
||||||
result += IRCodeChunk(null, null).also {
|
result += IRCodeChunk(null, null).also {
|
||||||
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=SyscallRegisterBase+2, immediate = iterable.length!!)
|
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=SyscallRegisterBase+2, immediate = iterable.length!!)
|
||||||
it += IRInstruction(Opcode.SYSCALL, immediate = IMSyscall.WORDARRAY_CONTAINS.number)
|
it += IRInstruction(Opcode.SYSCALLR, IRDataType.BYTE, reg1=resultReg, immediate = IMSyscall.WORDARRAY_CONTAINS.number)
|
||||||
it += IRInstruction(Opcode.LOADR, IRDataType.BYTE, reg1=resultReg, reg2=0)
|
|
||||||
}
|
}
|
||||||
return ExpressionCodeResult(result, IRDataType.BYTE, resultReg, -1)
|
return ExpressionCodeResult(result, IRDataType.BYTE, resultReg, -1)
|
||||||
}
|
}
|
||||||
@ -469,8 +466,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
val rightTr = translateExpression(binExpr.right)
|
val rightTr = translateExpression(binExpr.right)
|
||||||
addToResult(result, rightTr, SyscallRegisterBase+1, -1)
|
addToResult(result, rightTr, SyscallRegisterBase+1, -1)
|
||||||
result += IRCodeChunk(null, null).also {
|
result += IRCodeChunk(null, null).also {
|
||||||
it += IRInstruction(Opcode.SYSCALL, immediate = IMSyscall.COMPARE_STRINGS.number)
|
it += IRInstruction(Opcode.SYSCALLR, IRDataType.BYTE, reg1 = leftTr.resultReg, immediate = IMSyscall.COMPARE_STRINGS.number)
|
||||||
// SysCall call convention: return value in register r0
|
|
||||||
val zeroReg = codeGen.registers.nextFree()
|
val zeroReg = codeGen.registers.nextFree()
|
||||||
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = zeroReg, immediate = 0)
|
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = zeroReg, immediate = 0)
|
||||||
it += if (greaterEquals)
|
it += if (greaterEquals)
|
||||||
@ -524,17 +520,15 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
addToResult(result, leftTr, SyscallRegisterBase, -1)
|
addToResult(result, leftTr, SyscallRegisterBase, -1)
|
||||||
val rightTr = translateExpression(binExpr.right)
|
val rightTr = translateExpression(binExpr.right)
|
||||||
addToResult(result, rightTr, SyscallRegisterBase+1, -1)
|
addToResult(result, rightTr, SyscallRegisterBase+1, -1)
|
||||||
val resultReg = codeGen.registers.nextFree()
|
val resultReg = codeGen.registers.nextFree() // TODO reuse leftTr resultreg?
|
||||||
result += IRCodeChunk(null, null).also {
|
result += IRCodeChunk(null, null).also {
|
||||||
it += IRInstruction(Opcode.SYSCALL, immediate = IMSyscall.COMPARE_STRINGS.number)
|
it += IRInstruction(Opcode.SYSCALLR, IRDataType.BYTE, reg1=resultReg, immediate = IMSyscall.COMPARE_STRINGS.number)
|
||||||
// SysCall call convention: return value in register r0
|
|
||||||
val zeroReg = codeGen.registers.nextFree()
|
val zeroReg = codeGen.registers.nextFree()
|
||||||
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = zeroReg, immediate = 0)
|
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = zeroReg, immediate = 0)
|
||||||
it += if (lessEquals)
|
it += if (lessEquals)
|
||||||
IRInstruction(Opcode.SLES, IRDataType.BYTE, reg1 = 0, reg2 = zeroReg)
|
IRInstruction(Opcode.SLES, IRDataType.BYTE, reg1 = resultReg, reg2 = zeroReg)
|
||||||
else
|
else
|
||||||
IRInstruction(Opcode.SLTS, IRDataType.BYTE, reg1 = 0, reg2 = zeroReg)
|
IRInstruction(Opcode.SLTS, IRDataType.BYTE, reg1 = resultReg, reg2 = zeroReg)
|
||||||
it += IRInstruction(Opcode.LOADR, IRDataType.BYTE, reg1=resultReg, reg2=0)
|
|
||||||
}
|
}
|
||||||
return ExpressionCodeResult(result, IRDataType.BYTE, resultReg, -1)
|
return ExpressionCodeResult(result, IRDataType.BYTE, resultReg, -1)
|
||||||
} else {
|
} else {
|
||||||
@ -581,11 +575,9 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
addToResult(result, rightTr, SyscallRegisterBase+1, -1)
|
addToResult(result, rightTr, SyscallRegisterBase+1, -1)
|
||||||
val resultRegister = codeGen.registers.nextFree()
|
val resultRegister = codeGen.registers.nextFree()
|
||||||
result += IRCodeChunk(null, null).also {
|
result += IRCodeChunk(null, null).also {
|
||||||
it += IRInstruction(Opcode.SYSCALL, immediate = IMSyscall.COMPARE_STRINGS.number)
|
it += IRInstruction(Opcode.SYSCALLR, IRDataType.BYTE, reg1=resultRegister, immediate = IMSyscall.COMPARE_STRINGS.number)
|
||||||
// SysCall call convention: return value in register r0
|
|
||||||
if (!notEquals)
|
if (!notEquals)
|
||||||
it += IRInstruction(Opcode.INV, vmDt, reg1 = 0)
|
it += IRInstruction(Opcode.INV, vmDt, reg1 = resultRegister)
|
||||||
it += IRInstruction(Opcode.LOADR, vmDt, reg1=resultRegister, reg2=0)
|
|
||||||
it += IRInstruction(Opcode.AND, vmDt, reg1 = resultRegister, immediate = 1)
|
it += IRInstruction(Opcode.AND, vmDt, reg1 = resultRegister, immediate = 1)
|
||||||
}
|
}
|
||||||
return ExpressionCodeResult(result, IRDataType.BYTE, resultRegister, -1)
|
return ExpressionCodeResult(result, IRDataType.BYTE, resultRegister, -1)
|
||||||
|
@ -5,7 +5,7 @@ import prog8.intermediate.SyscallRegisterBase
|
|||||||
|
|
||||||
internal class RegisterPool {
|
internal class RegisterPool {
|
||||||
// reserve 0,1,2 for return values of subroutine calls and syscalls
|
// reserve 0,1,2 for return values of subroutine calls and syscalls
|
||||||
// TODO set this back to 0 once 'resultRegister' has been removed everywhere and SYSCALL/DIVMOD fixed?
|
// TODO set this back to 0 once 'resultRegister' has been removed everywhere and DIVMOD fixed to not use r0?
|
||||||
private var firstFree: Int=3
|
private var firstFree: Int=3
|
||||||
private var firstFreeFloat: Int=3
|
private var firstFreeFloat: Int=3
|
||||||
|
|
||||||
|
@ -197,7 +197,7 @@ sub str2uword(str string) -> uword {
|
|||||||
; (any non-digit character will terminate the number string that is parsed)
|
; (any non-digit character will terminate the number string that is parsed)
|
||||||
%ir {{
|
%ir {{
|
||||||
loadm.w r65500,conv.str2uword.string
|
loadm.w r65500,conv.str2uword.string
|
||||||
syscall 11
|
syscallr.w r0,11
|
||||||
returnreg.w r0
|
returnreg.w r0
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
@ -208,7 +208,7 @@ sub str2word(str string) -> word {
|
|||||||
; (any non-digit character will terminate the number string that is parsed)
|
; (any non-digit character will terminate the number string that is parsed)
|
||||||
%ir {{
|
%ir {{
|
||||||
loadm.w r65500,conv.str2word.string
|
loadm.w r65500,conv.str2word.string
|
||||||
syscall 12
|
syscallr.w r0,12
|
||||||
returnreg.w r0
|
returnreg.w r0
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
@ -126,7 +126,7 @@ sub ceil(float value) -> float {
|
|||||||
|
|
||||||
sub rndf() -> float {
|
sub rndf() -> float {
|
||||||
%ir {{
|
%ir {{
|
||||||
syscall 35
|
syscallr.f fr0,35
|
||||||
returnreg.f fr0
|
returnreg.f fr0
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
@ -161,14 +161,14 @@ math {
|
|||||||
|
|
||||||
sub rnd() -> ubyte {
|
sub rnd() -> ubyte {
|
||||||
%ir {{
|
%ir {{
|
||||||
syscall 33
|
syscallr.b r0,33
|
||||||
returnreg.b r0
|
returnreg.b r0
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub rndw() -> uword {
|
sub rndw() -> uword {
|
||||||
%ir {{
|
%ir {{
|
||||||
syscall 34
|
syscallr.w r0,34
|
||||||
returnreg.w r0
|
returnreg.w r0
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,7 @@ string {
|
|||||||
%ir {{
|
%ir {{
|
||||||
loadm.w r65500,string.compare.st1
|
loadm.w r65500,string.compare.st1
|
||||||
loadm.w r65501,string.compare.st2
|
loadm.w r65501,string.compare.st2
|
||||||
syscall 29
|
syscallr.b r0,29
|
||||||
returnreg.b r0
|
returnreg.b r0
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
@ -107,7 +107,7 @@ sys {
|
|||||||
%ir {{
|
%ir {{
|
||||||
loadm.w r65500,sys.gfx_getpixel.xx
|
loadm.w r65500,sys.gfx_getpixel.xx
|
||||||
loadm.w r65501,sys.gfx_getpixel.yy
|
loadm.w r65501,sys.gfx_getpixel.yy
|
||||||
syscall 30
|
syscallr.b r0,30
|
||||||
returnreg.b r0
|
returnreg.b r0
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
@ -123,7 +123,7 @@ sub input_chars (uword buffer) -> ubyte {
|
|||||||
; It assumes the keyboard is selected as I/O channel!
|
; It assumes the keyboard is selected as I/O channel!
|
||||||
%ir {{
|
%ir {{
|
||||||
loadm.w r65500,txt.input_chars.buffer
|
loadm.w r65500,txt.input_chars.buffer
|
||||||
syscall 6
|
syscallr.b r0,6
|
||||||
returnreg.b r0
|
returnreg.b r0
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,8 @@ jump location - continue running at instruction number g
|
|||||||
jumpa address - continue running at memory address (note: only used to encode a physical cpu jump to fixed address instruction)
|
jumpa address - continue running at memory address (note: only used to encode a physical cpu jump to fixed address instruction)
|
||||||
call location - save current instruction location+1, continue execution at instruction nr given by location. Expect no return value.
|
call location - save current instruction location+1, continue execution at instruction nr given by location. Expect no return value.
|
||||||
callrval reg1, location - like call but expects a return value from a returnreg instruction, and puts that in reg1
|
callrval reg1, location - like call but expects a return value from a returnreg instruction, and puts that in reg1
|
||||||
syscall value - do a systemcall identified by call number
|
syscall value - do a systemcall identified by call number, no result value
|
||||||
|
syscallr reg1, value - do a systemcall identified by call number, result value is set into reg1
|
||||||
return - restore last saved instruction location and continue at that instruction. No return value.
|
return - restore last saved instruction location and continue at that instruction. No return value.
|
||||||
returnreg reg1 - like return, but also returns a value to the caller via reg1
|
returnreg reg1 - like return, but also returns a value to the caller via reg1
|
||||||
|
|
||||||
@ -237,6 +238,7 @@ enum class Opcode {
|
|||||||
CALL,
|
CALL,
|
||||||
CALLRVAL,
|
CALLRVAL,
|
||||||
SYSCALL,
|
SYSCALL,
|
||||||
|
SYSCALLR,
|
||||||
RETURN,
|
RETURN,
|
||||||
RETURNREG,
|
RETURNREG,
|
||||||
|
|
||||||
@ -386,6 +388,7 @@ val OpcodesThatBranch = setOf(
|
|||||||
Opcode.CALL,
|
Opcode.CALL,
|
||||||
Opcode.CALLRVAL,
|
Opcode.CALLRVAL,
|
||||||
Opcode.SYSCALL,
|
Opcode.SYSCALL,
|
||||||
|
Opcode.SYSCALLR,
|
||||||
Opcode.BSTCC,
|
Opcode.BSTCC,
|
||||||
Opcode.BSTCS,
|
Opcode.BSTCS,
|
||||||
Opcode.BSTEQ,
|
Opcode.BSTEQ,
|
||||||
@ -517,6 +520,7 @@ val instructionFormats = mutableMapOf(
|
|||||||
Opcode.CALL to InstructionFormat.from("N,<a"),
|
Opcode.CALL to InstructionFormat.from("N,<a"),
|
||||||
Opcode.CALLRVAL to InstructionFormat.from("BW,>r1,<a | F,>fr1,<a"),
|
Opcode.CALLRVAL to InstructionFormat.from("BW,>r1,<a | F,>fr1,<a"),
|
||||||
Opcode.SYSCALL to InstructionFormat.from("N,<i"),
|
Opcode.SYSCALL to InstructionFormat.from("N,<i"),
|
||||||
|
Opcode.SYSCALLR to InstructionFormat.from("BW,>r1,<i | F,>fr1,<i"),
|
||||||
Opcode.RETURN to InstructionFormat.from("N"),
|
Opcode.RETURN to InstructionFormat.from("N"),
|
||||||
Opcode.RETURNREG to InstructionFormat.from("BW,>r1 | F,>fr1"),
|
Opcode.RETURNREG to InstructionFormat.from("BW,>r1 | F,>fr1"),
|
||||||
Opcode.BSTCC to InstructionFormat.from("N,<a"),
|
Opcode.BSTCC to InstructionFormat.from("N,<a"),
|
||||||
@ -695,7 +699,7 @@ data class IRInstruction(
|
|||||||
if(format.fpReg1==OperandDirection.UNUSED) require(fpReg1==null) { "invalid fpReg1" }
|
if(format.fpReg1==OperandDirection.UNUSED) require(fpReg1==null) { "invalid fpReg1" }
|
||||||
if(format.fpReg2==OperandDirection.UNUSED) require(fpReg2==null) { "invalid fpReg2" }
|
if(format.fpReg2==OperandDirection.UNUSED) require(fpReg2==null) { "invalid fpReg2" }
|
||||||
if(format.immediate) {
|
if(format.immediate) {
|
||||||
if(type==IRDataType.FLOAT) require(immediateFp !=null) {"missing immediate fp value"}
|
if(type==IRDataType.FLOAT && opcode!=Opcode.SYSCALLR) require(immediateFp !=null) {"missing immediate fp value"}
|
||||||
else require(immediate!=null || labelSymbol!=null) {"missing immediate value or labelsymbol"}
|
else require(immediate!=null || labelSymbol!=null) {"missing immediate value or labelsymbol"}
|
||||||
}
|
}
|
||||||
if(type!=IRDataType.FLOAT)
|
if(type!=IRDataType.FLOAT)
|
||||||
@ -703,12 +707,14 @@ data class IRInstruction(
|
|||||||
if(format.address!=OperandDirection.UNUSED)
|
if(format.address!=OperandDirection.UNUSED)
|
||||||
require(address!=null || labelSymbol!=null) {"missing an address or labelsymbol"}
|
require(address!=null || labelSymbol!=null) {"missing an address or labelsymbol"}
|
||||||
if(format.immediate && (immediate!=null || immediateFp!=null)) {
|
if(format.immediate && (immediate!=null || immediateFp!=null)) {
|
||||||
|
if(opcode!=Opcode.SYSCALL && opcode!=Opcode.SYSCALLR) {
|
||||||
when (type) {
|
when (type) {
|
||||||
IRDataType.BYTE -> require(immediate in -128..255) {"immediate value out of range for byte: $immediate"}
|
IRDataType.BYTE -> require(immediate in -128..255) { "immediate value out of range for byte: $immediate" }
|
||||||
IRDataType.WORD -> require(immediate in -32768..65535) {"immediate value out of range for word: $immediate"}
|
IRDataType.WORD -> require(immediate in -32768..65535) { "immediate value out of range for word: $immediate" }
|
||||||
IRDataType.FLOAT, null -> {}
|
IRDataType.FLOAT, null -> {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
reg1direction = format.reg1
|
reg1direction = format.reg1
|
||||||
reg2direction = format.reg2
|
reg2direction = format.reg2
|
||||||
fpReg1direction = format.fpReg1
|
fpReg1direction = format.fpReg1
|
||||||
@ -725,6 +731,12 @@ data class IRInstruction(
|
|||||||
else
|
else
|
||||||
require(reg1!=reg2) {"$opcode: reg1 and reg2 should be different"}
|
require(reg1!=reg2) {"$opcode: reg1 and reg2 should be different"}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(opcode==Opcode.SYSCALL || opcode==Opcode.SYSCALLR) {
|
||||||
|
require(immediate!=null) {
|
||||||
|
"syscall needs immediate integer for the syscall number"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addUsedRegistersCounts(
|
fun addUsedRegistersCounts(
|
||||||
|
@ -182,7 +182,7 @@ fun parseIRCodeLine(line: String, location: Pair<IRCodeChunk, Int>?, placeholder
|
|||||||
throw IRParseException("invalid fpReg1 for $line")
|
throw IRParseException("invalid fpReg1 for $line")
|
||||||
if(format.fpReg2==OperandDirection.UNUSED && fpReg2!=null)
|
if(format.fpReg2==OperandDirection.UNUSED && fpReg2!=null)
|
||||||
throw IRParseException("invalid fpReg2 for $line")
|
throw IRParseException("invalid fpReg2 for $line")
|
||||||
if(format.immediate) {
|
if(format.immediate && opcode!=Opcode.SYSCALL && opcode!=Opcode.SYSCALLR) {
|
||||||
if(immediateInt==null && immediateFp==null && labelSymbol==null)
|
if(immediateInt==null && immediateFp==null && labelSymbol==null)
|
||||||
throw IRParseException("needs value or symbol for $line")
|
throw IRParseException("needs value or symbol for $line")
|
||||||
when (type) {
|
when (type) {
|
||||||
@ -222,5 +222,10 @@ fun parseIRCodeLine(line: String, location: Pair<IRCodeChunk, Int>?, placeholder
|
|||||||
return left(IRInstruction(opcode, type, reg1, labelSymbol = reg))
|
return left(IRInstruction(opcode, type, reg1, labelSymbol = reg))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(opcode==Opcode.SYSCALLR && type==IRDataType.FLOAT) {
|
||||||
|
immediateInt = immediateFp!!.toInt()
|
||||||
|
immediateFp = null
|
||||||
|
}
|
||||||
|
|
||||||
return left(IRInstruction(opcode, type, reg1, reg2, fpReg1, fpReg2, immediateInt, immediateFp, address, labelSymbol = labelSymbol))
|
return left(IRInstruction(opcode, type, reg1, reg2, fpReg1, fpReg2, immediateInt, immediateFp, address, labelSymbol = labelSymbol))
|
||||||
}
|
}
|
||||||
|
@ -178,7 +178,8 @@ class VirtualMachine(irProgram: IRProgram) {
|
|||||||
Opcode.JUMPA -> throw IllegalArgumentException("vm program can't jump to system memory address (JUMPA)")
|
Opcode.JUMPA -> throw IllegalArgumentException("vm program can't jump to system memory address (JUMPA)")
|
||||||
Opcode.CALL -> InsCALL(ins)
|
Opcode.CALL -> InsCALL(ins)
|
||||||
Opcode.CALLRVAL -> InsCALLRVAL(ins)
|
Opcode.CALLRVAL -> InsCALLRVAL(ins)
|
||||||
Opcode.SYSCALL -> InsSYSCALL(ins)
|
Opcode.SYSCALL -> InsSYSCALL(ins, false)
|
||||||
|
Opcode.SYSCALLR -> InsSYSCALL(ins, true)
|
||||||
Opcode.RETURN -> InsRETURN()
|
Opcode.RETURN -> InsRETURN()
|
||||||
Opcode.RETURNREG -> InsRETURNREG(ins)
|
Opcode.RETURNREG -> InsRETURNREG(ins)
|
||||||
Opcode.BSTCC -> InsBSTCC(ins)
|
Opcode.BSTCC -> InsBSTCC(ins)
|
||||||
@ -360,7 +361,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
|||||||
nextPc()
|
nextPc()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun InsSYSCALL(i: IRInstruction) {
|
private fun InsSYSCALL(i: IRInstruction, hasReturnReg: Boolean) {
|
||||||
val call = Syscall.values()[i.immediate!!]
|
val call = Syscall.values()[i.immediate!!]
|
||||||
SysCalls.call(call, this)
|
SysCalls.call(call, this)
|
||||||
nextPc()
|
nextPc()
|
||||||
|
@ -100,7 +100,7 @@ class VmProgramLoader {
|
|||||||
private fun pass2translateSyscalls(chunks: MutableList<IRCodeChunk>) {
|
private fun pass2translateSyscalls(chunks: MutableList<IRCodeChunk>) {
|
||||||
chunks.forEach { chunk ->
|
chunks.forEach { chunk ->
|
||||||
chunk.instructions.withIndex().forEach { (index, ins) ->
|
chunk.instructions.withIndex().forEach { (index, ins) ->
|
||||||
if(ins.opcode == Opcode.SYSCALL) {
|
if(ins.opcode == Opcode.SYSCALL || ins.opcode==Opcode.SYSCALLR) {
|
||||||
// convert IR Syscall to VM Syscall
|
// convert IR Syscall to VM Syscall
|
||||||
val vmSyscall = when(ins.immediate!!) {
|
val vmSyscall = when(ins.immediate!!) {
|
||||||
IMSyscall.SORT_UBYTE.number -> Syscall.SORT_UBYTE
|
IMSyscall.SORT_UBYTE.number -> Syscall.SORT_UBYTE
|
||||||
|
Loading…
Reference in New Issue
Block a user