summaryrefslogtreecommitdiff
path: root/translate
diff options
context:
space:
mode:
Diffstat (limited to 'translate')
-rw-r--r--translate/ghdldrv/foreigns.adb64
-rw-r--r--translate/ghdldrv/foreigns.ads5
-rw-r--r--translate/ghdldrv/ghdlrun.adb64
-rw-r--r--translate/grt/Makefile.inc5
-rw-r--r--translate/grt/grt-avhpi.adb2
-rw-r--r--translate/grt/grt-rtis_addr.adb2
-rw-r--r--translate/grt/grt-signals.ads4
-rw-r--r--translate/grt/grt-vpi.adb199
-rw-r--r--translate/trans_be.adb2
-rw-r--r--translate/translation.adb208
-rw-r--r--translate/translation.ads24
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;