3
VY]W                 @   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 e
jdZe
jdZe
jd	Ze
jejZej 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j/d5dZ0edd8d9Z1edd;d<Z2ed=d> Z3edd@dAZ4edBdC Z5ddDdEZ6ddFdGZ7ddHdIZ8ddJdKZ9dLdM Z:dNdO Z;dPdQ Z<dRdS Z=e<Z>e;Z?dTdU Z@dVdW ZAddXdYZBeddZd[ZCeAZDd\d] ZEd^d_ ZFd`da ZGdbdc ZHddde ZIddfdgZJdhdi ZKddkdlZLdmdn ZMdodp ZNdqdr ZOdsdt ZPddudvZQddwdxZRdydz ZSd{d| ZTejUrd}d~ ZVndd~ ZVdd ZWdS )z+
Generic helpers for LLVM code generation.
    )print_functiondivisionabsolute_importN)contextmanager)ir   )utils       c             C   s   | j d||jdS )Nz!=r   )icmp_unsignedtype)buildervalue r   ,lib/python3.6/site-packages/numba/cgutils.pyas_bool_bit   s    r   c             C   sN   |dkrt jdd |D }|t j}x"t|D ]\}}| j|||}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   Z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jtjtj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 j|}|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_proxy7   s    

r0   c             C   s^   |j  }x.|jjD ]"}|j|t||}t| || qW x |j 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_structJ   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|| _
| j| j| _t| j sdt| j|\}}|jj| jkrtd| jj |jf |d k	r|j|jjkrtd|jj|jf | j
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%   r2   
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__b   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_oncerC   rE   )rN   rP   r   r   r   rH   {   s    z_StructProxy._make_refsc             C   s   t d S )N)NotImplementedError)rN   r>   r   r   r   rD      s    z_StructProxy._get_be_typec             C   s   t d S )N)rT   )rN   indexvalr   r   r   _cast_member_to_value   s    z"_StructProxy._cast_member_to_valuec             C   s   t d S )N)rT   )rN   rU   rV   r   r   r   _cast_member_from_value   s    z$_StructProxy._cast_member_from_valuec             C   s   t | j| jd|S )Nr   )gep_inboundsrC   rL   )rN   rU   r   r   r   _get_ptr_by_index   s    z_StructProxy._get_ptr_by_indexc             C   s   | j j|}| j|S )N)r2   get_field_positionrZ   )rN   attrnamerU   r   r   r   _get_ptr_by_name   s    z_StructProxy._get_ptr_by_namec             C   s&   |j ds| | jj| S t|dS )z;
        Load the LLVM value of the named *field*.
        r$   N)
startswithr2   r[   AttributeError)rN   fieldr   r   r   __getattr__   s    
z_StructProxy.__getattr__c                s0   |j drtt| j||S || | jj|< dS )z@
        Store the LLVM *value* into the named *field*.
        r$   N)r^   superr=   __setattr__r2   r[   )rN   r`   r   )	__class__r   r   rc      s    
z_StructProxy.__setattr__c             C   s   | j j| j|}| j||S )z>
        Load the LLVM value of the field at *index*.
        )rC   loadrZ   rW   )rN   rU   Z
member_valr   r   r   __getitem__   s    z_StructProxy.__getitem__c             C   s   | j |}| j||}|j|jjkr|t|jrft|jjrf|jj|jjjkrf| jj| j||jjj}nt	dj
||| |d| j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   ptrrN   rU   N)rZ   rX   r   rI   rF   r?   ZaddrspacecastrC   Z	addrspacerA   rB   rK   )rN   rU   r   rg   r   r   r   __setitem__   s    


z_StructProxy.__setitem__c             C   s   | j jS )z.
        Return the number of fields.
        )r2   Zfield_count)rN   r   r   r   __len__   s    z_StructProxy.__len__c             C   s   | j S )zF
        Return the LLVM pointer to the underlying structure.
        )rM   )rN   r   r   r   _getpointer   s    z_StructProxy._getpointerc             C   s   | j j| jS )zM
        Load and return the value of the underlying LLVM structure.
        )rC   re   rM   )rN   r   r   r   	_getvalue   s    z_StructProxy._getvaluec             C   s@   t |j st|j| jks,t|j| jf| jj|| j dS )z4
        Store the value in this structure.
        N)rF   r   rG   rE   rC   rK   rL   )rN   r   r   r   r   	_setvalue   s    z_StructProxy._setvalue)NN)r*   
