|
|
1.1 root 1: /*
2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
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.
11: *
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
14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
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.
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 ([email protected])
37: * Ported from m98k.
38: * 05-Nov-92 Mike DeMoney ([email protected])
39: * Created.
40: */
41:
42: #ifndef _ARCH_PPC_PSEUDO_INST_H_
43: #define _ARCH_PPC_PSEUDO_INST_H_
44:
45: #import <architecture/ppc/reg_help.h>
46: #import <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:
264: MEMREF_INST(lbz)
265: MEMREF_INST(lhz)
266: MEMREF_INST(lha)
267: MEMREF_INST(lwz)
268: MEMREF_INST(lwa)
269: MEMREF_INST(ld)
270:
271: MEMREF_INST(stb)
272: MEMREF_INST(sth)
273: MEMREF_INST(stw)
274: MEMREF_INST(std)
275:
276: MEMREF_INST(lmw)
277: MEMREF_INST(lmd)
278: MEMREF_INST(stmw)
279: MEMREF_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:
312: ARITH_INST(addi, add, )
313: ARITH_INST(subi, sub, )
314: ARITH_INST(addic, addc, )
315: ARITH_INST(subic, subc, )
316: ARITH_INST(addic, addc, .)
317: ARITH_INST(subic, subc, .)
318: ARITH_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:
372: CMPEX_INST(cmpdi, cmpd)
373: CMPEX_INST(cmpwi, cmpw)
374: CMPEX_INST(cmpldi, cmpld)
375: CMPEX_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:
409: CMP_INST(cmpi, cmp)
410: CMP_INST(cmpli, cmpl)
411:
412: #endif /* __ASSEMBLER__ */
413:
414: #endif /* _ARCH_PPC_PSEUDO_INST_H_ */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.