summaryrefslogtreecommitdiffstats
path: root/pk/ppe42/ppe42_asm.h
blob: 4a2e3aeccb7069db4053c943c6014be841e1296b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
#ifndef __PPE42_ASM_H__
#define __PPE42_ASM_H__
//-----------------------------------------------------------------------------
// *! (C) Copyright International Business Machines Corp. 2014
// *! All Rights Reserved -- Property of IBM
// *! *** IBM Confidential ***
//-----------------------------------------------------------------------------

/// \file ppe42_asm.h
/// \brief Generic assembler macros for 32-bit PPE42

// Doxygen is confused by assembler; the best I know how to make it
// work is to put all of the documentation at the beginning like below
// and effectively comment out the code using Doxygen cond/endcond.

/// \page ppe42_asm Generic assembler macros for 32-bit PPE42
///
///
/// \section _lxzi _l<w,h,b>zi - Load register and Zero from Immediate address
///
/// These macros encapsulate the 2-instruction sequence required to
/// load from a 32-bit immediate address.
///
/// \arg \c dreg A register to receive the load data.
/// \arg \c areg A register to hold the immediate address.  This can \e
///              not be register 0. Note that if \a areg != \a dreg
///              then \a areg will contain the address at the end of
///              the macro sequence.
/// \arg \c addr A 32-bit immediate address, which may be either an
///         absolute or relocatable expression.
///
/// Forms:
/// 
/// \b _lbzi \a dreg, \a areg, \a addr - Load Byte and Zero from Immediate address \n
/// \b _lhzi \a dreg, \a areg, \a addr - Load Halfword and Zero from Immediate address \n
/// \b _lwzi \a dreg, \a areg, \a addr - Load Word and Zero from Immediate address \n
/// 
///
/// \section _stxi _st<w,h,b>i - STore register to Immediate address
///
/// These macros encapsulate the 2-instruction sequence required to
/// store to a 32-bit immediate address.
///
/// \arg \c dreg The register to store.
/// \arg \c areg A register to hold the immediate address.  This can \e
///              not be register 0, and can not be the same as \a dreg.
///              Note that \a areg will contain the address at the end of
///              the macro sequence.
/// \arg \c addr A 32-bit immediate address, which may be either an
///         absolute or relocatable expression.
///
/// Forms:
/// 
/// \b _stbi \a dreg, \a areg, \a addr - STore Byte to Immediate address \n
/// \b _sthi \a dreg, \a areg, \a addr - STore Halfword to Immediate address \n
/// \b _stwi \a dreg, \a areg, \a addr - STore Word to Immediate address \n
///
///
/// \section _lstzsd _<l,st><w,h,b><z>sd - Load/STore register from/to Small Data area
///
/// These macros encapulate the small data area relocations for access
/// to storage in the small data sections .sbss, .sdata, .sbss2 and
/// .sdata2.  Use of these macros implies small data area support in
/// the compile environment (for variables shared between compiled and
/// assembled code) and initialization code that sets up the small data
/// area registers R13 (and optionally R2).
///
/// The relocations generated by this macro will work for both SVR4 ABI
/// and EABI environments.  In particular, for EABI environments
/// the link editor will insert offsets to either R13 or R2 depending
/// on the section of the symbol.
///
/// \arg \c dreg The register to load or store.
/// \arg \c addr A 32-bit immediate address, assumed to be a
///              relocatable address in one of the small data sections.
///
/// Forms:      
/// 
/// \b _lbzsd \a dreg, \a addr  - Load Byte and Zero from Small Data area \n
/// \b _lhzsd \a dreg, \a addr  - Load Halfword and Zero from Small Data area \n
/// \b _lwzsd \a dreg, \a addr  - Load Word and Zero from Small Data area \n
/// \b _stbsd \a dreg, \a addr  - STore Byte to Small Data area \n
/// \b _sthsd \a dreg, \a addr  - STore Halfword to Small Data area \n
/// \b _stwsd \a dreg, \a addr  - STore Word to Small Data area \n
///
///
/// \section _liw _liw<a> - Load Immediate Word (Absolute)
///
/// These macros encapsulate the two instructions required to load a
/// 32-bit immediate value into a register.  If the immediate is an
/// absolute expression, then the \c 'a' form may be able to optimize
/// to a single instruction depending on whether only the high- or
/// low-order bits of the immediate are non-zero.
///
/// Forms:
///
/// \b _liw  \a rd, \a imm - Load register \a rd with the 32-bit immediate \a imm \n
/// \b _liwa \a rd, \a imm - Load register \a rd with the 32-bit absolute immediate \a imm \n
///
///
/// \section _oriwa _oriwa - OR Immediate Word Absolute
///
/// This macro encapsulates the logical OR of a 32-bit immediate with a
/// register. The immediate value must be an absolute expression.
///
/// The PowerPC has instructions for OR-ing 16-bit immediates into the
/// upper (\c oris) and lower (\c ori) portions of a register.  This
/// macro optimizes the generated code based on which bits (if any) of
/// the absolte immediate are non-zero.
///
/// This special macro is only provided for the OR function. For other
/// logical operations and recording forms it is necessary in general
/// to first load the 32-bit immediate into a register (e.g., with \c
/// _liwa) then perform the logical operation.
///
/// \arg \c rd The destination register; at the end will contain \c rs
///            OR \a imm
/// \arg \c rs The source register.
/// \arg \c imm 32-bit absolute expression.
///
/// Forms:
///
/// \b _oriwa \a rd, \a rs, \a imm - \a rd gets \a rs OR \a imm \n
///
///
/// \section _incr64_fast - 64-bit increment for fast interrupt handlers
///
/// This macros implements 64-bit counter update in fast interrupt handlers
/// which are forbidden from using the carry-bit in the XER (without
/// saving/restoring it.)
///
/// \arg \c rs Scratch register
/// \arg \c ra Register containing the counter address at entry
///
/// \a rs and \a ra must be unique.  At the end of the macro the count
/// is updated to memory and \a ra is unmodified. 
///        
///
/// \section _setclear_bits Set/Clear/Copy Bits from Immediate Positions
///
///  There are situations where it is easier/faster to clear individual bits
///  and bit fields, set bits or copy fields, based on immediate bit numbers
///  and locations, rather than loading masks, since setting up a mask
///  requires 2 instruction in general, whereas these macros generate a single
///  instruction.
///
/// \arg \c rd - The destination register
/// \arg \c rs - The source register
/// \arg \c n - An immediate size of a bit field, in the range 0 to 32
/// \arg \c b - An immediate big-endian bit number in the range 0 to 31
///
/// Forms:
///
/// \b _clrfield \a rd, \a rs, \a n, \a b - Clear an \a n bit field from \a rs
/// to \a rd starting from bit \a b \n
/// \b _clrbit \a rd, \a rs, \a b - Clear bit \a b \n
/// \b _setbit \a rd, \a rs, \a b - Set bit \a b \n
/// \b _copyfield \a rd, \a rs, \a n, \a b - Copy an n-bit field from \a rs to
/// \a rd starting from bit \a b \n
///
///     
/// \section pseudo_ops Assembler Pseudo-Ops Macros
///
/// Several macros define new 'pseudo-ops'.
///
/// \subsection cache_align .cache_align
///
/// The \c .cache_align pseudo-op is used to force alignment on a
/// cache-line boundary.  It requires a preprocessor symbol definition for
/// \c LOG_CACHE_LINE_SIZE
///
/// Forms:
///
/// \b .cache_align \n
///
///
/// \subsection global_function Local and Global Functions
///
/// The \c .function and \c .global_function pseudo-ops define function
/// symbols in the \c .text section.
///
/// Forms:
///
/// \b .function \a symbol - Define a local function \a symbol \n
/// \b .global_function \a symbol - Define a global function \a symbol \n
///
/// 
/// \subsection epilogue .epilogue
///
/// The \c .epilogue pseudo-op adds size and type information for
/// functions defined in assembler.
///
/// \arg \c symbol - Assembler epilogue for the function \a symbol.
///
/// Forms:
///
/// \b .epilogue \a symbol \n
///
///
/// \cond

