o
    ߐiǂ                     @   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                        fdd}|S )Nc                       t | d fdd	}|S )N  c                    s&    | j |j|g||}| | |S Nblocktype_insert)selfargnameflagsinstrclsopnamer   b/var/www/html/eduruby.in/lip-sync/lip-sync-env/lib/python3.10/site-packages/llvmlite/ir/builder.pywrapped   s   
z$_unop.<locals>.wrap.<locals>.wrappedr   r   	functoolswrapsfnr!   r   r   r    wrap      z_unop.<locals>.wrapr   r   r   r(   r   r   r    _unop      	r+   c                    r   )Nc                    r   )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>.wrappedr"   r#   r&   r   r   r    r(      s   z_binop.<locals>.wrapr   r*   r   r   r    _binop   s   r1   c                    s    fdd}|S )Nc                       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/   r0   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   rB   c                    r   )Nc                       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>.wrappedrA   r#   r&   r   r   r    r(   G   r)   z_uniop.<locals>.wrapr   r*   r   r   r    _uniopF   r,   rE   c                        fdd}|S )Nc                    r2   )Nr   c                    s>   t |jtjstd|j | j |jg}| ||g|S )Nr3   )r6   r   r   r7   r8   r9   r;   r<   r   rD   r   r'   r@   r   r    r!   U   s   z3_uniop_intrinsic_int.<locals>.wrap.<locals>.wrappedrA   r#   r&   r@   r   r    r(   T   s   z"_uniop_intrinsic_int.<locals>.wrapr   r   r(   r   r@   r    _uniop_intrinsic_intS   s   rI   c                    rF   )Nc                    r2   )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)	r6   r   r   	FloatType
DoubleTyper8   r9   r;   r<   rG   r@   r   r    r!   e   s   z5_uniop_intrinsic_float.<locals>.wrap.<locals>.wrappedrA   r#   r&   r@   r   r    r(   d   s   z$_uniop_intrinsic_float.<locals>.wrapr   rH   r   r@   r    _uniop_intrinsic_floatc   s   rM   c                    rF   )Nc                    r2   )Nr   c                    sl   t |jtjstd|j t |jtjr|jjdks"td|j | j |j|jg}| |||g|S )Nr3   r4   zexpected an i1 type, got %s)	r6   r   r   r7   r8   widthr9   r;   r<   )r   rD   flagr   r'   r@   r   r    r!   t   s   z9_uniop_intrinsic_with_flag.<locals>.wrap.<locals>.wrappedrA   r#   r&   r@   r   r    r(   s   s   z(_uniop_intrinsic_with_flag.<locals>.wrapr   rH   r   r@   r    _uniop_intrinsic_with_flagr   s   rP   c                    rF   )Nc                    r2   )Nr   c                    s   |j |j ks|j |j krtd|j |j |j f t|j tjtjtjfs+t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   r8   r6   r   ZHalfTyperK   rL   r9   r;   r<   )r   abcr   r'   r@   r   r    r!      s&   z/_triop_intrinsic.<locals>.wrap.<locals>.wrappedrA   r#   r&   r@   r   r    r(      s   z_triop_intrinsic.<locals>.wrapr   rH   r   r@   r    _triop_intrinsic   s   rT   c                    r   )Nc                    rC   )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>.wrappedrA   r#   r&   r   r   r    r(      s   z_castop.<locals>.wrapr   r*   r   r   r    _castop   s   rW   c                 C   s0   t | dkrd}d| d| d|gS | | 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   	r^   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%dd&d'Zed(dd)d*Zed+dd,d-Zed.dd/d0Zed1dd2d3Zed4dd5d6Zed7dd8d9Zed:dd;d<Z ed=dd>d?Z!ed@ddAdBZ"edCddDdEZ#edFddGdHZ$edIddJdKZ%edLddMdNZ&edOddPdQZ'edRddSdTZ(edUddVdWZ)edXddYdZZ*e+d[dd\d]Z,e+d^dd_d`Z-e+daddbdcZ.e+ddddedfZ/e+dgddhdiZ0e+djddkdlZ1ddmdnZ2ddodpZ3e4dqd dsdtZ5dudv Z6ddwdxZ7ddydzZ8d d{d|Z9d d}d~Z:d ddZ;e<ddddZ=e<ddddZ>e<ddddZ?e<ddddZ@e<ddddZAe<ddddZBe<ddddZCe<ddddZDe<ddddZEe<ddddZFe<ddddZGe<ddddZHe<ddddZIdddZJdddZKdddZLdddZMdd ZNdd ZOdd ZPdd ZQdd ZRdd ZSdd ZTdd ZU	r	dddZVdddĄZWdddƄZXdddȄZY	dddʄZZddd̄Z[ddd΄Z\dddЄZ]ddd҄Z^dddԄZ_dddքZ`d dd؄Zaddڄ Zbddd܄ZcdddބZddddZedd ZfdddZgdd Zheiddd Zjeiddd Zkeiddd Zlemddd Znemddd Zoepddd ZqdddZresddd ZtdS (  	IRBuilderNc                 C   s$   || _ |r
t|jnd| _d | _d S )Nr   )_blockrZ   r   _anchordebug_metadatar   r   r   r   r    __init__   s   
zIRBuilder.__init__c                 C   s   | j S )z*
        The current basic block.
        )r`   r   r   r   r    r      s   zIRBuilder.blockc                 C   s   | j jS )z'
        The current function.
        )r   parentre   r   r   r    function   s   zIRBuilder.functionc                 C   s
   | j jjS )z%
        The current module.
        )r   rf   r9   re   r   r   r    r9      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rf   r`   r   indexra   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.
        r4   Nrh   rj   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)r`   ra   rc   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)r`   rZ   r   ra   rc   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.
        )rg   append_basic_block)r   r   r   r   r    ro      s   zIRBuilder.append_basic_blockc                 C   sL   | j j|}| j j|= | j j|krd| j _| j|kr$|  jd8  _dS dS )zRemove the given instruction.Nr4   )r`   r   ri   
terminatorra   )r   r   idxr   r   r    remove   s   

zIRBuilder.removec              	   c   sP    | j }|j}|dur| | n| | zdV  W | | dS | | w )z
        A context manager which temporarily positions the builder at the end
        of basic block *bb* (but before any terminator).
        N)basic_blockrp   rk   rn   )r   r   Z	old_blocktermr   r   r    
goto_block  s   
zIRBuilder.goto_blockc                 c   s<    |  | jj dV  W d   dS 1 sw   Y  dS )z}
        A context manager which temporarily positions the builder at the
        end of the function's entry block.
        N)ru   rg   Zentry_basic_blockre   r   r   r    goto_entry_block  s   "zIRBuilder.goto_entry_blockc                 c   s0    |  | |V  | jjd u r| | d S d S r   )rn   rs   rp   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ur0||r+ddgnddg | || |V  W d   n1 sDw   Y  | | 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.
        .ifr5   .endifNc   r4   rs   ro   r^   r   cbranchZset_weightsrx   rn   )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ur:||r5d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
        ry   r5   z.elserz   Nr{   r4   r|   )
r   r~   r   r   r   Zbbelser   r   ZthenZ	otherwiser   r   r    if_else@  s   
zIRBuilder.if_elsec                 C   sD   | j d urd|jvr| j |jd< | jj| j| |  jd7  _d S )NZdbgr4   )rb   metadatar`   r   insertra   rj   r   r   r    r   _  s   zIRBuilder._insertc                 C   s"   | j jrJ | | || j _|S r   )r   Zis_terminatedr   rp   )r   rt   r   r   r    _set_terminatore  s   
zIRBuilder._set_terminatorshlc                 C      dS )zC
        Left integer shift:
            name = lhs << rhs
        Nr   r   r/   r0   r   r   r   r    r   o      zIRBuilder.shllshrc                 C   r   )zW
        Logical (unsigned) right integer shift:
            name = lhs >> rhs
        Nr   r   r   r   r    r   v  r   zIRBuilder.lshrashrc                 C   r   )zX
        Arithmetic (signed) right integer shift:
            name = lhs >> rhs
        Nr   r   r   r   r    r   }  r   zIRBuilder.ashraddc                 C   r   )z@
        Integer addition:
            name = lhs + rhs
        Nr   r   r   r   r    r     r   zIRBuilder.addfaddc                 C   r   )zG
        Floating-point addition:
            name = lhs + rhs
        Nr   r   r   r   r    r     r   zIRBuilder.faddsubc                 C   r   )zC
        Integer subtraction:
            name = lhs - rhs
        Nr   r   r   r   r    r     r   zIRBuilder.subfsubc                 C   r   )zJ
        Floating-point subtraction:
            name = lhs - rhs
        Nr   r   r   r   r    r     r   zIRBuilder.fsubmulc                 C   r   )zF
        Integer multiplication:
            name = lhs * rhs
        Nr   r   r   r   r    r     r   zIRBuilder.mulfmulc                 C   r   )zM
        Floating-point multiplication:
            name = lhs * rhs
        Nr   r   r   r   r    r     r   zIRBuilder.fmuludivc                 C   r   )zI
        Unsigned integer division:
            name = lhs / rhs
        Nr   r   r   r   r    r     r   zIRBuilder.udivsdivc                 C   r   )zG
        Signed integer division:
            name = lhs / rhs
        Nr   r   r   r   r    r     r   zIRBuilder.sdivfdivc                 C   r   )zG
        Floating-point division:
            name = lhs / rhs
        Nr   r   r   r   r    r     r   zIRBuilder.fdivuremc                 C   r   )zJ
        Unsigned integer remainder:
            name = lhs % rhs
        Nr   r   r   r   r    r     r   zIRBuilder.uremsremc                 C   r   )zH
        Signed integer remainder:
            name = lhs % rhs
        Nr   r   r   r   r    r     r   zIRBuilder.sremfremc                 C   r   )zH
        Floating-point remainder:
            name = lhs % rhs
        Nr   r   r   r   r    r     r   zIRBuilder.fremorc                 C   r   )zB
        Bitwise integer OR:
            name = lhs | rhs
        Nr   r   r   r   r    or_  r   zIRBuilder.or_andc                 C   r   )zC
        Bitwise integer AND:
            name = lhs & rhs
        Nr   r   r   r   r    and_  r   zIRBuilder.and_xorc                 C   r   )zC
        Bitwise integer XOR:
            name = lhs ^ rhs
        Nr   r   r   r   r    r     r   zIRBuilder.xorZsaddc                 C   r   )zn
        Signed integer addition with overflow:
            name = {result, overflow bit} = lhs + rhs
        Nr   r   r   r   r    sadd_with_overflow  r   zIRBuilder.sadd_with_overflowZsmulc                 C   r   )zt
        Signed integer multiplication with overflow:
            name = {result, overflow bit} = lhs * rhs
        Nr   r   r   r   r    smul_with_overflow  r   zIRBuilder.smul_with_overflowZssubc                 C   r   )zq
        Signed integer subtraction with overflow:
            name = {result, overflow bit} = lhs - rhs
        Nr   r   r   r   r    ssub_with_overflow  r   zIRBuilder.ssub_with_overflowZuaddc                 C   r   )zp
        Unsigned integer addition with overflow:
            name = {result, overflow bit} = lhs + rhs
        Nr   r   r   r   r    uadd_with_overflow  r   zIRBuilder.uadd_with_overflowZumulc                 C   r   )zv
        Unsigned integer multiplication with overflow:
            name = {result, overflow bit} = lhs * rhs
        Nr   r   r   r   r    umul_with_overflow	  r   zIRBuilder.umul_with_overflowZusubc                 C   r   )zs
        Unsigned integer subtraction with overflow:
            name = {result, overflow bit} = lhs - rhs
        Nr   r   r   r   r    usub_with_overflow  r   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   r5   )r6   r   r   Z
