-- Nodes recognizer for ieee.numeric_std and ieee.numeric_bit. -- Copyright (C) 2016 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 GHDL; see the file COPYING. If not, write to the Free -- Software Foundation, 59 Temple Place - Suite 330, Boston, MA -- 02111-1307, USA. with Types; use Types; with Vhdl.Std_Package; with Std_Names; use Std_Names; with Vhdl.Errors; use Vhdl.Errors; with Vhdl.Ieee.Std_Logic_1164; with Vhdl.Utils; use Vhdl.Utils; package body Vhdl.Ieee.Numeric is type Pkg_Kind is (Pkg_Std, Pkg_Bit); type Sign_Kind is (Type_Signed, Type_Unsigned, Type_Log, Type_Slv, Type_Suv); subtype Sign_Num_Kind is Sign_Kind range Type_Signed .. Type_Unsigned; type Arg_Kind is (Arg_Vect, Arg_Scal); type Args_Kind is (Arg_Vect_Vect, Arg_Vect_Scal, Arg_Scal_Vect, Arg_Vect_Log, Arg_Log_Vect); type Binary_Pattern_Type is array (Pkg_Kind, Sign_Num_Kind, Args_Kind) of Iir_Predefined_Functions; type Unary_Pattern_Type is array (Pkg_Kind, Sign_Num_Kind) of Iir_Predefined_Functions; type Shift_Pattern_Type is array (Type_Signed .. Type_Unsigned) of Iir_Predefined_Functions; Add_Patterns : constant Binary_Pattern_Type := (Pkg_Std => (Type_Unsigned => (Arg_Vect_Vect => Iir_Predefined_Ieee_Numeric_Std_Add_Uns_Uns, Arg_Vect_Scal => Iir_Predefined_Ieee_Numeric_Std_Add_Uns_Nat, Arg_Scal_Vect => Iir_Predefined_Ieee_Numeric_Std_Add_Nat_Uns, Arg_Vect_Log => Iir_Predefined_Ieee_Numeric_Std_Add_Uns_Log, Arg_Log_Vect => Iir_Predefined_Ieee_Numeric_Std_Add_Log_Uns), Type_Signed => (Arg_Vect_Vect => Iir_Predefined_Ieee_Numeric_Std_Add_Sgn_Sgn, Arg_Vect_Scal => Iir_Predefined_Ieee_Numeric_Std_Add_Sgn_Int, Arg_Scal_Vect => Iir_Predefined_Ieee_Numeric_Std_Add_Int_Sgn, Arg_Vect_Log => Iir_Predefined_Ieee_Numeric_Std_Add_Sgn_Log, Arg_Log_Vect => Iir_Predefined_Ieee_Numeric_Std_Add_Log_Sgn)), Pkg_Bit => (others => (others => Iir_Predefined_None))); Sub_Patterns : constant Binary_Pattern_Type := (Pkg_Std => (Type_Unsigned => (Arg_Vect_Vect => Iir_Predefined_Ieee_Numeric_Std_Sub_Uns_Uns, Arg_Vect_Scal => Iir_Predefined_Ieee_Numeric_Std_Sub_Uns_Nat, Arg_Scal_Vect => Iir_Predefined_Ieee_Numeric_Std_Sub_Nat_Uns, Arg_Vect_Log => Iir_Predefined_Ieee_Numeric_Std_Sub_Uns_Log, Arg_Log_Vect => Iir_Predefined_Ieee_Numeric_Std_Sub_Log_Uns), Type_Signed => (Arg_Vect_Vect => Iir_Predefined_Ieee_Numeric_Std_Sub_Sgn_Sgn, Arg_Vect_Scal => Iir_Predefined_Ieee_Numeric_Std_Sub_Sgn_Int, Arg_Scal_Vect => Iir_Predefined_Ieee_Numeric_Std_Sub_Int_Sgn, Arg_Vect_Log => Iir_Predefined_Ieee_Numeric_Std_Sub_Sgn_Log, Arg_Log_Vect => Iir_Predefined_Ieee_Numeric_Std_Sub_Log_Sgn)), Pkg_Bit => (others => (others => Iir_Predefined_None))); Mul_Patterns : constant Binary_Pattern_Type := (Pkg_Std => (Type_Unsigned => (Arg_Vect_Vect => Iir_Predefined_Ieee_Numeric_Std_Mul_Uns_Uns, Arg_Vect_Scal => Iir_Predefined_Ieee_Numeric_Std_Mul_Uns_Nat, Arg_Scal_Vect => Iir_Predefined_Ieee_Numeric_Std_Mul_Nat_Uns, Arg_Vect_Log => Iir_Predefined_None, Arg_Log_Vect => Iir_Predefined_None), Type_Signed => (Arg_Vect_Vect => Iir_Predefined_Ieee_Numeric_Std_Mul_Sgn_Sgn, Arg_Vect_Scal => Iir_Predefined_Ieee_Numeric_Std_Mul_Sgn_Int, Arg_Scal_Vect => Iir_Predefined_Ieee_Numeric_Std_Mul_Int_Sgn, Arg_Vect_Log => Iir_Predefined_None, Arg_Log_Vect => Iir_Predefined_None)), Pkg_Bit => (others => (others => Iir_Predefined_None))); Div_Patterns : constant Binary_Pattern_Type := (Pkg_Std => (Type_Unsigned => (Arg_Vect_Vect => Iir_Predefined_Ieee_Numeric_Std_Div_Uns_Uns, Arg_Vect_Scal => Iir_Predefined_Ieee_Numeric_Std_Div_Uns_Nat, Arg_Scal_Vect => Iir_Predefined_Ieee_Numeric_Std_Div_Nat_Uns, Arg_Vect_Log => Iir_Predefined_None, Arg_Log_Vect => Iir_Predefined_None), Type_Signed => (Arg_Vect_Vect => Iir_Predefined_Ieee_Numeric_Std_Div_Sgn_Sgn, Arg_Vect_Scal => Iir_Predefined_Ieee_Numeric_Std_Div_Sgn_Int, Arg_Scal_Vect => Iir_Predefined_Ieee_Numeric_Std_Div_Int_Sgn, Arg_Vect_Log => Iir_Predefined_None, Arg_Log_Vect => Iir
"""
This script makes it possible to use mitmproxy in scenarios where IP spoofing
has been used to redirect connections to mitmproxy. The way this works is that
we rely on either the TLS Server Name Indication (SNI) or the Host header of the
HTTP request. Of course, this is not foolproof - if an HTTPS connection comes
without SNI, we don't know the actual target and cannot construct a certificate
that looks valid. Similarly, if there's no Host header or a spoofed Host header,
we're out of luck as well. Using transparent mode is the better option most of
the time.

Usage:
    mitmproxy
        -p 443
        -s dns_spoofing.py
        # Used as the target location if neither SNI nor host header are present.
        -R http://example.com/
        # To avoid auto rewriting of host header by the reverse proxy target.
        --keep-host-header
    mitmdump
        -p 80
        -R http://localhost:443/

    (Setting up a single proxy instance and using iptables to redirect to it
    works as well)
"""
import re

# This regex extracts splits the host header into host and port.
# Handles the edge case of IPv6 addresses containing colons.
# https://bugzilla.mozilla.org/show_bug.cgi?id=45891
parse_host_header = re.compile(r"^(?P<host>[^:]+|\[.+\])(?::(?P<port>\d+))?$")


class Rerouter:
    def request(self, flow):
        if flow.client_conn.ssl_established:
            flow.request.scheme = "https"
            sni = flow.client_conn.connection.get_servername()
            port = 443
        else:
            flow.request.scheme = "http"
            sni = None
            port = 80

        host_header = flow.request.host_header
        m = parse_host_header.match(host_header)
        if m:
            host_header = m.group("host").strip("[]")
            if m.group("port"):
                port = int(m.group("port"))

        flow.request.host_header = host_header
        flow.request.host = sni or host_header
        flow.request.port = port


addons = [Rerouter()]
Le_Nat_Uns, Arg_Vect_Log => Iir_Predefined_None, Arg_Log_Vect => Iir_Predefined_None), Type_Signed => (Arg_Vect_Vect => Iir_Predefined_Ieee_Numeric_Std_Match_Le_Sgn_Sgn, Arg_Vect_Scal => Iir_Predefined_Ieee_Numeric_Std_Match_Le_Sgn_Int, Arg_Scal_Vect => Iir_Predefined_Ieee_Numeric_Std_Match_Le_Int_Sgn, Arg_Vect_Log => Iir_Predefined_None, Arg_Log_Vect => Iir_Predefined_None)), Pkg_Bit => (others => (others => Iir_Predefined_None))); Match_Gt_Patterns : constant Binary_Pattern_Type := (Pkg_Std => (Type_Unsigned => (Arg_Vect_Vect => Iir_Predefined_Ieee_Numeric_Std_Match_Gt_Uns_Uns, Arg_Vect_Scal => Iir_Predefined_Ieee_Numeric_Std_Match_Gt_Uns_Nat, Arg_Scal_Vect => Iir_Predefined_Ieee_Numeric_Std_Match_Gt_Nat_Uns, Arg_Vect_Log => Iir_Predefined_None, Arg_Log_Vect => Iir_Predefined_None), Type_Signed => (Arg_Vect_Vect => Iir_Predefined_Ieee_Numeric_Std_Match_Gt_Sgn_Sgn, Arg_Vect_Scal => Iir_Predefined_Ieee_Numeric_Std_Match_Gt_Sgn_Int, Arg_Scal_Vect => Iir_Predefined_Ieee_Numeric_Std_Match_Gt_Int_Sgn, Arg_Vect_Log => Iir_Predefined_None, Arg_Log_Vect => Iir_Predefined_None)), Pkg_Bit => (others => (others => Iir_Predefined_None))); Match_Ge_Patterns : constant Binary_Pattern_Type := (Pkg_Std => (Type_Unsigned => (Arg_Vect_Vect => Iir_Predefined_Ieee_Numeric_Std_Match_Ge_Uns_Uns, Arg_Vect_Scal => Iir_Predefined_Ieee_Numeric_Std_Match_Ge_Uns_Nat, Arg_Scal_Vect => Iir_Predefined_Ieee_Numeric_Std_Match_Ge_Nat_Uns, Arg_Vect_Log => Iir_Predefined_None, Arg_Log_Vect => Iir_Predefined_None), Type_Signed => (Arg_Vect_Vect => Iir_Predefined_Ieee_Numeric_Std_Match_Ge_Sgn_Sgn, Arg_Vect_Scal => Iir_Predefined_Ieee_Numeric_Std_Match_Ge_Sgn_Int, Arg_Scal_Vect => Iir_Predefined_Ieee_Numeric_Std_Match_Ge_Int_Sgn, Arg_Vect_Log => Iir_Predefined_None, Arg_Log_Vect => Iir_Predefined_None)), Pkg_Bit => (others => (others => Iir_Predefined_None))); Neg_Patterns : constant Unary_Pattern_Type := (Pkg_Std => (Type_Unsigned => Iir_Predefined_Ieee_Numeric_Std_Neg_Uns, Type_Signed => Iir_Predefined_Ieee_Numeric_Std_Neg_Sgn), Pkg_Bit => (others => Iir_Predefined_None)); Abs_Patterns : constant Unary_Pattern_Type := (Pkg_Std => (Type_Unsigned => Iir_Predefined_None, Type_Signed => Iir_Predefined_Ieee_Numeric_Std_Abs_Sgn), Pkg_Bit => (others => Iir_Predefined_None)); Not_Patterns : constant Unary_Pattern_Type := (Pkg_Std => (Type_Unsigned => Iir_Predefined_Ieee_Numeric_Std_Not_Uns, Type_Signed => Iir_Predefined_Ieee_Numeric_Std_Not_Sgn), Pkg_Bit => (others => Iir_Predefined_None)); And_Patterns : constant Binary_Pattern_Type := (Pkg_Std => (Type_Unsigned => (Arg_Vect_Vect => Iir_Predefined_Ieee_Numeric_Std_And_Uns_Uns, others => Iir_Predefined_None), Type_Signed => (Arg_Vect_Vect => Iir_Predefined_Ieee_Numeric_Std_And_Sgn_Sgn, others => Iir_Predefined_None)), Pkg_Bit => (others => (others => Iir_Predefined_None))); Or_Patterns : constant Binary_Pattern_Type := (Pkg_Std => (Type_Unsigned => (Arg_Vect_Vect => Iir_Predefined_Ieee_Numeric_Std_Or_Uns_Uns, others => Iir_Predefined_None), Type_Signed => (Arg_Vect_Vect => Iir_Predefined_Ieee_Numeric_Std_Or_Sgn_Sgn, others => Iir_Predefined_None)), Pkg_Bit => (others => (others => Iir_Predefined_None))); Nand_Patterns : constant Binary_Pattern_Type := (Pkg_Std => (Type_Unsigned => (Arg_Vect_Vect => Iir_Predefined_Ieee_Numeric_Std_Nand_Uns_Uns, others => Iir_Predefined_None), Type_Signed => (Arg_Vect_Vect => Iir_Predefined_Ieee_Numeric_Std_Nand_Sgn_Sgn, others => Iir_Predefined_None)), Pkg_Bit => (others => (others => Iir_Predefined_None))); Nor_Patterns : constant Binary_Pattern_Type := (Pkg_Std => (Type_Unsigned => (Arg_Vect_Vect => Iir_Predefined_Ieee_Numeric_Std_Nor_Uns_Uns, others => Iir_Predefined_None), Type_Signed => (Arg_Vect_Vect => Iir_Predefined_Ieee_Numeric_Std_Nor_Sgn_Sgn, others => Iir_Predefined_None)), Pkg_Bit => (others => (others => Iir_Predefined_None))); Xor_Patterns : constant Binary_Pattern_Type := (Pkg_Std => (Type_Unsigned => (Arg_Vect_Vect => Iir_Predefined_Ieee_Numeric_Std_Xor_Uns_Uns, others => Iir_Predefined_None), Type_Signed => (Arg_Vect_Vect => Iir_Predefined_Ieee_Numeric_Std_Xor_Sgn_Sgn, others => Iir_Predefined_None)), Pkg_Bit => (others => (others => Iir_Predefined_None))); Xnor_Patterns : constant Binary_Pattern_Type := (Pkg_Std => (Type_Unsigned => (Arg_Vect_Vect => Iir_Predefined_Ieee_Numeric_Std_Xnor_Uns_Uns, others => Iir_Predefined_None), Type_Signed => (Arg_Vect_Vect => Iir_Predefined_Ieee_Numeric_Std_Xnor_Sgn_Sgn, others => Iir_Predefined_None)), Pkg_Bit => (others => (others => Iir_Predefined_None))); Shl_Patterns : constant Shift_Pattern_Type := (Type_Signed => Iir_Predefined_Ieee_Numeric_Std_Shf_Left_Sgn_Nat, Type_Unsigned => Iir_Predefined_Ieee_Numeric_Std_Shf_Left_Uns_Nat); Shr_Patterns : constant Shift_Pattern_Type := (Type_Signed => Iir_Predefined_Ieee_Numeric_Std_Shf_Right_Sgn_Nat, Type_Unsigned => Iir_Predefined_Ieee_Numeric_Std_Shf_Right_Uns_Nat); Rol_Patterns : constant Shift_Pattern_Type := (Type_Signed => Iir_Predefined_Ieee_Numeric_Std_Rot_Left_Sgn_Nat, Type_Unsigned => Iir_Predefined_Ieee_Numeric_Std_Rot_Left_Uns_Nat); Ror_Patterns : constant Shift_Pattern_Type := (Type_Signed => Iir_Predefined_Ieee_Numeric_Std_Rot_Right_Sgn_Nat, Type_Unsigned => Iir_Predefined_Ieee_Numeric_Std_Rot_Right_Uns_Nat); Sll_Patterns : constant Shift_Pattern_Type := (Type_Signed => Iir_Predefined_Ieee_Numeric_Std_Sll_Sgn_Int, Type_Unsigned => Iir_Predefined_Ieee_Numeric_Std_Sll_Uns_Int); Srl_Patterns : constant Shift_Pattern_Type := (Type_Signed => Iir_Predefined_Ieee_Numeric_Std_Srl_Sgn_Int, Type_Unsigned => Iir_Predefined_Ieee_Numeric_Std_Srl_Uns_Int); Sla_Patterns : constant Shift_Pattern_Type := (Type_Signed => Iir_Predefined_Ieee_Numeric_Std_Sla_Sgn_Int, Type_Unsigned => Iir_Predefined_Ieee_Numeric_Std_Sla_Uns_Int); Sra_Patterns : constant Shift_Pattern_Type := (Type_Signed => Iir_Predefined_Ieee_Numeric_Std_Sra_Sgn_Int, Type_Unsigned => Iir_Predefined_Ieee_Numeric_Std_Sra_Uns_Int); Error : exception; procedure Extract_Declarations (Pkg_Decl : Iir_Package_Declaration; Pkg : Pkg_Kind; Unsigned_Type : out Iir; Signed_Type : out Iir) is procedure Classify_Arg (Arg : Iir; Sign : out Sign_Kind; Kind : out Arg_Kind) is Arg_Type : constant Iir := Get_Type (Arg); begin if Arg_Type = Signed_Type then Sign := Type_Signed; Kind := Arg_Vect; elsif Arg_Type = Unsigned_Type then Sign := Type_Unsigned; Kind := Arg_Vect; elsif Arg_Type = Vhdl.Std_Package.Integer_Subtype_Definition then Sign := Type_Signed; Kind := Arg_Scal; elsif Arg_Type = Vhdl.Std_Package.Natural_Subtype_Definition then Sign := Type_Unsigned; Kind := Arg_Scal; elsif Arg_Type = Ieee.Std_Logic_1164.Std_Ulogic_Type then Sign := Type_Log; Kind := Arg_Scal; elsif Arg_Type = Ieee.Std_Logic_1164.Std_Ulogic_Vector_Type then Sign := Type_Suv; Kind := Arg_Vect; elsif Arg_Type = Ieee.Std_Logic_1164.Std_Logic_Type then Sign := Type_Log; Kind := Arg_Scal; elsif Arg_Type = Ieee.Std_Logic_1164.Std_Logic_Vector_Type then Sign := Type_Slv; Kind := Arg_Vect; else raise Error; end if; end Classify_Arg; Decl : Iir; Def : Iir; Arg1, Arg2 : Iir; Arg1_Sign, Arg2_Sign : Sign_Kind; Arg1_Kind, Arg2_Kind : Arg_Kind; procedure Handle_Binary (Pats : Binary_Pattern_Type) is Kind : Args_Kind; Sign : Sign_Kind; begin if Arg1_Sign = Arg2_Sign then Sign := Arg1_Sign; case Arg1_Kind is when Arg_Vect => case Arg2_Kind is when Arg_Vect => Kind := Arg_Vect_Vect; when Arg_Scal => Kind := Arg_Vect_Scal; end case; when Arg_Scal => case Arg2_Kind is when Arg_Vect => Kind := Arg_Scal_Vect; when Arg_Scal => raise Error; end case; end case; elsif Arg1_Kind = Arg_Vect and Arg2_Sign = Type_Log then Sign := Arg1_Sign; Kind := Arg_Vect_Log; elsif Arg1_Sign = Type_Log and Arg2_Kind = Arg_Vect then Sign := Arg2_Sign; Kind := Arg_Log_Vect; else raise Error; end if; Set_Implicit_Definition (Decl, Pats (Pkg, Sign, Kind)); end Handle_Binary; procedure Handle_Unary (Pats : Unary_Pattern_Type) is begin Set_Implicit_Definition (Decl, Pats (Pkg, Arg1_Sign)); end Handle_Unary; procedure Handle_To_Unsigned is begin if Arg1_Kind = Arg_Scal and Arg1_Sign = Type_Unsigned then if Arg2_Kind = Arg_Scal and Arg2_Sign = Type_Unsigned then Set_Implicit_Definition (Decl, Iir_Predefined_Ieee_Numeric_Std_Touns_Nat_Nat_Uns); elsif Arg2_Kind = Arg_Vect and Arg2_Sign = Type_Unsigned then Set_Implicit_Definition (Decl, Iir_Predefined_Ieee_Numeric_Std_Touns_Nat_Uns_Uns); else raise Error; end if; else raise Error; end if; end Handle_To_Unsigned; procedure Handle_To_Signed is begin if Arg1_Kind = Arg_Scal and Arg1_Sign = Type_Signed then if Arg2_Kind = Arg_Scal and Arg2_Sign = Type_Unsigned then Set_Implicit_Definition (Decl, Iir_Predefined_Ieee_Numeric_Std_Tosgn_Int_Nat_Sgn); elsif Arg2_Kind = Arg_Vect and Arg2_Sign = Type_Signed then Set_Implicit_Definition (Decl, Iir_Predefined_Ieee_Numeric_Std_Tosgn_Int_Sgn_Sgn); else raise Error; end if; else raise Error; end if; end Handle_To_Signed; procedure Handle_To_Integer is begin if Arg1_Kind = Arg_Vect and Arg1_Sign = Type_Unsigned then Set_Implicit_Definition (Decl, Iir_Predefined_Ieee_Numeric_Std_Toint_Uns_Nat); elsif Arg1_Kind = Arg_Vect and Arg1_Sign = Type_Signed then Set_Implicit_Definition (Decl, Iir_Predefined_Ieee_Numeric_Std_Toint_Sgn_Int); else raise Error; end if; end Handle_To_Integer; procedure Handle_Resize is begin if Arg2_Kind = Arg_Scal and Arg2_Sign = Type_Unsigned then if Arg1_Kind = Arg_Vect and Arg1_Sign = Type_Unsigned then Set_Implicit_Definition (Decl, Iir_Predefined_Ieee_Numeric_Std_Resize_Uns_Nat); elsif Arg1_Kind = Arg_Vect and Arg1_Sign = Type_Signed then Set_Implicit_Definition (Decl, Iir_Predefined_Ieee_Numeric_Std_Resize_Sgn_Nat); else raise Error; end if; elsif Arg2_Kind = Arg_Vect then if Arg1_Kind = Arg_Vect and Arg1_Sign = Type_Unsigned and Arg2_Sign = Type_Unsigned then Set_Implicit_Definition (Decl, Iir_Predefined_Ieee_Numeric_Std_Resize_Uns_Uns); elsif Arg1_Kind = Arg_Vect and Arg1_Sign = Type_Signed and Arg2_Sign = Type_Signed then Set_Implicit_Definition (Decl, Iir_Predefined_Ieee_Numeric_Std_Resize_Sgn_Sgn); else raise Error; end if; else raise Error; end if; end Handle_Resize; procedure Handle_Std_Match is Predefined : Iir_Predefined_Functions; begin if Arg1_Kind /= Arg2_Kind or else Arg1_Sign /= Arg2_Sign then raise Error; end if; if Arg1_Kind = Arg_Scal and Arg1_Sign = Type_Log then Predefined := Iir_Predefined_Ieee_Numeric_Std_Match_Log; elsif Arg1_Kind = Arg_Vect then case Arg1_Sign is when Type_Unsigned => Predefined := Iir_Predefined_Ieee_Numeric_Std_Match_Uns; when Type_Signed => Predefined := Iir_Predefined_Ieee_Numeric_Std_Match_Sgn; when Type_Suv => Predefined := Iir_Predefined_Ieee_Numeric_Std_Match_Suv; when Type_Slv => Predefined := Iir_Predefined_Ieee_Numeric_Std_Match_Slv; when Type_Log => raise Error; end case; else raise Error; end if; Set_Implicit_Definition (Decl, Predefined); end Handle_Std_Match; procedure Handle_To_01 is Predefined : Iir_Predefined_Functions; begin if Arg1_Kind /= Arg_Vect or else Arg2_Kind /= Arg_Scal or else Arg2_Sign /= Type_Log then raise Error; end if; case Arg1_Sign is when Type_Unsigned => Predefined := Iir_Predefined_Ieee_Numeric_Std_To_01_Uns; when Type_Signed => Predefined := Iir_Predefined_Ieee_Numeric_Std_To_01_Sgn; when others => raise Error; end case; Set_Implicit_Definition (Decl, Predefined); end Handle_To_01; procedure Handle_Shift (Pats : Shift_Pattern_Type; Sh_Sign : Sign_Kind) is Res : Iir_Predefined_Functions; begin if Arg1_Kind = Arg_Vect and then Arg2_Kind = Arg_Scal and then Arg2_Sign = Sh_Sign then case Arg1_Sign is when Type_Signed | Type_Unsigned => Res := Pats (Arg1_Sign); when others => Res := Iir_Predefined_None; end case; Set_Implicit_Definition (Decl, Res); end if; end Handle_Shift; begin Decl := Get_Declaration_Chain (Pkg_Decl); -- Skip a potential copyright constant. if Decl /= Null_Iir and then Get_Kind (Decl) = Iir_Kind_Constant_Declaration and then (Get_Base_Type (Get_Type (Decl)) = Vhdl.Std_Package.String_Type_Definition) then Decl := Get_Chain (Decl); end if; -- The first declaration should be type Unsigned or Unresolved_Unsigned if not (Decl /= Null_Iir and then Get_Kind (Decl) = Iir_Kind_Type_Declaration and then (Get_Identifier (Decl) = Name_Unsigned or else Get_Identifier (Decl) = Name_Unresolved_Unsigned)) then raise Error; end if; Def := Get_Type_Definition (Decl); if Get_Kind (Def) /= Iir_Kind_Array_Type_Definition then raise Error; end if; Unsigned_Type := Def; -- The second declaration should be type Signed. Decl := Get_Chain (Decl); Decl := Skip_Implicit (Decl); if not (Decl /= Null_Iir and then Get_Kind (Decl) = Iir_Kind_Type_Declaration and then (Get_Identifier (Decl) = Name_Signed or else Get_Identifier (Decl) = Name_Unresolved_Signed)) then raise Error; end if; Def := Get_Type_Definition (Decl); if Get_Kind (Def) /= Iir_Kind_Array_Type_Definition then raise Error; end if; Signed_Type := Def; -- For vhdl 2008, skip subtypes Decl := Get_Chain (Decl); Decl := Skip_Implicit (Decl); while Is_Valid (Decl) loop exit when Get_Kind (Decl) /= Iir_Kind_Subtype_Declaration; Decl := Get_Chain (Decl); end loop; -- Handle functions. while Is_Valid (Decl) loop case Get_Kind (Decl) is when Iir_Kind_Function_Declaration => Arg1 := Get_Interface_Declaration_Chain (Decl); if Is_Null (Arg1) then raise Error; end if; Classify_Arg (Arg1, Arg1_Sign, Arg1_Kind); Arg2 := Get_Chain (Arg1); if Is_Valid (Arg2) then -- Dyadic function. Classify_Arg (Arg2, Arg2_Sign, Arg2_Kind); case Get_Identifier (Decl) is when Name_Op_Plus => Handle_Binary (Add_Patterns); when Name_Op_Minus => Handle_Binary (Sub_Patterns); when Name_Op_Mul => Handle_Binary (Mul_Patterns); when Name_Op_Div => Handle_Binary (Div_Patterns); when Name_Mod => Handle_Binary (Mod_Patterns); when Name_Rem => Handle_Binary (Rem_Patterns); when Name_Op_Equality => Handle_Binary (Eq_Patterns); when Name_Op_Inequality => Handle_Binary (Ne_Patterns); when Name_Op_Less => Handle_Binary (Lt_Patterns); when Name_Op_Less_Equal => Handle_Binary (Le_Patterns); when Name_Op_Greater => Handle_Binary (Gt_Patterns); when Name_Op_Greater_Equal => Handle_Binary (Ge_Patterns); when Name_Minimum => Handle_Binary (Min_Patterns); when Name_Maximum => Handle_Binary (Max_Patterns); when Name_Op_Match_Equality => Handle_Binary (Match_Eq_Patterns); when Name_Op_Match_Inequality => Handle_Binary (Match_Ne_Patterns); when Name_Op_Match_Less => Handle_Binary (Match_Lt_Patterns); when Name_Op_Match_Less_Equal => Handle_Binary (Match_Le_Patterns); when Name_Op_Match_Greater => Handle_Binary (Match_Gt_Patterns); when Name_Op_Match_Greater_Equal => Handle_Binary (Match_Ge_Patterns); when Name_And => Handle_Binary (And_Patterns); when Name_Or => Handle_Binary (Or_Patterns); when Name_Nand => Handle_Binary (Nand_Patterns); when Name_Nor => Handle_Binary (Nor_Patterns); when Name_Xor => Handle_Binary (Xor_Patterns); when Name_Xnor => Handle_Binary (Xnor_Patterns); when Name_To_Bstring | Name_To_Ostring | Name_To_Hstring => null; when Name_To_Unsigned => Handle_To_Unsigned; when Name_To_Signed => Handle_To_Signed; when Name_Resize => Handle_Resize; when Name_Std_Match => Handle_Std_Match; when Name_Shift_Left => Handle_Shift (Shl_Patterns, Type_Unsigned); when Name_Shift_Right => Handle_Shift (Shr_Patterns, Type_Unsigned); when Name_Sll => Handle_Shift (Sll_Patterns, Type_Signed); when Name_Srl => Handle_Shift (Srl_Patterns, Type_Signed); when Name_Sla => Handle_Shift (Sla_Patterns, Type_Signed); when Name_Sra => Handle_Shift (Sra_Patterns, Type_Signed); when Name_Rotate_Left => Handle_Shift (Rol_Patterns, Type_Unsigned); when Name_Rotate_Right => Handle_Shift (Ror_Patterns, Type_Unsigned); when Name_To_01 => Handle_To_01; when others => null; end case; else -- Monadic function. case Get_Identifier (Decl) is when Name_Op_Minus => Handle_Unary (Neg_Patterns); when Name_Not => Handle_Unary (Not_Patterns); when Name_Abs => Handle_Unary (Abs_Patterns); when Name_To_Integer => Handle_To_Integer; when others => null; end case; end if; when Iir_Kind_Non_Object_Alias_Declaration | Iir_Kind_Procedure_Declaration => null; when others => raise Error; end case; Decl := Get_Chain (Decl); end loop; end Extract_Declarations; procedure Extract_Std_Declarations (Pkg : Iir_Package_Declaration) is begin Numeric_Std_Pkg := Pkg; Extract_Declarations (Pkg, Pkg_Std, Numeric_Std_Unsigned_Type, Numeric_Std_Signed_Type); exception when Error => Error_Msg_Sem (+Pkg, "package ieee.numeric_std is ill-formed"); Numeric_Std_Pkg := Null_Iir; Numeric_Std_Unsigned_Type := Null_Iir; Numeric_Std_Signed_Type := Null_Iir; end Extract_Std_Declarations; end Vhdl.Ieee.Numeric;