Home | History | Annotate | Download | only in x86_64
      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_64_ASM_SUPPORT_X86_64_S_
     18 #define ART_RUNTIME_ARCH_X86_64_ASM_SUPPORT_X86_64_S_
     19 
     20 #include "asm_support_x86_64.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) PLT_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 #else
     85     // Mac OS' doesn't like cfi_* directives.
     86     #define CFI_STARTPROC
     87     #define CFI_ENDPROC
     88     #define CFI_ADJUST_CFA_OFFSET(size)
     89     #define CFI_DEF_CFA(reg,size)
     90     #define CFI_DEF_CFA_REGISTER(reg)
     91     #define CFI_RESTORE(reg)
     92     #define CFI_REL_OFFSET(reg,size)
     93 #endif
     94 
     95     // Symbols.
     96 #if !defined(__APPLE__)
     97     #define SYMBOL(name) name
     98     #if defined(__clang__) && (__clang_major__ < 4) && (__clang_minor__ < 5)
     99         // TODO: Disabled for old clang 3.3, this leads to text relocations and there should be a
    100         // better fix.
    101         #define PLT_SYMBOL(name) name // ## @PLT
    102     #else
    103         #define PLT_SYMBOL(name) name ## @PLT
    104     #endif
    105 #else
    106     #define SYMBOL(name) _ ## name
    107     #define PLT_SYMBOL(name) _ ## name
    108 #endif
    109 
    110 // Directive to hide a function symbol.
    111 #if defined(__APPLE__)
    112     #define ASM_HIDDEN .private_extern
    113 #else
    114     #define ASM_HIDDEN .hidden
    115 #endif
    116 
    117     /* Cache alignment for function entry */
    118 MACRO0(ALIGN_FUNCTION_ENTRY)
    119     .balign 16
    120 END_MACRO
    121 
    122 MACRO1(DEFINE_FUNCTION, c_name)
    123     FUNCTION_TYPE(\c_name, 0)
    124     ASM_HIDDEN VAR(c_name, 0)
    125     .globl VAR(c_name, 0)
    126     ALIGN_FUNCTION_ENTRY
    127 VAR(c_name, 0):
    128     CFI_STARTPROC
    129     // Ensure we get a sane starting CFA.
    130     CFI_DEF_CFA(rsp, 8)
    131 END_MACRO
    132 
    133 MACRO1(DEFINE_FUNCTION_NO_HIDE, c_name)
    134     FUNCTION_TYPE(\c_name, 0)
    135     .globl VAR(c_name, 0)
    136     ALIGN_FUNCTION_ENTRY
    137 VAR(c_name, 0):
    138     CFI_STARTPROC
    139     // Ensure we get a sane starting CFA.
    140     CFI_DEF_CFA(rsp, 8)
    141 END_MACRO
    142 
    143 MACRO1(END_FUNCTION, c_name)
    144     CFI_ENDPROC
    145     SIZE(\c_name, 0)
    146 END_MACRO
    147 
    148 MACRO1(PUSH, reg)
    149     pushq REG_VAR(reg, 0)
    150     CFI_ADJUST_CFA_OFFSET(8)
    151     CFI_REL_OFFSET(REG_VAR(reg, 0), 0)
    152 END_MACRO
    153 
    154 MACRO1(POP, reg)
    155     popq REG_VAR(reg,0)
    156     CFI_ADJUST_CFA_OFFSET(-8)
    157     CFI_RESTORE(REG_VAR(reg,0))
    158 END_MACRO
    159 
    160 MACRO1(UNIMPLEMENTED,name)
    161     FUNCTION_TYPE(\name, 0)
    162     ASM_HIDDEN VAR(c_name, 0)
    163     .globl VAR(name, 0)
    164     ALIGN_FUNCTION_ENTRY
    165 VAR(name, 0):
    166     CFI_STARTPROC
    167     int3
    168     int3
    169     CFI_ENDPROC
    170     SIZE(\name, 0)
    171 END_MACRO
    172 
    173 MACRO1(UNIMPLEMENTED_NO_HIDE,name)
    174     FUNCTION_TYPE(\name, 0)
    175     .globl VAR(name, 0)
    176     ALIGN_FUNCTION_ENTRY
    177 VAR(name, 0):
    178     CFI_STARTPROC
    179     int3
    180     int3
    181     CFI_ENDPROC
    182     SIZE(\name, 0)
    183 END_MACRO
    184 
    185 MACRO0(UNREACHABLE)
    186     int3
    187 END_MACRO
    188 
    189 MACRO0(UNTESTED)
    190     int3
    191 END_MACRO
    192 
    193 #endif  // ART_RUNTIME_ARCH_X86_64_ASM_SUPPORT_X86_64_S_
    194