-- Iir to ortho translator. -- Copyright (C) 2002 - 2014 Tristan Gingold -- -- GHDL 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, or (at your option) any later -- version. -- -- GHDL 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 GCC; see the file COPYING. If not, write to the Free -- Software Foundation, 59 Temple Place - Suite 330, Boston, MA -- 02111-1307, USA. with Name_Table; with Trans.Chap3; with Trans.Chap6; with Trans_Decls; use Trans_Decls; with Files_Map; with Trans.Foreach_Non_Composite; package body Trans.Helpers2 is use Trans.Helpers; procedure Copy_Fat_Pointer (D : Mnode; S: Mnode) is begin New_Assign_Stmt (M2Lp (Chap3.Get_Composite_Base (D)), M2Addr (Chap3.Get_Composite_Base (S))); New_Assign_Stmt (M2Lp (Chap3.Get_Composite_Bounds (D)), M2Addr (Chap3.Get_Composite_Bounds (S))); end Copy_Fat_Pointer; -- Convert NAME into a STRING_CST. -- Append a NUL terminator (to make interfaces with C easier). function Create_String_Type (Str : String) return O_Tnode is begin return New_Constrained_Array_Type (Chararray_Type, New_Unsigned_Literal (Ghdl_Index_Type, Unsigned_64 (Str'Length + 1))); end Create_String_Type; procedure Create_String_Value (Const : in out O_Dnode; Const_Type : O_Tnode; Str : String) is Res : O_Cnode; List : O_Array_Aggr_List; begin Start_Init_Value (Const); Start_Array_Aggr (List, Const_Type); for I in Str'Range loop New_Array_Aggr_El (List, New_Unsigned_Literal (Char_Type_Node, Character'Pos (Str (I)))); end loop; New_Array_Aggr_El (List, New_Unsigned_Literal (Char_Type_Node, 0)); Finish_Array_Aggr (List, Res); Finish_Init_Value (Const, Res); end Create_String_Value; function Create_String (Str : String; Id : O_Ident) return O_Dnode is Atype : O_Tnode; Const : O_Dnode; begin Atype := Create_String_Type (Str); New_Const_Decl (Const, Id, O_Storage_Private, Atype); Create_String_Value (Const, Atype, Str); return Const; end Create_String; function Create_String (Str : String; Id : O_Ident; Storage : O_Storage) return O_Dnode is Atype : O_Tnode; Const : O_Dnode; begin Atype := Create_String_Type (Str); New_Const_Decl (Const, Id, Storage, Atype); if Storage /= O_Storage_External then Create_String_Value (Const, Atype, Str); end if; return Const; end Create_String; function Create_String (Str : Name_Id; Id : O_Ident; Storage : O_Storage) return O_Dnode is use Name_Table; begin pragma Assert (not Name_Table.Is_Character (Str)); return Create_String (Image (Str), Id, Storage); end Create_String; function Create_String_Len (Str : String; Id : O_Ident) return O_Cnode is Str_Cst : O_Dnode; Str_Len : O_Cnode; List : O_Record_Aggr_List; Res : O_Cnode; begin Str_Cst := Create_String (Str, Id); Str_Len := New_Unsigned_Literal (Ghdl_Index_Type, Unsigned_64 (Str'Length)); Start_Record_Aggr (List, Ghdl_Str_Len_Type_Node); New_Record_Aggr_El (List, Str_Len); New_Record_Aggr_El (List, New_Global_Address (New_Global (Str_Cst), Char_Ptr_Type)); Finish_Record_Aggr (List, Res); return Res; end Create_String_Len; procedure Gen_Memcpy (Dest : O_Enode; Src : O_Enode; Length : O_Enode) is Constr : O_Assoc_List; begin Start_Association (Constr, Ghdl_Memcpy); New_Association (Constr, New_Convert_Ov (Dest, Ghdl_Ptr_Type)); New_Association (Constr, New_Convert_Ov (Src, Ghdl_Ptr_Type)); New_Association (Constr, Length); New_Procedure_Call (Constr); end Gen_Memcpy; function Gen_Alloc (Kind : Allocation_Kind; Size : O_Enode; Ptype : O_Tnode) return O_Enode is Constr : O_Assoc_List; begin case Kind is when Alloc_Heap => Start_Association (Constr, Ghdl_Malloc); New_Association (Constr, Size); return New_Convert_Ov (New_Function_Call (Constr), Ptype); when Alloc_System => Start_Association (Constr, Ghdl_Malloc0); New_Association (Constr, Size); return New_Convert_Ov (New_Function_Call (Constr), Ptype); when Alloc_Stack => return New_Alloca (Ptype, Size); when Alloc_Return => Start_Association (Constr, Ghdl_Stack2_Allocate); New_Association (Constr, Size); return New_Convert_Ov (New_Function_Call (Constr), Ptype); end case; end Gen_Alloc; procedure Register_Non_Composite_Signal (Targ : Mnode; Targ_Type : Iir; Proc : O_Dnode) is pragma Unreferenced (Targ_Type); Constr : O_Assoc_List; begin Start_Association (Constr, Proc); New_Association (Constr, New_Convert_Ov (New_Value (M2Lv (Targ)), Ghdl_Signal_Ptr)); New_Procedure_Call (Constr); end Register_Non_Composite_Signal; function Register_Update_Data_Array (Data : O_Dnode; Targ_Type : Iir; Index : O_Dnode) return O_Dnode is pragma Unreferenced (Targ_Type); pragma Unreferenced (Index); begin return Data; end Register_Update_Data_Array; function Register_Prepare_Data_Composite (Targ : Mnode; Targ_Type : Iir; Data : O_Dnode) return O_Dnode is pragma Unreferenced (Targ); pragma Unreferenced (Targ_Type); begin return Data; end Register_Prepare_Data_Composite; function Register_Update_Data_Record (Data : O_Dnode; Targ_Type : Iir; El : Iir_Element_Declaration) return O_Dnode is pragma Unreferenced (Targ_Type); pragma Unreferenced (El); begin return Data; end Register_Update_Data_Record; procedure Register_Signal_1 is new Foreach_Non_Composite (Data_Type => O_Dnode, Composite_Data_Type => O_Dnode, Do_Non_Composite => Register_Non_Composite_Signal, Prepare_Data_Array => Register_Prepare_Data_Composite, Update_Data_Array => Register_Update_Data_Array, Prepare_Data_Record => Register_Prepare_Data_Composite, Update_Data_Record => Register_Update_Data_Record); procedure Register_Signal (Targ : Mnode; Targ_Type : Iir; Proc : O_Dnode) renames Register_Signal_1; procedure Register_Signal_List (List : Iir_List; Proc : O_Dnode) is It : List_Iterator; El : Iir; Sig : Mnode; begin It := List_Iterate_Safe (List); while Is_Valid (It) loop El := Get_Element (It); Open_Temp; Sig := Chap6.Translate_Name (El, Mode_Signal); Register_Signal (Sig, Get_Type (El), Proc); Close_Temp; Next (It); end loop; end Register_Signal_List; function Gen_Oenode_Prepare_Data_Composite (Targ : Mnode; Targ_Type : Iir; Val : O_Enode) return Mnode is pragma Unreferenced (Targ); Res : Mnode; Type_Info : Type_Info_Acc; begin Type_Info := Get_Info (Targ_Type); Res := E2M (Val, Type_Info, Mode_Value); case Type_Info.Type_Mode is when Type_Mode_Arrays => Res := Chap3.Get_Composite_Base (Res); Res := Chap3.Convert_Array_Base (Res); when Type_Mode_Records => Res := Stabilize (Res); when others => -- Not a composite type! raise Internal_Error; end case; return Res; end Gen_Oenode_Prepare_Data_Composite; function Gen_Oenode_Update_Data_Array (Val : Mnode; Targ_Type : Iir; Index : O_Dnode) return O_Enode is begin return M2E (Chap3.Index_Base (Val, Targ_Type, New_Obj_Value (Index))); end Gen_Oenode_Update_Data_Array; function Gen_Oenode_Update_Data_Record (Val : Mnode; Targ_Type : Iir; El : Iir_Element_Declaration) return O_Enode is pragma Unreferenced (Targ_Type); begin return M2E (Chap6.Translate_Selected_Element (Val, El)); end Gen_Oenode_Update_Data_Record; procedure Gen_Oenode_Finish_Data_Composite (Data : in out Mnode) is pragma Unreferenced (Data); begin null; end Gen_Oenode_Finish_Data_Composite; function Get_Line_Number (Target: Iir) return Natural is Line, Col: Natural; Name : Name_Id; begin Files_Map.Location_To_Position (Get_Location (Target), Name, Line, Col); return Line; end Get_Line_Number; procedure Assoc_Filename_Line (Assoc : in out O_Assoc_List; Line : Natural) is begin New_Association (Assoc, New_Address (New_Obj (Current_Filename_Node), Char_Ptr_Type)); New_Association (Assoc, New_Lit (New_Signed_Literal (Ghdl_I32_Type, Integer_64 (Line)))); end Assoc_Filename_Line; end Trans.Helpers2;