1 1.1 christos /* tc-ia64.c -- Assembler for the HP/Intel IA-64 architecture. 2 1.10 christos Copyright (C) 1998-2025 Free Software Foundation, Inc. 3 1.1 christos Contributed by David Mosberger-Tang <davidm (at) hpl.hp.com> 4 1.1 christos 5 1.1 christos This file is part of GAS, the GNU Assembler. 6 1.1 christos 7 1.1 christos GAS is free software; you can redistribute it and/or modify 8 1.1 christos it under the terms of the GNU General Public License as published by 9 1.1 christos the Free Software Foundation; either version 3, or (at your option) 10 1.1 christos any later version. 11 1.1 christos 12 1.1 christos GAS is distributed in the hope that it will be useful, 13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 1.1 christos GNU General Public License for more details. 16 1.1 christos 17 1.1 christos You should have received a copy of the GNU General Public License 18 1.1 christos along with GAS; see the file COPYING. If not, write to 19 1.1 christos the Free Software Foundation, 51 Franklin Street - Fifth Floor, 20 1.1 christos Boston, MA 02110-1301, USA. */ 21 1.1 christos 22 1.1 christos /* 23 1.1 christos TODO: 24 1.1 christos 25 1.1 christos - optional operands 26 1.1 christos - directives: 27 1.1 christos .eb 28 1.1 christos .estate 29 1.1 christos .lb 30 1.1 christos .popsection 31 1.1 christos .previous 32 1.1 christos .psr 33 1.1 christos .pushsection 34 1.1 christos - labels are wrong if automatic alignment is introduced 35 1.1 christos (e.g., checkout the second real10 definition in test-data.s) 36 1.1 christos - DV-related stuff: 37 1.1 christos <reg>.safe_across_calls and any other DV-related directives I don't 38 1.1 christos have documentation for. 39 1.1 christos verify mod-sched-brs reads/writes are checked/marked (and other 40 1.1 christos notes) 41 1.1 christos 42 1.1 christos */ 43 1.1 christos 44 1.1 christos #include "as.h" 45 1.1 christos #include "safe-ctype.h" 46 1.1 christos #include "dwarf2dbg.h" 47 1.1 christos #include "subsegs.h" 48 1.1 christos 49 1.1 christos #include "opcode/ia64.h" 50 1.1 christos 51 1.1 christos #include "elf/ia64.h" 52 1.1 christos #include "bfdver.h" 53 1.1 christos #include <time.h> 54 1.1 christos #include <limits.h> 55 1.1 christos 56 1.1 christos #define NELEMS(a) ((int) (sizeof (a)/sizeof ((a)[0]))) 57 1.1 christos 58 1.1 christos /* Some systems define MIN in, e.g., param.h. */ 59 1.1 christos #undef MIN 60 1.1 christos #define MIN(a,b) ((a) < (b) ? (a) : (b)) 61 1.1 christos 62 1.1 christos #define NUM_SLOTS 4 63 1.1 christos #define PREV_SLOT md.slot[(md.curr_slot + NUM_SLOTS - 1) % NUM_SLOTS] 64 1.1 christos #define CURR_SLOT md.slot[md.curr_slot] 65 1.1 christos 66 1.1 christos #define O_pseudo_fixup (O_max + 1) 67 1.1 christos 68 1.1 christos enum special_section 69 1.1 christos { 70 1.1 christos /* IA-64 ABI section pseudo-ops. */ 71 1.9 christos SPECIAL_SECTION_SBSS = 0, 72 1.1 christos SPECIAL_SECTION_SDATA, 73 1.1 christos SPECIAL_SECTION_RODATA, 74 1.1 christos SPECIAL_SECTION_COMMENT, 75 1.1 christos SPECIAL_SECTION_UNWIND, 76 1.1 christos SPECIAL_SECTION_UNWIND_INFO, 77 1.1 christos /* HPUX specific section pseudo-ops. */ 78 1.1 christos SPECIAL_SECTION_INIT_ARRAY, 79 1.1 christos SPECIAL_SECTION_FINI_ARRAY, 80 1.1 christos }; 81 1.1 christos 82 1.1 christos enum reloc_func 83 1.1 christos { 84 1.1 christos FUNC_DTP_MODULE, 85 1.1 christos FUNC_DTP_RELATIVE, 86 1.1 christos FUNC_FPTR_RELATIVE, 87 1.1 christos FUNC_GP_RELATIVE, 88 1.1 christos FUNC_LT_RELATIVE, 89 1.1 christos FUNC_LT_RELATIVE_X, 90 1.1 christos FUNC_PC_RELATIVE, 91 1.1 christos FUNC_PLT_RELATIVE, 92 1.1 christos FUNC_SEC_RELATIVE, 93 1.1 christos FUNC_SEG_RELATIVE, 94 1.1 christos FUNC_TP_RELATIVE, 95 1.1 christos FUNC_LTV_RELATIVE, 96 1.1 christos FUNC_LT_FPTR_RELATIVE, 97 1.1 christos FUNC_LT_DTP_MODULE, 98 1.1 christos FUNC_LT_DTP_RELATIVE, 99 1.1 christos FUNC_LT_TP_RELATIVE, 100 1.1 christos FUNC_IPLT_RELOC, 101 1.1 christos #ifdef TE_VMS 102 1.1 christos FUNC_SLOTCOUNT_RELOC, 103 1.1 christos #endif 104 1.1 christos }; 105 1.1 christos 106 1.1 christos enum reg_symbol 107 1.1 christos { 108 1.1 christos REG_GR = 0, 109 1.1 christos REG_FR = (REG_GR + 128), 110 1.1 christos REG_AR = (REG_FR + 128), 111 1.1 christos REG_CR = (REG_AR + 128), 112 1.1 christos REG_DAHR = (REG_CR + 128), 113 1.1 christos REG_P = (REG_DAHR + 8), 114 1.1 christos REG_BR = (REG_P + 64), 115 1.1 christos REG_IP = (REG_BR + 8), 116 1.1 christos REG_CFM, 117 1.1 christos REG_PR, 118 1.1 christos REG_PR_ROT, 119 1.1 christos REG_PSR, 120 1.1 christos REG_PSR_L, 121 1.1 christos REG_PSR_UM, 122 1.1 christos /* The following are pseudo-registers for use by gas only. */ 123 1.1 christos IND_CPUID, 124 1.1 christos IND_DBR, 125 1.1 christos IND_DTR, 126 1.1 christos IND_ITR, 127 1.1 christos IND_IBR, 128 1.1 christos IND_MSR, 129 1.1 christos IND_PKR, 130 1.1 christos IND_PMC, 131 1.1 christos IND_PMD, 132 1.1 christos IND_DAHR, 133 1.1 christos IND_RR, 134 1.1 christos /* The following pseudo-registers are used for unwind directives only: */ 135 1.1 christos REG_PSP, 136 1.1 christos REG_PRIUNAT, 137 1.1 christos REG_NUM 138 1.1 christos }; 139 1.1 christos 140 1.1 christos enum dynreg_type 141 1.1 christos { 142 1.1 christos DYNREG_GR = 0, /* dynamic general purpose register */ 143 1.1 christos DYNREG_FR, /* dynamic floating point register */ 144 1.1 christos DYNREG_PR, /* dynamic predicate register */ 145 1.1 christos DYNREG_NUM_TYPES 146 1.1 christos }; 147 1.1 christos 148 1.1 christos enum operand_match_result 149 1.1 christos { 150 1.1 christos OPERAND_MATCH, 151 1.1 christos OPERAND_OUT_OF_RANGE, 152 1.1 christos OPERAND_MISMATCH 153 1.1 christos }; 154 1.1 christos 155 1.1 christos /* On the ia64, we can't know the address of a text label until the 156 1.1 christos instructions are packed into a bundle. To handle this, we keep 157 1.1 christos track of the list of labels that appear in front of each 158 1.1 christos instruction. */ 159 1.1 christos struct label_fix 160 1.1 christos { 161 1.1 christos struct label_fix *next; 162 1.1 christos struct symbol *sym; 163 1.8 christos bool dw2_mark_labels; 164 1.1 christos }; 165 1.1 christos 166 1.1 christos #ifdef TE_VMS 167 1.1 christos /* An internally used relocation. */ 168 1.1 christos #define DUMMY_RELOC_IA64_SLOTCOUNT (BFD_RELOC_UNUSED + 1) 169 1.1 christos #endif 170 1.1 christos 171 1.1 christos /* This is the endianness of the current section. */ 172 1.1 christos extern int target_big_endian; 173 1.1 christos 174 1.1 christos /* This is the default endianness. */ 175 1.1 christos static int default_big_endian = TARGET_BYTES_BIG_ENDIAN; 176 1.1 christos 177 1.1 christos void (*ia64_number_to_chars) (char *, valueT, int); 178 1.1 christos 179 1.1 christos static void ia64_float_to_chars_bigendian (char *, LITTLENUM_TYPE *, int); 180 1.1 christos static void ia64_float_to_chars_littleendian (char *, LITTLENUM_TYPE *, int); 181 1.1 christos 182 1.1 christos static void (*ia64_float_to_chars) (char *, LITTLENUM_TYPE *, int); 183 1.1 christos 184 1.8 christos static htab_t alias_hash; 185 1.8 christos static htab_t alias_name_hash; 186 1.8 christos static htab_t secalias_hash; 187 1.8 christos static htab_t secalias_name_hash; 188 1.1 christos 189 1.1 christos /* List of chars besides those in app.c:symbol_chars that can start an 190 1.1 christos operand. Used to prevent the scrubber eating vital white-space. */ 191 1.1 christos const char ia64_symbol_chars[] = "@?"; 192 1.1 christos 193 1.1 christos /* Characters which always start a comment. */ 194 1.1 christos const char comment_chars[] = ""; 195 1.1 christos 196 1.1 christos /* Characters which start a comment at the beginning of a line. */ 197 1.1 christos const char line_comment_chars[] = "#"; 198 1.1 christos 199 1.1 christos /* Characters which may be used to separate multiple commands on a 200 1.1 christos single line. */ 201 1.1 christos const char line_separator_chars[] = ";{}"; 202 1.1 christos 203 1.1 christos /* Characters which are used to indicate an exponent in a floating 204 1.1 christos point number. */ 205 1.1 christos const char EXP_CHARS[] = "eE"; 206 1.1 christos 207 1.1 christos /* Characters which mean that a number is a floating point constant, 208 1.1 christos as in 0d1.0. */ 209 1.1 christos const char FLT_CHARS[] = "rRsSfFdDxXpP"; 210 1.1 christos 211 1.1 christos /* ia64-specific option processing: */ 212 1.1 christos 213 1.10 christos const char md_shortopts[] = "m:N:x::"; 214 1.1 christos 215 1.10 christos const struct option md_longopts[] = 216 1.1 christos { 217 1.1 christos #define OPTION_MCONSTANT_GP (OPTION_MD_BASE + 1) 218 1.1 christos {"mconstant-gp", no_argument, NULL, OPTION_MCONSTANT_GP}, 219 1.1 christos #define OPTION_MAUTO_PIC (OPTION_MD_BASE + 2) 220 1.1 christos {"mauto-pic", no_argument, NULL, OPTION_MAUTO_PIC} 221 1.1 christos }; 222 1.1 christos 223 1.10 christos const size_t md_longopts_size = sizeof (md_longopts); 224 1.1 christos 225 1.1 christos static struct 226 1.1 christos { 227 1.8 christos htab_t pseudo_hash; /* pseudo opcode hash table */ 228 1.8 christos htab_t reg_hash; /* register name hash table */ 229 1.8 christos htab_t dynreg_hash; /* dynamic register hash table */ 230 1.8 christos htab_t const_hash; /* constant hash table */ 231 1.8 christos htab_t entry_hash; /* code entry hint hash table */ 232 1.1 christos 233 1.6 christos /* If X_op is != O_absent, the register name for the instruction's 234 1.1 christos qualifying predicate. If NULL, p0 is assumed for instructions 235 1.1 christos that are predictable. */ 236 1.1 christos expressionS qp; 237 1.1 christos 238 1.1 christos /* Optimize for which CPU. */ 239 1.1 christos enum 240 1.1 christos { 241 1.1 christos itanium1, 242 1.1 christos itanium2 243 1.1 christos } tune; 244 1.1 christos 245 1.1 christos /* What to do when hint.b is used. */ 246 1.1 christos enum 247 1.1 christos { 248 1.1 christos hint_b_error, 249 1.1 christos hint_b_warning, 250 1.1 christos hint_b_ok 251 1.1 christos } hint_b; 252 1.1 christos 253 1.1 christos unsigned int 254 1.1 christos manual_bundling : 1, 255 1.1 christos debug_dv: 1, 256 1.1 christos detect_dv: 1, 257 1.1 christos explicit_mode : 1, /* which mode we're in */ 258 1.1 christos default_explicit_mode : 1, /* which mode is the default */ 259 1.1 christos mode_explicitly_set : 1, /* was the current mode explicitly set? */ 260 1.1 christos auto_align : 1, 261 1.1 christos keep_pending_output : 1; 262 1.1 christos 263 1.1 christos /* What to do when something is wrong with unwind directives. */ 264 1.1 christos enum 265 1.1 christos { 266 1.1 christos unwind_check_warning, 267 1.1 christos unwind_check_error 268 1.1 christos } unwind_check; 269 1.1 christos 270 1.1 christos /* Each bundle consists of up to three instructions. We keep 271 1.1 christos track of four most recent instructions so we can correctly set 272 1.1 christos the end_of_insn_group for the last instruction in a bundle. */ 273 1.1 christos int curr_slot; 274 1.1 christos int num_slots_in_use; 275 1.1 christos struct slot 276 1.1 christos { 277 1.1 christos unsigned int 278 1.1 christos end_of_insn_group : 1, 279 1.1 christos manual_bundling_on : 1, 280 1.1 christos manual_bundling_off : 1, 281 1.1 christos loc_directive_seen : 1; 282 1.1 christos signed char user_template; /* user-selected template, if any */ 283 1.1 christos unsigned char qp_regno; /* qualifying predicate */ 284 1.1 christos /* This duplicates a good fraction of "struct fix" but we 285 1.1 christos can't use a "struct fix" instead since we can't call 286 1.1 christos fix_new_exp() until we know the address of the instruction. */ 287 1.1 christos int num_fixups; 288 1.1 christos struct insn_fix 289 1.1 christos { 290 1.1 christos bfd_reloc_code_real_type code; 291 1.1 christos enum ia64_opnd opnd; /* type of operand in need of fix */ 292 1.1 christos unsigned int is_pcrel : 1; /* is operand pc-relative? */ 293 1.1 christos expressionS expr; /* the value to be inserted */ 294 1.1 christos } 295 1.1 christos fixup[2]; /* at most two fixups per insn */ 296 1.1 christos struct ia64_opcode *idesc; 297 1.1 christos struct label_fix *label_fixups; 298 1.1 christos struct label_fix *tag_fixups; 299 1.1 christos struct unw_rec_list *unwind_record; /* Unwind directive. */ 300 1.1 christos expressionS opnd[6]; 301 1.5 christos const char *src_file; 302 1.1 christos unsigned int src_line; 303 1.1 christos struct dwarf2_line_info debug_line; 304 1.1 christos } 305 1.1 christos slot[NUM_SLOTS]; 306 1.1 christos 307 1.1 christos segT last_text_seg; 308 1.8 christos subsegT last_text_subseg; 309 1.1 christos 310 1.1 christos struct dynreg 311 1.1 christos { 312 1.1 christos struct dynreg *next; /* next dynamic register */ 313 1.1 christos const char *name; 314 1.1 christos unsigned short base; /* the base register number */ 315 1.1 christos unsigned short num_regs; /* # of registers in this set */ 316 1.1 christos } 317 1.1 christos *dynreg[DYNREG_NUM_TYPES], in, loc, out, rot; 318 1.1 christos 319 1.1 christos flagword flags; /* ELF-header flags */ 320 1.1 christos 321 1.1 christos struct mem_offset { 322 1.1 christos unsigned hint:1; /* is this hint currently valid? */ 323 1.1 christos bfd_vma offset; /* mem.offset offset */ 324 1.1 christos bfd_vma base; /* mem.offset base */ 325 1.1 christos } mem_offset; 326 1.1 christos 327 1.1 christos int path; /* number of alt. entry points seen */ 328 1.1 christos const char **entry_labels; /* labels of all alternate paths in 329 1.1 christos the current DV-checking block. */ 330 1.1 christos int maxpaths; /* size currently allocated for 331 1.1 christos entry_labels */ 332 1.1 christos 333 1.1 christos int pointer_size; /* size in bytes of a pointer */ 334 1.1 christos int pointer_size_shift; /* shift size of a pointer for alignment */ 335 1.1 christos 336 1.1 christos symbolS *indregsym[IND_RR - IND_CPUID + 1]; 337 1.1 christos } 338 1.1 christos md; 339 1.1 christos 340 1.1 christos /* These are not const, because they are modified to MMI for non-itanium1 341 1.1 christos targets below. */ 342 1.1 christos /* MFI bundle of nops. */ 343 1.1 christos static unsigned char le_nop[16] = 344 1.1 christos { 345 1.1 christos 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 346 1.1 christos 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00 347 1.1 christos }; 348 1.1 christos /* MFI bundle of nops with stop-bit. */ 349 1.1 christos static unsigned char le_nop_stop[16] = 350 1.1 christos { 351 1.1 christos 0x0d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 352 1.1 christos 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00 353 1.1 christos }; 354 1.1 christos 355 1.1 christos /* application registers: */ 356 1.1 christos 357 1.1 christos #define AR_K0 0 358 1.1 christos #define AR_K7 7 359 1.1 christos #define AR_RSC 16 360 1.1 christos #define AR_BSP 17 361 1.1 christos #define AR_BSPSTORE 18 362 1.1 christos #define AR_RNAT 19 363 1.1 christos #define AR_FCR 21 364 1.1 christos #define AR_EFLAG 24 365 1.1 christos #define AR_CSD 25 366 1.1 christos #define AR_SSD 26 367 1.1 christos #define AR_CFLG 27 368 1.1 christos #define AR_FSR 28 369 1.1 christos #define AR_FIR 29 370 1.1 christos #define AR_FDR 30 371 1.1 christos #define AR_CCV 32 372 1.1 christos #define AR_UNAT 36 373 1.1 christos #define AR_FPSR 40 374 1.1 christos #define AR_ITC 44 375 1.1 christos #define AR_RUC 45 376 1.1 christos #define AR_PFS 64 377 1.1 christos #define AR_LC 65 378 1.1 christos #define AR_EC 66 379 1.1 christos 380 1.1 christos static const struct 381 1.1 christos { 382 1.1 christos const char *name; 383 1.1 christos unsigned int regnum; 384 1.1 christos } 385 1.1 christos ar[] = 386 1.1 christos { 387 1.1 christos {"ar.k0", AR_K0}, {"ar.k1", AR_K0 + 1}, 388 1.1 christos {"ar.k2", AR_K0 + 2}, {"ar.k3", AR_K0 + 3}, 389 1.1 christos {"ar.k4", AR_K0 + 4}, {"ar.k5", AR_K0 + 5}, 390 1.1 christos {"ar.k6", AR_K0 + 6}, {"ar.k7", AR_K7}, 391 1.1 christos {"ar.rsc", AR_RSC}, {"ar.bsp", AR_BSP}, 392 1.1 christos {"ar.bspstore", AR_BSPSTORE}, {"ar.rnat", AR_RNAT}, 393 1.1 christos {"ar.fcr", AR_FCR}, {"ar.eflag", AR_EFLAG}, 394 1.1 christos {"ar.csd", AR_CSD}, {"ar.ssd", AR_SSD}, 395 1.1 christos {"ar.cflg", AR_CFLG}, {"ar.fsr", AR_FSR}, 396 1.1 christos {"ar.fir", AR_FIR}, {"ar.fdr", AR_FDR}, 397 1.1 christos {"ar.ccv", AR_CCV}, {"ar.unat", AR_UNAT}, 398 1.1 christos {"ar.fpsr", AR_FPSR}, {"ar.itc", AR_ITC}, 399 1.1 christos {"ar.ruc", AR_RUC}, {"ar.pfs", AR_PFS}, 400 1.1 christos {"ar.lc", AR_LC}, {"ar.ec", AR_EC}, 401 1.1 christos }; 402 1.1 christos 403 1.1 christos /* control registers: */ 404 1.1 christos 405 1.1 christos #define CR_DCR 0 406 1.1 christos #define CR_ITM 1 407 1.1 christos #define CR_IVA 2 408 1.1 christos #define CR_PTA 8 409 1.1 christos #define CR_GPTA 9 410 1.1 christos #define CR_IPSR 16 411 1.1 christos #define CR_ISR 17 412 1.1 christos #define CR_IIP 19 413 1.1 christos #define CR_IFA 20 414 1.1 christos #define CR_ITIR 21 415 1.1 christos #define CR_IIPA 22 416 1.1 christos #define CR_IFS 23 417 1.1 christos #define CR_IIM 24 418 1.1 christos #define CR_IHA 25 419 1.1 christos #define CR_IIB0 26 420 1.1 christos #define CR_IIB1 27 421 1.1 christos #define CR_LID 64 422 1.1 christos #define CR_IVR 65 423 1.1 christos #define CR_TPR 66 424 1.1 christos #define CR_EOI 67 425 1.1 christos #define CR_IRR0 68 426 1.1 christos #define CR_IRR3 71 427 1.1 christos #define CR_ITV 72 428 1.1 christos #define CR_PMV 73 429 1.1 christos #define CR_CMCV 74 430 1.1 christos #define CR_LRR0 80 431 1.1 christos #define CR_LRR1 81 432 1.1 christos 433 1.1 christos static const struct 434 1.1 christos { 435 1.1 christos const char *name; 436 1.1 christos unsigned int regnum; 437 1.1 christos } 438 1.1 christos cr[] = 439 1.1 christos { 440 1.1 christos {"cr.dcr", CR_DCR}, 441 1.1 christos {"cr.itm", CR_ITM}, 442 1.1 christos {"cr.iva", CR_IVA}, 443 1.1 christos {"cr.pta", CR_PTA}, 444 1.1 christos {"cr.gpta", CR_GPTA}, 445 1.1 christos {"cr.ipsr", CR_IPSR}, 446 1.1 christos {"cr.isr", CR_ISR}, 447 1.1 christos {"cr.iip", CR_IIP}, 448 1.1 christos {"cr.ifa", CR_IFA}, 449 1.1 christos {"cr.itir", CR_ITIR}, 450 1.1 christos {"cr.iipa", CR_IIPA}, 451 1.1 christos {"cr.ifs", CR_IFS}, 452 1.1 christos {"cr.iim", CR_IIM}, 453 1.1 christos {"cr.iha", CR_IHA}, 454 1.1 christos {"cr.iib0", CR_IIB0}, 455 1.1 christos {"cr.iib1", CR_IIB1}, 456 1.1 christos {"cr.lid", CR_LID}, 457 1.1 christos {"cr.ivr", CR_IVR}, 458 1.1 christos {"cr.tpr", CR_TPR}, 459 1.1 christos {"cr.eoi", CR_EOI}, 460 1.1 christos {"cr.irr0", CR_IRR0}, 461 1.1 christos {"cr.irr1", CR_IRR0 + 1}, 462 1.1 christos {"cr.irr2", CR_IRR0 + 2}, 463 1.1 christos {"cr.irr3", CR_IRR3}, 464 1.1 christos {"cr.itv", CR_ITV}, 465 1.1 christos {"cr.pmv", CR_PMV}, 466 1.1 christos {"cr.cmcv", CR_CMCV}, 467 1.1 christos {"cr.lrr0", CR_LRR0}, 468 1.1 christos {"cr.lrr1", CR_LRR1} 469 1.1 christos }; 470 1.1 christos 471 1.1 christos #define PSR_MFL 4 472 1.1 christos #define PSR_IC 13 473 1.1 christos #define PSR_DFL 18 474 1.1 christos #define PSR_CPL 32 475 1.1 christos 476 1.1 christos static const struct const_desc 477 1.1 christos { 478 1.1 christos const char *name; 479 1.1 christos valueT value; 480 1.1 christos } 481 1.1 christos const_bits[] = 482 1.1 christos { 483 1.1 christos /* PSR constant masks: */ 484 1.1 christos 485 1.1 christos /* 0: reserved */ 486 1.1 christos {"psr.be", ((valueT) 1) << 1}, 487 1.1 christos {"psr.up", ((valueT) 1) << 2}, 488 1.1 christos {"psr.ac", ((valueT) 1) << 3}, 489 1.1 christos {"psr.mfl", ((valueT) 1) << 4}, 490 1.1 christos {"psr.mfh", ((valueT) 1) << 5}, 491 1.1 christos /* 6-12: reserved */ 492 1.1 christos {"psr.ic", ((valueT) 1) << 13}, 493 1.1 christos {"psr.i", ((valueT) 1) << 14}, 494 1.1 christos {"psr.pk", ((valueT) 1) << 15}, 495 1.1 christos /* 16: reserved */ 496 1.1 christos {"psr.dt", ((valueT) 1) << 17}, 497 1.1 christos {"psr.dfl", ((valueT) 1) << 18}, 498 1.1 christos {"psr.dfh", ((valueT) 1) << 19}, 499 1.1 christos {"psr.sp", ((valueT) 1) << 20}, 500 1.1 christos {"psr.pp", ((valueT) 1) << 21}, 501 1.1 christos {"psr.di", ((valueT) 1) << 22}, 502 1.1 christos {"psr.si", ((valueT) 1) << 23}, 503 1.1 christos {"psr.db", ((valueT) 1) << 24}, 504 1.1 christos {"psr.lp", ((valueT) 1) << 25}, 505 1.1 christos {"psr.tb", ((valueT) 1) << 26}, 506 1.1 christos {"psr.rt", ((valueT) 1) << 27}, 507 1.1 christos /* 28-31: reserved */ 508 1.1 christos /* 32-33: cpl (current privilege level) */ 509 1.1 christos {"psr.is", ((valueT) 1) << 34}, 510 1.1 christos {"psr.mc", ((valueT) 1) << 35}, 511 1.1 christos {"psr.it", ((valueT) 1) << 36}, 512 1.1 christos {"psr.id", ((valueT) 1) << 37}, 513 1.1 christos {"psr.da", ((valueT) 1) << 38}, 514 1.1 christos {"psr.dd", ((valueT) 1) << 39}, 515 1.1 christos {"psr.ss", ((valueT) 1) << 40}, 516 1.1 christos /* 41-42: ri (restart instruction) */ 517 1.1 christos {"psr.ed", ((valueT) 1) << 43}, 518 1.1 christos {"psr.bn", ((valueT) 1) << 44}, 519 1.1 christos }; 520 1.1 christos 521 1.1 christos /* indirect register-sets/memory: */ 522 1.1 christos 523 1.1 christos static const struct 524 1.1 christos { 525 1.1 christos const char *name; 526 1.1 christos unsigned int regnum; 527 1.1 christos } 528 1.1 christos indirect_reg[] = 529 1.1 christos { 530 1.1 christos { "CPUID", IND_CPUID }, 531 1.1 christos { "cpuid", IND_CPUID }, 532 1.1 christos { "dbr", IND_DBR }, 533 1.1 christos { "dtr", IND_DTR }, 534 1.1 christos { "itr", IND_ITR }, 535 1.1 christos { "ibr", IND_IBR }, 536 1.1 christos { "msr", IND_MSR }, 537 1.1 christos { "pkr", IND_PKR }, 538 1.1 christos { "pmc", IND_PMC }, 539 1.1 christos { "pmd", IND_PMD }, 540 1.1 christos { "dahr", IND_DAHR }, 541 1.1 christos { "rr", IND_RR }, 542 1.1 christos }; 543 1.1 christos 544 1.1 christos /* Pseudo functions used to indicate relocation types (these functions 545 1.1 christos start with an at sign (@). */ 546 1.1 christos static struct 547 1.1 christos { 548 1.1 christos const char *name; 549 1.1 christos enum pseudo_type 550 1.1 christos { 551 1.1 christos PSEUDO_FUNC_NONE, 552 1.1 christos PSEUDO_FUNC_RELOC, 553 1.1 christos PSEUDO_FUNC_CONST, 554 1.1 christos PSEUDO_FUNC_REG, 555 1.1 christos PSEUDO_FUNC_FLOAT 556 1.1 christos } 557 1.1 christos type; 558 1.1 christos union 559 1.1 christos { 560 1.1 christos unsigned long ival; 561 1.1 christos symbolS *sym; 562 1.1 christos } 563 1.1 christos u; 564 1.1 christos } 565 1.1 christos pseudo_func[] = 566 1.1 christos { 567 1.1 christos /* reloc pseudo functions (these must come first!): */ 568 1.1 christos { "dtpmod", PSEUDO_FUNC_RELOC, { 0 } }, 569 1.1 christos { "dtprel", PSEUDO_FUNC_RELOC, { 0 } }, 570 1.1 christos { "fptr", PSEUDO_FUNC_RELOC, { 0 } }, 571 1.1 christos { "gprel", PSEUDO_FUNC_RELOC, { 0 } }, 572 1.1 christos { "ltoff", PSEUDO_FUNC_RELOC, { 0 } }, 573 1.1 christos { "ltoffx", PSEUDO_FUNC_RELOC, { 0 } }, 574 1.1 christos { "pcrel", PSEUDO_FUNC_RELOC, { 0 } }, 575 1.1 christos { "pltoff", PSEUDO_FUNC_RELOC, { 0 } }, 576 1.1 christos { "secrel", PSEUDO_FUNC_RELOC, { 0 } }, 577 1.1 christos { "segrel", PSEUDO_FUNC_RELOC, { 0 } }, 578 1.1 christos { "tprel", PSEUDO_FUNC_RELOC, { 0 } }, 579 1.1 christos { "ltv", PSEUDO_FUNC_RELOC, { 0 } }, 580 1.1 christos { NULL, 0, { 0 } }, /* placeholder for FUNC_LT_FPTR_RELATIVE */ 581 1.1 christos { NULL, 0, { 0 } }, /* placeholder for FUNC_LT_DTP_MODULE */ 582 1.1 christos { NULL, 0, { 0 } }, /* placeholder for FUNC_LT_DTP_RELATIVE */ 583 1.1 christos { NULL, 0, { 0 } }, /* placeholder for FUNC_LT_TP_RELATIVE */ 584 1.1 christos { "iplt", PSEUDO_FUNC_RELOC, { 0 } }, 585 1.1 christos #ifdef TE_VMS 586 1.1 christos { "slotcount", PSEUDO_FUNC_RELOC, { 0 } }, 587 1.1 christos #endif 588 1.1 christos 589 1.1 christos /* mbtype4 constants: */ 590 1.1 christos { "alt", PSEUDO_FUNC_CONST, { 0xa } }, 591 1.1 christos { "brcst", PSEUDO_FUNC_CONST, { 0x0 } }, 592 1.1 christos { "mix", PSEUDO_FUNC_CONST, { 0x8 } }, 593 1.1 christos { "rev", PSEUDO_FUNC_CONST, { 0xb } }, 594 1.1 christos { "shuf", PSEUDO_FUNC_CONST, { 0x9 } }, 595 1.1 christos 596 1.1 christos /* fclass constants: */ 597 1.1 christos { "nat", PSEUDO_FUNC_CONST, { 0x100 } }, 598 1.1 christos { "qnan", PSEUDO_FUNC_CONST, { 0x080 } }, 599 1.1 christos { "snan", PSEUDO_FUNC_CONST, { 0x040 } }, 600 1.1 christos { "pos", PSEUDO_FUNC_CONST, { 0x001 } }, 601 1.1 christos { "neg", PSEUDO_FUNC_CONST, { 0x002 } }, 602 1.1 christos { "zero", PSEUDO_FUNC_CONST, { 0x004 } }, 603 1.1 christos { "unorm", PSEUDO_FUNC_CONST, { 0x008 } }, 604 1.1 christos { "norm", PSEUDO_FUNC_CONST, { 0x010 } }, 605 1.1 christos { "inf", PSEUDO_FUNC_CONST, { 0x020 } }, 606 1.1 christos 607 1.1 christos { "natval", PSEUDO_FUNC_CONST, { 0x100 } }, /* old usage */ 608 1.1 christos 609 1.1 christos /* hint constants: */ 610 1.1 christos { "pause", PSEUDO_FUNC_CONST, { 0x0 } }, 611 1.1 christos { "priority", PSEUDO_FUNC_CONST, { 0x1 } }, 612 1.1 christos 613 1.1 christos /* tf constants: */ 614 1.1 christos { "clz", PSEUDO_FUNC_CONST, { 32 } }, 615 1.1 christos { "mpy", PSEUDO_FUNC_CONST, { 33 } }, 616 1.1 christos { "datahints", PSEUDO_FUNC_CONST, { 34 } }, 617 1.1 christos 618 1.1 christos /* unwind-related constants: */ 619 1.1 christos { "svr4", PSEUDO_FUNC_CONST, { ELFOSABI_NONE } }, 620 1.1 christos { "hpux", PSEUDO_FUNC_CONST, { ELFOSABI_HPUX } }, 621 1.1 christos { "nt", PSEUDO_FUNC_CONST, { 2 } }, /* conflicts w/ELFOSABI_NETBSD */ 622 1.1 christos { "linux", PSEUDO_FUNC_CONST, { ELFOSABI_GNU } }, 623 1.1 christos { "freebsd", PSEUDO_FUNC_CONST, { ELFOSABI_FREEBSD } }, 624 1.1 christos { "openvms", PSEUDO_FUNC_CONST, { ELFOSABI_OPENVMS } }, 625 1.1 christos { "nsk", PSEUDO_FUNC_CONST, { ELFOSABI_NSK } }, 626 1.1 christos 627 1.1 christos /* unwind-related registers: */ 628 1.1 christos { "priunat",PSEUDO_FUNC_REG, { REG_PRIUNAT } } 629 1.1 christos }; 630 1.1 christos 631 1.1 christos /* 41-bit nop opcodes (one per unit): */ 632 1.1 christos static const bfd_vma nop[IA64_NUM_UNITS] = 633 1.1 christos { 634 1.1 christos 0x0000000000LL, /* NIL => break 0 */ 635 1.1 christos 0x0008000000LL, /* I-unit nop */ 636 1.1 christos 0x0008000000LL, /* M-unit nop */ 637 1.1 christos 0x4000000000LL, /* B-unit nop */ 638 1.1 christos 0x0008000000LL, /* F-unit nop */ 639 1.1 christos 0x0000000000LL, /* L-"unit" nop immediate */ 640 1.1 christos 0x0008000000LL, /* X-unit nop */ 641 1.1 christos }; 642 1.1 christos 643 1.1 christos /* Can't be `const' as it's passed to input routines (which have the 644 1.1 christos habit of setting temporary sentinels. */ 645 1.1 christos static char special_section_name[][20] = 646 1.1 christos { 647 1.9 christos {".sbss"}, {".sdata"}, {".rodata"}, {".comment"}, 648 1.1 christos {".IA_64.unwind"}, {".IA_64.unwind_info"}, 649 1.1 christos {".init_array"}, {".fini_array"} 650 1.1 christos }; 651 1.1 christos 652 1.1 christos /* The best template for a particular sequence of up to three 653 1.1 christos instructions: */ 654 1.1 christos #define N IA64_NUM_TYPES 655 1.1 christos static unsigned char best_template[N][N][N]; 656 1.1 christos #undef N 657 1.1 christos 658 1.1 christos /* Resource dependencies currently in effect */ 659 1.1 christos static struct rsrc { 660 1.1 christos int depind; /* dependency index */ 661 1.1 christos const struct ia64_dependency *dependency; /* actual dependency */ 662 1.1 christos unsigned specific:1, /* is this a specific bit/regno? */ 663 1.1 christos link_to_qp_branch:1; /* will a branch on the same QP clear it?*/ 664 1.1 christos int index; /* specific regno/bit within dependency */ 665 1.1 christos int note; /* optional qualifying note (0 if none) */ 666 1.1 christos #define STATE_NONE 0 667 1.1 christos #define STATE_STOP 1 668 1.1 christos #define STATE_SRLZ 2 669 1.1 christos int insn_srlz; /* current insn serialization state */ 670 1.1 christos int data_srlz; /* current data serialization state */ 671 1.1 christos int qp_regno; /* qualifying predicate for this usage */ 672 1.5 christos const char *file; /* what file marked this dependency */ 673 1.1 christos unsigned int line; /* what line marked this dependency */ 674 1.1 christos struct mem_offset mem_offset; /* optional memory offset hint */ 675 1.1 christos enum { CMP_NONE, CMP_OR, CMP_AND } cmp_type; /* OR or AND compare? */ 676 1.1 christos int path; /* corresponding code entry index */ 677 1.1 christos } *regdeps = NULL; 678 1.1 christos static int regdepslen = 0; 679 1.1 christos static int regdepstotlen = 0; 680 1.1 christos static const char *dv_mode[] = { "RAW", "WAW", "WAR" }; 681 1.1 christos static const char *dv_sem[] = { "none", "implied", "impliedf", 682 1.1 christos "data", "instr", "specific", "stop", "other" }; 683 1.1 christos static const char *dv_cmp_type[] = { "none", "OR", "AND" }; 684 1.1 christos 685 1.1 christos /* Current state of PR mutexation */ 686 1.1 christos static struct qpmutex { 687 1.1 christos valueT prmask; 688 1.1 christos int path; 689 1.1 christos } *qp_mutexes = NULL; /* QP mutex bitmasks */ 690 1.1 christos static int qp_mutexeslen = 0; 691 1.1 christos static int qp_mutexestotlen = 0; 692 1.1 christos static valueT qp_safe_across_calls = 0; 693 1.1 christos 694 1.1 christos /* Current state of PR implications */ 695 1.1 christos static struct qp_imply { 696 1.1 christos unsigned p1:6; 697 1.1 christos unsigned p2:6; 698 1.1 christos unsigned p2_branched:1; 699 1.1 christos int path; 700 1.1 christos } *qp_implies = NULL; 701 1.1 christos static int qp_implieslen = 0; 702 1.1 christos static int qp_impliestotlen = 0; 703 1.1 christos 704 1.1 christos /* Keep track of static GR values so that indirect register usage can 705 1.1 christos sometimes be tracked. */ 706 1.1 christos static struct gr { 707 1.1 christos unsigned known:1; 708 1.1 christos int path; 709 1.1 christos valueT value; 710 1.1 christos } gr_values[128] = { 711 1.1 christos { 712 1.1 christos 1, 713 1.1 christos #ifdef INT_MAX 714 1.1 christos INT_MAX, 715 1.1 christos #else 716 1.1 christos (((1 << (8 * sizeof(gr_values->path) - 2)) - 1) << 1) + 1, 717 1.1 christos #endif 718 1.1 christos 0 719 1.1 christos } 720 1.1 christos }; 721 1.1 christos 722 1.1 christos /* Remember the alignment frag. */ 723 1.1 christos static fragS *align_frag; 724 1.1 christos 725 1.1 christos /* These are the routines required to output the various types of 726 1.1 christos unwind records. */ 727 1.1 christos 728 1.1 christos /* A slot_number is a frag address plus the slot index (0-2). We use the 729 1.1 christos frag address here so that if there is a section switch in the middle of 730 1.1 christos a function, then instructions emitted to a different section are not 731 1.1 christos counted. Since there may be more than one frag for a function, this 732 1.1 christos means we also need to keep track of which frag this address belongs to 733 1.1 christos so we can compute inter-frag distances. This also nicely solves the 734 1.1 christos problem with nops emitted for align directives, which can't easily be 735 1.1 christos counted, but can easily be derived from frag sizes. */ 736 1.1 christos 737 1.1 christos typedef struct unw_rec_list { 738 1.1 christos unwind_record r; 739 1.1 christos unsigned long slot_number; 740 1.1 christos fragS *slot_frag; 741 1.1 christos struct unw_rec_list *next; 742 1.1 christos } unw_rec_list; 743 1.1 christos 744 1.10 christos #define SLOT_NUM_NOT_SET -1UL 745 1.1 christos 746 1.1 christos /* Linked list of saved prologue counts. A very poor 747 1.1 christos implementation of a map from label numbers to prologue counts. */ 748 1.1 christos typedef struct label_prologue_count 749 1.1 christos { 750 1.1 christos struct label_prologue_count *next; 751 1.1 christos unsigned long label_number; 752 1.1 christos unsigned int prologue_count; 753 1.1 christos } label_prologue_count; 754 1.1 christos 755 1.1 christos typedef struct proc_pending 756 1.1 christos { 757 1.1 christos symbolS *sym; 758 1.1 christos struct proc_pending *next; 759 1.1 christos } proc_pending; 760 1.1 christos 761 1.1 christos static struct 762 1.1 christos { 763 1.1 christos /* Maintain a list of unwind entries for the current function. */ 764 1.1 christos unw_rec_list *list; 765 1.1 christos unw_rec_list *tail; 766 1.1 christos 767 1.1 christos /* Any unwind entries that should be attached to the current slot 768 1.1 christos that an insn is being constructed for. */ 769 1.1 christos unw_rec_list *current_entry; 770 1.1 christos 771 1.1 christos /* These are used to create the unwind table entry for this function. */ 772 1.1 christos proc_pending proc_pending; 773 1.1 christos symbolS *info; /* pointer to unwind info */ 774 1.1 christos symbolS *personality_routine; 775 1.1 christos segT saved_text_seg; 776 1.1 christos subsegT saved_text_subseg; 777 1.1 christos unsigned int force_unwind_entry : 1; /* force generation of unwind entry? */ 778 1.1 christos 779 1.1 christos /* TRUE if processing unwind directives in a prologue region. */ 780 1.1 christos unsigned int prologue : 1; 781 1.1 christos unsigned int prologue_mask : 4; 782 1.1 christos unsigned int prologue_gr : 7; 783 1.1 christos unsigned int body : 1; 784 1.1 christos unsigned int insn : 1; 785 1.1 christos unsigned int prologue_count; /* number of .prologues seen so far */ 786 1.1 christos /* Prologue counts at previous .label_state directives. */ 787 1.1 christos struct label_prologue_count * saved_prologue_counts; 788 1.1 christos 789 1.1 christos /* List of split up .save-s. */ 790 1.1 christos unw_p_record *pending_saves; 791 1.1 christos } unwind; 792 1.1 christos 793 1.1 christos /* The input value is a negated offset from psp, and specifies an address 794 1.1 christos psp - offset. The encoded value is psp + 16 - (4 * offset). Thus we 795 1.1 christos must add 16 and divide by 4 to get the encoded value. */ 796 1.1 christos 797 1.1 christos #define ENCODED_PSP_OFFSET(OFFSET) (((OFFSET) + 16) / 4) 798 1.1 christos 799 1.1 christos typedef void (*vbyte_func) (int, char *, char *); 800 1.1 christos 801 1.1 christos /* Forward declarations: */ 802 1.1 christos static void dot_alias (int); 803 1.1 christos static int parse_operand_and_eval (expressionS *, int); 804 1.1 christos static void emit_one_bundle (void); 805 1.1 christos static bfd_reloc_code_real_type ia64_gen_real_reloc_type (struct symbol *, 806 1.1 christos bfd_reloc_code_real_type); 807 1.1 christos static void insn_group_break (int, int, int); 808 1.1 christos static void add_qp_mutex (valueT); 809 1.1 christos static void add_qp_imply (int, int); 810 1.1 christos static void clear_qp_mutex (valueT); 811 1.1 christos static void clear_qp_implies (valueT, valueT); 812 1.1 christos static void print_dependency (const char *, int); 813 1.1 christos static void instruction_serialization (void); 814 1.1 christos static void data_serialization (void); 815 1.1 christos static void output_R3_format (vbyte_func, unw_record_type, unsigned long); 816 1.1 christos static void output_B3_format (vbyte_func, unsigned long, unsigned long); 817 1.1 christos static void output_B4_format (vbyte_func, unw_record_type, unsigned long); 818 1.1 christos static void free_saved_prologue_counts (void); 819 1.1 christos 820 1.1 christos /* Determine if application register REGNUM resides only in the integer 821 1.1 christos unit (as opposed to the memory unit). */ 822 1.1 christos static int 823 1.1 christos ar_is_only_in_integer_unit (int reg) 824 1.1 christos { 825 1.1 christos reg -= REG_AR; 826 1.1 christos return reg >= 64 && reg <= 111; 827 1.1 christos } 828 1.1 christos 829 1.3 christos /* Determine if application register REGNUM resides only in the memory 830 1.1 christos unit (as opposed to the integer unit). */ 831 1.1 christos static int 832 1.1 christos ar_is_only_in_memory_unit (int reg) 833 1.1 christos { 834 1.1 christos reg -= REG_AR; 835 1.1 christos return reg >= 0 && reg <= 47; 836 1.1 christos } 837 1.1 christos 838 1.1 christos /* Switch to section NAME and create section if necessary. It's 839 1.1 christos rather ugly that we have to manipulate input_line_pointer but I 840 1.1 christos don't see any other way to accomplish the same thing without 841 1.1 christos changing obj-elf.c (which may be the Right Thing, in the end). */ 842 1.1 christos static void 843 1.1 christos set_section (char *name) 844 1.1 christos { 845 1.1 christos char *saved_input_line_pointer; 846 1.1 christos 847 1.1 christos saved_input_line_pointer = input_line_pointer; 848 1.1 christos input_line_pointer = name; 849 1.1 christos obj_elf_section (0); 850 1.1 christos input_line_pointer = saved_input_line_pointer; 851 1.1 christos } 852 1.1 christos 853 1.1 christos /* Map 's' to SHF_IA_64_SHORT. */ 854 1.1 christos 855 1.1 christos bfd_vma 856 1.5 christos ia64_elf_section_letter (int letter, const char **ptr_msg) 857 1.1 christos { 858 1.1 christos if (letter == 's') 859 1.1 christos return SHF_IA_64_SHORT; 860 1.1 christos else if (letter == 'o') 861 1.1 christos return SHF_LINK_ORDER; 862 1.1 christos #ifdef TE_VMS 863 1.1 christos else if (letter == 'O') 864 1.1 christos return SHF_IA_64_VMS_OVERLAID; 865 1.1 christos else if (letter == 'g') 866 1.1 christos return SHF_IA_64_VMS_GLOBAL; 867 1.1 christos #endif 868 1.1 christos 869 1.1 christos *ptr_msg = _("bad .section directive: want a,o,s,w,x,M,S,G,T in string"); 870 1.1 christos return -1; 871 1.1 christos } 872 1.1 christos 873 1.1 christos /* Map SHF_IA_64_SHORT to SEC_SMALL_DATA. */ 874 1.1 christos 875 1.1 christos flagword 876 1.1 christos ia64_elf_section_flags (flagword flags, 877 1.1 christos bfd_vma attr, 878 1.1 christos int type ATTRIBUTE_UNUSED) 879 1.1 christos { 880 1.1 christos if (attr & SHF_IA_64_SHORT) 881 1.1 christos flags |= SEC_SMALL_DATA; 882 1.1 christos return flags; 883 1.1 christos } 884 1.1 christos 885 1.1 christos int 886 1.1 christos ia64_elf_section_type (const char *str, size_t len) 887 1.1 christos { 888 1.1 christos #define STREQ(s) ((len == sizeof (s) - 1) && (strncmp (str, s, sizeof (s) - 1) == 0)) 889 1.1 christos 890 1.1 christos if (STREQ (ELF_STRING_ia64_unwind_info)) 891 1.1 christos return SHT_PROGBITS; 892 1.1 christos 893 1.1 christos if (STREQ (ELF_STRING_ia64_unwind_info_once)) 894 1.1 christos return SHT_PROGBITS; 895 1.1 christos 896 1.1 christos if (STREQ (ELF_STRING_ia64_unwind)) 897 1.1 christos return SHT_IA_64_UNWIND; 898 1.1 christos 899 1.1 christos if (STREQ (ELF_STRING_ia64_unwind_once)) 900 1.1 christos return SHT_IA_64_UNWIND; 901 1.1 christos 902 1.1 christos if (STREQ ("unwind")) 903 1.1 christos return SHT_IA_64_UNWIND; 904 1.1 christos 905 1.1 christos return -1; 906 1.1 christos #undef STREQ 907 1.1 christos } 908 1.1 christos 909 1.1 christos static unsigned int 910 1.1 christos set_regstack (unsigned int ins, 911 1.1 christos unsigned int locs, 912 1.1 christos unsigned int outs, 913 1.1 christos unsigned int rots) 914 1.1 christos { 915 1.1 christos /* Size of frame. */ 916 1.1 christos unsigned int sof; 917 1.1 christos 918 1.1 christos sof = ins + locs + outs; 919 1.1 christos if (sof > 96) 920 1.1 christos { 921 1.1 christos as_bad (_("Size of frame exceeds maximum of 96 registers")); 922 1.1 christos return 0; 923 1.1 christos } 924 1.1 christos if (rots > sof) 925 1.1 christos { 926 1.1 christos as_warn (_("Size of rotating registers exceeds frame size")); 927 1.1 christos return 0; 928 1.1 christos } 929 1.1 christos md.in.base = REG_GR + 32; 930 1.1 christos md.loc.base = md.in.base + ins; 931 1.1 christos md.out.base = md.loc.base + locs; 932 1.1 christos 933 1.1 christos md.in.num_regs = ins; 934 1.1 christos md.loc.num_regs = locs; 935 1.1 christos md.out.num_regs = outs; 936 1.1 christos md.rot.num_regs = rots; 937 1.1 christos return sof; 938 1.1 christos } 939 1.1 christos 940 1.1 christos void 941 1.1 christos ia64_flush_insns (void) 942 1.1 christos { 943 1.1 christos struct label_fix *lfix; 944 1.1 christos segT saved_seg; 945 1.1 christos subsegT saved_subseg; 946 1.1 christos unw_rec_list *ptr; 947 1.8 christos bool mark; 948 1.1 christos 949 1.1 christos if (!md.last_text_seg) 950 1.1 christos return; 951 1.1 christos 952 1.1 christos saved_seg = now_seg; 953 1.1 christos saved_subseg = now_subseg; 954 1.1 christos 955 1.8 christos subseg_set (md.last_text_seg, md.last_text_subseg); 956 1.1 christos 957 1.1 christos while (md.num_slots_in_use > 0) 958 1.1 christos emit_one_bundle (); /* force out queued instructions */ 959 1.1 christos 960 1.1 christos /* In case there are labels following the last instruction, resolve 961 1.1 christos those now. */ 962 1.8 christos mark = false; 963 1.1 christos for (lfix = CURR_SLOT.label_fixups; lfix; lfix = lfix->next) 964 1.1 christos { 965 1.1 christos symbol_set_value_now (lfix->sym); 966 1.1 christos mark |= lfix->dw2_mark_labels; 967 1.1 christos } 968 1.1 christos if (mark) 969 1.1 christos { 970 1.1 christos dwarf2_where (&CURR_SLOT.debug_line); 971 1.1 christos CURR_SLOT.debug_line.flags |= DWARF2_FLAG_BASIC_BLOCK; 972 1.1 christos dwarf2_gen_line_info (frag_now_fix (), &CURR_SLOT.debug_line); 973 1.1 christos dwarf2_consume_line_info (); 974 1.1 christos } 975 1.1 christos CURR_SLOT.label_fixups = 0; 976 1.1 christos 977 1.1 christos for (lfix = CURR_SLOT.tag_fixups; lfix; lfix = lfix->next) 978 1.1 christos symbol_set_value_now (lfix->sym); 979 1.1 christos CURR_SLOT.tag_fixups = 0; 980 1.1 christos 981 1.1 christos /* In case there are unwind directives following the last instruction, 982 1.1 christos resolve those now. We only handle prologue, body, and endp directives 983 1.1 christos here. Give an error for others. */ 984 1.1 christos for (ptr = unwind.current_entry; ptr; ptr = ptr->next) 985 1.1 christos { 986 1.1 christos switch (ptr->r.type) 987 1.1 christos { 988 1.1 christos case prologue: 989 1.1 christos case prologue_gr: 990 1.1 christos case body: 991 1.1 christos case endp: 992 1.1 christos ptr->slot_number = (unsigned long) frag_more (0); 993 1.1 christos ptr->slot_frag = frag_now; 994 1.1 christos break; 995 1.1 christos 996 1.1 christos /* Allow any record which doesn't have a "t" field (i.e., 997 1.1 christos doesn't relate to a particular instruction). */ 998 1.1 christos case unwabi: 999 1.1 christos case br_gr: 1000 1.1 christos case copy_state: 1001 1.1 christos case fr_mem: 1002 1.1 christos case frgr_mem: 1003 1.1 christos case gr_gr: 1004 1.1 christos case gr_mem: 1005 1.1 christos case label_state: 1006 1.1 christos case rp_br: 1007 1.1 christos case spill_base: 1008 1.1 christos case spill_mask: 1009 1.1 christos /* nothing */ 1010 1.1 christos break; 1011 1.1 christos 1012 1.1 christos default: 1013 1.1 christos as_bad (_("Unwind directive not followed by an instruction.")); 1014 1.1 christos break; 1015 1.1 christos } 1016 1.1 christos } 1017 1.1 christos unwind.current_entry = NULL; 1018 1.1 christos 1019 1.1 christos subseg_set (saved_seg, saved_subseg); 1020 1.1 christos 1021 1.1 christos if (md.qp.X_op == O_register) 1022 1.1 christos as_bad (_("qualifying predicate not followed by instruction")); 1023 1.1 christos } 1024 1.1 christos 1025 1.1 christos void 1026 1.1 christos ia64_cons_align (int nbytes) 1027 1.1 christos { 1028 1.1 christos if (md.auto_align) 1029 1.1 christos { 1030 1.5 christos int log; 1031 1.5 christos for (log = 0; (nbytes & 1) != 1; nbytes >>= 1) 1032 1.5 christos log++; 1033 1.5 christos 1034 1.5 christos do_align (log, NULL, 0, 0); 1035 1.1 christos } 1036 1.1 christos } 1037 1.1 christos 1038 1.1 christos #ifdef TE_VMS 1039 1.1 christos 1040 1.1 christos /* .vms_common section, symbol, size, alignment */ 1041 1.1 christos 1042 1.1 christos static void 1043 1.1 christos obj_elf_vms_common (int ignore ATTRIBUTE_UNUSED) 1044 1.1 christos { 1045 1.5 christos const char *sec_name; 1046 1.1 christos char *sym_name; 1047 1.1 christos char c; 1048 1.10 christos valueT size; 1049 1.10 christos valueT cur_size; 1050 1.10 christos valueT temp; 1051 1.1 christos symbolS *symbolP; 1052 1.1 christos segT current_seg = now_seg; 1053 1.1 christos subsegT current_subseg = now_subseg; 1054 1.1 christos offsetT log_align; 1055 1.1 christos 1056 1.1 christos /* Section name. */ 1057 1.1 christos sec_name = obj_elf_section_name (); 1058 1.1 christos if (sec_name == NULL) 1059 1.1 christos return; 1060 1.1 christos 1061 1.1 christos /* Symbol name. */ 1062 1.1 christos SKIP_WHITESPACE (); 1063 1.1 christos if (*input_line_pointer == ',') 1064 1.1 christos { 1065 1.1 christos input_line_pointer++; 1066 1.1 christos SKIP_WHITESPACE (); 1067 1.1 christos } 1068 1.1 christos else 1069 1.1 christos { 1070 1.1 christos as_bad (_("expected ',' after section name")); 1071 1.1 christos ignore_rest_of_line (); 1072 1.1 christos return; 1073 1.1 christos } 1074 1.1 christos 1075 1.3 christos c = get_symbol_name (&sym_name); 1076 1.1 christos 1077 1.1 christos if (input_line_pointer == sym_name) 1078 1.1 christos { 1079 1.3 christos (void) restore_line_pointer (c); 1080 1.1 christos as_bad (_("expected symbol name")); 1081 1.1 christos ignore_rest_of_line (); 1082 1.1 christos return; 1083 1.1 christos } 1084 1.1 christos 1085 1.1 christos symbolP = symbol_find_or_make (sym_name); 1086 1.3 christos (void) restore_line_pointer (c); 1087 1.1 christos 1088 1.1 christos if ((S_IS_DEFINED (symbolP) || symbol_equated_p (symbolP)) 1089 1.1 christos && !S_IS_COMMON (symbolP)) 1090 1.1 christos { 1091 1.1 christos as_bad (_("Ignoring attempt to re-define symbol")); 1092 1.1 christos ignore_rest_of_line (); 1093 1.1 christos return; 1094 1.1 christos } 1095 1.1 christos 1096 1.1 christos /* Symbol size. */ 1097 1.1 christos SKIP_WHITESPACE (); 1098 1.1 christos if (*input_line_pointer == ',') 1099 1.1 christos { 1100 1.1 christos input_line_pointer++; 1101 1.1 christos SKIP_WHITESPACE (); 1102 1.1 christos } 1103 1.1 christos else 1104 1.1 christos { 1105 1.1 christos as_bad (_("expected ',' after symbol name")); 1106 1.1 christos ignore_rest_of_line (); 1107 1.1 christos return; 1108 1.1 christos } 1109 1.1 christos 1110 1.1 christos temp = get_absolute_expression (); 1111 1.1 christos size = temp; 1112 1.10 christos size &= ((valueT) 2 << (stdoutput->arch_info->bits_per_address - 1)) - 1; 1113 1.1 christos if (temp != size) 1114 1.1 christos { 1115 1.1 christos as_warn (_("size (%ld) out of range, ignored"), (long) temp); 1116 1.1 christos ignore_rest_of_line (); 1117 1.1 christos return; 1118 1.1 christos } 1119 1.1 christos 1120 1.1 christos /* Alignment. */ 1121 1.1 christos SKIP_WHITESPACE (); 1122 1.1 christos if (*input_line_pointer == ',') 1123 1.1 christos { 1124 1.1 christos input_line_pointer++; 1125 1.1 christos SKIP_WHITESPACE (); 1126 1.1 christos } 1127 1.1 christos else 1128 1.1 christos { 1129 1.1 christos as_bad (_("expected ',' after symbol size")); 1130 1.1 christos ignore_rest_of_line (); 1131 1.1 christos return; 1132 1.1 christos } 1133 1.1 christos 1134 1.1 christos log_align = get_absolute_expression (); 1135 1.1 christos 1136 1.1 christos demand_empty_rest_of_line (); 1137 1.1 christos 1138 1.1 christos obj_elf_change_section 1139 1.8 christos (sec_name, SHT_NOBITS, 1140 1.1 christos SHF_ALLOC | SHF_WRITE | SHF_IA_64_VMS_OVERLAID | SHF_IA_64_VMS_GLOBAL, 1141 1.9 christos 0, NULL, true); 1142 1.1 christos 1143 1.1 christos S_SET_VALUE (symbolP, 0); 1144 1.1 christos S_SET_SIZE (symbolP, size); 1145 1.1 christos S_SET_EXTERNAL (symbolP); 1146 1.1 christos S_SET_SEGMENT (symbolP, now_seg); 1147 1.1 christos 1148 1.1 christos symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT; 1149 1.1 christos 1150 1.1 christos record_alignment (now_seg, log_align); 1151 1.1 christos 1152 1.7 christos cur_size = bfd_section_size (now_seg); 1153 1.10 christos if (size > cur_size) 1154 1.1 christos { 1155 1.10 christos char *pfrag = frag_var (rs_fill, 1, 1, 0, NULL, size - cur_size, NULL); 1156 1.1 christos *pfrag = 0; 1157 1.7 christos bfd_set_section_size (now_seg, size); 1158 1.1 christos } 1159 1.1 christos 1160 1.1 christos /* Switch back to current segment. */ 1161 1.1 christos subseg_set (current_seg, current_subseg); 1162 1.1 christos 1163 1.1 christos #ifdef md_elf_section_change_hook 1164 1.1 christos md_elf_section_change_hook (); 1165 1.1 christos #endif 1166 1.1 christos } 1167 1.1 christos 1168 1.1 christos #endif /* TE_VMS */ 1169 1.1 christos 1170 1.1 christos /* Output COUNT bytes to a memory location. */ 1171 1.1 christos static char *vbyte_mem_ptr = NULL; 1172 1.1 christos 1173 1.1 christos static void 1174 1.1 christos output_vbyte_mem (int count, char *ptr, char *comment ATTRIBUTE_UNUSED) 1175 1.1 christos { 1176 1.1 christos int x; 1177 1.1 christos if (vbyte_mem_ptr == NULL) 1178 1.1 christos abort (); 1179 1.1 christos 1180 1.1 christos if (count == 0) 1181 1.1 christos return; 1182 1.1 christos for (x = 0; x < count; x++) 1183 1.1 christos *(vbyte_mem_ptr++) = ptr[x]; 1184 1.1 christos } 1185 1.1 christos 1186 1.1 christos /* Count the number of bytes required for records. */ 1187 1.1 christos static int vbyte_count = 0; 1188 1.1 christos static void 1189 1.1 christos count_output (int count, 1190 1.1 christos char *ptr ATTRIBUTE_UNUSED, 1191 1.1 christos char *comment ATTRIBUTE_UNUSED) 1192 1.1 christos { 1193 1.1 christos vbyte_count += count; 1194 1.1 christos } 1195 1.1 christos 1196 1.1 christos static void 1197 1.1 christos output_R1_format (vbyte_func f, unw_record_type rtype, int rlen) 1198 1.1 christos { 1199 1.1 christos int r = 0; 1200 1.1 christos char byte; 1201 1.1 christos if (rlen > 0x1f) 1202 1.1 christos { 1203 1.1 christos output_R3_format (f, rtype, rlen); 1204 1.1 christos return; 1205 1.1 christos } 1206 1.1 christos 1207 1.1 christos if (rtype == body) 1208 1.1 christos r = 1; 1209 1.1 christos else if (rtype != prologue) 1210 1.1 christos as_bad (_("record type is not valid")); 1211 1.1 christos 1212 1.1 christos byte = UNW_R1 | (r << 5) | (rlen & 0x1f); 1213 1.1 christos (*f) (1, &byte, NULL); 1214 1.1 christos } 1215 1.1 christos 1216 1.1 christos static void 1217 1.1 christos output_R2_format (vbyte_func f, int mask, int grsave, unsigned long rlen) 1218 1.1 christos { 1219 1.1 christos char bytes[20]; 1220 1.1 christos int count = 2; 1221 1.1 christos mask = (mask & 0x0f); 1222 1.1 christos grsave = (grsave & 0x7f); 1223 1.1 christos 1224 1.1 christos bytes[0] = (UNW_R2 | (mask >> 1)); 1225 1.1 christos bytes[1] = (((mask & 0x01) << 7) | grsave); 1226 1.1 christos count += output_leb128 (bytes + 2, rlen, 0); 1227 1.1 christos (*f) (count, bytes, NULL); 1228 1.1 christos } 1229 1.1 christos 1230 1.1 christos static void 1231 1.1 christos output_R3_format (vbyte_func f, unw_record_type rtype, unsigned long rlen) 1232 1.1 christos { 1233 1.1 christos int r = 0, count; 1234 1.1 christos char bytes[20]; 1235 1.1 christos if (rlen <= 0x1f) 1236 1.1 christos { 1237 1.1 christos output_R1_format (f, rtype, rlen); 1238 1.1 christos return; 1239 1.1 christos } 1240 1.1 christos 1241 1.1 christos if (rtype == body) 1242 1.1 christos r = 1; 1243 1.1 christos else if (rtype != prologue) 1244 1.1 christos as_bad (_("record type is not valid")); 1245 1.1 christos bytes[0] = (UNW_R3 | r); 1246 1.1 christos count = output_leb128 (bytes + 1, rlen, 0); 1247 1.1 christos (*f) (count + 1, bytes, NULL); 1248 1.1 christos } 1249 1.1 christos 1250 1.1 christos static void 1251 1.1 christos output_P1_format (vbyte_func f, int brmask) 1252 1.1 christos { 1253 1.1 christos char byte; 1254 1.1 christos byte = UNW_P1 | (brmask & 0x1f); 1255 1.1 christos (*f) (1, &byte, NULL); 1256 1.1 christos } 1257 1.1 christos 1258 1.1 christos static void 1259 1.1 christos output_P2_format (vbyte_func f, int brmask, int gr) 1260 1.1 christos { 1261 1.1 christos char bytes[2]; 1262 1.1 christos brmask = (brmask & 0x1f); 1263 1.1 christos bytes[0] = UNW_P2 | (brmask >> 1); 1264 1.1 christos bytes[1] = (((brmask & 1) << 7) | gr); 1265 1.1 christos (*f) (2, bytes, NULL); 1266 1.1 christos } 1267 1.1 christos 1268 1.1 christos static void 1269 1.1 christos output_P3_format (vbyte_func f, unw_record_type rtype, int reg) 1270 1.1 christos { 1271 1.1 christos char bytes[2]; 1272 1.1 christos int r = 0; 1273 1.1 christos reg = (reg & 0x7f); 1274 1.1 christos switch (rtype) 1275 1.1 christos { 1276 1.1 christos case psp_gr: 1277 1.1 christos r = 0; 1278 1.1 christos break; 1279 1.1 christos case rp_gr: 1280 1.1 christos r = 1; 1281 1.1 christos break; 1282 1.1 christos case pfs_gr: 1283 1.1 christos r = 2; 1284 1.1 christos break; 1285 1.1 christos case preds_gr: 1286 1.1 christos r = 3; 1287 1.1 christos break; 1288 1.1 christos case unat_gr: 1289 1.1 christos r = 4; 1290 1.1 christos break; 1291 1.1 christos case lc_gr: 1292 1.1 christos r = 5; 1293 1.1 christos break; 1294 1.1 christos case rp_br: 1295 1.1 christos r = 6; 1296 1.1 christos break; 1297 1.1 christos case rnat_gr: 1298 1.1 christos r = 7; 1299 1.1 christos break; 1300 1.1 christos case bsp_gr: 1301 1.1 christos r = 8; 1302 1.1 christos break; 1303 1.1 christos case bspstore_gr: 1304 1.1 christos r = 9; 1305 1.1 christos break; 1306 1.1 christos case fpsr_gr: 1307 1.1 christos r = 10; 1308 1.1 christos break; 1309 1.1 christos case priunat_gr: 1310 1.1 christos r = 11; 1311 1.1 christos break; 1312 1.1 christos default: 1313 1.1 christos as_bad (_("Invalid record type for P3 format.")); 1314 1.1 christos } 1315 1.1 christos bytes[0] = (UNW_P3 | (r >> 1)); 1316 1.1 christos bytes[1] = (((r & 1) << 7) | reg); 1317 1.1 christos (*f) (2, bytes, NULL); 1318 1.1 christos } 1319 1.1 christos 1320 1.1 christos static void 1321 1.1 christos output_P4_format (vbyte_func f, unsigned char *imask, unsigned long imask_size) 1322 1.1 christos { 1323 1.1 christos imask[0] = UNW_P4; 1324 1.1 christos (*f) (imask_size, (char *) imask, NULL); 1325 1.1 christos } 1326 1.1 christos 1327 1.1 christos static void 1328 1.1 christos output_P5_format (vbyte_func f, int grmask, unsigned long frmask) 1329 1.1 christos { 1330 1.1 christos char bytes[4]; 1331 1.1 christos grmask = (grmask & 0x0f); 1332 1.1 christos 1333 1.1 christos bytes[0] = UNW_P5; 1334 1.1 christos bytes[1] = ((grmask << 4) | ((frmask & 0x000f0000) >> 16)); 1335 1.1 christos bytes[2] = ((frmask & 0x0000ff00) >> 8); 1336 1.1 christos bytes[3] = (frmask & 0x000000ff); 1337 1.1 christos (*f) (4, bytes, NULL); 1338 1.1 christos } 1339 1.1 christos 1340 1.1 christos static void 1341 1.1 christos output_P6_format (vbyte_func f, unw_record_type rtype, int rmask) 1342 1.1 christos { 1343 1.1 christos char byte; 1344 1.1 christos int r = 0; 1345 1.1 christos 1346 1.1 christos if (rtype == gr_mem) 1347 1.1 christos r = 1; 1348 1.1 christos else if (rtype != fr_mem) 1349 1.1 christos as_bad (_("Invalid record type for format P6")); 1350 1.1 christos byte = (UNW_P6 | (r << 4) | (rmask & 0x0f)); 1351 1.1 christos (*f) (1, &byte, NULL); 1352 1.1 christos } 1353 1.1 christos 1354 1.1 christos static void 1355 1.1 christos output_P7_format (vbyte_func f, 1356 1.1 christos unw_record_type rtype, 1357 1.1 christos unsigned long w1, 1358 1.1 christos unsigned long w2) 1359 1.1 christos { 1360 1.1 christos char bytes[20]; 1361 1.1 christos int count = 1; 1362 1.1 christos int r = 0; 1363 1.1 christos count += output_leb128 (bytes + 1, w1, 0); 1364 1.1 christos switch (rtype) 1365 1.1 christos { 1366 1.1 christos case mem_stack_f: 1367 1.1 christos r = 0; 1368 1.1 christos count += output_leb128 (bytes + count, w2 >> 4, 0); 1369 1.1 christos break; 1370 1.1 christos case mem_stack_v: 1371 1.1 christos r = 1; 1372 1.1 christos break; 1373 1.1 christos case spill_base: 1374 1.1 christos r = 2; 1375 1.1 christos break; 1376 1.1 christos case psp_sprel: 1377 1.1 christos r = 3; 1378 1.1 christos break; 1379 1.1 christos case rp_when: 1380 1.1 christos r = 4; 1381 1.1 christos break; 1382 1.1 christos case rp_psprel: 1383 1.1 christos r = 5; 1384 1.1 christos break; 1385 1.1 christos case pfs_when: 1386 1.1 christos r = 6; 1387 1.1 christos break; 1388 1.1 christos case pfs_psprel: 1389 1.1 christos r = 7; 1390 1.1 christos break; 1391 1.1 christos case preds_when: 1392 1.1 christos r = 8; 1393 1.1 christos break; 1394 1.1 christos case preds_psprel: 1395 1.1 christos r = 9; 1396 1.1 christos break; 1397 1.1 christos case lc_when: 1398 1.1 christos r = 10; 1399 1.1 christos break; 1400 1.1 christos case lc_psprel: 1401 1.1 christos r = 11; 1402 1.1 christos break; 1403 1.1 christos case unat_when: 1404 1.1 christos r = 12; 1405 1.1 christos break; 1406 1.1 christos case unat_psprel: 1407 1.1 christos r = 13; 1408 1.1 christos break; 1409 1.1 christos case fpsr_when: 1410 1.1 christos r = 14; 1411 1.1 christos break; 1412 1.1 christos case fpsr_psprel: 1413 1.1 christos r = 15; 1414 1.1 christos break; 1415 1.1 christos default: 1416 1.1 christos break; 1417 1.1 christos } 1418 1.1 christos bytes[0] = (UNW_P7 | r); 1419 1.1 christos (*f) (count, bytes, NULL); 1420 1.1 christos } 1421 1.1 christos 1422 1.1 christos static void 1423 1.1 christos output_P8_format (vbyte_func f, unw_record_type rtype, unsigned long t) 1424 1.1 christos { 1425 1.1 christos char bytes[20]; 1426 1.1 christos int r = 0; 1427 1.1 christos int count = 2; 1428 1.1 christos bytes[0] = UNW_P8; 1429 1.1 christos switch (rtype) 1430 1.1 christos { 1431 1.1 christos case rp_sprel: 1432 1.1 christos r = 1; 1433 1.1 christos break; 1434 1.1 christos case pfs_sprel: 1435 1.1 christos r = 2; 1436 1.1 christos break; 1437 1.1 christos case preds_sprel: 1438 1.1 christos r = 3; 1439 1.1 christos break; 1440 1.1 christos case lc_sprel: 1441 1.1 christos r = 4; 1442 1.1 christos break; 1443 1.1 christos case unat_sprel: 1444 1.1 christos r = 5; 1445 1.1 christos break; 1446 1.1 christos case fpsr_sprel: 1447 1.1 christos r = 6; 1448 1.1 christos break; 1449 1.1 christos case bsp_when: 1450 1.1 christos r = 7; 1451 1.1 christos break; 1452 1.1 christos case bsp_psprel: 1453 1.1 christos r = 8; 1454 1.1 christos break; 1455 1.1 christos case bsp_sprel: 1456 1.1 christos r = 9; 1457 1.1 christos break; 1458 1.1 christos case bspstore_when: 1459 1.1 christos r = 10; 1460 1.1 christos break; 1461 1.1 christos case bspstore_psprel: 1462 1.1 christos r = 11; 1463 1.1 christos break; 1464 1.1 christos case bspstore_sprel: 1465 1.1 christos r = 12; 1466 1.1 christos break; 1467 1.1 christos case rnat_when: 1468 1.1 christos r = 13; 1469 1.1 christos break; 1470 1.1 christos case rnat_psprel: 1471 1.1 christos r = 14; 1472 1.1 christos break; 1473 1.1 christos case rnat_sprel: 1474 1.1 christos r = 15; 1475 1.1 christos break; 1476 1.1 christos case priunat_when_gr: 1477 1.1 christos r = 16; 1478 1.1 christos break; 1479 1.1 christos case priunat_psprel: 1480 1.1 christos r = 17; 1481 1.1 christos break; 1482 1.1 christos case priunat_sprel: 1483 1.1 christos r = 18; 1484 1.1 christos break; 1485 1.1 christos case priunat_when_mem: 1486 1.1 christos r = 19; 1487 1.1 christos break; 1488 1.1 christos default: 1489 1.1 christos break; 1490 1.1 christos } 1491 1.1 christos bytes[1] = r; 1492 1.1 christos count += output_leb128 (bytes + 2, t, 0); 1493 1.1 christos (*f) (count, bytes, NULL); 1494 1.1 christos } 1495 1.1 christos 1496 1.1 christos static void 1497 1.1 christos output_P9_format (vbyte_func f, int grmask, int gr) 1498 1.1 christos { 1499 1.1 christos char bytes[3]; 1500 1.1 christos bytes[0] = UNW_P9; 1501 1.1 christos bytes[1] = (grmask & 0x0f); 1502 1.1 christos bytes[2] = (gr & 0x7f); 1503 1.1 christos (*f) (3, bytes, NULL); 1504 1.1 christos } 1505 1.1 christos 1506 1.1 christos static void 1507 1.1 christos output_P10_format (vbyte_func f, int abi, int context) 1508 1.1 christos { 1509 1.1 christos char bytes[3]; 1510 1.1 christos bytes[0] = UNW_P10; 1511 1.1 christos bytes[1] = (abi & 0xff); 1512 1.1 christos bytes[2] = (context & 0xff); 1513 1.1 christos (*f) (3, bytes, NULL); 1514 1.1 christos } 1515 1.1 christos 1516 1.1 christos static void 1517 1.1 christos output_B1_format (vbyte_func f, unw_record_type rtype, unsigned long label) 1518 1.1 christos { 1519 1.1 christos char byte; 1520 1.1 christos int r = 0; 1521 1.1 christos if (label > 0x1f) 1522 1.1 christos { 1523 1.1 christos output_B4_format (f, rtype, label); 1524 1.1 christos return; 1525 1.1 christos } 1526 1.1 christos if (rtype == copy_state) 1527 1.1 christos r = 1; 1528 1.1 christos else if (rtype != label_state) 1529 1.1 christos as_bad (_("Invalid record type for format B1")); 1530 1.1 christos 1531 1.1 christos byte = (UNW_B1 | (r << 5) | (label & 0x1f)); 1532 1.1 christos (*f) (1, &byte, NULL); 1533 1.1 christos } 1534 1.1 christos 1535 1.1 christos static void 1536 1.1 christos output_B2_format (vbyte_func f, unsigned long ecount, unsigned long t) 1537 1.1 christos { 1538 1.1 christos char bytes[20]; 1539 1.1 christos int count = 1; 1540 1.1 christos if (ecount > 0x1f) 1541 1.1 christos { 1542 1.1 christos output_B3_format (f, ecount, t); 1543 1.1 christos return; 1544 1.1 christos } 1545 1.1 christos bytes[0] = (UNW_B2 | (ecount & 0x1f)); 1546 1.1 christos count += output_leb128 (bytes + 1, t, 0); 1547 1.1 christos (*f) (count, bytes, NULL); 1548 1.1 christos } 1549 1.1 christos 1550 1.1 christos static void 1551 1.1 christos output_B3_format (vbyte_func f, unsigned long ecount, unsigned long t) 1552 1.1 christos { 1553 1.1 christos char bytes[20]; 1554 1.1 christos int count = 1; 1555 1.1 christos if (ecount <= 0x1f) 1556 1.1 christos { 1557 1.1 christos output_B2_format (f, ecount, t); 1558 1.1 christos return; 1559 1.1 christos } 1560 1.1 christos bytes[0] = UNW_B3; 1561 1.1 christos count += output_leb128 (bytes + 1, t, 0); 1562 1.1 christos count += output_leb128 (bytes + count, ecount, 0); 1563 1.1 christos (*f) (count, bytes, NULL); 1564 1.1 christos } 1565 1.1 christos 1566 1.1 christos static void 1567 1.1 christos output_B4_format (vbyte_func f, unw_record_type rtype, unsigned long label) 1568 1.1 christos { 1569 1.1 christos char bytes[20]; 1570 1.1 christos int r = 0; 1571 1.1 christos int count = 1; 1572 1.1 christos if (label <= 0x1f) 1573 1.1 christos { 1574 1.1 christos output_B1_format (f, rtype, label); 1575 1.1 christos return; 1576 1.1 christos } 1577 1.1 christos 1578 1.1 christos if (rtype == copy_state) 1579 1.1 christos r = 1; 1580 1.1 christos else if (rtype != label_state) 1581 1.1 christos as_bad (_("Invalid record type for format B1")); 1582 1.1 christos 1583 1.1 christos bytes[0] = (UNW_B4 | (r << 3)); 1584 1.1 christos count += output_leb128 (bytes + 1, label, 0); 1585 1.1 christos (*f) (count, bytes, NULL); 1586 1.1 christos } 1587 1.1 christos 1588 1.1 christos static char 1589 1.1 christos format_ab_reg (int ab, int reg) 1590 1.1 christos { 1591 1.1 christos int ret; 1592 1.1 christos ab = (ab & 3); 1593 1.1 christos reg = (reg & 0x1f); 1594 1.1 christos ret = (ab << 5) | reg; 1595 1.1 christos return ret; 1596 1.1 christos } 1597 1.1 christos 1598 1.1 christos static void 1599 1.1 christos output_X1_format (vbyte_func f, 1600 1.1 christos unw_record_type rtype, 1601 1.1 christos int ab, 1602 1.1 christos int reg, 1603 1.1 christos unsigned long t, 1604 1.1 christos unsigned long w1) 1605 1.1 christos { 1606 1.1 christos char bytes[20]; 1607 1.1 christos int r = 0; 1608 1.1 christos int count = 2; 1609 1.1 christos bytes[0] = UNW_X1; 1610 1.1 christos 1611 1.1 christos if (rtype == spill_sprel) 1612 1.1 christos r = 1; 1613 1.1 christos else if (rtype != spill_psprel) 1614 1.1 christos as_bad (_("Invalid record type for format X1")); 1615 1.1 christos bytes[1] = ((r << 7) | format_ab_reg (ab, reg)); 1616 1.1 christos count += output_leb128 (bytes + 2, t, 0); 1617 1.1 christos count += output_leb128 (bytes + count, w1, 0); 1618 1.1 christos (*f) (count, bytes, NULL); 1619 1.1 christos } 1620 1.1 christos 1621 1.1 christos static void 1622 1.1 christos output_X2_format (vbyte_func f, 1623 1.1 christos int ab, 1624 1.1 christos int reg, 1625 1.1 christos int x, 1626 1.1 christos int y, 1627 1.1 christos int treg, 1628 1.1 christos unsigned long t) 1629 1.1 christos { 1630 1.1 christos char bytes[20]; 1631 1.1 christos int count = 3; 1632 1.1 christos bytes[0] = UNW_X2; 1633 1.1 christos bytes[1] = (((x & 1) << 7) | format_ab_reg (ab, reg)); 1634 1.1 christos bytes[2] = (((y & 1) << 7) | (treg & 0x7f)); 1635 1.1 christos count += output_leb128 (bytes + 3, t, 0); 1636 1.1 christos (*f) (count, bytes, NULL); 1637 1.1 christos } 1638 1.1 christos 1639 1.1 christos static void 1640 1.1 christos output_X3_format (vbyte_func f, 1641 1.1 christos unw_record_type rtype, 1642 1.1 christos int qp, 1643 1.1 christos int ab, 1644 1.1 christos int reg, 1645 1.1 christos unsigned long t, 1646 1.1 christos unsigned long w1) 1647 1.1 christos { 1648 1.1 christos char bytes[20]; 1649 1.1 christos int r = 0; 1650 1.1 christos int count = 3; 1651 1.1 christos bytes[0] = UNW_X3; 1652 1.1 christos 1653 1.1 christos if (rtype == spill_sprel_p) 1654 1.1 christos r = 1; 1655 1.1 christos else if (rtype != spill_psprel_p) 1656 1.1 christos as_bad (_("Invalid record type for format X3")); 1657 1.1 christos bytes[1] = ((r << 7) | (qp & 0x3f)); 1658 1.1 christos bytes[2] = format_ab_reg (ab, reg); 1659 1.1 christos count += output_leb128 (bytes + 3, t, 0); 1660 1.1 christos count += output_leb128 (bytes + count, w1, 0); 1661 1.1 christos (*f) (count, bytes, NULL); 1662 1.1 christos } 1663 1.1 christos 1664 1.1 christos static void 1665 1.1 christos output_X4_format (vbyte_func f, 1666 1.1 christos int qp, 1667 1.1 christos int ab, 1668 1.1 christos int reg, 1669 1.1 christos int x, 1670 1.1 christos int y, 1671 1.1 christos int treg, 1672 1.1 christos unsigned long t) 1673 1.1 christos { 1674 1.1 christos char bytes[20]; 1675 1.1 christos int count = 4; 1676 1.1 christos bytes[0] = UNW_X4; 1677 1.1 christos bytes[1] = (qp & 0x3f); 1678 1.1 christos bytes[2] = (((x & 1) << 7) | format_ab_reg (ab, reg)); 1679 1.1 christos bytes[3] = (((y & 1) << 7) | (treg & 0x7f)); 1680 1.1 christos count += output_leb128 (bytes + 4, t, 0); 1681 1.1 christos (*f) (count, bytes, NULL); 1682 1.1 christos } 1683 1.1 christos 1684 1.1 christos /* This function checks whether there are any outstanding .save-s and 1685 1.1 christos discards them if so. */ 1686 1.1 christos 1687 1.1 christos static void 1688 1.1 christos check_pending_save (void) 1689 1.1 christos { 1690 1.1 christos if (unwind.pending_saves) 1691 1.1 christos { 1692 1.1 christos unw_rec_list *cur, *prev; 1693 1.1 christos 1694 1.1 christos as_warn (_("Previous .save incomplete")); 1695 1.1 christos for (cur = unwind.list, prev = NULL; cur; ) 1696 1.1 christos if (&cur->r.record.p == unwind.pending_saves) 1697 1.1 christos { 1698 1.1 christos if (prev) 1699 1.1 christos prev->next = cur->next; 1700 1.1 christos else 1701 1.1 christos unwind.list = cur->next; 1702 1.1 christos if (cur == unwind.tail) 1703 1.1 christos unwind.tail = prev; 1704 1.1 christos if (cur == unwind.current_entry) 1705 1.1 christos unwind.current_entry = cur->next; 1706 1.1 christos /* Don't free the first discarded record, it's being used as 1707 1.1 christos terminator for (currently) br_gr and gr_gr processing, and 1708 1.1 christos also prevents leaving a dangling pointer to it in its 1709 1.1 christos predecessor. */ 1710 1.1 christos cur->r.record.p.grmask = 0; 1711 1.1 christos cur->r.record.p.brmask = 0; 1712 1.1 christos cur->r.record.p.frmask = 0; 1713 1.1 christos prev = cur->r.record.p.next; 1714 1.1 christos cur->r.record.p.next = NULL; 1715 1.1 christos cur = prev; 1716 1.1 christos break; 1717 1.1 christos } 1718 1.1 christos else 1719 1.1 christos { 1720 1.1 christos prev = cur; 1721 1.1 christos cur = cur->next; 1722 1.1 christos } 1723 1.1 christos while (cur) 1724 1.1 christos { 1725 1.1 christos prev = cur; 1726 1.1 christos cur = cur->r.record.p.next; 1727 1.1 christos free (prev); 1728 1.1 christos } 1729 1.1 christos unwind.pending_saves = NULL; 1730 1.1 christos } 1731 1.1 christos } 1732 1.1 christos 1733 1.1 christos /* This function allocates a record list structure, and initializes fields. */ 1734 1.1 christos 1735 1.1 christos static unw_rec_list * 1736 1.1 christos alloc_record (unw_record_type t) 1737 1.1 christos { 1738 1.1 christos unw_rec_list *ptr; 1739 1.5 christos ptr = XNEW (unw_rec_list); 1740 1.1 christos memset (ptr, 0, sizeof (*ptr)); 1741 1.1 christos ptr->slot_number = SLOT_NUM_NOT_SET; 1742 1.1 christos ptr->r.type = t; 1743 1.1 christos return ptr; 1744 1.1 christos } 1745 1.1 christos 1746 1.1 christos /* Dummy unwind record used for calculating the length of the last prologue or 1747 1.1 christos body region. */ 1748 1.1 christos 1749 1.1 christos static unw_rec_list * 1750 1.1 christos output_endp (void) 1751 1.1 christos { 1752 1.1 christos unw_rec_list *ptr = alloc_record (endp); 1753 1.1 christos return ptr; 1754 1.1 christos } 1755 1.1 christos 1756 1.1 christos static unw_rec_list * 1757 1.1 christos output_prologue (void) 1758 1.1 christos { 1759 1.1 christos unw_rec_list *ptr = alloc_record (prologue); 1760 1.1 christos return ptr; 1761 1.1 christos } 1762 1.1 christos 1763 1.1 christos static unw_rec_list * 1764 1.1 christos output_prologue_gr (unsigned int saved_mask, unsigned int reg) 1765 1.1 christos { 1766 1.1 christos unw_rec_list *ptr = alloc_record (prologue_gr); 1767 1.1 christos ptr->r.record.r.grmask = saved_mask; 1768 1.1 christos ptr->r.record.r.grsave = reg; 1769 1.1 christos return ptr; 1770 1.1 christos } 1771 1.1 christos 1772 1.1 christos static unw_rec_list * 1773 1.1 christos output_body (void) 1774 1.1 christos { 1775 1.1 christos unw_rec_list *ptr = alloc_record (body); 1776 1.1 christos return ptr; 1777 1.1 christos } 1778 1.1 christos 1779 1.1 christos static unw_rec_list * 1780 1.1 christos output_mem_stack_f (unsigned int size) 1781 1.1 christos { 1782 1.1 christos unw_rec_list *ptr = alloc_record (mem_stack_f); 1783 1.1 christos ptr->r.record.p.size = size; 1784 1.1 christos return ptr; 1785 1.1 christos } 1786 1.1 christos 1787 1.1 christos static unw_rec_list * 1788 1.1 christos output_mem_stack_v (void) 1789 1.1 christos { 1790 1.1 christos unw_rec_list *ptr = alloc_record (mem_stack_v); 1791 1.1 christos return ptr; 1792 1.1 christos } 1793 1.1 christos 1794 1.1 christos static unw_rec_list * 1795 1.1 christos output_psp_gr (unsigned int gr) 1796 1.1 christos { 1797 1.1 christos unw_rec_list *ptr = alloc_record (psp_gr); 1798 1.1 christos ptr->r.record.p.r.gr = gr; 1799 1.1 christos return ptr; 1800 1.1 christos } 1801 1.1 christos 1802 1.1 christos static unw_rec_list * 1803 1.1 christos output_psp_sprel (unsigned int offset) 1804 1.1 christos { 1805 1.1 christos unw_rec_list *ptr = alloc_record (psp_sprel); 1806 1.1 christos ptr->r.record.p.off.sp = offset / 4; 1807 1.1 christos return ptr; 1808 1.1 christos } 1809 1.1 christos 1810 1.1 christos static unw_rec_list * 1811 1.1 christos output_rp_when (void) 1812 1.1 christos { 1813 1.1 christos unw_rec_list *ptr = alloc_record (rp_when); 1814 1.1 christos return ptr; 1815 1.1 christos } 1816 1.1 christos 1817 1.1 christos static unw_rec_list * 1818 1.1 christos output_rp_gr (unsigned int gr) 1819 1.1 christos { 1820 1.1 christos unw_rec_list *ptr = alloc_record (rp_gr); 1821 1.1 christos ptr->r.record.p.r.gr = gr; 1822 1.1 christos return ptr; 1823 1.1 christos } 1824 1.1 christos 1825 1.1 christos static unw_rec_list * 1826 1.1 christos output_rp_br (unsigned int br) 1827 1.1 christos { 1828 1.1 christos unw_rec_list *ptr = alloc_record (rp_br); 1829 1.1 christos ptr->r.record.p.r.br = br; 1830 1.1 christos return ptr; 1831 1.1 christos } 1832 1.1 christos 1833 1.1 christos static unw_rec_list * 1834 1.1 christos output_rp_psprel (unsigned int offset) 1835 1.1 christos { 1836 1.1 christos unw_rec_list *ptr = alloc_record (rp_psprel); 1837 1.1 christos ptr->r.record.p.off.psp = ENCODED_PSP_OFFSET (offset); 1838 1.1 christos return ptr; 1839 1.1 christos } 1840 1.1 christos 1841 1.1 christos static unw_rec_list * 1842 1.1 christos output_rp_sprel (unsigned int offset) 1843 1.1 christos { 1844 1.1 christos unw_rec_list *ptr = alloc_record (rp_sprel); 1845 1.1 christos ptr->r.record.p.off.sp = offset / 4; 1846 1.1 christos return ptr; 1847 1.1 christos } 1848 1.1 christos 1849 1.1 christos static unw_rec_list * 1850 1.1 christos output_pfs_when (void) 1851 1.1 christos { 1852 1.1 christos unw_rec_list *ptr = alloc_record (pfs_when); 1853 1.1 christos return ptr; 1854 1.1 christos } 1855 1.1 christos 1856 1.1 christos static unw_rec_list * 1857 1.1 christos output_pfs_gr (unsigned int gr) 1858 1.1 christos { 1859 1.1 christos unw_rec_list *ptr = alloc_record (pfs_gr); 1860 1.1 christos ptr->r.record.p.r.gr = gr; 1861 1.1 christos return ptr; 1862 1.1 christos } 1863 1.1 christos 1864 1.1 christos static unw_rec_list * 1865 1.1 christos output_pfs_psprel (unsigned int offset) 1866 1.1 christos { 1867 1.1 christos unw_rec_list *ptr = alloc_record (pfs_psprel); 1868 1.1 christos ptr->r.record.p.off.psp = ENCODED_PSP_OFFSET (offset); 1869 1.1 christos return ptr; 1870 1.1 christos } 1871 1.1 christos 1872 1.1 christos static unw_rec_list * 1873 1.1 christos output_pfs_sprel (unsigned int offset) 1874 1.1 christos { 1875 1.1 christos unw_rec_list *ptr = alloc_record (pfs_sprel); 1876 1.1 christos ptr->r.record.p.off.sp = offset / 4; 1877 1.1 christos return ptr; 1878 1.1 christos } 1879 1.1 christos 1880 1.1 christos static unw_rec_list * 1881 1.1 christos output_preds_when (void) 1882 1.1 christos { 1883 1.1 christos unw_rec_list *ptr = alloc_record (preds_when); 1884 1.1 christos return ptr; 1885 1.1 christos } 1886 1.1 christos 1887 1.1 christos static unw_rec_list * 1888 1.1 christos output_preds_gr (unsigned int gr) 1889 1.1 christos { 1890 1.1 christos unw_rec_list *ptr = alloc_record (preds_gr); 1891 1.1 christos ptr->r.record.p.r.gr = gr; 1892 1.1 christos return ptr; 1893 1.1 christos } 1894 1.1 christos 1895 1.1 christos static unw_rec_list * 1896 1.1 christos output_preds_psprel (unsigned int offset) 1897 1.1 christos { 1898 1.1 christos unw_rec_list *ptr = alloc_record (preds_psprel); 1899 1.1 christos ptr->r.record.p.off.psp = ENCODED_PSP_OFFSET (offset); 1900 1.1 christos return ptr; 1901 1.1 christos } 1902 1.1 christos 1903 1.1 christos static unw_rec_list * 1904 1.1 christos output_preds_sprel (unsigned int offset) 1905 1.1 christos { 1906 1.1 christos unw_rec_list *ptr = alloc_record (preds_sprel); 1907 1.1 christos ptr->r.record.p.off.sp = offset / 4; 1908 1.1 christos return ptr; 1909 1.1 christos } 1910 1.1 christos 1911 1.1 christos static unw_rec_list * 1912 1.1 christos output_fr_mem (unsigned int mask) 1913 1.1 christos { 1914 1.1 christos unw_rec_list *ptr = alloc_record (fr_mem); 1915 1.1 christos unw_rec_list *cur = ptr; 1916 1.1 christos 1917 1.1 christos ptr->r.record.p.frmask = mask; 1918 1.1 christos unwind.pending_saves = &ptr->r.record.p; 1919 1.1 christos for (;;) 1920 1.1 christos { 1921 1.1 christos unw_rec_list *prev = cur; 1922 1.1 christos 1923 1.1 christos /* Clear least significant set bit. */ 1924 1.1 christos mask &= ~(mask & (~mask + 1)); 1925 1.1 christos if (!mask) 1926 1.1 christos return ptr; 1927 1.1 christos cur = alloc_record (fr_mem); 1928 1.1 christos cur->r.record.p.frmask = mask; 1929 1.1 christos /* Retain only least significant bit. */ 1930 1.1 christos prev->r.record.p.frmask ^= mask; 1931 1.1 christos prev->r.record.p.next = cur; 1932 1.1 christos } 1933 1.1 christos } 1934 1.1 christos 1935 1.1 christos static unw_rec_list * 1936 1.1 christos output_frgr_mem (unsigned int gr_mask, unsigned int fr_mask) 1937 1.1 christos { 1938 1.1 christos unw_rec_list *ptr = alloc_record (frgr_mem); 1939 1.1 christos unw_rec_list *cur = ptr; 1940 1.1 christos 1941 1.1 christos unwind.pending_saves = &cur->r.record.p; 1942 1.1 christos cur->r.record.p.frmask = fr_mask; 1943 1.1 christos while (fr_mask) 1944 1.1 christos { 1945 1.1 christos unw_rec_list *prev = cur; 1946 1.1 christos 1947 1.1 christos /* Clear least significant set bit. */ 1948 1.1 christos fr_mask &= ~(fr_mask & (~fr_mask + 1)); 1949 1.1 christos if (!gr_mask && !fr_mask) 1950 1.1 christos return ptr; 1951 1.1 christos cur = alloc_record (frgr_mem); 1952 1.1 christos cur->r.record.p.frmask = fr_mask; 1953 1.1 christos /* Retain only least significant bit. */ 1954 1.1 christos prev->r.record.p.frmask ^= fr_mask; 1955 1.1 christos prev->r.record.p.next = cur; 1956 1.1 christos } 1957 1.1 christos cur->r.record.p.grmask = gr_mask; 1958 1.1 christos for (;;) 1959 1.1 christos { 1960 1.1 christos unw_rec_list *prev = cur; 1961 1.1 christos 1962 1.1 christos /* Clear least significant set bit. */ 1963 1.1 christos gr_mask &= ~(gr_mask & (~gr_mask + 1)); 1964 1.1 christos if (!gr_mask) 1965 1.1 christos return ptr; 1966 1.1 christos cur = alloc_record (frgr_mem); 1967 1.1 christos cur->r.record.p.grmask = gr_mask; 1968 1.1 christos /* Retain only least significant bit. */ 1969 1.1 christos prev->r.record.p.grmask ^= gr_mask; 1970 1.1 christos prev->r.record.p.next = cur; 1971 1.1 christos } 1972 1.1 christos } 1973 1.1 christos 1974 1.1 christos static unw_rec_list * 1975 1.1 christos output_gr_gr (unsigned int mask, unsigned int reg) 1976 1.1 christos { 1977 1.1 christos unw_rec_list *ptr = alloc_record (gr_gr); 1978 1.1 christos unw_rec_list *cur = ptr; 1979 1.1 christos 1980 1.1 christos ptr->r.record.p.grmask = mask; 1981 1.1 christos ptr->r.record.p.r.gr = reg; 1982 1.1 christos unwind.pending_saves = &ptr->r.record.p; 1983 1.1 christos for (;;) 1984 1.1 christos { 1985 1.1 christos unw_rec_list *prev = cur; 1986 1.1 christos 1987 1.1 christos /* Clear least significant set bit. */ 1988 1.1 christos mask &= ~(mask & (~mask + 1)); 1989 1.1 christos if (!mask) 1990 1.1 christos return ptr; 1991 1.1 christos cur = alloc_record (gr_gr); 1992 1.1 christos cur->r.record.p.grmask = mask; 1993 1.1 christos /* Indicate this record shouldn't be output. */ 1994 1.1 christos cur->r.record.p.r.gr = REG_NUM; 1995 1.1 christos /* Retain only least significant bit. */ 1996 1.1 christos prev->r.record.p.grmask ^= mask; 1997 1.1 christos prev->r.record.p.next = cur; 1998 1.1 christos } 1999 1.1 christos } 2000 1.1 christos 2001 1.1 christos static unw_rec_list * 2002 1.1 christos output_gr_mem (unsigned int mask) 2003 1.1 christos { 2004 1.1 christos unw_rec_list *ptr = alloc_record (gr_mem); 2005 1.1 christos unw_rec_list *cur = ptr; 2006 1.1 christos 2007 1.1 christos ptr->r.record.p.grmask = mask; 2008 1.1 christos unwind.pending_saves = &ptr->r.record.p; 2009 1.1 christos for (;;) 2010 1.1 christos { 2011 1.1 christos unw_rec_list *prev = cur; 2012 1.1 christos 2013 1.1 christos /* Clear least significant set bit. */ 2014 1.1 christos mask &= ~(mask & (~mask + 1)); 2015 1.1 christos if (!mask) 2016 1.1 christos return ptr; 2017 1.1 christos cur = alloc_record (gr_mem); 2018 1.1 christos cur->r.record.p.grmask = mask; 2019 1.1 christos /* Retain only least significant bit. */ 2020 1.1 christos prev->r.record.p.grmask ^= mask; 2021 1.1 christos prev->r.record.p.next = cur; 2022 1.1 christos } 2023 1.1 christos } 2024 1.1 christos 2025 1.1 christos static unw_rec_list * 2026 1.1 christos output_br_mem (unsigned int mask) 2027 1.1 christos { 2028 1.1 christos unw_rec_list *ptr = alloc_record (br_mem); 2029 1.1 christos unw_rec_list *cur = ptr; 2030 1.1 christos 2031 1.1 christos ptr->r.record.p.brmask = mask; 2032 1.1 christos unwind.pending_saves = &ptr->r.record.p; 2033 1.1 christos for (;;) 2034 1.1 christos { 2035 1.1 christos unw_rec_list *prev = cur; 2036 1.1 christos 2037 1.1 christos /* Clear least significant set bit. */ 2038 1.1 christos mask &= ~(mask & (~mask + 1)); 2039 1.1 christos if (!mask) 2040 1.1 christos return ptr; 2041 1.1 christos cur = alloc_record (br_mem); 2042 1.1 christos cur->r.record.p.brmask = mask; 2043 1.1 christos /* Retain only least significant bit. */ 2044 1.1 christos prev->r.record.p.brmask ^= mask; 2045 1.1 christos prev->r.record.p.next = cur; 2046 1.1 christos } 2047 1.1 christos } 2048 1.1 christos 2049 1.1 christos static unw_rec_list * 2050 1.1 christos output_br_gr (unsigned int mask, unsigned int reg) 2051 1.1 christos { 2052 1.1 christos unw_rec_list *ptr = alloc_record (br_gr); 2053 1.1 christos unw_rec_list *cur = ptr; 2054 1.1 christos 2055 1.1 christos ptr->r.record.p.brmask = mask; 2056 1.1 christos ptr->r.record.p.r.gr = reg; 2057 1.1 christos unwind.pending_saves = &ptr->r.record.p; 2058 1.1 christos for (;;) 2059 1.1 christos { 2060 1.1 christos unw_rec_list *prev = cur; 2061 1.1 christos 2062 1.1 christos /* Clear least significant set bit. */ 2063 1.1 christos mask &= ~(mask & (~mask + 1)); 2064 1.1 christos if (!mask) 2065 1.1 christos return ptr; 2066 1.1 christos cur = alloc_record (br_gr); 2067 1.1 christos cur->r.record.p.brmask = mask; 2068 1.1 christos /* Indicate this record shouldn't be output. */ 2069 1.1 christos cur->r.record.p.r.gr = REG_NUM; 2070 1.1 christos /* Retain only least significant bit. */ 2071 1.1 christos prev->r.record.p.brmask ^= mask; 2072 1.1 christos prev->r.record.p.next = cur; 2073 1.1 christos } 2074 1.1 christos } 2075 1.1 christos 2076 1.1 christos static unw_rec_list * 2077 1.1 christos output_spill_base (unsigned int offset) 2078 1.1 christos { 2079 1.1 christos unw_rec_list *ptr = alloc_record (spill_base); 2080 1.1 christos ptr->r.record.p.off.psp = ENCODED_PSP_OFFSET (offset); 2081 1.1 christos return ptr; 2082 1.1 christos } 2083 1.1 christos 2084 1.1 christos static unw_rec_list * 2085 1.1 christos output_unat_when (void) 2086 1.1 christos { 2087 1.1 christos unw_rec_list *ptr = alloc_record (unat_when); 2088 1.1 christos return ptr; 2089 1.1 christos } 2090 1.1 christos 2091 1.1 christos static unw_rec_list * 2092 1.1 christos output_unat_gr (unsigned int gr) 2093 1.1 christos { 2094 1.1 christos unw_rec_list *ptr = alloc_record (unat_gr); 2095 1.1 christos ptr->r.record.p.r.gr = gr; 2096 1.1 christos return ptr; 2097 1.1 christos } 2098 1.1 christos 2099 1.1 christos static unw_rec_list * 2100 1.1 christos output_unat_psprel (unsigned int offset) 2101 1.1 christos { 2102 1.1 christos unw_rec_list *ptr = alloc_record (unat_psprel); 2103 1.1 christos ptr->r.record.p.off.psp = ENCODED_PSP_OFFSET (offset); 2104 1.1 christos return ptr; 2105 1.1 christos } 2106 1.1 christos 2107 1.1 christos static unw_rec_list * 2108 1.1 christos output_unat_sprel (unsigned int offset) 2109 1.1 christos { 2110 1.1 christos unw_rec_list *ptr = alloc_record (unat_sprel); 2111 1.1 christos ptr->r.record.p.off.sp = offset / 4; 2112 1.1 christos return ptr; 2113 1.1 christos } 2114 1.1 christos 2115 1.1 christos static unw_rec_list * 2116 1.1 christos output_lc_when (void) 2117 1.1 christos { 2118 1.1 christos unw_rec_list *ptr = alloc_record (lc_when); 2119 1.1 christos return ptr; 2120 1.1 christos } 2121 1.1 christos 2122 1.1 christos static unw_rec_list * 2123 1.1 christos output_lc_gr (unsigned int gr) 2124 1.1 christos { 2125 1.1 christos unw_rec_list *ptr = alloc_record (lc_gr); 2126 1.1 christos ptr->r.record.p.r.gr = gr; 2127 1.1 christos return ptr; 2128 1.1 christos } 2129 1.1 christos 2130 1.1 christos static unw_rec_list * 2131 1.1 christos output_lc_psprel (unsigned int offset) 2132 1.1 christos { 2133 1.1 christos unw_rec_list *ptr = alloc_record (lc_psprel); 2134 1.1 christos ptr->r.record.p.off.psp = ENCODED_PSP_OFFSET (offset); 2135 1.1 christos return ptr; 2136 1.1 christos } 2137 1.1 christos 2138 1.1 christos static unw_rec_list * 2139 1.1 christos output_lc_sprel (unsigned int offset) 2140 1.1 christos { 2141 1.1 christos unw_rec_list *ptr = alloc_record (lc_sprel); 2142 1.1 christos ptr->r.record.p.off.sp = offset / 4; 2143 1.1 christos return ptr; 2144 1.1 christos } 2145 1.1 christos 2146 1.1 christos static unw_rec_list * 2147 1.1 christos output_fpsr_when (void) 2148 1.1 christos { 2149 1.1 christos unw_rec_list *ptr = alloc_record (fpsr_when); 2150 1.1 christos return ptr; 2151 1.1 christos } 2152 1.1 christos 2153 1.1 christos static unw_rec_list * 2154 1.1 christos output_fpsr_gr (unsigned int gr) 2155 1.1 christos { 2156 1.1 christos unw_rec_list *ptr = alloc_record (fpsr_gr); 2157 1.1 christos ptr->r.record.p.r.gr = gr; 2158 1.1 christos return ptr; 2159 1.1 christos } 2160 1.1 christos 2161 1.1 christos static unw_rec_list * 2162 1.1 christos output_fpsr_psprel (unsigned int offset) 2163 1.1 christos { 2164 1.1 christos unw_rec_list *ptr = alloc_record (fpsr_psprel); 2165 1.1 christos ptr->r.record.p.off.psp = ENCODED_PSP_OFFSET (offset); 2166 1.1 christos return ptr; 2167 1.1 christos } 2168 1.1 christos 2169 1.1 christos static unw_rec_list * 2170 1.1 christos output_fpsr_sprel (unsigned int offset) 2171 1.1 christos { 2172 1.1 christos unw_rec_list *ptr = alloc_record (fpsr_sprel); 2173 1.1 christos ptr->r.record.p.off.sp = offset / 4; 2174 1.1 christos return ptr; 2175 1.1 christos } 2176 1.1 christos 2177 1.1 christos static unw_rec_list * 2178 1.1 christos output_priunat_when_gr (void) 2179 1.1 christos { 2180 1.1 christos unw_rec_list *ptr = alloc_record (priunat_when_gr); 2181 1.1 christos return ptr; 2182 1.1 christos } 2183 1.1 christos 2184 1.1 christos static unw_rec_list * 2185 1.1 christos output_priunat_when_mem (void) 2186 1.1 christos { 2187 1.1 christos unw_rec_list *ptr = alloc_record (priunat_when_mem); 2188 1.1 christos return ptr; 2189 1.1 christos } 2190 1.1 christos 2191 1.1 christos static unw_rec_list * 2192 1.1 christos output_priunat_gr (unsigned int gr) 2193 1.1 christos { 2194 1.1 christos unw_rec_list *ptr = alloc_record (priunat_gr); 2195 1.1 christos ptr->r.record.p.r.gr = gr; 2196 1.1 christos return ptr; 2197 1.1 christos } 2198 1.1 christos 2199 1.1 christos static unw_rec_list * 2200 1.1 christos output_priunat_psprel (unsigned int offset) 2201 1.1 christos { 2202 1.1 christos unw_rec_list *ptr = alloc_record (priunat_psprel); 2203 1.1 christos ptr->r.record.p.off.psp = ENCODED_PSP_OFFSET (offset); 2204 1.1 christos return ptr; 2205 1.1 christos } 2206 1.1 christos 2207 1.1 christos static unw_rec_list * 2208 1.1 christos output_priunat_sprel (unsigned int offset) 2209 1.1 christos { 2210 1.1 christos unw_rec_list *ptr = alloc_record (priunat_sprel); 2211 1.1 christos ptr->r.record.p.off.sp = offset / 4; 2212 1.1 christos return ptr; 2213 1.1 christos } 2214 1.1 christos 2215 1.1 christos static unw_rec_list * 2216 1.1 christos output_bsp_when (void) 2217 1.1 christos { 2218 1.1 christos unw_rec_list *ptr = alloc_record (bsp_when); 2219 1.1 christos return ptr; 2220 1.1 christos } 2221 1.1 christos 2222 1.1 christos static unw_rec_list * 2223 1.1 christos output_bsp_gr (unsigned int gr) 2224 1.1 christos { 2225 1.1 christos unw_rec_list *ptr = alloc_record (bsp_gr); 2226 1.1 christos ptr->r.record.p.r.gr = gr; 2227 1.1 christos return ptr; 2228 1.1 christos } 2229 1.1 christos 2230 1.1 christos static unw_rec_list * 2231 1.1 christos output_bsp_psprel (unsigned int offset) 2232 1.1 christos { 2233 1.1 christos unw_rec_list *ptr = alloc_record (bsp_psprel); 2234 1.1 christos ptr->r.record.p.off.psp = ENCODED_PSP_OFFSET (offset); 2235 1.1 christos return ptr; 2236 1.1 christos } 2237 1.1 christos 2238 1.1 christos static unw_rec_list * 2239 1.1 christos output_bsp_sprel (unsigned int offset) 2240 1.1 christos { 2241 1.1 christos unw_rec_list *ptr = alloc_record (bsp_sprel); 2242 1.1 christos ptr->r.record.p.off.sp = offset / 4; 2243 1.1 christos return ptr; 2244 1.1 christos } 2245 1.1 christos 2246 1.1 christos static unw_rec_list * 2247 1.1 christos output_bspstore_when (void) 2248 1.1 christos { 2249 1.1 christos unw_rec_list *ptr = alloc_record (bspstore_when); 2250 1.1 christos return ptr; 2251 1.1 christos } 2252 1.1 christos 2253 1.1 christos static unw_rec_list * 2254 1.1 christos output_bspstore_gr (unsigned int gr) 2255 1.1 christos { 2256 1.1 christos unw_rec_list *ptr = alloc_record (bspstore_gr); 2257 1.1 christos ptr->r.record.p.r.gr = gr; 2258 1.1 christos return ptr; 2259 1.1 christos } 2260 1.1 christos 2261 1.1 christos static unw_rec_list * 2262 1.1 christos output_bspstore_psprel (unsigned int offset) 2263 1.1 christos { 2264 1.1 christos unw_rec_list *ptr = alloc_record (bspstore_psprel); 2265 1.1 christos ptr->r.record.p.off.psp = ENCODED_PSP_OFFSET (offset); 2266 1.1 christos return ptr; 2267 1.1 christos } 2268 1.1 christos 2269 1.1 christos static unw_rec_list * 2270 1.1 christos output_bspstore_sprel (unsigned int offset) 2271 1.1 christos { 2272 1.1 christos unw_rec_list *ptr = alloc_record (bspstore_sprel); 2273 1.1 christos ptr->r.record.p.off.sp = offset / 4; 2274 1.1 christos return ptr; 2275 1.1 christos } 2276 1.1 christos 2277 1.1 christos static unw_rec_list * 2278 1.1 christos output_rnat_when (void) 2279 1.1 christos { 2280 1.1 christos unw_rec_list *ptr = alloc_record (rnat_when); 2281 1.1 christos return ptr; 2282 1.1 christos } 2283 1.1 christos 2284 1.1 christos static unw_rec_list * 2285 1.1 christos output_rnat_gr (unsigned int gr) 2286 1.1 christos { 2287 1.1 christos unw_rec_list *ptr = alloc_record (rnat_gr); 2288 1.1 christos ptr->r.record.p.r.gr = gr; 2289 1.1 christos return ptr; 2290 1.1 christos } 2291 1.1 christos 2292 1.1 christos static unw_rec_list * 2293 1.1 christos output_rnat_psprel (unsigned int offset) 2294 1.1 christos { 2295 1.1 christos unw_rec_list *ptr = alloc_record (rnat_psprel); 2296 1.1 christos ptr->r.record.p.off.psp = ENCODED_PSP_OFFSET (offset); 2297 1.1 christos return ptr; 2298 1.1 christos } 2299 1.1 christos 2300 1.1 christos static unw_rec_list * 2301 1.1 christos output_rnat_sprel (unsigned int offset) 2302 1.1 christos { 2303 1.1 christos unw_rec_list *ptr = alloc_record (rnat_sprel); 2304 1.1 christos ptr->r.record.p.off.sp = offset / 4; 2305 1.1 christos return ptr; 2306 1.1 christos } 2307 1.1 christos 2308 1.1 christos static unw_rec_list * 2309 1.1 christos output_unwabi (unsigned long abi, unsigned long context) 2310 1.1 christos { 2311 1.1 christos unw_rec_list *ptr = alloc_record (unwabi); 2312 1.1 christos ptr->r.record.p.abi = abi; 2313 1.1 christos ptr->r.record.p.context = context; 2314 1.1 christos return ptr; 2315 1.1 christos } 2316 1.1 christos 2317 1.1 christos static unw_rec_list * 2318 1.1 christos output_epilogue (unsigned long ecount) 2319 1.1 christos { 2320 1.1 christos unw_rec_list *ptr = alloc_record (epilogue); 2321 1.1 christos ptr->r.record.b.ecount = ecount; 2322 1.1 christos return ptr; 2323 1.1 christos } 2324 1.1 christos 2325 1.1 christos static unw_rec_list * 2326 1.1 christos output_label_state (unsigned long label) 2327 1.1 christos { 2328 1.1 christos unw_rec_list *ptr = alloc_record (label_state); 2329 1.1 christos ptr->r.record.b.label = label; 2330 1.1 christos return ptr; 2331 1.1 christos } 2332 1.1 christos 2333 1.1 christos static unw_rec_list * 2334 1.1 christos output_copy_state (unsigned long label) 2335 1.1 christos { 2336 1.1 christos unw_rec_list *ptr = alloc_record (copy_state); 2337 1.1 christos ptr->r.record.b.label = label; 2338 1.1 christos return ptr; 2339 1.1 christos } 2340 1.1 christos 2341 1.1 christos static unw_rec_list * 2342 1.1 christos output_spill_psprel (unsigned int ab, 2343 1.1 christos unsigned int reg, 2344 1.1 christos unsigned int offset, 2345 1.1 christos unsigned int predicate) 2346 1.1 christos { 2347 1.1 christos unw_rec_list *ptr = alloc_record (predicate ? spill_psprel_p : spill_psprel); 2348 1.1 christos ptr->r.record.x.ab = ab; 2349 1.1 christos ptr->r.record.x.reg = reg; 2350 1.1 christos ptr->r.record.x.where.pspoff = ENCODED_PSP_OFFSET (offset); 2351 1.1 christos ptr->r.record.x.qp = predicate; 2352 1.1 christos return ptr; 2353 1.1 christos } 2354 1.1 christos 2355 1.1 christos static unw_rec_list * 2356 1.1 christos output_spill_sprel (unsigned int ab, 2357 1.1 christos unsigned int reg, 2358 1.1 christos unsigned int offset, 2359 1.1 christos unsigned int predicate) 2360 1.1 christos { 2361 1.1 christos unw_rec_list *ptr = alloc_record (predicate ? spill_sprel_p : spill_sprel); 2362 1.1 christos ptr->r.record.x.ab = ab; 2363 1.1 christos ptr->r.record.x.reg = reg; 2364 1.1 christos ptr->r.record.x.where.spoff = offset / 4; 2365 1.1 christos ptr->r.record.x.qp = predicate; 2366 1.1 christos return ptr; 2367 1.1 christos } 2368 1.1 christos 2369 1.1 christos static unw_rec_list * 2370 1.1 christos output_spill_reg (unsigned int ab, 2371 1.1 christos unsigned int reg, 2372 1.1 christos unsigned int targ_reg, 2373 1.1 christos unsigned int xy, 2374 1.1 christos unsigned int predicate) 2375 1.1 christos { 2376 1.1 christos unw_rec_list *ptr = alloc_record (predicate ? spill_reg_p : spill_reg); 2377 1.1 christos ptr->r.record.x.ab = ab; 2378 1.1 christos ptr->r.record.x.reg = reg; 2379 1.1 christos ptr->r.record.x.where.reg = targ_reg; 2380 1.1 christos ptr->r.record.x.xy = xy; 2381 1.1 christos ptr->r.record.x.qp = predicate; 2382 1.1 christos return ptr; 2383 1.1 christos } 2384 1.1 christos 2385 1.1 christos /* Given a unw_rec_list process the correct format with the 2386 1.1 christos specified function. */ 2387 1.1 christos 2388 1.1 christos static void 2389 1.1 christos process_one_record (unw_rec_list *ptr, vbyte_func f) 2390 1.1 christos { 2391 1.1 christos unsigned int fr_mask, gr_mask; 2392 1.1 christos 2393 1.1 christos switch (ptr->r.type) 2394 1.1 christos { 2395 1.1 christos /* This is a dummy record that takes up no space in the output. */ 2396 1.1 christos case endp: 2397 1.1 christos break; 2398 1.1 christos 2399 1.1 christos case gr_mem: 2400 1.1 christos case fr_mem: 2401 1.1 christos case br_mem: 2402 1.1 christos case frgr_mem: 2403 1.1 christos /* These are taken care of by prologue/prologue_gr. */ 2404 1.1 christos break; 2405 1.1 christos 2406 1.1 christos case prologue_gr: 2407 1.1 christos case prologue: 2408 1.1 christos if (ptr->r.type == prologue_gr) 2409 1.1 christos output_R2_format (f, ptr->r.record.r.grmask, 2410 1.1 christos ptr->r.record.r.grsave, ptr->r.record.r.rlen); 2411 1.1 christos else 2412 1.1 christos output_R1_format (f, ptr->r.type, ptr->r.record.r.rlen); 2413 1.1 christos 2414 1.1 christos /* Output descriptor(s) for union of register spills (if any). */ 2415 1.1 christos gr_mask = ptr->r.record.r.mask.gr_mem; 2416 1.1 christos fr_mask = ptr->r.record.r.mask.fr_mem; 2417 1.1 christos if (fr_mask) 2418 1.1 christos { 2419 1.1 christos if ((fr_mask & ~0xfUL) == 0) 2420 1.1 christos output_P6_format (f, fr_mem, fr_mask); 2421 1.1 christos else 2422 1.1 christos { 2423 1.1 christos output_P5_format (f, gr_mask, fr_mask); 2424 1.1 christos gr_mask = 0; 2425 1.1 christos } 2426 1.1 christos } 2427 1.1 christos if (gr_mask) 2428 1.1 christos output_P6_format (f, gr_mem, gr_mask); 2429 1.1 christos if (ptr->r.record.r.mask.br_mem) 2430 1.1 christos output_P1_format (f, ptr->r.record.r.mask.br_mem); 2431 1.1 christos 2432 1.1 christos /* output imask descriptor if necessary: */ 2433 1.1 christos if (ptr->r.record.r.mask.i) 2434 1.1 christos output_P4_format (f, ptr->r.record.r.mask.i, 2435 1.1 christos ptr->r.record.r.imask_size); 2436 1.1 christos break; 2437 1.1 christos 2438 1.1 christos case body: 2439 1.1 christos output_R1_format (f, ptr->r.type, ptr->r.record.r.rlen); 2440 1.1 christos break; 2441 1.1 christos case mem_stack_f: 2442 1.1 christos case mem_stack_v: 2443 1.1 christos output_P7_format (f, ptr->r.type, ptr->r.record.p.t, 2444 1.1 christos ptr->r.record.p.size); 2445 1.1 christos break; 2446 1.1 christos case psp_gr: 2447 1.1 christos case rp_gr: 2448 1.1 christos case pfs_gr: 2449 1.1 christos case preds_gr: 2450 1.1 christos case unat_gr: 2451 1.1 christos case lc_gr: 2452 1.1 christos case fpsr_gr: 2453 1.1 christos case priunat_gr: 2454 1.1 christos case bsp_gr: 2455 1.1 christos case bspstore_gr: 2456 1.1 christos case rnat_gr: 2457 1.1 christos output_P3_format (f, ptr->r.type, ptr->r.record.p.r.gr); 2458 1.1 christos break; 2459 1.1 christos case rp_br: 2460 1.1 christos output_P3_format (f, rp_br, ptr->r.record.p.r.br); 2461 1.1 christos break; 2462 1.1 christos case psp_sprel: 2463 1.1 christos output_P7_format (f, psp_sprel, ptr->r.record.p.off.sp, 0); 2464 1.1 christos break; 2465 1.1 christos case rp_when: 2466 1.1 christos case pfs_when: 2467 1.1 christos case preds_when: 2468 1.1 christos case unat_when: 2469 1.1 christos case lc_when: 2470 1.1 christos case fpsr_when: 2471 1.1 christos output_P7_format (f, ptr->r.type, ptr->r.record.p.t, 0); 2472 1.1 christos break; 2473 1.1 christos case rp_psprel: 2474 1.1 christos case pfs_psprel: 2475 1.1 christos case preds_psprel: 2476 1.1 christos case unat_psprel: 2477 1.1 christos case lc_psprel: 2478 1.1 christos case fpsr_psprel: 2479 1.1 christos case spill_base: 2480 1.1 christos output_P7_format (f, ptr->r.type, ptr->r.record.p.off.psp, 0); 2481 1.1 christos break; 2482 1.1 christos case rp_sprel: 2483 1.1 christos case pfs_sprel: 2484 1.1 christos case preds_sprel: 2485 1.1 christos case unat_sprel: 2486 1.1 christos case lc_sprel: 2487 1.1 christos case fpsr_sprel: 2488 1.1 christos case priunat_sprel: 2489 1.1 christos case bsp_sprel: 2490 1.1 christos case bspstore_sprel: 2491 1.1 christos case rnat_sprel: 2492 1.1 christos output_P8_format (f, ptr->r.type, ptr->r.record.p.off.sp); 2493 1.1 christos break; 2494 1.1 christos case gr_gr: 2495 1.1 christos if (ptr->r.record.p.r.gr < REG_NUM) 2496 1.1 christos { 2497 1.1 christos const unw_rec_list *cur = ptr; 2498 1.1 christos 2499 1.1 christos gr_mask = cur->r.record.p.grmask; 2500 1.1 christos while ((cur = cur->r.record.p.next) != NULL) 2501 1.1 christos gr_mask |= cur->r.record.p.grmask; 2502 1.1 christos output_P9_format (f, gr_mask, ptr->r.record.p.r.gr); 2503 1.1 christos } 2504 1.1 christos break; 2505 1.1 christos case br_gr: 2506 1.1 christos if (ptr->r.record.p.r.gr < REG_NUM) 2507 1.1 christos { 2508 1.1 christos const unw_rec_list *cur = ptr; 2509 1.1 christos 2510 1.1 christos gr_mask = cur->r.record.p.brmask; 2511 1.1 christos while ((cur = cur->r.record.p.next) != NULL) 2512 1.1 christos gr_mask |= cur->r.record.p.brmask; 2513 1.1 christos output_P2_format (f, gr_mask, ptr->r.record.p.r.gr); 2514 1.1 christos } 2515 1.1 christos break; 2516 1.1 christos case spill_mask: 2517 1.1 christos as_bad (_("spill_mask record unimplemented.")); 2518 1.1 christos break; 2519 1.1 christos case priunat_when_gr: 2520 1.1 christos case priunat_when_mem: 2521 1.1 christos case bsp_when: 2522 1.1 christos case bspstore_when: 2523 1.1 christos case rnat_when: 2524 1.1 christos output_P8_format (f, ptr->r.type, ptr->r.record.p.t); 2525 1.1 christos break; 2526 1.1 christos case priunat_psprel: 2527 1.1 christos case bsp_psprel: 2528 1.1 christos case bspstore_psprel: 2529 1.1 christos case rnat_psprel: 2530 1.1 christos output_P8_format (f, ptr->r.type, ptr->r.record.p.off.psp); 2531 1.1 christos break; 2532 1.1 christos case unwabi: 2533 1.1 christos output_P10_format (f, ptr->r.record.p.abi, ptr->r.record.p.context); 2534 1.1 christos break; 2535 1.1 christos case epilogue: 2536 1.1 christos output_B3_format (f, ptr->r.record.b.ecount, ptr->r.record.b.t); 2537 1.1 christos break; 2538 1.1 christos case label_state: 2539 1.1 christos case copy_state: 2540 1.1 christos output_B4_format (f, ptr->r.type, ptr->r.record.b.label); 2541 1.1 christos break; 2542 1.1 christos case spill_psprel: 2543 1.1 christos output_X1_format (f, ptr->r.type, ptr->r.record.x.ab, 2544 1.1 christos ptr->r.record.x.reg, ptr->r.record.x.t, 2545 1.1 christos ptr->r.record.x.where.pspoff); 2546 1.1 christos break; 2547 1.1 christos case spill_sprel: 2548 1.1 christos output_X1_format (f, ptr->r.type, ptr->r.record.x.ab, 2549 1.1 christos ptr->r.record.x.reg, ptr->r.record.x.t, 2550 1.1 christos ptr->r.record.x.where.spoff); 2551 1.1 christos break; 2552 1.1 christos case spill_reg: 2553 1.1 christos output_X2_format (f, ptr->r.record.x.ab, ptr->r.record.x.reg, 2554 1.1 christos ptr->r.record.x.xy >> 1, ptr->r.record.x.xy, 2555 1.1 christos ptr->r.record.x.where.reg, ptr->r.record.x.t); 2556 1.1 christos break; 2557 1.1 christos case spill_psprel_p: 2558 1.1 christos output_X3_format (f, ptr->r.type, ptr->r.record.x.qp, 2559 1.1 christos ptr->r.record.x.ab, ptr->r.record.x.reg, 2560 1.1 christos ptr->r.record.x.t, ptr->r.record.x.where.pspoff); 2561 1.1 christos break; 2562 1.1 christos case spill_sprel_p: 2563 1.1 christos output_X3_format (f, ptr->r.type, ptr->r.record.x.qp, 2564 1.1 christos ptr->r.record.x.ab, ptr->r.record.x.reg, 2565 1.1 christos ptr->r.record.x.t, ptr->r.record.x.where.spoff); 2566 1.1 christos break; 2567 1.1 christos case spill_reg_p: 2568 1.1 christos output_X4_format (f, ptr->r.record.x.qp, ptr->r.record.x.ab, 2569 1.1 christos ptr->r.record.x.reg, ptr->r.record.x.xy >> 1, 2570 1.1 christos ptr->r.record.x.xy, ptr->r.record.x.where.reg, 2571 1.1 christos ptr->r.record.x.t); 2572 1.1 christos break; 2573 1.1 christos default: 2574 1.1 christos as_bad (_("record_type_not_valid")); 2575 1.1 christos break; 2576 1.1 christos } 2577 1.1 christos } 2578 1.1 christos 2579 1.1 christos /* Given a unw_rec_list list, process all the records with 2580 1.1 christos the specified function. */ 2581 1.1 christos static void 2582 1.1 christos process_unw_records (unw_rec_list *list, vbyte_func f) 2583 1.1 christos { 2584 1.1 christos unw_rec_list *ptr; 2585 1.1 christos for (ptr = list; ptr; ptr = ptr->next) 2586 1.1 christos process_one_record (ptr, f); 2587 1.1 christos } 2588 1.1 christos 2589 1.1 christos /* Determine the size of a record list in bytes. */ 2590 1.1 christos static int 2591 1.1 christos calc_record_size (unw_rec_list *list) 2592 1.1 christos { 2593 1.1 christos vbyte_count = 0; 2594 1.1 christos process_unw_records (list, count_output); 2595 1.1 christos return vbyte_count; 2596 1.1 christos } 2597 1.1 christos 2598 1.1 christos /* Return the number of bits set in the input value. 2599 1.1 christos Perhaps this has a better place... */ 2600 1.1 christos #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) 2601 1.1 christos # define popcount __builtin_popcount 2602 1.1 christos #else 2603 1.1 christos static int 2604 1.1 christos popcount (unsigned x) 2605 1.1 christos { 2606 1.1 christos static const unsigned char popcnt[16] = 2607 1.1 christos { 2608 1.1 christos 0, 1, 1, 2, 2609 1.1 christos 1, 2, 2, 3, 2610 1.1 christos 1, 2, 2, 3, 2611 1.1 christos 2, 3, 3, 4 2612 1.1 christos }; 2613 1.1 christos 2614 1.1 christos if (x < NELEMS (popcnt)) 2615 1.1 christos return popcnt[x]; 2616 1.1 christos return popcnt[x % NELEMS (popcnt)] + popcount (x / NELEMS (popcnt)); 2617 1.1 christos } 2618 1.1 christos #endif 2619 1.1 christos 2620 1.1 christos /* Update IMASK bitmask to reflect the fact that one or more registers 2621 1.1 christos of type TYPE are saved starting at instruction with index T. If N 2622 1.1 christos bits are set in REGMASK, it is assumed that instructions T through 2623 1.1 christos T+N-1 save these registers. 2624 1.1 christos 2625 1.1 christos TYPE values: 2626 1.1 christos 0: no save 2627 1.1 christos 1: instruction saves next fp reg 2628 1.1 christos 2: instruction saves next general reg 2629 1.1 christos 3: instruction saves next branch reg */ 2630 1.1 christos static void 2631 1.1 christos set_imask (unw_rec_list *region, 2632 1.1 christos unsigned long regmask, 2633 1.1 christos unsigned long t, 2634 1.1 christos unsigned int type) 2635 1.1 christos { 2636 1.1 christos unsigned char *imask; 2637 1.1 christos unsigned long imask_size; 2638 1.1 christos unsigned int i; 2639 1.1 christos int pos; 2640 1.1 christos 2641 1.1 christos imask = region->r.record.r.mask.i; 2642 1.1 christos imask_size = region->r.record.r.imask_size; 2643 1.1 christos if (!imask) 2644 1.1 christos { 2645 1.1 christos imask_size = (region->r.record.r.rlen * 2 + 7) / 8 + 1; 2646 1.5 christos imask = XCNEWVEC (unsigned char, imask_size); 2647 1.1 christos 2648 1.1 christos region->r.record.r.imask_size = imask_size; 2649 1.1 christos region->r.record.r.mask.i = imask; 2650 1.1 christos } 2651 1.1 christos 2652 1.1 christos i = (t / 4) + 1; 2653 1.1 christos pos = 2 * (3 - t % 4); 2654 1.1 christos while (regmask) 2655 1.1 christos { 2656 1.1 christos if (i >= imask_size) 2657 1.1 christos { 2658 1.1 christos as_bad (_("Ignoring attempt to spill beyond end of region")); 2659 1.1 christos return; 2660 1.1 christos } 2661 1.1 christos 2662 1.1 christos imask[i] |= (type & 0x3) << pos; 2663 1.1 christos 2664 1.1 christos regmask &= (regmask - 1); 2665 1.1 christos pos -= 2; 2666 1.1 christos if (pos < 0) 2667 1.1 christos { 2668 1.1 christos pos = 0; 2669 1.1 christos ++i; 2670 1.1 christos } 2671 1.1 christos } 2672 1.1 christos } 2673 1.1 christos 2674 1.1 christos /* Return the number of instruction slots from FIRST_ADDR to SLOT_ADDR. 2675 1.1 christos SLOT_FRAG is the frag containing SLOT_ADDR, and FIRST_FRAG is the frag 2676 1.1 christos containing FIRST_ADDR. If BEFORE_RELAX, then we use worst-case estimates 2677 1.1 christos for frag sizes. */ 2678 1.1 christos 2679 1.1 christos static unsigned long 2680 1.1 christos slot_index (unsigned long slot_addr, 2681 1.1 christos fragS *slot_frag, 2682 1.1 christos unsigned long first_addr, 2683 1.1 christos fragS *first_frag, 2684 1.1 christos int before_relax) 2685 1.1 christos { 2686 1.1 christos unsigned long s_index = 0; 2687 1.1 christos 2688 1.1 christos /* First time we are called, the initial address and frag are invalid. */ 2689 1.1 christos if (first_addr == 0) 2690 1.1 christos return 0; 2691 1.1 christos 2692 1.1 christos /* If the two addresses are in different frags, then we need to add in 2693 1.1 christos the remaining size of this frag, and then the entire size of intermediate 2694 1.1 christos frags. */ 2695 1.1 christos while (slot_frag != first_frag) 2696 1.1 christos { 2697 1.1 christos unsigned long start_addr = (unsigned long) &first_frag->fr_literal; 2698 1.1 christos 2699 1.1 christos if (! before_relax) 2700 1.1 christos { 2701 1.1 christos /* We can get the final addresses only during and after 2702 1.1 christos relaxation. */ 2703 1.1 christos if (first_frag->fr_next && first_frag->fr_next->fr_address) 2704 1.1 christos s_index += 3 * ((first_frag->fr_next->fr_address 2705 1.1 christos - first_frag->fr_address 2706 1.1 christos - first_frag->fr_fix) >> 4); 2707 1.1 christos } 2708 1.1 christos else 2709 1.1 christos /* We don't know what the final addresses will be. We try our 2710 1.1 christos best to estimate. */ 2711 1.1 christos switch (first_frag->fr_type) 2712 1.1 christos { 2713 1.1 christos default: 2714 1.1 christos break; 2715 1.1 christos 2716 1.1 christos case rs_space: 2717 1.1 christos as_fatal (_("Only constant space allocation is supported")); 2718 1.1 christos break; 2719 1.1 christos 2720 1.1 christos case rs_align: 2721 1.1 christos case rs_align_code: 2722 1.1 christos case rs_align_test: 2723 1.1 christos /* Take alignment into account. Assume the worst case 2724 1.1 christos before relaxation. */ 2725 1.1 christos s_index += 3 * ((1 << first_frag->fr_offset) >> 4); 2726 1.1 christos break; 2727 1.1 christos 2728 1.1 christos case rs_org: 2729 1.1 christos if (first_frag->fr_symbol) 2730 1.1 christos { 2731 1.1 christos as_fatal (_("Only constant offsets are supported")); 2732 1.1 christos break; 2733 1.1 christos } 2734 1.6 christos /* Fall through. */ 2735 1.1 christos case rs_fill: 2736 1.1 christos s_index += 3 * (first_frag->fr_offset >> 4); 2737 1.1 christos break; 2738 1.1 christos } 2739 1.1 christos 2740 1.1 christos /* Add in the full size of the frag converted to instruction slots. */ 2741 1.1 christos s_index += 3 * (first_frag->fr_fix >> 4); 2742 1.1 christos /* Subtract away the initial part before first_addr. */ 2743 1.1 christos s_index -= (3 * ((first_addr >> 4) - (start_addr >> 4)) 2744 1.1 christos + ((first_addr & 0x3) - (start_addr & 0x3))); 2745 1.1 christos 2746 1.1 christos /* Move to the beginning of the next frag. */ 2747 1.1 christos first_frag = first_frag->fr_next; 2748 1.1 christos first_addr = (unsigned long) &first_frag->fr_literal; 2749 1.1 christos 2750 1.1 christos /* This can happen if there is section switching in the middle of a 2751 1.1 christos function, causing the frag chain for the function to be broken. 2752 1.1 christos It is too difficult to recover safely from this problem, so we just 2753 1.1 christos exit with an error. */ 2754 1.1 christos if (first_frag == NULL) 2755 1.1 christos as_fatal (_("Section switching in code is not supported.")); 2756 1.1 christos } 2757 1.1 christos 2758 1.1 christos /* Add in the used part of the last frag. */ 2759 1.1 christos s_index += (3 * ((slot_addr >> 4) - (first_addr >> 4)) 2760 1.1 christos + ((slot_addr & 0x3) - (first_addr & 0x3))); 2761 1.1 christos return s_index; 2762 1.1 christos } 2763 1.1 christos 2764 1.1 christos /* Optimize unwind record directives. */ 2765 1.1 christos 2766 1.1 christos static unw_rec_list * 2767 1.1 christos optimize_unw_records (unw_rec_list *list) 2768 1.1 christos { 2769 1.1 christos if (!list) 2770 1.1 christos return NULL; 2771 1.1 christos 2772 1.1 christos /* If the only unwind record is ".prologue" or ".prologue" followed 2773 1.1 christos by ".body", then we can optimize the unwind directives away. */ 2774 1.1 christos if (list->r.type == prologue 2775 1.1 christos && (list->next->r.type == endp 2776 1.1 christos || (list->next->r.type == body && list->next->next->r.type == endp))) 2777 1.1 christos return NULL; 2778 1.1 christos 2779 1.1 christos return list; 2780 1.1 christos } 2781 1.1 christos 2782 1.1 christos /* Given a complete record list, process any records which have 2783 1.1 christos unresolved fields, (ie length counts for a prologue). After 2784 1.1 christos this has been run, all necessary information should be available 2785 1.1 christos within each record to generate an image. */ 2786 1.1 christos 2787 1.1 christos static void 2788 1.1 christos fixup_unw_records (unw_rec_list *list, int before_relax) 2789 1.1 christos { 2790 1.1 christos unw_rec_list *ptr, *region = 0; 2791 1.1 christos unsigned long first_addr = 0, rlen = 0, t; 2792 1.1 christos fragS *first_frag = 0; 2793 1.1 christos 2794 1.1 christos for (ptr = list; ptr; ptr = ptr->next) 2795 1.1 christos { 2796 1.1 christos if (ptr->slot_number == SLOT_NUM_NOT_SET) 2797 1.6 christos as_bad (_("Insn slot not set in unwind record.")); 2798 1.1 christos t = slot_index (ptr->slot_number, ptr->slot_frag, 2799 1.1 christos first_addr, first_frag, before_relax); 2800 1.1 christos switch (ptr->r.type) 2801 1.1 christos { 2802 1.1 christos case prologue: 2803 1.1 christos case prologue_gr: 2804 1.1 christos case body: 2805 1.1 christos { 2806 1.1 christos unw_rec_list *last; 2807 1.1 christos int size; 2808 1.1 christos unsigned long last_addr = 0; 2809 1.1 christos fragS *last_frag = NULL; 2810 1.1 christos 2811 1.1 christos first_addr = ptr->slot_number; 2812 1.1 christos first_frag = ptr->slot_frag; 2813 1.1 christos /* Find either the next body/prologue start, or the end of 2814 1.1 christos the function, and determine the size of the region. */ 2815 1.1 christos for (last = ptr->next; last != NULL; last = last->next) 2816 1.1 christos if (last->r.type == prologue || last->r.type == prologue_gr 2817 1.1 christos || last->r.type == body || last->r.type == endp) 2818 1.1 christos { 2819 1.1 christos last_addr = last->slot_number; 2820 1.1 christos last_frag = last->slot_frag; 2821 1.1 christos break; 2822 1.1 christos } 2823 1.1 christos size = slot_index (last_addr, last_frag, first_addr, first_frag, 2824 1.1 christos before_relax); 2825 1.1 christos rlen = ptr->r.record.r.rlen = size; 2826 1.1 christos if (ptr->r.type == body) 2827 1.1 christos /* End of region. */ 2828 1.1 christos region = 0; 2829 1.1 christos else 2830 1.1 christos region = ptr; 2831 1.1 christos break; 2832 1.1 christos } 2833 1.1 christos case epilogue: 2834 1.1 christos if (t < rlen) 2835 1.1 christos ptr->r.record.b.t = rlen - 1 - t; 2836 1.1 christos else 2837 1.1 christos /* This happens when a memory-stack-less procedure uses a 2838 1.1 christos ".restore sp" directive at the end of a region to pop 2839 1.1 christos the frame state. */ 2840 1.1 christos ptr->r.record.b.t = 0; 2841 1.1 christos break; 2842 1.1 christos 2843 1.1 christos case mem_stack_f: 2844 1.1 christos case mem_stack_v: 2845 1.1 christos case rp_when: 2846 1.1 christos case pfs_when: 2847 1.1 christos case preds_when: 2848 1.1 christos case unat_when: 2849 1.1 christos case lc_when: 2850 1.1 christos case fpsr_when: 2851 1.1 christos case priunat_when_gr: 2852 1.1 christos case priunat_when_mem: 2853 1.1 christos case bsp_when: 2854 1.1 christos case bspstore_when: 2855 1.1 christos case rnat_when: 2856 1.1 christos ptr->r.record.p.t = t; 2857 1.1 christos break; 2858 1.1 christos 2859 1.1 christos case spill_reg: 2860 1.1 christos case spill_sprel: 2861 1.1 christos case spill_psprel: 2862 1.1 christos case spill_reg_p: 2863 1.1 christos case spill_sprel_p: 2864 1.1 christos case spill_psprel_p: 2865 1.1 christos ptr->r.record.x.t = t; 2866 1.1 christos break; 2867 1.1 christos 2868 1.1 christos case frgr_mem: 2869 1.1 christos if (!region) 2870 1.1 christos { 2871 1.1 christos as_bad (_("frgr_mem record before region record!")); 2872 1.1 christos return; 2873 1.1 christos } 2874 1.1 christos region->r.record.r.mask.fr_mem |= ptr->r.record.p.frmask; 2875 1.1 christos region->r.record.r.mask.gr_mem |= ptr->r.record.p.grmask; 2876 1.1 christos set_imask (region, ptr->r.record.p.frmask, t, 1); 2877 1.1 christos set_imask (region, ptr->r.record.p.grmask, t, 2); 2878 1.1 christos break; 2879 1.1 christos case fr_mem: 2880 1.1 christos if (!region) 2881 1.1 christos { 2882 1.1 christos as_bad (_("fr_mem record before region record!")); 2883 1.1 christos return; 2884 1.1 christos } 2885 1.1 christos region->r.record.r.mask.fr_mem |= ptr->r.record.p.frmask; 2886 1.1 christos set_imask (region, ptr->r.record.p.frmask, t, 1); 2887 1.1 christos break; 2888 1.1 christos case gr_mem: 2889 1.1 christos if (!region) 2890 1.1 christos { 2891 1.1 christos as_bad (_("gr_mem record before region record!")); 2892 1.1 christos return; 2893 1.1 christos } 2894 1.1 christos region->r.record.r.mask.gr_mem |= ptr->r.record.p.grmask; 2895 1.1 christos set_imask (region, ptr->r.record.p.grmask, t, 2); 2896 1.1 christos break; 2897 1.1 christos case br_mem: 2898 1.1 christos if (!region) 2899 1.1 christos { 2900 1.1 christos as_bad (_("br_mem record before region record!")); 2901 1.1 christos return; 2902 1.1 christos } 2903 1.1 christos region->r.record.r.mask.br_mem |= ptr->r.record.p.brmask; 2904 1.1 christos set_imask (region, ptr->r.record.p.brmask, t, 3); 2905 1.1 christos break; 2906 1.1 christos 2907 1.1 christos case gr_gr: 2908 1.1 christos if (!region) 2909 1.1 christos { 2910 1.1 christos as_bad (_("gr_gr record before region record!")); 2911 1.1 christos return; 2912 1.1 christos } 2913 1.1 christos set_imask (region, ptr->r.record.p.grmask, t, 2); 2914 1.1 christos break; 2915 1.1 christos case br_gr: 2916 1.1 christos if (!region) 2917 1.1 christos { 2918 1.1 christos as_bad (_("br_gr record before region record!")); 2919 1.1 christos return; 2920 1.1 christos } 2921 1.1 christos set_imask (region, ptr->r.record.p.brmask, t, 3); 2922 1.1 christos break; 2923 1.1 christos 2924 1.1 christos default: 2925 1.1 christos break; 2926 1.1 christos } 2927 1.1 christos } 2928 1.1 christos } 2929 1.1 christos 2930 1.1 christos /* Estimate the size of a frag before relaxing. We only have one type of frag 2931 1.1 christos to handle here, which is the unwind info frag. */ 2932 1.1 christos 2933 1.1 christos int 2934 1.1 christos ia64_estimate_size_before_relax (fragS *frag, 2935 1.1 christos asection *segtype ATTRIBUTE_UNUSED) 2936 1.1 christos { 2937 1.1 christos unw_rec_list *list; 2938 1.1 christos int len, size, pad; 2939 1.1 christos 2940 1.1 christos /* ??? This code is identical to the first part of ia64_convert_frag. */ 2941 1.1 christos list = (unw_rec_list *) frag->fr_opcode; 2942 1.1 christos fixup_unw_records (list, 0); 2943 1.1 christos 2944 1.1 christos len = calc_record_size (list); 2945 1.1 christos /* pad to pointer-size boundary. */ 2946 1.1 christos pad = len % md.pointer_size; 2947 1.1 christos if (pad != 0) 2948 1.1 christos len += md.pointer_size - pad; 2949 1.1 christos /* Add 8 for the header. */ 2950 1.1 christos size = len + 8; 2951 1.1 christos /* Add a pointer for the personality offset. */ 2952 1.1 christos if (frag->fr_offset) 2953 1.1 christos size += md.pointer_size; 2954 1.1 christos 2955 1.1 christos /* fr_var carries the max_chars that we created the fragment with. 2956 1.1 christos We must, of course, have allocated enough memory earlier. */ 2957 1.1 christos gas_assert (frag->fr_var >= size); 2958 1.1 christos 2959 1.1 christos return frag->fr_fix + size; 2960 1.1 christos } 2961 1.1 christos 2962 1.1 christos /* This function converts a rs_machine_dependent variant frag into a 2963 1.3 christos normal fill frag with the unwind image from the record list. */ 2964 1.1 christos void 2965 1.1 christos ia64_convert_frag (fragS *frag) 2966 1.1 christos { 2967 1.1 christos unw_rec_list *list; 2968 1.1 christos int len, size, pad; 2969 1.1 christos valueT flag_value; 2970 1.1 christos 2971 1.1 christos /* ??? This code is identical to ia64_estimate_size_before_relax. */ 2972 1.1 christos list = (unw_rec_list *) frag->fr_opcode; 2973 1.1 christos fixup_unw_records (list, 0); 2974 1.1 christos 2975 1.1 christos len = calc_record_size (list); 2976 1.1 christos /* pad to pointer-size boundary. */ 2977 1.1 christos pad = len % md.pointer_size; 2978 1.1 christos if (pad != 0) 2979 1.1 christos len += md.pointer_size - pad; 2980 1.1 christos /* Add 8 for the header. */ 2981 1.1 christos size = len + 8; 2982 1.1 christos /* Add a pointer for the personality offset. */ 2983 1.1 christos if (frag->fr_offset) 2984 1.1 christos size += md.pointer_size; 2985 1.1 christos 2986 1.1 christos /* fr_var carries the max_chars that we created the fragment with. 2987 1.1 christos We must, of course, have allocated enough memory earlier. */ 2988 1.1 christos gas_assert (frag->fr_var >= size); 2989 1.1 christos 2990 1.1 christos /* Initialize the header area. fr_offset is initialized with 2991 1.1 christos unwind.personality_routine. */ 2992 1.1 christos if (frag->fr_offset) 2993 1.1 christos { 2994 1.1 christos if (md.flags & EF_IA_64_ABI64) 2995 1.1 christos flag_value = (bfd_vma) 3 << 32; 2996 1.1 christos else 2997 1.1 christos /* 32-bit unwind info block. */ 2998 1.1 christos flag_value = (bfd_vma) 0x1003 << 32; 2999 1.1 christos } 3000 1.1 christos else 3001 1.1 christos flag_value = 0; 3002 1.1 christos 3003 1.1 christos md_number_to_chars (frag->fr_literal, 3004 1.1 christos (((bfd_vma) 1 << 48) /* Version. */ 3005 1.1 christos | flag_value /* U & E handler flags. */ 3006 1.1 christos | (len / md.pointer_size)), /* Length. */ 3007 1.1 christos 8); 3008 1.1 christos 3009 1.1 christos /* Skip the header. */ 3010 1.1 christos vbyte_mem_ptr = frag->fr_literal + 8; 3011 1.1 christos process_unw_records (list, output_vbyte_mem); 3012 1.1 christos 3013 1.1 christos /* Fill the padding bytes with zeros. */ 3014 1.1 christos if (pad != 0) 3015 1.1 christos md_number_to_chars (frag->fr_literal + len + 8 - md.pointer_size + pad, 0, 3016 1.1 christos md.pointer_size - pad); 3017 1.1 christos /* Fill the unwind personality with zeros. */ 3018 1.1 christos if (frag->fr_offset) 3019 1.1 christos md_number_to_chars (frag->fr_literal + size - md.pointer_size, 0, 3020 1.1 christos md.pointer_size); 3021 1.1 christos 3022 1.1 christos frag->fr_fix += size; 3023 1.1 christos frag->fr_type = rs_fill; 3024 1.1 christos frag->fr_var = 0; 3025 1.1 christos frag->fr_offset = 0; 3026 1.1 christos } 3027 1.1 christos 3028 1.1 christos static int 3029 1.1 christos parse_predicate_and_operand (expressionS *e, unsigned *qp, const char *po) 3030 1.1 christos { 3031 1.1 christos int sep = parse_operand_and_eval (e, ','); 3032 1.1 christos 3033 1.1 christos *qp = e->X_add_number - REG_P; 3034 1.1 christos if (e->X_op != O_register || *qp > 63) 3035 1.1 christos { 3036 1.1 christos as_bad (_("First operand to .%s must be a predicate"), po); 3037 1.1 christos *qp = 0; 3038 1.1 christos } 3039 1.1 christos else if (*qp == 0) 3040 1.1 christos as_warn (_("Pointless use of p0 as first operand to .%s"), po); 3041 1.1 christos if (sep == ',') 3042 1.1 christos sep = parse_operand_and_eval (e, ','); 3043 1.1 christos else 3044 1.1 christos e->X_op = O_absent; 3045 1.1 christos return sep; 3046 1.1 christos } 3047 1.1 christos 3048 1.1 christos static void 3049 1.1 christos convert_expr_to_ab_reg (const expressionS *e, 3050 1.1 christos unsigned int *ab, 3051 1.1 christos unsigned int *regp, 3052 1.1 christos const char *po, 3053 1.1 christos int n) 3054 1.1 christos { 3055 1.1 christos unsigned int reg = e->X_add_number; 3056 1.1 christos 3057 1.1 christos *ab = *regp = 0; /* Anything valid is good here. */ 3058 1.1 christos 3059 1.1 christos if (e->X_op != O_register) 3060 1.1 christos reg = REG_GR; /* Anything invalid is good here. */ 3061 1.1 christos 3062 1.1 christos if (reg >= (REG_GR + 4) && reg <= (REG_GR + 7)) 3063 1.1 christos { 3064 1.1 christos *ab = 0; 3065 1.1 christos *regp = reg - REG_GR; 3066 1.1 christos } 3067 1.1 christos else if ((reg >= (REG_FR + 2) && reg <= (REG_FR + 5)) 3068 1.1 christos || (reg >= (REG_FR + 16) && reg <= (REG_FR + 31))) 3069 1.1 christos { 3070 1.1 christos *ab = 1; 3071 1.1 christos *regp = reg - REG_FR; 3072 1.1 christos } 3073 1.1 christos else if (reg >= (REG_BR + 1) && reg <= (REG_BR + 5)) 3074 1.1 christos { 3075 1.1 christos *ab = 2; 3076 1.1 christos *regp = reg - REG_BR; 3077 1.1 christos } 3078 1.1 christos else 3079 1.1 christos { 3080 1.1 christos *ab = 3; 3081 1.1 christos switch (reg) 3082 1.1 christos { 3083 1.1 christos case REG_PR: *regp = 0; break; 3084 1.1 christos case REG_PSP: *regp = 1; break; 3085 1.1 christos case REG_PRIUNAT: *regp = 2; break; 3086 1.1 christos case REG_BR + 0: *regp = 3; break; 3087 1.1 christos case REG_AR + AR_BSP: *regp = 4; break; 3088 1.1 christos case REG_AR + AR_BSPSTORE: *regp = 5; break; 3089 1.1 christos case REG_AR + AR_RNAT: *regp = 6; break; 3090 1.1 christos case REG_AR + AR_UNAT: *regp = 7; break; 3091 1.1 christos case REG_AR + AR_FPSR: *regp = 8; break; 3092 1.1 christos case REG_AR + AR_PFS: *regp = 9; break; 3093 1.1 christos case REG_AR + AR_LC: *regp = 10; break; 3094 1.1 christos 3095 1.1 christos default: 3096 1.1 christos as_bad (_("Operand %d to .%s must be a preserved register"), n, po); 3097 1.1 christos break; 3098 1.1 christos } 3099 1.1 christos } 3100 1.1 christos } 3101 1.1 christos 3102 1.1 christos static void 3103 1.1 christos convert_expr_to_xy_reg (const expressionS *e, 3104 1.1 christos unsigned int *xy, 3105 1.1 christos unsigned int *regp, 3106 1.1 christos const char *po, 3107 1.1 christos int n) 3108 1.1 christos { 3109 1.1 christos unsigned int reg = e->X_add_number; 3110 1.1 christos 3111 1.1 christos *xy = *regp = 0; /* Anything valid is good here. */ 3112 1.1 christos 3113 1.1 christos if (e->X_op != O_register) 3114 1.1 christos reg = REG_GR; /* Anything invalid is good here. */ 3115 1.1 christos 3116 1.1 christos if (reg >= (REG_GR + 1) && reg <= (REG_GR + 127)) 3117 1.1 christos { 3118 1.1 christos *xy = 0; 3119 1.1 christos *regp = reg - REG_GR; 3120 1.1 christos } 3121 1.1 christos else if (reg >= (REG_FR + 2) && reg <= (REG_FR + 127)) 3122 1.1 christos { 3123 1.1 christos *xy = 1; 3124 1.1 christos *regp = reg - REG_FR; 3125 1.1 christos } 3126 1.1 christos else if (reg >= REG_BR && reg <= (REG_BR + 7)) 3127 1.1 christos { 3128 1.1 christos *xy = 2; 3129 1.1 christos *regp = reg - REG_BR; 3130 1.1 christos } 3131 1.1 christos else 3132 1.1 christos as_bad (_("Operand %d to .%s must be a writable register"), n, po); 3133 1.1 christos } 3134 1.1 christos 3135 1.1 christos static void 3136 1.1 christos dot_align (int arg) 3137 1.1 christos { 3138 1.1 christos /* The current frag is an alignment frag. */ 3139 1.1 christos align_frag = frag_now; 3140 1.1 christos s_align_bytes (arg); 3141 1.1 christos } 3142 1.1 christos 3143 1.1 christos static void 3144 1.1 christos dot_radix (int dummy ATTRIBUTE_UNUSED) 3145 1.1 christos { 3146 1.1 christos char *radix; 3147 1.1 christos int ch; 3148 1.1 christos 3149 1.1 christos SKIP_WHITESPACE (); 3150 1.1 christos 3151 1.1 christos if (is_it_end_of_statement ()) 3152 1.1 christos return; 3153 1.3 christos ch = get_symbol_name (&radix); 3154 1.1 christos ia64_canonicalize_symbol_name (radix); 3155 1.1 christos if (strcasecmp (radix, "C")) 3156 1.1 christos as_bad (_("Radix `%s' unsupported or invalid"), radix); 3157 1.3 christos (void) restore_line_pointer (ch); 3158 1.1 christos demand_empty_rest_of_line (); 3159 1.1 christos } 3160 1.1 christos 3161 1.1 christos /* Helper function for .loc directives. If the assembler is not generating 3162 1.1 christos line number info, then we need to remember which instructions have a .loc 3163 1.1 christos directive, and only call dwarf2_gen_line_info for those instructions. */ 3164 1.1 christos 3165 1.1 christos static void 3166 1.1 christos dot_loc (int x) 3167 1.1 christos { 3168 1.1 christos CURR_SLOT.loc_directive_seen = 1; 3169 1.1 christos dwarf2_directive_loc (x); 3170 1.1 christos } 3171 1.1 christos 3172 1.9 christos /* .sbss, .srodata etc. are macros that expand into ".section SECNAME". */ 3173 1.1 christos static void 3174 1.1 christos dot_special_section (int which) 3175 1.1 christos { 3176 1.1 christos set_section ((char *) special_section_name[which]); 3177 1.1 christos } 3178 1.1 christos 3179 1.1 christos /* Return -1 for warning and 0 for error. */ 3180 1.1 christos 3181 1.1 christos static int 3182 1.1 christos unwind_diagnostic (const char * region, const char *directive) 3183 1.1 christos { 3184 1.1 christos if (md.unwind_check == unwind_check_warning) 3185 1.1 christos { 3186 1.1 christos as_warn (_(".%s outside of %s"), directive, region); 3187 1.1 christos return -1; 3188 1.1 christos } 3189 1.1 christos else 3190 1.1 christos { 3191 1.1 christos as_bad (_(".%s outside of %s"), directive, region); 3192 1.1 christos ignore_rest_of_line (); 3193 1.1 christos return 0; 3194 1.1 christos } 3195 1.1 christos } 3196 1.1 christos 3197 1.1 christos /* Return 1 if a directive is in a procedure, -1 if a directive isn't in 3198 1.1 christos a procedure but the unwind directive check is set to warning, 0 if 3199 1.1 christos a directive isn't in a procedure and the unwind directive check is set 3200 1.1 christos to error. */ 3201 1.1 christos 3202 1.1 christos static int 3203 1.1 christos in_procedure (const char *directive) 3204 1.1 christos { 3205 1.1 christos if (unwind.proc_pending.sym 3206 1.1 christos && (!unwind.saved_text_seg || strcmp (directive, "endp") == 0)) 3207 1.1 christos return 1; 3208 1.1 christos return unwind_diagnostic ("procedure", directive); 3209 1.1 christos } 3210 1.1 christos 3211 1.1 christos /* Return 1 if a directive is in a prologue, -1 if a directive isn't in 3212 1.1 christos a prologue but the unwind directive check is set to warning, 0 if 3213 1.1 christos a directive isn't in a prologue and the unwind directive check is set 3214 1.1 christos to error. */ 3215 1.1 christos 3216 1.1 christos static int 3217 1.1 christos in_prologue (const char *directive) 3218 1.1 christos { 3219 1.1 christos int in = in_procedure (directive); 3220 1.1 christos 3221 1.1 christos if (in > 0 && !unwind.prologue) 3222 1.1 christos in = unwind_diagnostic ("prologue", directive); 3223 1.1 christos check_pending_save (); 3224 1.1 christos return in; 3225 1.1 christos } 3226 1.1 christos 3227 1.1 christos /* Return 1 if a directive is in a body, -1 if a directive isn't in 3228 1.1 christos a body but the unwind directive check is set to warning, 0 if 3229 1.1 christos a directive isn't in a body and the unwind directive check is set 3230 1.1 christos to error. */ 3231 1.1 christos 3232 1.1 christos static int 3233 1.1 christos in_body (const char *directive) 3234 1.1 christos { 3235 1.1 christos int in = in_procedure (directive); 3236 1.1 christos 3237 1.1 christos if (in > 0 && !unwind.body) 3238 1.1 christos in = unwind_diagnostic ("body region", directive); 3239 1.1 christos return in; 3240 1.1 christos } 3241 1.1 christos 3242 1.1 christos static void 3243 1.1 christos add_unwind_entry (unw_rec_list *ptr, int sep) 3244 1.1 christos { 3245 1.1 christos if (ptr) 3246 1.1 christos { 3247 1.1 christos if (unwind.tail) 3248 1.1 christos unwind.tail->next = ptr; 3249 1.1 christos else 3250 1.1 christos unwind.list = ptr; 3251 1.1 christos unwind.tail = ptr; 3252 1.1 christos 3253 1.1 christos /* The current entry can in fact be a chain of unwind entries. */ 3254 1.1 christos if (unwind.current_entry == NULL) 3255 1.1 christos unwind.current_entry = ptr; 3256 1.1 christos } 3257 1.1 christos 3258 1.1 christos /* The current entry can in fact be a chain of unwind entries. */ 3259 1.1 christos if (unwind.current_entry == NULL) 3260 1.1 christos unwind.current_entry = ptr; 3261 1.1 christos 3262 1.1 christos if (sep == ',') 3263 1.1 christos { 3264 1.3 christos char *name; 3265 1.1 christos /* Parse a tag permitted for the current directive. */ 3266 1.1 christos int ch; 3267 1.1 christos 3268 1.1 christos SKIP_WHITESPACE (); 3269 1.3 christos ch = get_symbol_name (&name); 3270 1.1 christos /* FIXME: For now, just issue a warning that this isn't implemented. */ 3271 1.1 christos { 3272 1.1 christos static int warned; 3273 1.1 christos 3274 1.1 christos if (!warned) 3275 1.1 christos { 3276 1.1 christos warned = 1; 3277 1.1 christos as_warn (_("Tags on unwind pseudo-ops aren't supported, yet")); 3278 1.1 christos } 3279 1.1 christos } 3280 1.3 christos (void) restore_line_pointer (ch); 3281 1.1 christos } 3282 1.1 christos if (sep != NOT_A_CHAR) 3283 1.1 christos demand_empty_rest_of_line (); 3284 1.1 christos } 3285 1.1 christos 3286 1.1 christos static void 3287 1.1 christos dot_fframe (int dummy ATTRIBUTE_UNUSED) 3288 1.1 christos { 3289 1.1 christos expressionS e; 3290 1.1 christos int sep; 3291 1.1 christos 3292 1.1 christos if (!in_prologue ("fframe")) 3293 1.1 christos return; 3294 1.1 christos 3295 1.1 christos sep = parse_operand_and_eval (&e, ','); 3296 1.1 christos 3297 1.1 christos if (e.X_op != O_constant) 3298 1.1 christos { 3299 1.1 christos as_bad (_("First operand to .fframe must be a constant")); 3300 1.1 christos e.X_add_number = 0; 3301 1.1 christos } 3302 1.1 christos add_unwind_entry (output_mem_stack_f (e.X_add_number), sep); 3303 1.1 christos } 3304 1.1 christos 3305 1.1 christos static void 3306 1.1 christos dot_vframe (int dummy ATTRIBUTE_UNUSED) 3307 1.1 christos { 3308 1.1 christos expressionS e; 3309 1.1 christos unsigned reg; 3310 1.1 christos int sep; 3311 1.1 christos 3312 1.1 christos if (!in_prologue ("vframe")) 3313 1.1 christos return; 3314 1.1 christos 3315 1.1 christos sep = parse_operand_and_eval (&e, ','); 3316 1.1 christos reg = e.X_add_number - REG_GR; 3317 1.1 christos if (e.X_op != O_register || reg > 127) 3318 1.1 christos { 3319 1.1 christos as_bad (_("First operand to .vframe must be a general register")); 3320 1.1 christos reg = 0; 3321 1.1 christos } 3322 1.1 christos add_unwind_entry (output_mem_stack_v (), sep); 3323 1.1 christos if (! (unwind.prologue_mask & 2)) 3324 1.1 christos add_unwind_entry (output_psp_gr (reg), NOT_A_CHAR); 3325 1.1 christos else if (reg != unwind.prologue_gr 3326 1.3 christos + (unsigned) popcount (unwind.prologue_mask & -(2 << 1))) 3327 1.1 christos as_warn (_("Operand of .vframe contradicts .prologue")); 3328 1.1 christos } 3329 1.1 christos 3330 1.1 christos static void 3331 1.1 christos dot_vframesp (int psp) 3332 1.1 christos { 3333 1.1 christos expressionS e; 3334 1.1 christos int sep; 3335 1.1 christos 3336 1.1 christos if (psp) 3337 1.1 christos as_warn (_(".vframepsp is meaningless, assuming .vframesp was meant")); 3338 1.1 christos 3339 1.1 christos if (!in_prologue ("vframesp")) 3340 1.1 christos return; 3341 1.1 christos 3342 1.1 christos sep = parse_operand_and_eval (&e, ','); 3343 1.1 christos if (e.X_op != O_constant) 3344 1.1 christos { 3345 1.1 christos as_bad (_("Operand to .vframesp must be a constant (sp-relative offset)")); 3346 1.1 christos e.X_add_number = 0; 3347 1.1 christos } 3348 1.1 christos add_unwind_entry (output_mem_stack_v (), sep); 3349 1.1 christos add_unwind_entry (output_psp_sprel (e.X_add_number), NOT_A_CHAR); 3350 1.1 christos } 3351 1.1 christos 3352 1.1 christos static void 3353 1.1 christos dot_save (int dummy ATTRIBUTE_UNUSED) 3354 1.1 christos { 3355 1.1 christos expressionS e1, e2; 3356 1.1 christos unsigned reg1, reg2; 3357 1.1 christos int sep; 3358 1.1 christos 3359 1.1 christos if (!in_prologue ("save")) 3360 1.1 christos return; 3361 1.1 christos 3362 1.1 christos sep = parse_operand_and_eval (&e1, ','); 3363 1.1 christos if (sep == ',') 3364 1.1 christos sep = parse_operand_and_eval (&e2, ','); 3365 1.1 christos else 3366 1.1 christos e2.X_op = O_absent; 3367 1.1 christos 3368 1.1 christos reg1 = e1.X_add_number; 3369 1.6 christos /* Make sure it's a valid ar.xxx reg, OR its br0, aka 'rp'. */ 3370 1.1 christos if (e1.X_op != O_register) 3371 1.1 christos { 3372 1.1 christos as_bad (_("First operand to .save not a register")); 3373 1.1 christos reg1 = REG_PR; /* Anything valid is good here. */ 3374 1.1 christos } 3375 1.1 christos reg2 = e2.X_add_number - REG_GR; 3376 1.1 christos if (e2.X_op != O_register || reg2 > 127) 3377 1.1 christos { 3378 1.1 christos as_bad (_("Second operand to .save not a valid register")); 3379 1.1 christos reg2 = 0; 3380 1.1 christos } 3381 1.1 christos switch (reg1) 3382 1.1 christos { 3383 1.1 christos case REG_AR + AR_BSP: 3384 1.1 christos add_unwind_entry (output_bsp_when (), sep); 3385 1.1 christos add_unwind_entry (output_bsp_gr (reg2), NOT_A_CHAR); 3386 1.1 christos break; 3387 1.1 christos case REG_AR + AR_BSPSTORE: 3388 1.1 christos add_unwind_entry (output_bspstore_when (), sep); 3389 1.1 christos add_unwind_entry (output_bspstore_gr (reg2), NOT_A_CHAR); 3390 1.1 christos break; 3391 1.1 christos case REG_AR + AR_RNAT: 3392 1.1 christos add_unwind_entry (output_rnat_when (), sep); 3393 1.1 christos add_unwind_entry (output_rnat_gr (reg2), NOT_A_CHAR); 3394 1.1 christos break; 3395 1.1 christos case REG_AR + AR_UNAT: 3396 1.1 christos add_unwind_entry (output_unat_when (), sep); 3397 1.1 christos add_unwind_entry (output_unat_gr (reg2), NOT_A_CHAR); 3398 1.1 christos break; 3399 1.1 christos case REG_AR + AR_FPSR: 3400 1.1 christos add_unwind_entry (output_fpsr_when (), sep); 3401 1.1 christos add_unwind_entry (output_fpsr_gr (reg2), NOT_A_CHAR); 3402 1.1 christos break; 3403 1.1 christos case REG_AR + AR_PFS: 3404 1.1 christos add_unwind_entry (output_pfs_when (), sep); 3405 1.1 christos if (! (unwind.prologue_mask & 4)) 3406 1.1 christos add_unwind_entry (output_pfs_gr (reg2), NOT_A_CHAR); 3407 1.1 christos else if (reg2 != unwind.prologue_gr 3408 1.3 christos + (unsigned) popcount (unwind.prologue_mask & -(4 << 1))) 3409 1.1 christos as_warn (_("Second operand of .save contradicts .prologue")); 3410 1.1 christos break; 3411 1.1 christos case REG_AR + AR_LC: 3412 1.1 christos add_unwind_entry (output_lc_when (), sep); 3413 1.1 christos add_unwind_entry (output_lc_gr (reg2), NOT_A_CHAR); 3414 1.1 christos break; 3415 1.1 christos case REG_BR: 3416 1.1 christos add_unwind_entry (output_rp_when (), sep); 3417 1.1 christos if (! (unwind.prologue_mask & 8)) 3418 1.1 christos add_unwind_entry (output_rp_gr (reg2), NOT_A_CHAR); 3419 1.1 christos else if (reg2 != unwind.prologue_gr) 3420 1.1 christos as_warn (_("Second operand of .save contradicts .prologue")); 3421 1.1 christos break; 3422 1.1 christos case REG_PR: 3423 1.1 christos add_unwind_entry (output_preds_when (), sep); 3424 1.1 christos if (! (unwind.prologue_mask & 1)) 3425 1.1 christos add_unwind_entry (output_preds_gr (reg2), NOT_A_CHAR); 3426 1.1 christos else if (reg2 != unwind.prologue_gr 3427 1.3 christos + (unsigned) popcount (unwind.prologue_mask & -(1 << 1))) 3428 1.1 christos as_warn (_("Second operand of .save contradicts .prologue")); 3429 1.1 christos break; 3430 1.1 christos case REG_PRIUNAT: 3431 1.1 christos add_unwind_entry (output_priunat_when_gr (), sep); 3432 1.1 christos add_unwind_entry (output_priunat_gr (reg2), NOT_A_CHAR); 3433 1.1 christos break; 3434 1.1 christos default: 3435 1.1 christos as_bad (_("First operand to .save not a valid register")); 3436 1.1 christos add_unwind_entry (NULL, sep); 3437 1.1 christos break; 3438 1.1 christos } 3439 1.1 christos } 3440 1.1 christos 3441 1.1 christos static void 3442 1.1 christos dot_restore (int dummy ATTRIBUTE_UNUSED) 3443 1.1 christos { 3444 1.1 christos expressionS e1; 3445 1.1 christos unsigned long ecount; /* # of _additional_ regions to pop */ 3446 1.1 christos int sep; 3447 1.1 christos 3448 1.1 christos if (!in_body ("restore")) 3449 1.1 christos return; 3450 1.1 christos 3451 1.1 christos sep = parse_operand_and_eval (&e1, ','); 3452 1.1 christos if (e1.X_op != O_register || e1.X_add_number != REG_GR + 12) 3453 1.1 christos as_bad (_("First operand to .restore must be stack pointer (sp)")); 3454 1.1 christos 3455 1.1 christos if (sep == ',') 3456 1.1 christos { 3457 1.1 christos expressionS e2; 3458 1.1 christos 3459 1.1 christos sep = parse_operand_and_eval (&e2, ','); 3460 1.1 christos if (e2.X_op != O_constant || e2.X_add_number < 0) 3461 1.1 christos { 3462 1.1 christos as_bad (_("Second operand to .restore must be a constant >= 0")); 3463 1.1 christos e2.X_add_number = 0; 3464 1.1 christos } 3465 1.1 christos ecount = e2.X_add_number; 3466 1.1 christos } 3467 1.1 christos else 3468 1.1 christos ecount = unwind.prologue_count - 1; 3469 1.1 christos 3470 1.1 christos if (ecount >= unwind.prologue_count) 3471 1.1 christos { 3472 1.1 christos as_bad (_("Epilogue count of %lu exceeds number of nested prologues (%u)"), 3473 1.1 christos ecount + 1, unwind.prologue_count); 3474 1.1 christos ecount = 0; 3475 1.1 christos } 3476 1.1 christos 3477 1.1 christos add_unwind_entry (output_epilogue (ecount), sep); 3478 1.1 christos 3479 1.1 christos if (ecount < unwind.prologue_count) 3480 1.1 christos unwind.prologue_count -= ecount + 1; 3481 1.1 christos else 3482 1.1 christos unwind.prologue_count = 0; 3483 1.1 christos } 3484 1.1 christos 3485 1.1 christos static void 3486 1.1 christos dot_restorereg (int pred) 3487 1.1 christos { 3488 1.1 christos unsigned int qp, ab, reg; 3489 1.1 christos expressionS e; 3490 1.1 christos int sep; 3491 1.1 christos const char * const po = pred ? "restorereg.p" : "restorereg"; 3492 1.1 christos 3493 1.1 christos if (!in_procedure (po)) 3494 1.1 christos return; 3495 1.1 christos 3496 1.1 christos if (pred) 3497 1.1 christos sep = parse_predicate_and_operand (&e, &qp, po); 3498 1.1 christos else 3499 1.1 christos { 3500 1.1 christos sep = parse_operand_and_eval (&e, ','); 3501 1.1 christos qp = 0; 3502 1.1 christos } 3503 1.1 christos convert_expr_to_ab_reg (&e, &ab, ®, po, 1 + pred); 3504 1.1 christos 3505 1.1 christos add_unwind_entry (output_spill_reg (ab, reg, 0, 0, qp), sep); 3506 1.1 christos } 3507 1.1 christos 3508 1.5 christos static const char *special_linkonce_name[] = 3509 1.1 christos { 3510 1.1 christos ".gnu.linkonce.ia64unw.", ".gnu.linkonce.ia64unwi." 3511 1.1 christos }; 3512 1.1 christos 3513 1.1 christos static void 3514 1.1 christos start_unwind_section (const segT text_seg, int sec_index) 3515 1.1 christos { 3516 1.1 christos /* 3517 1.1 christos Use a slightly ugly scheme to derive the unwind section names from 3518 1.1 christos the text section name: 3519 1.1 christos 3520 1.1 christos text sect. unwind table sect. 3521 1.1 christos name: name: comments: 3522 1.1 christos ---------- ----------------- -------------------------------- 3523 1.1 christos .text .IA_64.unwind 3524 1.1 christos .text.foo .IA_64.unwind.text.foo 3525 1.1 christos .foo .IA_64.unwind.foo 3526 1.1 christos .gnu.linkonce.t.foo 3527 1.1 christos .gnu.linkonce.ia64unw.foo 3528 1.1 christos _info .IA_64.unwind_info gas issues error message (ditto) 3529 1.1 christos _infoFOO .IA_64.unwind_infoFOO gas issues error message (ditto) 3530 1.1 christos 3531 1.1 christos This mapping is done so that: 3532 1.1 christos 3533 1.1 christos (a) An object file with unwind info only in .text will use 3534 1.1 christos unwind section names .IA_64.unwind and .IA_64.unwind_info. 3535 1.1 christos This follows the letter of the ABI and also ensures backwards 3536 1.1 christos compatibility with older toolchains. 3537 1.1 christos 3538 1.1 christos (b) An object file with unwind info in multiple text sections 3539 1.1 christos will use separate unwind sections for each text section. 3540 1.1 christos This allows us to properly set the "sh_info" and "sh_link" 3541 1.1 christos fields in SHT_IA_64_UNWIND as required by the ABI and also 3542 1.1 christos lets GNU ld support programs with multiple segments 3543 1.1 christos containing unwind info (as might be the case for certain 3544 1.1 christos embedded applications). 3545 1.1 christos 3546 1.1 christos (c) An error is issued if there would be a name clash. 3547 1.1 christos */ 3548 1.1 christos 3549 1.1 christos const char *text_name, *sec_text_name; 3550 1.1 christos char *sec_name; 3551 1.1 christos const char *prefix = special_section_name [sec_index]; 3552 1.1 christos const char *suffix; 3553 1.1 christos 3554 1.1 christos sec_text_name = segment_name (text_seg); 3555 1.1 christos text_name = sec_text_name; 3556 1.8 christos if (startswith (text_name, "_info")) 3557 1.1 christos { 3558 1.1 christos as_bad (_("Illegal section name `%s' (causes unwind section name clash)"), 3559 1.1 christos text_name); 3560 1.1 christos ignore_rest_of_line (); 3561 1.1 christos return; 3562 1.1 christos } 3563 1.1 christos if (strcmp (text_name, ".text") == 0) 3564 1.1 christos text_name = ""; 3565 1.1 christos 3566 1.1 christos /* Build the unwind section name by appending the (possibly stripped) 3567 1.1 christos text section name to the unwind prefix. */ 3568 1.1 christos suffix = text_name; 3569 1.8 christos if (startswith (text_name, ".gnu.linkonce.t.")) 3570 1.1 christos { 3571 1.1 christos prefix = special_linkonce_name [sec_index - SPECIAL_SECTION_UNWIND]; 3572 1.1 christos suffix += sizeof (".gnu.linkonce.t.") - 1; 3573 1.1 christos } 3574 1.1 christos 3575 1.10 christos sec_name = concat (prefix, suffix, (const char *) NULL); 3576 1.1 christos 3577 1.1 christos /* Handle COMDAT group. */ 3578 1.1 christos if ((text_seg->flags & SEC_LINK_ONCE) != 0 3579 1.1 christos && (elf_section_flags (text_seg) & SHF_GROUP) != 0) 3580 1.1 christos { 3581 1.1 christos char *section; 3582 1.1 christos const char *group_name = elf_group_name (text_seg); 3583 1.1 christos 3584 1.1 christos if (group_name == NULL) 3585 1.1 christos { 3586 1.1 christos as_bad (_("Group section `%s' has no group signature"), 3587 1.1 christos sec_text_name); 3588 1.1 christos ignore_rest_of_line (); 3589 1.5 christos free (sec_name); 3590 1.1 christos return; 3591 1.1 christos } 3592 1.5 christos 3593 1.5 christos /* We have to construct a fake section directive. */ 3594 1.10 christos section = concat (sec_name, ",\"aG\",@progbits,", group_name, 3595 1.10 christos ",comdat", (const char *) NULL); 3596 1.1 christos set_section (section); 3597 1.5 christos free (section); 3598 1.1 christos } 3599 1.1 christos else 3600 1.1 christos { 3601 1.1 christos set_section (sec_name); 3602 1.7 christos bfd_set_section_flags (now_seg, SEC_LOAD | SEC_ALLOC | SEC_READONLY); 3603 1.1 christos } 3604 1.1 christos 3605 1.1 christos elf_linked_to_section (now_seg) = text_seg; 3606 1.5 christos free (sec_name); 3607 1.1 christos } 3608 1.1 christos 3609 1.1 christos static void 3610 1.1 christos generate_unwind_image (const segT text_seg) 3611 1.1 christos { 3612 1.1 christos int size, pad; 3613 1.1 christos unw_rec_list *list; 3614 1.1 christos 3615 1.1 christos /* Mark the end of the unwind info, so that we can compute the size of the 3616 1.1 christos last unwind region. */ 3617 1.1 christos add_unwind_entry (output_endp (), NOT_A_CHAR); 3618 1.1 christos 3619 1.1 christos /* Force out pending instructions, to make sure all unwind records have 3620 1.1 christos a valid slot_number field. */ 3621 1.1 christos ia64_flush_insns (); 3622 1.1 christos 3623 1.1 christos /* Generate the unwind record. */ 3624 1.1 christos list = optimize_unw_records (unwind.list); 3625 1.1 christos fixup_unw_records (list, 1); 3626 1.1 christos size = calc_record_size (list); 3627 1.1 christos 3628 1.1 christos if (size > 0 || unwind.force_unwind_entry) 3629 1.1 christos { 3630 1.1 christos unwind.force_unwind_entry = 0; 3631 1.1 christos /* pad to pointer-size boundary. */ 3632 1.1 christos pad = size % md.pointer_size; 3633 1.1 christos if (pad != 0) 3634 1.1 christos size += md.pointer_size - pad; 3635 1.1 christos /* Add 8 for the header. */ 3636 1.1 christos size += 8; 3637 1.1 christos /* Add a pointer for the personality offset. */ 3638 1.1 christos if (unwind.personality_routine) 3639 1.1 christos size += md.pointer_size; 3640 1.1 christos } 3641 1.1 christos 3642 1.1 christos /* If there are unwind records, switch sections, and output the info. */ 3643 1.1 christos if (size != 0) 3644 1.1 christos { 3645 1.1 christos expressionS exp; 3646 1.1 christos bfd_reloc_code_real_type reloc; 3647 1.1 christos 3648 1.1 christos start_unwind_section (text_seg, SPECIAL_SECTION_UNWIND_INFO); 3649 1.1 christos 3650 1.1 christos /* Make sure the section has 4 byte alignment for ILP32 and 3651 1.1 christos 8 byte alignment for LP64. */ 3652 1.1 christos frag_align (md.pointer_size_shift, 0, 0); 3653 1.1 christos record_alignment (now_seg, md.pointer_size_shift); 3654 1.1 christos 3655 1.1 christos /* Set expression which points to start of unwind descriptor area. */ 3656 1.1 christos unwind.info = expr_build_dot (); 3657 1.3 christos 3658 1.1 christos frag_var (rs_machine_dependent, size, size, 0, 0, 3659 1.10 christos (intptr_t) unwind.personality_routine, 3660 1.1 christos (char *) list); 3661 1.1 christos 3662 1.1 christos /* Add the personality address to the image. */ 3663 1.1 christos if (unwind.personality_routine != 0) 3664 1.1 christos { 3665 1.1 christos exp.X_op = O_symbol; 3666 1.1 christos exp.X_add_symbol = unwind.personality_routine; 3667 1.1 christos exp.X_add_number = 0; 3668 1.1 christos 3669 1.1 christos if (md.flags & EF_IA_64_BE) 3670 1.1 christos { 3671 1.1 christos if (md.flags & EF_IA_64_ABI64) 3672 1.1 christos reloc = BFD_RELOC_IA64_LTOFF_FPTR64MSB; 3673 1.1 christos else 3674 1.1 christos reloc = BFD_RELOC_IA64_LTOFF_FPTR32MSB; 3675 1.1 christos } 3676 1.1 christos else 3677 1.1 christos { 3678 1.1 christos if (md.flags & EF_IA_64_ABI64) 3679 1.1 christos reloc = BFD_RELOC_IA64_LTOFF_FPTR64LSB; 3680 1.1 christos else 3681 1.1 christos reloc = BFD_RELOC_IA64_LTOFF_FPTR32LSB; 3682 1.1 christos } 3683 1.1 christos 3684 1.1 christos fix_new_exp (frag_now, frag_now_fix () - md.pointer_size, 3685 1.1 christos md.pointer_size, &exp, 0, reloc); 3686 1.1 christos unwind.personality_routine = 0; 3687 1.1 christos } 3688 1.1 christos } 3689 1.1 christos 3690 1.1 christos free_saved_prologue_counts (); 3691 1.1 christos unwind.list = unwind.tail = unwind.current_entry = NULL; 3692 1.1 christos } 3693 1.1 christos 3694 1.1 christos static void 3695 1.1 christos dot_handlerdata (int dummy ATTRIBUTE_UNUSED) 3696 1.1 christos { 3697 1.1 christos if (!in_procedure ("handlerdata")) 3698 1.1 christos return; 3699 1.1 christos unwind.force_unwind_entry = 1; 3700 1.1 christos 3701 1.1 christos /* Remember which segment we're in so we can switch back after .endp */ 3702 1.1 christos unwind.saved_text_seg = now_seg; 3703 1.1 christos unwind.saved_text_subseg = now_subseg; 3704 1.1 christos 3705 1.1 christos /* Generate unwind info into unwind-info section and then leave that 3706 1.1 christos section as the currently active one so dataXX directives go into 3707 1.1 christos the language specific data area of the unwind info block. */ 3708 1.1 christos generate_unwind_image (now_seg); 3709 1.1 christos demand_empty_rest_of_line (); 3710 1.1 christos } 3711 1.1 christos 3712 1.1 christos static void 3713 1.1 christos dot_unwentry (int dummy ATTRIBUTE_UNUSED) 3714 1.1 christos { 3715 1.1 christos if (!in_procedure ("unwentry")) 3716 1.1 christos return; 3717 1.1 christos unwind.force_unwind_entry = 1; 3718 1.1 christos demand_empty_rest_of_line (); 3719 1.1 christos } 3720 1.1 christos 3721 1.1 christos static void 3722 1.1 christos dot_altrp (int dummy ATTRIBUTE_UNUSED) 3723 1.1 christos { 3724 1.1 christos expressionS e; 3725 1.1 christos unsigned reg; 3726 1.1 christos 3727 1.1 christos if (!in_prologue ("altrp")) 3728 1.1 christos return; 3729 1.1 christos 3730 1.1 christos parse_operand_and_eval (&e, 0); 3731 1.1 christos reg = e.X_add_number - REG_BR; 3732 1.1 christos if (e.X_op != O_register || reg > 7) 3733 1.1 christos { 3734 1.1 christos as_bad (_("First operand to .altrp not a valid branch register")); 3735 1.1 christos reg = 0; 3736 1.1 christos } 3737 1.1 christos add_unwind_entry (output_rp_br (reg), 0); 3738 1.1 christos } 3739 1.1 christos 3740 1.1 christos static void 3741 1.1 christos dot_savemem (int psprel) 3742 1.1 christos { 3743 1.1 christos expressionS e1, e2; 3744 1.1 christos int sep; 3745 1.1 christos int reg1, val; 3746 1.1 christos const char * const po = psprel ? "savepsp" : "savesp"; 3747 1.1 christos 3748 1.1 christos if (!in_prologue (po)) 3749 1.1 christos return; 3750 1.1 christos 3751 1.1 christos sep = parse_operand_and_eval (&e1, ','); 3752 1.1 christos if (sep == ',') 3753 1.1 christos sep = parse_operand_and_eval (&e2, ','); 3754 1.1 christos else 3755 1.1 christos e2.X_op = O_absent; 3756 1.1 christos 3757 1.1 christos reg1 = e1.X_add_number; 3758 1.1 christos val = e2.X_add_number; 3759 1.1 christos 3760 1.6 christos /* Make sure it's a valid ar.xxx reg, OR its br0, aka 'rp'. */ 3761 1.1 christos if (e1.X_op != O_register) 3762 1.1 christos { 3763 1.1 christos as_bad (_("First operand to .%s not a register"), po); 3764 1.1 christos reg1 = REG_PR; /* Anything valid is good here. */ 3765 1.1 christos } 3766 1.1 christos if (e2.X_op != O_constant) 3767 1.1 christos { 3768 1.1 christos as_bad (_("Second operand to .%s not a constant"), po); 3769 1.1 christos val = 0; 3770 1.1 christos } 3771 1.1 christos 3772 1.1 christos switch (reg1) 3773 1.1 christos { 3774 1.1 christos case REG_AR + AR_BSP: 3775 1.1 christos add_unwind_entry (output_bsp_when (), sep); 3776 1.1 christos add_unwind_entry ((psprel 3777 1.1 christos ? output_bsp_psprel 3778 1.1 christos : output_bsp_sprel) (val), NOT_A_CHAR); 3779 1.1 christos break; 3780 1.1 christos case REG_AR + AR_BSPSTORE: 3781 1.1 christos add_unwind_entry (output_bspstore_when (), sep); 3782 1.1 christos add_unwind_entry ((psprel 3783 1.1 christos ? output_bspstore_psprel 3784 1.1 christos : output_bspstore_sprel) (val), NOT_A_CHAR); 3785 1.1 christos break; 3786 1.1 christos case REG_AR + AR_RNAT: 3787 1.1 christos add_unwind_entry (output_rnat_when (), sep); 3788 1.1 christos add_unwind_entry ((psprel 3789 1.1 christos ? output_rnat_psprel 3790 1.1 christos : output_rnat_sprel) (val), NOT_A_CHAR); 3791 1.1 christos break; 3792 1.1 christos case REG_AR + AR_UNAT: 3793 1.1 christos add_unwind_entry (output_unat_when (), sep); 3794 1.1 christos add_unwind_entry ((psprel 3795 1.1 christos ? output_unat_psprel 3796 1.1 christos : output_unat_sprel) (val), NOT_A_CHAR); 3797 1.1 christos break; 3798 1.1 christos case REG_AR + AR_FPSR: 3799 1.1 christos add_unwind_entry (output_fpsr_when (), sep); 3800 1.1 christos add_unwind_entry ((psprel 3801 1.1 christos ? output_fpsr_psprel 3802 1.1 christos : output_fpsr_sprel) (val), NOT_A_CHAR); 3803 1.1 christos break; 3804 1.1 christos case REG_AR + AR_PFS: 3805 1.1 christos add_unwind_entry (output_pfs_when (), sep); 3806 1.1 christos add_unwind_entry ((psprel 3807 1.1 christos ? output_pfs_psprel 3808 1.1 christos : output_pfs_sprel) (val), NOT_A_CHAR); 3809 1.1 christos break; 3810 1.1 christos case REG_AR + AR_LC: 3811 1.1 christos add_unwind_entry (output_lc_when (), sep); 3812 1.1 christos add_unwind_entry ((psprel 3813 1.1 christos ? output_lc_psprel 3814 1.1 christos : output_lc_sprel) (val), NOT_A_CHAR); 3815 1.1 christos break; 3816 1.1 christos case REG_BR: 3817 1.1 christos add_unwind_entry (output_rp_when (), sep); 3818 1.1 christos add_unwind_entry ((psprel 3819 1.1 christos ? output_rp_psprel 3820 1.1 christos : output_rp_sprel) (val), NOT_A_CHAR); 3821 1.1 christos break; 3822 1.1 christos case REG_PR: 3823 1.1 christos add_unwind_entry (output_preds_when (), sep); 3824 1.1 christos add_unwind_entry ((psprel 3825 1.1 christos ? output_preds_psprel 3826 1.1 christos : output_preds_sprel) (val), NOT_A_CHAR); 3827 1.1 christos break; 3828 1.1 christos case REG_PRIUNAT: 3829 1.1 christos add_unwind_entry (output_priunat_when_mem (), sep); 3830 1.1 christos add_unwind_entry ((psprel 3831 1.1 christos ? output_priunat_psprel 3832 1.1 christos : output_priunat_sprel) (val), NOT_A_CHAR); 3833 1.1 christos break; 3834 1.1 christos default: 3835 1.1 christos as_bad (_("First operand to .%s not a valid register"), po); 3836 1.1 christos add_unwind_entry (NULL, sep); 3837 1.1 christos break; 3838 1.1 christos } 3839 1.1 christos } 3840 1.1 christos 3841 1.1 christos static void 3842 1.1 christos dot_saveg (int dummy ATTRIBUTE_UNUSED) 3843 1.1 christos { 3844 1.1 christos expressionS e; 3845 1.1 christos unsigned grmask; 3846 1.1 christos int sep; 3847 1.1 christos 3848 1.1 christos if (!in_prologue ("save.g")) 3849 1.1 christos return; 3850 1.1 christos 3851 1.1 christos sep = parse_operand_and_eval (&e, ','); 3852 1.1 christos 3853 1.1 christos grmask = e.X_add_number; 3854 1.1 christos if (e.X_op != O_constant 3855 1.1 christos || e.X_add_number <= 0 3856 1.1 christos || e.X_add_number > 0xf) 3857 1.1 christos { 3858 1.1 christos as_bad (_("First operand to .save.g must be a positive 4-bit constant")); 3859 1.1 christos grmask = 0; 3860 1.1 christos } 3861 1.1 christos 3862 1.1 christos if (sep == ',') 3863 1.1 christos { 3864 1.1 christos unsigned reg; 3865 1.1 christos int n = popcount (grmask); 3866 1.1 christos 3867 1.1 christos parse_operand_and_eval (&e, 0); 3868 1.1 christos reg = e.X_add_number - REG_GR; 3869 1.1 christos if (e.X_op != O_register || reg > 127) 3870 1.1 christos { 3871 1.1 christos as_bad (_("Second operand to .save.g must be a general register")); 3872 1.1 christos reg = 0; 3873 1.1 christos } 3874 1.1 christos else if (reg > 128U - n) 3875 1.1 christos { 3876 1.1 christos as_bad (_("Second operand to .save.g must be the first of %d general registers"), n); 3877 1.1 christos reg = 0; 3878 1.1 christos } 3879 1.1 christos add_unwind_entry (output_gr_gr (grmask, reg), 0); 3880 1.1 christos } 3881 1.1 christos else 3882 1.1 christos add_unwind_entry (output_gr_mem (grmask), 0); 3883 1.1 christos } 3884 1.1 christos 3885 1.1 christos static void 3886 1.1 christos dot_savef (int dummy ATTRIBUTE_UNUSED) 3887 1.1 christos { 3888 1.1 christos expressionS e; 3889 1.1 christos 3890 1.1 christos if (!in_prologue ("save.f")) 3891 1.1 christos return; 3892 1.1 christos 3893 1.1 christos parse_operand_and_eval (&e, 0); 3894 1.1 christos 3895 1.1 christos if (e.X_op != O_constant 3896 1.1 christos || e.X_add_number <= 0 3897 1.1 christos || e.X_add_number > 0xfffff) 3898 1.1 christos { 3899 1.1 christos as_bad (_("Operand to .save.f must be a positive 20-bit constant")); 3900 1.1 christos e.X_add_number = 0; 3901 1.1 christos } 3902 1.1 christos add_unwind_entry (output_fr_mem (e.X_add_number), 0); 3903 1.1 christos } 3904 1.1 christos 3905 1.1 christos static void 3906 1.1 christos dot_saveb (int dummy ATTRIBUTE_UNUSED) 3907 1.1 christos { 3908 1.1 christos expressionS e; 3909 1.1 christos unsigned brmask; 3910 1.1 christos int sep; 3911 1.1 christos 3912 1.1 christos if (!in_prologue ("save.b")) 3913 1.1 christos return; 3914 1.1 christos 3915 1.1 christos sep = parse_operand_and_eval (&e, ','); 3916 1.1 christos 3917 1.1 christos brmask = e.X_add_number; 3918 1.1 christos if (e.X_op != O_constant 3919 1.1 christos || e.X_add_number <= 0 3920 1.1 christos || e.X_add_number > 0x1f) 3921 1.1 christos { 3922 1.1 christos as_bad (_("First operand to .save.b must be a positive 5-bit constant")); 3923 1.1 christos brmask = 0; 3924 1.1 christos } 3925 1.1 christos 3926 1.1 christos if (sep == ',') 3927 1.1 christos { 3928 1.1 christos unsigned reg; 3929 1.1 christos int n = popcount (brmask); 3930 1.1 christos 3931 1.1 christos parse_operand_and_eval (&e, 0); 3932 1.1 christos reg = e.X_add_number - REG_GR; 3933 1.1 christos if (e.X_op != O_register || reg > 127) 3934 1.1 christos { 3935 1.1 christos as_bad (_("Second operand to .save.b must be a general register")); 3936 1.1 christos reg = 0; 3937 1.1 christos } 3938 1.1 christos else if (reg > 128U - n) 3939 1.1 christos { 3940 1.1 christos as_bad (_("Second operand to .save.b must be the first of %d general registers"), n); 3941 1.1 christos reg = 0; 3942 1.1 christos } 3943 1.1 christos add_unwind_entry (output_br_gr (brmask, reg), 0); 3944 1.1 christos } 3945 1.1 christos else 3946 1.1 christos add_unwind_entry (output_br_mem (brmask), 0); 3947 1.1 christos } 3948 1.1 christos 3949 1.1 christos static void 3950 1.1 christos dot_savegf (int dummy ATTRIBUTE_UNUSED) 3951 1.1 christos { 3952 1.1 christos expressionS e1, e2; 3953 1.1 christos 3954 1.1 christos if (!in_prologue ("save.gf")) 3955 1.1 christos return; 3956 1.1 christos 3957 1.1 christos if (parse_operand_and_eval (&e1, ',') == ',') 3958 1.1 christos parse_operand_and_eval (&e2, 0); 3959 1.1 christos else 3960 1.1 christos e2.X_op = O_absent; 3961 1.1 christos 3962 1.1 christos if (e1.X_op != O_constant 3963 1.1 christos || e1.X_add_number < 0 3964 1.1 christos || e1.X_add_number > 0xf) 3965 1.1 christos { 3966 1.1 christos as_bad (_("First operand to .save.gf must be a non-negative 4-bit constant")); 3967 1.1 christos e1.X_op = O_absent; 3968 1.1 christos e1.X_add_number = 0; 3969 1.1 christos } 3970 1.1 christos if (e2.X_op != O_constant 3971 1.1 christos || e2.X_add_number < 0 3972 1.1 christos || e2.X_add_number > 0xfffff) 3973 1.1 christos { 3974 1.1 christos as_bad (_("Second operand to .save.gf must be a non-negative 20-bit constant")); 3975 1.1 christos e2.X_op = O_absent; 3976 1.1 christos e2.X_add_number = 0; 3977 1.1 christos } 3978 1.1 christos if (e1.X_op == O_constant 3979 1.1 christos && e2.X_op == O_constant 3980 1.1 christos && e1.X_add_number == 0 3981 1.1 christos && e2.X_add_number == 0) 3982 1.1 christos as_bad (_("Operands to .save.gf may not be both zero")); 3983 1.1 christos 3984 1.1 christos add_unwind_entry (output_frgr_mem (e1.X_add_number, e2.X_add_number), 0); 3985 1.1 christos } 3986 1.1 christos 3987 1.1 christos static void 3988 1.1 christos dot_spill (int dummy ATTRIBUTE_UNUSED) 3989 1.1 christos { 3990 1.1 christos expressionS e; 3991 1.1 christos 3992 1.1 christos if (!in_prologue ("spill")) 3993 1.1 christos return; 3994 1.1 christos 3995 1.1 christos parse_operand_and_eval (&e, 0); 3996 1.1 christos 3997 1.1 christos if (e.X_op != O_constant) 3998 1.1 christos { 3999 1.1 christos as_bad (_("Operand to .spill must be a constant")); 4000 1.1 christos e.X_add_number = 0; 4001 1.1 christos } 4002 1.1 christos add_unwind_entry (output_spill_base (e.X_add_number), 0); 4003 1.1 christos } 4004 1.1 christos 4005 1.1 christos static void 4006 1.1 christos dot_spillreg (int pred) 4007 1.1 christos { 4008 1.1 christos int sep; 4009 1.1 christos unsigned int qp, ab, xy, reg, treg; 4010 1.1 christos expressionS e; 4011 1.1 christos const char * const po = pred ? "spillreg.p" : "spillreg"; 4012 1.1 christos 4013 1.1 christos if (!in_procedure (po)) 4014 1.1 christos return; 4015 1.1 christos 4016 1.1 christos if (pred) 4017 1.1 christos sep = parse_predicate_and_operand (&e, &qp, po); 4018 1.1 christos else 4019 1.1 christos { 4020 1.1 christos sep = parse_operand_and_eval (&e, ','); 4021 1.1 christos qp = 0; 4022 1.1 christos } 4023 1.1 christos convert_expr_to_ab_reg (&e, &ab, ®, po, 1 + pred); 4024 1.1 christos 4025 1.1 christos if (sep == ',') 4026 1.1 christos sep = parse_operand_and_eval (&e, ','); 4027 1.1 christos else 4028 1.1 christos e.X_op = O_absent; 4029 1.1 christos convert_expr_to_xy_reg (&e, &xy, &treg, po, 2 + pred); 4030 1.1 christos 4031 1.1 christos add_unwind_entry (output_spill_reg (ab, reg, treg, xy, qp), sep); 4032 1.1 christos } 4033 1.1 christos 4034 1.1 christos static void 4035 1.1 christos dot_spillmem (int psprel) 4036 1.1 christos { 4037 1.1 christos expressionS e; 4038 1.1 christos int pred = (psprel < 0), sep; 4039 1.1 christos unsigned int qp, ab, reg; 4040 1.1 christos const char * po; 4041 1.1 christos 4042 1.1 christos if (pred) 4043 1.1 christos { 4044 1.1 christos psprel = ~psprel; 4045 1.1 christos po = psprel ? "spillpsp.p" : "spillsp.p"; 4046 1.1 christos } 4047 1.1 christos else 4048 1.1 christos po = psprel ? "spillpsp" : "spillsp"; 4049 1.1 christos 4050 1.1 christos if (!in_procedure (po)) 4051 1.1 christos return; 4052 1.1 christos 4053 1.1 christos if (pred) 4054 1.1 christos sep = parse_predicate_and_operand (&e, &qp, po); 4055 1.1 christos else 4056 1.1 christos { 4057 1.1 christos sep = parse_operand_and_eval (&e, ','); 4058 1.1 christos qp = 0; 4059 1.1 christos } 4060 1.1 christos convert_expr_to_ab_reg (&e, &ab, ®, po, 1 + pred); 4061 1.1 christos 4062 1.1 christos if (sep == ',') 4063 1.1 christos sep = parse_operand_and_eval (&e, ','); 4064 1.1 christos else 4065 1.1 christos e.X_op = O_absent; 4066 1.1 christos if (e.X_op != O_constant) 4067 1.1 christos { 4068 1.1 christos as_bad (_("Operand %d to .%s must be a constant"), 2 + pred, po); 4069 1.1 christos e.X_add_number = 0; 4070 1.1 christos } 4071 1.1 christos 4072 1.1 christos if (psprel) 4073 1.1 christos add_unwind_entry (output_spill_psprel (ab, reg, e.X_add_number, qp), sep); 4074 1.1 christos else 4075 1.1 christos add_unwind_entry (output_spill_sprel (ab, reg, e.X_add_number, qp), sep); 4076 1.1 christos } 4077 1.1 christos 4078 1.1 christos static unsigned int 4079 1.1 christos get_saved_prologue_count (unsigned long lbl) 4080 1.1 christos { 4081 1.1 christos label_prologue_count *lpc = unwind.saved_prologue_counts; 4082 1.1 christos 4083 1.1 christos while (lpc != NULL && lpc->label_number != lbl) 4084 1.1 christos lpc = lpc->next; 4085 1.1 christos 4086 1.1 christos if (lpc != NULL) 4087 1.1 christos return lpc->prologue_count; 4088 1.1 christos 4089 1.1 christos as_bad (_("Missing .label_state %ld"), lbl); 4090 1.1 christos return 1; 4091 1.1 christos } 4092 1.1 christos 4093 1.1 christos static void 4094 1.1 christos save_prologue_count (unsigned long lbl, unsigned int count) 4095 1.1 christos { 4096 1.1 christos label_prologue_count *lpc = unwind.saved_prologue_counts; 4097 1.1 christos 4098 1.1 christos while (lpc != NULL && lpc->label_number != lbl) 4099 1.1 christos lpc = lpc->next; 4100 1.1 christos 4101 1.1 christos if (lpc != NULL) 4102 1.1 christos lpc->prologue_count = count; 4103 1.1 christos else 4104 1.1 christos { 4105 1.5 christos label_prologue_count *new_lpc = XNEW (label_prologue_count); 4106 1.1 christos 4107 1.1 christos new_lpc->next = unwind.saved_prologue_counts; 4108 1.1 christos new_lpc->label_number = lbl; 4109 1.1 christos new_lpc->prologue_count = count; 4110 1.1 christos unwind.saved_prologue_counts = new_lpc; 4111 1.1 christos } 4112 1.1 christos } 4113 1.1 christos 4114 1.1 christos static void 4115 1.5 christos free_saved_prologue_counts (void) 4116 1.1 christos { 4117 1.1 christos label_prologue_count *lpc = unwind.saved_prologue_counts; 4118 1.1 christos label_prologue_count *next; 4119 1.1 christos 4120 1.1 christos while (lpc != NULL) 4121 1.1 christos { 4122 1.1 christos next = lpc->next; 4123 1.1 christos free (lpc); 4124 1.1 christos lpc = next; 4125 1.1 christos } 4126 1.1 christos 4127 1.1 christos unwind.saved_prologue_counts = NULL; 4128 1.1 christos } 4129 1.1 christos 4130 1.1 christos static void 4131 1.1 christos dot_label_state (int dummy ATTRIBUTE_UNUSED) 4132 1.1 christos { 4133 1.1 christos expressionS e; 4134 1.1 christos 4135 1.1 christos if (!in_body ("label_state")) 4136 1.1 christos return; 4137 1.1 christos 4138 1.1 christos parse_operand_and_eval (&e, 0); 4139 1.1 christos if (e.X_op == O_constant) 4140 1.1 christos save_prologue_count (e.X_add_number, unwind.prologue_count); 4141 1.1 christos else 4142 1.1 christos { 4143 1.1 christos as_bad (_("Operand to .label_state must be a constant")); 4144 1.1 christos e.X_add_number = 0; 4145 1.1 christos } 4146 1.1 christos add_unwind_entry (output_label_state (e.X_add_number), 0); 4147 1.1 christos } 4148 1.1 christos 4149 1.1 christos static void 4150 1.1 christos dot_copy_state (int dummy ATTRIBUTE_UNUSED) 4151 1.1 christos { 4152 1.1 christos expressionS e; 4153 1.1 christos 4154 1.1 christos if (!in_body ("copy_state")) 4155 1.1 christos return; 4156 1.1 christos 4157 1.1 christos parse_operand_and_eval (&e, 0); 4158 1.1 christos if (e.X_op == O_constant) 4159 1.1 christos unwind.prologue_count = get_saved_prologue_count (e.X_add_number); 4160 1.1 christos else 4161 1.1 christos { 4162 1.1 christos as_bad (_("Operand to .copy_state must be a constant")); 4163 1.1 christos e.X_add_number = 0; 4164 1.1 christos } 4165 1.1 christos add_unwind_entry (output_copy_state (e.X_add_number), 0); 4166 1.1 christos } 4167 1.1 christos 4168 1.1 christos static void 4169 1.1 christos dot_unwabi (int dummy ATTRIBUTE_UNUSED) 4170 1.1 christos { 4171 1.1 christos expressionS e1, e2; 4172 1.1 christos unsigned char sep; 4173 1.1 christos 4174 1.1 christos if (!in_prologue ("unwabi")) 4175 1.1 christos return; 4176 1.1 christos 4177 1.1 christos sep = parse_operand_and_eval (&e1, ','); 4178 1.1 christos if (sep == ',') 4179 1.1 christos parse_operand_and_eval (&e2, 0); 4180 1.1 christos else 4181 1.1 christos e2.X_op = O_absent; 4182 1.1 christos 4183 1.1 christos if (e1.X_op != O_constant) 4184 1.1 christos { 4185 1.1 christos as_bad (_("First operand to .unwabi must be a constant")); 4186 1.1 christos e1.X_add_number = 0; 4187 1.1 christos } 4188 1.1 christos 4189 1.1 christos if (e2.X_op != O_constant) 4190 1.1 christos { 4191 1.1 christos as_bad (_("Second operand to .unwabi must be a constant")); 4192 1.1 christos e2.X_add_number = 0; 4193 1.1 christos } 4194 1.1 christos 4195 1.1 christos add_unwind_entry (output_unwabi (e1.X_add_number, e2.X_add_number), 0); 4196 1.1 christos } 4197 1.1 christos 4198 1.1 christos static void 4199 1.1 christos dot_personality (int dummy ATTRIBUTE_UNUSED) 4200 1.1 christos { 4201 1.10 christos char *name, c; 4202 1.3 christos 4203 1.1 christos if (!in_procedure ("personality")) 4204 1.1 christos return; 4205 1.1 christos SKIP_WHITESPACE (); 4206 1.3 christos c = get_symbol_name (&name); 4207 1.1 christos unwind.personality_routine = symbol_find_or_make (name); 4208 1.1 christos unwind.force_unwind_entry = 1; 4209 1.10 christos restore_line_pointer (c); 4210 1.10 christos SKIP_WHITESPACE (); 4211 1.1 christos demand_empty_rest_of_line (); 4212 1.1 christos } 4213 1.1 christos 4214 1.1 christos static void 4215 1.1 christos dot_proc (int dummy ATTRIBUTE_UNUSED) 4216 1.1 christos { 4217 1.10 christos char *name, c; 4218 1.1 christos symbolS *sym; 4219 1.1 christos proc_pending *pending, *last_pending; 4220 1.1 christos 4221 1.1 christos if (unwind.proc_pending.sym) 4222 1.1 christos { 4223 1.1 christos (md.unwind_check == unwind_check_warning 4224 1.1 christos ? as_warn 4225 1.1 christos : as_bad) (_("Missing .endp after previous .proc")); 4226 1.1 christos while (unwind.proc_pending.next) 4227 1.1 christos { 4228 1.1 christos pending = unwind.proc_pending.next; 4229 1.1 christos unwind.proc_pending.next = pending->next; 4230 1.1 christos free (pending); 4231 1.1 christos } 4232 1.1 christos } 4233 1.1 christos last_pending = NULL; 4234 1.1 christos 4235 1.1 christos /* Parse names of main and alternate entry points and mark them as 4236 1.1 christos function symbols: */ 4237 1.1 christos while (1) 4238 1.1 christos { 4239 1.1 christos SKIP_WHITESPACE (); 4240 1.3 christos c = get_symbol_name (&name); 4241 1.1 christos if (!*name) 4242 1.1 christos as_bad (_("Empty argument of .proc")); 4243 1.1 christos else 4244 1.1 christos { 4245 1.1 christos sym = symbol_find_or_make (name); 4246 1.1 christos if (S_IS_DEFINED (sym)) 4247 1.1 christos as_bad (_("`%s' was already defined"), name); 4248 1.1 christos else if (!last_pending) 4249 1.1 christos { 4250 1.1 christos unwind.proc_pending.sym = sym; 4251 1.1 christos last_pending = &unwind.proc_pending; 4252 1.1 christos } 4253 1.1 christos else 4254 1.1 christos { 4255 1.5 christos pending = XNEW (proc_pending); 4256 1.1 christos pending->sym = sym; 4257 1.1 christos last_pending = last_pending->next = pending; 4258 1.1 christos } 4259 1.1 christos symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION; 4260 1.1 christos } 4261 1.10 christos restore_line_pointer (c); 4262 1.10 christos SKIP_WHITESPACE (); 4263 1.1 christos if (*input_line_pointer != ',') 4264 1.1 christos break; 4265 1.1 christos ++input_line_pointer; 4266 1.1 christos } 4267 1.1 christos if (!last_pending) 4268 1.1 christos { 4269 1.1 christos unwind.proc_pending.sym = expr_build_dot (); 4270 1.1 christos last_pending = &unwind.proc_pending; 4271 1.1 christos } 4272 1.1 christos last_pending->next = NULL; 4273 1.1 christos demand_empty_rest_of_line (); 4274 1.5 christos do_align (4, NULL, 0, 0); 4275 1.1 christos 4276 1.1 christos unwind.prologue = 0; 4277 1.1 christos unwind.prologue_count = 0; 4278 1.1 christos unwind.body = 0; 4279 1.1 christos unwind.insn = 0; 4280 1.1 christos unwind.list = unwind.tail = unwind.current_entry = NULL; 4281 1.1 christos unwind.personality_routine = 0; 4282 1.1 christos } 4283 1.1 christos 4284 1.1 christos static void 4285 1.1 christos dot_body (int dummy ATTRIBUTE_UNUSED) 4286 1.1 christos { 4287 1.1 christos if (!in_procedure ("body")) 4288 1.1 christos return; 4289 1.1 christos if (!unwind.prologue && !unwind.body && unwind.insn) 4290 1.1 christos as_warn (_("Initial .body should precede any instructions")); 4291 1.1 christos check_pending_save (); 4292 1.1 christos 4293 1.1 christos unwind.prologue = 0; 4294 1.1 christos unwind.prologue_mask = 0; 4295 1.1 christos unwind.body = 1; 4296 1.1 christos 4297 1.1 christos add_unwind_entry (output_body (), 0); 4298 1.1 christos } 4299 1.1 christos 4300 1.1 christos static void 4301 1.1 christos dot_prologue (int dummy ATTRIBUTE_UNUSED) 4302 1.1 christos { 4303 1.1 christos unsigned mask = 0, grsave = 0; 4304 1.1 christos 4305 1.1 christos if (!in_procedure ("prologue")) 4306 1.1 christos return; 4307 1.1 christos if (unwind.prologue) 4308 1.1 christos { 4309 1.1 christos as_bad (_(".prologue within prologue")); 4310 1.1 christos ignore_rest_of_line (); 4311 1.1 christos return; 4312 1.1 christos } 4313 1.1 christos if (!unwind.body && unwind.insn) 4314 1.1 christos as_warn (_("Initial .prologue should precede any instructions")); 4315 1.1 christos 4316 1.1 christos if (!is_it_end_of_statement ()) 4317 1.1 christos { 4318 1.1 christos expressionS e; 4319 1.1 christos int n, sep = parse_operand_and_eval (&e, ','); 4320 1.1 christos 4321 1.1 christos if (e.X_op != O_constant 4322 1.1 christos || e.X_add_number < 0 4323 1.1 christos || e.X_add_number > 0xf) 4324 1.1 christos as_bad (_("First operand to .prologue must be a positive 4-bit constant")); 4325 1.1 christos else if (e.X_add_number == 0) 4326 1.1 christos as_warn (_("Pointless use of zero first operand to .prologue")); 4327 1.1 christos else 4328 1.1 christos mask = e.X_add_number; 4329 1.5 christos 4330 1.5 christos n = popcount (mask); 4331 1.1 christos 4332 1.1 christos if (sep == ',') 4333 1.1 christos parse_operand_and_eval (&e, 0); 4334 1.1 christos else 4335 1.1 christos e.X_op = O_absent; 4336 1.5 christos 4337 1.1 christos if (e.X_op == O_constant 4338 1.1 christos && e.X_add_number >= 0 4339 1.1 christos && e.X_add_number < 128) 4340 1.1 christos { 4341 1.1 christos if (md.unwind_check == unwind_check_error) 4342 1.1 christos as_warn (_("Using a constant as second operand to .prologue is deprecated")); 4343 1.1 christos grsave = e.X_add_number; 4344 1.1 christos } 4345 1.1 christos else if (e.X_op != O_register 4346 1.1 christos || (grsave = e.X_add_number - REG_GR) > 127) 4347 1.1 christos { 4348 1.1 christos as_bad (_("Second operand to .prologue must be a general register")); 4349 1.1 christos grsave = 0; 4350 1.1 christos } 4351 1.1 christos else if (grsave > 128U - n) 4352 1.1 christos { 4353 1.1 christos as_bad (_("Second operand to .prologue must be the first of %d general registers"), n); 4354 1.1 christos grsave = 0; 4355 1.1 christos } 4356 1.1 christos } 4357 1.1 christos 4358 1.1 christos if (mask) 4359 1.1 christos add_unwind_entry (output_prologue_gr (mask, grsave), 0); 4360 1.1 christos else 4361 1.1 christos add_unwind_entry (output_prologue (), 0); 4362 1.1 christos 4363 1.1 christos unwind.prologue = 1; 4364 1.1 christos unwind.prologue_mask = mask; 4365 1.1 christos unwind.prologue_gr = grsave; 4366 1.1 christos unwind.body = 0; 4367 1.1 christos ++unwind.prologue_count; 4368 1.1 christos } 4369 1.1 christos 4370 1.1 christos static void 4371 1.1 christos dot_endp (int dummy ATTRIBUTE_UNUSED) 4372 1.1 christos { 4373 1.1 christos expressionS e; 4374 1.1 christos int bytes_per_address; 4375 1.1 christos long where; 4376 1.1 christos segT saved_seg; 4377 1.1 christos subsegT saved_subseg; 4378 1.1 christos proc_pending *pending; 4379 1.1 christos int unwind_check = md.unwind_check; 4380 1.1 christos 4381 1.1 christos md.unwind_check = unwind_check_error; 4382 1.1 christos if (!in_procedure ("endp")) 4383 1.1 christos return; 4384 1.1 christos md.unwind_check = unwind_check; 4385 1.1 christos 4386 1.1 christos if (unwind.saved_text_seg) 4387 1.1 christos { 4388 1.1 christos saved_seg = unwind.saved_text_seg; 4389 1.1 christos saved_subseg = unwind.saved_text_subseg; 4390 1.1 christos unwind.saved_text_seg = NULL; 4391 1.1 christos } 4392 1.1 christos else 4393 1.1 christos { 4394 1.1 christos saved_seg = now_seg; 4395 1.1 christos saved_subseg = now_subseg; 4396 1.1 christos } 4397 1.1 christos 4398 1.1 christos insn_group_break (1, 0, 0); 4399 1.1 christos 4400 1.1 christos /* If there wasn't a .handlerdata, we haven't generated an image yet. */ 4401 1.1 christos if (!unwind.info) 4402 1.1 christos generate_unwind_image (saved_seg); 4403 1.1 christos 4404 1.1 christos if (unwind.info || unwind.force_unwind_entry) 4405 1.1 christos { 4406 1.1 christos symbolS *proc_end; 4407 1.1 christos 4408 1.8 christos subseg_set (md.last_text_seg, md.last_text_subseg); 4409 1.1 christos proc_end = expr_build_dot (); 4410 1.1 christos 4411 1.1 christos start_unwind_section (saved_seg, SPECIAL_SECTION_UNWIND); 4412 1.1 christos 4413 1.1 christos /* Make sure that section has 4 byte alignment for ILP32 and 4414 1.1 christos 8 byte alignment for LP64. */ 4415 1.1 christos record_alignment (now_seg, md.pointer_size_shift); 4416 1.1 christos 4417 1.1 christos /* Need space for 3 pointers for procedure start, procedure end, 4418 1.1 christos and unwind info. */ 4419 1.1 christos memset (frag_more (3 * md.pointer_size), 0, 3 * md.pointer_size); 4420 1.1 christos where = frag_now_fix () - (3 * md.pointer_size); 4421 1.1 christos bytes_per_address = bfd_arch_bits_per_address (stdoutput) / 8; 4422 1.1 christos 4423 1.1 christos /* Issue the values of a) Proc Begin, b) Proc End, c) Unwind Record. */ 4424 1.1 christos e.X_op = O_pseudo_fixup; 4425 1.1 christos e.X_op_symbol = pseudo_func[FUNC_SEG_RELATIVE].u.sym; 4426 1.1 christos e.X_add_number = 0; 4427 1.1 christos if (!S_IS_LOCAL (unwind.proc_pending.sym) 4428 1.1 christos && S_IS_DEFINED (unwind.proc_pending.sym)) 4429 1.8 christos e.X_add_symbol 4430 1.8 christos = symbol_temp_new (S_GET_SEGMENT (unwind.proc_pending.sym), 4431 1.8 christos symbol_get_frag (unwind.proc_pending.sym), 4432 1.8 christos S_GET_VALUE (unwind.proc_pending.sym)); 4433 1.1 christos else 4434 1.1 christos e.X_add_symbol = unwind.proc_pending.sym; 4435 1.3 christos ia64_cons_fix_new (frag_now, where, bytes_per_address, &e, 4436 1.3 christos BFD_RELOC_NONE); 4437 1.1 christos 4438 1.1 christos e.X_op = O_pseudo_fixup; 4439 1.1 christos e.X_op_symbol = pseudo_func[FUNC_SEG_RELATIVE].u.sym; 4440 1.1 christos e.X_add_number = 0; 4441 1.1 christos e.X_add_symbol = proc_end; 4442 1.1 christos ia64_cons_fix_new (frag_now, where + bytes_per_address, 4443 1.3 christos bytes_per_address, &e, BFD_RELOC_NONE); 4444 1.1 christos 4445 1.1 christos if (unwind.info) 4446 1.1 christos { 4447 1.1 christos e.X_op = O_pseudo_fixup; 4448 1.1 christos e.X_op_symbol = pseudo_func[FUNC_SEG_RELATIVE].u.sym; 4449 1.1 christos e.X_add_number = 0; 4450 1.1 christos e.X_add_symbol = unwind.info; 4451 1.1 christos ia64_cons_fix_new (frag_now, where + (bytes_per_address * 2), 4452 1.3 christos bytes_per_address, &e, BFD_RELOC_NONE); 4453 1.1 christos } 4454 1.1 christos } 4455 1.1 christos subseg_set (saved_seg, saved_subseg); 4456 1.1 christos 4457 1.1 christos /* Set symbol sizes. */ 4458 1.1 christos pending = &unwind.proc_pending; 4459 1.1 christos if (S_GET_NAME (pending->sym)) 4460 1.1 christos { 4461 1.1 christos do 4462 1.1 christos { 4463 1.1 christos symbolS *sym = pending->sym; 4464 1.1 christos 4465 1.1 christos if (!S_IS_DEFINED (sym)) 4466 1.1 christos as_bad (_("`%s' was not defined within procedure"), S_GET_NAME (sym)); 4467 1.1 christos else if (S_GET_SIZE (sym) == 0 4468 1.1 christos && symbol_get_obj (sym)->size == NULL) 4469 1.1 christos { 4470 1.1 christos fragS *frag = symbol_get_frag (sym); 4471 1.1 christos 4472 1.1 christos if (frag) 4473 1.1 christos { 4474 1.1 christos if (frag == frag_now && SEG_NORMAL (now_seg)) 4475 1.1 christos S_SET_SIZE (sym, frag_now_fix () - S_GET_VALUE (sym)); 4476 1.1 christos else 4477 1.1 christos { 4478 1.10 christos OBJ_SYMFIELD_TYPE *obj = symbol_get_obj (sym); 4479 1.10 christos obj->size = notes_alloc (sizeof (*obj->size)); 4480 1.10 christos obj->size->X_op = O_subtract; 4481 1.10 christos obj->size->X_add_symbol 4482 1.1 christos = symbol_new (FAKE_LABEL_NAME, now_seg, 4483 1.8 christos frag_now, frag_now_fix ()); 4484 1.10 christos obj->size->X_op_symbol = sym; 4485 1.10 christos obj->size->X_add_number = 0; 4486 1.1 christos } 4487 1.1 christos } 4488 1.1 christos } 4489 1.1 christos } while ((pending = pending->next) != NULL); 4490 1.1 christos } 4491 1.1 christos 4492 1.1 christos /* Parse names of main and alternate entry points. */ 4493 1.1 christos while (1) 4494 1.1 christos { 4495 1.10 christos char *name, c; 4496 1.1 christos 4497 1.1 christos SKIP_WHITESPACE (); 4498 1.3 christos c = get_symbol_name (&name); 4499 1.1 christos if (!*name) 4500 1.1 christos (md.unwind_check == unwind_check_warning 4501 1.1 christos ? as_warn 4502 1.1 christos : as_bad) (_("Empty argument of .endp")); 4503 1.1 christos else 4504 1.1 christos { 4505 1.1 christos symbolS *sym = symbol_find (name); 4506 1.1 christos 4507 1.1 christos for (pending = &unwind.proc_pending; pending; pending = pending->next) 4508 1.1 christos { 4509 1.1 christos if (sym == pending->sym) 4510 1.1 christos { 4511 1.1 christos pending->sym = NULL; 4512 1.1 christos break; 4513 1.1 christos } 4514 1.1 christos } 4515 1.1 christos if (!sym || !pending) 4516 1.1 christos as_warn (_("`%s' was not specified with previous .proc"), name); 4517 1.1 christos } 4518 1.10 christos restore_line_pointer (c); 4519 1.10 christos SKIP_WHITESPACE (); 4520 1.1 christos if (*input_line_pointer != ',') 4521 1.1 christos break; 4522 1.1 christos ++input_line_pointer; 4523 1.1 christos } 4524 1.1 christos demand_empty_rest_of_line (); 4525 1.1 christos 4526 1.1 christos /* Deliberately only checking for the main entry point here; the 4527 1.1 christos language spec even says all arguments to .endp are ignored. */ 4528 1.1 christos if (unwind.proc_pending.sym 4529 1.1 christos && S_GET_NAME (unwind.proc_pending.sym) 4530 1.1 christos && strcmp (S_GET_NAME (unwind.proc_pending.sym), FAKE_LABEL_NAME)) 4531 1.1 christos as_warn (_("`%s' should be an operand to this .endp"), 4532 1.1 christos S_GET_NAME (unwind.proc_pending.sym)); 4533 1.1 christos while (unwind.proc_pending.next) 4534 1.1 christos { 4535 1.1 christos pending = unwind.proc_pending.next; 4536 1.1 christos unwind.proc_pending.next = pending->next; 4537 1.1 christos free (pending); 4538 1.1 christos } 4539 1.1 christos unwind.proc_pending.sym = unwind.info = NULL; 4540 1.1 christos } 4541 1.1 christos 4542 1.1 christos static void 4543 1.1 christos dot_template (int template_val) 4544 1.1 christos { 4545 1.1 christos CURR_SLOT.user_template = template_val; 4546 1.1 christos } 4547 1.1 christos 4548 1.1 christos static void 4549 1.1 christos dot_regstk (int dummy ATTRIBUTE_UNUSED) 4550 1.1 christos { 4551 1.1 christos int ins, locs, outs, rots; 4552 1.1 christos 4553 1.1 christos if (is_it_end_of_statement ()) 4554 1.1 christos ins = locs = outs = rots = 0; 4555 1.1 christos else 4556 1.1 christos { 4557 1.1 christos ins = get_absolute_expression (); 4558 1.1 christos if (*input_line_pointer++ != ',') 4559 1.1 christos goto err; 4560 1.1 christos locs = get_absolute_expression (); 4561 1.1 christos if (*input_line_pointer++ != ',') 4562 1.1 christos goto err; 4563 1.1 christos outs = get_absolute_expression (); 4564 1.1 christos if (*input_line_pointer++ != ',') 4565 1.1 christos goto err; 4566 1.1 christos rots = get_absolute_expression (); 4567 1.1 christos } 4568 1.1 christos set_regstack (ins, locs, outs, rots); 4569 1.1 christos return; 4570 1.1 christos 4571 1.1 christos err: 4572 1.1 christos as_bad (_("Comma expected")); 4573 1.1 christos ignore_rest_of_line (); 4574 1.1 christos } 4575 1.1 christos 4576 1.1 christos static void 4577 1.1 christos dot_rot (int type) 4578 1.1 christos { 4579 1.1 christos offsetT num_regs; 4580 1.1 christos valueT num_alloced = 0; 4581 1.1 christos struct dynreg **drpp, *dr; 4582 1.1 christos int ch, base_reg = 0; 4583 1.1 christos char *name, *start; 4584 1.1 christos size_t len; 4585 1.1 christos 4586 1.1 christos switch (type) 4587 1.1 christos { 4588 1.1 christos case DYNREG_GR: base_reg = REG_GR + 32; break; 4589 1.1 christos case DYNREG_FR: base_reg = REG_FR + 32; break; 4590 1.1 christos case DYNREG_PR: base_reg = REG_P + 16; break; 4591 1.1 christos default: break; 4592 1.1 christos } 4593 1.1 christos 4594 1.1 christos /* First, remove existing names from hash table. */ 4595 1.1 christos for (dr = md.dynreg[type]; dr && dr->num_regs; dr = dr->next) 4596 1.1 christos { 4597 1.8 christos str_hash_delete (md.dynreg_hash, dr->name); 4598 1.1 christos /* FIXME: Free dr->name. */ 4599 1.1 christos dr->num_regs = 0; 4600 1.1 christos } 4601 1.1 christos 4602 1.1 christos drpp = &md.dynreg[type]; 4603 1.1 christos while (1) 4604 1.1 christos { 4605 1.3 christos ch = get_symbol_name (&start); 4606 1.1 christos len = strlen (ia64_canonicalize_symbol_name (start)); 4607 1.10 christos restore_line_pointer (ch); 4608 1.1 christos 4609 1.10 christos SKIP_WHITESPACE (); 4610 1.1 christos if (*input_line_pointer != '[') 4611 1.1 christos { 4612 1.1 christos as_bad (_("Expected '['")); 4613 1.1 christos goto err; 4614 1.1 christos } 4615 1.1 christos ++input_line_pointer; /* skip '[' */ 4616 1.1 christos 4617 1.1 christos num_regs = get_absolute_expression (); 4618 1.1 christos 4619 1.1 christos if (*input_line_pointer++ != ']') 4620 1.1 christos { 4621 1.1 christos as_bad (_("Expected ']'")); 4622 1.1 christos goto err; 4623 1.1 christos } 4624 1.1 christos if (num_regs <= 0) 4625 1.1 christos { 4626 1.1 christos as_bad (_("Number of elements must be positive")); 4627 1.1 christos goto err; 4628 1.1 christos } 4629 1.1 christos SKIP_WHITESPACE (); 4630 1.1 christos 4631 1.1 christos num_alloced += num_regs; 4632 1.1 christos switch (type) 4633 1.1 christos { 4634 1.1 christos case DYNREG_GR: 4635 1.1 christos if (num_alloced > md.rot.num_regs) 4636 1.1 christos { 4637 1.1 christos as_bad (_("Used more than the declared %d rotating registers"), 4638 1.1 christos md.rot.num_regs); 4639 1.1 christos goto err; 4640 1.1 christos } 4641 1.1 christos break; 4642 1.1 christos case DYNREG_FR: 4643 1.1 christos if (num_alloced > 96) 4644 1.1 christos { 4645 1.1 christos as_bad (_("Used more than the available 96 rotating registers")); 4646 1.1 christos goto err; 4647 1.1 christos } 4648 1.1 christos break; 4649 1.1 christos case DYNREG_PR: 4650 1.1 christos if (num_alloced > 48) 4651 1.1 christos { 4652 1.1 christos as_bad (_("Used more than the available 48 rotating registers")); 4653 1.1 christos goto err; 4654 1.1 christos } 4655 1.1 christos break; 4656 1.1 christos 4657 1.1 christos default: 4658 1.1 christos break; 4659 1.1 christos } 4660 1.1 christos 4661 1.1 christos if (!*drpp) 4662 1.9 christos *drpp = notes_calloc (1, sizeof (**drpp)); 4663 1.1 christos 4664 1.9 christos name = notes_memdup (start, len, len + 1); 4665 1.1 christos 4666 1.1 christos dr = *drpp; 4667 1.1 christos dr->name = name; 4668 1.1 christos dr->num_regs = num_regs; 4669 1.1 christos dr->base = base_reg; 4670 1.1 christos drpp = &dr->next; 4671 1.1 christos base_reg += num_regs; 4672 1.1 christos 4673 1.8 christos if (str_hash_insert (md.dynreg_hash, name, dr, 0) != NULL) 4674 1.1 christos { 4675 1.1 christos as_bad (_("Attempt to redefine register set `%s'"), name); 4676 1.1 christos goto err; 4677 1.1 christos } 4678 1.1 christos 4679 1.1 christos if (*input_line_pointer != ',') 4680 1.1 christos break; 4681 1.1 christos ++input_line_pointer; /* skip comma */ 4682 1.1 christos SKIP_WHITESPACE (); 4683 1.1 christos } 4684 1.1 christos demand_empty_rest_of_line (); 4685 1.1 christos return; 4686 1.1 christos 4687 1.1 christos err: 4688 1.1 christos ignore_rest_of_line (); 4689 1.1 christos } 4690 1.1 christos 4691 1.1 christos static void 4692 1.1 christos dot_byteorder (int byteorder) 4693 1.1 christos { 4694 1.1 christos segment_info_type *seginfo = seg_info (now_seg); 4695 1.1 christos 4696 1.1 christos if (byteorder == -1) 4697 1.1 christos { 4698 1.1 christos if (seginfo->tc_segment_info_data.endian == 0) 4699 1.1 christos seginfo->tc_segment_info_data.endian = default_big_endian ? 1 : 2; 4700 1.1 christos byteorder = seginfo->tc_segment_info_data.endian == 1; 4701 1.1 christos } 4702 1.1 christos else 4703 1.1 christos seginfo->tc_segment_info_data.endian = byteorder ? 1 : 2; 4704 1.1 christos 4705 1.1 christos if (target_big_endian != byteorder) 4706 1.1 christos { 4707 1.1 christos target_big_endian = byteorder; 4708 1.1 christos if (target_big_endian) 4709 1.1 christos { 4710 1.1 christos ia64_number_to_chars = number_to_chars_bigendian; 4711 1.1 christos ia64_float_to_chars = ia64_float_to_chars_bigendian; 4712 1.1 christos } 4713 1.1 christos else 4714 1.1 christos { 4715 1.1 christos ia64_number_to_chars = number_to_chars_littleendian; 4716 1.1 christos ia64_float_to_chars = ia64_float_to_chars_littleendian; 4717 1.1 christos } 4718 1.1 christos } 4719 1.1 christos } 4720 1.1 christos 4721 1.1 christos static void 4722 1.1 christos dot_psr (int dummy ATTRIBUTE_UNUSED) 4723 1.1 christos { 4724 1.1 christos char *option; 4725 1.1 christos int ch; 4726 1.1 christos 4727 1.1 christos while (1) 4728 1.1 christos { 4729 1.3 christos ch = get_symbol_name (&option); 4730 1.1 christos if (strcmp (option, "lsb") == 0) 4731 1.1 christos md.flags &= ~EF_IA_64_BE; 4732 1.1 christos else if (strcmp (option, "msb") == 0) 4733 1.1 christos md.flags |= EF_IA_64_BE; 4734 1.1 christos else if (strcmp (option, "abi32") == 0) 4735 1.1 christos md.flags &= ~EF_IA_64_ABI64; 4736 1.1 christos else if (strcmp (option, "abi64") == 0) 4737 1.1 christos md.flags |= EF_IA_64_ABI64; 4738 1.1 christos else 4739 1.1 christos as_bad (_("Unknown psr option `%s'"), option); 4740 1.10 christos restore_line_pointer (ch); 4741 1.1 christos 4742 1.10 christos SKIP_WHITESPACE (); 4743 1.1 christos if (*input_line_pointer != ',') 4744 1.1 christos break; 4745 1.1 christos 4746 1.1 christos ++input_line_pointer; 4747 1.1 christos SKIP_WHITESPACE (); 4748 1.1 christos } 4749 1.1 christos demand_empty_rest_of_line (); 4750 1.1 christos } 4751 1.1 christos 4752 1.1 christos static void 4753 1.1 christos dot_ln (int dummy ATTRIBUTE_UNUSED) 4754 1.1 christos { 4755 1.1 christos new_logical_line (0, get_absolute_expression ()); 4756 1.1 christos demand_empty_rest_of_line (); 4757 1.1 christos } 4758 1.1 christos 4759 1.1 christos static void 4760 1.1 christos cross_section (int ref, void (*builder) (int), int ua) 4761 1.1 christos { 4762 1.1 christos char *start, *end; 4763 1.1 christos int saved_auto_align; 4764 1.1 christos unsigned int section_count; 4765 1.8 christos const char *name; 4766 1.1 christos 4767 1.1 christos start = input_line_pointer; 4768 1.8 christos name = obj_elf_section_name (); 4769 1.8 christos if (name == NULL) 4770 1.8 christos return; 4771 1.1 christos end = input_line_pointer; 4772 1.1 christos if (*input_line_pointer != ',') 4773 1.1 christos { 4774 1.1 christos as_bad (_("Comma expected after section name")); 4775 1.1 christos ignore_rest_of_line (); 4776 1.1 christos return; 4777 1.1 christos } 4778 1.1 christos *end = '\0'; 4779 1.1 christos end = input_line_pointer + 1; /* skip comma */ 4780 1.1 christos input_line_pointer = start; 4781 1.1 christos md.keep_pending_output = 1; 4782 1.1 christos section_count = bfd_count_sections (stdoutput); 4783 1.1 christos obj_elf_section (0); 4784 1.1 christos if (section_count != bfd_count_sections (stdoutput)) 4785 1.1 christos as_warn (_("Creating sections with .xdataN/.xrealN/.xstringZ is deprecated.")); 4786 1.1 christos input_line_pointer = end; 4787 1.1 christos saved_auto_align = md.auto_align; 4788 1.1 christos if (ua) 4789 1.1 christos md.auto_align = 0; 4790 1.1 christos (*builder) (ref); 4791 1.1 christos if (ua) 4792 1.1 christos md.auto_align = saved_auto_align; 4793 1.1 christos obj_elf_previous (0); 4794 1.1 christos md.keep_pending_output = 0; 4795 1.1 christos } 4796 1.1 christos 4797 1.1 christos static void 4798 1.1 christos dot_xdata (int size) 4799 1.1 christos { 4800 1.1 christos cross_section (size, cons, 0); 4801 1.1 christos } 4802 1.1 christos 4803 1.1 christos /* Why doesn't float_cons() call md_cons_align() the way cons() does? */ 4804 1.1 christos 4805 1.1 christos static void 4806 1.1 christos stmt_float_cons (int kind) 4807 1.1 christos { 4808 1.1 christos size_t alignment; 4809 1.1 christos 4810 1.1 christos switch (kind) 4811 1.1 christos { 4812 1.1 christos case 'd': 4813 1.5 christos alignment = 3; 4814 1.1 christos break; 4815 1.1 christos 4816 1.1 christos case 'x': 4817 1.1 christos case 'X': 4818 1.5 christos alignment = 4; 4819 1.1 christos break; 4820 1.1 christos 4821 1.1 christos case 'f': 4822 1.1 christos default: 4823 1.5 christos alignment = 2; 4824 1.1 christos break; 4825 1.1 christos } 4826 1.5 christos do_align (alignment, NULL, 0, 0); 4827 1.1 christos float_cons (kind); 4828 1.1 christos } 4829 1.1 christos 4830 1.1 christos static void 4831 1.1 christos stmt_cons_ua (int size) 4832 1.1 christos { 4833 1.1 christos int saved_auto_align = md.auto_align; 4834 1.1 christos 4835 1.1 christos md.auto_align = 0; 4836 1.1 christos cons (size); 4837 1.1 christos md.auto_align = saved_auto_align; 4838 1.1 christos } 4839 1.1 christos 4840 1.1 christos static void 4841 1.1 christos dot_xfloat_cons (int kind) 4842 1.1 christos { 4843 1.1 christos cross_section (kind, stmt_float_cons, 0); 4844 1.1 christos } 4845 1.1 christos 4846 1.1 christos static void 4847 1.1 christos dot_xstringer (int zero) 4848 1.1 christos { 4849 1.1 christos cross_section (zero, stringer, 0); 4850 1.1 christos } 4851 1.1 christos 4852 1.1 christos static void 4853 1.1 christos dot_xdata_ua (int size) 4854 1.1 christos { 4855 1.1 christos cross_section (size, cons, 1); 4856 1.1 christos } 4857 1.1 christos 4858 1.1 christos static void 4859 1.1 christos dot_xfloat_cons_ua (int kind) 4860 1.1 christos { 4861 1.1 christos cross_section (kind, float_cons, 1); 4862 1.1 christos } 4863 1.1 christos 4864 1.1 christos /* .reg.val <regname>,value */ 4865 1.1 christos 4866 1.1 christos static void 4867 1.1 christos dot_reg_val (int dummy ATTRIBUTE_UNUSED) 4868 1.1 christos { 4869 1.1 christos expressionS reg; 4870 1.1 christos 4871 1.1 christos expression_and_evaluate (®); 4872 1.1 christos if (reg.X_op != O_register) 4873 1.1 christos { 4874 1.1 christos as_bad (_("Register name expected")); 4875 1.1 christos ignore_rest_of_line (); 4876 1.1 christos } 4877 1.1 christos else if (*input_line_pointer++ != ',') 4878 1.1 christos { 4879 1.1 christos as_bad (_("Comma expected")); 4880 1.1 christos ignore_rest_of_line (); 4881 1.1 christos } 4882 1.1 christos else 4883 1.1 christos { 4884 1.1 christos valueT value = get_absolute_expression (); 4885 1.1 christos int regno = reg.X_add_number; 4886 1.1 christos if (regno <= REG_GR || regno > REG_GR + 127) 4887 1.1 christos as_warn (_("Register value annotation ignored")); 4888 1.1 christos else 4889 1.1 christos { 4890 1.1 christos gr_values[regno - REG_GR].known = 1; 4891 1.1 christos gr_values[regno - REG_GR].value = value; 4892 1.1 christos gr_values[regno - REG_GR].path = md.path; 4893 1.1 christos } 4894 1.1 christos } 4895 1.1 christos demand_empty_rest_of_line (); 4896 1.1 christos } 4897 1.1 christos 4898 1.1 christos /* 4899 1.1 christos .serialize.data 4900 1.1 christos .serialize.instruction 4901 1.1 christos */ 4902 1.1 christos static void 4903 1.1 christos dot_serialize (int type) 4904 1.1 christos { 4905 1.1 christos insn_group_break (0, 0, 0); 4906 1.1 christos if (type) 4907 1.1 christos instruction_serialization (); 4908 1.1 christos else 4909 1.1 christos data_serialization (); 4910 1.1 christos insn_group_break (0, 0, 0); 4911 1.1 christos demand_empty_rest_of_line (); 4912 1.1 christos } 4913 1.1 christos 4914 1.1 christos /* select dv checking mode 4915 1.1 christos .auto 4916 1.1 christos .explicit 4917 1.1 christos .default 4918 1.1 christos 4919 1.1 christos A stop is inserted when changing modes 4920 1.1 christos */ 4921 1.1 christos 4922 1.1 christos static void 4923 1.1 christos dot_dv_mode (int type) 4924 1.1 christos { 4925 1.1 christos if (md.manual_bundling) 4926 1.1 christos as_warn (_("Directive invalid within a bundle")); 4927 1.1 christos 4928 1.1 christos if (type == 'E' || type == 'A') 4929 1.1 christos md.mode_explicitly_set = 0; 4930 1.1 christos else 4931 1.1 christos md.mode_explicitly_set = 1; 4932 1.1 christos 4933 1.1 christos md.detect_dv = 1; 4934 1.1 christos switch (type) 4935 1.1 christos { 4936 1.1 christos case 'A': 4937 1.1 christos case 'a': 4938 1.1 christos if (md.explicit_mode) 4939 1.1 christos insn_group_break (1, 0, 0); 4940 1.1 christos md.explicit_mode = 0; 4941 1.1 christos break; 4942 1.1 christos case 'E': 4943 1.1 christos case 'e': 4944 1.1 christos if (!md.explicit_mode) 4945 1.1 christos insn_group_break (1, 0, 0); 4946 1.1 christos md.explicit_mode = 1; 4947 1.1 christos break; 4948 1.1 christos default: 4949 1.1 christos case 'd': 4950 1.1 christos if (md.explicit_mode != md.default_explicit_mode) 4951 1.1 christos insn_group_break (1, 0, 0); 4952 1.1 christos md.explicit_mode = md.default_explicit_mode; 4953 1.1 christos md.mode_explicitly_set = 0; 4954 1.1 christos break; 4955 1.1 christos } 4956 1.1 christos } 4957 1.1 christos 4958 1.1 christos static void 4959 1.1 christos print_prmask (valueT mask) 4960 1.1 christos { 4961 1.1 christos int regno; 4962 1.5 christos const char *comma = ""; 4963 1.1 christos for (regno = 0; regno < 64; regno++) 4964 1.1 christos { 4965 1.1 christos if (mask & ((valueT) 1 << regno)) 4966 1.1 christos { 4967 1.1 christos fprintf (stderr, "%s p%d", comma, regno); 4968 1.1 christos comma = ","; 4969 1.1 christos } 4970 1.1 christos } 4971 1.1 christos } 4972 1.1 christos 4973 1.1 christos /* 4974 1.1 christos .pred.rel.clear [p1 [,p2 [,...]]] (also .pred.rel "clear" or @clear) 4975 1.1 christos .pred.rel.imply p1, p2 (also .pred.rel "imply" or @imply) 4976 1.1 christos .pred.rel.mutex p1, p2 [,...] (also .pred.rel "mutex" or @mutex) 4977 1.1 christos .pred.safe_across_calls p1 [, p2 [,...]] 4978 1.1 christos */ 4979 1.1 christos 4980 1.1 christos static void 4981 1.1 christos dot_pred_rel (int type) 4982 1.1 christos { 4983 1.1 christos valueT mask = 0; 4984 1.1 christos int count = 0; 4985 1.1 christos int p1 = -1, p2 = -1; 4986 1.1 christos 4987 1.1 christos if (type == 0) 4988 1.1 christos { 4989 1.1 christos if (*input_line_pointer == '"') 4990 1.1 christos { 4991 1.1 christos int len; 4992 1.1 christos char *form = demand_copy_C_string (&len); 4993 1.1 christos 4994 1.1 christos if (strcmp (form, "mutex") == 0) 4995 1.1 christos type = 'm'; 4996 1.1 christos else if (strcmp (form, "clear") == 0) 4997 1.1 christos type = 'c'; 4998 1.1 christos else if (strcmp (form, "imply") == 0) 4999 1.1 christos type = 'i'; 5000 1.9 christos notes_free (form); 5001 1.1 christos } 5002 1.1 christos else if (*input_line_pointer == '@') 5003 1.1 christos { 5004 1.3 christos char *form; 5005 1.3 christos char c; 5006 1.3 christos 5007 1.3 christos ++input_line_pointer; 5008 1.3 christos c = get_symbol_name (&form); 5009 1.1 christos 5010 1.1 christos if (strcmp (form, "mutex") == 0) 5011 1.1 christos type = 'm'; 5012 1.1 christos else if (strcmp (form, "clear") == 0) 5013 1.1 christos type = 'c'; 5014 1.1 christos else if (strcmp (form, "imply") == 0) 5015 1.1 christos type = 'i'; 5016 1.3 christos (void) restore_line_pointer (c); 5017 1.1 christos } 5018 1.1 christos else 5019 1.1 christos { 5020 1.1 christos as_bad (_("Missing predicate relation type")); 5021 1.1 christos ignore_rest_of_line (); 5022 1.1 christos return; 5023 1.1 christos } 5024 1.1 christos if (type == 0) 5025 1.1 christos { 5026 1.1 christos as_bad (_("Unrecognized predicate relation type")); 5027 1.1 christos ignore_rest_of_line (); 5028 1.1 christos return; 5029 1.1 christos } 5030 1.1 christos if (*input_line_pointer == ',') 5031 1.1 christos ++input_line_pointer; 5032 1.1 christos SKIP_WHITESPACE (); 5033 1.1 christos } 5034 1.1 christos 5035 1.1 christos while (1) 5036 1.1 christos { 5037 1.1 christos valueT bits = 1; 5038 1.1 christos int sep, regno; 5039 1.1 christos expressionS pr, *pr1, *pr2; 5040 1.1 christos 5041 1.1 christos sep = parse_operand_and_eval (&pr, ','); 5042 1.1 christos if (pr.X_op == O_register 5043 1.1 christos && pr.X_add_number >= REG_P 5044 1.1 christos && pr.X_add_number <= REG_P + 63) 5045 1.1 christos { 5046 1.1 christos regno = pr.X_add_number - REG_P; 5047 1.1 christos bits <<= regno; 5048 1.1 christos count++; 5049 1.1 christos if (p1 == -1) 5050 1.1 christos p1 = regno; 5051 1.1 christos else if (p2 == -1) 5052 1.1 christos p2 = regno; 5053 1.1 christos } 5054 1.1 christos else if (type != 'i' 5055 1.1 christos && pr.X_op == O_subtract 5056 1.1 christos && (pr1 = symbol_get_value_expression (pr.X_add_symbol)) 5057 1.1 christos && pr1->X_op == O_register 5058 1.1 christos && pr1->X_add_number >= REG_P 5059 1.1 christos && pr1->X_add_number <= REG_P + 63 5060 1.1 christos && (pr2 = symbol_get_value_expression (pr.X_op_symbol)) 5061 1.1 christos && pr2->X_op == O_register 5062 1.1 christos && pr2->X_add_number >= REG_P 5063 1.1 christos && pr2->X_add_number <= REG_P + 63) 5064 1.1 christos { 5065 1.1 christos /* It's a range. */ 5066 1.1 christos int stop; 5067 1.1 christos 5068 1.1 christos regno = pr1->X_add_number - REG_P; 5069 1.1 christos stop = pr2->X_add_number - REG_P; 5070 1.1 christos if (regno >= stop) 5071 1.1 christos { 5072 1.1 christos as_bad (_("Bad register range")); 5073 1.1 christos ignore_rest_of_line (); 5074 1.1 christos return; 5075 1.1 christos } 5076 1.1 christos bits = ((bits << stop) << 1) - (bits << regno); 5077 1.1 christos count += stop - regno + 1; 5078 1.1 christos } 5079 1.1 christos else 5080 1.1 christos { 5081 1.1 christos as_bad (_("Predicate register expected")); 5082 1.1 christos ignore_rest_of_line (); 5083 1.1 christos return; 5084 1.1 christos } 5085 1.1 christos if (mask & bits) 5086 1.1 christos as_warn (_("Duplicate predicate register ignored")); 5087 1.1 christos mask |= bits; 5088 1.1 christos if (sep != ',') 5089 1.1 christos break; 5090 1.1 christos } 5091 1.1 christos 5092 1.1 christos switch (type) 5093 1.1 christos { 5094 1.1 christos case 'c': 5095 1.1 christos if (count == 0) 5096 1.1 christos mask = ~(valueT) 0; 5097 1.1 christos clear_qp_mutex (mask); 5098 1.10 christos clear_qp_implies (mask, 0); 5099 1.1 christos break; 5100 1.1 christos case 'i': 5101 1.1 christos if (count != 2 || p1 == -1 || p2 == -1) 5102 1.1 christos as_bad (_("Predicate source and target required")); 5103 1.1 christos else if (p1 == 0 || p2 == 0) 5104 1.1 christos as_bad (_("Use of p0 is not valid in this context")); 5105 1.1 christos else 5106 1.1 christos add_qp_imply (p1, p2); 5107 1.1 christos break; 5108 1.1 christos case 'm': 5109 1.1 christos if (count < 2) 5110 1.1 christos { 5111 1.1 christos as_bad (_("At least two PR arguments expected")); 5112 1.1 christos break; 5113 1.1 christos } 5114 1.1 christos else if (mask & 1) 5115 1.1 christos { 5116 1.1 christos as_bad (_("Use of p0 is not valid in this context")); 5117 1.1 christos break; 5118 1.1 christos } 5119 1.1 christos add_qp_mutex (mask); 5120 1.1 christos break; 5121 1.1 christos case 's': 5122 1.1 christos /* note that we don't override any existing relations */ 5123 1.1 christos if (count == 0) 5124 1.1 christos { 5125 1.1 christos as_bad (_("At least one PR argument expected")); 5126 1.1 christos break; 5127 1.1 christos } 5128 1.1 christos if (md.debug_dv) 5129 1.1 christos { 5130 1.1 christos fprintf (stderr, "Safe across calls: "); 5131 1.1 christos print_prmask (mask); 5132 1.1 christos fprintf (stderr, "\n"); 5133 1.1 christos } 5134 1.1 christos qp_safe_across_calls = mask; 5135 1.1 christos break; 5136 1.1 christos } 5137 1.1 christos demand_empty_rest_of_line (); 5138 1.1 christos } 5139 1.1 christos 5140 1.1 christos /* .entry label [, label [, ...]] 5141 1.1 christos Hint to DV code that the given labels are to be considered entry points. 5142 1.1 christos Otherwise, only global labels are considered entry points. */ 5143 1.1 christos 5144 1.1 christos static void 5145 1.1 christos dot_entry (int dummy ATTRIBUTE_UNUSED) 5146 1.1 christos { 5147 1.1 christos char *name; 5148 1.1 christos int c; 5149 1.1 christos symbolS *symbolP; 5150 1.1 christos 5151 1.1 christos do 5152 1.1 christos { 5153 1.3 christos c = get_symbol_name (&name); 5154 1.1 christos symbolP = symbol_find_or_make (name); 5155 1.1 christos 5156 1.8 christos if (str_hash_insert (md.entry_hash, S_GET_NAME (symbolP), symbolP, 0)) 5157 1.8 christos as_bad (_("duplicate entry hint %s"), name); 5158 1.1 christos 5159 1.10 christos restore_line_pointer (c); 5160 1.10 christos SKIP_WHITESPACE (); 5161 1.1 christos c = *input_line_pointer; 5162 1.1 christos if (c == ',') 5163 1.1 christos { 5164 1.1 christos input_line_pointer++; 5165 1.1 christos SKIP_WHITESPACE (); 5166 1.1 christos if (*input_line_pointer == '\n') 5167 1.1 christos c = '\n'; 5168 1.1 christos } 5169 1.1 christos } 5170 1.1 christos while (c == ','); 5171 1.1 christos 5172 1.1 christos demand_empty_rest_of_line (); 5173 1.1 christos } 5174 1.1 christos 5175 1.1 christos /* .mem.offset offset, base 5176 1.1 christos "base" is used to distinguish between offsets from a different base. */ 5177 1.1 christos 5178 1.1 christos static void 5179 1.1 christos dot_mem_offset (int dummy ATTRIBUTE_UNUSED) 5180 1.1 christos { 5181 1.1 christos md.mem_offset.hint = 1; 5182 1.1 christos md.mem_offset.offset = get_absolute_expression (); 5183 1.1 christos if (*input_line_pointer != ',') 5184 1.1 christos { 5185 1.1 christos as_bad (_("Comma expected")); 5186 1.1 christos ignore_rest_of_line (); 5187 1.1 christos return; 5188 1.1 christos } 5189 1.1 christos ++input_line_pointer; 5190 1.1 christos md.mem_offset.base = get_absolute_expression (); 5191 1.1 christos demand_empty_rest_of_line (); 5192 1.1 christos } 5193 1.1 christos 5194 1.1 christos /* ia64-specific pseudo-ops: */ 5195 1.1 christos const pseudo_typeS md_pseudo_table[] = 5196 1.1 christos { 5197 1.1 christos { "radix", dot_radix, 0 }, 5198 1.1 christos { "lcomm", s_lcomm_bytes, 1 }, 5199 1.1 christos { "loc", dot_loc, 0 }, 5200 1.1 christos { "sbss", dot_special_section, SPECIAL_SECTION_SBSS }, 5201 1.1 christos { "sdata", dot_special_section, SPECIAL_SECTION_SDATA }, 5202 1.1 christos { "rodata", dot_special_section, SPECIAL_SECTION_RODATA }, 5203 1.1 christos { "comment", dot_special_section, SPECIAL_SECTION_COMMENT }, 5204 1.1 christos { "ia_64.unwind", dot_special_section, SPECIAL_SECTION_UNWIND }, 5205 1.1 christos { "ia_64.unwind_info", dot_special_section, SPECIAL_SECTION_UNWIND_INFO }, 5206 1.1 christos { "init_array", dot_special_section, SPECIAL_SECTION_INIT_ARRAY }, 5207 1.1 christos { "fini_array", dot_special_section, SPECIAL_SECTION_FINI_ARRAY }, 5208 1.1 christos { "proc", dot_proc, 0 }, 5209 1.1 christos { "body", dot_body, 0 }, 5210 1.1 christos { "prologue", dot_prologue, 0 }, 5211 1.1 christos { "endp", dot_endp, 0 }, 5212 1.1 christos 5213 1.1 christos { "fframe", dot_fframe, 0 }, 5214 1.1 christos { "vframe", dot_vframe, 0 }, 5215 1.1 christos { "vframesp", dot_vframesp, 0 }, 5216 1.1 christos { "vframepsp", dot_vframesp, 1 }, 5217 1.1 christos { "save", dot_save, 0 }, 5218 1.1 christos { "restore", dot_restore, 0 }, 5219 1.1 christos { "restorereg", dot_restorereg, 0 }, 5220 1.1 christos { "restorereg.p", dot_restorereg, 1 }, 5221 1.1 christos { "handlerdata", dot_handlerdata, 0 }, 5222 1.1 christos { "unwentry", dot_unwentry, 0 }, 5223 1.1 christos { "altrp", dot_altrp, 0 }, 5224 1.1 christos { "savesp", dot_savemem, 0 }, 5225 1.1 christos { "savepsp", dot_savemem, 1 }, 5226 1.1 christos { "save.g", dot_saveg, 0 }, 5227 1.1 christos { "save.f", dot_savef, 0 }, 5228 1.1 christos { "save.b", dot_saveb, 0 }, 5229 1.1 christos { "save.gf", dot_savegf, 0 }, 5230 1.1 christos { "spill", dot_spill, 0 }, 5231 1.1 christos { "spillreg", dot_spillreg, 0 }, 5232 1.1 christos { "spillsp", dot_spillmem, 0 }, 5233 1.1 christos { "spillpsp", dot_spillmem, 1 }, 5234 1.1 christos { "spillreg.p", dot_spillreg, 1 }, 5235 1.1 christos { "spillsp.p", dot_spillmem, ~0 }, 5236 1.1 christos { "spillpsp.p", dot_spillmem, ~1 }, 5237 1.1 christos { "label_state", dot_label_state, 0 }, 5238 1.1 christos { "copy_state", dot_copy_state, 0 }, 5239 1.1 christos { "unwabi", dot_unwabi, 0 }, 5240 1.1 christos { "personality", dot_personality, 0 }, 5241 1.1 christos { "mii", dot_template, 0x0 }, 5242 1.1 christos { "mli", dot_template, 0x2 }, /* old format, for compatibility */ 5243 1.1 christos { "mlx", dot_template, 0x2 }, 5244 1.1 christos { "mmi", dot_template, 0x4 }, 5245 1.1 christos { "mfi", dot_template, 0x6 }, 5246 1.1 christos { "mmf", dot_template, 0x7 }, 5247 1.1 christos { "mib", dot_template, 0x8 }, 5248 1.1 christos { "mbb", dot_template, 0x9 }, 5249 1.1 christos { "bbb", dot_template, 0xb }, 5250 1.1 christos { "mmb", dot_template, 0xc }, 5251 1.1 christos { "mfb", dot_template, 0xe }, 5252 1.1 christos { "align", dot_align, 0 }, 5253 1.1 christos { "regstk", dot_regstk, 0 }, 5254 1.1 christos { "rotr", dot_rot, DYNREG_GR }, 5255 1.1 christos { "rotf", dot_rot, DYNREG_FR }, 5256 1.1 christos { "rotp", dot_rot, DYNREG_PR }, 5257 1.1 christos { "lsb", dot_byteorder, 0 }, 5258 1.1 christos { "msb", dot_byteorder, 1 }, 5259 1.1 christos { "psr", dot_psr, 0 }, 5260 1.1 christos { "alias", dot_alias, 0 }, 5261 1.1 christos { "secalias", dot_alias, 1 }, 5262 1.1 christos { "ln", dot_ln, 0 }, /* source line info (for debugging) */ 5263 1.1 christos 5264 1.1 christos { "xdata1", dot_xdata, 1 }, 5265 1.1 christos { "xdata2", dot_xdata, 2 }, 5266 1.1 christos { "xdata4", dot_xdata, 4 }, 5267 1.1 christos { "xdata8", dot_xdata, 8 }, 5268 1.1 christos { "xdata16", dot_xdata, 16 }, 5269 1.1 christos { "xreal4", dot_xfloat_cons, 'f' }, 5270 1.1 christos { "xreal8", dot_xfloat_cons, 'd' }, 5271 1.1 christos { "xreal10", dot_xfloat_cons, 'x' }, 5272 1.1 christos { "xreal16", dot_xfloat_cons, 'X' }, 5273 1.1 christos { "xstring", dot_xstringer, 8 + 0 }, 5274 1.1 christos { "xstringz", dot_xstringer, 8 + 1 }, 5275 1.1 christos 5276 1.1 christos /* unaligned versions: */ 5277 1.1 christos { "xdata2.ua", dot_xdata_ua, 2 }, 5278 1.1 christos { "xdata4.ua", dot_xdata_ua, 4 }, 5279 1.1 christos { "xdata8.ua", dot_xdata_ua, 8 }, 5280 1.1 christos { "xdata16.ua", dot_xdata_ua, 16 }, 5281 1.1 christos { "xreal4.ua", dot_xfloat_cons_ua, 'f' }, 5282 1.1 christos { "xreal8.ua", dot_xfloat_cons_ua, 'd' }, 5283 1.1 christos { "xreal10.ua", dot_xfloat_cons_ua, 'x' }, 5284 1.1 christos { "xreal16.ua", dot_xfloat_cons_ua, 'X' }, 5285 1.1 christos 5286 1.1 christos /* annotations/DV checking support */ 5287 1.1 christos { "entry", dot_entry, 0 }, 5288 1.1 christos { "mem.offset", dot_mem_offset, 0 }, 5289 1.1 christos { "pred.rel", dot_pred_rel, 0 }, 5290 1.1 christos { "pred.rel.clear", dot_pred_rel, 'c' }, 5291 1.1 christos { "pred.rel.imply", dot_pred_rel, 'i' }, 5292 1.1 christos { "pred.rel.mutex", dot_pred_rel, 'm' }, 5293 1.1 christos { "pred.safe_across_calls", dot_pred_rel, 's' }, 5294 1.1 christos { "reg.val", dot_reg_val, 0 }, 5295 1.1 christos { "serialize.data", dot_serialize, 0 }, 5296 1.1 christos { "serialize.instruction", dot_serialize, 1 }, 5297 1.1 christos { "auto", dot_dv_mode, 'a' }, 5298 1.1 christos { "explicit", dot_dv_mode, 'e' }, 5299 1.1 christos { "default", dot_dv_mode, 'd' }, 5300 1.1 christos 5301 1.1 christos /* ??? These are needed to make gas/testsuite/gas/elf/ehopt.s work. 5302 1.1 christos IA-64 aligns data allocation pseudo-ops by default, so we have to 5303 1.1 christos tell it that these ones are supposed to be unaligned. Long term, 5304 1.1 christos should rewrite so that only IA-64 specific data allocation pseudo-ops 5305 1.1 christos are aligned by default. */ 5306 1.1 christos {"2byte", stmt_cons_ua, 2}, 5307 1.1 christos {"4byte", stmt_cons_ua, 4}, 5308 1.1 christos {"8byte", stmt_cons_ua, 8}, 5309 1.1 christos 5310 1.1 christos #ifdef TE_VMS 5311 1.1 christos {"vms_common", obj_elf_vms_common, 0}, 5312 1.1 christos #endif 5313 1.1 christos 5314 1.1 christos { NULL, 0, 0 } 5315 1.1 christos }; 5316 1.1 christos 5317 1.1 christos static const struct pseudo_opcode 5318 1.1 christos { 5319 1.1 christos const char *name; 5320 1.1 christos void (*handler) (int); 5321 1.1 christos int arg; 5322 1.1 christos } 5323 1.1 christos pseudo_opcode[] = 5324 1.1 christos { 5325 1.1 christos /* these are more like pseudo-ops, but don't start with a dot */ 5326 1.1 christos { "data1", cons, 1 }, 5327 1.1 christos { "data2", cons, 2 }, 5328 1.1 christos { "data4", cons, 4 }, 5329 1.1 christos { "data8", cons, 8 }, 5330 1.1 christos { "data16", cons, 16 }, 5331 1.1 christos { "real4", stmt_float_cons, 'f' }, 5332 1.1 christos { "real8", stmt_float_cons, 'd' }, 5333 1.1 christos { "real10", stmt_float_cons, 'x' }, 5334 1.1 christos { "real16", stmt_float_cons, 'X' }, 5335 1.1 christos { "string", stringer, 8 + 0 }, 5336 1.1 christos { "stringz", stringer, 8 + 1 }, 5337 1.1 christos 5338 1.1 christos /* unaligned versions: */ 5339 1.1 christos { "data2.ua", stmt_cons_ua, 2 }, 5340 1.1 christos { "data4.ua", stmt_cons_ua, 4 }, 5341 1.1 christos { "data8.ua", stmt_cons_ua, 8 }, 5342 1.1 christos { "data16.ua", stmt_cons_ua, 16 }, 5343 1.1 christos { "real4.ua", float_cons, 'f' }, 5344 1.1 christos { "real8.ua", float_cons, 'd' }, 5345 1.1 christos { "real10.ua", float_cons, 'x' }, 5346 1.1 christos { "real16.ua", float_cons, 'X' }, 5347 1.1 christos }; 5348 1.1 christos 5349 1.1 christos /* Declare a register by creating a symbol for it and entering it in 5350 1.1 christos the symbol table. */ 5351 1.1 christos 5352 1.1 christos static symbolS * 5353 1.1 christos declare_register (const char *name, unsigned int regnum) 5354 1.1 christos { 5355 1.1 christos symbolS *sym; 5356 1.1 christos 5357 1.8 christos sym = symbol_create (name, reg_section, &zero_address_frag, regnum); 5358 1.1 christos 5359 1.8 christos if (str_hash_insert (md.reg_hash, S_GET_NAME (sym), sym, 0) != NULL) 5360 1.8 christos as_fatal (_("duplicate %s"), name); 5361 1.1 christos 5362 1.1 christos return sym; 5363 1.1 christos } 5364 1.1 christos 5365 1.1 christos static void 5366 1.1 christos declare_register_set (const char *prefix, 5367 1.1 christos unsigned int num_regs, 5368 1.1 christos unsigned int base_regnum) 5369 1.1 christos { 5370 1.1 christos char name[8]; 5371 1.1 christos unsigned int i; 5372 1.1 christos 5373 1.1 christos for (i = 0; i < num_regs; ++i) 5374 1.1 christos { 5375 1.1 christos snprintf (name, sizeof (name), "%s%u", prefix, i); 5376 1.1 christos declare_register (name, base_regnum + i); 5377 1.1 christos } 5378 1.1 christos } 5379 1.1 christos 5380 1.1 christos static unsigned int 5381 1.1 christos operand_width (enum ia64_opnd opnd) 5382 1.1 christos { 5383 1.1 christos const struct ia64_operand *odesc = &elf64_ia64_operands[opnd]; 5384 1.1 christos unsigned int bits = 0; 5385 1.1 christos int i; 5386 1.1 christos 5387 1.1 christos bits = 0; 5388 1.1 christos for (i = 0; i < NELEMS (odesc->field) && odesc->field[i].bits; ++i) 5389 1.1 christos bits += odesc->field[i].bits; 5390 1.1 christos 5391 1.1 christos return bits; 5392 1.1 christos } 5393 1.1 christos 5394 1.1 christos static enum operand_match_result 5395 1.1 christos operand_match (const struct ia64_opcode *idesc, int res_index, expressionS *e) 5396 1.1 christos { 5397 1.1 christos enum ia64_opnd opnd = idesc->operands[res_index]; 5398 1.1 christos int bits, relocatable = 0; 5399 1.1 christos struct insn_fix *fix; 5400 1.1 christos bfd_signed_vma val; 5401 1.1 christos 5402 1.1 christos switch (opnd) 5403 1.1 christos { 5404 1.1 christos /* constants: */ 5405 1.1 christos 5406 1.1 christos case IA64_OPND_AR_CCV: 5407 1.1 christos if (e->X_op == O_register && e->X_add_number == REG_AR + 32) 5408 1.1 christos return OPERAND_MATCH; 5409 1.1 christos break; 5410 1.1 christos 5411 1.1 christos case IA64_OPND_AR_CSD: 5412 1.1 christos if (e->X_op == O_register && e->X_add_number == REG_AR + 25) 5413 1.1 christos return OPERAND_MATCH; 5414 1.1 christos break; 5415 1.1 christos 5416 1.1 christos case IA64_OPND_AR_PFS: 5417 1.1 christos if (e->X_op == O_register && e->X_add_number == REG_AR + 64) 5418 1.1 christos return OPERAND_MATCH; 5419 1.1 christos break; 5420 1.1 christos 5421 1.1 christos case IA64_OPND_GR0: 5422 1.1 christos if (e->X_op == O_register && e->X_add_number == REG_GR + 0) 5423 1.1 christos return OPERAND_MATCH; 5424 1.1 christos break; 5425 1.1 christos 5426 1.1 christos case IA64_OPND_IP: 5427 1.1 christos if (e->X_op == O_register && e->X_add_number == REG_IP) 5428 1.1 christos return OPERAND_MATCH; 5429 1.1 christos break; 5430 1.1 christos 5431 1.1 christos case IA64_OPND_PR: 5432 1.1 christos if (e->X_op == O_register && e->X_add_number == REG_PR) 5433 1.1 christos return OPERAND_MATCH; 5434 1.1 christos break; 5435 1.1 christos 5436 1.1 christos case IA64_OPND_PR_ROT: 5437 1.1 christos if (e->X_op == O_register && e->X_add_number == REG_PR_ROT) 5438 1.1 christos return OPERAND_MATCH; 5439 1.1 christos break; 5440 1.1 christos 5441 1.1 christos case IA64_OPND_PSR: 5442 1.1 christos if (e->X_op == O_register && e->X_add_number == REG_PSR) 5443 1.1 christos return OPERAND_MATCH; 5444 1.1 christos break; 5445 1.1 christos 5446 1.1 christos case IA64_OPND_PSR_L: 5447 1.1 christos if (e->X_op == O_register && e->X_add_number == REG_PSR_L) 5448 1.1 christos return OPERAND_MATCH; 5449 1.1 christos break; 5450 1.1 christos 5451 1.1 christos case IA64_OPND_PSR_UM: 5452 1.1 christos if (e->X_op == O_register && e->X_add_number == REG_PSR_UM) 5453 1.1 christos return OPERAND_MATCH; 5454 1.1 christos break; 5455 1.1 christos 5456 1.1 christos case IA64_OPND_C1: 5457 1.1 christos if (e->X_op == O_constant) 5458 1.1 christos { 5459 1.1 christos if (e->X_add_number == 1) 5460 1.1 christos return OPERAND_MATCH; 5461 1.1 christos else 5462 1.1 christos return OPERAND_OUT_OF_RANGE; 5463 1.1 christos } 5464 1.1 christos break; 5465 1.1 christos 5466 1.1 christos case IA64_OPND_C8: 5467 1.1 christos if (e->X_op == O_constant) 5468 1.1 christos { 5469 1.1 christos if (e->X_add_number == 8) 5470 1.1 christos return OPERAND_MATCH; 5471 1.1 christos else 5472 1.1 christos return OPERAND_OUT_OF_RANGE; 5473 1.1 christos } 5474 1.1 christos break; 5475 1.1 christos 5476 1.1 christos case IA64_OPND_C16: 5477 1.1 christos if (e->X_op == O_constant) 5478 1.1 christos { 5479 1.1 christos if (e->X_add_number == 16) 5480 1.1 christos return OPERAND_MATCH; 5481 1.1 christos else 5482 1.1 christos return OPERAND_OUT_OF_RANGE; 5483 1.1 christos } 5484 1.1 christos break; 5485 1.1 christos 5486 1.1 christos /* register operands: */ 5487 1.1 christos 5488 1.1 christos case IA64_OPND_AR3: 5489 1.1 christos if (e->X_op == O_register && e->X_add_number >= REG_AR 5490 1.1 christos && e->X_add_number < REG_AR + 128) 5491 1.1 christos return OPERAND_MATCH; 5492 1.1 christos break; 5493 1.1 christos 5494 1.1 christos case IA64_OPND_B1: 5495 1.1 christos case IA64_OPND_B2: 5496 1.1 christos if (e->X_op == O_register && e->X_add_number >= REG_BR 5497 1.1 christos && e->X_add_number < REG_BR + 8) 5498 1.1 christos return OPERAND_MATCH; 5499 1.1 christos break; 5500 1.1 christos 5501 1.1 christos case IA64_OPND_CR3: 5502 1.1 christos if (e->X_op == O_register && e->X_add_number >= REG_CR 5503 1.1 christos && e->X_add_number < REG_CR + 128) 5504 1.1 christos return OPERAND_MATCH; 5505 1.1 christos break; 5506 1.1 christos 5507 1.1 christos case IA64_OPND_DAHR3: 5508 1.1 christos if (e->X_op == O_register && e->X_add_number >= REG_DAHR 5509 1.1 christos && e->X_add_number < REG_DAHR + 8) 5510 1.1 christos return OPERAND_MATCH; 5511 1.1 christos break; 5512 1.1 christos 5513 1.1 christos case IA64_OPND_F1: 5514 1.1 christos case IA64_OPND_F2: 5515 1.1 christos case IA64_OPND_F3: 5516 1.1 christos case IA64_OPND_F4: 5517 1.1 christos if (e->X_op == O_register && e->X_add_number >= REG_FR 5518 1.1 christos && e->X_add_number < REG_FR + 128) 5519 1.1 christos return OPERAND_MATCH; 5520 1.1 christos break; 5521 1.1 christos 5522 1.1 christos case IA64_OPND_P1: 5523 1.1 christos case IA64_OPND_P2: 5524 1.1 christos if (e->X_op == O_register && e->X_add_number >= REG_P 5525 1.1 christos && e->X_add_number < REG_P + 64) 5526 1.1 christos return OPERAND_MATCH; 5527 1.1 christos break; 5528 1.1 christos 5529 1.1 christos case IA64_OPND_R1: 5530 1.1 christos case IA64_OPND_R2: 5531 1.1 christos case IA64_OPND_R3: 5532 1.1 christos if (e->X_op == O_register && e->X_add_number >= REG_GR 5533 1.1 christos && e->X_add_number < REG_GR + 128) 5534 1.1 christos return OPERAND_MATCH; 5535 1.1 christos break; 5536 1.1 christos 5537 1.1 christos case IA64_OPND_R3_2: 5538 1.1 christos if (e->X_op == O_register && e->X_add_number >= REG_GR) 5539 1.1 christos { 5540 1.1 christos if (e->X_add_number < REG_GR + 4) 5541 1.1 christos return OPERAND_MATCH; 5542 1.1 christos else if (e->X_add_number < REG_GR + 128) 5543 1.1 christos return OPERAND_OUT_OF_RANGE; 5544 1.1 christos } 5545 1.1 christos break; 5546 1.1 christos 5547 1.1 christos /* indirect operands: */ 5548 1.1 christos case IA64_OPND_CPUID_R3: 5549 1.1 christos case IA64_OPND_DBR_R3: 5550 1.1 christos case IA64_OPND_DTR_R3: 5551 1.1 christos case IA64_OPND_ITR_R3: 5552 1.1 christos case IA64_OPND_IBR_R3: 5553 1.1 christos case IA64_OPND_MSR_R3: 5554 1.1 christos case IA64_OPND_PKR_R3: 5555 1.1 christos case IA64_OPND_PMC_R3: 5556 1.1 christos case IA64_OPND_PMD_R3: 5557 1.1 christos case IA64_OPND_DAHR_R3: 5558 1.1 christos case IA64_OPND_RR_R3: 5559 1.1 christos if (e->X_op == O_index && e->X_op_symbol 5560 1.1 christos && (S_GET_VALUE (e->X_op_symbol) - IND_CPUID 5561 1.1 christos == opnd - IA64_OPND_CPUID_R3)) 5562 1.1 christos return OPERAND_MATCH; 5563 1.1 christos break; 5564 1.1 christos 5565 1.1 christos case IA64_OPND_MR3: 5566 1.1 christos if (e->X_op == O_index && !e->X_op_symbol) 5567 1.1 christos return OPERAND_MATCH; 5568 1.1 christos break; 5569 1.1 christos 5570 1.1 christos /* immediate operands: */ 5571 1.1 christos case IA64_OPND_CNT2a: 5572 1.1 christos case IA64_OPND_LEN4: 5573 1.1 christos case IA64_OPND_LEN6: 5574 1.1 christos bits = operand_width (idesc->operands[res_index]); 5575 1.1 christos if (e->X_op == O_constant) 5576 1.1 christos { 5577 1.1 christos if ((bfd_vma) (e->X_add_number - 1) < ((bfd_vma) 1 << bits)) 5578 1.1 christos return OPERAND_MATCH; 5579 1.1 christos else 5580 1.1 christos return OPERAND_OUT_OF_RANGE; 5581 1.1 christos } 5582 1.1 christos break; 5583 1.1 christos 5584 1.1 christos case IA64_OPND_CNT2b: 5585 1.1 christos if (e->X_op == O_constant) 5586 1.1 christos { 5587 1.1 christos if ((bfd_vma) (e->X_add_number - 1) < 3) 5588 1.1 christos return OPERAND_MATCH; 5589 1.1 christos else 5590 1.1 christos return OPERAND_OUT_OF_RANGE; 5591 1.1 christos } 5592 1.1 christos break; 5593 1.1 christos 5594 1.1 christos case IA64_OPND_CNT2c: 5595 1.1 christos val = e->X_add_number; 5596 1.1 christos if (e->X_op == O_constant) 5597 1.1 christos { 5598 1.1 christos if ((val == 0 || val == 7 || val == 15 || val == 16)) 5599 1.1 christos return OPERAND_MATCH; 5600 1.1 christos else 5601 1.1 christos return OPERAND_OUT_OF_RANGE; 5602 1.1 christos } 5603 1.1 christos break; 5604 1.1 christos 5605 1.1 christos case IA64_OPND_SOR: 5606 1.1 christos /* SOR must be an integer multiple of 8 */ 5607 1.1 christos if (e->X_op == O_constant && e->X_add_number & 0x7) 5608 1.1 christos return OPERAND_OUT_OF_RANGE; 5609 1.6 christos /* Fall through. */ 5610 1.1 christos case IA64_OPND_SOF: 5611 1.1 christos case IA64_OPND_SOL: 5612 1.1 christos if (e->X_op == O_constant) 5613 1.1 christos { 5614 1.1 christos if ((bfd_vma) e->X_add_number <= 96) 5615 1.1 christos return OPERAND_MATCH; 5616 1.1 christos else 5617 1.1 christos return OPERAND_OUT_OF_RANGE; 5618 1.1 christos } 5619 1.1 christos break; 5620 1.1 christos 5621 1.1 christos case IA64_OPND_IMMU62: 5622 1.1 christos if (e->X_op == O_constant) 5623 1.1 christos { 5624 1.1 christos if ((bfd_vma) e->X_add_number < ((bfd_vma) 1 << 62)) 5625 1.1 christos return OPERAND_MATCH; 5626 1.1 christos else 5627 1.1 christos return OPERAND_OUT_OF_RANGE; 5628 1.1 christos } 5629 1.1 christos else 5630 1.1 christos { 5631 1.1 christos /* FIXME -- need 62-bit relocation type */ 5632 1.1 christos as_bad (_("62-bit relocation not yet implemented")); 5633 1.1 christos } 5634 1.1 christos break; 5635 1.1 christos 5636 1.1 christos case IA64_OPND_IMMU64: 5637 1.1 christos if (e->X_op == O_symbol || e->X_op == O_pseudo_fixup 5638 1.1 christos || e->X_op == O_subtract) 5639 1.1 christos { 5640 1.1 christos fix = CURR_SLOT.fixup + CURR_SLOT.num_fixups; 5641 1.1 christos fix->code = BFD_RELOC_IA64_IMM64; 5642 1.1 christos if (e->X_op != O_subtract) 5643 1.1 christos { 5644 1.1 christos fix->code = ia64_gen_real_reloc_type (e->X_op_symbol, fix->code); 5645 1.1 christos if (e->X_op == O_pseudo_fixup) 5646 1.1 christos e->X_op = O_symbol; 5647 1.1 christos } 5648 1.1 christos 5649 1.1 christos fix->opnd = idesc->operands[res_index]; 5650 1.1 christos fix->expr = *e; 5651 1.1 christos fix->is_pcrel = 0; 5652 1.1 christos ++CURR_SLOT.num_fixups; 5653 1.1 christos return OPERAND_MATCH; 5654 1.1 christos } 5655 1.1 christos else if (e->X_op == O_constant) 5656 1.1 christos return OPERAND_MATCH; 5657 1.1 christos break; 5658 1.1 christos 5659 1.1 christos case IA64_OPND_IMMU5b: 5660 1.1 christos if (e->X_op == O_constant) 5661 1.1 christos { 5662 1.1 christos val = e->X_add_number; 5663 1.1 christos if (val >= 32 && val <= 63) 5664 1.1 christos return OPERAND_MATCH; 5665 1.1 christos else 5666 1.1 christos return OPERAND_OUT_OF_RANGE; 5667 1.1 christos } 5668 1.1 christos break; 5669 1.1 christos 5670 1.1 christos case IA64_OPND_CCNT5: 5671 1.1 christos case IA64_OPND_CNT5: 5672 1.1 christos case IA64_OPND_CNT6: 5673 1.1 christos case IA64_OPND_CPOS6a: 5674 1.1 christos case IA64_OPND_CPOS6b: 5675 1.1 christos case IA64_OPND_CPOS6c: 5676 1.1 christos case IA64_OPND_IMMU2: 5677 1.1 christos case IA64_OPND_IMMU7a: 5678 1.1 christos case IA64_OPND_IMMU7b: 5679 1.1 christos case IA64_OPND_IMMU16: 5680 1.1 christos case IA64_OPND_IMMU19: 5681 1.1 christos case IA64_OPND_IMMU21: 5682 1.1 christos case IA64_OPND_IMMU24: 5683 1.1 christos case IA64_OPND_MBTYPE4: 5684 1.1 christos case IA64_OPND_MHTYPE8: 5685 1.1 christos case IA64_OPND_POS6: 5686 1.1 christos bits = operand_width (idesc->operands[res_index]); 5687 1.1 christos if (e->X_op == O_constant) 5688 1.1 christos { 5689 1.1 christos if ((bfd_vma) e->X_add_number < ((bfd_vma) 1 << bits)) 5690 1.1 christos return OPERAND_MATCH; 5691 1.1 christos else 5692 1.1 christos return OPERAND_OUT_OF_RANGE; 5693 1.1 christos } 5694 1.1 christos break; 5695 1.1 christos 5696 1.1 christos case IA64_OPND_IMMU9: 5697 1.1 christos bits = operand_width (idesc->operands[res_index]); 5698 1.1 christos if (e->X_op == O_constant) 5699 1.1 christos { 5700 1.1 christos if ((bfd_vma) e->X_add_number < ((bfd_vma) 1 << bits)) 5701 1.1 christos { 5702 1.1 christos int lobits = e->X_add_number & 0x3; 5703 1.1 christos if (((bfd_vma) e->X_add_number & 0x3C) != 0 && lobits == 0) 5704 1.1 christos e->X_add_number |= (bfd_vma) 0x3; 5705 1.1 christos return OPERAND_MATCH; 5706 1.1 christos } 5707 1.1 christos else 5708 1.1 christos return OPERAND_OUT_OF_RANGE; 5709 1.1 christos } 5710 1.1 christos break; 5711 1.1 christos 5712 1.1 christos case IA64_OPND_IMM44: 5713 1.1 christos /* least 16 bits must be zero */ 5714 1.1 christos if ((e->X_add_number & 0xffff) != 0) 5715 1.1 christos /* XXX technically, this is wrong: we should not be issuing warning 5716 1.1 christos messages until we're sure this instruction pattern is going to 5717 1.1 christos be used! */ 5718 1.1 christos as_warn (_("lower 16 bits of mask ignored")); 5719 1.1 christos 5720 1.1 christos if (e->X_op == O_constant) 5721 1.1 christos { 5722 1.1 christos if (((e->X_add_number >= 0 5723 1.1 christos && (bfd_vma) e->X_add_number < ((bfd_vma) 1 << 44)) 5724 1.1 christos || (e->X_add_number < 0 5725 1.1 christos && (bfd_vma) -e->X_add_number <= ((bfd_vma) 1 << 44)))) 5726 1.1 christos { 5727 1.1 christos /* sign-extend */ 5728 1.1 christos if (e->X_add_number >= 0 5729 1.1 christos && (e->X_add_number & ((bfd_vma) 1 << 43)) != 0) 5730 1.1 christos { 5731 1.1 christos e->X_add_number |= ~(((bfd_vma) 1 << 44) - 1); 5732 1.1 christos } 5733 1.1 christos return OPERAND_MATCH; 5734 1.1 christos } 5735 1.1 christos else 5736 1.1 christos return OPERAND_OUT_OF_RANGE; 5737 1.1 christos } 5738 1.1 christos break; 5739 1.1 christos 5740 1.1 christos case IA64_OPND_IMM17: 5741 1.1 christos /* bit 0 is a don't care (pr0 is hardwired to 1) */ 5742 1.1 christos if (e->X_op == O_constant) 5743 1.1 christos { 5744 1.1 christos if (((e->X_add_number >= 0 5745 1.1 christos && (bfd_vma) e->X_add_number < ((bfd_vma) 1 << 17)) 5746 1.1 christos || (e->X_add_number < 0 5747 1.1 christos && (bfd_vma) -e->X_add_number <= ((bfd_vma) 1 << 17)))) 5748 1.1 christos { 5749 1.1 christos /* sign-extend */ 5750 1.1 christos if (e->X_add_number >= 0 5751 1.1 christos && (e->X_add_number & ((bfd_vma) 1 << 16)) != 0) 5752 1.1 christos { 5753 1.1 christos e->X_add_number |= ~(((bfd_vma) 1 << 17) - 1); 5754 1.1 christos } 5755 1.1 christos return OPERAND_MATCH; 5756 1.1 christos } 5757 1.1 christos else 5758 1.1 christos return OPERAND_OUT_OF_RANGE; 5759 1.1 christos } 5760 1.1 christos break; 5761 1.1 christos 5762 1.1 christos case IA64_OPND_IMM14: 5763 1.1 christos case IA64_OPND_IMM22: 5764 1.1 christos relocatable = 1; 5765 1.6 christos /* Fall through. */ 5766 1.1 christos case IA64_OPND_IMM1: 5767 1.1 christos case IA64_OPND_IMM8: 5768 1.1 christos case IA64_OPND_IMM8U4: 5769 1.1 christos case IA64_OPND_IMM8M1: 5770 1.1 christos case IA64_OPND_IMM8M1U4: 5771 1.1 christos case IA64_OPND_IMM8M1U8: 5772 1.1 christos case IA64_OPND_IMM9a: 5773 1.1 christos case IA64_OPND_IMM9b: 5774 1.1 christos bits = operand_width (idesc->operands[res_index]); 5775 1.1 christos if (relocatable && (e->X_op == O_symbol 5776 1.1 christos || e->X_op == O_subtract 5777 1.1 christos || e->X_op == O_pseudo_fixup)) 5778 1.1 christos { 5779 1.1 christos fix = CURR_SLOT.fixup + CURR_SLOT.num_fixups; 5780 1.1 christos 5781 1.1 christos if (idesc->operands[res_index] == IA64_OPND_IMM14) 5782 1.1 christos fix->code = BFD_RELOC_IA64_IMM14; 5783 1.1 christos else 5784 1.1 christos fix->code = BFD_RELOC_IA64_IMM22; 5785 1.1 christos 5786 1.1 christos if (e->X_op != O_subtract) 5787 1.1 christos { 5788 1.1 christos fix->code = ia64_gen_real_reloc_type (e->X_op_symbol, fix->code); 5789 1.1 christos if (e->X_op == O_pseudo_fixup) 5790 1.1 christos e->X_op = O_symbol; 5791 1.1 christos } 5792 1.1 christos 5793 1.1 christos fix->opnd = idesc->operands[res_index]; 5794 1.1 christos fix->expr = *e; 5795 1.1 christos fix->is_pcrel = 0; 5796 1.1 christos ++CURR_SLOT.num_fixups; 5797 1.1 christos return OPERAND_MATCH; 5798 1.1 christos } 5799 1.1 christos else if (e->X_op != O_constant 5800 1.1 christos && ! (e->X_op == O_big && opnd == IA64_OPND_IMM8M1U8)) 5801 1.1 christos return OPERAND_MISMATCH; 5802 1.1 christos 5803 1.1 christos if (opnd == IA64_OPND_IMM8M1U4) 5804 1.1 christos { 5805 1.1 christos /* Zero is not valid for unsigned compares that take an adjusted 5806 1.1 christos constant immediate range. */ 5807 1.1 christos if (e->X_add_number == 0) 5808 1.1 christos return OPERAND_OUT_OF_RANGE; 5809 1.1 christos 5810 1.1 christos /* Sign-extend 32-bit unsigned numbers, so that the following range 5811 1.1 christos checks will work. */ 5812 1.1 christos val = e->X_add_number; 5813 1.7 christos if ((val & (~(bfd_vma) 0 << 32)) == 0) 5814 1.7 christos val = (val ^ ((bfd_vma) 1 << 31)) - ((bfd_vma) 1 << 31); 5815 1.1 christos 5816 1.1 christos /* Check for 0x100000000. This is valid because 5817 1.1 christos 0x100000000-1 is the same as ((uint32_t) -1). */ 5818 1.1 christos if (val == ((bfd_signed_vma) 1 << 32)) 5819 1.1 christos return OPERAND_MATCH; 5820 1.1 christos 5821 1.1 christos val = val - 1; 5822 1.1 christos } 5823 1.1 christos else if (opnd == IA64_OPND_IMM8M1U8) 5824 1.1 christos { 5825 1.1 christos /* Zero is not valid for unsigned compares that take an adjusted 5826 1.1 christos constant immediate range. */ 5827 1.1 christos if (e->X_add_number == 0) 5828 1.1 christos return OPERAND_OUT_OF_RANGE; 5829 1.1 christos 5830 1.1 christos /* Check for 0x10000000000000000. */ 5831 1.1 christos if (e->X_op == O_big) 5832 1.1 christos { 5833 1.1 christos if (generic_bignum[0] == 0 5834 1.1 christos && generic_bignum[1] == 0 5835 1.1 christos && generic_bignum[2] == 0 5836 1.1 christos && generic_bignum[3] == 0 5837 1.1 christos && generic_bignum[4] == 1) 5838 1.1 christos return OPERAND_MATCH; 5839 1.1 christos else 5840 1.1 christos return OPERAND_OUT_OF_RANGE; 5841 1.1 christos } 5842 1.1 christos else 5843 1.1 christos val = e->X_add_number - 1; 5844 1.1 christos } 5845 1.1 christos else if (opnd == IA64_OPND_IMM8M1) 5846 1.1 christos val = e->X_add_number - 1; 5847 1.1 christos else if (opnd == IA64_OPND_IMM8U4) 5848 1.1 christos { 5849 1.1 christos /* Sign-extend 32-bit unsigned numbers, so that the following range 5850 1.1 christos checks will work. */ 5851 1.1 christos val = e->X_add_number; 5852 1.7 christos if ((val & (~(bfd_vma) 0 << 32)) == 0) 5853 1.7 christos val = (val ^ ((bfd_vma) 1 << 31)) - ((bfd_vma) 1 << 31); 5854 1.1 christos } 5855 1.1 christos else 5856 1.1 christos val = e->X_add_number; 5857 1.1 christos 5858 1.1 christos if ((val >= 0 && (bfd_vma) val < ((bfd_vma) 1 << (bits - 1))) 5859 1.1 christos || (val < 0 && (bfd_vma) -val <= ((bfd_vma) 1 << (bits - 1)))) 5860 1.1 christos return OPERAND_MATCH; 5861 1.1 christos else 5862 1.1 christos return OPERAND_OUT_OF_RANGE; 5863 1.1 christos 5864 1.1 christos case IA64_OPND_INC3: 5865 1.1 christos /* +/- 1, 4, 8, 16 */ 5866 1.1 christos val = e->X_add_number; 5867 1.1 christos if (val < 0) 5868 1.1 christos val = -val; 5869 1.1 christos if (e->X_op == O_constant) 5870 1.1 christos { 5871 1.1 christos if ((val == 1 || val == 4 || val == 8 || val == 16)) 5872 1.1 christos return OPERAND_MATCH; 5873 1.1 christos else 5874 1.1 christos return OPERAND_OUT_OF_RANGE; 5875 1.1 christos } 5876 1.1 christos break; 5877 1.1 christos 5878 1.1 christos case IA64_OPND_TGT25: 5879 1.1 christos case IA64_OPND_TGT25b: 5880 1.1 christos case IA64_OPND_TGT25c: 5881 1.1 christos case IA64_OPND_TGT64: 5882 1.1 christos if (e->X_op == O_symbol) 5883 1.1 christos { 5884 1.1 christos fix = CURR_SLOT.fixup + CURR_SLOT.num_fixups; 5885 1.1 christos if (opnd == IA64_OPND_TGT25) 5886 1.1 christos fix->code = BFD_RELOC_IA64_PCREL21F; 5887 1.1 christos else if (opnd == IA64_OPND_TGT25b) 5888 1.1 christos fix->code = BFD_RELOC_IA64_PCREL21M; 5889 1.1 christos else if (opnd == IA64_OPND_TGT25c) 5890 1.1 christos fix->code = BFD_RELOC_IA64_PCREL21B; 5891 1.1 christos else if (opnd == IA64_OPND_TGT64) 5892 1.1 christos fix->code = BFD_RELOC_IA64_PCREL60B; 5893 1.1 christos else 5894 1.1 christos abort (); 5895 1.1 christos 5896 1.1 christos fix->code = ia64_gen_real_reloc_type (e->X_op_symbol, fix->code); 5897 1.1 christos fix->opnd = idesc->operands[res_index]; 5898 1.1 christos fix->expr = *e; 5899 1.1 christos fix->is_pcrel = 1; 5900 1.1 christos ++CURR_SLOT.num_fixups; 5901 1.1 christos return OPERAND_MATCH; 5902 1.1 christos } 5903 1.6 christos /* Fall through. */ 5904 1.1 christos case IA64_OPND_TAG13: 5905 1.1 christos case IA64_OPND_TAG13b: 5906 1.1 christos switch (e->X_op) 5907 1.1 christos { 5908 1.1 christos case O_constant: 5909 1.1 christos return OPERAND_MATCH; 5910 1.1 christos 5911 1.1 christos case O_symbol: 5912 1.1 christos fix = CURR_SLOT.fixup + CURR_SLOT.num_fixups; 5913 1.1 christos /* There are no external relocs for TAG13/TAG13b fields, so we 5914 1.1 christos create a dummy reloc. This will not live past md_apply_fix. */ 5915 1.1 christos fix->code = BFD_RELOC_UNUSED; 5916 1.1 christos fix->code = ia64_gen_real_reloc_type (e->X_op_symbol, fix->code); 5917 1.1 christos fix->opnd = idesc->operands[res_index]; 5918 1.1 christos fix->expr = *e; 5919 1.1 christos fix->is_pcrel = 1; 5920 1.1 christos ++CURR_SLOT.num_fixups; 5921 1.1 christos return OPERAND_MATCH; 5922 1.1 christos 5923 1.1 christos default: 5924 1.1 christos break; 5925 1.1 christos } 5926 1.1 christos break; 5927 1.1 christos 5928 1.1 christos case IA64_OPND_LDXMOV: 5929 1.1 christos fix = CURR_SLOT.fixup + CURR_SLOT.num_fixups; 5930 1.1 christos fix->code = BFD_RELOC_IA64_LDXMOV; 5931 1.1 christos fix->opnd = idesc->operands[res_index]; 5932 1.1 christos fix->expr = *e; 5933 1.1 christos fix->is_pcrel = 0; 5934 1.1 christos ++CURR_SLOT.num_fixups; 5935 1.1 christos return OPERAND_MATCH; 5936 1.1 christos 5937 1.1 christos case IA64_OPND_STRD5b: 5938 1.1 christos if (e->X_op == O_constant) 5939 1.1 christos { 5940 1.1 christos /* 5-bit signed scaled by 64 */ 5941 1.3 christos if ((e->X_add_number <= ( 0xf << 6 )) 5942 1.1 christos && (e->X_add_number >= -( 0x10 << 6 ))) 5943 1.1 christos { 5944 1.3 christos 5945 1.1 christos /* Must be a multiple of 64 */ 5946 1.1 christos if ((e->X_add_number & 0x3f) != 0) 5947 1.1 christos as_warn (_("stride must be a multiple of 64; lower 6 bits ignored")); 5948 1.1 christos 5949 1.1 christos e->X_add_number &= ~ 0x3f; 5950 1.1 christos return OPERAND_MATCH; 5951 1.1 christos } 5952 1.1 christos else 5953 1.1 christos return OPERAND_OUT_OF_RANGE; 5954 1.1 christos } 5955 1.1 christos break; 5956 1.1 christos case IA64_OPND_CNT6a: 5957 1.1 christos if (e->X_op == O_constant) 5958 1.1 christos { 5959 1.1 christos /* 6-bit unsigned biased by 1 -- count 0 is meaningless */ 5960 1.3 christos if ((e->X_add_number <= 64) 5961 1.1 christos && (e->X_add_number > 0) ) 5962 1.1 christos { 5963 1.1 christos return OPERAND_MATCH; 5964 1.1 christos } 5965 1.1 christos else 5966 1.1 christos return OPERAND_OUT_OF_RANGE; 5967 1.1 christos } 5968 1.1 christos break; 5969 1.1 christos 5970 1.1 christos default: 5971 1.1 christos break; 5972 1.1 christos } 5973 1.1 christos return OPERAND_MISMATCH; 5974 1.1 christos } 5975 1.1 christos 5976 1.1 christos static int 5977 1.1 christos parse_operand (expressionS *e, int more) 5978 1.1 christos { 5979 1.1 christos int sep = '\0'; 5980 1.1 christos 5981 1.1 christos memset (e, 0, sizeof (*e)); 5982 1.1 christos e->X_op = O_absent; 5983 1.1 christos SKIP_WHITESPACE (); 5984 1.1 christos expression (e); 5985 1.9 christos resolve_register (e); 5986 1.1 christos sep = *input_line_pointer; 5987 1.1 christos if (more && (sep == ',' || sep == more)) 5988 1.1 christos ++input_line_pointer; 5989 1.1 christos return sep; 5990 1.1 christos } 5991 1.1 christos 5992 1.1 christos static int 5993 1.1 christos parse_operand_and_eval (expressionS *e, int more) 5994 1.1 christos { 5995 1.1 christos int sep = parse_operand (e, more); 5996 1.1 christos resolve_expression (e); 5997 1.1 christos return sep; 5998 1.1 christos } 5999 1.1 christos 6000 1.1 christos static int 6001 1.1 christos parse_operand_maybe_eval (expressionS *e, int more, enum ia64_opnd op) 6002 1.1 christos { 6003 1.1 christos int sep = parse_operand (e, more); 6004 1.1 christos switch (op) 6005 1.1 christos { 6006 1.1 christos case IA64_OPND_IMM14: 6007 1.1 christos case IA64_OPND_IMM22: 6008 1.1 christos case IA64_OPND_IMMU64: 6009 1.1 christos case IA64_OPND_TGT25: 6010 1.1 christos case IA64_OPND_TGT25b: 6011 1.1 christos case IA64_OPND_TGT25c: 6012 1.1 christos case IA64_OPND_TGT64: 6013 1.1 christos case IA64_OPND_TAG13: 6014 1.1 christos case IA64_OPND_TAG13b: 6015 1.1 christos case IA64_OPND_LDXMOV: 6016 1.1 christos break; 6017 1.1 christos default: 6018 1.1 christos resolve_expression (e); 6019 1.1 christos break; 6020 1.1 christos } 6021 1.1 christos return sep; 6022 1.1 christos } 6023 1.1 christos 6024 1.1 christos /* Returns the next entry in the opcode table that matches the one in 6025 1.1 christos IDESC, and frees the entry in IDESC. If no matching entry is 6026 1.1 christos found, NULL is returned instead. */ 6027 1.1 christos 6028 1.1 christos static struct ia64_opcode * 6029 1.1 christos get_next_opcode (struct ia64_opcode *idesc) 6030 1.1 christos { 6031 1.1 christos struct ia64_opcode *next = ia64_find_next_opcode (idesc); 6032 1.1 christos ia64_free_opcode (idesc); 6033 1.1 christos return next; 6034 1.1 christos } 6035 1.1 christos 6036 1.1 christos /* Parse the operands for the opcode and find the opcode variant that 6037 1.1 christos matches the specified operands, or NULL if no match is possible. */ 6038 1.1 christos 6039 1.1 christos static struct ia64_opcode * 6040 1.1 christos parse_operands (struct ia64_opcode *idesc) 6041 1.1 christos { 6042 1.1 christos int i = 0, highest_unmatched_operand, num_operands = 0, num_outputs = 0; 6043 1.1 christos int error_pos, out_of_range_pos, curr_out_of_range_pos, sep = 0; 6044 1.1 christos int reg1, reg2; 6045 1.1 christos char reg_class; 6046 1.1 christos enum ia64_opnd expected_operand = IA64_OPND_NIL; 6047 1.1 christos enum operand_match_result result; 6048 1.1 christos char mnemonic[129]; 6049 1.1 christos char *first_arg = 0, *end, *saved_input_pointer; 6050 1.1 christos unsigned int sof; 6051 1.1 christos 6052 1.1 christos gas_assert (strlen (idesc->name) <= 128); 6053 1.1 christos 6054 1.1 christos strcpy (mnemonic, idesc->name); 6055 1.1 christos if (idesc->operands[2] == IA64_OPND_SOF 6056 1.1 christos || idesc->operands[1] == IA64_OPND_SOF) 6057 1.1 christos { 6058 1.1 christos /* To make the common idiom "alloc loc?=ar.pfs,0,1,0,0" work, we 6059 1.1 christos can't parse the first operand until we have parsed the 6060 1.1 christos remaining operands of the "alloc" instruction. */ 6061 1.1 christos SKIP_WHITESPACE (); 6062 1.1 christos first_arg = input_line_pointer; 6063 1.1 christos end = strchr (input_line_pointer, '='); 6064 1.1 christos if (!end) 6065 1.1 christos { 6066 1.1 christos as_bad (_("Expected separator `='")); 6067 1.1 christos return 0; 6068 1.1 christos } 6069 1.1 christos input_line_pointer = end + 1; 6070 1.1 christos ++i; 6071 1.1 christos ++num_outputs; 6072 1.1 christos } 6073 1.1 christos 6074 1.1 christos for (; ; ++i) 6075 1.1 christos { 6076 1.3 christos if (i < NELEMS (CURR_SLOT.opnd)) 6077 1.1 christos { 6078 1.8 christos enum ia64_opnd op = IA64_OPND_NIL; 6079 1.8 christos if (i < NELEMS (idesc->operands)) 6080 1.8 christos op = idesc->operands[i]; 6081 1.8 christos sep = parse_operand_maybe_eval (CURR_SLOT.opnd + i, '=', op); 6082 1.1 christos if (CURR_SLOT.opnd[i].X_op == O_absent) 6083 1.1 christos break; 6084 1.1 christos } 6085 1.1 christos else 6086 1.1 christos { 6087 1.1 christos expressionS dummy; 6088 1.1 christos 6089 1.1 christos sep = parse_operand (&dummy, '='); 6090 1.1 christos if (dummy.X_op == O_absent) 6091 1.1 christos break; 6092 1.1 christos } 6093 1.1 christos 6094 1.1 christos ++num_operands; 6095 1.1 christos 6096 1.1 christos if (sep != '=' && sep != ',') 6097 1.1 christos break; 6098 1.1 christos 6099 1.1 christos if (sep == '=') 6100 1.1 christos { 6101 1.1 christos if (num_outputs > 0) 6102 1.1 christos as_bad (_("Duplicate equal sign (=) in instruction")); 6103 1.1 christos else 6104 1.1 christos num_outputs = i + 1; 6105 1.1 christos } 6106 1.1 christos } 6107 1.1 christos if (sep != '\0') 6108 1.1 christos { 6109 1.1 christos as_bad (_("Illegal operand separator `%c'"), sep); 6110 1.1 christos return 0; 6111 1.1 christos } 6112 1.1 christos 6113 1.1 christos if (idesc->operands[2] == IA64_OPND_SOF 6114 1.1 christos || idesc->operands[1] == IA64_OPND_SOF) 6115 1.1 christos { 6116 1.1 christos /* Map alloc r1=ar.pfs,i,l,o,r to alloc r1=ar.pfs,(i+l+o),(i+l),r. 6117 1.1 christos Note, however, that due to that mapping operand numbers in error 6118 1.1 christos messages for any of the constant operands will not be correct. */ 6119 1.1 christos know (strcmp (idesc->name, "alloc") == 0); 6120 1.1 christos /* The first operand hasn't been parsed/initialized, yet (but 6121 1.1 christos num_operands intentionally doesn't account for that). */ 6122 1.1 christos i = num_operands > 4 ? 2 : 1; 6123 1.1 christos #define FORCE_CONST(n) (CURR_SLOT.opnd[n].X_op == O_constant \ 6124 1.1 christos ? CURR_SLOT.opnd[n].X_add_number \ 6125 1.1 christos : 0) 6126 1.1 christos sof = set_regstack (FORCE_CONST(i), 6127 1.1 christos FORCE_CONST(i + 1), 6128 1.1 christos FORCE_CONST(i + 2), 6129 1.1 christos FORCE_CONST(i + 3)); 6130 1.1 christos #undef FORCE_CONST 6131 1.1 christos 6132 1.1 christos /* now we can parse the first arg: */ 6133 1.1 christos saved_input_pointer = input_line_pointer; 6134 1.1 christos input_line_pointer = first_arg; 6135 1.1 christos sep = parse_operand_maybe_eval (CURR_SLOT.opnd + 0, '=', 6136 1.1 christos idesc->operands[0]); 6137 1.1 christos if (sep != '=') 6138 1.1 christos --num_outputs; /* force error */ 6139 1.1 christos input_line_pointer = saved_input_pointer; 6140 1.1 christos 6141 1.1 christos CURR_SLOT.opnd[i].X_add_number = sof; 6142 1.1 christos if (CURR_SLOT.opnd[i + 1].X_op == O_constant 6143 1.1 christos && CURR_SLOT.opnd[i + 2].X_op == O_constant) 6144 1.1 christos CURR_SLOT.opnd[i + 1].X_add_number 6145 1.1 christos = sof - CURR_SLOT.opnd[i + 2].X_add_number; 6146 1.1 christos else 6147 1.1 christos CURR_SLOT.opnd[i + 1].X_op = O_illegal; 6148 1.1 christos CURR_SLOT.opnd[i + 2] = CURR_SLOT.opnd[i + 3]; 6149 1.1 christos } 6150 1.1 christos 6151 1.1 christos highest_unmatched_operand = -4; 6152 1.1 christos curr_out_of_range_pos = -1; 6153 1.1 christos error_pos = 0; 6154 1.1 christos for (; idesc; idesc = get_next_opcode (idesc)) 6155 1.1 christos { 6156 1.1 christos if (num_outputs != idesc->num_outputs) 6157 1.1 christos continue; /* mismatch in # of outputs */ 6158 1.1 christos if (highest_unmatched_operand < 0) 6159 1.1 christos highest_unmatched_operand |= 1; 6160 1.1 christos if (num_operands > NELEMS (idesc->operands) 6161 1.1 christos || (num_operands < NELEMS (idesc->operands) 6162 1.1 christos && idesc->operands[num_operands]) 6163 1.1 christos || (num_operands > 0 && !idesc->operands[num_operands - 1])) 6164 1.1 christos continue; /* mismatch in number of arguments */ 6165 1.1 christos if (highest_unmatched_operand < 0) 6166 1.1 christos highest_unmatched_operand |= 2; 6167 1.1 christos 6168 1.1 christos CURR_SLOT.num_fixups = 0; 6169 1.1 christos 6170 1.1 christos /* Try to match all operands. If we see an out-of-range operand, 6171 1.1 christos then continue trying to match the rest of the operands, since if 6172 1.1 christos the rest match, then this idesc will give the best error message. */ 6173 1.1 christos 6174 1.1 christos out_of_range_pos = -1; 6175 1.1 christos for (i = 0; i < num_operands && idesc->operands[i]; ++i) 6176 1.1 christos { 6177 1.1 christos result = operand_match (idesc, i, CURR_SLOT.opnd + i); 6178 1.1 christos if (result != OPERAND_MATCH) 6179 1.1 christos { 6180 1.1 christos if (result != OPERAND_OUT_OF_RANGE) 6181 1.1 christos break; 6182 1.1 christos if (out_of_range_pos < 0) 6183 1.1 christos /* remember position of the first out-of-range operand: */ 6184 1.1 christos out_of_range_pos = i; 6185 1.1 christos } 6186 1.1 christos } 6187 1.1 christos 6188 1.1 christos /* If we did not match all operands, or if at least one operand was 6189 1.1 christos out-of-range, then this idesc does not match. Keep track of which 6190 1.1 christos idesc matched the most operands before failing. If we have two 6191 1.1 christos idescs that failed at the same position, and one had an out-of-range 6192 1.1 christos operand, then prefer the out-of-range operand. Thus if we have 6193 1.1 christos "add r0=0x1000000,r1" we get an error saying the constant is out 6194 1.1 christos of range instead of an error saying that the constant should have been 6195 1.1 christos a register. */ 6196 1.1 christos 6197 1.1 christos if (i != num_operands || out_of_range_pos >= 0) 6198 1.1 christos { 6199 1.1 christos if (i > highest_unmatched_operand 6200 1.1 christos || (i == highest_unmatched_operand 6201 1.1 christos && out_of_range_pos > curr_out_of_range_pos)) 6202 1.1 christos { 6203 1.1 christos highest_unmatched_operand = i; 6204 1.1 christos if (out_of_range_pos >= 0) 6205 1.1 christos { 6206 1.1 christos expected_operand = idesc->operands[out_of_range_pos]; 6207 1.1 christos error_pos = out_of_range_pos; 6208 1.1 christos } 6209 1.1 christos else 6210 1.1 christos { 6211 1.1 christos expected_operand = idesc->operands[i]; 6212 1.1 christos error_pos = i; 6213 1.1 christos } 6214 1.1 christos curr_out_of_range_pos = out_of_range_pos; 6215 1.1 christos } 6216 1.1 christos continue; 6217 1.1 christos } 6218 1.1 christos 6219 1.1 christos break; 6220 1.1 christos } 6221 1.1 christos if (!idesc) 6222 1.1 christos { 6223 1.1 christos if (expected_operand) 6224 1.1 christos as_bad (_("Operand %u of `%s' should be %s"), 6225 1.1 christos error_pos + 1, mnemonic, 6226 1.1 christos elf64_ia64_operands[expected_operand].desc); 6227 1.1 christos else if (highest_unmatched_operand < 0 && !(highest_unmatched_operand & 1)) 6228 1.1 christos as_bad (_("Wrong number of output operands")); 6229 1.1 christos else if (highest_unmatched_operand < 0 && !(highest_unmatched_operand & 2)) 6230 1.1 christos as_bad (_("Wrong number of input operands")); 6231 1.1 christos else 6232 1.1 christos as_bad (_("Operand mismatch")); 6233 1.1 christos return 0; 6234 1.1 christos } 6235 1.1 christos 6236 1.1 christos /* Check that the instruction doesn't use 6237 1.1 christos - r0, f0, or f1 as output operands 6238 1.1 christos - the same predicate twice as output operands 6239 1.1 christos - r0 as address of a base update load or store 6240 1.1 christos - the same GR as output and address of a base update load 6241 1.1 christos - two even- or two odd-numbered FRs as output operands of a floating 6242 1.1 christos point parallel load. 6243 1.1 christos At most two (conflicting) output (or output-like) operands can exist, 6244 1.1 christos (floating point parallel loads have three outputs, but the base register, 6245 1.1 christos if updated, cannot conflict with the actual outputs). */ 6246 1.1 christos reg2 = reg1 = -1; 6247 1.1 christos for (i = 0; i < num_operands; ++i) 6248 1.1 christos { 6249 1.1 christos int regno = 0; 6250 1.1 christos 6251 1.1 christos reg_class = 0; 6252 1.1 christos switch (idesc->operands[i]) 6253 1.1 christos { 6254 1.1 christos case IA64_OPND_R1: 6255 1.1 christos case IA64_OPND_R2: 6256 1.1 christos case IA64_OPND_R3: 6257 1.1 christos if (i < num_outputs) 6258 1.1 christos { 6259 1.1 christos if (CURR_SLOT.opnd[i].X_add_number == REG_GR) 6260 1.1 christos reg_class = 'r'; 6261 1.1 christos else if (reg1 < 0) 6262 1.1 christos reg1 = CURR_SLOT.opnd[i].X_add_number; 6263 1.1 christos else if (reg2 < 0) 6264 1.1 christos reg2 = CURR_SLOT.opnd[i].X_add_number; 6265 1.1 christos } 6266 1.1 christos break; 6267 1.1 christos case IA64_OPND_P1: 6268 1.1 christos case IA64_OPND_P2: 6269 1.1 christos if (i < num_outputs) 6270 1.1 christos { 6271 1.1 christos if (reg1 < 0) 6272 1.1 christos reg1 = CURR_SLOT.opnd[i].X_add_number; 6273 1.1 christos else if (reg2 < 0) 6274 1.1 christos reg2 = CURR_SLOT.opnd[i].X_add_number; 6275 1.1 christos } 6276 1.1 christos break; 6277 1.1 christos case IA64_OPND_F1: 6278 1.1 christos case IA64_OPND_F2: 6279 1.1 christos case IA64_OPND_F3: 6280 1.1 christos case IA64_OPND_F4: 6281 1.1 christos if (i < num_outputs) 6282 1.1 christos { 6283 1.1 christos if (CURR_SLOT.opnd[i].X_add_number >= REG_FR 6284 1.1 christos && CURR_SLOT.opnd[i].X_add_number <= REG_FR + 1) 6285 1.1 christos { 6286 1.1 christos reg_class = 'f'; 6287 1.1 christos regno = CURR_SLOT.opnd[i].X_add_number - REG_FR; 6288 1.1 christos } 6289 1.1 christos else if (reg1 < 0) 6290 1.1 christos reg1 = CURR_SLOT.opnd[i].X_add_number; 6291 1.1 christos else if (reg2 < 0) 6292 1.1 christos reg2 = CURR_SLOT.opnd[i].X_add_number; 6293 1.1 christos } 6294 1.1 christos break; 6295 1.1 christos case IA64_OPND_MR3: 6296 1.1 christos if (idesc->flags & IA64_OPCODE_POSTINC) 6297 1.1 christos { 6298 1.1 christos if (CURR_SLOT.opnd[i].X_add_number == REG_GR) 6299 1.1 christos reg_class = 'm'; 6300 1.1 christos else if (reg1 < 0) 6301 1.1 christos reg1 = CURR_SLOT.opnd[i].X_add_number; 6302 1.1 christos else if (reg2 < 0) 6303 1.1 christos reg2 = CURR_SLOT.opnd[i].X_add_number; 6304 1.1 christos } 6305 1.1 christos break; 6306 1.1 christos default: 6307 1.1 christos break; 6308 1.1 christos } 6309 1.1 christos switch (reg_class) 6310 1.1 christos { 6311 1.1 christos case 0: 6312 1.1 christos break; 6313 1.1 christos default: 6314 1.1 christos as_warn (_("Invalid use of `%c%d' as output operand"), reg_class, regno); 6315 1.1 christos break; 6316 1.1 christos case 'm': 6317 1.1 christos as_warn (_("Invalid use of `r%d' as base update address operand"), regno); 6318 1.1 christos break; 6319 1.1 christos } 6320 1.1 christos } 6321 1.1 christos if (reg1 == reg2) 6322 1.1 christos { 6323 1.1 christos if (reg1 >= REG_GR && reg1 <= REG_GR + 127) 6324 1.1 christos { 6325 1.1 christos reg1 -= REG_GR; 6326 1.1 christos reg_class = 'r'; 6327 1.1 christos } 6328 1.1 christos else if (reg1 >= REG_P && reg1 <= REG_P + 63) 6329 1.1 christos { 6330 1.1 christos reg1 -= REG_P; 6331 1.1 christos reg_class = 'p'; 6332 1.1 christos } 6333 1.1 christos else if (reg1 >= REG_FR && reg1 <= REG_FR + 127) 6334 1.1 christos { 6335 1.1 christos reg1 -= REG_FR; 6336 1.1 christos reg_class = 'f'; 6337 1.1 christos } 6338 1.1 christos else 6339 1.1 christos reg_class = 0; 6340 1.1 christos if (reg_class) 6341 1.1 christos as_warn (_("Invalid duplicate use of `%c%d'"), reg_class, reg1); 6342 1.1 christos } 6343 1.1 christos else if (((reg1 >= REG_FR && reg1 <= REG_FR + 31 6344 1.1 christos && reg2 >= REG_FR && reg2 <= REG_FR + 31) 6345 1.1 christos || (reg1 >= REG_FR + 32 && reg1 <= REG_FR + 127 6346 1.1 christos && reg2 >= REG_FR + 32 && reg2 <= REG_FR + 127)) 6347 1.1 christos && ! ((reg1 ^ reg2) & 1)) 6348 1.1 christos as_warn (_("Invalid simultaneous use of `f%d' and `f%d'"), 6349 1.1 christos reg1 - REG_FR, reg2 - REG_FR); 6350 1.1 christos else if ((reg1 >= REG_FR && reg1 <= REG_FR + 31 6351 1.1 christos && reg2 >= REG_FR + 32 && reg2 <= REG_FR + 127) 6352 1.1 christos || (reg1 >= REG_FR + 32 && reg1 <= REG_FR + 127 6353 1.1 christos && reg2 >= REG_FR && reg2 <= REG_FR + 31)) 6354 1.1 christos as_warn (_("Dangerous simultaneous use of `f%d' and `f%d'"), 6355 1.1 christos reg1 - REG_FR, reg2 - REG_FR); 6356 1.1 christos return idesc; 6357 1.1 christos } 6358 1.1 christos 6359 1.1 christos static void 6360 1.1 christos build_insn (struct slot *slot, bfd_vma *insnp) 6361 1.1 christos { 6362 1.1 christos const struct ia64_operand *odesc, *o2desc; 6363 1.1 christos struct ia64_opcode *idesc = slot->idesc; 6364 1.1 christos bfd_vma insn; 6365 1.1 christos bfd_signed_vma val; 6366 1.1 christos const char *err; 6367 1.1 christos int i; 6368 1.1 christos 6369 1.1 christos insn = idesc->opcode | slot->qp_regno; 6370 1.1 christos 6371 1.1 christos for (i = 0; i < NELEMS (idesc->operands) && idesc->operands[i]; ++i) 6372 1.1 christos { 6373 1.1 christos if (slot->opnd[i].X_op == O_register 6374 1.1 christos || slot->opnd[i].X_op == O_constant 6375 1.1 christos || slot->opnd[i].X_op == O_index) 6376 1.1 christos val = slot->opnd[i].X_add_number; 6377 1.1 christos else if (slot->opnd[i].X_op == O_big) 6378 1.1 christos { 6379 1.1 christos /* This must be the value 0x10000000000000000. */ 6380 1.1 christos gas_assert (idesc->operands[i] == IA64_OPND_IMM8M1U8); 6381 1.1 christos val = 0; 6382 1.1 christos } 6383 1.1 christos else 6384 1.1 christos val = 0; 6385 1.1 christos 6386 1.1 christos switch (idesc->operands[i]) 6387 1.1 christos { 6388 1.1 christos case IA64_OPND_IMMU64: 6389 1.1 christos *insnp++ = (val >> 22) & 0x1ffffffffffLL; 6390 1.1 christos insn |= (((val & 0x7f) << 13) | (((val >> 7) & 0x1ff) << 27) 6391 1.1 christos | (((val >> 16) & 0x1f) << 22) | (((val >> 21) & 0x1) << 21) 6392 1.1 christos | (((val >> 63) & 0x1) << 36)); 6393 1.1 christos continue; 6394 1.1 christos 6395 1.1 christos case IA64_OPND_IMMU62: 6396 1.1 christos val &= 0x3fffffffffffffffULL; 6397 1.1 christos if (val != slot->opnd[i].X_add_number) 6398 1.1 christos as_warn (_("Value truncated to 62 bits")); 6399 1.1 christos *insnp++ = (val >> 21) & 0x1ffffffffffLL; 6400 1.1 christos insn |= (((val & 0xfffff) << 6) | (((val >> 20) & 0x1) << 36)); 6401 1.1 christos continue; 6402 1.1 christos 6403 1.1 christos case IA64_OPND_TGT64: 6404 1.1 christos val >>= 4; 6405 1.1 christos *insnp++ = ((val >> 20) & 0x7fffffffffLL) << 2; 6406 1.1 christos insn |= ((((val >> 59) & 0x1) << 36) 6407 1.1 christos | (((val >> 0) & 0xfffff) << 13)); 6408 1.1 christos continue; 6409 1.1 christos 6410 1.1 christos case IA64_OPND_AR3: 6411 1.1 christos val -= REG_AR; 6412 1.1 christos break; 6413 1.1 christos 6414 1.1 christos case IA64_OPND_B1: 6415 1.1 christos case IA64_OPND_B2: 6416 1.1 christos val -= REG_BR; 6417 1.1 christos break; 6418 1.1 christos 6419 1.1 christos case IA64_OPND_CR3: 6420 1.1 christos val -= REG_CR; 6421 1.1 christos break; 6422 1.1 christos 6423 1.1 christos case IA64_OPND_DAHR3: 6424 1.1 christos val -= REG_DAHR; 6425 1.1 christos break; 6426 1.1 christos 6427 1.1 christos case IA64_OPND_F1: 6428 1.1 christos case IA64_OPND_F2: 6429 1.1 christos case IA64_OPND_F3: 6430 1.1 christos case IA64_OPND_F4: 6431 1.1 christos val -= REG_FR; 6432 1.1 christos break; 6433 1.1 christos 6434 1.1 christos case IA64_OPND_P1: 6435 1.1 christos case IA64_OPND_P2: 6436 1.1 christos val -= REG_P; 6437 1.1 christos break; 6438 1.1 christos 6439 1.1 christos case IA64_OPND_R1: 6440 1.1 christos case IA64_OPND_R2: 6441 1.1 christos case IA64_OPND_R3: 6442 1.1 christos case IA64_OPND_R3_2: 6443 1.1 christos case IA64_OPND_CPUID_R3: 6444 1.1 christos case IA64_OPND_DBR_R3: 6445 1.1 christos case IA64_OPND_DTR_R3: 6446 1.1 christos case IA64_OPND_ITR_R3: 6447 1.1 christos case IA64_OPND_IBR_R3: 6448 1.1 christos case IA64_OPND_MR3: 6449 1.1 christos case IA64_OPND_MSR_R3: 6450 1.1 christos case IA64_OPND_PKR_R3: 6451 1.1 christos case IA64_OPND_PMC_R3: 6452 1.1 christos case IA64_OPND_PMD_R3: 6453 1.1 christos case IA64_OPND_DAHR_R3: 6454 1.1 christos case IA64_OPND_RR_R3: 6455 1.1 christos val -= REG_GR; 6456 1.1 christos break; 6457 1.1 christos 6458 1.1 christos default: 6459 1.1 christos break; 6460 1.1 christos } 6461 1.1 christos 6462 1.1 christos odesc = elf64_ia64_operands + idesc->operands[i]; 6463 1.1 christos err = (*odesc->insert) (odesc, val, &insn); 6464 1.1 christos if (err) 6465 1.1 christos as_bad_where (slot->src_file, slot->src_line, 6466 1.1 christos _("Bad operand value: %s"), err); 6467 1.1 christos if (idesc->flags & IA64_OPCODE_PSEUDO) 6468 1.1 christos { 6469 1.1 christos if ((idesc->flags & IA64_OPCODE_F2_EQ_F3) 6470 1.1 christos && odesc == elf64_ia64_operands + IA64_OPND_F3) 6471 1.1 christos { 6472 1.1 christos o2desc = elf64_ia64_operands + IA64_OPND_F2; 6473 1.1 christos (*o2desc->insert) (o2desc, val, &insn); 6474 1.1 christos } 6475 1.1 christos if ((idesc->flags & IA64_OPCODE_LEN_EQ_64MCNT) 6476 1.1 christos && (odesc == elf64_ia64_operands + IA64_OPND_CPOS6a 6477 1.1 christos || odesc == elf64_ia64_operands + IA64_OPND_POS6)) 6478 1.1 christos { 6479 1.1 christos o2desc = elf64_ia64_operands + IA64_OPND_LEN6; 6480 1.1 christos (*o2desc->insert) (o2desc, 64 - val, &insn); 6481 1.1 christos } 6482 1.1 christos } 6483 1.1 christos } 6484 1.1 christos *insnp = insn; 6485 1.1 christos } 6486 1.1 christos 6487 1.1 christos static void 6488 1.1 christos emit_one_bundle (void) 6489 1.1 christos { 6490 1.1 christos int manual_bundling_off = 0, manual_bundling = 0; 6491 1.1 christos enum ia64_unit required_unit, insn_unit = 0; 6492 1.1 christos enum ia64_insn_type type[3], insn_type; 6493 1.1 christos unsigned int template_val, orig_template; 6494 1.1 christos bfd_vma insn[3] = { -1, -1, -1 }; 6495 1.1 christos struct ia64_opcode *idesc; 6496 1.1 christos int end_of_insn_group = 0, user_template = -1; 6497 1.1 christos int n, i, j, first, curr, last_slot; 6498 1.1 christos bfd_vma t0 = 0, t1 = 0; 6499 1.1 christos struct label_fix *lfix; 6500 1.8 christos bool mark_label; 6501 1.1 christos struct insn_fix *ifix; 6502 1.1 christos char mnemonic[16]; 6503 1.1 christos fixS *fix; 6504 1.1 christos char *f; 6505 1.1 christos int addr_mod; 6506 1.1 christos 6507 1.1 christos first = (md.curr_slot + NUM_SLOTS - md.num_slots_in_use) % NUM_SLOTS; 6508 1.1 christos know (first >= 0 && first < NUM_SLOTS); 6509 1.1 christos n = MIN (3, md.num_slots_in_use); 6510 1.1 christos 6511 1.1 christos /* Determine template: user user_template if specified, best match 6512 1.1 christos otherwise: */ 6513 1.1 christos 6514 1.1 christos if (md.slot[first].user_template >= 0) 6515 1.1 christos user_template = template_val = md.slot[first].user_template; 6516 1.1 christos else 6517 1.1 christos { 6518 1.1 christos /* Auto select appropriate template. */ 6519 1.1 christos memset (type, 0, sizeof (type)); 6520 1.1 christos curr = first; 6521 1.1 christos for (i = 0; i < n; ++i) 6522 1.1 christos { 6523 1.1 christos if (md.slot[curr].label_fixups && i != 0) 6524 1.1 christos break; 6525 1.1 christos type[i] = md.slot[curr].idesc->type; 6526 1.1 christos curr = (curr + 1) % NUM_SLOTS; 6527 1.1 christos } 6528 1.1 christos template_val = best_template[type[0]][type[1]][type[2]]; 6529 1.1 christos } 6530 1.1 christos 6531 1.1 christos /* initialize instructions with appropriate nops: */ 6532 1.1 christos for (i = 0; i < 3; ++i) 6533 1.1 christos insn[i] = nop[ia64_templ_desc[template_val].exec_unit[i]]; 6534 1.1 christos 6535 1.1 christos f = frag_more (16); 6536 1.1 christos 6537 1.1 christos /* Check to see if this bundle is at an offset that is a multiple of 16-bytes 6538 1.1 christos from the start of the frag. */ 6539 1.1 christos addr_mod = frag_now_fix () & 15; 6540 1.1 christos if (frag_now->has_code && frag_now->insn_addr != addr_mod) 6541 1.1 christos as_bad (_("instruction address is not a multiple of 16")); 6542 1.1 christos frag_now->insn_addr = addr_mod; 6543 1.1 christos frag_now->has_code = 1; 6544 1.1 christos 6545 1.1 christos /* now fill in slots with as many insns as possible: */ 6546 1.1 christos curr = first; 6547 1.1 christos idesc = md.slot[curr].idesc; 6548 1.1 christos end_of_insn_group = 0; 6549 1.1 christos last_slot = -1; 6550 1.1 christos for (i = 0; i < 3 && md.num_slots_in_use > 0; ++i) 6551 1.1 christos { 6552 1.1 christos /* If we have unwind records, we may need to update some now. */ 6553 1.1 christos unw_rec_list *ptr = md.slot[curr].unwind_record; 6554 1.1 christos unw_rec_list *end_ptr = NULL; 6555 1.1 christos 6556 1.1 christos if (ptr) 6557 1.1 christos { 6558 1.1 christos /* Find the last prologue/body record in the list for the current 6559 1.1 christos insn, and set the slot number for all records up to that point. 6560 1.1 christos This needs to be done now, because prologue/body records refer to 6561 1.1 christos the current point, not the point after the instruction has been 6562 1.1 christos issued. This matters because there may have been nops emitted 6563 1.1 christos meanwhile. Any non-prologue non-body record followed by a 6564 1.1 christos prologue/body record must also refer to the current point. */ 6565 1.1 christos unw_rec_list *last_ptr; 6566 1.1 christos 6567 1.1 christos for (j = 1; end_ptr == NULL && j < md.num_slots_in_use; ++j) 6568 1.1 christos end_ptr = md.slot[(curr + j) % NUM_SLOTS].unwind_record; 6569 1.1 christos for (last_ptr = NULL; ptr != end_ptr; ptr = ptr->next) 6570 1.1 christos if (ptr->r.type == prologue || ptr->r.type == prologue_gr 6571 1.1 christos || ptr->r.type == body) 6572 1.1 christos last_ptr = ptr; 6573 1.1 christos if (last_ptr) 6574 1.1 christos { 6575 1.1 christos /* Make last_ptr point one after the last prologue/body 6576 1.1 christos record. */ 6577 1.1 christos last_ptr = last_ptr->next; 6578 1.1 christos for (ptr = md.slot[curr].unwind_record; ptr != last_ptr; 6579 1.1 christos ptr = ptr->next) 6580 1.1 christos { 6581 1.1 christos ptr->slot_number = (unsigned long) f + i; 6582 1.1 christos ptr->slot_frag = frag_now; 6583 1.1 christos } 6584 1.1 christos /* Remove the initialized records, so that we won't accidentally 6585 1.1 christos update them again if we insert a nop and continue. */ 6586 1.1 christos md.slot[curr].unwind_record = last_ptr; 6587 1.1 christos } 6588 1.1 christos } 6589 1.1 christos 6590 1.1 christos manual_bundling_off = md.slot[curr].manual_bundling_off; 6591 1.1 christos if (md.slot[curr].manual_bundling_on) 6592 1.1 christos { 6593 1.1 christos if (curr == first) 6594 1.1 christos manual_bundling = 1; 6595 1.1 christos else 6596 1.1 christos break; /* Need to start a new bundle. */ 6597 1.1 christos } 6598 1.1 christos 6599 1.1 christos /* If this instruction specifies a template, then it must be the first 6600 1.1 christos instruction of a bundle. */ 6601 1.1 christos if (curr != first && md.slot[curr].user_template >= 0) 6602 1.1 christos break; 6603 1.1 christos 6604 1.1 christos if (idesc->flags & IA64_OPCODE_SLOT2) 6605 1.1 christos { 6606 1.1 christos if (manual_bundling && !manual_bundling_off) 6607 1.1 christos { 6608 1.1 christos as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line, 6609 1.1 christos _("`%s' must be last in bundle"), idesc->name); 6610 1.1 christos if (i < 2) 6611 1.1 christos manual_bundling = -1; /* Suppress meaningless post-loop errors. */ 6612 1.1 christos } 6613 1.1 christos i = 2; 6614 1.1 christos } 6615 1.1 christos if (idesc->flags & IA64_OPCODE_LAST) 6616 1.1 christos { 6617 1.1 christos int required_slot; 6618 1.1 christos unsigned int required_template; 6619 1.1 christos 6620 1.1 christos /* If we need a stop bit after an M slot, our only choice is 6621 1.1 christos template 5 (M;;MI). If we need a stop bit after a B 6622 1.1 christos slot, our only choice is to place it at the end of the 6623 1.1 christos bundle, because the only available templates are MIB, 6624 1.1 christos MBB, BBB, MMB, and MFB. We don't handle anything other 6625 1.1 christos than M and B slots because these are the only kind of 6626 1.1 christos instructions that can have the IA64_OPCODE_LAST bit set. */ 6627 1.1 christos required_template = template_val; 6628 1.1 christos switch (idesc->type) 6629 1.1 christos { 6630 1.1 christos case IA64_TYPE_M: 6631 1.1 christos required_slot = 0; 6632 1.1 christos required_template = 5; 6633 1.1 christos break; 6634 1.1 christos 6635 1.1 christos case IA64_TYPE_B: 6636 1.1 christos required_slot = 2; 6637 1.1 christos break; 6638 1.1 christos 6639 1.1 christos default: 6640 1.1 christos as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line, 6641 1.1 christos _("Internal error: don't know how to force %s to end of instruction group"), 6642 1.1 christos idesc->name); 6643 1.1 christos required_slot = i; 6644 1.1 christos break; 6645 1.1 christos } 6646 1.1 christos if (manual_bundling 6647 1.1 christos && (i > required_slot 6648 1.1 christos || (required_slot == 2 && !manual_bundling_off) 6649 1.1 christos || (user_template >= 0 6650 1.1 christos /* Changing from MMI to M;MI is OK. */ 6651 1.1 christos && (template_val ^ required_template) > 1))) 6652 1.1 christos { 6653 1.1 christos as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line, 6654 1.1 christos _("`%s' must be last in instruction group"), 6655 1.1 christos idesc->name); 6656 1.1 christos if (i < 2 && required_slot == 2 && !manual_bundling_off) 6657 1.1 christos manual_bundling = -1; /* Suppress meaningless post-loop errors. */ 6658 1.1 christos } 6659 1.1 christos if (required_slot < i) 6660 1.1 christos /* Can't fit this instruction. */ 6661 1.1 christos break; 6662 1.1 christos 6663 1.1 christos i = required_slot; 6664 1.1 christos if (required_template != template_val) 6665 1.1 christos { 6666 1.1 christos /* If we switch the template, we need to reset the NOPs 6667 1.1 christos after slot i. The slot-types of the instructions ahead 6668 1.1 christos of i never change, so we don't need to worry about 6669 1.1 christos changing NOPs in front of this slot. */ 6670 1.1 christos for (j = i; j < 3; ++j) 6671 1.1 christos insn[j] = nop[ia64_templ_desc[required_template].exec_unit[j]]; 6672 1.1 christos 6673 1.1 christos /* We just picked a template that includes the stop bit in the 6674 1.1 christos middle, so we don't need another one emitted later. */ 6675 1.1 christos md.slot[curr].end_of_insn_group = 0; 6676 1.1 christos } 6677 1.1 christos template_val = required_template; 6678 1.1 christos } 6679 1.1 christos if (curr != first && md.slot[curr].label_fixups) 6680 1.1 christos { 6681 1.1 christos if (manual_bundling) 6682 1.1 christos { 6683 1.1 christos as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line, 6684 1.1 christos _("Label must be first in a bundle")); 6685 1.1 christos manual_bundling = -1; /* Suppress meaningless post-loop errors. */ 6686 1.1 christos } 6687 1.1 christos /* This insn must go into the first slot of a bundle. */ 6688 1.1 christos break; 6689 1.1 christos } 6690 1.1 christos 6691 1.1 christos if (end_of_insn_group && md.num_slots_in_use >= 1) 6692 1.1 christos { 6693 1.1 christos /* We need an instruction group boundary in the middle of a 6694 1.1 christos bundle. See if we can switch to an other template with 6695 1.1 christos an appropriate boundary. */ 6696 1.1 christos 6697 1.1 christos orig_template = template_val; 6698 1.1 christos if (i == 1 && (user_template == 4 6699 1.1 christos || (user_template < 0 6700 1.1 christos && (ia64_templ_desc[template_val].exec_unit[0] 6701 1.1 christos == IA64_UNIT_M)))) 6702 1.1 christos { 6703 1.1 christos template_val = 5; 6704 1.1 christos end_of_insn_group = 0; 6705 1.1 christos } 6706 1.1 christos else if (i == 2 && (user_template == 0 6707 1.1 christos || (user_template < 0 6708 1.1 christos && (ia64_templ_desc[template_val].exec_unit[1] 6709 1.1 christos == IA64_UNIT_I))) 6710 1.1 christos /* This test makes sure we don't switch the template if 6711 1.1 christos the next instruction is one that needs to be first in 6712 1.1 christos an instruction group. Since all those instructions are 6713 1.1 christos in the M group, there is no way such an instruction can 6714 1.1 christos fit in this bundle even if we switch the template. The 6715 1.1 christos reason we have to check for this is that otherwise we 6716 1.1 christos may end up generating "MI;;I M.." which has the deadly 6717 1.1 christos effect that the second M instruction is no longer the 6718 1.1 christos first in the group! --davidm 99/12/16 */ 6719 1.1 christos && (idesc->flags & IA64_OPCODE_FIRST) == 0) 6720 1.1 christos { 6721 1.1 christos template_val = 1; 6722 1.1 christos end_of_insn_group = 0; 6723 1.1 christos } 6724 1.1 christos else if (i == 1 6725 1.1 christos && user_template == 0 6726 1.1 christos && !(idesc->flags & IA64_OPCODE_FIRST)) 6727 1.1 christos /* Use the next slot. */ 6728 1.1 christos continue; 6729 1.1 christos else if (curr != first) 6730 1.1 christos /* can't fit this insn */ 6731 1.1 christos break; 6732 1.1 christos 6733 1.1 christos if (template_val != orig_template) 6734 1.1 christos /* if we switch the template, we need to reset the NOPs 6735 1.1 christos after slot i. The slot-types of the instructions ahead 6736 1.1 christos of i never change, so we don't need to worry about 6737 1.1 christos changing NOPs in front of this slot. */ 6738 1.1 christos for (j = i; j < 3; ++j) 6739 1.1 christos insn[j] = nop[ia64_templ_desc[template_val].exec_unit[j]]; 6740 1.1 christos } 6741 1.1 christos required_unit = ia64_templ_desc[template_val].exec_unit[i]; 6742 1.1 christos 6743 1.1 christos /* resolve dynamic opcodes such as "break", "hint", and "nop": */ 6744 1.1 christos if (idesc->type == IA64_TYPE_DYN) 6745 1.1 christos { 6746 1.1 christos enum ia64_opnd opnd1, opnd2; 6747 1.1 christos 6748 1.1 christos if ((strcmp (idesc->name, "nop") == 0) 6749 1.1 christos || (strcmp (idesc->name, "break") == 0)) 6750 1.1 christos insn_unit = required_unit; 6751 1.1 christos else if (strcmp (idesc->name, "hint") == 0) 6752 1.1 christos { 6753 1.1 christos insn_unit = required_unit; 6754 1.1 christos if (required_unit == IA64_UNIT_B) 6755 1.1 christos { 6756 1.1 christos switch (md.hint_b) 6757 1.1 christos { 6758 1.1 christos case hint_b_ok: 6759 1.1 christos break; 6760 1.1 christos case hint_b_warning: 6761 1.1 christos as_warn (_("hint in B unit may be treated as nop")); 6762 1.1 christos break; 6763 1.1 christos case hint_b_error: 6764 1.1 christos /* When manual bundling is off and there is no 6765 1.1 christos user template, we choose a different unit so 6766 1.1 christos that hint won't go into the current slot. We 6767 1.1 christos will fill the current bundle with nops and 6768 1.1 christos try to put hint into the next bundle. */ 6769 1.1 christos if (!manual_bundling && user_template < 0) 6770 1.1 christos insn_unit = IA64_UNIT_I; 6771 1.1 christos else 6772 1.1 christos as_bad (_("hint in B unit can't be used")); 6773 1.1 christos break; 6774 1.1 christos } 6775 1.1 christos } 6776 1.1 christos } 6777 1.1 christos else if (strcmp (idesc->name, "chk.s") == 0 6778 1.1 christos || strcmp (idesc->name, "mov") == 0) 6779 1.1 christos { 6780 1.1 christos insn_unit = IA64_UNIT_M; 6781 1.1 christos if (required_unit == IA64_UNIT_I 6782 1.1 christos || (required_unit == IA64_UNIT_F && template_val == 6)) 6783 1.1 christos insn_unit = IA64_UNIT_I; 6784 1.1 christos } 6785 1.1 christos else 6786 1.1 christos as_fatal (_("emit_one_bundle: unexpected dynamic op")); 6787 1.1 christos 6788 1.1 christos snprintf (mnemonic, sizeof (mnemonic), "%s.%c", 6789 1.1 christos idesc->name, "?imbfxx"[insn_unit]); 6790 1.1 christos opnd1 = idesc->operands[0]; 6791 1.1 christos opnd2 = idesc->operands[1]; 6792 1.1 christos ia64_free_opcode (idesc); 6793 1.1 christos idesc = ia64_find_opcode (mnemonic); 6794 1.1 christos /* moves to/from ARs have collisions */ 6795 1.1 christos if (opnd1 == IA64_OPND_AR3 || opnd2 == IA64_OPND_AR3) 6796 1.1 christos { 6797 1.1 christos while (idesc != NULL 6798 1.1 christos && (idesc->operands[0] != opnd1 6799 1.1 christos || idesc->operands[1] != opnd2)) 6800 1.1 christos idesc = get_next_opcode (idesc); 6801 1.1 christos } 6802 1.1 christos md.slot[curr].idesc = idesc; 6803 1.1 christos } 6804 1.1 christos else 6805 1.1 christos { 6806 1.1 christos insn_type = idesc->type; 6807 1.1 christos insn_unit = IA64_UNIT_NIL; 6808 1.1 christos switch (insn_type) 6809 1.1 christos { 6810 1.1 christos case IA64_TYPE_A: 6811 1.1 christos if (required_unit == IA64_UNIT_I || required_unit == IA64_UNIT_M) 6812 1.1 christos insn_unit = required_unit; 6813 1.1 christos break; 6814 1.1 christos case IA64_TYPE_X: insn_unit = IA64_UNIT_L; break; 6815 1.1 christos case IA64_TYPE_I: insn_unit = IA64_UNIT_I; break; 6816 1.1 christos case IA64_TYPE_M: insn_unit = IA64_UNIT_M; break; 6817 1.1 christos case IA64_TYPE_B: insn_unit = IA64_UNIT_B; break; 6818 1.1 christos case IA64_TYPE_F: insn_unit = IA64_UNIT_F; break; 6819 1.1 christos default: break; 6820 1.1 christos } 6821 1.1 christos } 6822 1.1 christos 6823 1.1 christos if (insn_unit != required_unit) 6824 1.1 christos continue; /* Try next slot. */ 6825 1.1 christos 6826 1.1 christos /* Now is a good time to fix up the labels for this insn. */ 6827 1.8 christos mark_label = false; 6828 1.1 christos for (lfix = md.slot[curr].label_fixups; lfix; lfix = lfix->next) 6829 1.1 christos { 6830 1.1 christos S_SET_VALUE (lfix->sym, frag_now_fix () - 16); 6831 1.1 christos symbol_set_frag (lfix->sym, frag_now); 6832 1.1 christos mark_label |= lfix->dw2_mark_labels; 6833 1.1 christos } 6834 1.1 christos for (lfix = md.slot[curr].tag_fixups; lfix; lfix = lfix->next) 6835 1.1 christos { 6836 1.1 christos S_SET_VALUE (lfix->sym, frag_now_fix () - 16 + i); 6837 1.1 christos symbol_set_frag (lfix->sym, frag_now); 6838 1.1 christos } 6839 1.1 christos 6840 1.1 christos if (debug_type == DEBUG_DWARF2 6841 1.1 christos || md.slot[curr].loc_directive_seen 6842 1.1 christos || mark_label) 6843 1.1 christos { 6844 1.1 christos bfd_vma addr = frag_now->fr_address + frag_now_fix () - 16 + i; 6845 1.1 christos 6846 1.1 christos md.slot[curr].loc_directive_seen = 0; 6847 1.1 christos if (mark_label) 6848 1.1 christos md.slot[curr].debug_line.flags |= DWARF2_FLAG_BASIC_BLOCK; 6849 1.1 christos 6850 1.1 christos dwarf2_gen_line_info (addr, &md.slot[curr].debug_line); 6851 1.1 christos } 6852 1.1 christos 6853 1.1 christos build_insn (md.slot + curr, insn + i); 6854 1.1 christos 6855 1.1 christos ptr = md.slot[curr].unwind_record; 6856 1.1 christos if (ptr) 6857 1.1 christos { 6858 1.1 christos /* Set slot numbers for all remaining unwind records belonging to the 6859 1.1 christos current insn. There can not be any prologue/body unwind records 6860 1.1 christos here. */ 6861 1.1 christos for (; ptr != end_ptr; ptr = ptr->next) 6862 1.1 christos { 6863 1.1 christos ptr->slot_number = (unsigned long) f + i; 6864 1.1 christos ptr->slot_frag = frag_now; 6865 1.1 christos } 6866 1.1 christos md.slot[curr].unwind_record = NULL; 6867 1.1 christos } 6868 1.1 christos 6869 1.1 christos for (j = 0; j < md.slot[curr].num_fixups; ++j) 6870 1.1 christos { 6871 1.8 christos unsigned long where; 6872 1.8 christos 6873 1.1 christos ifix = md.slot[curr].fixup + j; 6874 1.8 christos where = frag_now_fix () - 16 + i; 6875 1.8 christos #ifdef TE_HPUX 6876 1.8 christos /* Relocations for instructions specify the slot in the 6877 1.8 christos bottom two bits of r_offset. The IA64 HP-UX linker 6878 1.8 christos expects PCREL60B relocations to specify slot 2 of an 6879 1.8 christos instruction. gas generates PCREL60B against slot 1. */ 6880 1.8 christos if (ifix->code == BFD_RELOC_IA64_PCREL60B) 6881 1.8 christos { 6882 1.8 christos know (i == 1); 6883 1.8 christos ++where; 6884 1.8 christos } 6885 1.8 christos #endif 6886 1.8 christos 6887 1.8 christos fix = fix_new_exp (frag_now, where, 8, 6888 1.1 christos &ifix->expr, ifix->is_pcrel, ifix->code); 6889 1.1 christos fix->tc_fix_data.opnd = ifix->opnd; 6890 1.1 christos fix->fx_file = md.slot[curr].src_file; 6891 1.1 christos fix->fx_line = md.slot[curr].src_line; 6892 1.1 christos } 6893 1.1 christos 6894 1.1 christos end_of_insn_group = md.slot[curr].end_of_insn_group; 6895 1.1 christos 6896 1.3 christos /* This adjustment to "i" must occur after the fix, otherwise the fix 6897 1.3 christos is assigned to the wrong slot, and the VMS linker complains. */ 6898 1.3 christos if (required_unit == IA64_UNIT_L) 6899 1.3 christos { 6900 1.3 christos know (i == 1); 6901 1.3 christos /* skip one slot for long/X-unit instructions */ 6902 1.3 christos ++i; 6903 1.3 christos } 6904 1.3 christos --md.num_slots_in_use; 6905 1.3 christos last_slot = i; 6906 1.3 christos 6907 1.1 christos /* clear slot: */ 6908 1.1 christos ia64_free_opcode (md.slot[curr].idesc); 6909 1.1 christos memset (md.slot + curr, 0, sizeof (md.slot[curr])); 6910 1.1 christos md.slot[curr].user_template = -1; 6911 1.1 christos 6912 1.1 christos if (manual_bundling_off) 6913 1.1 christos { 6914 1.1 christos manual_bundling = 0; 6915 1.1 christos break; 6916 1.1 christos } 6917 1.1 christos curr = (curr + 1) % NUM_SLOTS; 6918 1.1 christos idesc = md.slot[curr].idesc; 6919 1.1 christos } 6920 1.1 christos 6921 1.1 christos /* A user template was specified, but the first following instruction did 6922 1.1 christos not fit. This can happen with or without manual bundling. */ 6923 1.1 christos if (md.num_slots_in_use > 0 && last_slot < 0) 6924 1.1 christos { 6925 1.1 christos as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line, 6926 1.1 christos _("`%s' does not fit into %s template"), 6927 1.1 christos idesc->name, ia64_templ_desc[template_val].name); 6928 1.1 christos /* Drop first insn so we don't livelock. */ 6929 1.1 christos --md.num_slots_in_use; 6930 1.1 christos know (curr == first); 6931 1.1 christos ia64_free_opcode (md.slot[curr].idesc); 6932 1.1 christos memset (md.slot + curr, 0, sizeof (md.slot[curr])); 6933 1.1 christos md.slot[curr].user_template = -1; 6934 1.1 christos } 6935 1.1 christos else if (manual_bundling > 0) 6936 1.1 christos { 6937 1.1 christos if (md.num_slots_in_use > 0) 6938 1.1 christos { 6939 1.1 christos if (last_slot >= 2) 6940 1.1 christos as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line, 6941 1.1 christos _("`%s' does not fit into bundle"), idesc->name); 6942 1.1 christos else 6943 1.1 christos { 6944 1.1 christos const char *where; 6945 1.1 christos 6946 1.1 christos if (template_val == 2) 6947 1.1 christos where = "X slot"; 6948 1.1 christos else if (last_slot == 0) 6949 1.1 christos where = "slots 2 or 3"; 6950 1.1 christos else 6951 1.1 christos where = "slot 3"; 6952 1.1 christos as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line, 6953 1.1 christos _("`%s' can't go in %s of %s template"), 6954 1.1 christos idesc->name, where, ia64_templ_desc[template_val].name); 6955 1.1 christos } 6956 1.1 christos } 6957 1.1 christos else 6958 1.1 christos as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line, 6959 1.1 christos _("Missing '}' at end of file")); 6960 1.1 christos } 6961 1.3 christos 6962 1.1 christos know (md.num_slots_in_use < NUM_SLOTS); 6963 1.1 christos 6964 1.1 christos t0 = end_of_insn_group | (template_val << 1) | (insn[0] << 5) | (insn[1] << 46); 6965 1.1 christos t1 = ((insn[1] >> 18) & 0x7fffff) | (insn[2] << 23); 6966 1.1 christos 6967 1.1 christos number_to_chars_littleendian (f + 0, t0, 8); 6968 1.1 christos number_to_chars_littleendian (f + 8, t1, 8); 6969 1.1 christos } 6970 1.1 christos 6971 1.1 christos int 6972 1.5 christos md_parse_option (int c, const char *arg) 6973 1.1 christos { 6974 1.1 christos 6975 1.1 christos switch (c) 6976 1.1 christos { 6977 1.1 christos /* Switches from the Intel assembler. */ 6978 1.1 christos case 'm': 6979 1.1 christos if (strcmp (arg, "ilp64") == 0 6980 1.1 christos || strcmp (arg, "lp64") == 0 6981 1.1 christos || strcmp (arg, "p64") == 0) 6982 1.1 christos { 6983 1.1 christos md.flags |= EF_IA_64_ABI64; 6984 1.1 christos } 6985 1.1 christos else if (strcmp (arg, "ilp32") == 0) 6986 1.1 christos { 6987 1.1 christos md.flags &= ~EF_IA_64_ABI64; 6988 1.1 christos } 6989 1.1 christos else if (strcmp (arg, "le") == 0) 6990 1.1 christos { 6991 1.1 christos md.flags &= ~EF_IA_64_BE; 6992 1.1 christos default_big_endian = 0; 6993 1.1 christos } 6994 1.1 christos else if (strcmp (arg, "be") == 0) 6995 1.1 christos { 6996 1.1 christos md.flags |= EF_IA_64_BE; 6997 1.1 christos default_big_endian = 1; 6998 1.1 christos } 6999 1.8 christos else if (startswith (arg, "unwind-check=")) 7000 1.1 christos { 7001 1.1 christos arg += 13; 7002 1.1 christos if (strcmp (arg, "warning") == 0) 7003 1.1 christos md.unwind_check = unwind_check_warning; 7004 1.1 christos else if (strcmp (arg, "error") == 0) 7005 1.1 christos md.unwind_check = unwind_check_error; 7006 1.1 christos else 7007 1.1 christos return 0; 7008 1.1 christos } 7009 1.8 christos else if (startswith (arg, "hint.b=")) 7010 1.1 christos { 7011 1.1 christos arg += 7; 7012 1.1 christos if (strcmp (arg, "ok") == 0) 7013 1.1 christos md.hint_b = hint_b_ok; 7014 1.1 christos else if (strcmp (arg, "warning") == 0) 7015 1.1 christos md.hint_b = hint_b_warning; 7016 1.1 christos else if (strcmp (arg, "error") == 0) 7017 1.1 christos md.hint_b = hint_b_error; 7018 1.1 christos else 7019 1.1 christos return 0; 7020 1.1 christos } 7021 1.8 christos else if (startswith (arg, "tune=")) 7022 1.1 christos { 7023 1.1 christos arg += 5; 7024 1.1 christos if (strcmp (arg, "itanium1") == 0) 7025 1.1 christos md.tune = itanium1; 7026 1.1 christos else if (strcmp (arg, "itanium2") == 0) 7027 1.1 christos md.tune = itanium2; 7028 1.1 christos else 7029 1.1 christos return 0; 7030 1.1 christos } 7031 1.1 christos else 7032 1.1 christos return 0; 7033 1.1 christos break; 7034 1.1 christos 7035 1.1 christos case 'N': 7036 1.1 christos if (strcmp (arg, "so") == 0) 7037 1.1 christos { 7038 1.1 christos /* Suppress signon message. */ 7039 1.1 christos } 7040 1.1 christos else if (strcmp (arg, "pi") == 0) 7041 1.1 christos { 7042 1.1 christos /* Reject privileged instructions. FIXME */ 7043 1.1 christos } 7044 1.1 christos else if (strcmp (arg, "us") == 0) 7045 1.1 christos { 7046 1.1 christos /* Allow union of signed and unsigned range. FIXME */ 7047 1.1 christos } 7048 1.1 christos else if (strcmp (arg, "close_fcalls") == 0) 7049 1.1 christos { 7050 1.1 christos /* Do not resolve global function calls. */ 7051 1.1 christos } 7052 1.1 christos else 7053 1.1 christos return 0; 7054 1.1 christos break; 7055 1.1 christos 7056 1.1 christos case 'C': 7057 1.1 christos /* temp[="prefix"] Insert temporary labels into the object file 7058 1.1 christos symbol table prefixed by "prefix". 7059 1.1 christos Default prefix is ":temp:". 7060 1.1 christos */ 7061 1.1 christos break; 7062 1.1 christos 7063 1.1 christos case 'a': 7064 1.1 christos /* indirect=<tgt> Assume unannotated indirect branches behavior 7065 1.1 christos according to <tgt> -- 7066 1.1 christos exit: branch out from the current context (default) 7067 1.1 christos labels: all labels in context may be branch targets 7068 1.1 christos */ 7069 1.8 christos if (!startswith (arg, "indirect=")) 7070 1.1 christos return 0; 7071 1.1 christos break; 7072 1.1 christos 7073 1.1 christos case 'x': 7074 1.1 christos /* -X conflicts with an ignored option, use -x instead */ 7075 1.1 christos md.detect_dv = 1; 7076 1.1 christos if (!arg || strcmp (arg, "explicit") == 0) 7077 1.1 christos { 7078 1.1 christos /* set default mode to explicit */ 7079 1.1 christos md.default_explicit_mode = 1; 7080 1.1 christos break; 7081 1.1 christos } 7082 1.1 christos else if (strcmp (arg, "auto") == 0) 7083 1.1 christos { 7084 1.1 christos md.default_explicit_mode = 0; 7085 1.1 christos } 7086 1.1 christos else if (strcmp (arg, "none") == 0) 7087 1.1 christos { 7088 1.1 christos md.detect_dv = 0; 7089 1.1 christos } 7090 1.1 christos else if (strcmp (arg, "debug") == 0) 7091 1.1 christos { 7092 1.1 christos md.debug_dv = 1; 7093 1.1 christos } 7094 1.1 christos else if (strcmp (arg, "debugx") == 0) 7095 1.1 christos { 7096 1.1 christos md.default_explicit_mode = 1; 7097 1.1 christos md.debug_dv = 1; 7098 1.1 christos } 7099 1.1 christos else if (strcmp (arg, "debugn") == 0) 7100 1.1 christos { 7101 1.1 christos md.debug_dv = 1; 7102 1.1 christos md.detect_dv = 0; 7103 1.1 christos } 7104 1.1 christos else 7105 1.1 christos { 7106 1.1 christos as_bad (_("Unrecognized option '-x%s'"), arg); 7107 1.1 christos } 7108 1.1 christos break; 7109 1.1 christos 7110 1.1 christos case 'S': 7111 1.1 christos /* nops Print nops statistics. */ 7112 1.1 christos break; 7113 1.1 christos 7114 1.1 christos /* GNU specific switches for gcc. */ 7115 1.1 christos case OPTION_MCONSTANT_GP: 7116 1.1 christos md.flags |= EF_IA_64_CONS_GP; 7117 1.1 christos break; 7118 1.1 christos 7119 1.1 christos case OPTION_MAUTO_PIC: 7120 1.1 christos md.flags |= EF_IA_64_NOFUNCDESC_CONS_GP; 7121 1.1 christos break; 7122 1.1 christos 7123 1.1 christos default: 7124 1.1 christos return 0; 7125 1.1 christos } 7126 1.1 christos 7127 1.1 christos return 1; 7128 1.1 christos } 7129 1.1 christos 7130 1.1 christos void 7131 1.1 christos md_show_usage (FILE *stream) 7132 1.1 christos { 7133 1.1 christos fputs (_("\ 7134 1.1 christos IA-64 options:\n\ 7135 1.1 christos --mconstant-gp mark output file as using the constant-GP model\n\ 7136 1.1 christos (sets ELF header flag EF_IA_64_CONS_GP)\n\ 7137 1.1 christos --mauto-pic mark output file as using the constant-GP model\n\ 7138 1.1 christos without function descriptors (sets ELF header flag\n\ 7139 1.1 christos EF_IA_64_NOFUNCDESC_CONS_GP)\n\ 7140 1.1 christos -milp32|-milp64|-mlp64|-mp64 select data model (default -mlp64)\n\ 7141 1.1 christos -mle | -mbe select little- or big-endian byte order (default -mle)\n\ 7142 1.1 christos -mtune=[itanium1|itanium2]\n\ 7143 1.1 christos tune for a specific CPU (default -mtune=itanium2)\n\ 7144 1.1 christos -munwind-check=[warning|error]\n\ 7145 1.1 christos unwind directive check (default -munwind-check=warning)\n\ 7146 1.1 christos -mhint.b=[ok|warning|error]\n\ 7147 1.1 christos hint.b check (default -mhint.b=error)\n\ 7148 1.1 christos -x | -xexplicit turn on dependency violation checking\n"), stream); 7149 1.1 christos /* Note for translators: "automagically" can be translated as "automatically" here. */ 7150 1.1 christos fputs (_("\ 7151 1.1 christos -xauto automagically remove dependency violations (default)\n\ 7152 1.1 christos -xnone turn off dependency violation checking\n\ 7153 1.1 christos -xdebug debug dependency violation checker\n\ 7154 1.1 christos -xdebugn debug dependency violation checker but turn off\n\ 7155 1.1 christos dependency violation checking\n\ 7156 1.1 christos -xdebugx debug dependency violation checker and turn on\n\ 7157 1.1 christos dependency violation checking\n"), 7158 1.1 christos stream); 7159 1.1 christos } 7160 1.1 christos 7161 1.1 christos void 7162 1.1 christos ia64_after_parse_args (void) 7163 1.1 christos { 7164 1.1 christos if (debug_type == DEBUG_STABS) 7165 1.1 christos as_fatal (_("--gstabs is not supported for ia64")); 7166 1.1 christos } 7167 1.1 christos 7168 1.1 christos /* Return true if TYPE fits in TEMPL at SLOT. */ 7169 1.1 christos 7170 1.1 christos static int 7171 1.1 christos match (int templ, int type, int slot) 7172 1.1 christos { 7173 1.1 christos enum ia64_unit unit; 7174 1.1 christos int result; 7175 1.1 christos 7176 1.1 christos unit = ia64_templ_desc[templ].exec_unit[slot]; 7177 1.1 christos switch (type) 7178 1.1 christos { 7179 1.1 christos case IA64_TYPE_DYN: result = 1; break; /* for nop and break */ 7180 1.1 christos case IA64_TYPE_A: 7181 1.1 christos result = (unit == IA64_UNIT_I || unit == IA64_UNIT_M); 7182 1.1 christos break; 7183 1.1 christos case IA64_TYPE_X: result = (unit == IA64_UNIT_L); break; 7184 1.1 christos case IA64_TYPE_I: result = (unit == IA64_UNIT_I); break; 7185 1.1 christos case IA64_TYPE_M: result = (unit == IA64_UNIT_M); break; 7186 1.1 christos case IA64_TYPE_B: result = (unit == IA64_UNIT_B); break; 7187 1.1 christos case IA64_TYPE_F: result = (unit == IA64_UNIT_F); break; 7188 1.1 christos default: result = 0; break; 7189 1.1 christos } 7190 1.1 christos return result; 7191 1.1 christos } 7192 1.1 christos 7193 1.1 christos /* For Itanium 1, add a bit of extra goodness if a nop of type F or B would fit 7194 1.1 christos in TEMPL at SLOT. For Itanium 2, add a bit of extra goodness if a nop of 7195 1.1 christos type M or I would fit in TEMPL at SLOT. */ 7196 1.1 christos 7197 1.1 christos static inline int 7198 1.1 christos extra_goodness (int templ, int slot) 7199 1.1 christos { 7200 1.1 christos switch (md.tune) 7201 1.1 christos { 7202 1.1 christos case itanium1: 7203 1.1 christos if (slot == 1 && match (templ, IA64_TYPE_F, slot)) 7204 1.1 christos return 2; 7205 1.1 christos else if (slot == 2 && match (templ, IA64_TYPE_B, slot)) 7206 1.1 christos return 1; 7207 1.1 christos else 7208 1.1 christos return 0; 7209 1.1 christos break; 7210 1.1 christos case itanium2: 7211 1.1 christos if (match (templ, IA64_TYPE_M, slot) 7212 1.1 christos || match (templ, IA64_TYPE_I, slot)) 7213 1.1 christos /* Favor M- and I-unit NOPs. We definitely want to avoid 7214 1.1 christos F-unit and B-unit may cause split-issue or less-than-optimal 7215 1.1 christos branch-prediction. */ 7216 1.1 christos return 2; 7217 1.1 christos else 7218 1.1 christos return 0; 7219 1.1 christos break; 7220 1.1 christos default: 7221 1.1 christos abort (); 7222 1.1 christos return 0; 7223 1.1 christos } 7224 1.1 christos } 7225 1.1 christos 7226 1.1 christos /* This function is called once, at assembler startup time. It sets 7227 1.1 christos up all the tables, etc. that the MD part of the assembler will need 7228 1.1 christos that can be determined before arguments are parsed. */ 7229 1.1 christos void 7230 1.1 christos md_begin (void) 7231 1.1 christos { 7232 1.1 christos int i, j, k, t, goodness, best, ok; 7233 1.1 christos 7234 1.1 christos md.auto_align = 1; 7235 1.1 christos md.explicit_mode = md.default_explicit_mode; 7236 1.1 christos 7237 1.7 christos bfd_set_section_alignment (text_section, 4); 7238 1.1 christos 7239 1.1 christos /* Make sure function pointers get initialized. */ 7240 1.1 christos target_big_endian = -1; 7241 1.1 christos dot_byteorder (default_big_endian); 7242 1.1 christos 7243 1.8 christos alias_hash = str_htab_create (); 7244 1.8 christos alias_name_hash = str_htab_create (); 7245 1.8 christos secalias_hash = str_htab_create (); 7246 1.8 christos secalias_name_hash = str_htab_create (); 7247 1.1 christos 7248 1.1 christos pseudo_func[FUNC_DTP_MODULE].u.sym = 7249 1.8 christos symbol_new (".<dtpmod>", undefined_section, 7250 1.8 christos &zero_address_frag, FUNC_DTP_MODULE); 7251 1.1 christos 7252 1.1 christos pseudo_func[FUNC_DTP_RELATIVE].u.sym = 7253 1.8 christos symbol_new (".<dtprel>", undefined_section, 7254 1.8 christos &zero_address_frag, FUNC_DTP_RELATIVE); 7255 1.1 christos 7256 1.1 christos pseudo_func[FUNC_FPTR_RELATIVE].u.sym = 7257 1.8 christos symbol_new (".<fptr>", undefined_section, 7258 1.8 christos &zero_address_frag, FUNC_FPTR_RELATIVE); 7259 1.1 christos 7260 1.1 christos pseudo_func[FUNC_GP_RELATIVE].u.sym = 7261 1.8 christos symbol_new (".<gprel>", undefined_section, 7262 1.8 christos &zero_address_frag, FUNC_GP_RELATIVE); 7263 1.1 christos 7264 1.1 christos pseudo_func[FUNC_LT_RELATIVE].u.sym = 7265 1.8 christos symbol_new (".<ltoff>", undefined_section, 7266 1.8 christos &zero_address_frag, FUNC_LT_RELATIVE); 7267 1.1 christos 7268 1.1 christos pseudo_func[FUNC_LT_RELATIVE_X].u.sym = 7269 1.8 christos symbol_new (".<ltoffx>", undefined_section, 7270 1.8 christos &zero_address_frag, FUNC_LT_RELATIVE_X); 7271 1.1 christos 7272 1.1 christos pseudo_func[FUNC_PC_RELATIVE].u.sym = 7273 1.8 christos symbol_new (".<pcrel>", undefined_section, 7274 1.8 christos &zero_address_frag, FUNC_PC_RELATIVE); 7275 1.1 christos 7276 1.1 christos pseudo_func[FUNC_PLT_RELATIVE].u.sym = 7277 1.8 christos symbol_new (".<pltoff>", undefined_section, 7278 1.8 christos &zero_address_frag, FUNC_PLT_RELATIVE); 7279 1.1 christos 7280 1.1 christos pseudo_func[FUNC_SEC_RELATIVE].u.sym = 7281 1.8 christos symbol_new (".<secrel>", undefined_section, 7282 1.8 christos &zero_address_frag, FUNC_SEC_RELATIVE); 7283 1.1 christos 7284 1.1 christos pseudo_func[FUNC_SEG_RELATIVE].u.sym = 7285 1.8 christos symbol_new (".<segrel>", undefined_section, 7286 1.8 christos &zero_address_frag, FUNC_SEG_RELATIVE); 7287 1.1 christos 7288 1.1 christos pseudo_func[FUNC_TP_RELATIVE].u.sym = 7289 1.8 christos symbol_new (".<tprel>", undefined_section, 7290 1.8 christos &zero_address_frag, FUNC_TP_RELATIVE); 7291 1.1 christos 7292 1.1 christos pseudo_func[FUNC_LTV_RELATIVE].u.sym = 7293 1.8 christos symbol_new (".<ltv>", undefined_section, 7294 1.8 christos &zero_address_frag, FUNC_LTV_RELATIVE); 7295 1.1 christos 7296 1.1 christos pseudo_func[FUNC_LT_FPTR_RELATIVE].u.sym = 7297 1.8 christos symbol_new (".<ltoff.fptr>", undefined_section, 7298 1.8 christos &zero_address_frag, FUNC_LT_FPTR_RELATIVE); 7299 1.1 christos 7300 1.1 christos pseudo_func[FUNC_LT_DTP_MODULE].u.sym = 7301 1.8 christos symbol_new (".<ltoff.dtpmod>", undefined_section, 7302 1.8 christos &zero_address_frag, FUNC_LT_DTP_MODULE); 7303 1.1 christos 7304 1.1 christos pseudo_func[FUNC_LT_DTP_RELATIVE].u.sym = 7305 1.8 christos symbol_new (".<ltoff.dptrel>", undefined_section, 7306 1.8 christos &zero_address_frag, FUNC_LT_DTP_RELATIVE); 7307 1.1 christos 7308 1.1 christos pseudo_func[FUNC_LT_TP_RELATIVE].u.sym = 7309 1.8 christos symbol_new (".<ltoff.tprel>", undefined_section, 7310 1.8 christos &zero_address_frag, FUNC_LT_TP_RELATIVE); 7311 1.1 christos 7312 1.1 christos pseudo_func[FUNC_IPLT_RELOC].u.sym = 7313 1.8 christos symbol_new (".<iplt>", undefined_section, 7314 1.8 christos &zero_address_frag, FUNC_IPLT_RELOC); 7315 1.1 christos 7316 1.1 christos #ifdef TE_VMS 7317 1.1 christos pseudo_func[FUNC_SLOTCOUNT_RELOC].u.sym = 7318 1.8 christos symbol_new (".<slotcount>", undefined_section, 7319 1.8 christos &zero_address_frag, FUNC_SLOTCOUNT_RELOC); 7320 1.1 christos #endif 7321 1.1 christos 7322 1.1 christos if (md.tune != itanium1) 7323 1.1 christos { 7324 1.1 christos /* Convert MFI NOPs bundles into MMI NOPs bundles. */ 7325 1.1 christos le_nop[0] = 0x8; 7326 1.1 christos le_nop_stop[0] = 0x9; 7327 1.1 christos } 7328 1.1 christos 7329 1.1 christos /* Compute the table of best templates. We compute goodness as a 7330 1.1 christos base 4 value, in which each match counts for 3. Match-failures 7331 1.1 christos result in NOPs and we use extra_goodness() to pick the execution 7332 1.1 christos units that are best suited for issuing the NOP. */ 7333 1.1 christos for (i = 0; i < IA64_NUM_TYPES; ++i) 7334 1.1 christos for (j = 0; j < IA64_NUM_TYPES; ++j) 7335 1.1 christos for (k = 0; k < IA64_NUM_TYPES; ++k) 7336 1.1 christos { 7337 1.1 christos best = 0; 7338 1.1 christos for (t = 0; t < NELEMS (ia64_templ_desc); ++t) 7339 1.1 christos { 7340 1.1 christos goodness = 0; 7341 1.1 christos if (match (t, i, 0)) 7342 1.1 christos { 7343 1.1 christos if (match (t, j, 1)) 7344 1.1 christos { 7345 1.1 christos if ((t == 2 && j == IA64_TYPE_X) || match (t, k, 2)) 7346 1.1 christos goodness = 3 + 3 + 3; 7347 1.1 christos else 7348 1.1 christos goodness = 3 + 3 + extra_goodness (t, 2); 7349 1.1 christos } 7350 1.1 christos else if (match (t, j, 2)) 7351 1.1 christos goodness = 3 + 3 + extra_goodness (t, 1); 7352 1.1 christos else 7353 1.1 christos { 7354 1.1 christos goodness = 3; 7355 1.1 christos goodness += extra_goodness (t, 1); 7356 1.1 christos goodness += extra_goodness (t, 2); 7357 1.1 christos } 7358 1.1 christos } 7359 1.1 christos else if (match (t, i, 1)) 7360 1.1 christos { 7361 1.1 christos if ((t == 2 && i == IA64_TYPE_X) || match (t, j, 2)) 7362 1.1 christos goodness = 3 + 3; 7363 1.1 christos else 7364 1.1 christos goodness = 3 + extra_goodness (t, 2); 7365 1.1 christos } 7366 1.1 christos else if (match (t, i, 2)) 7367 1.1 christos goodness = 3 + extra_goodness (t, 1); 7368 1.1 christos 7369 1.1 christos if (goodness > best) 7370 1.1 christos { 7371 1.1 christos best = goodness; 7372 1.1 christos best_template[i][j][k] = t; 7373 1.1 christos } 7374 1.1 christos } 7375 1.1 christos } 7376 1.1 christos 7377 1.1 christos #ifdef DEBUG_TEMPLATES 7378 1.1 christos /* For debugging changes to the best_template calculations. We don't care 7379 1.1 christos about combinations with invalid instructions, so start the loops at 1. */ 7380 1.1 christos for (i = 0; i < IA64_NUM_TYPES; ++i) 7381 1.1 christos for (j = 0; j < IA64_NUM_TYPES; ++j) 7382 1.1 christos for (k = 0; k < IA64_NUM_TYPES; ++k) 7383 1.1 christos { 7384 1.1 christos char type_letter[IA64_NUM_TYPES] = { 'n', 'a', 'i', 'm', 'b', 'f', 7385 1.1 christos 'x', 'd' }; 7386 1.1 christos fprintf (stderr, "%c%c%c %s\n", type_letter[i], type_letter[j], 7387 1.1 christos type_letter[k], 7388 1.1 christos ia64_templ_desc[best_template[i][j][k]].name); 7389 1.1 christos } 7390 1.1 christos #endif 7391 1.1 christos 7392 1.1 christos for (i = 0; i < NUM_SLOTS; ++i) 7393 1.1 christos md.slot[i].user_template = -1; 7394 1.1 christos 7395 1.8 christos md.pseudo_hash = str_htab_create (); 7396 1.1 christos for (i = 0; i < NELEMS (pseudo_opcode); ++i) 7397 1.8 christos if (str_hash_insert (md.pseudo_hash, pseudo_opcode[i].name, 7398 1.8 christos pseudo_opcode + i, 0) != NULL) 7399 1.8 christos as_fatal (_("duplicate %s"), pseudo_opcode[i].name); 7400 1.8 christos 7401 1.8 christos md.reg_hash = str_htab_create (); 7402 1.8 christos md.dynreg_hash = str_htab_create (); 7403 1.8 christos md.const_hash = str_htab_create (); 7404 1.8 christos md.entry_hash = str_htab_create (); 7405 1.1 christos 7406 1.1 christos /* general registers: */ 7407 1.1 christos declare_register_set ("r", 128, REG_GR); 7408 1.1 christos declare_register ("gp", REG_GR + 1); 7409 1.1 christos declare_register ("sp", REG_GR + 12); 7410 1.1 christos declare_register ("tp", REG_GR + 13); 7411 1.1 christos declare_register_set ("ret", 4, REG_GR + 8); 7412 1.1 christos 7413 1.1 christos /* floating point registers: */ 7414 1.1 christos declare_register_set ("f", 128, REG_FR); 7415 1.1 christos declare_register_set ("farg", 8, REG_FR + 8); 7416 1.1 christos declare_register_set ("fret", 8, REG_FR + 8); 7417 1.1 christos 7418 1.1 christos /* branch registers: */ 7419 1.1 christos declare_register_set ("b", 8, REG_BR); 7420 1.1 christos declare_register ("rp", REG_BR + 0); 7421 1.1 christos 7422 1.1 christos /* predicate registers: */ 7423 1.1 christos declare_register_set ("p", 64, REG_P); 7424 1.1 christos declare_register ("pr", REG_PR); 7425 1.1 christos declare_register ("pr.rot", REG_PR_ROT); 7426 1.1 christos 7427 1.1 christos /* application registers: */ 7428 1.1 christos declare_register_set ("ar", 128, REG_AR); 7429 1.1 christos for (i = 0; i < NELEMS (ar); ++i) 7430 1.1 christos declare_register (ar[i].name, REG_AR + ar[i].regnum); 7431 1.1 christos 7432 1.1 christos /* control registers: */ 7433 1.1 christos declare_register_set ("cr", 128, REG_CR); 7434 1.1 christos for (i = 0; i < NELEMS (cr); ++i) 7435 1.1 christos declare_register (cr[i].name, REG_CR + cr[i].regnum); 7436 1.1 christos 7437 1.1 christos /* dahr registers: */ 7438 1.1 christos declare_register_set ("dahr", 8, REG_DAHR); 7439 1.1 christos 7440 1.1 christos declare_register ("ip", REG_IP); 7441 1.1 christos declare_register ("cfm", REG_CFM); 7442 1.1 christos declare_register ("psr", REG_PSR); 7443 1.1 christos declare_register ("psr.l", REG_PSR_L); 7444 1.1 christos declare_register ("psr.um", REG_PSR_UM); 7445 1.1 christos 7446 1.1 christos for (i = 0; i < NELEMS (indirect_reg); ++i) 7447 1.1 christos { 7448 1.1 christos unsigned int regnum = indirect_reg[i].regnum; 7449 1.1 christos 7450 1.1 christos md.indregsym[regnum - IND_CPUID] = declare_register (indirect_reg[i].name, regnum); 7451 1.1 christos } 7452 1.1 christos 7453 1.1 christos /* pseudo-registers used to specify unwind info: */ 7454 1.1 christos declare_register ("psp", REG_PSP); 7455 1.1 christos 7456 1.1 christos for (i = 0; i < NELEMS (const_bits); ++i) 7457 1.8 christos if (str_hash_insert (md.const_hash, const_bits[i].name, const_bits + i, 0)) 7458 1.8 christos as_fatal (_("duplicate %s"), const_bits[i].name); 7459 1.1 christos 7460 1.1 christos /* Set the architecture and machine depending on defaults and command line 7461 1.1 christos options. */ 7462 1.1 christos if (md.flags & EF_IA_64_ABI64) 7463 1.1 christos ok = bfd_set_arch_mach (stdoutput, bfd_arch_ia64, bfd_mach_ia64_elf64); 7464 1.1 christos else 7465 1.1 christos ok = bfd_set_arch_mach (stdoutput, bfd_arch_ia64, bfd_mach_ia64_elf32); 7466 1.1 christos 7467 1.1 christos if (! ok) 7468 1.1 christos as_warn (_("Could not set architecture and machine")); 7469 1.1 christos 7470 1.1 christos /* Set the pointer size and pointer shift size depending on md.flags */ 7471 1.1 christos 7472 1.1 christos if (md.flags & EF_IA_64_ABI64) 7473 1.1 christos { 7474 1.1 christos md.pointer_size = 8; /* pointers are 8 bytes */ 7475 1.1 christos md.pointer_size_shift = 3; /* alignment is 8 bytes = 2^2 */ 7476 1.1 christos } 7477 1.1 christos else 7478 1.1 christos { 7479 1.1 christos md.pointer_size = 4; /* pointers are 4 bytes */ 7480 1.1 christos md.pointer_size_shift = 2; /* alignment is 4 bytes = 2^2 */ 7481 1.1 christos } 7482 1.1 christos 7483 1.1 christos md.mem_offset.hint = 0; 7484 1.1 christos md.path = 0; 7485 1.1 christos md.maxpaths = 0; 7486 1.1 christos md.entry_labels = NULL; 7487 1.1 christos } 7488 1.1 christos 7489 1.1 christos /* Set the default options in md. Cannot do this in md_begin because 7490 1.1 christos that is called after md_parse_option which is where we set the 7491 1.1 christos options in md based on command line options. */ 7492 1.1 christos 7493 1.1 christos void 7494 1.1 christos ia64_init (int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) 7495 1.1 christos { 7496 1.1 christos md.flags = MD_FLAGS_DEFAULT; 7497 1.1 christos #ifndef TE_VMS 7498 1.1 christos /* Don't turn on dependency checking for VMS, doesn't work. */ 7499 1.1 christos md.detect_dv = 1; 7500 1.1 christos #endif 7501 1.1 christos /* FIXME: We should change it to unwind_check_error someday. */ 7502 1.1 christos md.unwind_check = unwind_check_warning; 7503 1.1 christos md.hint_b = hint_b_error; 7504 1.1 christos md.tune = itanium2; 7505 1.1 christos } 7506 1.1 christos 7507 1.1 christos /* Return a string for the target object file format. */ 7508 1.1 christos 7509 1.1 christos const char * 7510 1.1 christos ia64_target_format (void) 7511 1.1 christos { 7512 1.1 christos if (OUTPUT_FLAVOR == bfd_target_elf_flavour) 7513 1.1 christos { 7514 1.1 christos if (md.flags & EF_IA_64_BE) 7515 1.1 christos { 7516 1.1 christos if (md.flags & EF_IA_64_ABI64) 7517 1.1 christos #if defined(TE_AIX50) 7518 1.1 christos return "elf64-ia64-aix-big"; 7519 1.1 christos #elif defined(TE_HPUX) 7520 1.1 christos return "elf64-ia64-hpux-big"; 7521 1.1 christos #else 7522 1.1 christos return "elf64-ia64-big"; 7523 1.1 christos #endif 7524 1.1 christos else 7525 1.1 christos #if defined(TE_AIX50) 7526 1.1 christos return "elf32-ia64-aix-big"; 7527 1.1 christos #elif defined(TE_HPUX) 7528 1.1 christos return "elf32-ia64-hpux-big"; 7529 1.1 christos #else 7530 1.1 christos return "elf32-ia64-big"; 7531 1.1 christos #endif 7532 1.1 christos } 7533 1.1 christos else 7534 1.1 christos { 7535 1.1 christos if (md.flags & EF_IA_64_ABI64) 7536 1.1 christos #if defined (TE_AIX50) 7537 1.1 christos return "elf64-ia64-aix-little"; 7538 1.1 christos #elif defined (TE_VMS) 7539 1.1 christos { 7540 1.1 christos md.flags |= EF_IA_64_ARCHVER_1; 7541 1.1 christos return "elf64-ia64-vms"; 7542 1.1 christos } 7543 1.1 christos #else 7544 1.1 christos return "elf64-ia64-little"; 7545 1.1 christos #endif 7546 1.1 christos else 7547 1.1 christos #ifdef TE_AIX50 7548 1.1 christos return "elf32-ia64-aix-little"; 7549 1.1 christos #else 7550 1.1 christos return "elf32-ia64-little"; 7551 1.1 christos #endif 7552 1.1 christos } 7553 1.1 christos } 7554 1.1 christos else 7555 1.1 christos return "unknown-format"; 7556 1.1 christos } 7557 1.1 christos 7558 1.1 christos void 7559 1.9 christos ia64_md_finish (void) 7560 1.1 christos { 7561 1.1 christos /* terminate insn group upon reaching end of file: */ 7562 1.1 christos insn_group_break (1, 0, 0); 7563 1.1 christos 7564 1.1 christos /* emits slots we haven't written yet: */ 7565 1.1 christos ia64_flush_insns (); 7566 1.1 christos 7567 1.1 christos bfd_set_private_flags (stdoutput, md.flags); 7568 1.1 christos 7569 1.1 christos md.mem_offset.hint = 0; 7570 1.1 christos } 7571 1.1 christos 7572 1.1 christos void 7573 1.1 christos ia64_start_line (void) 7574 1.1 christos { 7575 1.1 christos static int first; 7576 1.1 christos 7577 1.1 christos if (!first) { 7578 1.1 christos /* Make sure we don't reference input_line_pointer[-1] when that's 7579 1.1 christos not valid. */ 7580 1.1 christos first = 1; 7581 1.1 christos return; 7582 1.1 christos } 7583 1.1 christos 7584 1.1 christos if (md.qp.X_op == O_register) 7585 1.1 christos as_bad (_("qualifying predicate not followed by instruction")); 7586 1.1 christos md.qp.X_op = O_absent; 7587 1.1 christos 7588 1.1 christos if (ignore_input ()) 7589 1.1 christos return; 7590 1.1 christos 7591 1.1 christos if (input_line_pointer[0] == ';' && input_line_pointer[-1] == ';') 7592 1.1 christos { 7593 1.1 christos if (md.detect_dv && !md.explicit_mode) 7594 1.1 christos { 7595 1.1 christos static int warned; 7596 1.1 christos 7597 1.1 christos if (!warned) 7598 1.1 christos { 7599 1.1 christos warned = 1; 7600 1.1 christos as_warn (_("Explicit stops are ignored in auto mode")); 7601 1.1 christos } 7602 1.1 christos } 7603 1.1 christos else 7604 1.1 christos insn_group_break (1, 0, 0); 7605 1.1 christos } 7606 1.1 christos else if (input_line_pointer[-1] == '{') 7607 1.1 christos { 7608 1.1 christos if (md.manual_bundling) 7609 1.1 christos as_warn (_("Found '{' when manual bundling is already turned on")); 7610 1.1 christos else 7611 1.1 christos CURR_SLOT.manual_bundling_on = 1; 7612 1.1 christos md.manual_bundling = 1; 7613 1.1 christos 7614 1.1 christos /* Bundling is only acceptable in explicit mode 7615 1.1 christos or when in default automatic mode. */ 7616 1.1 christos if (md.detect_dv && !md.explicit_mode) 7617 1.1 christos { 7618 1.1 christos if (!md.mode_explicitly_set 7619 1.1 christos && !md.default_explicit_mode) 7620 1.1 christos dot_dv_mode ('E'); 7621 1.1 christos else 7622 1.1 christos as_warn (_("Found '{' after explicit switch to automatic mode")); 7623 1.1 christos } 7624 1.1 christos } 7625 1.1 christos else if (input_line_pointer[-1] == '}') 7626 1.1 christos { 7627 1.1 christos if (!md.manual_bundling) 7628 1.1 christos as_warn (_("Found '}' when manual bundling is off")); 7629 1.1 christos else 7630 1.1 christos PREV_SLOT.manual_bundling_off = 1; 7631 1.1 christos md.manual_bundling = 0; 7632 1.1 christos 7633 1.1 christos /* switch back to automatic mode, if applicable */ 7634 1.1 christos if (md.detect_dv 7635 1.1 christos && md.explicit_mode 7636 1.1 christos && !md.mode_explicitly_set 7637 1.1 christos && !md.default_explicit_mode) 7638 1.1 christos dot_dv_mode ('A'); 7639 1.1 christos } 7640 1.1 christos } 7641 1.1 christos 7642 1.1 christos /* This is a hook for ia64_frob_label, so that it can distinguish tags from 7643 1.1 christos labels. */ 7644 1.1 christos static int defining_tag = 0; 7645 1.1 christos 7646 1.1 christos int 7647 1.1 christos ia64_unrecognized_line (int ch) 7648 1.1 christos { 7649 1.1 christos switch (ch) 7650 1.1 christos { 7651 1.1 christos case '(': 7652 1.1 christos expression_and_evaluate (&md.qp); 7653 1.1 christos if (*input_line_pointer++ != ')') 7654 1.1 christos { 7655 1.1 christos as_bad (_("Expected ')'")); 7656 1.1 christos return 0; 7657 1.1 christos } 7658 1.1 christos if (md.qp.X_op != O_register) 7659 1.1 christos { 7660 1.1 christos as_bad (_("Qualifying predicate expected")); 7661 1.1 christos return 0; 7662 1.1 christos } 7663 1.1 christos if (md.qp.X_add_number < REG_P || md.qp.X_add_number >= REG_P + 64) 7664 1.1 christos { 7665 1.1 christos as_bad (_("Predicate register expected")); 7666 1.1 christos return 0; 7667 1.1 christos } 7668 1.1 christos return 1; 7669 1.1 christos 7670 1.1 christos case '[': 7671 1.1 christos { 7672 1.1 christos char *s; 7673 1.1 christos char c; 7674 1.1 christos symbolS *tag; 7675 1.1 christos int temp; 7676 1.1 christos 7677 1.1 christos if (md.qp.X_op == O_register) 7678 1.1 christos { 7679 1.1 christos as_bad (_("Tag must come before qualifying predicate.")); 7680 1.1 christos return 0; 7681 1.1 christos } 7682 1.1 christos 7683 1.1 christos /* This implements just enough of read_a_source_file in read.c to 7684 1.1 christos recognize labels. */ 7685 1.1 christos if (is_name_beginner (*input_line_pointer)) 7686 1.1 christos { 7687 1.3 christos c = get_symbol_name (&s); 7688 1.1 christos } 7689 1.1 christos else if (LOCAL_LABELS_FB 7690 1.1 christos && ISDIGIT (*input_line_pointer)) 7691 1.1 christos { 7692 1.1 christos temp = 0; 7693 1.1 christos while (ISDIGIT (*input_line_pointer)) 7694 1.1 christos temp = (temp * 10) + *input_line_pointer++ - '0'; 7695 1.1 christos fb_label_instance_inc (temp); 7696 1.1 christos s = fb_label_name (temp, 0); 7697 1.1 christos c = *input_line_pointer; 7698 1.1 christos } 7699 1.1 christos else 7700 1.1 christos { 7701 1.1 christos s = NULL; 7702 1.1 christos c = '\0'; 7703 1.1 christos } 7704 1.1 christos if (c != ':') 7705 1.1 christos { 7706 1.1 christos /* Put ':' back for error messages' sake. */ 7707 1.1 christos *input_line_pointer++ = ':'; 7708 1.1 christos as_bad (_("Expected ':'")); 7709 1.1 christos return 0; 7710 1.1 christos } 7711 1.1 christos 7712 1.1 christos defining_tag = 1; 7713 1.1 christos tag = colon (s); 7714 1.1 christos defining_tag = 0; 7715 1.1 christos /* Put ':' back for error messages' sake. */ 7716 1.1 christos *input_line_pointer++ = ':'; 7717 1.1 christos if (*input_line_pointer++ != ']') 7718 1.1 christos { 7719 1.1 christos as_bad (_("Expected ']'")); 7720 1.1 christos return 0; 7721 1.1 christos } 7722 1.1 christos if (! tag) 7723 1.1 christos { 7724 1.1 christos as_bad (_("Tag name expected")); 7725 1.1 christos return 0; 7726 1.1 christos } 7727 1.1 christos return 1; 7728 1.1 christos } 7729 1.1 christos 7730 1.1 christos default: 7731 1.1 christos break; 7732 1.1 christos } 7733 1.1 christos 7734 1.1 christos /* Not a valid line. */ 7735 1.1 christos return 0; 7736 1.1 christos } 7737 1.1 christos 7738 1.1 christos void 7739 1.1 christos ia64_frob_label (struct symbol *sym) 7740 1.1 christos { 7741 1.1 christos struct label_fix *fix; 7742 1.1 christos 7743 1.1 christos /* Tags need special handling since they are not bundle breaks like 7744 1.1 christos labels. */ 7745 1.1 christos if (defining_tag) 7746 1.1 christos { 7747 1.5 christos fix = XOBNEW (¬es, struct label_fix); 7748 1.1 christos fix->sym = sym; 7749 1.1 christos fix->next = CURR_SLOT.tag_fixups; 7750 1.8 christos fix->dw2_mark_labels = false; 7751 1.1 christos CURR_SLOT.tag_fixups = fix; 7752 1.1 christos 7753 1.1 christos return; 7754 1.1 christos } 7755 1.1 christos 7756 1.7 christos if (bfd_section_flags (now_seg) & SEC_CODE) 7757 1.1 christos { 7758 1.1 christos md.last_text_seg = now_seg; 7759 1.8 christos md.last_text_subseg = now_subseg; 7760 1.5 christos fix = XOBNEW (¬es, struct label_fix); 7761 1.1 christos fix->sym = sym; 7762 1.1 christos fix->next = CURR_SLOT.label_fixups; 7763 1.1 christos fix->dw2_mark_labels = dwarf2_loc_mark_labels; 7764 1.1 christos CURR_SLOT.label_fixups = fix; 7765 1.1 christos 7766 1.1 christos /* Keep track of how many code entry points we've seen. */ 7767 1.1 christos if (md.path == md.maxpaths) 7768 1.1 christos { 7769 1.1 christos md.maxpaths += 20; 7770 1.5 christos md.entry_labels = XRESIZEVEC (const char *, md.entry_labels, 7771 1.5 christos md.maxpaths); 7772 1.1 christos } 7773 1.1 christos md.entry_labels[md.path++] = S_GET_NAME (sym); 7774 1.1 christos } 7775 1.1 christos } 7776 1.1 christos 7777 1.1 christos #ifdef TE_HPUX 7778 1.1 christos /* The HP-UX linker will give unresolved symbol errors for symbols 7779 1.1 christos that are declared but unused. This routine removes declared, 7780 1.1 christos unused symbols from an object. */ 7781 1.1 christos int 7782 1.1 christos ia64_frob_symbol (struct symbol *sym) 7783 1.1 christos { 7784 1.1 christos if ((S_GET_SEGMENT (sym) == bfd_und_section_ptr && ! symbol_used_p (sym) && 7785 1.1 christos ELF_ST_VISIBILITY (S_GET_OTHER (sym)) == STV_DEFAULT) 7786 1.1 christos || (S_GET_SEGMENT (sym) == bfd_abs_section_ptr 7787 1.1 christos && ! S_IS_EXTERNAL (sym))) 7788 1.1 christos return 1; 7789 1.1 christos return 0; 7790 1.1 christos } 7791 1.1 christos #endif 7792 1.1 christos 7793 1.1 christos void 7794 1.1 christos ia64_flush_pending_output (void) 7795 1.1 christos { 7796 1.1 christos if (!md.keep_pending_output 7797 1.7 christos && bfd_section_flags (now_seg) & SEC_CODE) 7798 1.1 christos { 7799 1.1 christos /* ??? This causes many unnecessary stop bits to be emitted. 7800 1.1 christos Unfortunately, it isn't clear if it is safe to remove this. */ 7801 1.1 christos insn_group_break (1, 0, 0); 7802 1.1 christos ia64_flush_insns (); 7803 1.1 christos } 7804 1.1 christos } 7805 1.1 christos 7806 1.1 christos /* Do ia64-specific expression optimization. All that's done here is 7807 1.1 christos to transform index expressions that are either due to the indexing 7808 1.1 christos of rotating registers or due to the indexing of indirect register 7809 1.1 christos sets. */ 7810 1.1 christos int 7811 1.1 christos ia64_optimize_expr (expressionS *l, operatorT op, expressionS *r) 7812 1.1 christos { 7813 1.1 christos if (op != O_index) 7814 1.1 christos return 0; 7815 1.1 christos resolve_expression (l); 7816 1.1 christos if (l->X_op == O_register) 7817 1.1 christos { 7818 1.1 christos unsigned num_regs = l->X_add_number >> 16; 7819 1.1 christos 7820 1.1 christos resolve_expression (r); 7821 1.1 christos if (num_regs) 7822 1.1 christos { 7823 1.1 christos /* Left side is a .rotX-allocated register. */ 7824 1.1 christos if (r->X_op != O_constant) 7825 1.1 christos { 7826 1.1 christos as_bad (_("Rotating register index must be a non-negative constant")); 7827 1.1 christos r->X_add_number = 0; 7828 1.1 christos } 7829 1.1 christos else if ((valueT) r->X_add_number >= num_regs) 7830 1.1 christos { 7831 1.1 christos as_bad (_("Index out of range 0..%u"), num_regs - 1); 7832 1.1 christos r->X_add_number = 0; 7833 1.1 christos } 7834 1.1 christos l->X_add_number = (l->X_add_number & 0xffff) + r->X_add_number; 7835 1.1 christos return 1; 7836 1.1 christos } 7837 1.1 christos else if (l->X_add_number >= IND_CPUID && l->X_add_number <= IND_RR) 7838 1.1 christos { 7839 1.1 christos if (r->X_op != O_register 7840 1.1 christos || r->X_add_number < REG_GR 7841 1.1 christos || r->X_add_number > REG_GR + 127) 7842 1.1 christos { 7843 1.1 christos as_bad (_("Indirect register index must be a general register")); 7844 1.1 christos r->X_add_number = REG_GR; 7845 1.1 christos } 7846 1.1 christos l->X_op = O_index; 7847 1.1 christos l->X_op_symbol = md.indregsym[l->X_add_number - IND_CPUID]; 7848 1.1 christos l->X_add_number = r->X_add_number; 7849 1.1 christos return 1; 7850 1.1 christos } 7851 1.1 christos } 7852 1.1 christos as_bad (_("Index can only be applied to rotating or indirect registers")); 7853 1.1 christos /* Fall back to some register use of which has as little as possible 7854 1.1 christos side effects, to minimize subsequent error messages. */ 7855 1.1 christos l->X_op = O_register; 7856 1.1 christos l->X_add_number = REG_GR + 3; 7857 1.1 christos return 1; 7858 1.1 christos } 7859 1.1 christos 7860 1.1 christos int 7861 1.1 christos ia64_parse_name (char *name, expressionS *e, char *nextcharP) 7862 1.1 christos { 7863 1.1 christos struct const_desc *cdesc; 7864 1.1 christos struct dynreg *dr = 0; 7865 1.1 christos unsigned int idx; 7866 1.1 christos struct symbol *sym; 7867 1.1 christos char *end; 7868 1.1 christos 7869 1.1 christos if (*name == '@') 7870 1.1 christos { 7871 1.1 christos enum pseudo_type pseudo_type = PSEUDO_FUNC_NONE; 7872 1.1 christos 7873 1.1 christos /* Find what relocation pseudo-function we're dealing with. */ 7874 1.1 christos for (idx = 0; idx < NELEMS (pseudo_func); ++idx) 7875 1.1 christos if (pseudo_func[idx].name 7876 1.1 christos && pseudo_func[idx].name[0] == name[1] 7877 1.1 christos && strcmp (pseudo_func[idx].name + 1, name + 2) == 0) 7878 1.1 christos { 7879 1.1 christos pseudo_type = pseudo_func[idx].type; 7880 1.1 christos break; 7881 1.1 christos } 7882 1.1 christos switch (pseudo_type) 7883 1.1 christos { 7884 1.1 christos case PSEUDO_FUNC_RELOC: 7885 1.1 christos end = input_line_pointer; 7886 1.1 christos if (*nextcharP != '(') 7887 1.1 christos { 7888 1.1 christos as_bad (_("Expected '('")); 7889 1.1 christos break; 7890 1.1 christos } 7891 1.1 christos /* Skip '('. */ 7892 1.1 christos ++input_line_pointer; 7893 1.1 christos expression (e); 7894 1.1 christos if (*input_line_pointer != ')') 7895 1.1 christos { 7896 1.1 christos as_bad (_("Missing ')'")); 7897 1.1 christos goto done; 7898 1.1 christos } 7899 1.1 christos /* Skip ')'. */ 7900 1.1 christos ++input_line_pointer; 7901 1.1 christos #ifdef TE_VMS 7902 1.1 christos if (idx == FUNC_SLOTCOUNT_RELOC) 7903 1.1 christos { 7904 1.1 christos /* @slotcount can accept any expression. Canonicalize. */ 7905 1.1 christos e->X_add_symbol = make_expr_symbol (e); 7906 1.1 christos e->X_op = O_symbol; 7907 1.1 christos e->X_add_number = 0; 7908 1.1 christos } 7909 1.1 christos #endif 7910 1.1 christos if (e->X_op != O_symbol) 7911 1.1 christos { 7912 1.1 christos if (e->X_op != O_pseudo_fixup) 7913 1.1 christos { 7914 1.1 christos as_bad (_("Not a symbolic expression")); 7915 1.1 christos goto done; 7916 1.1 christos } 7917 1.1 christos if (idx != FUNC_LT_RELATIVE) 7918 1.1 christos { 7919 1.1 christos as_bad (_("Illegal combination of relocation functions")); 7920 1.1 christos goto done; 7921 1.1 christos } 7922 1.1 christos switch (S_GET_VALUE (e->X_op_symbol)) 7923 1.1 christos { 7924 1.1 christos case FUNC_FPTR_RELATIVE: 7925 1.1 christos idx = FUNC_LT_FPTR_RELATIVE; break; 7926 1.1 christos case FUNC_DTP_MODULE: 7927 1.1 christos idx = FUNC_LT_DTP_MODULE; break; 7928 1.1 christos case FUNC_DTP_RELATIVE: 7929 1.1 christos idx = FUNC_LT_DTP_RELATIVE; break; 7930 1.1 christos case FUNC_TP_RELATIVE: 7931 1.1 christos idx = FUNC_LT_TP_RELATIVE; break; 7932 1.1 christos default: 7933 1.1 christos as_bad (_("Illegal combination of relocation functions")); 7934 1.1 christos goto done; 7935 1.1 christos } 7936 1.1 christos } 7937 1.1 christos /* Make sure gas doesn't get rid of local symbols that are used 7938 1.1 christos in relocs. */ 7939 1.1 christos e->X_op = O_pseudo_fixup; 7940 1.1 christos e->X_op_symbol = pseudo_func[idx].u.sym; 7941 1.1 christos done: 7942 1.1 christos *nextcharP = *input_line_pointer; 7943 1.1 christos break; 7944 1.1 christos 7945 1.1 christos case PSEUDO_FUNC_CONST: 7946 1.1 christos e->X_op = O_constant; 7947 1.1 christos e->X_add_number = pseudo_func[idx].u.ival; 7948 1.1 christos break; 7949 1.1 christos 7950 1.1 christos case PSEUDO_FUNC_REG: 7951 1.1 christos e->X_op = O_register; 7952 1.1 christos e->X_add_number = pseudo_func[idx].u.ival; 7953 1.1 christos break; 7954 1.1 christos 7955 1.1 christos default: 7956 1.1 christos return 0; 7957 1.1 christos } 7958 1.1 christos return 1; 7959 1.1 christos } 7960 1.1 christos 7961 1.1 christos /* first see if NAME is a known register name: */ 7962 1.8 christos sym = str_hash_find (md.reg_hash, name); 7963 1.1 christos if (sym) 7964 1.1 christos { 7965 1.1 christos e->X_op = O_register; 7966 1.1 christos e->X_add_number = S_GET_VALUE (sym); 7967 1.1 christos return 1; 7968 1.1 christos } 7969 1.1 christos 7970 1.8 christos cdesc = str_hash_find (md.const_hash, name); 7971 1.1 christos if (cdesc) 7972 1.1 christos { 7973 1.1 christos e->X_op = O_constant; 7974 1.1 christos e->X_add_number = cdesc->value; 7975 1.1 christos return 1; 7976 1.1 christos } 7977 1.1 christos 7978 1.1 christos /* check for inN, locN, or outN: */ 7979 1.1 christos idx = 0; 7980 1.1 christos switch (name[0]) 7981 1.1 christos { 7982 1.1 christos case 'i': 7983 1.1 christos if (name[1] == 'n' && ISDIGIT (name[2])) 7984 1.1 christos { 7985 1.1 christos dr = &md.in; 7986 1.1 christos idx = 2; 7987 1.1 christos } 7988 1.1 christos break; 7989 1.1 christos 7990 1.1 christos case 'l': 7991 1.1 christos if (name[1] == 'o' && name[2] == 'c' && ISDIGIT (name[3])) 7992 1.1 christos { 7993 1.1 christos dr = &md.loc; 7994 1.1 christos idx = 3; 7995 1.1 christos } 7996 1.1 christos break; 7997 1.1 christos 7998 1.1 christos case 'o': 7999 1.1 christos if (name[1] == 'u' && name[2] == 't' && ISDIGIT (name[3])) 8000 1.1 christos { 8001 1.1 christos dr = &md.out; 8002 1.1 christos idx = 3; 8003 1.1 christos } 8004 1.1 christos break; 8005 1.1 christos 8006 1.1 christos default: 8007 1.1 christos break; 8008 1.1 christos } 8009 1.1 christos 8010 1.1 christos /* Ignore register numbers with leading zeroes, except zero itself. */ 8011 1.1 christos if (dr && (name[idx] != '0' || name[idx + 1] == '\0')) 8012 1.1 christos { 8013 1.1 christos unsigned long regnum; 8014 1.1 christos 8015 1.1 christos /* The name is inN, locN, or outN; parse the register number. */ 8016 1.1 christos regnum = strtoul (name + idx, &end, 10); 8017 1.1 christos if (end > name + idx && *end == '\0' && regnum < 96) 8018 1.1 christos { 8019 1.1 christos if (regnum >= dr->num_regs) 8020 1.1 christos { 8021 1.1 christos if (!dr->num_regs) 8022 1.1 christos as_bad (_("No current frame")); 8023 1.1 christos else 8024 1.1 christos as_bad (_("Register number out of range 0..%u"), 8025 1.1 christos dr->num_regs - 1); 8026 1.1 christos regnum = 0; 8027 1.1 christos } 8028 1.1 christos e->X_op = O_register; 8029 1.1 christos e->X_add_number = dr->base + regnum; 8030 1.1 christos return 1; 8031 1.1 christos } 8032 1.1 christos } 8033 1.1 christos 8034 1.5 christos end = xstrdup (name); 8035 1.1 christos name = ia64_canonicalize_symbol_name (end); 8036 1.8 christos if ((dr = str_hash_find (md.dynreg_hash, name))) 8037 1.1 christos { 8038 1.1 christos /* We've got ourselves the name of a rotating register set. 8039 1.1 christos Store the base register number in the low 16 bits of 8040 1.1 christos X_add_number and the size of the register set in the top 16 8041 1.1 christos bits. */ 8042 1.1 christos e->X_op = O_register; 8043 1.1 christos e->X_add_number = dr->base | (dr->num_regs << 16); 8044 1.5 christos free (end); 8045 1.1 christos return 1; 8046 1.1 christos } 8047 1.5 christos free (end); 8048 1.1 christos return 0; 8049 1.1 christos } 8050 1.1 christos 8051 1.1 christos /* Remove the '#' suffix that indicates a symbol as opposed to a register. */ 8052 1.1 christos 8053 1.1 christos char * 8054 1.1 christos ia64_canonicalize_symbol_name (char *name) 8055 1.1 christos { 8056 1.1 christos size_t len = strlen (name), full = len; 8057 1.1 christos 8058 1.1 christos while (len > 0 && name[len - 1] == '#') 8059 1.1 christos --len; 8060 1.1 christos if (len <= 0) 8061 1.1 christos { 8062 1.1 christos if (full > 0) 8063 1.1 christos as_bad (_("Standalone `#' is illegal")); 8064 1.1 christos } 8065 1.1 christos else if (len < full - 1) 8066 1.1 christos as_warn (_("Redundant `#' suffix operators")); 8067 1.1 christos name[len] = '\0'; 8068 1.1 christos return name; 8069 1.1 christos } 8070 1.1 christos 8071 1.1 christos /* Return true if idesc is a conditional branch instruction. This excludes 8072 1.1 christos the modulo scheduled branches, and br.ia. Mod-sched branches are excluded 8073 1.1 christos because they always read/write resources regardless of the value of the 8074 1.1 christos qualifying predicate. br.ia must always use p0, and hence is always 8075 1.1 christos taken. Thus this function returns true for branches which can fall 8076 1.1 christos through, and which use no resources if they do fall through. */ 8077 1.1 christos 8078 1.1 christos static int 8079 1.1 christos is_conditional_branch (struct ia64_opcode *idesc) 8080 1.1 christos { 8081 1.1 christos /* br is a conditional branch. Everything that starts with br. except 8082 1.1 christos br.ia, br.c{loop,top,exit}, and br.w{top,exit} is a conditional branch. 8083 1.1 christos Everything that starts with brl is a conditional branch. */ 8084 1.1 christos return (idesc->name[0] == 'b' && idesc->name[1] == 'r' 8085 1.1 christos && (idesc->name[2] == '\0' 8086 1.1 christos || (idesc->name[2] == '.' && idesc->name[3] != 'i' 8087 1.1 christos && idesc->name[3] != 'c' && idesc->name[3] != 'w') 8088 1.1 christos || idesc->name[2] == 'l' 8089 1.1 christos /* br.cond, br.call, br.clr */ 8090 1.1 christos || (idesc->name[2] == '.' && idesc->name[3] == 'c' 8091 1.1 christos && (idesc->name[4] == 'a' || idesc->name[4] == 'o' 8092 1.1 christos || (idesc->name[4] == 'l' && idesc->name[5] == 'r'))))); 8093 1.1 christos } 8094 1.1 christos 8095 1.1 christos /* Return whether the given opcode is a taken branch. If there's any doubt, 8096 1.1 christos returns zero. */ 8097 1.1 christos 8098 1.1 christos static int 8099 1.1 christos is_taken_branch (struct ia64_opcode *idesc) 8100 1.1 christos { 8101 1.1 christos return ((is_conditional_branch (idesc) && CURR_SLOT.qp_regno == 0) 8102 1.8 christos || startswith (idesc->name, "br.ia")); 8103 1.1 christos } 8104 1.1 christos 8105 1.1 christos /* Return whether the given opcode is an interruption or rfi. If there's any 8106 1.1 christos doubt, returns zero. */ 8107 1.1 christos 8108 1.1 christos static int 8109 1.1 christos is_interruption_or_rfi (struct ia64_opcode *idesc) 8110 1.1 christos { 8111 1.1 christos if (strcmp (idesc->name, "rfi") == 0) 8112 1.1 christos return 1; 8113 1.1 christos return 0; 8114 1.1 christos } 8115 1.1 christos 8116 1.1 christos /* Returns the index of the given dependency in the opcode's list of chks, or 8117 1.1 christos -1 if there is no dependency. */ 8118 1.1 christos 8119 1.1 christos static int 8120 1.1 christos depends_on (int depind, struct ia64_opcode *idesc) 8121 1.1 christos { 8122 1.1 christos int i; 8123 1.1 christos const struct ia64_opcode_dependency *dep = idesc->dependencies; 8124 1.1 christos for (i = 0; i < dep->nchks; i++) 8125 1.1 christos { 8126 1.1 christos if (depind == DEP (dep->chks[i])) 8127 1.1 christos return i; 8128 1.1 christos } 8129 1.1 christos return -1; 8130 1.1 christos } 8131 1.1 christos 8132 1.1 christos /* Determine a set of specific resources used for a particular resource 8133 1.1 christos class. Returns the number of specific resources identified For those 8134 1.1 christos cases which are not determinable statically, the resource returned is 8135 1.1 christos marked nonspecific. 8136 1.1 christos 8137 1.1 christos Meanings of value in 'NOTE': 8138 1.1 christos 1) only read/write when the register number is explicitly encoded in the 8139 1.1 christos insn. 8140 1.1 christos 2) only read CFM when accessing a rotating GR, FR, or PR. mov pr only 8141 1.1 christos accesses CFM when qualifying predicate is in the rotating region. 8142 1.1 christos 3) general register value is used to specify an indirect register; not 8143 1.1 christos determinable statically. 8144 1.1 christos 4) only read the given resource when bits 7:0 of the indirect index 8145 1.1 christos register value does not match the register number of the resource; not 8146 1.1 christos determinable statically. 8147 1.1 christos 5) all rules are implementation specific. 8148 1.1 christos 6) only when both the index specified by the reader and the index specified 8149 1.1 christos by the writer have the same value in bits 63:61; not determinable 8150 1.1 christos statically. 8151 1.1 christos 7) only access the specified resource when the corresponding mask bit is 8152 1.1 christos set 8153 1.1 christos 8) PSR.dfh is only read when these insns reference FR32-127. PSR.dfl is 8154 1.1 christos only read when these insns reference FR2-31 8155 1.1 christos 9) PSR.mfl is only written when these insns write FR2-31. PSR.mfh is only 8156 1.1 christos written when these insns write FR32-127 8157 1.1 christos 10) The PSR.bn bit is only accessed when one of GR16-31 is specified in the 8158 1.1 christos instruction 8159 1.1 christos 11) The target predicates are written independently of PR[qp], but source 8160 1.1 christos registers are only read if PR[qp] is true. Since the state of PR[qp] 8161 1.1 christos cannot statically be determined, all source registers are marked used. 8162 1.1 christos 12) This insn only reads the specified predicate register when that 8163 1.1 christos register is the PR[qp]. 8164 1.1 christos 13) This reference to ld-c only applies to the GR whose value is loaded 8165 1.1 christos with data returned from memory, not the post-incremented address register. 8166 1.1 christos 14) The RSE resource includes the implementation-specific RSE internal 8167 1.1 christos state resources. At least one (and possibly more) of these resources are 8168 1.1 christos read by each instruction listed in IC:rse-readers. At least one (and 8169 1.1 christos possibly more) of these resources are written by each insn listed in 8170 1.1 christos IC:rse-writers. 8171 1.1 christos 15+16) Represents reserved instructions, which the assembler does not 8172 1.1 christos generate. 8173 1.1 christos 17) CR[TPR] has a RAW dependency only between mov-to-CR-TPR and 8174 1.1 christos mov-to-PSR-l or ssm instructions that set PSR.i, PSR.pp or PSR.up. 8175 1.1 christos 8176 1.1 christos Memory resources (i.e. locations in memory) are *not* marked or tracked by 8177 1.1 christos this code; there are no dependency violations based on memory access. 8178 1.1 christos */ 8179 1.1 christos 8180 1.1 christos #define MAX_SPECS 256 8181 1.1 christos #define DV_CHK 1 8182 1.1 christos #define DV_REG 0 8183 1.1 christos 8184 1.1 christos static int 8185 1.1 christos specify_resource (const struct ia64_dependency *dep, 8186 1.1 christos struct ia64_opcode *idesc, 8187 1.1 christos /* is this a DV chk or a DV reg? */ 8188 1.1 christos int type, 8189 1.1 christos /* returned specific resources */ 8190 1.1 christos struct rsrc specs[MAX_SPECS], 8191 1.1 christos /* resource note for this insn's usage */ 8192 1.1 christos int note, 8193 1.1 christos /* which execution path to examine */ 8194 1.1 christos int path) 8195 1.1 christos { 8196 1.1 christos int count = 0; 8197 1.1 christos int i; 8198 1.1 christos int rsrc_write = 0; 8199 1.1 christos struct rsrc tmpl; 8200 1.1 christos 8201 1.1 christos if (dep->mode == IA64_DV_WAW 8202 1.1 christos || (dep->mode == IA64_DV_RAW && type == DV_REG) 8203 1.1 christos || (dep->mode == IA64_DV_WAR && type == DV_CHK)) 8204 1.1 christos rsrc_write = 1; 8205 1.1 christos 8206 1.1 christos /* template for any resources we identify */ 8207 1.1 christos tmpl.dependency = dep; 8208 1.1 christos tmpl.note = note; 8209 1.1 christos tmpl.insn_srlz = tmpl.data_srlz = 0; 8210 1.1 christos tmpl.qp_regno = CURR_SLOT.qp_regno; 8211 1.1 christos tmpl.link_to_qp_branch = 1; 8212 1.1 christos tmpl.mem_offset.hint = 0; 8213 1.1 christos tmpl.mem_offset.offset = 0; 8214 1.1 christos tmpl.mem_offset.base = 0; 8215 1.1 christos tmpl.specific = 1; 8216 1.1 christos tmpl.index = -1; 8217 1.1 christos tmpl.cmp_type = CMP_NONE; 8218 1.1 christos tmpl.depind = 0; 8219 1.1 christos tmpl.file = NULL; 8220 1.1 christos tmpl.line = 0; 8221 1.1 christos tmpl.path = 0; 8222 1.1 christos 8223 1.1 christos #define UNHANDLED \ 8224 1.1 christos as_warn (_("Unhandled dependency %s for %s (%s), note %d"), \ 8225 1.1 christos dep->name, idesc->name, (rsrc_write?"write":"read"), note) 8226 1.1 christos #define KNOWN(REG) (gr_values[REG].known && gr_values[REG].path >= path) 8227 1.1 christos 8228 1.1 christos /* we don't need to track these */ 8229 1.1 christos if (dep->semantics == IA64_DVS_NONE) 8230 1.1 christos return 0; 8231 1.1 christos 8232 1.1 christos switch (dep->specifier) 8233 1.1 christos { 8234 1.1 christos case IA64_RS_AR_K: 8235 1.1 christos if (note == 1) 8236 1.1 christos { 8237 1.1 christos if (idesc->operands[!rsrc_write] == IA64_OPND_AR3) 8238 1.1 christos { 8239 1.1 christos int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_AR; 8240 1.1 christos if (regno >= 0 && regno <= 7) 8241 1.1 christos { 8242 1.1 christos specs[count] = tmpl; 8243 1.1 christos specs[count++].index = regno; 8244 1.1 christos } 8245 1.1 christos } 8246 1.1 christos } 8247 1.1 christos else if (note == 0) 8248 1.1 christos { 8249 1.1 christos for (i = 0; i < 8; i++) 8250 1.1 christos { 8251 1.1 christos specs[count] = tmpl; 8252 1.1 christos specs[count++].index = i; 8253 1.1 christos } 8254 1.1 christos } 8255 1.1 christos else 8256 1.1 christos { 8257 1.1 christos UNHANDLED; 8258 1.1 christos } 8259 1.1 christos break; 8260 1.1 christos 8261 1.1 christos case IA64_RS_AR_UNAT: 8262 1.1 christos /* This is a mov =AR or mov AR= instruction. */ 8263 1.1 christos if (idesc->operands[!rsrc_write] == IA64_OPND_AR3) 8264 1.1 christos { 8265 1.1 christos int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_AR; 8266 1.1 christos if (regno == AR_UNAT) 8267 1.1 christos { 8268 1.1 christos specs[count++] = tmpl; 8269 1.1 christos } 8270 1.1 christos } 8271 1.1 christos else 8272 1.1 christos { 8273 1.1 christos /* This is a spill/fill, or other instruction that modifies the 8274 1.1 christos unat register. */ 8275 1.1 christos 8276 1.1 christos /* Unless we can determine the specific bits used, mark the whole 8277 1.1 christos thing; bits 8:3 of the memory address indicate the bit used in 8278 1.1 christos UNAT. The .mem.offset hint may be used to eliminate a small 8279 1.1 christos subset of conflicts. */ 8280 1.1 christos specs[count] = tmpl; 8281 1.1 christos if (md.mem_offset.hint) 8282 1.1 christos { 8283 1.1 christos if (md.debug_dv) 8284 1.1 christos fprintf (stderr, " Using hint for spill/fill\n"); 8285 1.1 christos /* The index isn't actually used, just set it to something 8286 1.1 christos approximating the bit index. */ 8287 1.1 christos specs[count].index = (md.mem_offset.offset >> 3) & 0x3F; 8288 1.1 christos specs[count].mem_offset.hint = 1; 8289 1.1 christos specs[count].mem_offset.offset = md.mem_offset.offset; 8290 1.1 christos specs[count++].mem_offset.base = md.mem_offset.base; 8291 1.1 christos } 8292 1.1 christos else 8293 1.1 christos { 8294 1.1 christos specs[count++].specific = 0; 8295 1.1 christos } 8296 1.1 christos } 8297 1.1 christos break; 8298 1.1 christos 8299 1.1 christos case IA64_RS_AR: 8300 1.1 christos if (note == 1) 8301 1.1 christos { 8302 1.1 christos if (idesc->operands[!rsrc_write] == IA64_OPND_AR3) 8303 1.1 christos { 8304 1.1 christos int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_AR; 8305 1.1 christos if ((regno >= 8 && regno <= 15) 8306 1.1 christos || (regno >= 20 && regno <= 23) 8307 1.1 christos || (regno >= 31 && regno <= 39) 8308 1.1 christos || (regno >= 41 && regno <= 47) 8309 1.1 christos || (regno >= 67 && regno <= 111)) 8310 1.1 christos { 8311 1.1 christos specs[count] = tmpl; 8312 1.1 christos specs[count++].index = regno; 8313 1.1 christos } 8314 1.1 christos } 8315 1.1 christos } 8316 1.1 christos else 8317 1.1 christos { 8318 1.1 christos UNHANDLED; 8319 1.1 christos } 8320 1.1 christos break; 8321 1.1 christos 8322 1.1 christos case IA64_RS_ARb: 8323 1.1 christos if (note == 1) 8324 1.1 christos { 8325 1.1 christos if (idesc->operands[!rsrc_write] == IA64_OPND_AR3) 8326 1.1 christos { 8327 1.1 christos int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_AR; 8328 1.1 christos if ((regno >= 48 && regno <= 63) 8329 1.1 christos || (regno >= 112 && regno <= 127)) 8330 1.1 christos { 8331 1.1 christos specs[count] = tmpl; 8332 1.1 christos specs[count++].index = regno; 8333 1.1 christos } 8334 1.1 christos } 8335 1.1 christos } 8336 1.1 christos else if (note == 0) 8337 1.1 christos { 8338 1.1 christos for (i = 48; i < 64; i++) 8339 1.1 christos { 8340 1.1 christos specs[count] = tmpl; 8341 1.1 christos specs[count++].index = i; 8342 1.1 christos } 8343 1.1 christos for (i = 112; i < 128; i++) 8344 1.1 christos { 8345 1.1 christos specs[count] = tmpl; 8346 1.1 christos specs[count++].index = i; 8347 1.1 christos } 8348 1.1 christos } 8349 1.1 christos else 8350 1.1 christos { 8351 1.1 christos UNHANDLED; 8352 1.1 christos } 8353 1.1 christos break; 8354 1.1 christos 8355 1.1 christos case IA64_RS_BR: 8356 1.1 christos if (note != 1) 8357 1.1 christos { 8358 1.1 christos UNHANDLED; 8359 1.1 christos } 8360 1.1 christos else 8361 1.1 christos { 8362 1.1 christos if (rsrc_write) 8363 1.1 christos { 8364 1.1 christos for (i = 0; i < idesc->num_outputs; i++) 8365 1.1 christos if (idesc->operands[i] == IA64_OPND_B1 8366 1.1 christos || idesc->operands[i] == IA64_OPND_B2) 8367 1.1 christos { 8368 1.1 christos specs[count] = tmpl; 8369 1.1 christos specs[count++].index = 8370 1.1 christos CURR_SLOT.opnd[i].X_add_number - REG_BR; 8371 1.1 christos } 8372 1.1 christos } 8373 1.1 christos else 8374 1.1 christos { 8375 1.1 christos for (i = idesc->num_outputs; i < NELEMS (idesc->operands); i++) 8376 1.1 christos if (idesc->operands[i] == IA64_OPND_B1 8377 1.1 christos || idesc->operands[i] == IA64_OPND_B2) 8378 1.1 christos { 8379 1.1 christos specs[count] = tmpl; 8380 1.1 christos specs[count++].index = 8381 1.1 christos CURR_SLOT.opnd[i].X_add_number - REG_BR; 8382 1.1 christos } 8383 1.1 christos } 8384 1.1 christos } 8385 1.1 christos break; 8386 1.1 christos 8387 1.1 christos case IA64_RS_CPUID: /* four or more registers */ 8388 1.1 christos if (note == 3) 8389 1.1 christos { 8390 1.1 christos if (idesc->operands[!rsrc_write] == IA64_OPND_CPUID_R3) 8391 1.1 christos { 8392 1.1 christos int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_GR; 8393 1.1 christos if (regno >= 0 && regno < NELEMS (gr_values) 8394 1.1 christos && KNOWN (regno)) 8395 1.1 christos { 8396 1.1 christos specs[count] = tmpl; 8397 1.1 christos specs[count++].index = gr_values[regno].value & 0xFF; 8398 1.1 christos } 8399 1.1 christos else 8400 1.1 christos { 8401 1.1 christos specs[count] = tmpl; 8402 1.1 christos specs[count++].specific = 0; 8403 1.1 christos } 8404 1.1 christos } 8405 1.1 christos } 8406 1.1 christos else 8407 1.1 christos { 8408 1.1 christos UNHANDLED; 8409 1.1 christos } 8410 1.1 christos break; 8411 1.1 christos 8412 1.1 christos case IA64_RS_DBR: /* four or more registers */ 8413 1.1 christos if (note == 3) 8414 1.1 christos { 8415 1.1 christos if (idesc->operands[!rsrc_write] == IA64_OPND_DBR_R3) 8416 1.1 christos { 8417 1.1 christos int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_GR; 8418 1.1 christos if (regno >= 0 && regno < NELEMS (gr_values) 8419 1.1 christos && KNOWN (regno)) 8420 1.1 christos { 8421 1.1 christos specs[count] = tmpl; 8422 1.1 christos specs[count++].index = gr_values[regno].value & 0xFF; 8423 1.1 christos } 8424 1.1 christos else 8425 1.1 christos { 8426 1.1 christos specs[count] = tmpl; 8427 1.1 christos specs[count++].specific = 0; 8428 1.1 christos } 8429 1.1 christos } 8430 1.1 christos } 8431 1.1 christos else if (note == 0 && !rsrc_write) 8432 1.1 christos { 8433 1.1 christos specs[count] = tmpl; 8434 1.1 christos specs[count++].specific = 0; 8435 1.1 christos } 8436 1.1 christos else 8437 1.1 christos { 8438 1.1 christos UNHANDLED; 8439 1.1 christos } 8440 1.1 christos break; 8441 1.1 christos 8442 1.1 christos case IA64_RS_IBR: /* four or more registers */ 8443 1.1 christos if (note == 3) 8444 1.1 christos { 8445 1.1 christos if (idesc->operands[!rsrc_write] == IA64_OPND_IBR_R3) 8446 1.1 christos { 8447 1.1 christos int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_GR; 8448 1.1 christos if (regno >= 0 && regno < NELEMS (gr_values) 8449 1.1 christos && KNOWN (regno)) 8450 1.1 christos { 8451 1.1 christos specs[count] = tmpl; 8452 1.1 christos specs[count++].index = gr_values[regno].value & 0xFF; 8453 1.1 christos } 8454 1.1 christos else 8455 1.1 christos { 8456 1.1 christos specs[count] = tmpl; 8457 1.1 christos specs[count++].specific = 0; 8458 1.1 christos } 8459 1.1 christos } 8460 1.1 christos } 8461 1.1 christos else 8462 1.1 christos { 8463 1.1 christos UNHANDLED; 8464 1.1 christos } 8465 1.1 christos break; 8466 1.1 christos 8467 1.1 christos case IA64_RS_MSR: 8468 1.1 christos if (note == 5) 8469 1.1 christos { 8470 1.1 christos /* These are implementation specific. Force all references to 8471 1.1 christos conflict with all other references. */ 8472 1.1 christos specs[count] = tmpl; 8473 1.1 christos specs[count++].specific = 0; 8474 1.1 christos } 8475 1.1 christos else 8476 1.1 christos { 8477 1.1 christos UNHANDLED; 8478 1.1 christos } 8479 1.1 christos break; 8480 1.1 christos 8481 1.1 christos case IA64_RS_PKR: /* 16 or more registers */ 8482 1.1 christos if (note == 3 || note == 4) 8483 1.1 christos { 8484 1.1 christos if (idesc->operands[!rsrc_write] == IA64_OPND_PKR_R3) 8485 1.1 christos { 8486 1.1 christos int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_GR; 8487 1.1 christos if (regno >= 0 && regno < NELEMS (gr_values) 8488 1.1 christos && KNOWN (regno)) 8489 1.1 christos { 8490 1.1 christos if (note == 3) 8491 1.1 christos { 8492 1.1 christos specs[count] = tmpl; 8493 1.1 christos specs[count++].index = gr_values[regno].value & 0xFF; 8494 1.1 christos } 8495 1.1 christos else 8496 1.1 christos for (i = 0; i < NELEMS (gr_values); i++) 8497 1.1 christos { 8498 1.1 christos /* Uses all registers *except* the one in R3. */ 8499 1.1 christos if ((unsigned)i != (gr_values[regno].value & 0xFF)) 8500 1.1 christos { 8501 1.1 christos specs[count] = tmpl; 8502 1.1 christos specs[count++].index = i; 8503 1.1 christos } 8504 1.1 christos } 8505 1.1 christos } 8506 1.1 christos else 8507 1.1 christos { 8508 1.1 christos specs[count] = tmpl; 8509 1.1 christos specs[count++].specific = 0; 8510 1.1 christos } 8511 1.1 christos } 8512 1.1 christos } 8513 1.1 christos else if (note == 0) 8514 1.1 christos { 8515 1.1 christos /* probe et al. */ 8516 1.1 christos specs[count] = tmpl; 8517 1.1 christos specs[count++].specific = 0; 8518 1.1 christos } 8519 1.1 christos break; 8520 1.1 christos 8521 1.1 christos case IA64_RS_PMC: /* four or more registers */ 8522 1.1 christos if (note == 3) 8523 1.1 christos { 8524 1.1 christos if (idesc->operands[!rsrc_write] == IA64_OPND_PMC_R3 8525 1.1 christos || (!rsrc_write && idesc->operands[1] == IA64_OPND_PMD_R3)) 8526 1.1 christos 8527 1.1 christos { 8528 1.1 christos int reg_index = ((idesc->operands[1] == IA64_OPND_R3 && !rsrc_write) 8529 1.1 christos ? 1 : !rsrc_write); 8530 1.1 christos int regno = CURR_SLOT.opnd[reg_index].X_add_number - REG_GR; 8531 1.1 christos if (regno >= 0 && regno < NELEMS (gr_values) 8532 1.1 christos && KNOWN (regno)) 8533 1.1 christos { 8534 1.1 christos specs[count] = tmpl; 8535 1.1 christos specs[count++].index = gr_values[regno].value & 0xFF; 8536 1.1 christos } 8537 1.1 christos else 8538 1.1 christos { 8539 1.1 christos specs[count] = tmpl; 8540 1.1 christos specs[count++].specific = 0; 8541 1.1 christos } 8542 1.1 christos } 8543 1.1 christos } 8544 1.1 christos else 8545 1.1 christos { 8546 1.1 christos UNHANDLED; 8547 1.1 christos } 8548 1.1 christos break; 8549 1.1 christos 8550 1.1 christos case IA64_RS_PMD: /* four or more registers */ 8551 1.1 christos if (note == 3) 8552 1.1 christos { 8553 1.1 christos if (idesc->operands[!rsrc_write] == IA64_OPND_PMD_R3) 8554 1.1 christos { 8555 1.1 christos int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_GR; 8556 1.1 christos if (regno >= 0 && regno < NELEMS (gr_values) 8557 1.1 christos && KNOWN (regno)) 8558 1.1 christos { 8559 1.1 christos specs[count] = tmpl; 8560 1.1 christos specs[count++].index = gr_values[regno].value & 0xFF; 8561 1.1 christos } 8562 1.1 christos else 8563 1.1 christos { 8564 1.1 christos specs[count] = tmpl; 8565 1.1 christos specs[count++].specific = 0; 8566 1.1 christos } 8567 1.1 christos } 8568 1.1 christos } 8569 1.1 christos else 8570 1.1 christos { 8571 1.1 christos UNHANDLED; 8572 1.1 christos } 8573 1.1 christos break; 8574 1.1 christos 8575 1.1 christos case IA64_RS_RR: /* eight registers */ 8576 1.1 christos if (note == 6) 8577 1.1 christos { 8578 1.1 christos if (idesc->operands[!rsrc_write] == IA64_OPND_RR_R3) 8579 1.1 christos { 8580 1.1 christos int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_GR; 8581 1.1 christos if (regno >= 0 && regno < NELEMS (gr_values) 8582 1.1 christos && KNOWN (regno)) 8583 1.1 christos { 8584 1.1 christos specs[count] = tmpl; 8585 1.1 christos specs[count++].index = (gr_values[regno].value >> 61) & 0x7; 8586 1.1 christos } 8587 1.1 christos else 8588 1.1 christos { 8589 1.1 christos specs[count] = tmpl; 8590 1.1 christos specs[count++].specific = 0; 8591 1.1 christos } 8592 1.1 christos } 8593 1.1 christos } 8594 1.1 christos else if (note == 0 && !rsrc_write) 8595 1.1 christos { 8596 1.1 christos specs[count] = tmpl; 8597 1.1 christos specs[count++].specific = 0; 8598 1.1 christos } 8599 1.1 christos else 8600 1.1 christos { 8601 1.1 christos UNHANDLED; 8602 1.1 christos } 8603 1.1 christos break; 8604 1.1 christos 8605 1.1 christos case IA64_RS_CR_IRR: 8606 1.1 christos if (note == 0) 8607 1.1 christos { 8608 1.1 christos /* handle mov-from-CR-IVR; it's a read that writes CR[IRR] */ 8609 1.1 christos int regno = CURR_SLOT.opnd[1].X_add_number - REG_CR; 8610 1.1 christos if (rsrc_write 8611 1.1 christos && idesc->operands[1] == IA64_OPND_CR3 8612 1.1 christos && regno == CR_IVR) 8613 1.1 christos { 8614 1.1 christos for (i = 0; i < 4; i++) 8615 1.1 christos { 8616 1.1 christos specs[count] = tmpl; 8617 1.1 christos specs[count++].index = CR_IRR0 + i; 8618 1.1 christos } 8619 1.1 christos } 8620 1.1 christos } 8621 1.1 christos else if (note == 1) 8622 1.1 christos { 8623 1.1 christos int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_CR; 8624 1.1 christos if (idesc->operands[!rsrc_write] == IA64_OPND_CR3 8625 1.1 christos && regno >= CR_IRR0 8626 1.1 christos && regno <= CR_IRR3) 8627 1.1 christos { 8628 1.1 christos specs[count] = tmpl; 8629 1.1 christos specs[count++].index = regno; 8630 1.1 christos } 8631 1.1 christos } 8632 1.1 christos else 8633 1.1 christos { 8634 1.1 christos UNHANDLED; 8635 1.1 christos } 8636 1.1 christos break; 8637 1.1 christos 8638 1.1 christos case IA64_RS_CR_IIB: 8639 1.1 christos if (note != 0) 8640 1.1 christos { 8641 1.1 christos UNHANDLED; 8642 1.1 christos } 8643 1.1 christos else 8644 1.1 christos { 8645 1.1 christos int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_CR; 8646 1.1 christos if (idesc->operands[!rsrc_write] == IA64_OPND_CR3 8647 1.1 christos && (regno == CR_IIB0 || regno == CR_IIB1)) 8648 1.1 christos { 8649 1.1 christos specs[count] = tmpl; 8650 1.1 christos specs[count++].index = regno; 8651 1.1 christos } 8652 1.1 christos } 8653 1.1 christos break; 8654 1.1 christos 8655 1.1 christos case IA64_RS_CR_LRR: 8656 1.1 christos if (note != 1) 8657 1.1 christos { 8658 1.1 christos UNHANDLED; 8659 1.1 christos } 8660 1.1 christos else 8661 1.1 christos { 8662 1.1 christos int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_CR; 8663 1.1 christos if (idesc->operands[!rsrc_write] == IA64_OPND_CR3 8664 1.1 christos && (regno == CR_LRR0 || regno == CR_LRR1)) 8665 1.1 christos { 8666 1.1 christos specs[count] = tmpl; 8667 1.1 christos specs[count++].index = regno; 8668 1.1 christos } 8669 1.1 christos } 8670 1.1 christos break; 8671 1.1 christos 8672 1.1 christos case IA64_RS_CR: 8673 1.1 christos if (note == 1) 8674 1.1 christos { 8675 1.1 christos if (idesc->operands[!rsrc_write] == IA64_OPND_CR3) 8676 1.1 christos { 8677 1.1 christos specs[count] = tmpl; 8678 1.1 christos specs[count++].index = 8679 1.1 christos CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_CR; 8680 1.1 christos } 8681 1.1 christos } 8682 1.1 christos else 8683 1.1 christos { 8684 1.1 christos UNHANDLED; 8685 1.1 christos } 8686 1.1 christos break; 8687 1.1 christos 8688 1.1 christos case IA64_RS_DAHR: 8689 1.1 christos if (note == 0) 8690 1.1 christos { 8691 1.1 christos if (idesc->operands[!rsrc_write] == IA64_OPND_DAHR3) 8692 1.1 christos { 8693 1.1 christos specs[count] = tmpl; 8694 1.1 christos specs[count++].index = 8695 1.1 christos CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_DAHR; 8696 1.1 christos } 8697 1.1 christos } 8698 1.1 christos else 8699 1.1 christos { 8700 1.1 christos UNHANDLED; 8701 1.1 christos } 8702 1.1 christos break; 8703 1.1 christos 8704 1.1 christos case IA64_RS_FR: 8705 1.1 christos case IA64_RS_FRb: 8706 1.1 christos if (note != 1) 8707 1.1 christos { 8708 1.1 christos UNHANDLED; 8709 1.1 christos } 8710 1.1 christos else if (rsrc_write) 8711 1.1 christos { 8712 1.1 christos if (dep->specifier == IA64_RS_FRb 8713 1.1 christos && idesc->operands[0] == IA64_OPND_F1) 8714 1.1 christos { 8715 1.1 christos specs[count] = tmpl; 8716 1.1 christos specs[count++].index = CURR_SLOT.opnd[0].X_add_number - REG_FR; 8717 1.1 christos } 8718 1.1 christos } 8719 1.1 christos else 8720 1.1 christos { 8721 1.1 christos for (i = idesc->num_outputs; i < NELEMS (idesc->operands); i++) 8722 1.1 christos { 8723 1.1 christos if (idesc->operands[i] == IA64_OPND_F2 8724 1.1 christos || idesc->operands[i] == IA64_OPND_F3 8725 1.1 christos || idesc->operands[i] == IA64_OPND_F4) 8726 1.1 christos { 8727 1.1 christos specs[count] = tmpl; 8728 1.1 christos specs[count++].index = 8729 1.1 christos CURR_SLOT.opnd[i].X_add_number - REG_FR; 8730 1.1 christos } 8731 1.1 christos } 8732 1.1 christos } 8733 1.1 christos break; 8734 1.1 christos 8735 1.1 christos case IA64_RS_GR: 8736 1.1 christos if (note == 13) 8737 1.1 christos { 8738 1.1 christos /* This reference applies only to the GR whose value is loaded with 8739 1.1 christos data returned from memory. */ 8740 1.1 christos specs[count] = tmpl; 8741 1.1 christos specs[count++].index = CURR_SLOT.opnd[0].X_add_number - REG_GR; 8742 1.1 christos } 8743 1.1 christos else if (note == 1) 8744 1.1 christos { 8745 1.1 christos if (rsrc_write) 8746 1.1 christos { 8747 1.1 christos for (i = 0; i < idesc->num_outputs; i++) 8748 1.1 christos if (idesc->operands[i] == IA64_OPND_R1 8749 1.1 christos || idesc->operands[i] == IA64_OPND_R2 8750 1.1 christos || idesc->operands[i] == IA64_OPND_R3) 8751 1.1 christos { 8752 1.1 christos specs[count] = tmpl; 8753 1.1 christos specs[count++].index = 8754 1.1 christos CURR_SLOT.opnd[i].X_add_number - REG_GR; 8755 1.1 christos } 8756 1.1 christos if (idesc->flags & IA64_OPCODE_POSTINC) 8757 1.1 christos for (i = 0; i < NELEMS (idesc->operands); i++) 8758 1.1 christos if (idesc->operands[i] == IA64_OPND_MR3) 8759 1.1 christos { 8760 1.1 christos specs[count] = tmpl; 8761 1.1 christos specs[count++].index = 8762 1.1 christos CURR_SLOT.opnd[i].X_add_number - REG_GR; 8763 1.1 christos } 8764 1.1 christos } 8765 1.1 christos else 8766 1.1 christos { 8767 1.1 christos /* Look for anything that reads a GR. */ 8768 1.1 christos for (i = 0; i < NELEMS (idesc->operands); i++) 8769 1.1 christos { 8770 1.1 christos if (idesc->operands[i] == IA64_OPND_MR3 8771 1.1 christos || idesc->operands[i] == IA64_OPND_CPUID_R3 8772 1.1 christos || idesc->operands[i] == IA64_OPND_DBR_R3 8773 1.1 christos || idesc->operands[i] == IA64_OPND_IBR_R3 8774 1.1 christos || idesc->operands[i] == IA64_OPND_MSR_R3 8775 1.1 christos || idesc->operands[i] == IA64_OPND_PKR_R3 8776 1.1 christos || idesc->operands[i] == IA64_OPND_PMC_R3 8777 1.1 christos || idesc->operands[i] == IA64_OPND_PMD_R3 8778 1.1 christos || idesc->operands[i] == IA64_OPND_DAHR_R3 8779 1.1 christos || idesc->operands[i] == IA64_OPND_RR_R3 8780 1.1 christos || ((i >= idesc->num_outputs) 8781 1.1 christos && (idesc->operands[i] == IA64_OPND_R1 8782 1.1 christos || idesc->operands[i] == IA64_OPND_R2 8783 1.1 christos || idesc->operands[i] == IA64_OPND_R3 8784 1.1 christos /* addl source register. */ 8785 1.1 christos || idesc->operands[i] == IA64_OPND_R3_2))) 8786 1.1 christos { 8787 1.1 christos specs[count] = tmpl; 8788 1.1 christos specs[count++].index = 8789 1.1 christos CURR_SLOT.opnd[i].X_add_number - REG_GR; 8790 1.1 christos } 8791 1.1 christos } 8792 1.1 christos } 8793 1.1 christos } 8794 1.1 christos else 8795 1.1 christos { 8796 1.1 christos UNHANDLED; 8797 1.1 christos } 8798 1.1 christos break; 8799 1.1 christos 8800 1.1 christos /* This is the same as IA64_RS_PRr, except that the register range is 8801 1.1 christos from 1 - 15, and there are no rotating register reads/writes here. */ 8802 1.1 christos case IA64_RS_PR: 8803 1.1 christos if (note == 0) 8804 1.1 christos { 8805 1.1 christos for (i = 1; i < 16; i++) 8806 1.1 christos { 8807 1.1 christos specs[count] = tmpl; 8808 1.1 christos specs[count++].index = i; 8809 1.1 christos } 8810 1.1 christos } 8811 1.1 christos else if (note == 7) 8812 1.1 christos { 8813 1.1 christos valueT mask = 0; 8814 1.1 christos /* Mark only those registers indicated by the mask. */ 8815 1.1 christos if (rsrc_write) 8816 1.1 christos { 8817 1.1 christos mask = CURR_SLOT.opnd[2].X_add_number; 8818 1.1 christos for (i = 1; i < 16; i++) 8819 1.1 christos if (mask & ((valueT) 1 << i)) 8820 1.1 christos { 8821 1.1 christos specs[count] = tmpl; 8822 1.1 christos specs[count++].index = i; 8823 1.1 christos } 8824 1.1 christos } 8825 1.1 christos else 8826 1.1 christos { 8827 1.1 christos UNHANDLED; 8828 1.1 christos } 8829 1.1 christos } 8830 1.1 christos else if (note == 11) /* note 11 implies note 1 as well */ 8831 1.1 christos { 8832 1.1 christos if (rsrc_write) 8833 1.1 christos { 8834 1.1 christos for (i = 0; i < idesc->num_outputs; i++) 8835 1.1 christos { 8836 1.1 christos if (idesc->operands[i] == IA64_OPND_P1 8837 1.1 christos || idesc->operands[i] == IA64_OPND_P2) 8838 1.1 christos { 8839 1.1 christos int regno = CURR_SLOT.opnd[i].X_add_number - REG_P; 8840 1.1 christos if (regno >= 1 && regno < 16) 8841 1.1 christos { 8842 1.1 christos specs[count] = tmpl; 8843 1.1 christos specs[count++].index = regno; 8844 1.1 christos } 8845 1.1 christos } 8846 1.1 christos } 8847 1.1 christos } 8848 1.1 christos else 8849 1.1 christos { 8850 1.1 christos UNHANDLED; 8851 1.1 christos } 8852 1.1 christos } 8853 1.1 christos else if (note == 12) 8854 1.1 christos { 8855 1.1 christos if (CURR_SLOT.qp_regno >= 1 && CURR_SLOT.qp_regno < 16) 8856 1.1 christos { 8857 1.1 christos specs[count] = tmpl; 8858 1.1 christos specs[count++].index = CURR_SLOT.qp_regno; 8859 1.1 christos } 8860 1.1 christos } 8861 1.1 christos else if (note == 1) 8862 1.1 christos { 8863 1.1 christos if (rsrc_write) 8864 1.1 christos { 8865 1.1 christos int p1 = CURR_SLOT.opnd[0].X_add_number - REG_P; 8866 1.1 christos int p2 = CURR_SLOT.opnd[1].X_add_number - REG_P; 8867 1.1 christos int or_andcm = strstr (idesc->name, "or.andcm") != NULL; 8868 1.1 christos int and_orcm = strstr (idesc->name, "and.orcm") != NULL; 8869 1.1 christos 8870 1.1 christos if ((idesc->operands[0] == IA64_OPND_P1 8871 1.1 christos || idesc->operands[0] == IA64_OPND_P2) 8872 1.1 christos && p1 >= 1 && p1 < 16) 8873 1.1 christos { 8874 1.1 christos specs[count] = tmpl; 8875 1.1 christos specs[count].cmp_type = 8876 1.1 christos (or_andcm ? CMP_OR : (and_orcm ? CMP_AND : CMP_NONE)); 8877 1.1 christos specs[count++].index = p1; 8878 1.1 christos } 8879 1.1 christos if ((idesc->operands[1] == IA64_OPND_P1 8880 1.1 christos || idesc->operands[1] == IA64_OPND_P2) 8881 1.1 christos && p2 >= 1 && p2 < 16) 8882 1.1 christos { 8883 1.1 christos specs[count] = tmpl; 8884 1.1 christos specs[count].cmp_type = 8885 1.1 christos (or_andcm ? CMP_AND : (and_orcm ? CMP_OR : CMP_NONE)); 8886 1.1 christos specs[count++].index = p2; 8887 1.1 christos } 8888 1.1 christos } 8889 1.1 christos else 8890 1.1 christos { 8891 1.1 christos if (CURR_SLOT.qp_regno >= 1 && CURR_SLOT.qp_regno < 16) 8892 1.1 christos { 8893 1.1 christos specs[count] = tmpl; 8894 1.1 christos specs[count++].index = CURR_SLOT.qp_regno; 8895 1.1 christos } 8896 1.1 christos if (idesc->operands[1] == IA64_OPND_PR) 8897 1.1 christos { 8898 1.1 christos for (i = 1; i < 16; i++) 8899 1.1 christos { 8900 1.1 christos specs[count] = tmpl; 8901 1.1 christos specs[count++].index = i; 8902 1.1 christos } 8903 1.1 christos } 8904 1.1 christos } 8905 1.1 christos } 8906 1.1 christos else 8907 1.1 christos { 8908 1.1 christos UNHANDLED; 8909 1.1 christos } 8910 1.1 christos break; 8911 1.1 christos 8912 1.1 christos /* This is the general case for PRs. IA64_RS_PR and IA64_RS_PR63 are 8913 1.1 christos simplified cases of this. */ 8914 1.1 christos case IA64_RS_PRr: 8915 1.1 christos if (note == 0) 8916 1.1 christos { 8917 1.1 christos for (i = 16; i < 63; i++) 8918 1.1 christos { 8919 1.1 christos specs[count] = tmpl; 8920 1.1 christos specs[count++].index = i; 8921 1.1 christos } 8922 1.1 christos } 8923 1.1 christos else if (note == 7) 8924 1.1 christos { 8925 1.1 christos valueT mask = 0; 8926 1.1 christos /* Mark only those registers indicated by the mask. */ 8927 1.1 christos if (rsrc_write 8928 1.1 christos && idesc->operands[0] == IA64_OPND_PR) 8929 1.1 christos { 8930 1.1 christos mask = CURR_SLOT.opnd[2].X_add_number; 8931 1.1 christos if (mask & ((valueT) 1 << 16)) 8932 1.1 christos for (i = 16; i < 63; i++) 8933 1.1 christos { 8934 1.1 christos specs[count] = tmpl; 8935 1.1 christos specs[count++].index = i; 8936 1.1 christos } 8937 1.1 christos } 8938 1.1 christos else if (rsrc_write 8939 1.1 christos && idesc->operands[0] == IA64_OPND_PR_ROT) 8940 1.1 christos { 8941 1.1 christos for (i = 16; i < 63; i++) 8942 1.1 christos { 8943 1.1 christos specs[count] = tmpl; 8944 1.1 christos specs[count++].index = i; 8945 1.1 christos } 8946 1.1 christos } 8947 1.1 christos else 8948 1.1 christos { 8949 1.1 christos UNHANDLED; 8950 1.1 christos } 8951 1.1 christos } 8952 1.1 christos else if (note == 11) /* note 11 implies note 1 as well */ 8953 1.1 christos { 8954 1.1 christos if (rsrc_write) 8955 1.1 christos { 8956 1.1 christos for (i = 0; i < idesc->num_outputs; i++) 8957 1.1 christos { 8958 1.1 christos if (idesc->operands[i] == IA64_OPND_P1 8959 1.1 christos || idesc->operands[i] == IA64_OPND_P2) 8960 1.1 christos { 8961 1.1 christos int regno = CURR_SLOT.opnd[i].X_add_number - REG_P; 8962 1.1 christos if (regno >= 16 && regno < 63) 8963 1.1 christos { 8964 1.1 christos specs[count] = tmpl; 8965 1.1 christos specs[count++].index = regno; 8966 1.1 christos } 8967 1.1 christos } 8968 1.1 christos } 8969 1.1 christos } 8970 1.1 christos else 8971 1.1 christos { 8972 1.1 christos UNHANDLED; 8973 1.1 christos } 8974 1.1 christos } 8975 1.1 christos else if (note == 12) 8976 1.1 christos { 8977 1.1 christos if (CURR_SLOT.qp_regno >= 16 && CURR_SLOT.qp_regno < 63) 8978 1.1 christos { 8979 1.1 christos specs[count] = tmpl; 8980 1.1 christos specs[count++].index = CURR_SLOT.qp_regno; 8981 1.1 christos } 8982 1.1 christos } 8983 1.1 christos else if (note == 1) 8984 1.1 christos { 8985 1.1 christos if (rsrc_write) 8986 1.1 christos { 8987 1.1 christos int p1 = CURR_SLOT.opnd[0].X_add_number - REG_P; 8988 1.1 christos int p2 = CURR_SLOT.opnd[1].X_add_number - REG_P; 8989 1.1 christos int or_andcm = strstr (idesc->name, "or.andcm") != NULL; 8990 1.1 christos int and_orcm = strstr (idesc->name, "and.orcm") != NULL; 8991 1.1 christos 8992 1.1 christos if ((idesc->operands[0] == IA64_OPND_P1 8993 1.1 christos || idesc->operands[0] == IA64_OPND_P2) 8994 1.1 christos && p1 >= 16 && p1 < 63) 8995 1.1 christos { 8996 1.1 christos specs[count] = tmpl; 8997 1.1 christos specs[count].cmp_type = 8998 1.1 christos (or_andcm ? CMP_OR : (and_orcm ? CMP_AND : CMP_NONE)); 8999 1.1 christos specs[count++].index = p1; 9000 1.1 christos } 9001 1.1 christos if ((idesc->operands[1] == IA64_OPND_P1 9002 1.1 christos || idesc->operands[1] == IA64_OPND_P2) 9003 1.1 christos && p2 >= 16 && p2 < 63) 9004 1.1 christos { 9005 1.1 christos specs[count] = tmpl; 9006 1.1 christos specs[count].cmp_type = 9007 1.1 christos (or_andcm ? CMP_AND : (and_orcm ? CMP_OR : CMP_NONE)); 9008 1.1 christos specs[count++].index = p2; 9009 1.1 christos } 9010 1.1 christos } 9011 1.1 christos else 9012 1.1 christos { 9013 1.1 christos if (CURR_SLOT.qp_regno >= 16 && CURR_SLOT.qp_regno < 63) 9014 1.1 christos { 9015 1.1 christos specs[count] = tmpl; 9016 1.1 christos specs[count++].index = CURR_SLOT.qp_regno; 9017 1.1 christos } 9018 1.1 christos if (idesc->operands[1] == IA64_OPND_PR) 9019 1.1 christos { 9020 1.1 christos for (i = 16; i < 63; i++) 9021 1.1 christos { 9022 1.1 christos specs[count] = tmpl; 9023 1.1 christos specs[count++].index = i; 9024 1.1 christos } 9025 1.1 christos } 9026 1.1 christos } 9027 1.1 christos } 9028 1.1 christos else 9029 1.1 christos { 9030 1.1 christos UNHANDLED; 9031 1.1 christos } 9032 1.1 christos break; 9033 1.1 christos 9034 1.1 christos case IA64_RS_PSR: 9035 1.1 christos /* Verify that the instruction is using the PSR bit indicated in 9036 1.1 christos dep->regindex. */ 9037 1.1 christos if (note == 0) 9038 1.1 christos { 9039 1.1 christos if (idesc->operands[!rsrc_write] == IA64_OPND_PSR_UM) 9040 1.1 christos { 9041 1.1 christos if (dep->regindex < 6) 9042 1.1 christos { 9043 1.1 christos specs[count++] = tmpl; 9044 1.1 christos } 9045 1.1 christos } 9046 1.1 christos else if (idesc->operands[!rsrc_write] == IA64_OPND_PSR) 9047 1.1 christos { 9048 1.1 christos if (dep->regindex < 32 9049 1.1 christos || dep->regindex == 35 9050 1.1 christos || dep->regindex == 36 9051 1.1 christos || (!rsrc_write && dep->regindex == PSR_CPL)) 9052 1.1 christos { 9053 1.1 christos specs[count++] = tmpl; 9054 1.1 christos } 9055 1.1 christos } 9056 1.1 christos else if (idesc->operands[!rsrc_write] == IA64_OPND_PSR_L) 9057 1.1 christos { 9058 1.1 christos if (dep->regindex < 32 9059 1.1 christos || dep->regindex == 35 9060 1.1 christos || dep->regindex == 36 9061 1.1 christos || (rsrc_write && dep->regindex == PSR_CPL)) 9062 1.1 christos { 9063 1.1 christos specs[count++] = tmpl; 9064 1.1 christos } 9065 1.1 christos } 9066 1.1 christos else 9067 1.1 christos { 9068 1.1 christos /* Several PSR bits have very specific dependencies. */ 9069 1.1 christos switch (dep->regindex) 9070 1.1 christos { 9071 1.1 christos default: 9072 1.1 christos specs[count++] = tmpl; 9073 1.1 christos break; 9074 1.1 christos case PSR_IC: 9075 1.1 christos if (rsrc_write) 9076 1.1 christos { 9077 1.1 christos specs[count++] = tmpl; 9078 1.1 christos } 9079 1.1 christos else 9080 1.1 christos { 9081 1.1 christos /* Only certain CR accesses use PSR.ic */ 9082 1.1 christos if (idesc->operands[0] == IA64_OPND_CR3 9083 1.1 christos || idesc->operands[1] == IA64_OPND_CR3) 9084 1.1 christos { 9085 1.1 christos int reg_index = 9086 1.1 christos ((idesc->operands[0] == IA64_OPND_CR3) 9087 1.1 christos ? 0 : 1); 9088 1.1 christos int regno = 9089 1.1 christos CURR_SLOT.opnd[reg_index].X_add_number - REG_CR; 9090 1.1 christos 9091 1.1 christos switch (regno) 9092 1.1 christos { 9093 1.1 christos default: 9094 1.1 christos break; 9095 1.1 christos case CR_ITIR: 9096 1.1 christos case CR_IFS: 9097 1.1 christos case CR_IIM: 9098 1.1 christos case CR_IIP: 9099 1.1 christos case CR_IPSR: 9100 1.1 christos case CR_ISR: 9101 1.1 christos case CR_IFA: 9102 1.1 christos case CR_IHA: 9103 1.1 christos case CR_IIB0: 9104 1.1 christos case CR_IIB1: 9105 1.1 christos case CR_IIPA: 9106 1.1 christos specs[count++] = tmpl; 9107 1.1 christos break; 9108 1.1 christos } 9109 1.1 christos } 9110 1.1 christos } 9111 1.1 christos break; 9112 1.1 christos case PSR_CPL: 9113 1.1 christos if (rsrc_write) 9114 1.1 christos { 9115 1.1 christos specs[count++] = tmpl; 9116 1.1 christos } 9117 1.1 christos else 9118 1.1 christos { 9119 1.1 christos /* Only some AR accesses use cpl */ 9120 1.1 christos if (idesc->operands[0] == IA64_OPND_AR3 9121 1.1 christos || idesc->operands[1] == IA64_OPND_AR3) 9122 1.1 christos { 9123 1.1 christos int reg_index = 9124 1.1 christos ((idesc->operands[0] == IA64_OPND_AR3) 9125 1.1 christos ? 0 : 1); 9126 1.1 christos int regno = 9127 1.1 christos CURR_SLOT.opnd[reg_index].X_add_number - REG_AR; 9128 1.1 christos 9129 1.1 christos if (regno == AR_ITC 9130 1.1 christos || regno == AR_RUC 9131 1.1 christos || (reg_index == 0 9132 1.1 christos && (regno == AR_RSC 9133 1.1 christos || (regno >= AR_K0 9134 1.1 christos && regno <= AR_K7)))) 9135 1.1 christos { 9136 1.1 christos specs[count++] = tmpl; 9137 1.1 christos } 9138 1.1 christos } 9139 1.1 christos else 9140 1.1 christos { 9141 1.1 christos specs[count++] = tmpl; 9142 1.1 christos } 9143 1.1 christos break; 9144 1.1 christos } 9145 1.1 christos } 9146 1.1 christos } 9147 1.1 christos } 9148 1.1 christos else if (note == 7) 9149 1.1 christos { 9150 1.1 christos valueT mask = 0; 9151 1.1 christos if (idesc->operands[0] == IA64_OPND_IMMU24) 9152 1.1 christos { 9153 1.1 christos mask = CURR_SLOT.opnd[0].X_add_number; 9154 1.1 christos } 9155 1.1 christos else 9156 1.1 christos { 9157 1.1 christos UNHANDLED; 9158 1.1 christos } 9159 1.1 christos if (mask & ((valueT) 1 << dep->regindex)) 9160 1.1 christos { 9161 1.1 christos specs[count++] = tmpl; 9162 1.1 christos } 9163 1.1 christos } 9164 1.1 christos else if (note == 8) 9165 1.1 christos { 9166 1.1 christos int min = dep->regindex == PSR_DFL ? 2 : 32; 9167 1.1 christos int max = dep->regindex == PSR_DFL ? 31 : 127; 9168 1.1 christos /* dfh is read on FR32-127; dfl is read on FR2-31 */ 9169 1.1 christos for (i = 0; i < NELEMS (idesc->operands); i++) 9170 1.1 christos { 9171 1.1 christos if (idesc->operands[i] == IA64_OPND_F1 9172 1.1 christos || idesc->operands[i] == IA64_OPND_F2 9173 1.1 christos || idesc->operands[i] == IA64_OPND_F3 9174 1.1 christos || idesc->operands[i] == IA64_OPND_F4) 9175 1.1 christos { 9176 1.1 christos int reg = CURR_SLOT.opnd[i].X_add_number - REG_FR; 9177 1.1 christos if (reg >= min && reg <= max) 9178 1.1 christos { 9179 1.1 christos specs[count++] = tmpl; 9180 1.1 christos } 9181 1.1 christos } 9182 1.1 christos } 9183 1.1 christos } 9184 1.1 christos else if (note == 9) 9185 1.1 christos { 9186 1.1 christos int min = dep->regindex == PSR_MFL ? 2 : 32; 9187 1.1 christos int max = dep->regindex == PSR_MFL ? 31 : 127; 9188 1.1 christos /* mfh is read on writes to FR32-127; mfl is read on writes to 9189 1.1 christos FR2-31 */ 9190 1.1 christos for (i = 0; i < idesc->num_outputs; i++) 9191 1.1 christos { 9192 1.1 christos if (idesc->operands[i] == IA64_OPND_F1) 9193 1.1 christos { 9194 1.1 christos int reg = CURR_SLOT.opnd[i].X_add_number - REG_FR; 9195 1.1 christos if (reg >= min && reg <= max) 9196 1.1 christos { 9197 1.1 christos specs[count++] = tmpl; 9198 1.1 christos } 9199 1.1 christos } 9200 1.1 christos } 9201 1.1 christos } 9202 1.1 christos else if (note == 10) 9203 1.1 christos { 9204 1.1 christos for (i = 0; i < NELEMS (idesc->operands); i++) 9205 1.1 christos { 9206 1.1 christos if (idesc->operands[i] == IA64_OPND_R1 9207 1.1 christos || idesc->operands[i] == IA64_OPND_R2 9208 1.1 christos || idesc->operands[i] == IA64_OPND_R3) 9209 1.1 christos { 9210 1.1 christos int regno = CURR_SLOT.opnd[i].X_add_number - REG_GR; 9211 1.1 christos if (regno >= 16 && regno <= 31) 9212 1.1 christos { 9213 1.1 christos specs[count++] = tmpl; 9214 1.1 christos } 9215 1.1 christos } 9216 1.1 christos } 9217 1.1 christos } 9218 1.1 christos else 9219 1.1 christos { 9220 1.1 christos UNHANDLED; 9221 1.1 christos } 9222 1.1 christos break; 9223 1.1 christos 9224 1.1 christos case IA64_RS_AR_FPSR: 9225 1.1 christos if (idesc->operands[!rsrc_write] == IA64_OPND_AR3) 9226 1.1 christos { 9227 1.1 christos int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_AR; 9228 1.1 christos if (regno == AR_FPSR) 9229 1.1 christos { 9230 1.1 christos specs[count++] = tmpl; 9231 1.1 christos } 9232 1.1 christos } 9233 1.1 christos else 9234 1.1 christos { 9235 1.1 christos specs[count++] = tmpl; 9236 1.1 christos } 9237 1.1 christos break; 9238 1.1 christos 9239 1.1 christos case IA64_RS_ARX: 9240 1.1 christos /* Handle all AR[REG] resources */ 9241 1.1 christos if (note == 0 || note == 1) 9242 1.1 christos { 9243 1.1 christos int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_AR; 9244 1.1 christos if (idesc->operands[!rsrc_write] == IA64_OPND_AR3 9245 1.1 christos && regno == dep->regindex) 9246 1.1 christos { 9247 1.1 christos specs[count++] = tmpl; 9248 1.1 christos } 9249 1.1 christos /* other AR[REG] resources may be affected by AR accesses */ 9250 1.1 christos else if (idesc->operands[0] == IA64_OPND_AR3) 9251 1.1 christos { 9252 1.1 christos /* AR[] writes */ 9253 1.1 christos regno = CURR_SLOT.opnd[0].X_add_number - REG_AR; 9254 1.1 christos switch (dep->regindex) 9255 1.1 christos { 9256 1.1 christos default: 9257 1.1 christos break; 9258 1.1 christos case AR_BSP: 9259 1.1 christos case AR_RNAT: 9260 1.1 christos if (regno == AR_BSPSTORE) 9261 1.1 christos { 9262 1.1 christos specs[count++] = tmpl; 9263 1.1 christos } 9264 1.6 christos /* Fall through. */ 9265 1.1 christos case AR_RSC: 9266 1.1 christos if (!rsrc_write && 9267 1.1 christos (regno == AR_BSPSTORE 9268 1.1 christos || regno == AR_RNAT)) 9269 1.1 christos { 9270 1.1 christos specs[count++] = tmpl; 9271 1.1 christos } 9272 1.1 christos break; 9273 1.1 christos } 9274 1.1 christos } 9275 1.1 christos else if (idesc->operands[1] == IA64_OPND_AR3) 9276 1.1 christos { 9277 1.1 christos /* AR[] reads */ 9278 1.1 christos regno = CURR_SLOT.opnd[1].X_add_number - REG_AR; 9279 1.1 christos switch (dep->regindex) 9280 1.1 christos { 9281 1.1 christos default: 9282 1.1 christos break; 9283 1.1 christos case AR_RSC: 9284 1.1 christos if (regno == AR_BSPSTORE || regno == AR_RNAT) 9285 1.1 christos { 9286 1.1 christos specs[count++] = tmpl; 9287 1.1 christos } 9288 1.1 christos break; 9289 1.1 christos } 9290 1.1 christos } 9291 1.1 christos else 9292 1.1 christos { 9293 1.1 christos specs[count++] = tmpl; 9294 1.1 christos } 9295 1.1 christos } 9296 1.1 christos else 9297 1.1 christos { 9298 1.1 christos UNHANDLED; 9299 1.1 christos } 9300 1.1 christos break; 9301 1.1 christos 9302 1.1 christos case IA64_RS_CRX: 9303 1.1 christos /* Handle all CR[REG] resources. 9304 1.1 christos ??? FIXME: The rule 17 isn't really handled correctly. */ 9305 1.1 christos if (note == 0 || note == 1 || note == 17) 9306 1.1 christos { 9307 1.1 christos if (idesc->operands[!rsrc_write] == IA64_OPND_CR3) 9308 1.1 christos { 9309 1.1 christos int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_CR; 9310 1.1 christos if (regno == dep->regindex) 9311 1.1 christos { 9312 1.1 christos specs[count++] = tmpl; 9313 1.1 christos } 9314 1.1 christos else if (!rsrc_write) 9315 1.1 christos { 9316 1.1 christos /* Reads from CR[IVR] affect other resources. */ 9317 1.1 christos if (regno == CR_IVR) 9318 1.1 christos { 9319 1.1 christos if ((dep->regindex >= CR_IRR0 9320 1.1 christos && dep->regindex <= CR_IRR3) 9321 1.1 christos || dep->regindex == CR_TPR) 9322 1.1 christos { 9323 1.1 christos specs[count++] = tmpl; 9324 1.1 christos } 9325 1.1 christos } 9326 1.1 christos } 9327 1.1 christos } 9328 1.1 christos else 9329 1.1 christos { 9330 1.1 christos specs[count++] = tmpl; 9331 1.1 christos } 9332 1.1 christos } 9333 1.1 christos else 9334 1.1 christos { 9335 1.1 christos UNHANDLED; 9336 1.1 christos } 9337 1.1 christos break; 9338 1.1 christos 9339 1.1 christos case IA64_RS_INSERVICE: 9340 1.1 christos /* look for write of EOI (67) or read of IVR (65) */ 9341 1.1 christos if ((idesc->operands[0] == IA64_OPND_CR3 9342 1.1 christos && CURR_SLOT.opnd[0].X_add_number - REG_CR == CR_EOI) 9343 1.1 christos || (idesc->operands[1] == IA64_OPND_CR3 9344 1.1 christos && CURR_SLOT.opnd[1].X_add_number - REG_CR == CR_IVR)) 9345 1.1 christos { 9346 1.1 christos specs[count++] = tmpl; 9347 1.1 christos } 9348 1.1 christos break; 9349 1.1 christos 9350 1.1 christos case IA64_RS_GR0: 9351 1.1 christos if (note == 1) 9352 1.1 christos { 9353 1.1 christos specs[count++] = tmpl; 9354 1.1 christos } 9355 1.1 christos else 9356 1.1 christos { 9357 1.1 christos UNHANDLED; 9358 1.1 christos } 9359 1.1 christos break; 9360 1.1 christos 9361 1.1 christos case IA64_RS_CFM: 9362 1.1 christos if (note != 2) 9363 1.1 christos { 9364 1.1 christos specs[count++] = tmpl; 9365 1.1 christos } 9366 1.1 christos else 9367 1.1 christos { 9368 1.1 christos /* Check if any of the registers accessed are in the rotating region. 9369 1.1 christos mov to/from pr accesses CFM only when qp_regno is in the rotating 9370 1.1 christos region */ 9371 1.1 christos for (i = 0; i < NELEMS (idesc->operands); i++) 9372 1.1 christos { 9373 1.1 christos if (idesc->operands[i] == IA64_OPND_R1 9374 1.1 christos || idesc->operands[i] == IA64_OPND_R2 9375 1.1 christos || idesc->operands[i] == IA64_OPND_R3) 9376 1.1 christos { 9377 1.1 christos int num = CURR_SLOT.opnd[i].X_add_number - REG_GR; 9378 1.1 christos /* Assumes that md.rot.num_regs is always valid */ 9379 1.1 christos if (md.rot.num_regs > 0 9380 1.1 christos && num > 31 9381 1.1 christos && num < 31 + md.rot.num_regs) 9382 1.1 christos { 9383 1.1 christos specs[count] = tmpl; 9384 1.1 christos specs[count++].specific = 0; 9385 1.1 christos } 9386 1.1 christos } 9387 1.1 christos else if (idesc->operands[i] == IA64_OPND_F1 9388 1.1 christos || idesc->operands[i] == IA64_OPND_F2 9389 1.1 christos || idesc->operands[i] == IA64_OPND_F3 9390 1.1 christos || idesc->operands[i] == IA64_OPND_F4) 9391 1.1 christos { 9392 1.1 christos int num = CURR_SLOT.opnd[i].X_add_number - REG_FR; 9393 1.1 christos if (num > 31) 9394 1.1 christos { 9395 1.1 christos specs[count] = tmpl; 9396 1.1 christos specs[count++].specific = 0; 9397 1.1 christos } 9398 1.1 christos } 9399 1.1 christos else if (idesc->operands[i] == IA64_OPND_P1 9400 1.1 christos || idesc->operands[i] == IA64_OPND_P2) 9401 1.1 christos { 9402 1.1 christos int num = CURR_SLOT.opnd[i].X_add_number - REG_P; 9403 1.1 christos if (num > 15) 9404 1.1 christos { 9405 1.1 christos specs[count] = tmpl; 9406 1.1 christos specs[count++].specific = 0; 9407 1.1 christos } 9408 1.1 christos } 9409 1.1 christos } 9410 1.1 christos if (CURR_SLOT.qp_regno > 15) 9411 1.1 christos { 9412 1.1 christos specs[count] = tmpl; 9413 1.1 christos specs[count++].specific = 0; 9414 1.1 christos } 9415 1.1 christos } 9416 1.1 christos break; 9417 1.1 christos 9418 1.1 christos /* This is the same as IA64_RS_PRr, except simplified to account for 9419 1.1 christos the fact that there is only one register. */ 9420 1.1 christos case IA64_RS_PR63: 9421 1.1 christos if (note == 0) 9422 1.1 christos { 9423 1.1 christos specs[count++] = tmpl; 9424 1.1 christos } 9425 1.1 christos else if (note == 7) 9426 1.1 christos { 9427 1.1 christos valueT mask = 0; 9428 1.1 christos if (idesc->operands[2] == IA64_OPND_IMM17) 9429 1.1 christos mask = CURR_SLOT.opnd[2].X_add_number; 9430 1.1 christos if (mask & ((valueT) 1 << 63)) 9431 1.1 christos specs[count++] = tmpl; 9432 1.1 christos } 9433 1.1 christos else if (note == 11) 9434 1.1 christos { 9435 1.1 christos if ((idesc->operands[0] == IA64_OPND_P1 9436 1.1 christos && CURR_SLOT.opnd[0].X_add_number - REG_P == 63) 9437 1.1 christos || (idesc->operands[1] == IA64_OPND_P2 9438 1.1 christos && CURR_SLOT.opnd[1].X_add_number - REG_P == 63)) 9439 1.1 christos { 9440 1.1 christos specs[count++] = tmpl; 9441 1.1 christos } 9442 1.1 christos } 9443 1.1 christos else if (note == 12) 9444 1.1 christos { 9445 1.1 christos if (CURR_SLOT.qp_regno == 63) 9446 1.1 christos { 9447 1.1 christos specs[count++] = tmpl; 9448 1.1 christos } 9449 1.1 christos } 9450 1.1 christos else if (note == 1) 9451 1.1 christos { 9452 1.1 christos if (rsrc_write) 9453 1.1 christos { 9454 1.1 christos int p1 = CURR_SLOT.opnd[0].X_add_number - REG_P; 9455 1.1 christos int p2 = CURR_SLOT.opnd[1].X_add_number - REG_P; 9456 1.1 christos int or_andcm = strstr (idesc->name, "or.andcm") != NULL; 9457 1.1 christos int and_orcm = strstr (idesc->name, "and.orcm") != NULL; 9458 1.1 christos 9459 1.1 christos if (p1 == 63 9460 1.1 christos && (idesc->operands[0] == IA64_OPND_P1 9461 1.1 christos || idesc->operands[0] == IA64_OPND_P2)) 9462 1.1 christos { 9463 1.1 christos specs[count] = tmpl; 9464 1.1 christos specs[count++].cmp_type = 9465 1.1 christos (or_andcm ? CMP_OR : (and_orcm ? CMP_AND : CMP_NONE)); 9466 1.1 christos } 9467 1.1 christos if (p2 == 63 9468 1.1 christos && (idesc->operands[1] == IA64_OPND_P1 9469 1.1 christos || idesc->operands[1] == IA64_OPND_P2)) 9470 1.1 christos { 9471 1.1 christos specs[count] = tmpl; 9472 1.1 christos specs[count++].cmp_type = 9473 1.1 christos (or_andcm ? CMP_AND : (and_orcm ? CMP_OR : CMP_NONE)); 9474 1.1 christos } 9475 1.1 christos } 9476 1.1 christos else 9477 1.1 christos { 9478 1.1 christos if (CURR_SLOT.qp_regno == 63) 9479 1.1 christos { 9480 1.1 christos specs[count++] = tmpl; 9481 1.1 christos } 9482 1.1 christos } 9483 1.1 christos } 9484 1.1 christos else 9485 1.1 christos { 9486 1.1 christos UNHANDLED; 9487 1.1 christos } 9488 1.1 christos break; 9489 1.1 christos 9490 1.1 christos case IA64_RS_RSE: 9491 1.1 christos /* FIXME we can identify some individual RSE written resources, but RSE 9492 1.1 christos read resources have not yet been completely identified, so for now 9493 1.1 christos treat RSE as a single resource */ 9494 1.8 christos if (startswith (idesc->name, "mov")) 9495 1.1 christos { 9496 1.1 christos if (rsrc_write) 9497 1.1 christos { 9498 1.1 christos if (idesc->operands[0] == IA64_OPND_AR3 9499 1.1 christos && CURR_SLOT.opnd[0].X_add_number - REG_AR == AR_BSPSTORE) 9500 1.1 christos { 9501 1.1 christos specs[count++] = tmpl; 9502 1.1 christos } 9503 1.1 christos } 9504 1.1 christos else 9505 1.1 christos { 9506 1.1 christos if (idesc->operands[0] == IA64_OPND_AR3) 9507 1.1 christos { 9508 1.1 christos if (CURR_SLOT.opnd[0].X_add_number - REG_AR == AR_BSPSTORE 9509 1.1 christos || CURR_SLOT.opnd[0].X_add_number - REG_AR == AR_RNAT) 9510 1.1 christos { 9511 1.1 christos specs[count++] = tmpl; 9512 1.1 christos } 9513 1.1 christos } 9514 1.1 christos else if (idesc->operands[1] == IA64_OPND_AR3) 9515 1.1 christos { 9516 1.1 christos if (CURR_SLOT.opnd[1].X_add_number - REG_AR == AR_BSP 9517 1.1 christos || CURR_SLOT.opnd[1].X_add_number - REG_AR == AR_BSPSTORE 9518 1.1 christos || CURR_SLOT.opnd[1].X_add_number - REG_AR == AR_RNAT) 9519 1.1 christos { 9520 1.1 christos specs[count++] = tmpl; 9521 1.1 christos } 9522 1.1 christos } 9523 1.1 christos } 9524 1.1 christos } 9525 1.1 christos else 9526 1.1 christos { 9527 1.1 christos specs[count++] = tmpl; 9528 1.1 christos } 9529 1.1 christos break; 9530 1.1 christos 9531 1.1 christos case IA64_RS_ANY: 9532 1.1 christos /* FIXME -- do any of these need to be non-specific? */ 9533 1.1 christos specs[count++] = tmpl; 9534 1.1 christos break; 9535 1.1 christos 9536 1.1 christos default: 9537 1.1 christos as_bad (_("Unrecognized dependency specifier %d\n"), dep->specifier); 9538 1.1 christos break; 9539 1.1 christos } 9540 1.1 christos 9541 1.1 christos return count; 9542 1.1 christos } 9543 1.1 christos 9544 1.1 christos /* Clear branch flags on marked resources. This breaks the link between the 9545 1.1 christos QP of the marking instruction and a subsequent branch on the same QP. */ 9546 1.1 christos 9547 1.1 christos static void 9548 1.1 christos clear_qp_branch_flag (valueT mask) 9549 1.1 christos { 9550 1.1 christos int i; 9551 1.1 christos for (i = 0; i < regdepslen; i++) 9552 1.1 christos { 9553 1.1 christos valueT bit = ((valueT) 1 << regdeps[i].qp_regno); 9554 1.1 christos if ((bit & mask) != 0) 9555 1.1 christos { 9556 1.1 christos regdeps[i].link_to_qp_branch = 0; 9557 1.1 christos } 9558 1.1 christos } 9559 1.1 christos } 9560 1.1 christos 9561 1.1 christos /* MASK contains 2 and only 2 PRs which are mutually exclusive. Remove 9562 1.1 christos any mutexes which contain one of the PRs and create new ones when 9563 1.1 christos needed. */ 9564 1.1 christos 9565 1.1 christos static int 9566 1.1 christos update_qp_mutex (valueT mask) 9567 1.1 christos { 9568 1.1 christos int i; 9569 1.1 christos int add = 0; 9570 1.1 christos 9571 1.1 christos i = 0; 9572 1.1 christos while (i < qp_mutexeslen) 9573 1.1 christos { 9574 1.1 christos if ((qp_mutexes[i].prmask & mask) != 0) 9575 1.1 christos { 9576 1.1 christos /* If it destroys and creates the same mutex, do nothing. */ 9577 1.1 christos if (qp_mutexes[i].prmask == mask 9578 1.1 christos && qp_mutexes[i].path == md.path) 9579 1.1 christos { 9580 1.1 christos i++; 9581 1.1 christos add = -1; 9582 1.1 christos } 9583 1.1 christos else 9584 1.1 christos { 9585 1.1 christos int keep = 0; 9586 1.1 christos 9587 1.1 christos if (md.debug_dv) 9588 1.1 christos { 9589 1.1 christos fprintf (stderr, " Clearing mutex relation"); 9590 1.1 christos print_prmask (qp_mutexes[i].prmask); 9591 1.1 christos fprintf (stderr, "\n"); 9592 1.1 christos } 9593 1.3 christos 9594 1.1 christos /* Deal with the old mutex with more than 3+ PRs only if 9595 1.1 christos the new mutex on the same execution path with it. 9596 1.1 christos 9597 1.1 christos FIXME: The 3+ mutex support is incomplete. 9598 1.1 christos dot_pred_rel () may be a better place to fix it. */ 9599 1.1 christos if (qp_mutexes[i].path == md.path) 9600 1.1 christos { 9601 1.1 christos /* If it is a proper subset of the mutex, create a 9602 1.1 christos new mutex. */ 9603 1.1 christos if (add == 0 9604 1.1 christos && (qp_mutexes[i].prmask & mask) == mask) 9605 1.1 christos add = 1; 9606 1.3 christos 9607 1.1 christos qp_mutexes[i].prmask &= ~mask; 9608 1.1 christos if (qp_mutexes[i].prmask & (qp_mutexes[i].prmask - 1)) 9609 1.1 christos { 9610 1.1 christos /* Modify the mutex if there are more than one 9611 1.1 christos PR left. */ 9612 1.1 christos keep = 1; 9613 1.1 christos i++; 9614 1.1 christos } 9615 1.1 christos } 9616 1.3 christos 9617 1.1 christos if (keep == 0) 9618 1.1 christos /* Remove the mutex. */ 9619 1.1 christos qp_mutexes[i] = qp_mutexes[--qp_mutexeslen]; 9620 1.1 christos } 9621 1.1 christos } 9622 1.1 christos else 9623 1.1 christos ++i; 9624 1.1 christos } 9625 1.1 christos 9626 1.1 christos if (add == 1) 9627 1.1 christos add_qp_mutex (mask); 9628 1.1 christos 9629 1.1 christos return add; 9630 1.1 christos } 9631 1.1 christos 9632 1.1 christos /* Remove any mutexes which contain any of the PRs indicated in the mask. 9633 1.1 christos 9634 1.1 christos Any changes to a PR clears the mutex relations which include that PR. */ 9635 1.1 christos 9636 1.1 christos static void 9637 1.1 christos clear_qp_mutex (valueT mask) 9638 1.1 christos { 9639 1.1 christos int i; 9640 1.1 christos 9641 1.1 christos i = 0; 9642 1.1 christos while (i < qp_mutexeslen) 9643 1.1 christos { 9644 1.1 christos if ((qp_mutexes[i].prmask & mask) != 0) 9645 1.1 christos { 9646 1.1 christos if (md.debug_dv) 9647 1.1 christos { 9648 1.1 christos fprintf (stderr, " Clearing mutex relation"); 9649 1.1 christos print_prmask (qp_mutexes[i].prmask); 9650 1.1 christos fprintf (stderr, "\n"); 9651 1.1 christos } 9652 1.1 christos qp_mutexes[i] = qp_mutexes[--qp_mutexeslen]; 9653 1.1 christos } 9654 1.1 christos else 9655 1.1 christos ++i; 9656 1.1 christos } 9657 1.1 christos } 9658 1.1 christos 9659 1.1 christos /* Clear implies relations which contain PRs in the given masks. 9660 1.1 christos P1_MASK indicates the source of the implies relation, while P2_MASK 9661 1.1 christos indicates the implied PR. */ 9662 1.1 christos 9663 1.1 christos static void 9664 1.1 christos clear_qp_implies (valueT p1_mask, valueT p2_mask) 9665 1.1 christos { 9666 1.1 christos int i; 9667 1.1 christos 9668 1.1 christos i = 0; 9669 1.1 christos while (i < qp_implieslen) 9670 1.1 christos { 9671 1.1 christos if ((((valueT) 1 << qp_implies[i].p1) & p1_mask) != 0 9672 1.1 christos || (((valueT) 1 << qp_implies[i].p2) & p2_mask) != 0) 9673 1.1 christos { 9674 1.1 christos if (md.debug_dv) 9675 1.1 christos fprintf (stderr, "Clearing implied relation PR%d->PR%d\n", 9676 1.1 christos qp_implies[i].p1, qp_implies[i].p2); 9677 1.1 christos qp_implies[i] = qp_implies[--qp_implieslen]; 9678 1.1 christos } 9679 1.1 christos else 9680 1.1 christos ++i; 9681 1.1 christos } 9682 1.1 christos } 9683 1.1 christos 9684 1.1 christos /* Add the PRs specified to the list of implied relations. */ 9685 1.1 christos 9686 1.1 christos static void 9687 1.1 christos add_qp_imply (int p1, int p2) 9688 1.1 christos { 9689 1.1 christos valueT mask; 9690 1.1 christos valueT bit; 9691 1.1 christos int i; 9692 1.1 christos 9693 1.1 christos /* p0 is not meaningful here. */ 9694 1.1 christos if (p1 == 0 || p2 == 0) 9695 1.1 christos abort (); 9696 1.1 christos 9697 1.1 christos if (p1 == p2) 9698 1.1 christos return; 9699 1.1 christos 9700 1.1 christos /* If it exists already, ignore it. */ 9701 1.1 christos for (i = 0; i < qp_implieslen; i++) 9702 1.1 christos { 9703 1.1 christos if (qp_implies[i].p1 == p1 9704 1.1 christos && qp_implies[i].p2 == p2 9705 1.1 christos && qp_implies[i].path == md.path 9706 1.1 christos && !qp_implies[i].p2_branched) 9707 1.1 christos return; 9708 1.1 christos } 9709 1.1 christos 9710 1.1 christos if (qp_implieslen == qp_impliestotlen) 9711 1.1 christos { 9712 1.1 christos qp_impliestotlen += 20; 9713 1.5 christos qp_implies = XRESIZEVEC (struct qp_imply, qp_implies, qp_impliestotlen); 9714 1.1 christos } 9715 1.1 christos if (md.debug_dv) 9716 1.1 christos fprintf (stderr, " Registering PR%d implies PR%d\n", p1, p2); 9717 1.1 christos qp_implies[qp_implieslen].p1 = p1; 9718 1.1 christos qp_implies[qp_implieslen].p2 = p2; 9719 1.1 christos qp_implies[qp_implieslen].path = md.path; 9720 1.1 christos qp_implies[qp_implieslen++].p2_branched = 0; 9721 1.1 christos 9722 1.1 christos /* Add in the implied transitive relations; for everything that p2 implies, 9723 1.1 christos make p1 imply that, too; for everything that implies p1, make it imply p2 9724 1.1 christos as well. */ 9725 1.1 christos for (i = 0; i < qp_implieslen; i++) 9726 1.1 christos { 9727 1.1 christos if (qp_implies[i].p1 == p2) 9728 1.1 christos add_qp_imply (p1, qp_implies[i].p2); 9729 1.1 christos if (qp_implies[i].p2 == p1) 9730 1.1 christos add_qp_imply (qp_implies[i].p1, p2); 9731 1.1 christos } 9732 1.1 christos /* Add in mutex relations implied by this implies relation; for each mutex 9733 1.1 christos relation containing p2, duplicate it and replace p2 with p1. */ 9734 1.1 christos bit = (valueT) 1 << p1; 9735 1.1 christos mask = (valueT) 1 << p2; 9736 1.1 christos for (i = 0; i < qp_mutexeslen; i++) 9737 1.1 christos { 9738 1.1 christos if (qp_mutexes[i].prmask & mask) 9739 1.1 christos add_qp_mutex ((qp_mutexes[i].prmask & ~mask) | bit); 9740 1.1 christos } 9741 1.1 christos } 9742 1.1 christos 9743 1.1 christos /* Add the PRs specified in the mask to the mutex list; this means that only 9744 1.1 christos one of the PRs can be true at any time. PR0 should never be included in 9745 1.1 christos the mask. */ 9746 1.1 christos 9747 1.1 christos static void 9748 1.1 christos add_qp_mutex (valueT mask) 9749 1.1 christos { 9750 1.1 christos if (mask & 0x1) 9751 1.1 christos abort (); 9752 1.1 christos 9753 1.1 christos if (qp_mutexeslen == qp_mutexestotlen) 9754 1.1 christos { 9755 1.1 christos qp_mutexestotlen += 20; 9756 1.5 christos qp_mutexes = XRESIZEVEC (struct qpmutex, qp_mutexes, qp_mutexestotlen); 9757 1.1 christos } 9758 1.1 christos if (md.debug_dv) 9759 1.1 christos { 9760 1.1 christos fprintf (stderr, " Registering mutex on"); 9761 1.1 christos print_prmask (mask); 9762 1.1 christos fprintf (stderr, "\n"); 9763 1.1 christos } 9764 1.1 christos qp_mutexes[qp_mutexeslen].path = md.path; 9765 1.1 christos qp_mutexes[qp_mutexeslen++].prmask = mask; 9766 1.1 christos } 9767 1.1 christos 9768 1.1 christos static int 9769 1.1 christos has_suffix_p (const char *name, const char *suffix) 9770 1.1 christos { 9771 1.1 christos size_t namelen = strlen (name); 9772 1.1 christos size_t sufflen = strlen (suffix); 9773 1.1 christos 9774 1.1 christos if (namelen <= sufflen) 9775 1.1 christos return 0; 9776 1.1 christos return strcmp (name + namelen - sufflen, suffix) == 0; 9777 1.1 christos } 9778 1.1 christos 9779 1.1 christos static void 9780 1.1 christos clear_register_values (void) 9781 1.1 christos { 9782 1.1 christos int i; 9783 1.1 christos if (md.debug_dv) 9784 1.1 christos fprintf (stderr, " Clearing register values\n"); 9785 1.1 christos for (i = 1; i < NELEMS (gr_values); i++) 9786 1.1 christos gr_values[i].known = 0; 9787 1.1 christos } 9788 1.1 christos 9789 1.1 christos /* Keep track of register values/changes which affect DV tracking. 9790 1.1 christos 9791 1.1 christos optimization note: should add a flag to classes of insns where otherwise we 9792 1.1 christos have to examine a group of strings to identify them. */ 9793 1.1 christos 9794 1.1 christos static void 9795 1.1 christos note_register_values (struct ia64_opcode *idesc) 9796 1.1 christos { 9797 1.1 christos valueT qp_changemask = 0; 9798 1.1 christos int i; 9799 1.1 christos 9800 1.1 christos /* Invalidate values for registers being written to. */ 9801 1.1 christos for (i = 0; i < idesc->num_outputs; i++) 9802 1.1 christos { 9803 1.1 christos if (idesc->operands[i] == IA64_OPND_R1 9804 1.1 christos || idesc->operands[i] == IA64_OPND_R2 9805 1.1 christos || idesc->operands[i] == IA64_OPND_R3) 9806 1.1 christos { 9807 1.1 christos int regno = CURR_SLOT.opnd[i].X_add_number - REG_GR; 9808 1.1 christos if (regno > 0 && regno < NELEMS (gr_values)) 9809 1.1 christos gr_values[regno].known = 0; 9810 1.1 christos } 9811 1.1 christos else if (idesc->operands[i] == IA64_OPND_R3_2) 9812 1.1 christos { 9813 1.1 christos int regno = CURR_SLOT.opnd[i].X_add_number - REG_GR; 9814 1.1 christos if (regno > 0 && regno < 4) 9815 1.1 christos gr_values[regno].known = 0; 9816 1.1 christos } 9817 1.1 christos else if (idesc->operands[i] == IA64_OPND_P1 9818 1.1 christos || idesc->operands[i] == IA64_OPND_P2) 9819 1.1 christos { 9820 1.1 christos int regno = CURR_SLOT.opnd[i].X_add_number - REG_P; 9821 1.1 christos qp_changemask |= (valueT) 1 << regno; 9822 1.1 christos } 9823 1.1 christos else if (idesc->operands[i] == IA64_OPND_PR) 9824 1.1 christos { 9825 1.1 christos if (idesc->operands[2] & (valueT) 0x10000) 9826 1.1 christos qp_changemask = ~(valueT) 0x1FFFF | idesc->operands[2]; 9827 1.1 christos else 9828 1.1 christos qp_changemask = idesc->operands[2]; 9829 1.1 christos break; 9830 1.1 christos } 9831 1.1 christos else if (idesc->operands[i] == IA64_OPND_PR_ROT) 9832 1.1 christos { 9833 1.1 christos if (idesc->operands[1] & ((valueT) 1 << 43)) 9834 1.1 christos qp_changemask = -((valueT) 1 << 44) | idesc->operands[1]; 9835 1.1 christos else 9836 1.1 christos qp_changemask = idesc->operands[1]; 9837 1.1 christos qp_changemask &= ~(valueT) 0xFFFF; 9838 1.1 christos break; 9839 1.1 christos } 9840 1.1 christos } 9841 1.1 christos 9842 1.1 christos /* Always clear qp branch flags on any PR change. */ 9843 1.1 christos /* FIXME there may be exceptions for certain compares. */ 9844 1.1 christos clear_qp_branch_flag (qp_changemask); 9845 1.1 christos 9846 1.1 christos /* Invalidate rotating registers on insns which affect RRBs in CFM. */ 9847 1.1 christos if (idesc->flags & IA64_OPCODE_MOD_RRBS) 9848 1.1 christos { 9849 1.1 christos qp_changemask |= ~(valueT) 0xFFFF; 9850 1.1 christos if (strcmp (idesc->name, "clrrrb.pr") != 0) 9851 1.1 christos { 9852 1.1 christos for (i = 32; i < 32 + md.rot.num_regs; i++) 9853 1.1 christos gr_values[i].known = 0; 9854 1.1 christos } 9855 1.1 christos clear_qp_mutex (qp_changemask); 9856 1.1 christos clear_qp_implies (qp_changemask, qp_changemask); 9857 1.1 christos } 9858 1.1 christos /* After a call, all register values are undefined, except those marked 9859 1.1 christos as "safe". */ 9860 1.8 christos else if (startswith (idesc->name, "br.call") 9861 1.8 christos || startswith (idesc->name, "brl.call")) 9862 1.1 christos { 9863 1.1 christos /* FIXME keep GR values which are marked as "safe_across_calls" */ 9864 1.1 christos clear_register_values (); 9865 1.1 christos clear_qp_mutex (~qp_safe_across_calls); 9866 1.1 christos clear_qp_implies (~qp_safe_across_calls, ~qp_safe_across_calls); 9867 1.1 christos clear_qp_branch_flag (~qp_safe_across_calls); 9868 1.1 christos } 9869 1.1 christos else if (is_interruption_or_rfi (idesc) 9870 1.1 christos || is_taken_branch (idesc)) 9871 1.1 christos { 9872 1.1 christos clear_register_values (); 9873 1.1 christos clear_qp_mutex (~(valueT) 0); 9874 1.1 christos clear_qp_implies (~(valueT) 0, ~(valueT) 0); 9875 1.1 christos } 9876 1.1 christos /* Look for mutex and implies relations. */ 9877 1.1 christos else if ((idesc->operands[0] == IA64_OPND_P1 9878 1.1 christos || idesc->operands[0] == IA64_OPND_P2) 9879 1.1 christos && (idesc->operands[1] == IA64_OPND_P1 9880 1.1 christos || idesc->operands[1] == IA64_OPND_P2)) 9881 1.1 christos { 9882 1.1 christos int p1 = CURR_SLOT.opnd[0].X_add_number - REG_P; 9883 1.1 christos int p2 = CURR_SLOT.opnd[1].X_add_number - REG_P; 9884 1.1 christos valueT p1mask = (p1 != 0) ? (valueT) 1 << p1 : 0; 9885 1.1 christos valueT p2mask = (p2 != 0) ? (valueT) 1 << p2 : 0; 9886 1.1 christos 9887 1.1 christos /* If both PRs are PR0, we can't really do anything. */ 9888 1.1 christos if (p1 == 0 && p2 == 0) 9889 1.1 christos { 9890 1.1 christos if (md.debug_dv) 9891 1.1 christos fprintf (stderr, " Ignoring PRs due to inclusion of p0\n"); 9892 1.1 christos } 9893 1.1 christos /* In general, clear mutexes and implies which include P1 or P2, 9894 1.1 christos with the following exceptions. */ 9895 1.1 christos else if (has_suffix_p (idesc->name, ".or.andcm") 9896 1.1 christos || has_suffix_p (idesc->name, ".and.orcm")) 9897 1.1 christos { 9898 1.1 christos clear_qp_implies (p2mask, p1mask); 9899 1.1 christos } 9900 1.1 christos else if (has_suffix_p (idesc->name, ".andcm") 9901 1.1 christos || has_suffix_p (idesc->name, ".and")) 9902 1.1 christos { 9903 1.1 christos clear_qp_implies (0, p1mask | p2mask); 9904 1.1 christos } 9905 1.1 christos else if (has_suffix_p (idesc->name, ".orcm") 9906 1.1 christos || has_suffix_p (idesc->name, ".or")) 9907 1.1 christos { 9908 1.1 christos clear_qp_mutex (p1mask | p2mask); 9909 1.1 christos clear_qp_implies (p1mask | p2mask, 0); 9910 1.1 christos } 9911 1.1 christos else 9912 1.1 christos { 9913 1.1 christos int added = 0; 9914 1.1 christos 9915 1.1 christos clear_qp_implies (p1mask | p2mask, p1mask | p2mask); 9916 1.1 christos 9917 1.1 christos /* If one of the PRs is PR0, we call clear_qp_mutex. */ 9918 1.1 christos if (p1 == 0 || p2 == 0) 9919 1.1 christos clear_qp_mutex (p1mask | p2mask); 9920 1.1 christos else 9921 1.1 christos added = update_qp_mutex (p1mask | p2mask); 9922 1.1 christos 9923 1.1 christos if (CURR_SLOT.qp_regno == 0 9924 1.1 christos || has_suffix_p (idesc->name, ".unc")) 9925 1.1 christos { 9926 1.1 christos if (added == 0 && p1 && p2) 9927 1.1 christos add_qp_mutex (p1mask | p2mask); 9928 1.1 christos if (CURR_SLOT.qp_regno != 0) 9929 1.1 christos { 9930 1.1 christos if (p1) 9931 1.1 christos add_qp_imply (p1, CURR_SLOT.qp_regno); 9932 1.1 christos if (p2) 9933 1.1 christos add_qp_imply (p2, CURR_SLOT.qp_regno); 9934 1.1 christos } 9935 1.1 christos } 9936 1.1 christos } 9937 1.1 christos } 9938 1.1 christos /* Look for mov imm insns into GRs. */ 9939 1.1 christos else if (idesc->operands[0] == IA64_OPND_R1 9940 1.1 christos && (idesc->operands[1] == IA64_OPND_IMM22 9941 1.1 christos || idesc->operands[1] == IA64_OPND_IMMU64) 9942 1.1 christos && CURR_SLOT.opnd[1].X_op == O_constant 9943 1.1 christos && (strcmp (idesc->name, "mov") == 0 9944 1.1 christos || strcmp (idesc->name, "movl") == 0)) 9945 1.1 christos { 9946 1.1 christos int regno = CURR_SLOT.opnd[0].X_add_number - REG_GR; 9947 1.1 christos if (regno > 0 && regno < NELEMS (gr_values)) 9948 1.1 christos { 9949 1.1 christos gr_values[regno].known = 1; 9950 1.1 christos gr_values[regno].value = CURR_SLOT.opnd[1].X_add_number; 9951 1.1 christos gr_values[regno].path = md.path; 9952 1.1 christos if (md.debug_dv) 9953 1.9 christos fprintf (stderr, " Know gr%d = %" PRIx64 "\n", 9954 1.9 christos regno, gr_values[regno].value); 9955 1.1 christos } 9956 1.1 christos } 9957 1.1 christos /* Look for dep.z imm insns. */ 9958 1.1 christos else if (idesc->operands[0] == IA64_OPND_R1 9959 1.1 christos && idesc->operands[1] == IA64_OPND_IMM8 9960 1.1 christos && strcmp (idesc->name, "dep.z") == 0) 9961 1.1 christos { 9962 1.1 christos int regno = CURR_SLOT.opnd[0].X_add_number - REG_GR; 9963 1.1 christos if (regno > 0 && regno < NELEMS (gr_values)) 9964 1.1 christos { 9965 1.1 christos valueT value = CURR_SLOT.opnd[1].X_add_number; 9966 1.1 christos 9967 1.1 christos if (CURR_SLOT.opnd[3].X_add_number < 64) 9968 1.1 christos value &= ((valueT)1 << CURR_SLOT.opnd[3].X_add_number) - 1; 9969 1.1 christos value <<= CURR_SLOT.opnd[2].X_add_number; 9970 1.1 christos gr_values[regno].known = 1; 9971 1.1 christos gr_values[regno].value = value; 9972 1.1 christos gr_values[regno].path = md.path; 9973 1.1 christos if (md.debug_dv) 9974 1.9 christos fprintf (stderr, " Know gr%d = %" PRIx64 "\n", 9975 1.9 christos regno, gr_values[regno].value); 9976 1.1 christos } 9977 1.1 christos } 9978 1.1 christos else 9979 1.1 christos { 9980 1.1 christos clear_qp_mutex (qp_changemask); 9981 1.1 christos clear_qp_implies (qp_changemask, qp_changemask); 9982 1.1 christos } 9983 1.1 christos } 9984 1.1 christos 9985 1.1 christos /* Return whether the given predicate registers are currently mutex. */ 9986 1.1 christos 9987 1.1 christos static int 9988 1.1 christos qp_mutex (int p1, int p2, int path) 9989 1.1 christos { 9990 1.1 christos int i; 9991 1.1 christos valueT mask; 9992 1.1 christos 9993 1.1 christos if (p1 != p2) 9994 1.1 christos { 9995 1.1 christos mask = ((valueT) 1 << p1) | (valueT) 1 << p2; 9996 1.1 christos for (i = 0; i < qp_mutexeslen; i++) 9997 1.1 christos { 9998 1.1 christos if (qp_mutexes[i].path >= path 9999 1.1 christos && (qp_mutexes[i].prmask & mask) == mask) 10000 1.1 christos return 1; 10001 1.1 christos } 10002 1.1 christos } 10003 1.1 christos return 0; 10004 1.1 christos } 10005 1.1 christos 10006 1.1 christos /* Return whether the given resource is in the given insn's list of chks 10007 1.1 christos Return 1 if the conflict is absolutely determined, 2 if it's a potential 10008 1.1 christos conflict. */ 10009 1.1 christos 10010 1.1 christos static int 10011 1.1 christos resources_match (struct rsrc *rs, 10012 1.1 christos struct ia64_opcode *idesc, 10013 1.1 christos int note, 10014 1.1 christos int qp_regno, 10015 1.1 christos int path) 10016 1.1 christos { 10017 1.1 christos struct rsrc specs[MAX_SPECS]; 10018 1.1 christos int count; 10019 1.1 christos 10020 1.1 christos /* If the marked resource's qp_regno and the given qp_regno are mutex, 10021 1.1 christos we don't need to check. One exception is note 11, which indicates that 10022 1.1 christos target predicates are written regardless of PR[qp]. */ 10023 1.1 christos if (qp_mutex (rs->qp_regno, qp_regno, path) 10024 1.1 christos && note != 11) 10025 1.1 christos return 0; 10026 1.1 christos 10027 1.1 christos count = specify_resource (rs->dependency, idesc, DV_CHK, specs, note, path); 10028 1.1 christos while (count-- > 0) 10029 1.1 christos { 10030 1.1 christos /* UNAT checking is a bit more specific than other resources */ 10031 1.1 christos if (rs->dependency->specifier == IA64_RS_AR_UNAT 10032 1.1 christos && specs[count].mem_offset.hint 10033 1.1 christos && rs->mem_offset.hint) 10034 1.1 christos { 10035 1.1 christos if (rs->mem_offset.base == specs[count].mem_offset.base) 10036 1.1 christos { 10037 1.1 christos if (((rs->mem_offset.offset >> 3) & 0x3F) == 10038 1.1 christos ((specs[count].mem_offset.offset >> 3) & 0x3F)) 10039 1.1 christos return 1; 10040 1.1 christos else 10041 1.1 christos continue; 10042 1.1 christos } 10043 1.1 christos } 10044 1.1 christos 10045 1.1 christos /* Skip apparent PR write conflicts where both writes are an AND or both 10046 1.1 christos writes are an OR. */ 10047 1.1 christos if (rs->dependency->specifier == IA64_RS_PR 10048 1.1 christos || rs->dependency->specifier == IA64_RS_PRr 10049 1.1 christos || rs->dependency->specifier == IA64_RS_PR63) 10050 1.1 christos { 10051 1.1 christos if (specs[count].cmp_type != CMP_NONE 10052 1.1 christos && specs[count].cmp_type == rs->cmp_type) 10053 1.1 christos { 10054 1.1 christos if (md.debug_dv) 10055 1.1 christos fprintf (stderr, " %s on parallel compare allowed (PR%d)\n", 10056 1.1 christos dv_mode[rs->dependency->mode], 10057 1.1 christos rs->dependency->specifier != IA64_RS_PR63 ? 10058 1.1 christos specs[count].index : 63); 10059 1.1 christos continue; 10060 1.1 christos } 10061 1.1 christos if (md.debug_dv) 10062 1.1 christos fprintf (stderr, 10063 1.1 christos " %s on parallel compare conflict %s vs %s on PR%d\n", 10064 1.1 christos dv_mode[rs->dependency->mode], 10065 1.1 christos dv_cmp_type[rs->cmp_type], 10066 1.1 christos dv_cmp_type[specs[count].cmp_type], 10067 1.1 christos rs->dependency->specifier != IA64_RS_PR63 ? 10068 1.1 christos specs[count].index : 63); 10069 1.1 christos 10070 1.1 christos } 10071 1.1 christos 10072 1.1 christos /* If either resource is not specific, conservatively assume a conflict 10073 1.1 christos */ 10074 1.1 christos if (!specs[count].specific || !rs->specific) 10075 1.1 christos return 2; 10076 1.1 christos else if (specs[count].index == rs->index) 10077 1.1 christos return 1; 10078 1.1 christos } 10079 1.1 christos 10080 1.1 christos return 0; 10081 1.1 christos } 10082 1.1 christos 10083 1.1 christos /* Indicate an instruction group break; if INSERT_STOP is non-zero, then 10084 1.1 christos insert a stop to create the break. Update all resource dependencies 10085 1.1 christos appropriately. If QP_REGNO is non-zero, only apply the break to resources 10086 1.1 christos which use the same QP_REGNO and have the link_to_qp_branch flag set. 10087 1.1 christos If SAVE_CURRENT is non-zero, don't affect resources marked by the current 10088 1.1 christos instruction. */ 10089 1.1 christos 10090 1.1 christos static void 10091 1.1 christos insn_group_break (int insert_stop, int qp_regno, int save_current) 10092 1.1 christos { 10093 1.1 christos int i; 10094 1.1 christos 10095 1.1 christos if (insert_stop && md.num_slots_in_use > 0) 10096 1.1 christos PREV_SLOT.end_of_insn_group = 1; 10097 1.1 christos 10098 1.1 christos if (md.debug_dv) 10099 1.1 christos { 10100 1.1 christos fprintf (stderr, " Insn group break%s", 10101 1.1 christos (insert_stop ? " (w/stop)" : "")); 10102 1.1 christos if (qp_regno != 0) 10103 1.1 christos fprintf (stderr, " effective for QP=%d", qp_regno); 10104 1.1 christos fprintf (stderr, "\n"); 10105 1.1 christos } 10106 1.1 christos 10107 1.1 christos i = 0; 10108 1.1 christos while (i < regdepslen) 10109 1.1 christos { 10110 1.1 christos const struct ia64_dependency *dep = regdeps[i].dependency; 10111 1.1 christos 10112 1.1 christos if (qp_regno != 0 10113 1.1 christos && regdeps[i].qp_regno != qp_regno) 10114 1.1 christos { 10115 1.1 christos ++i; 10116 1.1 christos continue; 10117 1.1 christos } 10118 1.1 christos 10119 1.1 christos if (save_current 10120 1.1 christos && CURR_SLOT.src_file == regdeps[i].file 10121 1.1 christos && CURR_SLOT.src_line == regdeps[i].line) 10122 1.1 christos { 10123 1.1 christos ++i; 10124 1.1 christos continue; 10125 1.1 christos } 10126 1.1 christos 10127 1.1 christos /* clear dependencies which are automatically cleared by a stop, or 10128 1.1 christos those that have reached the appropriate state of insn serialization */ 10129 1.1 christos if (dep->semantics == IA64_DVS_IMPLIED 10130 1.1 christos || dep->semantics == IA64_DVS_IMPLIEDF 10131 1.1 christos || regdeps[i].insn_srlz == STATE_SRLZ) 10132 1.1 christos { 10133 1.1 christos print_dependency ("Removing", i); 10134 1.1 christos regdeps[i] = regdeps[--regdepslen]; 10135 1.1 christos } 10136 1.1 christos else 10137 1.1 christos { 10138 1.1 christos if (dep->semantics == IA64_DVS_DATA 10139 1.1 christos || dep->semantics == IA64_DVS_INSTR 10140 1.1 christos || dep->semantics == IA64_DVS_SPECIFIC) 10141 1.1 christos { 10142 1.1 christos if (regdeps[i].insn_srlz == STATE_NONE) 10143 1.1 christos regdeps[i].insn_srlz = STATE_STOP; 10144 1.1 christos if (regdeps[i].data_srlz == STATE_NONE) 10145 1.1 christos regdeps[i].data_srlz = STATE_STOP; 10146 1.1 christos } 10147 1.1 christos ++i; 10148 1.1 christos } 10149 1.1 christos } 10150 1.1 christos } 10151 1.1 christos 10152 1.1 christos /* Add the given resource usage spec to the list of active dependencies. */ 10153 1.1 christos 10154 1.1 christos static void 10155 1.1 christos mark_resource (struct ia64_opcode *idesc ATTRIBUTE_UNUSED, 10156 1.1 christos const struct ia64_dependency *dep ATTRIBUTE_UNUSED, 10157 1.1 christos struct rsrc *spec, 10158 1.1 christos int depind, 10159 1.1 christos int path) 10160 1.1 christos { 10161 1.1 christos if (regdepslen == regdepstotlen) 10162 1.1 christos { 10163 1.1 christos regdepstotlen += 20; 10164 1.5 christos regdeps = XRESIZEVEC (struct rsrc, regdeps, regdepstotlen); 10165 1.1 christos } 10166 1.1 christos 10167 1.1 christos regdeps[regdepslen] = *spec; 10168 1.1 christos regdeps[regdepslen].depind = depind; 10169 1.1 christos regdeps[regdepslen].path = path; 10170 1.1 christos regdeps[regdepslen].file = CURR_SLOT.src_file; 10171 1.1 christos regdeps[regdepslen].line = CURR_SLOT.src_line; 10172 1.1 christos 10173 1.1 christos print_dependency ("Adding", regdepslen); 10174 1.1 christos 10175 1.1 christos ++regdepslen; 10176 1.1 christos } 10177 1.1 christos 10178 1.1 christos static void 10179 1.1 christos print_dependency (const char *action, int depind) 10180 1.1 christos { 10181 1.1 christos if (md.debug_dv) 10182 1.1 christos { 10183 1.1 christos fprintf (stderr, " %s %s '%s'", 10184 1.1 christos action, dv_mode[(regdeps[depind].dependency)->mode], 10185 1.1 christos (regdeps[depind].dependency)->name); 10186 1.1 christos if (regdeps[depind].specific && regdeps[depind].index >= 0) 10187 1.1 christos fprintf (stderr, " (%d)", regdeps[depind].index); 10188 1.1 christos if (regdeps[depind].mem_offset.hint) 10189 1.9 christos fprintf (stderr, " %" PRIx64 "+%" PRIx64, 10190 1.9 christos regdeps[depind].mem_offset.base, 10191 1.9 christos regdeps[depind].mem_offset.offset); 10192 1.1 christos fprintf (stderr, "\n"); 10193 1.1 christos } 10194 1.1 christos } 10195 1.1 christos 10196 1.1 christos static void 10197 1.1 christos instruction_serialization (void) 10198 1.1 christos { 10199 1.1 christos int i; 10200 1.1 christos if (md.debug_dv) 10201 1.1 christos fprintf (stderr, " Instruction serialization\n"); 10202 1.1 christos for (i = 0; i < regdepslen; i++) 10203 1.1 christos if (regdeps[i].insn_srlz == STATE_STOP) 10204 1.1 christos regdeps[i].insn_srlz = STATE_SRLZ; 10205 1.1 christos } 10206 1.1 christos 10207 1.1 christos static void 10208 1.1 christos data_serialization (void) 10209 1.1 christos { 10210 1.1 christos int i = 0; 10211 1.1 christos if (md.debug_dv) 10212 1.1 christos fprintf (stderr, " Data serialization\n"); 10213 1.1 christos while (i < regdepslen) 10214 1.1 christos { 10215 1.1 christos if (regdeps[i].data_srlz == STATE_STOP 10216 1.1 christos /* Note: as of 991210, all "other" dependencies are cleared by a 10217 1.1 christos data serialization. This might change with new tables */ 10218 1.1 christos || (regdeps[i].dependency)->semantics == IA64_DVS_OTHER) 10219 1.1 christos { 10220 1.1 christos print_dependency ("Removing", i); 10221 1.1 christos regdeps[i] = regdeps[--regdepslen]; 10222 1.1 christos } 10223 1.1 christos else 10224 1.1 christos ++i; 10225 1.1 christos } 10226 1.1 christos } 10227 1.1 christos 10228 1.1 christos /* Insert stops and serializations as needed to avoid DVs. */ 10229 1.1 christos 10230 1.1 christos static void 10231 1.1 christos remove_marked_resource (struct rsrc *rs) 10232 1.1 christos { 10233 1.1 christos switch (rs->dependency->semantics) 10234 1.1 christos { 10235 1.1 christos case IA64_DVS_SPECIFIC: 10236 1.1 christos if (md.debug_dv) 10237 1.1 christos fprintf (stderr, "Implementation-specific, assume worst case...\n"); 10238 1.6 christos /* Fall through. */ 10239 1.1 christos case IA64_DVS_INSTR: 10240 1.1 christos if (md.debug_dv) 10241 1.1 christos fprintf (stderr, "Inserting instr serialization\n"); 10242 1.1 christos if (rs->insn_srlz < STATE_STOP) 10243 1.1 christos insn_group_break (1, 0, 0); 10244 1.1 christos if (rs->insn_srlz < STATE_SRLZ) 10245 1.1 christos { 10246 1.1 christos struct slot oldslot = CURR_SLOT; 10247 1.1 christos /* Manually jam a srlz.i insn into the stream */ 10248 1.1 christos memset (&CURR_SLOT, 0, sizeof (CURR_SLOT)); 10249 1.1 christos CURR_SLOT.user_template = -1; 10250 1.1 christos CURR_SLOT.idesc = ia64_find_opcode ("srlz.i"); 10251 1.1 christos instruction_serialization (); 10252 1.1 christos md.curr_slot = (md.curr_slot + 1) % NUM_SLOTS; 10253 1.1 christos if (++md.num_slots_in_use >= NUM_SLOTS) 10254 1.1 christos emit_one_bundle (); 10255 1.1 christos CURR_SLOT = oldslot; 10256 1.1 christos } 10257 1.1 christos insn_group_break (1, 0, 0); 10258 1.1 christos break; 10259 1.1 christos case IA64_DVS_OTHER: /* as of rev2 (991220) of the DV tables, all 10260 1.1 christos "other" types of DV are eliminated 10261 1.1 christos by a data serialization */ 10262 1.1 christos case IA64_DVS_DATA: 10263 1.1 christos if (md.debug_dv) 10264 1.1 christos fprintf (stderr, "Inserting data serialization\n"); 10265 1.1 christos if (rs->data_srlz < STATE_STOP) 10266 1.1 christos insn_group_break (1, 0, 0); 10267 1.1 christos { 10268 1.1 christos struct slot oldslot = CURR_SLOT; 10269 1.1 christos /* Manually jam a srlz.d insn into the stream */ 10270 1.1 christos memset (&CURR_SLOT, 0, sizeof (CURR_SLOT)); 10271 1.1 christos CURR_SLOT.user_template = -1; 10272 1.1 christos CURR_SLOT.idesc = ia64_find_opcode ("srlz.d"); 10273 1.1 christos data_serialization (); 10274 1.1 christos md.curr_slot = (md.curr_slot + 1) % NUM_SLOTS; 10275 1.1 christos if (++md.num_slots_in_use >= NUM_SLOTS) 10276 1.1 christos emit_one_bundle (); 10277 1.1 christos CURR_SLOT = oldslot; 10278 1.1 christos } 10279 1.1 christos break; 10280 1.1 christos case IA64_DVS_IMPLIED: 10281 1.1 christos case IA64_DVS_IMPLIEDF: 10282 1.1 christos if (md.debug_dv) 10283 1.1 christos fprintf (stderr, "Inserting stop\n"); 10284 1.1 christos insn_group_break (1, 0, 0); 10285 1.1 christos break; 10286 1.1 christos default: 10287 1.1 christos break; 10288 1.1 christos } 10289 1.1 christos } 10290 1.1 christos 10291 1.1 christos /* Check the resources used by the given opcode against the current dependency 10292 1.1 christos list. 10293 1.1 christos 10294 1.1 christos The check is run once for each execution path encountered. In this case, 10295 1.1 christos a unique execution path is the sequence of instructions following a code 10296 1.1 christos entry point, e.g. the following has three execution paths, one starting 10297 1.1 christos at L0, one at L1, and one at L2. 10298 1.1 christos 10299 1.1 christos L0: nop 10300 1.1 christos L1: add 10301 1.1 christos L2: add 10302 1.1 christos br.ret 10303 1.1 christos */ 10304 1.1 christos 10305 1.1 christos static void 10306 1.1 christos check_dependencies (struct ia64_opcode *idesc) 10307 1.1 christos { 10308 1.1 christos const struct ia64_opcode_dependency *opdeps = idesc->dependencies; 10309 1.1 christos int path; 10310 1.1 christos int i; 10311 1.1 christos 10312 1.1 christos /* Note that the number of marked resources may change within the 10313 1.1 christos loop if in auto mode. */ 10314 1.1 christos i = 0; 10315 1.1 christos while (i < regdepslen) 10316 1.1 christos { 10317 1.1 christos struct rsrc *rs = ®deps[i]; 10318 1.1 christos const struct ia64_dependency *dep = rs->dependency; 10319 1.1 christos int chkind; 10320 1.1 christos int note; 10321 1.1 christos int start_over = 0; 10322 1.1 christos 10323 1.1 christos if (dep->semantics == IA64_DVS_NONE 10324 1.1 christos || (chkind = depends_on (rs->depind, idesc)) == -1) 10325 1.1 christos { 10326 1.1 christos ++i; 10327 1.1 christos continue; 10328 1.1 christos } 10329 1.1 christos 10330 1.1 christos note = NOTE (opdeps->chks[chkind]); 10331 1.1 christos 10332 1.1 christos /* Check this resource against each execution path seen thus far. */ 10333 1.1 christos for (path = 0; path <= md.path; path++) 10334 1.1 christos { 10335 1.1 christos int matchtype; 10336 1.1 christos 10337 1.1 christos /* If the dependency wasn't on the path being checked, ignore it. */ 10338 1.1 christos if (rs->path < path) 10339 1.1 christos continue; 10340 1.1 christos 10341 1.1 christos /* If the QP for this insn implies a QP which has branched, don't 10342 1.1 christos bother checking. Ed. NOTE: I don't think this check is terribly 10343 1.1 christos useful; what's the point of generating code which will only be 10344 1.1 christos reached if its QP is zero? 10345 1.1 christos This code was specifically inserted to handle the following code, 10346 1.1 christos based on notes from Intel's DV checking code, where p1 implies p2. 10347 1.1 christos 10348 1.1 christos mov r4 = 2 10349 1.1 christos (p2) br.cond L 10350 1.1 christos (p1) mov r4 = 7 10351 1.1 christos */ 10352 1.1 christos if (CURR_SLOT.qp_regno != 0) 10353 1.1 christos { 10354 1.1 christos int skip = 0; 10355 1.1 christos int implies; 10356 1.1 christos for (implies = 0; implies < qp_implieslen; implies++) 10357 1.1 christos { 10358 1.1 christos if (qp_implies[implies].path >= path 10359 1.1 christos && qp_implies[implies].p1 == CURR_SLOT.qp_regno 10360 1.1 christos && qp_implies[implies].p2_branched) 10361 1.1 christos { 10362 1.1 christos skip = 1; 10363 1.1 christos break; 10364 1.1 christos } 10365 1.1 christos } 10366 1.1 christos if (skip) 10367 1.1 christos continue; 10368 1.1 christos } 10369 1.1 christos 10370 1.1 christos if ((matchtype = resources_match (rs, idesc, note, 10371 1.1 christos CURR_SLOT.qp_regno, path)) != 0) 10372 1.1 christos { 10373 1.1 christos char msg[1024]; 10374 1.1 christos char pathmsg[256] = ""; 10375 1.1 christos char indexmsg[256] = ""; 10376 1.1 christos int certain = (matchtype == 1 && CURR_SLOT.qp_regno == 0); 10377 1.1 christos 10378 1.1 christos if (path != 0) 10379 1.1 christos snprintf (pathmsg, sizeof (pathmsg), 10380 1.1 christos " when entry is at label '%s'", 10381 1.1 christos md.entry_labels[path - 1]); 10382 1.1 christos if (matchtype == 1 && rs->index >= 0) 10383 1.1 christos snprintf (indexmsg, sizeof (indexmsg), 10384 1.1 christos ", specific resource number is %d", 10385 1.1 christos rs->index); 10386 1.1 christos snprintf (msg, sizeof (msg), 10387 1.1 christos "Use of '%s' %s %s dependency '%s' (%s)%s%s", 10388 1.1 christos idesc->name, 10389 1.1 christos (certain ? "violates" : "may violate"), 10390 1.1 christos dv_mode[dep->mode], dep->name, 10391 1.1 christos dv_sem[dep->semantics], 10392 1.1 christos pathmsg, indexmsg); 10393 1.1 christos 10394 1.1 christos if (md.explicit_mode) 10395 1.1 christos { 10396 1.1 christos as_warn ("%s", msg); 10397 1.1 christos if (path < md.path) 10398 1.1 christos as_warn (_("Only the first path encountering the conflict is reported")); 10399 1.1 christos as_warn_where (rs->file, rs->line, 10400 1.1 christos _("This is the location of the conflicting usage")); 10401 1.1 christos /* Don't bother checking other paths, to avoid duplicating 10402 1.1 christos the same warning */ 10403 1.1 christos break; 10404 1.1 christos } 10405 1.1 christos else 10406 1.1 christos { 10407 1.1 christos if (md.debug_dv) 10408 1.1 christos fprintf (stderr, "%s @ %s:%d\n", msg, rs->file, rs->line); 10409 1.1 christos 10410 1.1 christos remove_marked_resource (rs); 10411 1.1 christos 10412 1.1 christos /* since the set of dependencies has changed, start over */ 10413 1.1 christos /* FIXME -- since we're removing dvs as we go, we 10414 1.1 christos probably don't really need to start over... */ 10415 1.1 christos start_over = 1; 10416 1.1 christos break; 10417 1.1 christos } 10418 1.1 christos } 10419 1.1 christos } 10420 1.1 christos if (start_over) 10421 1.1 christos i = 0; 10422 1.1 christos else 10423 1.1 christos ++i; 10424 1.1 christos } 10425 1.1 christos } 10426 1.1 christos 10427 1.1 christos /* Register new dependencies based on the given opcode. */ 10428 1.1 christos 10429 1.1 christos static void 10430 1.1 christos mark_resources (struct ia64_opcode *idesc) 10431 1.1 christos { 10432 1.1 christos int i; 10433 1.1 christos const struct ia64_opcode_dependency *opdeps = idesc->dependencies; 10434 1.1 christos int add_only_qp_reads = 0; 10435 1.1 christos 10436 1.1 christos /* A conditional branch only uses its resources if it is taken; if it is 10437 1.1 christos taken, we stop following that path. The other branch types effectively 10438 1.1 christos *always* write their resources. If it's not taken, register only QP 10439 1.1 christos reads. */ 10440 1.1 christos if (is_conditional_branch (idesc) || is_interruption_or_rfi (idesc)) 10441 1.1 christos { 10442 1.1 christos add_only_qp_reads = 1; 10443 1.1 christos } 10444 1.1 christos 10445 1.1 christos if (md.debug_dv) 10446 1.1 christos fprintf (stderr, "Registering '%s' resource usage\n", idesc->name); 10447 1.1 christos 10448 1.1 christos for (i = 0; i < opdeps->nregs; i++) 10449 1.1 christos { 10450 1.1 christos const struct ia64_dependency *dep; 10451 1.1 christos struct rsrc specs[MAX_SPECS]; 10452 1.1 christos int note; 10453 1.1 christos int path; 10454 1.1 christos int count; 10455 1.1 christos 10456 1.1 christos dep = ia64_find_dependency (opdeps->regs[i]); 10457 1.1 christos note = NOTE (opdeps->regs[i]); 10458 1.1 christos 10459 1.1 christos if (add_only_qp_reads 10460 1.1 christos && !(dep->mode == IA64_DV_WAR 10461 1.1 christos && (dep->specifier == IA64_RS_PR 10462 1.1 christos || dep->specifier == IA64_RS_PRr 10463 1.1 christos || dep->specifier == IA64_RS_PR63))) 10464 1.1 christos continue; 10465 1.1 christos 10466 1.1 christos count = specify_resource (dep, idesc, DV_REG, specs, note, md.path); 10467 1.1 christos 10468 1.1 christos while (count-- > 0) 10469 1.1 christos { 10470 1.1 christos mark_resource (idesc, dep, &specs[count], 10471 1.1 christos DEP (opdeps->regs[i]), md.path); 10472 1.1 christos } 10473 1.1 christos 10474 1.1 christos /* The execution path may affect register values, which may in turn 10475 1.1 christos affect which indirect-access resources are accessed. */ 10476 1.1 christos switch (dep->specifier) 10477 1.1 christos { 10478 1.1 christos default: 10479 1.1 christos break; 10480 1.1 christos case IA64_RS_CPUID: 10481 1.1 christos case IA64_RS_DBR: 10482 1.1 christos case IA64_RS_IBR: 10483 1.1 christos case IA64_RS_MSR: 10484 1.1 christos case IA64_RS_PKR: 10485 1.1 christos case IA64_RS_PMC: 10486 1.1 christos case IA64_RS_PMD: 10487 1.1 christos case IA64_RS_RR: 10488 1.1 christos for (path = 0; path < md.path; path++) 10489 1.1 christos { 10490 1.1 christos count = specify_resource (dep, idesc, DV_REG, specs, note, path); 10491 1.1 christos while (count-- > 0) 10492 1.1 christos mark_resource (idesc, dep, &specs[count], 10493 1.1 christos DEP (opdeps->regs[i]), path); 10494 1.1 christos } 10495 1.1 christos break; 10496 1.1 christos } 10497 1.1 christos } 10498 1.1 christos } 10499 1.1 christos 10500 1.1 christos /* Remove dependencies when they no longer apply. */ 10501 1.1 christos 10502 1.1 christos static void 10503 1.1 christos update_dependencies (struct ia64_opcode *idesc) 10504 1.1 christos { 10505 1.1 christos int i; 10506 1.1 christos 10507 1.1 christos if (strcmp (idesc->name, "srlz.i") == 0) 10508 1.1 christos { 10509 1.1 christos instruction_serialization (); 10510 1.1 christos } 10511 1.1 christos else if (strcmp (idesc->name, "srlz.d") == 0) 10512 1.1 christos { 10513 1.1 christos data_serialization (); 10514 1.1 christos } 10515 1.1 christos else if (is_interruption_or_rfi (idesc) 10516 1.1 christos || is_taken_branch (idesc)) 10517 1.1 christos { 10518 1.1 christos /* Although technically the taken branch doesn't clear dependencies 10519 1.1 christos which require a srlz.[id], we don't follow the branch; the next 10520 1.1 christos instruction is assumed to start with a clean slate. */ 10521 1.1 christos regdepslen = 0; 10522 1.1 christos md.path = 0; 10523 1.1 christos } 10524 1.1 christos else if (is_conditional_branch (idesc) 10525 1.1 christos && CURR_SLOT.qp_regno != 0) 10526 1.1 christos { 10527 1.1 christos int is_call = strstr (idesc->name, ".call") != NULL; 10528 1.1 christos 10529 1.1 christos for (i = 0; i < qp_implieslen; i++) 10530 1.1 christos { 10531 1.1 christos /* If the conditional branch's predicate is implied by the predicate 10532 1.1 christos in an existing dependency, remove that dependency. */ 10533 1.1 christos if (qp_implies[i].p2 == CURR_SLOT.qp_regno) 10534 1.1 christos { 10535 1.1 christos int depind = 0; 10536 1.1 christos /* Note that this implied predicate takes a branch so that if 10537 1.1 christos a later insn generates a DV but its predicate implies this 10538 1.1 christos one, we can avoid the false DV warning. */ 10539 1.1 christos qp_implies[i].p2_branched = 1; 10540 1.1 christos while (depind < regdepslen) 10541 1.1 christos { 10542 1.1 christos if (regdeps[depind].qp_regno == qp_implies[i].p1) 10543 1.1 christos { 10544 1.1 christos print_dependency ("Removing", depind); 10545 1.1 christos regdeps[depind] = regdeps[--regdepslen]; 10546 1.1 christos } 10547 1.1 christos else 10548 1.1 christos ++depind; 10549 1.1 christos } 10550 1.1 christos } 10551 1.1 christos } 10552 1.1 christos /* Any marked resources which have this same predicate should be 10553 1.1 christos cleared, provided that the QP hasn't been modified between the 10554 1.1 christos marking instruction and the branch. */ 10555 1.1 christos if (is_call) 10556 1.1 christos { 10557 1.1 christos insn_group_break (0, CURR_SLOT.qp_regno, 1); 10558 1.1 christos } 10559 1.1 christos else 10560 1.1 christos { 10561 1.1 christos i = 0; 10562 1.1 christos while (i < regdepslen) 10563 1.1 christos { 10564 1.1 christos if (regdeps[i].qp_regno == CURR_SLOT.qp_regno 10565 1.1 christos && regdeps[i].link_to_qp_branch 10566 1.1 christos && (regdeps[i].file != CURR_SLOT.src_file 10567 1.1 christos || regdeps[i].line != CURR_SLOT.src_line)) 10568 1.1 christos { 10569 1.1 christos /* Treat like a taken branch */ 10570 1.1 christos print_dependency ("Removing", i); 10571 1.1 christos regdeps[i] = regdeps[--regdepslen]; 10572 1.1 christos } 10573 1.1 christos else 10574 1.1 christos ++i; 10575 1.1 christos } 10576 1.1 christos } 10577 1.1 christos } 10578 1.1 christos } 10579 1.1 christos 10580 1.1 christos /* Examine the current instruction for dependency violations. */ 10581 1.1 christos 10582 1.1 christos static int 10583 1.1 christos check_dv (struct ia64_opcode *idesc) 10584 1.1 christos { 10585 1.1 christos if (md.debug_dv) 10586 1.1 christos { 10587 1.1 christos fprintf (stderr, "Checking %s for violations (line %d, %d/%d)\n", 10588 1.1 christos idesc->name, CURR_SLOT.src_line, 10589 1.1 christos idesc->dependencies->nchks, 10590 1.1 christos idesc->dependencies->nregs); 10591 1.1 christos } 10592 1.1 christos 10593 1.1 christos /* Look through the list of currently marked resources; if the current 10594 1.1 christos instruction has the dependency in its chks list which uses that resource, 10595 1.1 christos check against the specific resources used. */ 10596 1.1 christos check_dependencies (idesc); 10597 1.1 christos 10598 1.1 christos /* Look up the instruction's regdeps (RAW writes, WAW writes, and WAR reads), 10599 1.1 christos then add them to the list of marked resources. */ 10600 1.1 christos mark_resources (idesc); 10601 1.1 christos 10602 1.1 christos /* There are several types of dependency semantics, and each has its own 10603 1.1 christos requirements for being cleared 10604 1.1 christos 10605 1.1 christos Instruction serialization (insns separated by interruption, rfi, or 10606 1.1 christos writer + srlz.i + reader, all in separate groups) clears DVS_INSTR. 10607 1.1 christos 10608 1.1 christos Data serialization (instruction serialization, or writer + srlz.d + 10609 1.1 christos reader, where writer and srlz.d are in separate groups) clears 10610 1.1 christos DVS_DATA. (This also clears DVS_OTHER, but that is not guaranteed to 10611 1.1 christos always be the case). 10612 1.1 christos 10613 1.1 christos Instruction group break (groups separated by stop, taken branch, 10614 1.1 christos interruption or rfi) clears DVS_IMPLIED and DVS_IMPLIEDF. 10615 1.1 christos */ 10616 1.1 christos update_dependencies (idesc); 10617 1.1 christos 10618 1.1 christos /* Sometimes, knowing a register value allows us to avoid giving a false DV 10619 1.1 christos warning. Keep track of as many as possible that are useful. */ 10620 1.1 christos note_register_values (idesc); 10621 1.1 christos 10622 1.1 christos /* We don't need or want this anymore. */ 10623 1.1 christos md.mem_offset.hint = 0; 10624 1.1 christos 10625 1.1 christos return 0; 10626 1.1 christos } 10627 1.1 christos 10628 1.1 christos /* Translate one line of assembly. Pseudo ops and labels do not show 10629 1.1 christos here. */ 10630 1.1 christos void 10631 1.1 christos md_assemble (char *str) 10632 1.1 christos { 10633 1.5 christos char *saved_input_line_pointer, *temp; 10634 1.5 christos const char *mnemonic; 10635 1.1 christos const struct pseudo_opcode *pdesc; 10636 1.1 christos struct ia64_opcode *idesc; 10637 1.1 christos unsigned char qp_regno; 10638 1.1 christos unsigned int flags; 10639 1.1 christos int ch; 10640 1.1 christos 10641 1.1 christos saved_input_line_pointer = input_line_pointer; 10642 1.1 christos input_line_pointer = str; 10643 1.1 christos 10644 1.1 christos /* extract the opcode (mnemonic): */ 10645 1.1 christos 10646 1.5 christos ch = get_symbol_name (&temp); 10647 1.5 christos mnemonic = temp; 10648 1.10 christos pdesc = str_hash_find (md.pseudo_hash, mnemonic); 10649 1.1 christos if (pdesc) 10650 1.1 christos { 10651 1.3 christos (void) restore_line_pointer (ch); 10652 1.1 christos (*pdesc->handler) (pdesc->arg); 10653 1.1 christos goto done; 10654 1.1 christos } 10655 1.1 christos 10656 1.1 christos /* Find the instruction descriptor matching the arguments. */ 10657 1.1 christos 10658 1.1 christos idesc = ia64_find_opcode (mnemonic); 10659 1.3 christos (void) restore_line_pointer (ch); 10660 1.1 christos if (!idesc) 10661 1.1 christos { 10662 1.1 christos as_bad (_("Unknown opcode `%s'"), mnemonic); 10663 1.1 christos goto done; 10664 1.1 christos } 10665 1.1 christos 10666 1.1 christos idesc = parse_operands (idesc); 10667 1.1 christos if (!idesc) 10668 1.1 christos goto done; 10669 1.1 christos 10670 1.1 christos /* Handle the dynamic ops we can handle now: */ 10671 1.1 christos if (idesc->type == IA64_TYPE_DYN) 10672 1.1 christos { 10673 1.1 christos if (strcmp (idesc->name, "add") == 0) 10674 1.1 christos { 10675 1.1 christos if (CURR_SLOT.opnd[2].X_op == O_register 10676 1.1 christos && CURR_SLOT.opnd[2].X_add_number < 4) 10677 1.1 christos mnemonic = "addl"; 10678 1.1 christos else 10679 1.1 christos mnemonic = "adds"; 10680 1.1 christos ia64_free_opcode (idesc); 10681 1.1 christos idesc = ia64_find_opcode (mnemonic); 10682 1.1 christos } 10683 1.1 christos else if (strcmp (idesc->name, "mov") == 0) 10684 1.1 christos { 10685 1.1 christos enum ia64_opnd opnd1, opnd2; 10686 1.1 christos int rop; 10687 1.1 christos 10688 1.1 christos opnd1 = idesc->operands[0]; 10689 1.1 christos opnd2 = idesc->operands[1]; 10690 1.1 christos if (opnd1 == IA64_OPND_AR3) 10691 1.1 christos rop = 0; 10692 1.1 christos else if (opnd2 == IA64_OPND_AR3) 10693 1.1 christos rop = 1; 10694 1.1 christos else 10695 1.1 christos abort (); 10696 1.1 christos if (CURR_SLOT.opnd[rop].X_op == O_register) 10697 1.1 christos { 10698 1.1 christos if (ar_is_only_in_integer_unit (CURR_SLOT.opnd[rop].X_add_number)) 10699 1.1 christos mnemonic = "mov.i"; 10700 1.1 christos else if (ar_is_only_in_memory_unit (CURR_SLOT.opnd[rop].X_add_number)) 10701 1.1 christos mnemonic = "mov.m"; 10702 1.1 christos else 10703 1.1 christos rop = -1; 10704 1.1 christos } 10705 1.1 christos else 10706 1.1 christos abort (); 10707 1.1 christos if (rop >= 0) 10708 1.1 christos { 10709 1.1 christos ia64_free_opcode (idesc); 10710 1.1 christos idesc = ia64_find_opcode (mnemonic); 10711 1.1 christos while (idesc != NULL 10712 1.1 christos && (idesc->operands[0] != opnd1 10713 1.1 christos || idesc->operands[1] != opnd2)) 10714 1.1 christos idesc = get_next_opcode (idesc); 10715 1.1 christos } 10716 1.1 christos } 10717 1.1 christos } 10718 1.1 christos else if (strcmp (idesc->name, "mov.i") == 0 10719 1.1 christos || strcmp (idesc->name, "mov.m") == 0) 10720 1.1 christos { 10721 1.1 christos enum ia64_opnd opnd1, opnd2; 10722 1.1 christos int rop; 10723 1.3 christos 10724 1.1 christos opnd1 = idesc->operands[0]; 10725 1.1 christos opnd2 = idesc->operands[1]; 10726 1.1 christos if (opnd1 == IA64_OPND_AR3) 10727 1.1 christos rop = 0; 10728 1.1 christos else if (opnd2 == IA64_OPND_AR3) 10729 1.1 christos rop = 1; 10730 1.1 christos else 10731 1.1 christos abort (); 10732 1.1 christos if (CURR_SLOT.opnd[rop].X_op == O_register) 10733 1.1 christos { 10734 1.1 christos char unit = 'a'; 10735 1.1 christos if (ar_is_only_in_integer_unit (CURR_SLOT.opnd[rop].X_add_number)) 10736 1.1 christos unit = 'i'; 10737 1.1 christos else if (ar_is_only_in_memory_unit (CURR_SLOT.opnd[rop].X_add_number)) 10738 1.1 christos unit = 'm'; 10739 1.1 christos if (unit != 'a' && unit != idesc->name [4]) 10740 1.1 christos as_bad (_("AR %d can only be accessed by %c-unit"), 10741 1.1 christos (int) (CURR_SLOT.opnd[rop].X_add_number - REG_AR), 10742 1.1 christos TOUPPER (unit)); 10743 1.1 christos } 10744 1.1 christos } 10745 1.1 christos else if (strcmp (idesc->name, "hint.b") == 0) 10746 1.1 christos { 10747 1.1 christos switch (md.hint_b) 10748 1.1 christos { 10749 1.1 christos case hint_b_ok: 10750 1.1 christos break; 10751 1.1 christos case hint_b_warning: 10752 1.1 christos as_warn (_("hint.b may be treated as nop")); 10753 1.1 christos break; 10754 1.1 christos case hint_b_error: 10755 1.1 christos as_bad (_("hint.b shouldn't be used")); 10756 1.1 christos break; 10757 1.1 christos } 10758 1.1 christos } 10759 1.1 christos 10760 1.1 christos qp_regno = 0; 10761 1.1 christos if (md.qp.X_op == O_register) 10762 1.1 christos { 10763 1.1 christos qp_regno = md.qp.X_add_number - REG_P; 10764 1.1 christos md.qp.X_op = O_absent; 10765 1.1 christos } 10766 1.1 christos 10767 1.1 christos flags = idesc->flags; 10768 1.1 christos 10769 1.1 christos if ((flags & IA64_OPCODE_FIRST) != 0) 10770 1.1 christos { 10771 1.1 christos /* The alignment frag has to end with a stop bit only if the 10772 1.1 christos next instruction after the alignment directive has to be 10773 1.1 christos the first instruction in an instruction group. */ 10774 1.1 christos if (align_frag) 10775 1.1 christos { 10776 1.1 christos while (align_frag->fr_type != rs_align_code) 10777 1.1 christos { 10778 1.1 christos align_frag = align_frag->fr_next; 10779 1.1 christos if (!align_frag) 10780 1.1 christos break; 10781 1.1 christos } 10782 1.1 christos /* align_frag can be NULL if there are directives in 10783 1.1 christos between. */ 10784 1.1 christos if (align_frag && align_frag->fr_next == frag_now) 10785 1.1 christos align_frag->tc_frag_data = 1; 10786 1.1 christos } 10787 1.1 christos 10788 1.1 christos insn_group_break (1, 0, 0); 10789 1.1 christos } 10790 1.1 christos align_frag = NULL; 10791 1.1 christos 10792 1.1 christos if ((flags & IA64_OPCODE_NO_PRED) != 0 && qp_regno != 0) 10793 1.1 christos { 10794 1.1 christos as_bad (_("`%s' cannot be predicated"), idesc->name); 10795 1.1 christos goto done; 10796 1.1 christos } 10797 1.1 christos 10798 1.1 christos /* Build the instruction. */ 10799 1.1 christos CURR_SLOT.qp_regno = qp_regno; 10800 1.1 christos CURR_SLOT.idesc = idesc; 10801 1.5 christos CURR_SLOT.src_file = as_where (&CURR_SLOT.src_line); 10802 1.1 christos dwarf2_where (&CURR_SLOT.debug_line); 10803 1.1 christos dwarf2_consume_line_info (); 10804 1.1 christos 10805 1.1 christos /* Add unwind entries, if there are any. */ 10806 1.1 christos if (unwind.current_entry) 10807 1.1 christos { 10808 1.1 christos CURR_SLOT.unwind_record = unwind.current_entry; 10809 1.1 christos unwind.current_entry = NULL; 10810 1.1 christos } 10811 1.1 christos if (unwind.pending_saves) 10812 1.1 christos { 10813 1.1 christos if (unwind.pending_saves->next) 10814 1.1 christos { 10815 1.1 christos /* Attach the next pending save to the next slot so that its 10816 1.1 christos slot number will get set correctly. */ 10817 1.1 christos add_unwind_entry (unwind.pending_saves->next, NOT_A_CHAR); 10818 1.1 christos unwind.pending_saves = &unwind.pending_saves->next->r.record.p; 10819 1.1 christos } 10820 1.1 christos else 10821 1.1 christos unwind.pending_saves = NULL; 10822 1.1 christos } 10823 1.1 christos if (unwind.proc_pending.sym && S_IS_DEFINED (unwind.proc_pending.sym)) 10824 1.1 christos unwind.insn = 1; 10825 1.1 christos 10826 1.1 christos /* Check for dependency violations. */ 10827 1.1 christos if (md.detect_dv) 10828 1.1 christos check_dv (idesc); 10829 1.1 christos 10830 1.1 christos md.curr_slot = (md.curr_slot + 1) % NUM_SLOTS; 10831 1.1 christos if (++md.num_slots_in_use >= NUM_SLOTS) 10832 1.1 christos emit_one_bundle (); 10833 1.1 christos 10834 1.1 christos if ((flags & IA64_OPCODE_LAST) != 0) 10835 1.1 christos insn_group_break (1, 0, 0); 10836 1.1 christos 10837 1.1 christos md.last_text_seg = now_seg; 10838 1.8 christos md.last_text_subseg = now_subseg; 10839 1.1 christos 10840 1.1 christos done: 10841 1.1 christos input_line_pointer = saved_input_line_pointer; 10842 1.1 christos } 10843 1.1 christos 10844 1.1 christos /* Called when symbol NAME cannot be found in the symbol table. 10845 1.1 christos Should be used for dynamic valued symbols only. */ 10846 1.1 christos 10847 1.1 christos symbolS * 10848 1.1 christos md_undefined_symbol (char *name ATTRIBUTE_UNUSED) 10849 1.1 christos { 10850 1.1 christos return 0; 10851 1.1 christos } 10852 1.1 christos 10853 1.1 christos /* Called for any expression that can not be recognized. When the 10854 1.1 christos function is called, `input_line_pointer' will point to the start of 10855 1.1 christos the expression. */ 10856 1.1 christos 10857 1.1 christos void 10858 1.1 christos md_operand (expressionS *e) 10859 1.1 christos { 10860 1.1 christos switch (*input_line_pointer) 10861 1.1 christos { 10862 1.1 christos case '[': 10863 1.1 christos ++input_line_pointer; 10864 1.1 christos expression_and_evaluate (e); 10865 1.1 christos if (*input_line_pointer != ']') 10866 1.1 christos { 10867 1.1 christos as_bad (_("Closing bracket missing")); 10868 1.1 christos goto err; 10869 1.1 christos } 10870 1.1 christos else 10871 1.1 christos { 10872 1.1 christos if (e->X_op != O_register 10873 1.1 christos || e->X_add_number < REG_GR 10874 1.1 christos || e->X_add_number > REG_GR + 127) 10875 1.1 christos { 10876 1.1 christos as_bad (_("Index must be a general register")); 10877 1.1 christos e->X_add_number = REG_GR; 10878 1.1 christos } 10879 1.1 christos 10880 1.1 christos ++input_line_pointer; 10881 1.1 christos e->X_op = O_index; 10882 1.1 christos } 10883 1.1 christos break; 10884 1.1 christos 10885 1.1 christos default: 10886 1.1 christos break; 10887 1.1 christos } 10888 1.1 christos return; 10889 1.1 christos 10890 1.1 christos err: 10891 1.1 christos ignore_rest_of_line (); 10892 1.1 christos } 10893 1.1 christos 10894 1.1 christos /* Return 1 if it's OK to adjust a reloc by replacing the symbol with 10895 1.1 christos a section symbol plus some offset. For relocs involving @fptr(), 10896 1.1 christos directives we don't want such adjustments since we need to have the 10897 1.1 christos original symbol's name in the reloc. */ 10898 1.1 christos int 10899 1.1 christos ia64_fix_adjustable (fixS *fix) 10900 1.1 christos { 10901 1.1 christos /* Prevent all adjustments to global symbols */ 10902 1.1 christos if (S_IS_EXTERNAL (fix->fx_addsy) || S_IS_WEAK (fix->fx_addsy)) 10903 1.1 christos return 0; 10904 1.1 christos 10905 1.1 christos switch (fix->fx_r_type) 10906 1.1 christos { 10907 1.1 christos case BFD_RELOC_IA64_FPTR64I: 10908 1.1 christos case BFD_RELOC_IA64_FPTR32MSB: 10909 1.1 christos case BFD_RELOC_IA64_FPTR32LSB: 10910 1.1 christos case BFD_RELOC_IA64_FPTR64MSB: 10911 1.1 christos case BFD_RELOC_IA64_FPTR64LSB: 10912 1.1 christos case BFD_RELOC_IA64_LTOFF_FPTR22: 10913 1.1 christos case BFD_RELOC_IA64_LTOFF_FPTR64I: 10914 1.1 christos return 0; 10915 1.1 christos default: 10916 1.1 christos break; 10917 1.1 christos } 10918 1.1 christos 10919 1.1 christos return 1; 10920 1.1 christos } 10921 1.1 christos 10922 1.1 christos int 10923 1.1 christos ia64_force_relocation (fixS *fix) 10924 1.1 christos { 10925 1.1 christos switch (fix->fx_r_type) 10926 1.1 christos { 10927 1.1 christos case BFD_RELOC_IA64_FPTR64I: 10928 1.1 christos case BFD_RELOC_IA64_FPTR32MSB: 10929 1.1 christos case BFD_RELOC_IA64_FPTR32LSB: 10930 1.1 christos case BFD_RELOC_IA64_FPTR64MSB: 10931 1.1 christos case BFD_RELOC_IA64_FPTR64LSB: 10932 1.1 christos 10933 1.1 christos case BFD_RELOC_IA64_LTOFF22: 10934 1.1 christos case BFD_RELOC_IA64_LTOFF64I: 10935 1.1 christos case BFD_RELOC_IA64_LTOFF_FPTR22: 10936 1.1 christos case BFD_RELOC_IA64_LTOFF_FPTR64I: 10937 1.1 christos case BFD_RELOC_IA64_PLTOFF22: 10938 1.1 christos case BFD_RELOC_IA64_PLTOFF64I: 10939 1.1 christos case BFD_RELOC_IA64_PLTOFF64MSB: 10940 1.1 christos case BFD_RELOC_IA64_PLTOFF64LSB: 10941 1.1 christos 10942 1.1 christos case BFD_RELOC_IA64_LTOFF22X: 10943 1.1 christos case BFD_RELOC_IA64_LDXMOV: 10944 1.1 christos return 1; 10945 1.1 christos 10946 1.1 christos default: 10947 1.1 christos break; 10948 1.1 christos } 10949 1.1 christos 10950 1.1 christos return generic_force_reloc (fix); 10951 1.1 christos } 10952 1.1 christos 10953 1.1 christos /* Decide from what point a pc-relative relocation is relative to, 10954 1.1 christos relative to the pc-relative fixup. Er, relatively speaking. */ 10955 1.1 christos long 10956 1.1 christos ia64_pcrel_from_section (fixS *fix, segT sec) 10957 1.1 christos { 10958 1.1 christos unsigned long off = fix->fx_frag->fr_address + fix->fx_where; 10959 1.1 christos 10960 1.7 christos if (bfd_section_flags (sec) & SEC_CODE) 10961 1.1 christos off &= ~0xfUL; 10962 1.1 christos 10963 1.1 christos return off; 10964 1.1 christos } 10965 1.1 christos 10966 1.1 christos 10967 1.1 christos /* Used to emit section-relative relocs for the dwarf2 debug data. */ 10968 1.1 christos void 10969 1.1 christos ia64_dwarf2_emit_offset (symbolS *symbol, unsigned int size) 10970 1.1 christos { 10971 1.1 christos expressionS exp; 10972 1.1 christos 10973 1.1 christos exp.X_op = O_pseudo_fixup; 10974 1.1 christos exp.X_op_symbol = pseudo_func[FUNC_SEC_RELATIVE].u.sym; 10975 1.1 christos exp.X_add_number = 0; 10976 1.1 christos exp.X_add_symbol = symbol; 10977 1.1 christos emit_expr (&exp, size); 10978 1.1 christos } 10979 1.1 christos 10980 1.1 christos /* This is called whenever some data item (not an instruction) needs a 10981 1.1 christos fixup. We pick the right reloc code depending on the byteorder 10982 1.1 christos currently in effect. */ 10983 1.1 christos void 10984 1.3 christos ia64_cons_fix_new (fragS *f, int where, int nbytes, expressionS *exp, 10985 1.3 christos bfd_reloc_code_real_type code) 10986 1.1 christos { 10987 1.1 christos fixS *fix; 10988 1.1 christos 10989 1.1 christos switch (nbytes) 10990 1.1 christos { 10991 1.1 christos /* There are no reloc for 8 and 16 bit quantities, but we allow 10992 1.1 christos them here since they will work fine as long as the expression 10993 1.1 christos is fully defined at the end of the pass over the source file. */ 10994 1.1 christos case 1: code = BFD_RELOC_8; break; 10995 1.1 christos case 2: code = BFD_RELOC_16; break; 10996 1.1 christos case 4: 10997 1.1 christos if (target_big_endian) 10998 1.1 christos code = BFD_RELOC_IA64_DIR32MSB; 10999 1.1 christos else 11000 1.1 christos code = BFD_RELOC_IA64_DIR32LSB; 11001 1.1 christos break; 11002 1.1 christos 11003 1.1 christos case 8: 11004 1.1 christos /* In 32-bit mode, data8 could mean function descriptors too. */ 11005 1.1 christos if (exp->X_op == O_pseudo_fixup 11006 1.1 christos && exp->X_op_symbol 11007 1.1 christos && S_GET_VALUE (exp->X_op_symbol) == FUNC_IPLT_RELOC 11008 1.1 christos && !(md.flags & EF_IA_64_ABI64)) 11009 1.1 christos { 11010 1.1 christos if (target_big_endian) 11011 1.1 christos code = BFD_RELOC_IA64_IPLTMSB; 11012 1.1 christos else 11013 1.1 christos code = BFD_RELOC_IA64_IPLTLSB; 11014 1.1 christos exp->X_op = O_symbol; 11015 1.1 christos break; 11016 1.1 christos } 11017 1.1 christos else 11018 1.1 christos { 11019 1.1 christos if (target_big_endian) 11020 1.1 christos code = BFD_RELOC_IA64_DIR64MSB; 11021 1.1 christos else 11022 1.1 christos code = BFD_RELOC_IA64_DIR64LSB; 11023 1.1 christos break; 11024 1.1 christos } 11025 1.1 christos 11026 1.1 christos case 16: 11027 1.1 christos if (exp->X_op == O_pseudo_fixup 11028 1.1 christos && exp->X_op_symbol 11029 1.1 christos && S_GET_VALUE (exp->X_op_symbol) == FUNC_IPLT_RELOC) 11030 1.1 christos { 11031 1.1 christos if (target_big_endian) 11032 1.1 christos code = BFD_RELOC_IA64_IPLTMSB; 11033 1.1 christos else 11034 1.1 christos code = BFD_RELOC_IA64_IPLTLSB; 11035 1.1 christos exp->X_op = O_symbol; 11036 1.1 christos break; 11037 1.1 christos } 11038 1.1 christos /* FALLTHRU */ 11039 1.1 christos 11040 1.1 christos default: 11041 1.1 christos as_bad (_("Unsupported fixup size %d"), nbytes); 11042 1.1 christos ignore_rest_of_line (); 11043 1.1 christos return; 11044 1.1 christos } 11045 1.1 christos 11046 1.1 christos if (exp->X_op == O_pseudo_fixup) 11047 1.1 christos { 11048 1.1 christos exp->X_op = O_symbol; 11049 1.1 christos code = ia64_gen_real_reloc_type (exp->X_op_symbol, code); 11050 1.1 christos /* ??? If code unchanged, unsupported. */ 11051 1.1 christos } 11052 1.1 christos 11053 1.1 christos fix = fix_new_exp (f, where, nbytes, exp, 0, code); 11054 1.1 christos /* We need to store the byte order in effect in case we're going 11055 1.1 christos to fix an 8 or 16 bit relocation (for which there no real 11056 1.1 christos relocs available). See md_apply_fix(). */ 11057 1.1 christos fix->tc_fix_data.bigendian = target_big_endian; 11058 1.1 christos } 11059 1.1 christos 11060 1.1 christos /* Return the actual relocation we wish to associate with the pseudo 11061 1.1 christos reloc described by SYM and R_TYPE. SYM should be one of the 11062 1.1 christos symbols in the pseudo_func array, or NULL. */ 11063 1.1 christos 11064 1.1 christos static bfd_reloc_code_real_type 11065 1.1 christos ia64_gen_real_reloc_type (struct symbol *sym, bfd_reloc_code_real_type r_type) 11066 1.1 christos { 11067 1.1 christos bfd_reloc_code_real_type newr = 0; 11068 1.1 christos const char *type = NULL, *suffix = ""; 11069 1.1 christos 11070 1.1 christos if (sym == NULL) 11071 1.1 christos { 11072 1.1 christos return r_type; 11073 1.1 christos } 11074 1.1 christos 11075 1.1 christos switch (S_GET_VALUE (sym)) 11076 1.1 christos { 11077 1.1 christos case FUNC_FPTR_RELATIVE: 11078 1.1 christos switch (r_type) 11079 1.1 christos { 11080 1.1 christos case BFD_RELOC_IA64_IMM64: newr = BFD_RELOC_IA64_FPTR64I; break; 11081 1.1 christos case BFD_RELOC_IA64_DIR32MSB: newr = BFD_RELOC_IA64_FPTR32MSB; break; 11082 1.1 christos case BFD_RELOC_IA64_DIR32LSB: newr = BFD_RELOC_IA64_FPTR32LSB; break; 11083 1.1 christos case BFD_RELOC_IA64_DIR64MSB: newr = BFD_RELOC_IA64_FPTR64MSB; break; 11084 1.1 christos case BFD_RELOC_IA64_DIR64LSB: newr = BFD_RELOC_IA64_FPTR64LSB; break; 11085 1.1 christos default: type = "FPTR"; break; 11086 1.1 christos } 11087 1.1 christos break; 11088 1.1 christos 11089 1.1 christos case FUNC_GP_RELATIVE: 11090 1.1 christos switch (r_type) 11091 1.1 christos { 11092 1.1 christos case BFD_RELOC_IA64_IMM22: newr = BFD_RELOC_IA64_GPREL22; break; 11093 1.1 christos case BFD_RELOC_IA64_IMM64: newr = BFD_RELOC_IA64_GPREL64I; break; 11094 1.1 christos case BFD_RELOC_IA64_DIR32MSB: newr = BFD_RELOC_IA64_GPREL32MSB; break; 11095 1.1 christos case BFD_RELOC_IA64_DIR32LSB: newr = BFD_RELOC_IA64_GPREL32LSB; break; 11096 1.1 christos case BFD_RELOC_IA64_DIR64MSB: newr = BFD_RELOC_IA64_GPREL64MSB; break; 11097 1.1 christos case BFD_RELOC_IA64_DIR64LSB: newr = BFD_RELOC_IA64_GPREL64LSB; break; 11098 1.1 christos default: type = "GPREL"; break; 11099 1.1 christos } 11100 1.1 christos break; 11101 1.1 christos 11102 1.1 christos case FUNC_LT_RELATIVE: 11103 1.1 christos switch (r_type) 11104 1.1 christos { 11105 1.1 christos case BFD_RELOC_IA64_IMM22: newr = BFD_RELOC_IA64_LTOFF22; break; 11106 1.1 christos case BFD_RELOC_IA64_IMM64: newr = BFD_RELOC_IA64_LTOFF64I; break; 11107 1.1 christos default: type = "LTOFF"; break; 11108 1.1 christos } 11109 1.1 christos break; 11110 1.1 christos 11111 1.1 christos case FUNC_LT_RELATIVE_X: 11112 1.1 christos switch (r_type) 11113 1.1 christos { 11114 1.1 christos case BFD_RELOC_IA64_IMM22: newr = BFD_RELOC_IA64_LTOFF22X; break; 11115 1.1 christos default: type = "LTOFF"; suffix = "X"; break; 11116 1.1 christos } 11117 1.1 christos break; 11118 1.1 christos 11119 1.1 christos case FUNC_PC_RELATIVE: 11120 1.1 christos switch (r_type) 11121 1.1 christos { 11122 1.1 christos case BFD_RELOC_IA64_IMM22: newr = BFD_RELOC_IA64_PCREL22; break; 11123 1.1 christos case BFD_RELOC_IA64_IMM64: newr = BFD_RELOC_IA64_PCREL64I; break; 11124 1.1 christos case BFD_RELOC_IA64_DIR32MSB: newr = BFD_RELOC_IA64_PCREL32MSB; break; 11125 1.1 christos case BFD_RELOC_IA64_DIR32LSB: newr = BFD_RELOC_IA64_PCREL32LSB; break; 11126 1.1 christos case BFD_RELOC_IA64_DIR64MSB: newr = BFD_RELOC_IA64_PCREL64MSB; break; 11127 1.1 christos case BFD_RELOC_IA64_DIR64LSB: newr = BFD_RELOC_IA64_PCREL64LSB; break; 11128 1.1 christos default: type = "PCREL"; break; 11129 1.1 christos } 11130 1.1 christos break; 11131 1.1 christos 11132 1.1 christos case FUNC_PLT_RELATIVE: 11133 1.1 christos switch (r_type) 11134 1.1 christos { 11135 1.1 christos case BFD_RELOC_IA64_IMM22: newr = BFD_RELOC_IA64_PLTOFF22; break; 11136 1.1 christos case BFD_RELOC_IA64_IMM64: newr = BFD_RELOC_IA64_PLTOFF64I; break; 11137 1.1 christos case BFD_RELOC_IA64_DIR64MSB: newr = BFD_RELOC_IA64_PLTOFF64MSB;break; 11138 1.1 christos case BFD_RELOC_IA64_DIR64LSB: newr = BFD_RELOC_IA64_PLTOFF64LSB;break; 11139 1.1 christos default: type = "PLTOFF"; break; 11140 1.1 christos } 11141 1.1 christos break; 11142 1.1 christos 11143 1.1 christos case FUNC_SEC_RELATIVE: 11144 1.1 christos switch (r_type) 11145 1.1 christos { 11146 1.1 christos case BFD_RELOC_IA64_DIR32MSB: newr = BFD_RELOC_IA64_SECREL32MSB;break; 11147 1.1 christos case BFD_RELOC_IA64_DIR32LSB: newr = BFD_RELOC_IA64_SECREL32LSB;break; 11148 1.1 christos case BFD_RELOC_IA64_DIR64MSB: newr = BFD_RELOC_IA64_SECREL64MSB;break; 11149 1.1 christos case BFD_RELOC_IA64_DIR64LSB: newr = BFD_RELOC_IA64_SECREL64LSB;break; 11150 1.1 christos default: type = "SECREL"; break; 11151 1.1 christos } 11152 1.1 christos break; 11153 1.1 christos 11154 1.1 christos case FUNC_SEG_RELATIVE: 11155 1.1 christos switch (r_type) 11156 1.1 christos { 11157 1.1 christos case BFD_RELOC_IA64_DIR32MSB: newr = BFD_RELOC_IA64_SEGREL32MSB;break; 11158 1.1 christos case BFD_RELOC_IA64_DIR32LSB: newr = BFD_RELOC_IA64_SEGREL32LSB;break; 11159 1.1 christos case BFD_RELOC_IA64_DIR64MSB: newr = BFD_RELOC_IA64_SEGREL64MSB;break; 11160 1.1 christos case BFD_RELOC_IA64_DIR64LSB: newr = BFD_RELOC_IA64_SEGREL64LSB;break; 11161 1.1 christos default: type = "SEGREL"; break; 11162 1.1 christos } 11163 1.1 christos break; 11164 1.1 christos 11165 1.1 christos case FUNC_LTV_RELATIVE: 11166 1.1 christos switch (r_type) 11167 1.1 christos { 11168 1.1 christos case BFD_RELOC_IA64_DIR32MSB: newr = BFD_RELOC_IA64_LTV32MSB; break; 11169 1.1 christos case BFD_RELOC_IA64_DIR32LSB: newr = BFD_RELOC_IA64_LTV32LSB; break; 11170 1.1 christos case BFD_RELOC_IA64_DIR64MSB: newr = BFD_RELOC_IA64_LTV64MSB; break; 11171 1.1 christos case BFD_RELOC_IA64_DIR64LSB: newr = BFD_RELOC_IA64_LTV64LSB; break; 11172 1.1 christos default: type = "LTV"; break; 11173 1.1 christos } 11174 1.1 christos break; 11175 1.1 christos 11176 1.1 christos case FUNC_LT_FPTR_RELATIVE: 11177 1.1 christos switch (r_type) 11178 1.1 christos { 11179 1.1 christos case BFD_RELOC_IA64_IMM22: 11180 1.1 christos newr = BFD_RELOC_IA64_LTOFF_FPTR22; break; 11181 1.1 christos case BFD_RELOC_IA64_IMM64: 11182 1.1 christos newr = BFD_RELOC_IA64_LTOFF_FPTR64I; break; 11183 1.1 christos case BFD_RELOC_IA64_DIR32MSB: 11184 1.1 christos newr = BFD_RELOC_IA64_LTOFF_FPTR32MSB; break; 11185 1.1 christos case BFD_RELOC_IA64_DIR32LSB: 11186 1.1 christos newr = BFD_RELOC_IA64_LTOFF_FPTR32LSB; break; 11187 1.1 christos case BFD_RELOC_IA64_DIR64MSB: 11188 1.1 christos newr = BFD_RELOC_IA64_LTOFF_FPTR64MSB; break; 11189 1.1 christos case BFD_RELOC_IA64_DIR64LSB: 11190 1.1 christos newr = BFD_RELOC_IA64_LTOFF_FPTR64LSB; break; 11191 1.1 christos default: 11192 1.1 christos type = "LTOFF_FPTR"; break; 11193 1.1 christos } 11194 1.1 christos break; 11195 1.1 christos 11196 1.1 christos case FUNC_TP_RELATIVE: 11197 1.1 christos switch (r_type) 11198 1.1 christos { 11199 1.1 christos case BFD_RELOC_IA64_IMM14: newr = BFD_RELOC_IA64_TPREL14; break; 11200 1.1 christos case BFD_RELOC_IA64_IMM22: newr = BFD_RELOC_IA64_TPREL22; break; 11201 1.1 christos case BFD_RELOC_IA64_IMM64: newr = BFD_RELOC_IA64_TPREL64I; break; 11202 1.1 christos case BFD_RELOC_IA64_DIR64MSB: newr = BFD_RELOC_IA64_TPREL64MSB; break; 11203 1.1 christos case BFD_RELOC_IA64_DIR64LSB: newr = BFD_RELOC_IA64_TPREL64LSB; break; 11204 1.1 christos default: type = "TPREL"; break; 11205 1.1 christos } 11206 1.1 christos break; 11207 1.1 christos 11208 1.1 christos case FUNC_LT_TP_RELATIVE: 11209 1.1 christos switch (r_type) 11210 1.1 christos { 11211 1.1 christos case BFD_RELOC_IA64_IMM22: 11212 1.1 christos newr = BFD_RELOC_IA64_LTOFF_TPREL22; break; 11213 1.1 christos default: 11214 1.1 christos type = "LTOFF_TPREL"; break; 11215 1.1 christos } 11216 1.1 christos break; 11217 1.1 christos 11218 1.1 christos case FUNC_DTP_MODULE: 11219 1.1 christos switch (r_type) 11220 1.1 christos { 11221 1.1 christos case BFD_RELOC_IA64_DIR64MSB: 11222 1.1 christos newr = BFD_RELOC_IA64_DTPMOD64MSB; break; 11223 1.1 christos case BFD_RELOC_IA64_DIR64LSB: 11224 1.1 christos newr = BFD_RELOC_IA64_DTPMOD64LSB; break; 11225 1.1 christos default: 11226 1.1 christos type = "DTPMOD"; break; 11227 1.1 christos } 11228 1.1 christos break; 11229 1.1 christos 11230 1.1 christos case FUNC_LT_DTP_MODULE: 11231 1.1 christos switch (r_type) 11232 1.1 christos { 11233 1.1 christos case BFD_RELOC_IA64_IMM22: 11234 1.1 christos newr = BFD_RELOC_IA64_LTOFF_DTPMOD22; break; 11235 1.1 christos default: 11236 1.1 christos type = "LTOFF_DTPMOD"; break; 11237 1.1 christos } 11238 1.1 christos break; 11239 1.1 christos 11240 1.1 christos case FUNC_DTP_RELATIVE: 11241 1.1 christos switch (r_type) 11242 1.1 christos { 11243 1.1 christos case BFD_RELOC_IA64_DIR32MSB: 11244 1.1 christos newr = BFD_RELOC_IA64_DTPREL32MSB; break; 11245 1.1 christos case BFD_RELOC_IA64_DIR32LSB: 11246 1.1 christos newr = BFD_RELOC_IA64_DTPREL32LSB; break; 11247 1.1 christos case BFD_RELOC_IA64_DIR64MSB: 11248 1.1 christos newr = BFD_RELOC_IA64_DTPREL64MSB; break; 11249 1.1 christos case BFD_RELOC_IA64_DIR64LSB: 11250 1.1 christos newr = BFD_RELOC_IA64_DTPREL64LSB; break; 11251 1.1 christos case BFD_RELOC_IA64_IMM14: 11252 1.1 christos newr = BFD_RELOC_IA64_DTPREL14; break; 11253 1.1 christos case BFD_RELOC_IA64_IMM22: 11254 1.1 christos newr = BFD_RELOC_IA64_DTPREL22; break; 11255 1.1 christos case BFD_RELOC_IA64_IMM64: 11256 1.1 christos newr = BFD_RELOC_IA64_DTPREL64I; break; 11257 1.1 christos default: 11258 1.1 christos type = "DTPREL"; break; 11259 1.1 christos } 11260 1.1 christos break; 11261 1.1 christos 11262 1.1 christos case FUNC_LT_DTP_RELATIVE: 11263 1.1 christos switch (r_type) 11264 1.1 christos { 11265 1.1 christos case BFD_RELOC_IA64_IMM22: 11266 1.1 christos newr = BFD_RELOC_IA64_LTOFF_DTPREL22; break; 11267 1.1 christos default: 11268 1.1 christos type = "LTOFF_DTPREL"; break; 11269 1.1 christos } 11270 1.1 christos break; 11271 1.1 christos 11272 1.1 christos case FUNC_IPLT_RELOC: 11273 1.1 christos switch (r_type) 11274 1.1 christos { 11275 1.1 christos case BFD_RELOC_IA64_IPLTMSB: return r_type; 11276 1.1 christos case BFD_RELOC_IA64_IPLTLSB: return r_type; 11277 1.1 christos default: type = "IPLT"; break; 11278 1.1 christos } 11279 1.1 christos break; 11280 1.1 christos 11281 1.1 christos #ifdef TE_VMS 11282 1.1 christos case FUNC_SLOTCOUNT_RELOC: 11283 1.1 christos return DUMMY_RELOC_IA64_SLOTCOUNT; 11284 1.1 christos #endif 11285 1.1 christos 11286 1.1 christos default: 11287 1.1 christos abort (); 11288 1.1 christos } 11289 1.1 christos 11290 1.1 christos if (newr) 11291 1.1 christos return newr; 11292 1.1 christos else 11293 1.1 christos { 11294 1.1 christos int width; 11295 1.1 christos 11296 1.1 christos if (!type) 11297 1.1 christos abort (); 11298 1.1 christos switch (r_type) 11299 1.1 christos { 11300 1.1 christos case BFD_RELOC_IA64_DIR32MSB: width = 32; suffix = "MSB"; break; 11301 1.1 christos case BFD_RELOC_IA64_DIR32LSB: width = 32; suffix = "LSB"; break; 11302 1.1 christos case BFD_RELOC_IA64_DIR64MSB: width = 64; suffix = "MSB"; break; 11303 1.1 christos case BFD_RELOC_IA64_DIR64LSB: width = 64; suffix = "LSB"; break; 11304 1.1 christos case BFD_RELOC_UNUSED: width = 13; break; 11305 1.1 christos case BFD_RELOC_IA64_IMM14: width = 14; break; 11306 1.1 christos case BFD_RELOC_IA64_IMM22: width = 22; break; 11307 1.1 christos case BFD_RELOC_IA64_IMM64: width = 64; suffix = "I"; break; 11308 1.1 christos default: abort (); 11309 1.1 christos } 11310 1.1 christos 11311 1.1 christos /* This should be an error, but since previously there wasn't any 11312 1.1 christos diagnostic here, don't make it fail because of this for now. */ 11313 1.1 christos as_warn (_("Cannot express %s%d%s relocation"), type, width, suffix); 11314 1.1 christos return r_type; 11315 1.1 christos } 11316 1.1 christos } 11317 1.1 christos 11318 1.1 christos /* Here is where generate the appropriate reloc for pseudo relocation 11319 1.1 christos functions. */ 11320 1.1 christos void 11321 1.1 christos ia64_validate_fix (fixS *fix) 11322 1.1 christos { 11323 1.1 christos switch (fix->fx_r_type) 11324 1.1 christos { 11325 1.1 christos case BFD_RELOC_IA64_FPTR64I: 11326 1.1 christos case BFD_RELOC_IA64_FPTR32MSB: 11327 1.1 christos case BFD_RELOC_IA64_FPTR64LSB: 11328 1.1 christos case BFD_RELOC_IA64_LTOFF_FPTR22: 11329 1.1 christos case BFD_RELOC_IA64_LTOFF_FPTR64I: 11330 1.1 christos if (fix->fx_offset != 0) 11331 1.1 christos as_bad_where (fix->fx_file, fix->fx_line, 11332 1.1 christos _("No addend allowed in @fptr() relocation")); 11333 1.1 christos break; 11334 1.1 christos default: 11335 1.1 christos break; 11336 1.1 christos } 11337 1.1 christos } 11338 1.1 christos 11339 1.1 christos static void 11340 1.1 christos fix_insn (fixS *fix, const struct ia64_operand *odesc, valueT value) 11341 1.1 christos { 11342 1.1 christos bfd_vma insn[3], t0, t1, control_bits; 11343 1.1 christos const char *err; 11344 1.1 christos char *fixpos; 11345 1.1 christos long slot; 11346 1.1 christos 11347 1.1 christos slot = fix->fx_where & 0x3; 11348 1.1 christos fixpos = fix->fx_frag->fr_literal + (fix->fx_where - slot); 11349 1.1 christos 11350 1.1 christos /* Bundles are always in little-endian byte order */ 11351 1.1 christos t0 = bfd_getl64 (fixpos); 11352 1.1 christos t1 = bfd_getl64 (fixpos + 8); 11353 1.1 christos control_bits = t0 & 0x1f; 11354 1.1 christos insn[0] = (t0 >> 5) & 0x1ffffffffffLL; 11355 1.1 christos insn[1] = ((t0 >> 46) & 0x3ffff) | ((t1 & 0x7fffff) << 18); 11356 1.1 christos insn[2] = (t1 >> 23) & 0x1ffffffffffLL; 11357 1.1 christos 11358 1.1 christos err = NULL; 11359 1.1 christos if (odesc - elf64_ia64_operands == IA64_OPND_IMMU64) 11360 1.1 christos { 11361 1.1 christos insn[1] = (value >> 22) & 0x1ffffffffffLL; 11362 1.1 christos insn[2] |= (((value & 0x7f) << 13) 11363 1.1 christos | (((value >> 7) & 0x1ff) << 27) 11364 1.1 christos | (((value >> 16) & 0x1f) << 22) 11365 1.1 christos | (((value >> 21) & 0x1) << 21) 11366 1.1 christos | (((value >> 63) & 0x1) << 36)); 11367 1.1 christos } 11368 1.1 christos else if (odesc - elf64_ia64_operands == IA64_OPND_IMMU62) 11369 1.1 christos { 11370 1.1 christos if (value & ~0x3fffffffffffffffULL) 11371 1.1 christos err = _("integer operand out of range"); 11372 1.1 christos insn[1] = (value >> 21) & 0x1ffffffffffLL; 11373 1.1 christos insn[2] |= (((value & 0xfffff) << 6) | (((value >> 20) & 0x1) << 36)); 11374 1.1 christos } 11375 1.1 christos else if (odesc - elf64_ia64_operands == IA64_OPND_TGT64) 11376 1.1 christos { 11377 1.1 christos value >>= 4; 11378 1.1 christos insn[1] = ((value >> 20) & 0x7fffffffffLL) << 2; 11379 1.1 christos insn[2] |= ((((value >> 59) & 0x1) << 36) 11380 1.1 christos | (((value >> 0) & 0xfffff) << 13)); 11381 1.1 christos } 11382 1.1 christos else 11383 1.1 christos err = (*odesc->insert) (odesc, value, insn + slot); 11384 1.1 christos 11385 1.1 christos if (err) 11386 1.1 christos as_bad_where (fix->fx_file, fix->fx_line, "%s", err); 11387 1.1 christos 11388 1.1 christos t0 = control_bits | (insn[0] << 5) | (insn[1] << 46); 11389 1.1 christos t1 = ((insn[1] >> 18) & 0x7fffff) | (insn[2] << 23); 11390 1.1 christos number_to_chars_littleendian (fixpos + 0, t0, 8); 11391 1.1 christos number_to_chars_littleendian (fixpos + 8, t1, 8); 11392 1.1 christos } 11393 1.1 christos 11394 1.1 christos /* Attempt to simplify or even eliminate a fixup. The return value is 11395 1.1 christos ignored; perhaps it was once meaningful, but now it is historical. 11396 1.1 christos To indicate that a fixup has been eliminated, set FIXP->FX_DONE. 11397 1.1 christos 11398 1.1 christos If fixp->fx_addsy is non-NULL, we'll have to generate a reloc entry 11399 1.1 christos (if possible). */ 11400 1.1 christos 11401 1.1 christos void 11402 1.1 christos md_apply_fix (fixS *fix, valueT *valP, segT seg ATTRIBUTE_UNUSED) 11403 1.1 christos { 11404 1.1 christos char *fixpos; 11405 1.1 christos valueT value = *valP; 11406 1.1 christos 11407 1.1 christos fixpos = fix->fx_frag->fr_literal + fix->fx_where; 11408 1.1 christos 11409 1.1 christos if (fix->fx_pcrel) 11410 1.1 christos { 11411 1.1 christos switch (fix->fx_r_type) 11412 1.1 christos { 11413 1.1 christos case BFD_RELOC_IA64_PCREL21B: break; 11414 1.1 christos case BFD_RELOC_IA64_PCREL21BI: break; 11415 1.1 christos case BFD_RELOC_IA64_PCREL21F: break; 11416 1.1 christos case BFD_RELOC_IA64_PCREL21M: break; 11417 1.1 christos case BFD_RELOC_IA64_PCREL60B: break; 11418 1.1 christos case BFD_RELOC_IA64_PCREL22: break; 11419 1.1 christos case BFD_RELOC_IA64_PCREL64I: break; 11420 1.1 christos case BFD_RELOC_IA64_PCREL32MSB: break; 11421 1.1 christos case BFD_RELOC_IA64_PCREL32LSB: break; 11422 1.1 christos case BFD_RELOC_IA64_PCREL64MSB: break; 11423 1.1 christos case BFD_RELOC_IA64_PCREL64LSB: break; 11424 1.1 christos default: 11425 1.1 christos fix->fx_r_type = ia64_gen_real_reloc_type (pseudo_func[FUNC_PC_RELATIVE].u.sym, 11426 1.1 christos fix->fx_r_type); 11427 1.1 christos break; 11428 1.1 christos } 11429 1.1 christos } 11430 1.1 christos if (fix->fx_addsy) 11431 1.1 christos { 11432 1.1 christos switch ((unsigned) fix->fx_r_type) 11433 1.1 christos { 11434 1.1 christos case BFD_RELOC_UNUSED: 11435 1.1 christos /* This must be a TAG13 or TAG13b operand. There are no external 11436 1.1 christos relocs defined for them, so we must give an error. */ 11437 1.1 christos as_bad_where (fix->fx_file, fix->fx_line, 11438 1.1 christos _("%s must have a constant value"), 11439 1.1 christos elf64_ia64_operands[fix->tc_fix_data.opnd].desc); 11440 1.1 christos fix->fx_done = 1; 11441 1.1 christos return; 11442 1.1 christos 11443 1.1 christos case BFD_RELOC_IA64_TPREL14: 11444 1.1 christos case BFD_RELOC_IA64_TPREL22: 11445 1.1 christos case BFD_RELOC_IA64_TPREL64I: 11446 1.1 christos case BFD_RELOC_IA64_LTOFF_TPREL22: 11447 1.1 christos case BFD_RELOC_IA64_LTOFF_DTPMOD22: 11448 1.1 christos case BFD_RELOC_IA64_DTPREL14: 11449 1.1 christos case BFD_RELOC_IA64_DTPREL22: 11450 1.1 christos case BFD_RELOC_IA64_DTPREL64I: 11451 1.1 christos case BFD_RELOC_IA64_LTOFF_DTPREL22: 11452 1.1 christos S_SET_THREAD_LOCAL (fix->fx_addsy); 11453 1.1 christos break; 11454 1.1 christos 11455 1.1 christos #ifdef TE_VMS 11456 1.1 christos case DUMMY_RELOC_IA64_SLOTCOUNT: 11457 1.1 christos as_bad_where (fix->fx_file, fix->fx_line, 11458 1.1 christos _("cannot resolve @slotcount parameter")); 11459 1.1 christos fix->fx_done = 1; 11460 1.1 christos return; 11461 1.1 christos #endif 11462 1.1 christos 11463 1.1 christos default: 11464 1.1 christos break; 11465 1.1 christos } 11466 1.1 christos } 11467 1.1 christos else if (fix->tc_fix_data.opnd == IA64_OPND_NIL) 11468 1.1 christos { 11469 1.1 christos #ifdef TE_VMS 11470 1.1 christos if (fix->fx_r_type == DUMMY_RELOC_IA64_SLOTCOUNT) 11471 1.1 christos { 11472 1.1 christos /* For @slotcount, convert an addresses difference to a slots 11473 1.1 christos difference. */ 11474 1.1 christos valueT v; 11475 1.1 christos 11476 1.1 christos v = (value >> 4) * 3; 11477 1.1 christos switch (value & 0x0f) 11478 1.1 christos { 11479 1.1 christos case 0: 11480 1.1 christos case 1: 11481 1.1 christos case 2: 11482 1.1 christos v += value & 0x0f; 11483 1.1 christos break; 11484 1.1 christos case 0x0f: 11485 1.1 christos v += 2; 11486 1.1 christos break; 11487 1.1 christos case 0x0e: 11488 1.1 christos v += 1; 11489 1.1 christos break; 11490 1.1 christos default: 11491 1.1 christos as_bad (_("invalid @slotcount value")); 11492 1.1 christos } 11493 1.1 christos value = v; 11494 1.1 christos } 11495 1.1 christos #endif 11496 1.1 christos 11497 1.1 christos if (fix->tc_fix_data.bigendian) 11498 1.1 christos number_to_chars_bigendian (fixpos, value, fix->fx_size); 11499 1.1 christos else 11500 1.1 christos number_to_chars_littleendian (fixpos, value, fix->fx_size); 11501 1.1 christos fix->fx_done = 1; 11502 1.1 christos } 11503 1.1 christos else 11504 1.1 christos { 11505 1.1 christos fix_insn (fix, elf64_ia64_operands + fix->tc_fix_data.opnd, value); 11506 1.1 christos fix->fx_done = 1; 11507 1.1 christos } 11508 1.1 christos } 11509 1.1 christos 11510 1.1 christos /* Generate the BFD reloc to be stuck in the object file from the 11511 1.1 christos fixup used internally in the assembler. */ 11512 1.1 christos 11513 1.1 christos arelent * 11514 1.1 christos tc_gen_reloc (asection *sec ATTRIBUTE_UNUSED, fixS *fixp) 11515 1.1 christos { 11516 1.1 christos arelent *reloc; 11517 1.1 christos 11518 1.10 christos reloc = notes_alloc (sizeof (arelent)); 11519 1.10 christos reloc->sym_ptr_ptr = notes_alloc (sizeof (asymbol *)); 11520 1.1 christos *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); 11521 1.1 christos reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; 11522 1.1 christos reloc->addend = fixp->fx_offset; 11523 1.1 christos reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type); 11524 1.1 christos 11525 1.1 christos if (!reloc->howto) 11526 1.1 christos { 11527 1.1 christos as_bad_where (fixp->fx_file, fixp->fx_line, 11528 1.1 christos _("Cannot represent %s relocation in object file"), 11529 1.1 christos bfd_get_reloc_code_name (fixp->fx_r_type)); 11530 1.1 christos return NULL; 11531 1.1 christos } 11532 1.1 christos return reloc; 11533 1.1 christos } 11534 1.1 christos 11535 1.1 christos /* Turn a string in input_line_pointer into a floating point constant 11536 1.1 christos of type TYPE, and store the appropriate bytes in *LIT. The number 11537 1.1 christos of LITTLENUMS emitted is stored in *SIZE. An error message is 11538 1.1 christos returned, or NULL on OK. */ 11539 1.1 christos 11540 1.5 christos const char * 11541 1.1 christos md_atof (int type, char *lit, int *size) 11542 1.1 christos { 11543 1.1 christos LITTLENUM_TYPE words[MAX_LITTLENUMS]; 11544 1.1 christos char *t; 11545 1.1 christos int prec; 11546 1.1 christos 11547 1.1 christos switch (type) 11548 1.1 christos { 11549 1.1 christos /* IEEE floats */ 11550 1.1 christos case 'f': 11551 1.1 christos case 'F': 11552 1.1 christos case 's': 11553 1.1 christos case 'S': 11554 1.1 christos prec = 2; 11555 1.1 christos break; 11556 1.1 christos 11557 1.1 christos case 'd': 11558 1.1 christos case 'D': 11559 1.1 christos case 'r': 11560 1.1 christos case 'R': 11561 1.1 christos prec = 4; 11562 1.1 christos break; 11563 1.1 christos 11564 1.1 christos case 'x': 11565 1.1 christos case 'X': 11566 1.1 christos case 'p': 11567 1.1 christos case 'P': 11568 1.1 christos prec = 5; 11569 1.1 christos break; 11570 1.1 christos 11571 1.1 christos default: 11572 1.1 christos *size = 0; 11573 1.1 christos return _("Unrecognized or unsupported floating point constant"); 11574 1.1 christos } 11575 1.1 christos t = atof_ieee (input_line_pointer, type, words); 11576 1.1 christos if (t) 11577 1.1 christos input_line_pointer = t; 11578 1.1 christos 11579 1.1 christos (*ia64_float_to_chars) (lit, words, prec); 11580 1.1 christos 11581 1.1 christos if (type == 'X') 11582 1.1 christos { 11583 1.1 christos /* It is 10 byte floating point with 6 byte padding. */ 11584 1.1 christos memset (&lit [10], 0, 6); 11585 1.1 christos *size = 8 * sizeof (LITTLENUM_TYPE); 11586 1.1 christos } 11587 1.1 christos else 11588 1.1 christos *size = prec * sizeof (LITTLENUM_TYPE); 11589 1.1 christos 11590 1.1 christos return NULL; 11591 1.1 christos } 11592 1.1 christos 11593 1.1 christos /* Handle ia64 specific semantics of the align directive. */ 11594 1.1 christos 11595 1.1 christos void 11596 1.1 christos ia64_md_do_align (int n ATTRIBUTE_UNUSED, 11597 1.1 christos const char *fill ATTRIBUTE_UNUSED, 11598 1.1 christos int len ATTRIBUTE_UNUSED, 11599 1.1 christos int max ATTRIBUTE_UNUSED) 11600 1.1 christos { 11601 1.1 christos if (subseg_text_p (now_seg)) 11602 1.1 christos ia64_flush_insns (); 11603 1.1 christos } 11604 1.1 christos 11605 1.1 christos /* This is called from HANDLE_ALIGN in write.c. Fill in the contents 11606 1.1 christos of an rs_align_code fragment. */ 11607 1.1 christos 11608 1.1 christos void 11609 1.1 christos ia64_handle_align (fragS *fragp) 11610 1.1 christos { 11611 1.1 christos int bytes; 11612 1.1 christos char *p; 11613 1.1 christos const unsigned char *nop_type; 11614 1.1 christos 11615 1.1 christos if (fragp->fr_type != rs_align_code) 11616 1.1 christos return; 11617 1.1 christos 11618 1.1 christos /* Check if this frag has to end with a stop bit. */ 11619 1.1 christos nop_type = fragp->tc_frag_data ? le_nop_stop : le_nop; 11620 1.1 christos 11621 1.1 christos bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix; 11622 1.1 christos p = fragp->fr_literal + fragp->fr_fix; 11623 1.1 christos 11624 1.3 christos /* If no paddings are needed, we check if we need a stop bit. */ 11625 1.1 christos if (!bytes && fragp->tc_frag_data) 11626 1.1 christos { 11627 1.1 christos if (fragp->fr_fix < 16) 11628 1.1 christos #if 1 11629 1.1 christos /* FIXME: It won't work with 11630 1.1 christos .align 16 11631 1.1 christos alloc r32=ar.pfs,1,2,4,0 11632 1.1 christos */ 11633 1.1 christos ; 11634 1.1 christos #else 11635 1.1 christos as_bad_where (fragp->fr_file, fragp->fr_line, 11636 1.1 christos _("Can't add stop bit to mark end of instruction group")); 11637 1.1 christos #endif 11638 1.1 christos else 11639 1.1 christos /* Bundles are always in little-endian byte order. Make sure 11640 1.1 christos the previous bundle has the stop bit. */ 11641 1.1 christos *(p - 16) |= 1; 11642 1.1 christos } 11643 1.1 christos 11644 1.1 christos /* Make sure we are on a 16-byte boundary, in case someone has been 11645 1.1 christos putting data into a text section. */ 11646 1.1 christos if (bytes & 15) 11647 1.1 christos { 11648 1.1 christos int fix = bytes & 15; 11649 1.1 christos memset (p, 0, fix); 11650 1.1 christos p += fix; 11651 1.1 christos bytes -= fix; 11652 1.1 christos fragp->fr_fix += fix; 11653 1.1 christos } 11654 1.1 christos 11655 1.1 christos /* Instruction bundles are always little-endian. */ 11656 1.1 christos memcpy (p, nop_type, 16); 11657 1.1 christos fragp->fr_var = 16; 11658 1.1 christos } 11659 1.1 christos 11660 1.1 christos static void 11661 1.1 christos ia64_float_to_chars_bigendian (char *lit, LITTLENUM_TYPE *words, 11662 1.1 christos int prec) 11663 1.1 christos { 11664 1.1 christos while (prec--) 11665 1.1 christos { 11666 1.10 christos number_to_chars_bigendian (lit, *words++, sizeof (LITTLENUM_TYPE)); 11667 1.1 christos lit += sizeof (LITTLENUM_TYPE); 11668 1.1 christos } 11669 1.1 christos } 11670 1.1 christos 11671 1.1 christos static void 11672 1.1 christos ia64_float_to_chars_littleendian (char *lit, LITTLENUM_TYPE *words, 11673 1.1 christos int prec) 11674 1.1 christos { 11675 1.1 christos while (prec--) 11676 1.1 christos { 11677 1.10 christos number_to_chars_littleendian (lit, words[prec], 11678 1.1 christos sizeof (LITTLENUM_TYPE)); 11679 1.1 christos lit += sizeof (LITTLENUM_TYPE); 11680 1.1 christos } 11681 1.1 christos } 11682 1.1 christos 11683 1.1 christos void 11684 1.1 christos ia64_elf_section_change_hook (void) 11685 1.1 christos { 11686 1.1 christos if (elf_section_type (now_seg) == SHT_IA_64_UNWIND 11687 1.1 christos && elf_linked_to_section (now_seg) == NULL) 11688 1.1 christos elf_linked_to_section (now_seg) = text_section; 11689 1.1 christos dot_byteorder (-1); 11690 1.1 christos } 11691 1.1 christos 11692 1.1 christos /* Check if a label should be made global. */ 11693 1.1 christos void 11694 1.1 christos ia64_check_label (symbolS *label) 11695 1.1 christos { 11696 1.1 christos if (*input_line_pointer == ':') 11697 1.1 christos { 11698 1.1 christos S_SET_EXTERNAL (label); 11699 1.1 christos input_line_pointer++; 11700 1.1 christos } 11701 1.1 christos } 11702 1.1 christos 11703 1.1 christos /* Used to remember where .alias and .secalias directives are seen. We 11704 1.1 christos will rename symbol and section names when we are about to output 11705 1.1 christos the relocatable file. */ 11706 1.1 christos struct alias 11707 1.1 christos { 11708 1.5 christos const char *file; /* The file where the directive is seen. */ 11709 1.1 christos unsigned int line; /* The line number the directive is at. */ 11710 1.1 christos const char *name; /* The original name of the symbol. */ 11711 1.1 christos }; 11712 1.1 christos 11713 1.1 christos /* Called for .alias and .secalias directives. If SECTION is 1, it is 11714 1.1 christos .secalias. Otherwise, it is .alias. */ 11715 1.1 christos static void 11716 1.1 christos dot_alias (int section) 11717 1.1 christos { 11718 1.1 christos char *name, *alias; 11719 1.1 christos char delim; 11720 1.1 christos char *end_name; 11721 1.1 christos int len; 11722 1.1 christos struct alias *h; 11723 1.1 christos const char *a; 11724 1.8 christos htab_t ahash, nhash; 11725 1.1 christos const char *kind; 11726 1.1 christos 11727 1.3 christos delim = get_symbol_name (&name); 11728 1.1 christos end_name = input_line_pointer; 11729 1.10 christos restore_line_pointer (delim); 11730 1.1 christos 11731 1.1 christos if (name == end_name) 11732 1.1 christos { 11733 1.1 christos as_bad (_("expected symbol name")); 11734 1.1 christos ignore_rest_of_line (); 11735 1.1 christos return; 11736 1.1 christos } 11737 1.1 christos 11738 1.10 christos SKIP_WHITESPACE (); 11739 1.1 christos 11740 1.1 christos if (*input_line_pointer != ',') 11741 1.1 christos { 11742 1.1 christos *end_name = 0; 11743 1.1 christos as_bad (_("expected comma after \"%s\""), name); 11744 1.1 christos *end_name = delim; 11745 1.1 christos ignore_rest_of_line (); 11746 1.1 christos return; 11747 1.1 christos } 11748 1.1 christos 11749 1.1 christos input_line_pointer++; 11750 1.1 christos *end_name = 0; 11751 1.1 christos ia64_canonicalize_symbol_name (name); 11752 1.1 christos 11753 1.1 christos /* We call demand_copy_C_string to check if alias string is valid. 11754 1.1 christos There should be a closing `"' and no `\0' in the string. */ 11755 1.1 christos alias = demand_copy_C_string (&len); 11756 1.1 christos if (alias == NULL) 11757 1.1 christos { 11758 1.1 christos ignore_rest_of_line (); 11759 1.1 christos return; 11760 1.1 christos } 11761 1.1 christos 11762 1.1 christos /* Make a copy of name string. */ 11763 1.9 christos name = notes_strdup (name); 11764 1.1 christos 11765 1.1 christos if (section) 11766 1.1 christos { 11767 1.1 christos kind = "section"; 11768 1.1 christos ahash = secalias_hash; 11769 1.1 christos nhash = secalias_name_hash; 11770 1.1 christos } 11771 1.1 christos else 11772 1.1 christos { 11773 1.1 christos kind = "symbol"; 11774 1.1 christos ahash = alias_hash; 11775 1.1 christos nhash = alias_name_hash; 11776 1.1 christos } 11777 1.1 christos 11778 1.1 christos /* Check if alias has been used before. */ 11779 1.8 christos 11780 1.10 christos h = str_hash_find (ahash, alias); 11781 1.1 christos if (h) 11782 1.1 christos { 11783 1.1 christos if (strcmp (h->name, name)) 11784 1.1 christos as_bad (_("`%s' is already the alias of %s `%s'"), 11785 1.1 christos alias, kind, h->name); 11786 1.9 christos notes_free (alias); 11787 1.1 christos goto out; 11788 1.1 christos } 11789 1.1 christos 11790 1.1 christos /* Check if name already has an alias. */ 11791 1.10 christos a = str_hash_find (nhash, name); 11792 1.1 christos if (a) 11793 1.1 christos { 11794 1.1 christos if (strcmp (a, alias)) 11795 1.1 christos as_bad (_("%s `%s' already has an alias `%s'"), kind, name, a); 11796 1.9 christos notes_free (alias); 11797 1.1 christos goto out; 11798 1.1 christos } 11799 1.1 christos 11800 1.9 christos h = notes_alloc (sizeof (*h)); 11801 1.5 christos h->file = as_where (&h->line); 11802 1.1 christos h->name = name; 11803 1.3 christos 11804 1.8 christos str_hash_insert (ahash, alias, h, 0); 11805 1.8 christos str_hash_insert (nhash, name, alias, 0); 11806 1.1 christos 11807 1.1 christos out: 11808 1.1 christos demand_empty_rest_of_line (); 11809 1.1 christos } 11810 1.1 christos 11811 1.1 christos /* It renames the original symbol name to its alias. */ 11812 1.8 christos static int 11813 1.8 christos do_alias (void **slot, void *arg ATTRIBUTE_UNUSED) 11814 1.1 christos { 11815 1.8 christos string_tuple_t *tuple = *((string_tuple_t **) slot); 11816 1.8 christos struct alias *h = (struct alias *) tuple->value; 11817 1.1 christos symbolS *sym = symbol_find (h->name); 11818 1.1 christos 11819 1.1 christos if (sym == NULL) 11820 1.1 christos { 11821 1.1 christos #ifdef TE_VMS 11822 1.1 christos /* Uses .alias extensively to alias CRTL functions to same with 11823 1.1 christos decc$ prefix. Sometimes function gets optimized away and a 11824 1.1 christos warning results, which should be suppressed. */ 11825 1.8 christos if (!startswith (tuple->key, "decc$")) 11826 1.1 christos #endif 11827 1.1 christos as_warn_where (h->file, h->line, 11828 1.1 christos _("symbol `%s' aliased to `%s' is not used"), 11829 1.8 christos h->name, tuple->key); 11830 1.1 christos } 11831 1.1 christos else 11832 1.8 christos S_SET_NAME (sym, (char *) tuple->key); 11833 1.8 christos 11834 1.8 christos return 1; 11835 1.1 christos } 11836 1.1 christos 11837 1.1 christos /* Called from write_object_file. */ 11838 1.1 christos void 11839 1.1 christos ia64_adjust_symtab (void) 11840 1.1 christos { 11841 1.9 christos htab_traverse_noresize (alias_hash, do_alias, NULL); 11842 1.1 christos } 11843 1.1 christos 11844 1.1 christos /* It renames the original section name to its alias. */ 11845 1.8 christos static int 11846 1.8 christos do_secalias (void **slot, void *arg ATTRIBUTE_UNUSED) 11847 1.1 christos { 11848 1.8 christos string_tuple_t *tuple = *((string_tuple_t **) slot); 11849 1.8 christos struct alias *h = (struct alias *) tuple->value; 11850 1.1 christos segT sec = bfd_get_section_by_name (stdoutput, h->name); 11851 1.1 christos 11852 1.1 christos if (sec == NULL) 11853 1.1 christos as_warn_where (h->file, h->line, 11854 1.1 christos _("section `%s' aliased to `%s' is not used"), 11855 1.8 christos h->name, tuple->key); 11856 1.1 christos else 11857 1.8 christos sec->name = tuple->key; 11858 1.8 christos 11859 1.8 christos return 1; 11860 1.1 christos } 11861 1.1 christos 11862 1.1 christos /* Called from write_object_file. */ 11863 1.1 christos void 11864 1.1 christos ia64_frob_file (void) 11865 1.1 christos { 11866 1.9 christos htab_traverse_noresize (secalias_hash, do_secalias, NULL); 11867 1.1 christos } 11868 1.1 christos 11869 1.1 christos #ifdef TE_VMS 11870 1.1 christos #define NT_VMS_MHD 1 11871 1.1 christos #define NT_VMS_LNM 2 11872 1.1 christos 11873 1.1 christos /* Integrity VMS 8.x identifies it's ELF modules with a standard ELF 11874 1.1 christos .note section. */ 11875 1.1 christos 11876 1.1 christos /* Manufacture a VMS-like time string. */ 11877 1.1 christos static void 11878 1.1 christos get_vms_time (char *Now) 11879 1.1 christos { 11880 1.1 christos char *pnt; 11881 1.1 christos time_t timeb; 11882 1.1 christos 11883 1.1 christos time (&timeb); 11884 1.1 christos pnt = ctime (&timeb); 11885 1.1 christos pnt[3] = 0; 11886 1.1 christos pnt[7] = 0; 11887 1.1 christos pnt[10] = 0; 11888 1.1 christos pnt[16] = 0; 11889 1.1 christos pnt[24] = 0; 11890 1.1 christos sprintf (Now, "%2s-%3s-%s %s", pnt + 8, pnt + 4, pnt + 20, pnt + 11); 11891 1.1 christos } 11892 1.1 christos 11893 1.1 christos void 11894 1.1 christos ia64_vms_note (void) 11895 1.1 christos { 11896 1.1 christos char *p; 11897 1.1 christos asection *seg = now_seg; 11898 1.1 christos subsegT subseg = now_subseg; 11899 1.1 christos asection *secp = NULL; 11900 1.1 christos char *bname; 11901 1.1 christos char buf [256]; 11902 1.1 christos symbolS *sym; 11903 1.1 christos 11904 1.1 christos /* Create the .note section. */ 11905 1.1 christos 11906 1.1 christos secp = subseg_new (".note", 0); 11907 1.7 christos bfd_set_section_flags (secp, SEC_HAS_CONTENTS | SEC_READONLY); 11908 1.1 christos 11909 1.1 christos /* Module header note (MHD). */ 11910 1.1 christos bname = xstrdup (lbasename (out_file_name)); 11911 1.1 christos if ((p = strrchr (bname, '.'))) 11912 1.1 christos *p = '\0'; 11913 1.3 christos 11914 1.1 christos /* VMS note header is 24 bytes long. */ 11915 1.1 christos p = frag_more (8 + 8 + 8); 11916 1.1 christos number_to_chars_littleendian (p + 0, 8, 8); 11917 1.1 christos number_to_chars_littleendian (p + 8, 40 + strlen (bname), 8); 11918 1.1 christos number_to_chars_littleendian (p + 16, NT_VMS_MHD, 8); 11919 1.1 christos 11920 1.1 christos p = frag_more (8); 11921 1.1 christos strcpy (p, "IPF/VMS"); 11922 1.1 christos 11923 1.1 christos p = frag_more (17 + 17 + strlen (bname) + 1 + 5); 11924 1.1 christos get_vms_time (p); 11925 1.1 christos strcpy (p + 17, "24-FEB-2005 15:00"); 11926 1.1 christos p += 17 + 17; 11927 1.1 christos strcpy (p, bname); 11928 1.1 christos p += strlen (bname) + 1; 11929 1.1 christos free (bname); 11930 1.1 christos strcpy (p, "V1.0"); 11931 1.1 christos 11932 1.1 christos frag_align (3, 0, 0); 11933 1.1 christos 11934 1.1 christos /* Language processor name note. */ 11935 1.1 christos sprintf (buf, "GNU assembler version %s (%s) using BFD version %s", 11936 1.1 christos VERSION, TARGET_ALIAS, BFD_VERSION_STRING); 11937 1.1 christos 11938 1.1 christos p = frag_more (8 + 8 + 8); 11939 1.1 christos number_to_chars_littleendian (p + 0, 8, 8); 11940 1.1 christos number_to_chars_littleendian (p + 8, strlen (buf) + 1, 8); 11941 1.1 christos number_to_chars_littleendian (p + 16, NT_VMS_LNM, 8); 11942 1.1 christos 11943 1.1 christos p = frag_more (8); 11944 1.1 christos strcpy (p, "IPF/VMS"); 11945 1.1 christos 11946 1.1 christos p = frag_more (strlen (buf) + 1); 11947 1.1 christos strcpy (p, buf); 11948 1.1 christos 11949 1.1 christos frag_align (3, 0, 0); 11950 1.1 christos 11951 1.1 christos secp = subseg_new (".vms_display_name_info", 0); 11952 1.7 christos bfd_set_section_flags (secp, SEC_HAS_CONTENTS | SEC_READONLY); 11953 1.1 christos 11954 1.1 christos /* This symbol should be passed on the command line and be variable 11955 1.1 christos according to language. */ 11956 1.1 christos sym = symbol_new ("__gnat_vms_display_name@gnat_demangler_rtl", 11957 1.8 christos absolute_section, &zero_address_frag, 0); 11958 1.1 christos symbol_table_insert (sym); 11959 1.1 christos symbol_get_bfdsym (sym)->flags |= BSF_DEBUGGING | BSF_DYNAMIC; 11960 1.1 christos 11961 1.1 christos p = frag_more (4); 11962 1.1 christos /* Format 3 of VMS demangler Spec. */ 11963 1.1 christos number_to_chars_littleendian (p, 3, 4); 11964 1.1 christos 11965 1.1 christos p = frag_more (4); 11966 1.1 christos /* Place holder for symbol table index of above symbol. */ 11967 1.1 christos number_to_chars_littleendian (p, -1, 4); 11968 1.1 christos 11969 1.1 christos frag_align (3, 0, 0); 11970 1.1 christos 11971 1.1 christos /* We probably can't restore the current segment, for there likely 11972 1.1 christos isn't one yet... */ 11973 1.1 christos if (seg && subseg) 11974 1.1 christos subseg_set (seg, subseg); 11975 1.1 christos } 11976 1.1 christos 11977 1.1 christos #endif /* TE_VMS */ 11978