darwin-xnu/EXTERNAL_HEADERS/architecture/ppc/asm_help.h
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
   3 *
   4 * @APPLE_LICENSE_HEADER_START@
   5 * 
   6 * The contents of this file constitute Original Code as defined in and
   7 * are subject to the Apple Public Source License Version 1.1 (the
   8 * "License").  You may not use this file except in compliance with the
   9 * License.  Please obtain a copy of the License at
  10 * http://www.apple.com/publicsource and read it before using this file.
  11 * 
  12 * This Original Code and all software distributed under the License are
  13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
  16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
  17 * License for the specific language governing rights and limitations
  18 * under the License.
  19 * 
  20 * @APPLE_LICENSE_HEADER_END@
  21 */
  22/* Copyright (c) 1996 NeXT Software, Inc.  All rights reserved.
  23 *
  24 *      File:   architecture/ppc/asm_help.h
  25 *      Author: Mike DeMoney, NeXT Software, Inc.
  26 *
  27 *      This header file defines macros useful when writing assembly code
  28 *      for the PowerPC processors.
  29 *      r12 is used as the tmp register / PICIFY base.
  30 *
  31 * HISTORY
  32 * 20-May-97  Umesh Vaishampayan (umeshv@apple.com)
  33 *      Implemented Dynamic / PIC macros.
  34 *
  35 * 28-Dec-96  Umesh Vaishampayan (umeshv@NeXT.com)
  36 *      added ".align" directive to various macros to avoid alignment 
  37 *      faults. Moved Register Usage #defines to reg_help.h as that's
  38 *      where they should have been in the first place.
  39 *      Added Dynamic / PIC macroes for routines which refernce external
  40 *      symbols. Not implemented fully as yet.
  41 *
  42 * 05-Nov-92  Mike DeMoney (mike@next.com)
  43 *      Created.
  44 */
  45
  46#ifndef _ARCH_PPC_ASM_HELP_H_
  47#define _ARCH_PPC_ASM_HELP_H_
  48
  49#include        <architecture/ppc/reg_help.h>
  50
  51#ifdef  __ASSEMBLER__
  52/*
  53 * ppc stack frames look like this after procedure prolog has
  54 * been executed:
  55 *
  56 * Higher address:
  57 *                      .........
  58 *              +-------------------------------+
  59 *              | caller's LR                   |
  60 *              +-------------------------------+
  61 *              | caller's CR                   |
  62 *              +-------------------------------+
  63 * Caller's SP->| caller's caller's sp          |  ^^ Caller's Frame ^^
  64 *              +===============================+  vv Called Rtn Frame vv
  65 *              |       Save Area for           | FPF 31
  66 *                      ..........
  67 *              |       Caller's FPF's          | FPF n
  68 *              +-------------------------------+
  69 *              |       Save Area for           | GRF 31
  70 *                      ..........
  71 *              |       Caller's GRF's          | GRF n
  72 *              +-------------------------------+
  73 *              |       alignment pad           |
  74 *                      ............
  75 *              |       (if necessary)          |
  76 *              +-------------------------------+
  77 *              |       Local                   |
  78 *                      ........
  79 *              |       Variables               |
  80 *              +-------------------------------+
  81 * SP + X ->    | aN for FUTURE call            |
  82 *              +-------------------------------+
  83 *                      ..........
  84 *              +-------------------------------+
  85 * SP + 28 ->   | a1 for FUTURE call            |
  86 *              +-------------------------------+
  87 * SP + 24 ->   | a0 for FUTURE call            |
  88 *              +-------------------------------+
  89 * SP + 20 ->   | caller's TOC                  |
  90 *              +-------------------------------+
  91 * SP + 16 ->   | reserved                      |
  92 *              +-------------------------------+
  93 * SP + 12 ->   | reserved                      |
  94 *              +-------------------------------+
  95 * SP + 8 ->    | LR callee-save for FUTURE call|
  96 *              +-------------------------------+
  97 * SP + 4 ->    | CR callee-save for FUTURE call|
  98 *              +-------------------------------+
  99 * SP ->        | caller's sp                   |
 100 *              +===============================+
 101 * Lower address:
 102 *
 103 * NOTE: All state with the exception of LR and CR are saved in the
 104 * called routines frame.  LR and CR are saved in the CALLER'S FRAME.
 105 *
 106 * ALSO NOTE: Args to the called routine are found in the caller's frame.
 107 */
 108
 109/*
 110 * ARG(n) -- stack offset to n'th argument
 111 *
 112 * NOTE CAREFULLY!  These macros start numbering arguments at 1 (NOT 0)
 113 * The first argument is ARG(1).
 114 *
 115 * ALSO NOTE:  This stack offset is only valid if using routine
 116 * DOES NOT alter SP.
 117 *
 118 */
 119#define ARG(n)          ((((n) - 1) * 4) + 24)
 120
 121/*
 122 * Macros for building stack frame according to C calling conventions.
 123 * lr, cr, and sp are saved.
 124 *
 125 * NOTE WELL: localvarsize is in bytes, maxargsout is a count of words,
 126 * grfsaved and fpfsaved is a count of registers.  BE SURE TO COUNT
 127 * BOTH FP (r31) AND sN REGISTERS IN THE COUNT OF GRF REGISTERS SAVED!
 128 * This will be TWO more than the N of the highest sN register you
 129 * save: s2 implies you are saving s2, s1, s0, and fp => grfsaved
 130 * should be 4!
 131 *
 132 * FURTHER NOTE: These macros do NOT SAVE GRF or FPF registers.  User
 133 * must do that.  GRF sN regs should be saved via
 134 *      stmw    sN,SAVED_GRF_S(N)(sp)
 135 * where N is the highest numbered s* register to be saved.  E.g. if
 136 * s0, s1, and s2 are to be saved use:
 137 *      stmw    s2,SAVED_GRF_S(2)(sp)
 138 * Note that this also saves fp.
 139 * An individual saved grf can be loaded via:
 140 *      lwz     s2,SAVED_GRF_S(2)(sp)
 141 * Analogous stuff works for fpf's.
 142 *
 143 * NOTE: these simple routines will be replaced with more complicated
 144 * ones once we know what the linker and gdb will require as for as 
 145 * register use masks and frame declarations.
 146 *
 147 * Warning: ROUND_TO_STACK is only to be used in assembly language;
 148 * for C usage, use ROUND_FRAME() in reg_help.h.
 149 */
 150#define ROUND_TO_STACK(len)                             \
 151        (((len) + STACK_INCR - 1) / STACK_INCR * STACK_INCR)
 152
 153#define BUILD_FRAME(localvarsize, maxargsout, grfsaved, fpfsaved)       \
 154        .set    __argoutsize, ROUND_TO_STACK((maxargsout) * 4)          @\
 155        .if     __argoutsize < 32                                       @\
 156          .set  __argoutsize,32                                         @\
 157        .endif                                                          @\
 158        .set    __framesize, ROUND_TO_STACK(                            \
 159                        24 + __argoutsize + (localvarsize)              \
 160                        + 4*(grfsaved) + 8*(fpfsaved))                  @\
 161        .set    __grfbase,(__framesize - 4*(grfsaved) - 8*(fpfsaved))   @\
 162        .set    __fpfbase,(__framesize - 8*(fpfsaved))                  @\
 163        mflr    r0                                                      @\
 164        mfcr    r12                                                     @\
 165        stw     r0,8(sp)                                                @\
 166        stw     r12,4(sp)                                               @\
 167        stwu    r1,-__framesize(r1)
 168
 169/*
 170 * Macros for referencing data in stack frame.
 171 *
 172 * NOTE WELL: ARG's and VAR's start at 1, NOT 0. Why ??? (FIXME)
 173 */
 174#define LOCAL_VAR(n)    (((n)-1)*4 + __argoutsize + 24)
 175#define SAVED_GRF_S(n)  (__grfbase + ((grfsaved) - (n) - 2) * 4)
 176#define SAVED_FRF_FS(n) (__fpfbase + ((fpfsaved) - (n) - 1) * 4)
 177#define ARG_IN(n)       (ARG(n) + __framesize)
 178#define ARG_OUT(n)      (ARG(n) + 0)
 179#define SAVED_FP        (__grfbase + ((grfsaved) - 1) * 4)
 180#define SAVED_LR        (__framesize + 8)
 181#define SAVED_CR        (__framesize + 4)
 182
 183/*
 184 * Macros for unwinding stack frame.
 185 * NOTE: GRF's and FPF's are NOT RESTORED.  User must do this before
 186 * using this macro.
 187 */
 188#define RETURN                                          \
 189        .if     __framesize                             @\
 190          lwz32 r0,r1,SAVED_LR                          @\
 191          lwz32 r12,r1,SAVED_CR                         @\
 192          addic sp,r1,__framesize                       @\
 193          mtlr  r0                                      @\
 194          mtcrf 0xff,r12                                @\
 195          blr                                           @\
 196        .else                                           @\
 197          blr                                           @\
 198        .endif
 199
 200
 201/*
 202 * Macros for declaring procedures
 203 *
 204 * Use of these macros allows ctags to have a predictable way
 205 * to find various types of declarations.  They also simplify
 206 * inserting appropriate symbol table information.
 207 *
 208 * NOTE: these simple stubs will be replaced with more
 209 * complicated versions once we know what the linker and gdb
 210 * will require as far as register use masks and frame declarations.
 211 * These macros may also be ifdef'ed in the future to contain profiling
 212 * code.
 213 *
 214 * FIXME: Document what makes a leaf a LEAF and a handler a HANDLER.
 215 * (E.g. leaf's have return pc in lr, NESTED's have rpc in offset off
 216 * sp, handlers have rpc in exception frame which is found via exception
 217 * link, etc etc.)
 218 */
 219
 220/*
 221 * TEXT -- declare start of text segment
 222 */
 223#define TEXT                                            \
 224        .text                                           @\
 225        .align 2
 226
 227/*
 228 * LEAF -- declare global leaf procedure
 229 * NOTE: Control SHOULD NOT FLOW into a LEAF!  A LEAF should only
 230 * be jumped to.  (A leaf may do an align.)  Use a LABEL() if you
 231 * need control to flow into the label.
 232 */
 233#define LEAF(name)                                      \
 234        .align 2                                        @\
 235        .globl  name                                    @\
 236name:                                                   @\
 237        .set    __framesize,0
 238
 239/*
 240 * X_LEAF -- declare alternate global label for leaf
 241 */
 242#define X_LEAF(name, value)                             \
 243        .globl  name                                    @\
 244        .set    name,value
 245
 246/*
 247 * P_LEAF -- declare private leaf procedure
 248 */
 249#define P_LEAF(name)                                    \
 250        .align 2                                        @\
 251name:                                                   @\
 252        .set    __framesize,0
 253
 254/*
 255 * LABEL -- declare a global code label
 256 * MUST be used (rather than LEAF, NESTED, etc) if control
 257 * "flows into" the label.
 258 */
 259#define LABEL(name)                                     \
 260        .align 2                                        @\
 261        .globl  name                                    @\
 262name:
 263
 264/*
 265 * NESTED -- declare procedure that invokes other procedures
 266 */
 267#define NESTED(name, localvarsize, maxargsout, grfsaved, fpfsaved)\
 268        .align 2                                @\
 269        .globl  name                            @\
 270name:                                           @\
 271        BUILD_FRAME(localvarsize, maxargsout, grfsaved, fpfsaved)
 272
 273/*
 274 * X_NESTED -- declare alternate global label for nested proc
 275 */
 276#define X_NESTED(name, value)                   \
 277        .globl  name                            @\
 278        .set    name,value
 279
 280/*
 281 * P_NESTED -- declare private nested procedure
 282 */
 283#define P_NESTED(name, localvarsize, maxargsout, grfsaved, fpfsaved)\
 284        .align 2                                        @\
 285name:                                                   @\
 286        BUILD_FRAME(locavarsize, maxargsout, grfsaved, fpfsaved)
 287
 288/*
 289 * HANDLER -- declare procedure with exception frame rather than
 290 * standard C frame
 291 */
 292#define HANDLER(name)                                   \
 293        .align 2                                        @\
 294        .globl  name                                    @\
 295name:
 296
 297/*
 298 * X_HANDLER -- declare alternate name for exception handler
 299 * (Should appear immediately before a HANDLER declaration or
 300 * another X_HANDLER declaration)
 301 */
 302#define X_HANDLER(name)                                 \
 303        .align 2                                        @\
 304        .globl  name                                    @\
 305name:
 306
 307/*
 308 * P_HANDLER -- declare private handler
 309 */
 310#define P_HANDLER(name)                                 \
 311        .align 2                                @\
 312name:
 313
 314/*
 315 * END -- mark end of procedure
 316 * FIXME: Unimplemented for now.
 317 */
 318#define END(name)
 319
 320/*
 321 * BL -- call procedure (relative)
 322 */
 323#define BL(name)                                        \
 324        bl      name
 325
 326/*
 327 * Storage definition macros
 328 * The main purpose of these is to allow an easy handle for ctags
 329 */
 330
 331/*
 332 * IMPORT -- import symbol
 333 */
 334#define IMPORT(name)                                    \
 335        .reference      name
 336
 337/*
 338 * ABS -- declare global absolute symbol
 339 */
 340#define ABS(name, value)                                \
 341        .globl  name                                    @\
 342        .set    name,value
 343
 344/*
 345 * P_ABS -- declare private absolute symbol
 346 */
 347#define P_ABS(name, value)                              \
 348        .set    name,value
 349
 350/*
 351 * EXPORT -- declare global label for data
 352 */
 353#define EXPORT(name)                                    \
 354        .align 2                                        @\
 355        .globl  name                                    @\
 356name:
 357
 358/*
 359 * BSS -- declare global zero'ed storage
 360 */
 361#define BSS(name,size)                                  \
 362        .comm   name,size
 363
 364
 365/*
 366 * P_BSS -- declare private zero'ed storage
 367 */
 368#define P_BSS(name,size)                                \
 369        .lcomm  name,size
 370
 371/*
 372 * dynamic/PIC macros for routines which reference external symbols
 373 */
 374#if defined(__DYNAMIC__)
 375#define PICIFY_REG r12
 376
 377/* Assume that the lr is saved before calling any of these macros */
 378/* using PICIFY() */
 379
 380#define PICIFY(var)                             \
 381        mflr    r0                              @\
 382        bl      1f                              @\
 3831:      mflr    PICIFY_REG                      @\
 384        mtlr    r0                              @\
 385        addis   PICIFY_REG, PICIFY_REG, ha16(L ## var ## $non_lazy_ptr - 1b) @\
 386        lwz     PICIFY_REG, lo16(L ## var ## $non_lazy_ptr - 1b)(PICIFY_REG)
 387
 388#define CALL_EXTERN_AGAIN(var)                  \
 389        PICIFY(var)                             @\
 390        mtctr   PICIFY_REG                      @\
 391        mflr    r0                              @\
 392        stw     r0,8(r1)                        @\
 393        stwu    r1,-56(r1)                      @\
 394        bctrl                                   @\
 395        addic   r1,r1,56                        @\
 396        lwz     r0,8(r1)                        @\
 397        mtlr    r0
 398
 399#define NON_LAZY_STUB(var)                      \
 400        .non_lazy_symbol_pointer                @\
 401        .align 2                                @\
 402L ## var ## $non_lazy_ptr:                      @\
 403        .indirect_symbol var                    @\
 404        .long 0                                 @\
 405        .text                                   @\
 406        .align 2
 407
 408#define BRANCH_EXTERN(var)                      \
 409        PICIFY(var)                             @\
 410        mtctr   PICIFY_REG                      @\
 411        bctr                                    @\
 412        NON_LAZY_STUB(var)
 413
 414#define CALL_EXTERN(var)                        \
 415        CALL_EXTERN_AGAIN(var)                  @\
 416        NON_LAZY_STUB(var)
 417
 418#define REG_TO_EXTERN(reg, var)                 \
 419        PICIFY(var)                             @\
 420        stw reg, 0(PICIFY_REG)                  @\
 421        NON_LAZY_STUB(var)
 422
 423#define EXTERN_TO_REG(reg, var)                 \
 424        PICIFY(var)                             @\
 425        lwz     reg, 0(PICIFY_REG)              @\
 426        NON_LAZY_STUB(var)
 427
 428#else /* ! __DYNAMIC__ */
 429#define TMP_REG r12
 430#define BRANCH_EXTERN(var)                      \
 431        b       var
 432
 433#define CALL_EXTERN(var)                        \
 434        bl      var
 435
 436#define CALL_EXTERN_AGAIN(var)                  \
 437        CALL_EXTERN(var)
 438
 439#define REG_TO_EXTERN(reg, var)                 \
 440        lis     TMP_REG, ha16(var)              @\
 441        stw     reg, lo16(var)(TMP_REG)
 442
 443#define EXTERN_TO_REG(reg, var)                 \
 444        lis     reg, ha16(var)                  @\
 445        lwz     reg, lo16(var)(reg)
 446
 447#endif  /* __DYNAMIC__ */
 448
 449#endif  /* __ASSEMBLER__ */
 450#endif  /* _ARCH_PPC_ASM_HELP_H_ */
 451
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.