B
    Ꮚ\F8                 @   sb  d dl mZmZ d dlZd dlmZmZmZmZm	Z	m
Z
mZ ddlmZ ddlmZmZ dd ZG d	d
 d
eZdd Zdd Zdd ZddddZd*ddZdd ZG dd dejZeddddgZeddd d!d"d#gZG d$d% d%ejZG d&d' d'ejZ d(d) Z!eegej"j#_$eegej"j%_$eej"j%_&eegej"j'_$eegej"j(_$egej"j)_$eej"j)_&egej"j*_$ej+ej"j*_&ej+eegej"j,_$ej+gej"j-_$ej+ej.gej"j/_$eej"j/_&ej+ej.egej"j0_$eej"j0_&ej+ej.gej"j1_$eej"j1_&ej+ej.gej"j2_$eej"j2_&eeegej"j3_$ej4ej"j3_&ej4gej"j5_$eej"j5_&ej4gej"j6_$eej"j6_&ej4eeeeeegej"j7_$ej8ej"j7_&ej8gej"j9_$ej8eegej"j:_$ej8egej"j;_$ej8ej<gej"j=_$ej8ej>eeegej"j?_$ej@ej"j?_&ej@gej"jA_$e
ej"jA_&ej@gej"jB_$e	ej"jB_&ej@gej"jC_$ej8gej"jD_$ej+ej"jD_&g ej"jE_$eej"jE_&dS )+    )print_functionabsolute_importN)POINTERc_char_p
c_longlongc_intc_size_tc_void_p	string_at   )ffi)_decode_string_encode_stringc           	   C   s(   t  } t j|  t| S Q R X dS )a  
    Return a target triple suitable for generating code for the current process.
    An example when the default triple from ``get_default_triple()`` is not be
    suitable is when LLVM is compiled for 32-bit but the process is executing
    in 64-bit mode.
    N)r   OutputStringlibLLVMPY_GetProcessTriplestr)out r   7lib/python3.7/site-packages/llvmlite/binding/targets.pyget_process_triple   s    
r   c               @   s   e Zd ZdZdddZdS )
FeatureMapz
    Maps feature name to a boolean indicating the availability of the feature.
    Extends ``dict`` to add `.flatten()` method.
    Tc                s>   |rt |  n
t|  }ddd d fdd|D S )ap  
        Args
        ----
        sort: bool
            Optional.  If True, the features are sorted by name; otherwise,
            the ordering is unstable between python session due to hash
            randomization.  Defaults to True.

        Returns a string suitable for use as the ``features`` argument to
        ``Target.create_target_machine()``.

        +-)TF,c             3   s"   | ]\}}d   | |V  qdS )z{0}{1}N)format).0kv)flag_mapr   r   	<genexpr>+   s   z%FeatureMap.flatten.<locals>.<genexpr>)sorteditemsiterjoin)selfsortiteratorr   )r   r   flatten   s    
zFeatureMap.flattenN)T)__name__
__module____qualname____doc__r(   r   r   r   r   r      s   r   c           	   C   sx   t  f} t }t j| s$tdddd}t| }|rjx.|dD ] }|rF||d  ||dd < qFW |S Q R X dS )	ac  
    Returns a dictionary-like object indicating the CPU features for current
    architecture and whether they are enabled for this CPU.  The key-value pairs
    are the feature name as string and a boolean indicating whether the feature
    is available.  The returned value is an instance of ``FeatureMap`` class,
    which adds a new method ``.flatten()`` for returning a string suitable for
    use as the "features" argument to ``Target.create_target_machine()``.

    If LLVM has not implemented this feature or it fails to get the information,
    this function will raise a RuntimeError exception.
    z failed to get host cpu features.TF)r   r   r   r   r   N)r   r   r   r   LLVMPY_GetHostCPUFeaturesRuntimeErrorr   split)r   Zoutdictr   ZcontentZfeatr   r   r   get_host_cpu_features/   s    

r0   c           	   C   s(   t  } t j|  t| S Q R X dS )zR
    Return the default target triple LLVM is configured to produce code for.
    N)r   r   r   LLVMPY_GetDefaultTargetTripler   )r   r   r   r   get_default_tripleH   s    
r2   c           	   C   s(   t  } t j|  t| S Q R X dS )zm
    Get the name of the host's CPU, suitable for using with
    :meth:`Target.create_target_machine()`.
    N)r   r   r   LLVMPY_GetHostCPUNamer   )r   r   r   r   get_host_cpu_nameP   s    
r4   ZCOFFZELFZMachO)r         c             C   s&   | dkrt  } tjt| }t| S )z~
    Get the object format for the given *triple* string (or the default
    triple if omitted).
    A string is returned
    N)r2   r   r   LLVMPY_GetTripleObjectFormatr   _object_formats)tripleZresr   r   r   get_object_format_   s    r:   c             C   s   t tjt| S )zE
    Create a TargetData instance for the given *layout* string.
    )
TargetDatar   r   LLVMPY_CreateTargetDatar   )Zlayoutr   r   r   create_target_datak   s    r=   c               @   s@   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dS )r;   z{
    A TargetData provides structured access to a data layout.
    Use :func:`create_target_data` to create instances.
    c          	   C   s4   | j r
dS t }tj| | t|S Q R X d S )Nz<dead TargetData>)Z_closedr   r   r    LLVMPY_CopyStringRepOfTargetDatar   )r%   r   r   r   r   __str__x   s
    
zTargetData.__str__c             C   s   | j |  d S )N)_capiLLVMPY_DisposeTargetData)r%   r   r   r   _dispose   s    zTargetData._disposec             C   s   t j| |S )z1
        Get ABI size of LLVM type *ty*.
        )r   r   LLVMPY_ABISizeOfType)r%   tyr   r   r   get_abi_size   s    zTargetData.get_abi_sizec             C   s0   t j| ||}|dkr,td|t||S )zL
        Get byte offset of type's ty element at the given position
        zRCould not determined offset of {}th element of the type '{}'. Is it a struct type?)r   r   LLVMPY_OffsetOfElement
ValueErrorr   r   )r%   rD   Zpositionoffsetr   r   r   get_element_offset   s
    zTargetData.get_element_offsetc             C   s(   t j| |}|dkr$td|f |S )zI
        Get ABI size of pointee type of LLVM pointer type *ty*.
        rF   zNot a pointer type: %s)r   r   LLVMPY_ABISizeOfElementTyper.   )r%   rD   sizer   r   r   get_pointee_abi_size   s    zTargetData.get_pointee_abi_sizec             C   s(   t j| |}|dkr$td|f |S )zV
        Get minimum ABI alignment of pointee type of LLVM pointer type *ty*.
        rF   zNot a pointer type: %s)r   r    LLVMPY_ABIAlignmentOfElementTyper.   )r%   rD   rL   r   r   r   get_pointee_abi_alignment   s    z$TargetData.get_pointee_abi_alignmentN)
r)   r*   r+   r,   r?   rB   rE   rJ   rM   rO   r   r   r   r   r;   r   s   	r;   defaultZstaticZpicZdynamicnopic
jitdefaultZsmallZkernelZmediumZlargec               @   s^   e Zd ZdZedd Zedd Zedd Zedd	 Z	ed
d Z
dd ZdddZdS )Target c             C   s   t  }| |S )zB
        Create a Target instance for the default triple.
        )r2   from_triple)clsr9   r   r   r   from_default_triple   s    zTarget.from_default_triplec          	   C   sJ   t  8}t j|d|}|s.tt|| |}||_|S Q R X dS )zK
        Create a Target instance for the given triple (a string).
        utf8N)r   r   r   LLVMPY_GetTargetFromTripleencoder.   r   _triple)rU   r9   outerrtargetr   r   r   rT      s    
zTarget.from_triplec             C   s   t j| }t|S )N)r   r   LLVMPY_GetTargetNamer   )r%   sr   r   r   name   s    zTarget.namec             C   s   t j| }t|S )N)r   r   LLVMPY_GetTargetDescriptionr   )r%   r^   r   r   r   description   s    zTarget.descriptionc             C   s   | j S )N)rZ   )r%   r   r   r   r9      s    zTarget.triplec             C   s   d | j| jS )Nz<Target {0} ({1})>)r   r_   ra   )r%   r   r   r   r?      s    zTarget.__str__r5   rP   rQ   Fc       
      C   s   d|  krdksn t |tks&t |tks2t | j}tjdkrR|dkrR|d7 }tj| t	|t	|t	||t	|t	|t
|t
|	}	|	rt|	S tddS )a>  
        Create a new TargetMachine for this target and the given options.

        Specifying codemodel='default' will result in the use of the "small"
        code model. Specifying codemodel='jitdefault' will result in the code
        model being picked based on platform bitness (32="small", 64="large").
        r   r6   ntrQ   z-elfzCannot create target machineN)AssertionErrorRELOC	CODEMODELrZ   osr_   r   r   LLVMPY_CreateTargetMachiner   intTargetMachiner.   )
r%   ZcpuZfeaturesZoptZrelocZ	codemodelZjitdebugZprintmcr9   Ztmr   r   r   create_target_machine   s$    

zTarget.create_target_machineN)rS   rS   r5   rP   rQ   FF)r)   r*   r+   rZ   classmethodrV   rT   propertyr_   ra   r9   r?   rj   r   r   r   r   rR      s     rR   c               @   sV   e Zd Zdd Zdd Zdd Zdd Zd	d
 ZdddZe	dd Z
e	dd ZdS )ri   c             C   s   | j |  d S )N)r@   LLVMPY_DisposeTargetMachine)r%   r   r   r   rB      s    zTargetMachine._disposec             C   s   t j| | dS )zW
        Register analysis passes for this target machine with a pass manager.
        N)r   r   LLVMPY_AddAnalysisPasses)r%   Zpmr   r   r   add_analysis_passes  s    z!TargetMachine.add_analysis_passesc             C   s   t j| | dS )z
        Set whether this target machine will emit assembly with human-readable
        comments describing control flow, debug information, and so on.
        N)r   r   #LLVMPY_SetTargetMachineAsmVerbosity)r%   verboser   r   r   set_asm_verbosity  s    zTargetMachine.set_asm_verbosityc             C   s   | j |ddS )z
        Represent the module as a code object, suitable for use with
        the platform's linker.  Returns a byte string.
        T)
use_object)_emit_to_memory)r%   moduler   r   r   emit_object  s    zTargetMachine.emit_objectc             C   s   t | j|ddS )z
        Return the raw assembler of the module, as a string.

        llvm.initialize_native_asmprinter() must have been called first.
        F)rs   )r   rt   )r%   ru   r   r   r   emit_assembly  s    zTargetMachine.emit_assemblyFc          	   C   sp   t  ,}t j| |t||}|s0tt|W dQ R X t j|}t j|}z
t	||S t j
| X dS )zReturns bytes of object code of the module.

        Args
        ----
        use_object : bool
            Emit object code or (if False) emit assembly code.
        N)r   r   r    LLVMPY_TargetMachineEmitToMemoryrh   r.   r   LLVMPY_GetBufferStartLLVMPY_GetBufferSizer
   LLVMPY_DisposeMemoryBuffer)r%   ru   rs   r[   ZmbZbufptrZbufszr   r   r   rt     s    


zTargetMachine._emit_to_memoryc             C   s   t tj| S )N)r;   r   r   LLVMPY_CreateTargetMachineData)r%   r   r   r   target_data3  s    zTargetMachine.target_datac          	   C   s*   t  }t j| | t|S Q R X d S )N)r   r   r   LLVMPY_GetTargetMachineTripler   )r%   r   r   r   r   r9   7  s    
zTargetMachine.tripleN)F)r)   r*   r+   rB   ro   rr   rv   rw   rt   rl   r}   r9   r   r   r   r   ri      s   
ri   c               C   s   t j dkrdS dS dS )zG
    Returns True if SVML was enabled at FFI support compile time.
    r   FTN)r   r   LLVMPY_HasSVMLSupportr   r   r   r   has_svml=  s    r   )N)FZ
__future__r   r   rf   Zctypesr   r   r   r   r   r	   r
   rS   r   commonr   r   r   dictr   r0   r2   r4   r8   r:   r=   Z	ObjectRefr;   	frozensetrd   re   rR   ri   r   r   r   Zargtypesr-   Zrestyper1   r3   r7   r<   ZLLVMTargetDataRefr>   rA   ZLLVMTypeRefrC   rG   rK   rN   rX   ZLLVMTargetRefr]   r`   rg   ZLLVMTargetMachineRefrm   r~   rp   ZLLVMPassManagerRefrn   ZLLVMModuleRefrx   ZLLVMMemoryBufferRefry   rz   r{   r|   r   r   r   r   r   <module>   s   $

5PA










