mirror of
https://github.com/irmen/prog8.git
synced 2025-11-03 19:16:13 +00:00
start with introducing LONG datatype (32 bits signed integer)
This commit is contained in:
@@ -7,6 +7,7 @@ internal class RegisterPool {
|
||||
// everything from 99000 onwards is reserved for special purposes:
|
||||
// 99000 - 99099 : WORD registers for syscall arguments and response value(s)
|
||||
// 99100 - 99199 : BYTE registers for syscall arguments and response value(s)
|
||||
// 99200 - 99299 : LONG registers for syscall arguments and response value(s)
|
||||
|
||||
private var nextRegister: Int=1
|
||||
private val registerTypes: MutableMap<Int, IRDataType> = mutableMapOf()
|
||||
@@ -18,6 +19,8 @@ internal class RegisterPool {
|
||||
registerTypes[i] = IRDataType.WORD
|
||||
for(i in 99100..99199)
|
||||
registerTypes[i] = IRDataType.BYTE
|
||||
for(i in 99200..99299)
|
||||
registerTypes[i] = IRDataType.LONG
|
||||
}
|
||||
|
||||
fun next(type: IRDataType): Int {
|
||||
|
||||
@@ -35,7 +35,7 @@ class ConstantFoldingOptimizer(private val program: Program, private val errors:
|
||||
|
||||
override fun after(numLiteral: NumericLiteral, parent: Node): Iterable<IAstModification> {
|
||||
|
||||
if(numLiteral.type==BaseDataType.LONG) {
|
||||
if(numLiteral.type==BaseDataType.LONG && parent !is Assignment) {
|
||||
// see if LONG values may be reduced to something smaller
|
||||
val smaller = NumericLiteral.optimalInteger(numLiteral.number.toInt(), numLiteral.position)
|
||||
if(smaller.type!=BaseDataType.LONG) {
|
||||
|
||||
@@ -228,6 +228,22 @@ asmsub str_w (word value @ AY) clobbers(X) -> str @AY {
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub str_l (uword msw @ R0, uword lsw @ R1) clobbers(X) -> str @AY {
|
||||
; ---- convert the long in R0:R1 into decimal string form, without left padding 0s
|
||||
%asm {{
|
||||
lda #'?'
|
||||
sta string_out
|
||||
lda #'?'
|
||||
sta string_out+1
|
||||
lda #0
|
||||
sta string_out+2
|
||||
; TODO implement this!
|
||||
sta string_out
|
||||
lda #<string_out
|
||||
ldy #>string_out
|
||||
rts
|
||||
}}
|
||||
}
|
||||
|
||||
; ---- string conversion to numbers -----
|
||||
|
||||
|
||||
@@ -165,6 +165,11 @@ _allzero lda #'0'
|
||||
}}
|
||||
}
|
||||
|
||||
sub print_l (long value) {
|
||||
; ---- print the (signed) long in decimal form, without left padding 0's
|
||||
print(conv.str_l(msw(value), lsw(value)))
|
||||
}
|
||||
|
||||
asmsub input_chars (^^ubyte buffer @ AY) clobbers(A) -> ubyte @ Y {
|
||||
; ---- Input a string (max. 80 chars) from the keyboard, in PETSCII encoding.
|
||||
; Returns length in Y. (string is terminated with a 0 byte as well)
|
||||
|
||||
@@ -141,7 +141,7 @@ sub str_uw (uword value) -> str {
|
||||
}
|
||||
|
||||
sub str_w (word value) -> str {
|
||||
; ---- convert the (signed) word in A/Y in decimal string form, without left padding 0's
|
||||
; ---- convert the (signed) word into decimal string form, without left padding 0's
|
||||
^^ubyte out_ptr = &string_out
|
||||
if value<0 {
|
||||
@(out_ptr) = '-'
|
||||
@@ -152,6 +152,16 @@ sub str_w (word value) -> str {
|
||||
return string_out
|
||||
}
|
||||
|
||||
sub str_l (long value) -> str {
|
||||
; ---- convert the (signed) long into decimal string form, without left padding 0's
|
||||
%ir {{
|
||||
loadm.l r99200,conv.str_l.value
|
||||
load.w r99000,conv.string_out
|
||||
syscall 60 (r99200.l, r99000.w) : r99000.w
|
||||
returnr.w r99000
|
||||
}}
|
||||
}
|
||||
|
||||
sub internal_str_uw(uword value, str out_ptr) {
|
||||
uword value2 = value/10
|
||||
ubyte digits = value-value2*10 as ubyte
|
||||
|
||||
@@ -151,6 +151,14 @@ sub print_w (word value) {
|
||||
print(conv.str_w(value))
|
||||
}
|
||||
|
||||
sub print_l (long value) {
|
||||
; ---- print the (signed) long in decimal form, without left padding 0's
|
||||
%ir {{
|
||||
loadm.l r99200,txt.print_l.value
|
||||
syscall 59 (r99200.l)
|
||||
}}
|
||||
}
|
||||
|
||||
sub input_chars (str buffer) -> ubyte {
|
||||
; ---- Input a string (max. 80 chars) from the keyboard. Returns length of input. (string is terminated with a 0 byte as well)
|
||||
; It assumes the keyboard is selected as I/O channel!
|
||||
|
||||
@@ -82,7 +82,6 @@ internal class AstChecker(private val program: Program,
|
||||
}
|
||||
}
|
||||
|
||||
checkLongType(identifier)
|
||||
val stmt = identifier.targetStatement(program.builtinFunctions)
|
||||
if(stmt==null) {
|
||||
if(identifier.parent is ArrayIndexedExpression) {
|
||||
@@ -363,10 +362,6 @@ internal class AstChecker(private val program: Program,
|
||||
super.visit(label)
|
||||
}
|
||||
|
||||
override fun visit(numLiteral: NumericLiteral) {
|
||||
checkLongType(numLiteral)
|
||||
}
|
||||
|
||||
private fun hasReturnOrExternalJumpOrRts(scope: IStatementContainer): Boolean {
|
||||
class Searcher: IAstVisitor
|
||||
{
|
||||
@@ -813,7 +808,6 @@ internal class AstChecker(private val program: Program,
|
||||
}
|
||||
|
||||
override fun visit(addressOf: AddressOf) {
|
||||
checkLongType(addressOf)
|
||||
val variable=addressOf.identifier?.targetVarDecl()
|
||||
if (variable!=null) {
|
||||
if (variable.type == VarDeclType.CONST && addressOf.arrayIndex == null)
|
||||
@@ -862,8 +856,6 @@ internal class AstChecker(private val program: Program,
|
||||
if(decl.names.size>1)
|
||||
throw InternalCompilerException("vardecls with multiple names should have been converted into individual vardecls")
|
||||
|
||||
if(decl.datatype.isLong && decl.type!=VarDeclType.CONST)
|
||||
errors.err("cannot use long type for variables; only for constants", decl.position)
|
||||
if(decl.type==VarDeclType.MEMORY) {
|
||||
if (decl.datatype.isString)
|
||||
errors.err("strings cannot be memory-mapped", decl.position)
|
||||
@@ -1329,7 +1321,6 @@ internal class AstChecker(private val program: Program,
|
||||
}
|
||||
}
|
||||
|
||||
checkLongType(expr)
|
||||
val dt = expr.expression.inferType(program).getOrUndef()
|
||||
if(!dt.isUndefined) {
|
||||
|
||||
@@ -1474,8 +1465,6 @@ internal class AstChecker(private val program: Program,
|
||||
return
|
||||
}
|
||||
|
||||
checkLongType(expr)
|
||||
|
||||
val leftIDt = expr.left.inferType(program)
|
||||
val rightIDt = expr.right.inferType(program)
|
||||
if(!leftIDt.isKnown || !rightIDt.isKnown) {
|
||||
@@ -1614,7 +1603,6 @@ internal class AstChecker(private val program: Program,
|
||||
}
|
||||
|
||||
override fun visit(typecast: TypecastExpression) {
|
||||
checkLongType(typecast)
|
||||
if(typecast.type.isPassByRef)
|
||||
errors.err("cannot type cast to string or array type", typecast.position)
|
||||
|
||||
@@ -1671,7 +1659,6 @@ internal class AstChecker(private val program: Program,
|
||||
}
|
||||
|
||||
override fun visit(functionCallExpr: FunctionCallExpression) {
|
||||
checkLongType(functionCallExpr)
|
||||
// this function call is (part of) an expression, which should be in a statement somewhere.
|
||||
val stmtOfExpression = findParentNode<Statement>(functionCallExpr)
|
||||
?: throw FatalAstException("cannot determine statement scope of function call expression at ${functionCallExpr.position}")
|
||||
@@ -1905,7 +1892,6 @@ internal class AstChecker(private val program: Program,
|
||||
}
|
||||
|
||||
args.forEach{
|
||||
checkLongType(it)
|
||||
if(it.inferType(program).isStructInstance)
|
||||
errors.err("structs can only be passed via a pointer", it.position)
|
||||
}
|
||||
@@ -1918,7 +1904,6 @@ internal class AstChecker(private val program: Program,
|
||||
}
|
||||
|
||||
override fun visit(arrayIndexedExpression: ArrayIndexedExpression) {
|
||||
checkLongType(arrayIndexedExpression)
|
||||
val target = arrayIndexedExpression.plainarrayvar?.targetStatement(program.builtinFunctions)
|
||||
if(target is VarDecl) {
|
||||
if (!target.datatype.isIterable && !target.datatype.isUnsignedWord && !target.datatype.isPointer)
|
||||
@@ -2164,17 +2149,6 @@ internal class AstChecker(private val program: Program,
|
||||
super.visit(deref)
|
||||
}
|
||||
|
||||
private fun checkLongType(expression: Expression) {
|
||||
if(expression.inferType(program) issimpletype BaseDataType.LONG) {
|
||||
if((expression.parent as? VarDecl)?.type!=VarDeclType.CONST) {
|
||||
if (expression.parent !is RepeatLoop) {
|
||||
if (errors.noErrorForLine(expression.position))
|
||||
errors.err("integer overflow", expression.position)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkValueTypeAndRangeString(targetDt: DataType, value: StringLiteral) : Boolean {
|
||||
return if (targetDt.isString) {
|
||||
when {
|
||||
|
||||
@@ -1,11 +1,39 @@
|
||||
%import textio
|
||||
|
||||
main {
|
||||
sub start() {
|
||||
func()
|
||||
long bignum = 12345678
|
||||
long bignum2 = -999999
|
||||
|
||||
struct Node {
|
||||
ubyte id
|
||||
str name
|
||||
long array
|
||||
bool flag
|
||||
long counter
|
||||
}
|
||||
|
||||
sub func() {
|
||||
if cx16.r0<10 or cx16.r0>319 {
|
||||
cx16.r1++
|
||||
}
|
||||
sub start() {
|
||||
^^Node test = []
|
||||
|
||||
bignum++
|
||||
bignum2--
|
||||
|
||||
txt.print_l(bignum)
|
||||
txt.spc()
|
||||
txt.print_l(bignum2)
|
||||
txt.nl()
|
||||
|
||||
str output = "...................."
|
||||
txt.print(conv.str_l(bignum))
|
||||
txt.nl()
|
||||
|
||||
bignum = 999999
|
||||
bignum-- ; TODO this works in the current VM...
|
||||
bignum = -888888
|
||||
|
||||
test.counter = 0
|
||||
test.counter ++ ; TODO ... why doesn't this? (requires plusMinusMultAnyLong routine)
|
||||
test.counter = bignum2
|
||||
test.counter --
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,8 +136,8 @@ ARITHMETIC
|
||||
----------
|
||||
All have type b or w or f. Note: result types are the same as operand types! E.g. byte*byte->byte.
|
||||
|
||||
exts reg1, reg2 - reg1 = signed extension of reg2 (byte to word, or word to long) (note: unlike M68k, exts.b -> word and exts.w -> long. The latter is not yet implemented yet as we don't have longs yet)
|
||||
ext reg1, reg2 - reg1 = unsigned extension of reg2 (which in practice just means clearing the MSB / MSW) (note: unlike M68k, ext.b -> word and ext.w -> long. The latter is not yet implemented yet as we don't have longs yet)
|
||||
exts reg1, reg2 - reg1 = signed extension of reg2 (byte to word, or word to long) (note: unlike M68k, exts.b -> word and exts.w -> long.)
|
||||
ext reg1, reg2 - reg1 = unsigned extension of reg2 (which in practice just means clearing the MSB / MSW) (note: unlike M68k, ext.b -> word and ext.w -> long. )
|
||||
inc reg1 - reg1 = reg1+1
|
||||
incm address - memory at address += 1
|
||||
dec reg1 - reg1 = reg1-1
|
||||
@@ -247,9 +247,9 @@ sei - set interrupt disable flag
|
||||
nop - do nothing
|
||||
breakpoint - trigger a breakpoint
|
||||
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 (.w not yet implemented; requires 32 bits regs)
|
||||
msig [b, w] reg1, reg2 - reg1 becomes the most significant byte (or word) of the word (or int) in reg2 (.w not yet implemented; requires 32 bits regs)
|
||||
concat [b, w] reg1, reg2, reg3 - reg1.w = 'concatenate' two registers: lsb/lsw of reg2 (as msb) and lsb/lsw of reg3 (as lsb) into word or int (int not yet implemented; requires 32bits regs)
|
||||
lsig [b, w] reg1, reg2 - reg1 becomes the least significant byte (or word) of the word (or int) in reg2
|
||||
msig [b, w] reg1, reg2 - reg1 becomes the most significant byte (or word) of the word (or int) 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)
|
||||
push [b, w, f] reg1 - push value in reg1 on the stack
|
||||
pop [b, w, f] reg1 - pop value from stack into reg1
|
||||
pushst - push status register bits to stack
|
||||
@@ -559,8 +559,8 @@ val OpcodesThatSetStatusbits = OpcodesThatSetStatusbitsButNotCarry + OpcodesThat
|
||||
enum class IRDataType {
|
||||
BYTE,
|
||||
WORD,
|
||||
FLOAT
|
||||
// TODO add INT (32-bit)? INT24 (24-bit)?
|
||||
FLOAT,
|
||||
LONG // 32 bits integer
|
||||
}
|
||||
|
||||
enum class OperandDirection {
|
||||
@@ -623,6 +623,8 @@ data class InstructionFormat(val datatype: IRDataType?,
|
||||
result[IRDataType.BYTE] = InstructionFormat(IRDataType.BYTE, reg1, reg2, reg3, fpreg1, fpreg2, address, immediate, funcCall, sysCall)
|
||||
if('W' in typespec)
|
||||
result[IRDataType.WORD] = InstructionFormat(IRDataType.WORD, reg1, reg2, reg3, fpreg1, fpreg2, address, immediate, funcCall, sysCall)
|
||||
if('L' in typespec)
|
||||
result[IRDataType.LONG] = InstructionFormat(IRDataType.LONG, reg1, reg2, reg3, fpreg1, fpreg2, address, immediate, funcCall, sysCall)
|
||||
if('F' in typespec)
|
||||
result[IRDataType.FLOAT] = InstructionFormat(IRDataType.FLOAT, reg1, reg2, reg3, fpreg1, fpreg2, address, immediate, funcCall, sysCall)
|
||||
}
|
||||
@@ -643,12 +645,12 @@ data class InstructionFormat(val datatype: IRDataType?,
|
||||
*/
|
||||
val instructionFormats = mutableMapOf(
|
||||
Opcode.NOP to InstructionFormat.from("N"),
|
||||
Opcode.LOAD to InstructionFormat.from("BW,>r1,<i | F,>fr1,<i"),
|
||||
Opcode.LOADM to InstructionFormat.from("BW,>r1,<a | F,>fr1,<a"),
|
||||
Opcode.LOADI to InstructionFormat.from("BW,>r1,<r2 | F,>fr1,<r1"),
|
||||
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.LOADR to InstructionFormat.from("BW,>r1,<r2 | F,>fr1,<fr2"),
|
||||
Opcode.LOAD to InstructionFormat.from("BWL,>r1,<i | F,>fr1,<i"),
|
||||
Opcode.LOADM to InstructionFormat.from("BWL,>r1,<a | F,>fr1,<a"),
|
||||
Opcode.LOADI to InstructionFormat.from("BWL,>r1,<r2 | F,>fr1,<r1"),
|
||||
Opcode.LOADX to InstructionFormat.from("BWL,>r1,<r2,<a | F,>fr1,<r1,<a"),
|
||||
Opcode.LOADIX to InstructionFormat.from("BWL,>r1,<r2,<a | F,>fr1,<r1,<a"),
|
||||
Opcode.LOADR to InstructionFormat.from("BWL,>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"),
|
||||
@@ -656,16 +658,16 @@ val instructionFormats = mutableMapOf(
|
||||
Opcode.LOADHAX to InstructionFormat.from("W,>r1"),
|
||||
Opcode.LOADHAY to InstructionFormat.from("W,>r1"),
|
||||
Opcode.LOADHXY to InstructionFormat.from("W,>r1"),
|
||||
Opcode.LOADFIELD to InstructionFormat.from("BW,>r1,<r2,<i | F,>fr1,<r1,<i"),
|
||||
Opcode.LOADFIELD to InstructionFormat.from("BWL,>r1,<r2,<i | F,>fr1,<r1,<i"),
|
||||
Opcode.LOADHFACZERO to InstructionFormat.from("F,>fr1"),
|
||||
Opcode.LOADHFACONE to InstructionFormat.from("F,>fr1"),
|
||||
Opcode.STOREM to InstructionFormat.from("BW,<r1,>a | F,<fr1,>a"),
|
||||
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.STOREIX to InstructionFormat.from("BW,<r1,<r2,>a | F,<fr1,<r1,>a"),
|
||||
Opcode.STOREZM to InstructionFormat.from("BW,>a | F,>a"),
|
||||
Opcode.STOREZI to InstructionFormat.from("BW,<r1 | F,<r1"),
|
||||
Opcode.STOREZX to InstructionFormat.from("BW,<r1,>a | F,<r1,>a"),
|
||||
Opcode.STOREM to InstructionFormat.from("BWL,<r1,>a | F,<fr1,>a"),
|
||||
Opcode.STOREI to InstructionFormat.from("BWL,<r1,<r2 | F,<fr1,<r1"),
|
||||
Opcode.STOREX to InstructionFormat.from("BWL,<r1,<r2,>a | F,<fr1,<r1,>a"),
|
||||
Opcode.STOREIX to InstructionFormat.from("BWL,<r1,<r2,>a | F,<fr1,<r1,>a"),
|
||||
Opcode.STOREZM to InstructionFormat.from("BWL,>a | F,>a"),
|
||||
Opcode.STOREZI to InstructionFormat.from("BWL,<r1 | F,<r1"),
|
||||
Opcode.STOREZX to InstructionFormat.from("BWL,<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"),
|
||||
@@ -673,7 +675,7 @@ val instructionFormats = mutableMapOf(
|
||||
Opcode.STOREHAX to InstructionFormat.from("W,<r1"),
|
||||
Opcode.STOREHAY to InstructionFormat.from("W,<r1"),
|
||||
Opcode.STOREHXY to InstructionFormat.from("W,<r1"),
|
||||
Opcode.STOREFIELD to InstructionFormat.from("BW,<r1,<r2,<i | F,<fr1,<r1,<i"),
|
||||
Opcode.STOREFIELD to InstructionFormat.from("BWL,<r1,<r2,<i | F,<fr1,<r1,<i"),
|
||||
Opcode.STOREHFACZERO to InstructionFormat.from("F,<fr1"),
|
||||
Opcode.STOREHFACONE to InstructionFormat.from("F,<fr1"),
|
||||
Opcode.JUMP to InstructionFormat.from("N,<a"),
|
||||
@@ -684,8 +686,8 @@ val instructionFormats = mutableMapOf(
|
||||
Opcode.CALLFARVB to InstructionFormat.from("N,<r1,<a"),
|
||||
Opcode.SYSCALL to InstructionFormat.from("N,syscall"),
|
||||
Opcode.RETURN to InstructionFormat.from("N"),
|
||||
Opcode.RETURNR to InstructionFormat.from("BW,<r1 | F,<fr1"),
|
||||
Opcode.RETURNI to InstructionFormat.from("BW,<i | F,<i"),
|
||||
Opcode.RETURNR to InstructionFormat.from("BWL,<r1 | F,<fr1"),
|
||||
Opcode.RETURNI to InstructionFormat.from("BWL,<i | F,<i"),
|
||||
Opcode.BSTCC to InstructionFormat.from("N,<a"),
|
||||
Opcode.BSTCS to InstructionFormat.from("N,<a"),
|
||||
Opcode.BSTEQ to InstructionFormat.from("N,<a"),
|
||||
@@ -694,84 +696,84 @@ val instructionFormats = mutableMapOf(
|
||||
Opcode.BSTPOS to InstructionFormat.from("N,<a"),
|
||||
Opcode.BSTVC to InstructionFormat.from("N,<a"),
|
||||
Opcode.BSTVS to InstructionFormat.from("N,<a"),
|
||||
Opcode.BGTR to InstructionFormat.from("BW,<r1,<r2,<a"),
|
||||
Opcode.BGT to InstructionFormat.from("BW,<r1,<i,<a"),
|
||||
Opcode.BLT to InstructionFormat.from("BW,<r1,<i,<a"),
|
||||
Opcode.BGTSR to InstructionFormat.from("BW,<r1,<r2,<a"),
|
||||
Opcode.BGTS to InstructionFormat.from("BW,<r1,<i,<a"),
|
||||
Opcode.BLTS to InstructionFormat.from("BW,<r1,<i,<a"),
|
||||
Opcode.BGER to InstructionFormat.from("BW,<r1,<r2,<a"),
|
||||
Opcode.BGE to InstructionFormat.from("BW,<r1,<i,<a"),
|
||||
Opcode.BLE to InstructionFormat.from("BW,<r1,<i,<a"),
|
||||
Opcode.BGESR to InstructionFormat.from("BW,<r1,<r2,<a"),
|
||||
Opcode.BGES to InstructionFormat.from("BW,<r1,<i,<a"),
|
||||
Opcode.BLES to InstructionFormat.from("BW,<r1,<i,<a"),
|
||||
Opcode.INC to InstructionFormat.from("BW,<>r1 | F,<>fr1"),
|
||||
Opcode.INCM to InstructionFormat.from("BW,<>a | F,<>a"),
|
||||
Opcode.DEC to InstructionFormat.from("BW,<>r1 | F,<>fr1"),
|
||||
Opcode.DECM to InstructionFormat.from("BW,<>a | F,<>a"),
|
||||
Opcode.NEG to InstructionFormat.from("BW,<>r1 | F,<>fr1"),
|
||||
Opcode.NEGM to InstructionFormat.from("BW,<>a | F,<>a"),
|
||||
Opcode.ADDR to InstructionFormat.from("BW,<>r1,<r2 | F,<>fr1,<fr2"),
|
||||
Opcode.ADD to InstructionFormat.from("BW,<>r1,<i | F,<>fr1,<i"),
|
||||
Opcode.ADDM to InstructionFormat.from("BW,<r1,<>a | F,<fr1,<>a"),
|
||||
Opcode.SUBR to InstructionFormat.from("BW,<>r1,<r2 | F,<>fr1,<fr2"),
|
||||
Opcode.SUB to InstructionFormat.from("BW,<>r1,<i | F,<>fr1,<i"),
|
||||
Opcode.SUBM to InstructionFormat.from("BW,<r1,<>a | F,<fr1,<>a"),
|
||||
Opcode.BGTR to InstructionFormat.from("BWL,<r1,<r2,<a"),
|
||||
Opcode.BGT to InstructionFormat.from("BWL,<r1,<i,<a"),
|
||||
Opcode.BLT to InstructionFormat.from("BWL,<r1,<i,<a"),
|
||||
Opcode.BGTSR to InstructionFormat.from("BWL,<r1,<r2,<a"),
|
||||
Opcode.BGTS to InstructionFormat.from("BWL,<r1,<i,<a"),
|
||||
Opcode.BLTS to InstructionFormat.from("BWL,<r1,<i,<a"),
|
||||
Opcode.BGER to InstructionFormat.from("BWL,<r1,<r2,<a"),
|
||||
Opcode.BGE to InstructionFormat.from("BWL,<r1,<i,<a"),
|
||||
Opcode.BLE to InstructionFormat.from("BWL,<r1,<i,<a"),
|
||||
Opcode.BGESR to InstructionFormat.from("BWL,<r1,<r2,<a"),
|
||||
Opcode.BGES to InstructionFormat.from("BWL,<r1,<i,<a"),
|
||||
Opcode.BLES to InstructionFormat.from("BWL,<r1,<i,<a"),
|
||||
Opcode.INC to InstructionFormat.from("BWL,<>r1 | F,<>fr1"),
|
||||
Opcode.INCM to InstructionFormat.from("BWL,<>a | F,<>a"),
|
||||
Opcode.DEC to InstructionFormat.from("BWL,<>r1 | F,<>fr1"),
|
||||
Opcode.DECM to InstructionFormat.from("BWL,<>a | F,<>a"),
|
||||
Opcode.NEG to InstructionFormat.from("BWL,<>r1 | F,<>fr1"),
|
||||
Opcode.NEGM to InstructionFormat.from("BWL,<>a | F,<>a"),
|
||||
Opcode.ADDR to InstructionFormat.from("BWL,<>r1,<r2 | F,<>fr1,<fr2"),
|
||||
Opcode.ADD to InstructionFormat.from("BWL,<>r1,<i | F,<>fr1,<i"),
|
||||
Opcode.ADDM to InstructionFormat.from("BWL,<r1,<>a | F,<fr1,<>a"),
|
||||
Opcode.SUBR to InstructionFormat.from("BWL,<>r1,<r2 | F,<>fr1,<fr2"),
|
||||
Opcode.SUB to InstructionFormat.from("BWL,<>r1,<i | F,<>fr1,<i"),
|
||||
Opcode.SUBM to InstructionFormat.from("BWL,<r1,<>a | F,<fr1,<>a"),
|
||||
Opcode.MULR to InstructionFormat.from("BW,<>r1,<r2 | F,<>fr1,<fr2"),
|
||||
Opcode.MUL to InstructionFormat.from("BW,<>r1,<i | F,<>fr1,<i"),
|
||||
Opcode.MULM to InstructionFormat.from("BW,<r1,<>a | F,<fr1,<>a"),
|
||||
Opcode.MULSR to InstructionFormat.from("BW,<>r1,<r2 | F,<>fr1,<fr2"),
|
||||
Opcode.MULS to InstructionFormat.from("BW,<>r1,<i | F,<>fr1,<i"),
|
||||
Opcode.MULSM to InstructionFormat.from("BW,<r1,<>a | F,<fr1,<>a"),
|
||||
Opcode.MULSR to InstructionFormat.from("BWL,<>r1,<r2 | F,<>fr1,<fr2"),
|
||||
Opcode.MULS to InstructionFormat.from("BWL,<>r1,<i | F,<>fr1,<i"),
|
||||
Opcode.MULSM to InstructionFormat.from("BWL,<r1,<>a | F,<fr1,<>a"),
|
||||
Opcode.DIVR to InstructionFormat.from("BW,<>r1,<r2 | F,<>fr1,<fr2"),
|
||||
Opcode.DIV to InstructionFormat.from("BW,<>r1,<i | F,<>fr1,<i"),
|
||||
Opcode.DIVM to InstructionFormat.from("BW,<r1,<>a | F,<fr1,<>a"),
|
||||
Opcode.DIVSR to InstructionFormat.from("BW,<>r1,<r2 | F,<>fr1,<fr2"),
|
||||
Opcode.DIVS to InstructionFormat.from("BW,<>r1,<i | F,<>fr1,<i"),
|
||||
Opcode.DIVSM to InstructionFormat.from("BW,<r1,<>a | F,<fr1,<>a"),
|
||||
Opcode.SQRT to InstructionFormat.from("BW,>r1,<r2 | F,>fr1,<fr2"),
|
||||
Opcode.SQUARE to InstructionFormat.from("BW,>r1,<r2 | F,>fr1,<fr2"),
|
||||
Opcode.SGN to InstructionFormat.from("BW,>r1,<r2 | F,>r1,<fr1"),
|
||||
Opcode.DIVSR to InstructionFormat.from("BWL,<>r1,<r2 | F,<>fr1,<fr2"),
|
||||
Opcode.DIVS to InstructionFormat.from("BWL,<>r1,<i | F,<>fr1,<i"),
|
||||
Opcode.DIVSM to InstructionFormat.from("BWL,<r1,<>a | F,<fr1,<>a"),
|
||||
Opcode.SQRT to InstructionFormat.from("BWL,>r1,<r2 | F,>fr1,<fr2"),
|
||||
Opcode.SQUARE to InstructionFormat.from("BWL,>r1,<r2 | F,>fr1,<fr2"),
|
||||
Opcode.SGN to InstructionFormat.from("BWL,>r1,<r2 | F,>r1,<fr1"),
|
||||
Opcode.MODR to InstructionFormat.from("BW,<>r1,<r2"),
|
||||
Opcode.MOD to InstructionFormat.from("BW,<>r1,<i"),
|
||||
Opcode.DIVMODR to InstructionFormat.from("BW,<>r1,<r2"),
|
||||
Opcode.DIVMOD to InstructionFormat.from("BW,<>r1,<i"),
|
||||
Opcode.CMP to InstructionFormat.from("BW,<r1,<r2"),
|
||||
Opcode.CMPI to InstructionFormat.from("BW,<r1,<i"),
|
||||
Opcode.EXT to InstructionFormat.from("BW,>r1,<r2"),
|
||||
Opcode.EXTS to InstructionFormat.from("BW,>r1,<r2"),
|
||||
Opcode.ANDR to InstructionFormat.from("BW,<>r1,<r2"),
|
||||
Opcode.AND to InstructionFormat.from("BW,<>r1,<i"),
|
||||
Opcode.ANDM to InstructionFormat.from("BW,<r1,<>a"),
|
||||
Opcode.ORR to InstructionFormat.from("BW,<>r1,<r2"),
|
||||
Opcode.OR to InstructionFormat.from("BW,<>r1,<i"),
|
||||
Opcode.ORM to InstructionFormat.from("BW,<r1,<>a"),
|
||||
Opcode.XORR to InstructionFormat.from("BW,<>r1,<r2"),
|
||||
Opcode.XOR to InstructionFormat.from("BW,<>r1,<i"),
|
||||
Opcode.XORM to InstructionFormat.from("BW,<r1,<>a"),
|
||||
Opcode.INV to InstructionFormat.from("BW,<>r1"),
|
||||
Opcode.INVM to InstructionFormat.from("BW,<>a"),
|
||||
Opcode.ASRN to InstructionFormat.from("BW,<>r1,<r2"),
|
||||
Opcode.ASRNM to InstructionFormat.from("BW,<r1,<>a"),
|
||||
Opcode.LSRN to InstructionFormat.from("BW,<>r1,<r2"),
|
||||
Opcode.LSRNM to InstructionFormat.from("BW,<r1,<>a"),
|
||||
Opcode.LSLN to InstructionFormat.from("BW,<>r1,<r2"),
|
||||
Opcode.LSLNM to InstructionFormat.from("BW,<r1,<>a"),
|
||||
Opcode.ASR to InstructionFormat.from("BW,<>r1"),
|
||||
Opcode.ASRM to InstructionFormat.from("BW,<>a"),
|
||||
Opcode.LSR to InstructionFormat.from("BW,<>r1"),
|
||||
Opcode.LSRM to InstructionFormat.from("BW,<>a"),
|
||||
Opcode.LSL to InstructionFormat.from("BW,<>r1"),
|
||||
Opcode.LSLM to InstructionFormat.from("BW,<>a"),
|
||||
Opcode.ROR to InstructionFormat.from("BW,<>r1"),
|
||||
Opcode.RORM to InstructionFormat.from("BW,<>a"),
|
||||
Opcode.ROXR to InstructionFormat.from("BW,<>r1"),
|
||||
Opcode.ROXRM to InstructionFormat.from("BW,<>a"),
|
||||
Opcode.ROL to InstructionFormat.from("BW,<>r1"),
|
||||
Opcode.ROLM to InstructionFormat.from("BW,<>a"),
|
||||
Opcode.ROXL to InstructionFormat.from("BW,<>r1"),
|
||||
Opcode.ROXLM to InstructionFormat.from("BW,<>a"),
|
||||
Opcode.CMP to InstructionFormat.from("BWL,<r1,<r2"),
|
||||
Opcode.CMPI to InstructionFormat.from("BWL,<r1,<i"),
|
||||
Opcode.EXT to InstructionFormat.from("BWL,>r1,<r2"),
|
||||
Opcode.EXTS to InstructionFormat.from("BWL,>r1,<r2"),
|
||||
Opcode.ANDR to InstructionFormat.from("BWL,<>r1,<r2"),
|
||||
Opcode.AND to InstructionFormat.from("BWL,<>r1,<i"),
|
||||
Opcode.ANDM to InstructionFormat.from("BWL,<r1,<>a"),
|
||||
Opcode.ORR to InstructionFormat.from("BWL,<>r1,<r2"),
|
||||
Opcode.OR to InstructionFormat.from("BWL,<>r1,<i"),
|
||||
Opcode.ORM to InstructionFormat.from("BWL,<r1,<>a"),
|
||||
Opcode.XORR to InstructionFormat.from("BWL,<>r1,<r2"),
|
||||
Opcode.XOR to InstructionFormat.from("BWL,<>r1,<i"),
|
||||
Opcode.XORM to InstructionFormat.from("BWL,<r1,<>a"),
|
||||
Opcode.INV to InstructionFormat.from("BWL,<>r1"),
|
||||
Opcode.INVM to InstructionFormat.from("BWL,<>a"),
|
||||
Opcode.ASRN to InstructionFormat.from("BWL,<>r1,<r2"),
|
||||
Opcode.ASRNM to InstructionFormat.from("BWL,<r1,<>a"),
|
||||
Opcode.LSRN to InstructionFormat.from("BWL,<>r1,<r2"),
|
||||
Opcode.LSRNM to InstructionFormat.from("BWL,<r1,<>a"),
|
||||
Opcode.LSLN to InstructionFormat.from("BWL,<>r1,<r2"),
|
||||
Opcode.LSLNM to InstructionFormat.from("BWL,<r1,<>a"),
|
||||
Opcode.ASR to InstructionFormat.from("BWL,<>r1"),
|
||||
Opcode.ASRM to InstructionFormat.from("BWL,<>a"),
|
||||
Opcode.LSR to InstructionFormat.from("BWL,<>r1"),
|
||||
Opcode.LSRM to InstructionFormat.from("BWL,<>a"),
|
||||
Opcode.LSL to InstructionFormat.from("BWL,<>r1"),
|
||||
Opcode.LSLM to InstructionFormat.from("BWL,<>a"),
|
||||
Opcode.ROR to InstructionFormat.from("BWL,<>r1"),
|
||||
Opcode.RORM to InstructionFormat.from("BWL,<>a"),
|
||||
Opcode.ROXR to InstructionFormat.from("BWL,<>r1"),
|
||||
Opcode.ROXRM to InstructionFormat.from("BWL,<>a"),
|
||||
Opcode.ROL to InstructionFormat.from("BWL,<>r1"),
|
||||
Opcode.ROLM to InstructionFormat.from("BWL,<>a"),
|
||||
Opcode.ROXL to InstructionFormat.from("BWL,<>r1"),
|
||||
Opcode.ROXLM to InstructionFormat.from("BWL,<>a"),
|
||||
Opcode.BIT to InstructionFormat.from("B,<a"),
|
||||
|
||||
Opcode.FFROMUB to InstructionFormat.from("F,>fr1,<r1"),
|
||||
@@ -797,8 +799,8 @@ val instructionFormats = mutableMapOf(
|
||||
|
||||
Opcode.LSIG to InstructionFormat.from("BW,>r1,<r2"),
|
||||
Opcode.MSIG to InstructionFormat.from("BW,>r1,<r2"),
|
||||
Opcode.PUSH to InstructionFormat.from("BW,<r1 | F,<fr1"),
|
||||
Opcode.POP to InstructionFormat.from("BW,>r1 | F,>fr1"),
|
||||
Opcode.PUSH to InstructionFormat.from("BWL,<r1 | F,<fr1"),
|
||||
Opcode.POP to InstructionFormat.from("BWL,>r1 | F,>fr1"),
|
||||
Opcode.PUSHST to InstructionFormat.from("N"),
|
||||
Opcode.POPST to InstructionFormat.from("N"),
|
||||
Opcode.CONCAT to InstructionFormat.from("BW,<>r1,<r2,<r3"),
|
||||
@@ -903,6 +905,7 @@ data class IRInstruction(
|
||||
when (type) {
|
||||
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.LONG -> require(immediate in -2147483647..2147483647) { "immediate value out of range for long: $immediate" }
|
||||
IRDataType.FLOAT, null -> {}
|
||||
}
|
||||
}
|
||||
@@ -1083,8 +1086,7 @@ data class IRInstruction(
|
||||
// some word instructions have byte reg1
|
||||
return when (opcode) {
|
||||
Opcode.STOREZX, Opcode.SQRT -> IRDataType.BYTE
|
||||
Opcode.EXT, Opcode.EXTS -> TODO("ext.w into long type")
|
||||
Opcode.CONCAT -> TODO("concat.w into long type")
|
||||
Opcode.EXT, Opcode.EXTS, Opcode.CONCAT -> IRDataType.LONG
|
||||
else -> IRDataType.WORD
|
||||
}
|
||||
}
|
||||
@@ -1107,7 +1109,7 @@ data class IRInstruction(
|
||||
if(opcode==Opcode.MSIG || opcode==Opcode.LSIG)
|
||||
return when(type) {
|
||||
IRDataType.BYTE -> IRDataType.WORD
|
||||
IRDataType.WORD -> TODO("msig/lsig.w from long type")
|
||||
IRDataType.WORD -> IRDataType.LONG
|
||||
else -> null
|
||||
}
|
||||
if(opcode==Opcode.ASRN || opcode==Opcode.LSRN || opcode==Opcode.LSLN)
|
||||
@@ -1125,6 +1127,7 @@ data class IRInstruction(
|
||||
when(type) {
|
||||
IRDataType.BYTE -> result.add(".b ")
|
||||
IRDataType.WORD -> result.add(".w ")
|
||||
IRDataType.LONG -> result.add(".l ")
|
||||
IRDataType.FLOAT -> result.add(".f ")
|
||||
else -> result.add(" ")
|
||||
}
|
||||
@@ -1154,6 +1157,7 @@ data class IRInstruction(
|
||||
when(it.reg.dt) {
|
||||
IRDataType.BYTE -> result.add("${location}r${it.reg.registerNum}.b$cpuReg,")
|
||||
IRDataType.WORD -> result.add("${location}r${it.reg.registerNum}.w$cpuReg,")
|
||||
IRDataType.LONG -> result.add("${location}r${it.reg.registerNum}.l$cpuReg,")
|
||||
IRDataType.FLOAT -> result.add("${location}fr${it.reg.registerNum}.f$cpuReg,")
|
||||
}
|
||||
}
|
||||
@@ -1175,12 +1179,14 @@ data class IRInstruction(
|
||||
when (returnspec.dt) {
|
||||
IRDataType.BYTE -> "r${returnspec.registerNum}.b"
|
||||
IRDataType.WORD -> "r${returnspec.registerNum}.w"
|
||||
IRDataType.LONG -> "r${returnspec.registerNum}.l"
|
||||
IRDataType.FLOAT -> "fr${returnspec.registerNum}.f"
|
||||
}
|
||||
} else {
|
||||
when (returnspec.dt) {
|
||||
IRDataType.BYTE -> "r${returnspec.registerNum}.b@" + cpuReg
|
||||
IRDataType.WORD -> "r${returnspec.registerNum}.w@" + cpuReg
|
||||
IRDataType.LONG -> "r${returnspec.registerNum}.l@" + cpuReg
|
||||
IRDataType.FLOAT -> "r${returnspec.registerNum}.f@" + cpuReg
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ fun convertIRType(typestr: String): IRDataType? {
|
||||
"" -> null
|
||||
".b" -> IRDataType.BYTE
|
||||
".w" -> IRDataType.WORD
|
||||
".l" -> IRDataType.LONG
|
||||
".f" -> IRDataType.FLOAT
|
||||
else -> throw IRParseException("invalid type $typestr")
|
||||
}
|
||||
@@ -78,7 +79,7 @@ fun parseIRValue(value: String): Double {
|
||||
}
|
||||
|
||||
|
||||
private val instructionPattern = Regex("""([a-z]+)(\.b|\.w|\.f)?(.*)""", RegexOption.IGNORE_CASE)
|
||||
private val instructionPattern = Regex("""([a-z]+)(\.b|\.w|\.l|\.f)?(.*)""", RegexOption.IGNORE_CASE)
|
||||
private val labelPattern = Regex("""_([a-zA-Z\d\._]+):""")
|
||||
|
||||
fun parseIRCodeLine(line: String): Either<IRInstruction, String> {
|
||||
@@ -207,6 +208,10 @@ fun parseIRCodeLine(line: String): Either<IRInstruction, String> {
|
||||
if (immediateInt!=null && (immediateInt < -32768 || immediateInt > 65535))
|
||||
throw IRParseException("immediate value out of range for word: $immediateInt")
|
||||
}
|
||||
IRDataType.LONG -> {
|
||||
if (immediateInt!=null && immediateInt < -2147483647)
|
||||
throw IRParseException("immediate value out of range for long: $immediateInt")
|
||||
}
|
||||
IRDataType.FLOAT -> {}
|
||||
null -> {}
|
||||
}
|
||||
@@ -271,6 +276,7 @@ private fun parseCall(rest: String): ParsedCall {
|
||||
val type = when(match.groups[2]!!.value) {
|
||||
"b" -> IRDataType.BYTE
|
||||
"w" -> IRDataType.WORD
|
||||
"l" -> IRDataType.LONG
|
||||
"f" -> IRDataType.FLOAT
|
||||
else -> throw IRParseException("invalid type spec in $reg")
|
||||
}
|
||||
@@ -359,6 +365,7 @@ fun irType(type: DataType): IRDataType {
|
||||
BaseDataType.UBYTE,
|
||||
BaseDataType.BYTE -> IRDataType.BYTE
|
||||
BaseDataType.UWORD, BaseDataType.WORD, BaseDataType.POINTER -> IRDataType.WORD
|
||||
BaseDataType.LONG -> IRDataType.LONG
|
||||
BaseDataType.FLOAT -> IRDataType.FLOAT
|
||||
BaseDataType.STRUCT_INSTANCE -> throw AssemblyError("no support for struct instances yet so no IR datatype for $type")
|
||||
else -> throw AssemblyError("no IR datatype for $type")
|
||||
|
||||
@@ -32,6 +32,10 @@ class Memory {
|
||||
return (mem[address] + 256u*mem[address+1]).toUShort()
|
||||
}
|
||||
|
||||
fun getSL(address: Int): Int {
|
||||
return (mem[address] + 256u*mem[address+1] + 65536u*mem[address+2] + 16777216u*mem[address+3]).toInt()
|
||||
}
|
||||
|
||||
fun getSW(address: Int): Short {
|
||||
return (mem[address].toInt() + mem[address+1].toInt()*256).toShort()
|
||||
}
|
||||
@@ -47,6 +51,14 @@ class Memory {
|
||||
mem[address] = uv.toUByte()
|
||||
}
|
||||
|
||||
fun setSL(address: Int, value: Int) {
|
||||
val uv = value.toUInt()
|
||||
mem[address+3] = (uv shr 24).toUByte()
|
||||
mem[address+2] = (uv shr 16).toUByte()
|
||||
mem[address+1] = (uv shr 8).toUByte()
|
||||
mem[address] = uv.toUByte()
|
||||
}
|
||||
|
||||
fun setFloat(address: Int, value: Double) {
|
||||
var bits = value.toBits()
|
||||
mem[address] = bits.toUByte()
|
||||
|
||||
@@ -6,14 +6,14 @@ package prog8.vm
|
||||
* A,X and Y "physical" 6502 registers.
|
||||
*/
|
||||
class Registers {
|
||||
private val registers = Array<UShort>(99999) { 0u }
|
||||
private val registers = Array<Int>(99999) { 0 }
|
||||
private val floatRegisters = Array(99999) { 0.0 }
|
||||
var cpuA: UByte = 0u
|
||||
var cpuX: UByte = 0u
|
||||
var cpuY: UByte = 0u
|
||||
|
||||
fun reset() {
|
||||
registers.fill(0u)
|
||||
registers.fill(0)
|
||||
floatRegisters.fill(0.0)
|
||||
cpuA = 0u
|
||||
cpuX = 0u
|
||||
@@ -21,29 +21,35 @@ class Registers {
|
||||
}
|
||||
|
||||
fun setUB(reg: Int, value: UByte) {
|
||||
registers[reg] = registers[reg] and 0xff00u or value.toUShort()
|
||||
registers[reg] = value.toInt()
|
||||
}
|
||||
|
||||
fun setSB(reg: Int, value: Byte) {
|
||||
registers[reg] = registers[reg] and 0xff00u or (value.toUShort() and 0x00ffu)
|
||||
registers[reg] = value.toInt()
|
||||
}
|
||||
|
||||
fun setUW(reg: Int, value: UShort) {
|
||||
registers[reg] = value
|
||||
registers[reg] = value.toInt()
|
||||
}
|
||||
|
||||
fun setSW(reg: Int, value: Short) {
|
||||
registers[reg] = value.toUShort()
|
||||
registers[reg] = value.toInt()
|
||||
}
|
||||
|
||||
fun setSL(reg: Int, value: Int) {
|
||||
registers[reg] = value
|
||||
}
|
||||
|
||||
fun getUB(reg: Int) = registers[reg].toUByte()
|
||||
|
||||
fun getSB(reg: Int) = registers[reg].toByte()
|
||||
|
||||
fun getUW(reg: Int) = registers[reg]
|
||||
fun getUW(reg: Int) = registers[reg].toUShort()
|
||||
|
||||
fun getSW(reg: Int) = registers[reg].toShort()
|
||||
|
||||
fun getSL(reg: Int) = registers[reg]
|
||||
|
||||
fun getFloat(reg:Int) = floatRegisters[reg]
|
||||
|
||||
fun setFloat(reg:Int, value: Double) {
|
||||
|
||||
@@ -68,6 +68,9 @@ SYSCALLS: DO NOT RENUMBER THESE OR YOU WILL BREAK EXISTING CODE
|
||||
56 = CLOSE_FILE
|
||||
57 = CLOSE_FILE_WRITE
|
||||
58 = ncompare strings
|
||||
59 = print_i32 ; print signed 32 bits integer (prog8 long)
|
||||
60 = i32 to string ; put string representation of signed 32 bits integer (prog8 long) into memory
|
||||
61 = decimal string to prog8 long (i32 signed)
|
||||
*/
|
||||
|
||||
enum class Syscall {
|
||||
@@ -130,6 +133,9 @@ enum class Syscall {
|
||||
CLOSE_FILE,
|
||||
CLOSE_FILE_WRITE,
|
||||
NCOMPARE_STRINGS,
|
||||
PRINT_I32,
|
||||
I32_TO_STRING,
|
||||
STR_TO_LONG,
|
||||
;
|
||||
|
||||
companion object {
|
||||
@@ -143,6 +149,7 @@ object SysCalls {
|
||||
when(it.reg.dt) {
|
||||
IRDataType.BYTE -> vm.registers.getUB(it.reg.registerNum)
|
||||
IRDataType.WORD -> vm.registers.getUW(it.reg.registerNum)
|
||||
IRDataType.LONG -> vm.registers.getSL(it.reg.registerNum)
|
||||
IRDataType.FLOAT -> vm.registers.getFloat(it.reg.registerNum)
|
||||
}
|
||||
}
|
||||
@@ -164,6 +171,7 @@ object SysCalls {
|
||||
when(returns.dt) {
|
||||
IRDataType.BYTE -> vm.registers.setUB(returns.registerNum, vv.toInt().toUByte())
|
||||
IRDataType.WORD -> vm.registers.setUW(returns.registerNum, vv.toInt().toUShort())
|
||||
IRDataType.LONG -> vm.registers.setSL(returns.registerNum, vv.toInt())
|
||||
IRDataType.FLOAT -> vm.registers.setFloat(returns.registerNum, vv)
|
||||
}
|
||||
}
|
||||
@@ -200,6 +208,10 @@ object SysCalls {
|
||||
val value = getArgValues(callspec.arguments, vm).single()
|
||||
print(value)
|
||||
}
|
||||
Syscall.PRINT_I32 -> {
|
||||
val value = getArgValues(callspec.arguments, vm).single()
|
||||
print(value)
|
||||
}
|
||||
Syscall.INPUT -> {
|
||||
val (address, maxlen) = getArgValues(callspec.arguments, vm)
|
||||
var input = readln()
|
||||
@@ -263,6 +275,17 @@ object SysCalls {
|
||||
}
|
||||
return returnValue(callspec.returns.single(), value, vm)
|
||||
}
|
||||
Syscall.STR_TO_LONG -> {
|
||||
val stringAddr = getArgValues(callspec.arguments, vm).single() as UShort
|
||||
val memstring = vm.memory.getString(stringAddr.toInt())
|
||||
val match = Regex("^[+-]?\\d+").find(memstring) ?: return returnValue(callspec.returns.single(), 0, vm)
|
||||
val value = try {
|
||||
match.value.toInt()
|
||||
} catch(_: NumberFormatException) {
|
||||
0
|
||||
}
|
||||
return returnValue(callspec.returns.single(), value, vm)
|
||||
}
|
||||
Syscall.STR_TO_FLOAT -> {
|
||||
val stringAddr = getArgValues(callspec.arguments, vm).single() as UShort
|
||||
val memstring = vm.memory.getString(stringAddr.toInt()).replace(" ", "")
|
||||
@@ -634,6 +657,10 @@ object SysCalls {
|
||||
}
|
||||
Syscall.CLOSE_FILE -> vm.close_file_read()
|
||||
Syscall.CLOSE_FILE_WRITE -> vm.close_file_write()
|
||||
Syscall.I32_TO_STRING -> {
|
||||
val (number, stringbuffer) = getArgValues(callspec.arguments, vm)
|
||||
vm.memory.setString((stringbuffer as UShort).toInt(), number.toString(), true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -353,12 +353,17 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
IRDataType.BYTE -> {
|
||||
registers.setUB(reg, value.toUByte())
|
||||
statusZero = value==0
|
||||
statusNegative = value>=0x80
|
||||
statusNegative = value<0 || value>=0x80
|
||||
}
|
||||
IRDataType.WORD -> {
|
||||
registers.setUW(reg, value.toUShort())
|
||||
statusZero = value==0
|
||||
statusNegative = value>=0x8000
|
||||
statusNegative = value<0 || value>=0x8000
|
||||
}
|
||||
IRDataType.LONG -> {
|
||||
registers.setSL(reg, value)
|
||||
statusZero = value==0
|
||||
statusNegative = value<0
|
||||
}
|
||||
IRDataType.FLOAT -> throw IllegalArgumentException("attempt to set integer result register but float type")
|
||||
}
|
||||
@@ -377,6 +382,10 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
val value = registers.getUW(i.reg1!!)
|
||||
valueStack.pushw(value)
|
||||
}
|
||||
IRDataType.LONG -> {
|
||||
val value = registers.getSL(i.reg1!!)
|
||||
valueStack.pushl(value)
|
||||
}
|
||||
IRDataType.FLOAT -> {
|
||||
val value = registers.getFloat(i.fpReg1!!)
|
||||
valueStack.pushf(value)
|
||||
@@ -389,6 +398,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
when(i.type!!) {
|
||||
IRDataType.BYTE -> setResultReg(i.reg1!!, valueStack.removeLast().toInt(), i.type!!)
|
||||
IRDataType.WORD -> setResultReg(i.reg1!!, valueStack.popw().toInt(), i.type!!)
|
||||
IRDataType.LONG -> setResultReg(i.reg1!!, valueStack.popl(), i.type!!)
|
||||
IRDataType.FLOAT -> registers.setFloat(i.fpReg1!!, valueStack.popf())
|
||||
}
|
||||
nextPc()
|
||||
@@ -425,6 +435,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
when(value.dt!!) {
|
||||
IRDataType.BYTE -> valueStack.add(value.value as UByte)
|
||||
IRDataType.WORD -> valueStack.pushw(value.value as UShort)
|
||||
IRDataType.LONG -> valueStack.pushl(value.value as Int)
|
||||
IRDataType.FLOAT -> valueStack.pushf(value.value as Double)
|
||||
}
|
||||
value.dt=null
|
||||
@@ -472,6 +483,11 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
registers.setUW(i.reg1!!, value)
|
||||
statusbitsNZ(value.toInt(), i.type!!)
|
||||
}
|
||||
IRDataType.LONG -> {
|
||||
val value = memory.getSL(i.address!!)
|
||||
registers.setSL(i.reg1!!, value)
|
||||
statusbitsNZ(value, i.type!!)
|
||||
}
|
||||
IRDataType.FLOAT -> registers.setFloat(i.fpReg1!!, memory.getFloat(i.address!!))
|
||||
}
|
||||
nextPc()
|
||||
@@ -489,6 +505,11 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
registers.setUW(i.reg1!!, value)
|
||||
statusbitsNZ(value.toInt(), i.type!!)
|
||||
}
|
||||
IRDataType.LONG -> {
|
||||
val value = memory.getSL(registers.getUW(i.reg2!!).toInt())
|
||||
registers.setSL(i.reg1!!, value)
|
||||
statusbitsNZ(value, i.type!!)
|
||||
}
|
||||
IRDataType.FLOAT -> registers.setFloat(i.fpReg1!!, memory.getFloat(registers.getUW(i.reg1!!).toInt()))
|
||||
}
|
||||
nextPc()
|
||||
@@ -508,6 +529,11 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
registers.setUW(i.reg1!!, value)
|
||||
statusbitsNZ(value.toInt(), i.type!!)
|
||||
}
|
||||
IRDataType.LONG -> {
|
||||
val value = memory.getSL(registers.getUW(i.reg2!!).toInt() + offset)
|
||||
registers.setSL(i.reg1!!, value)
|
||||
statusbitsNZ(value, i.type!!)
|
||||
}
|
||||
IRDataType.FLOAT -> {
|
||||
registers.setFloat(i.fpReg1!!, memory.getFloat(registers.getUW(i.reg1!!).toInt() + offset))
|
||||
}
|
||||
@@ -527,6 +553,11 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
registers.setUW(i.reg1!!, value)
|
||||
statusbitsNZ(value.toInt(), i.type!!)
|
||||
}
|
||||
IRDataType.LONG -> {
|
||||
val value = memory.getSL(i.address!! + registers.getUB(i.reg2!!).toInt())
|
||||
registers.setSL(i.reg1!!, value)
|
||||
statusbitsNZ(value, i.type!!)
|
||||
}
|
||||
IRDataType.FLOAT -> registers.setFloat(i.fpReg1!!, memory.getFloat(i.address!! + registers.getUB(i.reg1!!).toInt()))
|
||||
}
|
||||
nextPc()
|
||||
@@ -546,6 +577,12 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
registers.setUW(i.reg1!!, value)
|
||||
statusbitsNZ(value.toInt(), i.type!!)
|
||||
}
|
||||
IRDataType.LONG -> {
|
||||
val pointer = memory.getUW(i.address!!) + registers.getUB(i.reg2!!)
|
||||
val value = memory.getSL(pointer.toInt())
|
||||
registers.setSL(i.reg1!!, value)
|
||||
statusbitsNZ(value.toInt(), i.type!!)
|
||||
}
|
||||
IRDataType.FLOAT -> {
|
||||
val pointer = memory.getUW(i.address!!) + registers.getUB(i.reg1!!)
|
||||
registers.setFloat(i.fpReg1!!, memory.getFloat(pointer.toInt()))
|
||||
@@ -566,6 +603,11 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
registers.setUW(i.reg1!!, value)
|
||||
statusbitsNZ(value.toInt(), i.type!!)
|
||||
}
|
||||
IRDataType.LONG -> {
|
||||
val value = registers.getSL(i.reg2!!)
|
||||
registers.setSL(i.reg1!!, value)
|
||||
statusbitsNZ(value, i.type!!)
|
||||
}
|
||||
IRDataType.FLOAT -> registers.setFloat(i.fpReg1!!, registers.getFloat(i.fpReg2!!))
|
||||
}
|
||||
nextPc()
|
||||
@@ -575,6 +617,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
when(i.type!!) {
|
||||
IRDataType.BYTE -> memory.setUB(i.address!!, registers.getUB(i.reg1!!))
|
||||
IRDataType.WORD -> memory.setUW(i.address!!, registers.getUW(i.reg1!!))
|
||||
IRDataType.LONG -> memory.setSL(i.address!!, registers.getSL(i.reg1!!))
|
||||
IRDataType.FLOAT -> memory.setFloat(i.address!!, registers.getFloat(i.fpReg1!!))
|
||||
}
|
||||
nextPc()
|
||||
@@ -584,6 +627,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
when (i.type!!) {
|
||||
IRDataType.BYTE -> memory.setUB(registers.getUW(i.reg2!!).toInt(), registers.getUB(i.reg1!!))
|
||||
IRDataType.WORD -> memory.setUW(registers.getUW(i.reg2!!).toInt(), registers.getUW(i.reg1!!))
|
||||
IRDataType.LONG -> memory.setSL(registers.getUW(i.reg2!!).toInt(), registers.getSL(i.reg1!!))
|
||||
IRDataType.FLOAT -> memory.setFloat(registers.getUW(i.reg1!!).toInt(), registers.getFloat(i.fpReg1!!))
|
||||
}
|
||||
nextPc()
|
||||
@@ -595,6 +639,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
when (i.type!!) {
|
||||
IRDataType.BYTE -> memory.setUB(registers.getUW(i.reg2!!).toInt() + offset, registers.getUB(i.reg1!!))
|
||||
IRDataType.WORD -> memory.setUW(registers.getUW(i.reg2!!).toInt() + offset, registers.getUW(i.reg1!!))
|
||||
IRDataType.LONG -> memory.setSL(registers.getUW(i.reg2!!).toInt() + offset, registers.getSL(i.reg1!!))
|
||||
IRDataType.FLOAT -> memory.setFloat(registers.getUW(i.reg1!!).toInt() + offset, registers.getFloat(i.fpReg1!!))
|
||||
}
|
||||
nextPc()
|
||||
@@ -604,6 +649,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
when (i.type!!) {
|
||||
IRDataType.BYTE -> memory.setUB(i.address!! + registers.getUB(i.reg2!!).toInt(), registers.getUB(i.reg1!!))
|
||||
IRDataType.WORD -> memory.setUW(i.address!! + registers.getUB(i.reg2!!).toInt(), registers.getUW(i.reg1!!))
|
||||
IRDataType.LONG -> memory.setSL(i.address!! + registers.getUB(i.reg2!!).toInt(), registers.getSL(i.reg1!!))
|
||||
IRDataType.FLOAT -> memory.setFloat(i.address!! + registers.getUB(i.reg1!!).toInt(), registers.getFloat(i.fpReg1!!))
|
||||
}
|
||||
nextPc()
|
||||
@@ -619,6 +665,10 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
val pointer = memory.getUW(i.address!!) + registers.getUB(i.reg2!!)
|
||||
memory.setUW(pointer.toInt(), registers.getUW(i.reg1!!))
|
||||
}
|
||||
IRDataType.LONG -> {
|
||||
val pointer = memory.getUW(i.address!!) + registers.getUB(i.reg2!!)
|
||||
memory.setSL(pointer.toInt(), registers.getSL(i.reg1!!))
|
||||
}
|
||||
IRDataType.FLOAT -> {
|
||||
val pointer = memory.getUW(i.address!!) + registers.getUB(i.reg1!!)
|
||||
memory.setFloat(pointer.toInt(), registers.getFloat(i.fpReg1!!))
|
||||
@@ -631,6 +681,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
when(i.type!!) {
|
||||
IRDataType.BYTE -> memory.setUB(i.address!!, 0u)
|
||||
IRDataType.WORD -> memory.setUW(i.address!!, 0u)
|
||||
IRDataType.LONG -> memory.setSL(i.address!!, 0)
|
||||
IRDataType.FLOAT -> memory.setFloat(i.address!!, 0.0)
|
||||
}
|
||||
nextPc()
|
||||
@@ -640,6 +691,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
when (i.type!!) {
|
||||
IRDataType.BYTE -> memory.setUB(registers.getUW(i.reg1!!).toInt(), 0u)
|
||||
IRDataType.WORD -> memory.setUW(registers.getUW(i.reg1!!).toInt(), 0u)
|
||||
IRDataType.LONG -> memory.setSL(registers.getUW(i.reg1!!).toInt(), 0)
|
||||
IRDataType.FLOAT -> memory.setFloat(registers.getUW(i.reg1!!).toInt(), 0.0)
|
||||
}
|
||||
nextPc()
|
||||
@@ -649,6 +701,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
when (i.type!!) {
|
||||
IRDataType.BYTE -> memory.setUB(i.address!! + registers.getUB(i.reg1!!).toInt(), 0u)
|
||||
IRDataType.WORD -> memory.setUW(i.address!! + registers.getUB(i.reg1!!).toInt(), 0u)
|
||||
IRDataType.LONG -> memory.setSL(i.address!! + registers.getUB(i.reg1!!).toInt(), 0)
|
||||
IRDataType.FLOAT -> memory.setFloat(i.address!! + registers.getUB(i.reg1!!).toInt(), 0.0)
|
||||
}
|
||||
nextPc()
|
||||
@@ -675,6 +728,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
when(arg.reg.dt) {
|
||||
IRDataType.BYTE -> memory.setUB(arg.address!!, registers.getUB(arg.reg.registerNum))
|
||||
IRDataType.WORD -> memory.setUW(arg.address!!, registers.getUW(arg.reg.registerNum))
|
||||
IRDataType.LONG -> memory.setSL(arg.address!!, registers.getSL(arg.reg.registerNum))
|
||||
IRDataType.FLOAT -> memory.setFloat(arg.address!!, registers.getFloat(arg.reg.registerNum))
|
||||
}
|
||||
}
|
||||
@@ -719,6 +773,15 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
throw IllegalArgumentException("missing return value reg")
|
||||
}
|
||||
}
|
||||
IRDataType.LONG -> {
|
||||
if(returns.isNotEmpty())
|
||||
registers.setSL(returns.single().registerNum, i.immediate!!)
|
||||
else {
|
||||
val callInstr = context.returnChunk.instructions[context.returnIndex-1]
|
||||
if(callInstr.opcode!=Opcode.CALL)
|
||||
throw IllegalArgumentException("missing return value reg")
|
||||
}
|
||||
}
|
||||
IRDataType.FLOAT -> {
|
||||
if(returns.isNotEmpty())
|
||||
registers.setFloat(returns.single().registerNum, i.immediateFp!!)
|
||||
@@ -759,6 +822,15 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
throw IllegalArgumentException("missing return value reg")
|
||||
}
|
||||
}
|
||||
IRDataType.LONG -> {
|
||||
if(returns.isNotEmpty())
|
||||
registers.setSL(returns.single().registerNum, registers.getSL(i.reg1!!))
|
||||
else {
|
||||
val callInstr = context.returnChunk.instructions[context.returnIndex-1]
|
||||
if(callInstr.opcode!=Opcode.CALL)
|
||||
throw IllegalArgumentException("missing return value reg")
|
||||
}
|
||||
}
|
||||
IRDataType.FLOAT -> {
|
||||
if(returns.isNotEmpty())
|
||||
registers.setFloat(returns.single().registerNum, registers.getFloat(i.fpReg1!!))
|
||||
@@ -938,6 +1010,11 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
registers.setUW(i.reg1!!, value)
|
||||
statusbitsNZ(value.toInt(), i.type!!)
|
||||
}
|
||||
IRDataType.LONG -> {
|
||||
val value = registers.getSL(i.reg1!!)+1
|
||||
registers.setSL(i.reg1!!, value)
|
||||
statusbitsNZ(value, i.type!!)
|
||||
}
|
||||
IRDataType.FLOAT -> registers.setFloat(i.fpReg1!!, registers.getFloat(i.fpReg1!!)+1f)
|
||||
}
|
||||
nextPc()
|
||||
@@ -956,6 +1033,11 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
memory.setUW(address, value)
|
||||
statusbitsNZ(value.toInt(), i.type!!)
|
||||
}
|
||||
IRDataType.LONG -> {
|
||||
val value = memory.getSL(address)+1
|
||||
memory.setSL(address, value)
|
||||
statusbitsNZ(value, i.type!!)
|
||||
}
|
||||
IRDataType.FLOAT -> memory.setFloat(address, memory.getFloat(address)+1f)
|
||||
}
|
||||
nextPc()
|
||||
@@ -973,6 +1055,11 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
registers.setUW(i.reg1!!, value)
|
||||
statusbitsNZ(value.toInt(), i.type!!)
|
||||
}
|
||||
IRDataType.LONG -> {
|
||||
val value = registers.getSL(i.reg1!!)-1
|
||||
registers.setSL(i.reg1!!, value)
|
||||
statusbitsNZ(value, i.type!!)
|
||||
}
|
||||
IRDataType.FLOAT -> registers.setFloat(i.fpReg1!!, registers.getFloat(i.fpReg1!!)-1f)
|
||||
}
|
||||
nextPc()
|
||||
@@ -990,6 +1077,11 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
memory.setUW(i.address!!, value)
|
||||
statusbitsNZ(value.toInt(), i.type!!)
|
||||
}
|
||||
IRDataType.LONG -> {
|
||||
val value = memory.getSL(i.address!!)-1
|
||||
memory.setSL(i.address!!, value)
|
||||
statusbitsNZ(value, i.type!!)
|
||||
}
|
||||
IRDataType.FLOAT -> memory.setFloat(i.address!!, memory.getFloat(i.address!!)-1f)
|
||||
}
|
||||
nextPc()
|
||||
@@ -1007,6 +1099,11 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
registers.setUW(i.reg1!!, value.toUShort())
|
||||
statusbitsNZ(value, IRDataType.WORD)
|
||||
}
|
||||
IRDataType.LONG -> {
|
||||
val value = -registers.getSL(i.reg1!!)
|
||||
registers.setSL(i.reg1!!, value)
|
||||
statusbitsNZ(value, IRDataType.LONG)
|
||||
}
|
||||
IRDataType.FLOAT -> registers.setFloat(i.fpReg1!!, -registers.getFloat(i.fpReg1!!))
|
||||
}
|
||||
nextPc()
|
||||
@@ -1025,6 +1122,11 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
memory.setUW(address, value.toUShort())
|
||||
statusbitsNZ(value, IRDataType.WORD)
|
||||
}
|
||||
IRDataType.LONG -> {
|
||||
val value = -memory.getSL(address)
|
||||
memory.setSL(address, value)
|
||||
statusbitsNZ(value, IRDataType.LONG)
|
||||
}
|
||||
IRDataType.FLOAT -> memory.setFloat(address, -memory.getFloat(address))
|
||||
}
|
||||
nextPc()
|
||||
@@ -1034,6 +1136,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
when(i.type!!) {
|
||||
IRDataType.BYTE -> plusMinusMultAnyByte("+", i.reg1!!, i.reg2!!)
|
||||
IRDataType.WORD -> plusMinusMultAnyWord("+", i.reg1!!, i.reg2!!)
|
||||
IRDataType.LONG -> plusMinusMultAnyLong("+", i.reg1!!, i.reg2!!)
|
||||
IRDataType.FLOAT -> {
|
||||
val left = registers.getFloat(i.fpReg1!!)
|
||||
val right = registers.getFloat(i.fpReg2!!)
|
||||
@@ -1048,6 +1151,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
when(i.type!!) {
|
||||
IRDataType.BYTE -> plusMinusMultConstByte("+", i.reg1!!, i.immediate!!.toUByte())
|
||||
IRDataType.WORD -> plusMinusMultConstWord("+", i.reg1!!, i.immediate!!.toUShort())
|
||||
IRDataType.LONG -> plusMinusMultConstLong("+", i.reg1!!, i.immediate!!)
|
||||
IRDataType.FLOAT -> {
|
||||
val left = registers.getFloat(i.fpReg1!!)
|
||||
val result = arithFloat(left, "+", i.immediateFp!!)
|
||||
@@ -1062,6 +1166,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
when(i.type!!) {
|
||||
IRDataType.BYTE -> plusMinusMultAnyByteInplace("+", i.reg1!!, address)
|
||||
IRDataType.WORD -> plusMinusMultAnyWordInplace("+", i.reg1!!, address)
|
||||
IRDataType.LONG -> plusMinusMultAnyLongInplace("+", i.reg1!!, address)
|
||||
IRDataType.FLOAT -> {
|
||||
val left = memory.getFloat(address)
|
||||
val right = registers.getFloat(i.fpReg1!!)
|
||||
@@ -1076,6 +1181,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
when(i.type!!) {
|
||||
IRDataType.BYTE -> plusMinusMultAnyByte("-", i.reg1!!, i.reg2!!)
|
||||
IRDataType.WORD -> plusMinusMultAnyWord("-", i.reg1!!, i.reg2!!)
|
||||
IRDataType.LONG -> plusMinusMultAnyLong("-", i.reg1!!, i.reg2!!)
|
||||
IRDataType.FLOAT -> {
|
||||
val left = registers.getFloat(i.fpReg1!!)
|
||||
val right = registers.getFloat(i.fpReg2!!)
|
||||
@@ -1090,6 +1196,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
when(i.type!!) {
|
||||
IRDataType.BYTE -> plusMinusMultConstByte("-", i.reg1!!, i.immediate!!.toUByte())
|
||||
IRDataType.WORD -> plusMinusMultConstWord("-", i.reg1!!, i.immediate!!.toUShort())
|
||||
IRDataType.LONG -> plusMinusMultConstLong("-", i.reg1!!, i.immediate!!)
|
||||
IRDataType.FLOAT -> {
|
||||
val left = registers.getFloat(i.fpReg1!!)
|
||||
val result = arithFloat(left, "-", i.immediateFp!!)
|
||||
@@ -1104,6 +1211,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
when(i.type!!) {
|
||||
IRDataType.BYTE -> plusMinusMultAnyByteInplace("-", i.reg1!!, address)
|
||||
IRDataType.WORD -> plusMinusMultAnyWordInplace("-", i.reg1!!, address)
|
||||
IRDataType.LONG -> plusMinusMultAnyLongInplace("-", i.reg1!!, address)
|
||||
IRDataType.FLOAT -> {
|
||||
val left = memory.getFloat(address)
|
||||
val right = registers.getFloat(i.fpReg1!!)
|
||||
@@ -1118,6 +1226,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
when(i.type!!) {
|
||||
IRDataType.BYTE -> plusMinusMultAnyByte("*", i.reg1!!, i.reg2!!)
|
||||
IRDataType.WORD -> plusMinusMultAnyWord("*", i.reg1!!, i.reg2!!)
|
||||
IRDataType.LONG -> throw IllegalArgumentException("mulr unsigned long not supported")
|
||||
IRDataType.FLOAT -> {
|
||||
val left = registers.getFloat(i.fpReg1!!)
|
||||
val right = registers.getFloat(i.fpReg2!!)
|
||||
@@ -1132,6 +1241,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
when(i.type!!) {
|
||||
IRDataType.BYTE -> plusMinusMultConstByte("*", i.reg1!!, i.immediate!!.toUByte())
|
||||
IRDataType.WORD -> plusMinusMultConstWord("*", i.reg1!!, i.immediate!!.toUShort())
|
||||
IRDataType.LONG -> throw IllegalArgumentException("mul unsigned long not supported")
|
||||
IRDataType.FLOAT -> {
|
||||
val left = registers.getFloat(i.fpReg1!!)
|
||||
val result = arithFloat(left, "*", i.immediateFp!!)
|
||||
@@ -1146,6 +1256,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
when(i.type!!) {
|
||||
IRDataType.BYTE -> plusMinusMultAnyByteInplace("*", i.reg1!!, address)
|
||||
IRDataType.WORD -> plusMinusMultAnyWordInplace("*", i.reg1!!, address)
|
||||
IRDataType.LONG -> throw IllegalArgumentException("mulm unsigned long not supported")
|
||||
IRDataType.FLOAT -> {
|
||||
val left = memory.getFloat(address)
|
||||
val right = registers.getFloat(i.fpReg1!!)
|
||||
@@ -1160,6 +1271,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
when(i.type!!) {
|
||||
IRDataType.BYTE -> plusMinusMultAnyByteSigned("*", i.reg1!!, i.reg2!!)
|
||||
IRDataType.WORD -> plusMinusMultAnyWordSigned("*", i.reg1!!, i.reg2!!)
|
||||
IRDataType.LONG -> plusMinusMultAnyLongSigned("*", i.reg1!!, i.reg2!!)
|
||||
IRDataType.FLOAT -> {
|
||||
val left = registers.getFloat(i.fpReg1!!)
|
||||
val right = registers.getFloat(i.fpReg2!!)
|
||||
@@ -1174,6 +1286,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
when(i.type!!) {
|
||||
IRDataType.BYTE -> plusMinusMultConstByteSigned("*", i.reg1!!, i.immediate!!.toByte())
|
||||
IRDataType.WORD -> plusMinusMultConstWordSigned("*", i.reg1!!, i.immediate!!.toShort())
|
||||
IRDataType.LONG -> plusMinusMultConstLongSigned("*", i.reg1!!, i.immediate!!)
|
||||
IRDataType.FLOAT -> {
|
||||
val left = registers.getFloat(i.fpReg1!!)
|
||||
val result = arithFloat(left, "*", i.immediateFp!!)
|
||||
@@ -1188,6 +1301,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
when(i.type!!) {
|
||||
IRDataType.BYTE -> plusMinusMultAnyByteSignedInplace("*", i.reg1!!, address)
|
||||
IRDataType.WORD -> plusMinusMultAnyWordSignedInplace("*", i.reg1!!, address)
|
||||
IRDataType.LONG -> plusMinusMultAnyLongSignedInplace("*", i.reg1!!, address)
|
||||
IRDataType.FLOAT -> {
|
||||
val left = memory.getFloat(address)
|
||||
val right = registers.getFloat(i.fpReg1!!)
|
||||
@@ -1202,6 +1316,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
when(i.type!!) {
|
||||
IRDataType.BYTE -> divOrModByteUnsigned("/", i.reg1!!, i.reg2!!)
|
||||
IRDataType.WORD -> divOrModWordUnsigned("/", i.reg1!!, i.reg2!!)
|
||||
IRDataType.LONG -> throw IllegalArgumentException("divr unsigned long not supported")
|
||||
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||
}
|
||||
nextPc()
|
||||
@@ -1211,6 +1326,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
when(i.type!!) {
|
||||
IRDataType.BYTE -> divOrModConstByteUnsigned("/", i.reg1!!, i.immediate!!.toUByte())
|
||||
IRDataType.WORD -> divOrModConstWordUnsigned("/", i.reg1!!, i.immediate!!.toUShort())
|
||||
IRDataType.LONG -> throw IllegalArgumentException("div unsigned long not supported")
|
||||
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||
}
|
||||
nextPc()
|
||||
@@ -1221,6 +1337,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
when(i.type!!) {
|
||||
IRDataType.BYTE -> divModByteUnsignedInplace("/", i.reg1!!, address)
|
||||
IRDataType.WORD -> divModWordUnsignedInplace("/", i.reg1!!, address)
|
||||
IRDataType.LONG -> throw IllegalArgumentException("divm unsigned long not supported")
|
||||
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||
}
|
||||
nextPc()
|
||||
@@ -1230,6 +1347,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
when(i.type!!) {
|
||||
IRDataType.BYTE -> divModByteSigned("/", i.reg1!!, i.reg2!!)
|
||||
IRDataType.WORD -> divModWordSigned("/", i.reg1!!, i.reg2!!)
|
||||
IRDataType.LONG -> divModLongSigned("/", i.reg1!!, i.reg2!!)
|
||||
IRDataType.FLOAT -> {
|
||||
val left = registers.getFloat(i.fpReg1!!)
|
||||
val right = registers.getFloat(i.fpReg2!!)
|
||||
@@ -1244,6 +1362,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
when(i.type!!) {
|
||||
IRDataType.BYTE -> divModConstByteSigned("/", i.reg1!!, i.immediate!!.toByte())
|
||||
IRDataType.WORD -> divModConstWordSigned("/", i.reg1!!, i.immediate!!.toShort())
|
||||
IRDataType.LONG -> divModConstLongSigned("/", i.reg1!!, i.immediate!!)
|
||||
IRDataType.FLOAT -> {
|
||||
val left = registers.getFloat(i.fpReg1!!)
|
||||
val result = arithFloat(left, "/", i.immediateFp!!)
|
||||
@@ -1258,6 +1377,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
when(i.type!!) {
|
||||
IRDataType.BYTE -> divModByteSignedInplace("/", i.reg1!!, address)
|
||||
IRDataType.WORD -> divModWordSignedInplace("/", i.reg1!!, address)
|
||||
IRDataType.LONG -> divModLongSignedInplace("/", i.reg1!!, address)
|
||||
IRDataType.FLOAT -> {
|
||||
val left = memory.getFloat(address)
|
||||
val right = registers.getFloat(i.fpReg1!!)
|
||||
@@ -1272,6 +1392,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
when(i.type!!) {
|
||||
IRDataType.BYTE -> divOrModByteUnsigned("%", i.reg1!!, i.reg2!!)
|
||||
IRDataType.WORD -> divOrModWordUnsigned("%", i.reg1!!, i.reg2!!)
|
||||
IRDataType.LONG -> throw IllegalArgumentException("modr unsigned long not supported")
|
||||
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||
}
|
||||
nextPc()
|
||||
@@ -1281,6 +1402,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
when(i.type!!) {
|
||||
IRDataType.BYTE -> divOrModConstByteUnsigned("%", i.reg1!!, i.immediate!!.toUByte())
|
||||
IRDataType.WORD -> divOrModConstWordUnsigned("%", i.reg1!!, i.immediate!!.toUShort())
|
||||
IRDataType.LONG -> throw IllegalArgumentException("mod unsigned long not supported")
|
||||
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||
}
|
||||
nextPc()
|
||||
@@ -1290,6 +1412,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
when(i.type!!) {
|
||||
IRDataType.BYTE -> divAndModUByte(i.reg1!!, i.reg2!!) // division+remainder results on value stack
|
||||
IRDataType.WORD -> divAndModUWord(i.reg1!!, i.reg2!!) // division+remainder results on value stack
|
||||
IRDataType.LONG -> throw IllegalArgumentException("divmodr unsigned long not supported")
|
||||
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||
}
|
||||
nextPc()
|
||||
@@ -1299,6 +1422,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
when(i.type!!) {
|
||||
IRDataType.BYTE -> divAndModConstUByte(i.reg1!!, i.immediate!!.toUByte()) // division+remainder results on value stack
|
||||
IRDataType.WORD -> divAndModConstUWord(i.reg1!!, i.immediate!!.toUShort()) // division+remainder results on value stack
|
||||
IRDataType.LONG -> throw IllegalArgumentException("divmod unsigned long not supported")
|
||||
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||
}
|
||||
nextPc()
|
||||
@@ -1308,6 +1432,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
when(i.type!!) {
|
||||
IRDataType.BYTE -> registers.setSB(i.reg1!!, registers.getSB(i.reg2!!).toInt().sign.toByte())
|
||||
IRDataType.WORD -> registers.setSB(i.reg1!!, registers.getSW(i.reg2!!).toInt().sign.toByte())
|
||||
IRDataType.LONG -> registers.setSB(i.reg1!!, registers.getSL(i.reg2!!).sign.toByte())
|
||||
IRDataType.FLOAT -> registers.setSB(i.reg1!!, registers.getFloat(i.fpReg1!!).sign.toInt().toByte())
|
||||
}
|
||||
nextPc()
|
||||
@@ -1317,6 +1442,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
when(i.type!!) {
|
||||
IRDataType.BYTE -> registers.setUB(i.reg1!!, sqrt(registers.getUB(i.reg2!!).toDouble()).toInt().toUByte())
|
||||
IRDataType.WORD -> registers.setUB(i.reg1!!, sqrt(registers.getUW(i.reg2!!).toDouble()).toInt().toUByte())
|
||||
IRDataType.LONG -> TODO("long sqrt")
|
||||
IRDataType.FLOAT -> registers.setFloat(i.fpReg1!!, sqrt(registers.getFloat(i.fpReg2!!)))
|
||||
}
|
||||
nextPc()
|
||||
@@ -1325,13 +1451,17 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
private fun InsSQUARE(i: IRInstruction) {
|
||||
when(i.type!!) {
|
||||
IRDataType.BYTE -> {
|
||||
val value = registers.getUB(i.reg2!!).toDouble().toInt()
|
||||
val value = registers.getUB(i.reg2!!).toInt()
|
||||
registers.setUB(i.reg1!!, (value*value).toUByte())
|
||||
}
|
||||
IRDataType.WORD -> {
|
||||
val value = registers.getUW(i.reg2!!).toDouble().toInt()
|
||||
val value = registers.getUW(i.reg2!!).toInt()
|
||||
registers.setUW(i.reg1!!, (value*value).toUShort())
|
||||
}
|
||||
IRDataType.LONG -> {
|
||||
val value = registers.getSL(i.reg2!!)
|
||||
registers.setSL(i.reg1!!, value*value)
|
||||
}
|
||||
IRDataType.FLOAT -> {
|
||||
val value = registers.getFloat(i.fpReg2!!)
|
||||
registers.setFloat(i.fpReg1!!, value*value)
|
||||
@@ -1352,6 +1482,11 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
val reg2 = registers.getUW(i.reg2!!)
|
||||
reg1.toInt() - reg2.toInt()
|
||||
}
|
||||
IRDataType.LONG -> {
|
||||
val reg1 = registers.getSL(i.reg1!!)
|
||||
val reg2 = registers.getSL(i.reg2!!)
|
||||
reg1 - reg2
|
||||
}
|
||||
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||
}
|
||||
statusbitsComparison(comparison, i.type!!)
|
||||
@@ -1368,6 +1503,10 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
val reg1 = registers.getUW(i.reg1!!)
|
||||
reg1.toInt() - (i.immediate!! and 65535)
|
||||
}
|
||||
IRDataType.LONG -> {
|
||||
val reg1 = registers.getSL(i.reg1!!)
|
||||
reg1 - i.immediate!!
|
||||
}
|
||||
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||
}
|
||||
statusbitsComparison(comparison, i.type!!)
|
||||
@@ -1400,6 +1539,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
when(type) {
|
||||
IRDataType.BYTE -> statusNegative = (value and 0x80)==0x80
|
||||
IRDataType.WORD -> statusNegative = (value and 0x8000)==0x8000
|
||||
IRDataType.LONG -> statusNegative = value<0
|
||||
IRDataType.FLOAT -> { /* floats don't change the status bits */ }
|
||||
}
|
||||
}
|
||||
@@ -1418,6 +1558,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
when(type) {
|
||||
IRDataType.BYTE -> statusNegative = (comparison and 0x80)!=0
|
||||
IRDataType.WORD -> statusNegative = (comparison and 0x8000)!=0
|
||||
IRDataType.LONG -> statusNegative = comparison<0
|
||||
IRDataType.FLOAT -> { /* floats don't change the status bits */ }
|
||||
}
|
||||
// TODO determine statusOverflow in comparison
|
||||
@@ -1850,7 +1991,8 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
private fun InsEXT(i: IRInstruction) {
|
||||
when(i.type!!){
|
||||
IRDataType.BYTE -> registers.setUW(i.reg1!!, registers.getUB(i.reg2!!).toUShort())
|
||||
IRDataType.WORD -> throw IllegalArgumentException("ext.w not yet supported, requires 32 bits registers")
|
||||
IRDataType.WORD -> registers.setSL(i.reg1!!, registers.getUW(i.reg2!!).toInt())
|
||||
IRDataType.LONG -> throw IllegalArgumentException("ext.l makes no sense, 32 bits is already the widest you can get")
|
||||
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||
}
|
||||
nextPc()
|
||||
@@ -1859,7 +2001,8 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
private fun InsEXTS(i: IRInstruction) {
|
||||
when(i.type!!){
|
||||
IRDataType.BYTE -> registers.setSW(i.reg1!!, registers.getSB(i.reg2!!).toShort())
|
||||
IRDataType.WORD -> throw IllegalArgumentException("exts.w not yet supported, requires 32 bits registers")
|
||||
IRDataType.WORD -> registers.setSL(i.reg1!!, registers.getSW(i.reg2!!).toInt())
|
||||
IRDataType.LONG -> throw IllegalArgumentException("exts.l makes no sense, 32 bits is already the widest you can get")
|
||||
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||
}
|
||||
nextPc()
|
||||
@@ -1871,6 +2014,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
when(i.type!!) {
|
||||
IRDataType.BYTE -> registers.setUB(i.reg1!!, value.toUByte())
|
||||
IRDataType.WORD -> registers.setUW(i.reg1!!, value.toUShort())
|
||||
IRDataType.LONG -> registers.setSL(i.reg1!!, value)
|
||||
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||
}
|
||||
statusbitsNZ(value, i.type!!)
|
||||
@@ -1888,6 +2032,10 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
value = registers.getUW(i.reg1!!).toInt() and i.immediate!!
|
||||
registers.setUW(i.reg1!!, value.toUShort())
|
||||
}
|
||||
IRDataType.LONG -> {
|
||||
value = registers.getSL(i.reg1!!) and i.immediate!!
|
||||
registers.setSL(i.reg1!!, value)
|
||||
}
|
||||
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||
}
|
||||
statusbitsNZ(value, i.type!!)
|
||||
@@ -1910,6 +2058,12 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
value = left.toInt() and right.toInt()
|
||||
memory.setUW(address, value.toUShort())
|
||||
}
|
||||
IRDataType.LONG -> {
|
||||
val left = memory.getSL(address)
|
||||
val right = registers.getSL(i.reg1!!)
|
||||
value = left and right
|
||||
memory.setSL(address, value)
|
||||
}
|
||||
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||
}
|
||||
statusbitsNZ(value, i.type!!)
|
||||
@@ -1922,6 +2076,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
when(i.type!!) {
|
||||
IRDataType.BYTE -> registers.setUB(i.reg1!!, value.toUByte())
|
||||
IRDataType.WORD -> registers.setUW(i.reg1!!, value.toUShort())
|
||||
IRDataType.LONG -> registers.setSL(i.reg1!!, value)
|
||||
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||
}
|
||||
statusbitsNZ(value, i.type!!)
|
||||
@@ -1939,6 +2094,10 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
value = registers.getUW(i.reg1!!).toInt() or i.immediate!!
|
||||
registers.setUW(i.reg1!!, value.toUShort())
|
||||
}
|
||||
IRDataType.LONG -> {
|
||||
value = registers.getSL(i.reg1!!) or i.immediate!!
|
||||
registers.setSL(i.reg1!!, value)
|
||||
}
|
||||
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||
}
|
||||
statusbitsNZ(value, i.type!!)
|
||||
@@ -1961,6 +2120,12 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
value = left.toInt() or right.toInt()
|
||||
memory.setUW(address, value.toUShort())
|
||||
}
|
||||
IRDataType.LONG -> {
|
||||
val left = memory.getSL(address)
|
||||
val right = registers.getSL(i.reg1!!)
|
||||
value = left or right
|
||||
memory.setSL(address, value)
|
||||
}
|
||||
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||
}
|
||||
statusbitsNZ(value, i.type!!)
|
||||
@@ -1973,6 +2138,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
when(i.type!!) {
|
||||
IRDataType.BYTE -> registers.setUB(i.reg1!!, value.toUByte())
|
||||
IRDataType.WORD -> registers.setUW(i.reg1!!, value.toUShort())
|
||||
IRDataType.LONG -> registers.setSL(i.reg1!!, value)
|
||||
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||
}
|
||||
statusbitsNZ(value, i.type!!)
|
||||
@@ -1990,6 +2156,10 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
value = registers.getUW(i.reg1!!).toInt() xor i.immediate!!
|
||||
registers.setUW(i.reg1!!, value.toUShort())
|
||||
}
|
||||
IRDataType.LONG -> {
|
||||
value = registers.getSL(i.reg1!!) xor i.immediate!!
|
||||
registers.setSL(i.reg1!!, value)
|
||||
}
|
||||
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||
}
|
||||
statusbitsNZ(value, i.type!!)
|
||||
@@ -2012,6 +2182,12 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
value = left.toInt() xor right.toInt()
|
||||
memory.setUW(address, value.toUShort())
|
||||
}
|
||||
IRDataType.LONG -> {
|
||||
val left = memory.getSL(address)
|
||||
val right = registers.getSL(i.reg1!!)
|
||||
value = left xor right
|
||||
memory.setSL(address, value)
|
||||
}
|
||||
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||
}
|
||||
statusbitsNZ(value, i.type!!)
|
||||
@@ -2022,6 +2198,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
when(i.type!!) {
|
||||
IRDataType.BYTE -> registers.setUB(i.reg1!!, registers.getUB(i.reg1!!).inv())
|
||||
IRDataType.WORD -> registers.setUW(i.reg1!!, registers.getUW(i.reg1!!).inv())
|
||||
IRDataType.LONG -> registers.setSL(i.reg1!!, registers.getSL(i.reg1!!).inv())
|
||||
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||
}
|
||||
nextPc()
|
||||
@@ -2032,6 +2209,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
when(i.type!!) {
|
||||
IRDataType.BYTE -> memory.setUB(address, memory.getUB(address).inv())
|
||||
IRDataType.WORD -> memory.setUW(address, memory.getUW(address).inv())
|
||||
IRDataType.LONG -> memory.setSL(address, memory.getSL(address).inv())
|
||||
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||
}
|
||||
nextPc()
|
||||
@@ -2042,6 +2220,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
when(i.type!!) {
|
||||
IRDataType.BYTE -> registers.setSB(i.reg1!!, (left shr right).toByte())
|
||||
IRDataType.WORD -> registers.setSW(i.reg1!!, (left shr right).toShort())
|
||||
IRDataType.LONG -> registers.setSL(i.reg1!!, left shr right)
|
||||
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||
}
|
||||
nextPc()
|
||||
@@ -2059,6 +2238,10 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
val memvalue = memory.getSW(address).toInt()
|
||||
memory.setSW(address, (memvalue shr operand).toShort())
|
||||
}
|
||||
IRDataType.LONG -> {
|
||||
val memvalue = memory.getSL(address)
|
||||
memory.setSL(address, memvalue shr operand)
|
||||
}
|
||||
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||
}
|
||||
nextPc()
|
||||
@@ -2076,6 +2259,11 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
statusCarry = (value and 1)!=0
|
||||
registers.setSW(i.reg1!!, (value shr 1).toShort())
|
||||
}
|
||||
IRDataType.LONG -> {
|
||||
val value = registers.getSL(i.reg1!!)
|
||||
statusCarry = (value and 1)!=0
|
||||
registers.setSL(i.reg1!!, value shr 1)
|
||||
}
|
||||
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||
}
|
||||
nextPc()
|
||||
@@ -2094,6 +2282,11 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
statusCarry = (value and 1)!=0
|
||||
memory.setSW(address, (value shr 1).toShort())
|
||||
}
|
||||
IRDataType.LONG -> {
|
||||
val value = memory.getSL(address)
|
||||
statusCarry = (value and 1)!=0
|
||||
memory.setSL(address, value shr 1)
|
||||
}
|
||||
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||
}
|
||||
nextPc()
|
||||
@@ -2104,6 +2297,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
when(i.type!!) {
|
||||
IRDataType.BYTE -> registers.setUB(i.reg1!!, (left shr right.toInt()).toUByte())
|
||||
IRDataType.WORD -> registers.setUW(i.reg1!!, (left shr right.toInt()).toUShort())
|
||||
IRDataType.LONG -> registers.setSL(i.reg1!!, (left shr right.toInt()).toInt())
|
||||
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||
}
|
||||
nextPc()
|
||||
@@ -2121,6 +2315,10 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
val memvalue = memory.getUW(address).toInt()
|
||||
memory.setUW(address, (memvalue shr operand).toUShort())
|
||||
}
|
||||
IRDataType.LONG -> {
|
||||
val memvalue = memory.getSL(address)
|
||||
memory.setSL(address, memvalue shr operand)
|
||||
}
|
||||
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||
}
|
||||
nextPc()
|
||||
@@ -2138,6 +2336,11 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
statusCarry = (value and 1)!=0
|
||||
registers.setUW(i.reg1!!, (value shr 1).toUShort())
|
||||
}
|
||||
IRDataType.LONG -> {
|
||||
val value = registers.getSL(i.reg1!!)
|
||||
statusCarry = (value and 1)!=0
|
||||
registers.setSL(i.reg1!!, value shr 1)
|
||||
}
|
||||
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||
}
|
||||
nextPc()
|
||||
@@ -2156,6 +2359,11 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
statusCarry = (value and 1)!=0
|
||||
memory.setUW(address, (value shr 1).toUShort())
|
||||
}
|
||||
IRDataType.LONG -> {
|
||||
val value = memory.getSL(address)
|
||||
statusCarry = (value and 1)!=0
|
||||
memory.setSL(address, value shr 1)
|
||||
}
|
||||
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||
}
|
||||
nextPc()
|
||||
@@ -2170,6 +2378,9 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
IRDataType.WORD -> {
|
||||
registers.setUW(i.reg1!!, (left shl right.toInt()).toUShort())
|
||||
}
|
||||
IRDataType.LONG -> {
|
||||
registers.setSL(i.reg1!!, (left shl right.toInt()).toInt())
|
||||
}
|
||||
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||
}
|
||||
nextPc()
|
||||
@@ -2187,6 +2398,10 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
val memvalue = memory.getUW(address).toInt()
|
||||
memory.setUW(address, (memvalue shl operand).toUShort())
|
||||
}
|
||||
IRDataType.LONG -> {
|
||||
val memvalue = memory.getSL(address)
|
||||
memory.setSL(address, memvalue shl operand)
|
||||
}
|
||||
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||
}
|
||||
nextPc()
|
||||
@@ -2204,6 +2419,11 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
statusCarry = (value and 0x8000)!=0
|
||||
registers.setUW(i.reg1!!, (value shl 1).toUShort())
|
||||
}
|
||||
IRDataType.LONG -> {
|
||||
val value = registers.getSL(i.reg1!!)
|
||||
statusCarry = value<0
|
||||
registers.setSL(i.reg1!!, value shl 1)
|
||||
}
|
||||
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||
}
|
||||
nextPc()
|
||||
@@ -2222,6 +2442,11 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
statusCarry = (value and 0x8000)!=0
|
||||
memory.setUW(address, (value shl 1).toUShort())
|
||||
}
|
||||
IRDataType.LONG -> {
|
||||
val value = memory.getSL(address)
|
||||
statusCarry = value<0
|
||||
memory.setSL(address, value shl 1)
|
||||
}
|
||||
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||
}
|
||||
nextPc()
|
||||
@@ -2250,6 +2475,16 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
orig.rotateRight(1)
|
||||
registers.setUW(i.reg1!!, rotated)
|
||||
}
|
||||
IRDataType.LONG -> {
|
||||
val orig = registers.getSL(i.reg1!!).toUInt()
|
||||
newStatusCarry = (orig and 1u) != 0u
|
||||
val rotated: UInt = if (useCarry) {
|
||||
val carry = if (statusCarry) 0x80000000u else 0u
|
||||
(orig.rotateRight(1) or carry)
|
||||
} else
|
||||
orig.rotateRight(1)
|
||||
registers.setSL(i.reg1!!, rotated.toInt())
|
||||
}
|
||||
IRDataType.FLOAT -> {
|
||||
throw IllegalArgumentException("can't ROR a float")
|
||||
}
|
||||
@@ -2282,6 +2517,16 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
orig.rotateRight(1)
|
||||
memory.setUW(address, rotated)
|
||||
}
|
||||
IRDataType.LONG -> {
|
||||
val orig = memory.getSL(address).toUInt()
|
||||
newStatusCarry = (orig and 1u) != 0u
|
||||
val rotated: UInt = (if (useCarry) {
|
||||
val carry = if (statusCarry) 0x80000000u else 0u
|
||||
(orig.rotateRight(1) or carry)
|
||||
} else
|
||||
orig.rotateRight(1))
|
||||
memory.setSL(address, rotated.toInt())
|
||||
}
|
||||
IRDataType.FLOAT -> {
|
||||
throw IllegalArgumentException("can't ROR a float")
|
||||
}
|
||||
@@ -2313,6 +2558,16 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
orig.rotateLeft(1)
|
||||
registers.setUW(i.reg1!!, rotated)
|
||||
}
|
||||
IRDataType.LONG -> {
|
||||
val orig = registers.getSL(i.reg1!!).toUInt()
|
||||
newStatusCarry = (orig and 0x80000000u) != 0u
|
||||
val rotated: UInt = (if (useCarry) {
|
||||
val carry = if (statusCarry) 1u else 0u
|
||||
(orig.toUInt().rotateLeft(1) or carry)
|
||||
} else
|
||||
orig.rotateLeft(1))
|
||||
registers.setSL(i.reg1!!, rotated.toInt())
|
||||
}
|
||||
IRDataType.FLOAT -> {
|
||||
throw IllegalArgumentException("can't ROL a float")
|
||||
}
|
||||
@@ -2345,6 +2600,16 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
orig.rotateLeft(1)
|
||||
memory.setUW(address, rotated)
|
||||
}
|
||||
IRDataType.LONG -> {
|
||||
val orig = memory.getSL(address).toUInt()
|
||||
newStatusCarry = (orig and 0x80000000u) != 0u
|
||||
val rotated: UInt = (if (useCarry) {
|
||||
val carry = if (statusCarry) 1u else 0u
|
||||
(orig.rotateLeft(1) or carry)
|
||||
} else
|
||||
orig.rotateLeft(1))
|
||||
memory.setSL(address, rotated.toInt())
|
||||
}
|
||||
IRDataType.FLOAT -> {
|
||||
throw IllegalArgumentException("can't ROL a float")
|
||||
}
|
||||
@@ -2360,7 +2625,11 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
registers.setUB(i.reg1!!, value.toUByte())
|
||||
statusbitsNZ(value.toInt(), i.type!!)
|
||||
}
|
||||
IRDataType.WORD -> throw IllegalArgumentException("lsig.w not yet supported, requires 32-bits registers")
|
||||
IRDataType.WORD -> {
|
||||
val value = registers.getSL(i.reg2!!)
|
||||
registers.setUW(i.reg1!!, value.toUShort())
|
||||
}
|
||||
IRDataType.LONG -> throw IllegalArgumentException("lsig.l makes no sense, 32 bits is already the widest")
|
||||
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||
}
|
||||
nextPc()
|
||||
@@ -2374,7 +2643,12 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
statusbitsNZ(newValue, i.type!!)
|
||||
registers.setUB(i.reg1!!, newValue.toUByte())
|
||||
}
|
||||
IRDataType.WORD -> throw IllegalArgumentException("msig.w not yet supported, requires 32-bits registers")
|
||||
IRDataType.WORD -> {
|
||||
val value = registers.getSL(i.reg2!!)
|
||||
val newValue = value ushr 16
|
||||
registers.setUW(i.reg1!!, newValue.toUShort())
|
||||
}
|
||||
IRDataType.LONG -> throw IllegalArgumentException("lsig.l makes no sense, 32 bits is already the widest")
|
||||
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||
}
|
||||
nextPc()
|
||||
@@ -2389,7 +2663,12 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
registers.setUW(i.reg1!!, value.toUShort())
|
||||
statusbitsNZ(value.toInt(), i.type!!)
|
||||
}
|
||||
IRDataType.WORD -> throw IllegalArgumentException("concat.w not yet supported, requires 32-bits registers")
|
||||
IRDataType.WORD -> {
|
||||
val msw = registers.getUW(i.reg2!!)
|
||||
val lsw = registers.getUW(i.reg3!!)
|
||||
registers.setSL(i.reg1!!, ((msw.toInt() shl 16) or lsw.toInt()))
|
||||
}
|
||||
IRDataType.LONG -> throw IllegalArgumentException("concat.l makes no sense, 32 bits is already the widest")
|
||||
IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
|
||||
}
|
||||
nextPc()
|
||||
@@ -2586,6 +2865,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
return when(i.type) {
|
||||
IRDataType.BYTE -> Pair(registers.getSB(i.reg1!!).toInt(), registers.getSB(i.reg2!!).toInt())
|
||||
IRDataType.WORD -> Pair(registers.getSW(i.reg1!!).toInt(), registers.getSW(i.reg2!!).toInt())
|
||||
IRDataType.LONG -> Pair(registers.getSL(i.reg1!!), registers.getSL(i.reg2!!))
|
||||
IRDataType.FLOAT -> {
|
||||
throw IllegalArgumentException("can't use float here")
|
||||
}
|
||||
@@ -2597,6 +2877,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
return when(i.type) {
|
||||
IRDataType.BYTE -> Pair(registers.getSB(i.reg1!!).toInt(), i.immediate!!)
|
||||
IRDataType.WORD -> Pair(registers.getSW(i.reg1!!).toInt(), i.immediate!!)
|
||||
IRDataType.LONG -> Pair(registers.getSL(i.reg1!!), i.immediate!!)
|
||||
IRDataType.FLOAT -> {
|
||||
throw IllegalArgumentException("can't use float here")
|
||||
}
|
||||
@@ -2608,6 +2889,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
return when(i.type) {
|
||||
IRDataType.BYTE -> Pair(registers.getUB(i.reg1!!).toUInt(), registers.getUB(i.reg2!!).toUInt())
|
||||
IRDataType.WORD -> Pair(registers.getUW(i.reg1!!).toUInt(), registers.getUW(i.reg2!!).toUInt())
|
||||
IRDataType.LONG -> Pair(registers.getSL(i.reg1!!).toUInt(), registers.getSL(i.reg2!!).toUInt())
|
||||
IRDataType.FLOAT -> {
|
||||
throw IllegalArgumentException("can't use float here")
|
||||
}
|
||||
@@ -2619,6 +2901,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
return when(i.type) {
|
||||
IRDataType.BYTE -> Pair(registers.getUB(i.reg1!!).toUInt(), i.immediate!!.toUInt())
|
||||
IRDataType.WORD -> Pair(registers.getUW(i.reg1!!).toUInt(), i.immediate!!.toUInt())
|
||||
IRDataType.LONG -> Pair(registers.getSL(i.reg1!!).toUInt(), i.immediate!!.toUInt())
|
||||
IRDataType.FLOAT -> {
|
||||
throw IllegalArgumentException("can't use float here")
|
||||
}
|
||||
@@ -2630,6 +2913,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
return when(i.type) {
|
||||
IRDataType.BYTE -> Pair(registers.getUB(i.reg1!!).toUInt(), registers.getUB(i.reg2!!).toUInt())
|
||||
IRDataType.WORD -> Pair(registers.getUW(i.reg1!!).toUInt(), registers.getUW(i.reg2!!).toUInt())
|
||||
IRDataType.LONG -> Pair(registers.getSL(i.reg1!!).toUInt(), registers.getSL(i.reg2!!).toUInt())
|
||||
IRDataType.FLOAT -> {
|
||||
throw IllegalArgumentException("can't use float here")
|
||||
}
|
||||
@@ -2641,6 +2925,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
return when(i.type) {
|
||||
IRDataType.BYTE -> Pair(registers.getSB(i.reg1!!).toInt(), registers.getSB(i.reg2!!).toInt())
|
||||
IRDataType.WORD -> Pair(registers.getSW(i.reg1!!).toInt(), registers.getSW(i.reg2!!).toInt())
|
||||
IRDataType.LONG -> Pair(registers.getSL(i.reg1!!), registers.getSL(i.reg2!!))
|
||||
IRDataType.FLOAT -> {
|
||||
throw IllegalArgumentException("can't use float here")
|
||||
}
|
||||
@@ -2648,6 +2933,43 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun plusMinusMultAnyLong(operator: String, reg1: Int, reg2: Int) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
private fun plusMinusMultConstLong(operator: String, reg1: Int, value: Int) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
private fun plusMinusMultAnyLongInplace(operator: String, reg1: Int, address: Int) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
private fun plusMinusMultAnyLongSigned(operator: String, reg1: Int, reg2: Int) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
private fun plusMinusMultConstLongSigned(operator: String, reg1: Int, value: Int) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
private fun plusMinusMultAnyLongSignedInplace(operator: String, reg1: Int, address: Int) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
private fun divModLongSigned(operator: String, reg1: Int, reg2: Int) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
private fun divModConstLongSigned(operator: String, reg1: Int, immediate: Int) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
private fun divModLongSignedInplace(operator: String, reg1: Int, address: Int) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
|
||||
private var window: GraphicsWindow? = null
|
||||
|
||||
fun gfx_enable(mode: UByte) {
|
||||
@@ -2754,6 +3076,14 @@ internal fun ArrayDeque<UByte>.pushw(value: UShort) {
|
||||
add((value.toInt() ushr 8).toUByte())
|
||||
}
|
||||
|
||||
internal fun ArrayDeque<UByte>.pushl(value: Int) {
|
||||
val uint = value.toUInt()
|
||||
add((uint and 255u).toUByte())
|
||||
add((uint shr 8 and 255u).toUByte())
|
||||
add((uint shr 16 and 255u).toUByte())
|
||||
add((uint shr 24 and 255u).toUByte())
|
||||
}
|
||||
|
||||
internal fun ArrayDeque<UByte>.pushf(value: Double) {
|
||||
// push float; lsb first, msb last
|
||||
var bits = value.toBits()
|
||||
@@ -2780,6 +3110,14 @@ internal fun ArrayDeque<UByte>.popw(): UShort {
|
||||
return ((msb.toInt() shl 8) + lsb.toInt()).toUShort()
|
||||
}
|
||||
|
||||
internal fun ArrayDeque<UByte>.popl(): Int {
|
||||
val b0 = removeLast().toUInt()
|
||||
val b1 = removeLast().toUInt()
|
||||
val b2 = removeLast().toUInt()
|
||||
val b3 = removeLast().toUInt()
|
||||
return (b0 shl 24 or b1 shl 16 or b2 shl 8 or b3).toInt()
|
||||
}
|
||||
|
||||
internal fun ArrayDeque<UByte>.popf(): Double {
|
||||
// pop float; lsb is on bottom, msb on top
|
||||
val b0 = removeLast().toLong()
|
||||
|
||||
@@ -236,6 +236,7 @@ class VmProgramLoader {
|
||||
dt.isSignedByte -> memory.setSB(addr, 0)
|
||||
dt.isUnsignedWord || dt.isPointer -> memory.setUW(addr, 0u)
|
||||
dt.isSignedWord -> memory.setSW(addr, 0)
|
||||
dt.isLong -> memory.setSL(addr, 0)
|
||||
dt.isFloat -> memory.setFloat(addr, 0.0)
|
||||
else -> throw IRParseException("invalid dt")
|
||||
}
|
||||
@@ -248,6 +249,7 @@ class VmProgramLoader {
|
||||
variable.dt.isSignedByte -> memory.setSB(addr, it.toInt().toByte())
|
||||
variable.dt.isUnsignedWord -> memory.setUW(addr, it.toInt().toUShort())
|
||||
variable.dt.isSignedWord -> memory.setSW(addr, it.toInt().toShort())
|
||||
variable.dt.isLong -> memory.setSL(addr, it.toInt())
|
||||
variable.dt.isFloat -> memory.setFloat(addr, it)
|
||||
else -> throw IRParseException("invalid dt")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user