VectorTyper   Constantcountr   )r   valuer   r0   r   r   r    not_  s   zIRBuilder.not_c                 C   s   | j t|jd||dS )z=
        Integer negative:
            name = -value
        r   r5   )r   r   r   r   )r   r   r   r   r   r    neg&  s   zIRBuilder.negfnegr   c                 C   r   )zB
        Floating-point negative:
            name = -arg
        Nr   )r   r   r   r   r   r   r    r   -  r   zIRBuilder.fnegc                 C   s^   zt | }W n ty   td|f w |dvr|| }tj| j||||d}| | |S )Nzinvalid comparison %r for icmp)r   r   r5   )_CMP_MAPKeyErrorr.   r   Z	ICMPInstrr   r   )r   prefixcmpopr/   r0   r   opr   r   r   r    _icmp8  s   
zIRBuilder._icmpc                 C      |  d||||S )z
        Signed integer comparison:
            name = lhs <cmpop> rhs

        where cmpop can be '==', '!=', '<', '<=', '>', '>='
        sr   r   r   r/   r0   r   r   r   r    icmp_signedC     zIRBuilder.icmp_signedc                 C   r   )z
        Unsigned integer (or pointer) comparison:
            name = lhs <cmpop> rhs

        where cmpop can be '==', '!=', '<', '<=', '>', '>='
        ur   r   r   r   r    icmp_unsignedL  r   zIRBuilder.icmp_unsignedc                 C   @   |t v 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/   r0   r   r   r   r   r   r   r    fcmp_orderedU     
