start with introducing LONG datatype (32 bits signed integer)

This commit is contained in:
Irmen de Jong
2025-09-17 01:04:26 +02:00
parent 44f70da113
commit a2b9d78cf3
15 changed files with 591 additions and 149 deletions

View File

@@ -7,6 +7,7 @@ internal class RegisterPool {
// everything from 99000 onwards is reserved for special purposes: // everything from 99000 onwards is reserved for special purposes:
// 99000 - 99099 : WORD registers for syscall arguments and response value(s) // 99000 - 99099 : WORD registers for syscall arguments and response value(s)
// 99100 - 99199 : BYTE 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 var nextRegister: Int=1
private val registerTypes: MutableMap<Int, IRDataType> = mutableMapOf() private val registerTypes: MutableMap<Int, IRDataType> = mutableMapOf()
@@ -18,6 +19,8 @@ internal class RegisterPool {
registerTypes[i] = IRDataType.WORD registerTypes[i] = IRDataType.WORD
for(i in 99100..99199) for(i in 99100..99199)
registerTypes[i] = IRDataType.BYTE registerTypes[i] = IRDataType.BYTE
for(i in 99200..99299)
registerTypes[i] = IRDataType.LONG
} }
fun next(type: IRDataType): Int { fun next(type: IRDataType): Int {

View File

@@ -35,7 +35,7 @@ class ConstantFoldingOptimizer(private val program: Program, private val errors:
override fun after(numLiteral: NumericLiteral, parent: Node): Iterable<IAstModification> { 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 // see if LONG values may be reduced to something smaller
val smaller = NumericLiteral.optimalInteger(numLiteral.number.toInt(), numLiteral.position) val smaller = NumericLiteral.optimalInteger(numLiteral.number.toInt(), numLiteral.position)
if(smaller.type!=BaseDataType.LONG) { if(smaller.type!=BaseDataType.LONG) {

View File

@@ -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 ----- ; ---- string conversion to numbers -----

View File

@@ -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 { asmsub input_chars (^^ubyte buffer @ AY) clobbers(A) -> ubyte @ Y {
; ---- Input a string (max. 80 chars) from the keyboard, in PETSCII encoding. ; ---- 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) ; Returns length in Y. (string is terminated with a 0 byte as well)

View File

@@ -141,7 +141,7 @@ sub str_uw (uword value) -> str {
} }
sub str_w (word 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 ^^ubyte out_ptr = &string_out
if value<0 { if value<0 {
@(out_ptr) = '-' @(out_ptr) = '-'
@@ -152,6 +152,16 @@ sub str_w (word value) -> str {
return string_out 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) { sub internal_str_uw(uword value, str out_ptr) {
uword value2 = value/10 uword value2 = value/10
ubyte digits = value-value2*10 as ubyte ubyte digits = value-value2*10 as ubyte

View File

@@ -151,6 +151,14 @@ sub print_w (word value) {
print(conv.str_w(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 { 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) ; ---- 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! ; It assumes the keyboard is selected as I/O channel!

View File

@@ -82,7 +82,6 @@ internal class AstChecker(private val program: Program,
} }
} }
checkLongType(identifier)
val stmt = identifier.targetStatement(program.builtinFunctions) val stmt = identifier.targetStatement(program.builtinFunctions)
if(stmt==null) { if(stmt==null) {
if(identifier.parent is ArrayIndexedExpression) { if(identifier.parent is ArrayIndexedExpression) {
@@ -363,10 +362,6 @@ internal class AstChecker(private val program: Program,
super.visit(label) super.visit(label)
} }
override fun visit(numLiteral: NumericLiteral) {
checkLongType(numLiteral)
}
private fun hasReturnOrExternalJumpOrRts(scope: IStatementContainer): Boolean { private fun hasReturnOrExternalJumpOrRts(scope: IStatementContainer): Boolean {
class Searcher: IAstVisitor class Searcher: IAstVisitor
{ {
@@ -813,7 +808,6 @@ internal class AstChecker(private val program: Program,
} }
override fun visit(addressOf: AddressOf) { override fun visit(addressOf: AddressOf) {
checkLongType(addressOf)
val variable=addressOf.identifier?.targetVarDecl() val variable=addressOf.identifier?.targetVarDecl()
if (variable!=null) { if (variable!=null) {
if (variable.type == VarDeclType.CONST && addressOf.arrayIndex == 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) if(decl.names.size>1)
throw InternalCompilerException("vardecls with multiple names should have been converted into individual vardecls") 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.type==VarDeclType.MEMORY) {
if (decl.datatype.isString) if (decl.datatype.isString)
errors.err("strings cannot be memory-mapped", decl.position) 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() val dt = expr.expression.inferType(program).getOrUndef()
if(!dt.isUndefined) { if(!dt.isUndefined) {
@@ -1474,8 +1465,6 @@ internal class AstChecker(private val program: Program,
return return
} }
checkLongType(expr)
val leftIDt = expr.left.inferType(program) val leftIDt = expr.left.inferType(program)
val rightIDt = expr.right.inferType(program) val rightIDt = expr.right.inferType(program)
if(!leftIDt.isKnown || !rightIDt.isKnown) { if(!leftIDt.isKnown || !rightIDt.isKnown) {
@@ -1614,7 +1603,6 @@ internal class AstChecker(private val program: Program,
} }
override fun visit(typecast: TypecastExpression) { override fun visit(typecast: TypecastExpression) {
checkLongType(typecast)
if(typecast.type.isPassByRef) if(typecast.type.isPassByRef)
errors.err("cannot type cast to string or array type", typecast.position) 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) { override fun visit(functionCallExpr: FunctionCallExpression) {
checkLongType(functionCallExpr)
// this function call is (part of) an expression, which should be in a statement somewhere. // this function call is (part of) an expression, which should be in a statement somewhere.
val stmtOfExpression = findParentNode<Statement>(functionCallExpr) val stmtOfExpression = findParentNode<Statement>(functionCallExpr)
?: throw FatalAstException("cannot determine statement scope of function call expression at ${functionCallExpr.position}") ?: 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{ args.forEach{
checkLongType(it)
if(it.inferType(program).isStructInstance) if(it.inferType(program).isStructInstance)
errors.err("structs can only be passed via a pointer", it.position) 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) { override fun visit(arrayIndexedExpression: ArrayIndexedExpression) {
checkLongType(arrayIndexedExpression)
val target = arrayIndexedExpression.plainarrayvar?.targetStatement(program.builtinFunctions) val target = arrayIndexedExpression.plainarrayvar?.targetStatement(program.builtinFunctions)
if(target is VarDecl) { if(target is VarDecl) {
if (!target.datatype.isIterable && !target.datatype.isUnsignedWord && !target.datatype.isPointer) if (!target.datatype.isIterable && !target.datatype.isUnsignedWord && !target.datatype.isPointer)
@@ -2164,17 +2149,6 @@ internal class AstChecker(private val program: Program,
super.visit(deref) 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 { private fun checkValueTypeAndRangeString(targetDt: DataType, value: StringLiteral) : Boolean {
return if (targetDt.isString) { return if (targetDt.isString) {
when { when {

View File

@@ -1,11 +1,39 @@
%import textio
main { main {
sub start() { long bignum = 12345678
func() long bignum2 = -999999
struct Node {
ubyte id
str name
long array
bool flag
long counter
} }
sub func() { sub start() {
if cx16.r0<10 or cx16.r0>319 { ^^Node test = []
cx16.r1++
} 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 --
} }
} }

View File

@@ -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. 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) 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. 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. )
inc reg1 - reg1 = reg1+1 inc reg1 - reg1 = reg1+1
incm address - memory at address += 1 incm address - memory at address += 1
dec reg1 - reg1 = reg1-1 dec reg1 - reg1 = reg1-1
@@ -247,9 +247,9 @@ 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 (.w not yet implemented; requires 32 bits 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 (.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
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) 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
pushst - push status register bits to stack pushst - push status register bits to stack
@@ -559,8 +559,8 @@ val OpcodesThatSetStatusbits = OpcodesThatSetStatusbitsButNotCarry + OpcodesThat
enum class IRDataType { enum class IRDataType {
BYTE, BYTE,
WORD, WORD,
FLOAT FLOAT,
// TODO add INT (32-bit)? INT24 (24-bit)? LONG // 32 bits integer
} }
enum class OperandDirection { 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) result[IRDataType.BYTE] = InstructionFormat(IRDataType.BYTE, reg1, reg2, reg3, fpreg1, fpreg2, address, immediate, funcCall, sysCall)
if('W' in typespec) if('W' in typespec)
result[IRDataType.WORD] = InstructionFormat(IRDataType.WORD, reg1, reg2, reg3, fpreg1, fpreg2, address, immediate, funcCall, sysCall) 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) if('F' in typespec)
result[IRDataType.FLOAT] = InstructionFormat(IRDataType.FLOAT, reg1, reg2, reg3, fpreg1, fpreg2, address, immediate, funcCall, sysCall) 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( val instructionFormats = mutableMapOf(
Opcode.NOP to InstructionFormat.from("N"), Opcode.NOP to InstructionFormat.from("N"),
Opcode.LOAD to InstructionFormat.from("BW,>r1,<i | F,>fr1,<i"), Opcode.LOAD to InstructionFormat.from("BWL,>r1,<i | F,>fr1,<i"),
Opcode.LOADM to InstructionFormat.from("BW,>r1,<a | F,>fr1,<a"), Opcode.LOADM to InstructionFormat.from("BWL,>r1,<a | F,>fr1,<a"),
Opcode.LOADI to InstructionFormat.from("BW,>r1,<r2 | F,>fr1,<r1"), Opcode.LOADI to InstructionFormat.from("BWL,>r1,<r2 | F,>fr1,<r1"),
Opcode.LOADX to InstructionFormat.from("BW,>r1,<r2,<a | F,>fr1,<r1,<a"), Opcode.LOADX to InstructionFormat.from("BWL,>r1,<r2,<a | F,>fr1,<r1,<a"),
Opcode.LOADIX to InstructionFormat.from("BW,>r1,<r2,<a | F,>fr1,<r1,<a"), Opcode.LOADIX to InstructionFormat.from("BWL,>r1,<r2,<a | F,>fr1,<r1,<a"),
Opcode.LOADR to InstructionFormat.from("BW,>r1,<r2 | F,>fr1,<fr2"), 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.LOADHA to InstructionFormat.from("B,>r1"), Opcode.LOADHA to InstructionFormat.from("B,>r1"),
Opcode.LOADHX 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.LOADHAX to InstructionFormat.from("W,>r1"),
Opcode.LOADHAY to InstructionFormat.from("W,>r1"), Opcode.LOADHAY to InstructionFormat.from("W,>r1"),
Opcode.LOADHXY 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.LOADHFACZERO to InstructionFormat.from("F,>fr1"),
Opcode.LOADHFACONE to InstructionFormat.from("F,>fr1"), Opcode.LOADHFACONE to InstructionFormat.from("F,>fr1"),
Opcode.STOREM to InstructionFormat.from("BW,<r1,>a | F,<fr1,>a"), Opcode.STOREM to InstructionFormat.from("BWL,<r1,>a | F,<fr1,>a"),
Opcode.STOREI to InstructionFormat.from("BW,<r1,<r2 | F,<fr1,<r1"), Opcode.STOREI to InstructionFormat.from("BWL,<r1,<r2 | F,<fr1,<r1"),
Opcode.STOREX to InstructionFormat.from("BW,<r1,<r2,>a | F,<fr1,<r1,>a"), Opcode.STOREX to InstructionFormat.from("BWL,<r1,<r2,>a | F,<fr1,<r1,>a"),
Opcode.STOREIX to InstructionFormat.from("BW,<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("BW,>a | F,>a"), Opcode.STOREZM to InstructionFormat.from("BWL,>a | F,>a"),
Opcode.STOREZI to InstructionFormat.from("BW,<r1 | F,<r1"), Opcode.STOREZI to InstructionFormat.from("BWL,<r1 | F,<r1"),
Opcode.STOREZX to InstructionFormat.from("BW,<r1,>a | F,<r1,>a"), 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.STOREHA to InstructionFormat.from("B,<r1"), Opcode.STOREHA to InstructionFormat.from("B,<r1"),
Opcode.STOREHX 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.STOREHAX to InstructionFormat.from("W,<r1"),
Opcode.STOREHAY to InstructionFormat.from("W,<r1"), Opcode.STOREHAY to InstructionFormat.from("W,<r1"),
Opcode.STOREHXY 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.STOREHFACZERO to InstructionFormat.from("F,<fr1"),
Opcode.STOREHFACONE to InstructionFormat.from("F,<fr1"), Opcode.STOREHFACONE to InstructionFormat.from("F,<fr1"),
Opcode.JUMP to InstructionFormat.from("N,<a"), Opcode.JUMP to InstructionFormat.from("N,<a"),
@@ -684,8 +686,8 @@ val instructionFormats = mutableMapOf(
Opcode.CALLFARVB to InstructionFormat.from("N,<r1,<a"), Opcode.CALLFARVB to InstructionFormat.from("N,<r1,<a"),
Opcode.SYSCALL to InstructionFormat.from("N,syscall"), Opcode.SYSCALL to InstructionFormat.from("N,syscall"),
Opcode.RETURN to InstructionFormat.from("N"), Opcode.RETURN to InstructionFormat.from("N"),
Opcode.RETURNR to InstructionFormat.from("BW,<r1 | F,<fr1"), Opcode.RETURNR to InstructionFormat.from("BWL,<r1 | F,<fr1"),
Opcode.RETURNI to InstructionFormat.from("BW,<i | F,<i"), Opcode.RETURNI to InstructionFormat.from("BWL,<i | F,<i"),
Opcode.BSTCC to InstructionFormat.from("N,<a"), Opcode.BSTCC to InstructionFormat.from("N,<a"),
Opcode.BSTCS to InstructionFormat.from("N,<a"), Opcode.BSTCS to InstructionFormat.from("N,<a"),
Opcode.BSTEQ 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.BSTPOS to InstructionFormat.from("N,<a"),
Opcode.BSTVC to InstructionFormat.from("N,<a"), Opcode.BSTVC to InstructionFormat.from("N,<a"),
Opcode.BSTVS to InstructionFormat.from("N,<a"), Opcode.BSTVS to InstructionFormat.from("N,<a"),
Opcode.BGTR to InstructionFormat.from("BW,<r1,<r2,<a"), Opcode.BGTR to InstructionFormat.from("BWL,<r1,<r2,<a"),
Opcode.BGT to InstructionFormat.from("BW,<r1,<i,<a"), Opcode.BGT to InstructionFormat.from("BWL,<r1,<i,<a"),
Opcode.BLT to InstructionFormat.from("BW,<r1,<i,<a"), Opcode.BLT to InstructionFormat.from("BWL,<r1,<i,<a"),
Opcode.BGTSR to InstructionFormat.from("BW,<r1,<r2,<a"), Opcode.BGTSR to InstructionFormat.from("BWL,<r1,<r2,<a"),
Opcode.BGTS to InstructionFormat.from("BW,<r1,<i,<a"), Opcode.BGTS to InstructionFormat.from("BWL,<r1,<i,<a"),
Opcode.BLTS to InstructionFormat.from("BW,<r1,<i,<a"), Opcode.BLTS to InstructionFormat.from("BWL,<r1,<i,<a"),
Opcode.BGER to InstructionFormat.from("BW,<r1,<r2,<a"), Opcode.BGER to InstructionFormat.from("BWL,<r1,<r2,<a"),
Opcode.BGE to InstructionFormat.from("BW,<r1,<i,<a"), Opcode.BGE to InstructionFormat.from("BWL,<r1,<i,<a"),
Opcode.BLE to InstructionFormat.from("BW,<r1,<i,<a"), Opcode.BLE to InstructionFormat.from("BWL,<r1,<i,<a"),
Opcode.BGESR to InstructionFormat.from("BW,<r1,<r2,<a"), Opcode.BGESR to InstructionFormat.from("BWL,<r1,<r2,<a"),
Opcode.BGES to InstructionFormat.from("BW,<r1,<i,<a"), Opcode.BGES to InstructionFormat.from("BWL,<r1,<i,<a"),
Opcode.BLES to InstructionFormat.from("BW,<r1,<i,<a"), Opcode.BLES to InstructionFormat.from("BWL,<r1,<i,<a"),
Opcode.INC to InstructionFormat.from("BW,<>r1 | F,<>fr1"), Opcode.INC to InstructionFormat.from("BWL,<>r1 | F,<>fr1"),
Opcode.INCM to InstructionFormat.from("BW,<>a | F,<>a"), Opcode.INCM to InstructionFormat.from("BWL,<>a | F,<>a"),
Opcode.DEC to InstructionFormat.from("BW,<>r1 | F,<>fr1"), Opcode.DEC to InstructionFormat.from("BWL,<>r1 | F,<>fr1"),
Opcode.DECM to InstructionFormat.from("BW,<>a | F,<>a"), Opcode.DECM to InstructionFormat.from("BWL,<>a | F,<>a"),
Opcode.NEG to InstructionFormat.from("BW,<>r1 | F,<>fr1"), Opcode.NEG to InstructionFormat.from("BWL,<>r1 | F,<>fr1"),
Opcode.NEGM to InstructionFormat.from("BW,<>a | F,<>a"), Opcode.NEGM to InstructionFormat.from("BWL,<>a | F,<>a"),
Opcode.ADDR to InstructionFormat.from("BW,<>r1,<r2 | F,<>fr1,<fr2"), Opcode.ADDR to InstructionFormat.from("BWL,<>r1,<r2 | F,<>fr1,<fr2"),
Opcode.ADD to InstructionFormat.from("BW,<>r1,<i | F,<>fr1,<i"), Opcode.ADD to InstructionFormat.from("BWL,<>r1,<i | F,<>fr1,<i"),
Opcode.ADDM to InstructionFormat.from("BW,<r1,<>a | F,<fr1,<>a"), Opcode.ADDM to InstructionFormat.from("BWL,<r1,<>a | F,<fr1,<>a"),
Opcode.SUBR to InstructionFormat.from("BW,<>r1,<r2 | F,<>fr1,<fr2"), Opcode.SUBR to InstructionFormat.from("BWL,<>r1,<r2 | F,<>fr1,<fr2"),
Opcode.SUB to InstructionFormat.from("BW,<>r1,<i | F,<>fr1,<i"), Opcode.SUB to InstructionFormat.from("BWL,<>r1,<i | F,<>fr1,<i"),
Opcode.SUBM to InstructionFormat.from("BW,<r1,<>a | F,<fr1,<>a"), Opcode.SUBM to InstructionFormat.from("BWL,<r1,<>a | F,<fr1,<>a"),
Opcode.MULR to InstructionFormat.from("BW,<>r1,<r2 | F,<>fr1,<fr2"), Opcode.MULR to InstructionFormat.from("BW,<>r1,<r2 | F,<>fr1,<fr2"),
Opcode.MUL to InstructionFormat.from("BW,<>r1,<i | F,<>fr1,<i"), Opcode.MUL to InstructionFormat.from("BW,<>r1,<i | F,<>fr1,<i"),
Opcode.MULM to InstructionFormat.from("BW,<r1,<>a | F,<fr1,<>a"), Opcode.MULM to InstructionFormat.from("BW,<r1,<>a | F,<fr1,<>a"),
Opcode.MULSR to InstructionFormat.from("BW,<>r1,<r2 | F,<>fr1,<fr2"), Opcode.MULSR to InstructionFormat.from("BWL,<>r1,<r2 | F,<>fr1,<fr2"),
Opcode.MULS to InstructionFormat.from("BW,<>r1,<i | F,<>fr1,<i"), Opcode.MULS to InstructionFormat.from("BWL,<>r1,<i | F,<>fr1,<i"),
Opcode.MULSM to InstructionFormat.from("BW,<r1,<>a | F,<fr1,<>a"), Opcode.MULSM to InstructionFormat.from("BWL,<r1,<>a | F,<fr1,<>a"),
Opcode.DIVR to InstructionFormat.from("BW,<>r1,<r2 | F,<>fr1,<fr2"), Opcode.DIVR to InstructionFormat.from("BW,<>r1,<r2 | F,<>fr1,<fr2"),
Opcode.DIV to InstructionFormat.from("BW,<>r1,<i | F,<>fr1,<i"), Opcode.DIV to InstructionFormat.from("BW,<>r1,<i | F,<>fr1,<i"),
Opcode.DIVM to InstructionFormat.from("BW,<r1,<>a | F,<fr1,<>a"), Opcode.DIVM to InstructionFormat.from("BW,<r1,<>a | F,<fr1,<>a"),
Opcode.DIVSR to InstructionFormat.from("BW,<>r1,<r2 | F,<>fr1,<fr2"), Opcode.DIVSR to InstructionFormat.from("BWL,<>r1,<r2 | F,<>fr1,<fr2"),
Opcode.DIVS to InstructionFormat.from("BW,<>r1,<i | F,<>fr1,<i"), Opcode.DIVS to InstructionFormat.from("BWL,<>r1,<i | F,<>fr1,<i"),
Opcode.DIVSM to InstructionFormat.from("BW,<r1,<>a | F,<fr1,<>a"), Opcode.DIVSM to InstructionFormat.from("BWL,<r1,<>a | F,<fr1,<>a"),
Opcode.SQRT to InstructionFormat.from("BW,>r1,<r2 | F,>fr1,<fr2"), Opcode.SQRT to InstructionFormat.from("BWL,>r1,<r2 | F,>fr1,<fr2"),
Opcode.SQUARE to InstructionFormat.from("BW,>r1,<r2 | F,>fr1,<fr2"), Opcode.SQUARE to InstructionFormat.from("BWL,>r1,<r2 | F,>fr1,<fr2"),
Opcode.SGN to InstructionFormat.from("BW,>r1,<r2 | F,>r1,<fr1"), Opcode.SGN to InstructionFormat.from("BWL,>r1,<r2 | F,>r1,<fr1"),
Opcode.MODR to InstructionFormat.from("BW,<>r1,<r2"), Opcode.MODR to InstructionFormat.from("BW,<>r1,<r2"),
Opcode.MOD to InstructionFormat.from("BW,<>r1,<i"), Opcode.MOD to InstructionFormat.from("BW,<>r1,<i"),
Opcode.DIVMODR to InstructionFormat.from("BW,<>r1,<r2"), Opcode.DIVMODR to InstructionFormat.from("BW,<>r1,<r2"),
Opcode.DIVMOD to InstructionFormat.from("BW,<>r1,<i"), Opcode.DIVMOD to InstructionFormat.from("BW,<>r1,<i"),
Opcode.CMP to InstructionFormat.from("BW,<r1,<r2"), Opcode.CMP to InstructionFormat.from("BWL,<r1,<r2"),
Opcode.CMPI to InstructionFormat.from("BW,<r1,<i"), Opcode.CMPI to InstructionFormat.from("BWL,<r1,<i"),
Opcode.EXT to InstructionFormat.from("BW,>r1,<r2"), Opcode.EXT to InstructionFormat.from("BWL,>r1,<r2"),
Opcode.EXTS to InstructionFormat.from("BW,>r1,<r2"), Opcode.EXTS to InstructionFormat.from("BWL,>r1,<r2"),
Opcode.ANDR to InstructionFormat.from("BW,<>r1,<r2"), Opcode.ANDR to InstructionFormat.from("BWL,<>r1,<r2"),
Opcode.AND to InstructionFormat.from("BW,<>r1,<i"), Opcode.AND to InstructionFormat.from("BWL,<>r1,<i"),
Opcode.ANDM to InstructionFormat.from("BW,<r1,<>a"), Opcode.ANDM to InstructionFormat.from("BWL,<r1,<>a"),
Opcode.ORR to InstructionFormat.from("BW,<>r1,<r2"), Opcode.ORR to InstructionFormat.from("BWL,<>r1,<r2"),
Opcode.OR to InstructionFormat.from("BW,<>r1,<i"), Opcode.OR to InstructionFormat.from("BWL,<>r1,<i"),
Opcode.ORM to InstructionFormat.from("BW,<r1,<>a"), Opcode.ORM to InstructionFormat.from("BWL,<r1,<>a"),
Opcode.XORR to InstructionFormat.from("BW,<>r1,<r2"), Opcode.XORR to InstructionFormat.from("BWL,<>r1,<r2"),
Opcode.XOR to InstructionFormat.from("BW,<>r1,<i"), Opcode.XOR to InstructionFormat.from("BWL,<>r1,<i"),
Opcode.XORM to InstructionFormat.from("BW,<r1,<>a"), Opcode.XORM to InstructionFormat.from("BWL,<r1,<>a"),
Opcode.INV to InstructionFormat.from("BW,<>r1"), Opcode.INV to InstructionFormat.from("BWL,<>r1"),
Opcode.INVM to InstructionFormat.from("BW,<>a"), Opcode.INVM to InstructionFormat.from("BWL,<>a"),
Opcode.ASRN to InstructionFormat.from("BW,<>r1,<r2"), Opcode.ASRN to InstructionFormat.from("BWL,<>r1,<r2"),
Opcode.ASRNM to InstructionFormat.from("BW,<r1,<>a"), Opcode.ASRNM to InstructionFormat.from("BWL,<r1,<>a"),
Opcode.LSRN to InstructionFormat.from("BW,<>r1,<r2"), Opcode.LSRN to InstructionFormat.from("BWL,<>r1,<r2"),
Opcode.LSRNM to InstructionFormat.from("BW,<r1,<>a"), Opcode.LSRNM to InstructionFormat.from("BWL,<r1,<>a"),
Opcode.LSLN to InstructionFormat.from("BW,<>r1,<r2"), Opcode.LSLN to InstructionFormat.from("BWL,<>r1,<r2"),
Opcode.LSLNM to InstructionFormat.from("BW,<r1,<>a"), Opcode.LSLNM to InstructionFormat.from("BWL,<r1,<>a"),
Opcode.ASR to InstructionFormat.from("BW,<>r1"), Opcode.ASR to InstructionFormat.from("BWL,<>r1"),
Opcode.ASRM to InstructionFormat.from("BW,<>a"), Opcode.ASRM to InstructionFormat.from("BWL,<>a"),
Opcode.LSR to InstructionFormat.from("BW,<>r1"), Opcode.LSR to InstructionFormat.from("BWL,<>r1"),
Opcode.LSRM to InstructionFormat.from("BW,<>a"), Opcode.LSRM to InstructionFormat.from("BWL,<>a"),
Opcode.LSL to InstructionFormat.from("BW,<>r1"), Opcode.LSL to InstructionFormat.from("BWL,<>r1"),
Opcode.LSLM to InstructionFormat.from("BW,<>a"), Opcode.LSLM to InstructionFormat.from("BWL,<>a"),
Opcode.ROR to InstructionFormat.from("BW,<>r1"), Opcode.ROR to InstructionFormat.from("BWL,<>r1"),
Opcode.RORM to InstructionFormat.from("BW,<>a"), Opcode.RORM to InstructionFormat.from("BWL,<>a"),
Opcode.ROXR to InstructionFormat.from("BW,<>r1"), Opcode.ROXR to InstructionFormat.from("BWL,<>r1"),
Opcode.ROXRM to InstructionFormat.from("BW,<>a"), Opcode.ROXRM to InstructionFormat.from("BWL,<>a"),
Opcode.ROL to InstructionFormat.from("BW,<>r1"), Opcode.ROL to InstructionFormat.from("BWL,<>r1"),
Opcode.ROLM to InstructionFormat.from("BW,<>a"), Opcode.ROLM to InstructionFormat.from("BWL,<>a"),
Opcode.ROXL to InstructionFormat.from("BW,<>r1"), Opcode.ROXL to InstructionFormat.from("BWL,<>r1"),
Opcode.ROXLM to InstructionFormat.from("BW,<>a"), Opcode.ROXLM to InstructionFormat.from("BWL,<>a"),
Opcode.BIT to InstructionFormat.from("B,<a"), Opcode.BIT to InstructionFormat.from("B,<a"),
Opcode.FFROMUB to InstructionFormat.from("F,>fr1,<r1"), Opcode.FFROMUB to InstructionFormat.from("F,>fr1,<r1"),
@@ -797,8 +799,8 @@ val instructionFormats = mutableMapOf(
Opcode.LSIG to InstructionFormat.from("BW,>r1,<r2"), Opcode.LSIG to InstructionFormat.from("BW,>r1,<r2"),
Opcode.MSIG to InstructionFormat.from("BW,>r1,<r2"), Opcode.MSIG to InstructionFormat.from("BW,>r1,<r2"),
Opcode.PUSH to InstructionFormat.from("BW,<r1 | F,<fr1"), Opcode.PUSH to InstructionFormat.from("BWL,<r1 | F,<fr1"),
Opcode.POP to InstructionFormat.from("BW,>r1 | F,>fr1"), Opcode.POP to InstructionFormat.from("BWL,>r1 | F,>fr1"),
Opcode.PUSHST to InstructionFormat.from("N"), Opcode.PUSHST to InstructionFormat.from("N"),
Opcode.POPST to InstructionFormat.from("N"), Opcode.POPST to InstructionFormat.from("N"),
Opcode.CONCAT to InstructionFormat.from("BW,<>r1,<r2,<r3"), Opcode.CONCAT to InstructionFormat.from("BW,<>r1,<r2,<r3"),
@@ -903,6 +905,7 @@ data class IRInstruction(
when (type) { when (type) {
IRDataType.BYTE -> require(immediate in -128..255) { "immediate value out of range for byte: $immediate" } IRDataType.BYTE -> require(immediate in -128..255) { "immediate value out of range for byte: $immediate" }
IRDataType.WORD -> require(immediate in -32768..65535) { "immediate value out of range for word: $immediate" } IRDataType.WORD -> require(immediate in -32768..65535) { "immediate value out of range for word: $immediate" }
IRDataType.LONG -> require(immediate in -2147483647..2147483647) { "immediate value out of range for long: $immediate" }
IRDataType.FLOAT, null -> {} IRDataType.FLOAT, null -> {}
} }
} }
@@ -1083,8 +1086,7 @@ data class IRInstruction(
// some word instructions have byte reg1 // some word instructions have byte reg1
return when (opcode) { return when (opcode) {
Opcode.STOREZX, Opcode.SQRT -> IRDataType.BYTE Opcode.STOREZX, Opcode.SQRT -> IRDataType.BYTE
Opcode.EXT, Opcode.EXTS -> TODO("ext.w into long type") Opcode.EXT, Opcode.EXTS, Opcode.CONCAT -> IRDataType.LONG
Opcode.CONCAT -> TODO("concat.w into long type")
else -> IRDataType.WORD else -> IRDataType.WORD
} }
} }
@@ -1107,7 +1109,7 @@ data class IRInstruction(
if(opcode==Opcode.MSIG || opcode==Opcode.LSIG) if(opcode==Opcode.MSIG || opcode==Opcode.LSIG)
return when(type) { return when(type) {
IRDataType.BYTE -> IRDataType.WORD IRDataType.BYTE -> IRDataType.WORD
IRDataType.WORD -> TODO("msig/lsig.w from long type") IRDataType.WORD -> IRDataType.LONG
else -> null else -> null
} }
if(opcode==Opcode.ASRN || opcode==Opcode.LSRN || opcode==Opcode.LSLN) if(opcode==Opcode.ASRN || opcode==Opcode.LSRN || opcode==Opcode.LSLN)
@@ -1125,6 +1127,7 @@ data class IRInstruction(
when(type) { when(type) {
IRDataType.BYTE -> result.add(".b ") IRDataType.BYTE -> result.add(".b ")
IRDataType.WORD -> result.add(".w ") IRDataType.WORD -> result.add(".w ")
IRDataType.LONG -> result.add(".l ")
IRDataType.FLOAT -> result.add(".f ") IRDataType.FLOAT -> result.add(".f ")
else -> result.add(" ") else -> result.add(" ")
} }
@@ -1154,6 +1157,7 @@ data class IRInstruction(
when(it.reg.dt) { when(it.reg.dt) {
IRDataType.BYTE -> result.add("${location}r${it.reg.registerNum}.b$cpuReg,") IRDataType.BYTE -> result.add("${location}r${it.reg.registerNum}.b$cpuReg,")
IRDataType.WORD -> result.add("${location}r${it.reg.registerNum}.w$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,") IRDataType.FLOAT -> result.add("${location}fr${it.reg.registerNum}.f$cpuReg,")
} }
} }
@@ -1175,12 +1179,14 @@ data class IRInstruction(
when (returnspec.dt) { when (returnspec.dt) {
IRDataType.BYTE -> "r${returnspec.registerNum}.b" IRDataType.BYTE -> "r${returnspec.registerNum}.b"
IRDataType.WORD -> "r${returnspec.registerNum}.w" IRDataType.WORD -> "r${returnspec.registerNum}.w"
IRDataType.LONG -> "r${returnspec.registerNum}.l"
IRDataType.FLOAT -> "fr${returnspec.registerNum}.f" IRDataType.FLOAT -> "fr${returnspec.registerNum}.f"
} }
} else { } else {
when (returnspec.dt) { when (returnspec.dt) {
IRDataType.BYTE -> "r${returnspec.registerNum}.b@" + cpuReg IRDataType.BYTE -> "r${returnspec.registerNum}.b@" + cpuReg
IRDataType.WORD -> "r${returnspec.registerNum}.w@" + cpuReg IRDataType.WORD -> "r${returnspec.registerNum}.w@" + cpuReg
IRDataType.LONG -> "r${returnspec.registerNum}.l@" + cpuReg
IRDataType.FLOAT -> "r${returnspec.registerNum}.f@" + cpuReg IRDataType.FLOAT -> "r${returnspec.registerNum}.f@" + cpuReg
} }
} }

View File

@@ -53,6 +53,7 @@ fun convertIRType(typestr: String): IRDataType? {
"" -> null "" -> null
".b" -> IRDataType.BYTE ".b" -> IRDataType.BYTE
".w" -> IRDataType.WORD ".w" -> IRDataType.WORD
".l" -> IRDataType.LONG
".f" -> IRDataType.FLOAT ".f" -> IRDataType.FLOAT
else -> throw IRParseException("invalid type $typestr") 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\._]+):""") private val labelPattern = Regex("""_([a-zA-Z\d\._]+):""")
fun parseIRCodeLine(line: String): Either<IRInstruction, String> { 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)) if (immediateInt!=null && (immediateInt < -32768 || immediateInt > 65535))
throw IRParseException("immediate value out of range for word: $immediateInt") 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 -> {} IRDataType.FLOAT -> {}
null -> {} null -> {}
} }
@@ -271,6 +276,7 @@ private fun parseCall(rest: String): ParsedCall {
val type = when(match.groups[2]!!.value) { val type = when(match.groups[2]!!.value) {
"b" -> IRDataType.BYTE "b" -> IRDataType.BYTE
"w" -> IRDataType.WORD "w" -> IRDataType.WORD
"l" -> IRDataType.LONG
"f" -> IRDataType.FLOAT "f" -> IRDataType.FLOAT
else -> throw IRParseException("invalid type spec in $reg") else -> throw IRParseException("invalid type spec in $reg")
} }
@@ -359,6 +365,7 @@ fun irType(type: DataType): IRDataType {
BaseDataType.UBYTE, BaseDataType.UBYTE,
BaseDataType.BYTE -> IRDataType.BYTE BaseDataType.BYTE -> IRDataType.BYTE
BaseDataType.UWORD, BaseDataType.WORD, BaseDataType.POINTER -> IRDataType.WORD BaseDataType.UWORD, BaseDataType.WORD, BaseDataType.POINTER -> IRDataType.WORD
BaseDataType.LONG -> IRDataType.LONG
BaseDataType.FLOAT -> IRDataType.FLOAT BaseDataType.FLOAT -> IRDataType.FLOAT
BaseDataType.STRUCT_INSTANCE -> throw AssemblyError("no support for struct instances yet so no IR datatype for $type") 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") else -> throw AssemblyError("no IR datatype for $type")

View File

@@ -32,6 +32,10 @@ class Memory {
return (mem[address] + 256u*mem[address+1]).toUShort() 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 { fun getSW(address: Int): Short {
return (mem[address].toInt() + mem[address+1].toInt()*256).toShort() return (mem[address].toInt() + mem[address+1].toInt()*256).toShort()
} }
@@ -47,6 +51,14 @@ class Memory {
mem[address] = uv.toUByte() 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) { fun setFloat(address: Int, value: Double) {
var bits = value.toBits() var bits = value.toBits()
mem[address] = bits.toUByte() mem[address] = bits.toUByte()

View File

@@ -6,14 +6,14 @@ package prog8.vm
* A,X and Y "physical" 6502 registers. * A,X and Y "physical" 6502 registers.
*/ */
class Registers { class Registers {
private val registers = Array<UShort>(99999) { 0u } private val registers = Array<Int>(99999) { 0 }
private val floatRegisters = Array(99999) { 0.0 } private val floatRegisters = Array(99999) { 0.0 }
var cpuA: UByte = 0u var cpuA: UByte = 0u
var cpuX: UByte = 0u var cpuX: UByte = 0u
var cpuY: UByte = 0u var cpuY: UByte = 0u
fun reset() { fun reset() {
registers.fill(0u) registers.fill(0)
floatRegisters.fill(0.0) floatRegisters.fill(0.0)
cpuA = 0u cpuA = 0u
cpuX = 0u cpuX = 0u
@@ -21,29 +21,35 @@ class Registers {
} }
fun setUB(reg: Int, value: UByte) { 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) { 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) { fun setUW(reg: Int, value: UShort) {
registers[reg] = value registers[reg] = value.toInt()
} }
fun setSW(reg: Int, value: Short) { 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 getUB(reg: Int) = registers[reg].toUByte()
fun getSB(reg: Int) = registers[reg].toByte() 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 getSW(reg: Int) = registers[reg].toShort()
fun getSL(reg: Int) = registers[reg]
fun getFloat(reg:Int) = floatRegisters[reg] fun getFloat(reg:Int) = floatRegisters[reg]
fun setFloat(reg:Int, value: Double) { fun setFloat(reg:Int, value: Double) {

View File

@@ -68,6 +68,9 @@ SYSCALLS: DO NOT RENUMBER THESE OR YOU WILL BREAK EXISTING CODE
56 = CLOSE_FILE 56 = CLOSE_FILE
57 = CLOSE_FILE_WRITE 57 = CLOSE_FILE_WRITE
58 = ncompare strings 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 { enum class Syscall {
@@ -130,6 +133,9 @@ enum class Syscall {
CLOSE_FILE, CLOSE_FILE,
CLOSE_FILE_WRITE, CLOSE_FILE_WRITE,
NCOMPARE_STRINGS, NCOMPARE_STRINGS,
PRINT_I32,
I32_TO_STRING,
STR_TO_LONG,
; ;
companion object { companion object {
@@ -143,6 +149,7 @@ object SysCalls {
when(it.reg.dt) { when(it.reg.dt) {
IRDataType.BYTE -> vm.registers.getUB(it.reg.registerNum) IRDataType.BYTE -> vm.registers.getUB(it.reg.registerNum)
IRDataType.WORD -> vm.registers.getUW(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) IRDataType.FLOAT -> vm.registers.getFloat(it.reg.registerNum)
} }
} }
@@ -164,6 +171,7 @@ object SysCalls {
when(returns.dt) { when(returns.dt) {
IRDataType.BYTE -> vm.registers.setUB(returns.registerNum, vv.toInt().toUByte()) IRDataType.BYTE -> vm.registers.setUB(returns.registerNum, vv.toInt().toUByte())
IRDataType.WORD -> vm.registers.setUW(returns.registerNum, vv.toInt().toUShort()) 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) IRDataType.FLOAT -> vm.registers.setFloat(returns.registerNum, vv)
} }
} }
@@ -200,6 +208,10 @@ object SysCalls {
val value = getArgValues(callspec.arguments, vm).single() val value = getArgValues(callspec.arguments, vm).single()
print(value) print(value)
} }
Syscall.PRINT_I32 -> {
val value = getArgValues(callspec.arguments, vm).single()
print(value)
}
Syscall.INPUT -> { Syscall.INPUT -> {
val (address, maxlen) = getArgValues(callspec.arguments, vm) val (address, maxlen) = getArgValues(callspec.arguments, vm)
var input = readln() var input = readln()
@@ -263,6 +275,17 @@ object SysCalls {
} }
return returnValue(callspec.returns.single(), value, vm) 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 -> { Syscall.STR_TO_FLOAT -> {
val stringAddr = getArgValues(callspec.arguments, vm).single() as UShort val stringAddr = getArgValues(callspec.arguments, vm).single() as UShort
val memstring = vm.memory.getString(stringAddr.toInt()).replace(" ", "") val memstring = vm.memory.getString(stringAddr.toInt()).replace(" ", "")
@@ -634,6 +657,10 @@ object SysCalls {
} }
Syscall.CLOSE_FILE -> vm.close_file_read() Syscall.CLOSE_FILE -> vm.close_file_read()
Syscall.CLOSE_FILE_WRITE -> vm.close_file_write() 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)
}
} }
} }
} }

View File

@@ -353,12 +353,17 @@ class VirtualMachine(irProgram: IRProgram) {
IRDataType.BYTE -> { IRDataType.BYTE -> {
registers.setUB(reg, value.toUByte()) registers.setUB(reg, value.toUByte())
statusZero = value==0 statusZero = value==0
statusNegative = value>=0x80 statusNegative = value<0 || value>=0x80
} }
IRDataType.WORD -> { IRDataType.WORD -> {
registers.setUW(reg, value.toUShort()) registers.setUW(reg, value.toUShort())
statusZero = value==0 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") 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!!) val value = registers.getUW(i.reg1!!)
valueStack.pushw(value) valueStack.pushw(value)
} }
IRDataType.LONG -> {
val value = registers.getSL(i.reg1!!)
valueStack.pushl(value)
}
IRDataType.FLOAT -> { IRDataType.FLOAT -> {
val value = registers.getFloat(i.fpReg1!!) val value = registers.getFloat(i.fpReg1!!)
valueStack.pushf(value) valueStack.pushf(value)
@@ -389,6 +398,7 @@ class VirtualMachine(irProgram: IRProgram) {
when(i.type!!) { when(i.type!!) {
IRDataType.BYTE -> setResultReg(i.reg1!!, valueStack.removeLast().toInt(), i.type!!) IRDataType.BYTE -> setResultReg(i.reg1!!, valueStack.removeLast().toInt(), i.type!!)
IRDataType.WORD -> setResultReg(i.reg1!!, valueStack.popw().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()) IRDataType.FLOAT -> registers.setFloat(i.fpReg1!!, valueStack.popf())
} }
nextPc() nextPc()
@@ -425,6 +435,7 @@ class VirtualMachine(irProgram: IRProgram) {
when(value.dt!!) { when(value.dt!!) {
IRDataType.BYTE -> valueStack.add(value.value as UByte) IRDataType.BYTE -> valueStack.add(value.value as UByte)
IRDataType.WORD -> valueStack.pushw(value.value as UShort) IRDataType.WORD -> valueStack.pushw(value.value as UShort)
IRDataType.LONG -> valueStack.pushl(value.value as Int)
IRDataType.FLOAT -> valueStack.pushf(value.value as Double) IRDataType.FLOAT -> valueStack.pushf(value.value as Double)
} }
value.dt=null value.dt=null
@@ -472,6 +483,11 @@ class VirtualMachine(irProgram: IRProgram) {
registers.setUW(i.reg1!!, value) registers.setUW(i.reg1!!, value)
statusbitsNZ(value.toInt(), i.type!!) 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!!)) IRDataType.FLOAT -> registers.setFloat(i.fpReg1!!, memory.getFloat(i.address!!))
} }
nextPc() nextPc()
@@ -489,6 +505,11 @@ class VirtualMachine(irProgram: IRProgram) {
registers.setUW(i.reg1!!, value) registers.setUW(i.reg1!!, value)
statusbitsNZ(value.toInt(), i.type!!) 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())) IRDataType.FLOAT -> registers.setFloat(i.fpReg1!!, memory.getFloat(registers.getUW(i.reg1!!).toInt()))
} }
nextPc() nextPc()
@@ -508,6 +529,11 @@ class VirtualMachine(irProgram: IRProgram) {
registers.setUW(i.reg1!!, value) registers.setUW(i.reg1!!, value)
statusbitsNZ(value.toInt(), i.type!!) 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 -> { IRDataType.FLOAT -> {
registers.setFloat(i.fpReg1!!, memory.getFloat(registers.getUW(i.reg1!!).toInt() + offset)) 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) registers.setUW(i.reg1!!, value)
statusbitsNZ(value.toInt(), i.type!!) 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())) IRDataType.FLOAT -> registers.setFloat(i.fpReg1!!, memory.getFloat(i.address!! + registers.getUB(i.reg1!!).toInt()))
} }
nextPc() nextPc()
@@ -546,6 +577,12 @@ class VirtualMachine(irProgram: IRProgram) {
registers.setUW(i.reg1!!, value) registers.setUW(i.reg1!!, value)
statusbitsNZ(value.toInt(), i.type!!) 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 -> { IRDataType.FLOAT -> {
val pointer = memory.getUW(i.address!!) + registers.getUB(i.reg1!!) val pointer = memory.getUW(i.address!!) + registers.getUB(i.reg1!!)
registers.setFloat(i.fpReg1!!, memory.getFloat(pointer.toInt())) registers.setFloat(i.fpReg1!!, memory.getFloat(pointer.toInt()))
@@ -566,6 +603,11 @@ class VirtualMachine(irProgram: IRProgram) {
registers.setUW(i.reg1!!, value) registers.setUW(i.reg1!!, value)
statusbitsNZ(value.toInt(), i.type!!) 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!!)) IRDataType.FLOAT -> registers.setFloat(i.fpReg1!!, registers.getFloat(i.fpReg2!!))
} }
nextPc() nextPc()
@@ -575,6 +617,7 @@ class VirtualMachine(irProgram: IRProgram) {
when(i.type!!) { when(i.type!!) {
IRDataType.BYTE -> memory.setUB(i.address!!, registers.getUB(i.reg1!!)) IRDataType.BYTE -> memory.setUB(i.address!!, registers.getUB(i.reg1!!))
IRDataType.WORD -> memory.setUW(i.address!!, registers.getUW(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!!)) IRDataType.FLOAT -> memory.setFloat(i.address!!, registers.getFloat(i.fpReg1!!))
} }
nextPc() nextPc()
@@ -584,6 +627,7 @@ class VirtualMachine(irProgram: IRProgram) {
when (i.type!!) { when (i.type!!) {
IRDataType.BYTE -> memory.setUB(registers.getUW(i.reg2!!).toInt(), registers.getUB(i.reg1!!)) 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.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!!)) IRDataType.FLOAT -> memory.setFloat(registers.getUW(i.reg1!!).toInt(), registers.getFloat(i.fpReg1!!))
} }
nextPc() nextPc()
@@ -595,6 +639,7 @@ class VirtualMachine(irProgram: IRProgram) {
when (i.type!!) { when (i.type!!) {
IRDataType.BYTE -> memory.setUB(registers.getUW(i.reg2!!).toInt() + offset, registers.getUB(i.reg1!!)) 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.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!!)) IRDataType.FLOAT -> memory.setFloat(registers.getUW(i.reg1!!).toInt() + offset, registers.getFloat(i.fpReg1!!))
} }
nextPc() nextPc()
@@ -604,6 +649,7 @@ class VirtualMachine(irProgram: IRProgram) {
when (i.type!!) { when (i.type!!) {
IRDataType.BYTE -> memory.setUB(i.address!! + registers.getUB(i.reg2!!).toInt(), registers.getUB(i.reg1!!)) 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.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!!)) IRDataType.FLOAT -> memory.setFloat(i.address!! + registers.getUB(i.reg1!!).toInt(), registers.getFloat(i.fpReg1!!))
} }
nextPc() nextPc()
@@ -619,6 +665,10 @@ class VirtualMachine(irProgram: IRProgram) {
val pointer = memory.getUW(i.address!!) + registers.getUB(i.reg2!!) val pointer = memory.getUW(i.address!!) + registers.getUB(i.reg2!!)
memory.setUW(pointer.toInt(), registers.getUW(i.reg1!!)) 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 -> { IRDataType.FLOAT -> {
val pointer = memory.getUW(i.address!!) + registers.getUB(i.reg1!!) val pointer = memory.getUW(i.address!!) + registers.getUB(i.reg1!!)
memory.setFloat(pointer.toInt(), registers.getFloat(i.fpReg1!!)) memory.setFloat(pointer.toInt(), registers.getFloat(i.fpReg1!!))
@@ -631,6 +681,7 @@ class VirtualMachine(irProgram: IRProgram) {
when(i.type!!) { when(i.type!!) {
IRDataType.BYTE -> memory.setUB(i.address!!, 0u) IRDataType.BYTE -> memory.setUB(i.address!!, 0u)
IRDataType.WORD -> memory.setUW(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) IRDataType.FLOAT -> memory.setFloat(i.address!!, 0.0)
} }
nextPc() nextPc()
@@ -640,6 +691,7 @@ class VirtualMachine(irProgram: IRProgram) {
when (i.type!!) { when (i.type!!) {
IRDataType.BYTE -> memory.setUB(registers.getUW(i.reg1!!).toInt(), 0u) IRDataType.BYTE -> memory.setUB(registers.getUW(i.reg1!!).toInt(), 0u)
IRDataType.WORD -> memory.setUW(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) IRDataType.FLOAT -> memory.setFloat(registers.getUW(i.reg1!!).toInt(), 0.0)
} }
nextPc() nextPc()
@@ -649,6 +701,7 @@ class VirtualMachine(irProgram: IRProgram) {
when (i.type!!) { when (i.type!!) {
IRDataType.BYTE -> memory.setUB(i.address!! + registers.getUB(i.reg1!!).toInt(), 0u) 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.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) IRDataType.FLOAT -> memory.setFloat(i.address!! + registers.getUB(i.reg1!!).toInt(), 0.0)
} }
nextPc() nextPc()
@@ -675,6 +728,7 @@ class VirtualMachine(irProgram: IRProgram) {
when(arg.reg.dt) { when(arg.reg.dt) {
IRDataType.BYTE -> memory.setUB(arg.address!!, registers.getUB(arg.reg.registerNum)) IRDataType.BYTE -> memory.setUB(arg.address!!, registers.getUB(arg.reg.registerNum))
IRDataType.WORD -> memory.setUW(arg.address!!, registers.getUW(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)) 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") 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 -> { IRDataType.FLOAT -> {
if(returns.isNotEmpty()) if(returns.isNotEmpty())
registers.setFloat(returns.single().registerNum, i.immediateFp!!) registers.setFloat(returns.single().registerNum, i.immediateFp!!)
@@ -759,6 +822,15 @@ class VirtualMachine(irProgram: IRProgram) {
throw IllegalArgumentException("missing return value reg") 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 -> { IRDataType.FLOAT -> {
if(returns.isNotEmpty()) if(returns.isNotEmpty())
registers.setFloat(returns.single().registerNum, registers.getFloat(i.fpReg1!!)) registers.setFloat(returns.single().registerNum, registers.getFloat(i.fpReg1!!))
@@ -938,6 +1010,11 @@ class VirtualMachine(irProgram: IRProgram) {
registers.setUW(i.reg1!!, value) registers.setUW(i.reg1!!, value)
statusbitsNZ(value.toInt(), i.type!!) 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) IRDataType.FLOAT -> registers.setFloat(i.fpReg1!!, registers.getFloat(i.fpReg1!!)+1f)
} }
nextPc() nextPc()
@@ -956,6 +1033,11 @@ class VirtualMachine(irProgram: IRProgram) {
memory.setUW(address, value) memory.setUW(address, value)
statusbitsNZ(value.toInt(), i.type!!) 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) IRDataType.FLOAT -> memory.setFloat(address, memory.getFloat(address)+1f)
} }
nextPc() nextPc()
@@ -973,6 +1055,11 @@ class VirtualMachine(irProgram: IRProgram) {
registers.setUW(i.reg1!!, value) registers.setUW(i.reg1!!, value)
statusbitsNZ(value.toInt(), i.type!!) 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) IRDataType.FLOAT -> registers.setFloat(i.fpReg1!!, registers.getFloat(i.fpReg1!!)-1f)
} }
nextPc() nextPc()
@@ -990,6 +1077,11 @@ class VirtualMachine(irProgram: IRProgram) {
memory.setUW(i.address!!, value) memory.setUW(i.address!!, value)
statusbitsNZ(value.toInt(), i.type!!) 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) IRDataType.FLOAT -> memory.setFloat(i.address!!, memory.getFloat(i.address!!)-1f)
} }
nextPc() nextPc()
@@ -1007,6 +1099,11 @@ class VirtualMachine(irProgram: IRProgram) {
registers.setUW(i.reg1!!, value.toUShort()) registers.setUW(i.reg1!!, value.toUShort())
statusbitsNZ(value, IRDataType.WORD) 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!!)) IRDataType.FLOAT -> registers.setFloat(i.fpReg1!!, -registers.getFloat(i.fpReg1!!))
} }
nextPc() nextPc()
@@ -1025,6 +1122,11 @@ class VirtualMachine(irProgram: IRProgram) {
memory.setUW(address, value.toUShort()) memory.setUW(address, value.toUShort())
statusbitsNZ(value, IRDataType.WORD) 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)) IRDataType.FLOAT -> memory.setFloat(address, -memory.getFloat(address))
} }
nextPc() nextPc()
@@ -1034,6 +1136,7 @@ class VirtualMachine(irProgram: IRProgram) {
when(i.type!!) { when(i.type!!) {
IRDataType.BYTE -> plusMinusMultAnyByte("+", i.reg1!!, i.reg2!!) IRDataType.BYTE -> plusMinusMultAnyByte("+", i.reg1!!, i.reg2!!)
IRDataType.WORD -> plusMinusMultAnyWord("+", i.reg1!!, i.reg2!!) IRDataType.WORD -> plusMinusMultAnyWord("+", i.reg1!!, i.reg2!!)
IRDataType.LONG -> plusMinusMultAnyLong("+", i.reg1!!, i.reg2!!)
IRDataType.FLOAT -> { IRDataType.FLOAT -> {
val left = registers.getFloat(i.fpReg1!!) val left = registers.getFloat(i.fpReg1!!)
val right = registers.getFloat(i.fpReg2!!) val right = registers.getFloat(i.fpReg2!!)
@@ -1048,6 +1151,7 @@ class VirtualMachine(irProgram: IRProgram) {
when(i.type!!) { when(i.type!!) {
IRDataType.BYTE -> plusMinusMultConstByte("+", i.reg1!!, i.immediate!!.toUByte()) IRDataType.BYTE -> plusMinusMultConstByte("+", i.reg1!!, i.immediate!!.toUByte())
IRDataType.WORD -> plusMinusMultConstWord("+", i.reg1!!, i.immediate!!.toUShort()) IRDataType.WORD -> plusMinusMultConstWord("+", i.reg1!!, i.immediate!!.toUShort())
IRDataType.LONG -> plusMinusMultConstLong("+", i.reg1!!, i.immediate!!)
IRDataType.FLOAT -> { IRDataType.FLOAT -> {
val left = registers.getFloat(i.fpReg1!!) val left = registers.getFloat(i.fpReg1!!)
val result = arithFloat(left, "+", i.immediateFp!!) val result = arithFloat(left, "+", i.immediateFp!!)
@@ -1062,6 +1166,7 @@ class VirtualMachine(irProgram: IRProgram) {
when(i.type!!) { when(i.type!!) {
IRDataType.BYTE -> plusMinusMultAnyByteInplace("+", i.reg1!!, address) IRDataType.BYTE -> plusMinusMultAnyByteInplace("+", i.reg1!!, address)
IRDataType.WORD -> plusMinusMultAnyWordInplace("+", i.reg1!!, address) IRDataType.WORD -> plusMinusMultAnyWordInplace("+", i.reg1!!, address)
IRDataType.LONG -> plusMinusMultAnyLongInplace("+", i.reg1!!, address)
IRDataType.FLOAT -> { IRDataType.FLOAT -> {
val left = memory.getFloat(address) val left = memory.getFloat(address)
val right = registers.getFloat(i.fpReg1!!) val right = registers.getFloat(i.fpReg1!!)
@@ -1076,6 +1181,7 @@ class VirtualMachine(irProgram: IRProgram) {
when(i.type!!) { when(i.type!!) {
IRDataType.BYTE -> plusMinusMultAnyByte("-", i.reg1!!, i.reg2!!) IRDataType.BYTE -> plusMinusMultAnyByte("-", i.reg1!!, i.reg2!!)
IRDataType.WORD -> plusMinusMultAnyWord("-", i.reg1!!, i.reg2!!) IRDataType.WORD -> plusMinusMultAnyWord("-", i.reg1!!, i.reg2!!)
IRDataType.LONG -> plusMinusMultAnyLong("-", i.reg1!!, i.reg2!!)
IRDataType.FLOAT -> { IRDataType.FLOAT -> {
val left = registers.getFloat(i.fpReg1!!) val left = registers.getFloat(i.fpReg1!!)
val right = registers.getFloat(i.fpReg2!!) val right = registers.getFloat(i.fpReg2!!)
@@ -1090,6 +1196,7 @@ class VirtualMachine(irProgram: IRProgram) {
when(i.type!!) { when(i.type!!) {
IRDataType.BYTE -> plusMinusMultConstByte("-", i.reg1!!, i.immediate!!.toUByte()) IRDataType.BYTE -> plusMinusMultConstByte("-", i.reg1!!, i.immediate!!.toUByte())
IRDataType.WORD -> plusMinusMultConstWord("-", i.reg1!!, i.immediate!!.toUShort()) IRDataType.WORD -> plusMinusMultConstWord("-", i.reg1!!, i.immediate!!.toUShort())
IRDataType.LONG -> plusMinusMultConstLong("-", i.reg1!!, i.immediate!!)
IRDataType.FLOAT -> { IRDataType.FLOAT -> {
val left = registers.getFloat(i.fpReg1!!) val left = registers.getFloat(i.fpReg1!!)
val result = arithFloat(left, "-", i.immediateFp!!) val result = arithFloat(left, "-", i.immediateFp!!)
@@ -1104,6 +1211,7 @@ class VirtualMachine(irProgram: IRProgram) {
when(i.type!!) { when(i.type!!) {
IRDataType.BYTE -> plusMinusMultAnyByteInplace("-", i.reg1!!, address) IRDataType.BYTE -> plusMinusMultAnyByteInplace("-", i.reg1!!, address)
IRDataType.WORD -> plusMinusMultAnyWordInplace("-", i.reg1!!, address) IRDataType.WORD -> plusMinusMultAnyWordInplace("-", i.reg1!!, address)
IRDataType.LONG -> plusMinusMultAnyLongInplace("-", i.reg1!!, address)
IRDataType.FLOAT -> { IRDataType.FLOAT -> {
val left = memory.getFloat(address) val left = memory.getFloat(address)
val right = registers.getFloat(i.fpReg1!!) val right = registers.getFloat(i.fpReg1!!)
@@ -1118,6 +1226,7 @@ class VirtualMachine(irProgram: IRProgram) {
when(i.type!!) { when(i.type!!) {
IRDataType.BYTE -> plusMinusMultAnyByte("*", i.reg1!!, i.reg2!!) IRDataType.BYTE -> plusMinusMultAnyByte("*", i.reg1!!, i.reg2!!)
IRDataType.WORD -> plusMinusMultAnyWord("*", i.reg1!!, i.reg2!!) IRDataType.WORD -> plusMinusMultAnyWord("*", i.reg1!!, i.reg2!!)
IRDataType.LONG -> throw IllegalArgumentException("mulr unsigned long not supported")
IRDataType.FLOAT -> { IRDataType.FLOAT -> {
val left = registers.getFloat(i.fpReg1!!) val left = registers.getFloat(i.fpReg1!!)
val right = registers.getFloat(i.fpReg2!!) val right = registers.getFloat(i.fpReg2!!)
@@ -1132,6 +1241,7 @@ class VirtualMachine(irProgram: IRProgram) {
when(i.type!!) { when(i.type!!) {
IRDataType.BYTE -> plusMinusMultConstByte("*", i.reg1!!, i.immediate!!.toUByte()) IRDataType.BYTE -> plusMinusMultConstByte("*", i.reg1!!, i.immediate!!.toUByte())
IRDataType.WORD -> plusMinusMultConstWord("*", i.reg1!!, i.immediate!!.toUShort()) IRDataType.WORD -> plusMinusMultConstWord("*", i.reg1!!, i.immediate!!.toUShort())
IRDataType.LONG -> throw IllegalArgumentException("mul unsigned long not supported")
IRDataType.FLOAT -> { IRDataType.FLOAT -> {
val left = registers.getFloat(i.fpReg1!!) val left = registers.getFloat(i.fpReg1!!)
val result = arithFloat(left, "*", i.immediateFp!!) val result = arithFloat(left, "*", i.immediateFp!!)
@@ -1146,6 +1256,7 @@ class VirtualMachine(irProgram: IRProgram) {
when(i.type!!) { when(i.type!!) {
IRDataType.BYTE -> plusMinusMultAnyByteInplace("*", i.reg1!!, address) IRDataType.BYTE -> plusMinusMultAnyByteInplace("*", i.reg1!!, address)
IRDataType.WORD -> plusMinusMultAnyWordInplace("*", i.reg1!!, address) IRDataType.WORD -> plusMinusMultAnyWordInplace("*", i.reg1!!, address)
IRDataType.LONG -> throw IllegalArgumentException("mulm unsigned long not supported")
IRDataType.FLOAT -> { IRDataType.FLOAT -> {
val left = memory.getFloat(address) val left = memory.getFloat(address)
val right = registers.getFloat(i.fpReg1!!) val right = registers.getFloat(i.fpReg1!!)
@@ -1160,6 +1271,7 @@ class VirtualMachine(irProgram: IRProgram) {
when(i.type!!) { when(i.type!!) {
IRDataType.BYTE -> plusMinusMultAnyByteSigned("*", i.reg1!!, i.reg2!!) IRDataType.BYTE -> plusMinusMultAnyByteSigned("*", i.reg1!!, i.reg2!!)
IRDataType.WORD -> plusMinusMultAnyWordSigned("*", i.reg1!!, i.reg2!!) IRDataType.WORD -> plusMinusMultAnyWordSigned("*", i.reg1!!, i.reg2!!)
IRDataType.LONG -> plusMinusMultAnyLongSigned("*", i.reg1!!, i.reg2!!)
IRDataType.FLOAT -> { IRDataType.FLOAT -> {
val left = registers.getFloat(i.fpReg1!!) val left = registers.getFloat(i.fpReg1!!)
val right = registers.getFloat(i.fpReg2!!) val right = registers.getFloat(i.fpReg2!!)
@@ -1174,6 +1286,7 @@ class VirtualMachine(irProgram: IRProgram) {
when(i.type!!) { when(i.type!!) {
IRDataType.BYTE -> plusMinusMultConstByteSigned("*", i.reg1!!, i.immediate!!.toByte()) IRDataType.BYTE -> plusMinusMultConstByteSigned("*", i.reg1!!, i.immediate!!.toByte())
IRDataType.WORD -> plusMinusMultConstWordSigned("*", i.reg1!!, i.immediate!!.toShort()) IRDataType.WORD -> plusMinusMultConstWordSigned("*", i.reg1!!, i.immediate!!.toShort())
IRDataType.LONG -> plusMinusMultConstLongSigned("*", i.reg1!!, i.immediate!!)
IRDataType.FLOAT -> { IRDataType.FLOAT -> {
val left = registers.getFloat(i.fpReg1!!) val left = registers.getFloat(i.fpReg1!!)
val result = arithFloat(left, "*", i.immediateFp!!) val result = arithFloat(left, "*", i.immediateFp!!)
@@ -1188,6 +1301,7 @@ class VirtualMachine(irProgram: IRProgram) {
when(i.type!!) { when(i.type!!) {
IRDataType.BYTE -> plusMinusMultAnyByteSignedInplace("*", i.reg1!!, address) IRDataType.BYTE -> plusMinusMultAnyByteSignedInplace("*", i.reg1!!, address)
IRDataType.WORD -> plusMinusMultAnyWordSignedInplace("*", i.reg1!!, address) IRDataType.WORD -> plusMinusMultAnyWordSignedInplace("*", i.reg1!!, address)
IRDataType.LONG -> plusMinusMultAnyLongSignedInplace("*", i.reg1!!, address)
IRDataType.FLOAT -> { IRDataType.FLOAT -> {
val left = memory.getFloat(address) val left = memory.getFloat(address)
val right = registers.getFloat(i.fpReg1!!) val right = registers.getFloat(i.fpReg1!!)
@@ -1202,6 +1316,7 @@ class VirtualMachine(irProgram: IRProgram) {
when(i.type!!) { when(i.type!!) {
IRDataType.BYTE -> divOrModByteUnsigned("/", i.reg1!!, i.reg2!!) IRDataType.BYTE -> divOrModByteUnsigned("/", i.reg1!!, i.reg2!!)
IRDataType.WORD -> divOrModWordUnsigned("/", 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") IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
} }
nextPc() nextPc()
@@ -1211,6 +1326,7 @@ class VirtualMachine(irProgram: IRProgram) {
when(i.type!!) { when(i.type!!) {
IRDataType.BYTE -> divOrModConstByteUnsigned("/", i.reg1!!, i.immediate!!.toUByte()) IRDataType.BYTE -> divOrModConstByteUnsigned("/", i.reg1!!, i.immediate!!.toUByte())
IRDataType.WORD -> divOrModConstWordUnsigned("/", i.reg1!!, i.immediate!!.toUShort()) 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") IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
} }
nextPc() nextPc()
@@ -1221,6 +1337,7 @@ class VirtualMachine(irProgram: IRProgram) {
when(i.type!!) { when(i.type!!) {
IRDataType.BYTE -> divModByteUnsignedInplace("/", i.reg1!!, address) IRDataType.BYTE -> divModByteUnsignedInplace("/", i.reg1!!, address)
IRDataType.WORD -> divModWordUnsignedInplace("/", 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") IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
} }
nextPc() nextPc()
@@ -1230,6 +1347,7 @@ class VirtualMachine(irProgram: IRProgram) {
when(i.type!!) { when(i.type!!) {
IRDataType.BYTE -> divModByteSigned("/", i.reg1!!, i.reg2!!) IRDataType.BYTE -> divModByteSigned("/", i.reg1!!, i.reg2!!)
IRDataType.WORD -> divModWordSigned("/", i.reg1!!, i.reg2!!) IRDataType.WORD -> divModWordSigned("/", i.reg1!!, i.reg2!!)
IRDataType.LONG -> divModLongSigned("/", i.reg1!!, i.reg2!!)
IRDataType.FLOAT -> { IRDataType.FLOAT -> {
val left = registers.getFloat(i.fpReg1!!) val left = registers.getFloat(i.fpReg1!!)
val right = registers.getFloat(i.fpReg2!!) val right = registers.getFloat(i.fpReg2!!)
@@ -1244,6 +1362,7 @@ class VirtualMachine(irProgram: IRProgram) {
when(i.type!!) { when(i.type!!) {
IRDataType.BYTE -> divModConstByteSigned("/", i.reg1!!, i.immediate!!.toByte()) IRDataType.BYTE -> divModConstByteSigned("/", i.reg1!!, i.immediate!!.toByte())
IRDataType.WORD -> divModConstWordSigned("/", i.reg1!!, i.immediate!!.toShort()) IRDataType.WORD -> divModConstWordSigned("/", i.reg1!!, i.immediate!!.toShort())
IRDataType.LONG -> divModConstLongSigned("/", i.reg1!!, i.immediate!!)
IRDataType.FLOAT -> { IRDataType.FLOAT -> {
val left = registers.getFloat(i.fpReg1!!) val left = registers.getFloat(i.fpReg1!!)
val result = arithFloat(left, "/", i.immediateFp!!) val result = arithFloat(left, "/", i.immediateFp!!)
@@ -1258,6 +1377,7 @@ class VirtualMachine(irProgram: IRProgram) {
when(i.type!!) { when(i.type!!) {
IRDataType.BYTE -> divModByteSignedInplace("/", i.reg1!!, address) IRDataType.BYTE -> divModByteSignedInplace("/", i.reg1!!, address)
IRDataType.WORD -> divModWordSignedInplace("/", i.reg1!!, address) IRDataType.WORD -> divModWordSignedInplace("/", i.reg1!!, address)
IRDataType.LONG -> divModLongSignedInplace("/", i.reg1!!, address)
IRDataType.FLOAT -> { IRDataType.FLOAT -> {
val left = memory.getFloat(address) val left = memory.getFloat(address)
val right = registers.getFloat(i.fpReg1!!) val right = registers.getFloat(i.fpReg1!!)
@@ -1272,6 +1392,7 @@ class VirtualMachine(irProgram: IRProgram) {
when(i.type!!) { when(i.type!!) {
IRDataType.BYTE -> divOrModByteUnsigned("%", i.reg1!!, i.reg2!!) IRDataType.BYTE -> divOrModByteUnsigned("%", i.reg1!!, i.reg2!!)
IRDataType.WORD -> divOrModWordUnsigned("%", 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") IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
} }
nextPc() nextPc()
@@ -1281,6 +1402,7 @@ class VirtualMachine(irProgram: IRProgram) {
when(i.type!!) { when(i.type!!) {
IRDataType.BYTE -> divOrModConstByteUnsigned("%", i.reg1!!, i.immediate!!.toUByte()) IRDataType.BYTE -> divOrModConstByteUnsigned("%", i.reg1!!, i.immediate!!.toUByte())
IRDataType.WORD -> divOrModConstWordUnsigned("%", i.reg1!!, i.immediate!!.toUShort()) 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") IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
} }
nextPc() nextPc()
@@ -1290,6 +1412,7 @@ class VirtualMachine(irProgram: IRProgram) {
when(i.type!!) { when(i.type!!) {
IRDataType.BYTE -> divAndModUByte(i.reg1!!, i.reg2!!) // division+remainder results on value stack 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.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") IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
} }
nextPc() nextPc()
@@ -1299,6 +1422,7 @@ class VirtualMachine(irProgram: IRProgram) {
when(i.type!!) { when(i.type!!) {
IRDataType.BYTE -> divAndModConstUByte(i.reg1!!, i.immediate!!.toUByte()) // division+remainder results on value stack 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.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") IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
} }
nextPc() nextPc()
@@ -1308,6 +1432,7 @@ class VirtualMachine(irProgram: IRProgram) {
when(i.type!!) { when(i.type!!) {
IRDataType.BYTE -> registers.setSB(i.reg1!!, registers.getSB(i.reg2!!).toInt().sign.toByte()) 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.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()) IRDataType.FLOAT -> registers.setSB(i.reg1!!, registers.getFloat(i.fpReg1!!).sign.toInt().toByte())
} }
nextPc() nextPc()
@@ -1317,6 +1442,7 @@ class VirtualMachine(irProgram: IRProgram) {
when(i.type!!) { when(i.type!!) {
IRDataType.BYTE -> registers.setUB(i.reg1!!, sqrt(registers.getUB(i.reg2!!).toDouble()).toInt().toUByte()) 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.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!!))) IRDataType.FLOAT -> registers.setFloat(i.fpReg1!!, sqrt(registers.getFloat(i.fpReg2!!)))
} }
nextPc() nextPc()
@@ -1325,13 +1451,17 @@ class VirtualMachine(irProgram: IRProgram) {
private fun InsSQUARE(i: IRInstruction) { private fun InsSQUARE(i: IRInstruction) {
when(i.type!!) { when(i.type!!) {
IRDataType.BYTE -> { IRDataType.BYTE -> {
val value = registers.getUB(i.reg2!!).toDouble().toInt() val value = registers.getUB(i.reg2!!).toInt()
registers.setUB(i.reg1!!, (value*value).toUByte()) registers.setUB(i.reg1!!, (value*value).toUByte())
} }
IRDataType.WORD -> { IRDataType.WORD -> {
val value = registers.getUW(i.reg2!!).toDouble().toInt() val value = registers.getUW(i.reg2!!).toInt()
registers.setUW(i.reg1!!, (value*value).toUShort()) registers.setUW(i.reg1!!, (value*value).toUShort())
} }
IRDataType.LONG -> {
val value = registers.getSL(i.reg2!!)
registers.setSL(i.reg1!!, value*value)
}
IRDataType.FLOAT -> { IRDataType.FLOAT -> {
val value = registers.getFloat(i.fpReg2!!) val value = registers.getFloat(i.fpReg2!!)
registers.setFloat(i.fpReg1!!, value*value) registers.setFloat(i.fpReg1!!, value*value)
@@ -1352,6 +1482,11 @@ class VirtualMachine(irProgram: IRProgram) {
val reg2 = registers.getUW(i.reg2!!) val reg2 = registers.getUW(i.reg2!!)
reg1.toInt() - reg2.toInt() 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") IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
} }
statusbitsComparison(comparison, i.type!!) statusbitsComparison(comparison, i.type!!)
@@ -1368,6 +1503,10 @@ class VirtualMachine(irProgram: IRProgram) {
val reg1 = registers.getUW(i.reg1!!) val reg1 = registers.getUW(i.reg1!!)
reg1.toInt() - (i.immediate!! and 65535) 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") IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
} }
statusbitsComparison(comparison, i.type!!) statusbitsComparison(comparison, i.type!!)
@@ -1400,6 +1539,7 @@ class VirtualMachine(irProgram: IRProgram) {
when(type) { when(type) {
IRDataType.BYTE -> statusNegative = (value and 0x80)==0x80 IRDataType.BYTE -> statusNegative = (value and 0x80)==0x80
IRDataType.WORD -> statusNegative = (value and 0x8000)==0x8000 IRDataType.WORD -> statusNegative = (value and 0x8000)==0x8000
IRDataType.LONG -> statusNegative = value<0
IRDataType.FLOAT -> { /* floats don't change the status bits */ } IRDataType.FLOAT -> { /* floats don't change the status bits */ }
} }
} }
@@ -1418,6 +1558,7 @@ class VirtualMachine(irProgram: IRProgram) {
when(type) { when(type) {
IRDataType.BYTE -> statusNegative = (comparison and 0x80)!=0 IRDataType.BYTE -> statusNegative = (comparison and 0x80)!=0
IRDataType.WORD -> statusNegative = (comparison and 0x8000)!=0 IRDataType.WORD -> statusNegative = (comparison and 0x8000)!=0
IRDataType.LONG -> statusNegative = comparison<0
IRDataType.FLOAT -> { /* floats don't change the status bits */ } IRDataType.FLOAT -> { /* floats don't change the status bits */ }
} }
// TODO determine statusOverflow in comparison // TODO determine statusOverflow in comparison
@@ -1850,7 +1991,8 @@ class VirtualMachine(irProgram: IRProgram) {
private fun InsEXT(i: IRInstruction) { private fun InsEXT(i: IRInstruction) {
when(i.type!!){ when(i.type!!){
IRDataType.BYTE -> registers.setUW(i.reg1!!, registers.getUB(i.reg2!!).toUShort()) 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") IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
} }
nextPc() nextPc()
@@ -1859,7 +2001,8 @@ class VirtualMachine(irProgram: IRProgram) {
private fun InsEXTS(i: IRInstruction) { private fun InsEXTS(i: IRInstruction) {
when(i.type!!){ when(i.type!!){
IRDataType.BYTE -> registers.setSW(i.reg1!!, registers.getSB(i.reg2!!).toShort()) 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") IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
} }
nextPc() nextPc()
@@ -1871,6 +2014,7 @@ class VirtualMachine(irProgram: IRProgram) {
when(i.type!!) { when(i.type!!) {
IRDataType.BYTE -> registers.setUB(i.reg1!!, value.toUByte()) IRDataType.BYTE -> registers.setUB(i.reg1!!, value.toUByte())
IRDataType.WORD -> registers.setUW(i.reg1!!, value.toUShort()) 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") IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
} }
statusbitsNZ(value, i.type!!) statusbitsNZ(value, i.type!!)
@@ -1888,6 +2032,10 @@ class VirtualMachine(irProgram: IRProgram) {
value = registers.getUW(i.reg1!!).toInt() and i.immediate!! value = registers.getUW(i.reg1!!).toInt() and i.immediate!!
registers.setUW(i.reg1!!, value.toUShort()) 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") IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
} }
statusbitsNZ(value, i.type!!) statusbitsNZ(value, i.type!!)
@@ -1910,6 +2058,12 @@ class VirtualMachine(irProgram: IRProgram) {
value = left.toInt() and right.toInt() value = left.toInt() and right.toInt()
memory.setUW(address, value.toUShort()) 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") IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
} }
statusbitsNZ(value, i.type!!) statusbitsNZ(value, i.type!!)
@@ -1922,6 +2076,7 @@ class VirtualMachine(irProgram: IRProgram) {
when(i.type!!) { when(i.type!!) {
IRDataType.BYTE -> registers.setUB(i.reg1!!, value.toUByte()) IRDataType.BYTE -> registers.setUB(i.reg1!!, value.toUByte())
IRDataType.WORD -> registers.setUW(i.reg1!!, value.toUShort()) 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") IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
} }
statusbitsNZ(value, i.type!!) statusbitsNZ(value, i.type!!)
@@ -1939,6 +2094,10 @@ class VirtualMachine(irProgram: IRProgram) {
value = registers.getUW(i.reg1!!).toInt() or i.immediate!! value = registers.getUW(i.reg1!!).toInt() or i.immediate!!
registers.setUW(i.reg1!!, value.toUShort()) 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") IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
} }
statusbitsNZ(value, i.type!!) statusbitsNZ(value, i.type!!)
@@ -1961,6 +2120,12 @@ class VirtualMachine(irProgram: IRProgram) {
value = left.toInt() or right.toInt() value = left.toInt() or right.toInt()
memory.setUW(address, value.toUShort()) 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") IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
} }
statusbitsNZ(value, i.type!!) statusbitsNZ(value, i.type!!)
@@ -1973,6 +2138,7 @@ class VirtualMachine(irProgram: IRProgram) {
when(i.type!!) { when(i.type!!) {
IRDataType.BYTE -> registers.setUB(i.reg1!!, value.toUByte()) IRDataType.BYTE -> registers.setUB(i.reg1!!, value.toUByte())
IRDataType.WORD -> registers.setUW(i.reg1!!, value.toUShort()) 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") IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
} }
statusbitsNZ(value, i.type!!) statusbitsNZ(value, i.type!!)
@@ -1990,6 +2156,10 @@ class VirtualMachine(irProgram: IRProgram) {
value = registers.getUW(i.reg1!!).toInt() xor i.immediate!! value = registers.getUW(i.reg1!!).toInt() xor i.immediate!!
registers.setUW(i.reg1!!, value.toUShort()) 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") IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
} }
statusbitsNZ(value, i.type!!) statusbitsNZ(value, i.type!!)
@@ -2012,6 +2182,12 @@ class VirtualMachine(irProgram: IRProgram) {
value = left.toInt() xor right.toInt() value = left.toInt() xor right.toInt()
memory.setUW(address, value.toUShort()) 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") IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
} }
statusbitsNZ(value, i.type!!) statusbitsNZ(value, i.type!!)
@@ -2022,6 +2198,7 @@ class VirtualMachine(irProgram: IRProgram) {
when(i.type!!) { when(i.type!!) {
IRDataType.BYTE -> registers.setUB(i.reg1!!, registers.getUB(i.reg1!!).inv()) IRDataType.BYTE -> registers.setUB(i.reg1!!, registers.getUB(i.reg1!!).inv())
IRDataType.WORD -> registers.setUW(i.reg1!!, registers.getUW(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") IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
} }
nextPc() nextPc()
@@ -2032,6 +2209,7 @@ class VirtualMachine(irProgram: IRProgram) {
when(i.type!!) { when(i.type!!) {
IRDataType.BYTE -> memory.setUB(address, memory.getUB(address).inv()) IRDataType.BYTE -> memory.setUB(address, memory.getUB(address).inv())
IRDataType.WORD -> memory.setUW(address, memory.getUW(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") IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
} }
nextPc() nextPc()
@@ -2042,6 +2220,7 @@ class VirtualMachine(irProgram: IRProgram) {
when(i.type!!) { when(i.type!!) {
IRDataType.BYTE -> registers.setSB(i.reg1!!, (left shr right).toByte()) IRDataType.BYTE -> registers.setSB(i.reg1!!, (left shr right).toByte())
IRDataType.WORD -> registers.setSW(i.reg1!!, (left shr right).toShort()) 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") IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
} }
nextPc() nextPc()
@@ -2059,6 +2238,10 @@ class VirtualMachine(irProgram: IRProgram) {
val memvalue = memory.getSW(address).toInt() val memvalue = memory.getSW(address).toInt()
memory.setSW(address, (memvalue shr operand).toShort()) 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") IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
} }
nextPc() nextPc()
@@ -2076,6 +2259,11 @@ class VirtualMachine(irProgram: IRProgram) {
statusCarry = (value and 1)!=0 statusCarry = (value and 1)!=0
registers.setSW(i.reg1!!, (value shr 1).toShort()) 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") IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
} }
nextPc() nextPc()
@@ -2094,6 +2282,11 @@ class VirtualMachine(irProgram: IRProgram) {
statusCarry = (value and 1)!=0 statusCarry = (value and 1)!=0
memory.setSW(address, (value shr 1).toShort()) 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") IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
} }
nextPc() nextPc()
@@ -2104,6 +2297,7 @@ class VirtualMachine(irProgram: IRProgram) {
when(i.type!!) { when(i.type!!) {
IRDataType.BYTE -> registers.setUB(i.reg1!!, (left shr right.toInt()).toUByte()) IRDataType.BYTE -> registers.setUB(i.reg1!!, (left shr right.toInt()).toUByte())
IRDataType.WORD -> registers.setUW(i.reg1!!, (left shr right.toInt()).toUShort()) 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") IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
} }
nextPc() nextPc()
@@ -2121,6 +2315,10 @@ class VirtualMachine(irProgram: IRProgram) {
val memvalue = memory.getUW(address).toInt() val memvalue = memory.getUW(address).toInt()
memory.setUW(address, (memvalue shr operand).toUShort()) 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") IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
} }
nextPc() nextPc()
@@ -2138,6 +2336,11 @@ class VirtualMachine(irProgram: IRProgram) {
statusCarry = (value and 1)!=0 statusCarry = (value and 1)!=0
registers.setUW(i.reg1!!, (value shr 1).toUShort()) 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") IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
} }
nextPc() nextPc()
@@ -2156,6 +2359,11 @@ class VirtualMachine(irProgram: IRProgram) {
statusCarry = (value and 1)!=0 statusCarry = (value and 1)!=0
memory.setUW(address, (value shr 1).toUShort()) 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") IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
} }
nextPc() nextPc()
@@ -2170,6 +2378,9 @@ class VirtualMachine(irProgram: IRProgram) {
IRDataType.WORD -> { IRDataType.WORD -> {
registers.setUW(i.reg1!!, (left shl right.toInt()).toUShort()) 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") IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
} }
nextPc() nextPc()
@@ -2187,6 +2398,10 @@ class VirtualMachine(irProgram: IRProgram) {
val memvalue = memory.getUW(address).toInt() val memvalue = memory.getUW(address).toInt()
memory.setUW(address, (memvalue shl operand).toUShort()) 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") IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
} }
nextPc() nextPc()
@@ -2204,6 +2419,11 @@ class VirtualMachine(irProgram: IRProgram) {
statusCarry = (value and 0x8000)!=0 statusCarry = (value and 0x8000)!=0
registers.setUW(i.reg1!!, (value shl 1).toUShort()) 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") IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
} }
nextPc() nextPc()
@@ -2222,6 +2442,11 @@ class VirtualMachine(irProgram: IRProgram) {
statusCarry = (value and 0x8000)!=0 statusCarry = (value and 0x8000)!=0
memory.setUW(address, (value shl 1).toUShort()) 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") IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
} }
nextPc() nextPc()
@@ -2250,6 +2475,16 @@ class VirtualMachine(irProgram: IRProgram) {
orig.rotateRight(1) orig.rotateRight(1)
registers.setUW(i.reg1!!, rotated) 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 -> { IRDataType.FLOAT -> {
throw IllegalArgumentException("can't ROR a float") throw IllegalArgumentException("can't ROR a float")
} }
@@ -2282,6 +2517,16 @@ class VirtualMachine(irProgram: IRProgram) {
orig.rotateRight(1) orig.rotateRight(1)
memory.setUW(address, rotated) 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 -> { IRDataType.FLOAT -> {
throw IllegalArgumentException("can't ROR a float") throw IllegalArgumentException("can't ROR a float")
} }
@@ -2313,6 +2558,16 @@ class VirtualMachine(irProgram: IRProgram) {
orig.rotateLeft(1) orig.rotateLeft(1)
registers.setUW(i.reg1!!, rotated) 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 -> { IRDataType.FLOAT -> {
throw IllegalArgumentException("can't ROL a float") throw IllegalArgumentException("can't ROL a float")
} }
@@ -2345,6 +2600,16 @@ class VirtualMachine(irProgram: IRProgram) {
orig.rotateLeft(1) orig.rotateLeft(1)
memory.setUW(address, rotated) 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 -> { IRDataType.FLOAT -> {
throw IllegalArgumentException("can't ROL a float") throw IllegalArgumentException("can't ROL a float")
} }
@@ -2360,7 +2625,11 @@ class VirtualMachine(irProgram: IRProgram) {
registers.setUB(i.reg1!!, value.toUByte()) registers.setUB(i.reg1!!, value.toUByte())
statusbitsNZ(value.toInt(), i.type!!) 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") IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
} }
nextPc() nextPc()
@@ -2374,7 +2643,12 @@ class VirtualMachine(irProgram: IRProgram) {
statusbitsNZ(newValue, i.type!!) statusbitsNZ(newValue, i.type!!)
registers.setUB(i.reg1!!, newValue.toUByte()) 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") IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
} }
nextPc() nextPc()
@@ -2389,7 +2663,12 @@ class VirtualMachine(irProgram: IRProgram) {
registers.setUW(i.reg1!!, value.toUShort()) registers.setUW(i.reg1!!, value.toUShort())
statusbitsNZ(value.toInt(), i.type!!) 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") IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i")
} }
nextPc() nextPc()
@@ -2586,6 +2865,7 @@ class VirtualMachine(irProgram: IRProgram) {
return when(i.type) { return when(i.type) {
IRDataType.BYTE -> Pair(registers.getSB(i.reg1!!).toInt(), registers.getSB(i.reg2!!).toInt()) 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.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 -> { IRDataType.FLOAT -> {
throw IllegalArgumentException("can't use float here") throw IllegalArgumentException("can't use float here")
} }
@@ -2597,6 +2877,7 @@ class VirtualMachine(irProgram: IRProgram) {
return when(i.type) { return when(i.type) {
IRDataType.BYTE -> Pair(registers.getSB(i.reg1!!).toInt(), i.immediate!!) IRDataType.BYTE -> Pair(registers.getSB(i.reg1!!).toInt(), i.immediate!!)
IRDataType.WORD -> Pair(registers.getSW(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 -> { IRDataType.FLOAT -> {
throw IllegalArgumentException("can't use float here") throw IllegalArgumentException("can't use float here")
} }
@@ -2608,6 +2889,7 @@ class VirtualMachine(irProgram: IRProgram) {
return when(i.type) { return when(i.type) {
IRDataType.BYTE -> Pair(registers.getUB(i.reg1!!).toUInt(), registers.getUB(i.reg2!!).toUInt()) 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.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 -> { IRDataType.FLOAT -> {
throw IllegalArgumentException("can't use float here") throw IllegalArgumentException("can't use float here")
} }
@@ -2619,6 +2901,7 @@ class VirtualMachine(irProgram: IRProgram) {
return when(i.type) { return when(i.type) {
IRDataType.BYTE -> Pair(registers.getUB(i.reg1!!).toUInt(), i.immediate!!.toUInt()) IRDataType.BYTE -> Pair(registers.getUB(i.reg1!!).toUInt(), i.immediate!!.toUInt())
IRDataType.WORD -> Pair(registers.getUW(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 -> { IRDataType.FLOAT -> {
throw IllegalArgumentException("can't use float here") throw IllegalArgumentException("can't use float here")
} }
@@ -2630,6 +2913,7 @@ class VirtualMachine(irProgram: IRProgram) {
return when(i.type) { return when(i.type) {
IRDataType.BYTE -> Pair(registers.getUB(i.reg1!!).toUInt(), registers.getUB(i.reg2!!).toUInt()) 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.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 -> { IRDataType.FLOAT -> {
throw IllegalArgumentException("can't use float here") throw IllegalArgumentException("can't use float here")
} }
@@ -2641,6 +2925,7 @@ class VirtualMachine(irProgram: IRProgram) {
return when(i.type) { return when(i.type) {
IRDataType.BYTE -> Pair(registers.getSB(i.reg1!!).toInt(), registers.getSB(i.reg2!!).toInt()) 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.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 -> { IRDataType.FLOAT -> {
throw IllegalArgumentException("can't use float here") 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 private var window: GraphicsWindow? = null
fun gfx_enable(mode: UByte) { fun gfx_enable(mode: UByte) {
@@ -2754,6 +3076,14 @@ internal fun ArrayDeque<UByte>.pushw(value: UShort) {
add((value.toInt() ushr 8).toUByte()) 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) { internal fun ArrayDeque<UByte>.pushf(value: Double) {
// push float; lsb first, msb last // push float; lsb first, msb last
var bits = value.toBits() var bits = value.toBits()
@@ -2780,6 +3110,14 @@ internal fun ArrayDeque<UByte>.popw(): UShort {
return ((msb.toInt() shl 8) + lsb.toInt()).toUShort() 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 { internal fun ArrayDeque<UByte>.popf(): Double {
// pop float; lsb is on bottom, msb on top // pop float; lsb is on bottom, msb on top
val b0 = removeLast().toLong() val b0 = removeLast().toLong()

View File

@@ -236,6 +236,7 @@ class VmProgramLoader {
dt.isSignedByte -> memory.setSB(addr, 0) dt.isSignedByte -> memory.setSB(addr, 0)
dt.isUnsignedWord || dt.isPointer -> memory.setUW(addr, 0u) dt.isUnsignedWord || dt.isPointer -> memory.setUW(addr, 0u)
dt.isSignedWord -> memory.setSW(addr, 0) dt.isSignedWord -> memory.setSW(addr, 0)
dt.isLong -> memory.setSL(addr, 0)
dt.isFloat -> memory.setFloat(addr, 0.0) dt.isFloat -> memory.setFloat(addr, 0.0)
else -> throw IRParseException("invalid dt") else -> throw IRParseException("invalid dt")
} }
@@ -248,6 +249,7 @@ class VmProgramLoader {
variable.dt.isSignedByte -> memory.setSB(addr, it.toInt().toByte()) variable.dt.isSignedByte -> memory.setSB(addr, it.toInt().toByte())
variable.dt.isUnsignedWord -> memory.setUW(addr, it.toInt().toUShort()) variable.dt.isUnsignedWord -> memory.setUW(addr, it.toInt().toUShort())
variable.dt.isSignedWord -> memory.setSW(addr, it.toInt().toShort()) variable.dt.isSignedWord -> memory.setSW(addr, it.toInt().toShort())
variable.dt.isLong -> memory.setSL(addr, it.toInt())
variable.dt.isFloat -> memory.setFloat(addr, it) variable.dt.isFloat -> memory.setFloat(addr, it)
else -> throw IRParseException("invalid dt") else -> throw IRParseException("invalid dt")
} }