OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [bfd/] [libhppa.h] - Blame information for rev 279

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 khays
/* HP PA-RISC SOM object file format:  definitions internal to BFD.
2
   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000,
3
   2003, 2005, 2007  Free Software Foundation, Inc.
4
 
5
   Contributed by the Center for Software Science at the
6
   University of Utah (pa-gdb-bugs@cs.utah.edu).
7
 
8
   This file is part of BFD, the Binary File Descriptor library.
9
 
10
   This program is free software; you can redistribute it and/or modify
11
   it under the terms of the GNU General Public License as published by
12
   the Free Software Foundation; either version 3 of the License, or
13
   (at your option) any later version.
14
 
15
   This program is distributed in the hope that it will be useful,
16
   but WITHOUT ANY WARRANTY; without even the implied warranty of
17
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
   GNU General Public License for more details.
19
 
20
   You should have received a copy of the GNU General Public License
21
   along with this program; if not, write to the Free Software
22
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
23
   MA 02110-1301, USA.  */
24
 
25
#ifndef _LIBHPPA_H
26
#define _LIBHPPA_H
27
 
28
#define BYTES_IN_WORD 4
29
#define PA_PAGESIZE 0x1000
30
 
31
/* The PA instruction set variants.  */
32
enum pa_arch {pa10 = 10, pa11 = 11, pa20 = 20, pa20w = 25};
33
 
34
/* HP PA-RISC relocation types */
35
 
36
enum hppa_reloc_field_selector_type
37
  {
38
    R_HPPA_FSEL = 0x0,
39
    R_HPPA_LSSEL = 0x1,
40
    R_HPPA_RSSEL = 0x2,
41
    R_HPPA_LSEL = 0x3,
42
    R_HPPA_RSEL = 0x4,
43
    R_HPPA_LDSEL = 0x5,
44
    R_HPPA_RDSEL = 0x6,
45
    R_HPPA_LRSEL = 0x7,
46
    R_HPPA_RRSEL = 0x8,
47
    R_HPPA_NSEL  = 0x9,
48
    R_HPPA_NLSEL  = 0xa,
49
    R_HPPA_NLRSEL  = 0xb,
50
    R_HPPA_PSEL = 0xc,
51
    R_HPPA_LPSEL = 0xd,
52
    R_HPPA_RPSEL = 0xe,
53
    R_HPPA_TSEL = 0xf,
54
    R_HPPA_LTSEL = 0x10,
55
    R_HPPA_RTSEL = 0x11,
56
    R_HPPA_LTPSEL = 0x12,
57
    R_HPPA_RTPSEL = 0x13
58
  };
59
 
60
/* /usr/include/reloc.h defines these to constants.  We want to use
61
   them in enums, so #undef them before we start using them.  We might
62
   be able to fix this another way by simply managing not to include
63
   /usr/include/reloc.h, but currently GDB picks up these defines
64
   somewhere.  */
65
#undef e_fsel
66
#undef e_lssel
67
#undef e_rssel
68
#undef e_lsel
69
#undef e_rsel
70
#undef e_ldsel
71
#undef e_rdsel
72
#undef e_lrsel
73
#undef e_rrsel
74
#undef e_nsel
75
#undef e_nlsel
76
#undef e_nlrsel
77
#undef e_psel
78
#undef e_lpsel
79
#undef e_rpsel
80
#undef e_tsel
81
#undef e_ltsel
82
#undef e_rtsel
83
#undef e_one
84
#undef e_two
85
#undef e_pcrel
86
#undef e_con
87
#undef e_plabel
88
#undef e_abs
89
 
90
/* for compatibility */
91
enum hppa_reloc_field_selector_type_alt
92
  {
93
    e_fsel = R_HPPA_FSEL,
94
    e_lssel = R_HPPA_LSSEL,
95
    e_rssel = R_HPPA_RSSEL,
96
    e_lsel = R_HPPA_LSEL,
97
    e_rsel = R_HPPA_RSEL,
98
    e_ldsel = R_HPPA_LDSEL,
99
    e_rdsel = R_HPPA_RDSEL,
100
    e_lrsel = R_HPPA_LRSEL,
101
    e_rrsel = R_HPPA_RRSEL,
102
    e_nsel = R_HPPA_NSEL,
103
    e_nlsel = R_HPPA_NLSEL,
104
    e_nlrsel = R_HPPA_NLRSEL,
105
    e_psel = R_HPPA_PSEL,
106
    e_lpsel = R_HPPA_LPSEL,
107
    e_rpsel = R_HPPA_RPSEL,
108
    e_tsel = R_HPPA_TSEL,
109
    e_ltsel = R_HPPA_LTSEL,
110
    e_rtsel = R_HPPA_RTSEL,
111
    e_ltpsel = R_HPPA_LTPSEL,
112
    e_rtpsel = R_HPPA_RTPSEL
113
  };