zIRBuilder.fcmp_orderedc                 C   r   )z
        Floating-point unordered comparison:
            name = lhs <cmpop> rhs

        where cmpop can be '==', '!=', '<', '<=', '>', '>=', 'ord', 'uno'
        r   r   r   r   r   r   r    fcmp_unorderede  r   zIRBuilder.fcmp_unorderedc                 C   &   t j| j|||||d}| | |S )zN
        Ternary select operator:
            name = cond ? lhs : rhs
        r   )r   ZSelectInstrr   r   )r   condr/   r0   r   r   r   r   r   r    selectu  s
   
zIRBuilder.selecttruncc                 C   r   )z_
        Truncating integer downcast to a smaller type:
            name = (typ) value
        Nr   r   r   rV   r   r   r   r    r     r   zIRBuilder.trunczextc                 C   r   )z`
        Zero-extending integer upcast to a larger type:
            name = (typ) value
        Nr   r   r   r   r    r     r   zIRBuilder.zextsextc                 C   r   )z`
        Sign-extending integer upcast to a larger type:
            name = (typ) value
        Nr   r   r   r   r    r     r   zIRBuilder.sextfptruncc                 C   r   )z`
        Floating-point downcast to a less precise type:
            name = (typ) value
        Nr   r   r   r   r    r     r   zIRBuilder.fptruncfpextc                 C   r   )z^
        Floating-point upcast to a more precise type:
            name = (typ) value
        Nr   r   r   r   r    r     r   zIRBuilder.fpextbitcastc                 C   r   )zZ
        Pointer cast to a different pointer type:
            name = (typ) value
        Nr   r   r   r   r    r     r   zIRBuilder.bitcastaddrspacecastc                 C   r   )z[
        Pointer cast to a different address space:
            name = (typ) value
        Nr   r   r   r   r    r     r   zIRBuilder.addrspacecastfptouic                 C   r   )z\
        Convert floating-point to unsigned integer:
            name = (typ) value
        Nr   r   r   r   r    r     r   zIRBuilder.fptouiuitofpc                 C   r   )z\
        Convert unsigned integer to floating-point:
            name = (typ) value
        Nr   r   r   r   r    r     r   zIRBuilder.uitofpfptosic                 C   r   )zZ
        Convert floating-point to signed integer:
            name = (typ) value
        Nr   r   r   r   r    r     r   zIRBuilder.fptosisitofpc                 C   r   )zZ
        Convert signed integer to floating-point:
            name = (typ) value
        Nr   r   r   r   r    r     r   zIRBuilder.sitofpptrtointc                 C   r   )zI
        Cast pointer to integer:
            name = (typ) value
        Nr   r   r   r   r    r     r   zIRBuilder.ptrtointinttoptrc                 C   r   )zI
        Cast integer to pointer:
            name = (typ) value
        Nr   r   r   r   r    r     r   zIRBuilder.inttoptrc                 C   sb   |du rnt |tjtjfrt |jtjsJ n	ttd|}t| j	|||}| 
| |S )zl
        Stack-allocate a slot for *size* elements of the given type.
        (default one element)
        N    )r6   r   Valuer   r   r   r7   r   ZAllocaInstrr   r   )r   rV   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)r6   r   r   PointerTyper8   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r%t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)r6   r   r   r   r8   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   )
r6   r   r   r   r8   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r%td|j|jf t| j	||||}| 
| |S r   )r6   r   r   r   r8   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     
zIRBuilder.switchc                 C       t | jd|g}| | |S )z3
        Unconditional branch to *target*.
        r   r   ZBranchr   r   )r   targetr   r   r   r    rw   :  r   zIRBuilder.branchc                 C   s$   t | jd|||g}| | |S )zV
        Conditional branch to *truebr* if *cond* is true, else to *falsebr*.
        r   )r   ZConditionalBranchr   r   )r   r   ZtruebrZfalsebrr   r   r   r    r}   B  s
   

zIRBuilder.cbranchc                 C   s   t | jd|}| | |S )z3
        Indirect branch to target *addr*.
        Z
indirectbr)r   ZIndirectBranchr   r   )r   addrr   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   re   r   r   r    ret_voidS  s   zIRBuilder.ret_voidc                 C   s   |  t| jd|S )z>
        Return from function with the given *value*.
        r?   r   )r   r   r   r   r    r?   Z  s   zIRBuilder.retc                 C   r   )z0
        Resume an in-flight exception.
        resumer   )r   
landingpadr   r   r   r    r   a  r   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    r<   k  s   
zIRBuilder.callc                 C   s   t ||||}| |||S )z#
        Inline assembler.
        )r   Z	InlineAsmr<   )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   r:   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   r:   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   $   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   "   t j| j|||d}| | |S )z4
        Returns the value at position idx.
        r5   )r   ZExtractElementr   r   )r   vectorrq   r   r   r   r   r    extract_element  s   
zIRBuilder.extract_elementc                 C   r  )z
        Returns vector with vector[idx] replaced by value.
        The result is undefined if the idx is larger or equal the vector length.
        r5   )r   ZInsertElementr   r   )r   r  r   rq   r   r   r   r   r    insert_element  s
   
zIRBuilder.insert_elementc                 C   r  )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.
        r5   )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.
        r5   )r6   tuplelistr   ZExtractValuer   r   )r   aggrq   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.
        r5   )r6   r  r  r   ZInsertValuer   r   )r   r  r   rq   r   r   r   r   r    insert_value  s
   
zIRBuilder.insert_valuec                 C   r  )Nr   )r   ZPhiInstrr   r   )r   rV   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   r   )Nr5   )r   Z	AtomicRMWr   r   )r   r   r   rU   r   r   r   r   r   r    
atomic_rmw  s
   
zIRBuilder.atomic_rmwc              	   C   s8   |du 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.
        Nr5   )r   ZCmpXchgr   r   )r   r   cmprU   r   Zfailorderingr   r   r   r   r    cmpxchg  s   
zIRBuilder.cmpxchgc                 C   s    t | j|||}| | |S r   )r   ZLandingPadInstrr   r   )r   rV   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)r9   r;   r<   )r   r   r'   r   r   r    assume  s   zIRBuilder.assumec                 C   r  )z
        Add a memory barrier, preventing certain reorderings of load and/or
        store accesses with
        respect to other processors and devices.
        r5   )r   ZFencer   r   )r   r   Ztargetscoper   r   r   r   r    fence  s   
zIRBuilder.fencec                 C   s   t | j|}| | |S )a  
        Puts a single-line comment into the generated IR. This will be ignored
        by LLVM, but can be useful for debugging the output of a compiler. Adds
        a comment to the source file.

        * *text* is a string that does not contain new line characters.
        )r   Commentr   r   )r   textr   r   r   r    comment  s   
zIRBuilder.commentz
llvm.bswapc                 C   r   )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$  r   zIRBuilder.bswapzllvm.bitreversec                 C   r   )zp
        Reverse the bitpattern of an integer value; for example 0b10110110
        becomes 0b01101101.
        Nr   r  r   r   r    
bitreverse+  r   zIRBuilder.bitreversez
llvm.ctpopc                 C   r   )z;
        Counts the number of bits set in a value.
        Nr   r  r   r   r    ctpop2  r   zIRBuilder.ctpopz	llvm.ctlzc                 C   r   )z
        Counts leading zero bits in *value*. Boolean *flag* indicates whether
        the result is defined for ``0``.
        Nr   r   r   rO   r   r   r    ctlz8  r   zIRBuilder.ctlzz	llvm.cttzc                 C   r   )z
        Counts trailing zero bits in *value*. Boolean *flag* indicates whether
        the result is defined for ``0``.
        Nr   r!  r   r   r    cttz?  r   zIRBuilder.cttzzllvm.fmac                 C   r   )z;
        Perform the fused multiply-add operation.
        Nr   )r   rQ   rR   rS   r   r   r    fmaF  r   zIRBuilder.fmac                 C   sv   |st dt|tjtjfst d| t|jtjr"|jjdks)t d|j d}| j	||g}| 
||g|S )z:
        Convert from an i16 to the given FP type
        zexpected a float return typerJ      zexpected an i16 type, got %szllvm.convert.from.fp16)r8   r6   r   rK   rL   r   r7   rN   r9   r;   r<   )r   rQ   tor   r   r'   r   r   r    convert_from_fp16L  s   zIRBuilder.convert_from_fp16zllvm.convert.to.fp16c                 C   r   )z7
        Convert the given FP number to an i16
        Nr   )r   rQ   r   r   r    convert_to_fp16[  r   zIRBuilder.convert_to_fp16r   rA   r"   )Nr   )r   N)r   NFr   r   N)r   Nr   r   N)Fr   )r   F)u__name__
__module____qualname__rd   propertyr   rs   rg   r9   rk   rl   rm   rn   ro   rr   
contextlibcontextmanagerru   rv   rx   r   r   r   r   r1   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rB   r   r   r   r   r   r   r   r   r+   r   r   r   r   r   r   r   rW   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rw   r}   r   r   r?   r   r<   r   r   r  r  r  r	  r
  r  r  r  r  r  r  r  r   r  r  r  rI   r  r  r   rP   r"  r#  rT   r$  r'  rM   r(  r   r   r   r    r_      s@   




	









		


	



















r_   )r-  r$   Zllvmlite.irr   r   r   r   Instructionr+   r1   rB   rE   rI   rM   rP   rT   Z	CastInstrrW   r^   objectr_   r   r   r   r    <module>   s*    
