From fc47d3feb85e9fd7a1bb7074cf5468f15c06cbd4 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sun, 7 Apr 2019 23:19:31 +0200 Subject: [PATCH 1/3] repaired min(f) max(f) fixes #13 --- compiler/res/prog8lib/c64flt.p8 | 42 ++++++++++++++++----------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/compiler/res/prog8lib/c64flt.p8 b/compiler/res/prog8lib/c64flt.p8 index c0127f811..a2a536a6b 100644 --- a/compiler/res/prog8lib/c64flt.p8 +++ b/compiler/res/prog8lib/c64flt.p8 @@ -893,46 +893,44 @@ _cmp_mod cpy #255 ; modified .pend func_max_f .proc - lda #<_min_float - ldy #>_min_float - jsr c64flt.MOVFM ; fac1=min(float) lda #255 - sta _cmp_mod+1 ; compare using 255 so we keep larger values -_minmax_entry jsr pop_array_and_lengthmin1Y + sta _minmax_cmp+1 + lda #<_largest_neg_float + ldy #>_largest_neg_float +_minmax_entry jsr MOVFM + jsr prog8_lib.pop_array_and_lengthmin1Y stx c64.SCRATCH_ZPREGX - sty c64.SCRATCH_ZPREG lda c64.SCRATCH_ZPWORD1 ldy c64.SCRATCH_ZPWORD1+1 - jsr c64flt.FCOMP -_cmp_mod cmp #255 ; will be modified + jsr FCOMP +_minmax_cmp cmp #255 ; modified bne + - ; fac1 is smaller/larger, so store the new value instead lda c64.SCRATCH_ZPWORD1 ldy c64.SCRATCH_ZPWORD1+1 - jsr c64flt.MOVFM - ldy c64.SCRATCH_ZPREG - dey - cmp #255 - beq + - lda c64.SCRATCH_ZPWORD1 + jsr MOVFM ++ lda c64.SCRATCH_ZPWORD1 clc adc #5 sta c64.SCRATCH_ZPWORD1 - bcc - + bcc + inc c64.SCRATCH_ZPWORD1+1 ++ ldy c64.SCRATCH_ZPREG + dey bne - -+ jmp push_fac1_as_result -_min_float .byte 255,255,255,255,255 ; -1.7014118345e+38 + jmp push_fac1_as_result + rts +_largest_neg_float .byte 255,255,255,255,255 ; largest negative float -1.7014118345e+38 .pend func_min_f .proc - lda #<_max_float - ldy #>_max_float - jsr c64flt.MOVFM ; fac1=max(float) lda #1 - sta func_max_f._cmp_mod+1 ; compare using 1 so we keep smaller values + sta func_max_f._minmax_cmp+1 + lda #<_largest_pos_float + ldy #>_largest_pos_float jmp func_max_f._minmax_entry -_max_float .byte 255,127,255,255,255 ; 1.7014118345e+38 +_largest_pos_float .byte 255,127,255,255,255 ; largest positive float + rts .pend func_sum_f .proc From ede2b83ce467b847ea97fde8662700febac2f7c8 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Mon, 8 Apr 2019 00:00:43 +0200 Subject: [PATCH 2/3] got rid of unused avg syscalls and fixed stackvm iterable functions (min, max, avg, sum, any, all) --- .../src/prog8/compiler/target/c64/AsmGen.kt | 1 - compiler/src/prog8/stackvm/StackVm.kt | 224 ++++++++++++------ 2 files changed, 149 insertions(+), 76 deletions(-) diff --git a/compiler/src/prog8/compiler/target/c64/AsmGen.kt b/compiler/src/prog8/compiler/target/c64/AsmGen.kt index 0352010a9..14e9a8f65 100644 --- a/compiler/src/prog8/compiler/target/c64/AsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/AsmGen.kt @@ -485,7 +485,6 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, Syscall.FUNC_ALL_F, Syscall.FUNC_MAX_F, Syscall.FUNC_MIN_F, - Syscall.FUNC_AVG_F, Syscall.FUNC_SUM_F -> " jsr c64flt.${call.name.toLowerCase()}" null -> "" else -> " jsr prog8_lib.${call.name.toLowerCase()}" diff --git a/compiler/src/prog8/stackvm/StackVm.kt b/compiler/src/prog8/stackvm/StackVm.kt index 225eee64f..bca05b122 100644 --- a/compiler/src/prog8/stackvm/StackVm.kt +++ b/compiler/src/prog8/stackvm/StackVm.kt @@ -69,11 +69,6 @@ enum class Syscall(val callNr: Short) { FUNC_MIN_UW(122), FUNC_MIN_W(123), FUNC_MIN_F(124), - FUNC_AVG_UB(125), - FUNC_AVG_B(126), - FUNC_AVG_UW(127), - FUNC_AVG_W(128), - FUNC_AVG_F(129), FUNC_SUM_UB(130), FUNC_SUM_B(131), FUNC_SUM_UW(132), @@ -1051,24 +1046,48 @@ class StackVm(private var traceOutputFile: String?) { } Opcode.POP_REGAX_WORD -> { val value=evalstack.pop().integerValue() - val valueA=Value(DataType.UBYTE, value and 255) - val valueX=Value(DataType.UBYTE, value shr 8) + val valueA: Value + val valueX: Value + if(value>=0) { + valueA = Value(DataType.UBYTE, value and 255) + valueX = Value(DataType.UBYTE, value shr 8) + } else { + val value2c = 65536+value + valueA = Value(DataType.UBYTE, value2c and 255) + valueX = Value(DataType.UBYTE, value2c shr 8) + } variables["A"] = valueA variables["X"] = valueX setFlags(valueA.bitor(valueX)) } Opcode.POP_REGAY_WORD -> { val value=evalstack.pop().integerValue() - val valueA=Value(DataType.UBYTE, value and 255) - val valueY=Value(DataType.UBYTE, value shr 8) + val valueA: Value + val valueY: Value + if(value>=0) { + valueA = Value(DataType.UBYTE, value and 255) + valueY = Value(DataType.UBYTE, value shr 8) + } else { + val value2c = 65536+value + valueA = Value(DataType.UBYTE, value2c and 255) + valueY = Value(DataType.UBYTE, value2c shr 8) + } variables["A"] = valueA variables["Y"] = valueY setFlags(valueA.bitor(valueY)) } Opcode.POP_REGXY_WORD -> { val value=evalstack.pop().integerValue() - val valueX=Value(DataType.UBYTE, value and 255) - val valueY=Value(DataType.UBYTE, value shr 8) + val valueX: Value + val valueY: Value + if(value>=0) { + valueX = Value(DataType.UBYTE, value and 255) + valueY = Value(DataType.UBYTE, value shr 8) + } else { + val value2c = 65536+value + valueX = Value(DataType.UBYTE, value2c and 255) + valueY = Value(DataType.UBYTE, value2c shr 8) + } variables["X"] = valueX variables["Y"] = valueY setFlags(valueX.bitor(valueY)) @@ -2049,94 +2068,140 @@ class StackVm(private var traceOutputFile: String?) { else throw VmExecutionException("cannot get ceil of $value") } Syscall.FUNC_MAX_UB -> { - val iterable = evalstack.pop() - val value = heap.get(iterable.heapId) - val result = value.array!!.max() ?: 0 - evalstack.push(Value(DataType.UBYTE, result)) + val length = evalstack.pop().integerValue() + val heapVarId = evalstack.pop().integerValue() + val value = heap.get(heapVarId) + if(length!=value.array!!.size) + throw VmExecutionException("iterable length mismatch") + evalstack.push(Value(DataType.UBYTE, value.array.max() ?: 0)) } Syscall.FUNC_MAX_B -> { - val iterable = evalstack.pop() - val value = heap.get(iterable.heapId) - val result = value.array!!.max() ?: 0 - evalstack.push(Value(DataType.BYTE, result)) + val length = evalstack.pop().integerValue() + val heapVarId = evalstack.pop().integerValue() + val value = heap.get(heapVarId) + if(length!=value.array!!.size) + throw VmExecutionException("iterable length mismatch") + evalstack.push(Value(DataType.BYTE, value.array.max() ?: 0)) } Syscall.FUNC_MAX_UW -> { - val iterable = evalstack.pop() - val value = heap.get(iterable.heapId) - val result = value.array!!.max() ?: 0 - evalstack.push(Value(DataType.UWORD, result)) + val length = evalstack.pop().integerValue() + val heapVarId = evalstack.pop().integerValue() + val value = heap.get(heapVarId) + if(length!=value.array!!.size) + throw VmExecutionException("iterable length mismatch") + evalstack.push(Value(DataType.UWORD, value.array.max() ?: 0)) } Syscall.FUNC_MAX_W -> { - val iterable = evalstack.pop() - val value = heap.get(iterable.heapId) - val result = value.array!!.max() ?: 0 - evalstack.push(Value(DataType.WORD, result)) + val length = evalstack.pop().integerValue() + val heapVarId = evalstack.pop().integerValue() + val value = heap.get(heapVarId) + if(length!=value.array!!.size) + throw VmExecutionException("iterable length mismatch") + evalstack.push(Value(DataType.WORD, value.array.max() ?: 0)) } Syscall.FUNC_MAX_F -> { - val iterable = evalstack.pop() - val value = heap.get(iterable.heapId) - val result = value.array!!.max() ?: 0 - evalstack.push(Value(DataType.FLOAT, result)) + val length = evalstack.pop().integerValue() + val heapVarId = evalstack.pop().integerValue() + val value = heap.get(heapVarId) + if(length!=value.doubleArray!!.size) + throw VmExecutionException("iterable length mismatch") + evalstack.push(Value(DataType.FLOAT, value.doubleArray.max() ?: 0.0)) } Syscall.FUNC_MIN_UB -> { - val iterable = evalstack.pop() - val value = heap.get(iterable.heapId) - val result = value.array!!.min() ?: 0 - evalstack.push(Value(DataType.UBYTE, result)) + val length = evalstack.pop().integerValue() + val heapVarId = evalstack.pop().integerValue() + val value = heap.get(heapVarId) + if(length!=value.array!!.size) + throw VmExecutionException("iterable length mismatch") + evalstack.push(Value(DataType.UBYTE, value.array.min() ?: 0)) } Syscall.FUNC_MIN_B -> { - val iterable = evalstack.pop() - val value = heap.get(iterable.heapId) - val result = value.array!!.min() ?: 0 - evalstack.push(Value(DataType.BYTE, result)) + val length = evalstack.pop().integerValue() + val heapVarId = evalstack.pop().integerValue() + val value = heap.get(heapVarId) + if(length!=value.array!!.size) + throw VmExecutionException("iterable length mismatch") + evalstack.push(Value(DataType.BYTE, value.array.min() ?: 0)) } Syscall.FUNC_MIN_UW -> { - val iterable = evalstack.pop() - val value = heap.get(iterable.heapId) - val result = value.array!!.min() ?: 0 - evalstack.push(Value(DataType.UWORD, result)) + val length = evalstack.pop().integerValue() + val heapVarId = evalstack.pop().integerValue() + val value = heap.get(heapVarId) + if(length!=value.array!!.size) + throw VmExecutionException("iterable length mismatch") + evalstack.push(Value(DataType.UWORD, value.array.min() ?: 0)) } Syscall.FUNC_MIN_W -> { - val iterable = evalstack.pop() - val value = heap.get(iterable.heapId) - val result = value.array!!.min() ?: 0 - evalstack.push(Value(DataType.WORD, result)) + val length = evalstack.pop().integerValue() + val heapVarId = evalstack.pop().integerValue() + val value = heap.get(heapVarId) + if(length!=value.array!!.size) + throw VmExecutionException("iterable length mismatch") + evalstack.push(Value(DataType.WORD, value.array.min() ?: 0)) } Syscall.FUNC_MIN_F -> { - val iterable = evalstack.pop() - val value = heap.get(iterable.heapId) - val result = value.array!!.min() ?: 0 - evalstack.push(Value(DataType.FLOAT, result)) + val length = evalstack.pop().integerValue() + val heapVarId = evalstack.pop().integerValue() + val value = heap.get(heapVarId) + if(length!=value.doubleArray!!.size) + throw VmExecutionException("iterable length mismatch") + evalstack.push(Value(DataType.FLOAT, value.doubleArray.min() ?: 0.0)) } - Syscall.FUNC_AVG_UB, Syscall.FUNC_AVG_B, Syscall.FUNC_AVG_UW, Syscall.FUNC_AVG_W, Syscall.FUNC_AVG_F -> { - val iterable = evalstack.pop() - val value = heap.get(iterable.heapId) - evalstack.push(Value(DataType.FLOAT, value.array!!.average())) + Syscall.FUNC_SUM_W, Syscall.FUNC_SUM_B -> { + val length = evalstack.pop().integerValue() + val heapVarId = evalstack.pop().integerValue() + val value = heap.get(heapVarId) + if(length!=value.array!!.size) + throw VmExecutionException("iterable length mismatch") + evalstack.push(Value(DataType.WORD, value.array.sum())) } - Syscall.FUNC_SUM_UB -> { - val iterable = evalstack.pop() - val value = heap.get(iterable.heapId) - evalstack.push(Value(DataType.UWORD, value.array!!.sum())) + Syscall.FUNC_SUM_UW, Syscall.FUNC_SUM_UB -> { + val length = evalstack.pop().integerValue() + val heapVarId = evalstack.pop().integerValue() + val value = heap.get(heapVarId) + if(length!=value.array!!.size) + throw VmExecutionException("iterable length mismatch") + evalstack.push(Value(DataType.UWORD, value.array.sum())) } - Syscall.FUNC_SUM_B -> { - val iterable = evalstack.pop() - val value = heap.get(iterable.heapId) - evalstack.push(Value(DataType.WORD, value.array!!.sum())) + Syscall.FUNC_SUM_F -> { + val length = evalstack.pop().integerValue() + val heapVarId = evalstack.pop().integerValue() + val value = heap.get(heapVarId) + if(length!=value.doubleArray!!.size) + throw VmExecutionException("iterable length mismatch") + evalstack.push(Value(DataType.FLOAT, value.doubleArray.sum())) } - Syscall.FUNC_SUM_UW, Syscall.FUNC_SUM_W, Syscall.FUNC_SUM_F -> { - val iterable = evalstack.pop() - val value = heap.get(iterable.heapId) - evalstack.push(Value(DataType.FLOAT, value.array!!.sum())) + Syscall.FUNC_ANY_B, Syscall.FUNC_ANY_W -> { + val length = evalstack.pop().integerValue() + val heapVarId = evalstack.pop().integerValue() + val value = heap.get(heapVarId) + if(length!=value.array!!.size) + throw VmExecutionException("iterable length mismatch") + evalstack.push(Value(DataType.UBYTE, if (value.array.any { v -> v != 0 }) 1 else 0)) } - Syscall.FUNC_ANY_B, Syscall.FUNC_ANY_W, Syscall.FUNC_ANY_F -> { - val iterable = evalstack.pop() - val value = heap.get(iterable.heapId) - evalstack.push(Value(DataType.UBYTE, if (value.array!!.any { v -> v != 0 }) 1 else 0)) + Syscall.FUNC_ANY_F -> { + val length = evalstack.pop().integerValue() + val heapVarId = evalstack.pop().integerValue() + val value = heap.get(heapVarId) + if(length!=value.doubleArray!!.size) + throw VmExecutionException("iterable length mismatch") + evalstack.push(Value(DataType.UBYTE, if (value.doubleArray.any { v -> v != 0.0 }) 1 else 0)) } - Syscall.FUNC_ALL_B, Syscall.FUNC_ALL_W, Syscall.FUNC_ALL_F -> { - val iterable = evalstack.pop() - val value = heap.get(iterable.heapId) - evalstack.push(Value(DataType.UBYTE, if (value.array!!.all { v -> v != 0 }) 1 else 0)) + Syscall.FUNC_ALL_B, Syscall.FUNC_ALL_W -> { + val length = evalstack.pop().integerValue() + val heapVarId = evalstack.pop().integerValue() + val value = heap.get(heapVarId) + if(length!=value.array!!.size) + throw VmExecutionException("iterable length mismatch") + evalstack.push(Value(DataType.UBYTE, if (value.array.all { v -> v != 0 }) 1 else 0)) + } + Syscall.FUNC_ALL_F -> { + val length = evalstack.pop().integerValue() + val heapVarId = evalstack.pop().integerValue() + val value = heap.get(heapVarId) + if(length!=value.doubleArray!!.size) + throw VmExecutionException("iterable length mismatch") + evalstack.push(Value(DataType.UBYTE, if (value.doubleArray.all { v -> v != 0.0 }) 1 else 0)) } Syscall.FUNC_MEMCOPY -> { val numbytes = evalstack.pop().integerValue() @@ -2191,6 +2256,15 @@ class StackVm(private var traceOutputFile: String?) { val number = lo+256*hi canvas?.printText(number.toString(), 1, true) } + Syscall.SYSASM_c64scr_print_w -> { + val lo = variables.getValue("A").integerValue() + val hi = variables.getValue("Y").integerValue() + val number = lo+256*hi + if(number<=32767) + canvas?.printText(number.toString(), 1, true) + else + canvas?.printText("-${65536-number}", 1, true) + } Syscall.SYSASM_c64flt_print_f -> { val number = variables.getValue("c64flt.print_f.value").numericValue() canvas?.printText(number.toString(), 1, true) From fd19298a05a37fb7b59821ead211610742bd9e74 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Mon, 8 Apr 2019 00:08:23 +0200 Subject: [PATCH 3/3] fixed stackvm pop signed byte into register --- compiler/src/prog8/stackvm/StackVm.kt | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/compiler/src/prog8/stackvm/StackVm.kt b/compiler/src/prog8/stackvm/StackVm.kt index bca05b122..d5006b41e 100644 --- a/compiler/src/prog8/stackvm/StackVm.kt +++ b/compiler/src/prog8/stackvm/StackVm.kt @@ -1097,8 +1097,11 @@ class StackVm(private var traceOutputFile: String?) { checkDt(value, DataType.UBYTE, DataType.BYTE) val variable = getVar(ins.callLabel!!) checkDt(variable, DataType.UBYTE, DataType.BYTE) - if(value.type!=variable.type) - throw VmExecutionException("datatype mismatch") + if(value.type!=variable.type) { + if(ins.callLabel !in Register.values().map { it.name }) { + throw VmExecutionException("datatype mismatch") + } + } variables[ins.callLabel] = value setFlags(value) } @@ -2250,6 +2253,13 @@ class StackVm(private var traceOutputFile: String?) { val num = variables.getValue("A").integerValue() canvas?.printText(num.toString(), 1, true) } + Syscall.SYSASM_c64scr_print_b -> { + val num = variables.getValue("A").integerValue() + if(num<=127) + canvas?.printText(num.toString(), 1, true) + else + canvas?.printText("-${256-num}", 1, true) + } Syscall.SYSASM_c64scr_print_uw -> { val lo = variables.getValue("A").integerValue() val hi = variables.getValue("Y").integerValue()