114
 
115
enum hppa_reloc_expr_type
116
  {
117
    R_HPPA_E_ONE = 0,
118
    R_HPPA_E_TWO = 1,
119
    R_HPPA_E_PCREL = 2,
120
    R_HPPA_E_CON = 3,
121
    R_HPPA_E_PLABEL = 7,
122
    R_HPPA_E_ABS = 18
123
  };
124
 
125
/* for compatibility */
126
enum hppa_reloc_expr_type_alt
127
  {
128
    e_one = R_HPPA_E_ONE,
129
    e_two = R_HPPA_E_TWO,
130
    e_pcrel = R_HPPA_E_PCREL,
131
    e_con = R_HPPA_E_CON,
132
    e_plabel = R_HPPA_E_PLABEL,
133
    e_abs = R_HPPA_E_ABS
134
  };
135
 
136
 
137
/* Relocations for function calls must be accompanied by parameter
138
   relocation bits.  These bits describe exactly where the caller has
139
   placed the function's arguments and where it expects to find a return
140
   value.
141
 
142
   Both ELF and SOM encode this information within the addend field
143
   of the call relocation.  (Note this could break very badly if one
144
   was to make a call like bl foo + 0x12345678).
145
 
146
   The high order 10 bits contain parameter relocation information,
147
   the low order 22 bits contain the constant offset.  */
148
 
149
#define HPPA_R_ARG_RELOC(a)     \
150
  (((a) >> 22) & 0x3ff)
151
#define HPPA_R_CONSTANT(a)      \
152
  ((((bfd_signed_vma)(a)) << (BFD_ARCH_SIZE-22)) >> (BFD_ARCH_SIZE-22))
153
#define HPPA_R_ADDEND(r, c)     \
154
  (((r) << 22) + ((c) & 0x3fffff))
155
 
156
 
157
/* Some functions to manipulate PA instructions.  */
158
 
159
/* Declare the functions with the unused attribute to avoid warnings.  */
160
static inline int sign_extend (int, int) ATTRIBUTE_UNUSED;
161
static inline int low_sign_extend (int, int) ATTRIBUTE_UNUSED;
162
static inline int sign_unext (int, int) ATTRIBUTE_UNUSED;
163
static inline int low_sign_unext (int, int) ATTRIBUTE_UNUSED;
164
static inline int re_assemble_3 (int) ATTRIBUTE_UNUSED;
165
static inline int re_assemble_12 (int) ATTRIBUTE_UNUSED;
166
static inline int re_assemble_14 (int) ATTRIBUTE_UNUSED;
167
static inline int re_assemble_16 (int) ATTRIBUTE_UNUSED;
168
static inline int re_assemble_17 (int) ATTRIBUTE_UNUSED;
169
static inline int re_assemble_21 (int) ATTRIBUTE_UNUSED;
170
static inline int re_assemble_22 (int) ATTRIBUTE_UNUSED;
171
static inline bfd_signed_vma hppa_field_adjust
172
  (bfd_vma, bfd_signed_vma, enum hppa_reloc_field_selector_type_alt)
173
  ATTRIBUTE_UNUSED;
174
static inline int bfd_hppa_insn2fmt (bfd *, int) ATTRIBUTE_UNUSED;
175
static inline int hppa_rebuild_insn (int, int, int) ATTRIBUTE_UNUSED;
176
 
177
 
178
/* The *sign_extend functions are used to assemble various bitfields
179
   taken from an instruction and return the resulting immediate
180
   value.  */
181
 
182
static inline int
183
sign_extend (int x, int len)
184
{
185
  int signbit = (1 << (len - 1));
186
  int mask = (signbit << 1) - 1;
187
  return ((x & mask) ^ signbit) - signbit;
188
}
189
 
190
static inline int
191
low_sign_extend (int x, int len)
192
{
193
  return (x >> 1) - ((x & 1) << (len - 1));
194
}
195
 
196
 
197
/* The re_assemble_* functions prepare an immediate value for
198
   insertion into an opcode. pa-risc uses all sorts of weird bitfields
199
   in the instruction to hold the value.  */
200
 
201
static inline int
202
sign_unext (int x, int len)
203
{
204
  int len_ones;
205
 
206
  len_ones = (1 << len) - 1;
207
 
208
  return x & len_ones;
209
}
210
 
