From 836a2700f2d09800048b10c555830a993fd95c42 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Tue, 15 Nov 2022 02:45:51 +0100 Subject: [PATCH] func(x>>1) no longer uses slow stack eval --- .../cpu6502/assignment/AssignmentAsmGen.kt | 52 +++++++++++++++++++ docs/source/todo.rst | 3 +- examples/cx16/adpcm.p8 | 3 +- 3 files changed, 55 insertions(+), 3 deletions(-) diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt index 1cccb3890..2894834cb 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt @@ -622,6 +622,58 @@ internal class AssignmentAsmGen(private val program: Program, } } } + else if(expr.operator=="<<" || expr.operator==">>") { + val shifts = expr.right.constValue(program)?.number?.toInt() + if(shifts!=null) { + val dt = expr.left.inferType(program) + if(dt.isBytes && shifts in 0..7) { + val signed = dt istype DataType.BYTE + assignExpressionToRegister(expr.left, RegisterOrPair.A, signed) + if(expr.operator=="<<") { + repeat(shifts) { + asmgen.out(" asl a") + } + } else { + if(signed && shifts>0) { + asmgen.out(" ldy #$shifts | jsr math.lsr_byte_A") + } else { + repeat(shifts) { + asmgen.out(" lsr a") + } + } + } + assignRegisterByte(assign.target, CpuRegister.A) + return true + } else if(dt.isWords && shifts in 0..7) { + val signed = dt istype DataType.WORD + assignExpressionToRegister(expr.left, RegisterOrPair.AY, signed) + if(expr.operator=="<<") { + if(shifts>0) { + asmgen.out(" sty P8ZP_SCRATCH_B1") + repeat(shifts) { + asmgen.out(" asl a | rol P8ZP_SCRATCH_B1") + } + asmgen.out(" ldy P8ZP_SCRATCH_B1") + } + } else { + if(signed) { + // TODO("shift AY >> $shifts signed") + return false + } else { + if(shifts>0) { + asmgen.out(" sty P8ZP_SCRATCH_B1") + repeat(shifts) { + asmgen.out(" lsr P8ZP_SCRATCH_B1 | ror a") + } + asmgen.out(" ldy P8ZP_SCRATCH_B1") + } + } + } + assignRegisterpairWord(assign.target, RegisterOrPair.AY) + return true + } + } + } return false } diff --git a/docs/source/todo.rst b/docs/source/todo.rst index eec509f9e..521ecd8c4 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,8 +3,9 @@ TODO For next release ^^^^^^^^^^^^^^^^ -- why is func(x&15) fast, but func(x>>4) using stack eval for the arg? +- word << 12 is suddenly an uword - ir/vm: allow label in block scope +- regression test the various projects - 6502 codegen: make it possible to use cpu opcodes such as 'nop' as variable names by prefixing all asm vars with something such as ``p8v_``? Or not worth it (most 3 letter opcodes as variables are nonsensical anyway) then we can get rid of the instruction lists in the machinedefinitions as well. This is already no problem at all in the IR codegen. - create BSS section in output program and put StStaticVariables in there with bss=true. Don't forget to add init code to zero out everything that was put in bss. If array in bss->only zero ONCE! So requires self-modifying code diff --git a/examples/cx16/adpcm.p8 b/examples/cx16/adpcm.p8 index 50055003e..000ded07b 100644 --- a/examples/cx16/adpcm.p8 +++ b/examples/cx16/adpcm.p8 @@ -23,8 +23,7 @@ main { adpcm.decode_nibble(nibble & 15) txt.print_w(adpcm.predict as word) txt.spc() - nibble >>= 4 - adpcm.decode_nibble(nibble) + adpcm.decode_nibble(nibble>>4) txt.print_w(adpcm.predict as word) txt.spc() nibblesptr++