diff options
author | Tristan Gingold | 2014-11-04 20:14:19 +0100 |
---|---|---|
committer | Tristan Gingold | 2014-11-04 20:14:19 +0100 |
commit | 9c195bf5d86d67ea5eb419ccf6e48dc153e57c68 (patch) | |
tree | 575346e529b99e26382b4a06f6ff2caa0b391ab2 /ortho/mcode/ortho_code-exprs.adb | |
parent | 184a123f91e07c927292d67462561dc84f3a920d (diff) | |
download | ghdl-9c195bf5d86d67ea5eb419ccf6e48dc153e57c68.tar.gz ghdl-9c195bf5d86d67ea5eb419ccf6e48dc153e57c68.tar.bz2 ghdl-9c195bf5d86d67ea5eb419ccf6e48dc153e57c68.zip |
Move sources to src/ subdirectory.
Diffstat (limited to 'ortho/mcode/ortho_code-exprs.adb')
-rw-r--r-- | ortho/mcode/ortho_code-exprs.adb | 1663 |
1 files changed, 0 insertions, 1663 deletions
diff --git a/ortho/mcode/ortho_code-exprs.adb b/ortho/mcode/ortho_code-exprs.adb deleted file mode 100644 index b2dfa1a..0000000 --- a/ortho/mcode/ortho_code-exprs.adb +++ /dev/null @@ -1,1663 +0,0 @@ --- Mcode back-end for ortho - Expressions and control handling. --- Copyright (C) 2006 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 Ada.Text_IO; -with Ada.Unchecked_Deallocation; -with GNAT.Table; -with Ortho_Code.Types; use Ortho_Code.Types; -with Ortho_Code.Consts; use Ortho_Code.Consts; -with Ortho_Code.Decls; use Ortho_Code.Decls; -with Ortho_Code.Debug; use Ortho_Code.Debug; -with Ortho_Code.Abi; use Ortho_Code.Abi; -with Ortho_Code.Disps; -with Ortho_Code.Opts; -with Ortho_Code.Flags; - -package body Ortho_Code.Exprs is - - type Enode_Pad is mod 256; - - type Enode_Common is record - Kind : OE_Kind; -- about 1 byte (6 bits) - Reg : O_Reg; -- 1 byte - Mode : Mode_Type; -- 4 bits - Ref : Boolean; - Flag1 : Boolean; - Flag2 : Boolean; - Flag3 : Boolean; - Pad : Enode_Pad; - Arg1 : O_Enode; - Arg2 : O_Enode; - Info : Int32; - end record; - pragma Pack (Enode_Common); - for Enode_Common'Size use 4*32; - for Enode_Common'Alignment use 4; - - package Enodes is new GNAT.Table - (Table_Component_Type => Enode_Common, - Table_Index_Type => O_Enode, - Table_Low_Bound => 2, - Table_Initial => 1024, - Table_Increment => 100); - - function Get_Expr_Kind (Enode : O_Enode) return OE_Kind is - begin - return Enodes.Table (Enode).Kind; - end Get_Expr_Kind; - - function Get_Expr_Mode (Enode : O_Enode) return Mode_Type is - begin - return Enodes.Table (Enode).Mode; - end Get_Expr_Mode; - - function Get_Enode_Type (Enode : O_Enode) return O_Tnode is - begin - return O_Tnode (Enodes.Table (Enode).Info); - end Get_Enode_Type; - - function Get_Expr_Reg (Enode : O_Enode) return O_Reg is - begin - return Enodes.Table (Enode).Reg; - end Get_Expr_Reg; - - procedure Set_Expr_Reg (Enode : O_Enode; Reg : O_Reg) is - begin - Enodes.Table (Enode).Reg := Reg; - end Set_Expr_Reg; - - function Get_Expr_Operand (Enode : O_Enode) return O_Enode is - begin - return Enodes.Table (Enode).Arg1; - end Get_Expr_Operand; - - procedure Set_Expr_Operand (Enode : O_Enode; Val : O_Enode) is - begin - Enodes.Table (Enode).Arg1 := Val; - end Set_Expr_Operand; - - function Get_Expr_Left (Enode : O_Enode) return O_Enode is - begin - return Enodes.Table (Enode).Arg1; - end Get_Expr_Left; - - function Get_Expr_Right (Enode : O_Enode) return O_Enode is - begin - return Enodes.Table (Enode).Arg2; - end Get_Expr_Right; - - procedure Set_Expr_Left (Enode : O_Enode; Val : O_Enode) is - begin - Enodes.Table (Enode).Arg1 := Val; - end Set_Expr_Left; - - procedure Set_Expr_Right (Enode : O_Enode; Val : O_Enode) is - begin - Enodes.Table (Enode).Arg2 := Val; - end Set_Expr_Right; - - function Get_Expr_Low (Cst : O_Enode) return Uns32 is - begin - return To_Uns32 (Int32 (Enodes.Table (Cst).Arg1)); - end Get_Expr_Low; - - function Get_Expr_High (Cst : O_Enode) return Uns32 is - begin - return To_Uns32 (Int32 (Enodes.Table (Cst).Arg2)); - end Get_Expr_High; - - function Get_Assign_Target (Enode : O_Enode) return O_Enode is - begin - return Enodes.Table (Enode).Arg2; - end Get_Assign_Target; - - procedure Set_Assign_Target (Enode : O_Enode; Targ : O_Enode) is - begin - Enodes.Table (Enode).Arg2 := Targ; - end Set_Assign_Target; - - function Get_Expr_Lit (Lit : O_Enode) return O_Cnode is - begin - return O_Cnode (Enodes.Table (Lit).Arg1); - end Get_Expr_Lit; - - function Get_Conv_Type (Enode : O_Enode) return O_Tnode is - begin - return O_Tnode (Enodes.Table (Enode).Arg2); - end Get_Conv_Type; - - -- Leave node corresponding to the entry. - function Get_Entry_Leave (Enode : O_Enode) return O_Enode is - begin - return Enodes.Table (Enode).Arg1; - end Get_Entry_Leave; - - procedure Set_Entry_Leave (Enode : O_Enode; Leave : O_Enode) is - begin - Enodes.Table (Enode).Arg1 := Leave; - end Set_Entry_Leave; - - function Get_Jump_Label (Enode : O_Enode) return O_Enode is - begin - return Enodes.Table (Enode).Arg2; - end Get_Jump_Label; - - procedure Set_Jump_Label (Enode : O_Enode; Label : O_Enode) is - begin - Enodes.Table (Enode).Arg2 := Label; - end Set_Jump_Label; - - function Get_Addr_Object (Enode : O_Enode) return O_Dnode is - begin - return O_Dnode (Enodes.Table (Enode).Arg1); - end Get_Addr_Object; - - function Get_Addrl_Frame (Enode : O_Enode) return O_Enode is - begin - return Enodes.Table (Enode).Arg2; - end Get_Addrl_Frame; - - procedure Set_Addrl_Frame (Enode : O_Enode; Frame : O_Enode) is - begin - Enodes.Table (Enode).Arg2 := Frame; - end Set_Addrl_Frame; - - function Get_Call_Subprg (Enode : O_Enode) return O_Dnode is - begin - return O_Dnode (Enodes.Table (Enode).Arg1); - end Get_Call_Subprg; - - function Get_Stack_Adjust (Enode : O_Enode) return Int32 is - begin - return Int32 (Enodes.Table (Enode).Arg1); - end Get_Stack_Adjust; - - function Get_Arg_Link (Enode : O_Enode) return O_Enode is - begin - return Enodes.Table (Enode).Arg2; - end Get_Arg_Link; - - function Get_Block_Decls (Blk : O_Enode) return O_Dnode is - begin - return O_Dnode (Enodes.Table (Blk).Arg2); - end Get_Block_Decls; - - function Get_Block_Parent (Blk : O_Enode) return O_Enode is - begin - return Enodes.Table (Blk).Arg1; - end Get_Block_Parent; - - function Get_Block_Has_Alloca (Blk : O_Enode) return Boolean is - begin - return Enodes.Table (Blk).Flag1; - end Get_Block_Has_Alloca; - - procedure Set_Block_Has_Alloca (Blk : O_Enode; Flag : Boolean) is - begin - Enodes.Table (Blk).Flag1 := Flag; - end Set_Block_Has_Alloca; - - function Get_End_Beg (Blk : O_Enode) return O_Enode is - begin - return Enodes.Table (Blk).Arg1; - end Get_End_Beg; - - function Get_Label_Info (Label : O_Enode) return Int32 is - begin - return Int32 (Enodes.Table (Label).Arg2); - end Get_Label_Info; - - procedure Set_Label_Info (Label : O_Enode; Info : Int32) is - begin - Enodes.Table (Label).Arg2 := O_Enode (Info); - end Set_Label_Info; - - function Get_Label_Block (Label : O_Enode) return O_Enode is - begin - return Enodes.Table (Label).Arg1; - end Get_Label_Block; - - function Get_Spill_Info (Spill : O_Enode) return Int32 is - begin - return Int32 (Enodes.Table (Spill).Arg2); - end Get_Spill_Info; - - procedure Set_Spill_Info (Spill : O_Enode; Info : Int32) is - begin - Enodes.Table (Spill).Arg2 := O_Enode (Info); - end Set_Spill_Info; - - -- Get the statement link. - function Get_Stmt_Link (Stmt : O_Enode) return O_Enode is - begin - return O_Enode (Enodes.Table (Stmt).Info); - end Get_Stmt_Link; - - procedure Set_Stmt_Link (Stmt : O_Enode; Next : O_Enode) is - begin - Enodes.Table (Stmt).Info := Int32 (Next); - end Set_Stmt_Link; - - function Get_BB_Next (Stmt : O_Enode) return O_Enode is - begin - return Enodes.Table (Stmt).Arg1; - end Get_BB_Next; - pragma Unreferenced (Get_BB_Next); - - procedure Set_BB_Next (Stmt : O_Enode; Next : O_Enode) is - begin - Enodes.Table (Stmt).Arg1 := Next; - end Set_BB_Next; - - function Get_BB_Number (Stmt : O_Enode) return Int32 is - begin - return Int32 (Enodes.Table (Stmt).Arg2); - end Get_BB_Number; - - function Get_Loop_Level (Stmt : O_Enode) return Int32 is - begin - return Int32 (Enodes.Table (Stmt).Arg1); - end Get_Loop_Level; - - procedure Set_Loop_Level (Stmt : O_Enode; Level : Int32) is - begin - Enodes.Table (Stmt).Arg1 := O_Enode (Level); - end Set_Loop_Level; - - procedure Set_Case_Branch (C : O_Enode; Branch : O_Enode) is - begin - Enodes.Table (C).Arg2 := Branch; - end Set_Case_Branch; - - procedure Set_Case_Branch_Choice (Branch : O_Enode; Choice : O_Enode) is - begin - Enodes.Table (Branch).Arg1 := Choice; - end Set_Case_Branch_Choice; - - function Get_Case_Branch_Choice (Branch : O_Enode) return O_Enode is - begin - return Enodes.Table (Branch).Arg1; - end Get_Case_Branch_Choice; - - procedure Set_Case_Choice_Link (Choice : O_Enode; N_Choice : O_Enode) is - begin - Enodes.Table (Choice).Info := Int32 (N_Choice); - end Set_Case_Choice_Link; - - function Get_Case_Choice_Link (Choice : O_Enode) return O_Enode is - begin - return O_Enode (Enodes.Table (Choice).Info); - end Get_Case_Choice_Link; - - function Get_Ref_Field (Ref : O_Enode) return O_Fnode is - begin - return O_Fnode (Enodes.Table (Ref).Arg2); - end Get_Ref_Field; - - function Get_Ref_Index (Ref : O_Enode) return O_Enode is - begin - return Enodes.Table (Ref).Arg2; - end Get_Ref_Index; - - function Get_Expr_Line_Number (Stmt : O_Enode) return Int32 is - begin - return Int32 (Enodes.Table (Stmt).Arg1); - end Get_Expr_Line_Number; - - function Get_Intrinsic_Operation (Stmt : O_Enode) return Int32 is - begin - return Int32 (Enodes.Table (Stmt).Arg1); - end Get_Intrinsic_Operation; - - Last_Stmt : O_Enode := O_Enode_Null; - - procedure Link_Stmt (Stmt : O_Enode) is - begin - if Last_Stmt = O_Enode_Null then - raise Program_Error; - end if; - Set_Stmt_Link (Last_Stmt, Stmt); - Last_Stmt := Stmt; - end Link_Stmt; - - function New_Enode (Kind : OE_Kind; - Rtype : O_Tnode; - Arg1 : O_Enode; - Arg2 : O_Enode) return O_Enode - is - Mode : Mode_Type; - begin - Mode := Get_Type_Mode (Rtype); - Enodes.Append (Enode_Common'(Kind => Kind, - Reg => 0, - Mode => Mode, - Ref => False, - Flag1 => False, - Flag2 => False, - Flag3 => False, - Pad => 0, - Arg1 => Arg1, - Arg2 => Arg2, - Info => Int32 (Rtype))); - return Enodes.Last; - end New_Enode; - - function New_Enode (Kind : OE_Kind; - Mode : Mode_Type; - Rtype : O_Tnode; - Arg1 : O_Enode; - Arg2 : O_Enode) return O_Enode - is - begin - Enodes.Append (Enode_Common'(Kind => Kind, - Reg => 0, - Mode => Mode, - Ref => False, - Flag1 => False, - Flag2 => False, - Flag3 => False, - Pad => 0, - Arg1 => Arg1, - Arg2 => Arg2, - Info => Int32 (Rtype))); - return Enodes.Last; - end New_Enode; - - procedure New_Enode_Stmt (Kind : OE_Kind; Arg1 : O_Enode; Arg2 : O_Enode) - is - begin - Enodes.Append (Enode_Common'(Kind => Kind, - Reg => 0, - Mode => Mode_Nil, - Ref => False, - Flag1 => False, - Flag2 => False, - Flag3 => False, - Pad => 0, - Arg1 => Arg1, - Arg2 => Arg2, - Info => 0)); - Link_Stmt (Enodes.Last); - end New_Enode_Stmt; - - procedure New_Enode_Stmt - (Kind : OE_Kind; Mode : Mode_Type; Arg1 : O_Enode; Arg2 : O_Enode) - is - begin - Enodes.Append (Enode_Common'(Kind => Kind, - Reg => 0, - Mode => Mode, - Ref => False, - Flag1 => False, - Flag2 => False, - Flag3 => False, - Pad => 0, - Arg1 => Arg1, - Arg2 => Arg2, - Info => 0)); - Link_Stmt (Enodes.Last); - end New_Enode_Stmt; - - Bb_Num : Int32 := 0; - Last_Bb : O_Enode := O_Enode_Null; - - procedure Create_BB is - begin - New_Enode_Stmt (OE_BB, Mode_Nil, O_Enode_Null, O_Enode (Bb_Num)); - if Last_Bb /= O_Enode_Null then - Set_BB_Next (Last_Bb, Enodes.Last); - end if; - Last_Bb := Enodes.Last; - Bb_Num := Bb_Num + 1; - end Create_BB; - - procedure Start_BB is - begin - if Flags.Flag_Opt_BB then - Create_BB; - end if; - end Start_BB; - pragma Inline (Start_BB); - - procedure Check_Ref (E : O_Enode) is - begin - if Enodes.Table (E).Ref then - raise Syntax_Error; - end if; - Enodes.Table (E).Ref := True; - end Check_Ref; - - procedure Check_Ref (E : O_Lnode) is - begin - Check_Ref (O_Enode (E)); - end Check_Ref; - - procedure Check_Value_Type (Val : O_Enode; Vtype : O_Tnode) is - begin - if Get_Enode_Type (Val) /= Vtype then - raise Syntax_Error; - end if; - end Check_Value_Type; - - function New_Const_U32 (Val : Uns32; Vtype : O_Tnode) return O_Enode - is - begin - return New_Enode (OE_Const, Vtype, - O_Enode (To_Int32 (Val)), O_Enode_Null); - end New_Const_U32; - - Last_Decl : O_Dnode := 2; - Cur_Block : O_Enode := O_Enode_Null; - - procedure Start_Declare_Stmt - is - Res : O_Enode; - begin - New_Enode_Stmt (OE_Beg, Cur_Block, O_Enode_Null); - Res := Enodes.Last; - Enodes.Table (Res).Arg2 := O_Enode - (Ortho_Code.Decls.Start_Declare_Stmt); - Cur_Block := Res; - end Start_Declare_Stmt; - - function New_Stack (Rtype : O_Tnode) return O_Enode is - begin - return New_Enode (OE_Get_Stack, Rtype, O_Enode_Null, O_Enode_Null); - end New_Stack; - - procedure New_Stack_Restore (Blk : O_Enode) - is - Save_Asgn : O_Enode; - Save_Var : O_Dnode; - begin - Save_Asgn := Get_Stmt_Link (Blk); - Save_Var := Get_Addr_Object (Get_Assign_Target (Save_Asgn)); - New_Enode_Stmt (OE_Set_Stack, New_Value (New_Obj (Save_Var)), - O_Enode_Null); - end New_Stack_Restore; - - procedure Finish_Declare_Stmt - is - Parent : O_Dnode; - begin - if Get_Block_Has_Alloca (Cur_Block) then - New_Stack_Restore (Cur_Block); - end if; - New_Enode_Stmt (OE_End, Cur_Block, O_Enode_Null); - Cur_Block := Get_Block_Parent (Cur_Block); - if Cur_Block = O_Enode_Null then - Parent := O_Dnode_Null; - else - Parent := Get_Block_Decls (Cur_Block); - end if; - Ortho_Code.Decls.Finish_Declare_Stmt (Parent); - end Finish_Declare_Stmt; - - function New_Label return O_Enode is - begin - return New_Enode (OE_Label, Mode_Nil, O_Tnode_Null, - Cur_Block, O_Enode_Null); - end New_Label; - - procedure Start_Subprogram_Body (Func : O_Dnode) - is - Start : O_Enode; - D_Body : O_Dnode; - Data : Subprogram_Data_Acc; - begin - if Cur_Subprg = null then - Abi.Start_Body (Func); - end if; - - Start := New_Enode (OE_Entry, Mode_Nil, O_Tnode_Null, - Last_Stmt, O_Enode_Null); - D_Body := Decls.Start_Subprogram_Body (Func, Start); - - -- Create the corresponding decl. - Enodes.Table (Start).Arg2 := O_Enode (D_Body); - - -- Create the data record. - Data := new Subprogram_Data'(Parent => Cur_Subprg, - First_Child => null, - Last_Child => null, - Brother => null, - Depth => Get_Decl_Depth (Func), - D_Decl => Func, - E_Entry => Start, - D_Body => D_Body, - Exit_Label => O_Enode_Null, - Last_Stmt => O_Enode_Null, - Stack_Max => 0); - - if not Flag_Debug_Hli then - Data.Exit_Label := New_Label; - end if; - - -- Link the record. - if Cur_Subprg = null then - -- A top-level subprogram. - if First_Subprg = null then - First_Subprg := Data; - else - Last_Subprg.Brother := Data; - end if; - Last_Subprg := Data; - else - -- A nested subprogram. - if Cur_Subprg.First_Child = null then - Cur_Subprg.First_Child := Data; - else - Cur_Subprg.Last_Child.Brother := Data; - end if; - Cur_Subprg.Last_Child := Data; - - -- Also save last_stmt. - Cur_Subprg.Last_Stmt := Last_Stmt; - end if; - - Cur_Subprg := Data; - Last_Stmt := Start; - - Start_Declare_Stmt; - - -- Create a basic block for the beginning of the subprogram. - Start_BB; - - -- Disp declarations. - if Cur_Subprg.Parent = null then - if Ortho_Code.Debug.Flag_Debug_Body - or Ortho_Code.Debug.Flag_Debug_Code - then - while Last_Decl <= D_Body loop - case Get_Decl_Kind (Last_Decl) is - when OD_Block => - -- Skip blocks. - Disp_Decl (1, Last_Decl); - Last_Decl := Get_Block_Last (Last_Decl) + 1; - when others => - Disp_Decl (1, Last_Decl); - Last_Decl := Last_Decl + 1; - end case; - end loop; - end if; - end if; - end Start_Subprogram_Body; - - procedure Finish_Subprogram_Body - is - Parent : Subprogram_Data_Acc; - begin - Finish_Declare_Stmt; - - -- Create a new basic block for the epilog. - Start_BB; - - if not Flag_Debug_Hli then - Link_Stmt (Cur_Subprg.Exit_Label); - end if; - - New_Enode_Stmt (OE_Leave, O_Enode_Null, O_Enode_Null); - - -- Save last statement. - Cur_Subprg.Last_Stmt := Enodes.Last; - -- Set Leave of Entry. - Set_Entry_Leave (Cur_Subprg.E_Entry, Enodes.Last); - - Decls.Finish_Subprogram_Body; - - Parent := Cur_Subprg.Parent; - - if Flags.Flag_Optimize then - Opts.Optimize_Subprg (Cur_Subprg); - end if; - - if Parent = null then - -- This is a top-level subprogram. - if Ortho_Code.Debug.Flag_Disp_Code then - Disps.Disp_Subprg (Cur_Subprg); - end if; - if Ortho_Code.Debug.Flag_Dump_Code then - Disp_Subprg_Body (1, Cur_Subprg.E_Entry); - end if; - if not Ortho_Code.Debug.Flag_Debug_Dump then - Abi.Finish_Body (Cur_Subprg); - end if; - end if; - - -- Restore Cur_Subprg. - Cur_Subprg := Parent; - - -- Restore Last_Stmt. - if Cur_Subprg = null then - Last_Stmt := O_Enode_Null; - else - Last_Stmt := Cur_Subprg.Last_Stmt; - end if; - end Finish_Subprogram_Body; - - function Get_Inner_Alloca (Label : O_Enode) return O_Enode - is - Res : O_Enode := O_Enode_Null; - Blk : O_Enode; - Last_Blk : constant O_Enode := Get_Label_Block (Label); - begin - Blk := Cur_Block; - while Blk /= Last_Blk loop - if Get_Block_Has_Alloca (Blk) then - Res := Blk; - end if; - Blk := Get_Block_Parent (Blk); - end loop; - return Res; - end Get_Inner_Alloca; - - procedure Emit_Jmp (Code : OE_Kind; Expr : O_Enode; Label : O_Enode) - is - begin - -- Discard jump after jump. - if Code /= OE_Jump or else Get_Expr_Kind (Last_Stmt) /= OE_Jump then - New_Enode_Stmt (Code, Expr, Label); - end if; - end Emit_Jmp; - - - -- If there is stack allocated memory to be freed, free it. - -- Then jump to LABEL. - procedure New_Allocb_Jump (Label : O_Enode) - is - Inner_Alloca : O_Enode; - begin - Inner_Alloca := Get_Inner_Alloca (Label); - if Inner_Alloca /= O_Enode_Null then - New_Stack_Restore (Inner_Alloca); - end if; - Emit_Jmp (OE_Jump, O_Enode_Null, Label); - end New_Allocb_Jump; - - function New_Lit (Lit : O_Cnode) return O_Enode - is - L_Type : O_Tnode; - H, L : Uns32; - begin - L_Type := Get_Const_Type (Lit); - if Flag_Debug_Hli then - return New_Enode (OE_Lit, L_Type, O_Enode (Lit), O_Enode_Null); - else - case Get_Const_Kind (Lit) is - when OC_Signed - | OC_Unsigned - | OC_Float - | OC_Null - | OC_Lit => - Get_Const_Bytes (Lit, H, L); - return New_Enode - (OE_Const, L_Type, - O_Enode (To_Int32 (L)), O_Enode (To_Int32 (H))); - when OC_Address - | OC_Subprg_Address => - return New_Enode (OE_Addrg, L_Type, - O_Enode (Get_Const_Decl (Lit)), O_Enode_Null); - when OC_Array - | OC_Record - | OC_Union - | OC_Sizeof - | OC_Alignof => - raise Syntax_Error; - end case; - end if; - end New_Lit; - - function Get_Static_Chain (Depth : O_Depth) return O_Enode - is - Cur_Depth : O_Depth := Cur_Subprg.Depth; - Subprg : Subprogram_Data_Acc; - Res : O_Enode; - begin - if Depth = Cur_Depth then - return New_Enode (OE_Get_Frame, Abi.Mode_Ptr, O_Tnode_Ptr, - O_Enode_Null, O_Enode_Null); - else - Subprg := Cur_Subprg; - Res := O_Enode_Null; - loop - -- The static chain is the first interface of the subprogram. - Res := New_Enode (OE_Addrl, Abi.Mode_Ptr, O_Tnode_Ptr, - O_Enode (Get_Subprg_Interfaces (Subprg.D_Decl)), - Res); - Res := New_Enode (OE_Indir, O_Tnode_Ptr, Res, O_Enode_Null); - Cur_Depth := Cur_Depth - 1; - if Cur_Depth = Depth then - return Res; - end if; - Subprg := Subprg.Parent; - end loop; - end if; - end Get_Static_Chain; - - function New_Obj (Obj : O_Dnode) return O_Lnode - is - O_Type : O_Tnode; - Kind : OE_Kind; - Chain : O_Enode; - Depth : O_Depth; - begin - O_Type := Get_Decl_Type (Obj); - case Get_Decl_Kind (Obj) is - when OD_Local - | OD_Interface => - Kind := OE_Addrl; - -- Local declarations are 1 deeper than their subprogram. - Depth := Get_Decl_Depth (Obj) - 1; - if Depth /= Cur_Subprg.Depth then - Chain := Get_Static_Chain (Depth); - else - Chain := O_Enode_Null; - end if; - when OD_Var - | OD_Const => - Kind := OE_Addrg; - Chain := O_Enode_Null; - when others => - raise Program_Error; - end case; - return O_Lnode (New_Enode (Kind, Abi.Mode_Ptr, O_Type, - O_Enode (Obj), Chain)); - end New_Obj; - - function New_Dyadic_Op (Kind : ON_Dyadic_Op_Kind; Left, Right : O_Enode) - return O_Enode - is - L_Type : O_Tnode; - begin - L_Type := Get_Enode_Type (Left); - if Flag_Debug_Assert then - if L_Type /= Get_Enode_Type (Right) then - raise Syntax_Error; - end if; - if Get_Type_Mode (L_Type) = Mode_Blk then - raise Syntax_Error; - end if; - Check_Ref (Left); - Check_Ref (Right); - end if; - - return New_Enode (OE_Kind'Val (ON_Op_Kind'Pos (Kind)), - L_Type, Left, Right); - end New_Dyadic_Op; - - function New_Monadic_Op (Kind : ON_Monadic_Op_Kind; Operand : O_Enode) - return O_Enode - is - O_Type : O_Tnode; - begin - O_Type := Get_Enode_Type (Operand); - - if Flag_Debug_Assert then - if Get_Type_Mode (O_Type) = Mode_Blk then - raise Syntax_Error; - end if; - Check_Ref (Operand); - end if; - - return New_Enode (OE_Kind'Val (ON_Op_Kind'Pos (Kind)), O_Type, - Operand, O_Enode_Null); - end New_Monadic_Op; - - function New_Compare_Op - (Kind : ON_Compare_Op_Kind; Left, Right : O_Enode; Ntype : O_Tnode) - return O_Enode - is - Res : O_Enode; - begin - if Flag_Debug_Assert then - if Get_Enode_Type (Left) /= Get_Enode_Type (Right) then - raise Syntax_Error; - end if; - if Get_Expr_Mode (Left) = Mode_Blk then - raise Syntax_Error; - end if; - if Get_Type_Kind (Ntype) /= OT_Boolean then - raise Syntax_Error; - end if; - Check_Ref (Left); - Check_Ref (Right); - end if; - - Res := New_Enode (OE_Kind'Val (ON_Op_Kind'Pos (Kind)), Ntype, - Left, Right); - if Flag_Debug_Hli then - return New_Enode (OE_Typed, Ntype, Res, O_Enode (Ntype)); - else - return Res; - end if; - end New_Compare_Op; - - function New_Sizeof (Atype : O_Tnode; Rtype : O_Tnode) return O_Enode is - begin - return New_Const_U32 (Get_Type_Size (Atype), Rtype); - end New_Sizeof; - - function New_Offsetof (Field : O_Fnode; Rtype : O_Tnode) return O_Enode is - begin - return New_Const_U32 (Get_Field_Offset (Field), Rtype); - end New_Offsetof; - - function Is_Pow2 (V : Uns32) return Boolean is - begin - return (V and -V) = V; - end Is_Pow2; - - function Extract_Pow2 (V : Uns32) return Uns32 is - begin - for I in Natural range 0 .. 31 loop - if V = Shift_Left (1, I) then - return Uns32 (I); - end if; - end loop; - raise Program_Error; - end Extract_Pow2; - - function New_Index_Slice_Element - (Arr : O_Lnode; Index : O_Enode; Res_Type : O_Tnode) - return O_Lnode - is - El_Type : O_Tnode; - In_Type : O_Tnode; - Sz : O_Enode; - El_Size : Uns32; - begin - El_Type := Get_Type_Array_Element (Get_Enode_Type (O_Enode (Arr))); - In_Type := Get_Enode_Type (Index); - - if Flag_Debug_Assert then - Check_Ref (Index); - Check_Ref (Arr); - end if; - - -- result := arr + index * sizeof (element). - El_Size := Get_Type_Size (El_Type); - if El_Size = 1 then - Sz := Index; - elsif Get_Expr_Kind (Index) = OE_Const then - -- FIXME: may recycle previous index? - Sz := New_Const_U32 (Get_Expr_Low (Index) * El_Size, In_Type); - else - if Is_Pow2 (El_Size) then - Sz := New_Const_U32 (Extract_Pow2 (El_Size), In_Type); - Sz := New_Enode (OE_Shl, In_Type, Index, Sz); - else - Sz := New_Const_U32 (El_Size, In_Type); - Sz := New_Enode (OE_Mul, In_Type, Index, Sz); - end if; - end if; - return O_Lnode (New_Enode (OE_Add, Abi.Mode_Ptr, Res_Type, - O_Enode (Arr), Sz)); - end New_Index_Slice_Element; - - function New_Hli_Index_Slice - (Kind : OE_Kind; Res_Type : O_Tnode; Arr : O_Lnode; Index : O_Enode) - return O_Lnode - is - begin - if Flag_Debug_Assert then - Check_Ref (Index); - Check_Ref (Arr); - end if; - return O_Lnode (New_Enode (Kind, Res_Type, O_Enode (Arr), Index)); - end New_Hli_Index_Slice; - - -- Get an element of an array. - -- INDEX must be of the type of the array index. - function New_Indexed_Element (Arr : O_Lnode; Index : O_Enode) - return O_Lnode - is - El_Type : O_Tnode; - begin - El_Type := Get_Type_Array_Element (Get_Enode_Type (O_Enode (Arr))); - - if Flag_Debug_Hli then - return New_Hli_Index_Slice (OE_Index_Ref, El_Type, Arr, Index); - else - return New_Index_Slice_Element (Arr, Index, El_Type); - end if; - end New_Indexed_Element; - - -- Get a slice of an array; this is equivalent to a conversion between - -- an array or an array subtype and an array subtype. - -- RES_TYPE must be an array_sub_type whose base type is the same as the - -- base type of ARR. - -- INDEX must be of the type of the array index. - function New_Slice (Arr : O_Lnode; Res_Type : O_Tnode; Index : O_Enode) - return O_Lnode - is - begin - if Flag_Debug_Hli then - return New_Hli_Index_Slice (OE_Slice_Ref, Res_Type, Arr, Index); - else - return New_Index_Slice_Element (Arr, Index, Res_Type); - end if; - end New_Slice; - - function New_Selected_Element (Rec : O_Lnode; El : O_Fnode) - return O_Lnode - is - Offset : Uns32; - Off : O_Enode; - Res_Type : O_Tnode; - begin - if Flag_Debug_Assert then - Check_Ref (Rec); - end if; - - Res_Type := Get_Field_Type (El); - if Flag_Debug_Hli then - return O_Lnode (New_Enode (OE_Record_Ref, Res_Type, - O_Enode (Rec), O_Enode (El))); - else - Offset := Get_Field_Offset (El); - if Offset = 0 then - return O_Lnode (New_Enode (OE_Conv_Ptr, Abi.Mode_Ptr, Res_Type, - O_Enode (Rec), O_Enode (Res_Type))); - else - Off := New_Enode (OE_Const, Mode_U32, O_Tnode_Null, - O_Enode (Offset), O_Enode_Null); - - return O_Lnode (New_Enode (OE_Add, Abi.Mode_Ptr, Res_Type, - O_Enode (Rec), Off)); - end if; - end if; - end New_Selected_Element; - - function New_Access_Element (Acc : O_Enode) return O_Lnode - is - Acc_Type : O_Tnode; - Res_Type : O_Tnode; - begin - Acc_Type := Get_Enode_Type (Acc); - - if Flag_Debug_Assert then - if Get_Type_Kind (Acc_Type) /= OT_Access then - raise Syntax_Error; - end if; - Check_Ref (Acc); - end if; - - Res_Type := Get_Type_Access_Type (Acc_Type); - if Flag_Debug_Hli then - return O_Lnode (New_Enode (OE_Access_Ref, Abi.Mode_Ptr, Res_Type, - Acc, O_Enode_Null)); - else - return O_Lnode (New_Enode (OE_Conv_Ptr, Abi.Mode_Ptr, Res_Type, - Acc, O_Enode (Res_Type))); - end if; - end New_Access_Element; - - function New_Convert_Ov (Val : O_Enode; Rtype : O_Tnode) return O_Enode is - begin - if Flag_Debug_Assert then - Check_Ref (Val); - end if; - - return New_Enode (OE_Conv, Rtype, Val, O_Enode (Rtype)); - end New_Convert_Ov; - - function New_Unchecked_Address (Lvalue : O_Lnode; Atype : O_Tnode) - return O_Enode is - begin - if Flag_Debug_Assert then - if Get_Type_Kind (Atype) /= OT_Access then - raise Syntax_Error; - end if; - Check_Ref (Lvalue); - end if; - - return New_Enode (OE_Conv_Ptr, Abi.Mode_Ptr, Atype, - O_Enode (Lvalue), O_Enode (Atype)); - end New_Unchecked_Address; - - function New_Address (Lvalue : O_Lnode; Atype : O_Tnode) return O_Enode is - begin - if Flag_Debug_Assert then - if Get_Type_Kind (Atype) /= OT_Access then - raise Syntax_Error; - end if; - if Get_Base_Type (Get_Enode_Type (O_Enode (Lvalue))) - /= Get_Base_Type (Get_Type_Access_Type (Atype)) - then - raise Syntax_Error; - end if; - Check_Ref (Lvalue); - end if; - - return New_Enode (OE_Conv_Ptr, Abi.Mode_Ptr, Atype, - O_Enode (Lvalue), O_Enode (Atype)); - end New_Address; - - function New_Subprogram_Address (Subprg : O_Dnode; Atype : O_Tnode) - return O_Enode is - begin - raise Program_Error; - return O_Enode_Null; - end New_Subprogram_Address; - - function New_Value (Lvalue : O_Lnode) return O_Enode - is - V_Type : O_Tnode; - begin - V_Type := Get_Enode_Type (O_Enode (Lvalue)); - - if Flag_Debug_Assert then - Check_Ref (Lvalue); - end if; - - return New_Enode (OE_Indir, V_Type, O_Enode (Lvalue), O_Enode_Null); - end New_Value; - - function New_Alloca (Rtype : O_Tnode; Size : O_Enode) return O_Enode - is - Save_Var : O_Dnode; - Stmt : O_Enode; - St_Type : O_Tnode; - begin - if Flag_Debug_Assert then - Check_Ref (Size); - if Get_Type_Kind (Rtype) /= OT_Access then - raise Syntax_Error; - end if; - if Get_Type_Kind (Get_Enode_Type (Size)) /= OT_Unsigned then - raise Syntax_Error; - end if; - end if; - - if not Get_Block_Has_Alloca (Cur_Block) then - Set_Block_Has_Alloca (Cur_Block, True); - if Stack_Ptr_Type /= O_Tnode_Null then - St_Type := Stack_Ptr_Type; - else - St_Type := Rtype; - end if; - -- Add a decl. - New_Var_Decl (Save_Var, O_Ident_Nul, O_Storage_Local, St_Type); - -- Add insn to save stack ptr. - Stmt := New_Enode (OE_Asgn, St_Type, - New_Stack (St_Type), - O_Enode (New_Obj (Save_Var))); - if Cur_Block = Last_Stmt then - Set_Stmt_Link (Last_Stmt, Stmt); - Last_Stmt := Stmt; - else - Set_Stmt_Link (Stmt, Get_Stmt_Link (Cur_Block)); - Set_Stmt_Link (Cur_Block, Stmt); - end if; - end if; - - return New_Enode (OE_Alloca, Rtype, Size, O_Enode (Rtype)); - end New_Alloca; - - procedure Start_Association (Assocs : out O_Assoc_List; Subprg : O_Dnode) - is - Depth : O_Depth; - Arg : O_Enode; - First_Inter : O_Dnode; - begin - First_Inter := Get_Subprg_Interfaces (Subprg); - if Get_Decl_Storage (Subprg) = O_Storage_Local then - Depth := Get_Decl_Depth (Subprg); - Arg := New_Enode (OE_Arg, Abi.Mode_Ptr, O_Tnode_Ptr, - Get_Static_Chain (Depth - 1), O_Enode_Null); - First_Inter := Get_Interface_Chain (First_Inter); - else - Arg := O_Enode_Null; - end if; - Assocs := (Subprg => Subprg, - First_Arg => Arg, - Last_Arg => Arg, - Next_Inter => First_Inter); - end Start_Association; - - procedure New_Association (Assocs : in out O_Assoc_List; Val : O_Enode) - is - V_Type : O_Tnode; - Mode : Mode_Type; - N_Mode : Mode_Type; - Res : O_Enode; - begin - V_Type := Get_Enode_Type (Val); - - if Flag_Debug_Assert then - if Assocs.Next_Inter = O_Dnode_Null then - -- More assocs than interfaces. - raise Syntax_Error; - end if; - Check_Value_Type (Val, Get_Decl_Type (Assocs.Next_Inter)); - Check_Ref (Val); - end if; - - -- Follow the C convention call: no parameters shorter than int. - Mode := Get_Type_Mode (V_Type); - case Mode is - when Mode_B2 - | Mode_U8 - | Mode_U16 => - N_Mode := Mode_U32; - when Mode_I8 - | Mode_I16 => - N_Mode := Mode_I32; - when Mode_P32 - | Mode_U32 - | Mode_I32 - | Mode_U64 - | Mode_I64 - | Mode_P64 - | Mode_F32 - | Mode_F64 => - N_Mode := Mode; - when Mode_Blk - | Mode_Nil - | Mode_X1 => - raise Program_Error; - end case; - if N_Mode /= Mode and not Flag_Debug_Hli then - Res := New_Enode (OE_Conv, N_Mode, V_Type, Val, O_Enode (V_Type)); - else - Res := Val; - end if; - Res := New_Enode (OE_Arg, N_Mode, V_Type, Res, O_Enode_Null); - if Assocs.Last_Arg /= O_Enode_Null then - Enodes.Table (Assocs.Last_Arg).Arg2 := Res; - else - Assocs.First_Arg := Res; - end if; - Assocs.Last_Arg := Res; - Assocs.Next_Inter := Get_Interface_Chain (Assocs.Next_Inter); - end New_Association; - - function New_Function_Call (Assocs : O_Assoc_List) return O_Enode - is - F_Type : O_Tnode; - begin - if Flag_Debug_Assert then - if Assocs.Next_Inter /= O_Dnode_Null then - -- Not enough assocs. - raise Syntax_Error; - end if; - end if; - - F_Type := Get_Decl_Type (Assocs.Subprg); - return New_Enode (OE_Call, F_Type, - O_Enode (Assocs.Subprg), Assocs.First_Arg); - end New_Function_Call; - - procedure New_Procedure_Call (Assocs : in out O_Assoc_List) is - begin - if Flag_Debug_Assert then - if Assocs.Next_Inter /= O_Dnode_Null then - -- Not enough assocs. - raise Syntax_Error; - end if; - end if; - New_Enode_Stmt (OE_Call, O_Enode (Assocs.Subprg), Assocs.First_Arg); - end New_Procedure_Call; - - procedure New_Assign_Stmt (Target : O_Lnode; Value : O_Enode) - is - V_Type : O_Tnode; - begin - V_Type := Get_Enode_Type (Value); - - if Flag_Debug_Assert then - Check_Value_Type (Value, Get_Enode_Type (O_Enode (Target))); - Check_Ref (Value); - Check_Ref (Target); - end if; - - New_Enode_Stmt (OE_Asgn, Get_Type_Mode (V_Type), - Value, O_Enode (Target)); - end New_Assign_Stmt; - - procedure New_Return_Stmt (Value : O_Enode) - is - V_Type : O_Tnode; - begin - V_Type := Get_Enode_Type (Value); - - if Flag_Debug_Assert then - Check_Ref (Value); - Check_Value_Type (Value, Get_Decl_Type (Cur_Subprg.D_Decl)); - end if; - - New_Enode_Stmt (OE_Ret, Get_Type_Mode (V_Type), Value, O_Enode_Null); - if not Flag_Debug_Hli then - New_Allocb_Jump (Cur_Subprg.Exit_Label); - end if; - end New_Return_Stmt; - - procedure New_Return_Stmt is - begin - if Flag_Debug_Assert then - if Get_Decl_Kind (Cur_Subprg.D_Decl) /= OD_Procedure then - raise Syntax_Error; - end if; - end if; - - if not Flag_Debug_Hli then - New_Allocb_Jump (Cur_Subprg.Exit_Label); - else - New_Enode_Stmt (OE_Ret, Mode_Nil, O_Enode_Null, O_Enode_Null); - end if; - end New_Return_Stmt; - - - procedure Start_If_Stmt (Block : out O_If_Block; Cond : O_Enode) is - begin - if Flag_Debug_Assert then - if Get_Expr_Mode (Cond) /= Mode_B2 then - -- COND must be a boolean. - raise Syntax_Error; - end if; - Check_Ref (Cond); - end if; - - if not Flag_Lower_Stmt then - New_Enode_Stmt (OE_If, Cond, O_Enode_Null); - Block := (Label_End => O_Enode_Null, - Label_Next => Last_Stmt); - else - Block := (Label_End => O_Enode_Null, - Label_Next => New_Label); - Emit_Jmp (OE_Jump_F, Cond, Block.Label_Next); - Start_BB; - end if; - end Start_If_Stmt; - - procedure New_Else_Stmt (Block : in out O_If_Block) is - begin - if not Flag_Lower_Stmt then - New_Enode_Stmt (OE_Else, O_Enode_Null, O_Enode_Null); - else - if Block.Label_End = O_Enode_Null then - Block.Label_End := New_Label; - end if; - Emit_Jmp (OE_Jump, O_Enode_Null, Block.Label_End); - Start_BB; - Link_Stmt (Block.Label_Next); - Block.Label_Next := O_Enode_Null; - end if; - end New_Else_Stmt; - - procedure Finish_If_Stmt (Block : in out O_If_Block) is - begin - if not Flag_Lower_Stmt then - New_Enode_Stmt (OE_Endif, O_Enode_Null, O_Enode_Null); - else - -- Create a badic-block after the IF. - Start_BB; - if Block.Label_Next /= O_Enode_Null then - Link_Stmt (Block.Label_Next); - end if; - if Block.Label_End /= O_Enode_Null then - Link_Stmt (Block.Label_End); - end if; - end if; - end Finish_If_Stmt; - - procedure Start_Loop_Stmt (Label : out O_Snode) is - begin - if not Flag_Lower_Stmt then - New_Enode_Stmt (OE_Loop, O_Enode_Null, O_Enode_Null); - Label := (Label_Start => Last_Stmt, - Label_End => O_Enode_Null); - else - -- Create a basic-block at the beginning of the loop. - Start_BB; - Label.Label_Start := New_Label; - Link_Stmt (Label.Label_Start); - Label.Label_End := New_Label; - end if; - end Start_Loop_Stmt; - - procedure Finish_Loop_Stmt (Label : in out O_Snode) - is - begin - if not Flag_Lower_Stmt then - New_Enode_Stmt (OE_Eloop, Label.Label_Start, O_Enode_Null); - else - Emit_Jmp (OE_Jump, O_Enode_Null, Label.Label_Start); - Start_BB; - Link_Stmt (Label.Label_End); - end if; - end Finish_Loop_Stmt; - - procedure New_Exit_Stmt (L : O_Snode) - is - begin - if not Flag_Lower_Stmt then - New_Enode_Stmt (OE_Exit, O_Enode_Null, L.Label_Start); - else - New_Allocb_Jump (L.Label_End); - end if; - end New_Exit_Stmt; - - procedure New_Next_Stmt (L : O_Snode) - is - begin - if not Flag_Lower_Stmt then - New_Enode_Stmt (OE_Next, O_Enode_Null, L.Label_Start); - else - New_Allocb_Jump (L.Label_Start); - end if; - end New_Next_Stmt; - - procedure Start_Case_Stmt (Block : out O_Case_Block; Value : O_Enode) - is - V_Type : O_Tnode; - Mode : Mode_Type; - Start : O_Enode; - begin - V_Type := Get_Enode_Type (Value); - Mode := Get_Type_Mode (V_Type); - - if Flag_Debug_Assert then - Check_Ref (Value); - case Mode is - when Mode_U8 .. Mode_U64 - | Mode_I8 .. Mode_I64 - | Mode_B2 => - null; - when others => - raise Syntax_Error; - end case; - end if; - - New_Enode_Stmt (OE_Case, Mode, Value, O_Enode_Null); - Start := Enodes.Last; - if Flag_Debug_Hli then - Block := (Expr => Start, - Expr_Type => V_Type, - Last_Node => O_Enode_Null, - Label_End => O_Enode_Null, - Label_Branch => Start); - else - Block := (Expr => Start, - Expr_Type => V_Type, - Last_Node => Start, - Label_End => New_Label, - Label_Branch => O_Enode_Null); - end if; - end Start_Case_Stmt; - - procedure Start_Choice (Block : in out O_Case_Block) - is - B : O_Enode; - begin - if Flag_Debug_Hli then - B := New_Enode (OE_Case_Branch, Mode_Nil, O_Tnode_Null, - O_Enode_Null, O_Enode_Null); - Link_Stmt (B); - -- Link it. - Set_Case_Branch (Block.Label_Branch, B); - Block.Label_Branch := B; - else - -- Jump to the end of the case statement. - -- If there is already a branch open, this is ok - -- (do not fall-through). - -- If there is no branch open, then this is the default choice - -- (nothing to do). - Emit_Jmp (OE_Jump, O_Enode_Null, Block.Label_End); - - -- Create a label for the code of this branch. - Block.Label_Branch := New_Label; - end if; - end Start_Choice; - - procedure Insert_Choice_Stmt (Block : in out O_Case_Block; Stmt : O_Enode) - is - Prev : O_Enode; - begin - Prev := Get_Stmt_Link (Block.Last_Node); - Set_Stmt_Link (Block.Last_Node, Stmt); - Block.Last_Node := Stmt; - if Prev = O_Enode_Null then - Last_Stmt := Stmt; - else - Set_Stmt_Link (Stmt, Prev); - end if; - end Insert_Choice_Stmt; - - procedure Emit_Choice_Jmp (Block : in out O_Case_Block; - Code : OE_Kind; Expr : O_Enode; Label : O_Enode) - is - Jmp : O_Enode; - begin - Jmp := New_Enode (Code, Mode_Nil, O_Tnode_Null, Expr, Label); - Insert_Choice_Stmt (Block, Jmp); - end Emit_Choice_Jmp; - - -- Create a node containing the value of the case expression. - function New_Case_Expr (Block : O_Case_Block) return O_Enode is - begin - return New_Enode (OE_Case_Expr, Block.Expr_Type, - Block.Expr, O_Enode_Null); - end New_Case_Expr; - - procedure New_Hli_Choice (Block : in out O_Case_Block; - Hi, Lo : O_Enode) - is - Res : O_Enode; - begin - Res := New_Enode (OE_Case_Choice, Mode_Nil, O_Tnode_Null, Hi, Lo); - if Block.Label_End = O_Enode_Null then - Set_Case_Branch_Choice (Block.Label_Branch, Res); - else - Set_Case_Choice_Link (Block.Label_End, Res); - end if; - Block.Label_End := Res; - end New_Hli_Choice; - - procedure New_Expr_Choice (Block : in out O_Case_Block; Expr : O_Cnode) - is - Res : O_Enode; - begin - if Flag_Debug_Hli then - New_Hli_Choice (Block, New_Lit (Expr), O_Enode_Null); - else - Res := New_Enode (OE_Eq, Mode_B2, O_Tnode_Null, - New_Case_Expr (Block), New_Lit (Expr)); - Emit_Choice_Jmp (Block, OE_Jump_T, Res, Block.Label_Branch); - end if; - end New_Expr_Choice; - - procedure New_Range_Choice (Block : in out O_Case_Block; - Low, High : O_Cnode) - is - E1 : O_Enode; - E2 : O_Enode; - Label : O_Enode; - begin - if Flag_Debug_Hli then - New_Hli_Choice (Block, New_Lit (Low), New_Lit (High)); - else - -- Internal label. - Label := New_Label; - E1 := New_Enode (OE_Lt, Mode_B2, O_Tnode_Null, - New_Case_Expr (Block), New_Lit (Low)); - Emit_Choice_Jmp (Block, OE_Jump_T, E1, Label); - E2 := New_Enode (OE_Le, Mode_B2, O_Tnode_Null, - New_Case_Expr (Block), New_Lit (High)); - Emit_Choice_Jmp (Block, OE_Jump_T, E2, Block.Label_Branch); - Insert_Choice_Stmt (Block, Label); - end if; - end New_Range_Choice; - - procedure New_Default_Choice (Block : in out O_Case_Block) is - begin - if Flag_Debug_Hli then - New_Hli_Choice (Block, O_Enode_Null, O_Enode_Null); - else - -- Jump to the code. - Emit_Choice_Jmp (Block, OE_Jump, O_Enode_Null, Block.Label_Branch); - end if; - end New_Default_Choice; - - procedure Finish_Choice (Block : in out O_Case_Block) is - begin - if Flag_Debug_Hli then - Block.Label_End := O_Enode_Null; - else - -- Put the label of the branch. - Start_BB; - Link_Stmt (Block.Label_Branch); - end if; - end Finish_Choice; - - procedure Finish_Case_Stmt (Block : in out O_Case_Block) is - begin - if Flag_Debug_Hli then - New_Enode_Stmt (OE_Case_End, O_Enode_Null, O_Enode_Null); - else - -- Jump to the end of the case statement. - -- Note: this is not required, since the next instruction is the - -- label. - -- Emit_Jmp (OE_Jump, O_Enode_Null, Block.Label_End); - - -- Put the label of the end of the case. - Start_BB; - Link_Stmt (Block.Label_End); - Block.Label_End := O_Enode_Null; - end if; - end Finish_Case_Stmt; - - procedure New_Debug_Line_Stmt (Line : Natural) is - begin - New_Enode_Stmt (OE_Line, O_Enode (Line), O_Enode_Null); - end New_Debug_Line_Stmt; - - procedure Debug_Expr (N : O_Enode) - is - use Ada.Text_IO; - use Ortho_Code.Debug.Int32_IO; - Indent : constant Count := Col; - begin - Put (Int32 (N), 0); - Set_Col (Indent + 7); - Disp_Mode (Get_Expr_Mode (N)); - Put (" "); - Put (OE_Kind'Image (Get_Expr_Kind (N))); - Set_Col (Indent + 28); --- Put (Abi.Image_Insn (Get_Expr_Insn (N))); --- Put (" "); - Put (Abi.Image_Reg (Get_Expr_Reg (N))); - Put (" "); - Put (Int32 (Enodes.Table (N).Arg1), 7); - Put (Int32 (Enodes.Table (N).Arg2), 7); - Put (Enodes.Table (N).Info, 7); - New_Line; - end Debug_Expr; - - procedure Disp_Subprg_Body (Indent : Natural; Subprg : O_Enode) - is - use Ada.Text_IO; - N : O_Enode; - N_Indent : Natural; - begin - N := Subprg; - if Get_Expr_Kind (N) /= OE_Entry then - raise Program_Error; - end if; - -- Display the entry. - Set_Col (Count (Indent)); - Debug_Expr (N); - -- Display the subprogram, binding. - N_Indent := Indent;-- + 1; - N := N + 1; - loop - case Get_Expr_Kind (N) is - when OE_Entry => - N := Get_Entry_Leave (N) + 1; - when OE_Leave => - Set_Col (Count (Indent)); - Debug_Expr (N); - exit; - when others => - Set_Col (Count (N_Indent)); - Debug_Expr (N); - case Get_Expr_Kind (N) is - when OE_Beg => - Disp_Block (N_Indent + 2, - O_Dnode (Enodes.Table (N).Arg2)); - N_Indent := N_Indent + 1; - when OE_End => - N_Indent := N_Indent - 1; - when others => - null; - end case; - N := N + 1; - end case; - end loop; - end Disp_Subprg_Body; - - procedure Disp_All_Enode is - begin - for I in Enodes.First .. Enodes.Last loop - Debug_Expr (I); - end loop; - end Disp_All_Enode; - - Max_Enode : O_Enode := O_Enode_Null; - - procedure Mark (M : out Mark_Type) is - begin - M.Enode := Enodes.Last; - end Mark; - - procedure Release (M : Mark_Type) is - begin - Max_Enode := O_Enode'Max (Max_Enode, Enodes.Last); - Enodes.Set_Last (M.Enode); - end Release; - - procedure Disp_Stats - is - use Ada.Text_IO; - begin - Max_Enode := O_Enode'Max (Max_Enode, Enodes.Last); - Put ("Number of Enodes:" & O_Enode'Image (Enodes.Last)); - Put (", max:" & O_Enode'Image (Max_Enode)); - New_Line; - end Disp_Stats; - - procedure Free_Subprogram_Data (Data : in out Subprogram_Data_Acc) - is - procedure Free is new Ada.Unchecked_Deallocation - (Subprogram_Data, Subprogram_Data_Acc); - Ch, N_Ch : Subprogram_Data_Acc; - begin - Ch := Data.First_Child; - while Ch /= null loop - N_Ch := Ch.Brother; - Free_Subprogram_Data (Ch); - Ch := N_Ch; - end loop; - Free (Data); - end Free_Subprogram_Data; - - procedure Finish is - begin - Enodes.Free; - Free_Subprogram_Data (First_Subprg); - end Finish; -end Ortho_Code.Exprs; |