mirror of
https://github.com/irmen/prog8.git
synced 2025-11-23 14:17:51 +00:00
fix abs(long), mklong(), mklong2(), peekl(), pokel()
This commit is contained in:
@@ -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)
|
||||
}
|
||||
BaseDataType.LONG -> {
|
||||
asmgen.out(" jsr prog8_lib.abs_l_into_R0R1")
|
||||
assignAsmGen.assignRegisterLong(AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.R0R1_32, true, fcall.position, scope, asmgen), RegisterOrPair.R0R1_32)
|
||||
asmgen.out(" jsr prog8_lib.abs_l_into_R14R15")
|
||||
assignAsmGen.assignRegisterLong(AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.R14R15_32, true, fcall.position, scope, asmgen), RegisterOrPair.R14R15_32)
|
||||
}
|
||||
BaseDataType.FLOAT -> {
|
||||
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.saveRegisterStack(CpuRegister.A, 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.A, false)
|
||||
asmgen.out(" jsr prog8_lib.func_pokel")
|
||||
@@ -1190,8 +1191,8 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||
// TODO optimize for the simple cases
|
||||
asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.AY)
|
||||
asmgen.out(" jsr prog8_lib.func_peekl")
|
||||
val targetReg = AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.R0R1_32, true, fcall.position, fcall.definingISub(), asmgen)
|
||||
assignAsmGen.assignRegisterLong(targetReg, RegisterOrPair.R0R1_32)
|
||||
val targetReg = AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.R14R15_32, true, fcall.position, fcall.definingISub(), asmgen)
|
||||
assignAsmGen.assignRegisterLong(targetReg, RegisterOrPair.R14R15_32)
|
||||
}
|
||||
|
||||
|
||||
@@ -1357,7 +1358,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||
}
|
||||
|
||||
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 {
|
||||
if(expression !is PtIdentifier)
|
||||
@@ -1367,25 +1368,25 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||
|
||||
if(fcall.args.size==2) {
|
||||
// mklong2(msw, lsw)
|
||||
if(isArgRegister(fcall.args[0], RegisterOrPair.R0) || isArgRegister(fcall.args[0], RegisterOrPair.R1) ||
|
||||
isArgRegister(fcall.args[1], RegisterOrPair.R0) || isArgRegister(fcall.args[1], RegisterOrPair.R1)) {
|
||||
error("cannot use R0 and/or R1 as arguments for mklong2 because the result should go into R0:R1 ${fcall.position}")
|
||||
if(isArgRegister(fcall.args[0], RegisterOrPair.R14) || isArgRegister(fcall.args[0], RegisterOrPair.R15) ||
|
||||
isArgRegister(fcall.args[1], RegisterOrPair.R14) || isArgRegister(fcall.args[1], RegisterOrPair.R15)) {
|
||||
error("cannot use R14 and/or R15 as arguments for mklong2 because the result should go into R0:R1 ${fcall.position}")
|
||||
} else {
|
||||
assignAsmGen.assignExpressionToVariable(fcall.args[0], "cx16.r1", DataType.UWORD)
|
||||
assignAsmGen.assignExpressionToVariable(fcall.args[1], "cx16.r0", DataType.UWORD)
|
||||
assignAsmGen.assignExpressionToVariable(fcall.args[0], "cx16.r15", DataType.UWORD)
|
||||
assignAsmGen.assignExpressionToVariable(fcall.args[1], "cx16.r14", DataType.UWORD)
|
||||
}
|
||||
} else {
|
||||
// mklong(msb, b2, b1, lsb)
|
||||
if(isArgRegister(fcall.args[0], RegisterOrPair.R0) || isArgRegister(fcall.args[0], RegisterOrPair.R1) ||
|
||||
isArgRegister(fcall.args[1], RegisterOrPair.R0) || isArgRegister(fcall.args[1], RegisterOrPair.R1) ||
|
||||
isArgRegister(fcall.args[2], RegisterOrPair.R0) || isArgRegister(fcall.args[2], RegisterOrPair.R1) ||
|
||||
isArgRegister(fcall.args[3], RegisterOrPair.R0) || isArgRegister(fcall.args[3], RegisterOrPair.R1)) {
|
||||
error("cannot use R0 and/or R1 as arguments for mklong because the result should go into R0:R1 ${fcall.position}")
|
||||
if(isArgRegister(fcall.args[0], RegisterOrPair.R14) || isArgRegister(fcall.args[0], RegisterOrPair.R15) ||
|
||||
isArgRegister(fcall.args[1], RegisterOrPair.R14) || isArgRegister(fcall.args[1], RegisterOrPair.R15) ||
|
||||
isArgRegister(fcall.args[2], RegisterOrPair.R14) || isArgRegister(fcall.args[2], RegisterOrPair.R15) ||
|
||||
isArgRegister(fcall.args[3], RegisterOrPair.R14) || isArgRegister(fcall.args[3], RegisterOrPair.R15)) {
|
||||
error("cannot use R14 and/or R15 as arguments for mklong because the result should go into R14:R15 ${fcall.position}")
|
||||
} else {
|
||||
assignAsmGen.assignExpressionToVariable(fcall.args[0], "cx16.r1H", DataType.UBYTE)
|
||||
assignAsmGen.assignExpressionToVariable(fcall.args[1], "cx16.r1L", DataType.UBYTE)
|
||||
assignAsmGen.assignExpressionToVariable(fcall.args[2], "cx16.r0H", DataType.UBYTE)
|
||||
assignAsmGen.assignExpressionToVariable(fcall.args[3], "cx16.r0L", DataType.UBYTE)
|
||||
assignAsmGen.assignExpressionToVariable(fcall.args[0], "cx16.r15H", DataType.UBYTE)
|
||||
assignAsmGen.assignExpressionToVariable(fcall.args[1], "cx16.r15L", DataType.UBYTE)
|
||||
assignAsmGen.assignExpressionToVariable(fcall.args[2], "cx16.r14H", DataType.UBYTE)
|
||||
assignAsmGen.assignExpressionToVariable(fcall.args[3], "cx16.r14L", DataType.UBYTE)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -655,8 +655,8 @@ internal class AssignmentAsmGen(
|
||||
}
|
||||
}
|
||||
returnDt== BaseDataType.LONG -> {
|
||||
// longs are in R0:R1 (r0=lsw, r1=msw)
|
||||
assignRegisterLong(target, RegisterOrPair.R0R1_32)
|
||||
// longs are in R14:R15 (r14=lsw, r15=msw)
|
||||
assignRegisterLong(target, RegisterOrPair.R14R15_32)
|
||||
}
|
||||
returnDt==BaseDataType.FLOAT -> {
|
||||
// float result from function sits in FAC1
|
||||
@@ -3923,7 +3923,7 @@ $endLabel""")
|
||||
else throw AssemblyError("only combined vreg allowed as long target ${target.position}")
|
||||
}
|
||||
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.REGISTER -> {
|
||||
|
||||
@@ -29,33 +29,33 @@ abs_w_into_AY .proc
|
||||
+ rts
|
||||
.pend
|
||||
|
||||
abs_l_into_R0R1 .proc
|
||||
; -- R0:R1 = abs(R0:R1)
|
||||
lda cx16.r1H
|
||||
abs_l_into_R14R15 .proc
|
||||
; -- R14:R15 = abs(R14:R15)
|
||||
lda cx16.r15H
|
||||
bmi + ; Negative if high bit of highest byte is set
|
||||
rts
|
||||
+
|
||||
; Invert all four bytes
|
||||
lda cx16.r0L
|
||||
lda cx16.r14L
|
||||
eor #$FF
|
||||
sta cx16.r0L
|
||||
lda cx16.r0H
|
||||
sta cx16.r14L
|
||||
lda cx16.r14H
|
||||
eor #$FF
|
||||
sta cx16.r0H
|
||||
lda cx16.r1L
|
||||
sta cx16.r14H
|
||||
lda cx16.r15L
|
||||
eor #$FF
|
||||
sta cx16.r1L
|
||||
lda cx16.r1H
|
||||
sta cx16.r15L
|
||||
lda cx16.r15H
|
||||
eor #$FF
|
||||
sta cx16.r1H
|
||||
sta cx16.r15H
|
||||
; Add 1 to whole 32-bit value
|
||||
inc cx16.r0L
|
||||
inc cx16.r14L
|
||||
bne +
|
||||
inc cx16.r0H
|
||||
inc cx16.r14H
|
||||
bne +
|
||||
inc cx16.r1L
|
||||
inc cx16.r15L
|
||||
bne +
|
||||
inc cx16.r1H
|
||||
inc cx16.r15H
|
||||
+ rts
|
||||
.pend
|
||||
|
||||
@@ -479,22 +479,22 @@ from_scratchW1
|
||||
.pend
|
||||
|
||||
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
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
from_scratchW1
|
||||
ldy #0
|
||||
lda (P8ZP_SCRATCH_W1),y
|
||||
sta cx16.r0
|
||||
sta cx16.r14
|
||||
iny
|
||||
lda (P8ZP_SCRATCH_W1),y
|
||||
sta cx16.r0+1
|
||||
sta cx16.r14+1
|
||||
iny
|
||||
lda (P8ZP_SCRATCH_W1),y
|
||||
sta cx16.r0+2
|
||||
sta cx16.r14+2
|
||||
iny
|
||||
lda (P8ZP_SCRATCH_W1),y
|
||||
sta cx16.r0+3
|
||||
sta cx16.r14+3
|
||||
rts
|
||||
.pend
|
||||
|
||||
@@ -522,20 +522,20 @@ func_pokew_scratchW2 .proc
|
||||
.pend
|
||||
|
||||
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
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
ldy #0
|
||||
lda cx16.r0
|
||||
lda cx16.r14
|
||||
sta (P8ZP_SCRATCH_W1),y
|
||||
iny
|
||||
lda cx16.r0+1
|
||||
lda cx16.r14+1
|
||||
sta (P8ZP_SCRATCH_W1),y
|
||||
iny
|
||||
lda cx16.r0+2
|
||||
lda cx16.r14+2
|
||||
sta (P8ZP_SCRATCH_W1),y
|
||||
iny
|
||||
lda cx16.r0+3
|
||||
lda cx16.r14+3
|
||||
sta (P8ZP_SCRATCH_W1),y
|
||||
rts
|
||||
.pend
|
||||
|
||||
@@ -3,42 +3,22 @@
|
||||
|
||||
main {
|
||||
sub start() {
|
||||
long @shared lv1, lv2, lv3
|
||||
long @shared lv1 = -123456
|
||||
|
||||
cx16.r0 = 12345
|
||||
txt.print_l(cx16.r0)
|
||||
txt.print_l(abs(lv1))
|
||||
txt.spc()
|
||||
cx16.r0s = -9999
|
||||
txt.print_l(cx16.r0)
|
||||
|
||||
lv1 = -99999
|
||||
lv1 = abs(lv1)
|
||||
txt.print_l(abs(lv1))
|
||||
txt.nl()
|
||||
|
||||
txt.print("sgns:\n")
|
||||
word @shared w1, w2, w3
|
||||
w1 = $1100
|
||||
w2 = $ff00 as word
|
||||
w3 = $0000
|
||||
txt.print_b(sgn(w1))
|
||||
cx16.r4 = $1122
|
||||
cx16.r5 = $abcd
|
||||
txt.print_ulhex(mklong(cx16.r5H,cx16.r5L,cx16.r4H,cx16.r4L), true)
|
||||
txt.spc()
|
||||
txt.print_b(sgn(w2))
|
||||
txt.spc()
|
||||
txt.print_b(sgn(w3))
|
||||
txt.print_ulhex(mklong2(cx16.r5,cx16.r4), true)
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user