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