mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-18 08:29:20 +02:00
* handle LOC_(C)SUBSETREG/REF in second_NegNot_assign
* changed the way OP_NEG and OP_NOT are handled in op_reg_ref, in order to be
consistent with op_reg_reg
* introduced op_reg,op_ref,op_subsetreg,op_subsetref and op_loc for the unary
operations only (OP_NEG,OP_NOT)
git-svn-id: trunk@45302 -
(cherry picked from commit 0f6ab0de17
)
# Conflicts:
# compiler/cgobj.pas
This commit is contained in:
parent
3b8df7736c
commit
c9d2028ebd
@ -738,12 +738,17 @@ unit cg64f32;
|
|||||||
begin
|
begin
|
||||||
tempreg.reghi:=cg.getintregister(list,OS_32);
|
tempreg.reghi:=cg.getintregister(list,OS_32);
|
||||||
tempreg.reglo:=cg.getintregister(list,OS_32);
|
tempreg.reglo:=cg.getintregister(list,OS_32);
|
||||||
a_load64_ref_reg(list,ref,tempreg);
|
|
||||||
if op in [OP_NEG,OP_NOT] then
|
if op in [OP_NEG,OP_NOT] then
|
||||||
a_op64_reg_reg(list,op,size,tempreg,tempreg)
|
begin
|
||||||
|
a_op64_reg_reg(list,op,size,reg,tempreg);
|
||||||
|
a_load64_reg_ref(list,tempreg,ref);
|
||||||
|
end
|
||||||
else
|
else
|
||||||
a_op64_reg_reg(list,op,size,reg,tempreg);
|
begin
|
||||||
a_load64_reg_ref(list,tempreg,ref);
|
a_load64_ref_reg(list,ref,tempreg);
|
||||||
|
a_op64_reg_reg(list,op,size,reg,tempreg);
|
||||||
|
a_load64_reg_ref(list,tempreg,ref);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
@ -304,10 +304,6 @@ unit cgobj;
|
|||||||
procedure a_loadmm_reg_intreg(list: TAsmList; fromsize, tosize : tcgsize; mmreg, intreg: tregister; shuffle : pmmshuffle); virtual;
|
procedure a_loadmm_reg_intreg(list: TAsmList; fromsize, tosize : tcgsize; mmreg, intreg: tregister; shuffle : pmmshuffle); virtual;
|
||||||
|
|
||||||
{ basic arithmetic operations }
|
{ basic arithmetic operations }
|
||||||
{ note: for operators which require only one argument (not, neg), use }
|
|
||||||
{ the op_reg_reg, op_reg_ref or op_reg_loc methods and keep in mind }
|
|
||||||
{ that in this case the *second* operand is used as both source and }
|
|
||||||
{ destination (JM) }
|
|
||||||
procedure a_op_const_reg(list : TAsmList; Op: TOpCG; size: TCGSize; a: tcgint; reg: TRegister); virtual; abstract;
|
procedure a_op_const_reg(list : TAsmList; Op: TOpCG; size: TCGSize; a: tcgint; reg: TRegister); virtual; abstract;
|
||||||
procedure a_op_const_ref(list : TAsmList; Op: TOpCG; size: TCGSize; a: tcgint; const ref: TReference); virtual;
|
procedure a_op_const_ref(list : TAsmList; Op: TOpCG; size: TCGSize; a: tcgint; const ref: TReference); virtual;
|
||||||
procedure a_op_const_loc(list : TAsmList; Op: TOpCG; a: tcgint; const loc: tlocation);
|
procedure a_op_const_loc(list : TAsmList; Op: TOpCG; a: tcgint; const loc: tlocation);
|
||||||
@ -326,6 +322,11 @@ unit cgobj;
|
|||||||
procedure a_op_const_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tcgsize; a: tcgint; src, dst: tregister;setflags : boolean;var ovloc : tlocation); virtual;
|
procedure a_op_const_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tcgsize; a: tcgint; src, dst: tregister;setflags : boolean;var ovloc : tlocation); virtual;
|
||||||
procedure a_op_reg_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tcgsize; src1, src2, dst: tregister;setflags : boolean;var ovloc : tlocation); virtual;
|
procedure a_op_reg_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tcgsize; src1, src2, dst: tregister;setflags : boolean;var ovloc : tlocation); virtual;
|
||||||
|
|
||||||
|
{ unary operations (not, neg) }
|
||||||
|
procedure a_op_reg(list : TAsmList; Op: TOpCG; size: TCGSize; reg: TRegister); virtual;
|
||||||
|
procedure a_op_ref(list : TAsmList; Op: TOpCG; size: TCGSize; const ref: TReference); virtual;
|
||||||
|
procedure a_op_loc(list : TAsmList; Op: TOpCG; const loc: tlocation);
|
||||||
|
|
||||||
{ comparison operations }
|
{ comparison operations }
|
||||||
procedure a_cmp_const_reg_label(list : TAsmList;size : tcgsize;cmp_op : topcmp;a : tcgint;reg : tregister;
|
procedure a_cmp_const_reg_label(list : TAsmList;size : tcgsize;cmp_op : topcmp;a : tcgint;reg : tregister;
|
||||||
l : tasmlabel); virtual;
|
l : tasmlabel); virtual;
|
||||||
@ -526,6 +527,9 @@ unit cgobj;
|
|||||||
procedure a_op64_reg_reg_reg(list: TAsmList;op:TOpCG;size : tcgsize;regsrc1,regsrc2,regdst : tregister64);virtual;
|
procedure a_op64_reg_reg_reg(list: TAsmList;op:TOpCG;size : tcgsize;regsrc1,regsrc2,regdst : tregister64);virtual;
|
||||||
procedure a_op64_const_reg_reg_checkoverflow(list: TAsmList;op:TOpCG;size : tcgsize;value : int64;regsrc,regdst : tregister64;setflags : boolean;var ovloc : tlocation);virtual;
|
procedure a_op64_const_reg_reg_checkoverflow(list: TAsmList;op:TOpCG;size : tcgsize;value : int64;regsrc,regdst : tregister64;setflags : boolean;var ovloc : tlocation);virtual;
|
||||||
procedure a_op64_reg_reg_reg_checkoverflow(list: TAsmList;op:TOpCG;size : tcgsize;regsrc1,regsrc2,regdst : tregister64;setflags : boolean;var ovloc : tlocation);virtual;
|
procedure a_op64_reg_reg_reg_checkoverflow(list: TAsmList;op:TOpCG;size : tcgsize;regsrc1,regsrc2,regdst : tregister64;setflags : boolean;var ovloc : tlocation);virtual;
|
||||||
|
procedure a_op64_reg(list : TAsmList;op:TOpCG;size : tcgsize;regdst : tregister64);virtual;
|
||||||
|
procedure a_op64_ref(list : TAsmList;op:TOpCG;size : tcgsize;const ref : treference);virtual;
|
||||||
|
procedure a_op64_loc(list : TAsmList;op:TOpCG;size : tcgsize;const l : tlocation);virtual;
|
||||||
|
|
||||||
procedure a_op64_const_subsetref(list : TAsmList; Op : TOpCG; size : TCGSize; a : int64; const sref: tsubsetreference);
|
procedure a_op64_const_subsetref(list : TAsmList; Op : TOpCG; size : TCGSize; a : int64; const sref: tsubsetreference);
|
||||||
procedure a_op64_reg_subsetref(list : TAsmList; Op : TOpCG; size : TCGSize; reg: tregister64; const sref: tsubsetreference);
|
procedure a_op64_reg_subsetref(list : TAsmList; Op : TOpCG; size : TCGSize; reg: tregister64; const sref: tsubsetreference);
|
||||||
@ -580,9 +584,6 @@ unit cgobj;
|
|||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses
|
uses
|
||||||
globals,systems,
|
|
||||||
verbose,paramgr,symsym,
|
|
||||||
tgobj,cutils,procinfo;
|
|
||||||
globals,systems,fmodule,
|
globals,systems,fmodule,
|
||||||
verbose,paramgr,symsym,symtable,
|
verbose,paramgr,symsym,symtable,
|
||||||
tgobj,cutils,procinfo,
|
tgobj,cutils,procinfo,
|
||||||
@ -1995,13 +1996,17 @@ implementation
|
|||||||
tmpref:=ref;
|
tmpref:=ref;
|
||||||
if op in [OP_NEG,OP_NOT] then
|
if op in [OP_NEG,OP_NOT] then
|
||||||
begin
|
begin
|
||||||
if reg<>NR_NO then
|
tmpreg:=getintregister(list,size);
|
||||||
internalerror(2017040901);
|
a_op_reg_reg(list,op,size,reg,tmpreg);
|
||||||
a_op_reg_reg(list,op,size,tmpreg,tmpreg);
|
a_load_reg_ref(list,size,size,tmpreg,tmpref);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
a_op_reg_reg(list,op,size,reg,tmpreg);
|
begin
|
||||||
a_load_reg_ref(list,size,size,tmpreg,ref);
|
tmpreg:=getintregister(list,size);
|
||||||
|
a_load_ref_reg(list,size,size,tmpref,tmpreg);
|
||||||
|
a_op_reg_reg(list,op,size,reg,tmpreg);
|
||||||
|
a_load_reg_ref(list,size,size,tmpreg,tmpref);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -2192,6 +2197,49 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure tcg.a_op_reg(list: TAsmList; Op: TOpCG; size: TCGSize; reg: TRegister);
|
||||||
|
begin
|
||||||
|
if not (Op in [OP_NOT,OP_NEG]) then
|
||||||
|
internalerror(2020050701);
|
||||||
|
a_op_reg_reg(list,op,size,reg,reg);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure tcg.a_op_ref(list: TAsmList; Op: TOpCG; size: TCGSize; const ref: TReference);
|
||||||
|
var
|
||||||
|
tmpreg: TRegister;
|
||||||
|
tmpref: treference;
|
||||||
|
begin
|
||||||
|
if not (Op in [OP_NOT,OP_NEG]) then
|
||||||
|
internalerror(2020050701);
|
||||||
|
if assigned(ref.symbol) then
|
||||||
|
begin
|
||||||
|
tmpreg:=getaddressregister(list);
|
||||||
|
a_loadaddr_ref_reg(list,ref,tmpreg);
|
||||||
|
reference_reset_base(tmpref,tmpreg,0,ref.temppos,ref.alignment,[]);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
tmpref:=ref;
|
||||||
|
tmpreg:=getintregister(list,size);
|
||||||
|
a_load_ref_reg(list,size,size,tmpref,tmpreg);
|
||||||
|
a_op_reg_reg(list,op,size,tmpreg,tmpreg);
|
||||||
|
a_load_reg_ref(list,size,size,tmpreg,tmpref);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure tcg.a_op_loc(list: TAsmList; Op: TOpCG; const loc: tlocation);
|
||||||
|
begin
|
||||||
|
case loc.loc of
|
||||||
|
LOC_REGISTER, LOC_CREGISTER:
|
||||||
|
a_op_reg(list,op,loc.size,loc.register);
|
||||||
|
LOC_REFERENCE, LOC_CREFERENCE:
|
||||||
|
a_op_ref(list,op,loc.size,loc.reference);
|
||||||
|
else
|
||||||
|
internalerror(2020050702);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure tcg.a_cmp_const_reg_label(list: TAsmList; size: tcgsize;
|
procedure tcg.a_cmp_const_reg_label(list: TAsmList; size: tcgsize;
|
||||||
cmp_op: topcmp; a: tcgint; reg: tregister; l: tasmlabel);
|
cmp_op: topcmp; a: tcgint; reg: tregister; l: tasmlabel);
|
||||||
var
|
var
|
||||||
@ -3044,6 +3092,41 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure tcg64.a_op64_reg(list: TAsmList; op: TOpCG; size: tcgsize; regdst: tregister64);
|
||||||
|
begin
|
||||||
|
if not (op in [OP_NOT,OP_NEG]) then
|
||||||
|
internalerror(2020050706);
|
||||||
|
a_op64_reg_reg(list,op,size,regdst,regdst);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure tcg64.a_op64_ref(list: TAsmList; op: TOpCG; size: tcgsize; const ref: treference);
|
||||||
|
var
|
||||||
|
tempreg: tregister64;
|
||||||
|
begin
|
||||||
|
if not (op in [OP_NOT,OP_NEG]) then
|
||||||
|
internalerror(2020050706);
|
||||||
|
tempreg.reghi:=cg.getintregister(list,OS_32);
|
||||||
|
tempreg.reglo:=cg.getintregister(list,OS_32);
|
||||||
|
a_load64_ref_reg(list,ref,tempreg);
|
||||||
|
a_op64_reg_reg(list,op,size,tempreg,tempreg);
|
||||||
|
a_load64_reg_ref(list,tempreg,ref);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure tcg64.a_op64_loc(list: TAsmList; op: TOpCG; size: tcgsize; const l: tlocation);
|
||||||
|
begin
|
||||||
|
case l.loc of
|
||||||
|
LOC_REFERENCE, LOC_CREFERENCE:
|
||||||
|
a_op64_ref(list,op,size,l.reference);
|
||||||
|
LOC_REGISTER,LOC_CREGISTER:
|
||||||
|
a_op64_reg(list,op,size,l.register64);
|
||||||
|
else
|
||||||
|
internalerror(2020050707);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure tcg64.a_load64_loc_subsetref(list : TAsmList;const l: tlocation; const sref : tsubsetreference);
|
procedure tcg64.a_load64_loc_subsetref(list : TAsmList;const l: tlocation; const sref : tsubsetreference);
|
||||||
begin
|
begin
|
||||||
case l.loc of
|
case l.loc of
|
||||||
|
@ -221,6 +221,11 @@ unit hlcg2ll;
|
|||||||
procedure a_op_const_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tdef; a: tcgint; src, dst: tregister;setflags : boolean;var ovloc : tlocation); override;
|
procedure a_op_const_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tdef; a: tcgint; src, dst: tregister;setflags : boolean;var ovloc : tlocation); override;
|
||||||
procedure a_op_reg_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tdef; src1, src2, dst: tregister;setflags : boolean;var ovloc : tlocation); override;
|
procedure a_op_reg_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tdef; src1, src2, dst: tregister;setflags : boolean;var ovloc : tlocation); override;
|
||||||
|
|
||||||
|
{ unary operations (not, neg) }
|
||||||
|
procedure a_op_reg(list : TAsmList; Op: TOpCG; size: tdef; reg: TRegister); override;
|
||||||
|
procedure a_op_ref(list : TAsmList; Op: TOpCG; size: tdef; const ref: TReference); override;
|
||||||
|
procedure a_op_loc(list : TAsmList; Op: TOpCG; size: tdef; const loc: tlocation); override;
|
||||||
|
|
||||||
{ comparison operations }
|
{ comparison operations }
|
||||||
procedure a_cmp_const_reg_label(list : TAsmList;size : tdef;cmp_op : topcmp;a : tcgint;reg : tregister;
|
procedure a_cmp_const_reg_label(list : TAsmList;size : tdef;cmp_op : topcmp;a : tcgint;reg : tregister;
|
||||||
l : tasmlabel);override;
|
l : tasmlabel);override;
|
||||||
@ -862,6 +867,31 @@ implementation
|
|||||||
cg.a_op_reg_reg_reg_checkoverflow(list,op,def_cgsize(size),src1,src2,dst,setflags,ovloc);
|
cg.a_op_reg_reg_reg_checkoverflow(list,op,def_cgsize(size),src1,src2,dst,setflags,ovloc);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure thlcg2ll.a_op_reg(list: TAsmList; Op: TOpCG; size: tdef; reg: TRegister);
|
||||||
|
begin
|
||||||
|
cg.a_op_reg(list,op,def_cgsize(size),reg);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure thlcg2ll.a_op_ref(list: TAsmList; Op: TOpCG; size: tdef; const ref: TReference);
|
||||||
|
begin
|
||||||
|
cg.a_op_ref(list,op,def_cgsize(size),ref);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure thlcg2ll.a_op_loc(list: TAsmList; Op: TOpCG; size: tdef; const loc: tlocation);
|
||||||
|
begin
|
||||||
|
{$ifdef extdebug}
|
||||||
|
if def_cgsize(size)<>loc.size then
|
||||||
|
internalerror(2020050704);
|
||||||
|
{$endif}
|
||||||
|
case loc.loc of
|
||||||
|
LOC_SUBSETREG,LOC_CSUBSETREG,
|
||||||
|
LOC_SUBSETREF,LOC_CSUBSETREF:
|
||||||
|
inherited
|
||||||
|
else
|
||||||
|
cg.a_op_loc(list,op,loc);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure thlcg2ll.a_cmp_const_reg_label(list: TAsmList; size: tdef; cmp_op: topcmp; a: tcgint; reg: tregister; l: tasmlabel);
|
procedure thlcg2ll.a_cmp_const_reg_label(list: TAsmList; size: tdef; cmp_op: topcmp; a: tcgint; reg: tregister; l: tasmlabel);
|
||||||
begin
|
begin
|
||||||
cg.a_cmp_const_reg_label(list,def_cgsize(size),cmp_op,a,reg,l);
|
cg.a_cmp_const_reg_label(list,def_cgsize(size),cmp_op,a,reg,l);
|
||||||
|
@ -340,10 +340,6 @@ unit hlcgobj;
|
|||||||
procedure a_loadmm_reg_intreg(list: TAsmList; fromsize, tosize : tdef; mmreg, intreg: tregister; shuffle : pmmshuffle); virtual; abstract;
|
procedure a_loadmm_reg_intreg(list: TAsmList; fromsize, tosize : tdef; mmreg, intreg: tregister; shuffle : pmmshuffle); virtual; abstract;
|
||||||
|
|
||||||
{ basic arithmetic operations }
|
{ basic arithmetic operations }
|
||||||
{ note: for operators which require only one argument (not, neg), use }
|
|
||||||
{ the op_reg_reg, op_reg_ref or op_reg_loc methods and keep in mind }
|
|
||||||
{ that in this case the *second* operand is used as both source and }
|
|
||||||
{ destination (JM) }
|
|
||||||
procedure a_op_const_reg(list : TAsmList; Op: TOpCG; size: tdef; a: tcgint; reg: TRegister); virtual; abstract;
|
procedure a_op_const_reg(list : TAsmList; Op: TOpCG; size: tdef; a: tcgint; reg: TRegister); virtual; abstract;
|
||||||
procedure a_op_const_ref(list : TAsmList; Op: TOpCG; size: tdef; a: tcgint; const ref: TReference); virtual;
|
procedure a_op_const_ref(list : TAsmList; Op: TOpCG; size: tdef; a: tcgint; const ref: TReference); virtual;
|
||||||
procedure a_op_const_subsetreg(list : TAsmList; Op : TOpCG; size, subsetsize : tdef; a : tcgint; const sreg: tsubsetregister); virtual;
|
procedure a_op_const_subsetreg(list : TAsmList; Op : TOpCG; size, subsetsize : tdef; a : tcgint; const sreg: tsubsetregister); virtual;
|
||||||
@ -365,6 +361,13 @@ unit hlcgobj;
|
|||||||
procedure a_op_const_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tdef; a: tcgint; src, dst: tregister;setflags : boolean;var ovloc : tlocation); virtual;
|
procedure a_op_const_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tdef; a: tcgint; src, dst: tregister;setflags : boolean;var ovloc : tlocation); virtual;
|
||||||
procedure a_op_reg_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tdef; src1, src2, dst: tregister;setflags : boolean;var ovloc : tlocation); virtual;
|
procedure a_op_reg_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tdef; src1, src2, dst: tregister;setflags : boolean;var ovloc : tlocation); virtual;
|
||||||
|
|
||||||
|
{ unary operations (not, neg) }
|
||||||
|
procedure a_op_reg(list : TAsmList; Op: TOpCG; size: tdef; reg: TRegister); virtual;
|
||||||
|
procedure a_op_ref(list : TAsmList; Op: TOpCG; size: tdef; const ref: TReference); virtual;
|
||||||
|
procedure a_op_subsetreg(list: TAsmList; Op: TOpCG; destsubsetsize: tdef; const sreg: tsubsetregister); virtual;
|
||||||
|
procedure a_op_subsetref(list: TAsmList; Op: TOpCG; destsubsetsize: tdef; const sref: tsubsetreference); virtual;
|
||||||
|
procedure a_op_loc(list : TAsmList; Op: TOpCG; size: tdef; const loc: tlocation); virtual;
|
||||||
|
|
||||||
{ comparison operations }
|
{ comparison operations }
|
||||||
procedure a_cmp_const_reg_label(list : TAsmList;size : tdef;cmp_op : topcmp;a : tcgint;reg : tregister;
|
procedure a_cmp_const_reg_label(list : TAsmList;size : tdef;cmp_op : topcmp;a : tcgint;reg : tregister;
|
||||||
l : tasmlabel);virtual;
|
l : tasmlabel);virtual;
|
||||||
@ -2994,6 +2997,65 @@ implementation
|
|||||||
internalerror(2010122911);
|
internalerror(2010122911);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure thlcgobj.a_op_reg(list: TAsmList; Op: TOpCG; size: tdef; reg: TRegister);
|
||||||
|
begin
|
||||||
|
if not (Op in [OP_NOT,OP_NEG]) then
|
||||||
|
internalerror(2020050701);
|
||||||
|
a_op_reg_reg(list,op,size,reg,reg);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure thlcgobj.a_op_ref(list: TAsmList; Op: TOpCG; size: tdef; const ref: TReference);
|
||||||
|
var
|
||||||
|
tmpreg: TRegister;
|
||||||
|
begin
|
||||||
|
if not (Op in [OP_NOT,OP_NEG]) then
|
||||||
|
internalerror(2020050701);
|
||||||
|
tmpreg:=getintregister(list,size);
|
||||||
|
a_load_ref_reg(list,size,size,ref,tmpreg);
|
||||||
|
a_op_reg_reg(list,op,size,tmpreg,tmpreg);
|
||||||
|
a_load_reg_ref(list,size,size,tmpreg,ref);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure thlcgobj.a_op_subsetreg(list: TAsmList; Op: TOpCG; destsubsetsize: tdef; const sreg: tsubsetregister);
|
||||||
|
var
|
||||||
|
tmpreg: tregister;
|
||||||
|
subsetregdef: torddef;
|
||||||
|
begin
|
||||||
|
subsetregdef:=cgsize_orddef(sreg.subsetregsize);
|
||||||
|
tmpreg:=getintregister(list,subsetregdef);
|
||||||
|
a_load_subsetreg_reg(list,destsubsetsize,subsetregdef,sreg,tmpreg);
|
||||||
|
a_op_reg(list,op,subsetregdef,tmpreg);
|
||||||
|
a_load_reg_subsetreg(list,subsetregdef,destsubsetsize,tmpreg,sreg);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure thlcgobj.a_op_subsetref(list: TAsmList; Op: TOpCG; destsubsetsize: tdef; const sref: tsubsetreference);
|
||||||
|
var
|
||||||
|
tmpreg: tregister;
|
||||||
|
subsetregdef: torddef;
|
||||||
|
begin
|
||||||
|
subsetregdef:=cgsize_orddef(def_cgsize(destsubsetsize));
|
||||||
|
tmpreg:=getintregister(list,subsetregdef);
|
||||||
|
a_load_subsetref_reg(list,destsubsetsize,subsetregdef,sref,tmpreg);
|
||||||
|
a_op_reg(list,op,subsetregdef,tmpreg);
|
||||||
|
a_load_reg_subsetref(list,subsetregdef,destsubsetsize,tmpreg,sref);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure thlcgobj.a_op_loc(list: TAsmList; Op: TOpCG; size: tdef; const loc: tlocation);
|
||||||
|
begin
|
||||||
|
case loc.loc of
|
||||||
|
LOC_REGISTER, LOC_CREGISTER:
|
||||||
|
a_op_reg(list,op,size,loc.register);
|
||||||
|
LOC_REFERENCE, LOC_CREFERENCE:
|
||||||
|
a_op_ref(list,op,size,loc.reference);
|
||||||
|
LOC_SUBSETREG, LOC_CSUBSETREG:
|
||||||
|
a_op_subsetreg(list,op,size,loc.sreg);
|
||||||
|
LOC_SUBSETREF, LOC_CSUBSETREF:
|
||||||
|
a_op_subsetref(list,op,size,loc.sref);
|
||||||
|
else
|
||||||
|
internalerror(2020050703);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure thlcgobj.a_cmp_const_reg_label(list: TAsmList; size: tdef; cmp_op: topcmp; a: tcgint; reg: tregister; l: tasmlabel);
|
procedure thlcgobj.a_cmp_const_reg_label(list: TAsmList; size: tdef; cmp_op: topcmp; a: tcgint; reg: tregister; l: tasmlabel);
|
||||||
var
|
var
|
||||||
tmpreg: tregister;
|
tmpreg: tregister;
|
||||||
|
@ -56,6 +56,7 @@ unit cgcpu;
|
|||||||
procedure a_op64_reg_reg(list : TAsmList;op:TOpCG;size : tcgsize;regsrc,regdst : tregister64);override;
|
procedure a_op64_reg_reg(list : TAsmList;op:TOpCG;size : tcgsize;regsrc,regdst : tregister64);override;
|
||||||
procedure a_op64_const_reg(list : TAsmList;op:TOpCG;size : tcgsize;value : int64;reg : tregister64);override;
|
procedure a_op64_const_reg(list : TAsmList;op:TOpCG;size : tcgsize;value : int64;reg : tregister64);override;
|
||||||
procedure a_op64_const_ref(list : TAsmList;op:TOpCG;size : tcgsize;value : int64;const ref : treference);override;
|
procedure a_op64_const_ref(list : TAsmList;op:TOpCG;size : tcgsize;value : int64;const ref : treference);override;
|
||||||
|
procedure a_op64_ref(list : TAsmList;op:TOpCG;size : tcgsize;const ref: treference);override;
|
||||||
private
|
private
|
||||||
procedure get_64bit_ops(op:TOpCG;var op1,op2:TAsmOp);
|
procedure get_64bit_ops(op:TOpCG;var op1,op2:TAsmOp);
|
||||||
end;
|
end;
|
||||||
@ -663,27 +664,8 @@ unit cgcpu;
|
|||||||
l1, l2: TAsmLabel;
|
l1, l2: TAsmLabel;
|
||||||
begin
|
begin
|
||||||
case op of
|
case op of
|
||||||
OP_NOT:
|
OP_NOT,OP_NEG:
|
||||||
begin
|
inherited;
|
||||||
tempref:=ref;
|
|
||||||
tcgx86(cg).make_simple_ref(list,tempref);
|
|
||||||
list.concat(taicpu.op_ref(A_NOT,S_L,tempref));
|
|
||||||
inc(tempref.offset,4);
|
|
||||||
list.concat(taicpu.op_ref(A_NOT,S_L,tempref));
|
|
||||||
end;
|
|
||||||
OP_NEG:
|
|
||||||
begin
|
|
||||||
tempref:=ref;
|
|
||||||
tcgx86(cg).make_simple_ref(list,tempref);
|
|
||||||
inc(tempref.offset,4);
|
|
||||||
list.concat(taicpu.op_ref(A_NOT,S_L,tempref));
|
|
||||||
cg.a_reg_alloc(list,NR_DEFAULTFLAGS);
|
|
||||||
dec(tempref.offset,4);
|
|
||||||
list.concat(taicpu.op_ref(A_NEG,S_L,tempref));
|
|
||||||
inc(tempref.offset,4);
|
|
||||||
list.concat(taicpu.op_const_ref(A_SBB,S_L,-1,tempref));
|
|
||||||
cg.a_reg_dealloc(list,NR_DEFAULTFLAGS);
|
|
||||||
end;
|
|
||||||
OP_SHR,OP_SHL,OP_SAR:
|
OP_SHR,OP_SHL,OP_SAR:
|
||||||
begin
|
begin
|
||||||
{ load right operators in a register }
|
{ load right operators in a register }
|
||||||
@ -1140,6 +1122,39 @@ unit cgcpu;
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure tcg64f386.a_op64_ref(list: TAsmList; op: TOpCG; size: tcgsize; const ref: treference);
|
||||||
|
var
|
||||||
|
tempref : treference;
|
||||||
|
begin
|
||||||
|
case op of
|
||||||
|
OP_NOT:
|
||||||
|
begin
|
||||||
|
tempref:=ref;
|
||||||
|
tcgx86(cg).make_simple_ref(list,tempref);
|
||||||
|
list.concat(taicpu.op_ref(A_NOT,S_L,tempref));
|
||||||
|
inc(tempref.offset,4);
|
||||||
|
list.concat(taicpu.op_ref(A_NOT,S_L,tempref));
|
||||||
|
end;
|
||||||
|
OP_NEG:
|
||||||
|
begin
|
||||||
|
tempref:=ref;
|
||||||
|
tcgx86(cg).make_simple_ref(list,tempref);
|
||||||
|
inc(tempref.offset,4);
|
||||||
|
list.concat(taicpu.op_ref(A_NOT,S_L,tempref));
|
||||||
|
cg.a_reg_alloc(list,NR_DEFAULTFLAGS);
|
||||||
|
dec(tempref.offset,4);
|
||||||
|
list.concat(taicpu.op_ref(A_NEG,S_L,tempref));
|
||||||
|
inc(tempref.offset,4);
|
||||||
|
list.concat(taicpu.op_const_ref(A_SBB,S_L,-1,tempref));
|
||||||
|
cg.a_reg_dealloc(list,NR_DEFAULTFLAGS);
|
||||||
|
end;
|
||||||
|
else
|
||||||
|
internalerror(2020050708);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure create_codegen;
|
procedure create_codegen;
|
||||||
begin
|
begin
|
||||||
cg := tcg386.create;
|
cg := tcg386.create;
|
||||||
|
@ -53,6 +53,7 @@ unit cgcpu;
|
|||||||
procedure a_op_reg_reg(list : TAsmList; Op: TOpCG; size: TCGSize; src, dst: TRegister); override;
|
procedure a_op_reg_reg(list : TAsmList; Op: TOpCG; size: TCGSize; src, dst: TRegister); override;
|
||||||
procedure a_op_ref_reg(list : TAsmList; Op: TOpCG; size: TCGSize; const ref: TReference; reg: TRegister); override;
|
procedure a_op_ref_reg(list : TAsmList; Op: TOpCG; size: TCGSize; const ref: TReference; reg: TRegister); override;
|
||||||
procedure a_op_reg_ref(list : TAsmList; Op: TOpCG; size: TCGSize;reg: TRegister; const ref: TReference); override;
|
procedure a_op_reg_ref(list : TAsmList; Op: TOpCG; size: TCGSize;reg: TRegister; const ref: TReference); override;
|
||||||
|
procedure a_op_ref(list : TAsmList; Op: TOpCG; size: TCGSize; const ref: TReference); override;
|
||||||
|
|
||||||
procedure push_const(list:TAsmList;size:tcgsize;a:tcgint);
|
procedure push_const(list:TAsmList;size:tcgsize;a:tcgint);
|
||||||
|
|
||||||
@ -1138,7 +1139,7 @@ unit cgcpu;
|
|||||||
begin
|
begin
|
||||||
tmpref:=ref;
|
tmpref:=ref;
|
||||||
make_simple_ref(list,tmpref);
|
make_simple_ref(list,tmpref);
|
||||||
if not (op in [OP_NEG,OP_NOT,OP_SHR,OP_SHL,OP_SAR,OP_ROL,OP_ROR]) then
|
if not (op in [OP_SHR,OP_SHL,OP_SAR,OP_ROL,OP_ROR]) then
|
||||||
check_register_size(size,reg);
|
check_register_size(size,reg);
|
||||||
|
|
||||||
if size in [OS_64, OS_S64] then
|
if size in [OS_64, OS_S64] then
|
||||||
@ -1147,27 +1148,8 @@ unit cgcpu;
|
|||||||
if size in [OS_32, OS_S32] then
|
if size in [OS_32, OS_S32] then
|
||||||
begin
|
begin
|
||||||
case op of
|
case op of
|
||||||
OP_NEG:
|
OP_NEG,OP_NOT:
|
||||||
begin
|
inherited;
|
||||||
if reg<>NR_NO then
|
|
||||||
internalerror(200109237);
|
|
||||||
inc(tmpref.offset, 2);
|
|
||||||
list.concat(taicpu.op_ref(A_NOT, S_W, tmpref));
|
|
||||||
dec(tmpref.offset, 2);
|
|
||||||
cg.a_reg_alloc(list,NR_DEFAULTFLAGS);
|
|
||||||
list.concat(taicpu.op_ref(A_NEG, S_W, tmpref));
|
|
||||||
inc(tmpref.offset, 2);
|
|
||||||
list.concat(taicpu.op_const_ref(A_SBB, S_W,-1, tmpref));
|
|
||||||
cg.a_reg_dealloc(list,NR_DEFAULTFLAGS);
|
|
||||||
end;
|
|
||||||
OP_NOT:
|
|
||||||
begin
|
|
||||||
if reg<>NR_NO then
|
|
||||||
internalerror(200109237);
|
|
||||||
list.concat(taicpu.op_ref(A_NOT, S_W, tmpref));
|
|
||||||
inc(tmpref.offset, 2);
|
|
||||||
list.concat(taicpu.op_ref(A_NOT, S_W, tmpref));
|
|
||||||
end;
|
|
||||||
OP_IMUL:
|
OP_IMUL:
|
||||||
begin
|
begin
|
||||||
{ this one needs a load/imul/store, which is the default }
|
{ this one needs a load/imul/store, which is the default }
|
||||||
@ -1260,6 +1242,46 @@ unit cgcpu;
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure tcg8086.a_op_ref(list: TAsmList; Op: TOpCG; size: TCGSize; const ref: TReference);
|
||||||
|
begin
|
||||||
|
var
|
||||||
|
tmpref: treference;
|
||||||
|
begin
|
||||||
|
tmpref:=ref;
|
||||||
|
make_simple_ref(list,tmpref);
|
||||||
|
|
||||||
|
if size in [OS_64, OS_S64] then
|
||||||
|
internalerror(2013050803);
|
||||||
|
|
||||||
|
if size in [OS_32, OS_S32] then
|
||||||
|
begin
|
||||||
|
case op of
|
||||||
|
OP_NEG:
|
||||||
|
begin
|
||||||
|
inc(tmpref.offset, 2);
|
||||||
|
list.concat(taicpu.op_ref(A_NOT, S_W, tmpref));
|
||||||
|
dec(tmpref.offset, 2);
|
||||||
|
cg.a_reg_alloc(list,NR_DEFAULTFLAGS);
|
||||||
|
list.concat(taicpu.op_ref(A_NEG, S_W, tmpref));
|
||||||
|
inc(tmpref.offset, 2);
|
||||||
|
list.concat(taicpu.op_const_ref(A_SBB, S_W,-1, tmpref));
|
||||||
|
cg.a_reg_dealloc(list,NR_DEFAULTFLAGS);
|
||||||
|
end;
|
||||||
|
OP_NOT:
|
||||||
|
begin
|
||||||
|
list.concat(taicpu.op_ref(A_NOT, S_W, tmpref));
|
||||||
|
inc(tmpref.offset, 2);
|
||||||
|
list.concat(taicpu.op_ref(A_NOT, S_W, tmpref));
|
||||||
|
end;
|
||||||
|
else
|
||||||
|
internalerror(2020050709);
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
inherited a_op_reg_ref(list,Op,size,reg,tmpref);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure tcg8086.push_const(list: TAsmList; size: tcgsize; a: tcgint);
|
procedure tcg8086.push_const(list: TAsmList; size: tcgsize; a: tcgint);
|
||||||
var
|
var
|
||||||
tmpreg: TRegister;
|
tmpreg: TRegister;
|
||||||
|
@ -527,36 +527,18 @@ implementation
|
|||||||
procedure tcginlinenode.second_NegNot_assign;
|
procedure tcginlinenode.second_NegNot_assign;
|
||||||
const
|
const
|
||||||
negnotop:array[in_neg_assign_x..in_not_assign_x] of TOpCG=(OP_NEG,OP_NOT);
|
negnotop:array[in_neg_assign_x..in_not_assign_x] of TOpCG=(OP_NEG,OP_NOT);
|
||||||
{$ifndef cpu64bitalu}
|
|
||||||
var
|
|
||||||
NR_NO64: tregister64=(reglo:NR_NO;reghi:NR_NO);
|
|
||||||
{$endif not cpu64bitalu}
|
|
||||||
begin
|
begin
|
||||||
{ load parameter, must be a reference }
|
{ load parameter, must be a reference }
|
||||||
secondpass(left);
|
secondpass(left);
|
||||||
|
|
||||||
location_reset(location,LOC_VOID,OS_NO);
|
location_reset(location,LOC_VOID,OS_NO);
|
||||||
|
|
||||||
if left.location.loc in [LOC_REGISTER,LOC_CREGISTER] then
|
|
||||||
begin
|
|
||||||
{$ifndef cpu64bitalu}
|
{$ifndef cpu64bitalu}
|
||||||
if def_cgsize(left.resultdef) in [OS_64,OS_S64] then
|
if (def_cgsize(left.resultdef) in [OS_64,OS_S64]) and (left.location.loc in [LOC_REGISTER,LOC_CREGISTER,LOC_REFERENCE,LOC_CREFERENCE]) then
|
||||||
cg64.a_op64_reg_loc(current_asmdata.CurrAsmList,negnotop[inlinenumber],def_cgsize(left.resultdef),left.location.register64,left.location)
|
cg64.a_op64_loc(current_asmdata.CurrAsmList,negnotop[inlinenumber],def_cgsize(left.resultdef),left.location)
|
||||||
else
|
|
||||||
{$endif not cpu64bitalu}
|
|
||||||
hlcg.a_op_reg_loc(current_asmdata.CurrAsmList,negnotop[inlinenumber],left.resultdef,left.location.register,left.location);
|
|
||||||
end
|
|
||||||
else if left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE] then
|
|
||||||
begin
|
|
||||||
{$ifndef cpu64bitalu}
|
|
||||||
if def_cgsize(left.resultdef) in [OS_64,OS_S64] then
|
|
||||||
cg64.a_op64_reg_loc(current_asmdata.CurrAsmList,negnotop[inlinenumber],def_cgsize(left.resultdef),NR_NO64,left.location)
|
|
||||||
else
|
|
||||||
{$endif not cpu64bitalu}
|
|
||||||
hlcg.a_op_reg_loc(current_asmdata.CurrAsmList,negnotop[inlinenumber],left.resultdef,NR_NO,left.location);
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
internalerror(2017040701);
|
{$endif not cpu64bitalu}
|
||||||
|
hlcg.a_op_loc(current_asmdata.CurrAsmList,negnotop[inlinenumber],left.resultdef,left.location);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
@ -67,6 +67,7 @@ unit cgx86;
|
|||||||
procedure a_op_reg_reg(list : TAsmList; Op: TOpCG; size: TCGSize; src, dst: TRegister); override;
|
procedure a_op_reg_reg(list : TAsmList; Op: TOpCG; size: TCGSize; src, dst: TRegister); override;
|
||||||
procedure a_op_ref_reg(list : TAsmList; Op: TOpCG; size: TCGSize; const ref: TReference; reg: TRegister); override;
|
procedure a_op_ref_reg(list : TAsmList; Op: TOpCG; size: TCGSize; const ref: TReference; reg: TRegister); override;
|
||||||
procedure a_op_reg_ref(list : TAsmList; Op: TOpCG; size: TCGSize;reg: TRegister; const ref: TReference); override;
|
procedure a_op_reg_ref(list : TAsmList; Op: TOpCG; size: TCGSize;reg: TRegister; const ref: TReference); override;
|
||||||
|
procedure a_op_ref(list : TAsmList; Op: TOpCG; size: TCGSize; const ref: TReference); override;
|
||||||
|
|
||||||
{$ifndef i8086}
|
{$ifndef i8086}
|
||||||
procedure a_op_const_reg_reg(list : TAsmList; op : Topcg; size : Tcgsize; a : tcgint; src,dst : Tregister); override;
|
procedure a_op_const_reg_reg(list : TAsmList; op : Topcg; size : Tcgsize; a : tcgint; src,dst : Tregister); override;
|
||||||
@ -2433,8 +2434,6 @@ unit cgx86;
|
|||||||
tmpref:=ref;
|
tmpref:=ref;
|
||||||
make_simple_ref(list,tmpref);
|
make_simple_ref(list,tmpref);
|
||||||
{ we don't check the register size for some operations, for the following reasons:
|
{ we don't check the register size for some operations, for the following reasons:
|
||||||
NEG,NOT:
|
|
||||||
reg isn't used in these operations (they are unary and use only ref)
|
|
||||||
SHR,SHL,SAR,ROL,ROR:
|
SHR,SHL,SAR,ROL,ROR:
|
||||||
We allow the register size to differ from the destination size.
|
We allow the register size to differ from the destination size.
|
||||||
This allows generating better code when performing, for example, a
|
This allows generating better code when performing, for example, a
|
||||||
@ -2445,17 +2444,13 @@ unit cgx86;
|
|||||||
EDX have 8-bit subregisters)
|
EDX have 8-bit subregisters)
|
||||||
- avoids partial register writes, which can cause various
|
- avoids partial register writes, which can cause various
|
||||||
performance issues on modern out-of-order execution x86 CPUs }
|
performance issues on modern out-of-order execution x86 CPUs }
|
||||||
if not (op in [OP_NEG,OP_NOT,OP_SHR,OP_SHL,OP_SAR,OP_ROL,OP_ROR]) then
|
if not (op in [OP_SHR,OP_SHL,OP_SAR,OP_ROL,OP_ROR]) then
|
||||||
check_register_size(size,reg);
|
check_register_size(size,reg);
|
||||||
if (op=OP_MUL) and not (cs_check_overflow in current_settings.localswitches) then
|
if (op=OP_MUL) and not (cs_check_overflow in current_settings.localswitches) then
|
||||||
op:=OP_IMUL;
|
op:=OP_IMUL;
|
||||||
case op of
|
case op of
|
||||||
OP_NEG,OP_NOT:
|
OP_NEG,OP_NOT:
|
||||||
begin
|
inherited;
|
||||||
if reg<>NR_NO then
|
|
||||||
internalerror(200109237);
|
|
||||||
list.concat(taicpu.op_ref(TOpCG2AsmOp[op],tcgsize2opsize[size],tmpref));
|
|
||||||
end;
|
|
||||||
OP_SHR,OP_SHL,OP_SAR,OP_ROL,OP_ROR:
|
OP_SHR,OP_SHL,OP_SAR,OP_ROL,OP_ROR:
|
||||||
begin
|
begin
|
||||||
{ Use ecx to load the value, that allows better coalescing }
|
{ Use ecx to load the value, that allows better coalescing }
|
||||||
@ -2480,6 +2475,17 @@ unit cgx86;
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure tcgx86.a_op_ref(list: TAsmList; Op: TOpCG; size: TCGSize; const ref: TReference);
|
||||||
|
var
|
||||||
|
tmpref: treference;
|
||||||
|
begin
|
||||||
|
if not (Op in [OP_NOT,OP_NEG]) then
|
||||||
|
internalerror(2020050705);
|
||||||
|
tmpref:=ref;
|
||||||
|
make_simple_ref(list,tmpref);
|
||||||
|
list.concat(taicpu.op_ref(TOpCG2AsmOp[op],tcgsize2opsize[size],tmpref));
|
||||||
|
end;
|
||||||
|
|
||||||
procedure tcgx86.a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; srcsize, dstsize: TCGSize; src, dst: TRegister);
|
procedure tcgx86.a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; srcsize, dstsize: TCGSize; src, dst: TRegister);
|
||||||
var
|
var
|
||||||
tmpreg: tregister;
|
tmpreg: tregister;
|
||||||
|
Loading…
Reference in New Issue
Block a user