Root/
Source at commit 1146 created 12 years 11 months ago. By azimutz, Sync with trunk (r1145). Add nVidia dev id's, 0DF4 for "GeForce GT 450M" (issue 99) and 1251 for "GeForce GTX 560M" (thanks to oSxFr33k for testing). | |
---|---|
1 | /*␊ |
2 | * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.␊ |
3 | *␊ |
4 | * @APPLE_LICENSE_HEADER_START@␊ |
5 | * ␊ |
6 | * This file contains Original Code and/or Modifications of Original Code␊ |
7 | * as defined in and that are subject to the Apple Public Source License␊ |
8 | * Version 2.0 (the 'License'). You may not use this file except in␊ |
9 | * compliance with the License. Please obtain a copy of the License at␊ |
10 | * http://www.opensource.apple.com/apsl/ and read it before using this␊ |
11 | * file.␊ |
12 | * ␊ |
13 | * The Original Code and all software distributed under the License are␊ |
14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER␊ |
15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,␊ |
16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,␊ |
17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.␊ |
18 | * Please see the License for the specific language governing rights and␊ |
19 | * limitations under the License.␊ |
20 | * ␊ |
21 | * @APPLE_LICENSE_HEADER_END@␊ |
22 | */␊ |
23 | ␊ |
24 | #ifndef _PPC_MODE_INDEPENDENT_ASM_H_␊ |
25 | #define _PPC_MODE_INDEPENDENT_ASM_H_␊ |
26 | ␊ |
27 | ␊ |
28 | /* This file facilitates writing mode-independent PPC assembler source, ie␊ |
29 | * source which can be built both for 32-bit mode (__ppc__) and 64-bit ␊ |
30 | * mode (__ppc64__.)␊ |
31 | *␊ |
32 | * It defines constants such as the number of bytes in a GPR (GPR_BYTES),␊ |
33 | * macros to address and call externals (MI_GET_ADDRESS), and a set of mode␊ |
34 | * independent PPC assembler pseudo-mnemonics.␊ |
35 | *␊ |
36 | * The assembler mnemonics map to word operations when building for __ppc__,␊ |
37 | * and to doubleword operations when building for __ppc64__. They use "g" to␊ |
38 | * stand for either word or doubleword, depending on the target mode. ␊ |
39 | *␊ |
40 | * Although there are certainly other things to be aware of when writing code␊ |
41 | * targeted at both 32 and 64-bit mode, using these macros and psuedo-mnemonics␊ |
42 | * is surprisingly helpful.␊ |
43 | */␊ |
44 | ␊ |
45 | #if defined(__ppc64__)␊ |
46 | #define MODE_CHOICE(x, y) y␊ |
47 | #elif defined(__ppc__)␊ |
48 | #define MODE_CHOICE(x, y) x␊ |
49 | #else␊ |
50 | #error undefined architecture␊ |
51 | #endif␊ |
52 | ␊ |
53 | ␊ |
54 | /* The mode-independent "g" mnemonics. */␊ |
55 | ␊ |
56 | #define cmpg MODE_CHOICE(cmpw, cmpd)␊ |
57 | #define cmplg MODE_CHOICE(cmplw, cmpld)␊ |
58 | #define cmpgi MODE_CHOICE(cmpwi, cmpdi)␊ |
59 | #define cmplgi MODE_CHOICE(cmplwi, cmpldi)␊ |
60 | #define srgi MODE_CHOICE(srwi, srdi)␊ |
61 | #define srg MODE_CHOICE(srw, srd)␊ |
62 | #define sragi MODE_CHOICE(srawi, sradi)␊ |
63 | #define slgi MODE_CHOICE(slwi, sldi)␊ |
64 | #define rotlgi MODE_CHOICE(rotlwi, rotldi)␊ |
65 | #define clrrgi MODE_CHOICE(clrrwi, clrrdi)␊ |
66 | #define cntlzg MODE_CHOICE(cntlzw, cntlzd)␊ |
67 | #define lg MODE_CHOICE(lwz, ld)␊ |
68 | #define stg MODE_CHOICE(stw, std)␊ |
69 | #define lgx MODE_CHOICE(lwzx, ldx)␊ |
70 | #define stgx MODE_CHOICE(stwx, stdx)␊ |
71 | #define lgu MODE_CHOICE(lwzu, ldu)␊ |
72 | #define stgu MODE_CHOICE(stwu, stdu)␊ |
73 | #define lgux MODE_CHOICE(lwzux, ldux)␊ |
74 | #define stgux MODE_CHOICE(stwux, stdux)␊ |
75 | #define lgwa MODE_CHOICE(lwz, lwa)␊ |
76 | ␊ |
77 | #define g_long MODE_CHOICE(long, quad) // usage is ".g_long"␊ |
78 | ␊ |
79 | ␊ |
80 | /* Architectural constants. */␊ |
81 | ␊ |
82 | #define GPR_BYTES MODE_CHOICE(4,8) // size of a GPR in bytes␊ |
83 | #define LOG2_GPR_BYTES MODE_CHOICE(2,3) // log2(GPR_BYTES)␊ |
84 | ␊ |
85 | ␊ |
86 | /* Stack frame definitions. To keep things simple, we are limited␊ |
87 | * to eight arguments and two locals.␊ |
88 | */␊ |
89 | #define SF_CRSAVE MODE_CHOICE(4,8)␊ |
90 | #define SF_RETURN MODE_CHOICE(8,16)␊ |
91 | #define SF_ARG1 MODE_CHOICE(24,48)␊ |
92 | #define SF_ARG2 MODE_CHOICE(28,56)␊ |
93 | #define SF_ARG3 MODE_CHOICE(32,64)␊ |
94 | #define SF_ARG4 MODE_CHOICE(36,72)␊ |
95 | #define SF_ARG5 MODE_CHOICE(40,80)␊ |
96 | #define SF_ARG6 MODE_CHOICE(44,88)␊ |
97 | #define SF_ARG7 MODE_CHOICE(48,96)␊ |
98 | #define SF_ARG8 MODE_CHOICE(52,104)␊ |
99 | #define SF_LOCAL1 MODE_CHOICE(56,112)␊ |
100 | #define SF_LOCAL2 MODE_CHOICE(60,120)␊ |
101 | #define SF_SIZE MODE_CHOICE(64,128)␊ |
102 | ␊ |
103 | #define SF_ALIGNMENT MODE_CHOICE(16,32)␊ |
104 | #define SF_REDZONE MODE_CHOICE(224,320)␊ |
105 | ␊ |
106 | #define SF_ROUND(x) (((x)+SF_ALIGNMENT-1)&(-SF_ALIGNMENT))␊ |
107 | ␊ |
108 | #define SF_MINSIZE MODE_CHOICE(64,128)␊ |
109 | ␊ |
110 | ␊ |
111 | /* WARNING: some clients fall through this macro, so do not attempt␊ |
112 | * to optimize by doing an ".align 5" in the macro. Do the 32-byte␊ |
113 | * alignment in the .s file, before invoking the macro.␊ |
114 | */␊ |
115 | #define MI_ENTRY_POINT(name) \␊ |
116 | .globl name @\␊ |
117 | .text @\␊ |
118 | .align 2 @\␊ |
119 | name:␊ |
120 | ␊ |
121 | #define MI_PUSH_STACK_FRAME \␊ |
122 | mflr r0 @\␊ |
123 | stg r0,SF_RETURN(r1) @\␊ |
124 | stgu r1,-SF_SIZE(r1)␊ |
125 | ␊ |
126 | #define MI_POP_STACK_FRAME_AND_RETURN \␊ |
127 | lg r0,SF_RETURN+SF_SIZE(r1) @\␊ |
128 | addi r1,r1,SF_SIZE @\␊ |
129 | mtlr r0 @\␊ |
130 | blr␊ |
131 | ␊ |
132 | ␊ |
133 | /* MI_GET_ADDRESS(reg,var) is the basic primitive to address data or code.␊ |
134 | * It works both in 32 and 64-bit mode, and with static and dynamic␊ |
135 | * code generation. Note however that it can be invoked at most once per␊ |
136 | * symbol, since it always creates a non_lazy_ptr in dynamic mode.␊ |
137 | * Save the address for re-use, rather than invoking the macro again.␊ |
138 | */␊ |
139 | #if defined(__DYNAMIC__)␊ |
140 | #define MI_GET_ADDRESS(reg,var) \␊ |
141 | mflr r0 @\␊ |
142 | bcl 20,31,1f @\␊ |
143 | 1: mflr reg @\␊ |
144 | mtlr r0 @\␊ |
145 | addis reg,reg,ha16(L ## var ## __non_lazy_ptr - 1b) @\␊ |
146 | lg reg,lo16(L ## var ## __non_lazy_ptr - 1b)(reg) @\␊ |
147 | .non_lazy_symbol_pointer @\␊ |
148 | .align LOG2_GPR_BYTES @\␊ |
149 | .indirect_symbol var @\␊ |
150 | L ## var ## __non_lazy_ptr: @\␊ |
151 | .g_long 0 @\␊ |
152 | .text @\␊ |
153 | .align 2␊ |
154 | #else /* ! __DYNAMIC__ */␊ |
155 | #define MI_GET_ADDRESS(reg,var) \␊ |
156 | lis reg,hi16(var) @\␊ |
157 | ori reg,reg,lo16(var)␊ |
158 | #endif␊ |
159 | ␊ |
160 | ␊ |
161 | /* MI_CALL_EXTERNAL(var) */␊ |
162 | ␊ |
163 | #if defined(__DYNAMIC__)␊ |
164 | #define MI_CALL_EXTERNAL(var) \␊ |
165 | MI_GET_ADDRESS(r12,var) @\␊ |
166 | mtctr r12 @\␊ |
167 | bctrl␊ |
168 | #else /* ! __DYNAMIC__ */␊ |
169 | #define MI_CALL_EXTERNAL(var) \␊ |
170 | bl var␊ |
171 | #endif␊ |
172 | ␊ |
173 | ␊ |
174 | /* MI_BRANCH_EXTERNAL(var) */␊ |
175 | ␊ |
176 | #if defined(__DYNAMIC__)␊ |
177 | #define MI_BRANCH_EXTERNAL(var) \␊ |
178 | MI_GET_ADDRESS(r12,var) @\␊ |
179 | mtctr r12 @\␊ |
180 | bctr␊ |
181 | #else /* ! __DYNAMIC__ */␊ |
182 | #define MI_BRANCH_EXTERNAL(var) \␊ |
183 | b var␊ |
184 | #endif␊ |
185 | ␊ |
186 | ␊ |
187 | #endif /* _PPC_MODE_INDEPENDENT_ASM_H_ */␊ |
188 |