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