U
    +d                     @   s   d dl Z d dlZd dlmZmZmZ ddddddd	Zejfd
dZejfddZ	ejfddZ
ejfddZdd Zdd Zdd Zdd ZejfddZdd ZG dd deZdS )     N)instructionstypesvaluesgtlteqnegele)><==!=z>=z<=c                    s    fdd}|S )Nc                    s   t | d fdd	}|S )N  c                    s&    | j |j|g||}| | |S Nblocktype_insert)selfargnameflagsinstrclsopnamer   7/tmp/pip-unpacked-wheel-stw2luzp/llvmlite/ir/builder.pywrapped   s    
z$_unop.<locals>.wrap.<locals>.wrapped)r   r   	functoolswrapsfnr   r   r   r   wrap   s    z_unop.<locals>.wrapr   r   r   r%   r   r   r   _unop   s    	r'   c                    s    fdd}|S )Nc                    s   t | d fdd	}|S )Nr   r   c                    sH   |j |j kr td|j |j f  | j|j ||f||}| | |S )N,Operands must be the same type, got (%s, %s))r   
ValueErrorr   r   )r   lhsrhsr   r   r   r   r   r   r      s    

z%_binop.<locals>.wrap.<locals>.wrapped)r   r   r    r#   r   r   r   r%      s    z_binop.<locals>.wrapr   r&   r   r   r   _binop   s    r,   c                    s    fdd}|S )Nc                    s   t | d fdd	}|S )Nr   c           
         s   |j |j kr td|j |j f |j }t|tjs@td|f td}| j}tt||g||g}|	d f |g|}| j
|||g|d}	|	S )Nr(    expected an integer type, got %s   zllvm.%s.with.overflowr   )r   r)   
isinstancer   IntType	TypeErrormoduleFunctionTypeZLiteralStructTypedeclare_intrinsiccall)
r   r*   r+   r   tyZbool_tymodZfntyr$   retr   r   r   r   /   s$    

 z3_binop_with_overflow.<locals>.wrap.<locals>.wrapped)r   r    r#   r:   r   r   r%   .   s    z"_binop_with_overflow.<locals>.wrapr   r&   r   r:   r   _binop_with_overflow-   s    r;   c                    s    fdd}|S )Nc                    s   t | d fdd	}|S )Nr   c                    s$    | j |j|g|}| | |S r   r   )r   operandr   r   r   r   r   r   H   s    
z%_uniop.<locals>.wrap.<locals>.wrapped)r   r    r#   r   r   r   r%   G   s    z_uniop.<locals>.wrapr   r&   r   r   r   _uniopF   s    	r=   c                    s    fdd}|S )Nc                    s   t | d fdd	}|S )Nr   c                    s>   t |jtjstd|j | j |jg}| ||g|S )Nr-   )r0   r   r   r1   r2   r3   r5   r6   r   r<   r   r$   r:   r   r   r   U   s    z3_uniop_intrinsic_int.<locals>.wrap.<locals>.wrapped)r   r    r#   r:   r   r   r%   T   s    z"_uniop_intrinsic_int.<locals>.wrapr   r   r%   r   r:   r   _uniop_intrinsic_intS   s    r@   c                    s    fdd}|S )Nc                    s   t | d fdd	}|S )Nr   c                    sD   t |jtjtjfs"td|j | j |jg}| ||g|S )Nexpected a float type, got %s)	r0   r   r   	FloatType
DoubleTyper2   r3   r5   r6   r>   r:   r   r   r   e   s     
z5_uniop_intrinsic_float.<locals>.wrap.<locals>.wrapped)r   r    r#   r:   r   r   r%   d   s    z$_uniop_intrinsic_float.<locals>.wrapr   r?   r   r:   r   _uniop_intrinsic_floatc   s    rD   c                    s    fdd}|S )Nc                    s   t | d fdd	}|S )Nr   c                    sl   t |jtjstd|j t |jtjr6|jjdksDtd|j | j |j|jg}| |||g|S )Nr-   r.   zexpected an i1 type, got %s)	r0   r   r   r1   r2   widthr3   r5   r6   )r   r<   flagr   r$   r:   r   r   r   t   s    
 
