]> git.saurik.com Git - apple/xnu.git/blob - EXTERNAL_HEADERS/architecture/ppc/pseudo_inst.h
xnu-792.6.56.tar.gz
[apple/xnu.git] / EXTERNAL_HEADERS / architecture / ppc / pseudo_inst.h
1 /*
2 * Copyright (c) 2000 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 /* Copyright (c) 1996 NeXT Software, Inc. All rights reserved.
24 *
25 * File: architecture/ppc/pseudo_inst.h
26 * Author: Mike DeMoney
27 *
28 * This header file defines assembler pseudo-instruction macros for
29 * for the ppc.
30 *
31 * NOTE: This is obviously only useful to include in assembly
32 * code source.
33 *
34 * ALSO NOTE: These macros don't attempt to be 64-bit compatable
35 *
36 * HISTORY
37 * 29-Dec-96 Umesh Vaishampayan (umeshv@NeXT.com)
38 * Ported from m98k.
39 * 05-Nov-92 Mike DeMoney (mike@next.com)
40 * Created.
41 */
42
43 #ifndef _ARCH_PPC_PSEUDO_INST_H_
44 #define _ARCH_PPC_PSEUDO_INST_H_
45
46 #include <architecture/ppc/reg_help.h>
47 #include <architecture/ppc/asm_help.h>
48
49 #ifdef __ASSEMBLER__
50
51 /*
52 * Pseudo instruction definitions
53 */
54
55 /*
56 * Macro package initialization
57 */
58 .set __no_at,0 /* allow at by default */
59
60 /*
61 * .at_off -- disable use of at by macros
62 * .at_on -- enable use of at by macros
63 */
64 .macro .at_off
65 .set __no_at,1
66 .endmacro
67
68 .macro .at_on
69 .set __no_at,0
70 .endmacro
71
72 /*
73 * li32 rD,IMMED
74 *
75 * Load 32-bit immediate into rD
76 * FIXME: Need a way to undefine built-in macro for this.
77 */
78 .macro li32 // li32 rD,immed
79 .if $n != 2
80 .abort "invalid operands of li32"
81 .endif
82 .abs __is_abs,$1
83 .if !__is_abs
84 addis $0,0,hi16($1)
85 ori $0,$0,lo16($1)
86 .elseif $1 == 0
87 addi $0,0,0
88 .elseif ($1 & 0xffff) == 0
89 addis $0,0,hi16($1)
90 .elseif ($1 & 0xffff8000) == 0
91 addi $0,0,$1
92 .elseif ($1 & 0xffff8000) == 0xffff8000
93 addi $0,0,$1
94 .else
95 addis $0,0,hi16($1)
96 ori $0,$0,lo16($1)
97 .endif
98 .endmacro
99
100
101 /*
102 * andi32. rD,rS1,IMMED
103 *
104 * Perform "andi." with (possibly) 32-bit immediate
105 */
106 .macro andi32. // andi32. rD,rS1,IMMED
107 .if $n != 3
108 .abort "invalid operands of andi."
109 .endif
110 .set __used_at,0
111 .abs __is_abs,$2
112 .if !__is_abs
113 .set __used_at,1
114 li32 at,$2
115 and. $0,$1,at
116 .elseif ($2 & 0xffff0000) == 0
117 andi. $0,$1,$2
118 .elseif ($2 & 0xffff) == 0
119 andis. $0,$1,hi16($2)
120 .else
121 .set __used_at,1
122 li32 at,$2
123 and. $0,$1,at
124 .endif
125 .if __no_at & __used_at
126 .abort "Macro uses at while .no_at in effect"
127 .endif
128 .endmacro
129
130 /*
131 * ori32 rD,rS1,IMMED
132 *
133 * Perform "ori" with (possibly) 32-bit immediate
134 */
135 .macro ori32 // ori32 rD,rS1,IMMED
136 .if $n != 3
137 .abort "invalid operands of ori"
138 .endif
139 .abs __is_abs,$2
140 .if !__is_abs
141 oris $0,$1,hi16($2)
142 ori $0,$1,lo16($2)
143 .elseif ($2 & 0xffff0000) == 0
144 ori $0,$1,$2
145 .elseif ($2 & 0xffff) == 0
146 oris $0,$1,hi16($2)
147 .else
148 oris $0,$1,hi16($2)
149 ori $0,$1,lo16($2)
150 .endif
151 .endmacro
152
153 /*
154 * xori32 rD,rS1,IMMED
155 *
156 * Perform "xor" with (possibly) 32-bit immediate
157 */
158 .macro xori32 // xori32 rD,rS1,IMMED
159 .if $n != 3
160 .abort "invalid operands of xori"
161 .endif
162 .abs __is_abs,$2
163 .if !__is_abs
164 xoris $0,$1,hi16($2)
165 xori $0,$1,lo16($2)
166 .elseif ($2 & 0xffff0000) == 0
167 xori $0,$1,$2
168 .elseif ($2 & 0xffff) == 0
169 xoris $0,$1,hi16($2)
170 .else
171 xoris $0,$1,hi16($2)
172 xori $0,$1,lo16($2)
173 .endif
174 .endmacro
175
176
177 /*
178 * MEMREF_INST -- macros to memory referencing instructions
179 * "capable" of dealing with 32 bit offsets.
180 *
181 * NOTE: Because the assembler doesn't have any mechanism for easily
182 * parsing the d(rS) syntax of register-displacement form instructions,
183 * these instructions do NOT mirror the normal memory reference
184 * instructions. The following "transformation" is used:
185 * lbz rD,d(rS)
186 * becomes:
187 * lbz32 rD,rS,d
188 * I.e.: "32" is appended to the instruction name and the base register
189 * and displacement become the 2'nd and 3'rd comma-separated operands.
190 *
191 * The forms:
192 * lbz32 rD,d
193 * and:
194 * lbz32 rD,rS
195 * are also recognized and the missing operand is assumed 0.
196 *
197 * ALSO NOTE: r0 or zt should never be used as rS in these instructions.
198 * Use "0" as rS in this case.
199 */
200 #define MEMREF_INST(op) \
201 .macro op ## 32 @\
202 .set __used_at,0 @\
203 .if $n == 3 @\
204 .greg __is_greg,$1 @\
205 .abs __is_abs,$2 @\
206 .if __is_abs @\
207 .if ($2 & 0xffff8000) == 0 @\
208 op $0,$2($1) @\
209 .elseif ($2 & 0xffff8000) == 0xffff8000 @\
210 op $0,$2($1) @\
211 .else @\
212 .if !__is_greg @\
213 .set __used_at,1 @\
214 lis at,ha16($2) @\
215 op $0,lo16($2)(at) @\
216 .else @\
217 .set __used_at,1 @\
218 lis at,ha16($2) @\
219 add at,at,$1 @\
220 op $0,lo16($2)(at) @\
221 .endif @\
222 .endif @\
223 .else @\
224 .if !__is_greg @\
225 .set __used_at,1 @\
226 lis at,ha16($2) @\
227 op $0,lo16($2)(at) @\
228 .else @\
229 .set __used_at,1 @\
230 lis at,ha16($2) @\
231 add at,at,$1 @\
232 op $0,lo16($2)(at) @\
233 .endif @\
234 .endif @\
235 .elseif $n == 2 @\
236 .greg __is_greg,$1 @\
237 .if !__is_greg @\
238 .abs __is_abs,$1 @\
239 .if __is_abs @\
240 .if ($1 & 0xffff8000) == 0 @\
241 op $0,$1(0) @\
242 .elseif ($1 & 0xffff8000) == 0xffff8000 @\
243 op $0,$1(0) @\
244 .else @\
245 .set __used_at,1 @\
246 lis at,ha16($1) @\
247 op $0,lo16($1)(at) @\
248 .endif @\
249 .else @\
250 .set __used_at,1 @\
251 lis at,ha16($1) @\
252 op $0,lo16($1)(at) @\
253 .endif @\
254 .else @\
255 op $0,0($1) @\
256 .endif @\
257 .else @\
258 .abort "Invalid operands of " #op "32" @\
259 .endif @\
260 .if __no_at & __used_at @\
261 .abort "Macro uses at while .no_at in effect" @\
262 .endif @\
263 .endmacro
264
265 MEMREF_INST(lbz)
266 MEMREF_INST(lhz)
267 MEMREF_INST(lha)
268 MEMREF_INST(lwz)
269 MEMREF_INST(lwa)
270 MEMREF_INST(ld)
271
272 MEMREF_INST(stb)
273 MEMREF_INST(sth)
274 MEMREF_INST(stw)
275 MEMREF_INST(std)
276
277 MEMREF_INST(lmw)
278 MEMREF_INST(lmd)
279 MEMREF_INST(stmw)
280 MEMREF_INST(stmd)
281
282 /*
283 * ARITH_INST -- define 32-bit immediate forms of arithmetic
284 * instructions
285 *
286 * E.g. addi32 rD,rS,IMMED
287 */
288 #define ARITH_INST(op, op3, sf) \
289 .macro op ## 32 ## sf @\
290 .if $n != 3 @\
291 .abort "invalid operands to " #op "32" @\
292 .endif @\
293 .abs __is_abs,$2 @\
294 .if __is_abs @\
295 .if ($2 & 0xffff8000) == 0 @\
296 op##sf $0,$1,$2 @\
297 .elseif ($2 & 0xffff8000) == 0xffff8000 @\
298 op##sf $0,$1,$2 @\
299 .elseif __no_at @\
300 .abort "Macro uses at while .no_at in effect" @\
301 .else @\
302 li32 at,$2 @\
303 op3##sf $0,$1,at @\
304 .endif @\
305 .elseif __no_at @\
306 .abort "Macro uses at while .no_at in effect" @\
307 .else @\
308 li32 at,$2 @\
309 op3##sf $0,$1,at @\
310 .endif @\
311 .endmacro
312
313 ARITH_INST(addi, add, )
314 ARITH_INST(subi, sub, )
315 ARITH_INST(addic, addc, )
316 ARITH_INST(subic, subc, )
317 ARITH_INST(addic, addc, .)
318 ARITH_INST(subic, subc, .)
319 ARITH_INST(mulli, mull, )
320
321 /*
322 * CMPEX_INST -- define 32-bit immediate forms of extended compare
323 * instructions
324 *
325 * E.g. cmpwi32 cr3,rS,IMMED
326 * cmpwi32 rS,IMMED
327 */
328 #define CMPEX_INST(op, op3) \
329 .macro op ## 32 @\
330 .if $n == 3 @\
331 .abs __is_abs,$2 @\
332 .if __is_abs @\
333 .if ($2 & 0xffff8000) == 0 @\
334 op $0,$1,$2 @\
335 .elseif ($2 & 0xffff8000) == 0xffff8000 @\
336 op $0,$1,$2 @\
337 .elseif __no_at @\
338 .abort "Macro uses at while .no_at in effect" @\
339 .else @\
340 li32 at,$2 @\
341 op3 $0,$1,at @\
342 .endif @\
343 .elseif __no_at @\
344 .abort "Macro uses at while .no_at in effect" @\
345 .else @\
346 li32 at,$2 @\
347 op3 $0,$1,at @\
348 .endif @\
349 .elseif $n == 2 @\
350 .abs __is_abs,$1 @\
351 .if __is_abs @\
352 .if ($1 & 0xffff8000) == 0 @\
353 op $0,$1 @\
354 .elseif ($1 & 0xffff8000) == 0xffff8000 @\
355 op $0,$1 @\
356 .elseif __no_at @\
357 .abort "Macro uses at while .no_at in effect" @\
358 .else @\
359 li32 at,$1 @\
360 op3 $0,at @\
361 .endif @\
362 .elseif __no_at @\
363 .abort "Macro uses at while .no_at in effect" @\
364 .else @\
365 li32 at,$1 @\
366 op3 $0,at @\
367 .endif @\
368 .else @\
369 .abort "invalid operands to " #op "32" @\
370 .endif @\
371 .endmacro
372
373 CMPEX_INST(cmpdi, cmpd)
374 CMPEX_INST(cmpwi, cmpw)
375 CMPEX_INST(cmpldi, cmpld)
376 CMPEX_INST(cmplwi, cmplw)
377
378 /*
379 * CMP_INST -- define 32-bit immediate forms of standard compare
380 * instructions
381 *
382 * E.g. cmpi32 cr3,0,rS,IMMED
383 */
384 #define CMP_INST(op, op3) \
385 .macro op ## 32 @\
386 .if $n == 4 @\
387 .abs __is_abs,$3 @\
388 .if __is_abs @\
389 .if ($3 & 0xffff8000) == 0 @\
390 op $0,$1,$2,$3 @\
391 .elseif ($3 & 0xffff8000) == 0xffff8000 @\
392 op $0,$1,$2,$3 @\
393 .elseif __no_at @\
394 .abort "Macro uses at while .no_at in effect" @\
395 .else @\
396 li32 at,$3 @\
397 op3 $0,$1,$2,at @\
398 .endif @\
399 .elseif __no_at @\
400 .abort "Macro uses at while .no_at in effect" @\
401 .else @\
402 li32 at,$3 @\
403 op3 $0,$1,$2,at @\
404 .endif @\
405 .else @\
406 .abort "invalid operands to " #op "32" @\
407 .endif @\
408 .endmacro
409
410 CMP_INST(cmpi, cmp)
411 CMP_INST(cmpli, cmpl)
412
413 #endif /* __ASSEMBLER__ */
414
415 #endif /* _ARCH_PPC_PSEUDO_INST_H_ */