mirror of
https://github.com/irmen/prog8.git
synced 2024-06-14 00:29:34 +00:00
IR: fix some things related to asmsubs
This commit is contained in:
parent
60244aaf16
commit
66e7c51064
|
@ -44,7 +44,7 @@ sealed class PtExpression(val type: DataType, position: Position) : PtNode(posit
|
||||||
}
|
}
|
||||||
is PtContainmentCheck -> other is PtContainmentCheck && other.type==type && other.element isSameAs element && other.iterable isSameAs iterable
|
is PtContainmentCheck -> other is PtContainmentCheck && other.type==type && other.element isSameAs element && other.iterable isSameAs iterable
|
||||||
is PtIdentifier -> other is PtIdentifier && other.type==type && other.name==name
|
is PtIdentifier -> other is PtIdentifier && other.type==type && other.name==name
|
||||||
is PtMachineRegister -> other is PtMachineRegister && other.type==type && other.register==register
|
is PtIrRegister -> other is PtIrRegister && other.type==type && other.register==register
|
||||||
is PtMemoryByte -> other is PtMemoryByte && other.address isSameAs address
|
is PtMemoryByte -> other is PtMemoryByte && other.address isSameAs address
|
||||||
is PtNumber -> other is PtNumber && other.type==type && other.number==number
|
is PtNumber -> other is PtNumber && other.type==type && other.number==number
|
||||||
is PtBool -> other is PtBool && other.value==value
|
is PtBool -> other is PtBool && other.value==value
|
||||||
|
@ -87,7 +87,7 @@ sealed class PtExpression(val type: DataType, position: Position) : PtNode(posit
|
||||||
is PtContainmentCheck -> false
|
is PtContainmentCheck -> false
|
||||||
is PtFunctionCall -> false
|
is PtFunctionCall -> false
|
||||||
is PtIdentifier -> true
|
is PtIdentifier -> true
|
||||||
is PtMachineRegister -> true
|
is PtIrRegister -> true
|
||||||
is PtMemoryByte -> address is PtNumber || address is PtIdentifier
|
is PtMemoryByte -> address is PtNumber || address is PtIdentifier
|
||||||
is PtBool -> true
|
is PtBool -> true
|
||||||
is PtNumber -> true
|
is PtNumber -> true
|
||||||
|
@ -354,7 +354,7 @@ class PtTypeCast(type: DataType, position: Position) : PtExpression(type, positi
|
||||||
|
|
||||||
|
|
||||||
// special node that isn't created from compiling user code, but used internally in the Intermediate Code
|
// special node that isn't created from compiling user code, but used internally in the Intermediate Code
|
||||||
class PtMachineRegister(val register: Int, type: DataType, position: Position) : PtExpression(type, position)
|
class PtIrRegister(val register: Int, type: DataType, position: Position) : PtExpression(type, position)
|
||||||
|
|
||||||
|
|
||||||
fun constValue(expr: PtExpression): Double? = if(expr is PtNumber) expr.number else if(expr is PtBool) expr.asInt().toDouble() else null
|
fun constValue(expr: PtExpression): Double? = if(expr is PtNumber) expr.number else if(expr is PtBool) expr.asInt().toDouble() else null
|
||||||
|
|
|
@ -34,7 +34,7 @@ fun printAst(root: PtNode, skipLibraries: Boolean, output: (text: String) -> Uni
|
||||||
str + node.name + "()"
|
str + node.name + "()"
|
||||||
}
|
}
|
||||||
is PtIdentifier -> "${node.name} ${type(node.type)}"
|
is PtIdentifier -> "${node.name} ${type(node.type)}"
|
||||||
is PtMachineRegister -> "VMREG#${node.register} ${type(node.type)}"
|
is PtIrRegister -> "VMREG#${node.register} ${type(node.type)}"
|
||||||
is PtMemoryByte -> "@()"
|
is PtMemoryByte -> "@()"
|
||||||
is PtNumber -> {
|
is PtNumber -> {
|
||||||
val numstr = if(node.type == DataType.FLOAT) node.number.toString() else node.number.toHex()
|
val numstr = if(node.type == DataType.FLOAT) node.number.toString() else node.number.toHex()
|
||||||
|
|
|
@ -81,7 +81,7 @@ internal class FunctionCallAsmGen(private val program: PtProgram, private val as
|
||||||
}
|
}
|
||||||
is PtAddressOf -> false
|
is PtAddressOf -> false
|
||||||
is PtIdentifier -> false
|
is PtIdentifier -> false
|
||||||
is PtMachineRegister -> false
|
is PtIrRegister -> false
|
||||||
is PtMemoryByte -> return usesOtherRegistersWhileEvaluating(arg.address)
|
is PtMemoryByte -> return usesOtherRegistersWhileEvaluating(arg.address)
|
||||||
is PtNumber -> false
|
is PtNumber -> false
|
||||||
is PtBool -> false
|
is PtBool -> false
|
||||||
|
|
|
@ -70,7 +70,7 @@ internal class IfElseAsmGen(private val program: PtProgram,
|
||||||
is PtNumber,
|
is PtNumber,
|
||||||
is PtBool,
|
is PtBool,
|
||||||
is PtIdentifier,
|
is PtIdentifier,
|
||||||
is PtMachineRegister,
|
is PtIrRegister,
|
||||||
is PtArrayIndexer,
|
is PtArrayIndexer,
|
||||||
is PtPrefix,
|
is PtPrefix,
|
||||||
is PtBinaryExpression -> { /* no cmp necessary the lda has been done just prior */ }
|
is PtBinaryExpression -> { /* no cmp necessary the lda has been done just prior */ }
|
||||||
|
|
|
@ -667,7 +667,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||||
internal fun directIntoY(expr: PtExpression): Boolean {
|
internal fun directIntoY(expr: PtExpression): Boolean {
|
||||||
return when(expr) {
|
return when(expr) {
|
||||||
is PtIdentifier -> true
|
is PtIdentifier -> true
|
||||||
is PtMachineRegister -> true
|
is PtIrRegister -> true
|
||||||
is PtNumber -> true
|
is PtNumber -> true
|
||||||
is PtBuiltinFunctionCall -> expr.name in arrayOf("lsb", "msb")
|
is PtBuiltinFunctionCall -> expr.name in arrayOf("lsb", "msb")
|
||||||
else -> false
|
else -> false
|
||||||
|
|
|
@ -8,7 +8,7 @@ import prog8.intermediate.*
|
||||||
internal class AssignmentGen(private val codeGen: IRCodeGen, private val expressionEval: ExpressionGen) {
|
internal class AssignmentGen(private val codeGen: IRCodeGen, private val expressionEval: ExpressionGen) {
|
||||||
|
|
||||||
internal fun translate(assignment: PtAssignment): IRCodeChunks {
|
internal fun translate(assignment: PtAssignment): IRCodeChunks {
|
||||||
if(assignment.target.children.single() is PtMachineRegister)
|
if(assignment.target.children.single() is PtIrRegister)
|
||||||
throw AssemblyError("assigning to a register should be done by just evaluating the expression into resultregister")
|
throw AssemblyError("assigning to a register should be done by just evaluating the expression into resultregister")
|
||||||
|
|
||||||
val chunks = translateRegularAssign(assignment)
|
val chunks = translateRegularAssign(assignment)
|
||||||
|
@ -17,7 +17,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun translate(augAssign: PtAugmentedAssign): IRCodeChunks {
|
internal fun translate(augAssign: PtAugmentedAssign): IRCodeChunks {
|
||||||
if(augAssign.target.children.single() is PtMachineRegister)
|
if(augAssign.target.children.single() is PtIrRegister)
|
||||||
throw AssemblyError("assigning to a register should be done by just evaluating the expression into resultregister")
|
throw AssemblyError("assigning to a register should be done by just evaluating the expression into resultregister")
|
||||||
|
|
||||||
val target = augAssign.target
|
val target = augAssign.target
|
||||||
|
@ -270,11 +270,11 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||||
else
|
else
|
||||||
throw AssemblyError("assignment value and target dt mismatch")
|
throw AssemblyError("assignment value and target dt mismatch")
|
||||||
} else false
|
} else false
|
||||||
if (assignment.value is PtMachineRegister) {
|
if (assignment.value is PtIrRegister) {
|
||||||
valueRegister = (assignment.value as PtMachineRegister).register
|
valueRegister = (assignment.value as PtIrRegister).register
|
||||||
if(extendByteToWord) {
|
if(extendByteToWord) {
|
||||||
valueRegister = codeGen.registers.nextFree()
|
valueRegister = codeGen.registers.nextFree()
|
||||||
addInstr(result, IRInstruction(Opcode.EXT, IRDataType.BYTE, reg1=valueRegister, reg2=(assignment.value as PtMachineRegister).register), null)
|
addInstr(result, IRInstruction(Opcode.EXT, IRDataType.BYTE, reg1=valueRegister, reg2=(assignment.value as PtIrRegister).register), null)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val tr = expressionEval.translateExpression(assignment.value)
|
val tr = expressionEval.translateExpression(assignment.value)
|
||||||
|
|
|
@ -857,7 +857,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||||
val assignTarget = PtAssignTarget(target.position)
|
val assignTarget = PtAssignTarget(target.position)
|
||||||
assignTarget.children.add(target)
|
assignTarget.children.add(target)
|
||||||
assignment.children.add(assignTarget)
|
assignment.children.add(assignTarget)
|
||||||
assignment.children.add(PtMachineRegister(register, target.type, target.position))
|
assignment.children.add(PtIrRegister(register, target.type, target.position))
|
||||||
val result = mutableListOf<IRCodeChunkBase>()
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
result += codeGen.translateNode(assignment)
|
result += codeGen.translateNode(assignment)
|
||||||
return result
|
return result
|
||||||
|
|
|
@ -24,7 +24,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||||
|
|
||||||
fun translateExpression(expr: PtExpression): ExpressionCodeResult {
|
fun translateExpression(expr: PtExpression): ExpressionCodeResult {
|
||||||
return when (expr) {
|
return when (expr) {
|
||||||
is PtMachineRegister -> {
|
is PtIrRegister -> {
|
||||||
ExpressionCodeResult(emptyList(), irType(expr.type), expr.register, -1)
|
ExpressionCodeResult(emptyList(), irType(expr.type), expr.register, -1)
|
||||||
}
|
}
|
||||||
is PtBool -> {
|
is PtBool -> {
|
||||||
|
@ -505,8 +505,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||||
if(returnIrType==IRDataType.FLOAT)
|
if(returnIrType==IRDataType.FLOAT)
|
||||||
FunctionCallArgs.RegSpec(returnIrType, codeGen.registers.nextFreeFloat(), returns.register)
|
FunctionCallArgs.RegSpec(returnIrType, codeGen.registers.nextFreeFloat(), returns.register)
|
||||||
else {
|
else {
|
||||||
statusFlagResult = returns.register.statusflag
|
val returnRegister = codeGen.registers.nextFree()
|
||||||
val returnRegister = if(statusFlagResult==null) codeGen.registers.nextFree() else -1
|
|
||||||
FunctionCallArgs.RegSpec(returnIrType, returnRegister, returns.register)
|
FunctionCallArgs.RegSpec(returnIrType, returnRegister, returns.register)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -3,16 +3,17 @@
|
||||||
%option no_sysinit
|
%option no_sysinit
|
||||||
|
|
||||||
main {
|
main {
|
||||||
str scanline_buf = "?"* 20
|
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
if diskio.f_open("test.prg") and diskio.f_read(scanline_buf, 2)==2
|
bool @shared flag
|
||||||
cx16.r0++
|
|
||||||
|
|
||||||
if diskio.f_open("test.prg") or diskio.f_read(scanline_buf, 2)==2
|
cx16.r0L = test(12345, flag, -42)
|
||||||
cx16.r0++
|
|
||||||
|
|
||||||
if diskio.f_open("test.prg") xor diskio.f_read(scanline_buf, 2)==2
|
}
|
||||||
cx16.r0++
|
|
||||||
|
asmsub test(uword arg @AY, bool flag @Pc, byte value @X) -> ubyte @A, bool @Pc {
|
||||||
|
%asm {{
|
||||||
|
txa
|
||||||
|
rts
|
||||||
|
}}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -497,7 +497,7 @@ class IRFileReader {
|
||||||
private fun parseDatatype(type: String, isArray: Boolean): DataType {
|
private fun parseDatatype(type: String, isArray: Boolean): DataType {
|
||||||
if(isArray) {
|
if(isArray) {
|
||||||
return when(type) {
|
return when(type) {
|
||||||
// note: there are no BOOLEANS anymore in the IR. Only UBYTE.
|
// note: there are no BOOLEANS arrays anymore in the IR. Only UBYTE.
|
||||||
"byte" -> DataType.ARRAY_B
|
"byte" -> DataType.ARRAY_B
|
||||||
"ubyte", "str" -> DataType.ARRAY_UB
|
"ubyte", "str" -> DataType.ARRAY_UB
|
||||||
"word" -> DataType.ARRAY_W
|
"word" -> DataType.ARRAY_W
|
||||||
|
@ -509,7 +509,7 @@ class IRFileReader {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return when(type) {
|
return when(type) {
|
||||||
// note: there are no BOOLEANS anymore in the IR. Only UBYTE.
|
"bool" -> DataType.BOOL
|
||||||
"byte" -> DataType.BYTE
|
"byte" -> DataType.BYTE
|
||||||
"ubyte" -> DataType.UBYTE
|
"ubyte" -> DataType.UBYTE
|
||||||
"word" -> DataType.WORD
|
"word" -> DataType.WORD
|
||||||
|
|
|
@ -41,6 +41,12 @@ loadi reg1, reg2 - load reg1 with value at memory indirect,
|
||||||
loadx reg1, reg2, address - load reg1 with value at memory address indexed by value in reg2 (only the lsb part used for indexing)
|
loadx reg1, reg2, address - load reg1 with value at memory address indexed by value in reg2 (only the lsb part used for indexing)
|
||||||
loadix reg1, reg2, pointeraddr - load reg1 with value at memory indirect, pointed to by pointeraddr indexed by value in reg2 (only the lsb part used for indexing)
|
loadix reg1, reg2, pointeraddr - load reg1 with value at memory indirect, pointed to by pointeraddr indexed by value in reg2 (only the lsb part used for indexing)
|
||||||
loadr reg1, reg2 - load reg1 with value in register reg2
|
loadr reg1, reg2 - load reg1 with value in register reg2
|
||||||
|
loadha reg1 - load cpu hardware register A into reg1.b
|
||||||
|
loadhx reg1 - load cpu hardware register X into reg1.b
|
||||||
|
loadhy reg1 - load cpu hardware register Y into reg1.b
|
||||||
|
loadhax reg1 - load cpu hardware register pair AX into reg1.w
|
||||||
|
loadhay reg1 - load cpu hardware register pair AY into reg1.w
|
||||||
|
loadhxy reg1 - load cpu hardware register pair XY into reg1.w
|
||||||
storem reg1, address - store reg1 at memory address
|
storem reg1, address - store reg1 at memory address
|
||||||
storei reg1, reg2 - store reg1 at memory indirect, memory pointed to by reg2
|
storei reg1, reg2 - store reg1 at memory indirect, memory pointed to by reg2
|
||||||
storex reg1, reg2, address - store reg1 at memory address, indexed by value in reg2 (only the lsb part used for indexing)
|
storex reg1, reg2, address - store reg1 at memory address, indexed by value in reg2 (only the lsb part used for indexing)
|
||||||
|
@ -48,6 +54,12 @@ storeix reg1, reg2, pointeraddr - store reg1 at memory indirect, pointed t
|
||||||
storezm address - store zero at memory address
|
storezm address - store zero at memory address
|
||||||
storezi reg1 - store zero at memory pointed to by reg1
|
storezi reg1 - store zero at memory pointed to by reg1
|
||||||
storezx reg1, address - store zero at memory address, indexed by value in reg1 (only the lsb part used for indexing)
|
storezx reg1, address - store zero at memory address, indexed by value in reg1 (only the lsb part used for indexing)
|
||||||
|
storeha reg1 - store reg1.b into cpu hardware register A
|
||||||
|
storehx reg1 - store reg1.b into cpu hardware register X
|
||||||
|
storehy reg1 - store reg1.b into cpu hardware register Y
|
||||||
|
storehax reg1 - store reg1.w into cpu hardware register pair AX
|
||||||
|
storehay reg1 - store reg1.w into cpu hardware register pair AY
|
||||||
|
storehxy reg1 - store reg1.w into cpu hardware register pair XY
|
||||||
|
|
||||||
|
|
||||||
CONTROL FLOW
|
CONTROL FLOW
|
||||||
|
@ -247,6 +259,12 @@ enum class Opcode {
|
||||||
LOADX,
|
LOADX,
|
||||||
LOADIX,
|
LOADIX,
|
||||||
LOADR,
|
LOADR,
|
||||||
|
LOADHA,
|
||||||
|
LOADHX,
|
||||||
|
LOADHY,
|
||||||
|
LOADHAX,
|
||||||
|
LOADHAY,
|
||||||
|
LOADHXY,
|
||||||
STOREM,
|
STOREM,
|
||||||
STOREI,
|
STOREI,
|
||||||
STOREX,
|
STOREX,
|
||||||
|
@ -254,6 +272,12 @@ enum class Opcode {
|
||||||
STOREZM,
|
STOREZM,
|
||||||
STOREZI,
|
STOREZI,
|
||||||
STOREZX,
|
STOREZX,
|
||||||
|
STOREHA,
|
||||||
|
STOREHX,
|
||||||
|
STOREHY,
|
||||||
|
STOREHAX,
|
||||||
|
STOREHAY,
|
||||||
|
STOREHXY,
|
||||||
|
|
||||||
JUMP,
|
JUMP,
|
||||||
JUMPI,
|
JUMPI,
|
||||||
|
@ -444,6 +468,12 @@ val OpcodesThatSetStatusbitsButNotCarry = arrayOf(
|
||||||
Opcode.LOADX,
|
Opcode.LOADX,
|
||||||
Opcode.LOADIX,
|
Opcode.LOADIX,
|
||||||
Opcode.LOADR,
|
Opcode.LOADR,
|
||||||
|
Opcode.LOADHA,
|
||||||
|
Opcode.LOADHX,
|
||||||
|
Opcode.LOADHY,
|
||||||
|
Opcode.LOADHAX,
|
||||||
|
Opcode.LOADHAY,
|
||||||
|
Opcode.LOADHXY,
|
||||||
Opcode.NEG,
|
Opcode.NEG,
|
||||||
Opcode.NEGM,
|
Opcode.NEGM,
|
||||||
Opcode.INC,
|
Opcode.INC,
|
||||||
|
@ -585,6 +615,13 @@ val instructionFormats = mutableMapOf(
|
||||||
Opcode.LOADX to InstructionFormat.from("BW,>r1,<r2,<a | F,>fr1,<r1,<a"),
|
Opcode.LOADX to InstructionFormat.from("BW,>r1,<r2,<a | F,>fr1,<r1,<a"),
|
||||||
Opcode.LOADIX to InstructionFormat.from("BW,>r1,<r2,<a | F,>fr1,<r1,<a"),
|
Opcode.LOADIX to InstructionFormat.from("BW,>r1,<r2,<a | F,>fr1,<r1,<a"),
|
||||||
Opcode.LOADR to InstructionFormat.from("BW,>r1,<r2 | F,>fr1,<fr2"),
|
Opcode.LOADR to InstructionFormat.from("BW,>r1,<r2 | F,>fr1,<fr2"),
|
||||||
|
Opcode.LOADHA to InstructionFormat.from("B,>r1"),
|
||||||
|
Opcode.LOADHA to InstructionFormat.from("B,>r1"),
|
||||||
|
Opcode.LOADHX to InstructionFormat.from("B,>r1"),
|
||||||
|
Opcode.LOADHY to InstructionFormat.from("B,>r1"),
|
||||||
|
Opcode.LOADHAX to InstructionFormat.from("W,>r1"),
|
||||||
|
Opcode.LOADHAY to InstructionFormat.from("W,>r1"),
|
||||||
|
Opcode.LOADHXY to InstructionFormat.from("W,>r1"),
|
||||||
Opcode.STOREM to InstructionFormat.from("BW,<r1,>a | F,<fr1,>a"),
|
Opcode.STOREM to InstructionFormat.from("BW,<r1,>a | F,<fr1,>a"),
|
||||||
Opcode.STOREI to InstructionFormat.from("BW,<r1,<r2 | F,<fr1,<r1"),
|
Opcode.STOREI to InstructionFormat.from("BW,<r1,<r2 | F,<fr1,<r1"),
|
||||||
Opcode.STOREX to InstructionFormat.from("BW,<r1,<r2,>a | F,<fr1,<r1,>a"),
|
Opcode.STOREX to InstructionFormat.from("BW,<r1,<r2,>a | F,<fr1,<r1,>a"),
|
||||||
|
@ -592,6 +629,13 @@ val instructionFormats = mutableMapOf(
|
||||||
Opcode.STOREZM to InstructionFormat.from("BW,>a | F,>a"),
|
Opcode.STOREZM to InstructionFormat.from("BW,>a | F,>a"),
|
||||||
Opcode.STOREZI to InstructionFormat.from("BW,<r1 | F,<r1"),
|
Opcode.STOREZI to InstructionFormat.from("BW,<r1 | F,<r1"),
|
||||||
Opcode.STOREZX to InstructionFormat.from("BW,<r1,>a | F,<r1,>a"),
|
Opcode.STOREZX to InstructionFormat.from("BW,<r1,>a | F,<r1,>a"),
|
||||||
|
Opcode.STOREHA to InstructionFormat.from("B,<r1"),
|
||||||
|
Opcode.STOREHA to InstructionFormat.from("B,<r1"),
|
||||||
|
Opcode.STOREHX to InstructionFormat.from("B,<r1"),
|
||||||
|
Opcode.STOREHY to InstructionFormat.from("B,<r1"),
|
||||||
|
Opcode.STOREHAX to InstructionFormat.from("W,<r1"),
|
||||||
|
Opcode.STOREHAY to InstructionFormat.from("W,<r1"),
|
||||||
|
Opcode.STOREHXY to InstructionFormat.from("W,<r1"),
|
||||||
Opcode.JUMP to InstructionFormat.from("N,<a"),
|
Opcode.JUMP to InstructionFormat.from("N,<a"),
|
||||||
Opcode.JUMPI to InstructionFormat.from("N,<a"),
|
Opcode.JUMPI to InstructionFormat.from("N,<a"),
|
||||||
Opcode.PREPARECALL to InstructionFormat.from("N,<i"),
|
Opcode.PREPARECALL to InstructionFormat.from("N,<i"),
|
||||||
|
@ -1020,13 +1064,10 @@ data class IRInstruction(
|
||||||
IRDataType.FLOAT -> result.add("fr${returns.registerNum}.f")
|
IRDataType.FLOAT -> result.add("fr${returns.registerNum}.f")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
result.add("@" + cpuReg)
|
when(returns.dt) {
|
||||||
if(returns.cpuRegister?.statusflag==null) {
|
IRDataType.BYTE -> result.add("r${returns.registerNum}.b@" + cpuReg)
|
||||||
when (returns.dt) {
|
IRDataType.WORD -> result.add("r${returns.registerNum}.w@" + cpuReg)
|
||||||
IRDataType.BYTE -> result.add(".b")
|
IRDataType.FLOAT -> result.add("r${returns.registerNum}.f@" + cpuReg)
|
||||||
IRDataType.WORD -> result.add(".w")
|
|
||||||
IRDataType.FLOAT -> result.add(".f")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -178,6 +178,12 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||||
Opcode.LOADI -> InsLOADI(ins)
|
Opcode.LOADI -> InsLOADI(ins)
|
||||||
Opcode.LOADIX -> InsLOADIX(ins)
|
Opcode.LOADIX -> InsLOADIX(ins)
|
||||||
Opcode.LOADR -> InsLOADR(ins)
|
Opcode.LOADR -> InsLOADR(ins)
|
||||||
|
Opcode.LOADHA,
|
||||||
|
Opcode.LOADHX,
|
||||||
|
Opcode.LOADHY,
|
||||||
|
Opcode.LOADHAX,
|
||||||
|
Opcode.LOADHAY,
|
||||||
|
Opcode.LOADHXY -> throw IllegalArgumentException("VM cannot access actual CPU hardware register")
|
||||||
Opcode.STOREM -> InsSTOREM(ins)
|
Opcode.STOREM -> InsSTOREM(ins)
|
||||||
Opcode.STOREX -> InsSTOREX(ins)
|
Opcode.STOREX -> InsSTOREX(ins)
|
||||||
Opcode.STOREIX -> InsSTOREIX(ins)
|
Opcode.STOREIX -> InsSTOREIX(ins)
|
||||||
|
@ -185,10 +191,16 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||||
Opcode.STOREZM -> InsSTOREZM(ins)
|
Opcode.STOREZM -> InsSTOREZM(ins)
|
||||||
Opcode.STOREZX -> InsSTOREZX(ins)
|
Opcode.STOREZX -> InsSTOREZX(ins)
|
||||||
Opcode.STOREZI -> InsSTOREZI(ins)
|
Opcode.STOREZI -> InsSTOREZI(ins)
|
||||||
|
Opcode.STOREHA,
|
||||||
|
Opcode.STOREHX,
|
||||||
|
Opcode.STOREHY,
|
||||||
|
Opcode.STOREHAX,
|
||||||
|
Opcode.STOREHAY,
|
||||||
|
Opcode.STOREHXY -> throw IllegalArgumentException("VM cannot access actual CPU hardware register")
|
||||||
Opcode.JUMP -> InsJUMP(ins)
|
Opcode.JUMP -> InsJUMP(ins)
|
||||||
Opcode.JUMPI -> InsJUMPI(ins)
|
Opcode.JUMPI -> InsJUMPI(ins)
|
||||||
Opcode.PREPARECALL -> nextPc()
|
Opcode.PREPARECALL -> nextPc()
|
||||||
Opcode.CALLI -> throw IllegalArgumentException("VM cannot run code from memory")
|
Opcode.CALLI -> throw IllegalArgumentException("VM cannot run code from memory bytes")
|
||||||
Opcode.CALL -> InsCALL(ins)
|
Opcode.CALL -> InsCALL(ins)
|
||||||
Opcode.SYSCALL -> InsSYSCALL(ins)
|
Opcode.SYSCALL -> InsSYSCALL(ins)
|
||||||
Opcode.RETURN -> InsRETURN()
|
Opcode.RETURN -> InsRETURN()
|
||||||
|
@ -319,6 +331,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||||
Opcode.FFLOOR -> InsFFLOOR(ins)
|
Opcode.FFLOOR -> InsFFLOOR(ins)
|
||||||
Opcode.FCEIL -> InsFCEIL(ins)
|
Opcode.FCEIL -> InsFCEIL(ins)
|
||||||
Opcode.FCOMP -> InsFCOMP(ins)
|
Opcode.FCOMP -> InsFCOMP(ins)
|
||||||
|
|
||||||
else -> throw IllegalArgumentException("invalid opcode ${ins.opcode}")
|
else -> throw IllegalArgumentException("invalid opcode ${ins.opcode}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ class VmProgramLoader {
|
||||||
|
|
||||||
block.children.forEach { child ->
|
block.children.forEach { child ->
|
||||||
when(child) {
|
when(child) {
|
||||||
is IRAsmSubroutine -> throw IRParseException("vm does not support non-inlined asmsubs (use normal sub): ${child.label}")
|
is IRAsmSubroutine -> throw IRParseException("vm does not support asmsubs (use normal sub): ${child.label}")
|
||||||
is IRCodeChunk -> programChunks += child
|
is IRCodeChunk -> programChunks += child
|
||||||
is IRInlineAsmChunk -> throw IRParseException("encountered unconverted inline assembly chunk")
|
is IRInlineAsmChunk -> throw IRParseException("encountered unconverted inline assembly chunk")
|
||||||
is IRInlineBinaryChunk -> throw IRParseException("inline binary data not yet supported in the VM")
|
is IRInlineBinaryChunk -> throw IRParseException("inline binary data not yet supported in the VM")
|
||||||
|
|
|
@ -85,7 +85,7 @@ class TestVm: FunSpec( {
|
||||||
)
|
)
|
||||||
block += startSub
|
block += startSub
|
||||||
program.addBlock(block)
|
program.addBlock(block)
|
||||||
shouldThrowWithMessage<IRParseException>("vm does not support non-inlined asmsubs (use normal sub): main.asmstart") {
|
shouldThrowWithMessage<IRParseException>("vm does not support asmsubs (use normal sub): main.asmstart") {
|
||||||
VirtualMachine(program)
|
VirtualMachine(program)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user