diff --git a/compiler/z80/cgcpu.pas b/compiler/z80/cgcpu.pas index cab2f7bf87..ed45ba87d7 100644 --- a/compiler/z80/cgcpu.pas +++ b/compiler/z80/cgcpu.pas @@ -98,8 +98,7 @@ unit cgcpu; procedure a_jmp_cond(list : TAsmList;cond : TOpCmp;l: tasmlabel); procedure fixref(list : TAsmList;var ref : treference); - function normalize_ref(list : TAsmList;ref : treference; - tmpreg : tregister) : treference; + function normalize_ref(list : TAsmList;ref : treference; const refopertypes:trefoperandtypes) : treference; procedure emit_mov(list: TAsmList;reg2: tregister; reg1: tregister); @@ -1189,112 +1188,66 @@ unit cgcpu; end; - function tcgz80.normalize_ref(list:TAsmList;ref: treference;tmpreg : tregister) : treference; - + function tcgz80.normalize_ref(list: TAsmList; ref: treference; const refopertypes: trefoperandtypes): treference; var tmpref : treference; l : tasmlabel; begin - Result:=ref; -// -// if ref.addressmode<>AM_UNCHANGED then -// internalerror(2011021701); -// -// { Be sure to have a base register } -// if (ref.base=NR_NO) then -// begin -// { only symbol+offset? } -// if ref.index=NR_NO then -// exit; -// ref.base:=ref.index; -// ref.index:=NR_NO; -// end; -// -// { can we take advantage of adiw/sbiw? } -// if (current_settings.cputype>=cpu_avr2) and not(assigned(ref.symbol)) and (ref.offset<>0) and (ref.offset>=-63) and (ref.offset<=63) and -// ((tmpreg=NR_R24) or (tmpreg=NR_R26) or (tmpreg=NR_R28) or (tmpreg=NR_R30)) and (ref.base<>NR_NO) then -// begin -// maybegetcpuregister(list,tmpreg); -// emit_mov(list,tmpreg,ref.base); -// maybegetcpuregister(list,GetNextReg(tmpreg)); -// emit_mov(list,GetNextReg(tmpreg),GetNextReg(ref.base)); -// if ref.index<>NR_NO then -// begin -// list.concat(taicpu.op_reg_reg(A_ADD,tmpreg,ref.index)); -// list.concat(taicpu.op_reg_reg(A_ADC,GetNextReg(tmpreg),GetNextReg(ref.index))); -// end; -// if ref.offset>0 then -// list.concat(taicpu.op_reg_const(A_ADIW,tmpreg,ref.offset)) -// else -// list.concat(taicpu.op_reg_const(A_SBIW,tmpreg,-ref.offset)); -// ref.offset:=0; -// ref.base:=tmpreg; -// ref.index:=NR_NO; -// end -// else if assigned(ref.symbol) or (ref.offset<>0) then -// begin -// reference_reset(tmpref,0,[]); -// tmpref.symbol:=ref.symbol; -// tmpref.offset:=ref.offset; -// if assigned(ref.symbol) and (ref.symbol.typ in [AT_FUNCTION,AT_LABEL]) then -// tmpref.refaddr:=addr_lo8_gs -// else -// tmpref.refaddr:=addr_lo8; -// maybegetcpuregister(list,tmpreg); -// list.concat(taicpu.op_reg_ref(A_LDI,tmpreg,tmpref)); -// -// if assigned(ref.symbol) and (ref.symbol.typ in [AT_FUNCTION,AT_LABEL]) then -// tmpref.refaddr:=addr_hi8_gs -// else -// tmpref.refaddr:=addr_hi8; -// maybegetcpuregister(list,GetNextReg(tmpreg)); -// list.concat(taicpu.op_reg_ref(A_LDI,GetNextReg(tmpreg),tmpref)); -// -// if (ref.base<>NR_NO) then -// begin -// list.concat(taicpu.op_reg_reg(A_ADD,tmpreg,ref.base)); -// list.concat(taicpu.op_reg_reg(A_ADC,GetNextReg(tmpreg),GetNextReg(ref.base))); -// end; -// if (ref.index<>NR_NO) then -// begin -// list.concat(taicpu.op_reg_reg(A_ADD,tmpreg,ref.index)); -// list.concat(taicpu.op_reg_reg(A_ADC,GetNextReg(tmpreg),GetNextReg(ref.index))); -// end; -// ref.symbol:=nil; -// ref.offset:=0; -// ref.base:=tmpreg; -// ref.index:=NR_NO; -// end -// else if (ref.base<>NR_NO) and (ref.index<>NR_NO) then -// begin -// maybegetcpuregister(list,tmpreg); -// emit_mov(list,tmpreg,ref.base); -// maybegetcpuregister(list,GetNextReg(tmpreg)); -// emit_mov(list,GetNextReg(tmpreg),GetNextReg(ref.base)); -// list.concat(taicpu.op_reg_reg(A_ADD,tmpreg,ref.index)); -// list.concat(taicpu.op_reg_reg(A_ADC,GetNextReg(tmpreg),GetNextReg(ref.index))); -// ref.base:=tmpreg; -// ref.index:=NR_NO; -// end -// else if (ref.base<>NR_NO) then -// begin -// maybegetcpuregister(list,tmpreg); -// emit_mov(list,tmpreg,ref.base); -// maybegetcpuregister(list,GetNextReg(tmpreg)); -// emit_mov(list,GetNextReg(tmpreg),GetNextReg(ref.base)); -// ref.base:=tmpreg; -// ref.index:=NR_NO; -// end -// else if (ref.index<>NR_NO) then -// begin -// maybegetcpuregister(list,tmpreg); -// emit_mov(list,tmpreg,ref.index); -// maybegetcpuregister(list,GetNextReg(tmpreg)); -// emit_mov(list,GetNextReg(tmpreg),GetNextReg(ref.index)); -// ref.base:=tmpreg; -// ref.index:=NR_NO; -// end; - Result:=ref; + if (ref.base=NR_NO) and (ref.index<>NR_NO) and (ref.scalefactor<=1) then + begin + ref.base:=ref.index; + ref.index:=NR_NO; + end; + + if is_ref_in_opertypes(ref,refopertypes) then + begin + Result:=ref; + exit; + end; + + { can we use the HL register? } + if OT_REF_HL in refopertypes then + begin + getcpuregister(list,NR_H); + getcpuregister(list,NR_L); + if assigned(ref.symbol) then + begin + reference_reset(tmpref,0,[]); + tmpref.symbol:=ref.symbol; + tmpref.offset:=ref.offset; + + tmpref.refaddr:=addr_full; + list.concat(taicpu.op_reg_ref(A_LD,NR_HL,tmpref)); + end + else + list.concat(taicpu.op_reg_const(A_LD,NR_HL,ref.offset)); + if ref.base<>NR_NO then + begin + getcpuregister(list,NR_A); + emit_mov(list,NR_A,NR_L); + list.concat(taicpu.op_reg_reg(A_ADD,NR_A,ref.base)); + emit_mov(list,NR_L,NR_A); + emit_mov(list,NR_A,NR_H); + list.concat(taicpu.op_reg_reg(A_ADC,NR_A,GetNextReg(ref.base))); + emit_mov(list,NR_H,NR_A); + ungetcpuregister(list,NR_A); + end; + if ref.index<>NR_NO then + begin + if ref.scalefactor>1 then + internalerror(2020042002); + getcpuregister(list,NR_A); + emit_mov(list,NR_A,NR_L); + list.concat(taicpu.op_reg_reg(A_ADD,NR_A,ref.index)); + emit_mov(list,NR_L,NR_A); + emit_mov(list,NR_A,NR_H); + list.concat(taicpu.op_reg_reg(A_ADC,NR_A,GetNextReg(ref.index))); + emit_mov(list,NR_H,NR_A); + ungetcpuregister(list,NR_A); + end; + end + else + internalerror(2020042001); end;