~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/skiboot/libpore/pgas.h

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* IBM_PROLOG_BEGIN_TAG                                                   */
 
2
/* This is an automatically generated prolog.                             */
 
3
/*                                                                        */
 
4
/* $Source: src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/pgas.h $    */
 
5
/*                                                                        */
 
6
/* OpenPOWER HostBoot Project                                             */
 
7
/*                                                                        */
 
8
/* COPYRIGHT International Business Machines Corp. 2012,2014              */
 
9
/*                                                                        */
 
10
/* Licensed under the Apache License, Version 2.0 (the "License");        */
 
11
/* you may not use this file except in compliance with the License.       */
 
12
/* You may obtain a copy of the License at                                */
 
13
/*                                                                        */
 
14
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
 
15
/*                                                                        */
 
16
/* Unless required by applicable law or agreed to in writing, software    */
 
17
/* distributed under the License is distributed on an "AS IS" BASIS,      */
 
18
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
 
19
/* implied. See the License for the specific language governing           */
 
20
/* permissions and limitations under the License.                         */
 
21
/*                                                                        */
 
22
/* IBM_PROLOG_END_TAG                                                     */
 
23
#ifndef __PGAS_H__
 
24
#define __PGAS_H__
 
25
 
 
26
#define __PGAS__
 
27
 
 
28
// $Id: pgas.h,v 1.21 2013/11/20 14:06:39 bcbrock Exp $
 
29
 
 
30
// ** WARNING : This file is maintained as part of the OCC firmware.  Do **
 
31
// ** not edit this file in the PMX area, the hardware procedure area,   **
 
32
// ** or the PoreVe area as any changes will be lost.                    **
 
33
 
 
34
/// \file pgas.h
 
35
/// \brief Pore GAS
 
36
///
 
37
/// PGAS is documented in a separate standalone document entitled <em> PGAS :
 
38
/// PORE GAS (GNU Assembler) User's and Reference Manual </em>.
 
39
///
 
40
/// This file defines support macros for the GNU PORE assembler, and the PORE
 
41
/// inline assembler and disassebler which follow the PGAS assembly syntax.
 
42
/// If the compile swith PGAS_PPC is defined in the environment then pgas.h
 
43
/// includes pgas_ppc.h which transforms a PowerPC assembler into an assembler
 
44
/// for PORE.
 
45
 
 
46
// These are the opcodes and mnemonics as defined by the PORE hardware
 
47
// manual.  Many of them will change names slightly in PGAS.  
 
48
 
 
49
#define PORE_OPCODE_NOP     0x0f
 
50
#define PORE_OPCODE_WAIT    0x01
 
51
#define PORE_OPCODE_TRAP    0x02
 
52
#define PORE_OPCODE_HOOK    0x4f
 
53
 
 
54
#define PORE_OPCODE_BRA     0x10
 
55
#define PORE_OPCODE_BRAZ    0x12
 
56
#define PORE_OPCODE_BRANZ   0x13
 
57
#define PORE_OPCODE_BRAI    0x51
 
58
#define PORE_OPCODE_BSR     0x14
 
59
#define PORE_OPCODE_BRAD    0x1c
 
60
#define PORE_OPCODE_BSRD    0x1d
 
61
#define PORE_OPCODE_RET     0x15
 
62
#define PORE_OPCODE_CMPBRA  0x56
 
63
#define PORE_OPCODE_CMPNBRA 0x57
 
64
#define PORE_OPCODE_CMPBSR  0x58
 
65
#define PORE_OPCODE_LOOP    0x1f
 
66
 
 
67
#define PORE_OPCODE_ANDI    0x60
 
68
#define PORE_OPCODE_ORI     0x61
 
69
#define PORE_OPCODE_XORI    0x62
 
70
        
 
71
#define PORE_OPCODE_AND     0x25
 
72
#define PORE_OPCODE_OR      0x26
 
73
#define PORE_OPCODE_XOR     0x27
 
74
        
 
75
#define PORE_OPCODE_ADD     0x23
 
76
#define PORE_OPCODE_ADDI    0x24
 
77
#define PORE_OPCODE_SUB     0x29
 
78
#define PORE_OPCODE_SUBI    0x28
 
79
#define PORE_OPCODE_NEG     0x2a
 
80
 
 
81
#define PORE_OPCODE_COPY    0x2c
 
82
#define PORE_OPCODE_ROL     0x2e
 
83
 
 
84
#define PORE_OPCODE_LOAD20  0x30
 
85
#define PORE_OPCODE_LOAD64  0x71
 
86
#define PORE_OPCODE_SCR1RD  0x32
 
87
#define PORE_OPCODE_SCR1RDA 0x73
 
88
#define PORE_OPCODE_SCR2RD  0x36
 
89
#define PORE_OPCODE_SCR2RDA 0x77
 
90
#define PORE_OPCODE_WRI     0x78
 
91
#define PORE_OPCODE_BS      0x74
 
92
#define PORE_OPCODE_BC      0x75
 
93
#define PORE_OPCODE_SCR1WR  0x39
 
94
#define PORE_OPCODE_SCR2WR  0x3a
 
95
#define PORE_OPCODE_SCAND   0x7c
 
96
 
 
97
 
 
98
// These are the PGAS versions of the PORE opcodes used in the legacy PGAS_PPC
 
99
// assembler and the current PORE inline assembler/disassembler.
 
100
 
 
101
#define PGAS_OPCODE_NOP       PORE_OPCODE_NOP     
 
102
#define PGAS_OPCODE_WAITS     PORE_OPCODE_WAIT    
 
103
#define PGAS_OPCODE_TRAP      PORE_OPCODE_TRAP    
 
104
#define PGAS_OPCODE_HOOKI     PORE_OPCODE_HOOK    
 
105
 
 
106
#define PGAS_OPCODE_BRA       PORE_OPCODE_BRA     
 
107
#define PGAS_OPCODE_BRAZ      PORE_OPCODE_BRAZ    
 
108
#define PGAS_OPCODE_BRANZ     PORE_OPCODE_BRANZ   
 
109
#define PGAS_OPCODE_BRAI      PORE_OPCODE_BRAI    
 
110
#define PGAS_OPCODE_BSR       PORE_OPCODE_BSR 
 
111
#define PGAS_OPCODE_BRAD      PORE_OPCODE_BRAD    
 
112
#define PGAS_OPCODE_BSRD      PORE_OPCODE_BSRD    
 
113
#define PGAS_OPCODE_RET       PORE_OPCODE_RET     
 
114
#define PGAS_OPCODE_CMPIBRAEQ PORE_OPCODE_CMPBRA  
 
115
#define PGAS_OPCODE_CMPIBRANE PORE_OPCODE_CMPNBRA 
 
