Home | History | Annotate | Download | only in x86
      1 /*
      2  * Copyright (C) 2013 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef ART_RUNTIME_ARCH_X86_ASM_SUPPORT_X86_S_
     18 #define ART_RUNTIME_ARCH_X86_ASM_SUPPORT_X86_S_
     19 
     20 #include "asm_support_x86.h"
     21 
     22 #if defined(__APPLE__) || (defined(__clang__) && (__clang_major__ < 4) && (__clang_minor__ < 5))
     23     // Clang's as(1) doesn't let you name macro parameters prior to 3.5.
     24     #define MACRO0(macro_name) .macro macro_name
     25     #define MACRO1(macro_name, macro_arg1) .macro macro_name
     26     #define MACRO2(macro_name, macro_arg1, macro_args2) .macro macro_name
     27     #define MACRO3(macro_name, macro_arg1, macro_args2, macro_args3) .macro macro_name
     28     #define END_MACRO .endmacro
     29 
     30     // Clang's as(1) uses $0, $1, and so on for macro arguments.
     31     #define RAW_VAR(name,index) $index
     32     #define VAR(name,index) SYMBOL($index)
     33     #define PLT_VAR(name, index) SYMBOL($index)
     34     #define REG_VAR(name,index) %$index
     35     #define CALL_MACRO(name,index) $index
     36 
     37     //  The use of $x for arguments mean that literals need to be represented with $$x in macros.
     38     #define LITERAL(value) $value
     39     #define MACRO_LITERAL(value) $$value
     40 #else
     41     // Regular gas(1) lets you name macro parameters.
     42     #define MACRO0(macro_name) .macro macro_name
     43     #define MACRO1(macro_name, macro_arg1) .macro macro_name macro_arg1
     44     #define MACRO2(macro_name, macro_arg1, macro_arg2) .macro macro_name macro_arg1, macro_arg2
     45     #define MACRO3(macro_name, macro_arg1, macro_arg2, macro_arg3) .macro macro_name macro_arg1, macro_arg2, macro_arg3
     46     #define END_MACRO .endm
     47 
     48     // Regular gas(1) uses \argument_name for macro arguments.
     49     // We need to turn on alternate macro syntax so we can use & instead or the preprocessor
     50     // will screw us by inserting a space between the \ and the name. Even in this mode there's
     51     // no special meaning to $, so literals are still just $x. The use of altmacro means % is a
     52     // special character meaning care needs to be taken when passing registers as macro arguments.
     53     .altmacro
     54     #define RAW_VAR(name,index) name&
     55     #define VAR(name,index) name&
     56     #define PLT_VAR(name, index) name&@PLT
     57     #define REG_VAR(name,index) %name
     58     #define CALL_MACRO(name,index) name&
     59 
     60     #define LITERAL(value) $value
     61     #define MACRO_LITERAL(value) $value
     62 #endif
     63 
     64 #if defined(__APPLE__)
     65     #define FUNCTION_TYPE(name,index)
     66     #define SIZE(name,index)
     67 #elif defined(__clang__) && (__clang_major__ < 4) && (__clang_minor__ < 5)
     68     #define FUNCTION_TYPE(name,index) .type $index, @function
     69     #define SIZE(name,index) .size $index, .-$index
     70 #else
     71     #define FUNCTION_TYPE(name,index) .type name&, @function
     72     #define SIZE(name,index) .size name, .-name
     73 #endif
     74 
     75     // CFI support.
     76 #if !defined(__APPLE__)
     77     #define CFI_STARTPROC .cfi_startproc
     78     #define CFI_ENDPROC .cfi_endproc
     79     #define CFI_ADJUST_CFA_OFFSET(size) .cfi_adjust_cfa_offset size
     80     #define CFI_DEF_CFA(reg,size) .cfi_def_cfa reg,size
     81     #define CFI_DEF_CFA_REGISTER(reg) .cfi_def_cfa_register reg
     82     #define CFI_RESTORE(reg) .cfi_restore reg
     83     #define CFI_REL_OFFSET(reg,size) .cfi_rel_offset reg,size
     84     #define CFI_RESTORE_STATE .cfi_restore_state
     85     #define CFI_REMEMBER_STATE .cfi_remember_state
     86 #else
     87     // Mac OS' doesn't like cfi_* directives.
     88     #define CFI_STARTPROC
     89     #define CFI_ENDPROC
     90     #define CFI_ADJUST_CFA_OFFSET(size)
     91     #define CFI_DEF_CFA(reg,size)
     92     #define CFI_DEF_CFA_REGISTER(reg)
     93     #define CFI_RESTORE(reg)
     94     #define CFI_REL_OFFSET(reg,size)
     95     #define CFI_RESTORE_STATE
     96     #define CFI_REMEMBER_STATE
     97 #endif
     98 
     99     // Symbols.
    100 #if !defined(__APPLE__)
    101     #define SYMBOL(name) name
    102     #if defined(__clang__) && (__clang_major__ < 4) && (__clang_minor__ < 5)
    103         // TODO: Disabled for old clang 3.3, this leads to text relocations and there should be a
    104         // better fix.
    105         #define PLT_SYMBOL(name) name // ## @PLT
    106     #else
    107         #define PLT_SYMBOL(name) name ## @PLT
    108     #endif
    109 #else
    110     // Mac OS' symbols have an _ prefix.
    111     #define SYMBOL(name) _ ## name
    112     #define PLT_SYMBOL(name) _ ## name
    113 #endif
    114 
    115 // Directive to hide a function symbol.
    116 #if defined(__APPLE__)
    117     #define ASM_HIDDEN .private_extern
    118 #else
    119     #define ASM_HIDDEN .hidden
    120 #endif
    121 
    122     /* Cache alignment for function entry */
    123 MACRO0(ALIGN_FUNCTION_ENTRY)
    124     .balign 16
    125 END_MACRO
    126 
    127 MACRO1(DEFINE_FUNCTION, c_name)
    128     FUNCTION_TYPE(\c_name, 0)
    129     ASM_HIDDEN VAR(c_name, 0)
    130     .globl VAR(c_name, 0)
    131     ALIGN_FUNCTION_ENTRY
    132 VAR(c_name, 0):
    133     CFI_STARTPROC
    134     // Ensure we get a sane starting CFA.
    135     CFI_DEF_CFA(esp, 4)
    136 END_MACRO
    137 
    138 MACRO1(DEFINE_FUNCTION_NO_HIDE, c_name)
    139     FUNCTION_TYPE(\c_name, 0)
    140     .globl VAR(c_name, 0)
    141     ALIGN_FUNCTION_ENTRY
    142 VAR(c_name, 0):
    143     CFI_STARTPROC
    144     // Ensure we get a sane starting CFA.
    145     CFI_DEF_CFA(esp, 4)
    146 END_MACRO
    147 
    148 MACRO1(END_FUNCTION, c_name)
    149     CFI_ENDPROC
    150     SIZE(\c_name, 0)
    151 END_MACRO
    152 
    153 MACRO1(PUSH, reg)
    154     pushl REG_VAR(reg, 0)
    155     CFI_ADJUST_CFA_OFFSET(4)
    156     CFI_REL_OFFSET(REG_VAR(reg, 0), 0)
    157 END_MACRO
    158 
    159 MACRO1(POP, reg)
    160     popl REG_VAR(reg,0)
    161     CFI_ADJUST_CFA_OFFSET(-4)
    162     CFI_RESTORE(REG_VAR(reg,0))
    163 END_MACRO
    164 
    165 MACRO1(UNIMPLEMENTED,name)
    166     FUNCTION_TYPE(\name, 0)
    167     .globl VAR(name, 0)
    168     ALIGN_FUNCTION_ENTRY
    169 VAR(name, 0):
    170     CFI_STARTPROC
    171     int3
    172     int3
    173     CFI_ENDPROC
    174     SIZE(\name, 0)
    175 END_MACRO
    176 
    177 MACRO0(SETUP_GOT_NOSAVE)
    178 #ifndef __APPLE__
    179     call __x86.get_pc_thunk.bx
    180     addl $_GLOBAL_OFFSET_TABLE_, %ebx
    181 #endif
    182 END_MACRO
    183 
    184 MACRO0(SETUP_GOT)
    185     PUSH  ebx
    186     SETUP_GOT_NOSAVE
    187 END_MACRO
    188 
    189 MACRO0(UNDO_SETUP_GOT)
    190     POP  ebx
    191 END_MACRO
    192 
    193 #endif  // ART_RUNTIME_ARCH_X86_ASM_SUPPORT_X86_S_
    194