B
     \                 @   s  d Z ddlmZmZmZ ddlZddlmZ ddlZddl	m
Z
 ddlmZmZ e
dZe
dZe
d	Ze
ejZe ZedZedZedZedZd
d ZdddZdd Zi ZdddZi fddZG dd de Z!G dd de!Z"G dd de!Z#G dd de Z$ddd Z%dd!d"Z&d#d$ Z'd%d& Z(d'd( Z)d)d* Z*d+d, Z+d-d. Z,d/d0 Z-d1d2 Z.d3d4 Z/e0d5d6Z1edd7d8Z2edd:d;Z3ed<d= Z4edd?d@Z5edAdB Z6ddCdDZ7dEdF Z8ddGdHZ9ddIdJZ:ddKdLZ;dMdN Z<dOdP Z=dQdR Z>dSdT Z?e>Z@e=ZAdUdV ZBdWdX ZCddYdZZDedd[d\ZEeCZFd]d^ ZGd_d` ZHdadb ZIdcdd ZJdedf ZKddgdhZLdidj ZMddldmZNdndo ZOdpdq ZPdrds ZQdtdu ZRddvdwZSddxdyZTdzd{ ZUd|d} ZVd~d ZWdd ZXejYrdd ZZndd ZZdd Z[dS )z+
Generic helpers for LLVM code generation.
    )print_functiondivisionabsolute_importN)contextmanager)ir   )utilsconfig       c             C   s   |  d||dS )Nz!=r   )icmp_unsignedtype)buildervalue r   ,lib/python3.7/site-packages/numba/cgutils.pyas_bool_bit   s    r   c             C   sN   |dkrt dd |D }|t j}x"t|D ]\}}| |||}q0W |S )zH
    Create an anonymous struct containing the given LLVM *values*.
    Nc             S   s   g | ]
}|j qS r   )r   ).0vr   r   r   
<listcomp>%   s    z)make_anonymous_struct.<locals>.<listcomp>)r   LiteralStructType	Undefined	enumerateinsert_value)r   valuesZstruct_typeZ
struct_valir   r   r   r   make_anonymous_struct    s    
r   c             C   s*   t | }t|}tttd||S )z0
    Make a byte array constant from *buf*.
    r
   )	bytearraylenr   Constant	ArrayTypeIntType)Zbufbnr   r   r   make_bytearray,   s    r$   r   c             C   sb   | |f}t |}|dkr^ttd| }|jd t|  }|f}t| d}t|||}|t |< |S )zK
    Returns a specialized StructProxy subclass for the given fe_type.
    N)r   data_)_fe_type)_struct_proxy_cachegetValueStructProxyDataStructProxy__name__strdictr   )Zfe_typeZkindZ	cache_keyresbaseZclsnamebasesZ
clsmembersr   r   r   create_struct_proxy8   s    

r2   c             C   s^   |  }x.|jjD ]"}||t||}t| || qW x | D ]\}}t| || qBW | S )zJ
    Copy structure from *src* to *dst* with replacement from *repl*.
    )copy
_datamodel_fieldspopgetattrsetattritems)dstsrcreplkr   r   r   r   copy_structK   s    r>   c                   s   e Zd ZdZdZd!ddZdd Zdd Zd	d
 Zdd Z	dd Z
dd Zdd Z fddZdd Zdd Zdd Zdd Zdd Zdd  Z  ZS )"_StructProxyz
    Creates a `Structure` like interface that is constructed with information
    from DataModel instance.  FE type must have a data model that is a
    subclass of StructModel.
    Nc             C   s   ddl m} || _| jj| j | _t| j|js@td	| j|| _
