summaryrefslogtreecommitdiff
path: root/rtl/arm/cpu.pp
blob: 440fb04f87876546a8494d71c5734eefd3b2fcdf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
{
    This file is part of the Free Pascal run time library.
    Copyright (c) 2016 by the Free Pascal development team

    This unit contains some routines to get informations about the
    processor

    See the file COPYING.FPC, included in this distribution,
    for details about the copyright.

    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.

 **********************************************************************}
{$mode objfpc}
unit cpu;

  interface

    function VFPv4Support : Boolean;

  implementation

     var
       has_vfpv4_support,
       gothwcaps : boolean;
       hwcaps : dword;

     const
      AT_NULL         = 0;
      AT_HWCAPS       = 16;

    type
      TAuxiliaryValue = DWord;

      TInternalUnion = record
        a_val: DWord;           //* Integer value */
          {* We use to have pointer elements added here.  We cannot do that,
             though, since it does not work when using 32-bit definitions
             on 64-bit platforms and vice versa.  *}
      end;

      Elf32_auxv_t = record
        a_type: DWord;              //* Entry type */
        a_un: TInternalUnion;
      end;
      TElf32AuxiliaryVector = Elf32_auxv_t;
      PElf32AuxiliaryVector = ^TElf32AuxiliaryVector;

    var
      psysinfo: LongWord = 0;

    procedure InitHWCaps;
      var
        ep: PPChar;
        auxv: PElf32AuxiliaryVector;
      begin
        psysinfo := 0;
        ep := envp;
        while ep^ <> nil do
          Inc(ep);

        Inc(ep);

        auxv := PElf32AuxiliaryVector(ep);

        while auxv^.a_type <> AT_NULL do
          begin
            if auxv^.a_type = AT_HWCAPS then
              begin
                hwcaps := auxv^.a_un.a_val;
                gothwcaps := true;
                Break;
            end;
            Inc(auxv);
          end;
      end;


    function VFPv4Support : Boolean;
      begin
        Result:=has_vfpv4_support;
      end;

begin
  gothwcaps:=false;
  InitHWCaps;
  has_vfpv4_support:=gothwcaps and ((hwcaps and (1 shl 16))<>0);
end.