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)
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 -> {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user