__module____qualname____doc__r%   rQ   rH   rD   rW   rX   rZ   r]   ra   rc   rf   rh   ri   rj   rk   rl   __classcell__r   r   )rd   r   r=   Y   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   |j  S )N)Zget_value_type)rN   r>   r   r   r   rD      s    zValueStructProxy._get_be_typec             C   s   |S )Nr   )rN   rU   rV   r   r   r   rW      s    z&ValueStructProxy._cast_member_to_valuec             C   s   |S )Nr   )rN   rU   rV   r   r   r   rX      s    z(ValueStructProxy._cast_member_from_valueN)r*   rm   rn   ro   rD   rW   rX   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   |j  S )N)Zget_data_type)rN   r>   r   r   r   rD      s    zDataStructProxy._get_be_typec             C   s   | j j|}|j| j|S )N)r2   	get_modelZ	from_datarC   )rN   rU   rV   modelr   r   r   rW      s    z%DataStructProxy._cast_member_to_valuec             C   s   | j j|}|j| j|S )N)r2   rq   Zas_datarC   )rN   rU   rV   rr   r   r   r   rX      s    z'DataStructProxy._cast_member_from_valueN)r*   rm   rn   ro   rD   rW   rX   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   s2  |j | | _|| _|| _|d krrt|| j| _|d k	rt|j sFt|j| jksbt|j| jf|j	|| j n\|d ks~tt|jst| j|jj
kr|r|j|| jj }ntd|jj
| jf || _i | _g | _g | _td}xDt| jD ]6\}\}}	|| j|< | jj|t|f | jj|	 qW d S )Nz-mismatching pointer type: got %s, expected %sr   )Zget_struct_type_typer?   rC   rS   rL   rF   r   rG   rK   rI   bitcastrJ   rA   _namemap_fdmapZ_typemapint32_tr   r3   append)
rN   rO   r   r   rP   Zcast_refr.   r   r;   tpr   r   r   rQ     s4    
zStructure.__init__c             C   s   | j j| j| j| dd}|S )NT)inbounds)rC   geprL   rw   )rN   rU   rg   r   r   r   rZ   #  s    zStructure._get_ptr_by_indexc             C   s   | j | j| S )N)rZ   rv   )rN   r\   r   r   r   r]   '  s    zStructure._get_ptr_by_namec             C   s$   |j ds| | j|  S t|dS )z;
        Load the LLVM value of the named *field*.
        r$   N)r^   rv   r_   )rN   r`   r   r   r   ra   *  s    
zStructure.__getattr__c                s.   |j drtt| j||S || | j| < dS )z@
        Store the LLVM *value* into the named *field*.
        r$   N)r^   rb   rs   rc   rv   )rN   r`   r   )rd   r   r   rc   3  s    
zStructure.__setattr__c             C   s   | j j| j|S )z>
        Load the LLVM value of the field at *index*.
        )rC   re   rZ   )rN   rU   r   r   r   rf   ;  s    zStructure.__getitem__c             C   sN   | j |}|jj|jkr<d}t||t|jjt|jf | jj|| dS )zC
        Store the LLVM *value* into the field at *index*.
        z:Type mismatch: __setitem__(%d, ...) expected %r but got %rN)rZ   r   rI   rG   r+   rC   rK   )rN   rU   r   rg   Zfmtr   r   r   rh   B  s    