| | j| _t| jrbt| |\}}|jj| jkrtd| j |jf |d k	r|j|jjkrtd|jj|jf | j
|| || _|| _d S )Nr   )	datamodelzNot a structure model: {0}z!bad ref type: expected %s, got %sz#bad value type: expected %s, got %s)Znumbar@   _contextZdata_model_managerr'   r4   
isinstanceZStructModel	TypeErrorformat_builder_get_be_type_be_type
is_pointerAssertionError
_make_refsr   pointee
as_pointerstore_value
_outer_ref)selfcontextr   r   refr@   Z	outer_refr   r   r   __init__c   s&    z_StructProxy.__init__c             C   s"   |dkrt | j| jdd}||fS )z
        Return an (outer ref, value ref) pair.  By default, these are
        the same pointers, but a derived class may override this.
        NT)zfill)alloca_oncerE   rG   )rP   rR   r   r   r   rJ   |   s    z_StructProxy._make_refsc             C   s   t d S )N)NotImplementedError)rP   r@   r   r   r   rF      s    z_StructProxy._get_be_typec             C   s   t d S )N)rV   )rP   indexvalr   r   r   _cast_member_to_value   s    z"_StructProxy._cast_member_to_valuec             C   s   t d S )N)rV   )rP   rW   rX   r   r   r   _cast_member_from_value   s    z$_StructProxy._cast_member_from_valuec             C   s   t | j| jd|S )Nr   )gep_inboundsrE   rN   )rP   rW   r   r   r   _get_ptr_by_index   s    z_StructProxy._get_ptr_by_indexc             C   s   | j |}| |S )N)r4   get_field_positionr\   )rP   attrnamerW   r   r   r   _get_ptr_by_name   s    z_StructProxy._get_ptr_by_namec             C   s&   | ds| | j| S t|dS )z;
        Load the LLVM value of the named *field*.
        r&   N)
