]> git.saurik.com Git - apple/xnu.git/blame - EXTERNAL_HEADERS/architecture/ppc/pseudo_inst.h
xnu-344.49.tar.gz
[apple/xnu.git] / EXTERNAL_HEADERS / architecture / ppc / pseudo_inst.h
CommitLineData
1c79356b
A
1/*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
43866e37 6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
1c79356b 7 *
43866e37
A
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
1c79356b
A
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
43866e37
A
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.
1c79356b
A
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
267MEMREF_INST(lbz)
268MEMREF_INST(lhz)
269MEMREF_INST(lha)
270MEMREF_INST(lwz)
271MEMREF_INST(lwa)
272MEMREF_INST(ld)
273
274MEMREF_INST(stb)
275MEMREF_INST(sth)
276MEMREF_INST(stw)
277MEMREF_INST(std)
278
279MEMREF_INST(lmw)
280MEMREF_INST(lmd)
281MEMREF_INST(stmw)
282MEMREF_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
315ARITH_INST(addi, add, )
316ARITH_INST(subi, sub, )
317ARITH_INST(addic, addc, )
318ARITH_INST(subic, subc, )
319ARITH_INST(addic, addc, .)
320ARITH_INST(subic, subc, .)
321ARITH_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
375CMPEX_INST(cmpdi, cmpd)
376CMPEX_INST(cmpwi, cmpw)
377CMPEX_INST(cmpldi, cmpld)
378CMPEX_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
412CMP_INST(cmpi, cmp)
413CMP_INST(cmpli, cmpl)
414
415#endif /* __ASSEMBLER__ */
416
417#endif /* _ARCH_PPC_PSEUDO_INST_H_ */