1 /* HP PA-RISC SOM object file format: definitions internal to BFD. 2 Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 98, 99, 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 _HPPA_H 25 #define _HPPA_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 #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) 39 /* Declare the functions with the unused attribute to avoid warnings. */ 40 static INLINE unsigned int assemble_3 (unsigned int) 41 __attribute__ ((__unused__)); 42 static INLINE void dis_assemble_3 (unsigned int, unsigned int *) 43 __attribute__ ((__unused__)); 44 static INLINE unsigned int assemble_12 (unsigned int, unsigned int) 45 __attribute__ ((__unused__)); 46 static INLINE void dis_assemble_12 (unsigned int, unsigned int *, 47 unsigned int *) 48 __attribute__ ((__unused__)); 49 static INLINE unsigned long assemble_17 (unsigned int, unsigned int, 50 unsigned int) 51 __attribute__ ((__unused__)); 52 static INLINE void dis_assemble_17 (unsigned int, unsigned int *, 53 unsigned int *, unsigned int *) 54 __attribute__ ((__unused__)); 55 static INLINE void dis_assemble_22 (unsigned int, unsigned int *, 56 unsigned int *, unsigned int *, 57 unsigned int *) 58 __attribute__ ((__unused__)); 59 static INLINE unsigned long assemble_21 (unsigned int) 60 __attribute ((__unused__)); 61 static INLINE void dis_assemble_21 (unsigned int, unsigned int *) 62 __attribute__ ((__unused__)); 63 static INLINE unsigned long sign_extend (unsigned int, unsigned int) 64 __attribute__ ((__unused__)); 65 static INLINE unsigned int ones (int) __attribute ((__unused__)); 66 static INLINE void sign_unext (unsigned int, unsigned int, unsigned int *) 67 __attribute__ ((__unused__)); 68 static INLINE unsigned long low_sign_extend (unsigned int, unsigned int) 69 __attribute__ ((__unused__)); 70 static INLINE void low_sign_unext (unsigned int, unsigned int, unsigned int *) 71 __attribute__ ((__unused__)); 72 static INLINE unsigned long hppa_field_adjust (unsigned long, unsigned long, 73 unsigned short) 74 __attribute__ ((__unused__)); 75 static INLINE int bfd_hppa_insn2fmt (unsigned long) 76 __attribute__ ((__unused__)); 77 static INLINE unsigned long hppa_rebuild_insn (bfd *, unsigned long, 78 unsigned long, unsigned long) 79 __attribute__ ((__unused__)); 80 #endif /* gcc 2.7 or higher */ 81 82 83 /* The PA instruction set variants. */ 84 enum pa_arch {pa10 = 10, pa11 = 11, pa20 = 20}; 85 86 /* HP PA-RISC relocation types */ 87 88 enum hppa_reloc_field_selector_type 89 { 90 R_HPPA_FSEL = 0x0, 91 R_HPPA_LSSEL = 0x1, 92 R_HPPA_RSSEL = 0x2, 93 R_HPPA_LSEL = 0x3, 94 R_HPPA_RSEL = 0x4, 95 R_HPPA_LDSEL = 0x5, 96 R_HPPA_RDSEL = 0x6, 97 R_HPPA_LRSEL = 0x7, 98 R_HPPA_RRSEL = 0x8, 99 R_HPPA_NSEL = 0x9, 100 R_HPPA_NLSEL = 0xa, 101 R_HPPA_NLRSEL = 0xb, 102 R_HPPA_PSEL = 0xc, 103 R_HPPA_LPSEL = 0xd, 104 R_HPPA_RPSEL = 0xe, 105 R_HPPA_TSEL = 0xf, 106 R_HPPA_LTSEL = 0x10, 107 R_HPPA_RTSEL = 0x11, 108 R_HPPA_LTPSEL = 0x12, 109 R_HPPA_RTPSEL = 0x13 110 }; 111 112 /* /usr/include/reloc.h defines these to constants. We want to use 113 them in enums, so #undef them before we start using them. We might 114 be able to fix this another way by simply managing not to include 115 /usr/include/reloc.h, but currently GDB picks up these defines 116 somewhere. */ 117 #undef e_fsel 118 #undef e_lssel 119 #undef e_rssel 120 #undef e_lsel 121 #undef e_rsel 122 #undef e_ldsel 123 #undef e_rdsel 124 #undef e_lrsel 125 #undef e_rrsel 126 #undef e_nsel 127 #undef e_nlsel 128 #undef e_nlrsel 129 #undef e_psel 130 #undef e_lpsel 131 #undef e_rpsel 132 #undef e_tsel 133 #undef e_ltsel 134 #undef e_rtsel 135 #undef e_one 136 #undef e_two 137 #undef e_pcrel 138 #undef e_con 139 #undef e_plabel 140 #undef e_abs 141 142 /* for compatibility */ 143 enum hppa_reloc_field_selector_type_alt 144 { 145 e_fsel = R_HPPA_FSEL, 146 e_lssel = R_HPPA_LSSEL, 147 e_rssel = R_HPPA_RSSEL, 148 e_lsel = R_HPPA_LSEL, 149 e_rsel = R_HPPA_RSEL, 150 e_ldsel = R_HPPA_LDSEL, 151 e_rdsel = R_HPPA_RDSEL, 152 e_lrsel = R_HPPA_LRSEL, 153 e_rrsel = R_HPPA_RRSEL, 154 e_nsel = R_HPPA_NSEL, 155 e_nlsel = R_HPPA_NLSEL, 156 e_nlrsel = R_HPPA_NLRSEL, 157 e_psel = R_HPPA_PSEL, 158 e_lpsel = R_HPPA_LPSEL, 159 e_rpsel = R_HPPA_RPSEL, 160 e_tsel = R_HPPA_TSEL, 161 e_ltsel = R_HPPA_LTSEL, 162 e_rtsel = R_HPPA_RTSEL, 163 e_ltpsel = R_HPPA_LTPSEL, 164 e_rtpsel = R_HPPA_RTPSEL 165 }; 166 167 enum hppa_reloc_expr_type 168 { 169 R_HPPA_E_ONE = 0, 170 R_HPPA_E_TWO = 1, 171 R_HPPA_E_PCREL = 2, 172 R_HPPA_E_CON = 3, 173 R_HPPA_E_PLABEL = 7, 174 R_HPPA_E_ABS = 18 175 }; 176 177 /* for compatibility */ 178 enum hppa_reloc_expr_type_alt 179 { 180 e_one = R_HPPA_E_ONE, 181 e_two = R_HPPA_E_TWO, 182 e_pcrel = R_HPPA_E_PCREL, 183 e_con = R_HPPA_E_CON, 184 e_plabel = R_HPPA_E_PLABEL, 185 e_abs = R_HPPA_E_ABS 186 }; 187 188 189 /* Relocations for function calls must be accompanied by parameter 190 relocation bits. These bits describe exactly where the caller has 191 placed the function's arguments and where it expects to find a return 192 value. 193 194 Both ELF and SOM encode this information within the addend field 195 of the call relocation. (Note this could break very badly if one 196 was to make a call like bl foo + 0x12345678). 197 198 The high order 10 bits contain parameter relocation information, 199 the low order 22 bits contain the constant offset. */ 200 201 #define HPPA_R_ARG_RELOC(a) (((a) >> 22) & 0x3FF) 202 #define HPPA_R_CONSTANT(a) ((((int)(a)) << 10) >> 10) 203 #define HPPA_R_ADDEND(r,c) (((r) << 22) + ((c) & 0x3FFFFF)) 204 #define HPPA_WIDE (0) /* PSW W-bit, need to check! FIXME */ 205 206 /* These macros get bit fields using HP's numbering (MSB = 0), 207 * but note that "MASK" assumes that the LSB bits are what's 208 * wanted. 209 */ 210 #ifndef GET_FIELD 211 #define GET_FIELD(X, FROM, TO) \ 212 ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1)) 213 #endif 214 #define GET_BIT(X, WHICH) \ 215 GET_FIELD (X, WHICH, WHICH) 216 217 #define MASK(SIZE) \ 218 (~((-1) << SIZE)) 219 220 #define CATENATE(X, XSIZE, Y, YSIZE) \ 221 (((X & MASK (XSIZE)) << YSIZE) | (Y & MASK (YSIZE))) 222 223 #define ELEVEN(X) \ 224 CATENATE (GET_BIT (X, 10), 1, GET_FIELD (X, 0, 9), 10) 225 226 /* Some functions to manipulate PA instructions. */ 227 228 /* NOTE: these use the HP convention that f{1} is the _left_ most 229 * bit (MSB) of f; they sometimes have to impose an assumption 230 * about the size of a field; and as far as I can tell, most 231 * aren't used. 232 */ 233 234 static INLINE unsigned long 235 sign_extend (x, len) 236 unsigned int x, len; 237 { 238 return (int)(x >> (len - 1) ? (-1 << len) | x : x); 239 } 240 241 static INLINE unsigned int 242 assemble_3 (x) 243 unsigned int x; 244 { 245 return CATENATE (GET_BIT (x, 2), 1, GET_FIELD (x, 0, 1), 2); 246 } 247 248 static INLINE void 249 dis_assemble_3 (x, r) 250 unsigned int x; 251 unsigned int *r; 252 { 253 *r = (((x & 4) >> 2) | ((x & 3) << 1)) & 7; 254 } 255 256 static INLINE unsigned int 257 assemble_6 (x, y) 258 unsigned int x, y; 259 { 260 return (((x & 0x1) << 5) + (32 - (y & 0x1f))); 261 } 262 263 static INLINE unsigned int 264 assemble_12 (x, y) 265 unsigned int x, y; 266 { 267 return CATENATE (CATENATE (y, 1, GET_BIT (x, 10), 1), 2, 268 GET_FIELD (x, 0, 9), 9); 269 } 270 271 static INLINE void 272 dis_assemble_12 (as12, x, y) 273 unsigned int as12; 274 unsigned int *x, *y; 275 { 276 *y = (as12 & 0x800) >> 11; 277 *x = ((as12 & 0x3ff) << 1) | ((as12 & 0x400) >> 10); 278 } 279 280 static INLINE unsigned long 281 assemble_16 (x, y) 282 unsigned int x, y; 283 { 284 /* Depends on PSW W-bit !*/ 285 unsigned int temp; 286 287 if (HPPA_WIDE) 288 temp = CATENATE (CATENATE (GET_BIT (y, 13), 1, 289 (GET_BIT (y, 13) ^ GET_BIT (x, 0)), 1), 2, 290 CATENATE ((GET_BIT (y, 13) ^ GET_BIT (x, 1)), 1, 291 GET_FIELD (y, 0, 12), 13), 14); 292 else 293 temp = CATENATE (CATENATE (GET_BIT (y, 13), 1, GET_BIT (y, 13), 1), 2, 294 CATENATE (GET_BIT (y, 13), 1, GET_FIELD (y, 0, 12), 13), 14); 295 296 return sign_extend (temp, 16); 297 } 298 299 300 static INLINE unsigned long 301 assemble_16a (x, y, z) 302 unsigned int x, y, z; 303 { 304 /* Depends on PSW W-bit !*/ 305 unsigned int temp; 306 307 if (HPPA_WIDE) 308 temp = CATENATE (CATENATE (z, 1, (z ^ GET_BIT (x, 0)), 1), 2, 309 CATENATE ((z ^ GET_BIT (x, 1)), 1, y, 11), 12); 310 else 311 temp = CATENATE (CATENATE (z, 1, z, 1), 2, CATENATE (z, 1, y, 11), 12); 312 313 return sign_extend ((temp << 2), 16); 314 } 315 316 static INLINE unsigned long 317 assemble_17 (x, y, z) 318 unsigned int x, y, z; 319 { 320 unsigned long temp; 321 322 temp = CATENATE (CATENATE (z, 1, x, 5), 6, 323 CATENATE (GET_BIT (y, 10), 1, GET_FIELD (y, 0, 9), 10), 11); 324 325 return temp; 326 } 327 328 static INLINE void 329 dis_assemble_17 (as17, x, y, z) 330 unsigned int as17; 331 unsigned int *x, *y, *z; 332 { 333 334 *z = (as17 & 0x10000) >> 16; 335 *x = (as17 & 0x0f800) >> 11; 336 *y = (((as17 & 0x00400) >> 10) | ((as17 & 0x3ff) << 1)) & 0x7ff; 337 } 338 339 static INLINE void 340 dis_assemble_22 (as22, a, b, c, d) 341 unsigned int as22; 342 unsigned int *a, *b, *c, *d; 343 { 344 345 *d = (as22 & 0x200000) >> 21; 346 *a = (as22 & 0x1f0000) >> 16; 347 *b = (as22 & 0x0f800) >> 11; 348 *c = (((as22 & 0x00400) >> 10) | ((as22 & 0x3ff) << 1)) & 0x7ff; 349 } 350 351 static INLINE unsigned long 352 assemble_21 (x) 353 unsigned int x; 354 { 355 unsigned long temp; 356 357 temp = ((x & 1) << 20) | 358 ((x & 0xffe) << 8) | 359 ((x & 0xc000) >> 7) | 360 ((x & 0x1f0000) >> 14) | 361 ((x & 0x003000) >> 12); 362 return temp & 0x1fffff; 363 } 364 365 static INLINE unsigned long 366 assemble_22 (a,b,c,d) 367 unsigned int a,b,c,d; 368 { 369 unsigned long temp; 370 371 temp = CATENATE (CATENATE (d, 1, a, 5), 6, 372 CATENATE (b, 5, ELEVEN (c), 11), 16); 373 374 return sign_extend (temp, 22); 375 } 376 377 static INLINE void 378 dis_assemble_21 (as21, x) 379 unsigned int as21, *x; 380 { 381 unsigned long temp; 382 383 384 temp = (as21 & 0x100000) >> 20; 385 temp |= (as21 & 0x0ffe00) >> 8; 386 temp |= (as21 & 0x000180) << 7; 387 temp |= (as21 & 0x00007c) << 14; 388 temp |= (as21 & 0x000003) << 12; 389 *x = temp; 390 } 391 392 static INLINE unsigned int 393 ones (n) 394 int n; 395 { 396 unsigned int len_ones; 397 int i; 398 399 i = 0; 400 len_ones = 0; 401 while (i < n) 402 { 403 len_ones = (len_ones << 1) | 1; 404 i++; 405 } 406 407 return len_ones; 408 } 409 410 static INLINE void 411 sign_unext (x, len, result) 412 unsigned int x, len; 413 unsigned int *result; 414 { 415 unsigned int len_ones; 416 417 len_ones = ones (len); 418 419 *result = x & len_ones; 420 } 421 422 static INLINE unsigned long 423 low_sign_extend (x, len) 424 unsigned int x, len; 425 { 426 return (int)((x & 0x1 ? (-1 << (len - 1)) : 0) | x >> 1); 427 } 428 429 static INLINE void 430 low_sign_unext (x, len, result) 431 unsigned int x, len; 432 unsigned int *result; 433 { 434 unsigned int temp; 435 unsigned int sign; 436 unsigned int rest; 437 unsigned int one_bit_at_len; 438 unsigned int len_ones; 439 440 len_ones = ones (len); 441 one_bit_at_len = 1 << (len - 1); 442 443 sign_unext (x, len, &temp); 444 sign = temp & one_bit_at_len; 445 sign >>= (len - 1); 446 447 rest = temp & (len_ones ^ one_bit_at_len); 448 rest <<= 1; 449 450 *result = rest | sign; 451 } 452 453 /* Handle field selectors for PA instructions. */ 454 455 static INLINE unsigned long 456 hppa_field_adjust (value, constant_value, r_field) 457 unsigned long value; 458 unsigned long constant_value; 459 unsigned short r_field; 460 { 461 switch (r_field) 462 { 463 case e_fsel: /* F : no change */ 464 case e_nsel: /* N : no change */ 465 value += constant_value; 466 break; 467 468 case e_lssel: /* LS : if (bit 21) then add 0x800 469 arithmetic shift right 11 bits */ 470 value += constant_value; 471 if (value & 0x00000400) 472 value += 0x800; 473 value = (value & 0xfffff800) >> 11; 474 break; 475 476 case e_rssel: /* RS : Sign extend from bit 21 */ 477 value += constant_value; 478 if (value & 0x00000400) 479 value |= 0xfffff800; 480 else 481 value &= 0x7ff; 482 break; 483 484 case e_lsel: /* L : Arithmetic shift right 11 bits */ 485 case e_nlsel: /* NL : Arithmetic shift right 11 bits */ 486 value += constant_value; 487 value = (value & 0xfffff800) >> 11; 488 break; 489 490 case e_rsel: /* R : Set bits 0-20 to zero */ 491 value += constant_value; 492 value = value & 0x7ff; 493 break; 494 495 case e_ldsel: /* LD : Add 0x800, arithmetic shift 496 right 11 bits */ 497 value += constant_value; 498 value += 0x800; 499 value = (value & 0xfffff800) >> 11; 500 break; 501 502 case e_rdsel: /* RD : Set bits 0-20 to one */ 503 value += constant_value; 504 value |= 0xfffff800; 505 break; 506 507 case e_lrsel: /* LR : L with "rounded" constant */ 508 case e_nlrsel: /* NLR : NL with "rounded" constant */ 509 value = value + ((constant_value + 0x1000) & 0xffffe000); 510 value = (value & 0xfffff800) >> 11; 511 break; 512 513 case e_rrsel: /* RR : R with "rounded" constant */ 514 value = value + ((constant_value + 0x1000) & 0xffffe000); 515 value = (value & 0x7ff) + constant_value - ((constant_value + 0x1000) & 0xffffe000); 516 break; 517 518 default: 519 abort (); 520 } 521 return value; 522 523 } 524 525 /* PA-RISC OPCODES */ 526 #define get_opcode(insn) ((insn) & 0xfc000000) >> 26 527 528 /* FIXME: this list is incomplete. It should also be an enumerated 529 type rather than #defines. */ 530 531 #define LDO 0x0d 532 #define LDB 0x10 533 #define LDH 0x11 534 #define LDW 0x12 535 #define LDWM 0x13 536 #define STB 0x18 537 #define STH 0x19 538 #define STW 0x1a 539 #define STWM 0x1b 540 #define COMICLR 0x24 541 #define SUBI 0x25 542 #define SUBIO 0x25 543 #define ADDIT 0x2c 544 #define ADDITO 0x2c 545 #define ADDI 0x2d 546 #define ADDIO 0x2d 547 #define LDIL 0x08 548 #define ADDIL 0x0a 549 550 #define MOVB 0x32 551 #define MOVIB 0x33 552 #define COMBT 0x20 553 #define COMBF 0x22 554 #define COMIBT 0x21 555 #define COMIBF 0x23 556 #define ADDBT 0x28 557 #define ADDBF 0x2a 558 #define ADDIBT 0x29 559 #define ADDIBF 0x2b 560 #define BVB 0x30 561 #define BB 0x31 562 563 #define BL 0x3a 564 #define BLE 0x39 565 #define BE 0x38 566 567 #define CMPBDT 0x27 568 #define CMPBDF 0x2f 569 #define CMPIBD 0x3b 570 #define LDD 0x14 571 #define STD 0x1c 572 #define LDWL 0x17 573 #define STWL 0x1f 574 #define FDLW 0x16 575 #define FSTW 0x1e 576 577 /* Given a machine instruction, return its format. 578 579 FIXME: opcodes which do not map to a known format 580 should return an error of some sort. */ 581 582 static INLINE int 583 bfd_hppa_insn2fmt (insn) 584 unsigned long insn; 585 { 586 int fmt = -1; 587 unsigned char op = get_opcode (insn); 588 589 switch (op) 590 { 591 case ADDI: 592 case ADDIT: 593 case SUBI: 594 fmt = 11; 595 break; 596 case MOVB: 597 case MOVIB: 598 case COMBT: 599 case COMBF: 600 case COMIBT: 601 case COMIBF: 602 case ADDBT: 603 case ADDBF: 604 case ADDIBT: 605 case ADDIBF: 606 case BVB: 607 case BB: 608 case CMPBDT: 609 case CMPBDF: 610 case CMPIBD: 611 fmt = 12; 612 break; 613 case LDO: 614 case LDB: 615 case LDH: 616 case LDW: 617 case LDWM: 618 case STB: 619 case STH: 620 case STW: 621 case STWM: 622 fmt = 14; 623 break; 624 case LDWL: 625 case STWL: 626 case FDLW: 627 case FSTW: 628 /* This is a hack. Unfortunately, format 11 is already taken 629 and we're using integers rather than an enum, so it's hard 630 to describe the 10a format. */ 631 fmt = -11; 632 break; 633 case LDD: 634 case STD: 635 fmt = 10; 636 break; 637 case BL: 638 case BE: 639 case BLE: 640 if ((insn & 0x00008000) == 0x00008000) 641 return 22; 642 fmt = 17; 643 break; 644 case LDIL: 645 case ADDIL: 646 fmt = 21; 647 break; 648 default: 649 fmt = 32; 650 break; 651 } 652 return fmt; 653 } 654 655 656 /* Insert VALUE into INSN using R_FORMAT to determine exactly what 657 bits to change. */ 658 659 static INLINE unsigned long 660 hppa_rebuild_insn (abfd, insn, value, r_format) 661 bfd *abfd ATTRIBUTE_UNUSED; 662 unsigned long insn; 663 unsigned long value; 664 unsigned long r_format; 665 { 666 unsigned long const_part; 667 unsigned long rebuilt_part; 668 669 switch (r_format) 670 { 671 case 11: 672 { 673 unsigned w1, w; 674 675 const_part = insn & 0xffffe002; 676 dis_assemble_12 (value, &w1, &w); 677 rebuilt_part = (w1 << 2) | w; 678 return const_part | rebuilt_part; 679 } 680 681 case 12: 682 { 683 unsigned w1, w; 684 685 const_part = insn & 0xffffe002; 686 dis_assemble_12 (value, &w1, &w); 687 rebuilt_part = (w1 << 2) | w; 688 return const_part | rebuilt_part; 689 } 690 691 case 14: 692 { 693 unsigned int ext; 694 695 const_part = insn & 0xffffc000; 696 low_sign_unext (value, 14, &ext); 697 return const_part | ext; 698 } 699 700 case 17: 701 { 702 unsigned w1, w2, w; 703 704 const_part = insn & 0xffe0e002; 705 dis_assemble_17 (value, &w1, &w2, &w); 706 rebuilt_part = (w2 << 2) | (w1 << 16) | w; 707 return const_part | rebuilt_part; 708 } 709 710 case 21: 711 { 712 unsigned int w; 713 714 const_part = insn & 0xffe00000; 715 dis_assemble_21 (value, &w); 716 return const_part | w; 717 } 718 719 case 32: 720 const_part = 0; 721 return value; 722 723 default: 724 abort (); 725 } 726 return insn; 727 } 728 729 #endif /* _HPPA_H */ 730