diff options
Diffstat (limited to 'src/vhdl/translate/trans-chap8.adb')
-rw-r--r-- | src/vhdl/translate/trans-chap8.adb | 551 |
1 files changed, 367 insertions, 184 deletions
diff --git a/src/vhdl/translate/trans-chap8.adb b/src/vhdl/translate/trans-chap8.adb index 6fd794deb..9bedbf369 100644 --- a/src/vhdl/translate/trans-chap8.adb +++ b/src/vhdl/translate/trans-chap8.adb @@ -950,7 +950,7 @@ package body Trans.Chap8 is declare Targ_Node : Mnode; begin - Targ_Node := Chap6.Translate_Name (Targ); + Targ_Node := Chap6.Translate_Name (Targ, Mode_Value); Chap3.Translate_Object_Copy (Targ_Node, M2E (Val), Targ_Type); end; end if; @@ -982,7 +982,7 @@ package body Trans.Chap8 is return; end; else - Targ_Node := Chap6.Translate_Name (Target); + Targ_Node := Chap6.Translate_Name (Target, Mode_Value); if Get_Kind (Expr) = Iir_Kind_Aggregate then declare E : O_Enode; @@ -1881,7 +1881,8 @@ package body Trans.Chap8 is New_Association (Assocs, Chap7.Translate_Expression (Get_Actual (F_Assoc))); -- value - Value := Chap6.Translate_Name (Get_Actual (Value_Assoc)); + Value := + Chap6.Translate_Name (Get_Actual (Value_Assoc), Mode_Value); New_Association (Assocs, New_Convert_Ov (M2Addr (Value), Ghdl_Ptr_Type)); -- length. @@ -1920,7 +1921,8 @@ package body Trans.Chap8 is (Assocs, Chap7.Translate_Expression (Get_Actual (Value_Assoc), Formal_Type)); - Length := Chap6.Translate_Name (Get_Actual (Length_Assoc)); + Length := + Chap6.Translate_Name (Get_Actual (Length_Assoc), Mode_Value); New_Assign_Stmt (M2Lv (Length), New_Function_Call (Assocs)); end; when Type_Mode_Unknown @@ -1984,7 +1986,8 @@ package body Trans.Chap8 is Str := Chap7.Translate_Expression (Get_Actual (N_Param), String_Type_Definition); N_Param := Get_Chain (N_Param); - Res := Chap6.Translate_Name (Get_Actual (N_Param)); + Res := + Chap6.Translate_Name (Get_Actual (N_Param), Mode_Value); Start_Association (Assocs, Ghdl_Text_Read_Length); -- compute file parameter (get an index) New_Association @@ -2049,7 +2052,7 @@ package body Trans.Chap8 is Constr : O_Assoc_List; Status : Mnode; begin - Status := Chap6.Translate_Name (Status_Param); + Status := Chap6.Translate_Name (Status_Param, Mode_Value); N_Param := Get_Chain (Param_Chain); File_Param := Get_Actual (N_Param); N_Param := Get_Chain (N_Param); @@ -2147,13 +2150,13 @@ package body Trans.Chap8 is Call_Assoc_Info : Call_Assoc_Info_Acc; Actual : Iir; Act_Type : Iir; - Atype_Info : Type_Info_Acc; Has_Bounds_Field : Boolean; Has_Fat_Pointer_Field : Boolean; Has_Value_Field : Boolean; Has_Ref_Field : Boolean; Object_Kind : Object_Kind_Type; Val_Type : O_Tnode; + Vident : Var_Ident_Type; -- For unconstrained interfaces: -- * create a field for the fat pointer, unless @@ -2288,7 +2291,7 @@ package body Trans.Chap8 is end case; -- For out or inout scalar variable, create a field for the - -- value. + -- actual value. if Actual /= Null_Iir and then (Get_Kind (Inter) = Iir_Kind_Interface_Variable_Declaration) @@ -2324,44 +2327,88 @@ package body Trans.Chap8 is -- Reference to the actual. Therefore the type of the -- actual must be used (due to a possible conversion or -- function call). - Atype_Info := Get_Info (Act_Type); - Call_Assoc_Info.Call_Assoc_Ref := Create_Var - (Create_Var_Identifier (Inter, "__REF", Num), - Atype_Info.Ortho_Ptr_Type (Object_Kind), - O_Storage_Local); + pragma Assert (Object_Kind = Mode_Value); + declare + Atype_Info : constant Type_Info_Acc := + Get_Info (Act_Type); + Atype_Binfo : Type_Info_Acc; + Ref_Type : O_Tnode; + begin + if Atype_Info /= null then + Ref_Type := Atype_Info.Ortho_Ptr_Type (Object_Kind); + else + -- Type of actual was not yet translated. Possible + -- only for slice. Do it manually. + Atype_Binfo := Get_Info (Get_Base_Type (Act_Type)); + Ref_Type := Atype_Binfo.T.Base_Ptr_Type (Object_Kind); + end if; + Call_Assoc_Info.Call_Assoc_Ref := Create_Var + (Create_Var_Identifier (Inter, "__REF", Num), + Ref_Type, O_Storage_Local); + end; end if; + if Has_Value_Field then - if Ftype_Info.Type_Mode = Type_Mode_Fat_Array then - -- For unconstrained arrays/records: - -- - the array (if the actual is constrained and not - -- complex) - TODO - -- - a pointer to the base. - Val_Type := Ftype_Info.T.Base_Ptr_Type (Object_Kind); - else - -- For constrained arrays/records: - -- - the base if not complex - -- - a pointer to the base, if complex - if Is_Complex_Type (Ftype_Info) then - Val_Type := Ftype_Info.Ortho_Ptr_Type (Object_Kind); + for Mode in Mode_Value .. Object_Kind loop + if Ftype_Info.Type_Mode = Type_Mode_Fat_Array then + -- For unconstrained arrays/records: + -- - the array (if the actual is constrained and not + -- complex) - TODO + -- - a pointer to the base. + Val_Type := Ftype_Info.T.Base_Ptr_Type (Mode); else - Val_Type := Ftype_Info.Ortho_Type (Object_Kind); + -- For constrained arrays/records: + -- - the base if not complex + -- - a pointer to the base, if complex + if Is_Complex_Type (Ftype_Info) then + Val_Type := Ftype_Info.Ortho_Ptr_Type (Mode); + else + Val_Type := Ftype_Info.Ortho_Type (Mode); + end if; end if; - end if; - Call_Assoc_Info.Call_Assoc_Value := Create_Var - (Create_Var_Identifier (Inter, "__VAL", Num), - Val_Type, O_Storage_Local); + case Mode is + when Mode_Value => + Vident := + Create_Var_Identifier (Inter, "__VAL", Num); + when Mode_Signal => + Vident := + Create_Var_Identifier (Inter, "__SIG", Num); + end case; + Call_Assoc_Info.Call_Assoc_Value (Mode) := Create_Var + (Vident, Val_Type, O_Storage_Local); + end loop; end if; + if Has_Bounds_Field then Call_Assoc_Info.Call_Assoc_Bounds := Create_Var (Create_Var_Identifier (Inter, "__BND", Num), Ftype_Info.T.Bounds_Type, O_Storage_Local); end if; + if Has_Fat_Pointer_Field then - Call_Assoc_Info.Call_Assoc_Fat := Create_Var - (Create_Var_Identifier (Inter, "__FAT", Num), - Ftype_Info.Ortho_Type (Object_Kind)); + Call_Assoc_Info.Call_Assoc_Fat (Mode_Value) := Create_Var + (Create_Var_Identifier (Inter, "__FATV", Num), + Ftype_Info.Ortho_Type (Mode_Value)); + if Object_Kind = Mode_Signal then + Call_Assoc_Info.Call_Assoc_Fat (Mode_Signal) := Create_Var + (Create_Var_Identifier (Inter, "__FATS", Num), + Ftype_Info.Ortho_Type (Mode_Signal)); + end if; end if; Num := Num + 1; + + elsif Formal /= Inter + and then + Get_Kind (Inter) = Iir_Kind_Interface_Signal_Declaration + then + -- The whole signal value is composed of parts and must be + -- updated when it changes (at each cycle is a worst case + -- approximation). Keep pointer to the individual value. + Call_Assoc_Info := Add_Info (Assoc, Kind_Call_Assoc); + Call_Assoc_Info.Call_Assoc_Value (Mode_Value) := Create_Var + (Create_Var_Identifier (Inter, "__VALP", Num), + Ftype_Info.Ortho_Ptr_Type (Mode_Value)); + Num := Num + 1; end if; end; Assoc := Get_Chain (Assoc); @@ -2438,26 +2485,27 @@ package body Trans.Chap8 is function Translate_Individual_Association_Formal (Formal_Name : Iir; Formal_Info : Ortho_Info_Acc; - Inter_Var : Mnode) + Inter_Var : Mnode; + Mode : Object_Kind_Type) return Mnode is - Prev_Node : O_Dnode; + Prev_Decl : O_Dnode; Prev_Field : O_Fnode; Res : Mnode; begin -- Change the formal variable so that it is the local variable -- that will be passed to the subprogram. - Prev_Node := Formal_Info.Interface_Node; - Prev_Field := Formal_Info.Interface_Field; + Prev_Decl := Formal_Info.Interface_Decl (Mode); + Prev_Field := Formal_Info.Interface_Field (Mode); -- We need a pointer since the interface is by reference. - Formal_Info.Interface_Node := M2Dp (Inter_Var); - Formal_Info.Interface_Field := O_Fnode_Null; + Formal_Info.Interface_Decl (Mode) := M2Dp (Inter_Var); + Formal_Info.Interface_Field (Mode) := O_Fnode_Null; - Res := Chap6.Translate_Name (Formal_Name); + Res := Chap6.Translate_Name (Formal_Name, Mode); - Formal_Info.Interface_Node := Prev_Node; - Formal_Info.Interface_Field := Prev_Field; + Formal_Info.Interface_Decl (Mode) := Prev_Decl; + Formal_Info.Interface_Field (Mode) := Prev_Field; return Res; end Translate_Individual_Association_Formal; @@ -2494,6 +2542,7 @@ package body Trans.Chap8 is -- The values of actuals. E_Params : O_Enode_Array (0 .. Nbr_Assoc - 1); + E_Sig_Params : O_Enode_Array (0 .. Nbr_Assoc - 1); -- Only for inout/out variables passed by copy of foreign procedures: -- the copy of the scalar. @@ -2568,6 +2617,7 @@ package body Trans.Chap8 is while El /= Null_Iir loop Params (Pos) := Mnode_Null; E_Params (Pos) := O_Enode_Null; + E_Sig_Params (Pos) := O_Enode_Null; Inout_Params (Pos) := Mnode_Null; declare @@ -2576,19 +2626,32 @@ package body Trans.Chap8 is Formal : constant Iir := Strip_Denoting_Name (Get_Formal (El)); Formal_Type : constant Iir := Get_Type (Formal); Ftype_Info : constant Type_Info_Acc := Get_Info (Formal_Type); - Formal_Info : constant Ortho_Info_Acc := Get_Info (Base_Formal); + Formal_Info : constant Interface_Info_Acc := + Get_Info (Base_Formal); Formal_Object_Kind : constant Object_Kind_Type := Get_Interface_Kind (Base_Formal); Act : Iir; Actual_Type : Iir; In_Conv : Iir; Param : Mnode; + Param_Sig : Mnode; Param_Type : Iir; Val : O_Enode; + Sig : O_Enode; Mval : Mnode; Mode : Iir_Mode; - Ptr : O_Lnode; Bounds : Mnode; + + -- Assign PARAMS field for formal to V. + procedure Assign_Params_Field + (V : O_Enode; Mode : Object_Kind_Type) + is + Ptr : O_Lnode; + begin + Ptr := New_Selected_Element + (Get_Var (Params_Var), Formal_Info.Interface_Field (Mode)); + New_Assign_Stmt (Ptr, V); + end Assign_Params_Field; begin -- To translate user redefined operators, -- translate_operator_function_call creates associations, that @@ -2612,56 +2675,63 @@ package body Trans.Chap8 is when Iir_Kind_Association_Element_By_Individual => Actual_Type := Get_Actual_Type (El); - if Assoc_Info = null then - Param := Create_Temp (Ftype_Info, Formal_Object_Kind); - else + for Mode in Mode_Value .. Formal_Object_Kind loop + -- For individual associations, create a variable + -- containing the whole actual. Each individual + -- association (to the same formal) will set a part of + -- this variable. + if Assoc_Info = null then + Param := Create_Temp (Ftype_Info, Mode); + else + declare + Param_Var : Var_Type; + begin + if Ftype_Info.Type_Mode = Type_Mode_Fat_Array then + Param_Var := Assoc_Info.Call_Assoc_Fat (Mode); + else + Param_Var := Assoc_Info.Call_Assoc_Value (Mode); + end if; + Param := Stabilize + (Get_Var (Param_Var, Ftype_Info, Mode)); + end; + end if; + declare - Param_Var : Var_Type; + Alloc : Allocation_Kind; begin + if Does_Callee_Suspend then + Alloc := Alloc_Return; + else + Alloc := Alloc_Stack; + end if; + if Ftype_Info.Type_Mode = Type_Mode_Fat_Array then - Param_Var := Assoc_Info.Call_Assoc_Fat; + -- Create the constraints and then the object. + -- FIXME: do not allocate bounds. + Chap3.Create_Array_Subtype (Actual_Type); + Bounds := Chap3.Get_Array_Type_Bounds (Actual_Type); + Chap3.Translate_Object_Allocation + (Param, Alloc, Formal_Type, Bounds); else - Param_Var := Assoc_Info.Call_Assoc_Value; + -- Create the object. + Chap4.Allocate_Complex_Object + (Formal_Type, Alloc, Param); end if; - Param := Stabilize (Get_Var (Param_Var, Ftype_Info, - Formal_Object_Kind)); end; - end if; - declare - Alloc : Allocation_Kind; - begin - if Does_Callee_Suspend then - Alloc := Alloc_Return; - else - Alloc := Alloc_Stack; - end if; + -- Save the object as it will be used by the following + -- associations. + Last_Individual := Pos; + -- In case of signals, don't keep value, only keep + -- signal (so override the value). + Params (Pos) := Param; - if Ftype_Info.Type_Mode = Type_Mode_Fat_Array then - -- Create the constraints and then the object. - -- FIXME: do not allocate bounds. - Chap3.Create_Array_Subtype (Actual_Type); - Bounds := Chap3.Get_Array_Type_Bounds (Actual_Type); - Chap3.Translate_Object_Allocation - (Param, Alloc, Formal_Type, Bounds); - else - -- Create the object. - Chap4.Allocate_Complex_Object - (Formal_Type, Alloc, Param); + if Formal_Info.Interface_Field (Mode) /= O_Fnode_Null + then + -- Set the PARAMS field. + Assign_Params_Field (M2E (Param), Mode); end if; - end; - - -- Save the object as it will be used by the following - -- associations. - Last_Individual := Pos; - Params (Pos) := Param; - - if Formal_Info.Interface_Field /= O_Fnode_Null then - -- Set the PARAMS field. - Ptr := New_Selected_Element - (Get_Var (Params_Var), Formal_Info.Interface_Field); - New_Assign_Stmt (Ptr, M2E (Param)); - end if; + end loop; goto Continue; when others => @@ -2677,17 +2747,25 @@ package body Trans.Chap8 is -- No conversion here. pragma Assert (In_Conv = Null_Iir); Val := Chap7.Translate_Expression (Act, Formal_Type); + Sig := O_Enode_Null; Param_Type := Formal_Type; when Iir_Kind_Interface_Signal_Declaration => -- No conversion. - Param := Chap6.Translate_Name (Act); - Val := M2E (Param); + Chap6.Translate_Signal_Name (Act, Param_Sig, Param); + case Formal_Info.Interface_Mechanism (Mode_Value) is + when Pass_By_Copy => + Val := M2E (Param); + when Pass_By_Address => + Val := M2Addr (Param); + end case; + Sig := M2E (Param_Sig); when Iir_Kind_Interface_Variable_Declaration => Mode := Get_Mode (Base_Formal); + Sig := O_Enode_Null; if Mode = Iir_In_Mode then Val := Chap7.Translate_Expression (Act); else - Param := Chap6.Translate_Name (Act); + Param := Chap6.Translate_Name (Act, Mode_Value); if Base_Formal /= Formal or else Ftype_Info.Type_Mode in Type_Mode_Call_By_Value then @@ -2738,7 +2816,12 @@ package body Trans.Chap8 is if Param_Type /= Formal_Type then -- Implicit array conversion or subtype check. Val := Chap7.Translate_Implicit_Conv - (Val, Param_Type, Formal_Type, Formal_Object_Kind, Act); + (Val, Param_Type, Formal_Type, Mode_Value, Act); + if Sig /= O_Enode_Null then + -- FIXME: convert without checking. + Sig := Chap7.Translate_Implicit_Conv + (Sig, Param_Type, Formal_Type, Mode_Signal, Act); + end if; end if; if Get_Kind (Base_Formal) /= Iir_Kind_Interface_Signal_Declaration then @@ -2747,106 +2830,140 @@ package body Trans.Chap8 is -- Assign actual, if needed. if Base_Formal /= Formal then - -- Individual association: assign the individual actual to + -- Individual association: assign the individual actual of -- the whole actual. Param := Translate_Individual_Association_Formal - (Formal, Formal_Info, Params (Last_Individual)); - Chap7.Translate_Assign - (Param, Val, Act, Formal_Type, El); + (Formal, Formal_Info, Params (Last_Individual), + Formal_Object_Kind); + if Formal_Object_Kind = Mode_Value then + Chap7.Translate_Assign (Param, Val, Act, Formal_Type, El); + else + Chap7.Translate_Assign (Param, Sig, Act, Formal_Type, El); + if Is_Suspendable then + -- Keep reference to the value to update the whole object + -- at each call. + New_Assign_Stmt + (Get_Var (Assoc_Info.Call_Assoc_Value (Mode_Value)), + Val); + else + -- Assign the value to the whole object, as there is + -- only one call. + Param := Translate_Individual_Association_Formal + (Formal, Formal_Info, Params (Last_Individual), + Mode_Value); + Chap7.Translate_Assign (Param, Val, Act, Formal_Type, El); + end if; + end if; elsif Assoc_Info /= null then + -- For suspendable caller, write the actual to the state + -- record. In some cases (like expressions), the value has + -- to be copied (it may be the result of a computation). + -- Only for whole association. pragma Assert (Base_Formal = Formal); - Mval := Stabilize - (E2M (Val, Ftype_Info, Formal_Object_Kind), True); - - declare - Fat : Mnode; - Bnd : Mnode; - begin - - if Assoc_Info.Call_Assoc_Fat /= Null_Var then - -- Fat pointer. VAL is a pointer to a fat pointer, so - -- copy the fat pointer to the FAT field, and set the - -- PARAM field to FAT field. - Fat := Stabilize - (Get_Var (Assoc_Info.Call_Assoc_Fat, - Ftype_Info, Formal_Object_Kind)); - - -- Set PARAM field to the address of the FAT field. - pragma Assert - (Formal_Info.Interface_Field /= O_Fnode_Null); - New_Assign_Stmt - (New_Selected_Element (Get_Var (Params_Var), - Formal_Info.Interface_Field), - M2E (Fat)); + for Mode in Mode_Value .. Formal_Object_Kind loop + if Mode = Mode_Value then + Mval := Stabilize + (E2M (Val, Ftype_Info, Mode_Value), True); + else + Mval := Stabilize + (E2M (Sig, Ftype_Info, Mode_Signal), True); + end if; - if Assoc_Info.Call_Assoc_Bounds = Null_Var then - Copy_Fat_Pointer (Fat, Mval); - else - -- Copy the bounds. - Bnd := Stabilize - (Lv2M (Get_Var (Assoc_Info.Call_Assoc_Bounds), - Ftype_Info, Formal_Object_Kind, - Ftype_Info.T.Bounds_Type, - Ftype_Info.T.Bounds_Ptr_Type)); - Chap3.Copy_Bounds (Bnd, Chap3.Get_Array_Bounds (Mval), - Formal_Type); - New_Assign_Stmt - (M2Lp (Chap3.Get_Array_Bounds (Fat)), - M2Addr (Bnd)); - New_Assign_Stmt - (M2Lp (Chap3.Get_Array_Base (Fat)), - M2Addr (Chap3.Get_Array_Base (Mval))); + declare + Fat : Mnode; + Bnd : Mnode; + begin + if Assoc_Info.Call_Assoc_Fat (Mode) /= Null_Var then + -- pragma Assert (Sig = O_Enode_Null); -- TODO + -- Fat pointer. VAL is a pointer to a fat pointer, so + -- copy the fat pointer to the FAT field, and set the + -- PARAM field to FAT field. + Fat := Stabilize + (Get_Var (Assoc_Info.Call_Assoc_Fat (Mode), + Ftype_Info, Mode)); + + -- Set PARAM field to the address of the FAT field. + pragma Assert (Formal_Info.Interface_Field (Mode) + /= O_Fnode_Null); + Assign_Params_Field (M2E (Fat), Mode); + + if Assoc_Info.Call_Assoc_Bounds /= Null_Var then + -- Copy the bounds. + Bnd := Stabilize + (Lv2M (Get_Var (Assoc_Info.Call_Assoc_Bounds), + Ftype_Info, Mode_Value, + Ftype_Info.T.Bounds_Type, + Ftype_Info.T.Bounds_Ptr_Type)); + Chap3.Copy_Bounds + (Bnd, Chap3.Get_Array_Bounds (Mval), Formal_Type); + New_Assign_Stmt + (M2Lp (Chap3.Get_Array_Bounds (Fat)), + M2Addr (Bnd)); + New_Assign_Stmt + (M2Lp (Chap3.Get_Array_Base (Fat)), + M2Addr (Chap3.Get_Array_Base (Mval))); + else + -- No need to copy the bounds. + Copy_Fat_Pointer (Fat, Mval); + end if; end if; - end if; - if Assoc_Info.Call_Assoc_Value /= Null_Var then - if Ftype_Info.Type_Mode = Type_Mode_Fat_Array then - pragma Assert (Assoc_Info.Call_Assoc_Fat /= Null_Var); - -- Allocate array base - Param := Fat; - Chap3.Allocate_Fat_Array_Base - (Alloc_Return, Fat, Formal_Type); - -- NOTE: Call_Assoc_Value is not used, the base is - -- directly allocated in the fat pointer. - else - Param := Get_Var (Assoc_Info.Call_Assoc_Value, - Ftype_Info, Formal_Object_Kind); - Stabilize (Param); - Chap4.Allocate_Complex_Object - (Formal_Type, Alloc_Return, Param); - New_Assign_Stmt - (New_Selected_Element (Get_Var (Params_Var), - Formal_Info.Interface_Field), - M2Addr (Param)); + if Mode = Mode_Value + and then + Assoc_Info.Call_Assoc_Value (Mode_Value) /= Null_Var + then + pragma Assert (Sig = O_Enode_Null); -- TODO + + if Ftype_Info.Type_Mode = Type_Mode_Fat_Array then + pragma Assert + (Assoc_Info.Call_Assoc_Fat (Mode) /= Null_Var); + -- Allocate array base + Param := Fat; + Chap3.Allocate_Fat_Array_Base + (Alloc_Return, Fat, Formal_Type); + -- NOTE: Call_Assoc_Value is not used, the base is + -- directly allocated in the fat pointer. + else + Param := Get_Var + (Assoc_Info.Call_Assoc_Value (Mode_Value), + Ftype_Info, Mode_Value); + Stabilize (Param); + Chap4.Allocate_Complex_Object + (Formal_Type, Alloc_Return, Param); + Assign_Params_Field (M2Addr (Param), Mode); + end if; + Chap3.Translate_Object_Copy + (Param, M2E (Mval), Formal_Type); end if; - Chap3.Translate_Object_Copy - (Param, M2E (Mval), Formal_Type); - end if; - end; + end; + end loop; - if Assoc_Info.Call_Assoc_Value = Null_Var - and then Assoc_Info.Call_Assoc_Fat = Null_Var + if Assoc_Info.Call_Assoc_Value (Mode_Value) = Null_Var + and then Assoc_Info.Call_Assoc_Fat (Mode_Value) = Null_Var then + pragma Assert (Sig = O_Enode_Null); -- Not possible. -- Set the PARAMS field. - New_Assign_Stmt - (New_Selected_Element - (Get_Var (Params_Var), Formal_Info.Interface_Field), - M2E (Mval)); + Assign_Params_Field (M2E (Mval), Mode_Value); + end if; + elsif Formal_Info.Interface_Field (Mode_Value) /= O_Fnode_Null then + Assign_Params_Field (Val, Mode_Value); + + if Sig /= O_Enode_Null then + Assign_Params_Field (Sig, Mode_Signal); end if; - elsif Formal_Info.Interface_Field /= O_Fnode_Null then - -- Set the PARAMS field. - Ptr := New_Selected_Element - (Get_Var (Params_Var), Formal_Info.Interface_Field); - New_Assign_Stmt (Ptr, Val); elsif Inout_Params (Pos) /= Mnode_Null then + -- Not for signals. + pragma Assert (Sig = O_Enode_Null); + Chap3.Translate_Object_Copy (Inout_Params (Pos), Val, Formal_Type); E_Params (Pos) := M2Addr (Inout_Params (Pos)); else E_Params (Pos) := Val; + E_Sig_Params (Pos) := Sig; end if; << Continue >> null; @@ -2874,6 +2991,63 @@ package body Trans.Chap8 is -- Call state. State_Jump (Call_State); State_Start (Call_State); + + -- Update signals value in case of individual association. + declare + Base_Formal : Iir; + Formal : Iir; + Formal_Info : Interface_Info_Acc; + Assoc_Info : Call_Assoc_Info_Acc; + Base_Param : Mnode; + Param : Mnode; + Val : O_Lnode; + begin + Open_Temp; + El := Assoc_Chain; + while El /= Null_Iir loop + Base_Formal := Get_Association_Interface (El); + case Get_Kind (El) is + when Iir_Kind_Association_Element_By_Individual => + if Get_Kind (Base_Formal) + = Iir_Kind_Interface_Signal_Declaration + then + -- Get the whole value. + Formal_Info := Get_Info (Base_Formal); + Base_Param := Lp2M + (New_Selected_Element + (Get_Var (Params_Var), + Formal_Info.Interface_Field (Mode_Value)), + Get_Info (Get_Type (Base_Formal)), Mode_Value); + Stabilize (Base_Param); + end if; + when Iir_Kind_Association_Element_By_Expression => + if not Get_Whole_Association_Flag (El) + and then (Get_Kind (Base_Formal) + = Iir_Kind_Interface_Signal_Declaration) + then + Formal := Strip_Denoting_Name (Get_Formal (El)); + Formal_Info := Get_Info (Base_Formal); + Assoc_Info := Get_Info (El); + -- Reference the individual sub-elements of the + -- whole value. + Param := Translate_Individual_Association_Formal + (Formal, Formal_Info, Base_Param, Mode_Value); + Val := Get_Var + (Assoc_Info.Call_Assoc_Value (Mode_Value)); + -- FIXME: that's for scalar. Use Mnode. + Val := New_Acc_Value (Val); + -- Update. + Chap7.Translate_Assign + (Param, New_Value (Val), Get_Actual (El), + Get_Type (Formal), El); + end if; + when others => + null; + end case; + El := Get_Chain (El); + end loop; + Close_Temp; + end; end if; Start_Association (Constr, Info.Ortho_Func); @@ -2892,7 +3066,8 @@ package body Trans.Chap8 is if Obj /= Null_Iir then -- Protected object. - New_Association (Constr, M2E (Chap6.Translate_Name (Obj))); + New_Association + (Constr, M2E (Chap6.Translate_Name (Obj, Mode_Value))); else -- Instance. Subprgs.Add_Subprg_Instance_Assoc (Constr, Info.Subprg_Instance); @@ -2907,7 +3082,7 @@ package body Trans.Chap8 is Base_Formal : constant Iir := Get_Association_Interface (El); Formal_Info : constant Ortho_Info_Acc := Get_Info (Base_Formal); begin - if Formal_Info.Interface_Field = O_Fnode_Null then + if Formal_Info.Interface_Field (Mode_Value) = O_Fnode_Null then -- Not a PARAMS field. if Get_Kind (El) = Iir_Kind_Association_Element_By_Individual then @@ -2916,6 +3091,9 @@ package body Trans.Chap8 is elsif Base_Formal = Formal then -- Whole association. New_Association (Constr, E_Params (Pos)); + if E_Sig_Params (Pos) /= O_Enode_Null then + New_Association (Constr, E_Sig_Params (Pos)); + end if; end if; end if; @@ -2965,26 +3143,28 @@ package body Trans.Chap8 is Last_Individual := Pos; declare Assoc_Info : constant Call_Assoc_Info_Acc := Get_Info (El); + Base_Formal : constant Iir := Get_Association_Interface (El); Formal_Type : Iir; - Base_Formal : Iir; Ftype_Info : Type_Info_Acc; - Formal_Object_Kind : Object_Kind_Type; begin - if Assoc_Info /= null then + if Assoc_Info /= null + and then (Get_Kind (Base_Formal) + = Iir_Kind_Interface_Variable_Declaration) + then Formal_Type := Get_Type (Get_Formal (El)); Ftype_Info := Get_Info (Formal_Type); - Base_Formal := Get_Association_Interface (El); - Formal_Object_Kind := Get_Interface_Kind (Base_Formal); + pragma Assert + (Get_Interface_Kind (Base_Formal) = Mode_Value); declare Param_Var : Var_Type; begin if Ftype_Info.Type_Mode = Type_Mode_Fat_Array then - Param_Var := Assoc_Info.Call_Assoc_Fat; + Param_Var := Assoc_Info.Call_Assoc_Fat (Mode_Value); else - Param_Var := Assoc_Info.Call_Assoc_Value; + Param_Var := Assoc_Info.Call_Assoc_Value (Mode_Value); end if; Params (Pos) := Stabilize - (Get_Var (Param_Var, Ftype_Info, Formal_Object_Kind)); + (Get_Var (Param_Var, Ftype_Info, Mode_Value)); end; end if; end; @@ -3012,13 +3192,16 @@ package body Trans.Chap8 is if Base_Formal /= Formal then -- By individual, copy back. Param := Translate_Individual_Association_Formal - (Formal, Formal_Info, Params (Last_Individual)); + (Formal, Formal_Info, Params (Last_Individual), + Mode_Value); elsif Inout_Params (Pos) /= Mnode_Null then Param := Inout_Params (Pos); else - pragma Assert (Formal_Info.Interface_Field /= O_Fnode_Null); + pragma Assert + (Formal_Info.Interface_Field (Mode_Value) /= O_Fnode_Null); Ptr := New_Selected_Element - (Get_Var (Params_Var), Formal_Info.Interface_Field); + (Get_Var (Params_Var), + Formal_Info.Interface_Field (Mode_Value)); case Type_Mode_Valid (Ftype_Info.Type_Mode) is when Type_Mode_Pass_By_Copy => Param := Lv2M (Ptr, Ftype_Info, Mode_Value); @@ -3044,6 +3227,7 @@ package body Trans.Chap8 is Param := Lp2M (Get_Var (Assoc_Info.Call_Assoc_Ref), Get_Info (Actual_Type), Mode_Value); end if; + -- FIXME: scalar check ? Chap7.Translate_Assign (Param, Val, Out_Expr, Actual_Type, El); end; end if; @@ -3666,7 +3850,7 @@ package body Trans.Chap8 is Close_Temp; end; else - Src := Chap6.Translate_Name (Target); + Src := Chap6.Translate_Name (Target, Mode_Signal); Chap3.Translate_Object_Copy (Aggr, M2E (Src), Target_Type); end if; end Translate_Signal_Target_Aggr; @@ -3858,8 +4042,7 @@ package body Trans.Chap8 is Translate_Direct_Signal_Assignment (Stmt, Value); return; end if; - Targ := Chap6.Translate_Name (Target); - pragma Assert (Get_Object_Kind (Targ) = Mode_Signal); + Targ := Chap6.Translate_Name (Target, Mode_Signal); end if; if We = Null_Iir then |