116
#define PGAS_OPCODE_CMPIBSREQ PORE_OPCODE_CMPBSR  
 
117
#define PGAS_OPCODE_LOOP      PORE_OPCODE_LOOP    
 
118
 
 
119
#define PGAS_OPCODE_ANDI      PORE_OPCODE_ANDI    
 
120
#define PGAS_OPCODE_ORI       PORE_OPCODE_ORI     
 
121
#define PGAS_OPCODE_XORI      PORE_OPCODE_XORI    
 
122
 
 
123
#define PGAS_OPCODE_AND       PORE_OPCODE_AND     
 
124
#define PGAS_OPCODE_OR        PORE_OPCODE_OR      
 
125
#define PGAS_OPCODE_XOR       PORE_OPCODE_XOR     
 
126
 
 
127
#define PGAS_OPCODE_ADD       PORE_OPCODE_ADD     
 
128
#define PGAS_OPCODE_ADDS      PORE_OPCODE_ADDI    
 
129
#define PGAS_OPCODE_SUB       PORE_OPCODE_SUB     
 
130
#define PGAS_OPCODE_SUBS      PORE_OPCODE_SUBI    
 
131
#define PGAS_OPCODE_NEG       PORE_OPCODE_NEG     
 
132
 
 
133
#define PGAS_OPCODE_MR        PORE_OPCODE_COPY    
 
134
#define PGAS_OPCODE_ROLS      PORE_OPCODE_ROL     
 
135
 
 
136
#define PGAS_OPCODE_LS        PORE_OPCODE_LOAD20  
 
137
#define PGAS_OPCODE_LI        PORE_OPCODE_LOAD64  
 
138
#define PGAS_OPCODE_LD0       PORE_OPCODE_SCR1RD  /* Used by LD */
 
139
#define PGAS_OPCODE_LD0ANDI   PORE_OPCODE_SCR1RDA /* Used by LDANDI */
 
140
#define PGAS_OPCODE_LD1       PORE_OPCODE_SCR2RD  /* Used by LD */
 
141
#define PGAS_OPCODE_LD1ANDI   PORE_OPCODE_SCR2RDA /* Used by LDANDI */
 
142
#define PGAS_OPCODE_STI       PORE_OPCODE_WRI     
 
143
#define PGAS_OPCODE_STD0      PORE_OPCODE_SCR1WR  /* Used by STD */
 
144
#define PGAS_OPCODE_STD1      PORE_OPCODE_SCR2WR  /* Used by STD */
 
145
#define PGAS_OPCODE_SCAND     PORE_OPCODE_SCAND   
 
146
 
 
147
#ifdef IGNORE_HW274735
 
148
 
 
149
// BSI and BCI are normally redacted due to HW274735. See also pgas.h
 
150
 
 
151
#define PGAS_OPCODE_BSI       PORE_OPCODE_BS      
 
152
#define PGAS_OPCODE_BCI       PORE_OPCODE_BC      
 
153
 
 
154
#endif // IGNORE_HW274735
 
155
 
 
156
// These are the programmer-visible register names as defined by the PORE
 
157
// hardware manual.  All of these names (except the PC) appear differently in
 
158
// the PGAS syntax, in some cases to reduce confusion, in other cases just to
 
159
// have more traditional short mnemonics.
 
160
 
 
161
#define PORE_REGISTER_PRV_BASE_ADDR0  0x0
 
162
#define PORE_REGISTER_PRV_BASE_ADDR1  0x1
 
163
#define PORE_REGISTER_OCI_BASE_ADDR0  0x2
 
164
#define PORE_REGISTER_OCI_BASE_ADDR1  0x3
 
165
#define PORE_REGISTER_SCRATCH0        0x4
 
166
#define PORE_REGISTER_SCRATCH1        0x5
 
167
#define PORE_REGISTER_SCRATCH2        0x6
 
168
#define PORE_REGISTER_ERROR_MASK      0x7
 
169
#define PORE_REGISTER_EXE_TRIGGER     0x9
 
170
#define PORE_REGISTER_DATA0           0xa
 
171
#define PORE_REGISTER_PC              0xe
 
172
#define PORE_REGISTER_IBUF_ID         0xf
 
173
 
 
174
 
 
175
// PgP IBUF_ID values
 
176
 
 
177
#define PORE_ID_GPE0 0x00
 
178
#define PORE_ID_GPE1 0x01
 
179
#define PORE_ID_SLW  0x08
 
180
#define PORE_ID_SBE  0x04
 
181
 
 
182
 
 
183
// Condition Codes
 
184
 
 
185
#define PORE_CC_UGT 0x8000
 
186
#define PORE_CC_ULT 0x4000
 
187
#define PORE_CC_SGT 0x2000
 
188
#define PORE_CC_SLT 0x1000
 
189
#define PORE_CC_C   0x0800
 
190
#define PORE_CC_V   0x0400
 
191
#define PORE_CC_N   0x0200
 
192
#define PORE_CC_Z   0x0100
 
193
 
 
194
 
 
195
// Memory Spaces
 
196
 
 
197
#define PORE_SPACE_UNDEFINED 0xffff
 
198
#define PORE_SPACE_OCI       0x8000
 
199
#define PORE_SPACE_PNOR      0x800b
 
200
#define PORE_SPACE_OTPROM    0x0001
 
201
#define PORE_SPACE_SEEPROM   0x800c
 
202
#define PORE_SPACE_PIBMEM    0x0008             
 
203
 
 
204
 
 
205
#ifdef __ASSEMBLER__
 
206
 
 
207
////////////////////////////////////////////////////////////////////////////
 
208
// PGAS Base Assembler Support
 
209
////////////////////////////////////////////////////////////////////////////    
 
210
 
 
211
 
 
212
        //////////////////////////////////////////////////////////////////////
 
213
        // Condition Codes
 
214
        //////////////////////////////////////////////////////////////////////
 
215
 
 
216
        .set    CC_UGT, PORE_CC_UGT 
 
217
        .set    CC_ULT, PORE_CC_ULT 
 
218
        .set    CC_SGT, PORE_CC_SGT 
 
219
        .set    CC_SLT, PORE_CC_SLT 
 
220
        .set    CC_C,   PORE_CC_C   
 
221
        .set    CC_V,   PORE_CC_V   
 
222
        .set    CC_N,   PORE_CC_N   
 
223
        .set    CC_Z,   PORE_CC_Z
 
224
 
 
225
 
 
226
        //////////////////////////////////////////////////////////////////////
 
227
        // Utility Macros
 
228
        //////////////////////////////////////////////////////////////////////
 
229
 
 
230
        // 'Undefine' PowerPC mnemonics to trap programming errors
 