211
static inline int
212
low_sign_unext (int x, int len)
213
{
214
  int temp;
215
  int sign;
216
 
217
  sign = (x >> (len-1)) & 1;
218
 
219
  temp = sign_unext (x, len-1);
220
 
221
  return (temp << 1) | sign;
222
}
223
 
224
static inline int
225
re_assemble_3 (int as3)
226
{
227
  return ((  (as3 & 4) << (13-2))
228
          | ((as3 & 3) << (13+1)));
229
}
230
 
231
static inline int
232
re_assemble_12 (int as12)
233
{
234
  return ((  (as12 & 0x800) >> 11)
235
          | ((as12 & 0x400) >> (10 - 2))
236
          | ((as12 & 0x3ff) << (1 + 2)));
237
}
238
 
239
static inline int
240
re_assemble_14 (int as14)
241
{
242
  return ((  (as14 & 0x1fff) << 1)
243
          | ((as14 & 0x2000) >> 13));
244
}
245
 
246
static inline int
247
re_assemble_16 (int as16)
248
{
249
  int s, t;
250
 
251
  /* Unusual 16-bit encoding, for wide mode only.  */
252
  t = (as16 << 1) & 0xffff;
253
  s = (as16 & 0x8000);
254
  return (t ^ s ^ (s >> 1)) | (s >> 15);
255
}
256
 
257
static inline int
258
re_assemble_17 (int as17)
259
{
260
  return ((  (as17 & 0x10000) >> 16)
261
          | ((as17 & 0x0f800) << (16 - 11))
262
          | ((as17 & 0x00400) >> (10 - 2))
263
          | ((as17 & 0x003ff) << (1 + 2)));
264
}
265
 
266
static inline int
267
re_assemble_21 (int as21)
268
{
269
  return ((  (as21 & 0x100000) >> 20)
270
          | ((as21 & 0x0ffe00) >> 8)
271
          | ((as21 & 0x000180) << 7)
272
          | ((as21 & 0x00007c) << 14)
273
          | ((as21 & 0x000003) << 12));
274
}
275
 
276
static inline int
277
re_assemble_22 (int as22)
278
{
279
  return ((  (as22 & 0x200000) >> 21)
280
          | ((as22 & 0x1f0000) << (21 - 16))
281
          | ((as22 & 0x00f800) << (16 - 11))
282
          | ((as22 & 0x000400) >> (10 - 2))
283
          | ((as22 & 0x0003ff) << (1 + 2)));
284
}
285
 
286
 
287
/* Handle field selectors for PA instructions.
288
   The L and R (and LS, RS etc.) selectors are used in pairs to form a
289
   full 32 bit address.  eg.
290
 
291
   LDIL L'start,%r1             ; put left part into r1
292
   LDW  R'start(%r1),%r2        ; add r1 and right part to form address
293
 
294
   This function returns sign extended values in all cases.
295
*/
296
 
297
static inline bfd_signed_vma
298
hppa_field_adjust (bfd_vma sym_val,
299
                   bfd_signed_vma addend,
300
                   enum hppa_reloc_field_selector_type_alt r_field)