startswithr4   r]   AttributeError)rP   fieldr   r   r   __getattr__   s    
z_StructProxy.__getattr__c                s0   | drtt| ||S || | j|< dS )z@
        Store the LLVM *value* into the named *field*.
        r&   N)r`   superr?   __setattr__r4   r]   )rP   rb   r   )	__class__r   r   re      s    
z_StructProxy.__setattr__c             C   s   | j | |}| ||S )z>
        Load the LLVM value of the field at *index*.
        )rE   loadr\   rY   )rP   rW   Z
member_valr   r   r   __getitem__   s    z_StructProxy.__getitem__c             C   s   |  |}| ||}|j|jjkr|t|jrft|jjrf|jj|jjjkrf| j| j||jjj}nt	dj
||| |d| j|| dS )zC
        Store the LLVM *value* into the field at *index*.
        zjInvalid store of {value.type} to {ptr.type.pointee} in {self._datamodel} (trying to write member #{index}))r   ptrrP   rW   N)r\   rZ   r   rK   rH   rA   ZaddrspacecastrE   Z	addrspacerC   rD   rM   )rP   rW   r   ri   r   r   r   __setitem__   s    


z_StructProxy.__setitem__c             C   s   | j jS )z.
        Return the number of fields.
        )r4   Zfield_count)rP   r   r   r   __len__   s    z_StructProxy.__len__c             C   s   | j S )zF
        Return the LLVM pointer to the underlying structure.
        )rO   )rP   r   r   r   _getpointer   s    z_StructProxy._getpointerc             C   s   | j | jS )zM
        Load and return the value of the underlying LLVM structure.
        )rE   rg   rO   )rP   r   r   r   	_getvalue   s    z_StructProxy._getvaluec             C   s>   t |jrt|j| jks*t|j| jf| j|| j dS )z4
        Store the value in this structure.
        N)rH   r   rI   rG   rE   rM   rN   )rP   r   r   r   r   	_setvalue   s    z_StructProxy._setvalue)NN)r,   
__module____qualname____doc__r'   rS   rJ   rF   rY   rZ   r\   r_   rc   re   rh   rj   rk   rl   rm   rn   __classcell__r   r   )rf   r   r?   Z   s"   
		r?   c               @   s(   e Zd ZdZdd Zdd Zdd ZdS )	r*   zl
    Create a StructProxy suitable for accessing regular values
    (e.g. LLVM values or alloca slots).
    c             C   s   |  S )N)Zget_value_type)rP   r@   r   r   r   rF      s    zValueStructProxy._get_be_typec             C   s   |S )Nr   )rP   rW   rX   r   r   r   rY      s    z&ValueStructProxy._cast_member_to_valuec             C   s   |S )Nr   )rP   rW   rX   r   r   r   rZ      s    z(ValueStructProxy._cast_member_from_valueN)r,   ro   rp   rq   rF   rY   rZ   r   r   r   r   r*      s   r*   c               @   s(   e Zd ZdZdd Zdd Zdd ZdS )	r+   zO
    Create a StructProxy suitable for accessing data persisted in memory.
    c             C   s   |  S )N)Zget_data_type)rP   r@   r   r   r   rF      s    zDataStructProxy._get_be_typec             C   s   | j |}|| j|S )N)r4   	get_modelZ	from_datarE   )rP   rW   rX   modelr   r   r   rY      s    z%DataStructProxy._cast_member_to_valuec             C   s   | j |}|| j|S )N)r4   rs   Zas_datarE   )rP   rW   rX   rt   r   r   r   rZ      s    z'DataStructProxy._cast_member_from_valueN)r,   ro   rp   rq   rF   rY   rZ   r   r   r   r   r+      s   r+   c                   sr   e Zd ZdZdddZdd Zdd	 Zd
d Z fddZdd Z	dd Z
dd Zdd Zdd Zdd Z  ZS )	Structurezs
    A high-level object wrapping a alloca'ed LLVM structure, including
    named fields and attribute access.
    NFc       
      C   s4  | | | _|| _|| _|d krtt|| jdd| _|d k	rt|jrHt|j| jksdt|j| jf|	|| j n\|d kstt|jst| j|jj
kr|r||| j }ntd|jj
| jf || _i | _g | _g | _td}xDt| jD ]6\}\}}	|| j|< | j|t|f | j|	 qW d S )NT)rT   z-mismatching pointer type: got %s, expected %sr   )Zget_struct_type_typerA   rE   rU   rN   rH   r   rI   rM   rK   bitcastrL   rC   _namemap_fdmapZ_typemapint32_tr   r5   append)
rP   rQ   r   r   rR   Zcast_refr0   r   r=   tpr   r   r   rS     s4    
zStructure.__init__c             C   s   | j j| j| j| dd}|S )NT)inbounds)rE   geprN   ry   )rP   rW   ri   r   r   r   r\   $  s    zStructure._get_ptr_by_indexc             C   s   |  | j| S )N)r\   rx   )rP   r^   r   r   r   r_   (  s    zStructure._get_ptr_by_namec             C   s$   | ds| | j|  S t|dS )z;
        Load the LLVM value of the named *field*.
        r&   N)r`   rx   ra   )rP   rb   r   r   r   rc   +  s    
