fix abs(long), mklong(), mklong2(), peekl(), pokel()

This commit is contained in:
Irmen de Jong
2025-10-12 14:06:21 +02:00
parent 6db3611d93
commit d69eead6d8
4 changed files with 59 additions and 78 deletions

View File

@@ -887,8 +887,8 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
assignAsmGen.assignRegisterpairWord(AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.AY, false, fcall.position, scope, asmgen), RegisterOrPair.AY) assignAsmGen.assignRegisterpairWord(AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.AY, false, fcall.position, scope, asmgen), RegisterOrPair.AY)
} }
BaseDataType.LONG -> { BaseDataType.LONG -> {
asmgen.out(" jsr prog8_lib.abs_l_into_R0R1") asmgen.out(" jsr prog8_lib.abs_l_into_R14R15")
assignAsmGen.assignRegisterLong(AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.R0R1_32, true, fcall.position, scope, asmgen), RegisterOrPair.R0R1_32) assignAsmGen.assignRegisterLong(AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.R14R15_32, true, fcall.position, scope, asmgen), RegisterOrPair.R14R15_32)
} }
BaseDataType.FLOAT -> { BaseDataType.FLOAT -> {
asmgen.out(" jsr floats.func_abs_f_into_FAC1") asmgen.out(" jsr floats.func_abs_f_into_FAC1")
@@ -1059,7 +1059,8 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.AY) asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.AY)
asmgen.saveRegisterStack(CpuRegister.A, false) asmgen.saveRegisterStack(CpuRegister.A, false)
asmgen.saveRegisterStack(CpuRegister.Y, false) asmgen.saveRegisterStack(CpuRegister.Y, false)
asmgen.assignExpressionToRegister(fcall.args[1], RegisterOrPair.R0R1_32, true) // it's a statement so no need to preserve R14:R15
asmgen.assignExpressionToRegister(fcall.args[1], RegisterOrPair.R14R15_32, true)
asmgen.restoreRegisterStack(CpuRegister.Y, false) asmgen.restoreRegisterStack(CpuRegister.Y, false)
asmgen.restoreRegisterStack(CpuRegister.A, false) asmgen.restoreRegisterStack(CpuRegister.A, false)
asmgen.out(" jsr prog8_lib.func_pokel") asmgen.out(" jsr prog8_lib.func_pokel")
@@ -1190,8 +1191,8 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
// TODO optimize for the simple cases // TODO optimize for the simple cases
asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.AY) asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.AY)
asmgen.out(" jsr prog8_lib.func_peekl") asmgen.out(" jsr prog8_lib.func_peekl")
val targetReg = AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.R0R1_32, true, fcall.position, fcall.definingISub(), asmgen) val targetReg = AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.R14R15_32, true, fcall.position, fcall.definingISub(), asmgen)
assignAsmGen.assignRegisterLong(targetReg, RegisterOrPair.R0R1_32) assignAsmGen.assignRegisterLong(targetReg, RegisterOrPair.R14R15_32)
} }
@@ -1357,7 +1358,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
} }
private fun funcMklong(fcall: PtBuiltinFunctionCall) { private fun funcMklong(fcall: PtBuiltinFunctionCall) {
// result long in R0:R1 (r0=lsw, r1=msw) // result long in R14:R15 (r14=lsw, r15=msw)
fun isArgRegister(expression: PtExpression, reg: RegisterOrPair): Boolean { fun isArgRegister(expression: PtExpression, reg: RegisterOrPair): Boolean {
if(expression !is PtIdentifier) if(expression !is PtIdentifier)
@@ -1367,25 +1368,25 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
if(fcall.args.size==2) { if(fcall.args.size==2) {
// mklong2(msw, lsw) // mklong2(msw, lsw)
if(isArgRegister(fcall.args[0], RegisterOrPair.R0) || isArgRegister(fcall.args[0], RegisterOrPair.R1) || if(isArgRegister(fcall.args[0], RegisterOrPair.R14) || isArgRegister(fcall.args[0], RegisterOrPair.R15) ||
isArgRegister(fcall.args[1], RegisterOrPair.R0) || isArgRegister(fcall.args[1], RegisterOrPair.R1)) { isArgRegister(fcall.args[1], RegisterOrPair.R14) || isArgRegister(fcall.args[1], RegisterOrPair.R15)) {
error("cannot use R0 and/or R1 as arguments for mklong2 because the result should go into R0:R1 ${fcall.position}") error("cannot use R14 and/or R15 as arguments for mklong2 because the result should go into R0:R1 ${fcall.position}")
} else { } else {
assignAsmGen.assignExpressionToVariable(fcall.args[0], "cx16.r1", DataType.UWORD) assignAsmGen.assignExpressionToVariable(fcall.args[0], "cx16.r15", DataType.UWORD)
assignAsmGen.assignExpressionToVariable(fcall.args[1], "cx16.r0", DataType.UWORD) assignAsmGen.assignExpressionToVariable(fcall.args[1], "cx16.r14", DataType.UWORD)
} }
} else { } else {
// mklong(msb, b2, b1, lsb) // mklong(msb, b2, b1, lsb)
if(isArgRegister(fcall.args[0], RegisterOrPair.R0) || isArgRegister(fcall.args[0], RegisterOrPair.R1) || if(isArgRegister(fcall.args[0], RegisterOrPair.R14) || isArgRegister(fcall.args[0], RegisterOrPair.R15) ||
isArgRegister(fcall.args[1], RegisterOrPair.R0) || isArgRegister(fcall.args[1], RegisterOrPair.R1) || isArgRegister(fcall.args[1], RegisterOrPair.R14) || isArgRegister(fcall.args[1], RegisterOrPair.R15) ||
isArgRegister(fcall.args[2], RegisterOrPair.R0) || isArgRegister(fcall.args[2], RegisterOrPair.R1) || isArgRegister(fcall.args[2], RegisterOrPair.R14) || isArgRegister(fcall.args[2], RegisterOrPair.R15) ||
isArgRegister(fcall.args[3], RegisterOrPair.R0) || isArgRegister(fcall.args[3], RegisterOrPair.R1)) { isArgRegister(fcall.args[3], RegisterOrPair.R14) || isArgRegister(fcall.args[3], RegisterOrPair.R15)) {
error("cannot use R0 and/or R1 as arguments for mklong because the result should go into R0:R1 ${fcall.position}") error("cannot use R14 and/or R15 as arguments for mklong because the result should go into R14:R15 ${fcall.position}")
} else { } else {
assignAsmGen.assignExpressionToVariable(fcall.args[0], "cx16.r1H", DataType.UBYTE) assignAsmGen.assignExpressionToVariable(fcall.args[0], "cx16.r15H", DataType.UBYTE)
assignAsmGen.assignExpressionToVariable(fcall.args[1], "cx16.r1L", DataType.UBYTE) assignAsmGen.assignExpressionToVariable(fcall.args[1], "cx16.r15L", DataType.UBYTE)
assignAsmGen.assignExpressionToVariable(fcall.args[2], "cx16.r0H", DataType.UBYTE) assignAsmGen.assignExpressionToVariable(fcall.args[2], "cx16.r14H", DataType.UBYTE)
assignAsmGen.assignExpressionToVariable(fcall.args[3], "cx16.r0L", DataType.UBYTE) assignAsmGen.assignExpressionToVariable(fcall.args[3], "cx16.r14L", DataType.UBYTE)
} }
} }
} }

View File

@@ -655,8 +655,8 @@ internal class AssignmentAsmGen(
} }
} }
returnDt== BaseDataType.LONG -> { returnDt== BaseDataType.LONG -> {
// longs are in R0:R1 (r0=lsw, r1=msw) // longs are in R14:R15 (r14=lsw, r15=msw)
assignRegisterLong(target, RegisterOrPair.R0R1_32) assignRegisterLong(target, RegisterOrPair.R14R15_32)
} }
returnDt==BaseDataType.FLOAT -> { returnDt==BaseDataType.FLOAT -> {
// float result from function sits in FAC1 // float result from function sits in FAC1
@@ -3923,7 +3923,7 @@ $endLabel""")
else throw AssemblyError("only combined vreg allowed as long target ${target.position}") else throw AssemblyError("only combined vreg allowed as long target ${target.position}")
} }
TargetStorageKind.ARRAY -> { TargetStorageKind.ARRAY -> {
TODO("assign 32 bits int in R0:R1 into array ${target.position}") TODO("assign 32 bits int into array ${target.position}")
} }
TargetStorageKind.MEMORY -> throw AssemblyError("memory is bytes not long ${target.position}") TargetStorageKind.MEMORY -> throw AssemblyError("memory is bytes not long ${target.position}")
TargetStorageKind.REGISTER -> { TargetStorageKind.REGISTER -> {

View File

@@ -29,33 +29,33 @@ abs_w_into_AY .proc
+ rts + rts
.pend .pend
abs_l_into_R0R1 .proc abs_l_into_R14R15 .proc
; -- R0:R1 = abs(R0:R1) ; -- R14:R15 = abs(R14:R15)
lda cx16.r1H lda cx16.r15H
bmi + ; Negative if high bit of highest byte is set bmi + ; Negative if high bit of highest byte is set
rts rts
+ +
; Invert all four bytes ; Invert all four bytes
lda cx16.r0L lda cx16.r14L
eor #$FF eor #$FF
sta cx16.r0L sta cx16.r14L
lda cx16.r0H lda cx16.r14H
eor #$FF eor #$FF
sta cx16.r0H sta cx16.r14H
lda cx16.r1L lda cx16.r15L
eor #$FF eor #$FF
sta cx16.r1L sta cx16.r15L
lda cx16.r1H lda cx16.r15H
eor #$FF eor #$FF
sta cx16.r1H sta cx16.r15H
; Add 1 to whole 32-bit value ; Add 1 to whole 32-bit value
inc cx16.r0L inc cx16.r14L
bne + bne +
inc cx16.r0H inc cx16.r14H
bne + bne +
inc cx16.r1L inc cx16.r15L
bne + bne +
inc cx16.r1H inc cx16.r15H
+ rts + rts
.pend .pend
@@ -479,22 +479,22 @@ from_scratchW1
.pend .pend
func_peekl .proc func_peekl .proc
; -- read the ;pmg value on the address in AY, into R0:R1 ; -- read the ;pmg value on the address in AY, into R14:R15
sta P8ZP_SCRATCH_W1 sta P8ZP_SCRATCH_W1
sty P8ZP_SCRATCH_W1+1 sty P8ZP_SCRATCH_W1+1
from_scratchW1 from_scratchW1
ldy #0 ldy #0
lda (P8ZP_SCRATCH_W1),y lda (P8ZP_SCRATCH_W1),y
sta cx16.r0 sta cx16.r14
iny iny
lda (P8ZP_SCRATCH_W1),y lda (P8ZP_SCRATCH_W1),y
sta cx16.r0+1 sta cx16.r14+1
iny iny
lda (P8ZP_SCRATCH_W1),y lda (P8ZP_SCRATCH_W1),y
sta cx16.r0+2 sta cx16.r14+2
iny iny
lda (P8ZP_SCRATCH_W1),y lda (P8ZP_SCRATCH_W1),y
sta cx16.r0+3 sta cx16.r14+3
rts rts
.pend .pend
@@ -522,20 +522,20 @@ func_pokew_scratchW2 .proc
.pend .pend
func_pokel .proc func_pokel .proc
; -- store the long value in R0:R1 in the address in AY ; -- store the long value in R14:R15 in the address in AY
sta P8ZP_SCRATCH_W1 sta P8ZP_SCRATCH_W1
sty P8ZP_SCRATCH_W1+1 sty P8ZP_SCRATCH_W1+1
ldy #0 ldy #0
lda cx16.r0 lda cx16.r14
sta (P8ZP_SCRATCH_W1),y sta (P8ZP_SCRATCH_W1),y
iny iny
lda cx16.r0+1 lda cx16.r14+1
sta (P8ZP_SCRATCH_W1),y sta (P8ZP_SCRATCH_W1),y
iny iny
lda cx16.r0+2 lda cx16.r14+2
sta (P8ZP_SCRATCH_W1),y sta (P8ZP_SCRATCH_W1),y
iny iny
lda cx16.r0+3 lda cx16.r14+3
sta (P8ZP_SCRATCH_W1),y sta (P8ZP_SCRATCH_W1),y
rts rts
.pend .pend

View File

@@ -3,42 +3,22 @@
main { main {
sub start() { sub start() {
long @shared lv1, lv2, lv3 long @shared lv1 = -123456
cx16.r0 = 12345 txt.print_l(abs(lv1))
txt.print_l(cx16.r0)
txt.spc() txt.spc()
cx16.r0s = -9999
txt.print_l(cx16.r0) lv1 = -99999
lv1 = abs(lv1)
txt.print_l(abs(lv1))
txt.nl() txt.nl()
txt.print("sgns:\n") cx16.r4 = $1122
word @shared w1, w2, w3 cx16.r5 = $abcd
w1 = $1100 txt.print_ulhex(mklong(cx16.r5H,cx16.r5L,cx16.r4H,cx16.r4L), true)
w2 = $ff00 as word
w3 = $0000
txt.print_b(sgn(w1))
txt.spc() txt.spc()
txt.print_b(sgn(w2)) txt.print_ulhex(mklong2(cx16.r5,cx16.r4), true)
txt.spc()
txt.print_b(sgn(w3))
txt.nl() txt.nl()
lv1= 333333
lv2 = -22222
lv3 = 0
txt.print_b(sgn(lv1))
txt.spc()
txt.print_b(sgn(lv2))
txt.spc()
txt.print_b(sgn(lv3))
txt.nl()
lv2 = 555555
lv3 = 222222
txt.print_bool(lv1 >= lv2+4*lv3)
txt.nl()
} }
} }