libhppa.h revision 1.4
1/* 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. */ 39enum pa_arch {pa10 = 10, pa11 = 11, pa20 = 20, pa20w = 25}; 40 41/* HP PA-RISC relocation types */ 42 43enum 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 */ 98enum 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 122enum 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 */ 133enum 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. */ 167static INLINE int sign_extend PARAMS ((int, int)) ATTRIBUTE_UNUSED; 168static INLINE int low_sign_extend PARAMS ((int, int)) ATTRIBUTE_UNUSED; 169static INLINE int sign_unext PARAMS ((int, int)) ATTRIBUTE_UNUSED; 170static INLINE int low_sign_unext PARAMS ((int, int)) ATTRIBUTE_UNUSED; 171static INLINE int re_assemble_3 PARAMS ((int)) ATTRIBUTE_UNUSED; 172static INLINE int re_assemble_12 PARAMS ((int)) ATTRIBUTE_UNUSED; 173static INLINE int re_assemble_14 PARAMS ((int)) ATTRIBUTE_UNUSED; 174static INLINE int re_assemble_16 PARAMS ((int)) ATTRIBUTE_UNUSED; 175static INLINE int re_assemble_17 PARAMS ((int)) ATTRIBUTE_UNUSED; 176static INLINE int re_assemble_21 PARAMS ((int)) ATTRIBUTE_UNUSED; 177static INLINE int re_assemble_22 PARAMS ((int)) ATTRIBUTE_UNUSED; 178static INLINE bfd_signed_vma hppa_field_adjust 179 PARAMS ((bfd_vma, bfd_signed_vma, 180 enum hppa_reloc_field_selector_type_alt)) ATTRIBUTE_UNUSED; 181static INLINE int bfd_hppa_insn2fmt PARAMS ((bfd *, int)) ATTRIBUTE_UNUSED; 182static 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 189static INLINE int 190sign_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 198static INLINE int 199low_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 210static INLINE int 211sign_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 221static INLINE int 222low_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 235static INLINE int 236re_assemble_3 (as3) 237 int as3; 238{ 239 return (( (as3 & 4) << (13-2)) 240 | ((as3 & 3) << (13+1))); 241} 242 243static INLINE int 244re_assemble_12 (as12) 245 int as12; 246{ 247 return (( (as12 & 0x800) >> 11) 248 | ((as12 & 0x400) >> (10 - 2)) 249 | ((as12 & 0x3ff) << (1 + 2))); 250} 251 252static INLINE int 253re_assemble_14 (as14) 254 int as14; 255{ 256 return (( (as14 & 0x1fff) << 1) 257 | ((as14 & 0x2000) >> 13)); 258} 259 260static INLINE int 261re_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 272static INLINE int 273re_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 282static INLINE int 283re_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 293static INLINE int 294re_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 315static INLINE bfd_signed_vma 316hppa_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 402enum 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 482static INLINE int 483bfd_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 566static INLINE int 567hppa_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 */ 620