231
 
 
232
        .macro  ..undefppc1, i
 
233
        .ifnc   \i, ignore
 
234
        .macro  \i, args:vararg
 
235
        .error  "This is a PowerPC opcode - NOT a PGAS opcode or extended mnemonic"
 
236
        .endm
 
237
        .endif
 
238
        .endm
 
239
 
 
240
        .macro  .undefppc, i0, i1=ignore, i2=ignore, i3=ignore
 
241
        ..undefppc1 \i0
 
242
        ..undefppc1 \i1
 
243
        ..undefppc1 \i2
 
244
        ..undefppc1 \i3
 
245
        .endm
 
246
 
 
247
      
 
248
        //////////////////////////////////////////////////////////////////////
 
249
        // Argument Checking Macros
 
250
        //////////////////////////////////////////////////////////////////////
 
251
        //
 
252
        // These macros remain in the final pgas.h file because 1) they are
 
253
        // required for some PGAS pseudo-ops, and 2) to support robust
 
254
        // assembler macro definitions. 
 
255
 
 
256
         // Check an unsigned immediate for size
 
257
 
 
258
        .macro  ..checku, x:req, bits:req, err="Unsigned value too large"
 
259
 
 
260
        .if     (((\bits) <= 0) || ((\bits) > 63))
 
261
        .error  "The number of bits must be in the range 0 < bits < 64"
 
262
        .endif
 
263
 
 
264
        .iflt   (\x)
 
265
        .error  "An unsigned value is required here"
 
266
        .endif
 
267
        
 
268
        .ifgt   ((\x) - (0xffffffffffffffff >> (64 - (\bits))))
 
269
        .error  "\err"
 
270
        .endif
 
271
 
 
272
        .endm
 
273
 
 
274
        // Check unsigned 16/22-bit immediates for size
 
275
        //
 
276
        // In general, PGAS can check immediate values for size restrictions,
 
277
        // but unfortunately is not able to check address offset immediates for
 
278
        // range. 
 
279
 
 
280
        .macro  ..check_u16, u16
 
281
        ..checku (\u16), 16, "Unsigned immediate is larger than 16 bits"
 
282
        .endm
 
283
 
 
284
        .macro  ..check_u24, u24
 
285
        ..checku (\u24), 24, "Unsigned immediate is larger than 24 bits"
 
286
        .endm
 
287
 
 
288
        // Check a 16/20/22-bit signed immediate for size
 
289
 
 
290
        .macro  ..check_s16, s16
 
291
        .iflt   \s16
 
292
        .iflt   \s16 + 0x8000
 
293
        .error  "Immediate value too small for a signed 16-bit field"
 
294
        .endif
 
295
        .else
 
296
        .ifgt   \s16 - 0x7fff
 
297
        .error  "Immediate value too large for a signed 16-bit field"
 
298
        .endif
 
299
        .endif
 
300
        .endm
 
301
 
 
302
        .macro  ..check_s20, s20
 
303
        .iflt   \s20
 
304
        .iflt   \s20 + 0x80000
 
305
        .error  "Immediate value too small for a signed 20-bit field"
 
306
        .endif
 
307
        .else
 
308
        .ifgt   \s20 - 0x7ffff
 
309
        .error  "Immediate value too large for a signed 20-bit field"
 
310
        .endif
 
311
        .endif
 
312
        .endm
 
313
 
 
314
        .macro  ..check_s22, s22
 
315
        .iflt   \s22
 
316
        .iflt   \s22 + 0x200000
 
317
        .error  "Immediate value too small for a signed 22-bit field"
 
318
        .endif
 
319
        .else
 
320
        .ifgt   \s22 - 0x1fffff
 
321
        .error  "Immediate value too large for a signed 22-bit field"
 
322
        .endif
 
323
        .endif
 
324
        .endm
 
325
 
 
326
        // Check a putative SCOM address for bits 0 and 8:11 == 0.
 
327
 
 
328
        .macro  ..check_scom, address
 
329
        .if     ((\address) & 0x80f00000)
 
330
        .error  "Valid SCOM addresses must have bits 0 and 8:11 equal to 0."
 
331
        .endif
 
332
        .endm
 
333
 
 
334
        // A register required to be D0
 
335
 
 
336
        .macro  ..d0, reg
 
337
        .if     (\reg != D0)
 
338
        .error  "Data register D0 is required here"
 
339
        .endif
 
340
        .endm
 
341
 
 
342
        // A register pair required to be D0, D1 in order
 
343
 
 
344
        .macro  ..d0d1, reg1, reg2
 
345
        .if     (((\reg1) != D0) && ((\reg2) != D1))
 
346
        .error  "Register-Register ALU operations are only defined on the source pair D0, D1"
 
347
        .endif
 
348
        .endm
 
349
 
 
350
        // A register pair required to be D0, D1 in any order
 
351
        .macro  ..dxdy, reg1, reg2, err="Expecting D0, D1 in either order"
 
352
        .if     !((((\reg1) == D0) && ((\reg2) == D1)) || \
 
353
                  (((\reg1) == D1) && ((\reg2) == D0)))
 
354
        .error "\err"
 
355
        .endif
 
356
        .endm
 
357
 
 
358
        // A register pair required to be A0, A1 in any order
 
359
        .macro  ..axay, reg1, reg2, err="Expecting A0, A1 in either order"
 
360
        .if     !((((\reg1) == A0) && ((\reg2) == A1)) || \
 
361
                  (((\reg1) == A1) && ((\reg2) == A0)))
 
362
        .error "\err"
 
363
        .endif
 
364
        .endm
 
365
 
 
366
        // A register pair required to be the same register
 
367
 
 
368
        .macro  ..same, dest, src
 
369
        .if     ((\dest) != (\src))
 
370
        .error  "PGAS requires the src and dest register of ADDS/SUBS to be explicit and identical"
 
371
        .endif
 
372
        .endm
 
373
        
 
374
        // A "Data" register    
 
375
 
 
376
        .macro  ..data, reg:req, err="Expecting a 'Data' register"
 
377
        .if     (\reg != D0)
 
378
        .if     (\reg != D1)
 
379
        .error  "\err"
 
380
        .endif
 
381
        .endif
 
382
        .endm
 
383
 
 
384
        // An "Address" register
 
385
 
 
386
        .macro  ..address, reg:req, err=:"Expecting an 'Address' register"
 
387
        .if     (\reg != A0)
 
388
        .if     (\reg != A1)
 
389
        .error  "\err"
 
390
        .endif
 
391
        .endif
 
392
        .endm
 
393
 
 
394
        // A "Pervasive Chiplet ID" register
 
395
 
 
396
        .macro  ..pervasive_chiplet_id, reg:req, err="Expecting a 'Pervasive Chiplet ID' register"
 
