mirror of
https://github.com/irmen/prog8.git
synced 2024-11-26 11:49:22 +00:00
optimizing X register saving for 65c02 using phx/plx instead of zp location
This commit is contained in:
parent
0b55372b3b
commit
9154d8bd37
@ -42,7 +42,7 @@ asmsub print (str text @ AY) clobbers(A,Y) {
|
||||
asmsub print_ub0 (ubyte value @ A) clobbers(A,Y) {
|
||||
; ---- print the ubyte in A in decimal form, with left padding 0s (3 positions total)
|
||||
%asm {{
|
||||
stx P8ZP_SCRATCH_REG_X
|
||||
phx
|
||||
jsr conv.ubyte2decimal
|
||||
pha
|
||||
tya
|
||||
@ -51,7 +51,7 @@ asmsub print_ub0 (ubyte value @ A) clobbers(A,Y) {
|
||||
jsr c64.CHROUT
|
||||
txa
|
||||
jsr c64.CHROUT
|
||||
ldx P8ZP_SCRATCH_REG_X
|
||||
plx
|
||||
rts
|
||||
}}
|
||||
}
|
||||
@ -59,7 +59,7 @@ asmsub print_ub0 (ubyte value @ A) clobbers(A,Y) {
|
||||
asmsub print_ub (ubyte value @ A) clobbers(A,Y) {
|
||||
; ---- print the ubyte in A in decimal form, without left padding 0s
|
||||
%asm {{
|
||||
stx P8ZP_SCRATCH_REG_X
|
||||
phx
|
||||
jsr conv.ubyte2decimal
|
||||
_print_byte_digits
|
||||
pha
|
||||
@ -76,7 +76,7 @@ _print_byte_digits
|
||||
jsr c64.CHROUT
|
||||
_ones txa
|
||||
jsr c64.CHROUT
|
||||
ldx P8ZP_SCRATCH_REG_X
|
||||
plx
|
||||
rts
|
||||
}}
|
||||
}
|
||||
@ -84,7 +84,7 @@ _ones txa
|
||||
asmsub print_b (byte value @ A) clobbers(A,Y) {
|
||||
; ---- print the byte in A in decimal form, without left padding 0s
|
||||
%asm {{
|
||||
stx P8ZP_SCRATCH_REG_X
|
||||
phx
|
||||
pha
|
||||
cmp #0
|
||||
bpl +
|
||||
@ -93,7 +93,7 @@ asmsub print_b (byte value @ A) clobbers(A,Y) {
|
||||
+ pla
|
||||
jsr conv.byte2decimal
|
||||
jsr print_ub._print_byte_digits
|
||||
ldx P8ZP_SCRATCH_REG_X
|
||||
plx
|
||||
rts
|
||||
}}
|
||||
}
|
||||
@ -101,7 +101,7 @@ asmsub print_b (byte value @ A) clobbers(A,Y) {
|
||||
asmsub print_ubhex (ubyte value @ A, ubyte prefix @ Pc) clobbers(A,Y) {
|
||||
; ---- print the ubyte in A in hex form (if Carry is set, a radix prefix '$' is printed as well)
|
||||
%asm {{
|
||||
stx P8ZP_SCRATCH_REG_X
|
||||
phx
|
||||
bcc +
|
||||
pha
|
||||
lda #'$'
|
||||
@ -111,7 +111,7 @@ asmsub print_ubhex (ubyte value @ A, ubyte prefix @ Pc) clobbers(A,Y) {
|
||||
jsr c64.CHROUT
|
||||
tya
|
||||
jsr c64.CHROUT
|
||||
ldx P8ZP_SCRATCH_REG_X
|
||||
plx
|
||||
rts
|
||||
}}
|
||||
}
|
||||
@ -119,7 +119,7 @@ asmsub print_ubhex (ubyte value @ A, ubyte prefix @ Pc) clobbers(A,Y) {
|
||||
asmsub print_ubbin (ubyte value @ A, ubyte prefix @ Pc) clobbers(A,Y) {
|
||||
; ---- print the ubyte in A in binary form (if Carry is set, a radix prefix '%' is printed as well)
|
||||
%asm {{
|
||||
stx P8ZP_SCRATCH_REG_X
|
||||
phx
|
||||
sta P8ZP_SCRATCH_B1
|
||||
bcc +
|
||||
lda #'%'
|
||||
@ -132,7 +132,7 @@ asmsub print_ubbin (ubyte value @ A, ubyte prefix @ Pc) clobbers(A,Y) {
|
||||
+ jsr c64.CHROUT
|
||||
dey
|
||||
bne -
|
||||
ldx P8ZP_SCRATCH_REG_X
|
||||
plx
|
||||
rts
|
||||
}}
|
||||
}
|
||||
@ -165,7 +165,7 @@ asmsub print_uwhex (uword value @ AY, ubyte prefix @ Pc) clobbers(A,Y) {
|
||||
asmsub print_uw0 (uword value @ AY) clobbers(A,Y) {
|
||||
; ---- print the uword in A/Y in decimal form, with left padding 0s (5 positions total)
|
||||
%asm {{
|
||||
stx P8ZP_SCRATCH_REG_X
|
||||
phx
|
||||
jsr conv.uword2decimal
|
||||
ldy #0
|
||||
- lda conv.uword2decimal.decTenThousands,y
|
||||
@ -173,7 +173,7 @@ asmsub print_uw0 (uword value @ AY) clobbers(A,Y) {
|
||||
jsr c64.CHROUT
|
||||
iny
|
||||
bne -
|
||||
+ ldx P8ZP_SCRATCH_REG_X
|
||||
+ plx
|
||||
rts
|
||||
}}
|
||||
}
|
||||
@ -181,9 +181,9 @@ asmsub print_uw0 (uword value @ AY) clobbers(A,Y) {
|
||||
asmsub print_uw (uword value @ AY) clobbers(A,Y) {
|
||||
; ---- print the uword in A/Y in decimal form, without left padding 0s
|
||||
%asm {{
|
||||
stx P8ZP_SCRATCH_REG_X
|
||||
phx
|
||||
jsr conv.uword2decimal
|
||||
ldx P8ZP_SCRATCH_REG_X
|
||||
plx
|
||||
ldy #0
|
||||
- lda conv.uword2decimal.decTenThousands,y
|
||||
beq _allzero
|
||||
@ -228,11 +228,11 @@ asmsub print_w (word value @ AY) clobbers(A,Y) {
|
||||
asmsub plot (ubyte col @ Y, ubyte row @ A) clobbers(A) {
|
||||
; ---- safe wrapper around PLOT kernel routine, to save the X register.
|
||||
%asm {{
|
||||
stx P8ZP_SCRATCH_REG_X
|
||||
phx
|
||||
tax
|
||||
clc
|
||||
jsr c64.PLOT
|
||||
ldx P8ZP_SCRATCH_REG_X
|
||||
plx
|
||||
rts
|
||||
}}
|
||||
}
|
||||
|
@ -551,7 +551,12 @@ internal class AsmGen(private val program: Program,
|
||||
internal fun saveRegister(register: CpuRegister) {
|
||||
when(register) {
|
||||
CpuRegister.A -> out(" pha")
|
||||
CpuRegister.X -> out(" txa | pha")
|
||||
CpuRegister.X -> {
|
||||
if(CompilationTarget.machine.cpu == CpuType.CPU65c02)
|
||||
out(" phx")
|
||||
else
|
||||
out(" stx P8ZP_SCRATCH_REG_X")
|
||||
}
|
||||
CpuRegister.Y -> out(" tya | pha")
|
||||
}
|
||||
}
|
||||
@ -559,7 +564,12 @@ internal class AsmGen(private val program: Program,
|
||||
internal fun restoreRegister(register: CpuRegister) {
|
||||
when(register) {
|
||||
CpuRegister.A -> out(" pla")
|
||||
CpuRegister.X -> out(" pla | tax")
|
||||
CpuRegister.X -> {
|
||||
if(CompilationTarget.machine.cpu == CpuType.CPU65c02)
|
||||
out(" plx")
|
||||
else
|
||||
out(" ldx P8ZP_SCRATCH_REG_X")
|
||||
}
|
||||
CpuRegister.Y -> out(" pla | tay")
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg
|
||||
val sub = stmt.target.targetSubroutine(program.namespace) ?: throw AssemblyError("undefined subroutine ${stmt.target}")
|
||||
val saveX = CpuRegister.X in sub.asmClobbers || sub.regXasResult() || sub.regXasParam()
|
||||
if(saveX)
|
||||
asmgen.out(" stx P8ZP_SCRATCH_REG_X") // we only save X for now (required! is the eval stack pointer), screw A and Y...
|
||||
asmgen.saveRegister(CpuRegister.X) // we only save X for now (required! is the eval stack pointer), screw A and Y...
|
||||
|
||||
val subName = asmgen.asmSymbolName(stmt.target)
|
||||
if(stmt.args.isNotEmpty()) {
|
||||
@ -57,7 +57,7 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg
|
||||
asmgen.out(" jsr $subName")
|
||||
|
||||
if(saveX)
|
||||
asmgen.out(" ldx P8ZP_SCRATCH_REG_X") // restore X again
|
||||
asmgen.restoreRegister(CpuRegister.X)
|
||||
}
|
||||
|
||||
private fun registerArgsViaStackEvaluation(stmt: IFunctionCall, sub: Subroutine) {
|
||||
|
@ -97,7 +97,8 @@ internal class PostIncrDecrAsmGen(private val program: Program, private val asmg
|
||||
}
|
||||
else -> {
|
||||
asmgen.loadScaledArrayIndexIntoRegister(targetArrayIdx, elementDt, CpuRegister.A)
|
||||
asmgen.out(" stx P8ZP_SCRATCH_REG_X | tax")
|
||||
asmgen.saveRegister(CpuRegister.X)
|
||||
asmgen.out(" tax")
|
||||
when(elementDt) {
|
||||
in ByteDatatypes -> {
|
||||
asmgen.out(if(incr) " inc $asmArrayvarname,x" else " dec $asmArrayvarname,x")
|
||||
@ -124,7 +125,7 @@ internal class PostIncrDecrAsmGen(private val program: Program, private val asmg
|
||||
}
|
||||
else -> throw AssemblyError("weird array elt dt")
|
||||
}
|
||||
asmgen.out(" ldx P8ZP_SCRATCH_REG_X")
|
||||
asmgen.restoreRegister(CpuRegister.X)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1059,11 +1059,11 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
||||
// because the value is evaluated onto the eval stack (=slow).
|
||||
println("warning: slow stack evaluation used (2): $name $operator= ${value::class.simpleName} at ${value.position}") // TODO
|
||||
asmgen.translateExpression(value)
|
||||
asmgen.saveRegister(CpuRegister.X)
|
||||
when (operator) {
|
||||
"**" -> {
|
||||
asmgen.out("""
|
||||
jsr c64flt.pop_float_fac1
|
||||
stx P8ZP_SCRATCH_REG_X
|
||||
lda #<$name
|
||||
ldy #>$name
|
||||
jsr c64flt.CONUPK
|
||||
@ -1073,7 +1073,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
||||
"+" -> {
|
||||
asmgen.out("""
|
||||
jsr c64flt.pop_float_fac1
|
||||
stx P8ZP_SCRATCH_REG_X
|
||||
lda #<$name
|
||||
ldy #>$name
|
||||
jsr c64flt.FADD
|
||||
@ -1082,7 +1081,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
||||
"-" -> {
|
||||
asmgen.out("""
|
||||
jsr c64flt.pop_float_fac1
|
||||
stx P8ZP_SCRATCH_REG_X
|
||||
lda #<$name
|
||||
ldy #>$name
|
||||
jsr c64flt.FSUB
|
||||
@ -1091,7 +1089,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
||||
"*" -> {
|
||||
asmgen.out("""
|
||||
jsr c64flt.pop_float_fac1
|
||||
stx P8ZP_SCRATCH_REG_X
|
||||
lda #<$name
|
||||
ldy #>$name
|
||||
jsr c64flt.FMULT
|
||||
@ -1100,7 +1097,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
||||
"/" -> {
|
||||
asmgen.out("""
|
||||
jsr c64flt.pop_float_fac1
|
||||
stx P8ZP_SCRATCH_REG_X
|
||||
lda #<$name
|
||||
ldy #>$name
|
||||
jsr c64flt.FDIV
|
||||
@ -1113,8 +1109,8 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
||||
ldx #<$name
|
||||
ldy #>$name
|
||||
jsr c64flt.MOVMF
|
||||
ldx P8ZP_SCRATCH_REG_X
|
||||
""")
|
||||
asmgen.restoreRegister(CpuRegister.X)
|
||||
}
|
||||
|
||||
private fun inplaceModification_float_variable_to_variable(name: String, operator: String, ident: IdentifierReference) {
|
||||
@ -1123,10 +1119,10 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
||||
throw AssemblyError("float variable expected")
|
||||
|
||||
val otherName = asmgen.asmVariableName(ident)
|
||||
asmgen.saveRegister(CpuRegister.X)
|
||||
when (operator) {
|
||||
"**" -> {
|
||||
asmgen.out("""
|
||||
stx P8ZP_SCRATCH_REG_X
|
||||
lda #<$name
|
||||
ldy #>$name
|
||||
jsr c64flt.CONUPK
|
||||
@ -1137,7 +1133,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
||||
}
|
||||
"+" -> {
|
||||
asmgen.out("""
|
||||
stx P8ZP_SCRATCH_REG_X
|
||||
lda #<$name
|
||||
ldy #>$name
|
||||
jsr c64flt.MOVFM
|
||||
@ -1148,7 +1143,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
||||
}
|
||||
"-" -> {
|
||||
asmgen.out("""
|
||||
stx P8ZP_SCRATCH_REG_X
|
||||
lda #<$otherName
|
||||
ldy #>$otherName
|
||||
jsr c64flt.MOVFM
|
||||
@ -1159,7 +1153,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
||||
}
|
||||
"*" -> {
|
||||
asmgen.out("""
|
||||
stx P8ZP_SCRATCH_REG_X
|
||||
lda #<$name
|
||||
ldy #>$name
|
||||
jsr c64flt.MOVFM
|
||||
@ -1170,7 +1163,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
||||
}
|
||||
"/" -> {
|
||||
asmgen.out("""
|
||||
stx P8ZP_SCRATCH_REG_X
|
||||
lda #<$otherName
|
||||
ldy #>$otherName
|
||||
jsr c64flt.MOVFM
|
||||
@ -1186,16 +1178,16 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
||||
ldx #<$name
|
||||
ldy #>$name
|
||||
jsr c64flt.MOVMF
|
||||
ldx P8ZP_SCRATCH_REG_X
|
||||
""")
|
||||
asmgen.restoreRegister(CpuRegister.X)
|
||||
}
|
||||
|
||||
private fun inplaceModification_float_litval_to_variable(name: String, operator: String, value: Double) {
|
||||
val constValueName = asmgen.getFloatAsmConst(value)
|
||||
asmgen.saveRegister(CpuRegister.X)
|
||||
when (operator) {
|
||||
"**" -> {
|
||||
asmgen.out("""
|
||||
stx P8ZP_SCRATCH_REG_X
|
||||
lda #<$name
|
||||
ldy #>$name
|
||||
jsr c64flt.CONUPK
|
||||
@ -1208,7 +1200,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
||||
if (value == 0.0)
|
||||
return
|
||||
asmgen.out("""
|
||||
stx P8ZP_SCRATCH_REG_X
|
||||
lda #<$name
|
||||
ldy #>$name
|
||||
jsr c64flt.MOVFM
|
||||
@ -1221,7 +1212,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
||||
if (value == 0.0)
|
||||
return
|
||||
asmgen.out("""
|
||||
stx P8ZP_SCRATCH_REG_X
|
||||
lda #<$constValueName
|
||||
ldy #>$constValueName
|
||||
jsr c64flt.MOVFM
|
||||
@ -1232,7 +1222,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
||||
}
|
||||
"*" -> {
|
||||
asmgen.out("""
|
||||
stx P8ZP_SCRATCH_REG_X
|
||||
lda #<$name
|
||||
ldy #>$name
|
||||
jsr c64flt.MOVFM
|
||||
@ -1245,7 +1234,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
||||
if (value == 0.0)
|
||||
throw AssemblyError("division by zero")
|
||||
asmgen.out("""
|
||||
stx P8ZP_SCRATCH_REG_X
|
||||
lda #<$constValueName
|
||||
ldy #>$constValueName
|
||||
jsr c64flt.MOVFM
|
||||
@ -1261,8 +1249,8 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
||||
ldx #<$name
|
||||
ldy #>$name
|
||||
jsr c64flt.MOVMF
|
||||
ldx P8ZP_SCRATCH_REG_X
|
||||
""")
|
||||
asmgen.restoreRegister(CpuRegister.X)
|
||||
}
|
||||
|
||||
private fun inplaceCast(target: AsmAssignTarget, cast: TypecastExpression, position: Position) {
|
||||
@ -1499,8 +1487,8 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
||||
DataType.FLOAT -> {
|
||||
when(target.kind) {
|
||||
TargetStorageKind.VARIABLE -> {
|
||||
asmgen.saveRegister(CpuRegister.X)
|
||||
asmgen.out("""
|
||||
stx P8ZP_SCRATCH_REG_X
|
||||
lda #<${target.asmVarname}
|
||||
ldy #>${target.asmVarname}
|
||||
jsr c64flt.MOVFM
|
||||
@ -1508,8 +1496,8 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
||||
ldx #<${target.asmVarname}
|
||||
ldy #>${target.asmVarname}
|
||||
jsr c64flt.MOVMF
|
||||
ldx P8ZP_SCRATCH_REG_X
|
||||
""")
|
||||
asmgen.restoreRegister(CpuRegister.X)
|
||||
}
|
||||
TargetStorageKind.ARRAY -> TODO("in-place negate float array")
|
||||
TargetStorageKind.STACK -> TODO("stack float negate")
|
||||
|
Loading…
Reference in New Issue
Block a user