mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-05-25 22:22:35 +02:00
689 lines
23 KiB
ObjectPascal
689 lines
23 KiB
ObjectPascal
{
|
|
$Id$
|
|
Copyright (c) 2000-2002 by Florian Klaempfl
|
|
|
|
Code generation for add nodes on the i386
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
****************************************************************************
|
|
}
|
|
unit n386add;
|
|
|
|
{$i fpcdefs.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
node,nadd,cpubase,nx86add;
|
|
|
|
type
|
|
ti386addnode = class(tx86addnode)
|
|
{$ifdef SUPPORT_MMX}
|
|
procedure second_addmmxset;override;
|
|
procedure second_addmmx;override;
|
|
{$endif SUPPORT_MMX}
|
|
procedure second_add64bit;override;
|
|
procedure second_cmp64bit;override;
|
|
procedure second_mul;override;
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses
|
|
globtype,systems,
|
|
cutils,verbose,globals,
|
|
symconst,symdef,paramgr,
|
|
aasmbase,aasmtai,aasmcpu,
|
|
cgbase,
|
|
ncon,nset,cgutils,tgobj,
|
|
cga,ncgutil,cgobj,cg64f32;
|
|
|
|
{*****************************************************************************
|
|
addmmxset
|
|
*****************************************************************************}
|
|
|
|
{$ifdef SUPPORT_MMX}
|
|
procedure ti386addnode.second_addmmxset;
|
|
|
|
var opsize : TCGSize;
|
|
op : TAsmOp;
|
|
cmpop,
|
|
pushedfpu,
|
|
noswap : boolean;
|
|
begin
|
|
pass_left_and_right(pushedfpu);
|
|
|
|
cmpop:=false;
|
|
noswap:=false;
|
|
opsize:=OS_32;
|
|
case nodetype of
|
|
addn:
|
|
begin
|
|
{ are we adding set elements ? }
|
|
if right.nodetype=setelementn then
|
|
begin
|
|
{ adding elements is not commutative }
|
|
{ if nf_swaped in flags then
|
|
swapleftright;}
|
|
{ bts requires both elements to be registers }
|
|
{ location_force_reg(exprasmlist,left.location,opsize_2_cgsize[opsize],false);
|
|
location_force_reg(exprasmlist,right.location,opsize_2_cgsize[opsize],true);
|
|
op:=A_BTS;
|
|
noswap:=true;}
|
|
end
|
|
else
|
|
op:=A_POR;
|
|
end;
|
|
symdifn :
|
|
op:=A_PXOR;
|
|
muln:
|
|
op:=A_PAND;
|
|
subn:
|
|
op:=A_PANDN;
|
|
equaln,
|
|
unequaln :
|
|
begin
|
|
op:=A_PCMPEQD;
|
|
cmpop:=true;
|
|
end;
|
|
lten,gten:
|
|
begin
|
|
if (not(nf_swaped in flags) and (nodetype = lten)) or
|
|
((nf_swaped in flags) and (nodetype = gten)) then
|
|
swapleftright;
|
|
location_force_reg(exprasmlist,left.location,opsize,true);
|
|
emit_op_right_left(A_AND,TCGSize2Opsize[opsize]);
|
|
op:=A_PCMPEQD;
|
|
cmpop:=true;
|
|
{ warning: ugly hack, we need a JE so change the node to equaln }
|
|
nodetype:=equaln;
|
|
end;
|
|
xorn :
|
|
op:=A_PXOR;
|
|
orn :
|
|
op:=A_POR;
|
|
andn :
|
|
op:=A_PAND;
|
|
else
|
|
internalerror(2003042215);
|
|
end;
|
|
{ left must be a register }
|
|
left_must_be_reg(opsize,noswap);
|
|
{ emit_generic_code(op,opsize,true,extra_not,false);}
|
|
location_freetemp(exprasmlist,right.location);
|
|
if cmpop then
|
|
location_freetemp(exprasmlist,left.location);
|
|
set_result_location(cmpop,true);
|
|
end;
|
|
{$endif SUPPORT_MMX}
|
|
|
|
|
|
{*****************************************************************************
|
|
Add64bit
|
|
*****************************************************************************}
|
|
|
|
procedure ti386addnode.second_add64bit;
|
|
var
|
|
op : TOpCG;
|
|
op1,op2 : TAsmOp;
|
|
opsize : TOpSize;
|
|
hregister,
|
|
hregister2 : tregister;
|
|
hl4 : tasmlabel;
|
|
mboverflow,
|
|
unsigned:boolean;
|
|
r:Tregister;
|
|
begin
|
|
firstcomplex(self);
|
|
pass_left_right;
|
|
|
|
op1:=A_NONE;
|
|
op2:=A_NONE;
|
|
mboverflow:=false;
|
|
opsize:=S_L;
|
|
unsigned:=((left.resulttype.def.deftype=orddef) and
|
|
(torddef(left.resulttype.def).typ=u64bit)) or
|
|
((right.resulttype.def.deftype=orddef) and
|
|
(torddef(right.resulttype.def).typ=u64bit));
|
|
case nodetype of
|
|
addn :
|
|
begin
|
|
op:=OP_ADD;
|
|
mboverflow:=true;
|
|
end;
|
|
subn :
|
|
begin
|
|
op:=OP_SUB;
|
|
op1:=A_SUB;
|
|
op2:=A_SBB;
|
|
mboverflow:=true;
|
|
end;
|
|
xorn:
|
|
op:=OP_XOR;
|
|
orn:
|
|
op:=OP_OR;
|
|
andn:
|
|
op:=OP_AND;
|
|
else
|
|
begin
|
|
{ everything should be handled in pass_1 (JM) }
|
|
internalerror(200109051);
|
|
end;
|
|
end;
|
|
|
|
{ left and right no register? }
|
|
{ then one must be demanded }
|
|
if (left.location.loc<>LOC_REGISTER) then
|
|
begin
|
|
if (right.location.loc<>LOC_REGISTER) then
|
|
begin
|
|
hregister:=cg.getintregister(exprasmlist,OS_INT);
|
|
hregister2:=cg.getintregister(exprasmlist,OS_INT);
|
|
cg64.a_load64_loc_reg(exprasmlist,left.location,joinreg64(hregister,hregister2));
|
|
location_reset(left.location,LOC_REGISTER,OS_64);
|
|
left.location.register64.reglo:=hregister;
|
|
left.location.register64.reghi:=hregister2;
|
|
end
|
|
else
|
|
begin
|
|
location_swap(left.location,right.location);
|
|
toggleflag(nf_swaped);
|
|
end;
|
|
end;
|
|
|
|
{ at this point, left.location.loc should be LOC_REGISTER }
|
|
if right.location.loc=LOC_REGISTER then
|
|
begin
|
|
{ when swapped another result register }
|
|
if (nodetype=subn) and (nf_swaped in flags) then
|
|
begin
|
|
cg64.a_op64_reg_reg(exprasmlist,op,
|
|
left.location.register64,
|
|
right.location.register64);
|
|
location_swap(left.location,right.location);
|
|
toggleflag(nf_swaped);
|
|
end
|
|
else
|
|
begin
|
|
cg64.a_op64_reg_reg(exprasmlist,op,
|
|
right.location.register64,
|
|
left.location.register64);
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
{ right.location<>LOC_REGISTER }
|
|
if (nodetype=subn) and (nf_swaped in flags) then
|
|
begin
|
|
r:=cg.getintregister(exprasmlist,OS_INT);
|
|
cg64.a_load64low_loc_reg(exprasmlist,right.location,r);
|
|
emit_reg_reg(op1,opsize,left.location.register64.reglo,r);
|
|
emit_reg_reg(A_MOV,opsize,r,left.location.register64.reglo);
|
|
cg64.a_load64high_loc_reg(exprasmlist,right.location,r);
|
|
{ the carry flag is still ok }
|
|
emit_reg_reg(op2,opsize,left.location.register64.reghi,r);
|
|
emit_reg_reg(A_MOV,opsize,r,left.location.register64.reghi);
|
|
end
|
|
else
|
|
begin
|
|
cg64.a_op64_loc_reg(exprasmlist,op,right.location,
|
|
left.location.register64);
|
|
end;
|
|
location_freetemp(exprasmlist,right.location);
|
|
end;
|
|
|
|
{ only in case of overflow operations }
|
|
{ produce overflow code }
|
|
{ we must put it here directly, because sign of operation }
|
|
{ is in unsigned VAR!! }
|
|
if mboverflow then
|
|
begin
|
|
if cs_check_overflow in aktlocalswitches then
|
|
begin
|
|
objectlibrary.getlabel(hl4);
|
|
if unsigned then
|
|
cg.a_jmp_flags(exprasmlist,F_AE,hl4)
|
|
else
|
|
cg.a_jmp_flags(exprasmlist,F_NO,hl4);
|
|
cg.a_call_name(exprasmlist,'FPC_OVERFLOW');
|
|
cg.a_label(exprasmlist,hl4);
|
|
end;
|
|
end;
|
|
|
|
location_copy(location,left.location);
|
|
end;
|
|
|
|
|
|
procedure ti386addnode.second_cmp64bit;
|
|
var
|
|
hregister,
|
|
hregister2 : tregister;
|
|
href : treference;
|
|
unsigned : boolean;
|
|
|
|
procedure firstjmp64bitcmp;
|
|
|
|
var
|
|
oldnodetype : tnodetype;
|
|
|
|
begin
|
|
{$ifdef OLDREGVARS}
|
|
load_all_regvars(exprasmlist);
|
|
{$endif OLDREGVARS}
|
|
{ the jump the sequence is a little bit hairy }
|
|
case nodetype of
|
|
ltn,gtn:
|
|
begin
|
|
cg.a_jmp_flags(exprasmlist,getresflags(unsigned),truelabel);
|
|
{ cheat a little bit for the negative test }
|
|
toggleflag(nf_swaped);
|
|
cg.a_jmp_flags(exprasmlist,getresflags(unsigned),falselabel);
|
|
toggleflag(nf_swaped);
|
|
end;
|
|
lten,gten:
|
|
begin
|
|
oldnodetype:=nodetype;
|
|
if nodetype=lten then
|
|
nodetype:=ltn
|
|
else
|
|
nodetype:=gtn;
|
|
cg.a_jmp_flags(exprasmlist,getresflags(unsigned),truelabel);
|
|
{ cheat for the negative test }
|
|
if nodetype=ltn then
|
|
nodetype:=gtn
|
|
else
|
|
nodetype:=ltn;
|
|
cg.a_jmp_flags(exprasmlist,getresflags(unsigned),falselabel);
|
|
nodetype:=oldnodetype;
|
|
end;
|
|
equaln:
|
|
cg.a_jmp_flags(exprasmlist,F_NE,falselabel);
|
|
unequaln:
|
|
cg.a_jmp_flags(exprasmlist,F_NE,truelabel);
|
|
end;
|
|
end;
|
|
|
|
procedure secondjmp64bitcmp;
|
|
|
|
begin
|
|
{ the jump the sequence is a little bit hairy }
|
|
case nodetype of
|
|
ltn,gtn,lten,gten:
|
|
begin
|
|
{ the comparisaion of the low dword have to be }
|
|
{ always unsigned! }
|
|
cg.a_jmp_flags(exprasmlist,getresflags(true),truelabel);
|
|
cg.a_jmp_always(exprasmlist,falselabel);
|
|
end;
|
|
equaln:
|
|
begin
|
|
cg.a_jmp_flags(exprasmlist,F_NE,falselabel);
|
|
cg.a_jmp_always(exprasmlist,truelabel);
|
|
end;
|
|
unequaln:
|
|
begin
|
|
cg.a_jmp_flags(exprasmlist,F_NE,truelabel);
|
|
cg.a_jmp_always(exprasmlist,falselabel);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
begin
|
|
firstcomplex(self);
|
|
|
|
pass_left_right;
|
|
|
|
unsigned:=((left.resulttype.def.deftype=orddef) and
|
|
(torddef(left.resulttype.def).typ=u64bit)) or
|
|
((right.resulttype.def.deftype=orddef) and
|
|
(torddef(right.resulttype.def).typ=u64bit));
|
|
|
|
{ left and right no register? }
|
|
{ then one must be demanded }
|
|
if (left.location.loc<>LOC_REGISTER) then
|
|
begin
|
|
if (right.location.loc<>LOC_REGISTER) then
|
|
begin
|
|
{ we can reuse a CREGISTER for comparison }
|
|
if (left.location.loc<>LOC_CREGISTER) then
|
|
begin
|
|
hregister:=cg.getintregister(exprasmlist,OS_INT);
|
|
hregister2:=cg.getintregister(exprasmlist,OS_INT);
|
|
cg64.a_load64_loc_reg(exprasmlist,left.location,joinreg64(hregister,hregister2));
|
|
location_reset(left.location,LOC_REGISTER,OS_64);
|
|
left.location.register64.reglo:=hregister;
|
|
left.location.register64.reghi:=hregister2;
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
location_swap(left.location,right.location);
|
|
toggleflag(nf_swaped);
|
|
end;
|
|
end;
|
|
|
|
{ at this point, left.location.loc should be LOC_REGISTER }
|
|
if right.location.loc=LOC_REGISTER then
|
|
begin
|
|
emit_reg_reg(A_CMP,S_L,right.location.register64.reghi,left.location.register64.reghi);
|
|
firstjmp64bitcmp;
|
|
emit_reg_reg(A_CMP,S_L,right.location.register64.reglo,left.location.register64.reglo);
|
|
secondjmp64bitcmp;
|
|
end
|
|
else
|
|
begin
|
|
case right.location.loc of
|
|
LOC_CREGISTER :
|
|
begin
|
|
emit_reg_reg(A_CMP,S_L,right.location.register64.reghi,left.location.register64.reghi);
|
|
firstjmp64bitcmp;
|
|
emit_reg_reg(A_CMP,S_L,right.location.register64.reglo,left.location.register64.reglo);
|
|
secondjmp64bitcmp;
|
|
end;
|
|
LOC_CREFERENCE,
|
|
LOC_REFERENCE :
|
|
begin
|
|
href:=right.location.reference;
|
|
inc(href.offset,4);
|
|
emit_ref_reg(A_CMP,S_L,href,left.location.register64.reghi);
|
|
firstjmp64bitcmp;
|
|
emit_ref_reg(A_CMP,S_L,right.location.reference,left.location.register64.reglo);
|
|
secondjmp64bitcmp;
|
|
cg.a_jmp_always(exprasmlist,falselabel);
|
|
location_freetemp(exprasmlist,right.location);
|
|
end;
|
|
LOC_CONSTANT :
|
|
begin
|
|
exprasmlist.concat(taicpu.op_const_reg(A_CMP,S_L,aint(hi(right.location.value64)),left.location.register64.reghi));
|
|
firstjmp64bitcmp;
|
|
exprasmlist.concat(taicpu.op_const_reg(A_CMP,S_L,aint(lo(right.location.value64)),left.location.register64.reglo));
|
|
secondjmp64bitcmp;
|
|
end;
|
|
else
|
|
internalerror(200203282);
|
|
end;
|
|
end;
|
|
|
|
location_freetemp(exprasmlist,left.location);
|
|
|
|
{ we have LOC_JUMP as result }
|
|
location_reset(location,LOC_JUMP,OS_NO)
|
|
end;
|
|
|
|
|
|
{*****************************************************************************
|
|
AddMMX
|
|
*****************************************************************************}
|
|
|
|
{$ifdef SUPPORT_MMX}
|
|
procedure ti386addnode.second_addmmx;
|
|
var
|
|
op : TAsmOp;
|
|
pushedfpu,
|
|
cmpop : boolean;
|
|
mmxbase : tmmxtype;
|
|
hreg,
|
|
hregister : tregister;
|
|
begin
|
|
pass_left_and_right(pushedfpu);
|
|
|
|
cmpop:=false;
|
|
mmxbase:=mmx_type(left.resulttype.def);
|
|
case nodetype of
|
|
addn :
|
|
begin
|
|
if (cs_mmx_saturation in aktlocalswitches) then
|
|
begin
|
|
case mmxbase of
|
|
mmxs8bit:
|
|
op:=A_PADDSB;
|
|
mmxu8bit:
|
|
op:=A_PADDUSB;
|
|
mmxs16bit,mmxfixed16:
|
|
op:=A_PADDSB;
|
|
mmxu16bit:
|
|
op:=A_PADDUSW;
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
case mmxbase of
|
|
mmxs8bit,mmxu8bit:
|
|
op:=A_PADDB;
|
|
mmxs16bit,mmxu16bit,mmxfixed16:
|
|
op:=A_PADDW;
|
|
mmxs32bit,mmxu32bit:
|
|
op:=A_PADDD;
|
|
end;
|
|
end;
|
|
end;
|
|
muln :
|
|
begin
|
|
case mmxbase of
|
|
mmxs16bit,mmxu16bit:
|
|
op:=A_PMULLW;
|
|
mmxfixed16:
|
|
op:=A_PMULHW;
|
|
end;
|
|
end;
|
|
subn :
|
|
begin
|
|
if (cs_mmx_saturation in aktlocalswitches) then
|
|
begin
|
|
case mmxbase of
|
|
mmxs8bit:
|
|
op:=A_PSUBSB;
|
|
mmxu8bit:
|
|
op:=A_PSUBUSB;
|
|
mmxs16bit,mmxfixed16:
|
|
op:=A_PSUBSB;
|
|
mmxu16bit:
|
|
op:=A_PSUBUSW;
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
case mmxbase of
|
|
mmxs8bit,mmxu8bit:
|
|
op:=A_PSUBB;
|
|
mmxs16bit,mmxu16bit,mmxfixed16:
|
|
op:=A_PSUBW;
|
|
mmxs32bit,mmxu32bit:
|
|
op:=A_PSUBD;
|
|
end;
|
|
end;
|
|
end;
|
|
xorn:
|
|
op:=A_PXOR;
|
|
orn:
|
|
op:=A_POR;
|
|
andn:
|
|
op:=A_PAND;
|
|
else
|
|
internalerror(2003042214);
|
|
end;
|
|
|
|
{ left and right no register? }
|
|
{ then one must be demanded }
|
|
if (left.location.loc<>LOC_MMXREGISTER) then
|
|
begin
|
|
if (right.location.loc=LOC_MMXREGISTER) then
|
|
begin
|
|
location_swap(left.location,right.location);
|
|
toggleflag(nf_swaped);
|
|
end
|
|
else
|
|
begin
|
|
{ register variable ? }
|
|
if (left.location.loc=LOC_CMMXREGISTER) then
|
|
begin
|
|
hregister:=cg.getmmxregister(exprasmlist,OS_M64);
|
|
emit_reg_reg(A_MOVQ,S_NO,left.location.register,hregister);
|
|
end
|
|
else
|
|
begin
|
|
if not(left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
|
|
internalerror(200203245);
|
|
|
|
hregister:=cg.getmmxregister(exprasmlist,OS_M64);
|
|
emit_ref_reg(A_MOVQ,S_NO,left.location.reference,hregister);
|
|
end;
|
|
|
|
location_reset(left.location,LOC_MMXREGISTER,OS_NO);
|
|
left.location.register:=hregister;
|
|
end;
|
|
end;
|
|
|
|
{ at this point, left.location.loc should be LOC_MMXREGISTER }
|
|
if right.location.loc<>LOC_MMXREGISTER then
|
|
begin
|
|
if (nodetype=subn) and (nf_swaped in flags) then
|
|
begin
|
|
if right.location.loc=LOC_CMMXREGISTER then
|
|
begin
|
|
hreg:=cg.getmmxregister(exprasmlist,OS_M64);
|
|
emit_reg_reg(A_MOVQ,S_NO,right.location.register,hreg);
|
|
emit_reg_reg(op,S_NO,left.location.register,hreg);
|
|
cg.ungetregister(exprasmlist,hreg);
|
|
emit_reg_reg(A_MOVQ,S_NO,hreg,left.location.register);
|
|
end
|
|
else
|
|
begin
|
|
if not(left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
|
|
internalerror(200203247);
|
|
hreg:=cg.getmmxregister(exprasmlist,OS_M64);
|
|
emit_ref_reg(A_MOVQ,S_NO,right.location.reference,hreg);
|
|
emit_reg_reg(op,S_NO,left.location.register,hreg);
|
|
cg.ungetregister(exprasmlist,hreg);
|
|
emit_reg_reg(A_MOVQ,S_NO,hreg,left.location.register);
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
if (right.location.loc=LOC_CMMXREGISTER) then
|
|
emit_reg_reg(op,S_NO,right.location.register,left.location.register)
|
|
else
|
|
begin
|
|
if not(right.location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
|
|
internalerror(200203246);
|
|
emit_ref_reg(op,S_NO,right.location.reference,left.location.register);
|
|
end;
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
{ right.location=LOC_MMXREGISTER }
|
|
if (nodetype=subn) and (nf_swaped in flags) then
|
|
begin
|
|
emit_reg_reg(op,S_NO,left.location.register,right.location.register);
|
|
location_swap(left.location,right.location);
|
|
toggleflag(nf_swaped);
|
|
end
|
|
else
|
|
begin
|
|
emit_reg_reg(op,S_NO,right.location.register,left.location.register);
|
|
end;
|
|
end;
|
|
|
|
location_freetemp(exprasmlist,right.location);
|
|
if cmpop then
|
|
location_freetemp(exprasmlist,left.location);
|
|
|
|
set_result_location(cmpop,true);
|
|
end;
|
|
{$endif SUPPORT_MMX}
|
|
|
|
|
|
{*****************************************************************************
|
|
x86 MUL
|
|
*****************************************************************************}
|
|
|
|
procedure ti386addnode.second_mul;
|
|
|
|
var r:Tregister;
|
|
hl4 : tasmlabel;
|
|
|
|
begin
|
|
{The location.register will be filled in later (JM)}
|
|
location_reset(location,LOC_REGISTER,OS_INT);
|
|
{Get a temp register and load the left value into it
|
|
and free the location.}
|
|
r:=cg.getintregister(exprasmlist,OS_INT);
|
|
cg.a_load_loc_reg(exprasmlist,OS_INT,left.location,r);
|
|
{Allocate EAX.}
|
|
cg.getcpuregister(exprasmlist,NR_EAX);
|
|
{Load the right value.}
|
|
cg.a_load_loc_reg(exprasmlist,OS_INT,right.location,NR_EAX);
|
|
{Also allocate EDX, since it is also modified by a mul (JM).}
|
|
cg.getcpuregister(exprasmlist,NR_EDX);
|
|
emit_reg(A_MUL,S_L,r);
|
|
if cs_check_overflow in aktlocalswitches then
|
|
begin
|
|
objectlibrary.getlabel(hl4);
|
|
cg.a_jmp_flags(exprasmlist,F_AE,hl4);
|
|
cg.a_call_name(exprasmlist,'FPC_OVERFLOW');
|
|
cg.a_label(exprasmlist,hl4);
|
|
end;
|
|
{Free EAX,EDX}
|
|
cg.ungetcpuregister(exprasmlist,NR_EDX);
|
|
cg.ungetcpuregister(exprasmlist,NR_EAX);
|
|
{Allocate a new register and store the result in EAX in it.}
|
|
location.register:=cg.getintregister(exprasmlist,OS_INT);
|
|
cg.a_load_reg_reg(exprasmlist,OS_INT,OS_INT,NR_EAX,location.register);
|
|
location_freetemp(exprasmlist,left.location);
|
|
location_freetemp(exprasmlist,right.location);
|
|
end;
|
|
|
|
|
|
begin
|
|
caddnode:=ti386addnode;
|
|
end.
|
|
{
|
|
$Log$
|
|
Revision 1.101 2004-11-01 12:43:29 peter
|
|
* shortstr compare with empty string fixed
|
|
* removed special i386 code
|
|
|
|
Revision 1.100 2004/10/31 21:45:03 peter
|
|
* generic tlocation
|
|
* move tlocation to cgutils
|
|
|
|
Revision 1.99 2004/09/25 14:23:54 peter
|
|
* ungetregister is now only used for cpuregisters, renamed to
|
|
ungetcpuregister
|
|
* renamed (get|unget)explicitregister(s) to ..cpuregister
|
|
* removed location-release/reference_release
|
|
|
|
Revision 1.98 2004/06/20 08:55:31 florian
|
|
* logs truncated
|
|
|
|
Revision 1.97 2004/06/16 20:07:10 florian
|
|
* dwarf branch merged
|
|
|
|
Revision 1.96 2004/05/19 23:30:18 peter
|
|
* extra typecast to prevent range check
|
|
|
|
Revision 1.95.2.1 2004/04/29 19:07:22 peter
|
|
* compile fixes
|
|
|
|
Revision 1.95 2004/02/04 19:22:27 peter
|
|
*** empty log message ***
|
|
|
|
Revision 1.94 2004/01/20 12:59:37 florian
|
|
* common addnode code for x86-64 and i386
|
|
|
|
}
|