* 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:
nickysn 2020-05-07 02:43:02 +00:00 committed by florian
parent 3b8df7736c
commit c9d2028ebd
8 changed files with 298 additions and 93 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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