From 038230bbeaa0828d92b1740874b753308afb162b Mon Sep 17 00:00:00 2001 From: florian Date: Sun, 1 May 2022 20:13:08 +0200 Subject: [PATCH] * AVR: use adiw to create spilling constants if possible * AVR: insert allocations for registers used by spilling so the assembler optimizer does not remove spilling code --- compiler/avr/rgcpu.pas | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/compiler/avr/rgcpu.pas b/compiler/avr/rgcpu.pas index 1eb0afa659..33d86e84d3 100644 --- a/compiler/avr/rgcpu.pas +++ b/compiler/avr/rgcpu.pas @@ -49,7 +49,7 @@ unit rgcpu; uses verbose, cutils, - globals, + globtype, globals, cgobj, procinfo, cpuinfo; @@ -120,18 +120,38 @@ unit rgcpu; var tmpref : treference; helplist : TAsmList; + ofs : asizeint; begin if (abs(spilltemp.offset)>63) or (CPUAVR_16_REGS in cpu_capabilities[current_settings.cputype]) then begin helplist:=TAsmList.create; + ofs:=spilltemp.offset; - helplist.concat(taicpu.op_reg_const(A_LDI,NR_R26,lo(word(spilltemp.offset)))); - helplist.concat(taicpu.op_reg_const(A_LDI,NR_R27,hi(word(spilltemp.offset)))); - helplist.concat(taicpu.op_reg_reg(A_ADD,NR_R26,spilltemp.base)); - helplist.concat(taicpu.op_reg_reg(A_ADC,NR_R27,cg.GetNextReg(spilltemp.base))); + helplist.concat(tai_regalloc.alloc(NR_R26,nil)); + helplist.concat(tai_regalloc.alloc(NR_R27,nil)); + if (CPUAVR_HAS_ADIW in cpu_capabilities[current_settings.cputype]) and (ofs>0) and (ofs<=126) then + begin + { this might be converted into movw } + helplist.concat(taicpu.op_reg_reg(A_MOV,NR_R26,spilltemp.base)); + helplist.concat(taicpu.op_reg_reg(A_MOV,NR_R27,cg.GetNextReg(spilltemp.base))); + while ofs>0 do + begin + helplist.concat(taicpu.op_reg_const(A_ADIW,NR_R26,min(63,ofs))); + dec(ofs,min(63,ofs)); + end; + end + else + begin + helplist.concat(taicpu.op_reg_const(A_LDI,NR_R26,lo(word(spilltemp.offset)))); + helplist.concat(taicpu.op_reg_const(A_LDI,NR_R27,hi(word(spilltemp.offset)))); + helplist.concat(taicpu.op_reg_reg(A_ADD,NR_R26,spilltemp.base)); + helplist.concat(taicpu.op_reg_reg(A_ADC,NR_R27,cg.GetNextReg(spilltemp.base))); + end; reference_reset_base(tmpref,NR_R26,0,spilltemp.temppos,1,[]); helplist.concat(spilling_create_store(tempreg,tmpref)); + helplist.concat(tai_regalloc.dealloc(NR_R26,nil)); + helplist.concat(tai_regalloc.dealloc(NR_R27,nil)); list.insertlistafter(pos,helplist); helplist.free; end