Merged revisions 555 via svnmerge from

/trunk

git-svn-id: branches/fixes_2_0@667 -
This commit is contained in:
peter 2005-07-19 07:13:48 +00:00
parent b856c34794
commit 845dd70787
9 changed files with 284 additions and 293 deletions

View File

@ -36,6 +36,7 @@
{$define cpuflags}
{$define cpuextended}
{$define USECMOV}
{$define SUPPORT_MMX}
{$endif i386}
{$ifdef x86_64}

View File

@ -30,13 +30,9 @@ interface
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;
procedure second_add64bit;override;
procedure second_cmp64bit;override;
procedure second_mul;override;
end;
implementation
@ -50,86 +46,6 @@ interface
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
*****************************************************************************}
@ -423,189 +339,6 @@ interface
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
*****************************************************************************}

View File

@ -50,12 +50,12 @@ interface
procedure second_addfloat;virtual;abstract;
procedure second_addboolean;virtual;
procedure second_addsmallset;virtual;
{$ifdef i386}
{$ifdef x86}
{$ifdef SUPPORT_MMX}
procedure second_addmmxset;virtual;abstract;
procedure second_addmmx;virtual;abstract;
procedure second_opmmxset;virtual;abstract;
procedure second_opmmx;virtual;abstract;
{$endif SUPPORT_MMX}
{$endif}
{$endif x86}
procedure second_add64bit;virtual;
procedure second_addordinal;virtual;
procedure second_cmpfloat;virtual;abstract;
@ -775,7 +775,7 @@ interface
{$ifdef SUPPORT_MMX}
else
if is_mmx_able_array(left.resulttype.def) then
second_opmmx;
second_opmmx
{$endif SUPPORT_MMX}
else
internalerror(200306016);

View File

@ -301,7 +301,7 @@ implementation
{$ifdef SUPPORT_MMX}
LOC_MMXREGISTER,
LOC_CMMXREGISTER:
cg.a_parammm_reg(exprasmlist,left.location.register);
cg.a_parammm_reg(exprasmlist,OS_M64,left.location.register,tempcgpara,nil);
{$endif SUPPORT_MMX}
else
internalerror(200204241);

View File

@ -600,9 +600,9 @@ implementation
LOC_MMXREGISTER:
begin
if left.location.loc=LOC_CMMXREGISTER then
cg.a_loadmm_reg_reg(exprasmlist,right.location.register,left.location.register)
cg.a_loadmm_reg_reg(exprasmlist,OS_M64,OS_M64,right.location.register,left.location.register,nil)
else
cg.a_loadmm_reg_ref(exprasmlist,right.location.register,left.location.reference);
cg.a_loadmm_reg_ref(exprasmlist,OS_M64,OS_M64,right.location.register,left.location.reference,nil);
end;
{$endif SUPPORT_MMX}
LOC_MMREGISTER,

View File

@ -804,7 +804,7 @@ implementation
p.registersfpu:=registersfpu;
{$ifdef SUPPORT_MMX}
p.registersmmx:=registersmmx;
p.registerskni:=registerskni;
p.registersmm:=registersmm;
{$endif SUPPORT_MMX}
p.resulttype:=resulttype;
p.fileinfo:=fileinfo;

View File