z9_uniop_intrinsic_with_flag.<locals>.wrap.<locals>.wrapped)r   r    r#   r:   r   r   r%   s   s    z(_uniop_intrinsic_with_flag.<locals>.wrapr   r?   r   r:   r   _uniop_intrinsic_with_flagr   s    rG   c                    s    fdd}|S )Nc                    s   t | d fdd	}|S )Nr   c                    s   |j |j ks|j |j kr2td|j |j |j f n&t|j tjtjtjfsXtd|j  | j |j |j |j g}| 	||||g|S )Nz-expected types to be the same, got %s, %s, %sz'expected an floating point type, got %s)
r   r2   r0   r   ZHalfTyperB   rC   r3   r5   r6   )r   abcr   r$   r:   r   r   r      s&    z/_triop_intrinsic.<locals>.wrap.<locals>.wrapped)r   r    r#   r:   r   r   r%      s    z_triop_intrinsic.<locals>.wrapr   r?   r   r:   r   _triop_intrinsic   s    rK   c                    s    fdd}|S )Nc                    s   t | d fdd	}|S )Nr   c                    s.   |j |kr|S  | j|||}| | |S r   )r   r   r   )r   valtypr   r   r   r   r   r      s
    

z&_castop.<locals>.wrap.<locals>.wrapped)r   r    r#   r   r   r   r%      s    z_castop.<locals>.wrapr   r&   r   r   r   _castop   s    rN   c                 C   s4   t | dkr(d}d| d| d|gS | | S dS )zReturns (label + suffix) or a truncated version if it's too long.
    Parameters
    ----------
    label : str
        Label name
    suffix : str
        Label suffix
    2      r   Nz..)lenjoin)labelsuffixZnheadr   r   r   _label_suffix   s    	rU   c                   @   s  e Zd ZdddZedd ZeZedd Zedd	 Zd