zStructure.__getattr__c                s.   | drtt| ||S || | j| < dS )z@
        Store the LLVM *value* into the named *field*.
        r&   N)r`   rd   ru   re   rx   )rP   rb   r   )rf   r   r   re   4  s    
zStructure.__setattr__c             C   s   | j | |S )z>
        Load the LLVM value of the field at *index*.
        )rE   rg   r\   )rP   rW   r   r   r   rh   <  s    zStructure.__getitem__c             C   sN   |  |}|jj|jkr<d}t||t|jjt|jf | j|| dS )zC
        Store the LLVM *value* into the field at *index*.
        z:Type mismatch: __setitem__(%d, ...) expected %r but got %rN)r\   r   rK   rI   r-   rE   rM   )rP   rW   r   ri   Zfmtr   r   r   rj   C  s    

zStructure.__setitem__c             C   s
   t | jS )z.
        Return the number of fields.
        )r   rx   )rP   r   r   r   rk   O  s    zStructure.__len__c             C   s   | j S )zF
        Return the LLVM pointer to the underlying structure.
        )rN   )rP   r   r   r   rl   U  s    zStructure._getpointerc             C   s   | j | jS )zM
        Load and return the value of the underlying LLVM structure.
        )rE   rg   rN   )rP   r   r   r   rm   [  s    zStructure._getvaluec             C   s>   t |jrt|j| jks*t|j| jf| j|| j dS )z!Store the value in this structureN)rH   r   rI   rv   rE   rM   rN   )rP   r   r   r   r   rn   a  s    zStructure._setvalue)NNF)r,   ro   rp   rq   rS   r\   r_   rc   re   rh   rj   rk   rl   rm   rn   rr   r   r   )rf   r   ru      s   
	ru    Fc          	   C   sh   t |tjrtt|}|  * | j|||d}|rF| |d| W dQ R X |rd| |d| |S )aa  Allocate stack memory at the entry block of the current function
    pointed by ``builder`` withe llvm type ``ty``.  The optional ``size`` arg
    set the number of element to allocate.  The default is 1.  The optional
    ``name`` arg set the symbol name inside the llvm IR for debugging.
    If ``zfill`` is set, also filling zeros to the memory.
    )sizenameN)	rB   r   	INT_TYPESr   r   intp_tZgoto_entry_blockZallocarM   )r   tyr   r   rT   ri   r   r   r   rU   j  s    
rU   c             C   s   t | |j}| || |S )z
    Like alloca_once(), but passing a *value* instead of a type.  The
    type is inferred and the allocated slot is also initialized with the
    given value.
    )rU   r   rM   )r   r   r   Zstorager   r   r   alloca_once_value~  s    r   c             C   s*   | j ||d}|jd |jd |S )z_
    Insert a pure function (in the functional programming sense) in the
    given module.
    )r   readonlyZnounwind)Zget_or_insert_functionZ
attributesadd)modulefntyr   fnr   r   r   insert_pure_function  s    r   c             C   s   | j }|jd kr| | d S )N)basic_block
terminatorbranch)r   bbendZbbr   r   r   	terminate  s    
r   c             C   s   | d S )Nr   )Zltyper   r   r   get_null_value  s    r   c             C   s   t |j}| d||S )Nz==)r   r   r   )r   rX   nullr   r   r   is_null  s    
r   c             C   s   t |j}| d||S )Nz!=)r   r   r   )r   rX   r   r   r   r   is_not_null  s    
r   c             C   s   | j |ddS )NF)likely)if_then)r   predr   r   r   if_unlikely  s    r   c             C   s   | j |ddS )NT)r   )r   )r   r   r   r   r   	if_likely  s    r   c             C   s   |  | |S )N)r   not_)r   r   r   r   r   ifnot  s    r   c             C   s   | d}| j||dgdS )z#
    Increment an index *val*.
    r   Znsw)flags)r   r   )r   rX   oner   r   r   increment_index  s    
r   Loop)rW   do_breakc          	   #   s   |dkr|j }|dkr|d}|}d}d}d  fdd}j}| |0 j|dd	}	d
|	|}
|
|  W dQ R X |, t|	|V  j}t	|	}t
| W dQ R X |	|| |	||   dS )a  
    Generate LLVM IR for a for-loop in [start, count).
    *start* is equal to 0 by default.

    Yields a Loop namedtuple with the following members:
    - `index` is the loop index's value
    - `do_break` is a no-argument callable to break out of the loop
    Nr   zfor.condzfor.bodyzfor.endc                  s      d S )N)r   r   )r   r   r   r   r     s    zfor_range.<locals>.do_breakz
loop.index)r   <)r   append_basic_blockr   r   
goto_blockphiicmp_signedcbranchr   r   r   add_incomingposition_at_end)r   countstartintpstopbbcondbbbodyr   bbstartrW   r   incrr   )r   r   r   	for_range  s.    





r   Tc          	   c   s*  |dkr|j }| d}| d}| d}| j}	| | | |R | j|dd}
| j|dd}|rx| d|
|}n| d	|
|}| ||| W dQ R X | |6 |
|fV  | j}| |
|}t	| |}t
| | W dQ R X |
||	 |
|| |t|d
|	 ||| | | dS )aY  
    Generate LLVM IR for a for-loop based on a slice.  Yields a
    (index, count) tuple where `index` is the slice index's value
    inside the loop, and `count` the iteration count.

    Parameters
    -------------
    builder : object
        Builder object
    start : int
        The beginning value of the slice
    stop : int
        The end value of the slice
    step : int
        The step value of the slice
    intp :
        The data type
    inc : boolean, optional
        Signals whether the step is positive (True) or negative (False).

    Returns
    -----------
        None
    Nzfor.condzfor.bodyzfor.endz
loop.index)r   z
loop.countr   >r   )r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )r   r   r   stepr   incr   r   r   r   rW   r   r   r   Z
next_countr   r   r   for_range_slice  s2    





r   c          	   c   s   |j }| d|t|d}t| ||||dd}t| ||||dd}tdd }| j|dd \}	}
||	|||
|fV  W d	Q R X d	S )
a  
    A helper wrapper for for_range_slice().  This is a context manager which
    yields two for_range_slice()-alike context managers, the first for
    the positive step case, the second for the negative step case.

    Use:
        with for_range_slice_generic(...) as (pos_range, neg_range):
            with pos_range as (idx, count):
                ...
            with neg_range as (idx, count):
                ...
    z>=r   T)r   Fc          
   s   s*   |  |}|V  W d Q R X W d Q R X d S )Nr   )condZinner_cmr   r   r   r   cm_cond<  s    z(for_range_slice_generic.<locals>.cm_cond)r   N)r   r   r   r   r   r   if_else)r   r   r   r   r   Zis_pos_stepZpos_for_rangeZneg_for_ranger   ZthenZ	otherwiser   r   r   for_range_slice_generic(  s    r   Cc          	   c   sp   |dkst |sdV  nT|dkr*dd }ndd }t| |||$}t|t|ksXt ||V  W dQ R X dS )a  
    Generate a loop nest walking a N-dimensional array.
    Yields a tuple of N indices for use in the inner loop body,
    iterating over the *shape* space.

    If *order* is 'C' (the default), indices are incremented inside-out
    (i.e. (0,0), (0,1), (0,2), (1,0) etc.).
    If *order* is 'F', they are incremented outside-in
    (i.e. (0,0), (1,0), (2,0), (0,1) etc.).
    This has performance implications when walking an array as it impacts
    the spatial locality of memory accesses.
    CFr   Fc             S   s   | d d d S )Nr   )xr   r   r   <lambda>Z  s    zloop_nest.<locals>.<lambda>c             S   s   | S )Nr   )r   r   r   r   r   \  s    N)rI   
_loop_nestr   )r   shaper   orderZ_swapindicesr   r   r   	loop_nestF  s    
r   c          
   c   sh   t | |d |dL}t|dkrPt| |dd  |}|jf| V  W d Q R X n
|jfV  W d Q R X d S )Nr   )r   r   )r   r   r   rW   )r   r   r   loopr   r   r   r   r   b  s
    r   c             C   sT   t |}|dkr|d j}t||tj}x"t|D ]\}}| |||}q6W |S )z
    Pack a sequence of values in a LLVM array.  *ty* should be given
    if the array may be empty, in which case the type can't be inferred
    from the values.
    Nr   )r   r   r   r    r   r   r   )r   r   r   r#   aryr   r   r   r   r   
pack_arrayl  s    
r   c             C   sF   t dd |D }|t j}x"t|D ]\}}| |||}q(W |S )z7
    Pack a sequence of values into a LLVM struct.
    c             S   s   g | ]
}|j qS r   )r   )r   r   r   r   r   r     s    zpack_struct.<locals>.<listcomp>)r   r   r   r   r   )r   r   Zstructtystr   r   r   r   r   pack_struct{  s
    
r   c                s0   |dkrt jj} fddt|D }|S )zH
    Unpack an array or structure of values, return a Python tuple.
    Nc                s   g | ]}  |qS r   )extract_value)r   r   )r   tupr   r   r     s   z unpack_tuple.<locals>.<listcomp>)r   r   elementsrange)r   r   r   Zvalsr   )r   r   r   unpack_tuple  s
    r   c          	   C   s>   t | |j|jd}t | |j|jd}t| |j|||j||dS )N)r   )r%   r   strideslayoutinds
wraparound)r   r   ndimr   get_item_pointer2r%   r   )r   Zarytyr   r   r   Zshapesr   r   r   r   get_item_pointer  s
    
r   c                s  |rZg }xTt ||D ]@\}}	 d||d}
 |	|} |
||}|| qW n|}|st |tdgS |d j}|dkrg }|dkrxtt	|D ]<}|d}x$||d d  D ]} 
||}qW || qW n`|dkr<xTtt	|D ]:}|d}x"|d | D ]} 
||}qW || qW ntd|d}x0t ||D ]"\}} 
||} ||}qXW  ||g}|S  fdd	t ||D }t j|}t ||S d S )
Nr   r   r   r   r   r   Zunreachablec                s   g | ]\}}  ||qS r   )mul)r   sr   )r   r   r   r     s    z%get_item_pointer2.<locals>.<listcomp>)zipr   r   r   Zselectr{   r~   rz   r   r   r   	Exception	functoolsreducepointer_add)r   r%   r   r   r   r   r   r   indZdimlennegativewrappedZselectedr   Zstepsr   ZlastjZlocr   Ztmpri   Zdimoffsoffsetr   )r   r   r     sF    