zStructure.__setitem__c             C   s
   t | jS )z.
        Return the number of fields.
        )r   rv   )rN   r   r   r   ri   N  s    zStructure.__len__c             C   s   | j S )zF
        Return the LLVM pointer to the underlying structure.
        )rL   )rN   r   r   r   rj   T  s    zStructure._getpointerc             C   s   | j j| jS )zM
        Load and return the value of the underlying LLVM structure.
        )rC   re   rL   )rN   r   r   r   rk   Z  s    zStructure._getvaluec             C   s@   t |j st|j| jks,t|j| jf| jj|| j dS )z!Store the value in this structureN)rF   r   rG   rt   rC   rK   rL   )rN   r   r   r   r   rl   `  s    zStructure._setvalue)NNF)r*   rm   rn   ro   rQ   rZ   r]   ra   rc   rf   rh   ri   rj   rk   rl   rp   r   r   )rd   r   rs      s   
	rs    Fc             C   sT   t |tjrtjt|}| j * | j|||d}|rF| j|d| |S Q R X 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)	r@   r   	INT_TYPESr   r   intp_tZgoto_entry_blockZallocarK   )r   tyr~   r   rR   rg   r   r   r   rS   i  s    
rS   c             C   s   t | |j}| 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.
    )rS   r   rK   )r   r   r   Zstorager   r   r   alloca_once_valuey  s    r   c             C   s*   | j ||d}|jjd |j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| j| 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}| jd||S )Nz==)r   r   r   )r   rV   nullr   r   r   is_null  s    
r   c             C   s   t |j}| jd||S )Nz!=)r   r   r   )r   rV   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   | j | j|S )N)r   not_)r   r   r   r   r   ifnot  s    r   c             C   s   |j d}| j||dgdS )z#
    Increment an index *val*.
    r   Znsw)flags)r   r   )r   rV   oner   r   r   increment_index  s    
r   LooprU   do_breakc             #   s   |dkr|j }|dkr|d}|}jd}jd}jd  fdd}j}j| j|0 j|dd	}	jd
|	|}
j|
|  W dQ R X j|, t|	|V  j}t	|	}t
| W dQ R X |	j|| |	j|| j  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   j   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   bbstartrU   r   incrr   )r   r   r   	for_range  s.    





r   Tc             c   s*  |dkr|j }| jd}| jd}| jd}| j}	| j| | j|R | j|dd}
| j|dd}|rx| jd|
|}n| jd	|
|}| j||| W dQ R X | j|6 |
|fV  | j}| j|
|}t	| |}t
| | W dQ R X |
j||	 |
j|| |jtj|d
|	 |j|| | j| 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   rU   r   r   r   Z
next_countr   r   r   for_range_slice  s2    





r   c             c   s   |j }| jd|tj|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_cond6  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f 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.
    CFFc             S   s   | d d d S )Nr   r   )xr   r   r   <lambda>T  s    zloop_nest.<locals>.<lambda>c             S   s   | S )Nr   )r   r   r   r   r   V  s    N)rG   
_loop_nestr   )r   shaper   orderZ_swapindicesr   r   r   	loop_nest@  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   rU   )r   r   r   loopr   r   r   r   r   \  s
    r   c             C   sT   t |}|dkr|d j}tj||tj}x"t|D ]\}}| j|||}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_arrayf  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 | ]} j |qS r   )extract_value)r   r   )r   tupr   r   r   |  s   z unpack_tuple.<locals>.<listcomp>)r   r   elementsrange)r   r   r   valsr   )r   r   r   unpack_tupleu  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 ]@\}}	 jd||jd}
 j|	|} j|
||}|j| qW n|}|st j|tdgS |d j}|dkrg }|dkrxtt	|D ]<}|d}x$||d d  D ]} j
||}qW |j| qW n`|dkr<xTtt	|D ]:}|d}x"|d | D ]} j
||}qW |j| qW ntd|d}x0t ||D ]"\}} j
||} j||}qXW  j||g}|S  fdd	t ||D }tj j|}t ||S d S )
Nr   r   r   r   r   r   Zunreachablec                s   g | ]\}} j ||qS r   )mul)r   sr   )r   r   r   r     s    z%get_item_pointer2.<locals>.<listcomp>)zipr   r   r   Zselectry   r|   rx   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jlocr   Ztmprg   Zdimoffsoffsetr   )r   r   r     sF    


r   c             C   s\   |j d}t|j tjtjfr*|||}n.t|j tjrH| j|||}ntd|j f |S )Nr   zunexpected value type %s)r   r@   r   Z	FloatTypeZ
DoubleTyper   r   rA   )r   r   ZfpredZicondZnullvalZisnullr   r   r   _scalar_pred_against_zero  s    
r   c             C   s   t | |tj| 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| 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| 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| 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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)rO   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f }|jt||dd | jj|t	| W dQ R X dS )zG
    Guard against *pointer* being NULL (and raise a MemoryError).
    F)r   N)
