mirror of
https://github.com/irmen/prog8.git
synced 2026-04-19 20:16:51 +00:00
vm: loadix instruction added for indirect addressing via pointer
This commit is contained in:
@@ -82,34 +82,34 @@ internal class VmCodeInstruction(
|
||||
value: Int?=null, // 0-$ffff
|
||||
fpValue: Float?=null,
|
||||
labelSymbol: List<String>?=null // alternative to value for branch/call/jump labels
|
||||
): VmCodeLine() {
|
||||
val ins = Instruction(opcode, type, reg1, reg2, fpReg1, fpReg2, value, fpValue, labelSymbol)
|
||||
): VmCodeLine() {
|
||||
val ins = Instruction(opcode, type, reg1, reg2, fpReg1, fpReg2, value, fpValue, labelSymbol)
|
||||
|
||||
init {
|
||||
if(reg1!=null && (reg1<0 || reg1>65536))
|
||||
throw IllegalArgumentException("reg1 out of bounds")
|
||||
if(reg2!=null && (reg2<0 || reg2>65536))
|
||||
throw IllegalArgumentException("reg2 out of bounds")
|
||||
if(fpReg1!=null && (fpReg1<0 || fpReg1>65536))
|
||||
throw IllegalArgumentException("fpReg1 out of bounds")
|
||||
if(fpReg2!=null && (fpReg2<0 || fpReg2>65536))
|
||||
throw IllegalArgumentException("fpReg2 out of bounds")
|
||||
init {
|
||||
if(reg1!=null && (reg1<0 || reg1>65536))
|
||||
throw IllegalArgumentException("reg1 out of bounds")
|
||||
if(reg2!=null && (reg2<0 || reg2>65536))
|
||||
throw IllegalArgumentException("reg2 out of bounds")
|
||||
if(fpReg1!=null && (fpReg1<0 || fpReg1>65536))
|
||||
throw IllegalArgumentException("fpReg1 out of bounds")
|
||||
if(fpReg2!=null && (fpReg2<0 || fpReg2>65536))
|
||||
throw IllegalArgumentException("fpReg2 out of bounds")
|
||||
|
||||
if(value!=null && opcode !in OpcodesWithAddress) {
|
||||
when (type) {
|
||||
VmDataType.BYTE -> {
|
||||
if (value < -128 || value > 255)
|
||||
throw IllegalArgumentException("value out of range for byte: $value")
|
||||
}
|
||||
VmDataType.WORD -> {
|
||||
if (value < -32768 || value > 65535)
|
||||
throw IllegalArgumentException("value out of range for word: $value")
|
||||
}
|
||||
VmDataType.FLOAT, null -> {}
|
||||
if(value!=null && opcode !in OpcodesWithAddress) {
|
||||
when (type) {
|
||||
VmDataType.BYTE -> {
|
||||
if (value < -128 || value > 255)
|
||||
throw IllegalArgumentException("value out of range for byte: $value")
|
||||
}
|
||||
VmDataType.WORD -> {
|
||||
if (value < -32768 || value > 65535)
|
||||
throw IllegalArgumentException("value out of range for word: $value")
|
||||
}
|
||||
VmDataType.FLOAT, null -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class VmCodeLabel(val name: List<String>): VmCodeLine()
|
||||
internal class VmCodeComment(val comment: String): VmCodeLine()
|
||||
|
||||
@@ -154,12 +154,8 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
|
||||
// indexing a pointer var instead of a real array or string
|
||||
if(eltSize!=1)
|
||||
throw AssemblyError("non-array var indexing requires bytes dt")
|
||||
val pointerReg = codeGen.vmRegisters.nextFree()
|
||||
code += translateExpression(arrayIx.index, idxReg, -1)
|
||||
// TODO introduce LOADIX instruction to skip the ADD (requires 3 registers)
|
||||
code += VmCodeInstruction(Opcode.LOADM, VmDataType.WORD, reg1=pointerReg, value=arrayLocation)
|
||||
code += VmCodeInstruction(Opcode.ADD, VmDataType.WORD, reg1=pointerReg, reg2=idxReg)
|
||||
code += VmCodeInstruction(Opcode.LOADI, vmDt, reg1=resultRegister, reg2=pointerReg)
|
||||
code += VmCodeInstruction(Opcode.LOADIX, vmDt, reg1=resultRegister, reg2=idxReg, value = arrayLocation)
|
||||
return code
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user