r   c             C   s\   | d}t|j tjtjfr*|||}n.t|j tjrH| |||}ntd|j f |S )Nr   zunexpected value type %s)r   rB   r   Z	FloatTypeZ
DoubleTyper!   r   rC   )r   r   ZfpredZicondZnullvalZisnullr   r   r   _scalar_pred_against_zero  s    
r   c             C   s   t | |t| jddS )zK
    Return a predicate representing whether *value* is equal to zero.
    z==)r   r   partialfcmp_ordered)r   r   r   r   r   is_scalar_zero  s    r   c             C   s   t | |t| jddS )z
    Return a predicate representin whether a *value* is not equal to zero.
    (not exactly "not is_scalar_zero" because of nans)
    z!=)r   r   r   fcmp_unordered)r   r   r   r   r   is_not_scalar_zero  s    r   c             C   s   t | |t| jddS )z]
    Return a predicate representing whether *value* is equal to either zero
    or NaN.
    z==)r   r   r   r   )r   r   r   r   r   is_scalar_zero_or_nan  s    r   c             C   s   t | |t| jddS )z:
    Is *value* negative?  Assumes *value* is signed.
    r   )r   r   r   r   )r   r   r   r   r   is_scalar_neg  s    r   c          	   C   sL   |j t||dd. |d }|dd p,d}| j||| W dQ R X dS )zu
    Guard against *value* being null or zero.
    *exc_tuple* should be a (exception type, arguments...) tuple.
    F)r   r   r   N)r   r   	call_convreturn_user_exc)rQ   r   r   Z	exc_tupleexcexc_argsr   r   r   