d Z	dd Z
dd Zdd ZdddZdd Zejdd Zejdd Zejdd ZejdddZejddd Zd!d" Zd#d$ Zed%d d&d'Zed(dd)d*Zed+dd,d-Zed.dd/d0Zed1dd2d3Zed4dd5d6Zed7dd8d9Zed:dd;d<Z ed=dd>d?Z!ed@d	dAdBZ"edCd
dDdEZ#edFddGdHZ$edIddJdKZ%edLddMdNZ&edOddPdQZ'edRddSdTZ(edUddVdWZ)edXddYdZZ*e+d[dd\d]Z,e+d^dd_d`Z-e+daddbdcZ.e+ddddedfZ/e+dgddhdiZ0e+djddkdlZ1ddmdnZ2ddodpZ3e4dqddsdtZ5dudv Z6ddwdxZ7ddydzZ8dd{d|Z9dd}d~Z:dddZ;e<dd ddZ=e<dd!ddZ>e<dd"ddZ?e<dd#ddZ@e<dd$ddZAe<dd%ddZBe<dd&ddZCe<dd'ddZDe<dd(ddZEe<dd)ddZFe<dd*ddZGe<dd+ddZHe<dd,ddZId-ddZJd.ddZKd/ddZLd0ddZMdd ZNdd ZOdd ZPdd ZQdd ZRdd ZSdd ZTdd ZUd1ddZVd2ddĄZWd3ddƄZXd4ddȄZYd5ddʄZZd6dd̄Z[d7dd΄Z\d8ddЄZ]d9dd҄Z^d:ddԄZ_d;ddքZ`d<dd؄Zaddڄ Zbd=dd܄Zcd>ddބZdd?ddZedd Zfd@ddZgehddd Ziehddd Zjehddd Zkelddd Zmelddd Zneoddd ZpdAddZqerddd ZsdS (B  	IRBuilderNc                 C   s$   || _ |rt|jnd| _d | _d S )Nr   )_blockrQ   r   _anchordebug_metadatar   r   r   r   r   __init__   s    zIRBuilder.__init__c                 C   s   | j S )z*
        The current basic block.
        )rW   r   r   r   r   r      s    zIRBuilder.blockc                 C   s   | j jS )z'
        The current function.
        )r   parentr\   r   r   r   function   s    zIRBuilder.functionc                 C   s
   | j jjS )z%
        The current module.
        )r   r]   r3   r\   r   r   r   r3      s    zIRBuilder.modulec                 C   s   |j | _| jj|| _dS )z
        Position immediately before the given instruction.  The current block
        is also changed to the instruction's basic block.
        Nr]   rW   r   indexrX   r   r   r   r   r   position_before   s    zIRBuilder.position_beforec                 C   s    |j | _| jj|d | _dS )z
        Position immediately after the given instruction.  The current block
        is also changed to the instruction's basic block.
        r.   Nr_   ra   r   r   r   position_after   s    zIRBuilder.position_afterc                 C   s   || _ d| _dS )z=
        Position at the start of the basic *block*.
        r   N)rW   rX   rZ   r   r   r   position_at_start   s    zIRBuilder.position_at_startc                 C   s   || _ t|j| _dS )z;
        Position at the end of the basic *block*.
        N)rW   rQ   r   rX   rZ   r   r   r   position_at_end   s    zIRBuilder.position_at_endr   c                 C   s   | j |S )z
        Append a basic block, with the given optional *name*, to the current
        function.  The current block is not changed.  The new block is returned.
        )r^   append_basic_block)r   r   r   r   r   rf      s    zIRBuilder.append_basic_blockc                 C   sH   | j j|}| j j|= | j j|kr,d| j _| j|krD|  jd8  _dS )zRemove the given instruction.Nr.   )rW   r   r`   
terminatorrX   )r   r   idxr   r   r   remove   s    

zIRBuilder.removec              	   c   sF   | j }|j}|dk	r | | n
| | z
dV  W 5 | | X dS )z
        A context manager which temporarily positions the builder at the end
        of basic block *bb* (but before any terminator).
        N)basic_blockrg   rb   re   )r   r   Z	old_blocktermr   r   r   
goto_block  s    

zIRBuilder.goto_blockc              	   c   s$   |  | jj dV  W 5 Q R X dS )z}
        A context manager which temporarily positions the builder at the
        end of the function's entry block.
        N)rl   r^   Zentry_basic_blockr\   r   r   r   goto_entry_block  s    zIRBuilder.goto_entry_blockc                 c   s*   |  | |V  | jjd kr&| | d S r   )re   rj   rg   branch)r   ZbbenterZbbexitr   r   r   _branch_helper"  s    
zIRBuilder._branch_helperc              	   c   s   | j }| jt|jdd}| jt|jdd}| |||}|dk	r^||rTddgnddg | || |V  W 5 Q R X | | dS )a  
        A context manager which sets up a conditional basic block based
        on the given predicate (a i1 value).  If the conditional block
        is not explicitly terminated, a branch will be added to the next
        block.
        If *likely* is given, its boolean value indicates whether the
        predicate is likely to be true or not, and metadata is issued
        for LLVM's optimizers to account for that.
        .ifr/   .endifNc   r.   rj   rf   rU   r   cbranchZset_weightsro   re   )r   predlikelybbbbifbbendbrr   r   r   if_then)  s    zIRBuilder.if_thenc           
      c   s   | j }| jt|jdd}| jt|jdd}| jt|jdd}| |||}|dk	rr||rhddgnddg | ||}| ||}	||	fV  | | dS )a@  
        A context manager which sets up two conditional basic blocks based
        on the given predicate (a i1 value).
        A tuple of context managers is yield'ed.  Each context manager
        acts as a if_then() block.
        *likely* has the same meaning as in if_then().

        Typical use::
            with builder.if_else(pred) as (then, otherwise):
                with then:
                    # emit instructions for when the predicate is true
                with otherwise:
                    # emit instructions for when the predicate is false
        rp   r/   z.elserq   Nrr   r.   rs   )
r   ru   rv   rw   rx   Zbbelsery   rz   ZthenZ	otherwiser   r   r   if_else@  s    
zIRBuilder.if_elsec                 C   sD   | j d k	r d|jkr | j |jd< | jj| j| |  jd7  _d S )NZdbgr.   )rY   metadatarW   r   insertrX   ra   r   r   r   r   _  s    zIRBuilder._insertc                 C   s"   | j jrt| | || j _|S r   )r   Zis_terminatedAssertionErrorr   rg   )r   rk   r   r   r   _set_terminatore  s    
zIRBuilder._set_terminatorshlc                 C   s   dS )zC
        Left integer shift:
            name = lhs << rhs
        Nr   r   r*   r+   r   r   r   r   r   o  s    zIRBuilder.shllshrc                 C   s   dS )zW
        Logical (unsigned) right integer shift:
            name = lhs >> rhs
        Nr   r   r   r   r   r   v  s    zIRBuilder.lshrashrc                 C   s   dS )zX
        Arithmetic (signed) right integer shift:
            name = lhs >> rhs
        Nr   r   r   r   r   r   }  s    zIRBuilder.ashraddc                 C   s   dS )z@
        Integer addition:
            name = lhs + rhs
        Nr   r   r   r   r   r     s    zIRBuilder.addfaddc                 C   s   dS )zG
        Floating-point addition:
            name = lhs + rhs
        Nr   r   r   r   r   r     s    zIRBuilder.faddsubc                 C   s   dS )zC
        Integer subtraction:
            name = lhs - rhs
        Nr   r   r   r   r   r     s    zIRBuilder.subfsubc                 C   s   dS )zJ
        Floating-point subtraction:
            name = lhs - rhs
        Nr   r   r   r   r   r     s    zIRBuilder.fsubmulc                 C   s   dS )zF
        Integer multiplication:
            name = lhs * rhs
        Nr   r   r   r   r   r     s    zIRBuilder.mulfmulc                 C   s   dS )zM
        Floating-point multiplication:
            name = lhs * rhs
        Nr   r   r   r   r   r     s    zIRBuilder.fmuludivc                 C   s   dS )zI
        Unsigned integer division:
            name = lhs / rhs
        Nr   r   r   r   r   r     s    zIRBuilder.udivsdivc                 C   s   dS )zG
        Signed integer division:
            name = lhs / rhs
        Nr   r   r   r   r   r     s    zIRBuilder.sdivfdivc                 C   s   dS )zG
        Floating-point division:
            name = lhs / rhs
        Nr   r   r   r   r   r     s    zIRBuilder.fdivuremc                 C   s   dS )zJ
        Unsigned integer remainder:
            name = lhs % rhs
        Nr   r   r   r   r   r     s    zIRBuilder.uremsremc                 C   s   dS )zH
        Signed integer remainder:
            name = lhs % rhs
        Nr   r   r   r   r   r     s    zIRBuilder.sremfremc                 C   s   dS )zH
        Floating-point remainder:
            name = lhs % rhs
        Nr   r   r   r   r   r     s    zIRBuilder.fremorc                 C   s   dS )zB
        Bitwise integer OR:
            name = lhs | rhs
        Nr   r   r   r   r   or_  s    zIRBuilder.or_andc                 C   s   dS )zC
        Bitwise integer AND:
            name = lhs & rhs
        Nr   r   r   r   r   and_  s    zIRBuilder.and_xorc                 C   s   dS )zC
        Bitwise integer XOR:
            name = lhs ^ rhs
        Nr   r   r   r   r   r     s    zIRBuilder.xorZsaddc                 C   s   dS )zn
        Signed integer addition with overflow:
            name = {result, overflow bit} = lhs + rhs
        Nr   r   r   r   r   sadd_with_overflow  s    zIRBuilder.sadd_with_overflowZsmulc                 C   s   dS )zt
        Signed integer multiplication with overflow:
            name = {result, overflow bit} = lhs * rhs
        Nr   r   r   r   r   smul_with_overflow  s    zIRBuilder.smul_with_overflowZssubc                 C   s   dS )zq
        Signed integer subtraction with overflow:
            name = {result, overflow bit} = lhs - rhs
        Nr   r   r   r   r   ssub_with_overflow  s    zIRBuilder.ssub_with_overflowZuaddc                 C   s   dS )zp
        Unsigned integer addition with overflow:
            name = {result, overflow bit} = lhs + rhs
        Nr   r   r   r   r   uadd_with_overflow  s    zIRBuilder.uadd_with_overflowZumulc                 C   s   dS )zv
        Unsigned integer multiplication with overflow:
            name = {result, overflow bit} = lhs * rhs
        Nr   r   r   r   r   umul_with_overflow	  s    zIRBuilder.umul_with_overflowZusubc                 C   s   dS )zs
        Unsigned integer subtraction with overflow:
            name = {result, overflow bit} = lhs - rhs
        Nr   r   r   r   r   usub_with_overflow  s    zIRBuilder.usub_with_overflowc                 C   sD   t |jtjr&t|jd|jj }nt|jd}| j|||dS )zG
        Bitwise integer complement:
            name = ~value
        )r   r/   )r0   r   r   Z
VectorTyper   Constantcountr   )r   valuer   r+   r   r   r   not_  s    zIRBuilder.not_c                 C   s   | j t|jd||dS )z=
        Integer negative:
            name = -value
        r   r/   )r   r   r   r   )r   r   r   r   r   r   neg&  s    zIRBuilder.negfnegr   c                 C   s   dS )zB
        Floating-point negative:
            name = -arg
        Nr   )r   r   r   r   r   r   r   r   -  s    zIRBuilder.fnegc                 C   sd   zt | }W n" tk
r.   td|f Y nX |dkr@|| }tj| j||||d}| | |S )Nzinvalid comparison %r for icmp)r   r   r/   )_CMP_MAPKeyErrorr)   r   Z	ICMPInstrr   r   )r   prefixcmpopr*   r+   r   opr   r   r   r   _icmp8  s    
zIRBuilder._icmpc                 C   s   |  d||||S )z
        Signed integer comparison:
            name = lhs <cmpop> rhs

        where cmpop can be '==', '!=', '<', '<=', '>', '>='
        sr   r   r   r*   r+   r   r   r   r   icmp_signedC  s    zIRBuilder.icmp_signedc                 C   s   |  d||||S )z
        Unsigned integer (or pointer) comparison:
            name = lhs <cmpop> rhs

        where cmpop can be '==', '!=', '<', '<=', '>', '>='
        ur   r   r   r   r   icmp_unsignedL  s    zIRBuilder.icmp_unsignedc                 C   s@   |t krdt |  }n|}tj| j|||||d}| | |S )z
        Floating-point ordered comparison:
            name = lhs <cmpop> rhs

        where cmpop can be '==', '!=', '<', '<=', '>', '>=', 'ord', 'uno'
        or   r   r   r   Z	FCMPInstrr   r   r   r   r*   r+   r   r   r   r   r   r   r   fcmp_orderedU  s         
zIRBuilder.fcmp_orderedc                 C   s@   |t krdt |  }n|}tj| j|||||d}| | |S )z
        Floating-point unordered comparison:
            name = lhs <cmpop> rhs

        where cmpop can be '==', '!=', '<', '<=', '>', '>=', 'ord', 'uno'
        r   r   r   r   r   r   r   fcmp_unorderede  s         
zIRBuilder.fcmp_unorderedc                 C   s&   t j| j|||||d}| | |S )zN
        Ternary select operator:
            name = cond ? lhs : rhs
        r   )r   ZSelectInstrr   r   )r   condr*   r+   r   r   r   r   r   r   selectu  s
    
zIRBuilder.selecttruncc                 C   s   dS )z_
        Truncating integer downcast to a smaller type:
            name = (typ) value
        Nr   r   r   rM   r   r   r   r   r     s    zIRBuilder.trunczextc                 C   s   dS )z`
        Zero-extending integer upcast to a larger type:
            name = (typ) value
        Nr   r   r   r   r   r     s    zIRBuilder.zextsextc                 C   s   dS )z`
        Sign-extending integer upcast to a larger type:
            name = (typ) value
        Nr   r   r   r   r   r     s    zIRBuilder.sextfptruncc                 C   s   dS )z`
        Floating-point downcast to a less precise type:
            name = (typ) value
        Nr   r   r   r   r   r     s    zIRBuilder.fptruncfpextc                 C   s   dS )z^
        Floating-point upcast to a more precise type:
            name = (typ) value
        Nr   r   r   r   r   r     s    zIRBuilder.fpextbitcastc                 C   s   dS )zZ
        Pointer cast to a different pointer type:
            name = (typ) value
        Nr   r   r   r   r   r     s    zIRBuilder.bitcastaddrspacecastc                 C   s   dS )z[
        Pointer cast to a different address space:
            name = (typ) value
        Nr   r   r   r   r   r     s    zIRBuilder.addrspacecastfptouic                 C   s   dS )z\
        Convert floating-point to unsigned integer:
            name = (typ) value
        Nr   r   r   r   r   r     s    zIRBuilder.fptouiuitofpc                 C   s   dS )z\
        Convert unsigned integer to floating-point:
            name = (typ) value
        Nr   r   r   r   r   r     s    zIRBuilder.uitofpfptosic                 C   s   dS )zZ
        Convert floating-point to signed integer:
            name = (typ) value
        Nr   r   r   r   r   r     s    zIRBuilder.fptosisitofpc                 C   s   dS )zZ
        Convert signed integer to floating-point:
            name = (typ) value
        Nr   r   r   r   r   r     s    zIRBuilder.sitofpptrtointc                 C   s   dS )zI
        Cast pointer to integer:
            name = (typ) value
        Nr   r   r   r   r   r     s    zIRBuilder.ptrtointinttoptrc                 C   s   dS )zI
        Cast integer to pointer:
            name = (typ) value
        Nr   r   r   r   r   r     s    zIRBuilder.inttoptrc                 C   sb   |dkr