301
{
302
  bfd_signed_vma value;
303
 
304
  value = sym_val + addend;
305
  switch (r_field)
306
    {
307
    case e_fsel:
308
      /* F: No change.  */
309
      break;
310
 
311
    case e_nsel:
312
      /* N: null selector.  I don't really understand what this is all
313
         about, but HP's documentation says "this indicates that zero
314
         bits are to be used for the displacement on the instruction.
315
         This fixup is used to identify three-instruction sequences to
316
         access data (for importing shared library data)."  */
317
      value = 0;
318
      break;
319
 
320
    case e_lsel:
321
    case e_nlsel:
322
      /* L:  Select top 21 bits.  */
323
      value = value >> 11;
324
      break;
325
 
326
    case e_rsel:
327
      /* R:  Select bottom 11 bits.  */
328
      value = value & 0x7ff;
329
      break;
330
 
331
    case e_lssel:
332
      /* LS:  Round to nearest multiple of 2048 then select top 21 bits.  */
333
      value = value + 0x400;
334
      value = value >> 11;
335
      break;
336
 
337
    case e_rssel:
338
      /* RS:  Select bottom 11 bits for LS.
339
         We need to return a value such that 2048 * LS'x + RS'x == x.
340
         ie. RS'x = x - ((x + 0x400) & -0x800)
341
         this is just a sign extension from bit 21.  */
342
      value = ((value & 0x7ff) ^ 0x400) - 0x400;
343
      break;
344
 
345
    case e_ldsel:
346
      /* LD:  Round to next multiple of 2048 then select top 21 bits.
347
         Yes, if we are already on a multiple of 2048, we go up to the
348
         next one.  RD in this case will be -2048.  */
349
      value = value + 0x800;
350
      value = value >> 11;
351
      break;
352
 
353
    case e_rdsel:
354
      /* RD:  Set bits 0-20 to one.  */
355
      value = value | -0x800;
356
      break;
357
 
358
    case e_lrsel:
359
    case e_nlrsel:
360
      /* LR:  L with rounding of the addend to nearest 8k.  */
361
      value = sym_val + ((addend + 0x1000) & -0x2000);
362
      value = value >> 11;
363
      break;
364
 
365
    case e_rrsel:
366
      /* RR:  R with rounding of the addend to nearest 8k.
367
         We need to return a value such that 2048 * LR'x + RR'x == x
368
         ie. RR'x = s+a - (s + (((a + 0x1000) & -0x2000) & -0x800))
369
         .        = s+a - ((s & -0x800) + ((a + 0x1000) & -0x2000))
370
         .        = (s & 0x7ff) + a - ((a + 0x1000) & -0x2000)  */
371
      value = (sym_val & 0x7ff) + (((addend & 0x1fff) ^ 0x1000) - 0x1000);
372
      break;
373
 
374
    default:
375
      abort ();
376
    }
377
  return value;
378
}
379
 
380
/* PA-RISC OPCODES */
381
#define get_opcode(insn)        (((insn) >> 26) & 0x3f)
382
 
383
enum hppa_opcode_type
384
{
385
  /* None of the opcodes in the first group generate relocs, so we
386
     aren't too concerned about them.  */
387
  OP_SYSOP   = 0x00,
388
  OP_MEMMNG  = 0x01,
389
  OP_ALU     = 0x02,
390
  OP_NDXMEM  = 0x03,
391
  OP_SPOP    = 0x04,
392
  OP_DIAG    = 0x05,
393
  OP_FMPYADD = 0x06,
394
  OP_UNDEF07 = 0x07,
395
  OP_COPRW   = 0x09,
396
  OP_COPRDW  = 0x0b,
397
  OP_COPR    = 0x0c,
398
  OP_FLOAT   = 0x0e,
399
  OP_PRDSPEC = 0x0f,
400
  OP_UNDEF15 = 0x15,
401
  OP_UNDEF1d = 0x1d,
402
  OP_FMPYSUB = 0x26,
403
  OP_FPFUSED = 0x2e,
404
  OP_SHEXDP0 = 0x34,
405
  OP_SHEXDP1 = 0x35,
406
  OP_SHEXDP2 = 0x36,
407
  OP_UNDEF37 = 0x37,
408
  OP_SHEXDP3 = 0x3c,
409
  OP_SHEXDP4 = 0x3d,
410
  OP_MULTMED = 0x3e,
411
  OP_UNDEF3f = 0x3f,
412
 
413
  OP_LDIL    = 0x08,
414
  OP_ADDIL   = 0x0a,
415
 
416
  OP_LDO     = 0x0d,
417
  OP_LDB     = 0x10,
418
  OP_LDH     = 0x11,
419
  OP_LDW     = 0x12,
420
  OP_LDWM    = 0x13,
421
  OP_STB     = 0x18,
422
  OP_STH     = 0x19,
423
  OP_STW     = 0x1a,
424
  OP_STWM    = 0x1b,
425
 
426
  OP_LDD     = 0x14,
427
  OP_STD     = 0x1c,
428
 
429
  OP_FLDW    = 0x16,
430
  OP_LDWL    = 0x17,
431
  OP_FSTW    = 0x1e,
432
  OP_STWL    = 0x1f,
433
 
434
  OP_COMBT   = 0x20,
435
  OP_COMIBT  = 0x21,
436
  OP_COMBF   = 0x22,
437
  OP_COMIBF  = 0x23,
438
  OP_CMPBDT  = 0x27,
439
  OP_ADDBT   = 0x28,
440
  OP_ADDIBT  = 0x29,
441
  OP_ADDBF   = 0x2a,
442
  OP_ADDIBF  = 0x2b,
443
  OP_CMPBDF  = 0x2f,
444
  OP_BVB     = 0x30,
445
  OP_BB      = 0x31,
446
  OP_MOVB    = 0x32,
447
  OP_MOVIB   = 0x33,
448
  OP_CMPIBD  = 0x3b,
449
 
450
  OP_COMICLR = 0x24,
451
  OP_SUBI    = 0x25,
452
  OP_ADDIT   = 0x2c,
453
  OP_ADDI    = 0x2d,
454
 
455
  OP_BE      = 0x38,
456
  OP_BLE     = 0x39,
457
  OP_BL      = 0x3a
458
};
459
 
