U
    ºmœ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   úL/home/sam/Atlas/atlas_env/lib/python3.8/site-packages/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 )z­Returns (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düd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dýdd„Zdd„ Zejdd„ ƒZejdd„ ƒZejdd„ ƒZejdþdd„ƒZejdÿd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 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Žd�„ƒZAe<d�ƒ�d%d‘d’„ƒZBe<d“ƒ�d&d”d•„ƒZCe<d–ƒ�d'd—d˜„ƒZDe<d™ƒ�d(dšd›„ƒZEe<dœƒ�d)d�dž„ƒZFe<dŸƒ�d*d d¡„ƒZGe<d¢ƒ�d+d£d¤„ƒZHe<d¥ƒ�d,d¦d§„ƒZI�d-d¨d©„ZJ�d.dªd«„ZK�d/d¬d­„ZL�d0d®d¯„ZMd°d±„ ZNd²d³„ ZOd´dµ„ ZPd¶d·„ ZQd¸d¹„ ZRdºd»„ ZSd¼d½„ ZTd¾d¿„ ZU�d1dÁdÂ„ZV�d2dÃdÄ„ZW�d3dÅdÆ„ZX�d4dÇdÈ„ZY�d5dÉdÊ„ZZ�d6dËdÌ„Z[�d7dÍdÎ„Z\�d8dÏdÐ„Z]�d9dÑdÒ„Z^�d:dÓdÔ„Z_�d;dÕdÖ„Z`�d<d×dØ„ZadÙdÚ„ Zb�d=dÛdÜ„Zc�d>dÝdÞ„Zd�d?dßdà„Zedádâ„ Zf�d@dãdä„Zgehdåƒdædç„ ƒZiehdèƒdédê„ ƒZjehdëƒdìdí„ ƒZkeldîƒdïdð„ ƒZmeldñƒdòdó„ ƒZneodôƒdõdö„ ƒZp�dAd÷dø„Zqerdùƒdúdû„ ƒ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/   ú.endifNéc   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(   ú