guard_null  s    r   c          	   C   sZ   t |jtjst|j|r"|fnd}|jt||dd | j|t	| W dQ R X dS )zG
    Guard against *pointer* being NULL (and raise a MemoryError).
    r   F)r   N)
rB   r   r   PointerTyperI   r   r   r   r   MemoryError)rQ   r   Zpointermsgr   r   r   r   guard_memory_error	  s    r   c          	   c   s*   | j t| ||d dV  W dQ R X dS )z>
    Execute the given block if the scalar value is zero.
    )r   N)r   r   )r   r   r   r   r   r   if_zero  s    r   c             C   s   t | tjS )z7
    Whether the LLVM type *typ* is a struct type.
    )rB   r   r   )Zltypr   r   r   rH     s    rH   c             C   s.   t | |d|}t|jjrt| || S )Nr   )r[   rH   r   rK   rI   rw   rL   )r   recordr   typZpvalr   r   r   get_record_member&  s    r   c             C   s   |  d||dS )Nr   r   )r   r   )r   rX   r   r   r   
is_neg_int,  s    r   c             O   s   t | |f|ddi|S )z8
    Same as *gep*, but add the `inbounds` keyword.
    r}   T)r~   )r   ri   r   kwsr   r   r   r[   0  s    r[   c       	      O   sh   | dd}| dd}|r tg }x0|D ](}t|tjrDt|}n|}|| q*W | j||||dS )z
    Emit a getelementptr instruction for the given pointer and indices.
    The indices can be LLVM values or Python int constants.
    r   r   r}   F)r   r}   )r6   rI   rB   r   r   rz   r{   r~   )	r   ri   r   r   r   r}   idxr   r   r   r   r   r~   7  s    