397
        .if     (\reg != P0)
 
398
        .if     (\reg != P1)
 
399
        .error  "\err"
 
400
        .endif
 
401
        .endif
 
402
        .endm
 
403
 
 
404
        // A "Branch Compare Data" register
 
405
 
 
406
        .macro  ..branch_compare_data, reg
 
407
        .if     (\reg != D0)
 
408
        .if     (\reg != D1) 
 
409
        .if     (\reg != CTR)
 
410
        .error  "Expecting a 'Branch Compare Data' register"
 
411
        .endif
 
412
        .endif
 
413
        .endif
 
414
        .endm
 
415
 
 
416
        // An "LS Destination" register; Also the set for ADDS/SUBS
 
417
 
 
418
        .macro  ..ls_destination, reg
 
419
        .if     (\reg != D0)
 
420
        .if     (\reg != D1)
 
421
        .if     (\reg != A0)
 
422
        .if     (\reg != A1)
 
423
        .if     (\reg != P0)
 
424
        .if     (\reg != P1)
 
425
        .if     (\reg != CTR)
 
426
        .error "Expecting an 'LS Destination' register"
 
427
        .endif
 
428
        .endif
 
429
        .endif
 
430
        .endif
 
431
        .endif
 
432
        .endif
 
433
        .endif
 
434
        .endm
 
435
 
 
436
        // An "LI Destination" register
 
437
 
 
438
        .macro  ..li_destination, reg
 
439
        .if     (\reg != D0)
 
440
        .if     (\reg != D1)
 
441
        .if     (\reg != A0)
 
442
        .if     (\reg != A1)
 
443
        .if     (\reg != CTR)
 
444
        .error "Expecting an 'LI Destination' register"
 
445
        .endif
 
446
        .endif
 
447
        .endif
 
448
        .endif
 
449
        .endif
 
450
        .endm
 
451
 
 
452
        // An "LIA Destination" register 
 
453
 
 
454
        .macro  ..lia_destination, reg
 
455
        .if     (\reg != D0)
 
456
        .if     (\reg != D1)
 
457
        .if     (\reg != A0)
 
458
        .if     (\reg != A1)
 
459
        .if     (\reg != TBAR)
 
460
        .error "Expecting an 'LIA Destination' register"
 
461
        .endif
 
462
        .endif
 
463
        .endif
 
464
        .endif
 
465
        .endif
 
466
        .endm
 
467
 
 
468
        // An "MR Source" register
 
469
 
 
470
        .macro  ..mr_source, reg
 
471
        .if     (\reg != D0)
 
472
        .if     (\reg != D1)
 
473
        .if     (\reg != A0)
 
474
        .if     (\reg != A1)
 
475
        .if     (\reg != P0)
 
476
        .if     (\reg != P1)
 
477
        .if     (\reg != CTR)
 
478
        .if     (\reg != PC)
 
479
        .if     (\reg != ETR)
 
480
        .if     (\reg != SPRG0)
 
481
        .if     (\reg != IFR)
 
482
        .if     (\reg != EMR)
 
483
        .error  "Expecting an 'MR Source' register"
 
484
        .endif
 
485
        .endif
 
486
        .endif
 
487
        .endif
 
488
        .endif
 
489
        .endif
 
490
        .endif
 
491
        .endif
 
492
        .endif
 
493
        .endif
 
494
        .endif
 
495
        .endif
 
496
        .endm
 
497
 
 
498
        // An "MR Destination" register
 
499
 
 
500
        .macro  ..mr_destination, reg
 
501
        .if     (\reg != D0)
 
502
        .if     (\reg != D1)
 
503
        .if     (\reg != A0)
 
504
        .if     (\reg != A1)
 
505
        .if     (\reg != P0)
 
506
        .if     (\reg != P1)
 
507
        .if     (\reg != CTR)
 
508
        .if     (\reg != PC)
 
509
        .if     (\reg != ETR)
 
510
        .if     (\reg != SPRG0)
 
511
        .if     (\reg != EMR)
 
512
        .error "Expecting an 'MR Destination' register"
 
513
        .endif
 
514
        .endif
 
515
        .endif
 
516
        .endif
 
517
        .endif
 
518
        .endif
 
519
        .endif
 
520
        .endif
 
521
        .endif
 
522
        .endif
 
523
        .endif
 
524
        .endm
 
525
 
 
526
 
 
527
        //////////////////////////////////////////////////////////////////////
 
528
        // PORE address spaces
 
529
        //////////////////////////////////////////////////////////////////////
 
530
 
 
531
        // The ..set_address_space pseudo-op defines the default address
 
532
        // space. It must be defined in order to use BRAA, BRAIA, BSR and
 
533
        // CMPIBSR.  Pseudo-ops are provided to set the default space of the
 
534
        // program.  Note that code assembled for PNOR will also work in the
 
535
        // OCI space in the Sleep/Winkle engine.
 
536
 
 
537
        .macro  ..set_default_space, s
 
538
        ..check_u16 (\s)
 
539
        .set    _PGAS_DEFAULT_SPACE, (\s)
 
540
        .endm
 
541
 
 
542
        .macro  ..check_default_space
 
543
        .if     (_PGAS_DEFAULT_SPACE == PORE_SPACE_UNDEFINED)
 
544
        .error  "The PGAS default address space has not been defined"
 
545
        .endif
 
546
        .endm   
 
547
 
 
548
        ..set_default_space PORE_SPACE_UNDEFINED
 
549
 
 
550
        .macro  .oci
 
551
        ..set_default_space PORE_SPACE_OCI
 
552
        .endm
 
553
 
 
554
        .macro  .pnor
 
555
        ..set_default_space PORE_SPACE_PNOR
 
556
        .endm
 
557
 
 
558
        .macro  .seeprom
 
559
        ..set_default_space PORE_SPACE_SEEPROM
 
560
        .endm
 
561
 
 
562
        .macro  .otprom
 
563
        ..set_default_space PORE_SPACE_OTPROM
 
564
        .endm
 
565
 
 
566
        .macro  .pibmem
 
567
        ..set_default_space PORE_SPACE_PIBMEM
 
568
#ifndef PGAS_PPC
 
569
        .pibmem_port (PORE_SPACE_PIBMEM & 0xf)
 
570
#else
 
571
        // NB: PGAS_PPC does not support relocatable PIBMEM addressing
 
572
#endif
 
573
        .endm
 
574
 
 
575
 
 
576
        //////////////////////////////////////////////////////////////////////
 
577
        // Address-Generation Pseudo Ops
 
578
        //////////////////////////////////////////////////////////////////////
 
579
 
 
580
        // .QUADA, .QUADIA
 