n8t |tjtjfr0t |jtjsBtnttd|}t	| j
|||}| | |S )zl
        Stack-allocate a slot for *size* elements of the given type.
        (default one element)
        N    )r0   r   Valuer   r   r   r1   r   r   ZAllocaInstrr   r   )r   rM   sizer   alr   r   r   alloca  s    
zIRBuilder.allocac                 C   sL   t |jtjs(d}t||jt|f t| j||}||_	| 
| |S zf
        Load value from pointer, with optional guaranteed alignment:
            name = *ptr
        z5cannot load from value of type %s (%r): not a pointer)r0   r   r   PointerTyper2   strr   Z	LoadInstrr   alignr   )r   ptrr   r   msgldr   r   r   load  s    
zIRBuilder.loadc                 C   sn   t |jtjs(d}t||jt|f |jj|jkrJtd|j|jf t| j	||}||_
| | |S ze
        Store value to pointer, with optional guaranteed alignment:
            *ptr = name
        z4cannot store to value of type %s (%r): not a pointerz(cannot store %s to %s: mismatching types)r0   r   r   r   r2   r   pointeer   Z
StoreInstrr   r   r   )r   r   r   r   r   str   r   r   store  s    

zIRBuilder.storec                 C   sJ   t |jtjs(d}t||jt|f t| j||||}| 	| |S r   )
r0   r   r   r   r2   r   r   ZLoadAtomicInstrr   r   )r   r   orderingr   r   r   r   r   r   r   load_atomic  s        
zIRBuilder.load_atomicc                 C   sl   t |jtjs(d}t||jt|f |jj|jkrJtd|j|jf t| j	||||}| 
| |S r   )r0   r   r   r   r2   r   r   r   ZStoreAtomicInstrr   r   )r   r   r   r   r   r   r   r   r   r   store_atomic  s     
    
