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 // Regular gas(1) & current clang/llvm assembler support named macro parameters.
     23 #define MACRO0(macro_name) .macro macro_name
     24 #define MACRO1(macro_name, macro_arg1) .macro macro_name macro_arg1
     25 #define MACRO2(macro_name, macro_arg1, macro_arg2) .macro macro_name macro_arg1, macro_arg2
     26 #define MACRO3(macro_name, macro_arg1, macro_arg2, macro_arg3) .macro macro_name macro_arg1, macro_arg2, macro_arg3
     27 #define MACRO4(macro_name, macro_arg1, macro_arg2, macro_arg3, macro_arg4) .macro macro_name macro_arg1, macro_arg2, macro_arg3, macro_arg4
     28 #define MACRO5(macro_name, macro_arg1, macro_arg2, macro_arg3, macro_arg4, macro_arg5) .macro macro_name macro_arg1, macro_arg2, macro_arg3, macro_arg4, macro_arg5
     29 #define END_MACRO .endm
     30 
     31 #if defined(__clang__)
     32     // Clang/llvm does not support .altmacro. However, the clang/llvm preprocessor doesn't
     33     // separate the backslash and parameter by a space. Everything just works.
     34     #define RAW_VAR(name) \name
     35     #define VAR(name) \name
     36     #define CALLVAR(name) SYMBOL(\name)
     37     #define PLT_VAR(name) \name@PLT
     38     #define REG_VAR(name) %\name
     39     #define CALL_MACRO(name) \name
     40 #else
     41     // Regular gas(1) uses \argument_name for macro arguments.
     42     // We need to turn on alternate macro syntax so we can use & instead or the preprocessor
     43     // will screw us by inserting a space between the \ and the name. Even in this mode there's
     44     // no special meaning to $, so literals are still just $x. The use of altmacro means % is a
     45     // special character meaning care needs to be taken when passing registers as macro
     46     // arguments.
     47     .altmacro
     48     #define RAW_VAR(name) name&
     49     #define VAR(name) name&
     50     #define CALLVAR(name) SYMBOL(name&)
     51     #define PLT_VAR(name) name&@PLT
     52     #define REG_VAR(name) %name
     53     #define CALL_MACRO(name) name&
     54 #endif
     55 
     56 #define LITERAL(value) $value
     57 #if defined(__APPLE__)
     58     #define MACRO_LITERAL(value) $(value)
     59 #else
     60     #define MACRO_LITERAL(value) $value
     61 #endif
     62 
     63 #if defined(__APPLE__)
     64     #define FUNCTION_TYPE(name)
     65     #define SIZE(name)
     66 #else
     67     #define FUNCTION_TYPE(name) .type name, @function
     68     #define SIZE(name) .size name, .-name
     69 #endif
     70 
     71     // CFI support.
     72 #if !defined(__APPLE__)
     73     #define CFI_STARTPROC .cfi_startproc
     74     #define CFI_ENDPROC .cfi_endproc
     75     #define CFI_ADJUST_CFA_OFFSET(size) .cfi_adjust_cfa_offset size
     76     #define CFI_DEF_CFA(reg,size) .cfi_def_cfa reg,size
     77     #define CFI_DEF_CFA_REGISTER(reg) .cfi_def_cfa_register reg
     78     #define CFI_RESTORE(reg) .cfi_restore reg
     79     #define CFI_REL_OFFSET(reg,size) .cfi_rel_offset reg,size
     80     #define CFI_RESTORE_STATE .cfi_restore_state
     81     #define CFI_REMEMBER_STATE .cfi_remember_state
     82     #define CFI_ESCAPE(...) .cfi_escape __VA_ARGS__
     83 #else
     84     // Mac OS' doesn't like cfi_* directives.
     85     #define CFI_STARTPROC
     86     #define CFI_ENDPROC
     87     #define CFI_ADJUST_CFA_OFFSET(size)
     88     #define CFI_DEF_CFA(reg,size)
     89     #define CFI_DEF_CFA_REGISTER(reg)
     90     #define CFI_RESTORE(reg)
     91     #define CFI_REL_OFFSET(reg,size)
     92     #define CFI_RESTORE_STATE
     93     #define CFI_REMEMBER_STATE
     94     #define CFI_ESCAPE(...)
     95 #endif
     96 
     97     // Symbols. On a Mac, we need a leading underscore.
     98 #if !defined(__APPLE__)
     99     #define SYMBOL(name) name
    100     #define PLT_SYMBOL(name) name ## @PLT
    101 #else
    102     // Mac OS' symbols have an _ prefix.
    103     #define SYMBOL(name) _ ## name
    104     #define PLT_SYMBOL(name) _ ## name
    105 #endif
    106 
    107 // Directive to hide a function symbol.
    108 #if defined(__APPLE__)
    109     #define ASM_HIDDEN .private_extern
    110 #else
    111     #define ASM_HIDDEN .hidden
    112 #endif
    113 
    114     /* Cache alignment for function entry */
    115 MACRO0(ALIGN_FUNCTION_ENTRY)
    116     .balign 16
    117 END_MACRO
    118 
    119 MACRO2(DEFINE_FUNCTION_CUSTOM_CFA, c_name, cfa_offset)
    120     FUNCTION_TYPE(SYMBOL(\c_name))
    121     ASM_HIDDEN CALLVAR(c_name)
    122     .globl CALLVAR(c_name)
    123     ALIGN_FUNCTION_ENTRY
    124 CALLVAR(c_name):
    125     CFI_STARTPROC
    126     // Ensure we get a sane starting CFA.
    127     CFI_DEF_CFA(esp, RAW_VAR(cfa_offset))
    128 END_MACRO
    129 
    130 MACRO1(DEFINE_FUNCTION, c_name)
    131     DEFINE_FUNCTION_CUSTOM_CFA RAW_VAR(c_name), __SIZEOF_POINTER__
    132 END_MACRO
    133 
    134 MACRO1(END_FUNCTION, c_name)
    135     CFI_ENDPROC
    136     SIZE(SYMBOL(\c_name))
    137 END_MACRO
    138 
    139 MACRO1(PUSH, reg)
    140     pushl REG_VAR(reg)
    141     CFI_ADJUST_CFA_OFFSET(4)
    142     CFI_REL_OFFSET(REG_VAR(reg), 0)
    143 END_MACRO
    144 
    145 MACRO1(POP, reg)
    146     popl REG_VAR(reg)
    147     CFI_ADJUST_CFA_OFFSET(-4)
    148     CFI_RESTORE(REG_VAR(reg))
    149 END_MACRO
    150 
    151 MACRO1(CFI_RESTORE_REG, reg)
    152     CFI_RESTORE(REG_VAR(reg))
    153 END_MACRO
    154 
    155 #define UNREACHABLE int3
    156 
    157 MACRO1(UNIMPLEMENTED,name)
    158     FUNCTION_TYPE(\name)
    159     .globl VAR(name)
    160     ALIGN_FUNCTION_ENTRY
    161 VAR(name):
    162     CFI_STARTPROC
    163     UNREACHABLE
    164     UNREACHABLE
    165     CFI_ENDPROC
    166     SIZE(\name)
    167 END_MACRO
    168 
    169 MACRO1(SETUP_GOT_NOSAVE, got_reg)
    170 #ifndef __APPLE__
    171     .ifc VAR(got_reg), ebx
    172       call __x86.get_pc_thunk.bx
    173       addl $_GLOBAL_OFFSET_TABLE_, %ebx
    174     .else
    175       .error "Unknown GOT register \got_reg"
    176     .endif
    177 #endif
    178 END_MACRO
    179 
    180 // Macros to poison (negate) the reference for heap poisoning.
    181 MACRO1(POISON_HEAP_REF, rRef)
    182 #ifdef USE_HEAP_POISONING
    183     neg REG_VAR(rRef)
    184 #endif  // USE_HEAP_POISONING
    185 END_MACRO
    186 
    187 // Macros to unpoison (negate) the reference for heap poisoning.
    188 MACRO1(UNPOISON_HEAP_REF, rRef)
    189 #ifdef USE_HEAP_POISONING
    190     neg REG_VAR(rRef)
    191 #endif  // USE_HEAP_POISONING
    192 END_MACRO
    193 
    194 
    195 #endif  // ART_RUNTIME_ARCH_X86_ASM_SUPPORT_X86_S_
    196