+ initial implementation of tcgz80.normalize_ref

git-svn-id: branches/z80@44890 -
This commit is contained in:
nickysn 2020-04-20 20:27:08 +00:00
parent 6e1dd417cf
commit 882522259e

View File

@ -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;