|
@@ -93,7 +93,7 @@ unit cgcpu;
|
|
|
procedure g_proc_exit(list: TAsmList; parasize: longint; nostackframe: boolean); override;
|
|
procedure g_proc_exit(list: TAsmList; parasize: longint; nostackframe: boolean); override;
|
|
|
|
|
|
|
|
protected
|
|
protected
|
|
|
- function fixref(list: TAsmList; var ref: treference; mode : tfixref;out tmpreg : tregister): boolean;
|
|
|
|
|
|
|
+ function fixref(list: TAsmList; var ref: treference; mode : tfixref;out tmpreg, tmpreg2 : tregister): boolean;
|
|
|
procedure ungetregister(r : tregister;list :TAsmList);
|
|
procedure ungetregister(r : tregister;list :TAsmList);
|
|
|
procedure maybeadjustresult(list: TAsmList; op: topcg; size: tcgsize; dst: tregister);
|
|
procedure maybeadjustresult(list: TAsmList; op: topcg; size: tcgsize; dst: tregister);
|
|
|
end;
|
|
end;
|
|
@@ -333,7 +333,7 @@ implementation
|
|
|
href: treference;
|
|
href: treference;
|
|
|
op: TAsmOp;
|
|
op: TAsmOp;
|
|
|
hlist: TAsmList;
|
|
hlist: TAsmList;
|
|
|
- tmpreg : tregister;
|
|
|
|
|
|
|
+ tmpreg,tmpreg2 : tregister;
|
|
|
const
|
|
const
|
|
|
st_ops: array[boolean,OS_8..OS_INT] of TAsmOp = (
|
|
st_ops: array[boolean,OS_8..OS_INT] of TAsmOp = (
|
|
|
(A_ST_B,A_ST_H,A_ST_W,A_ST_D),
|
|
(A_ST_B,A_ST_H,A_ST_W,A_ST_D),
|
|
@@ -351,7 +351,7 @@ implementation
|
|
|
if stptr_ops[tosize]<>A_NONE then
|
|
if stptr_ops[tosize]<>A_NONE then
|
|
|
begin
|
|
begin
|
|
|
href:=ref;
|
|
href:=ref;
|
|
|
- if fixref(hlist,href,fr_big,tmpreg) then
|
|
|
|
|
|
|
+ if fixref(hlist,href,fr_big,tmpreg,tmpreg2) then
|
|
|
begin
|
|
begin
|
|
|
list.concatList(hlist);
|
|
list.concatList(hlist);
|
|
|
hlist.free;
|
|
hlist.free;
|
|
@@ -359,13 +359,17 @@ implementation
|
|
|
exit;
|
|
exit;
|
|
|
end
|
|
end
|
|
|
else
|
|
else
|
|
|
- if (tmpreg<>NR_NO) then
|
|
|
|
|
- ungetregister(tmpreg,hlist);
|
|
|
|
|
|
|
+ begin
|
|
|
|
|
+ if (tmpreg<>NR_NO) then
|
|
|
|
|
+ ungetregister(tmpreg,hlist);
|
|
|
|
|
+ if (tmpreg2<>NR_NO) then
|
|
|
|
|
+ ungetregister(tmpreg2,hlist);
|
|
|
|
|
+ end;
|
|
|
end;
|
|
end;
|
|
|
hlist.Clear;
|
|
hlist.Clear;
|
|
|
hlist.free;
|
|
hlist.free;
|
|
|
href:=ref;
|
|
href:=ref;
|
|
|
- op:=st_ops[fixref(list,href,fr_reg,tmpreg),tosize];
|
|
|
|
|
|
|
+ op:=st_ops[fixref(list,href,fr_reg,tmpreg,tmpreg2),tosize];
|
|
|
list.concat(taicpu.op_reg_ref(op,reg,href));
|
|
list.concat(taicpu.op_reg_ref(op,reg,href));
|
|
|
end;
|
|
end;
|
|
|
|
|
|
|
@@ -378,7 +382,7 @@ implementation
|
|
|
have_done: boolean;
|
|
have_done: boolean;
|
|
|
hlist: TAsmList;
|
|
hlist: TAsmList;
|
|
|
samesign: boolean;
|
|
samesign: boolean;
|
|
|
- tmpreg : tregister;
|
|
|
|
|
|
|
+ tmpreg, tmpreg2 : tregister;
|
|
|
const
|
|
const
|
|
|
ld_ops: array[boolean,boolean,OS_8..OS_INT] of TAsmOp = (
|
|
ld_ops: array[boolean,boolean,OS_8..OS_INT] of TAsmOp = (
|
|
|
((A_LD_B,A_LD_H,A_LD_W,A_LD_D),
|
|
((A_LD_B,A_LD_H,A_LD_W,A_LD_D),
|
|
@@ -388,6 +392,7 @@ implementation
|
|
|
);
|
|
);
|
|
|
begin
|
|
begin
|
|
|
tmpreg:=NR_NO;
|
|
tmpreg:=NR_NO;
|
|
|
|
|
+ tmpreg2:=NR_NO;
|
|
|
if not (fromsize in [OS_8..OS_INT,OS_S8..OS_SINT]) then
|
|
if not (fromsize in [OS_8..OS_INT,OS_S8..OS_SINT]) then
|
|
|
internalerror(2022111938);
|
|
internalerror(2022111938);
|
|
|
if not (tosize in [OS_8..OS_INT,OS_S8..OS_SINT]) then
|
|
if not (tosize in [OS_8..OS_INT,OS_S8..OS_SINT]) then
|
|
@@ -401,7 +406,7 @@ implementation
|
|
|
if (fromsize=OS_S32) then
|
|
if (fromsize=OS_S32) then
|
|
|
begin
|
|
begin
|
|
|
href:=ref;
|
|
href:=ref;
|
|
|
- if fixref(hlist,href,fr_big,tmpreg) then
|
|
|
|
|
|
|
+ if fixref(hlist,href,fr_big,tmpreg,tmpreg2) then
|
|
|
begin
|
|
begin
|
|
|
hlist.concat(taicpu.op_reg_ref(A_LDPTR_W,reg,href));
|
|
hlist.concat(taicpu.op_reg_ref(A_LDPTR_W,reg,href));
|
|
|
have_done:=true;
|
|
have_done:=true;
|
|
@@ -410,7 +415,7 @@ implementation
|
|
|
else if (fromsize=OS_S64) or (fromsize=OS_64) then
|
|
else if (fromsize=OS_S64) or (fromsize=OS_64) then
|
|
|
begin
|
|
begin
|
|
|
href:=ref;
|
|
href:=ref;
|
|
|
- if fixref(hlist,href,fr_big,tmpreg) then
|
|
|
|
|
|
|
+ if fixref(hlist,href,fr_big,tmpreg,tmpreg2) then
|
|
|
begin
|
|
begin
|
|
|
hlist.concat(taicpu.op_reg_ref(A_LDPTR_D,reg,href));
|
|
hlist.concat(taicpu.op_reg_ref(A_LDPTR_D,reg,href));
|
|
|
have_done:=true;
|
|
have_done:=true;
|
|
@@ -421,9 +426,11 @@ implementation
|
|
|
begin
|
|
begin
|
|
|
if (tmpreg<>NR_NO) then
|
|
if (tmpreg<>NR_NO) then
|
|
|
ungetregister(tmpreg,hlist);
|
|
ungetregister(tmpreg,hlist);
|
|
|
|
|
+ if (tmpreg2<>NR_NO) then
|
|
|
|
|
+ ungetregister(tmpreg2,hlist);
|
|
|
hlist.Clear;
|
|
hlist.Clear;
|
|
|
href:=ref;
|
|
href:=ref;
|
|
|
- op:=ld_ops[fixref(list,href,fr_reg,tmpreg),fromsize=usizef,usizef];
|
|
|
|
|
|
|
+ op:=ld_ops[fixref(list,href,fr_reg,tmpreg,tmpreg2),fromsize=usizef,usizef];
|
|
|
list.concat(taicpu.op_reg_ref(op,reg,href));
|
|
list.concat(taicpu.op_reg_ref(op,reg,href));
|
|
|
end
|
|
end
|
|
|
else
|
|
else
|
|
@@ -504,10 +511,10 @@ implementation
|
|
|
var
|
|
var
|
|
|
href: treference;
|
|
href: treference;
|
|
|
l: TAsmLabel;
|
|
l: TAsmLabel;
|
|
|
- tmpreg : tregister;
|
|
|
|
|
|
|
+ tmpreg, tmpreg2 : tregister;
|
|
|
begin
|
|
begin
|
|
|
href:=ref;
|
|
href:=ref;
|
|
|
- fixref(list,href,fr_normal,tmpreg);
|
|
|
|
|
|
|
+ fixref(list,href,fr_normal,tmpreg,tmpreg2);
|
|
|
{ Fixref, so simplely work here. }
|
|
{ Fixref, so simplely work here. }
|
|
|
if href.offset=0 then
|
|
if href.offset=0 then
|
|
|
a_load_reg_reg(list,OS_ADDR,OS_ADDR,href.base,r)
|
|
a_load_reg_reg(list,OS_ADDR,OS_ADDR,href.base,r)
|
|
@@ -820,7 +827,7 @@ implementation
|
|
|
var
|
|
var
|
|
|
op: TAsmOp;
|
|
op: TAsmOp;
|
|
|
href: treference;
|
|
href: treference;
|
|
|
- tmpreg : tregister;
|
|
|
|
|
|
|
+ tmpreg, tmpreg2 : tregister;
|
|
|
const
|
|
const
|
|
|
fld_ops: array[boolean,boolean] of TAsmOp = (
|
|
fld_ops: array[boolean,boolean] of TAsmOp = (
|
|
|
(A_FLD_D, A_FLD_S),
|
|
(A_FLD_D, A_FLD_S),
|
|
@@ -828,7 +835,7 @@ implementation
|
|
|
);
|
|
);
|
|
|
begin
|
|
begin
|
|
|
href:=ref;
|
|
href:=ref;
|
|
|
- op:=fld_ops[fixref(list,href,fr_reg,tmpreg),fromsize=OS_F32];
|
|
|
|
|
|
|
+ op:=fld_ops[fixref(list,href,fr_reg,tmpreg,tmpreg2),fromsize=OS_F32];
|
|
|
list.concat(taicpu.op_reg_ref(op,reg,href));
|
|
list.concat(taicpu.op_reg_ref(op,reg,href));
|
|
|
if fromsize<>tosize then
|
|
if fromsize<>tosize then
|
|
|
a_loadfpu_reg_reg(list,fromsize,tosize,reg,reg);
|
|
a_loadfpu_reg_reg(list,fromsize,tosize,reg,reg);
|
|
@@ -839,7 +846,7 @@ implementation
|
|
|
op: TAsmOp;
|
|
op: TAsmOp;
|
|
|
tmpfreg: TRegister;
|
|
tmpfreg: TRegister;
|
|
|
href: treference;
|
|
href: treference;
|
|
|
- tmpreg : tregister;
|
|
|
|
|
|
|
+ tmpreg, tmpreg2 : tregister;
|
|
|
fst_ops: array[boolean,boolean] of TAsmOp = (
|
|
fst_ops: array[boolean,boolean] of TAsmOp = (
|
|
|
(A_FST_D, A_FST_S),
|
|
(A_FST_D, A_FST_S),
|
|
|
(A_FSTX_D, A_FSTX_S)
|
|
(A_FSTX_D, A_FSTX_S)
|
|
@@ -853,7 +860,7 @@ implementation
|
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
href:=ref;
|
|
href:=ref;
|
|
|
- op:=fst_ops[fixref(list,href,fr_reg,tmpreg),tosize=OS_F32];
|
|
|
|
|
|
|
+ op:=fst_ops[fixref(list,href,fr_reg,tmpreg,tmpreg2),tosize=OS_F32];
|
|
|
list.concat(taicpu.op_reg_ref(op,reg,href));
|
|
list.concat(taicpu.op_reg_ref(op,reg,href));
|
|
|
end;
|
|
end;
|
|
|
|
|
|
|
@@ -1498,11 +1505,14 @@ implementation
|
|
|
end;
|
|
end;
|
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
- function tcgloongarch64.fixref(list: TAsmList; var ref: treference; mode : tfixref; out tmpreg : tregister): boolean;
|
|
|
|
|
|
|
+ function tcgloongarch64.fixref(list: TAsmList; var ref: treference; mode : tfixref; out tmpreg, tmpreg2 : tregister): boolean;
|
|
|
var
|
|
var
|
|
|
href: treference;
|
|
href: treference;
|
|
|
|
|
+ ltmpreg : tregister;
|
|
|
begin
|
|
begin
|
|
|
tmpreg:=NR_NO;
|
|
tmpreg:=NR_NO;
|
|
|
|
|
+ tmpreg2:=NR_NO;
|
|
|
|
|
+ result:=false;
|
|
|
if ref.refaddr=addr_reg_12i then
|
|
if ref.refaddr=addr_reg_12i then
|
|
|
begin
|
|
begin
|
|
|
result:=mode=fr_normal;
|
|
result:=mode=fr_normal;
|
|
@@ -1513,7 +1523,7 @@ implementation
|
|
|
result:=mode=fr_reg;
|
|
result:=mode=fr_reg;
|
|
|
exit;
|
|
exit;
|
|
|
end
|
|
end
|
|
|
- else if ref.refaddr=addr_reg_reg then
|
|
|
|
|
|
|
+ else if ref.refaddr=addr_reg_14i then
|
|
|
begin
|
|
begin
|
|
|
result:=mode=fr_big;
|
|
result:=mode=fr_big;
|
|
|
exit;
|
|
exit;
|
|
@@ -1579,7 +1589,8 @@ implementation
|
|
|
begin
|
|
begin
|
|
|
if ref.index<>NR_R0 then
|
|
if ref.index<>NR_R0 then
|
|
|
begin
|
|
begin
|
|
|
- tmpreg:=getintregister(list,OS_INT);
|
|
|
|
|
|
|
+ if tmpreg=NR_NO then
|
|
|
|
|
+ tmpreg:=getintregister(list,OS_INT);
|
|
|
a_op_reg_reg_reg(list,OP_ADD,OS_INT,ref.base,ref.index,tmpreg);
|
|
a_op_reg_reg_reg(list,OP_ADD,OS_INT,ref.base,ref.index,tmpreg);
|
|
|
ref.base:=tmpreg;
|
|
ref.base:=tmpreg;
|
|
|
end;
|
|
end;
|
|
@@ -1593,7 +1604,8 @@ implementation
|
|
|
begin
|
|
begin
|
|
|
if ref.index<>NR_NO then
|
|
if ref.index<>NR_NO then
|
|
|
begin
|
|
begin
|
|
|
- tmpreg:=getintregister(list,OS_INT);
|
|
|
|
|
|
|
+ if tmpreg=NR_NO then
|
|
|
|
|
+ tmpreg:=getintregister(list,OS_INT);
|
|
|
a_op_reg_reg_reg(list,OP_ADD,OS_INT,ref.base,ref.index,tmpreg);
|
|
a_op_reg_reg_reg(list,OP_ADD,OS_INT,ref.base,ref.index,tmpreg);
|
|
|
ref.base:=tmpreg;
|
|
ref.base:=tmpreg;
|
|
|
end;
|
|
end;
|
|
@@ -1607,15 +1619,21 @@ implementation
|
|
|
begin
|
|
begin
|
|
|
if ref.offset<>0 then
|
|
if ref.offset<>0 then
|
|
|
begin
|
|
begin
|
|
|
- tmpreg:=getintregister(list,OS_INT);
|
|
|
|
|
- a_load_const_reg(list,OS_INT,ref.offset,tmpreg);
|
|
|
|
|
- if ref.index<>NR_R0 then
|
|
|
|
|
|
|
+ if (tmpreg<>NR_NO) and (ref.index=tmpreg) then
|
|
|
begin
|
|
begin
|
|
|
- a_op_reg_reg(list,OP_ADD,OS_INT,ref.index,tmpreg);
|
|
|
|
|
- ref.index:=tmpreg;
|
|
|
|
|
|
|
+ tmpreg2:=getintregister(list,OS_INT);
|
|
|
|
|
+ ltmpreg:=tmpreg2;
|
|
|
end
|
|
end
|
|
|
else
|
|
else
|
|
|
- ref.index:=tmpreg;
|
|
|
|
|
|
|
+ begin
|
|
|
|
|
+ if tmpreg=NR_NO then
|
|
|
|
|
+ tmpreg:=getintregister(list,OS_INT);
|
|
|
|
|
+ ltmpreg:=tmpreg;
|
|
|
|
|
+ end;
|
|
|
|
|
+ a_load_const_reg(list,OS_INT,ref.offset,ltmpreg);
|
|
|
|
|
+ if ref.index<>NR_R0 then
|
|
|
|
|
+ a_op_reg_reg(list,OP_ADD,OS_INT,ref.index,ltmpreg);
|
|
|
|
|
+ ref.index:=ltmpreg;
|
|
|
end;
|
|
end;
|
|
|
ref.refaddr:=addr_reg_reg;
|
|
ref.refaddr:=addr_reg_reg;
|
|
|
ref.offset:=0;
|
|
ref.offset:=0;
|
|
@@ -1623,12 +1641,22 @@ implementation
|
|
|
exit;
|
|
exit;
|
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
- tmpreg:=getintregister(list,OS_INT);
|
|
|
|
|
- a_load_const_reg(list,OS_INT,ref.offset,tmpreg);
|
|
|
|
|
|
|
+ if (tmpreg<>NR_NO) and ((tmpreg=ref.base) or (tmpreg=ref.index)) then
|
|
|
|
|
+ begin
|
|
|
|
|
+ tmpreg2:=getintregister(list,OS_INT);
|
|
|
|
|
+ ltmpreg:=tmpreg2;
|
|
|
|
|
+ end
|
|
|
|
|
+ else
|
|
|
|
|
+ begin
|
|
|
|
|
+ if tmpreg=NR_NO then
|
|
|
|
|
+ tmpreg:=getintregister(list,OS_INT);
|
|
|
|
|
+ ltmpreg:=tmpreg;
|
|
|
|
|
+ end;
|
|
|
|
|
+ a_load_const_reg(list,OS_INT,ref.offset,ltmpreg);
|
|
|
if ref.index<>NR_R0 then
|
|
if ref.index<>NR_R0 then
|
|
|
- a_op_reg_reg(list,OP_ADD,OS_INT,ref.index,tmpreg);
|
|
|
|
|
- a_op_reg_reg(list,OP_ADD,OS_INT,ref.base,tmpreg);
|
|
|
|
|
- ref.base:=tmpreg;
|
|
|
|
|
|
|
+ a_op_reg_reg(list,OP_ADD,OS_INT,ref.index,ltmpreg);
|
|
|
|
|
+ a_op_reg_reg(list,OP_ADD,OS_INT,ref.base,ltmpreg);
|
|
|
|
|
+ ref.base:=ltmpreg;
|
|
|
ref.index:=NR_NO;
|
|
ref.index:=NR_NO;
|
|
|
ref.offset:=0;
|
|
ref.offset:=0;
|
|
|
result:=mode=fr_normal;
|
|
result:=mode=fr_normal;
|