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