581
 
 
582
        .macro  .quada, offset:req
 
583
        ..check_default_space
 
584
        .long   _PGAS_DEFAULT_SPACE
 
585
        .long   (\offset)
 
586
        .endm
 
587
        
 
588
        .macro  .quadia, space:req, offset:req
 
589
        ..check_u16 (\space)
 
590
        .long   (\space)
 
591
        .long   (\offset)
 
592
        .endm
 
593
 
 
594
        //////////////////////////////////////////////////////////////////////
 
595
        // Bug workarounds
 
596
        //////////////////////////////////////////////////////////////////////
 
597
 
 
598
#ifndef IGNORE_HW274735
 
599
 
 
600
        // HW274735 documents that BC and BS are broken for the PORE-GPE0/1
 
601
        // pair. This bug is unfixed in POWER8, and by default we require BSI
 
602
        // and BCI to be implemented as macros on all engines. For
 
603
        // compatibility we continue to require that dx == D0.
 
604
 
 
605
        .macro  bsi, dx:req, offset:req, base:req, imm:req
 
606
        ..d0    (\dx)
 
607
        ld      D0, (\offset), (\base)
 
608
        ori     D0, D0, (\imm)
 
609
        std     D0, (\offset), (\base)
 
610
        .endm
 
611
 
 
612
        .macro  bci, dx:req, offset:req, base:req, imm:req
 
613
        ..d0    (\dx)
 
614
        ldandi  D0, (\offset), (\base), ~(\imm)
 
615
        std     D0, (\offset), (\base)
 
616
        .endm
 
617
 
 
618
#endif // IGNORE_HW274735
 
619
 
 
620
        //////////////////////////////////////////////////////////////////////
 
621
        // "A"- and "IA"-form Instructions
 
622
        //////////////////////////////////////////////////////////////////////
 
623
 
 
624
        // BRAA (Branch Address) is a 'long branch' to an address in the
 
625
        // default memory space.
 
626
 
 
627
        .macro  braa, offset:req
 
628
        braia   _PGAS_DEFAULT_SPACE, (\offset)
 
629
        .endm
 
630
 
 
631
        // LA (Load Address) loads the full address of an address in the
 
632
        // default memory space.
 
633
 
 
634
        .macro  la, dest:req, offset:req
 
635
        lia     (\dest), _PGAS_DEFAULT_SPACE, (\offset)
 
636
        .endm
 
637
 
 
638
        // STA (Store Address) stores the full address of an address in the
 
639
        // default memory space.
 
640
 
 
641
        .macro  sta, mem_offset:req, base:req, addr_offset:req
 
642
        stia    (\mem_offset), (\base), _PGAS_DEFAULT_SPACE, (\addr_offset)
 
643
        .endm
 
644
 
 
645
        // BSRIA is a subroutine branch into another memory space.  This has to
 
646
        // be emulated by a local subroutine branch and a BRAIA.
 
647
        
 
648
        .macro  bsria, space:req, offset:req
 
649
        bsr     27742f
 
650
        bra     27743f
 
651
27742:
 
652
        braia   (\space), (\offset)
 
653
27743:  
 
654
        .endm             
 
655
 
 
656
 
 
657
////////////////////////////////////////////////////////////////////////////
 
658
// Extended Mnemonics, Macros and Special Cases
 
659
////////////////////////////////////////////////////////////////////////////
 
660
 
 
661
        //////////////////////////////////////////////////////////////////////
 
662
        // TFB<c> - Test flags and branch conditionally
 
663
        //////////////////////////////////////////////////////////////////////'
 
664
        
 
665
        .macro  ..tfb, dest, target, flags
 
666
        ..data  (\dest)
 
667
        mr      (\dest), IFR
 
668
        andi    (\dest), (\dest), (\flags)
 
669
        branz   (\dest), (\target)
 
670
        .endm   
 
671
 
 
672
        .macro  ..tfbn dest, target, flags
 
673
        ..data  (\dest)
 
674
        mr      (\dest), IFR
 
675
        andi    (\dest), (\dest), (\flags)
 
676
        braz    (\dest), (\target)
 
677
        .endm   
 
678
 
 
679
        .macro  tfbcs, dest:req, target:req
 
680
        ..tfb    (\dest), (\target), CC_C
 
681
        .endm
 
682
 
 
683
        .macro  tfbcc, dest:req, target:req
 
684
        ..tfbn  (\dest), (\target), CC_C
 
685
        .endm
 
686
 
 
687
        .macro  tfbvs, dest:req, target:req
 
688
        ..tfb    (\dest), (\target), CC_V
 
689
        .endm
 
690
 
 
691
        .macro  tfbvc, dest:req, target:req
 
692
        ..tfbn   (\dest), (\target), CC_V
 
693
        .endm
 
694
 
 
695
        .macro  tfbns, dest:req, target:req
 
696
        ..tfb    (\dest), (\target), CC_N
 
697
        .endm
 
698
 
 
699
        .macro  tfbnc, dest:req, target:req
 
700
        ..tfbn   (\dest), (\target), CC_N
 
701
        .endm
 
702
 
 
703
        .macro  tfbeq, dest:req, target:req
 
704
        ..tfb   (\dest), (\target), CC_Z
 
705
        .endm
 
706
 
 
707
        .macro  tfbne, dest:req, target:req
 
708
        ..tfbn  (\dest), (\target), CC_Z
 
709
        .endm
 
710
 
 
711
        .macro  tfbult, dest:req, target:req
 
712
        ..tfb   (\dest), (\target), CC_ULT
 
713
        .endm
 
714
 
 
715
        .macro  tfbule, dest:req, target:req
 
716
        ..tfbn  (\dest), (\target), CC_UGT
 
717
        .endm
 
718
 
 
719
        .macro  tfbuge, dest:req, target:req
 
720
        ..tfbn  (\dest), (\target), CC_ULT
 
721
        .endm
 
722
 
 
723
        .macro  tfbugt, dest:req, target:req
 
724
        ..tfb   (\dest), (\target), CC_UGT
 
725
        .endm
 
726
 
 
727
        .macro  tfbslt, dest:req, target:req
 
728
        ..tfb   (\dest), (\target), CC_SLT
 
729
        .endm
 
730
 
 
731
        .macro  tfbsle, dest:req, target:req
 
732
        ..tfbn  (\dest), (\target), CC_SGT
 
733
        .endm
 
734
 
 
735
        .macro  tfbsge, dest:req, target:req
 
736
        ..tfbn  (\dest), (\target), CC_SLT
 
737
        .endm
 
738
 
 
739
        .macro  tfbsgt, dest:req, target:req
 
740
        ..tfb   (\dest), (\target), CC_SGT
 
741
        .endm
 