@ -51,6 +51,10 @@ unit nx86add;
procedure second_cmpsmallset;override;
procedure second_cmp64bit;override;
procedure second_cmpordinal;override;
{$ifdef SUPPORT_MMX}
procedure second_opmmxset;override;
procedure second_opmmx;override;
{$endif SUPPORT_MMX}
end;
@ -434,6 +438,264 @@ unit nx86add;
end;
{*****************************************************************************
AddMMX
*****************************************************************************}
{$ifdef SUPPORT_MMX}
procedure tx86addnode.second_opmmx;
var
op : TAsmOp;
cmpop : boolean;
mmxbase : tmmxtype;
hreg,
hregister : tregister;
begin
pass_left_right;
cmpop:=false;
mmxbase:=mmx_type(left.resulttype.def);
location_reset(location,LOC_MMXREGISTER,def_cgsize(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:=tcgx86(cg).getmmxregister(exprasmlist);
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:=tcgx86(cg).getmmxregister(exprasmlist);
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
hreg:=tcgx86(cg).getmmxregister(exprasmlist);
if right.location.loc=LOC_CMMXREGISTER then
begin
emit_reg_reg(A_MOVQ,S_NO,right.location.register,hreg);
emit_reg_reg(op,S_NO,left.location.register,hreg);
end
else
begin
if not(left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
internalerror(200203247);
emit_ref_reg(A_MOVQ,S_NO,right.location.reference,hreg);
emit_reg_reg(op,S_NO,left.location.register,hreg);
end;
location.register:=hreg;
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;
location.register:=left.location.register;
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;
location.register:=left.location.register;
end;
location_freetemp(exprasmlist,right.location);
if cmpop then
location_freetemp(exprasmlist,left.location);
end;
{$endif SUPPORT_MMX}
{*****************************************************************************
addmmxset
*****************************************************************************}
{$ifdef SUPPORT_MMX}
procedure tx86addnode.second_opmmxset;
var opsize : TCGSize;
op : TAsmOp;
cmpop,
noswap : boolean;
begin
pass_left_right;
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,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);
end;
{$endif SUPPORT_MMX}
{*****************************************************************************
AddFloat
*****************************************************************************}

View File

@ -47,6 +47,7 @@ interface
implementation
uses
globtype,
systems,
cutils,verbose,globals,
symconst,aasmbase,aasmtai,defutil,
@ -108,7 +109,7 @@ interface
begin
secondpass(left);
location_reset(location,LOC_MMXREGISTER,OS_NO);
hreg:=cg.getmmxregister(exprasmlist,OS_M64);
hreg:=tcgx86(cg).getmmxregister(exprasmlist);
emit_reg_reg(A_PXOR,S_NO,hreg,hreg);
case left.location.loc of
LOC_MMXREGISTER:
@ -117,14 +118,13 @@ interface
end;
LOC_CMMXREGISTER:
begin
location.register:=cg.getmmxregister(exprasmlist,OS_M64);
location.register:=tcgx86(cg).getmmxregister(exprasmlist);
emit_reg_reg(A_MOVQ,S_NO,left.location.register,location.register);
end;
LOC_REFERENCE,
LOC_CREFERENCE:
begin
reference_release(exprasmlist,left.location.reference);
location.register:=cg.getmmxregister(exprasmlist,OS_M64);
location.register:=tcgx86(cg).getmmxregister(exprasmlist);
emit_ref_reg(A_MOVQ,S_NO,left.location.reference,location.register);
end;
else
@ -151,7 +151,6 @@ interface
op:=A_PSUBD;
end;
emit_reg_reg(op,S_NO,location.register,hreg);
cg.ungetregister(exprasmlist,hreg);
emit_reg_reg(A_MOVQ,S_NO,hreg,location.register);
end;
{$endif SUPPORT_MMX}
@ -293,28 +292,25 @@ interface
location_copy(location,left.location);
LOC_CMMXREGISTER:
begin
location.register:=cg.getmmxregister(exprasmlist,OS_M64);
location.register:=tcgx86(cg).getmmxregister(exprasmlist);
emit_reg_reg(A_MOVQ,S_NO,left.location.register,location.register);
end;
LOC_REFERENCE,
LOC_CREFERENCE:
begin
location_release(exprasmlist,left.location);
location.register:=cg.getmmxregister(exprasmlist,OS_M64);
location.register:=tcgx86(cg).getmmxregister(exprasmlist);
emit_ref_reg(A_MOVQ,S_NO,left.location.reference,location.register);
end;
end;
{ load mask }
hreg:=cg.getmmxregister(exprasmlist,OS_M64);
hreg:=tcgx86(cg).getmmxregister(exprasmlist);
emit_reg_reg(A_MOVD,S_NO,r,hreg);
cg.ungetregister(exprasmlist,r);
{ lower 32 bit }
emit_reg_reg(A_PXOR,S_D,hreg,location.register);
emit_reg_reg(A_PXOR,S_NO,hreg,location.register);
{ shift mask }
emit_const_reg(A_PSLLQ,S_NO,32,hreg);
{ higher 32 bit }
cg.ungetregister(exprasmlist,hreg);
emit_reg_reg(A_PXOR,S_D,hreg,location.register);
emit_reg_reg(A_PXOR,S_NO,hreg,location.register);
end;
{$endif SUPPORT_MMX}
end.

View File

@ -1,5 +1,4 @@
{ %CPU=i386 }
{ %maxversion=1.0.99 }
{ this contains currently only a basic test of mmx support }
{ the following instructions are tested: