B
      ›\X  ã               @   s¾   d Z ddlZddlZddlmZ ddlmZ ddlm	Z	m
Z
 ddlmZ ddlmZ e
jdkoje
joje
j Zd	d
„ Zdd„ Zdd„ ZG dd„ deƒZG dd„ deƒZdd„ Zdd„ Zeƒ ZdS )zD
Register external C functions necessary for Numba code generation.
é    N)Úir)ÚutilsÚconfig)Ú
_helperlibé   )Ú
intrinsics)é   é   c             C   s   t  | ¡st  | |¡ dS )z1Add missing symbol into LLVM internal symtab
    N)ÚllZaddress_of_symbolÚ
add_symbol)ÚsymbolZaddr© r   ú6lib/python3.7/site-packages/numba/targets/externals.pyÚ_add_missing_symbol   s    
r   c             C   s,   ddl m}m}m} t|j| ƒ}|||ƒjS )zr
    Under Windows, look up a symbol inside the C runtime
    and return the raw pointer value as an integer.
    r   )ÚcdllÚcastÚc_void_p)Úctypesr   r   r   ÚgetattrZmsvcrtÚvalue)r   r   r   r   Úfr   r   r   Ú_get_msvcrt_symbol   s    r   c          
   C   s@  |   ¡ }| d¡}| d¡}t d¡}t d¡}t |d¡}t |d¡}t |d¡}t |||g¡}	tj||	dd}
|
j\}}|
 	¡ }t 
|¡}| ||¡}| ||¡}| | ||¡|¡}| | ||¡|¡}| | ||¡| ||¡¡}| ||¡}| ||¡}| || | ||¡| ||¡¡¡}| || ||¡¡}| ||¡}| ||¡}| ||¡}| || | ||¡| ||¡¡¡}| || ||¡¡}| || ||¡¡}| || | ||¡| ||¡¡¡}| || ||¡¡}| || ||¡¡}| ||¡}| || | ||¡|¡¡}| |¡ | |¡ | ¡  |S )zo
    Compile the multi3() helper function used by LLVM
    for 128-bit multiplication on 32-bit platforms.
    Úmulti3é@   é€   l   ÿÿ é    )Úname)ÚcodegenÚcreate_libraryZcreate_ir_moduler   ZIntTypeZConstantÚFunctionTypeZFunctionÚargsZappend_basic_blockZ	IRBuilderZtruncZashrÚmulÚand_ZlshrÚaddZshlZzextZretZadd_ir_moduleÚfinalize)Úcontextr   ÚlibraryÚir_modZi64Zi128Z
lower_maskZ_32Z_64Zfn_typeÚfnÚaÚbZbbZbuilderZalZblZahZbhZrlÚtZrhÚrr   r   r   Úcompile_multi3&   sP    







r-   c               @   s   e Zd ZdZdd„ ZdS )Ú
_InstallerFc             C   s   | j s|  |¡ d| _ dS )z˜
        Install the functions into LLVM.  This only needs to be done once,
        as the mappings are persistent during the process lifetime.
        TN)Ú
_installedÚ_do_install)Úselfr%   r   r   r   Úinstalls   s    
z_Installer.installN)Ú__name__Ú
__module__Ú__qualname__r/   r2   r   r   r   r   r.   o   s   r.   c               @   s   e Zd ZdZdd„ ZdS )Ú_ExternalMathFunctionszd
    Map the math functions from the C runtime library into the LLVM
    execution environment.
    c             C   sä   t jdk}tj}tj d¡r4|r4tdƒ}td|ƒ n,tj d¡r`|r`td|d ƒ td|d	 ƒ |rŒt	|ƒ| _
| j
 d
¡}|s‚t‚td|ƒ xBtjD ]8}tr¼| d¡r¼t ||d|  ¡ q”t ||| ¡ q”W tràt||ƒ| _d S )Nr   Zwin32Z_ftolZ_ftol2ZlinuxZ__fixunsdfdiZfptouiZ__fixunssfdiZfptouifr   Z__multi3ZfmodZfixed_)r   ZMACHINE_BITSr   Ú	c_helpersÚsysÚplatformÚ
startswithr   r   r-   Z_multi3_libÚget_pointer_to_functionÚAssertionErrorr   Z	INTR_MATHÚneed_kb982107r
   r   Ú
set_fnclexZ_kb982107_lib)r1   r%   Zis32bitr7   ZftolZptrÚfnamer   r   r   r0   ƒ   s&    


z"_ExternalMathFunctions._do_installN)r3   r4   r5   Ú__doc__r0   r   r   r   r   r6   }   s   r6   c             C   s8   |d }t  dt j¡|ƒ}t| ƒ}| d¡}||ƒ |S )zl
    Install fnclex before fmod calls.
    Workaround for https://support.microsoft.com/en-us/kb/982107
    r>   NZfnclex)r   Z	CFUNCTYPEr   Úcompile_fnclexr;   )r%   r7   Zptr_set_fnclexr(   r&   Z
fnclex_ptrr   r   r   r>   ©   s    
r>   c             C   s:   |   ¡ }| d¡}d}t ¡  | t |¡¡ | ¡  |S )zm
    Compile a function that calls fnclex to workround
    https://support.microsoft.com/en-us/kb/982107
    Zkb982107zT
define void @fnclex() {
  call void asm sideeffect "fnclex", ""()
  ret void
}
    )r   r   r
   Zinitialize_native_asmparserZadd_llvm_moduleZparse_assemblyr$   )r%   r   r&   r'   r   r   r   rA   ¸   s    
rA   )r@   r8   r   Zllvmliter   Zllvmlite.bindingZbindingr
   Znumbar   r   r   Ú r   Z	PYVERSIONZIS_WIN32Z	IS_32BITSr=   r   r   r-   Úobjectr.   r6   r>   rA   Zc_math_functionsr   r   r   r   Ú<module>   s$   

I,