Mode-Independent Macros
If you want to write assembly code that runs both in 32-bit PowerPC and 64-bit PowerPC environments, you must make sure that 32-bit–specific code runs in 32-bit environments and 64-bit–specific code runs in 64-bit environments. This appendix introduces the macros included in the OS X v10.4 SDK to facilitate the development of assembly code that runs in both environments.
The mode_independent_asm.h
file in /usr/include/architecture/ppc
defines a set of macros that make it easy to write code that runs in 32-bit PowerPC and 64-bit PowerPC environments. These macros include both manifest constants and pseudo mnemonics. For instance, the GPR_BYTES
constant is either 4
or 8
(the size of the general-purpose registers). And lg
pseudo mnemonic expands to lwz
in a 32-bit environment or ld
in a 64-bit environment. The header file documents all the macros in detail.
For example, the 32-bit code to get a pointer at offset 16 from GPR15 into GPR14 is:
lwz r14,16(r15) |
The 64-bit code is:
ld r14,16(r15) |
One way to support both environments is by using conditional inclusion statements. For example, the following code uses __ppc64__
to determine whether the program is running in 64-bit mode and executes the appropriate statement:
#ifdef __ppc64__ |
ld r14,16(r15) |
#else |
lwz r14,16(r15) |
#endif |
However, a simpler way is to use the lg
pseudo mnemonic, as shown here:
#include <architecture/ppc/mode_independent_asm.h> |
... |
lg r14,16(r15) |
If you write code that invokes functions that may be relocated, you may need to create a lazy symbol pointer in 32-bit code similar to this:
.lazy_symbol_pointer |
L_foo$lazy_ptr: |
.indirect_symbol _foo |
.long dyld_stub_binding_helper |
The assembly sequence for is as for 64-bit code is similar to the 32-bit code, but you need to ensure you allocate an 8-byte space for the symbol, using .quad
instead of .long
, as shown here:
.lazy_symbol_pointer |
L_foo$lazy_ptr: |
.indirect_symbol _foo |
.quad dyld_stub_binding_helper |
Using the g_long
mode-independent macro instead of .long
or .quad
, you can write a streamlined dual-environment sequence without adding an #ifdef
statement. The mode-independent sequence would look like this:
#include <architecture/ppc/mode_independent_asm.h> |
... |
.lazy_symbol_pointer |
L_foo$lazy_ptr: |
.indirect_symbol _foo |
.g_long dyld_stub_binding_helper |
Copyright © 2003, 2009 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2009-01-07