mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-05 05:58:02 +02:00

o fixes several places where there was a check whether something is a fieldvarsym, but not whether it's an instance rather than a class field git-svn-id: trunk@43786 -
122 lines
3.5 KiB
ObjectPascal
122 lines
3.5 KiB
ObjectPascal
{
|
|
Copyright (c) 2019 by Jonas Maebe
|
|
|
|
ARM and AArch64 common parameter helpers
|
|
|
|
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 armpara;
|
|
|
|
{$i fpcdefs.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
symtype,
|
|
paramgr;
|
|
|
|
type
|
|
tarmgenparamanager = class(tparamanager)
|
|
protected
|
|
{ Returns whether a def is a "homogeneous float array" at the machine level.
|
|
This means that in the memory layout, the def only consists of maximally
|
|
4 floating point values that appear consecutively in memory }
|
|
function is_hfa(p: tdef; out basedef: tdef) : boolean;
|
|
private
|
|
function is_hfa_internal(p: tdef; var basedef: tdef; var elecount: longint): boolean;
|
|
end;
|
|
|
|
|
|
implementation
|
|
|
|
uses
|
|
symconst,symdef,symsym,symutil,defutil;
|
|
|
|
|
|
function tarmgenparamanager.is_hfa(p: tdef; out basedef: tdef): boolean;
|
|
var
|
|
elecount: longint;
|
|
begin
|
|
result:=false;
|
|
basedef:=nil;
|
|
elecount:=0;
|
|
result:=is_hfa_internal(p,basedef,elecount);
|
|
result:=
|
|
result and
|
|
(elecount>0) and
|
|
(elecount<=4) and
|
|
(p.size=basedef.size*elecount)
|
|
end;
|
|
|
|
|
|
function tarmgenparamanager.is_hfa_internal(p: tdef; var basedef: tdef; var elecount: longint): boolean;
|
|
var
|
|
i: longint;
|
|
sym: tsym;
|
|
tmpelecount: longint;
|
|
begin
|
|
result:=false;
|
|
case p.typ of
|
|
arraydef:
|
|
begin
|
|
if is_special_array(p) then
|
|
exit;
|
|
{ an array of empty records has no influence }
|
|
if tarraydef(p).elementdef.size=0 then
|
|
begin
|
|
result:=true;
|
|
exit
|
|
end;
|
|
tmpelecount:=0;
|
|
if not is_hfa_internal(tarraydef(p).elementdef,basedef,tmpelecount) then
|
|
exit;
|
|
{ tmpelecount now contains the number of hfa elements in a
|
|
single array element (e.g. 2 if it's an array of a record
|
|
containing two singles) -> multiply by number of elements
|
|
in the array }
|
|
inc(elecount,tarraydef(p).elecount*tmpelecount);
|
|
if elecount>4 then
|
|
exit;
|
|
result:=true;
|
|
end;
|
|
floatdef:
|
|
begin
|
|
if not assigned(basedef) then
|
|
basedef:=p
|
|
else if basedef<>p then
|
|
exit;
|
|
inc(elecount);
|
|
result:=true;
|
|
end;
|
|
recorddef:
|
|
begin
|
|
for i:=0 to tabstractrecorddef(p).symtable.symlist.count-1 do
|
|
begin
|
|
sym:=tsym(tabstractrecorddef(p).symtable.symlist[i]);
|
|
if not is_normal_fieldvarsym(sym) then
|
|
continue;
|
|
if not is_hfa_internal(tfieldvarsym(sym).vardef,basedef,elecount) then
|
|
exit
|
|
end;
|
|
result:=true;
|
|
end;
|
|
else
|
|
exit
|
|
end;
|
|
end;
|
|
|
|
end.
|