#ifdef __ASSEMBLER__

### ****************************************************************************
### TODO: shouldnt these be supported by the assembler??
### ****************************************************************************
#        .macro  lis treg, imm
#        addis   \treg, 0, imm
#        .endm

#        .macro  li  treg, imm
#        addi    \treg, 0, imm
#        .endm

#        .macro  beq target
#        bc      12, 2, \target
#        .endm

### ****************************************************************************
### _l<b,h,w>zi
### _st<b,h,w>i
### ****************************************************************************

        .macro  _lbzi dreg, areg, addr
        lis     \areg, \addr@ha
        .ifc    \areg, \dreg
        lbz     \dreg, \addr@l(\areg)
        .else
        lbzu    \dreg, \addr@l(\areg)
        .endif
        .endm
        
        .macro  _lhzi dreg, areg, addr
        lis     \areg, \addr@ha
        .ifc    \areg, \dreg
        lhz     \dreg, \addr@l(\areg)
        .else
        lhzu    \dreg, \addr@l(\areg)
        .endif
        .endm
        
        .macro  _lwzi dreg, areg, addr
        lis     \areg, \addr@ha
        .ifc    \areg, \dreg
        lwz     \dreg, \addr@l(\areg)
        .else
        lwzu    \dreg, \addr@l(\areg)
        .endif
        .endm

        .macro  _stbi dreg, areg, addr
        .ifc    \areg, \dreg
        .err
        .endif
        lis     \areg, \addr@ha
        stbu    \dreg, \addr@l(\areg)
        .endm
        
        .macro  _sthi dreg, areg, addr
        .ifc    \areg, \dreg
        .err
        .endif
        lis     \areg, \addr@ha
        sthu    \dreg, \addr@l(\areg)
        .endm
        
        .macro  _stwi dreg, areg, addr
        .ifc    \areg, \dreg
        .err
        .endif
        lis     \areg, \addr@ha
        stwu    \dreg, \addr@l(\areg)
        .endm