r@   r   r   PointerTyperG   r   r   r   r   MemoryError)rO   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.
    )r@   r   r   )Zltypr   r   r   rF     s    rF   c             C   s0   t | |d|}t|jj s t| j||j S )Nr   )rY   rF   r   rI   rG   ru   rJ   )r   recordr   typZpvalr   r   r   get_record_member  s    r   c             C   s   | j d||jdS )Nr   r   )r   r   )r   rV   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   rg   r   kwsr   r   r   rY     s    rY   c       	      O   sj   |j dd}|j dd}| s"tg }x0|D ](}t|tjrFt|}n|}|j| 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{   )r4   rG   r@   r   r   rx   ry   r|   )	r   rg   r   r   r   r{   idxr   r   r   r   r   r|   #  s    


r|   c             C   s>   | j |t}t|tjr t|}| j||}| j||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   r@   r   r   r   Zinttoptrr   )r   rg   r   Zreturn_typeZintptrr   r   r   r   6  s
    r   c             C   sd   |j }d|j }| jjdt|j f}| j|t}t|trBt|}| j	||||t
dtdg dS )z=
    Fill *size* bytes starting from *ptr* with *value*.
    zllvm.memset.p0i8.i%dzllvm.memsetr   N)r   widthr   declare_intrinsic	voidptr_tru   r@   intint8_tcallrx   bool_t)r   rg   r~   r   Zsizetymemsetr   r   r   r   r   E  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)	r@   r   ZModuler   Zadd_global_variabler   linkageglobal_constantZinitializer)Zbuilder_or_moduler   r   r  r   r#   r   r   r   r  R  s    r  c       
      C   s   |dkst |j|}|jd}t| |j}| jt| |n\}}| | j||}| j|| W dQ R X |2 | j||}| j||}| j| j||| W dQ R X W dQ R X | j	|}| j|| j
||}	||	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)rG   r   rS   r   r   ZsdivrK   r   subre   r   )
r   rV   Zdivisorr   ZquotZif_negZif_posZquot_valZval_plus_oneZrem_valr   r   r   divmod_by_constanta  s    

(
r  c             C   s&   | j d}| j||| | j| |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||jg}| j||jg}| j| j|| 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   rG   r   r|   rU   rK   re   )r   r8   r9   r   r   Zout_ptrZin_ptrr   r   r   memcpy  s
    r  c       
      C   sz   |j }t|tjrtj||}| jj|tt|g}tjtj	d|}t
}	| j|| j|t| j|t| j||||	g d S )Nr
   )r   r@   r   r   r   r   r   r   r   r   	false_bitr   ru   r   )
r   Z	func_namer8   r9   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   r8   r9   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   r8   r9   r   r  r	  r   r   r   raw_memmove  s    r  c       
      C   sX   | j ||}| j|d}| j|d}| j||}| j|d}| j|| j|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 jd}t|d|}tj	t
|gdd}y|jd}W n$ tk
rz   tj||dd}Y nX | j||}	| j||	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)Zvar_argprintf)r   )r@   r+   rG   r   r   r"   encoder  r   FunctionTyperx   Z
get_globalKeyErrorZFunctionru   r   list)
r   rB   argsmodZcstringZ	fmt_bytesZ
global_fmtr   r   Zptr_fmtr   r   r   r    s    	r  c             C   s   | j dj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}| j |t}t| d|| tjd}| j||j }t| |p}| j|j	t|}| j
d|td}| j| t| d W dQ R X | j||j	g}| j|}	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   ru   rJ   r   ZuremrU   r   r   r|   re   )
r   rg   nbytesZbytes_per_lineZbyte_tr   Zdiv_byZdo_new_liner   rV   r   r   r   hexdump  s    

r#  )N)r   )Nr}   F)r}   )rU   r   )NN)NT)r   )N)N)F)F)N)F)N)r   )r   )r   )Xro   Z
__future__r   r   r   collections
contextlibr   r   Zllvmliter   r}   r   r   r   r   rx   ZMACHINE_BITSr   rJ   r   Ztrue_bitr  Z	true_byteZ
false_byter   r   r"   r&   r0   r<   objectr=   r(   r)   rs   rS   r   r   r   r   r   r   r   r   r   r   
namedtupler   r   r   r   r   r   r   r   r   r   r   r   r   r   Zis_trueZis_falser   r   r   r   Z
guard_zerorF   r   r   rY   r|   r   r   r  r  r  r  r
  r  r  r  r  ZPY3r  r#  r   r   r   r   <module>   s   



	
 l

+9

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

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