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