aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/gcc/ada/set_targ.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.9/gcc/ada/set_targ.adb')
-rwxr-xr-xgcc-4.9/gcc/ada/set_targ.adb863
1 files changed, 863 insertions, 0 deletions
diff --git a/gcc-4.9/gcc/ada/set_targ.adb b/gcc-4.9/gcc/ada/set_targ.adb
new file mode 100755
index 000000000..d6268c823
--- /dev/null
+++ b/gcc-4.9/gcc/ada/set_targ.adb
@@ -0,0 +1,863 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- S E T _ T A R G --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2013-2014, Free Software Foundation, Inc. --
+-- --
+-- GNAT is free software; you can redistribute it and/or modify it under --
+-- terms of the GNU General Public License as published by the Free Soft- --
+-- ware Foundation; either version 3, or (at your option) any later ver- --
+-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT 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 distributed with GNAT; see file COPYING3. If not, go to --
+-- http://www.gnu.org/licenses for a complete copy of the license. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+with Debug; use Debug;
+with Get_Targ; use Get_Targ;
+with Opt; use Opt;
+with Output; use Output;
+
+with System; use System;
+with System.OS_Lib; use System.OS_Lib;
+
+with Unchecked_Conversion;
+
+package body Set_Targ is
+
+ --------------------------------------------------------
+ -- Data Used to Read/Write Target Dependent Info File --
+ --------------------------------------------------------
+
+ -- Table of string names written to file
+
+ subtype Str is String;
+
+ S_Bits_BE : constant Str := "Bits_BE";
+ S_Bits_Per_Unit : constant Str := "Bits_Per_Unit";
+ S_Bits_Per_Word : constant Str := "Bits_Per_Word";
+ S_Bytes_BE : constant Str := "Bytes_BE";
+ S_Char_Size : constant Str := "Char_Size";
+ S_Double_Float_Alignment : constant Str := "Double_Float_Alignment";
+ S_Double_Scalar_Alignment : constant Str := "Double_Scalar_Alignment";
+ S_Double_Size : constant Str := "Double_Size";
+ S_Float_Size : constant Str := "Float_Size";
+ S_Float_Words_BE : constant Str := "Float_Words_BE";
+ S_Int_Size : constant Str := "Int_Size";
+ S_Long_Double_Size : constant Str := "Long_Double_Size";
+ S_Long_Long_Size : constant Str := "Long_Long_Size";
+ S_Long_Size : constant Str := "Long_Size";
+ S_Maximum_Alignment : constant Str := "Maximum_Alignment";
+ S_Max_Unaligned_Field : constant Str := "Max_Unaligned_Field";
+ S_Pointer_Size : constant Str := "Pointer_Size";
+ S_Short_Enums : constant Str := "Short_Enums";
+ S_Short_Size : constant Str := "Short_Size";
+ S_Strict_Alignment : constant Str := "Strict_Alignment";
+ S_System_Allocator_Alignment : constant Str := "System_Allocator_Alignment";
+ S_Wchar_T_Size : constant Str := "Wchar_T_Size";
+ S_Words_BE : constant Str := "Words_BE";
+
+ -- Table of names
+
+ type AStr is access all String;
+
+ DTN : constant array (Nat range <>) of AStr := (
+ S_Bits_BE 'Unrestricted_Access,
+ S_Bits_Per_Unit 'Unrestricted_Access,
+ S_Bits_Per_Word 'Unrestricted_Access,
+ S_Bytes_BE 'Unrestricted_Access,
+ S_Char_Size 'Unrestricted_Access,
+ S_Double_Float_Alignment 'Unrestricted_Access,
+ S_Double_Scalar_Alignment 'Unrestricted_Access,
+ S_Double_Size 'Unrestricted_Access,
+ S_Float_Size 'Unrestricted_Access,
+ S_Float_Words_BE 'Unrestricted_Access,
+ S_Int_Size 'Unrestricted_Access,
+ S_Long_Double_Size 'Unrestricted_Access,
+ S_Long_Long_Size 'Unrestricted_Access,
+ S_Long_Size 'Unrestricted_Access,
+ S_Maximum_Alignment 'Unrestricted_Access,
+ S_Max_Unaligned_Field 'Unrestricted_Access,
+ S_Pointer_Size 'Unrestricted_Access,
+ S_Short_Enums 'Unrestricted_Access,
+ S_Short_Size 'Unrestricted_Access,
+ S_Strict_Alignment 'Unrestricted_Access,
+ S_System_Allocator_Alignment 'Unrestricted_Access,
+ S_Wchar_T_Size 'Unrestricted_Access,
+ S_Words_BE 'Unrestricted_Access);
+
+ -- Table of corresponding value pointers
+
+ DTV : constant array (Nat range <>) of System.Address := (
+ Bits_BE 'Address,
+ Bits_Per_Unit 'Address,
+ Bits_Per_Word 'Address,
+ Bytes_BE 'Address,
+ Char_Size 'Address,
+ Double_Float_Alignment 'Address,
+ Double_Scalar_Alignment 'Address,
+ Double_Size 'Address,
+ Float_Size 'Address,
+ Float_Words_BE 'Address,
+ Int_Size 'Address,
+ Long_Double_Size 'Address,
+ Long_Long_Size 'Address,
+ Long_Size 'Address,
+ Maximum_Alignment 'Address,
+ Max_Unaligned_Field 'Address,
+ Pointer_Size 'Address,
+ Short_Enums 'Address,
+ Short_Size 'Address,
+ Strict_Alignment 'Address,
+ System_Allocator_Alignment 'Address,
+ Wchar_T_Size 'Address,
+ Words_BE 'Address);
+
+ DTR : array (Nat range DTV'Range) of Boolean := (others => False);
+ -- Table of flags used to validate that all values are present in file
+
+ -----------------------
+ -- Local Subprograms --
+ -----------------------
+
+ procedure Fail (E : String);
+ pragma No_Return (Fail);
+ -- Terminate program with fatal error message passed as parameter
+
+ procedure Register_Float_Type
+ (Name : C_String;
+ Digs : Natural;
+ Complex : Boolean;
+ Count : Natural;
+ Float_Rep : Float_Rep_Kind;
+ Precision : Positive;
+ Size : Positive;
+ Alignment : Natural);
+ pragma Convention (C, Register_Float_Type);
+ -- Call back to allow the back end to register available types. This call
+ -- back makes entries in the FPT_Mode_Table for any floating point types
+ -- reported by the back end. Name is the name of the type as a normal
+ -- format Null-terminated string. Digs is the number of digits, where 0
+ -- means it is not a fpt type (ignored during registration). Complex is
+ -- non-zero if the type has real and imaginary parts (also ignored during
+ -- registration). Count is the number of elements in a vector type (zero =
+ -- not a vector, registration ignores vectors). Float_Rep shows the kind of
+ -- floating-point type, and Precision, Size and Alignment are the precision
+ -- size and alignment in bits.
+ --
+ -- So to summarize, the only types that are actually registered have Digs
+ -- non-zero, Complex zero (false), and Count zero (not a vector).
+
+ ----------
+ -- Fail --
+ ----------
+
+ procedure Fail (E : String) is
+ E_Fatal : constant := 4;
+ -- Code for fatal error
+ begin
+ Write_Str (E);
+ Write_Eol;
+ OS_Exit (E_Fatal);
+ end Fail;
+
+ -------------------------
+ -- Register_Float_Type --
+ -------------------------
+
+ procedure Register_Float_Type
+ (Name : C_String;
+ Digs : Natural;
+ Complex : Boolean;
+ Count : Natural;
+ Float_Rep : Float_Rep_Kind;
+ Precision : Positive;
+ Size : Positive;
+ Alignment : Natural)
+ is
+ T : String (1 .. Name'Length);
+ Last : Natural := 0;
+
+ procedure Dump;
+ -- Dump information given by the back end for the type to register
+
+ ----------
+ -- Dump --
+ ----------
+
+ procedure Dump is
+ begin
+ Write_Str ("type " & T (1 .. Last) & " is ");
+
+ if Count > 0 then
+ Write_Str ("array (1 .. ");
+ Write_Int (Int (Count));
+
+ if Complex then
+ Write_Str (", 1 .. 2");
+ end if;
+
+ Write_Str (") of ");
+
+ elsif Complex then
+ Write_Str ("array (1 .. 2) of ");
+ end if;
+
+ if Digs > 0 then
+ Write_Str ("digits ");
+ Write_Int (Int (Digs));
+ Write_Line (";");
+
+ Write_Str ("pragma Float_Representation (");
+
+ case Float_Rep is
+ when IEEE_Binary =>
+ Write_Str ("IEEE");
+
+ when VAX_Native =>
+ case Digs is
+ when 6 =>
+ Write_Str ("VAXF");
+
+ when 9 =>
+ Write_Str ("VAXD");
+
+ when 15 =>
+ Write_Str ("VAXG");
+
+ when others =>
+ Write_Str ("VAX_");
+ Write_Int (Int (Digs));
+ end case;
+
+ when AAMP => Write_Str ("AAMP");
+ end case;
+
+ Write_Line (", " & T (1 .. Last) & ");");
+
+ else
+ Write_Str ("mod 2**");
+ Write_Int (Int (Precision / Positive'Max (1, Count)));
+ Write_Line (";");
+ end if;
+
+ if Precision = Size then
+ Write_Str ("for " & T (1 .. Last) & "'Size use ");
+ Write_Int (Int (Size));
+ Write_Line (";");
+
+ else
+ Write_Str ("for " & T (1 .. Last) & "'Value_Size use ");
+ Write_Int (Int (Precision));
+ Write_Line (";");
+
+ Write_Str ("for " & T (1 .. Last) & "'Object_Size use ");
+ Write_Int (Int (Size));
+ Write_Line (";");
+ end if;
+
+ Write_Str ("for " & T (1 .. Last) & "'Alignment use ");
+ Write_Int (Int (Alignment / 8));
+ Write_Line (";");
+ Write_Eol;
+ end Dump;
+
+ -- Start of processing for Register_Float_Type
+
+ begin
+ -- Acquire name
+
+ for J in T'Range loop
+ T (J) := Name (Name'First + J - 1);
+
+ if T (J) = ASCII.NUL then
+ Last := J - 1;
+ exit;
+ end if;
+ end loop;
+
+ -- Dump info if debug flag set
+
+ if Debug_Flag_Dot_B then
+ Dump;
+ end if;
+
+ -- Acquire entry if non-vector non-complex fpt type (digits non-zero)
+
+ if Digs > 0 and then not Complex and then Count = 0 then
+ Num_FPT_Modes := Num_FPT_Modes + 1;
+ FPT_Mode_Table (Num_FPT_Modes) :=
+ (NAME => new String'(T (1 .. Last)),
+ DIGS => Digs,
+ FLOAT_REP => Float_Rep,
+ PRECISION => Precision,
+ SIZE => Size,
+ ALIGNMENT => Alignment);
+ end if;
+ end Register_Float_Type;
+
+ -----------------------------------
+ -- Write_Target_Dependent_Values --
+ -----------------------------------
+
+ -- We do this at the System.Os_Lib level, since we have to do the read at
+ -- that level anyway, so it is easier and more consistent to follow the
+ -- same path for the write.
+
+ procedure Write_Target_Dependent_Values is
+ Fdesc : File_Descriptor;
+ OK : Boolean;
+
+ Buffer : String (1 .. 80);
+ Buflen : Natural;
+ -- Buffer used to build line one of file
+
+ type ANat is access all Natural;
+ -- Pointer to Nat or Pos value (it is harmless to treat Pos values and
+ -- Nat values as Natural via Unchecked_Conversion).
+
+ function To_ANat is new Unchecked_Conversion (Address, ANat);
+
+ procedure AddC (C : Character);
+ -- Add one character to buffer
+
+ procedure AddN (N : Natural);
+ -- Add representation of integer N to Buffer, updating Buflen. N
+ -- must be less than 1000, and output is 3 characters with leading
+ -- spaces as needed.
+
+ procedure Write_Line;
+ -- Output contents of Buffer (1 .. Buflen) followed by a New_Line,
+ -- and set Buflen back to zero, ready to write next line.
+
+ ----------
+ -- AddC --
+ ----------
+
+ procedure AddC (C : Character) is
+ begin
+ Buflen := Buflen + 1;
+ Buffer (Buflen) := C;
+ end AddC;
+
+ ----------
+ -- AddN --
+ ----------
+
+ procedure AddN (N : Natural) is
+ begin
+ if N > 999 then
+ raise Program_Error;
+ end if;
+
+ if N > 99 then
+ AddC (Character'Val (48 + N / 100));
+ else
+ AddC (' ');
+ end if;
+
+ if N > 9 then
+ AddC (Character'Val (48 + N / 10 mod 10));
+ else
+ AddC (' ');
+ end if;
+
+ AddC (Character'Val (48 + N mod 10));
+ end AddN;
+
+ ----------------
+ -- Write_Line --
+ ----------------
+
+ procedure Write_Line is
+ begin
+ AddC (ASCII.LF);
+
+ if Buflen /= Write (Fdesc, Buffer'Address, Buflen) then
+ Delete_File (Target_Dependent_Info_Write_Name'Address, OK);
+ Fail ("disk full writing file "
+ & Target_Dependent_Info_Write_Name.all);
+ end if;
+
+ Buflen := 0;
+ end Write_Line;
+
+ -- Start of processing for Write_Target_Dependent_Values
+
+ begin
+ Fdesc :=
+ Create_File (Target_Dependent_Info_Write_Name.all'Address, Text);
+
+ if Fdesc = Invalid_FD then
+ Fail ("cannot create file " & Target_Dependent_Info_Write_Name.all);
+ end if;
+
+ -- Loop through values
+
+ for J in DTN'Range loop
+
+ -- Output name
+
+ Buflen := DTN (J)'Length;
+ Buffer (1 .. Buflen) := DTN (J).all;
+
+ -- Line up values
+
+ while Buflen < 26 loop
+ AddC (' ');
+ end loop;
+
+ AddC (' ');
+ AddC (' ');
+
+ -- Output value and write line
+
+ AddN (To_ANat (DTV (J)).all);
+ Write_Line;
+ end loop;
+
+ -- Blank line to separate sections
+
+ Write_Line;
+
+ -- Write lines for registered FPT types
+
+ for J in 1 .. Num_FPT_Modes loop
+ declare
+ E : FPT_Mode_Entry renames FPT_Mode_Table (J);
+ begin
+ Buflen := E.NAME'Last;
+ Buffer (1 .. Buflen) := E.NAME.all;
+
+ -- Pad out to line up values
+
+ while Buflen < 11 loop
+ AddC (' ');
+ end loop;
+
+ AddC (' ');
+ AddC (' ');
+
+ AddN (E.DIGS);
+ AddC (' ');
+ AddC (' ');
+
+ case E.FLOAT_REP is
+ when IEEE_Binary =>
+ AddC ('I');
+ when VAX_Native =>
+ AddC ('V');
+ when AAMP =>
+ AddC ('A');
+ end case;
+
+ AddC (' ');
+
+ AddN (E.PRECISION);
+ AddC (' ');
+
+ AddN (E.ALIGNMENT);
+ Write_Line;
+ end;
+ end loop;
+
+ -- Close file
+
+ Close (Fdesc, OK);
+
+ if not OK then
+ Fail ("disk full writing file "
+ & Target_Dependent_Info_Write_Name.all);
+ end if;
+ end Write_Target_Dependent_Values;
+
+-- Package Initialization, set target dependent values. This must be done
+-- early on, before we start accessing various compiler packages, since
+-- these values are used all over the place.
+
+begin
+ -- First step: see if the -gnateT switch is present. As we have noted,
+ -- this has to be done very early, so can not depend on the normal circuit
+ -- for reading switches and setting switches in Opt. The following code
+ -- will set Opt.Target_Dependent_Info_Read_Name if the switch -gnateT=name
+ -- is present in the options string.
+
+ declare
+ type Arg_Array is array (Nat) of Big_String_Ptr;
+ type Arg_Array_Ptr is access Arg_Array;
+ -- Types to access compiler arguments
+
+ save_argc : Nat;
+ pragma Import (C, save_argc);
+ -- Saved value of argc (number of arguments), imported from misc.c
+
+ save_argv : Arg_Array_Ptr;
+ pragma Import (C, save_argv);
+ -- Saved value of argv (argument pointers), imported from misc.c
+
+ gnat_argc : Nat;
+ gnat_argv : Arg_Array_Ptr;
+ pragma Import (C, gnat_argc);
+ pragma Import (C, gnat_argv);
+ -- If save_argv is not set, default to gnat_argc/argv
+
+ argc : Nat;
+ argv : Arg_Array_Ptr;
+
+ function Len_Arg (Arg : Big_String_Ptr) return Nat;
+ -- Determine length of argument Arg (a nul terminated C string).
+
+ -------------
+ -- Len_Arg --
+ -------------
+
+ function Len_Arg (Arg : Big_String_Ptr) return Nat is
+ begin
+ for J in 1 .. Nat'Last loop
+ if Arg (Natural (J)) = ASCII.NUL then
+ return J - 1;
+ end if;
+ end loop;
+
+ raise Program_Error;
+ end Len_Arg;
+
+ begin
+ if save_argv /= null then
+ argv := save_argv;
+ argc := save_argc;
+ else
+ -- Case of a non gcc compiler, e.g. gnat2why or gnat2scil
+ argv := gnat_argv;
+ argc := gnat_argc;
+ end if;
+
+ -- Loop through arguments looking for -gnateT, also look for -gnatd.b
+
+ for Arg in 1 .. argc - 1 loop
+ declare
+ Argv_Ptr : constant Big_String_Ptr := argv (Arg);
+ Argv_Len : constant Nat := Len_Arg (Argv_Ptr);
+
+ begin
+ if Argv_Len > 8
+ and then Argv_Ptr (1 .. 8) = "-gnateT="
+ then
+ Opt.Target_Dependent_Info_Read_Name :=
+ new String'(Argv_Ptr (9 .. Natural (Argv_Len)));
+
+ elsif Argv_Len >= 8
+ and then Argv_Ptr (1 .. 8) = "-gnatd.b"
+ then
+ Debug_Flag_Dot_B := True;
+ end if;
+ end;
+ end loop;
+ end;
+
+ -- If the switch is not set, we get all values from the back end
+
+ if Opt.Target_Dependent_Info_Read_Name = null then
+
+ -- Set values by direct calls to the back end
+
+ Bits_BE := Get_Bits_BE;
+ Bits_Per_Unit := Get_Bits_Per_Unit;
+ Bits_Per_Word := Get_Bits_Per_Word;
+ Bytes_BE := Get_Bytes_BE;
+ Char_Size := Get_Char_Size;
+ Double_Float_Alignment := Get_Double_Float_Alignment;
+ Double_Scalar_Alignment := Get_Double_Scalar_Alignment;
+ Double_Size := Get_Double_Size;
+ Float_Size := Get_Float_Size;
+ Float_Words_BE := Get_Float_Words_BE;
+ Int_Size := Get_Int_Size;
+ Long_Double_Size := Get_Long_Double_Size;
+ Long_Long_Size := Get_Long_Long_Size;
+ Long_Size := Get_Long_Size;
+ Maximum_Alignment := Get_Maximum_Alignment;
+ Max_Unaligned_Field := Get_Max_Unaligned_Field;
+ Pointer_Size := Get_Pointer_Size;
+ Short_Enums := Get_Short_Enums;
+ Short_Size := Get_Short_Size;
+ Strict_Alignment := Get_Strict_Alignment;
+ System_Allocator_Alignment := Get_System_Allocator_Alignment;
+ Wchar_T_Size := Get_Wchar_T_Size;
+ Words_BE := Get_Words_BE;
+
+ -- Register floating-point types from the back end
+
+ Register_Back_End_Types (Register_Float_Type'Access);
+
+ -- Case of reading the target dependent values from file
+
+ -- This is bit more complex than might be expected, because it has to be
+ -- done very early. All kinds of packages depend on these values, and we
+ -- can't wait till the normal processing of reading command line switches
+ -- etc to read the file. We do this at the System.OS_Lib level since it is
+ -- too early to be using Osint directly.
+
+ else
+ Read_Target_Dependent_Values : declare
+ File_Desc : File_Descriptor;
+ N : Natural;
+
+ type ANat is access all Natural;
+ -- Pointer to Nat or Pos value (it is harmless to treat Pos values
+ -- as Nat via Unchecked_Conversion).
+
+ function To_ANat is new Unchecked_Conversion (Address, ANat);
+
+ VP : ANat;
+
+ Buffer : String (1 .. 2000);
+ Buflen : Natural;
+ -- File information and length (2000 easily enough)
+
+ Nam_Buf : String (1 .. 40);
+ Nam_Len : Natural;
+
+ procedure Check_Spaces;
+ -- Checks that we have one or more spaces and skips them
+
+ procedure FailN (S : String);
+ -- Calls Fail adding " name in file xxx", where name is the currently
+ -- gathered name in Nam_Buf, surrounded by quotes, and xxx is the
+ -- name of the file.
+
+ procedure Get_Name;
+ -- Scan out name, leaving it in Nam_Buf with Nam_Len set. Calls
+ -- Skip_Spaces to skip any following spaces. Note that the name is
+ -- terminated by a sequence of at least two spaces.
+
+ function Get_Nat return Natural;
+ -- N on entry points to decimal integer, scan out decimal integer
+ -- and return it, leaving N pointing to following space or LF.
+
+ procedure Skip_Spaces;
+ -- Skip past spaces
+
+ ------------------
+ -- Check_Spaces --
+ ------------------
+
+ procedure Check_Spaces is
+ begin
+ if N > Buflen or else Buffer (N) /= ' ' then
+ FailN ("missing space for");
+ end if;
+
+ Skip_Spaces;
+ return;
+ end Check_Spaces;
+
+ -----------
+ -- FailN --
+ -----------
+
+ procedure FailN (S : String) is
+ begin
+ Fail (S & " """ & Nam_Buf (1 .. Nam_Len) & """ in file "
+ & Target_Dependent_Info_Read_Name.all);
+ end FailN;
+
+ --------------
+ -- Get_Name --
+ --------------
+
+ procedure Get_Name is
+ begin
+ Nam_Len := 0;
+
+ -- Scan out name and put it in Nam_Buf
+
+ loop
+ if N > Buflen or else Buffer (N) = ASCII.LF then
+ FailN ("incorrectly formatted line for");
+ end if;
+
+ -- Name is terminated by two blanks
+
+ exit when N < Buflen and then Buffer (N .. N + 1) = " ";
+
+ Nam_Len := Nam_Len + 1;
+
+ if Nam_Len > Nam_Buf'Last then
+ Fail ("name too long");
+ end if;
+
+ Nam_Buf (Nam_Len) := Buffer (N);
+ N := N + 1;
+ end loop;
+
+ Check_Spaces;
+ end Get_Name;
+
+ -------------
+ -- Get_Nat --
+ -------------
+
+ function Get_Nat return Natural is
+ Result : Natural := 0;
+
+ begin
+ loop
+ if N > Buflen
+ or else Buffer (N) not in '0' .. '9'
+ or else Result > 999
+ then
+ FailN ("bad value for");
+ end if;
+
+ Result := Result * 10 + (Character'Pos (Buffer (N)) - 48);
+ N := N + 1;
+
+ exit when N <= Buflen
+ and then (Buffer (N) = ASCII.LF or else Buffer (N) = ' ');
+ end loop;
+
+ return Result;
+ end Get_Nat;
+
+ -----------------
+ -- Skip_Spaces --
+ -----------------
+
+ procedure Skip_Spaces is
+ begin
+ while N <= Buflen and Buffer (N) = ' ' loop
+ N := N + 1;
+ end loop;
+ end Skip_Spaces;
+
+ -- Start of processing for Read_Target_Dependent_Values
+
+ begin
+ File_Desc := Open_Read (Target_Dependent_Info_Read_Name.all, Text);
+
+ if File_Desc = Invalid_FD then
+ Fail ("cannot read file " & Target_Dependent_Info_Read_Name.all);
+ end if;
+
+ Buflen := Read (File_Desc, Buffer'Address, Buffer'Length);
+
+ if Buflen = Buffer'Length then
+ Fail ("file is too long: " & Target_Dependent_Info_Read_Name.all);
+ end if;
+
+ -- Scan through file for properly formatted entries in first section
+
+ N := 1;
+ while N <= Buflen and then Buffer (N) /= ASCII.LF loop
+ Get_Name;
+
+ -- Validate name and get corresponding value pointer
+
+ VP := null;
+
+ for J in DTN'Range loop
+ if DTN (J).all = Nam_Buf (1 .. Nam_Len) then
+ VP := To_ANat (DTV (J));
+ DTR (J) := True;
+ exit;
+ end if;
+ end loop;
+
+ if VP = null then
+ FailN ("unrecognized name");
+ end if;
+
+ -- Scan out value
+
+ VP.all := Get_Nat;
+
+ if N > Buflen or else Buffer (N) /= ASCII.LF then
+ FailN ("misformatted line for");
+ end if;
+
+ N := N + 1; -- skip LF
+ end loop;
+
+ -- Fall through this loop when all lines in first section read.
+ -- Check that values have been supplied for all entries.
+
+ for J in DTR'Range loop
+ if not DTR (J) then
+ Fail ("missing entry for " & DTN (J).all & " in file "
+ & Target_Dependent_Info_Read_Name.all);
+ end if;
+ end loop;
+
+ -- Now acquire FPT entries
+
+ if N >= Buflen then
+ Fail ("missing entries for FPT modes in file "
+ & Target_Dependent_Info_Read_Name.all);
+ end if;
+
+ if Buffer (N) = ASCII.LF then
+ N := N + 1;
+ else
+ Fail ("missing blank line in file "
+ & Target_Dependent_Info_Read_Name.all);
+ end if;
+
+ Num_FPT_Modes := 0;
+ while N <= Buflen loop
+ Get_Name;
+
+ Num_FPT_Modes := Num_FPT_Modes + 1;
+
+ declare
+ E : FPT_Mode_Entry renames FPT_Mode_Table (Num_FPT_Modes);
+
+ begin
+ E.NAME := new String'(Nam_Buf (1 .. Nam_Len));
+
+ E.DIGS := Get_Nat;
+ Check_Spaces;
+
+ case Buffer (N) is
+ when 'I' =>
+ E.FLOAT_REP := IEEE_Binary;
+ when 'V' =>
+ E.FLOAT_REP := VAX_Native;
+ when 'A' =>
+ E.FLOAT_REP := AAMP;
+ when others =>
+ FailN ("bad float rep field for");
+ end case;
+
+ N := N + 1;
+ Check_Spaces;
+
+ E.PRECISION := Get_Nat;
+ Check_Spaces;
+
+ E.ALIGNMENT := Get_Nat;
+
+ if Buffer (N) /= ASCII.LF then
+ FailN ("junk at end of line for");
+ end if;
+
+ -- ??? We do not read E.SIZE, see Write_Target_Dependent_Values
+
+ E.SIZE :=
+ (E.PRECISION + E.ALIGNMENT - 1) / E.ALIGNMENT * E.ALIGNMENT;
+
+ N := N + 1;
+ end;
+ end loop;
+ end Read_Target_Dependent_Values;
+ end if;
+end Set_Targ;