zIRBuilder.store_atomicc                 C   s    t | jd||}| | |S )zF
        Create a switch-case with a single *default* target.
        switch)r   ZSwitchInstrr   r   )r   r   defaultZswtr   r   r   r   2  s    
zIRBuilder.switchc                 C   s    t | jd|g}| | |S )z3
        Unconditional branch to *target*.
        rz   r   ZBranchr   r   )r   targetrz   r   r   r   rn   :  s    
zIRBuilder.branchc                 C   s$   t | jd|||g}| | |S )zV
        Conditional branch to *truebr* if *cond* is true, else to *falsebr*.
        rz   )r   ZConditionalBranchr   r   )r   r   ZtruebrZfalsebrrz   r   r   r   rt   B  s
    

zIRBuilder.cbranchc                 C   s   t | jd|}| | |S )z3
        Indirect branch to target *addr*.
        Z
indirectbr)r   ZIndirectBranchr   r   )r   addrrz   r   r   r   branch_indirectK  s    
zIRBuilder.branch_indirectc                 C   s   |  t| jdS )z7
        Return from function without a value.
        zret voidr   r   ZRetr   r\   r   r   r   ret_voidS  s    zIRBuilder.ret_voidc                 C   s   |  t| jd|S )z>
        Return from function with the given *value*.
        r9   r   )r   r   r   r   r   r9   Z  s    zIRBuilder.retc                 C   s    t | jd|g}| | |S )z0
        Resume an in-flight exception.
        resumer   )r   