742
 
 
743
 
 
744
        //////////////////////////////////////////////////////////////////////
 
745
        // TEB[N]<eng> - Test Engine and branch if [not] engine.
 
746
        //////////////////////////////////////////////////////////////////////
 
747
        //
 
748
        // All but GPE0 use a 1-hot code.
 
749
        
 
750
        .macro  tebgpe0, dest:req, target:req
 
751
        mr      (\dest), IFR
 
752
        andi    (\dest), (\dest), 0xf
 
753
        braz    (\dest), (\target)
 
754
        .endm   
 
755
 
 
756
        .macro  tebgpe1, dest:req, target:req
 
757
        mr      (\dest), IFR
 
758
        andi    (\dest), (\dest), PORE_ID_GPE1
 
759
        branz   (\dest), (\target)
 
760
        .endm   
 
761
 
 
762
        .macro  tebslw, dest:req, target:req
 
763
        mr      (\dest), IFR
 
764
        andi    (\dest), (\dest), PORE_ID_SLW
 
765
        branz   (\dest), (\target)
 
766
        .endm   
 
767
 
 
768
        .macro  tebsbe, dest:req, target:req
 
769
        mr      (\dest), IFR
 
770
        andi    (\dest), (\dest), PORE_ID_SBE
 
771
        branz   (\dest), (\target)
 
772
        .endm   
 
773
 
 
774
 
 
775
        .macro  tebngpe0, dest:req, target:req
 
776
        mr      (\dest), IFR
 
777
        andi    (\dest), (\dest), 0xf
 
778
        branz   (\dest), (\target)
 
779
        .endm   
 
780
 
 
781
        .macro  tebngpe1, dest:req, target:req
 
782
        mr      (\dest), IFR
 
783
        andi    (\dest), (\dest), PORE_ID_GPE1
 
784
        braz    (\dest), (\target)
 
785
        .endm   
 
786
 
 
787
        .macro  tebnslw, dest:req, target:req
 
788
        mr      (\dest), IFR
 
789
        andi    (\dest), (\dest), PORE_ID_SLW
 
790
        braz    (\dest), (\target)
 
791
        .endm   
 
792
 
 
793
        .macro  tebnsbe, dest:req, target:req
 
794
        mr      (\dest), IFR
 
795
        andi    (\dest), (\dest), PORE_ID_SBE
 
796
        braz    (\dest), (\target)
 
797
        .endm   
 
798
 
 
799
 
 
800
        //////////////////////////////////////////////////////////////////////
 
801
        // EXTRPRC   - Extract and right-justify the PIB/PCB return code
 
802
        // TPRCB[N]Z - Test PIB return code and branch if [not] zero
 
803
        // TPRCBGT   - Test PIB return code and branch if greater-than
 
804
        // TPRCBLE   - Test PIB return code and branch if less-then or equal
 
805
        //////////////////////////////////////////////////////////////////////
 
806
        //
 
807
        // To support cases where PORE code expects or must explicitly handle
 
808
        // non-0 PIB return codes, the PIB return code and parity indication
 
809
        // are stored in bits 32 (parity) and 33-35 (return code) of the IFR.
 
810
        // These macros extract the four PIB/PCB status bits from the IFR and
 
811
        // right-justifies them into the data register provided. For EXTRPRC
 
812
        // that is the total function of the macro. The TPRCB[N]Z macros
 
813
        // provide a simple non-destructive test and branch for zero (success)
 
814
        // and non-zero (potential problem) codes after the extraction.
 
815
        //
 
816
        // In complex error handling scenarios one would typically compare the
 
817
        // PIB return code against an upper-bound, e.g., the offline response
 
818
        // (0x2), and then take further action. If the parity error bit is set
 
819
        // then this would produce an aggregate "return code" higher than any
 
820
        // that one would typically want to ignore. The TPRCBGT/TPRCBLE macros
 
821
        // provide this function; however the test destroys the extracted
 
822
        // return code so that if further analysis is required the code will
 
823
        // need to be a extracted again.
 
824
        //////////////////////////////////////////////////////////////////////
 
825
 
 
826
        .macro  extrprc, dest:req
 
827
        ..data  (\dest)
 
828
        mr      (\dest), IFR
 
829
        extrdi  (\dest), (\dest), 4, 32             
 
830
        .endm
 
831
 
 
832
        .macro  tprcbz, dest:req, target:req
 
833
        extrprc (\dest)
 
834
        braz    (\dest), (\target)
 
835
        .endm
 
836
        
 
837
        .macro  tprcbnz, dest:req, target:req
 
838
        extrprc (\dest)
 
839
        branz   (\dest), (\target)
 
840
        .endm
 
841
        
 
842
        .macro  tprcbgt, dest:req, target:req, bound:req
 
843
        extrprc (\dest)
 
844
        subs    (\dest), (\dest), (\bound)
 
845
        tfbugt  (\dest), (\target)
 
846
        .endm
 
847
        
 
848
        .macro  tprcble, dest:req, target:req, bound:req
 
849
        extrprc (\dest)
 
850
        subs    (\dest), (\dest), (\bound)
 
851
        tfbule  (\dest), (\target)
 
852
        .endm
 
853
        
 
854
        //////////////////////////////////////////////////////////////////////
 
855
        // LPCS - Load Pervasive Chiplet from Scom address
 
856
        //////////////////////////////////////////////////////////////////////
 
857
 
 
858
        .macro  lpcs, dest:req, scom:req
 
859
        ..pervasive_chiplet_id (\dest)
 
860
        ..check_scom (\scom)
 
861
        ls      (\dest), (((\scom) >> 24) & 0x7f)
 
862
        .endm
 
863
 
 
864
 
 
865
        //////////////////////////////////////////////////////////////////////
 
866
        // Shift/Mask extended mnemonics
 
867
        //////////////////////////////////////////////////////////////////////
 
868
 
 
869
        // All of the 'dot-dot' macros assume that error and identity
 
870
        // checking has been done on the arguments already.
 
871
 
 
872
        // The initial register-register rotate.  If the incoming shift amount
 
873
        // is 0 then the instruction generated is a simple MR.
 
874
 
 
875
        .macro  ..rotlrr, ra, rs, sh
 
876
 
 
877
        .if     (\sh) >= 32
 
878
                rols    (\ra), (\rs), 32
 
879
                ..rotlr  (\ra), ((\sh) - 32)
 
880
        .elseif (\sh) >= 16
 
881
                rols    (\ra), (\rs), 16
 
882
                ..rotlr  (\ra), ((\sh) - 16)
 
883
        .elseif (\sh) >= 8
 
884
                rols    (\ra), (\rs), 8
 
885
                ..rotlr  (\ra), ((\sh) - 8)
 
