Home | History | Annotate | Download | only in powerpc
      1 /* -----------------------------------------------------------------------
      2    asm.h - Copyright (c) 1998 Geoffrey Keating
      3 
      4    PowerPC Assembly glue.
      5 
      6    Permission is hereby granted, free of charge, to any person obtaining
      7    a copy of this software and associated documentation files (the
      8    ``Software''), to deal in the Software without restriction, including
      9    without limitation the rights to use, copy, modify, merge, publish,
     10    distribute, sublicense, and/or sell copies of the Software, and to
     11    permit persons to whom the Software is furnished to do so, subject to
     12    the following conditions:
     13 
     14    The above copyright notice and this permission notice shall be included
     15    in all copies or substantial portions of the Software.
     16 
     17    THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
     18    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     19    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
     20    IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
     21    OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     22    ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     23    OTHER DEALINGS IN THE SOFTWARE.
     24    ----------------------------------------------------------------------- */
     25 
     26 #define ASM_GLOBAL_DIRECTIVE .globl
     27 
     28 
     29 #define C_SYMBOL_NAME(name) name
     30 /* Macro for a label.  */
     31 #ifdef	__STDC__
     32 #define C_LABEL(name)		name##:
     33 #else
     34 #define C_LABEL(name)		name/**/:
     35 #endif
     36 
     37 /* This seems to always be the case on PPC.  */
     38 #define ALIGNARG(log2) log2
     39 /* For ELF we need the `.type' directive to make shared libs work right.  */
     40 #define ASM_TYPE_DIRECTIVE(name,typearg) .type name,typearg;
     41 #define ASM_SIZE_DIRECTIVE(name) .size name,.-name
     42 
     43 /* If compiled for profiling, call `_mcount' at the start of each function.  */
     44 #ifdef	PROF
     45 /* The mcount code relies on a the return address being on the stack
     46    to locate our caller and so it can restore it; so store one just
     47    for its benefit.  */
     48 #ifdef PIC
     49 #define CALL_MCOUNT							      \
     50   .pushsection;								      \
     51   .section ".data";							      \
     52   .align ALIGNARG(2);							      \
     53 0:.long 0;								      \
     54   .previous;								      \
     55   mflr  %r0;								      \
     56   stw   %r0,4(%r1);							      \
     57   bl    _GLOBAL_OFFSET_TABLE_@local-4;					      \
     58   mflr  %r11;								      \
     59   lwz   %r0,0b@got(%r11);						      \
     60   bl    JUMPTARGET(_mcount);
     61 #else  /* PIC */
     62 #define CALL_MCOUNT							      \
     63   .section ".data";							      \
     64   .align ALIGNARG(2);							      \
     65 0:.long 0;								      \
     66   .previous;								      \
     67   mflr  %r0;								      \
     68   lis   %r11,0b@ha;							      \
     69   stw   %r0,4(%r1);							      \
     70   addi  %r0,%r11,0b@l;							      \
     71   bl    JUMPTARGET(_mcount);
     72 #endif /* PIC */
     73 #else  /* PROF */
     74 #define CALL_MCOUNT		/* Do nothing.  */
     75 #endif /* PROF */
     76 
     77 #define	ENTRY(name)							      \
     78   ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name);				      \
     79   ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function)			      \
     80   .align ALIGNARG(2);							      \
     81   C_LABEL(name)								      \
     82   CALL_MCOUNT
     83 
     84 #define EALIGN_W_0  /* No words to insert.  */
     85 #define EALIGN_W_1  nop
     86 #define EALIGN_W_2  nop;nop
     87 #define EALIGN_W_3  nop;nop;nop
     88 #define EALIGN_W_4  EALIGN_W_3;nop
     89 #define EALIGN_W_5  EALIGN_W_4;nop
     90 #define EALIGN_W_6  EALIGN_W_5;nop
     91 #define EALIGN_W_7  EALIGN_W_6;nop
     92 
     93 /* EALIGN is like ENTRY, but does alignment to 'words'*4 bytes
     94    past a 2^align boundary.  */
     95 #ifdef PROF
     96 #define EALIGN(name, alignt, words)					      \
     97   ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name);				      \
     98   ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function)			      \
     99   .align ALIGNARG(2);							      \
    100   C_LABEL(name)								      \
    101   CALL_MCOUNT								      \
    102   b 0f;									      \
    103   .align ALIGNARG(alignt);						      \
    104   EALIGN_W_##words;							      \
    105   0:
    106 #else /* PROF */
    107 #define EALIGN(name, alignt, words)					      \
    108   ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name);				      \
    109   ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function)			      \
    110   .align ALIGNARG(alignt);						      \
    111   EALIGN_W_##words;							      \
    112   C_LABEL(name)
    113 #endif
    114 
    115 #define END(name)							      \
    116   ASM_SIZE_DIRECTIVE(name)
    117 
    118 #ifdef PIC
    119 #define JUMPTARGET(name) name##@plt
    120 #else
    121 #define JUMPTARGET(name) name
    122 #endif
    123 
    124 /* Local labels stripped out by the linker.  */
    125 #define L(x) .L##x
    126