landingpadrz   r   r   r   r   a  s    
zIRBuilder.resumeFc	           
      C   s,   t j| j||||||||d	}	| |	 |	S )zP
        Call function *fn* with *args*:
            name = fn(args...)
        )r   cconvtailfastmathattrs	arg_attrs)r   Z	CallInstrr   r   )
r   r$   argsr   r   r   r   r   r   instr   r   r   r6   k  s       
zIRBuilder.callc                 C   s   t ||||}| |||S )z#
        Inline assembler.
        )r   Z	InlineAsmr6   )r   ftypeasm
constraintr   Zside_effectr   r   r   r   r   w  s    zIRBuilder.asmc                 C   s$   t |g }| |dd| g d|S )zo
        Load a register value into an LLVM value.
          Example: v = load_reg(IntType(32), "eax")
        r   z={%s}F)r   r4   r   )r   reg_typereg_namer   r   r   r   r   load_reg~  s    zIRBuilder.load_regc                 C   s,   t t  |g}| |dd| |gd|S )z
        Store an LLVM value inside a register
        Example:
          store_reg(Constant(IntType(32), 0xAAAAAAAA), IntType(32), "eax")
        r   z{%s}T)r   r4   ZVoidTyper   )r   r   r   r   r   r   r   r   r   	store_reg  s    zIRBuilder.store_regc
                 C   s.   t j| j|||||||||	d
}
| |
 |