886
        .elseif (\sh) >= 4
 
887
                rols    (\ra), (\rs), 4
 
888
                ..rotlr  (\ra), ((\sh) - 4)
 
889
        .elseif (\sh) >= 1
 
890
                rols    (\ra), (\rs), 1
 
891
                ..rotlr  (\ra), ((\sh) - 1)
 
892
        .else
 
893
                mr      (\ra), (\rs)
 
894
        .endif
 
895
 
 
896
        .endm
 
897
 
 
898
 
 
899
        // Subsequent rotation of the same register.  The SH should never be 0
 
900
        // here. 
 
901
 
 
902
        .macro  ..rotlr, ra, sh
 
903
 
 
904
        .if     (\sh) >= 32
 
905
                rols    (\ra), (\ra), 32
 
906
                ..rotlr  (\ra), ((\sh) - 32)
 
907
        .elseif (\sh) >= 16
 
908
                rols    (\ra), (\ra), 16
 
909
                ..rotlr  (\ra), ((\sh) - 16)
 
910
        .elseif (\sh) >= 8
 
911
                rols    (\ra), (\ra), 8
 
912
                ..rotlr  (\ra), ((\sh) - 8)
 
913
        .elseif (\sh) >= 4
 
914
                rols    (\ra), (\ra), 4
 
915
                ..rotlr  (\ra), ((\sh) - 4)
 
916
        .elseif (\sh) >= 1
 
917
                rols    (\ra), (\ra), 1
 
918
                ..rotlr  (\ra), ((\sh) - 1)
 
919
 
 
920
        .endif
 
921
 
 
922
        .endm
 
923
 
 
924
 
 
925
        // RLDINM RA, RS, SH, MB, ME
 
926
        //
 
927
        // Defined as if there were an equivalent PowerPC instruction. The
 
928
        // 'word' forms of the PowerPC instructions and extended mnemonics are
 
929
        // undefined in order to catch programming typos.
 
930
 
 
931
        .undefppc       rlwinm, extrwi, rotlwi, rotrwi
 
932
        .undefppc       slwi, srwi
 
933
 
 
934
        .macro  rldinm, ra:req, rs:req, sh:req, mb:req, me:req
 
935
 
 
936
        .if     ((\sh) < 0) || ((\sh) > 63)
 
937
                .error  "SH must be in the range 0..63"
 
938
        .endif
 
939
        .if     ((\mb) < 0) || ((\mb) > 63)
 
940
                .error  "MB must be in the range 0..63"
 
941
        .endif
 
942
        .if     ((\me) < 0) || ((\me) > 63)
 
943
                .error  "ME must be in the range 0..63"
 
944
        .endif
 
945
        
 
946
        .if     (((\mb) == 0) && ((\me) == 63) || ((\me) == ((\mb) - 1)))
 
947
 
 
948
                // The mask is effectively 0..63, i.e., no mask. This is a
 
949
                // simple rotate.
 
950
                
 
951
                ..rotlrr (\ra), (\rs), (\sh)
 
952
        
 
953
        .else
 
954
        
 
955
                // We need a mask step.  However if SH == 0 and RA == RS we can
 
956
                // bypass the rotate step.
 
957
                
 
958
                .if     ((\sh) != 0) || ((\ra) != (\rs))
 
959
                        ..rotlrr (\ra), (\rs), (\sh)
 
960
                .endif
 
961
                .if     ((\mb) <= (\me))
 
962
 
 
963
                        // This is a straightforward masking operation with a
 
964
                        // single mask.
 
965
                
 
966
                        andi    (\ra), (\ra), ((0xffffffffffffffff >> (\mb)) & (0xffffffffffffffff << (63 - (\me))))
 
967
                .else
 
968
                
 
969
                        // This is a wrapped mask.  
 
970
                        // It is created as 2 masks OR-ed together - 0-ME and MB-63
 
971
                
 
972
                        andi    (\ra), (\ra), (((0xffffffffffffffff >> 0) & (0xffffffffffffffff << (63 - (\me)))) | ((0xffffffffffffffff >> (\mb)) & (0xffffffffffffffff << (63 - 63))))
 
973
                .endif
 
974
        
 
975
        .endif
 
976
        
 
977
        .endm           
 
978
 
 
979
        // RLDINM Extended Mnemonics
 
980
        //
 
981
        // Defined as if they were equivalent to PowerPC 32-bit extended
 
982
        // mnemonics
 
983
 
 
984
        .macro  extldi, ra:req, rs:req, n:req, b:req
 
985
        .if     ((\n) < 0)
 
986
                .error  "EXTLDI requires N > 0"
 
987
        .endif
 
988
         rldinm (\ra), (\rs), (\b), 0, ((\n) - 1)
 
989
        .endm
 
990
 
 
991
        .macro  extrdi, ra:req, rs:req, n:req, b:req
 
992
        .if     ((\n) < 0)
 
993
                .error  "EXTRDI requires N > 0"
 
994
        .endif
 
995
        rldinm  (\ra), (\rs), (((\b) + (\n)) % 64), (64 - (\n)), 63
 
996
        .endm
 
997
 
 
998
        .macro  rotldi, ra:req, rs:req, n:req
 
999
        rldinm  (\ra), (\rs), (\n), 0, 63
 
1000
        .endm
 
1001
 
 
1002
 
 
1003
        .macro  rotrdi, ra:req, rs:req, n:req
 
1004
        rldinm  (\ra), (\rs), (64 - (\n)), 0, 63
 
1005
        .endm
 
1006
 
 
1007
 
 
1008
        .macro  sldi, ra:req, rs:req, n:req
 
1009
        rldinm  (\ra), (\rs), (\n), 0, (63 - (\n))
 
1010
        .endm
 
1011
        
 
1012
 
 
1013
        .macro  srdi, ra:req, rs:req, n:req
 
1014
        rldinm  (\ra), (\rs), (64 - (\n)), (\n), 63
 
1015
        .endm
 
1016
        
 
1017
 
 
1018
        // RLDIMI RA, RS, SH, MB, ME
 
1019
        //
 
1020
        // Defined as if there were an equivalent PowerPC instruction. The
 
1021
        // 'word' forms of the PowerPC instructions and extended mnemonics are
 
1022
        // undefined in order to catch programming typos.
 
1023
        //
 
1024
        // Note that unlike the PowerPC instructions, here RLDIMI must destroy
 
1025
        // RS by masking and shifting it, and RA and RS may not be the same
 
1026
        // register. 
 
1027
 
 
1028
        .undefppc       rlwimi, inslwi, insrwi
 
1029
 
 
1030
        .macro  rldimi, ra:req, rs:req, sh:req, mb:req, me:req
 
1031
 
 
1032
        ..dxdy  (\ra), (\rs)
 