### ****************************************************************************
### _l<b,h,w>zsd
### _st<b,h,w>sd
### ****************************************************************************

        .macro  _lbzsd  dreg, addr
        lbz     \dreg, \addr@sda21(0)
        .endm

        .macro  _lhzsd  dreg, addr
        lhz     \dreg, \addr@sda21(0)
        .endm

        .macro  _lwzsd  dreg, addr
        lwz     \dreg, \addr@sda21(0)
        .endm

        .macro  _stbsd  dreg, addr
        stb     \dreg, \addr@sda21(0)
        .endm

        .macro  _sthsd  dreg, addr
        sth     \dreg, \addr@sda21(0)
        .endm

        .macro  _stwsd  dreg, addr
        stw     \dreg, \addr@sda21(0)
        .endm


### ****************************************************************************
### _liw<a>
### _oriwa
### ****************************************************************************

        .macro  _liw    rd, imm
        lis     \rd, \imm@h
        ori     \rd, \rd, \imm@l
        .endm

        .macro  _liwa   rd, imm
        .if     (\imm & 0xffff0000)
        lis     \rd, \imm@h
                .if     (\imm & 0xffff)
                ori     \rd, \rd, \imm@l
                .endif
        .else
        li      \rd, \imm@l
        .endif
        .endm

        .macro  _oriwa  rd, rs, imm
        .if     (\imm & 0xffff0000)
        oris    \rd, \rs, \imm@h
                .if     (\imm & 0xffff)
                ori     \rd, \rd, \imm@l
                .endif
        .else
        ori     \rd, \rs, \imm@l
        .endif
        .endm

### ****************************************************************************
### _incr64_fast
### ****************************************************************************

        .macro  _incr64_fast, rs:req, ra:req

        lwz     \rs, 4(\ra)
        addi    \rs, \rs, 1
        cmpwi   \rs, 0
        stw     \rs, 4(\ra)
        bne     233643278f

        lwz     \rs, 0(\ra)
        addi    \rs, \rs, 1
        stw     \rs, 0(\ra)
233643278:              

        .endm        

### ****************************************************************************
### _clrfield
### _clrbit
### _setbit
### _copyfield
### ****************************************************************************

        .macro  _clrfield, rd, rs, n, b
        rlwinm   \rd, \rs, 0, (\b + \n) & 0x1f, (\b - 1) & 0x1f
        .endm           

        .macro  _clrbit, rd, rs, b
        _clrfield \rd, \rs, 1, \b
        .endm

        .macro  _setbit, rd, rs, b
        .ifle   \b - 15
        oris    \rd, \rs, 1 << (15 - \b)
        .else
        ori     \rd, \rs, 1 << (31 - \b)
        .endif
        .endm

        .macro  _copyfield, rd, rs, n, b
        rlwimi  \rd, \rs, 0, \b , (\b + \n - 1)
        .endm

### ****************************************************************************
### .cache_align
### .<global_>function
### .epilogue
### ****************************************************************************

        .set    _log_cache_line_size, LOG_CACHE_LINE_SIZE

        .macro  .cache_align
        .align  _log_cache_line_size
        .endm

        .macro  .function symbol
        .text
        .align  2
        .endm

        .macro  .global_function symbol
        .text
        .align  2
        .global \symbol
        .endm

        .macro .epilogue symbol
        .type   \symbol, @function
        .size   \symbol, . - \symbol
        .endm           

#endif /* __ASSEMBLER__ */

/// \endcond
        
// Local Variables:
// mode:asm
// End:
        
#endif /* __PPE42_ASM_H__ */
OpenPOWER on IntegriCloud