S )N)r   r   r   r   r   )r   ZInvokeInstrr   r   )r   r$   r   Z	normal_toZ	unwind_tor   r   r   r   r   r   r   r   r   invoke  s       
zIRBuilder.invokec                 C   s$   t j| j||||d}| | |S )zo
        Compute effective address (getelementptr):
            name = getelementptr ptr, <indices...>
        )inboundsr   )r   ZGEPInstrr   r   )r   r   indicesr   r   r   r   r   r   gep  s     
zIRBuilder.gepc                 C   s"   t j| j|||d}| | |S )z4
        Returns the value at position idx.
        r/   )r   ZExtractElementr   r   )r   vectorrh   r   r   r   r   r   extract_element  s    
zIRBuilder.extract_elementc                 C   s$   t j| j||||d}| | |S )z
        Returns vector with vector[idx] replaced by value.
        The result is undefined if the idx is larger or equal the vector length.
        r/   )r   ZInsertElementr   r   )r   r   r   rh   r   r   r   r   r   insert_element  s
    
zIRBuilder.insert_elementc                 C   s$   t j| j||||d}| | |S )a  
        Constructs a permutation of elements from *vector1* and *vector2*.
        Returns a new vector in the same length of *mask*.

        * *vector1* and *vector2* must have the same element type.
        * *mask* must be a constant vector of integer types.
        r/   )r   ZShuffleVectorr   r   )r   Zvector1Zvector2maskr   r   r   r   r   shuffle_vector  s
    
zIRBuilder.shuffle_vectorc                 C   s6   t |ttfs|g}tj| j|||d}| | |S )z=
        Extract member number *idx* from aggregate.
        r/   )r0   tuplelistr   ZExtractValuer   r   )r   aggrh   r   r   r   r   r   extract_value  s
    
zIRBuilder.extract_valuec                 C   s8   t |ttfs|g}tj| j||||d}| | |S )zI
        Insert *value* into member number *idx* from aggregate.
        r/   )r0   r   r   r   ZInsertValuer   r   )r   r   r   rh   r   r   r   r   r   insert_value  s
    
zIRBuilder.insert_valuec                 C   s"   t j| j|||d}| | |S )Nr   )r   ZPhiInstrr   r   )r   rM   r   r   r   r   r   r   phi  s    
zIRBuilder.phic                 C   s   t | j}| | |S r   )r   ZUnreachabler   r   )r   r   r   r   r   unreachable  s    
zIRBuilder.unreachablec                 C   s&   t j| j|||||d}| | |S )Nr/   )r   Z	AtomicRMWr   r   )r   r   r   rL   r   r   r   r   r   r   
atomic_rmw  s         
zIRBuilder.atomic_rmwc              	   C   s8   |dkr|n|}t j| j||||||d}| | |S )a8  
        Atomic compared-and-set:
            atomic {
                old = *ptr
                success = (old == cmp)
                if (success)
                    *ptr = val
                }
            name = { old, success }

        If failordering is `None`, the value of `ordering` is used.
        Nr/   )r   ZCmpXchgr   r   )r   r   cmprL   r   Zfailorderingr   r   r   r   r   cmpxchg  s     
