mirror of
https://github.com/irmen/prog8.git
synced 2025-11-03 04:17:16 +00:00
changed (and fixed) msb(long) and lsb(long)
This commit is contained in:
@@ -117,8 +117,10 @@ val BuiltinFunctions: Map<String, FSignature> = mapOf(
|
|||||||
"divmod__ubyte" to FSignature(false, null, FParam("dividend", BaseDataType.UBYTE), FParam("divisor", BaseDataType.UBYTE), FParam("quotient", BaseDataType.UBYTE), FParam("remainder", BaseDataType.UBYTE)),
|
"divmod__ubyte" to FSignature(false, null, FParam("dividend", BaseDataType.UBYTE), FParam("divisor", BaseDataType.UBYTE), FParam("quotient", BaseDataType.UBYTE), FParam("remainder", BaseDataType.UBYTE)),
|
||||||
"divmod__uword" to FSignature(false, null, FParam("dividend", BaseDataType.UWORD), FParam("divisor", BaseDataType.UWORD), FParam("quotient", BaseDataType.UWORD), FParam("remainder", BaseDataType.UWORD)),
|
"divmod__uword" to FSignature(false, null, FParam("dividend", BaseDataType.UWORD), FParam("divisor", BaseDataType.UWORD), FParam("quotient", BaseDataType.UWORD), FParam("remainder", BaseDataType.UWORD)),
|
||||||
"lsb" to FSignature(true, BaseDataType.UBYTE, FParam("value", BaseDataType.UWORD, BaseDataType.WORD, BaseDataType.LONG)),
|
"lsb" to FSignature(true, BaseDataType.UBYTE, FParam("value", BaseDataType.UWORD, BaseDataType.WORD, BaseDataType.LONG)),
|
||||||
"lsw" to FSignature(true, BaseDataType.UWORD, FParam("value", BaseDataType.UWORD, BaseDataType.WORD, BaseDataType.LONG)),
|
"lsb__long" to FSignature(true, BaseDataType.UBYTE, FParam("value", BaseDataType.LONG)),
|
||||||
"msb" to FSignature(true, BaseDataType.UBYTE, FParam("value", BaseDataType.UWORD, BaseDataType.WORD, BaseDataType.LONG)),
|
"msb" to FSignature(true, BaseDataType.UBYTE, FParam("value", BaseDataType.UWORD, BaseDataType.WORD, BaseDataType.LONG)),
|
||||||
|
"msb__long" to FSignature(true, BaseDataType.UBYTE, FParam("value", BaseDataType.LONG)),
|
||||||
|
"lsw" to FSignature(true, BaseDataType.UWORD, FParam("value", BaseDataType.UWORD, BaseDataType.WORD, BaseDataType.LONG)),
|
||||||
"msw" to FSignature(true, BaseDataType.UWORD, FParam("value", BaseDataType.UWORD, BaseDataType.WORD, BaseDataType.LONG)),
|
"msw" to FSignature(true, BaseDataType.UWORD, FParam("value", BaseDataType.UWORD, BaseDataType.WORD, BaseDataType.LONG)),
|
||||||
"mkword" to FSignature(true, BaseDataType.UWORD, FParam("msb", BaseDataType.UBYTE), FParam("lsb", BaseDataType.UBYTE)),
|
"mkword" to FSignature(true, BaseDataType.UWORD, FParam("msb", BaseDataType.UBYTE), FParam("lsb", BaseDataType.UBYTE)),
|
||||||
"mklong" to FSignature(true, BaseDataType.LONG, FParam("msb", BaseDataType.UBYTE), FParam("b2", BaseDataType.UBYTE), FParam("b1", BaseDataType.UBYTE), FParam("lsb", BaseDataType.UBYTE)),
|
"mklong" to FSignature(true, BaseDataType.LONG, FParam("msb", BaseDataType.UBYTE), FParam("b2", BaseDataType.UBYTE), FParam("b1", BaseDataType.UBYTE), FParam("lsb", BaseDataType.UBYTE)),
|
||||||
|
|||||||
@@ -30,9 +30,11 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
|||||||
"msw" -> funcMsw(fcall, resultRegister)
|
"msw" -> funcMsw(fcall, resultRegister)
|
||||||
"lsw" -> funcLsw(fcall, resultRegister)
|
"lsw" -> funcLsw(fcall, resultRegister)
|
||||||
"msb" -> funcMsb(fcall, resultRegister)
|
"msb" -> funcMsb(fcall, resultRegister)
|
||||||
"lsb" -> funcLsb(fcall, resultRegister)
|
"msb__long" -> funcMsbLong(fcall, resultRegister)
|
||||||
|
"lsb" -> funcLsb(fcall, resultRegister, false)
|
||||||
|
"lsb__long" -> funcLsb(fcall, resultRegister, true)
|
||||||
"mkword" -> funcMkword(fcall, resultRegister)
|
"mkword" -> funcMkword(fcall, resultRegister)
|
||||||
"mklong", "mklong2" -> funcMklong(fcall) // result is in R0:R1
|
"mklong", "mklong2" -> funcMklong(fcall) // result is in R14:R15
|
||||||
"clamp__byte", "clamp__ubyte", "clamp__word", "clamp__uword", "clamp__long" -> funcClamp(fcall, resultRegister)
|
"clamp__byte", "clamp__ubyte", "clamp__word", "clamp__uword", "clamp__long" -> funcClamp(fcall, resultRegister)
|
||||||
"min__byte", "min__ubyte", "min__word", "min__uword", "min__long" -> funcMin(fcall, resultRegister)
|
"min__byte", "min__ubyte", "min__word", "min__uword", "min__long" -> funcMin(fcall, resultRegister)
|
||||||
"max__byte", "max__ubyte", "max__word", "max__uword", "max__long" -> funcMax(fcall, resultRegister)
|
"max__byte", "max__ubyte", "max__word", "max__uword", "max__long" -> funcMax(fcall, resultRegister)
|
||||||
@@ -1458,6 +1460,39 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun funcMsbLong(fcall: PtBuiltinFunctionCall, resultRegister: RegisterOrPair?) {
|
||||||
|
val arg = fcall.args.single()
|
||||||
|
if (!arg.type.isLong)
|
||||||
|
throw AssemblyError("msb__long requires long argument")
|
||||||
|
if (arg is PtNumber)
|
||||||
|
throw AssemblyError("msb(const) should have been const-folded away")
|
||||||
|
|
||||||
|
if (arg is PtIdentifier) {
|
||||||
|
val sourceName = asmgen.asmVariableName(arg)
|
||||||
|
when(resultRegister) {
|
||||||
|
null, RegisterOrPair.A -> asmgen.out(" lda $sourceName+3")
|
||||||
|
RegisterOrPair.X -> asmgen.out(" ldx $sourceName+3")
|
||||||
|
RegisterOrPair.Y -> asmgen.out(" ldy $sourceName+3")
|
||||||
|
RegisterOrPair.AX -> asmgen.out(" lda $sourceName+3 | ldx #0")
|
||||||
|
RegisterOrPair.AY -> asmgen.out(" lda $sourceName+3 | ldy #0")
|
||||||
|
RegisterOrPair.XY -> asmgen.out(" ldx $sourceName+3 | ldy #0")
|
||||||
|
in Cx16VirtualRegisters -> {
|
||||||
|
val regname = resultRegister.name.lowercase()
|
||||||
|
if(asmgen.isTargetCpu(CpuType.CPU65C02))
|
||||||
|
asmgen.out(" lda $sourceName+3 | sta cx16.$regname | stz cx16.$regname+1")
|
||||||
|
else
|
||||||
|
asmgen.out(" lda $sourceName+3 | sta cx16.$regname | lda #0 | sta cx16.$regname+1")
|
||||||
|
}
|
||||||
|
in combinedLongRegisters -> {
|
||||||
|
TODO("msb__long into long register ${fcall.position}")
|
||||||
|
}
|
||||||
|
else -> throw AssemblyError("invalid reg")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
TODO("msb__long from $arg ${fcall.position}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun funcMsb(fcall: PtBuiltinFunctionCall, resultRegister: RegisterOrPair?) {
|
private fun funcMsb(fcall: PtBuiltinFunctionCall, resultRegister: RegisterOrPair?) {
|
||||||
val arg = fcall.args.single()
|
val arg = fcall.args.single()
|
||||||
if (!arg.type.isWord)
|
if (!arg.type.isWord)
|
||||||
@@ -1567,10 +1602,13 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun funcLsb(fcall: PtBuiltinFunctionCall, resultRegister: RegisterOrPair?) {
|
private fun funcLsb(fcall: PtBuiltinFunctionCall, resultRegister: RegisterOrPair?, fromLong: Boolean) {
|
||||||
val arg = fcall.args.single()
|
val arg = fcall.args.single()
|
||||||
if (!arg.type.isWord)
|
if(fromLong) {
|
||||||
throw AssemblyError("lsb required word argument")
|
if (!arg.type.isLong) throw AssemblyError("lsb__long requires long")
|
||||||
|
} else {
|
||||||
|
if (!arg.type.isWord) throw AssemblyError("lsb requires word")
|
||||||
|
}
|
||||||
if (arg is PtNumber)
|
if (arg is PtNumber)
|
||||||
throw AssemblyError("lsb(const) should have been const-folded away")
|
throw AssemblyError("lsb(const) should have been const-folded away")
|
||||||
|
|
||||||
|
|||||||
@@ -702,9 +702,9 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
|||||||
val chunk = IRCodeChunk(null, null).also {
|
val chunk = IRCodeChunk(null, null).also {
|
||||||
if(targetArray.splitWords) {
|
if(targetArray.splitWords) {
|
||||||
val lsbmsbReg = codeGen.registers.next(IRDataType.BYTE)
|
val lsbmsbReg = codeGen.registers.next(IRDataType.BYTE)
|
||||||
it += IRInstruction(Opcode.LSIG, IRDataType.BYTE, reg1 = lsbmsbReg, reg2 = valueRegister)
|
it += IRInstruction(Opcode.LSIGB, IRDataType.WORD, reg1 = lsbmsbReg, reg2 = valueRegister)
|
||||||
it += IRInstruction(Opcode.STOREM, IRDataType.BYTE, reg1 = lsbmsbReg, immediate = arrayLength, labelSymbol = "${variable}_lsb", symbolOffset = fixedIndex)
|
it += IRInstruction(Opcode.STOREM, IRDataType.BYTE, reg1 = lsbmsbReg, immediate = arrayLength, labelSymbol = "${variable}_lsb", symbolOffset = fixedIndex)
|
||||||
it += IRInstruction(Opcode.MSIG, IRDataType.BYTE, reg1 = lsbmsbReg, reg2 = valueRegister)
|
it += IRInstruction(Opcode.MSIGB, IRDataType.WORD, reg1 = lsbmsbReg, reg2 = valueRegister)
|
||||||
it += IRInstruction(Opcode.STOREM, IRDataType.BYTE, reg1 = lsbmsbReg, immediate = arrayLength, labelSymbol = "${variable}_msb", symbolOffset = fixedIndex)
|
it += IRInstruction(Opcode.STOREM, IRDataType.BYTE, reg1 = lsbmsbReg, immediate = arrayLength, labelSymbol = "${variable}_msb", symbolOffset = fixedIndex)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -717,9 +717,9 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
|||||||
result += IRCodeChunk(null, null).also {
|
result += IRCodeChunk(null, null).also {
|
||||||
if(targetArray.splitWords) {
|
if(targetArray.splitWords) {
|
||||||
val lsbmsbReg = codeGen.registers.next(IRDataType.BYTE)
|
val lsbmsbReg = codeGen.registers.next(IRDataType.BYTE)
|
||||||
it += IRInstruction(Opcode.LSIG, IRDataType.BYTE, reg1 = lsbmsbReg, reg2 = valueRegister)
|
it += IRInstruction(Opcode.LSIGB, IRDataType.WORD, reg1 = lsbmsbReg, reg2 = valueRegister)
|
||||||
it += IRInstruction(Opcode.STOREX, IRDataType.BYTE, reg1 = lsbmsbReg, reg2=indexReg, immediate = arrayLength, labelSymbol = "${variable}_lsb")
|
it += IRInstruction(Opcode.STOREX, IRDataType.BYTE, reg1 = lsbmsbReg, reg2=indexReg, immediate = arrayLength, labelSymbol = "${variable}_lsb")
|
||||||
it += IRInstruction(Opcode.MSIG, IRDataType.BYTE, reg1 = lsbmsbReg, reg2 = valueRegister)
|
it += IRInstruction(Opcode.MSIGB, IRDataType.WORD, reg1 = lsbmsbReg, reg2 = valueRegister)
|
||||||
it += IRInstruction(Opcode.STOREX, IRDataType.BYTE, reg1 = lsbmsbReg, reg2=indexReg, immediate = arrayLength, labelSymbol = "${variable}_msb")
|
it += IRInstruction(Opcode.STOREX, IRDataType.BYTE, reg1 = lsbmsbReg, reg2=indexReg, immediate = arrayLength, labelSymbol = "${variable}_msb")
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -26,8 +26,10 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
|||||||
"call" -> funcCall(call)
|
"call" -> funcCall(call)
|
||||||
"msw" -> funcMsw(call)
|
"msw" -> funcMsw(call)
|
||||||
"lsw" -> funcLsw(call)
|
"lsw" -> funcLsw(call)
|
||||||
"msb" -> funcMsb(call)
|
"msb" -> funcMsb(call, false)
|
||||||
"lsb" -> funcLsb(call)
|
"msb__long" -> funcMsb(call, true)
|
||||||
|
"lsb" -> funcLsb(call, false)
|
||||||
|
"lsb__long" -> funcLsb(call, true)
|
||||||
"memory" -> funcMemory(call)
|
"memory" -> funcMemory(call)
|
||||||
"peek" -> funcPeek(call, IRDataType.BYTE)
|
"peek" -> funcPeek(call, IRDataType.BYTE)
|
||||||
"peekbool" -> funcPeek(call, IRDataType.BYTE)
|
"peekbool" -> funcPeek(call, IRDataType.BYTE)
|
||||||
@@ -584,12 +586,15 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
|||||||
return ExpressionCodeResult(code, IRDataType.WORD, resultReg, -1)
|
return ExpressionCodeResult(code, IRDataType.WORD, resultReg, -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun funcLsb(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
private fun funcLsb(call: PtBuiltinFunctionCall, fromLong: Boolean): ExpressionCodeResult {
|
||||||
val result = mutableListOf<IRCodeChunkBase>()
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
val tr = exprGen.translateExpression(call.args.single())
|
val tr = exprGen.translateExpression(call.args.single())
|
||||||
addToResult(result, tr, tr.resultReg, -1)
|
addToResult(result, tr, tr.resultReg, -1)
|
||||||
val resultReg = codeGen.registers.next(IRDataType.BYTE)
|
val resultReg = codeGen.registers.next(IRDataType.BYTE)
|
||||||
addInstr(result, IRInstruction(Opcode.LSIG, IRDataType.BYTE, reg1 = resultReg, reg2 = tr.resultReg), null)
|
if(fromLong)
|
||||||
|
addInstr(result, IRInstruction(Opcode.LSIGB, IRDataType.LONG, reg1 = resultReg, reg2 = tr.resultReg), null)
|
||||||
|
else
|
||||||
|
addInstr(result, IRInstruction(Opcode.LSIGB, IRDataType.WORD, reg1 = resultReg, reg2 = tr.resultReg), null)
|
||||||
// note: if a word result is needed, the upper byte is cleared by the typecast that follows. No need to do it here.
|
// 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, resultReg, -1)
|
return ExpressionCodeResult(result, IRDataType.BYTE, resultReg, -1)
|
||||||
}
|
}
|
||||||
@@ -599,16 +604,19 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
|||||||
val tr = exprGen.translateExpression(call.args.single())
|
val tr = exprGen.translateExpression(call.args.single())
|
||||||
addToResult(result, tr, tr.resultReg, -1)
|
addToResult(result, tr, tr.resultReg, -1)
|
||||||
val resultReg = codeGen.registers.next(IRDataType.WORD)
|
val resultReg = codeGen.registers.next(IRDataType.WORD)
|
||||||
addInstr(result, IRInstruction(Opcode.LSIG, IRDataType.WORD, reg1 = resultReg, reg2 = tr.resultReg), null)
|
addInstr(result, IRInstruction(Opcode.LSIGW, IRDataType.LONG, reg1 = resultReg, reg2 = tr.resultReg), null)
|
||||||
return ExpressionCodeResult(result, IRDataType.WORD, resultReg, -1)
|
return ExpressionCodeResult(result, IRDataType.WORD, resultReg, -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun funcMsb(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
private fun funcMsb(call: PtBuiltinFunctionCall, fromLong: Boolean): ExpressionCodeResult {
|
||||||
val result = mutableListOf<IRCodeChunkBase>()
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
val tr = exprGen.translateExpression(call.args.single())
|
val tr = exprGen.translateExpression(call.args.single())
|
||||||
addToResult(result, tr, tr.resultReg, -1)
|
addToResult(result, tr, tr.resultReg, -1)
|
||||||
val resultReg = codeGen.registers.next(IRDataType.BYTE)
|
val resultReg = codeGen.registers.next(IRDataType.BYTE)
|
||||||
addInstr(result, IRInstruction(Opcode.MSIG, IRDataType.BYTE, reg1 = resultReg, reg2 = tr.resultReg), null)
|
if(fromLong)
|
||||||
|
addInstr(result, IRInstruction(Opcode.MSIGB, IRDataType.LONG, reg1 = resultReg, reg2 = tr.resultReg), null)
|
||||||
|
else
|
||||||
|
addInstr(result, IRInstruction(Opcode.MSIGB, IRDataType.WORD, reg1 = resultReg, reg2 = tr.resultReg), null)
|
||||||
// note: if a word result is needed, the upper byte is cleared by the typecast that follows. No need to do it here.
|
// 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, resultReg, -1)
|
return ExpressionCodeResult(result, IRDataType.BYTE, resultReg, -1)
|
||||||
}
|
}
|
||||||
@@ -618,7 +626,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
|||||||
val tr = exprGen.translateExpression(call.args.single())
|
val tr = exprGen.translateExpression(call.args.single())
|
||||||
addToResult(result, tr, tr.resultReg, -1)
|
addToResult(result, tr, tr.resultReg, -1)
|
||||||
val resultReg = codeGen.registers.next(IRDataType.WORD)
|
val resultReg = codeGen.registers.next(IRDataType.WORD)
|
||||||
addInstr(result, IRInstruction(Opcode.MSIG, IRDataType.WORD, reg1 = resultReg, reg2 = tr.resultReg), null)
|
addInstr(result, IRInstruction(Opcode.MSIGW, IRDataType.LONG, reg1 = resultReg, reg2 = tr.resultReg), null)
|
||||||
return ExpressionCodeResult(result, IRDataType.WORD, resultReg, -1)
|
return ExpressionCodeResult(result, IRDataType.WORD, resultReg, -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -707,13 +707,11 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
}
|
}
|
||||||
BaseDataType.UWORD, BaseDataType.WORD -> {
|
BaseDataType.UWORD, BaseDataType.WORD -> {
|
||||||
actualResultReg2 = codeGen.registers.next(IRDataType.BYTE)
|
actualResultReg2 = codeGen.registers.next(IRDataType.BYTE)
|
||||||
addInstr(result, IRInstruction(Opcode.LSIG, IRDataType.BYTE, reg1=actualResultReg2, reg2=tr.resultReg, immediate = 0), null)
|
addInstr(result, IRInstruction(Opcode.LSIGB, IRDataType.WORD, reg1=actualResultReg2, reg2=tr.resultReg, immediate = 0), null)
|
||||||
}
|
}
|
||||||
BaseDataType.LONG -> {
|
BaseDataType.LONG -> {
|
||||||
actualResultReg2 = codeGen.registers.next(IRDataType.BYTE)
|
actualResultReg2 = codeGen.registers.next(IRDataType.BYTE)
|
||||||
val wordReg = codeGen.registers.next(IRDataType.WORD)
|
addInstr(result, IRInstruction(Opcode.LSIGB, IRDataType.LONG, reg1=actualResultReg2, reg2=tr.resultReg, immediate = 0), null)
|
||||||
addInstr(result, IRInstruction(Opcode.LSIG, IRDataType.WORD, reg1=wordReg, reg2=tr.resultReg, immediate = 0), null)
|
|
||||||
addInstr(result, IRInstruction(Opcode.LSIG, IRDataType.BYTE, reg1=actualResultReg2, reg2=wordReg, immediate = 0), null)
|
|
||||||
}
|
}
|
||||||
BaseDataType.FLOAT -> {
|
BaseDataType.FLOAT -> {
|
||||||
actualResultReg2 = codeGen.registers.next(IRDataType.BYTE)
|
actualResultReg2 = codeGen.registers.next(IRDataType.BYTE)
|
||||||
@@ -729,13 +727,11 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
}
|
}
|
||||||
BaseDataType.UWORD, BaseDataType.WORD -> {
|
BaseDataType.UWORD, BaseDataType.WORD -> {
|
||||||
actualResultReg2 = codeGen.registers.next(IRDataType.BYTE)
|
actualResultReg2 = codeGen.registers.next(IRDataType.BYTE)
|
||||||
addInstr(result, IRInstruction(Opcode.LSIG, IRDataType.BYTE, reg1=actualResultReg2, reg2=tr.resultReg, immediate = 0), null)
|
addInstr(result, IRInstruction(Opcode.LSIGB, IRDataType.WORD, reg1=actualResultReg2, reg2=tr.resultReg, immediate = 0), null)
|
||||||
}
|
}
|
||||||
BaseDataType.LONG -> {
|
BaseDataType.LONG -> {
|
||||||
actualResultReg2 = codeGen.registers.next(IRDataType.BYTE)
|
actualResultReg2 = codeGen.registers.next(IRDataType.BYTE)
|
||||||
val wordReg = codeGen.registers.next(IRDataType.WORD)
|
addInstr(result, IRInstruction(Opcode.LSIGB, IRDataType.LONG, reg1=actualResultReg2, reg2=tr.resultReg, immediate = 0), null)
|
||||||
addInstr(result, IRInstruction(Opcode.LSIG, IRDataType.WORD, reg1=wordReg, reg2=tr.resultReg, immediate = 0), null)
|
|
||||||
addInstr(result, IRInstruction(Opcode.LSIG, IRDataType.BYTE, reg1=actualResultReg2, reg2=wordReg, immediate = 0), null)
|
|
||||||
}
|
}
|
||||||
BaseDataType.FLOAT -> {
|
BaseDataType.FLOAT -> {
|
||||||
actualResultReg2 = codeGen.registers.next(IRDataType.BYTE)
|
actualResultReg2 = codeGen.registers.next(IRDataType.BYTE)
|
||||||
@@ -761,7 +757,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
}
|
}
|
||||||
BaseDataType.LONG -> {
|
BaseDataType.LONG -> {
|
||||||
actualResultReg2 = codeGen.registers.next(IRDataType.WORD)
|
actualResultReg2 = codeGen.registers.next(IRDataType.WORD)
|
||||||
addInstr(result, IRInstruction(Opcode.LSIG, IRDataType.WORD, reg1=actualResultReg2, reg2=tr.resultReg, immediate = 0), null)
|
addInstr(result, IRInstruction(Opcode.LSIGW, IRDataType.LONG, reg1=actualResultReg2, reg2=tr.resultReg, immediate = 0), null)
|
||||||
}
|
}
|
||||||
BaseDataType.FLOAT -> {
|
BaseDataType.FLOAT -> {
|
||||||
actualResultReg2 = codeGen.registers.next(IRDataType.WORD)
|
actualResultReg2 = codeGen.registers.next(IRDataType.WORD)
|
||||||
@@ -790,7 +786,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
}
|
}
|
||||||
BaseDataType.LONG -> {
|
BaseDataType.LONG -> {
|
||||||
actualResultReg2 = codeGen.registers.next(IRDataType.WORD)
|
actualResultReg2 = codeGen.registers.next(IRDataType.WORD)
|
||||||
addInstr(result, IRInstruction(Opcode.LSIG, IRDataType.WORD, reg1=actualResultReg2, reg2=tr.resultReg, immediate = 0), null)
|
addInstr(result, IRInstruction(Opcode.LSIGW, IRDataType.LONG, reg1=actualResultReg2, reg2=tr.resultReg, immediate = 0), null)
|
||||||
}
|
}
|
||||||
BaseDataType.FLOAT -> {
|
BaseDataType.FLOAT -> {
|
||||||
actualResultReg2 = codeGen.registers.next(IRDataType.WORD)
|
actualResultReg2 = codeGen.registers.next(IRDataType.WORD)
|
||||||
|
|||||||
@@ -254,6 +254,15 @@ class VarConstantValueTypeAdjuster(
|
|||||||
functionCallExpr))
|
functionCallExpr))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(func==listOf("lsb") || func==listOf("msb")) {
|
||||||
|
val t1 = functionCallExpr.args[0].inferType(program)
|
||||||
|
if(t1.isLong) {
|
||||||
|
val replaceFunc = func[0]+"__long"
|
||||||
|
return listOf(IAstModification.SetExpression({functionCallExpr.target = it as IdentifierReference},
|
||||||
|
IdentifierReference(listOf(replaceFunc), functionCallExpr.target.position),
|
||||||
|
functionCallExpr))
|
||||||
|
}
|
||||||
|
}
|
||||||
return noModifications
|
return noModifications
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ txt {
|
|||||||
sub width() -> ubyte {
|
sub width() -> ubyte {
|
||||||
%ir {{
|
%ir {{
|
||||||
syscall 46 (): r99000.w
|
syscall 46 (): r99000.w
|
||||||
lsig.b r99100,r99000
|
lsigb.w r99100,r99000
|
||||||
returnr.b r99100
|
returnr.b r99100
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
@@ -16,7 +16,7 @@ sub width() -> ubyte {
|
|||||||
sub height() -> ubyte {
|
sub height() -> ubyte {
|
||||||
%ir {{
|
%ir {{
|
||||||
syscall 46 (): r99000.w
|
syscall 46 (): r99000.w
|
||||||
msig.b r99100,r99000
|
msigb.w r99100,r99000
|
||||||
returnr.b r99100
|
returnr.b r99100
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,8 +22,10 @@ internal val constEvaluatorsForBuiltinFuncs: Map<String, ConstExpressionCaller>
|
|||||||
"sqrt__uword" to { a, p, prg -> oneIntArgOutputInt(a, p, prg, false) { sqrt(it.toDouble()) } },
|
"sqrt__uword" to { a, p, prg -> oneIntArgOutputInt(a, p, prg, false) { sqrt(it.toDouble()) } },
|
||||||
"sqrt__float" to { a, p, prg -> oneFloatArgOutputFloat(a, p, prg) { sqrt(it) } },
|
"sqrt__float" to { a, p, prg -> oneFloatArgOutputFloat(a, p, prg) { sqrt(it) } },
|
||||||
"lsb" to { a, p, prg -> oneIntArgOutputInt(a, p, prg, true) { x: Int -> (x and 255).toDouble() } },
|
"lsb" to { a, p, prg -> oneIntArgOutputInt(a, p, prg, true) { x: Int -> (x and 255).toDouble() } },
|
||||||
|
"lsb__long" to { a, p, prg -> oneIntArgOutputInt(a, p, prg, true) { x: Int -> (x and 255).toDouble() } },
|
||||||
"lsw" to { a, p, prg -> oneIntArgOutputInt(a, p, prg, true) { x: Int -> (x and 65535).toDouble() } },
|
"lsw" to { a, p, prg -> oneIntArgOutputInt(a, p, prg, true) { x: Int -> (x and 65535).toDouble() } },
|
||||||
"msb" to { a, p, prg -> oneIntArgOutputInt(a, p, prg, true) { x: Int -> (x ushr 8 and 255).toDouble()} },
|
"msb" to { a, p, prg -> oneIntArgOutputInt(a, p, prg, true) { x: Int -> (x ushr 8 and 255).toDouble()} },
|
||||||
|
"msb__long" to { a, p, prg -> oneIntArgOutputInt(a, p, prg, true) { x: Int -> (x ushr 24 and 255).toDouble()} },
|
||||||
"msw" to { a, p, prg -> oneIntArgOutputInt(a, p, prg, true) { x: Int -> (x ushr 16 and 65535).toDouble()} },
|
"msw" to { a, p, prg -> oneIntArgOutputInt(a, p, prg, true) { x: Int -> (x ushr 16 and 65535).toDouble()} },
|
||||||
"mkword" to ::builtinMkword,
|
"mkword" to ::builtinMkword,
|
||||||
"mklong" to ::builtinMklong,
|
"mklong" to ::builtinMklong,
|
||||||
|
|||||||
@@ -91,16 +91,13 @@ cmp (x,y)
|
|||||||
Normally you should just use a comparison expression (``x < y``)
|
Normally you should just use a comparison expression (``x < y``)
|
||||||
|
|
||||||
lsb (x)
|
lsb (x)
|
||||||
Get the least significant (lower) byte of the value x. Equivalent to ``x & 255``.
|
Get the least significant (lower) byte of the value x. Equivalent to ``x & 255`` or even ``x as ubyte``.
|
||||||
|
|
||||||
lsw (x)
|
lsw (x)
|
||||||
Get the least significant (lower) word of the value x. Equivalent to ``x & 65535``.
|
Get the least significant (lower) word of the value x. Equivalent to ``x & 65535`` or even ``x as uword``.
|
||||||
|
|
||||||
msb (x)
|
msb (x)
|
||||||
Get the most significant (higher) byte of the word value x.
|
Get the most significant (highest) byte of the word or long value x.
|
||||||
If x is a value greater than a word, it will not actually return the *highest* byte of this value,
|
|
||||||
but it will only look a the lower word part of this value and return the higher byte from that.
|
|
||||||
So you're always getting bits 8-16 of the value x: ``msb($1234)`` is $12, whereas ``msb($123456)`` is $34.
|
|
||||||
|
|
||||||
msw (x)
|
msw (x)
|
||||||
Get the most significant (higher) word of the value x. For all word and byte numbers this will always result in 0.
|
Get the most significant (higher) word of the value x. For all word and byte numbers this will always result in 0.
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ STRUCTS and TYPED POINTERS
|
|||||||
Future Things and Ideas
|
Future Things and Ideas
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
- make $8000000 a valid long integer (-2147483648) this is more involved than you think. To make this work: long |= $80000000
|
- make $8000000 a valid long integer (-2147483648) this is more involved than you think. To make this work: long |= $80000000
|
||||||
|
- make memory mapped variables support more constant expressions such as: &uword MyHigh = &mylong1+2
|
||||||
- fix the line, cols in Position, sometimes they count from 0 sometimes from 1, should both always be 1-based (is this the reason some source lines end up missing in the IR file?)
|
- fix the line, cols in Position, sometimes they count from 0 sometimes from 1, should both always be 1-based (is this the reason some source lines end up missing in the IR file?)
|
||||||
- handle Alias in a general way in LiteralsToAutoVarsAndRecombineIdentifiers instead of replacing it scattered over multiple functions
|
- handle Alias in a general way in LiteralsToAutoVarsAndRecombineIdentifiers instead of replacing it scattered over multiple functions
|
||||||
- After long variable type is completed: make all constants long by default (remove type name altogether), reduce to target type implictly if the actual value fits.
|
- After long variable type is completed: make all constants long by default (remove type name altogether), reduce to target type implictly if the actual value fits.
|
||||||
|
|||||||
@@ -6,14 +6,25 @@ main {
|
|||||||
sub start() {
|
sub start() {
|
||||||
long @shared lv1 = $12345678
|
long @shared lv1 = $12345678
|
||||||
|
|
||||||
; TODO support long+1 / -1 expressions....
|
txt.print_ubhex(msb(lv1), true)
|
||||||
cx16.r4 = msw(lv1-1)
|
txt.spc()
|
||||||
cx16.r5 = lsw(lv1-1)
|
txt.print_ubhex(lsb(lv1), true)
|
||||||
txt.print_uwhex(cx16.r4, true)
|
txt.spc()
|
||||||
txt.print_uwhex(cx16.r5, true)
|
txt.print_ubhex(lv1 as ubyte, true)
|
||||||
|
txt.nl()
|
||||||
|
txt.print_uwhex(msw(lv1), true)
|
||||||
|
txt.spc()
|
||||||
|
txt.print_uwhex(lsw(lv1), true)
|
||||||
txt.nl()
|
txt.nl()
|
||||||
|
|
||||||
txt.print_ubhex((lv1-1) as ubyte, true)
|
; ; TODO support long+1 / -1 expressions....
|
||||||
txt.nl()
|
; cx16.r4 = msw(lv1-1)
|
||||||
|
; cx16.r5 = lsw(lv1-1)
|
||||||
|
; txt.print_uwhex(cx16.r4, true)
|
||||||
|
; txt.print_uwhex(cx16.r5, true)
|
||||||
|
; txt.nl()
|
||||||
|
;
|
||||||
|
; txt.print_ubhex((lv1-1) as ubyte, true)
|
||||||
|
; txt.nl()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -248,8 +248,10 @@ sei - set interrupt disable flag
|
|||||||
nop - do nothing
|
nop - do nothing
|
||||||
breakpoint - trigger a breakpoint
|
breakpoint - trigger a breakpoint
|
||||||
align alignmentvalue - represents a memory alignment directive
|
align alignmentvalue - represents a memory alignment directive
|
||||||
lsig [b, w] reg1, reg2 - reg1 becomes the least significant byte (or word) of the word (or int) in reg2
|
lsigb [w, l] reg1, reg2 - reg1 becomes the least significant byte of the word (or long) in reg2
|
||||||
msig [b, w] reg1, reg2 - reg1 becomes the most significant byte (or word) of the word (or int) in reg2
|
lsigw [l] reg1, reg2 - reg1 becomes the least significant word of the long in reg2
|
||||||
|
msigb [w, l] reg1, reg2 - reg1 becomes the most significant byte of the word (or long) in reg2
|
||||||
|
msigw [l] reg1, reg2 - reg1 becomes the most significant word of the long in reg2
|
||||||
concat [b, w] reg1, reg2, reg3 - reg1.w/l = 'concatenate' two registers: lsb/lsw of reg2 (as msb) and lsb/lsw of reg3 (as lsb) into word or int)
|
concat [b, w] reg1, reg2, reg3 - reg1.w/l = 'concatenate' two registers: lsb/lsw of reg2 (as msb) and lsb/lsw of reg3 (as lsb) into word or int)
|
||||||
push [b, w, f] reg1 - push value in reg1 on the stack
|
push [b, w, f] reg1 - push value in reg1 on the stack
|
||||||
pop [b, w, f] reg1 - pop value from stack into reg1
|
pop [b, w, f] reg1 - pop value from stack into reg1
|
||||||
@@ -421,8 +423,10 @@ enum class Opcode {
|
|||||||
POP,
|
POP,
|
||||||
PUSHST,
|
PUSHST,
|
||||||
POPST,
|
POPST,
|
||||||
LSIG,
|
LSIGB,
|
||||||
MSIG,
|
LSIGW,
|
||||||
|
MSIGB,
|
||||||
|
MSIGW,
|
||||||
CONCAT,
|
CONCAT,
|
||||||
BREAKPOINT,
|
BREAKPOINT,
|
||||||
ALIGN
|
ALIGN
|
||||||
@@ -521,8 +525,10 @@ val OpcodesThatSetStatusbitsButNotCarry = arrayOf(
|
|||||||
Opcode.XORM,
|
Opcode.XORM,
|
||||||
Opcode.XORR,
|
Opcode.XORR,
|
||||||
Opcode.XOR,
|
Opcode.XOR,
|
||||||
Opcode.LSIG,
|
Opcode.LSIGB,
|
||||||
Opcode.MSIG,
|
Opcode.LSIGW,
|
||||||
|
Opcode.MSIGB,
|
||||||
|
Opcode.MSIGW,
|
||||||
Opcode.CONCAT
|
Opcode.CONCAT
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -798,8 +804,10 @@ val instructionFormats = mutableMapOf(
|
|||||||
Opcode.FFLOOR to InstructionFormat.from("F,>fr1,<fr2"),
|
Opcode.FFLOOR to InstructionFormat.from("F,>fr1,<fr2"),
|
||||||
Opcode.FCEIL to InstructionFormat.from("F,>fr1,<fr2"),
|
Opcode.FCEIL to InstructionFormat.from("F,>fr1,<fr2"),
|
||||||
|
|
||||||
Opcode.LSIG to InstructionFormat.from("BW,>r1,<r2"),
|
Opcode.LSIGB to InstructionFormat.from("WL,>r1,<r2"),
|
||||||
Opcode.MSIG to InstructionFormat.from("BW,>r1,<r2"),
|
Opcode.LSIGW to InstructionFormat.from("L,>r1,<r2"),
|
||||||
|
Opcode.MSIGB to InstructionFormat.from("WL,>r1,<r2"),
|
||||||
|
Opcode.MSIGW to InstructionFormat.from("L,>r1,<r2"),
|
||||||
Opcode.PUSH to InstructionFormat.from("BWL,<r1 | F,<fr1"),
|
Opcode.PUSH to InstructionFormat.from("BWL,<r1 | F,<fr1"),
|
||||||
Opcode.POP to InstructionFormat.from("BWL,>r1 | F,>fr1"),
|
Opcode.POP to InstructionFormat.from("BWL,>r1 | F,>fr1"),
|
||||||
Opcode.PUSHST to InstructionFormat.from("N"),
|
Opcode.PUSHST to InstructionFormat.from("N"),
|
||||||
@@ -1095,13 +1103,13 @@ data class IRInstruction(
|
|||||||
if(opcode==Opcode.SGN)
|
if(opcode==Opcode.SGN)
|
||||||
return IRDataType.BYTE
|
return IRDataType.BYTE
|
||||||
}
|
}
|
||||||
if(opcode==Opcode.JUMPI || opcode==Opcode.CALLI || opcode==Opcode.STOREZI)
|
if(opcode==Opcode.JUMPI || opcode==Opcode.CALLI || opcode==Opcode.STOREZI || opcode==Opcode.LSIGW || opcode==Opcode.MSIGW)
|
||||||
return IRDataType.WORD
|
return IRDataType.WORD
|
||||||
if(opcode==Opcode.EXT || opcode==Opcode.EXTS)
|
if(opcode==Opcode.EXT || opcode==Opcode.EXTS)
|
||||||
return if (type == IRDataType.BYTE) IRDataType.WORD else null
|
return if (type == IRDataType.BYTE) IRDataType.WORD else null
|
||||||
if(opcode==Opcode.CONCAT)
|
if(opcode==Opcode.CONCAT)
|
||||||
return if (type == IRDataType.BYTE) IRDataType.WORD else null
|
return if (type == IRDataType.BYTE) IRDataType.WORD else null
|
||||||
if(opcode==Opcode.ASRNM || opcode==Opcode.LSRNM || opcode==Opcode.LSLNM || opcode==Opcode.SQRT)
|
if(opcode==Opcode.ASRNM || opcode==Opcode.LSRNM || opcode==Opcode.LSLNM || opcode==Opcode.SQRT || opcode==Opcode.LSIGB || opcode==Opcode.MSIGB)
|
||||||
return IRDataType.BYTE
|
return IRDataType.BYTE
|
||||||
return this.type
|
return this.type
|
||||||
}
|
}
|
||||||
@@ -1111,12 +1119,6 @@ data class IRInstruction(
|
|||||||
return IRDataType.BYTE
|
return IRDataType.BYTE
|
||||||
if(opcode==Opcode.LOADI || opcode==Opcode.STOREI || opcode==Opcode.LOADFIELD || opcode==Opcode.STOREFIELD)
|
if(opcode==Opcode.LOADI || opcode==Opcode.STOREI || opcode==Opcode.LOADFIELD || opcode==Opcode.STOREFIELD)
|
||||||
return IRDataType.WORD
|
return IRDataType.WORD
|
||||||
if(opcode==Opcode.MSIG || opcode==Opcode.LSIG)
|
|
||||||
return when(type) {
|
|
||||||
IRDataType.BYTE -> IRDataType.WORD
|
|
||||||
IRDataType.WORD -> IRDataType.LONG
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
if(opcode==Opcode.ASRN || opcode==Opcode.LSRN || opcode==Opcode.LSLN)
|
if(opcode==Opcode.ASRN || opcode==Opcode.LSRN || opcode==Opcode.LSLN)
|
||||||
return IRDataType.BYTE
|
return IRDataType.BYTE
|
||||||
return this.type
|
return this.type
|
||||||
|
|||||||
@@ -311,8 +311,10 @@ class VirtualMachine(irProgram: IRProgram) {
|
|||||||
Opcode.ROLM -> InsROLM(ins, false)
|
Opcode.ROLM -> InsROLM(ins, false)
|
||||||
Opcode.ROXL -> InsROL(ins, true)
|
Opcode.ROXL -> InsROL(ins, true)
|
||||||
Opcode.ROXLM -> InsROLM(ins, true)
|
Opcode.ROXLM -> InsROLM(ins, true)
|
||||||
Opcode.LSIG -> InsLSIG(ins)
|
Opcode.LSIGB -> InsLSIGB(ins)
|
||||||
Opcode.MSIG -> InsMSIG(ins)
|
Opcode.LSIGW -> InsLSIGW(ins)
|
||||||
|
Opcode.MSIGB -> InsMSIGB(ins)
|
||||||
|
Opcode.MSIGW -> InsMSIGW(ins)
|
||||||
Opcode.CONCAT -> InsCONCAT(ins)
|
Opcode.CONCAT -> InsCONCAT(ins)
|
||||||
Opcode.PUSH -> InsPUSH(ins)
|
Opcode.PUSH -> InsPUSH(ins)
|
||||||
Opcode.POP -> InsPOP(ins)
|
Opcode.POP -> InsPOP(ins)
|
||||||
@@ -2579,39 +2581,63 @@ class VirtualMachine(irProgram: IRProgram) {
|
|||||||
statusCarry = newStatusCarry
|
statusCarry = newStatusCarry
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun InsLSIG(i: IRInstruction) {
|
private fun InsLSIGB(i: IRInstruction) {
|
||||||
when(i.type!!) {
|
when(i.type!!) {
|
||||||
IRDataType.BYTE -> {
|
|
||||||
val value = registers.getUW(i.reg2!!)
|
|
||||||
registers.setUB(i.reg1!!, value.toUByte())
|
|
||||||
statusbitsNZ(value.toInt(), i.type!!)
|
|
||||||
}
|
|
||||||
IRDataType.WORD -> {
|
IRDataType.WORD -> {
|
||||||
val value = registers.getSL(i.reg2!!)
|
val value = registers.getUW(i.reg2!!)
|
||||||
registers.setUW(i.reg1!!, value.toUShort())
|
val byte = value.toUByte()
|
||||||
|
registers.setUB(i.reg1!!, byte)
|
||||||
|
statusbitsNZ(byte.toInt(), i.type!!)
|
||||||
}
|
}
|
||||||
IRDataType.LONG -> throw IllegalArgumentException("lsig.l makes no sense, 32 bits is already the widest")
|
IRDataType.LONG -> {
|
||||||
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
val value = registers.getSL(i.reg2!!)
|
||||||
|
val byte = value.toUByte()
|
||||||
|
registers.setUB(i.reg1!!, byte)
|
||||||
|
statusbitsNZ(byte.toInt(), i.type!!)
|
||||||
|
}
|
||||||
|
else -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||||
}
|
}
|
||||||
nextPc()
|
nextPc()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun InsMSIG(i: IRInstruction) {
|
private fun InsLSIGW(i: IRInstruction) {
|
||||||
|
if (i.type!! == IRDataType.LONG) {
|
||||||
|
val value = registers.getSL(i.reg2!!)
|
||||||
|
val word = value.toUShort()
|
||||||
|
registers.setUW(i.reg1!!, word)
|
||||||
|
statusbitsNZ(word.toInt(), i.type!!)
|
||||||
|
}
|
||||||
|
else throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||||
|
nextPc()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun InsMSIGB(i: IRInstruction) {
|
||||||
when(i.type!!) {
|
when(i.type!!) {
|
||||||
IRDataType.BYTE -> {
|
IRDataType.WORD -> {
|
||||||
val value = registers.getUW(i.reg2!!)
|
val value = registers.getUW(i.reg2!!)
|
||||||
val newValue = value.toInt() ushr 8
|
val newValue = value.toInt() ushr 8
|
||||||
statusbitsNZ(newValue, i.type!!)
|
statusbitsNZ(newValue, i.type!!)
|
||||||
registers.setUB(i.reg1!!, newValue.toUByte())
|
registers.setUB(i.reg1!!, newValue.toUByte())
|
||||||
}
|
}
|
||||||
IRDataType.WORD -> {
|
IRDataType.LONG -> {
|
||||||
|
val value = registers.getSL(i.reg2!!)
|
||||||
|
val newValue = value ushr 24
|
||||||
|
statusbitsNZ(newValue, i.type!!)
|
||||||
|
registers.setUB(i.reg1!!, newValue.toUByte())
|
||||||
|
}
|
||||||
|
else -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||||
|
}
|
||||||
|
nextPc()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun InsMSIGW(i: IRInstruction) {
|
||||||
|
if (i.type!! == IRDataType.LONG) {
|
||||||
val value = registers.getSL(i.reg2!!)
|
val value = registers.getSL(i.reg2!!)
|
||||||
val newValue = value ushr 16
|
val newValue = value ushr 16
|
||||||
|
statusbitsNZ(newValue, i.type!!)
|
||||||
registers.setUW(i.reg1!!, newValue.toUShort())
|
registers.setUW(i.reg1!!, newValue.toUShort())
|
||||||
}
|
}
|
||||||
IRDataType.LONG -> throw IllegalArgumentException("lsig.l makes no sense, 32 bits is already the widest")
|
else throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||||
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
|
||||||
}
|
|
||||||
nextPc()
|
nextPc()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user