460
 
461
/* Given a machine instruction, return its format.  */
462
 
463
static inline int
464
bfd_hppa_insn2fmt (bfd *abfd, int insn)
465
{
466
  enum hppa_opcode_type op = get_opcode (insn);
467
 
468
  switch (op)
469
    {
470
    case OP_COMICLR:
471
    case OP_SUBI:
472
    case OP_ADDIT:
473
    case OP_ADDI:
474
      return 11;
475
 
476
    case OP_COMBT:
477
    case OP_COMIBT:
478
    case OP_COMBF:
479
    case OP_COMIBF:
480
    case OP_CMPBDT:
481
    case OP_ADDBT:
482
    case OP_ADDIBT:
483
    case OP_ADDBF:
484
    case OP_ADDIBF:
485
    case OP_CMPBDF:
486
    case OP_BVB:
487
    case OP_BB:
488
    case OP_MOVB:
489
    case OP_MOVIB:
490
    case OP_CMPIBD:
491
      return 12;
492
 
493
    case OP_LDO:
494
    case OP_LDB:
495
    case OP_LDH:
496
    case OP_LDW:
497
    case OP_LDWM:
498
    case OP_STB:
499
    case OP_STH:
500
    case OP_STW:
501
    case OP_STWM:
502
      if (abfd->arch_info->mach >= 25)
503
        return 16;      /* Wide mode, format 16.  */
504
      return 14;
505
 
506
    case OP_FLDW:
507
    case OP_LDWL:
508
    case OP_FSTW:
509
    case OP_STWL:
510
      /* This is a hack.  Unfortunately, format 11 is already taken
511
         and we're using integers rather than an enum, so it's hard
512
         to describe the 11a format.  */
513
      if (abfd->arch_info->mach >= 25)
514
        return -16;     /* Wide mode, format 16a.  */
515
      return -11;
516
 
517
    case OP_LDD:
518
    case OP_STD:
519
      if (abfd->arch_info->mach >= 25)
520
        return -10;     /* Wide mode, format 10a.  */
521
      return 10;
522
 
523
    case OP_BL:
524
      if ((insn & 0x8000) != 0)
525
        return 22;
526
      /* fall thru */
527
    case OP_BE:
528
    case OP_BLE:
529
      return 17;
530
 
531
    case OP_LDIL:
532
    case OP_ADDIL:
533
      return 21;
534
 
535
    default:
536
      break;
537
    }
538
  return 32;
539
}
540
 
541
 
542
/* Insert VALUE into INSN using R_FORMAT to determine exactly what
543
   bits to change.  */
544
 
545
static inline int
546
hppa_rebuild_insn (int insn, int value, int r_format)
547
{
548
  switch (r_format)
549
    {
550
    case 11:
551
      return (insn & ~ 0x7ff) | low_sign_unext (value, 11);
552
 
553
    case 12:
554
      return (insn & ~ 0x1ffd) | re_assemble_12 (value);
555
 
556
 
557
    case 10:
558
      return (insn & ~ 0x3ff1) | re_assemble_14 (value & -8);
559
 
560
    case -11:
561
      return (insn & ~ 0x3ff9) | re_assemble_14 (value & -4);
562
 
563
    case 14:
564
      return (insn & ~ 0x3fff) | re_assemble_14 (value);
565
 
566
 
567
    case -10:
568
      return (insn & ~ 0xfff1) | re_assemble_16 (value & -8);
569
 
570
    case -16:
571
      return (insn & ~ 0xfff9) | re_assemble_16 (value & -4);
572
 
573
    case 16:
574
      return (insn & ~ 0xffff) | re_assemble_16 (value);
575
 
576
 
577
    case 17:
578
      return (insn & ~ 0x1f1ffd) | re_assemble_17 (value);
579
 
580
    case 21:
581
      return (insn & ~ 0x1fffff) | re_assemble_21 (value);
582
 
583
    case 22:
584
      return (insn & ~ 0x3ff1ffd) | re_assemble_22 (value);
585
 
586
    case 32:
587
      return value;
588
 
589
    default:
590
      abort ();
591
    }
592
  return insn;
593
}
594
 
595
#endif /* _LIBHPPA_H */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.