r~   c             C   s>   |  |t}t|tjr t|}| ||}| ||p:|jS )z
    Add an integral *offset* to pointer *ptr*, and return a pointer
    of *return_type* (or, if omitted, the same type as *ptr*).

    Note the computation is done in bytes, and ignores the width of
    the pointed item type.
    )Zptrtointr   rB   r   r   r   Zinttoptrr   )r   ri   r   Zreturn_typeZintptrr   r   r   r   J  s
    r   c          	   C   sT   | j dt|jf}| |t}t|tr2t|}| ||||t	dt
dg dS )z=
    Fill *size* bytes starting from *ptr* with *value*.
    zllvm.memsetr   N)r   declare_intrinsic	voidptr_tr   rw   rB   intint8_tcallrz   bool_t)r   ri   r   r   r   r   r   r   memsetY  s
    
r   internalc             C   s>   t | tjr| }n| j}|j|j|d}||_d|_||_|S )zO
    Get or create a (LLVM module-)global constant with *name* or *value*.
    )r   T)	rB   r   ZModuler   Zadd_global_variabler   linkageglobal_constantZinitializer)Zbuilder_or_moduler   r   r  r   r%   r   r   r   r  d  s    r  c       
   
   C   s   |dkst ||}|d}t| |j}| t| |n\}}| | ||}| || W dQ R X |2 | ||}| ||}| | ||| W dQ R X W dQ R X | 	|}| || 
||}	||	fS )a  
    Compute the (quotient, remainder) of *val* divided by the constant
    positive *divisor*.  The semantics reflects those of Python integer
    floor division, rather than C's / LLVM's signed division and modulo.
    The difference lies with a negative *val*.
    r   r   N)rI   r   rU   r   r   ZsdivrM   r   subrg   r   )
r   rX   Zdivisorr   ZquotZif_negZif_posZquot_valZval_plus_oneZrem_valr   r   r   divmod_by_constants  s    

(
r  c             C   s&   |  d}| ||| | | |S )z
    Branch conditionally or continue.

    Note: a new block is created and builder is moved to the end of the new
          block.
    z	.continue)r   r   r   )r   r   ZbbtrueZbbcontr   r   r   cbranch_or_continue  s    

r  c          	   C   sb   |j |j kstt| ||j d8}| ||jg}| ||jg}| | || W dQ R X dS )z
    Emit a memcpy to the builder.

    Copies each element of dst to src. Unlike the C equivalent, each element
    can be any LLVM type.

    Assumes
    -------
    * dst.type == src.type
    * count is positive
    )r   N)r   rI   r   r~   rW   rM   rg   )r   r:   r;   r   r   Zout_ptrZin_ptrr   r   r   memcpy  s
    r  c       
   	   C   sz   |j }t|tjrt||}| j|tt|g}tt	d|}t
}	| || |t| |t| ||||	g d S )Nr   )r   rB   r   r   r   r   r   r   r   r!   	false_bitr   rw   r   )
r   Z	func_namer:   r;   r   itemsizealignZsize_tr  Zis_volatiler   r   r   _raw_memcpy  s    

r  c             C   s   t | d|||||S )za
    Emit a raw memcpy() call for `count` items of size `itemsize`
    from `src` to `dest`.
    zllvm.memcpy)r  )r   r:   r;   r   r	  r
  r   r   r   
