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

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [insight/] [bfd/] [libhppa.h] - Blame information for rev 1765

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

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

powered by: WebSVN 2.1.0

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