mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-14 20:39:34 +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
|
||||
tempreg.reghi:=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
|
||||
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
|
||||
a_op64_reg_reg(list,op,size,reg,tempreg);
|
||||
a_load64_reg_ref(list,tempreg,ref);
|
||||
begin
|
||||
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;
|
||||
|
||||
|
||||
|
@ -304,10 +304,6 @@ unit cgobj;
|
||||
procedure a_loadmm_reg_intreg(list: TAsmList; fromsize, tosize : tcgsize; mmreg, intreg: tregister; shuffle : pmmshuffle); virtual;
|
||||
|
||||
{ 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_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);
|
||||
@ -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_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 }
|
||||
procedure a_cmp_const_reg_label(list : TAsmList;size : tcgsize;cmp_op : topcmp;a : tcgint;reg : tregister;
|
||||
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_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(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_reg_subsetref(list : TAsmList; Op : TOpCG; size : TCGSize; reg: tregister64; const sref: tsubsetreference);
|
||||
@ -580,9 +584,6 @@ unit cgobj;
|
||||
implementation
|
||||
|
||||
uses
|
||||
globals,systems,
|
||||
verbose,paramgr,symsym,
|
||||
tgobj,cutils,procinfo;
|
||||
globals,systems,fmodule,
|
||||
verbose,paramgr,symsym,symtable,
|
||||
tgobj,cutils,procinfo,
|
||||
@ -1995,13 +1996,17 @@ implementation
|
||||
tmpref:=ref;
|
||||
if op in [OP_NEG,OP_NOT] then
|
||||
begin
|
||||
if reg<>NR_NO then
|
||||
internalerror(2017040901);
|
||||
a_op_reg_reg(list,op,size,tmpreg,tmpreg);
|
||||
tmpreg:=getintregister(list,size);
|
||||
a_op_reg_reg(list,op,size,reg,tmpreg);
|
||||
a_load_reg_ref(list,size,size,tmpreg,tmpref);
|
||||
end
|
||||
else
|
||||
a_op_reg_reg(list,op,size,reg,tmpreg);
|
||||
a_load_reg_ref(list,size,size,tmpreg,ref);
|
||||
begin
|
||||
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;
|
||||
|
||||
|
||||
@ -2192,6 +2197,49 @@ implementation
|
||||
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;
|
||||
cmp_op: topcmp; a: tcgint; reg: tregister; l: tasmlabel);
|
||||
var
|
||||
@ -3044,6 +3092,41 @@ implementation
|
||||
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);
|
||||
begin
|
||||
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_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 }
|
||||
procedure a_cmp_const_reg_label(list : TAsmList;size : tdef;cmp_op : topcmp;a : tcgint;reg : tregister;
|
||||
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);
|
||||
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);
|
||||
begin
|
||||
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;
|
||||
|
||||
{ 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_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;
|
||||
@ -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_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 }
|
||||
procedure a_cmp_const_reg_label(list : TAsmList;size : tdef;cmp_op : topcmp;a : tcgint;reg : tregister;
|
||||
l : tasmlabel);virtual;
|
||||
@ -2994,6 +2997,65 @@ implementation
|
||||
internalerror(2010122911);
|
||||
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);
|
||||
var
|
||||
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_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_ref(list : TAsmList;op:TOpCG;size : tcgsize;const ref: treference);override;
|
||||
private
|
||||
procedure get_64bit_ops(op:TOpCG;var op1,op2:TAsmOp);
|
||||
end;
|
||||
@ -663,27 +664,8 @@ unit cgcpu;
|
||||
l1, l2: TAsmLabel;
|
||||
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;
|
||||
OP_NOT,OP_NEG:
|
||||
inherited;
|
||||
OP_SHR,OP_SHL,OP_SAR:
|
||||
begin
|
||||
{ load right operators in a register }
|
||||
@ -1140,6 +1122,39 @@ unit cgcpu;
|
||||
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;
|
||||
begin
|
||||
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_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_ref(list : TAsmList; Op: TOpCG; size: TCGSize; const ref: TReference); override;
|
||||
|
||||
procedure push_const(list:TAsmList;size:tcgsize;a:tcgint);
|
||||
|
||||
@ -1138,7 +1139,7 @@ unit cgcpu;
|
||||
begin
|
||||
tmpref:=ref;
|
||||
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);
|
||||
|
||||
if size in [OS_64, OS_S64] then
|
||||
@ -1147,27 +1148,8 @@ unit cgcpu;
|
||||
if size in [OS_32, OS_S32] then
|
||||
begin
|
||||
case op of
|
||||
OP_NEG:
|
||||
begin
|
||||
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_NEG,OP_NOT:
|
||||
inherited;
|
||||
OP_IMUL:
|
||||
begin
|
||||
{ this one needs a load/imul/store, which is the default }
|
||||
@ -1260,6 +1242,46 @@ unit cgcpu;
|
||||
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);
|
||||
var
|
||||
tmpreg: TRegister;
|
||||
|
@ -527,36 +527,18 @@ implementation
|
||||
procedure tcginlinenode.second_NegNot_assign;
|
||||
const
|
||||
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
|
||||
{ load parameter, must be a reference }
|
||||
secondpass(left);
|
||||
|
||||
location_reset(location,LOC_VOID,OS_NO);
|
||||
|
||||
if left.location.loc in [LOC_REGISTER,LOC_CREGISTER] 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),left.location.register64,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
|
||||
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_loc(current_asmdata.CurrAsmList,negnotop[inlinenumber],def_cgsize(left.resultdef),left.location)
|
||||
else
|
||||
internalerror(2017040701);
|
||||
{$endif not cpu64bitalu}
|
||||
hlcg.a_op_loc(current_asmdata.CurrAsmList,negnotop[inlinenumber],left.resultdef,left.location);
|
||||
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_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_ref(list : TAsmList; Op: TOpCG; size: TCGSize; const ref: TReference); override;
|
||||
|
||||
{$ifndef i8086}
|
||||
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;
|
||||
make_simple_ref(list,tmpref);
|
||||
{ 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:
|
||||
We allow the register size to differ from the destination size.
|
||||
This allows generating better code when performing, for example, a
|
||||
@ -2445,17 +2444,13 @@ unit cgx86;
|
||||
EDX have 8-bit subregisters)
|
||||
- avoids partial register writes, which can cause various
|
||||
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);
|
||||
if (op=OP_MUL) and not (cs_check_overflow in current_settings.localswitches) then
|
||||
op:=OP_IMUL;
|
||||
case op of
|
||||
OP_NEG,OP_NOT:
|
||||
begin
|
||||
if reg<>NR_NO then
|
||||
internalerror(200109237);
|
||||
list.concat(taicpu.op_ref(TOpCG2AsmOp[op],tcgsize2opsize[size],tmpref));
|
||||
end;
|
||||
inherited;
|
||||
OP_SHR,OP_SHL,OP_SAR,OP_ROL,OP_ROR:
|
||||
begin
|
||||
{ Use ecx to load the value, that allows better coalescing }
|
||||
@ -2480,6 +2475,17 @@ unit cgx86;
|
||||
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);
|
||||
var
|
||||
tmpreg: tregister;
|
||||
|
Loading…
Reference in New Issue
Block a user