raw_memcpy  s    r  c             C   s   t | d|||||S )zb
    Emit a raw memmove() call for `count` items of size `itemsize`
    from `src` to `dest`.
    zllvm.memmove)r  )r   r:   r;   r   r	  r
  r   r   r   raw_memmove  s    r  c       
      C   sX   |  ||}| |d}| |d}| ||}| |d}| || |d}	||	fS )zq
    Compute (a * b + c) and return a (result, overflow bit) pair.
    The operands must be signed integers.
    r   r   )Zsmul_with_overflowr   Zsadd_with_overflowor_)
r   ar"   cpZprodZprod_ovfr   r/   Zovfr   r   r   muladd_with_overflow  s    r  c       
      G   s   t |tst| j}t}t|d d}t|d|}tj	t
|gdd}y|d}W n$ tk
rz   tj||dd}Y nX | ||}	| ||	gt| S )a  
    Calls printf().
    Argument `format` is expected to be a Python string.
    Values to be printed are listed in `args`.

    Note: There is no checking to ensure there is correct number of values
    in `args` and there type matches the declaration in the format string.
     asciiZprintf_formatT)var_argprintf)r   )rB   r-   rI   r   r   r$   encoder  r   FunctionTyperz   
get_globalKeyErrorFunctionrw   r   list)
r   rD   argsmodcstring	fmt_bytes
global_fmtr   r   ptr_fmtr   r   r   r    s    	r  c             G   s   t |tst| j}t}t|d d}t|d|}tj	t
|t|gdd}	d}
tjr^d|
 }
y||
}W n$ tk
r   tj||	|
d}Y nX | ||}| ||||gt| S )	z8Calls libc snprintf(buffer, bufsz, format, ...args)
    r  r  Zsnprintf_formatT)r  snprintfr&   )r   )rB   r-   rI   r   r   r$   r  r  r   r  rz   r   r	   ZIS_WIN32r  r  r  rw   r   r  )r   bufferbufszrD   r  r  r  r   r!  r   Zsymbolr   r"  r   r   r   r#    s     r#  c             G   sV   t |tstttd|}t| |dd}| |t}t	| |t
||f|  |S )zwSimilar to `snprintf()` but the buffer is stack allocated to size *bufsz*.

    Returns the buffer pointer as i8*.
    r
   T)rT   )rB   r   rI   r   r    r!   rU   rw   r   r#  r   )r   r%  rD   r  ZspacetyZspacer$  r   r   r   snprintf_stackbuffer  s    r&  c             C   s   |  ddS )zw
        Normalize the given string to latin1 compatible encoding that is suitable
        for use in LLVM IR.
        utf8latin1)r  decode)textr   r   r   normalize_ir_text$  s    r+  c             C   s   | S )zI
        No-op for python2. Assume there won't be unicode names.
        r   )r*  r   r   r   r+  ,  s    c       
   
   C   s   d}|  |t}t| d|| td}| || }t| |p}| |j	t|}| 
d|td}| | t| d W dQ R X | ||j	g}| |}	t| d|	 W dQ R X t| d dS )	zIDebug print the memory region in *ptr* to *ptr + nbytes*
    as hex.
       zhexdump p=%p n=%zur
   z==r   
Nz %02x)Zzextr   r  r   r!   rw   rL   r   ZuremrW   r   r   r~   rg   )
r   ri   nbytesZbytes_per_lineZbyte_tr   Zdiv_byZdo_new_liner   rX   r   r   r   hexdump3  s    

r/  )N)r   )Nr   F)r   )NN)NT)r   )N)N)F)F)N)F)N)r  )r   )r   )\rq   Z
__future__r   r   r   collections
contextlibr   r   Zllvmliter   r   r   r	   r!   r   r   rz   ZMACHINE_BITSr   rL   r   Ztrue_bitr  Z	true_byteZ
false_byter   r   r$   r(   r2   r>   objectr?   r*   r+   ru   rU   r   r   r   r   r   r   r   r   r   r   
namedtupler   r   r   r   r   r   r   r   r   r   r   r   r   r   r   Zis_trueZis_falser   r   r   r   Z
guard_zerorH   r   r   r[   r~   r   r   r  r  r  r  r  r  r  r  r  r#  r&  ZPY3r+  r/  r   r   r   r   <module>   s   



	
 l

+9



	
2		






