diff options
author | Tristan Gingold <tgingold@free.fr> | 2020-07-24 18:31:11 +0200 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2020-07-25 11:28:49 +0200 |
commit | 04cd83fb46bee1e7a7b37be95bee73449af9c8b8 (patch) | |
tree | 3fe35d0bc6d4b1be8d81ad44df685057c221d2dc /src/ortho/mcode | |
parent | 4033dd795927a4953879bdc92d395788893a5468 (diff) | |
download | ghdl-04cd83fb46bee1e7a7b37be95bee73449af9c8b8.tar.gz ghdl-04cd83fb46bee1e7a7b37be95bee73449af9c8b8.tar.bz2 ghdl-04cd83fb46bee1e7a7b37be95bee73449af9c8b8.zip |
ortho: add unbounded records, rework array subtypes.
Diffstat (limited to 'src/ortho/mcode')
-rw-r--r-- | src/ortho/mcode/ortho_code-consts.adb | 43 | ||||
-rw-r--r-- | src/ortho/mcode/ortho_code-consts.ads | 4 | ||||
-rw-r--r-- | src/ortho/mcode/ortho_code-disps.adb | 10 | ||||
-rw-r--r-- | src/ortho/mcode/ortho_code-dwarf.adb | 50 | ||||
-rw-r--r-- | src/ortho/mcode/ortho_code-exprs.adb | 19 | ||||
-rw-r--r-- | src/ortho/mcode/ortho_code-types.adb | 257 | ||||
-rw-r--r-- | src/ortho/mcode/ortho_code-types.ads | 54 | ||||
-rw-r--r-- | src/ortho/mcode/ortho_code-x86-emits.adb | 13 | ||||
-rw-r--r-- | src/ortho/mcode/ortho_mcode.adb | 44 | ||||
-rw-r--r-- | src/ortho/mcode/ortho_mcode.ads | 40 | ||||
-rw-r--r-- | src/ortho/mcode/ortho_mcode.private.ads | 15 |
11 files changed, 408 insertions, 141 deletions
diff --git a/src/ortho/mcode/ortho_code-consts.adb b/src/ortho/mcode/ortho_code-consts.adb index dcb9c13be..c83b98459 100644 --- a/src/ortho/mcode/ortho_code-consts.adb +++ b/src/ortho/mcode/ortho_code-consts.adb @@ -507,11 +507,11 @@ package body Ortho_Code.Consts is return To_Cnode_Union (Cnodes.Table (Cst + 1)).El; end Get_Const_Union_Value; + function To_Cnode_Common is new Ada.Unchecked_Conversion + (Source => Cnode_Sizeof, Target => Cnode_Common); + function New_Sizeof (Atype : O_Tnode; Rtype : O_Tnode) return O_Cnode is - function To_Cnode_Common is new Ada.Unchecked_Conversion - (Source => Cnode_Sizeof, Target => Cnode_Common); - Res : O_Cnode; begin if Debug.Flag_Debug_Hli then @@ -527,6 +527,24 @@ package body Ortho_Code.Consts is end if; end New_Sizeof; + function New_Record_Sizeof + (Atype : O_Tnode; Rtype : O_Tnode) return O_Cnode + is + Res : O_Cnode; + begin + if Debug.Flag_Debug_Hli then + Cnodes.Append (Cnode_Common'(Kind => OC_Record_Sizeof, + Lit_Type => Rtype)); + Res := Cnodes.Last; + Cnodes.Append (To_Cnode_Common (Cnode_Sizeof'(Atype => Atype, + Pad => 0))); + return Res; + else + return New_Unsigned_Literal + (Rtype, Unsigned_64 (Get_Type_Record_Size (Atype))); + end if; + end New_Record_Sizeof; + function Get_Sizeof_Type (Cst : O_Cnode) return O_Tnode is function To_Cnode_Sizeof is new Ada.Unchecked_Conversion @@ -645,8 +663,8 @@ package body Ortho_Code.Consts is begin case Get_Const_Kind (Cst) is when OC_Signed - | OC_Unsigned - | OC_Float => + | OC_Unsigned + | OC_Float => H := Get_Const_High (Cst); L := Get_Const_Low (Cst); when OC_Null => @@ -656,13 +674,14 @@ package body Ortho_Code.Consts is H := 0; L := To_Cnode_Enum (Cnodes.Table (Cst + 1)).Val; when OC_Array - | OC_Record - | OC_Union - | OC_Sizeof - | OC_Alignof - | OC_Address - | OC_Subprg_Address - | OC_Zero => + | OC_Record + | OC_Union + | OC_Sizeof + | OC_Record_Sizeof + | OC_Alignof + | OC_Address + | OC_Subprg_Address + | OC_Zero => raise Syntax_Error; end case; end Get_Const_Bytes; diff --git a/src/ortho/mcode/ortho_code-consts.ads b/src/ortho/mcode/ortho_code-consts.ads index f49dbb315..05ff4389e 100644 --- a/src/ortho/mcode/ortho_code-consts.ads +++ b/src/ortho/mcode/ortho_code-consts.ads @@ -22,7 +22,7 @@ package Ortho_Code.Consts is OC_Zero, OC_Array, OC_Record, OC_Union, OC_Subprg_Address, OC_Address, - OC_Sizeof, OC_Alignof); + OC_Sizeof, OC_Record_Sizeof, OC_Alignof); type OG_Kind is (OG_Decl, OG_Record_Ref); @@ -140,6 +140,8 @@ package Ortho_Code.Consts is -- unsigned type RTYPE -- ATYPE cannot be an unconstrained array type. function New_Sizeof (Atype : O_Tnode; Rtype : O_Tnode) return O_Cnode; + function New_Record_Sizeof + (Atype : O_Tnode; Rtype : O_Tnode) return O_Cnode; -- Returns the alignment in bytes for ATYPE. The result is a literal of -- unsgined type RTYPE. diff --git a/src/ortho/mcode/ortho_code-disps.adb b/src/ortho/mcode/ortho_code-disps.adb index 45507a52e..8195f675d 100644 --- a/src/ortho/mcode/ortho_code-disps.adb +++ b/src/ortho/mcode/ortho_code-disps.adb @@ -400,10 +400,20 @@ package body Ortho_Code.Disps is Put ("["); Put_Trim (Uns32'Image (Get_Type_Subarray_Length (Atype))); Put ("]"); + Put (" "); + Put ("of"); + Put (" "); + Disp_Type (Get_Type_Subarray_Element (Atype)); when OT_Record => Put_Line ("record"); Disp_Fields (1, Atype); Put ("end record"); + when OT_Subrecord => + Put_Line ("subrecord"); + Disp_Type (Get_Type_Subrecord_Base (Atype)); + Put ("("); + Disp_Fields (1, Atype); + Put (")"); when OT_Union => Put_Line ("union"); Disp_Fields (1, Atype); diff --git a/src/ortho/mcode/ortho_code-dwarf.adb b/src/ortho/mcode/ortho_code-dwarf.adb index 0275b870f..31acadd0f 100644 --- a/src/ortho/mcode/ortho_code-dwarf.adb +++ b/src/ortho/mcode/ortho_code-dwarf.adb @@ -674,10 +674,9 @@ package body Ortho_Code.Dwarf is end if; end Emit_Access_Type; - procedure Emit_Ucarray_Type (Atype : O_Tnode; Decl : O_Dnode) + procedure Emit_Array_Type + (Decl : O_Dnode; El_Type : O_Tnode; Idx_Type : O_Tnode) is - use Ortho_Code.Types; - procedure Finish_Gen_Abbrev is begin Gen_Abbrev_Tuple (DW_AT_Type, DW_FORM_Ref4); @@ -701,7 +700,7 @@ package body Ortho_Code.Dwarf is Gen_Info_Header (Abbrev_Ucarray_Name); Emit_Decl_Ident (Decl); end if; - Emit_Type_Ref (Get_Type_Ucarray_Element (Atype)); + Emit_Type_Ref (El_Type); if Abbrev_Uc_Subrange = 0 then Generate_Abbrev (Abbrev_Uc_Subrange); @@ -712,9 +711,18 @@ package body Ortho_Code.Dwarf is end if; Gen_Info_Header (Abbrev_Uc_Subrange); - Emit_Type_Ref (Get_Type_Ucarray_Index (Atype)); + Emit_Type_Ref (Idx_Type); Gen_Uleb128 (0); + end Emit_Array_Type; + + procedure Emit_Ucarray_Type (Atype : O_Tnode; Decl : O_Dnode) + is + use Ortho_Code.Types; + begin + Emit_Array_Type (Decl, + Get_Type_Ucarray_Element (Atype), + Get_Type_Ucarray_Index (Atype)); end Emit_Ucarray_Type; procedure Emit_Subarray_Type (Atype : O_Tnode; Decl : O_Dnode) @@ -747,9 +755,8 @@ package body Ortho_Code.Dwarf is Emit_Decl_Ident (Decl); end if; - Base := Get_Type_Subarray_Base (Atype); - Emit_Type_Ref (Get_Type_Ucarray_Element (Base)); + Emit_Type_Ref (Get_Type_Subarray_Element (Atype)); Gen_Uleb128 (Unsigned_32 (Get_Type_Size (Atype))); if Abbrev_Subrange = 0 then @@ -763,6 +770,7 @@ package body Ortho_Code.Dwarf is end if; Gen_Info_Header (Abbrev_Subrange); + Base := Get_Type_Subarray_Base (Atype); Emit_Type_Ref (Get_Type_Ucarray_Index (Base)); Gen_8 (0); Gen_Uleb128 (Unsigned_32 (Get_Type_Subarray_Length (Atype))); @@ -777,6 +785,7 @@ package body Ortho_Code.Dwarf is F : O_Fnode; Loc_Pc : Pc_Type; Sibling_Pc : Pc_Type; + Sz : Uns32; begin if Abbrev_Member = 0 then Generate_Abbrev (Abbrev_Member); @@ -792,7 +801,12 @@ package body Ortho_Code.Dwarf is Set_Current_Section (Info_Sect); Sibling_Pc := Gen_Info_Sibling; Emit_Decl_Ident_If_Set (Decl); - Gen_Uleb128 (Unsigned_32 (Get_Type_Size (Atype))); + if Get_Type_Sized (Atype) then + Sz := Get_Type_Size (Atype); + else + Sz := Get_Type_Record_Size (Atype); + end if; + Gen_Uleb128 (Unsigned_32 (Sz)); Nbr := Get_Type_Record_Nbr_Fields (Atype); F := Get_Type_Record_Fields (Atype); @@ -975,10 +989,10 @@ package body Ortho_Code.Dwarf is -- First step: emit inner types (if any). case Kind is when OT_Signed - | OT_Unsigned - | OT_Float - | OT_Boolean - | OT_Enum => + | OT_Unsigned + | OT_Float + | OT_Boolean + | OT_Enum => null; when OT_Access => null; @@ -988,7 +1002,8 @@ package body Ortho_Code.Dwarf is when OT_Subarray => Emit_Type (Get_Type_Subarray_Base (Atype)); when OT_Record - | OT_Union => + | OT_Subrecord + | OT_Union => declare Nbr : Uns32; F : O_Fnode; @@ -1013,8 +1028,8 @@ package body Ortho_Code.Dwarf is -- Second step: emit info. case Kind is when OT_Signed - | OT_Unsigned - | OT_Float => + | OT_Unsigned + | OT_Float => Emit_Base_Type (Atype, Decl); -- base types. when OT_Access => @@ -1023,12 +1038,13 @@ package body Ortho_Code.Dwarf is Emit_Ucarray_Type (Atype, Decl); when OT_Subarray => Emit_Subarray_Type (Atype, Decl); - when OT_Record => + when OT_Record + | OT_Subrecord => Emit_Record_Type (Atype, Decl); when OT_Union => Emit_Union_Type (Atype, Decl); when OT_Enum - | OT_Boolean => + | OT_Boolean => Emit_Enum_Type (Atype, Decl); when OT_Complete => null; diff --git a/src/ortho/mcode/ortho_code-exprs.adb b/src/ortho/mcode/ortho_code-exprs.adb index e580082c7..619f124a6 100644 --- a/src/ortho/mcode/ortho_code-exprs.adb +++ b/src/ortho/mcode/ortho_code-exprs.adb @@ -708,10 +708,10 @@ package body Ortho_Code.Exprs is else case Get_Const_Kind (Lit) is when OC_Signed - | OC_Unsigned - | OC_Float - | OC_Null - | OC_Lit => + | OC_Unsigned + | OC_Float + | OC_Null + | OC_Lit => declare H, L : Uns32; begin @@ -726,11 +726,12 @@ package body Ortho_Code.Exprs is return New_Enode (OE_Addrd, L_Type, O_Enode (Get_Const_Decl (Lit)), O_Enode_Null); when OC_Array - | OC_Record - | OC_Union - | OC_Sizeof - | OC_Alignof - | OC_Zero => + | OC_Record + | OC_Record_Sizeof + | OC_Union + | OC_Sizeof + | OC_Alignof + | OC_Zero => raise Syntax_Error; end case; end if; diff --git a/src/ortho/mcode/ortho_code-types.adb b/src/ortho/mcode/ortho_code-types.adb index 177c1ec99..5cd17f0d1 100644 --- a/src/ortho/mcode/ortho_code-types.adb +++ b/src/ortho/mcode/ortho_code-types.adb @@ -32,8 +32,9 @@ package body Ortho_Code.Types is Mode : Mode_Type; -- 4 bits. Align : Small_Natural; -- 2 bits. Deferred : Boolean; -- 1 bit (True if the type was incomplete at first) + Sized : Boolean; -- 1 bit (True if the type has a size, is constrained) Flag1 : Boolean; - Pad0 : Bool_Array (0 .. 19); + Pad0 : Bool_Array (0 .. 18); Size : Uns32; end record; pragma Pack (Tnode_Common); @@ -49,7 +50,7 @@ package body Ortho_Code.Types is Index_Type : O_Tnode; end record; - type Tnode_Subarray is record + type Tnode_Subarray_2 is record Base_Type : O_Tnode; Length : Uns32; end record; @@ -59,6 +60,11 @@ package body Ortho_Code.Types is Nbr_Fields : Uns32; end record; + type Tnode_Subrecord_2 is record + Base_Type : O_Tnode; + Pad : Uns32; + end record; + type Tnode_Enum is record Lits : O_Cnode; Nbr_Lits : Uns32; @@ -94,12 +100,28 @@ package body Ortho_Code.Types is return Tnodes.Table (Atype).Kind; end Get_Type_Kind; + function Get_Type_Sized (Atype : O_Tnode) return Boolean is + begin + return Tnodes.Table (Atype).Sized; + end Get_Type_Sized; + + procedure Set_Type_Sized (Atype : O_Tnode; Sized : Boolean) is + begin + Tnodes.Table (Atype).Sized := Sized; + end Set_Type_Sized; + function Get_Type_Size (Atype : O_Tnode) return Uns32 is begin - pragma Assert (Get_Type_Kind (Atype) /= OT_Ucarray); + pragma Assert (Get_Type_Sized (Atype)); return Tnodes.Table (Atype).Size; end Get_Type_Size; + function Get_Type_Record_Size (Atype : O_Tnode) return Uns32 is + begin + pragma Assert (Get_Type_Kind (Atype) = OT_Record); + return Tnodes.Table (Atype).Size; + end Get_Type_Record_Size; + function Get_Type_Align (Atype : O_Tnode) return Small_Natural is begin return Tnodes.Table (Atype).Align; @@ -154,20 +176,26 @@ package body Ortho_Code.Types is end Get_Type_Ucarray_Element; - function To_Tnode_Subarray is new Ada.Unchecked_Conversion - (Source => Tnode_Common, Target => Tnode_Subarray); + function To_Tnode_Subarray_2 is new Ada.Unchecked_Conversion + (Source => Tnode_Common, Target => Tnode_Subarray_2); function Get_Type_Subarray_Base (Atype : O_Tnode) return O_Tnode is begin - return To_Tnode_Subarray (Tnodes.Table (Atype + 1)).Base_Type; + return To_Tnode_Subarray_2 (Tnodes.Table (Atype + 2)).Base_Type; end Get_Type_Subarray_Base; function Get_Type_Subarray_Length (Atype : O_Tnode) return Uns32 is begin - return To_Tnode_Subarray (Tnodes.Table (Atype + 1)).Length; + return To_Tnode_Subarray_2 (Tnodes.Table (Atype + 2)).Length; end Get_Type_Subarray_Length; + function Get_Type_Subarray_Element (Atype : O_Tnode) return O_Tnode is + begin + return To_Tnode_Array (Tnodes.Table (Atype + 1)).Element_Type; + end Get_Type_Subarray_Element; + + function To_Tnode_Record is new Ada.Unchecked_Conversion (Source => Tnode_Common, Target => Tnode_Record); @@ -181,6 +209,14 @@ package body Ortho_Code.Types is return To_Tnode_Record (Tnodes.Table (Atype + 1)).Nbr_Fields; end Get_Type_Record_Nbr_Fields; + function To_Tnode_Subrecord_2 is new Ada.Unchecked_Conversion + (Source => Tnode_Common, Target => Tnode_Subrecord_2); + + function Get_Type_Subrecord_Base (Atype : O_Tnode) return O_Tnode is + begin + return To_Tnode_Subrecord_2 (Tnodes.Table (Atype + 2)).Base_Type; + end Get_Type_Subrecord_Base; + function To_Tnode_Enum is new Ada.Unchecked_Conversion (Source => Tnode_Common, Target => Tnode_Enum); @@ -271,6 +307,7 @@ package body Ortho_Code.Types is Mode => Mode, Align => Mode_Align (Mode), Deferred => False, + Sized => True, Flag1 => False, Pad0 => (others => False), Size => Sz)); @@ -302,6 +339,7 @@ package body Ortho_Code.Types is Mode => Mode, Align => Mode_Align (Mode), Deferred => False, + Sized => True, Flag1 => False, Pad0 => (others => False), Size => Sz)); @@ -314,6 +352,7 @@ package body Ortho_Code.Types is Mode => Mode_F64, Align => Mode_Align (Mode_F64), Deferred => False, + Sized => True, Flag1 => False, Pad0 => (others => False), Size => 8)); @@ -348,6 +387,7 @@ package body Ortho_Code.Types is Mode => Mode, Align => Mode_Align (Mode), Deferred => False, + Sized => True, Flag1 => False, Pad0 => (others => False), Size => Sz)); @@ -393,6 +433,7 @@ package body Ortho_Code.Types is Mode => Mode_B2, Align => 0, Deferred => False, + Sized => True, Flag1 => False, Pad0 => (others => False), Size => 1)); @@ -415,6 +456,7 @@ package body Ortho_Code.Types is Mode => Mode_Blk, Align => Get_Type_Align (El_Type), Deferred => False, + Sized => False, Flag1 => False, Pad0 => (others => False), Size => 0)); @@ -425,27 +467,32 @@ package body Ortho_Code.Types is end New_Array_Type; function To_Tnode_Common is new Ada.Unchecked_Conversion - (Source => Tnode_Subarray, Target => Tnode_Common); + (Source => Tnode_Subarray_2, Target => Tnode_Common); - function New_Constrained_Array_Type (Atype : O_Tnode; Length : Uns32) - return O_Tnode + function New_Array_Subtype + (Atype : O_Tnode; El_Type : O_Tnode; Length : Uns32) return O_Tnode is Res : O_Tnode; Size : Uns32; begin - Size := Get_Type_Size (Get_Type_Array_Element (Atype)); + Size := Get_Type_Size (El_Type); Tnodes.Append (Tnode_Common'(Kind => OT_Subarray, Mode => Mode_Blk, Align => Get_Type_Align (Atype), Deferred => False, + Sized => True, Flag1 => False, Pad0 => (others => False), Size => Size * Length)); Res := Tnodes.Last; - Tnodes.Append (To_Tnode_Common (Tnode_Subarray'(Base_Type => Atype, - Length => Length))); + Tnodes.Append (To_Tnode_Common + (Tnode_Array'(Element_Type => El_Type, + Index_Type => O_Tnode_Null))); + Tnodes.Append (To_Tnode_Common + (Tnode_Subarray_2'(Base_Type => Atype, + Length => Length))); return Res; - end New_Constrained_Array_Type; + end New_Array_Subtype; procedure Create_Completer (Atype : O_Tnode) is begin @@ -453,6 +500,7 @@ package body Ortho_Code.Types is Mode => Mode_Nil, Align => 0, Deferred => False, + Sized => False, Flag1 => False, Pad0 => (others => False), Size => To_Uns32 (Int32 (Atype)))); @@ -476,6 +524,7 @@ package body Ortho_Code.Types is Mode => Mode_Ptr, Align => Mode_Align (Mode_Ptr), Deferred => Dtype = O_Tnode_Null, + Sized => True, Flag1 => False, Pad0 => (others => False), Size => Sz)); @@ -502,6 +551,9 @@ package body Ortho_Code.Types is function To_Tnode_Common is new Ada.Unchecked_Conversion (Source => Tnode_Record, Target => Tnode_Common); + function To_Tnode_Common is new Ada.Unchecked_Conversion + (Source => Tnode_Subrecord_2, Target => Tnode_Common); + function Create_Record_Type (Deferred : Boolean) return O_Tnode is Res : O_Tnode; @@ -510,6 +562,7 @@ package body Ortho_Code.Types is Mode => Mode_Blk, Align => 0, Deferred => Deferred, + Sized => True, Flag1 => False, Pad0 => (others => False), Size => 0)); @@ -519,17 +572,6 @@ package body Ortho_Code.Types is return Res; end Create_Record_Type; - procedure Start_Record_Type (Elements : out O_Element_List) - is - begin - Elements := (Res => Create_Record_Type (False), - First_Field => O_Fnode_Null, - Last_Field => O_Fnode_Null, - Off => 0, - Align => 0, - Nbr => 0); - end Start_Record_Type; - procedure New_Uncomplete_Record_Type (Res : out O_Tnode) is begin Res := Create_Record_Type (True); @@ -544,7 +586,8 @@ package body Ortho_Code.Types is Last_Field => O_Fnode_Null, Off => 0, Align => 0, - Nbr => 0); + Nbr => 0, + Base_Field => O_Fnode_Null); end Start_Uncomplete_Record_Type; function Get_Mode_Size (Mode : Mode_Type) return Uns32 is @@ -590,12 +633,10 @@ package body Ortho_Code.Types is return (Off + Msk) and (not Msk); end Do_Align; - procedure New_Record_Field - (Elements : in out O_Element_List; - El : out O_Fnode; - Ident : O_Ident; - Etype : O_Tnode) - is + procedure Append_Field (Elements : in out O_Element_List; + El : out O_Fnode; + Ident : O_Ident; + Etype : O_Tnode) is begin Elements.Off := Do_Align (Elements.Off, Etype); @@ -605,7 +646,11 @@ package body Ortho_Code.Types is Offset => Elements.Off, Next => O_Fnode_Null)); El := Fnodes.Last; - Elements.Off := Elements.Off + Get_Type_Size (Etype); + if Get_Type_Sized (Etype) then + Elements.Off := Elements.Off + Get_Type_Size (Etype); + else + Set_Type_Sized (Elements.Res, False); + end if; if Get_Type_Align (Etype) > Elements.Align then Elements.Align := Get_Type_Align (Etype); end if; @@ -615,12 +660,35 @@ package body Ortho_Code.Types is Elements.First_Field := Fnodes.Last; end if; Elements.Last_Field := Fnodes.Last; + end Append_Field; + + procedure Start_Record_Type (Elements : out O_Element_List) is + begin + Elements := (Res => Create_Record_Type (False), + First_Field => O_Fnode_Null, + Last_Field => O_Fnode_Null, + Off => 0, + Align => 0, + Nbr => 0, + Base_Field => O_Fnode_Null); + end Start_Record_Type; + + procedure New_Record_Field (Elements : in out O_Element_List; + El : out O_Fnode; + Ident : O_Ident; + Etype : O_Tnode) is + begin + if Get_Type_Sized (Etype) then + -- Cannot append bounded elements after unbounded onces. + pragma Assert (Get_Type_Sized (Elements.Res)); + null; + end if; + + Append_Field (Elements, El, Ident, Etype); Elements.Nbr := Elements.Nbr + 1; end New_Record_Field; - procedure Finish_Record_Type - (Elements : in out O_Element_List; Res : out O_Tnode) - is + procedure Finish_Record (Elements : O_Element_List) is begin Tnodes.Table (Elements.Res).Align := Elements.Align; Tnodes.Table (Elements.Res).Size := Do_Align (Elements.Off, @@ -628,6 +696,12 @@ package body Ortho_Code.Types is Tnodes.Table (Elements.Res + 1) := To_Tnode_Common (Tnode_Record'(Fields => Elements.First_Field, Nbr_Fields => Elements.Nbr)); + end Finish_Record; + + procedure Finish_Record_Type + (Elements : in out O_Element_List; Res : out O_Tnode) is + begin + Finish_Record (Elements); Res := Elements.Res; if Flag_Type_Completer and then Tnodes.Table (Elements.Res).Deferred @@ -636,6 +710,71 @@ package body Ortho_Code.Types is end if; end Finish_Record_Type; + procedure Start_Record_Subtype + (Rtype : O_Tnode; Elements : out O_Element_List) + is + Res : O_Tnode; + Nbr : Uns32; + begin + pragma Assert (Get_Type_Kind (Rtype) = OT_Record); + Nbr := Get_Type_Record_Nbr_Fields (Rtype); + + Tnodes.Append (Tnode_Common'(Kind => OT_Subrecord, + Mode => Mode_Blk, + Align => 0, + Deferred => False, + Sized => True, + Flag1 => False, + Pad0 => (others => False), + Size => 0)); + Res := Tnodes.Last; + Tnodes.Append (To_Tnode_Common (Tnode_Record'(Fields => O_Fnode_Null, + Nbr_Fields => Nbr))); + Tnodes.Append (To_Tnode_Common (Tnode_Subrecord_2'(Base_Type => Rtype, + Pad => 0))); + Elements := (Res => Res, + First_Field => O_Fnode_Null, + Last_Field => O_Fnode_Null, + Off => 0, + Align => 0, + Nbr => Nbr, + Base_Field => Get_Type_Record_Fields (Rtype)); + end Start_Record_Subtype; + + procedure New_Subrecord_Field + (Elements : in out O_Element_List; El : out O_Fnode; Etype : O_Tnode) + is + Base_Type : O_Tnode; + begin + pragma Assert (Elements.Nbr > 0); + Elements.Nbr := Elements.Nbr - 1; + + Base_Type := Get_Field_Type (Elements.Base_Field); + if Get_Type_Sized (Base_Type) then + -- For bounded elements, the type must be the same. + pragma Assert (Etype = Base_Type); + null; + else + -- For unbounded elements, those from the subtype must be bounded. + pragma Assert (Get_Base_Type (Etype) = Base_Type); + pragma Assert (Get_Type_Sized (Etype)); + null; + end if; + + Append_Field (Elements, + El, Get_Field_Ident (Elements.Base_Field), Etype); + Elements.Base_Field := Get_Field_Chain (Elements.Base_Field); + end New_Subrecord_Field; + + procedure Finish_Record_Subtype + (Elements : in out O_Element_List; Res : out O_Tnode) is + begin + Elements.Nbr := Get_Type_Record_Nbr_Fields (Elements.Res); + Finish_Record (Elements); + Res := Elements.Res; + end Finish_Record_Subtype; + + procedure Start_Union_Type (Elements : out O_Element_List) is begin @@ -643,6 +782,7 @@ package body Ortho_Code.Types is Mode => Mode_Blk, Align => 0, Deferred => False, + Sized => True, Flag1 => False, Pad0 => (others => False), Size => 0)); @@ -651,7 +791,8 @@ package body Ortho_Code.Types is Last_Field => O_Fnode_Null, Off => 0, Align => 0, - Nbr => 0); + Nbr => 0, + Base_Field => O_Fnode_Null); Tnodes.Append (To_Tnode_Common (Tnode_Record'(Fields => O_Fnode_Null, Nbr_Fields => 0))); end Start_Union_Type; @@ -679,22 +820,19 @@ package body Ortho_Code.Types is Finish_Record_Type (Elements, Res); end Finish_Union_Type; - function Get_Type_Array_Element (Atype : O_Tnode) return O_Tnode - is - Base : O_Tnode; + function Get_Type_Array_Element (Atype : O_Tnode) return O_Tnode is begin case Get_Type_Kind (Atype) is when OT_Ucarray => - Base := Atype; + return Get_Type_Ucarray_Element (Atype); when OT_Subarray => - Base := Get_Type_Subarray_Base (Atype); + return Get_Type_Subarray_Element (Atype); when others => raise Program_Error; end case; - return Get_Type_Ucarray_Element (Base); end Get_Type_Array_Element; - procedure Debug_Type (Atype : O_Tnode) + procedure Dump_Tnode (Atype : O_Tnode) is use Ortho_Code.Debug.Int32_IO; use Ada.Text_IO; @@ -733,13 +871,15 @@ package body Ortho_Code.Types is Put (Int32 (Get_Type_Subarray_Base (Atype))); Put (", length: "); Put (To_Int32 (Get_Type_Subarray_Length (Atype))); + Put (", el_type: "); + Put (Int32 (Get_Type_Subarray_Element (Atype))); New_Line; when others => null; end case; - end Debug_Type; + end Dump_Tnode; - procedure Debug_Field (Field : O_Fnode) + procedure Dump_Fnode (Field : O_Fnode) is use Ortho_Code.Debug.Int32_IO; use Ada.Text_IO; @@ -755,7 +895,7 @@ package body Ortho_Code.Types is Put (", Chain="); Put (Int32 (Get_Field_Chain (Field)), 0); New_Line; - end Debug_Field; + end Dump_Fnode; function Get_Type_Limit return O_Tnode is begin @@ -766,28 +906,31 @@ package body Ortho_Code.Types is begin case Tnodes.Table (Atype).Kind is when OT_Unsigned - | OT_Signed - | OT_Float => + | OT_Signed + | OT_Float => return Atype + 1; when OT_Boolean - | OT_Enum - | OT_Ucarray - | OT_Subarray - | OT_Access - | OT_Record - | OT_Union => + | OT_Enum + | OT_Ucarray + | OT_Access + | OT_Record + | OT_Union => return Atype + 2; + when OT_Subarray + | OT_Subrecord => + return Atype + 3; when OT_Complete => return Atype + 1; end case; end Get_Type_Next; - function Get_Base_Type (Atype : O_Tnode) return O_Tnode - is + function Get_Base_Type (Atype : O_Tnode) return O_Tnode is begin case Get_Type_Kind (Atype) is when OT_Subarray => return Get_Type_Subarray_Base (Atype); + when OT_Subrecord => + return Get_Type_Subrecord_Base (Atype); when others => return Atype; end case; diff --git a/src/ortho/mcode/ortho_code-types.ads b/src/ortho/mcode/ortho_code-types.ads index a9d15b60a..1fd336ebd 100644 --- a/src/ortho/mcode/ortho_code-types.ads +++ b/src/ortho/mcode/ortho_code-types.ads @@ -17,8 +17,10 @@ -- 02111-1307, USA. package Ortho_Code.Types is type OT_Kind is (OT_Unsigned, OT_Signed, OT_Boolean, OT_Enum, OT_Float, - OT_Ucarray, OT_Subarray, OT_Access, - OT_Record, OT_Union, + OT_Ucarray, OT_Subarray, + OT_Access, + OT_Record, OT_Subrecord, + OT_Union, -- Type completion. Mark the completion of a type. -- Optionnal. @@ -32,6 +34,9 @@ package Ortho_Code.Types is -- Number of bytes of type ATYPE. function Get_Type_Size (Atype : O_Tnode) return Uns32; + -- True if ATYPE is bounded (and therefore its size is valid). + function Get_Type_Sized (Atype : O_Tnode) return Boolean; + -- Same as Get_Type_Size but for modes. -- Returns 0 in case of error. function Get_Mode_Size (Mode : Mode_Type) return Uns32; @@ -75,12 +80,21 @@ package Ortho_Code.Types is -- Get number of element for array type ATYPE. function Get_Type_Subarray_Length (Atype : O_Tnode) return Uns32; + -- Get the element type of subarray type ATYPE. + function Get_Type_Subarray_Element (Atype : O_Tnode) return O_Tnode; + + -- Get the size of the bounded part of ATYPE. + function Get_Type_Record_Size (Atype : O_Tnode) return Uns32; + -- Get the first field of record/union ATYPE. function Get_Type_Record_Fields (Atype : O_Tnode) return O_Fnode; -- Get the number of fields of record/union ATYPE. function Get_Type_Record_Nbr_Fields (Atype : O_Tnode) return Uns32; + -- Get the base type of subrecord ATYPE. + function Get_Type_Subrecord_Base (Atype : O_Tnode) return O_Tnode; + -- Get the first literal of enum type ATYPE. function Get_Type_Enum_Lits (Atype : O_Tnode) return O_Cnode; @@ -148,11 +162,11 @@ package Ortho_Code.Types is -- Build an array type. -- The array is not constrained and unidimensional. function New_Array_Type (El_Type : O_Tnode; Index_Type : O_Tnode) - return O_Tnode; + return O_Tnode; -- Build a constrained array type. - function New_Constrained_Array_Type (Atype : O_Tnode; Length : Uns32) - return O_Tnode; + function New_Array_Subtype + (Atype : O_Tnode; El_Type : O_Tnode; Length : Uns32) return O_Tnode; -- Return the base type of ATYPE: for a subarray this is the uc array, -- otherwise this is the type. @@ -172,6 +186,14 @@ package Ortho_Code.Types is procedure Finish_Record_Type (Elements : in out O_Element_List; Res : out O_Tnode); + -- Record subtype. + procedure Start_Record_Subtype + (Rtype : O_Tnode; Elements : out O_Element_List); + procedure New_Subrecord_Field + (Elements : in out O_Element_List; El : out O_Fnode; Etype : O_Tnode); + procedure Finish_Record_Subtype + (Elements : in out O_Element_List; Res : out O_Tnode); + -- Build an uncomplete record type: -- First call NEW_UNCOMPLETE_RECORD_TYPE, which returns a record type. -- This type can be declared or used to define access types on it. @@ -214,23 +236,25 @@ package Ortho_Code.Types is procedure Mark (M : out Mark_Type); procedure Release (M : Mark_Type); - procedure Debug_Type (Atype : O_Tnode); - procedure Debug_Field (Field : O_Fnode); + procedure Dump_Tnode (Atype : O_Tnode); + procedure Dump_Fnode (Field : O_Fnode); private type O_Enum_List is record - Res : O_Tnode; + Res : O_Tnode; First : O_Cnode; - Last : O_Cnode; - Nbr : Uns32; + Last : O_Cnode; + Nbr : Uns32; end record; type O_Element_List is record - Res : O_Tnode; - Nbr : Uns32; - Off : Uns32; - Align : Small_Natural; + Res : O_Tnode; + Nbr : Uns32; + Off : Uns32; + Align : Small_Natural; First_Field : O_Fnode; - Last_Field : O_Fnode; + Last_Field : O_Fnode; + -- For subrecords + Base_Field : O_Fnode; end record; type Mark_Type is record diff --git a/src/ortho/mcode/ortho_code-x86-emits.adb b/src/ortho/mcode/ortho_code-x86-emits.adb index 91db6b54d..f55793eec 100644 --- a/src/ortho/mcode/ortho_code-x86-emits.adb +++ b/src/ortho/mcode/ortho_code-x86-emits.adb @@ -3163,10 +3163,10 @@ package body Ortho_Code.X86.Emits is begin case Get_Const_Kind (Val) is when OC_Signed - | OC_Unsigned - | OC_Float - | OC_Null - | OC_Lit => + | OC_Unsigned + | OC_Float + | OC_Null + | OC_Lit => Get_Const_Bytes (Val, H, L); case Get_Type_Mode (Get_Const_Type (Val)) is when Mode_U8 @@ -3216,8 +3216,9 @@ package body Ortho_Code.X86.Emits is Gen_8 (0); end loop; when OC_Sizeof - | OC_Alignof - | OC_Union => + | OC_Record_Sizeof + | OC_Alignof + | OC_Union => raise Program_Error; end case; end Emit_Const; diff --git a/src/ortho/mcode/ortho_mcode.adb b/src/ortho/mcode/ortho_mcode.adb index cd7131d73..235bb0e47 100644 --- a/src/ortho/mcode/ortho_mcode.adb +++ b/src/ortho/mcode/ortho_mcode.adb @@ -60,6 +60,31 @@ package body Ortho_Mcode is Ortho_Code.O_Tnode (Res)); end Finish_Record_Type; + procedure Start_Record_Subtype + (Rtype : O_Tnode; Elements : out O_Element_Sublist) is + begin + Ortho_Code.Types.Start_Record_Subtype + (Ortho_Code.O_Tnode (Rtype), + Ortho_Code.Types.O_Element_List (Elements)); + end Start_Record_Subtype; + + procedure New_Subrecord_Field + (Elements : in out O_Element_Sublist; El : out O_Fnode; Etype : O_Tnode) + is + begin + Ortho_Code.Types.New_Subrecord_Field + (Ortho_Code.Types.O_Element_List (Elements), + Ortho_Code.O_Fnode (El), Ortho_Code.O_Tnode (Etype)); + end New_Subrecord_Field; + + procedure Finish_Record_Subtype + (Elements : in out O_Element_Sublist; Res : out O_Tnode) is + begin + Ortho_Code.Types.Finish_Record_Subtype + (Ortho_Code.Types.O_Element_List (Elements), + Ortho_Code.O_Tnode (Res)); + end Finish_Record_Subtype; + procedure New_Uncomplete_Record_Type (Res : out O_Tnode) is begin Ortho_Code.Types.New_Uncomplete_Record_Type (Ortho_Code.O_Tnode (Res)); @@ -127,8 +152,8 @@ package body Ortho_Mcode is Ortho_Code.O_Tnode (Index_Type))); end New_Array_Type; - function New_Constrained_Array_Type (Atype : O_Tnode; Length : O_Cnode) - return O_Tnode + function New_Array_Subtype + (Atype : O_Tnode; El_Type : O_Tnode; Length : O_Cnode) return O_Tnode is Len : constant Ortho_Code.O_Cnode := Ortho_Code.O_Cnode (Length); L_Type : Ortho_Code.O_Tnode; @@ -137,9 +162,10 @@ package body Ortho_Mcode is if Get_Type_Kind (L_Type) /= OT_Unsigned then raise Syntax_Error; end if; - return O_Tnode (New_Constrained_Array_Type - (Ortho_Code.O_Tnode (Atype), Get_Const_U32 (Len))); - end New_Constrained_Array_Type; + return O_Tnode (New_Array_Subtype (Ortho_Code.O_Tnode (Atype), + Ortho_Code.O_Tnode (El_Type), + Get_Const_U32 (Len))); + end New_Array_Subtype; function New_Unsigned_Type (Size : Natural) return O_Tnode is begin @@ -325,6 +351,14 @@ package body Ortho_Mcode is Ortho_Code.O_Tnode (Rtype))); end New_Sizeof; + function New_Record_Sizeof + (Atype : O_Tnode; Rtype : O_Tnode) return O_Cnode is + begin + return O_Cnode + (Ortho_Code.Consts.New_Record_Sizeof (Ortho_Code.O_Tnode (Atype), + Ortho_Code.O_Tnode (Rtype))); + end New_Record_Sizeof; + function New_Alignof (Atype : O_Tnode; Rtype : O_Tnode) return O_Cnode is begin return O_Cnode diff --git a/src/ortho/mcode/ortho_mcode.ads b/src/ortho/mcode/ortho_mcode.ads index ef24372e3..1e3aa6a44 100644 --- a/src/ortho/mcode/ortho_mcode.ads +++ b/src/ortho/mcode/ortho_mcode.ads @@ -64,8 +64,8 @@ package Ortho_Mcode is -- Build a record type. procedure Start_Record_Type (Elements : out O_Element_List); - -- Add a field in the record; not constrained array are prohibited, since - -- its size is unlimited. + -- Add a field in the record. Unconstrained fields must be at the end, + -- and cannot be followed by a constrained one. procedure New_Record_Field (Elements : in out O_Element_List; El : out O_Fnode; @@ -74,6 +74,17 @@ package Ortho_Mcode is procedure Finish_Record_Type (Elements : in out O_Element_List; Res : out O_Tnode); + type O_Element_Sublist is limited private; + + -- Build a record subtype. + -- Re-declare only unconstrained fields with a subtype of them. + procedure Start_Record_Subtype + (Rtype : O_Tnode; Elements : out O_Element_Sublist); + procedure New_Subrecord_Field + (Elements : in out O_Element_Sublist; El : out O_Fnode; Etype : O_Tnode); + procedure Finish_Record_Subtype + (Elements : in out O_Element_Sublist; Res : out O_Tnode); + -- Build an uncomplete record type: -- First call NEW_UNCOMPLETE_RECORD_TYPE, which returns a record type. -- This type can be declared or used to define access types on it. @@ -105,8 +116,8 @@ package Ortho_Mcode is return O_Tnode; -- Build a constrained array type. - function New_Constrained_Array_Type (Atype : O_Tnode; Length : O_Cnode) - return O_Tnode; + function New_Array_Subtype + (Atype : O_Tnode; El_Type : O_Tnode; Length : O_Cnode) return O_Tnode; -- Build a scalar type; size may be 8, 16, 32 or 64. function New_Unsigned_Type (Size : Natural) return O_Tnode; @@ -179,9 +190,13 @@ package Ortho_Mcode is -- Returns the size in bytes of ATYPE. The result is a literal of -- unsigned type RTYPE - -- ATYPE cannot be an unconstrained array type. + -- ATYPE cannot be an unconstrained type. function New_Sizeof (Atype : O_Tnode; Rtype : O_Tnode) return O_Cnode; + -- Get the size of the bounded part of a record. + function New_Record_Sizeof + (Atype : O_Tnode; Rtype : O_Tnode) return O_Cnode; + -- Returns the alignment in bytes for ATYPE. The result is a literal of -- unsgined type RTYPE. function New_Alignof (Atype : O_Tnode; Rtype : O_Tnode) return O_Cnode; @@ -498,14 +513,15 @@ private O_Snode_Null : constant O_Snode := O_Snode (Ortho_Code.Exprs.O_Snode_Null); O_Tnode_Null : constant O_Tnode := O_Tnode (Ortho_Code.O_Tnode_Null); - type O_Element_List is new Ortho_Code.Types.O_Element_List; - type O_Enum_List is new Ortho_Code.Types.O_Enum_List; - type O_Inter_List is new Ortho_Code.Decls.O_Inter_List; + type O_Element_List is new Ortho_Code.Types.O_Element_List; + type O_Element_Sublist is new Ortho_Code.Types.O_Element_List; + type O_Enum_List is new Ortho_Code.Types.O_Enum_List; + type O_Inter_List is new Ortho_Code.Decls.O_Inter_List; type O_Record_Aggr_List is new Ortho_Code.Consts.O_Record_Aggr_List; - type O_Array_Aggr_List is new Ortho_Code.Consts.O_Array_Aggr_List; - type O_Assoc_List is new Ortho_Code.Exprs.O_Assoc_List; - type O_If_Block is new Ortho_Code.Exprs.O_If_Block; - type O_Case_Block is new Ortho_Code.Exprs.O_Case_Block; + type O_Array_Aggr_List is new Ortho_Code.Consts.O_Array_Aggr_List; + type O_Assoc_List is new Ortho_Code.Exprs.O_Assoc_List; + type O_If_Block is new Ortho_Code.Exprs.O_If_Block; + type O_Case_Block is new Ortho_Code.Exprs.O_Case_Block; pragma Inline (New_Lit); pragma Inline (New_Dyadic_Op); diff --git a/src/ortho/mcode/ortho_mcode.private.ads b/src/ortho/mcode/ortho_mcode.private.ads index a78a1a170..def9b7a72 100644 --- a/src/ortho/mcode/ortho_mcode.private.ads +++ b/src/ortho/mcode/ortho_mcode.private.ads @@ -52,14 +52,15 @@ private O_Snode_Null : constant O_Snode := O_Snode (Ortho_Code.Exprs.O_Snode_Null); O_Tnode_Null : constant O_Tnode := O_Tnode (Ortho_Code.O_Tnode_Null); - type O_Element_List is new Ortho_Code.Types.O_Element_List; - type O_Enum_List is new Ortho_Code.Types.O_Enum_List; - type O_Inter_List is new Ortho_Code.Decls.O_Inter_List; + type O_Element_List is new Ortho_Code.Types.O_Element_List; + type O_Element_Sublist is new Ortho_Code.Types.O_Element_List; + type O_Enum_List is new Ortho_Code.Types.O_Enum_List; + type O_Inter_List is new Ortho_Code.Decls.O_Inter_List; type O_Record_Aggr_List is new Ortho_Code.Consts.O_Record_Aggr_List; - type O_Array_Aggr_List is new Ortho_Code.Consts.O_Array_Aggr_List; - type O_Assoc_List is new Ortho_Code.Exprs.O_Assoc_List; - type O_If_Block is new Ortho_Code.Exprs.O_If_Block; - type O_Case_Block is new Ortho_Code.Exprs.O_Case_Block; + type O_Array_Aggr_List is new Ortho_Code.Consts.O_Array_Aggr_List; + type O_Assoc_List is new Ortho_Code.Exprs.O_Assoc_List; + type O_If_Block is new Ortho_Code.Exprs.O_If_Block; + type O_Case_Block is new Ortho_Code.Exprs.O_Case_Block; pragma Inline (New_Lit); pragma Inline (New_Dyadic_Op); |