Merge branch 'master' into pointerto

# Conflicts:
#	compiler/res/prog8lib/c64flt.p8
#	compiler/src/prog8/stackvm/StackVm.kt
This commit is contained in:
Irmen de Jong 2019-04-08 00:19:18 +02:00
commit 1dde49d644
3 changed files with 240 additions and 158 deletions

View File

@ -34,7 +34,6 @@
memory float FL_PIHALF = $e2e0 ; PI / 2
memory float FL_TWOPI = $e2e5 ; 2 * PI
memory float FL_FR4 = $e2ea ; .25
float FL_ZERO = 0.0 ; oddly enough 0.0 isn't available in the kernel
; note: fac1/2 might get clobbered even if not mentioned in the function's name.
@ -776,8 +775,8 @@ func_log2 .proc
stx c64.SCRATCH_ZPREGX
jsr c64flt.LOG
jsr c64flt.MOVEF
lda #<FL_LOG2
ldy #>FL_LOG2
lda #<c64.FL_LOG2
ldy #>c64.FL_LOG2
jsr c64flt.MOVFM
jsr c64flt.FDIVT
jmp push_fac1_as_result
@ -854,7 +853,7 @@ func_any_f .proc
asl a
clc
adc c64.SCRATCH_ZPB1 ; times 5 because of float
jmp prog8_lib.func_any_b._entry
jmp func_any_b._entry
.pend
func_all_f .proc
@ -866,7 +865,7 @@ func_all_f .proc
clc
adc c64.SCRATCH_ZPB1 ; times 5 because of float
sta _cmp_mod+1 ; self-modifying code
jsr prog8_lib.peek_address
jsr peek_address
ldy #0
- lda (c64.SCRATCH_ZPWORD1),y
bne +
@ -894,18 +893,51 @@ _cmp_mod cpy #255 ; modified
.pend
func_max_f .proc
.warn "todo: fix func_max_f / func_min_f" ; TODO
lda #255
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 FCOMP
_minmax_cmp cmp #255 ; modified
bne +
lda c64.SCRATCH_ZPWORD1
ldy c64.SCRATCH_ZPWORD1+1
jsr MOVFM
+ lda c64.SCRATCH_ZPWORD1
clc
adc #5
sta c64.SCRATCH_ZPWORD1
bcc +
inc c64.SCRATCH_ZPWORD1+1
+ ldy c64.SCRATCH_ZPREG
dey
bne -
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
.warn "todo: fix func_max_f / func_min_f" ; TODO
lda #1
sta func_max_f._minmax_cmp+1
lda #<_largest_pos_float
ldy #>_largest_pos_float
jmp func_max_f._minmax_entry
_largest_pos_float .byte 255,127,255,255,255 ; largest positive float
rts
.pend
func_sum_f .proc
lda #<FL_ZERO
ldy #>FL_ZERO
lda #<c64.FL_NEGHLF
ldy #>c64.FL_NEGHLF
jsr c64flt.MOVFM
jsr prog8_lib.pop_array_and_lengthmin1Y
jsr pop_array_and_lengthmin1Y
stx c64.SCRATCH_ZPREGX
- sty c64.SCRATCH_ZPREG
lda c64.SCRATCH_ZPWORD1
@ -922,7 +954,8 @@ func_sum_f .proc
bcc -
inc c64.SCRATCH_ZPWORD1+1
bne -
+ jmp push_fac1_as_result
+ jsr c64flt.FADDH
jmp push_fac1_as_result
.pend
}}

View File

@ -494,7 +494,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()}"

View File

@ -70,11 +70,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),
@ -1052,24 +1047,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))
@ -1079,8 +1098,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)
if(value.type!=variable.type) {
if(ins.callLabel !in Register.values().map { it.name }) {
throw VmExecutionException("datatype mismatch")
}
}
variables[ins.callLabel] = value
setFlags(value)
}
@ -2056,128 +2078,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)
if(value.array!!.any{it.integer==null})
throw VmExecutionException("cannot deal with PointerTo value in array $value")
val result = value.array.map{it.integer!!}.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)
if(value.array!!.any{it.integer==null})
throw VmExecutionException("cannot deal with PointerTo value in array $value")
val result = value.array.map{it.integer!!}.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)
if(value.array!!.any{it.integer==null})
throw VmExecutionException("cannot deal with PointerTo value in array $value")
val result = value.array.map{it.integer!!}.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)
if(value.array!!.any{it.integer==null})
throw VmExecutionException("cannot deal with PointerTo value in array $value")
val result = value.array.map{it.integer!!}.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.doubleArray!!.max() ?: 0.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)
if(value.array!!.any{it.integer==null})
throw VmExecutionException("cannot deal with PointerTo value in array $value")
val result = value.array.map{it.integer!!}.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)
if(value.array!!.any{it.integer==null})
throw VmExecutionException("cannot deal with PointerTo value in array $value")
val result = value.array.map{it.integer!!}.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)
if(value.array!!.any{it.integer==null})
throw VmExecutionException("cannot deal with PointerTo value in array $value")
val result = value.array.map{it.integer!!}.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)
if(value.array!!.any{it.integer==null})
throw VmExecutionException("cannot deal with PointerTo value in array $value")
val result = value.array.map{it.integer!!}.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.doubleArray!!.min() ?: 0.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 -> {
val iterable = evalstack.pop()
val value = heap.get(iterable.heapId)
if(value.array!!.any{it.integer==null})
throw VmExecutionException("cannot deal with PointerTo value in array $value")
evalstack.push(Value(DataType.FLOAT, value.array.map{it.integer!!}.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_AVG_F -> {
val iterable = evalstack.pop()
val value = heap.get(iterable.heapId)
evalstack.push(Value(DataType.FLOAT, value.doubleArray!!.average()))
}
Syscall.FUNC_SUM_UB -> {
val iterable = evalstack.pop()
val value = heap.get(iterable.heapId)
if(value.array!!.any{it.integer==null})
throw VmExecutionException("cannot deal with PointerTo value in array $value")
evalstack.push(Value(DataType.UWORD, value.array.map{it.integer!!}.sum()))
}
Syscall.FUNC_SUM_B -> {
val iterable = evalstack.pop()
val value = heap.get(iterable.heapId)
if(value.array!!.any{it.integer==null})
throw VmExecutionException("cannot deal with PointerTo value in array $value")
evalstack.push(Value(DataType.WORD, value.array.map{it.integer!!}.sum()))
}
Syscall.FUNC_SUM_UW, Syscall.FUNC_SUM_W -> {
val iterable = evalstack.pop()
val value = heap.get(iterable.heapId)
if(value.array!!.any{it.integer==null})
throw VmExecutionException("cannot deal with PointerTo value in array $value")
evalstack.push(Value(DataType.FLOAT, value.array.map{it.integer!!}.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_F -> {
val iterable = evalstack.pop()
val value = heap.get(iterable.heapId)
evalstack.push(Value(DataType.FLOAT, value.doubleArray!!.sum()))
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_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.pointerOf!=null || (v.integer!=null && v.integer != 0) }) 1 else 0))
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_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.pointerOf!=null || (v.integer!=null && v.integer != 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.pointerOf!=null || (v.integer!=null && v.integer != 0.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.pointerOf!=null || (v.integer!=null && v.integer != 0.0) }) 1 else 0))
}
Syscall.FUNC_MEMCOPY -> {
val numbytes = evalstack.pop().integerValue()
@ -2226,12 +2260,28 @@ 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()
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)