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 #else
     83     // Mac OS' doesn't like cfi_* directives.
     84     #define CFI_STARTPROC
     85     #define CFI_ENDPROC
     86     #define CFI_ADJUST_CFA_OFFSET(size)
     87     #define CFI_DEF_CFA(reg,size)
     88     #define CFI_DEF_CFA_REGISTER(reg)
     89     #define CFI_RESTORE(reg)
     90     #define CFI_REL_OFFSET(reg,size)
     91     #define CFI_RESTORE_STATE
     92     #define CFI_REMEMBER_STATE
     93 #endif
     94 
     95     // Symbols. On a Mac, we need a leading underscore.
     96 #if !defined(__APPLE__)
     97     #define SYMBOL(name) name
     98     #define PLT_SYMBOL(name) name ## @PLT
     99 #else
    100     // Mac OS' symbols have an _ prefix.
    101     #define SYMBOL(name) _ ## name
    102     #define PLT_SYMBOL(name) _ ## name
    103 #endif
    104 
    105 // Directive to hide a function symbol.
    106 #if defined(__APPLE__)
    107     #define ASM_HIDDEN .private_extern
    108 #else
    109     #define ASM_HIDDEN .hidden
    110 #endif
    111 
    112     /* Cache alignment for function entry */
    113 MACRO0(ALIGN_FUNCTION_ENTRY)
    114     .balign 16
    115 END_MACRO
    116 
    117 MACRO1(DEFINE_FUNCTION, c_name)
    118     FUNCTION_TYPE(SYMBOL(\c_name))
    119     ASM_HIDDEN CALLVAR(c_name)
    120     .globl CALLVAR(c_name)
    121     ALIGN_FUNCTION_ENTRY
    122 CALLVAR(c_name):
    123     CFI_STARTPROC
    124     // Ensure we get a sane starting CFA.
    125     CFI_DEF_CFA(esp, 4)
    126 END_MACRO
    127 
    128 MACRO1(END_FUNCTION, c_name)
    129     CFI_ENDPROC
    130     SIZE(SYMBOL(\c_name))
    131 END_MACRO
    132 
    133 MACRO1(PUSH, reg)
    134     pushl REG_VAR(reg)
    135     CFI_ADJUST_CFA_OFFSET(4)
    136     CFI_REL_OFFSET(REG_VAR(reg), 0)
    137 END_MACRO
    138 
    139 MACRO1(POP, reg)
    140     popl REG_VAR(reg)
    141     CFI_ADJUST_CFA_OFFSET(-4)
    142     CFI_RESTORE(REG_VAR(reg))
    143 END_MACRO
    144 
    145 MACRO1(CFI_RESTORE_REG, reg)
    146     CFI_RESTORE(REG_VAR(reg))
    147 END_MACRO
    148 
    149 #define UNREACHABLE int3
    150 
    151 MACRO1(UNIMPLEMENTED,name)
    152     FUNCTION_TYPE(\name)
    153     .globl VAR(name)
    154     ALIGN_FUNCTION_ENTRY
    155 VAR(name):
    156     CFI_STARTPROC
    157     UNREACHABLE
    158     UNREACHABLE
    159     CFI_ENDPROC
    160     SIZE(\name)
    161 END_MACRO
    162 
    163 MACRO1(SETUP_GOT_NOSAVE, got_reg)
    164 #ifndef __APPLE__
    165     .ifc VAR(got_reg), ebx
    166       call __x86.get_pc_thunk.bx
    167       addl $_GLOBAL_OFFSET_TABLE_, %ebx
    168     .else
    169       .error "Unknown GOT register \got_reg"
    170     .endif
    171 #endif
    172 END_MACRO
    173 
    174 // Macros to poison (negate) the reference for heap poisoning.
    175 MACRO1(POISON_HEAP_REF, rRef)
    176 #ifdef USE_HEAP_POISONING
    177     neg REG_VAR(rRef)
    178 #endif  // USE_HEAP_POISONING
    179 END_MACRO
    180 
    181 // Macros to unpoison (negate) the reference for heap poisoning.
    182 MACRO1(UNPOISON_HEAP_REF, rRef)
    183 #ifdef USE_HEAP_POISONING
    184     neg REG_VAR(rRef)
    185 #endif  // USE_HEAP_POISONING
    186 END_MACRO
    187 
    188 
    189 #endif  // ART_RUNTIME_ARCH_X86_ASM_SUPPORT_X86_S_
    190