zIRBuilder.cmpxchgc                 C   s    t | j|||}| | |S r   )r   ZLandingPadInstrr   r   )r   rM   r   cleanupr   r   r   r   r     s    
zIRBuilder.landingpadc                 C   s   | j d}| ||gS )z?
        Optimizer hint: assume *cond* is always true.
        zllvm.assume)r3   r5   r6   )r   r   r$   r   r   r   assume  s    zIRBuilder.assumec                 C   s"   t j| j|||d}| | |S )z
        Add a memory barrier, preventing certain reorderings of load and/or
        store accesses with
        respect to other processors and devices.
        r/   )r   ZFencer   r   )r   r   Ztargetscoper   r   r   r   r   fence  s    
zIRBuilder.fencez
llvm.bswapc                 C   s   dS )zv
        Used to byte swap integer values with an even number of bytes (positive
        multiple of 16 bits)
        Nr   r   r   r   r   r   bswap  s    zIRBuilder.bswapzllvm.bitreversec                 C   s   dS )zp
        Reverse the bitpattern of an integer value; for example 0b10110110
        becomes 0b01101101.
        Nr   r  r   r   r   
bitreverse  s    zIRBuilder.bitreversez
llvm.ctpopc                 C   s   dS )z;
        Counts the number of bits set in a value.
        Nr   r  r   r   r   ctpop&  s    zIRBuilder.ctpopz	llvm.ctlzc                 C   s   dS )z
        Counts leading zero bits in *value*. Boolean *flag* indicates whether
        the result is defined for ``0``.
        Nr   r   r   rF   r   r   r   ctlz,  s    zIRBuilder.ctlzz	llvm.cttzc                 C   s   dS )z
        Counts trailing zero bits in *value*. Boolean *flag* indicates whether
        the result is defined for ``0``.
        Nr   r  r   r   r   cttz3  s    zIRBuilder.cttzzllvm.fmac                 C   s   dS )z;
        Perform the fused multiply-add operation.
        Nr   )r   rH   rI   rJ   r   r   r   fma:  s    zIRBuilder.fmac                 C   sv   |st dt|tjtjfs*t d| t|jtjrD|jjdksRt d|j d}| j	||g}| 
||g|S )z:
        Convert from an i16 to the given FP type
        zexpected a float return typerA      zexpected an i16 type, got %szllvm.convert.from.fp16)r2   r0   r   rB   rC   r   r1   rE   r3   r5   r6   )r   rH   tor   r   r$   r   r   r   convert_from_fp16@  s    zIRBuilder.convert_from_fp16zllvm.convert.to.fp16c                 C   s   dS )z7
        Convert the given FP number to an i16
        Nr   )r   rH   r   r   r   convert_to_fp16O  s    zIRBuilder.convert_to_fp16)N)r   )N)N)r   )r   )r   )r   )r   )r   )r   )r   )r   )r   )r   )r   )r   )r   )r   )r   )r   )r   )r   )r   )r   )r   )r   )r   )r   )r   )r   r   )r   )r   )r   r   )r   r   )r   r   )r   )r   )r   )r   )r   )r   )r   )r   )r   )r   )r   )r   )r   )Nr   )r   N)N)r   )r   NFr   r   N)r   )r   )r   )r   Nr   r   N)Fr   )r   )r   )r   )r   )r   )r   r   )r   )Nr   )r   F)Nr   )Nr   )t__name__
__module____qualname__r[   propertyr   rj   r^   r3   rb   rc   rd   re   rf   ri   
contextlibcontextmanagerrl   rm   ro   r{   r|   r   r   r,   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r;   r   r   r   r   r   r   r   r   r'   r   r   r   r   r   r   r   rN   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rn   rt   r   r   r9   r   r6   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r   r  r  r@   r  r	  r
  rG   r  r  rK   r  r  rD   r  r   r   r   r   rV      sF  




	





		
	
   

        









rV   )r  r!   Zllvmlite.irr   r   r   r   Instructionr'   r,   r;   r=   r@   rD   rG   rK   Z	CastInstrrN   rU   objectrV   r   r   r   r   <module>   s(   
