aboutsummaryrefslogtreecommitdiffstats
path: root/src/vhdl
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2020-07-19 16:59:13 +0200
committerTristan Gingold <tgingold@free.fr>2020-07-19 16:59:13 +0200
commit8677e93d3c0ab2158b906728dbb767bc48fa776b (patch)
treea721178c090f368c3a1b6f04ee1114cbe894399a /src/vhdl
parenta5f7ddf81a2aa5d70fdeedf08e1652a7f54addfb (diff)
downloadghdl-8677e93d3c0ab2158b906728dbb767bc48fa776b.tar.gz
ghdl-8677e93d3c0ab2158b906728dbb767bc48fa776b.tar.bz2
ghdl-8677e93d3c0ab2158b906728dbb767bc48fa776b.zip
vhdl trans-chap7: fix result of read with length. Fix #1392
Diffstat (limited to 'src/vhdl')
-rw-r--r--src/vhdl/translate/trans-chap7.adb81
1 files changed, 70 insertions, 11 deletions
diff --git a/src/vhdl/translate/trans-chap7.adb b/src/vhdl/translate/trans-chap7.adb
index 0f4200b29..f7ea2cdf7 100644
--- a/src/vhdl/translate/trans-chap7.adb
+++ b/src/vhdl/translate/trans-chap7.adb
@@ -5820,9 +5820,9 @@ package body Trans.Chap7 is
Gen_Exit_When
(Label,
New_Compare_Op (ON_Eq,
- New_Obj_Value (Var_It),
- New_Obj_Value (Var_Max),
- Ghdl_Bool_Type));
+ New_Obj_Value (Var_It),
+ New_Obj_Value (Var_Max),
+ Ghdl_Bool_Type));
Translate_Rw
(Chap3.Index_Base (Val, Val_Type, New_Obj_Value (Var_It)),
Get_Element_Subtype (Val_Type), Proc);
@@ -5945,22 +5945,81 @@ package body Trans.Chap7 is
when Iir_Predefined_Read_Length =>
declare
+ El_Type : constant Iir := Get_Element_Subtype (Etype);
+ El_Tinfo : constant Type_Info_Acc := Get_Info (El_Type);
Var_Len : O_Dnode;
+ Var_Max : O_Dnode;
+ Var_It : O_Dnode;
+ Label : O_Snode;
+ If_Blk : O_If_Block;
+ Targ : O_Dnode;
+ Dummy : Mnode;
begin
Open_Temp;
+ Var_Max := Create_Temp (Ghdl_Index_Type);
+ New_Assign_Stmt (New_Obj (Var_Max),
+ Chap3.Get_Array_Length (Var, Etype));
+ -- TODO: complex element type.
+ pragma Assert (Is_Static_Type (El_Tinfo));
+ Dummy := Create_Temp (El_Tinfo);
+ Targ := Create_Temp (El_Tinfo.Ortho_Ptr_Type (Mode_Value));
+
+ -- Read length.
Var_Len := Create_Temp (Ghdl_Index_Type);
Translate_Rw_Length (Var_Len, Ghdl_Read_Scalar);
- Chap6.Check_Bound_Error
- (New_Compare_Op (ON_Gt,
+ -- LRM08 5.5.2 File Operations
+ -- If the object associated with formal parameter VALUE is
+ -- shorter than this length, then only that portion of the
+ -- array value read by the operation that can be contained in
+ -- the object is returned by the READ operation, and the rest
+ -- of the value is lost. If the object associated with formal
+ -- parameter VALUE is longer than this length, then the entire
+ -- value is returned and remaining elements of the object are
+ -- unaffected.
+
+ -- Iterate on length.
+ Var_It := Create_Temp (Ghdl_Index_Type);
+ Init_Var (Var_It);
+ Start_Loop_Stmt (Label);
+ Gen_Exit_When
+ (Label,
+ New_Compare_Op (ON_Eq,
+ New_Obj_Value (Var_It),
New_Obj_Value (Var_Len),
- Chap3.Get_Array_Length (Var, Etype),
- Ghdl_Bool_Type),
- Subprg);
- Translate_Rw_Array (Chap3.Get_Composite_Base (Var), Etype,
- Var_Len, Ghdl_Read_Scalar);
- New_Return_Stmt (New_Convert_Ov (New_Obj_Value (Var_Len),
+ Ghdl_Bool_Type));
+ Start_If_Stmt
+ (If_Blk, New_Compare_Op (ON_Gt,
+ New_Obj_Value (Var_It),
+ New_Obj_Value (Var_Max),
+ Ghdl_Bool_Type));
+ New_Assign_Stmt (New_Obj (Targ), M2Addr (Dummy));
+ New_Else_Stmt (If_Blk);
+ New_Assign_Stmt
+ (New_Obj (Targ),
+ M2Addr (Chap3.Index_Base (Chap3.Get_Composite_Base (Var),
+ Etype,
+ New_Obj_Value (Var_It))));
+ Finish_If_Stmt (If_Blk);
+
+ Translate_Rw (Dp2M (Targ, El_Tinfo, Mode_Value),
+ El_Type, Ghdl_Read_Scalar);
+ Inc_Var (Var_It);
+ Finish_Loop_Stmt (Label);
+
+ -- Return the length (the minimum of len, max)
+ Start_If_Stmt
+ (If_Blk, New_Compare_Op (ON_Gt,
+ New_Obj_Value (Var_Len),
+ New_Obj_Value (Var_Max),
+ Ghdl_Bool_Type));
+ New_Assign_Stmt (New_Obj (Var_It), New_Obj_Value (Var_Max));
+ New_Else_Stmt (If_Blk);
+ New_Assign_Stmt (New_Obj (Var_It), New_Obj_Value (Var_Len));
+ Finish_If_Stmt (If_Blk);
+ New_Return_Stmt (New_Convert_Ov (New_Obj_Value (Var_It),
Std_Integer_Otype));
+
Close_Temp;
end;
when others =>