1033
 
 
1034
        // SH error checks are done by rldinm
 
1035
                
 
1036
        .if     (((\mb) == 0) && ((\me) == 63) || ((\me) == ((\mb) - 1)))
 
1037
 
 
1038
                // The mask is effectively 0..63, i.e., no mask. This is a
 
1039
                // simple rotate of RS into RA
 
1040
                
 
1041
                rotldi  (\ra), (\rs), (\sh)
 
1042
        
 
1043
        .else
 
1044
 
 
1045
                // Rotate RS and AND with mask
 
1046
 
 
1047
                rldinm  (\rs), (\rs), (\sh), (\mb), (\me)
 
1048
 
 
1049
                // Mask out the significant bits of RS, clear that section of
 
1050
                // RA, and logical OR RS into RA
 
1051
        
 
1052
                .if     ((\mb) <= (\me))
 
1053
 
 
1054
                        // This is a straightforward masking operation with a
 
1055
                        // single mask.
 
1056
                
 
1057
                        andi    (\ra), (\ra), \
 
1058
                                 (~((0xffffffffffffffff >> (\mb)) & (0xffffffffffffffff << (63 - (\me)))))
 
1059
                .else
 
1060
                
 
1061
                        // This is a wrapped mask.  
 
1062
                        // It is created as 2 masks OR-ed together - 0-ME and MB-63
 
1063
                
 
1064
                        andi    (\ra), (\ra), \
 
1065
                                (~(((0xffffffffffffffff >> 0) & (0xffffffffffffffff << (63 - (\me)))) | \
 
1066
                                  ((0xffffffffffffffff >> (\mb)) & (0xffffffffffffffff << (63 - 63)))))
 
1067
                .endif
 
1068
 
 
1069
                or      (\ra), D0, D1
 
1070
        
 
1071
        .endif
 
1072
 
 
1073
        .endm           
 
1074
 
 
1075
        // RLDIMI Extended Mnemonics
 
1076
        //
 
1077
        // Defined as if they were equivalent to PowerPC 32-bit extended
 
1078
        // mnemonics
 
1079
 
 
1080
        .macro  insldi, ra:req, rs:req, n:req, b:req
 
1081
        .if     ((\n) < 0)
 
1082
                .error  "INSLDI requires N > 0"
 
1083
        .endif
 
1084
        rldimi   (\ra), (\rs), (64 - (\b)), (\b), ((\b) + (\n) - 1)
 
1085
        .endm
 
1086
 
 
1087
        .macro  insrdi, ra:req, rs:req, n:req, b:req
 
1088
        .if     ((\n) < 0)
 
1089
                .error  "INSRDI requires N > 0"
 
1090
        .endif
 
1091
        rldimi  (\ra), (\rs), (64 - (\b) - (\n)), (\b), ((\b) + (\n) - 1)
 
1092
        .endm
 
1093
 
 
1094
 
 
1095
        //////////////////////////////////////////////////////////////////////
 
1096
        // .HOOK
 
1097
        //////////////////////////////////////////////////////////////////////
 
1098
 
 
1099
        // The PoreVe (PORE Virtual Environment) is a PORE simulation
 
1100
        // environment that allows the programmer to embed C/C++ code into the
 
1101
        // PORE assembler source code, and arranges for the C/C++ code to be
 
1102
        // executed in-line with the PORE assembly code.  Instances of the
 
1103
        // .hook macro are inserted into the assembler input by the
 
1104
        // hook_extractor script, to mark the locations where hooks are
 
1105
        // present.  The hook reference is a string that combines the source
 
1106
        // file name with an index number to uniquely identify the hook.
 
1107
        //
 
1108
        //     .hook <file name>_<sequence number>
 
1109
        //
 
1110
        // The .hook macro marks the location of each hook in the relocatable
 
1111
        // binaries with special symbols.  The symbol name includes the hook
 
1112
        // reference, which is used to locate the hook in the HookManager
 
1113
        // symbol table. Because hooks can be defined in macros, a hook that
 
1114
        // appears once in a source file may appear multiple times in the
 
1115
        // final binary.  For this reason each hook must also be tagged with a
 
1116
        // unique index number to avoid symbol name collisions.  The
 
1117
        // complexity of the .hook macro is due to the necessity to decode a
 
1118
        // dynamic symbol value (_PGAS_HOOK_INDEX) into its binary string form
 
1119
        // to create the unique symbol name.  The final hook symbol has the
 
1120
        // form:
 
1121
        //
 
1122
        // __hook__<unique>_<reference>
 
1123
        //
 
1124
        // where <unique> is a binary string. It is then straightforward to
 
1125
        // locate these symbols in the 'nm' output of the final link and
 
1126
        // create a map of final addresses to the hook routine to call (the
 
1127
        // <reference>) before executing the instruction at that address.
 
1128
        //
 
1129
        // Note: The maximum nesting depth of the recursive ..hook_helper
 
1130
        // macro is log2(index), and the assembler supports nesting of at
 
1131
        // least 32 which is much more than sufficient.
 
1132
 
 
1133
        .set    _PGAS_HOOK_INDEX, 0
 
1134
 
 
1135
        .macro  .hook, reference:req
 
1136
        .set    _PGAS_HOOK_INDEX, (_PGAS_HOOK_INDEX + 1)
 
1137
        ..hook_helper _PGAS_HOOK_INDEX, "", \reference
 
1138
        .endm
 
1139
 
 
1140
        .macro  ..hook_helper, index, unique, reference
 
1141
        .ifeq   \index
 
1142
        __hook__\unique\()_\reference\():       
 
1143
        .elseif (\index % 2)
 
1144
        ..hook_helper (\index / 2), 1\unique, \reference
 
1145
        .else
 
1146
        ..hook_helper (\index / 2), 0\unique, \reference
 
1147
        .endif
 
1148
        .endm
 
1149
 
 
1150
 
 
1151
////////////////////////////////////////////////////////////////////////////
 
1152
// Help for Conversion from Old to New PGAS syntax
 
1153
////////////////////////////////////////////////////////////////////////////
 
1154
 
 
1155
        .macro  loadp, arg:vararg
 
1156
        .error  "PGAS now implements 'lpcs' rather then 'loadp'"
 
1157
        .endm
 
1158
 
 
1159
        .macro  loadx, arg:vararg
 
1160
        .error  "PGAS now implements 'la' rather than 'loadx'"
 
1161
        .endm
 
1162
 
 
1163
#endif  // __ASSEMBLER__
 
1164
                    
 
1165
#ifdef PGAS_PPC
 
1166
#include "pgas_ppc.h"
 
1167
#endif
 
1168
 
 
1169
#endif // __PGAS_H__