diff options
Diffstat (limited to 'translate')
-rw-r--r-- | translate/ghdldrv/foreigns.adb | 64 | ||||
-rw-r--r-- | translate/ghdldrv/foreigns.ads | 5 | ||||
-rw-r--r-- | translate/ghdldrv/ghdlrun.adb | 64 | ||||
-rw-r--r-- | translate/grt/Makefile.inc | 5 | ||||
-rw-r--r-- | translate/grt/grt-avhpi.adb | 2 | ||||
-rw-r--r-- | translate/grt/grt-rtis_addr.adb | 2 | ||||
-rw-r--r-- | translate/grt/grt-signals.ads | 4 | ||||
-rw-r--r-- | translate/grt/grt-vpi.adb | 199 | ||||
-rw-r--r-- | translate/trans_be.adb | 2 | ||||
-rw-r--r-- | translate/translation.adb | 208 | ||||
-rw-r--r-- | translate/translation.ads | 24 |
11 files changed, 499 insertions, 80 deletions
diff --git a/translate/ghdldrv/foreigns.adb b/translate/ghdldrv/foreigns.adb new file mode 100644 index 0000000..15e3dd0 --- /dev/null +++ b/translate/ghdldrv/foreigns.adb @@ -0,0 +1,64 @@ +with Interfaces.C; use Interfaces.C; + +package body Foreigns is + function Sin (Arg : double) return double; + pragma Import (C, Sin); + + function Log (Arg : double) return double; + pragma Import (C, Log); + + function Exp (Arg : double) return double; + pragma Import (C, Exp); + + function Sqrt (Arg : double) return double; + pragma Import (C, Sqrt); + + function Asin (Arg : double) return double; + pragma Import (C, Asin); + + function Acos (Arg : double) return double; + pragma Import (C, Acos); + + function Asinh (Arg : double) return double; + pragma Import (C, Asinh); + + function Acosh (Arg : double) return double; + pragma Import (C, Acosh); + + function Atanh (X : double) return double; + pragma Import (C, Atanh); + + function Atan2 (X, Y : double) return double; + pragma Import (C, Atan2); + + type String_Cacc is access constant String; + type Foreign_Record is record + Name : String_Cacc; + Addr : Address; + end record; + + + Foreign_Arr : constant array (Natural range <>) of Foreign_Record := + ( + (new String'("sin"), Sin'Address), + (new String'("log"), Log'Address), + (new String'("exp"), Exp'Address), + (new String'("sqrt"), Sqrt'Address), + (new String'("asin"), Asin'Address), + (new String'("acos"), Acos'Address), + (new String'("asinh"), Asinh'Address), + (new String'("acosh"), Acosh'Address), + (new String'("atanh"), Atanh'Address), + (new String'("atan2"), Atan2'Address) + ); + + function Find_Foreign (Name : String) return Address is + begin + for I in Foreign_Arr'Range loop + if Foreign_Arr(I).Name.all = Name then + return Foreign_Arr(I).Addr; + end if; + end loop; + return Null_Address; + end Find_Foreign; +end Foreigns; diff --git a/translate/ghdldrv/foreigns.ads b/translate/ghdldrv/foreigns.ads new file mode 100644 index 0000000..5759ae4 --- /dev/null +++ b/translate/ghdldrv/foreigns.ads @@ -0,0 +1,5 @@ +with System; use System; + +package Foreigns is + function Find_Foreign (Name : String) return Address; +end Foreigns; diff --git a/translate/ghdldrv/ghdlrun.adb b/translate/ghdldrv/ghdlrun.adb index 1d70c14..b08ac82 100644 --- a/translate/ghdldrv/ghdlrun.adb +++ b/translate/ghdldrv/ghdlrun.adb @@ -47,6 +47,7 @@ with Trans_Be; with Translation; with Std_Names; with Ieee.Std_Logic_1164; +with Interfaces.C; with Binary_File.Elf; @@ -70,9 +71,14 @@ with Grt.Values; with Grt.Names; with Ghdlcomp; +with Foreigns; package body Ghdlrun is - Snap_Filename : String_Access := null; + Snap_Filename : GNAT.OS_Lib.String_Access := null; + + procedure Foreign_Hook (Decl : Iir; + Info : Translation.Foreign_Info_Type; + Ortho : O_Dnode); procedure Compile_Init (Analyze_Only : Boolean) is begin @@ -82,6 +88,8 @@ package body Ghdlrun is return; end if; + Translation.Foreign_Hook := Foreign_Hook'Access; + -- Initialize. Back_End.Finish_Compilation := Trans_Be.Finish_Compilation'Access; @@ -92,6 +100,7 @@ package body Ghdlrun is Libraries.Load_Std_Library; Ortho_Mcode.Init; + Binary_File.Memory.Write_Memory_Init; Translation.Initialize; Canon.Canon_Flag_Add_Labels := True; @@ -237,6 +246,34 @@ package body Ghdlrun is return Conv (Get_Symbol_Vaddr (Get_Decl_Symbol (Decl))); end Get_Address; + procedure Foreign_Hook (Decl : Iir; + Info : Translation.Foreign_Info_Type; + Ortho : O_Dnode) + is + use Translation; + Res : Address; + begin + case Info.Kind is + when Foreign_Vhpidirect => + declare + Name : String := Name_Table.Name_Buffer (Info.Subprg_First + .. Info.Subprg_Last); + begin + Res := Foreigns.Find_Foreign (Name); + if Res /= Null_Address then + Def (Ortho, Res); + else + Error_Msg_Sem ("unknown foreign VHPIDIRECT '" & Name & "'", + Decl); + end if; + end; + when Foreign_Intrinsic => + null; + when Foreign_Unknown => + null; + end case; + end Foreign_Hook; + procedure Run is use Binary_File; @@ -257,8 +294,6 @@ package body Ghdlrun is raise Compile_Error; end if; - Binary_File.Memory.Write_Memory_Init; - Ortho_Code.Abi.Link_Intrinsics; Def (Trans_Decls.Ghdl_Memcpy, @@ -467,17 +502,6 @@ package body Ghdlrun is Grt.Rtis.Ghdl_Rti_Top_Instance'Address); Def (Trans_Decls.Ghdl_Rti_Top_Ptr, Grt.Rtis.Ghdl_Rti_Top_Ptr'Address); - Std_Standard_Boolean_RTI_Ptr := - Get_Address (Trans_Decls.Std_Standard_Boolean_Rti); - Std_Standard_Bit_RTI_Ptr := - Get_Address (Trans_Decls.Std_Standard_Bit_Rti); - if Ieee.Std_Logic_1164.Resolved /= Null_Iir then - Decl := Translation.Get_Resolv_Ortho_Decl - (Ieee.Std_Logic_1164.Resolved); - if Decl /= O_Dnode_Null then - Ieee_Std_Logic_1164_Resolved_Resolv_Ptr := Get_Address (Decl); - end if; - end if; Def (Trans_Decls.Ghdl_Protected_Enter, Grt.Processes.Ghdl_Protected_Enter'Address); @@ -555,6 +579,18 @@ package body Ghdlrun is raise Compile_Error; end if; + Std_Standard_Boolean_RTI_Ptr := + Get_Address (Trans_Decls.Std_Standard_Boolean_Rti); + Std_Standard_Bit_RTI_Ptr := + Get_Address (Trans_Decls.Std_Standard_Bit_Rti); + if Ieee.Std_Logic_1164.Resolved /= Null_Iir then + Decl := Translation.Get_Resolv_Ortho_Decl + (Ieee.Std_Logic_1164.Resolved); + if Decl /= O_Dnode_Null then + Ieee_Std_Logic_1164_Resolved_Resolv_Ptr := Get_Address (Decl); + end if; + end if; + Flag_String := Flags.Flag_String; Elaborate_Proc := Conv (Get_Address (Trans_Decls.Ghdl_Elaborate)); diff --git a/translate/grt/Makefile.inc b/translate/grt/Makefile.inc index 584ed55..2d9d60e 100644 --- a/translate/grt/Makefile.inc +++ b/translate/grt/Makefile.inc @@ -52,6 +52,11 @@ ifeq ($(filter-out x86_64 linux,$(arch) $(osys)),) GRT_TARGET_OBJS=amd64.o linux.o times.o GRT_EXTRA_LIB=-ldl -lm $(GRT_ELF_OPTS) endif +ifeq ($(filter-out i%86 freebsd%,$(arch) $(osys)),) + GRT_TARGET_OBJS=i386.o linux.o times.o + GRT_EXTRA_LIB=-lm $(GRT_ELF_OPTS) + ADAC=gnatgcc +endif ifeq ($(filter-out sparc solaris%,$(arch) $(osys)),) GRT_TARGET_OBJS=sparc.o linux.o times.o GRT_EXTRA_LIB=-ldl -lm diff --git a/translate/grt/grt-avhpi.adb b/translate/grt/grt-avhpi.adb index 7c8b10f..4b4086f 100644 --- a/translate/grt/grt-avhpi.adb +++ b/translate/grt/grt-avhpi.adb @@ -330,7 +330,7 @@ package body Grt.Avhpi is end; when Ghdl_Rtik_Type_B2 | Ghdl_Rtik_Type_E8 - | Ghdl_Rtik_Type_E32 => + | Ghdl_Rtik_Type_E32 => Res := (Kind => VhpiEnumTypeDeclK, Ctxt => Ctxt, Atype => Rti); diff --git a/translate/grt/grt-rtis_addr.adb b/translate/grt/grt-rtis_addr.adb index 64273b3..84d7c3a 100644 --- a/translate/grt/grt-rtis_addr.adb +++ b/translate/grt/grt-rtis_addr.adb @@ -253,7 +253,7 @@ package body Grt.Rtis_Addr is return To_Ghdl_Rti_Access (To_Ghdl_Rtin_Subtype_Array_Acc (Atype).Basetype); when Ghdl_Rtik_Type_E8 - | Ghdl_Rtik_Type_E32 + | Ghdl_Rtik_Type_E32 | Ghdl_Rtik_Type_B2 => return Atype; when others => diff --git a/translate/grt/grt-signals.ads b/translate/grt/grt-signals.ads index 500cd55..69cee8c 100644 --- a/translate/grt/grt-signals.ads +++ b/translate/grt/grt-signals.ads @@ -382,6 +382,10 @@ package Grt.Signals is -- Update signals. procedure Update_Signals; + -- Set the effective value of signal SIG to VAL. + -- If the value is different from the previous one, resume processes. + procedure Set_Effective_Value (Sig : Ghdl_Signal_Ptr; Val : Value_Union); + -- Add PROC in the list of processes to be resumed in case of event on -- SIG. procedure Resume_Process_If_Event diff --git a/translate/grt/grt-vpi.adb b/translate/grt/grt-vpi.adb index f811306..f2c30b6 100644 --- a/translate/grt/grt-vpi.adb +++ b/translate/grt/grt-vpi.adb @@ -507,6 +507,189 @@ package body Grt.Vpi is end vpi_get_value; ------------------------------------------------------------------------ + -- void vpiHandle vpi_put_value(vpiHandle obj, p_vpi_value value, + -- p_vpi_time when, int flags) + -- Alter the simulation value of an object. + -- see IEEE 1364-2001, chapter 27.14, page 675 + -- FIXME + + procedure ii_vpi_put_value_bin_str_B2 (SigPtr : Ghdl_Signal_Ptr; + Value : Character) + is + Tempval : Value_Union; + begin + -- use the Set_Effective_Value procedure to update the signal + case Value is + when '0' => + Tempval.B2 := false; + when '1' => + Tempval.B2 := true; + when others => + dbgPut_Line("ii_vpi_put_value_bin_str_B2: " + & "wrong character - signal wont be set"); + return; + end case; + SigPtr.Driving_Value := Tempval; + Set_Effective_Value (SigPtr, Tempval); + end ii_vpi_put_value_bin_str_B2; + + procedure ii_vpi_put_value_bin_str_E8 (SigPtr : Ghdl_Signal_Ptr; + Value : Character) + is + Tempval : Value_Union; + begin + case Value is + when 'U' => + Tempval.E8 := 0; + when 'X' => + Tempval.E8 := 1; + when '0' => + Tempval.E8 := 2; + when '1' => + Tempval.E8 := 3; + when 'Z' => + Tempval.E8 := 4; + when 'W' => + Tempval.E8 := 5; + when 'L' => + Tempval.E8 := 6; + when 'H' => + Tempval.E8 := 7; + when '-' => + Tempval.E8 := 8; + when others => + dbgPut_Line("ii_vpi_put_value_bin_str_B8: " + & "wrong character - signal wont be set"); + return; + end case; + SigPtr.Driving_Value := Tempval; + Set_Effective_Value (SigPtr, Tempval); + end ii_vpi_put_value_bin_str_E8; + + + procedure ii_vpi_put_value_bin_str(Obj : VhpiHandleT; + ValueStr : Ghdl_C_String) + is + Info : Verilog_Wire_Info; + Len : Ghdl_Index_Type; + begin + -- Check the Obj type. + -- * The vpiHandle has a reference (field Ref) to a VhpiHandleT + -- when it doesnt come from a callback. + case Vhpi_Get_Kind(Obj) is + when VhpiPortDeclK + | VhpiSigDeclK => + null; + when others => + return; + end case; + + -- The following code segment was copied from the + -- ii_vpi_get_value function. + -- Get verilog compat info. + Get_Verilog_Wire (Obj, Info); + if Info.Kind = Vcd_Bad then + return; + end if; + + if Info.Irange = null then + Len := 1; + else + Len := Info.Irange.I32.Len; + end if; + + -- Step 1: convert vpi object to internal format. + -- p_vpi_handle -> Ghdl_Signal_Ptr + -- To_Signal_Arr_Ptr (Info.Addr) does part of the magic + + -- Step 2: convert datum to appropriate type. + -- Ghdl_C_String -> Value_Union + + -- Step 3: assigns value to object using Set_Effective_Value + -- call (from grt-signals) + -- Set_Effective_Value(sig_ptr, conv_value); + + + -- Took the skeleton from ii_vpi_get_value function + -- This point of the function must convert the string value to the + -- native ghdl format. + case Info.Kind is + when Vcd_Bad => + return; + when Vcd_Bit + | Vcd_Bool + | Vcd_Bitvector => + for J in 0 .. Len - 1 loop + ii_vpi_put_value_bin_str_B2( + To_Signal_Arr_Ptr(Info.Addr)(J), ValueStr(Integer(J+1))); + end loop; + when Vcd_Stdlogic + | Vcd_Stdlogic_Vector => + for J in 0 .. Len - 1 loop + ii_vpi_put_value_bin_str_E8( + To_Signal_Arr_Ptr(Info.Addr)(J), ValueStr(Integer(J+1))); + end loop; + when Vcd_Integer32 => + null; + end case; + + -- Always return null, because this simulation kernel cannot send + -- a handle to the event back. + return; + end ii_vpi_put_value_bin_str; + + + -- vpiHandle vpi_put_value(vpiHandle obj, p_vpi_value value, + -- p_vpi_time when, int flags) + function vpi_put_value (aObj: vpiHandle; + aValue: p_vpi_value; + aWhen: p_vpi_time; + aFlags: integer) + return vpiHandle + is + pragma Unreferenced (aWhen); + pragma Unreferenced (aFlags); + begin + -- A very simple write procedure for VPI. + -- Basically, it accepts bin_str values and converts to appropriate + -- types (only std_logic and bit values and vectors). + + -- It'll use Set_Effective_Value procedure to update signals + + -- Ignoring aWhen and aFlags, for now. + + -- Checks the format of aValue. Only vpiBinStrVal will be accepted + -- for now. + case aValue.Format is + when vpiObjTypeVal=> + dbgPut_Line ("vpi_put_value: vpiObjTypeVal"); + when vpiBinStrVal=> + ii_vpi_put_value_bin_str(aObj.Ref, aValue.Str); + dbgPut_Line ("vpi_put_value: vpiBinStrVal"); + when vpiOctStrVal=> + dbgPut_Line ("vpi_put_value: vpiNet, vpiOctStrVal"); + when vpiDecStrVal=> + dbgPut_Line ("vpi_put_value: vpiNet, vpiDecStrVal"); + when vpiHexStrVal=> + dbgPut_Line ("vpi_put_value: vpiNet, vpiHexStrVal"); + when vpiScalarVal=> + dbgPut_Line ("vpi_put_value: vpiNet, vpiScalarVal"); + when vpiIntVal=> + dbgPut_Line ("vpi_put_value: vpiIntVal"); + when vpiRealVal=> dbgPut_Line("vpi_put_value: vpiRealVal"); + when vpiStringVal=> dbgPut_Line("vpi_put_value: vpiStringVal"); + when vpiTimeVal=> dbgPut_Line("vpi_put_value: vpiTimeVal"); + when vpiVectorVal=> dbgPut_Line("vpi_put_value: vpiVectorVal"); + when vpiStrengthVal=> dbgPut_Line("vpi_put_value: vpiStrengthVal"); + when others=> dbgPut_Line("vpi_put_value: unknown mFormat"); + end case; + + -- Must return a scheduled event caused by vpi_put_value() + -- Still dont know how to do it. + return null; + end vpi_put_value; + + ------------------------------------------------------------------------ -- void vpi_get_time(vpiHandle obj, s_vpi_time*t); -- see IEEE 1364-2001, page xxx Sim_Time : Std_Time; @@ -631,22 +814,6 @@ package body Grt.Vpi is return 0; end vpi_mcd_open; - -- vpiHandle vpi_put_value(vpiHandle obj, p_vpi_value value, - -- p_vpi_time when, int flags) - function vpi_put_value (aObj: vpiHandle; - aValue: p_vpi_value; - aWhen: p_vpi_time; - aFlags: integer) - return vpiHandle - is - pragma Unreferenced (aObj); - pragma Unreferenced (aValue); - pragma Unreferenced (aWhen); - pragma Unreferenced (aFlags); - begin - return null; - end vpi_put_value; - -- void vpi_register_systf(const struct t_vpi_systf_data*ss) procedure vpi_register_systf(aSs: System.Address) is diff --git a/translate/trans_be.adb b/translate/trans_be.adb index 60d886c..4058217 100644 --- a/translate/trans_be.adb +++ b/translate/trans_be.adb @@ -144,6 +144,6 @@ package body Trans_Be is Error_Kind ("sem_foreign", Decl); end case; -- Let is generate error messages. - Fi := Translate_Foreign_Id (Decl, False); + Fi := Translate_Foreign_Id (Decl); end Sem_Foreign; end Trans_Be; diff --git a/translate/translation.adb b/translate/translation.adb index ff38401..37a1074 100644 --- a/translate/translation.adb +++ b/translate/translation.adb @@ -2897,15 +2897,13 @@ package body Translation is end if; end Create_Temp; - function Translate_Foreign_Id (Decl : Iir; Extract_Name : Boolean) - return Foreign_Info_Type + function Translate_Foreign_Id (Decl : Iir) return Foreign_Info_Type is use Name_Table; Attr : Iir_Attribute_Value; Spec : Iir_Attribute_Specification; Attr_Decl : Iir; Expr : Iir; - P : Natural; begin -- Look for 'FOREIGN. Attr := Get_Attribute_Value_Chain (Decl); @@ -2972,27 +2970,60 @@ package body Translation is if Name_Length >= 10 and then Name_Buffer (1 .. 10) = "VHPIDIRECT" then - P := 11; + declare + P : Natural; + Sf, Sl : Natural; + Lf, Ll : Natural; + begin + P := 11; - -- Skip spaces. - while P <= Name_Length and then Name_Buffer (P) = ' ' loop + -- Skip spaces. + while P <= Name_Length and then Name_Buffer (P) = ' ' loop + P := P + 1; + end loop; + if P > Name_Length then + Error_Msg_Sem + ("missing subprogram/library name after VHPIDIRECT", Spec); + end if; + -- Extract library. + Lf := P; + while P < Name_Length and then Name_Buffer (P) /= ' ' loop + P := P + 1; + end loop; + Ll := P; + -- Extract subprogram. P := P + 1; - end loop; - if Extract_Name then + while P <= Name_Length and then Name_Buffer (P) = ' ' loop + P := P + 1; + end loop; + Sf := P; + while P < Name_Length and then Name_Buffer (P) /= ' ' loop + P := P + 1; + end loop; + Sl := P; + if P < Name_Length then + Error_Msg_Sem ("garbage at end of VHPIDIRECT", Spec); + end if; + + -- Accept empty library. + if Sf > Name_Length then + Sf := Lf; + Sl := Ll; + Lf := 0; + Ll := 0; + end if; + return Foreign_Info_Type' (Kind => Foreign_Vhpidirect, - Subprg => Get_Identifier (Name_Buffer (P .. Name_Length)), - Lib => Null_Identifier); - else - return Foreign_Info_Type'(Kind => Foreign_Vhpidirect, - Subprg => O_Ident_Nul, - Lib => Null_Identifier); - end if; + Lib_First => Lf, + Lib_Last => Ll, + Subprg_First => Sf, + Subprg_Last => Sl); + end; elsif Name_Length = 14 and then Name_Buffer (1 .. 14) = "GHDL intrinsic" then - return Foreign_Info_Type'(Kind => Foreign_Intrinsic, - Subprg => Create_Identifier); + return Foreign_Info_Type'(Kind => Foreign_Intrinsic); else Error_Msg_Sem ("value of 'FOREIGN attribute does not begin with VHPIDIRECT", @@ -4640,6 +4671,7 @@ package body Translation is Rtype : Iir; Id : O_Ident; Storage : O_Storage; + Foreign : Foreign_Info_Type := Foreign_Bad; begin Info := Get_Info (Spec); Info.Res_Interface := O_Dnode_Null; @@ -4650,20 +4682,18 @@ package body Translation is Push_Subprg_Identifier (Spec, Mark); if Get_Foreign_Flag (Spec) then - declare - Fi : Foreign_Info_Type; - begin - Fi := Translate_Foreign_Id (Spec, True); - case Fi.Kind is - when Foreign_Unknown => - Id := Create_Identifier; - when Foreign_Intrinsic => - Id := Fi.Subprg; - when Foreign_Vhpidirect => - Id := Fi.Subprg; - end case; - Storage := O_Storage_External; - end; + Foreign := Translate_Foreign_Id (Spec); + case Foreign.Kind is + when Foreign_Unknown => + Id := Create_Identifier; + when Foreign_Intrinsic => + Id := Create_Identifier; + when Foreign_Vhpidirect => + Id := Get_Identifier + (Name_Table.Name_Buffer (Foreign.Subprg_First + .. Foreign.Subprg_Last)); + end case; + Storage := O_Storage_External; else Id := Create_Identifier; Storage := Global_Storage; @@ -4778,6 +4808,10 @@ package body Translation is end loop; Finish_Subprogram_Decl (Interface_List, Info.Ortho_Func); + if Get_Foreign_Flag (Spec) and then Foreign_Hook /= null then + Foreign_Hook.all (Spec, Foreign, Info.Ortho_Func); + end if; + Save_Local_Identifier (Info.Subprg_Local_Id); Pop_Identifier_Prefix (Mark); end Translate_Subprogram_Declaration; @@ -4804,7 +4838,7 @@ package body Translation is Old_Subprogram : Iir; Mark : Id_Mark_Type; Final : Boolean; - Is_Func : Boolean; + Is_Ortho_Func : Boolean; -- Set for a public method. In this case, the lock must be acquired -- and retained. @@ -4877,8 +4911,8 @@ package body Translation is Chap3.Call_Ghdl_Protected_Procedure (Get_Method_Type (Spec), Ghdl_Protected_Enter); end if; - Is_Func := Is_Subprogram_Ortho_Function (Spec); - if Is_Func then + Is_Ortho_Func := Is_Subprogram_Ortho_Function (Spec); + if Is_Ortho_Func then New_Var_Decl (Info.Subprg_Result, Get_Identifier ("RESULT"), O_Storage_Local, @@ -4906,7 +4940,7 @@ package body Translation is Chap3.Call_Ghdl_Protected_Procedure (Get_Method_Type (Spec), Ghdl_Protected_Leave); end if; - if Is_Func then + if Is_Ortho_Func then New_Return_Stmt (New_Obj_Value (Info.Subprg_Result)); end if; end if; @@ -13218,6 +13252,7 @@ package body Translation is Res : O_Cnode; begin Lit_Type := Get_Type (Str); + Chap3.Translate_Anonymous_Type_Definition (Lit_Type, True); Start_Array_Aggr (List, Get_Ortho_Type (Lit_Type, Mode_Value)); @@ -13230,6 +13265,86 @@ package body Translation is return Res; end Translate_Static_String_Literal; + -- Some strings literal have an unconstrained array type, + -- eg: 'image of constant. Its type is not constrained + -- because it is not so in VHDL! + function Translate_Static_Unconstrained_String_Literal (Str : Iir) + return O_Cnode + is + use Name_Table; + + Lit_Type : Iir; + Element_Type : Iir; + Index_Type : Iir; + Val_Aggr : O_Array_Aggr_List; + Bound_Aggr : O_Record_Aggr_List; + Index_Aggr : O_Record_Aggr_List; + Res_Aggr : O_Record_Aggr_List; + Res : O_Cnode; + Str_Type : O_Tnode; + Type_Info : Type_Info_Acc; + Index_Type_Info : Type_Info_Acc; + Len : Int32; + Val : Var_Acc; + Bound : Var_Acc; + begin + Lit_Type := Get_Type (Str); + Type_Info := Get_Info (Get_Base_Type (Lit_Type)); + + -- Create the string value. + Len := Get_String_Length (Str); + Str_Type := New_Constrained_Array_Type + (Type_Info.T.Base_Type (Mode_Value), + New_Unsigned_Literal (Ghdl_Index_Type, Unsigned_64 (Len))); + + Start_Array_Aggr (Val_Aggr, Str_Type); + Element_Type := Get_Element_Subtype (Lit_Type); + Translate_Static_String_Literal_Inner (Val_Aggr, Str, Element_Type); + Finish_Array_Aggr (Val_Aggr, Res); + + Val := Create_Global_Const + (Create_Uniq_Identifier, Str_Type, O_Storage_Private, Res); + + -- Create the string bound. + Index_Type := Get_First_Element (Get_Index_Subtype_List (Lit_Type)); + Index_Type_Info := Get_Info (Index_Type); + Start_Record_Aggr (Bound_Aggr, Type_Info.T.Bounds_Type); + Start_Record_Aggr (Index_Aggr, Index_Type_Info.T.Range_Type); + New_Record_Aggr_El + (Index_Aggr, + New_Signed_Literal (Index_Type_Info.Ortho_Type (Mode_Value), 0)); + New_Record_Aggr_El + (Index_Aggr, + New_Signed_Literal (Index_Type_Info.Ortho_Type (Mode_Value), + Integer_64 (Len - 1))); + New_Record_Aggr_El + (Index_Aggr, Ghdl_Dir_To_Node); + New_Record_Aggr_El + (Index_Aggr, + New_Unsigned_Literal (Ghdl_Index_Type, Unsigned_64 (Len))); + Finish_Record_Aggr (Index_Aggr, Res); + New_Record_Aggr_El (Bound_Aggr, Res); + Finish_Record_Aggr (Bound_Aggr, Res); + Bound := Create_Global_Const + (Create_Uniq_Identifier, Type_Info.T.Bounds_Type, + O_Storage_Private, Res); + + -- The descriptor. + Start_Record_Aggr (Res_Aggr, Type_Info.Ortho_Type (Mode_Value)); + New_Record_Aggr_El + (Res_Aggr, + New_Global_Address (Get_Var_Label (Val), + Type_Info.T.Base_Ptr_Type (Mode_Value))); + New_Record_Aggr_El + (Res_Aggr, + New_Global_Address (Get_Var_Label (Bound), + Type_Info.T.Bounds_Ptr_Type)); + Finish_Record_Aggr (Res_Aggr, Res); + Free_Var (Val); + Free_Var (Bound); + return Res; + end Translate_Static_Unconstrained_String_Literal; + -- Only for Strings of STD.Character. function Translate_Static_String (Str_Type : Iir; Str_Ident : Name_Id) return O_Cnode @@ -13284,7 +13399,13 @@ package body Translation is begin case Get_Kind (Str) is when Iir_Kind_String_Literal => - Res := Translate_Static_String_Literal (Str); + if Get_Kind (Get_Type (Str)) + = Iir_Kind_Array_Subtype_Definition + then + Res := Translate_Static_String_Literal (Str); + else + Res := Translate_Static_Unconstrained_String_Literal (Str); + end if; when Iir_Kind_Bit_String_Literal => Res := Translate_Static_Bit_String_Literal (Str); when Iir_Kind_Simple_Aggregate => @@ -25325,9 +25446,22 @@ package body Translation is when Iir_Kind_Type_Declaration | Iir_Kind_Subtype_Declaration => Add_Rti_Node (Generate_Type_Decl (Decl)); + when Iir_Kind_Constant_Declaration => + -- Do not generate RTIs for full declarations. + -- (RTI will be generated for the deferred declaration). + if Get_Deferred_Declaration (Decl) = Null_Iir + or else Get_Deferred_Declaration_Flag (Decl) + then + declare + Info : Object_Info_Acc; + begin + Info := Get_Info (Decl); + Generate_Object (Decl, Info.Object_Rti); + Add_Rti_Node (Info.Object_Rti); + end; + end if; when Iir_Kind_Signal_Declaration | Iir_Kind_Signal_Interface_Declaration - | Iir_Kind_Constant_Declaration | Iir_Kind_Constant_Interface_Declaration | Iir_Kind_Variable_Declaration | Iir_Kind_File_Declaration diff --git a/translate/translation.ads b/translate/translation.ads index 2b885a8..55af069 100644 --- a/translate/translation.ads +++ b/translate/translation.ads @@ -17,8 +17,6 @@ -- 02111-1307, USA. with Iirs; use Iirs; with Ortho_Nodes; -with Ortho_Ident; use Ortho_Ident; -with Types; use Types; package Translation is -- Initialize the package: create internal nodes. @@ -69,20 +67,21 @@ package Translation is type Foreign_Info_Type (Kind : Foreign_Kind_Type := Foreign_Unknown) is record - Subprg : O_Ident; - case Kind is when Foreign_Unknown => null; when Foreign_Vhpidirect => - Lib : Name_Id; + -- Positions in name_table.name_buffer. + Lib_First : Natural; + Lib_Last : Natural; + Subprg_First : Natural; + Subprg_Last : Natural; when Foreign_Intrinsic => null; end case; end record; - Foreign_Bad : constant Foreign_Info_Type := (Kind => Foreign_Unknown, - Subprg => O_Ident_Nul); + Foreign_Bad : constant Foreign_Info_Type := (Kind => Foreign_Unknown); -- Return a foreign_info for DECL. -- Can generate error messages, if the attribute expression is ill-formed. @@ -90,7 +89,12 @@ package Translation is -- Otherwise, only KIND discriminent is set. -- EXTRACT_NAME should be set only inside translation itself, since the -- name can be based on the prefix. - function Translate_Foreign_Id (Decl : Iir; Extract_Name : Boolean) - return Foreign_Info_Type; - + function Translate_Foreign_Id (Decl : Iir) return Foreign_Info_Type; + + -- If not null, this procedure is called when a foreign subprogram is + -- created. + type Foreign_Hook_Access is access procedure (Decl : Iir; + Info : Foreign_Info_Type; + Ortho : Ortho_Nodes.O_Dnode); + Foreign_Hook : Foreign_Hook_Access := null; end Translation; |