* remove implicit typecast to extended automatically inserted for trunc/round

(due to the declaration in the system unit) on x86_64 if this allows us
    to use SSE code instead (mantis #28366)

git-svn-id: trunk@31192 -
This commit is contained in:
Jonas Maebe 2015-07-03 21:01:18 +00:00
parent fa1ac2515e
commit 1bcc276dcf
2 changed files with 42 additions and 1 deletions

View File

@ -30,6 +30,9 @@ interface
type
tx86inlinenode = class(tcginlinenode)
protected
procedure maybe_remove_round_trunc_typeconv; virtual;
public
{ first pass override
so that the code generator will actually generate
these nodes.
@ -91,6 +94,12 @@ implementation
TX86INLINENODE
*****************************************************************************}
procedure tx86inlinenode.maybe_remove_round_trunc_typeconv;
begin
{ only makes a difference for x86_64 }
end;
function tx86inlinenode.first_pi : tnode;
begin
if (tfloatdef(pbestrealtype^).floattype=s80real) then
@ -202,6 +211,7 @@ implementation
function tx86inlinenode.first_round_real : tnode;
begin
maybe_remove_round_trunc_typeconv;
{$ifdef x86_64}
if use_vectorfpu(left.resultdef) then
expectloc:=LOC_REGISTER
@ -214,6 +224,7 @@ implementation
function tx86inlinenode.first_trunc_real: tnode;
begin
maybe_remove_round_trunc_typeconv;
if (cs_opt_size in current_settings.optimizerswitches)
{$ifdef x86_64}
and not(use_vectorfpu(left.resultdef))

View File

@ -30,12 +30,42 @@ interface
type
tx8664inlinenode = class(tx86inlinenode)
protected
procedure maybe_remove_round_trunc_typeconv; override;
end;
implementation
uses
ninl;
symconst,
node,ncnv,ninl;
procedure tx8664inlinenode.maybe_remove_round_trunc_typeconv;
var
temp: tnode;
begin
{ the prototype of trunc()/round() in the system unit is declared
with valreal as parameter type, so the argument will always be
extended -> remove the typeconversion to extended if any; not done
in ninl, because there are other code generators that assume that
the parameter to trunc has been converted to valreal (e.g. PowerPC).
We can always remove such typeconversions here if they exist, because
on the x87 all floating point types are handled the same, and
if we call the inherited version we'll insert a call node, which
will insert the necessary type conversion again }
if (left.nodetype=typeconvn) and
not(nf_explicit in left.flags) and
(ttypeconvnode(left).left.resultdef.typ=floatdef) then
begin
{ get rid of the type conversion, so the use_vectorfpu will be
applied to the original type }
temp:=ttypeconvnode(left).left;
ttypeconvnode(left).left:=nil;
left.free;
left:=temp;
end;
end;
begin
cinlinenode:=tx8664inlinenode;