]> Git Repo - binutils.git/blame - gas/config/tc-ia64.c
MIPS is always multi-arch enabled.
[binutils.git] / gas / config / tc-ia64.c
CommitLineData
800eeca4 1/* tc-ia64.c -- Assembler for the HP/Intel IA-64 architecture.
e0c9811a 2 Copyright (C) 1998, 1999, 2000 Free Software Foundation.
800eeca4
JW
3 Contributed by David Mosberger-Tang <[email protected]>
4
5 This file is part of GAS, the GNU Assembler.
6
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
21
22/*
23 TODO:
24
25 - optional operands
26 - directives:
27 .alias
28 .eb
29 .estate
30 .lb
31 .popsection
32 .previous
33 .psr
34 .pushsection
800eeca4
JW
35 - labels are wrong if automatic alignment is introduced
36 (e.g., checkout the second real10 definition in test-data.s)
37 - DV-related stuff:
38 <reg>.safe_across_calls and any other DV-related directives I don't
39 have documentation for.
40 verify mod-sched-brs reads/writes are checked/marked (and other
41 notes)
42
43 */
44
45#include "as.h"
46#include "dwarf2dbg.h"
47#include "subsegs.h"
48
49#include "opcode/ia64.h"
50
51#include "elf/ia64.h"
52
53#define NELEMS(a) ((int) (sizeof (a)/sizeof ((a)[0])))
54#define MIN(a,b) ((a) < (b) ? (a) : (b))
55
56#define NUM_SLOTS 4
57#define PREV_SLOT md.slot[(md.curr_slot + NUM_SLOTS - 1) % NUM_SLOTS]
58#define CURR_SLOT md.slot[md.curr_slot]
59
60#define O_pseudo_fixup (O_max + 1)
61
62enum special_section
63 {
64 SPECIAL_SECTION_BSS = 0,
65 SPECIAL_SECTION_SBSS,
66 SPECIAL_SECTION_SDATA,
67 SPECIAL_SECTION_RODATA,
68 SPECIAL_SECTION_COMMENT,
69 SPECIAL_SECTION_UNWIND,
70 SPECIAL_SECTION_UNWIND_INFO
71 };
72
73enum reloc_func
74 {
75 FUNC_FPTR_RELATIVE,
76 FUNC_GP_RELATIVE,
77 FUNC_LT_RELATIVE,
c67e42c9 78 FUNC_PC_RELATIVE,
800eeca4
JW
79 FUNC_PLT_RELATIVE,
80 FUNC_SEC_RELATIVE,
81 FUNC_SEG_RELATIVE,
82 FUNC_LTV_RELATIVE,
83 FUNC_LT_FPTR_RELATIVE,
84 };
85
86enum reg_symbol
87 {
88 REG_GR = 0,
89 REG_FR = (REG_GR + 128),
90 REG_AR = (REG_FR + 128),
91 REG_CR = (REG_AR + 128),
92 REG_P = (REG_CR + 128),
93 REG_BR = (REG_P + 64),
94 REG_IP = (REG_BR + 8),
95 REG_CFM,
96 REG_PR,
97 REG_PR_ROT,
98 REG_PSR,
99 REG_PSR_L,
100 REG_PSR_UM,
101 /* The following are pseudo-registers for use by gas only. */
102 IND_CPUID,
103 IND_DBR,
104 IND_DTR,
105 IND_ITR,
106 IND_IBR,
107 IND_MEM,
108 IND_MSR,
109 IND_PKR,
110 IND_PMC,
111 IND_PMD,
112 IND_RR,
e0c9811a
JW
113 /* The following pseudo-registers are used for unwind directives only: */
114 REG_PSP,
115 REG_PRIUNAT,
800eeca4
JW
116 REG_NUM
117 };
118
119enum dynreg_type
120 {
121 DYNREG_GR = 0, /* dynamic general purpose register */
122 DYNREG_FR, /* dynamic floating point register */
123 DYNREG_PR, /* dynamic predicate register */
124 DYNREG_NUM_TYPES
125 };
126
127/* On the ia64, we can't know the address of a text label until the
128 instructions are packed into a bundle. To handle this, we keep
129 track of the list of labels that appear in front of each
130 instruction. */
131struct label_fix
132 {
133 struct label_fix *next;
134 struct symbol *sym;
135 };
136
137extern int target_big_endian;
138
139/* Characters which always start a comment. */
140const char comment_chars[] = "";
141
142/* Characters which start a comment at the beginning of a line. */
143const char line_comment_chars[] = "#";
144
145/* Characters which may be used to separate multiple commands on a
146 single line. */
147const char line_separator_chars[] = ";";
148
149/* Characters which are used to indicate an exponent in a floating
150 point number. */
151const char EXP_CHARS[] = "eE";
152
153/* Characters which mean that a number is a floating point constant,
154 as in 0d1.0. */
155const char FLT_CHARS[] = "rRsSfFdDxXpP";
156
157/* ia64-specific option processing: */
158
159const char *md_shortopts = "M:N:x::";
160
161struct option md_longopts[] =
162 {
163 { NULL, no_argument, NULL, 0}
164 };
165
166size_t md_longopts_size = sizeof (md_longopts);
167
168static struct
169 {
170 struct hash_control *pseudo_hash; /* pseudo opcode hash table */
171 struct hash_control *reg_hash; /* register name hash table */
172 struct hash_control *dynreg_hash; /* dynamic register hash table */
173 struct hash_control *const_hash; /* constant hash table */
174 struct hash_control *entry_hash; /* code entry hint hash table */
175
176 symbolS *regsym[REG_NUM];
177
178 /* If X_op is != O_absent, the registername for the instruction's
179 qualifying predicate. If NULL, p0 is assumed for instructions
180 that are predicatable. */
181 expressionS qp;
182
183 unsigned int
184 manual_bundling : 1,
185 debug_dv: 1,
186 detect_dv: 1,
187 explicit_mode : 1, /* which mode we're in */
188 default_explicit_mode : 1, /* which mode is the default */
189 mode_explicitly_set : 1, /* was the current mode explicitly set? */
190 auto_align : 1;
191
192 /* Each bundle consists of up to three instructions. We keep
193 track of four most recent instructions so we can correctly set
194 the end_of_insn_group for the last instruction in a bundle. */
195 int curr_slot;
196 int num_slots_in_use;
197 struct slot
198 {
199 unsigned int
200 end_of_insn_group : 1,
201 manual_bundling_on : 1,
202 manual_bundling_off : 1;
203 signed char user_template; /* user-selected template, if any */
204 unsigned char qp_regno; /* qualifying predicate */
205 /* This duplicates a good fraction of "struct fix" but we
206 can't use a "struct fix" instead since we can't call
207 fix_new_exp() until we know the address of the instruction. */
208 int num_fixups;
209 struct insn_fix
210 {
211 bfd_reloc_code_real_type code;
212 enum ia64_opnd opnd; /* type of operand in need of fix */
213 unsigned int is_pcrel : 1; /* is operand pc-relative? */
214 expressionS expr; /* the value to be inserted */
215 }
216 fixup[2]; /* at most two fixups per insn */
217 struct ia64_opcode *idesc;
218 struct label_fix *label_fixups;
219 struct unw_rec_list *unwind_record; /* Unwind directive. */
220 expressionS opnd[6];
221 char *src_file;
222 unsigned int src_line;
223 struct dwarf2_line_info debug_line;
224 }
225 slot[NUM_SLOTS];
226
227 segT last_text_seg;
228
229 struct dynreg
230 {
231 struct dynreg *next; /* next dynamic register */
232 const char *name;
233 unsigned short base; /* the base register number */
234 unsigned short num_regs; /* # of registers in this set */
235 }
236 *dynreg[DYNREG_NUM_TYPES], in, loc, out, rot;
237
238 flagword flags; /* ELF-header flags */
239
240 struct mem_offset {
241 unsigned hint:1; /* is this hint currently valid? */
242 bfd_vma offset; /* mem.offset offset */
243 bfd_vma base; /* mem.offset base */
244 } mem_offset;
245
246 int path; /* number of alt. entry points seen */
247 const char **entry_labels; /* labels of all alternate paths in
248 the current DV-checking block. */
249 int maxpaths; /* size currently allocated for
250 entry_labels */
251 }
252md;
253
254/* application registers: */
255
e0c9811a
JW
256#define AR_K0 0
257#define AR_K7 7
258#define AR_RSC 16
259#define AR_BSP 17
260#define AR_BSPSTORE 18
261#define AR_RNAT 19
262#define AR_UNAT 36
263#define AR_FPSR 40
264#define AR_ITC 44
265#define AR_PFS 64
266#define AR_LC 65
800eeca4
JW
267
268static const struct
269 {
270 const char *name;
271 int regnum;
272 }
273ar[] =
274 {
275 {"ar.k0", 0}, {"ar.k1", 1}, {"ar.k2", 2}, {"ar.k3", 3},
276 {"ar.k4", 4}, {"ar.k5", 5}, {"ar.k6", 6}, {"ar.k7", 7},
277 {"ar.rsc", 16}, {"ar.bsp", 17},
278 {"ar.bspstore", 18}, {"ar.rnat", 19},
279 {"ar.fcr", 21}, {"ar.eflag", 24},
280 {"ar.csd", 25}, {"ar.ssd", 26},
281 {"ar.cflg", 27}, {"ar.fsr", 28},
282 {"ar.fir", 29}, {"ar.fdr", 30},
283 {"ar.ccv", 32}, {"ar.unat", 36},
284 {"ar.fpsr", 40}, {"ar.itc", 44},
285 {"ar.pfs", 64}, {"ar.lc", 65},
286 {"ar.ec", 66},
287 };
288
289#define CR_IPSR 16
290#define CR_ISR 17
291#define CR_IIP 19
292#define CR_IFA 20
293#define CR_ITIR 21
294#define CR_IIPA 22
295#define CR_IFS 23
296#define CR_IIM 24
297#define CR_IHA 25
298#define CR_IVR 65
299#define CR_TPR 66
300#define CR_EOI 67
301#define CR_IRR0 68
302#define CR_IRR3 71
303#define CR_LRR0 80
304#define CR_LRR1 81
305
306/* control registers: */
307static const struct
308 {
309 const char *name;
310 int regnum;
311 }
312cr[] =
313 {
314 {"cr.dcr", 0},
315 {"cr.itm", 1},
316 {"cr.iva", 2},
317 {"cr.pta", 8},
318 {"cr.gpta", 9},
319 {"cr.ipsr", 16},
320 {"cr.isr", 17},
321 {"cr.iip", 19},
322 {"cr.ifa", 20},
323 {"cr.itir", 21},
324 {"cr.iipa", 22},
325 {"cr.ifs", 23},
326 {"cr.iim", 24},
327 {"cr.iha", 25},
328 {"cr.lid", 64},
329 {"cr.ivr", 65},
330 {"cr.tpr", 66},
331 {"cr.eoi", 67},
332 {"cr.irr0", 68},
333 {"cr.irr1", 69},
334 {"cr.irr2", 70},
335 {"cr.irr3", 71},
336 {"cr.itv", 72},
337 {"cr.pmv", 73},
338 {"cr.cmcv", 74},
339 {"cr.lrr0", 80},
340 {"cr.lrr1", 81}
341 };
342
343#define PSR_MFL 4
344#define PSR_IC 13
345#define PSR_DFL 18
346#define PSR_CPL 32
347
348static const struct const_desc
349 {
350 const char *name;
351 valueT value;
352 }
353const_bits[] =
354 {
355 /* PSR constant masks: */
356
357 /* 0: reserved */
358 {"psr.be", ((valueT) 1) << 1},
359 {"psr.up", ((valueT) 1) << 2},
360 {"psr.ac", ((valueT) 1) << 3},
361 {"psr.mfl", ((valueT) 1) << 4},
362 {"psr.mfh", ((valueT) 1) << 5},
363 /* 6-12: reserved */
364 {"psr.ic", ((valueT) 1) << 13},
365 {"psr.i", ((valueT) 1) << 14},
366 {"psr.pk", ((valueT) 1) << 15},
367 /* 16: reserved */
368 {"psr.dt", ((valueT) 1) << 17},
369 {"psr.dfl", ((valueT) 1) << 18},
370 {"psr.dfh", ((valueT) 1) << 19},
371 {"psr.sp", ((valueT) 1) << 20},
372 {"psr.pp", ((valueT) 1) << 21},
373 {"psr.di", ((valueT) 1) << 22},
374 {"psr.si", ((valueT) 1) << 23},
375 {"psr.db", ((valueT) 1) << 24},
376 {"psr.lp", ((valueT) 1) << 25},
377 {"psr.tb", ((valueT) 1) << 26},
378 {"psr.rt", ((valueT) 1) << 27},
379 /* 28-31: reserved */
380 /* 32-33: cpl (current privilege level) */
381 {"psr.is", ((valueT) 1) << 34},
382 {"psr.mc", ((valueT) 1) << 35},
383 {"psr.it", ((valueT) 1) << 36},
384 {"psr.id", ((valueT) 1) << 37},
385 {"psr.da", ((valueT) 1) << 38},
386 {"psr.dd", ((valueT) 1) << 39},
387 {"psr.ss", ((valueT) 1) << 40},
388 /* 41-42: ri (restart instruction) */
389 {"psr.ed", ((valueT) 1) << 43},
390 {"psr.bn", ((valueT) 1) << 44},
391 };
392
393/* indirect register-sets/memory: */
394
395static const struct
396 {
397 const char *name;
398 int regnum;
399 }
400indirect_reg[] =
401 {
402 { "CPUID", IND_CPUID },
403 { "cpuid", IND_CPUID },
404 { "dbr", IND_DBR },
405 { "dtr", IND_DTR },
406 { "itr", IND_ITR },
407 { "ibr", IND_IBR },
408 { "msr", IND_MSR },
409 { "pkr", IND_PKR },
410 { "pmc", IND_PMC },
411 { "pmd", IND_PMD },
412 { "rr", IND_RR },
413 };
414
415/* Pseudo functions used to indicate relocation types (these functions
416 start with an at sign (@). */
417static struct
418 {
419 const char *name;
420 enum pseudo_type
421 {
422 PSEUDO_FUNC_NONE,
423 PSEUDO_FUNC_RELOC,
424 PSEUDO_FUNC_CONST,
e0c9811a 425 PSEUDO_FUNC_REG,
800eeca4
JW
426 PSEUDO_FUNC_FLOAT
427 }
428 type;
429 union
430 {
431 unsigned long ival;
432 symbolS *sym;
433 }
434 u;
435 }
436pseudo_func[] =
437 {
438 /* reloc pseudo functions (these must come first!): */
439 { "fptr", PSEUDO_FUNC_RELOC },
440 { "gprel", PSEUDO_FUNC_RELOC },
441 { "ltoff", PSEUDO_FUNC_RELOC },
c67e42c9 442 { "pcrel", PSEUDO_FUNC_RELOC },
800eeca4
JW
443 { "pltoff", PSEUDO_FUNC_RELOC },
444 { "secrel", PSEUDO_FUNC_RELOC },
445 { "segrel", PSEUDO_FUNC_RELOC },
446 { "ltv", PSEUDO_FUNC_RELOC },
447 { 0, }, /* placeholder for FUNC_LT_FPTR_RELATIVE */
448
449 /* mbtype4 constants: */
450 { "alt", PSEUDO_FUNC_CONST, { 0xa } },
451 { "brcst", PSEUDO_FUNC_CONST, { 0x0 } },
452 { "mix", PSEUDO_FUNC_CONST, { 0x8 } },
453 { "rev", PSEUDO_FUNC_CONST, { 0xb } },
454 { "shuf", PSEUDO_FUNC_CONST, { 0x9 } },
455
456 /* fclass constants: */
bf3ca999 457 { "nat", PSEUDO_FUNC_CONST, { 0x100 } },
800eeca4
JW
458 { "qnan", PSEUDO_FUNC_CONST, { 0x080 } },
459 { "snan", PSEUDO_FUNC_CONST, { 0x040 } },
460 { "pos", PSEUDO_FUNC_CONST, { 0x001 } },
461 { "neg", PSEUDO_FUNC_CONST, { 0x002 } },
462 { "zero", PSEUDO_FUNC_CONST, { 0x004 } },
463 { "unorm", PSEUDO_FUNC_CONST, { 0x008 } },
464 { "norm", PSEUDO_FUNC_CONST, { 0x010 } },
465 { "inf", PSEUDO_FUNC_CONST, { 0x020 } },
bf3ca999
TW
466
467 { "natval", PSEUDO_FUNC_CONST, { 0x100 } }, /* old usage */
e0c9811a
JW
468
469 /* unwind-related constants: */
470 { "svr4", PSEUDO_FUNC_CONST, { 0 } },
471 { "hpux", PSEUDO_FUNC_CONST, { 1 } },
472 { "nt", PSEUDO_FUNC_CONST, { 2 } },
473
474 /* unwind-related registers: */
475 { "priunat",PSEUDO_FUNC_REG, { REG_PRIUNAT } }
800eeca4
JW
476 };
477
478/* 41-bit nop opcodes (one per unit): */
479static const bfd_vma nop[IA64_NUM_UNITS] =
480 {
481 0x0000000000LL, /* NIL => break 0 */
482 0x0008000000LL, /* I-unit nop */
483 0x0008000000LL, /* M-unit nop */
484 0x4000000000LL, /* B-unit nop */
485 0x0008000000LL, /* F-unit nop */
486 0x0008000000LL, /* L-"unit" nop */
487 0x0008000000LL, /* X-unit nop */
488 };
489
490/* Can't be `const' as it's passed to input routines (which have the
491 habit of setting temporary sentinels. */
492static char special_section_name[][20] =
493 {
494 {".bss"}, {".sbss"}, {".sdata"}, {".rodata"}, {".comment"},
495 {".IA_64.unwind"}, {".IA_64.unwind_info"}
496 };
497
498/* The best template for a particular sequence of up to three
499 instructions: */
500#define N IA64_NUM_TYPES
501static unsigned char best_template[N][N][N];
502#undef N
503
504/* Resource dependencies currently in effect */
505static struct rsrc {
506 int depind; /* dependency index */
507 const struct ia64_dependency *dependency; /* actual dependency */
508 unsigned specific:1, /* is this a specific bit/regno? */
509 link_to_qp_branch:1; /* will a branch on the same QP clear it?*/
510 int index; /* specific regno/bit within dependency */
511 int note; /* optional qualifying note (0 if none) */
512#define STATE_NONE 0
513#define STATE_STOP 1
514#define STATE_SRLZ 2
515 int insn_srlz; /* current insn serialization state */
516 int data_srlz; /* current data serialization state */
517 int qp_regno; /* qualifying predicate for this usage */
518 char *file; /* what file marked this dependency */
519 int line; /* what line marked this dependency */
520 struct mem_offset mem_offset; /* optional memory offset hint */
521 int path; /* corresponding code entry index */
522} *regdeps = NULL;
523static int regdepslen = 0;
524static int regdepstotlen = 0;
525static const char *dv_mode[] = { "RAW", "WAW", "WAR" };
526static const char *dv_sem[] = { "none", "implied", "impliedf",
527 "data", "instr", "specific", "other" };
528
529/* Current state of PR mutexation */
530static struct qpmutex {
531 valueT prmask;
532 int path;
533} *qp_mutexes = NULL; /* QP mutex bitmasks */
534static int qp_mutexeslen = 0;
535static int qp_mutexestotlen = 0;
536static valueT qp_safe_across_calls = 0;
537
538/* Current state of PR implications */
539static struct qp_imply {
540 unsigned p1:6;
541 unsigned p2:6;
542 unsigned p2_branched:1;
543 int path;
544} *qp_implies = NULL;
545static int qp_implieslen = 0;
546static int qp_impliestotlen = 0;
547
548/* Keep track of static GR values so that indirect register usage can
549 sometimes be tracked. */
550static struct gr {
551 unsigned known:1;
552 int path;
553 valueT value;
554} gr_values[128] = {{ 1, 0 }};
555
556/* These are the routines required to output the various types of
557 unwind records. */
558
559typedef struct unw_rec_list {
560 unwind_record r;
e0c9811a 561 unsigned long slot_number;
800eeca4
JW
562 struct unw_rec_list *next;
563} unw_rec_list;
564
565#define SLOT_NUM_NOT_SET -1
566
e0c9811a
JW
567static struct
568{
569 unsigned long next_slot_number;
570
571 /* Maintain a list of unwind entries for the current function. */
572 unw_rec_list *list;
573 unw_rec_list *tail;
800eeca4 574
e0c9811a
JW
575 /* Any unwind entires that should be attached to the current slot
576 that an insn is being constructed for. */
577 unw_rec_list *current_entry;
800eeca4 578
e0c9811a
JW
579 /* These are used to create the unwind table entry for this function. */
580 symbolS *proc_start;
581 symbolS *proc_end;
582 symbolS *info; /* pointer to unwind info */
583 symbolS *personality_routine;
800eeca4 584
e0c9811a
JW
585 /* TRUE if processing unwind directives in a prologue region. */
586 int prologue;
587} unwind;
800eeca4
JW
588
589typedef void (*vbyte_func) PARAMS ((int, char *, char *));
590
591/* Forward delarations: */
592static int ar_is_in_integer_unit PARAMS ((int regnum));
593static void set_section PARAMS ((char *name));
594static unsigned int set_regstack PARAMS ((unsigned int, unsigned int,
595 unsigned int, unsigned int));
596static void dot_radix PARAMS ((int));
597static void dot_special_section PARAMS ((int));
598static void dot_proc PARAMS ((int));
599static void dot_fframe PARAMS ((int));
600static void dot_vframe PARAMS ((int));
150f24a2
JW
601static void dot_vframesp PARAMS ((int));
602static void dot_vframepsp PARAMS ((int));
800eeca4
JW
603static void dot_save PARAMS ((int));
604static void dot_restore PARAMS ((int));
150f24a2
JW
605static void dot_restorereg PARAMS ((int));
606static void dot_restorereg_p PARAMS ((int));
800eeca4
JW
607static void dot_handlerdata PARAMS ((int));
608static void dot_unwentry PARAMS ((int));
609static void dot_altrp PARAMS ((int));
e0c9811a 610static void dot_savemem PARAMS ((int));
800eeca4
JW
611static void dot_saveg PARAMS ((int));
612static void dot_savef PARAMS ((int));
613static void dot_saveb PARAMS ((int));
614static void dot_savegf PARAMS ((int));
615static void dot_spill PARAMS ((int));
150f24a2
JW
616static void dot_spillreg PARAMS ((int));
617static void dot_spillmem PARAMS ((int));
618static void dot_spillreg_p PARAMS ((int));
619static void dot_spillmem_p PARAMS ((int));
620static void dot_label_state PARAMS ((int));
621static void dot_copy_state PARAMS ((int));
800eeca4
JW
622static void dot_unwabi PARAMS ((int));
623static void dot_personality PARAMS ((int));
624static void dot_body PARAMS ((int));
625static void dot_prologue PARAMS ((int));
626static void dot_endp PARAMS ((int));
627static void dot_template PARAMS ((int));
628static void dot_regstk PARAMS ((int));
629static void dot_rot PARAMS ((int));
630static void dot_byteorder PARAMS ((int));
631static void dot_psr PARAMS ((int));
632static void dot_alias PARAMS ((int));
633static void dot_ln PARAMS ((int));
634static char *parse_section_name PARAMS ((void));
635static void dot_xdata PARAMS ((int));
636static void stmt_float_cons PARAMS ((int));
637static void stmt_cons_ua PARAMS ((int));
638static void dot_xfloat_cons PARAMS ((int));
639static void dot_xstringer PARAMS ((int));
640static void dot_xdata_ua PARAMS ((int));
641static void dot_xfloat_cons_ua PARAMS ((int));
150f24a2 642static void print_prmask PARAMS ((valueT mask));
800eeca4
JW
643static void dot_pred_rel PARAMS ((int));
644static void dot_reg_val PARAMS ((int));
645static void dot_dv_mode PARAMS ((int));
646static void dot_entry PARAMS ((int));
647static void dot_mem_offset PARAMS ((int));
e0c9811a 648static void add_unwind_entry PARAMS((unw_rec_list *ptr));
800eeca4
JW
649static symbolS* declare_register PARAMS ((const char *name, int regnum));
650static void declare_register_set PARAMS ((const char *, int, int));
651static unsigned int operand_width PARAMS ((enum ia64_opnd));
652static int operand_match PARAMS ((const struct ia64_opcode *idesc,
653 int index, expressionS *e));
654static int parse_operand PARAMS ((expressionS *e));
655static struct ia64_opcode * parse_operands PARAMS ((struct ia64_opcode *));
656static void build_insn PARAMS ((struct slot *, bfd_vma *));
657static void emit_one_bundle PARAMS ((void));
658static void fix_insn PARAMS ((fixS *, const struct ia64_operand *, valueT));
659static bfd_reloc_code_real_type ia64_gen_real_reloc_type PARAMS ((struct symbol *sym,
660 bfd_reloc_code_real_type r_type));
661static void insn_group_break PARAMS ((int, int, int));
150f24a2
JW
662static void mark_resource PARAMS ((struct ia64_opcode *, const struct ia64_dependency *,
663 struct rsrc *, int depind, int path));
800eeca4
JW
664static void add_qp_mutex PARAMS((valueT mask));
665static void add_qp_imply PARAMS((int p1, int p2));
666static void clear_qp_branch_flag PARAMS((valueT mask));
667static void clear_qp_mutex PARAMS((valueT mask));
668static void clear_qp_implies PARAMS((valueT p1_mask, valueT p2_mask));
669static void clear_register_values PARAMS ((void));
670static void print_dependency PARAMS ((const char *action, int depind));
150f24a2
JW
671static void instruction_serialization PARAMS ((void));
672static void data_serialization PARAMS ((void));
673static void remove_marked_resource PARAMS ((struct rsrc *));
800eeca4 674static int is_conditional_branch PARAMS ((struct ia64_opcode *));
150f24a2 675static int is_taken_branch PARAMS ((struct ia64_opcode *));
800eeca4 676static int is_interruption_or_rfi PARAMS ((struct ia64_opcode *));
150f24a2
JW
677static int depends_on PARAMS ((int, struct ia64_opcode *));
678static int specify_resource PARAMS ((const struct ia64_dependency *,
679 struct ia64_opcode *, int, struct rsrc [], int, int));
800eeca4
JW
680static int check_dv PARAMS((struct ia64_opcode *idesc));
681static void check_dependencies PARAMS((struct ia64_opcode *));
682static void mark_resources PARAMS((struct ia64_opcode *));
683static void update_dependencies PARAMS((struct ia64_opcode *));
684static void note_register_values PARAMS((struct ia64_opcode *));
150f24a2
JW
685static int qp_mutex PARAMS ((int, int, int));
686static int resources_match PARAMS ((struct rsrc *, struct ia64_opcode *, int, int, int));
687static void output_vbyte_mem PARAMS ((int, char *, char *));
688static void count_output PARAMS ((int, char *, char *));
689static void output_R1_format PARAMS ((vbyte_func, unw_record_type, int));
690static void output_R2_format PARAMS ((vbyte_func, int, int, unsigned long));
800eeca4 691static void output_R3_format PARAMS ((vbyte_func, unw_record_type, unsigned long));
150f24a2
JW
692static void output_P1_format PARAMS ((vbyte_func, int));
693static void output_P2_format PARAMS ((vbyte_func, int, int));
694static void output_P3_format PARAMS ((vbyte_func, unw_record_type, int));
695static void output_P4_format PARAMS ((vbyte_func, unsigned char *, unsigned long));
696static void output_P5_format PARAMS ((vbyte_func, int, unsigned long));
697static void output_P6_format PARAMS ((vbyte_func, unw_record_type, int));
698static void output_P7_format PARAMS ((vbyte_func, unw_record_type, unsigned long, unsigned long));
699static void output_P8_format PARAMS ((vbyte_func, unw_record_type, unsigned long));
700static void output_P9_format PARAMS ((vbyte_func, int, int));
701static void output_P10_format PARAMS ((vbyte_func, int, int));
702static void output_B1_format PARAMS ((vbyte_func, unw_record_type, unsigned long));
703static void output_B2_format PARAMS ((vbyte_func, unsigned long, unsigned long));
800eeca4
JW
704static void output_B3_format PARAMS ((vbyte_func, unsigned long, unsigned long));
705static void output_B4_format PARAMS ((vbyte_func, unw_record_type, unsigned long));
150f24a2
JW
706static char format_ab_reg PARAMS ((int, int));
707static void output_X1_format PARAMS ((vbyte_func, unw_record_type, int, int, unsigned long,
708 unsigned long));
709static void output_X2_format PARAMS ((vbyte_func, int, int, int, int, int, unsigned long));
710static void output_X3_format PARAMS ((vbyte_func, unw_record_type, int, int, int, unsigned long,
711 unsigned long));
712static void output_X4_format PARAMS ((vbyte_func, int, int, int, int, int, int, unsigned long));
713static void free_list_records PARAMS ((unw_rec_list *));
714static unw_rec_list *output_prologue PARAMS ((void));
715static unw_rec_list *output_prologue_gr PARAMS ((unsigned int, unsigned int));
716static unw_rec_list *output_body PARAMS ((void));
717static unw_rec_list *output_mem_stack_f PARAMS ((unsigned int));
718static unw_rec_list *output_mem_stack_v PARAMS ((void));
719static unw_rec_list *output_psp_gr PARAMS ((unsigned int));
720static unw_rec_list *output_psp_sprel PARAMS ((unsigned int));
721static unw_rec_list *output_rp_when PARAMS ((void));
722static unw_rec_list *output_rp_gr PARAMS ((unsigned int));
723static unw_rec_list *output_rp_br PARAMS ((unsigned int));
724static unw_rec_list *output_rp_psprel PARAMS ((unsigned int));
725static unw_rec_list *output_rp_sprel PARAMS ((unsigned int));
726static unw_rec_list *output_pfs_when PARAMS ((void));
727static unw_rec_list *output_pfs_gr PARAMS ((unsigned int));
728static unw_rec_list *output_pfs_psprel PARAMS ((unsigned int));
729static unw_rec_list *output_pfs_sprel PARAMS ((unsigned int));
730static unw_rec_list *output_preds_when PARAMS ((void));
731static unw_rec_list *output_preds_gr PARAMS ((unsigned int));
732static unw_rec_list *output_preds_psprel PARAMS ((unsigned int));
733static unw_rec_list *output_preds_sprel PARAMS ((unsigned int));
734static unw_rec_list *output_fr_mem PARAMS ((unsigned int));
735static unw_rec_list *output_frgr_mem PARAMS ((unsigned int, unsigned int));
736static unw_rec_list *output_gr_gr PARAMS ((unsigned int, unsigned int));
737static unw_rec_list *output_gr_mem PARAMS ((unsigned int));
738static unw_rec_list *output_br_mem PARAMS ((unsigned int));
739static unw_rec_list *output_br_gr PARAMS ((unsigned int, unsigned int));
740static unw_rec_list *output_spill_base PARAMS ((unsigned int));
741static unw_rec_list *output_unat_when PARAMS ((void));
742static unw_rec_list *output_unat_gr PARAMS ((unsigned int));
743static unw_rec_list *output_unat_psprel PARAMS ((unsigned int));
744static unw_rec_list *output_unat_sprel PARAMS ((unsigned int));
745static unw_rec_list *output_lc_when PARAMS ((void));
746static unw_rec_list *output_lc_gr PARAMS ((unsigned int));
747static unw_rec_list *output_lc_psprel PARAMS ((unsigned int));
748static unw_rec_list *output_lc_sprel PARAMS ((unsigned int));
749static unw_rec_list *output_fpsr_when PARAMS ((void));
750static unw_rec_list *output_fpsr_gr PARAMS ((unsigned int));
751static unw_rec_list *output_fpsr_psprel PARAMS ((unsigned int));
752static unw_rec_list *output_fpsr_sprel PARAMS ((unsigned int));
753static unw_rec_list *output_priunat_when_gr PARAMS ((void));
754static unw_rec_list *output_priunat_when_mem PARAMS ((void));
755static unw_rec_list *output_priunat_gr PARAMS ((unsigned int));
756static unw_rec_list *output_priunat_psprel PARAMS ((unsigned int));
757static unw_rec_list *output_priunat_sprel PARAMS ((unsigned int));
758static unw_rec_list *output_bsp_when PARAMS ((void));
759static unw_rec_list *output_bsp_gr PARAMS ((unsigned int));
760static unw_rec_list *output_bsp_psprel PARAMS ((unsigned int));
761static unw_rec_list *output_bsp_sprel PARAMS ((unsigned int));
762static unw_rec_list *output_bspstore_when PARAMS ((void));
763static unw_rec_list *output_bspstore_gr PARAMS ((unsigned int));
764static unw_rec_list *output_bspstore_psprel PARAMS ((unsigned int));
765static unw_rec_list *output_bspstore_sprel PARAMS ((unsigned int));
766static unw_rec_list *output_rnat_when PARAMS ((void));
767static unw_rec_list *output_rnat_gr PARAMS ((unsigned int));
768static unw_rec_list *output_rnat_psprel PARAMS ((unsigned int));
769static unw_rec_list *output_rnat_sprel PARAMS ((unsigned int));
770static unw_rec_list *output_unwabi PARAMS ((unsigned long, unsigned long));
771static unw_rec_list *output_epilogue PARAMS ((unsigned long));
772static unw_rec_list *output_label_state PARAMS ((unsigned long));
773static unw_rec_list *output_copy_state PARAMS ((unsigned long));
774static unw_rec_list *output_spill_psprel PARAMS ((unsigned int, unsigned int, unsigned int));
775static unw_rec_list *output_spill_sprel PARAMS ((unsigned int, unsigned int, unsigned int));
776static unw_rec_list *output_spill_psprel_p PARAMS ((unsigned int, unsigned int, unsigned int,
777 unsigned int));
778static unw_rec_list *output_spill_sprel_p PARAMS ((unsigned int, unsigned int, unsigned int,
779 unsigned int));
780static unw_rec_list *output_spill_reg PARAMS ((unsigned int, unsigned int, unsigned int,
781 unsigned int));
782static unw_rec_list *output_spill_reg_p PARAMS ((unsigned int, unsigned int, unsigned int,
783 unsigned int, unsigned int));
784static void process_one_record PARAMS ((unw_rec_list *, vbyte_func));
785static void process_unw_records PARAMS ((unw_rec_list *, vbyte_func));
786static int calc_record_size PARAMS ((unw_rec_list *));
787static void set_imask PARAMS ((unw_rec_list *, unsigned long, unsigned long, unsigned int));
788static int count_bits PARAMS ((unsigned long));
789static unsigned long slot_index PARAMS ((unsigned long, unsigned long));
790static void fixup_unw_records PARAMS ((unw_rec_list *));
791static int output_unw_records PARAMS ((unw_rec_list *, void **));
792static int convert_expr_to_ab_reg PARAMS ((expressionS *, unsigned int *, unsigned int *));
793static int convert_expr_to_xy_reg PARAMS ((expressionS *, unsigned int *, unsigned int *));
794static int generate_unwind_image PARAMS ((void));
800eeca4
JW
795
796/* Determine if application register REGNUM resides in the integer
797 unit (as opposed to the memory unit). */
798static int
799ar_is_in_integer_unit (reg)
800 int reg;
801{
802 reg -= REG_AR;
803
804 return (reg == 64 /* pfs */
805 || reg == 65 /* lc */
806 || reg == 66 /* ec */
807 /* ??? ias accepts and puts these in the integer unit. */
808 || (reg >= 112 && reg <= 127));
809}
810
811/* Switch to section NAME and create section if necessary. It's
812 rather ugly that we have to manipulate input_line_pointer but I
813 don't see any other way to accomplish the same thing without
814 changing obj-elf.c (which may be the Right Thing, in the end). */
815static void
816set_section (name)
817 char *name;
818{
819 char *saved_input_line_pointer;
820
821 saved_input_line_pointer = input_line_pointer;
822 input_line_pointer = name;
823 obj_elf_section (0);
824 input_line_pointer = saved_input_line_pointer;
825}
826
827/* Map SHF_IA_64_SHORT to SEC_SMALL_DATA. */
828
829flagword
830ia64_elf_section_flags (flags, attr, type)
831 flagword flags;
832 int attr, type;
833{
834 if (attr & SHF_IA_64_SHORT)
835 flags |= SEC_SMALL_DATA;
836 return flags;
837}
838
839static unsigned int
840set_regstack (ins, locs, outs, rots)
841 unsigned int ins, locs, outs, rots;
842{
843 unsigned int sof; /* size of frame */
844
845 sof = ins + locs + outs;
846 if (sof > 96)
847 {
848 as_bad ("Size of frame exceeds maximum of 96 registers");
849 return 0;
850 }
851 if (rots > sof)
852 {
853 as_warn ("Size of rotating registers exceeds frame size");
854 return 0;
855 }
856 md.in.base = REG_GR + 32;
857 md.loc.base = md.in.base + ins;
858 md.out.base = md.loc.base + locs;
859
860 md.in.num_regs = ins;
861 md.loc.num_regs = locs;
862 md.out.num_regs = outs;
863 md.rot.num_regs = rots;
864 return sof;
865}
866
867void
868ia64_flush_insns ()
869{
870 struct label_fix *lfix;
871 segT saved_seg;
872 subsegT saved_subseg;
873
874 if (!md.last_text_seg)
875 return;
876
877 saved_seg = now_seg;
878 saved_subseg = now_subseg;
879
880 subseg_set (md.last_text_seg, 0);
881
882 while (md.num_slots_in_use > 0)
883 emit_one_bundle (); /* force out queued instructions */
884
885 /* In case there are labels following the last instruction, resolve
886 those now: */
887 for (lfix = CURR_SLOT.label_fixups; lfix; lfix = lfix->next)
888 {
889 S_SET_VALUE (lfix->sym, frag_now_fix ());
890 symbol_set_frag (lfix->sym, frag_now);
891 }
892 CURR_SLOT.label_fixups = 0;
893
894 subseg_set (saved_seg, saved_subseg);
895}
896
897void
898ia64_do_align (nbytes)
899 int nbytes;
900{
901 char *saved_input_line_pointer = input_line_pointer;
902
903 input_line_pointer = "";
904 s_align_bytes (nbytes);
905 input_line_pointer = saved_input_line_pointer;
906}
907
908void
909ia64_cons_align (nbytes)
910 int nbytes;
911{
912 if (md.auto_align)
913 {
914 char *saved_input_line_pointer = input_line_pointer;
915 input_line_pointer = "";
916 s_align_bytes (nbytes);
917 input_line_pointer = saved_input_line_pointer;
918 }
919}
920
921/* Output COUNT bytes to a memory location. */
922static unsigned char *vbyte_mem_ptr = NULL;
923
924void
925output_vbyte_mem (count, ptr, comment)
926 int count;
927 char *ptr;
928 char *comment;
929{
930 int x;
931 if (vbyte_mem_ptr == NULL)
932 abort ();
933
934 if (count == 0)
935 return;
936 for (x = 0; x < count; x++)
937 *(vbyte_mem_ptr++) = ptr[x];
938}
939
940/* Count the number of bytes required for records. */
941static int vbyte_count = 0;
942void
943count_output (count, ptr, comment)
944 int count;
945 char *ptr;
946 char *comment;
947{
948 vbyte_count += count;
949}
950
951static void
952output_R1_format (f, rtype, rlen)
953 vbyte_func f;
954 unw_record_type rtype;
955 int rlen;
956{
e0c9811a 957 int r = 0;
800eeca4
JW
958 char byte;
959 if (rlen > 0x1f)
960 {
961 output_R3_format (f, rtype, rlen);
962 return;
963 }
800eeca4 964
e0c9811a
JW
965 if (rtype == body)
966 r = 1;
967 else if (rtype != prologue)
968 as_bad ("record type is not valid");
969
800eeca4
JW
970 byte = UNW_R1 | (r << 5) | (rlen & 0x1f);
971 (*f) (1, &byte, NULL);
972}
973
974static void
975output_R2_format (f, mask, grsave, rlen)
976 vbyte_func f;
977 int mask, grsave;
978 unsigned long rlen;
979{
980 char bytes[20];
981 int count = 2;
982 mask = (mask & 0x0f);
983 grsave = (grsave & 0x7f);
984
985 bytes[0] = (UNW_R2 | (mask >> 1));
986 bytes[1] = (((mask & 0x01) << 7) | grsave);
987 count += output_leb128 (bytes + 2, rlen, 0);
988 (*f) (count, bytes, NULL);
989}
990
991static void
992output_R3_format (f, rtype, rlen)
993 vbyte_func f;
994 unw_record_type rtype;
995 unsigned long rlen;
996{
e0c9811a 997 int r = 0, count;
800eeca4
JW
998 char bytes[20];
999 if (rlen <= 0x1f)
1000 {
1001 output_R1_format (f, rtype, rlen);
1002 return;
1003 }
e0c9811a
JW
1004
1005 if (rtype == body)
1006 r = 1;
1007 else if (rtype != prologue)
1008 as_bad ("record type is not valid");
800eeca4
JW
1009 bytes[0] = (UNW_R3 | r);
1010 count = output_leb128 (bytes + 1, rlen, 0);
1011 (*f) (count + 1, bytes, NULL);
1012}
1013
1014static void
1015output_P1_format (f, brmask)
1016 vbyte_func f;
1017 int brmask;
1018{
1019 char byte;
1020 byte = UNW_P1 | (brmask & 0x1f);
1021 (*f) (1, &byte, NULL);
1022}
1023
1024static void
1025output_P2_format (f, brmask, gr)
1026 vbyte_func f;
1027 int brmask;
1028 int gr;
1029{
1030 char bytes[2];
1031 brmask = (brmask & 0x1f);
1032 bytes[0] = UNW_P2 | (brmask >> 1);
1033 bytes[1] = (((brmask & 1) << 7) | gr);
1034 (*f) (2, bytes, NULL);
1035}
1036
1037static void
1038output_P3_format (f, rtype, reg)
1039 vbyte_func f;
1040 unw_record_type rtype;
1041 int reg;
1042{
1043 char bytes[2];
e0c9811a 1044 int r = 0;
800eeca4
JW
1045 reg = (reg & 0x7f);
1046 switch (rtype)
1047 {
1048 case psp_gr:
1049 r = 0;
1050 break;
1051 case rp_gr:
1052 r = 1;
1053 break;
1054 case pfs_gr:
1055 r = 2;
1056 break;
1057 case preds_gr:
1058 r = 3;
1059 break;
1060 case unat_gr:
1061 r = 4;
1062 break;
1063 case lc_gr:
1064 r = 5;
1065 break;
1066 case rp_br:
1067 r = 6;
1068 break;
1069 case rnat_gr:
1070 r = 7;
1071 break;
1072 case bsp_gr:
1073 r = 8;
1074 break;
1075 case bspstore_gr:
1076 r = 9;
1077 break;
1078 case fpsr_gr:
1079 r = 10;
1080 break;
1081 case priunat_gr:
1082 r = 11;
1083 break;
1084 default:
1085 as_bad ("Invalid record type for P3 format.");
1086 }
1087 bytes[0] = (UNW_P3 | (r >> 1));
1088 bytes[1] = (((r & 1) << 7) | reg);
1089 (*f) (2, bytes, NULL);
1090}
1091
1092
1093static void
e0c9811a 1094output_P4_format (f, imask, imask_size)
800eeca4 1095 vbyte_func f;
e0c9811a
JW
1096 unsigned char *imask;
1097 unsigned long imask_size;
800eeca4 1098{
e0c9811a
JW
1099 imask[0] = UNW_P4;
1100 (*f) (imask_size, imask, NULL);
800eeca4
JW
1101}
1102
1103static void
1104output_P5_format (f, grmask, frmask)
1105 vbyte_func f;
1106 int grmask;
1107 unsigned long frmask;
1108{
1109 char bytes[4];
1110 grmask = (grmask & 0x0f);
1111
1112 bytes[0] = UNW_P5;
1113 bytes[1] = ((grmask << 4) | ((frmask & 0x000f0000) >> 16));
1114 bytes[2] = ((frmask & 0x0000ff00) >> 8);
1115 bytes[3] = (frmask & 0x000000ff);
1116 (*f) (4, bytes, NULL);
1117}
1118
1119static void
1120output_P6_format (f, rtype, rmask)
1121 vbyte_func f;
1122 unw_record_type rtype;
1123 int rmask;
1124{
1125 char byte;
e0c9811a
JW
1126 int r = 0;
1127
1128 if (rtype == gr_mem)
1129 r = 1;
1130 else if (rtype != fr_mem)
1131 as_bad ("Invalid record type for format P6");
800eeca4
JW
1132 byte = (UNW_P6 | (r << 4) | (rmask & 0x0f));
1133 (*f) (1, &byte, NULL);
1134}
1135
1136static void
1137output_P7_format (f, rtype, w1, w2)
1138 vbyte_func f;
1139 unw_record_type rtype;
1140 unsigned long w1;
1141 unsigned long w2;
1142{
1143 char bytes[20];
1144 int count = 1;
e0c9811a 1145 int r = 0;
800eeca4
JW
1146 count += output_leb128 (bytes + 1, w1, 0);
1147 switch (rtype)
1148 {
1149 case mem_stack_f:
e4c58b25
JW
1150 r = 0;
1151 count += output_leb128 (bytes + count, w2 >> 4, 0);
800eeca4
JW
1152 break;
1153 case mem_stack_v:
1154 r = 1;
1155 break;
1156 case spill_base:
1157 r = 2;
1158 break;
1159 case psp_sprel:
1160 r = 3;
1161 break;
1162 case rp_when:
1163 r = 4;
1164 break;
1165 case rp_psprel:
1166 r = 5;
1167 break;
1168 case pfs_when:
1169 r = 6;
1170 break;
1171 case pfs_psprel:
1172 r = 7;
1173 break;
1174 case preds_when:
1175 r = 8;
1176 break;
1177 case preds_psprel:
1178 r = 9;
1179 break;
1180 case lc_when:
1181 r = 10;
1182 break;
1183 case lc_psprel:
1184 r = 11;
1185 break;
1186 case unat_when:
1187 r = 12;
1188 break;
1189 case unat_psprel:
1190 r = 13;
1191 break;
1192 case fpsr_when:
1193 r = 14;
1194 break;
1195 case fpsr_psprel:
1196 r = 15;
1197 break;
e0c9811a
JW
1198 default:
1199 break;
800eeca4
JW
1200 }
1201 bytes[0] = (UNW_P7 | r);
1202 (*f) (count, bytes, NULL);
1203}
1204
1205static void
1206output_P8_format (f, rtype, t)
1207 vbyte_func f;
1208 unw_record_type rtype;
1209 unsigned long t;
1210{
1211 char bytes[20];
e0c9811a 1212 int r = 0;
800eeca4
JW
1213 int count = 2;
1214 bytes[0] = UNW_P8;
1215 switch (rtype)
1216 {
1217 case rp_sprel:
1218 r = 1;
1219 break;
1220 case pfs_sprel:
1221 r = 2;
1222 break;
1223 case preds_sprel:
1224 r = 3;
1225 break;
1226 case lc_sprel:
1227 r = 4;
1228 break;
1229 case unat_sprel:
1230 r = 5;
1231 break;
1232 case fpsr_sprel:
1233 r = 6;
1234 break;
1235 case bsp_when:
1236 r = 7;
1237 break;
1238 case bsp_psprel:
1239 r = 8;
1240 break;
1241 case bsp_sprel:
1242 r = 9;
1243 break;
1244 case bspstore_when:
1245 r = 10;
1246 break;
1247 case bspstore_psprel:
1248 r = 11;
1249 break;
1250 case bspstore_sprel:
1251 r = 12;
1252 break;
1253 case rnat_when:
1254 r = 13;
1255 break;
1256 case rnat_psprel:
1257 r = 14;
1258 break;
1259 case rnat_sprel:
1260 r = 15;
1261 break;
1262 case priunat_when_gr:
1263 r = 16;
1264 break;
1265 case priunat_psprel:
1266 r = 17;
1267 break;
1268 case priunat_sprel:
1269 r = 18;
1270 break;
1271 case priunat_when_mem:
1272 r = 19;
1273 break;
e0c9811a
JW
1274 default:
1275 break;
800eeca4
JW
1276 }
1277 bytes[1] = r;
1278 count += output_leb128 (bytes + 2, t, 0);
1279 (*f) (count, bytes, NULL);
1280}
1281
1282static void
1283output_P9_format (f, grmask, gr)
1284 vbyte_func f;
1285 int grmask;
1286 int gr;
1287{
1288 char bytes[3];
1289 bytes[0] = UNW_P9;
1290 bytes[1] = (grmask & 0x0f);
1291 bytes[2] = (gr & 0x7f);
1292 (*f) (3, bytes, NULL);
1293}
1294
1295static void
1296output_P10_format (f, abi, context)
1297 vbyte_func f;
1298 int abi;
1299 int context;
1300{
1301 char bytes[3];
1302 bytes[0] = UNW_P10;
1303 bytes[1] = (abi & 0xff);
1304 bytes[2] = (context & 0xff);
1305 (*f) (3, bytes, NULL);
1306}
1307
1308static void
1309output_B1_format (f, rtype, label)
1310 vbyte_func f;
1311 unw_record_type rtype;
1312 unsigned long label;
1313{
1314 char byte;
e0c9811a 1315 int r = 0;
800eeca4
JW
1316 if (label > 0x1f)
1317 {
1318 output_B4_format (f, rtype, label);
1319 return;
1320 }
e0c9811a
JW
1321 if (rtype == copy_state)
1322 r = 1;
1323 else if (rtype != label_state)
1324 as_bad ("Invalid record type for format B1");
800eeca4
JW
1325
1326 byte = (UNW_B1 | (r << 5) | (label & 0x1f));
1327 (*f) (1, &byte, NULL);
1328}
1329
1330static void
1331output_B2_format (f, ecount, t)
1332 vbyte_func f;
1333 unsigned long ecount;
1334 unsigned long t;
1335{
1336 char bytes[20];
1337 int count = 1;
1338 if (ecount > 0x1f)
1339 {
1340 output_B3_format (f, ecount, t);
1341 return;
1342 }
1343 bytes[0] = (UNW_B2 | (ecount & 0x1f));
1344 count += output_leb128 (bytes + 1, t, 0);
1345 (*f) (count, bytes, NULL);
1346}
1347
1348static void
1349output_B3_format (f, ecount, t)
1350 vbyte_func f;
1351 unsigned long ecount;
1352 unsigned long t;
1353{
1354 char bytes[20];
1355 int count = 1;
1356 if (ecount <= 0x1f)
1357 {
1358 output_B2_format (f, ecount, t);
1359 return;
1360 }
1361 bytes[0] = UNW_B3;
1362 count += output_leb128 (bytes + 1, t, 0);
1363 count += output_leb128 (bytes + count, ecount, 0);
1364 (*f) (count, bytes, NULL);
1365}
1366
1367static void
1368output_B4_format (f, rtype, label)
1369 vbyte_func f;
1370 unw_record_type rtype;
1371 unsigned long label;
1372{
1373 char bytes[20];
e0c9811a 1374 int r = 0;
800eeca4
JW
1375 int count = 1;
1376 if (label <= 0x1f)
1377 {
1378 output_B1_format (f, rtype, label);
1379 return;
1380 }
e0c9811a
JW
1381
1382 if (rtype == copy_state)
1383 r = 1;
1384 else if (rtype != label_state)
1385 as_bad ("Invalid record type for format B1");
800eeca4
JW
1386
1387 bytes[0] = (UNW_B4 | (r << 3));
1388 count += output_leb128 (bytes + 1, label, 0);
1389 (*f) (count, bytes, NULL);
1390}
1391
1392static char
e0c9811a
JW
1393format_ab_reg (ab, reg)
1394 int ab;
800eeca4
JW
1395 int reg;
1396{
1397 int ret;
e0c9811a 1398 ab = (ab & 3);
800eeca4 1399 reg = (reg & 0x1f);
e0c9811a 1400 ret = (ab << 5) | reg;
800eeca4
JW
1401 return ret;
1402}
1403
1404static void
e0c9811a 1405output_X1_format (f, rtype, ab, reg, t, w1)
800eeca4
JW
1406 vbyte_func f;
1407 unw_record_type rtype;
e0c9811a 1408 int ab, reg;
800eeca4
JW
1409 unsigned long t;
1410 unsigned long w1;
1411{
1412 char bytes[20];
e0c9811a 1413 int r = 0;
800eeca4
JW
1414 int count = 2;
1415 bytes[0] = UNW_X1;
e0c9811a
JW
1416
1417 if (rtype == spill_sprel)
1418 r = 1;
1419 else if (rtype != spill_psprel)
1420 as_bad ("Invalid record type for format X1");
1421 bytes[1] = ((r << 7) | format_ab_reg (ab, reg));
800eeca4
JW
1422 count += output_leb128 (bytes + 2, t, 0);
1423 count += output_leb128 (bytes + count, w1, 0);
1424 (*f) (count, bytes, NULL);
1425}
1426
1427static void
e0c9811a 1428output_X2_format (f, ab, reg, x, y, treg, t)
800eeca4 1429 vbyte_func f;
e0c9811a 1430 int ab, reg;
800eeca4
JW
1431 int x, y, treg;
1432 unsigned long t;
1433{
1434 char bytes[20];
800eeca4
JW
1435 int count = 3;
1436 bytes[0] = UNW_X2;
e0c9811a 1437 bytes[1] = (((x & 1) << 7) | format_ab_reg (ab, reg));
800eeca4
JW
1438 bytes[2] = (((y & 1) << 7) | (treg & 0x7f));
1439 count += output_leb128 (bytes + 3, t, 0);
1440 (*f) (count, bytes, NULL);
1441}
1442
1443static void
e0c9811a 1444output_X3_format (f, rtype, qp, ab, reg, t, w1)
800eeca4
JW
1445 vbyte_func f;
1446 unw_record_type rtype;
1447 int qp;
e0c9811a 1448 int ab, reg;
800eeca4
JW
1449 unsigned long t;
1450 unsigned long w1;
1451{
1452 char bytes[20];
e0c9811a 1453 int r = 0;
800eeca4 1454 int count = 3;
e0c9811a
JW
1455 bytes[0] = UNW_X3;
1456
1457 if (rtype == spill_sprel_p)
1458 r = 1;
1459 else if (rtype != spill_psprel_p)
1460 as_bad ("Invalid record type for format X3");
800eeca4 1461 bytes[1] = ((r << 7) | (qp & 0x3f));
e0c9811a 1462 bytes[2] = format_ab_reg (ab, reg);
800eeca4
JW
1463 count += output_leb128 (bytes + 3, t, 0);
1464 count += output_leb128 (bytes + count, w1, 0);
1465 (*f) (count, bytes, NULL);
1466}
1467
1468static void
e0c9811a 1469output_X4_format (f, qp, ab, reg, x, y, treg, t)
800eeca4
JW
1470 vbyte_func f;
1471 int qp;
e0c9811a 1472 int ab, reg;
800eeca4
JW
1473 int x, y, treg;
1474 unsigned long t;
1475{
1476 char bytes[20];
800eeca4 1477 int count = 4;
e0c9811a 1478 bytes[0] = UNW_X4;
800eeca4 1479 bytes[1] = (qp & 0x3f);
e0c9811a 1480 bytes[2] = (((x & 1) << 7) | format_ab_reg (ab, reg));
800eeca4
JW
1481 bytes[3] = (((y & 1) << 7) | (treg & 0x7f));
1482 count += output_leb128 (bytes + 4, t, 0);
1483 (*f) (count, bytes, NULL);
1484}
1485
1486/* This function allocates a record list structure, and initializes fields. */
1487static unw_rec_list *
1488alloc_record (unw_record_type t)
1489{
1490 unw_rec_list *ptr;
1491 ptr = xmalloc (sizeof (*ptr));
1492 ptr->next = NULL;
1493 ptr->slot_number = SLOT_NUM_NOT_SET;
1494 ptr->r.type = t;
1495 return ptr;
1496}
1497
800eeca4
JW
1498/* This function frees an entire list of record structures. */
1499void
1500free_list_records (unw_rec_list *first)
1501{
1502 unw_rec_list *ptr;
1503 for (ptr = first; ptr != NULL; )
1504 {
1505 unw_rec_list *tmp = ptr;
e0c9811a
JW
1506
1507 if ((tmp->r.type == prologue || tmp->r.type == prologue_gr)
1508 && tmp->r.record.r.mask.i)
1509 free (tmp->r.record.r.mask.i);
1510
800eeca4
JW
1511 ptr = ptr->next;
1512 free (tmp);
1513 }
1514}
1515
1516static unw_rec_list *
1517output_prologue ()
1518{
1519 unw_rec_list *ptr = alloc_record (prologue);
e0c9811a 1520 memset (&ptr->r.record.r.mask, 0, sizeof (ptr->r.record.r.mask));
800eeca4
JW
1521 return ptr;
1522}
1523
1524static unw_rec_list *
1525output_prologue_gr (saved_mask, reg)
1526 unsigned int saved_mask;
1527 unsigned int reg;
1528{
1529 unw_rec_list *ptr = alloc_record (prologue_gr);
e0c9811a
JW
1530 memset (&ptr->r.record.r.mask, 0, sizeof (ptr->r.record.r.mask));
1531 ptr->r.record.r.grmask = saved_mask;
800eeca4
JW
1532 ptr->r.record.r.grsave = reg;
1533 return ptr;
1534}
1535
1536static unw_rec_list *
1537output_body ()
1538{
1539 unw_rec_list *ptr = alloc_record (body);
1540 return ptr;
1541}
1542
1543static unw_rec_list *
1544output_mem_stack_f (size)
1545 unsigned int size;
1546{
1547 unw_rec_list *ptr = alloc_record (mem_stack_f);
1548 ptr->r.record.p.size = size;
1549 return ptr;
1550}
1551
1552static unw_rec_list *
1553output_mem_stack_v ()
1554{
1555 unw_rec_list *ptr = alloc_record (mem_stack_v);
1556 return ptr;
1557}
1558
1559static unw_rec_list *
1560output_psp_gr (gr)
1561 unsigned int gr;
1562{
1563 unw_rec_list *ptr = alloc_record (psp_gr);
1564 ptr->r.record.p.gr = gr;
1565 return ptr;
1566}
1567
1568static unw_rec_list *
1569output_psp_sprel (offset)
1570 unsigned int offset;
1571{
1572 unw_rec_list *ptr = alloc_record (psp_sprel);
e0c9811a 1573 ptr->r.record.p.spoff = offset/4;
800eeca4
JW
1574 return ptr;
1575}
1576
1577static unw_rec_list *
1578output_rp_when ()
1579{
1580 unw_rec_list *ptr = alloc_record (rp_when);
1581 return ptr;
1582}
1583
1584static unw_rec_list *
1585output_rp_gr (gr)
1586 unsigned int gr;
1587{
1588 unw_rec_list *ptr = alloc_record (rp_gr);
1589 ptr->r.record.p.gr = gr;
1590 return ptr;
1591}
1592
1593static unw_rec_list *
1594output_rp_br (br)
1595 unsigned int br;
1596{
1597 unw_rec_list *ptr = alloc_record (rp_br);
1598 ptr->r.record.p.br = br;
1599 return ptr;
1600}
1601
1602static unw_rec_list *
1603output_rp_psprel (offset)
1604 unsigned int offset;
1605{
1606 unw_rec_list *ptr = alloc_record (rp_psprel);
e0c9811a 1607 ptr->r.record.p.pspoff = offset/4;
800eeca4
JW
1608 return ptr;
1609}
1610
1611static unw_rec_list *
1612output_rp_sprel (offset)
1613 unsigned int offset;
1614{
1615 unw_rec_list *ptr = alloc_record (rp_sprel);
e0c9811a 1616 ptr->r.record.p.spoff = offset/4;
800eeca4
JW
1617 return ptr;
1618}
1619
1620static unw_rec_list *
1621output_pfs_when ()
1622{
1623 unw_rec_list *ptr = alloc_record (pfs_when);
1624 return ptr;
1625}
1626
1627static unw_rec_list *
1628output_pfs_gr (gr)
1629 unsigned int gr;
1630{
1631 unw_rec_list *ptr = alloc_record (pfs_gr);
1632 ptr->r.record.p.gr = gr;
1633 return ptr;
1634}
1635
1636static unw_rec_list *
1637output_pfs_psprel (offset)
1638 unsigned int offset;
1639{
1640 unw_rec_list *ptr = alloc_record (pfs_psprel);
e0c9811a 1641 ptr->r.record.p.pspoff = offset/4;
800eeca4
JW
1642 return ptr;
1643}
1644
1645static unw_rec_list *
1646output_pfs_sprel (offset)
1647 unsigned int offset;
1648{
1649 unw_rec_list *ptr = alloc_record (pfs_sprel);
e0c9811a 1650 ptr->r.record.p.spoff = offset/4;
800eeca4
JW
1651 return ptr;
1652}
1653
1654static unw_rec_list *
1655output_preds_when ()
1656{
1657 unw_rec_list *ptr = alloc_record (preds_when);
1658 return ptr;
1659}
1660
1661static unw_rec_list *
1662output_preds_gr (gr)
1663 unsigned int gr;
1664{
1665 unw_rec_list *ptr = alloc_record (preds_gr);
1666 ptr->r.record.p.gr = gr;
1667 return ptr;
1668}
1669
1670static unw_rec_list *
1671output_preds_psprel (offset)
1672 unsigned int offset;
1673{
1674 unw_rec_list *ptr = alloc_record (preds_psprel);
e0c9811a 1675 ptr->r.record.p.pspoff = offset/4;
800eeca4
JW
1676 return ptr;
1677}
1678
1679static unw_rec_list *
1680output_preds_sprel (offset)
1681 unsigned int offset;
1682{
1683 unw_rec_list *ptr = alloc_record (preds_sprel);
e0c9811a 1684 ptr->r.record.p.spoff = offset/4;
800eeca4
JW
1685 return ptr;
1686}
1687
1688static unw_rec_list *
1689output_fr_mem (mask)
1690 unsigned int mask;
1691{
1692 unw_rec_list *ptr = alloc_record (fr_mem);
1693 ptr->r.record.p.rmask = mask;
1694 return ptr;
1695}
1696
1697static unw_rec_list *
1698output_frgr_mem (gr_mask, fr_mask)
1699 unsigned int gr_mask;
1700 unsigned int fr_mask;
1701{
1702 unw_rec_list *ptr = alloc_record (frgr_mem);
1703 ptr->r.record.p.grmask = gr_mask;
1704 ptr->r.record.p.frmask = fr_mask;
1705 return ptr;
1706}
1707
1708static unw_rec_list *
1709output_gr_gr (mask, reg)
1710 unsigned int mask;
1711 unsigned int reg;
1712{
1713 unw_rec_list *ptr = alloc_record (gr_gr);
1714 ptr->r.record.p.grmask = mask;
1715 ptr->r.record.p.gr = reg;
1716 return ptr;
1717}
1718
1719static unw_rec_list *
1720output_gr_mem (mask)
1721 unsigned int mask;
1722{
1723 unw_rec_list *ptr = alloc_record (gr_mem);
1724 ptr->r.record.p.rmask = mask;
1725 return ptr;
1726}
1727
1728static unw_rec_list *
1729output_br_mem (unsigned int mask)
1730{
1731 unw_rec_list *ptr = alloc_record (br_mem);
1732 ptr->r.record.p.brmask = mask;
1733 return ptr;
1734}
1735
1736static unw_rec_list *
1737output_br_gr (save_mask, reg)
1738 unsigned int save_mask;
1739 unsigned int reg;
1740{
1741 unw_rec_list *ptr = alloc_record (br_gr);
1742 ptr->r.record.p.brmask = save_mask;
1743 ptr->r.record.p.gr = reg;
1744 return ptr;
1745}
1746
1747static unw_rec_list *
1748output_spill_base (offset)
1749 unsigned int offset;
1750{
1751 unw_rec_list *ptr = alloc_record (spill_base);
e0c9811a 1752 ptr->r.record.p.pspoff = offset/4;
800eeca4
JW
1753 return ptr;
1754}
1755
1756static unw_rec_list *
1757output_unat_when ()
1758{
1759 unw_rec_list *ptr = alloc_record (unat_when);
1760 return ptr;
1761}
1762
1763static unw_rec_list *
1764output_unat_gr (gr)
1765 unsigned int gr;
1766{
1767 unw_rec_list *ptr = alloc_record (unat_gr);
1768 ptr->r.record.p.gr = gr;
1769 return ptr;
1770}
1771
1772static unw_rec_list *
1773output_unat_psprel (offset)
1774 unsigned int offset;
1775{
1776 unw_rec_list *ptr = alloc_record (unat_psprel);
e0c9811a 1777 ptr->r.record.p.pspoff = offset/4;
800eeca4
JW
1778 return ptr;
1779}
1780
1781static unw_rec_list *
1782output_unat_sprel (offset)
1783 unsigned int offset;
1784{
1785 unw_rec_list *ptr = alloc_record (unat_sprel);
e0c9811a 1786 ptr->r.record.p.spoff = offset/4;
800eeca4
JW
1787 return ptr;
1788}
1789
1790static unw_rec_list *
1791output_lc_when ()
1792{
1793 unw_rec_list *ptr = alloc_record (lc_when);
1794 return ptr;
1795}
1796
1797static unw_rec_list *
1798output_lc_gr (gr)
1799 unsigned int gr;
1800{
1801 unw_rec_list *ptr = alloc_record (lc_gr);
1802 ptr->r.record.p.gr = gr;
1803 return ptr;
1804}
1805
1806static unw_rec_list *
1807output_lc_psprel (offset)
1808 unsigned int offset;
1809{
1810 unw_rec_list *ptr = alloc_record (lc_psprel);
e0c9811a 1811 ptr->r.record.p.pspoff = offset/4;
800eeca4
JW
1812 return ptr;
1813}
1814
1815static unw_rec_list *
1816output_lc_sprel (offset)
1817 unsigned int offset;
1818{
1819 unw_rec_list *ptr = alloc_record (lc_sprel);
e0c9811a 1820 ptr->r.record.p.spoff = offset/4;
800eeca4
JW
1821 return ptr;
1822}
1823
1824static unw_rec_list *
1825output_fpsr_when ()
1826{
1827 unw_rec_list *ptr = alloc_record (fpsr_when);
1828 return ptr;
1829}
1830
1831static unw_rec_list *
1832output_fpsr_gr (gr)
1833 unsigned int gr;
1834{
1835 unw_rec_list *ptr = alloc_record (fpsr_gr);
1836 ptr->r.record.p.gr = gr;
1837 return ptr;
1838}
1839
1840static unw_rec_list *
1841output_fpsr_psprel (offset)
1842 unsigned int offset;
1843{
1844 unw_rec_list *ptr = alloc_record (fpsr_psprel);
e0c9811a 1845 ptr->r.record.p.pspoff = offset/4;
800eeca4
JW
1846 return ptr;
1847}
1848
1849static unw_rec_list *
1850output_fpsr_sprel (offset)
1851 unsigned int offset;
1852{
1853 unw_rec_list *ptr = alloc_record (fpsr_sprel);
e0c9811a 1854 ptr->r.record.p.spoff = offset/4;
800eeca4
JW
1855 return ptr;
1856}
1857
1858static unw_rec_list *
1859output_priunat_when_gr ()
1860{
1861 unw_rec_list *ptr = alloc_record (priunat_when_gr);
1862 return ptr;
1863}
1864
1865static unw_rec_list *
1866output_priunat_when_mem ()
1867{
1868 unw_rec_list *ptr = alloc_record (priunat_when_mem);
1869 return ptr;
1870}
1871
1872static unw_rec_list *
1873output_priunat_gr (gr)
1874 unsigned int gr;
1875{
1876 unw_rec_list *ptr = alloc_record (priunat_gr);
1877 ptr->r.record.p.gr = gr;
1878 return ptr;
1879}
1880
1881static unw_rec_list *
1882output_priunat_psprel (offset)
1883 unsigned int offset;
1884{
1885 unw_rec_list *ptr = alloc_record (priunat_psprel);
e0c9811a 1886 ptr->r.record.p.pspoff = offset/4;
800eeca4
JW
1887 return ptr;
1888}
1889
1890static unw_rec_list *
1891output_priunat_sprel (offset)
1892 unsigned int offset;
1893{
1894 unw_rec_list *ptr = alloc_record (priunat_sprel);
e0c9811a 1895 ptr->r.record.p.spoff = offset/4;
800eeca4
JW
1896 return ptr;
1897}
1898
1899static unw_rec_list *
1900output_bsp_when ()
1901{
1902 unw_rec_list *ptr = alloc_record (bsp_when);
1903 return ptr;
1904}
1905
1906static unw_rec_list *
1907output_bsp_gr (gr)
1908 unsigned int gr;
1909{
1910 unw_rec_list *ptr = alloc_record (bsp_gr);
1911 ptr->r.record.p.gr = gr;
1912 return ptr;
1913}
1914
1915static unw_rec_list *
1916output_bsp_psprel (offset)
1917 unsigned int offset;
1918{
1919 unw_rec_list *ptr = alloc_record (bsp_psprel);
e0c9811a 1920 ptr->r.record.p.pspoff = offset/4;
800eeca4
JW
1921 return ptr;
1922}
1923
1924static unw_rec_list *
1925output_bsp_sprel (offset)
1926 unsigned int offset;
1927{
1928 unw_rec_list *ptr = alloc_record (bsp_sprel);
e0c9811a 1929 ptr->r.record.p.spoff = offset/4;
800eeca4
JW
1930 return ptr;
1931}
1932
1933static unw_rec_list *
1934output_bspstore_when ()
1935{
1936 unw_rec_list *ptr = alloc_record (bspstore_when);
1937 return ptr;
1938}
1939
1940static unw_rec_list *
1941output_bspstore_gr (gr)
1942 unsigned int gr;
1943{
1944 unw_rec_list *ptr = alloc_record (bspstore_gr);
1945 ptr->r.record.p.gr = gr;
1946 return ptr;
1947}
1948
1949static unw_rec_list *
1950output_bspstore_psprel (offset)
1951 unsigned int offset;
1952{
1953 unw_rec_list *ptr = alloc_record (bspstore_psprel);
e0c9811a 1954 ptr->r.record.p.pspoff = offset/4;
800eeca4
JW
1955 return ptr;
1956}
1957
1958static unw_rec_list *
1959output_bspstore_sprel (offset)
1960 unsigned int offset;
1961{
1962 unw_rec_list *ptr = alloc_record (bspstore_sprel);
e0c9811a 1963 ptr->r.record.p.spoff = offset/4;
800eeca4
JW
1964 return ptr;
1965}
1966
1967static unw_rec_list *
1968output_rnat_when ()
1969{
1970 unw_rec_list *ptr = alloc_record (rnat_when);
1971 return ptr;
1972}
1973
1974static unw_rec_list *
1975output_rnat_gr (gr)
1976 unsigned int gr;
1977{
1978 unw_rec_list *ptr = alloc_record (rnat_gr);
1979 ptr->r.record.p.gr = gr;
1980 return ptr;
1981}
1982
1983static unw_rec_list *
1984output_rnat_psprel (offset)
1985 unsigned int offset;
1986{
1987 unw_rec_list *ptr = alloc_record (rnat_psprel);
e0c9811a 1988 ptr->r.record.p.pspoff = offset/4;
800eeca4
JW
1989 return ptr;
1990}
1991
1992static unw_rec_list *
1993output_rnat_sprel (offset)
1994 unsigned int offset;
1995{
1996 unw_rec_list *ptr = alloc_record (rnat_sprel);
e0c9811a 1997 ptr->r.record.p.spoff = offset/4;
800eeca4
JW
1998 return ptr;
1999}
2000
2001static unw_rec_list *
e0c9811a
JW
2002output_unwabi (abi, context)
2003 unsigned long abi;
2004 unsigned long context;
800eeca4 2005{
e0c9811a
JW
2006 unw_rec_list *ptr = alloc_record (unwabi);
2007 ptr->r.record.p.abi = abi;
2008 ptr->r.record.p.context = context;
800eeca4
JW
2009 return ptr;
2010}
2011
2012static unw_rec_list *
e0c9811a 2013output_epilogue (unsigned long ecount)
800eeca4 2014{
e0c9811a
JW
2015 unw_rec_list *ptr = alloc_record (epilogue);
2016 ptr->r.record.b.ecount = ecount;
800eeca4
JW
2017 return ptr;
2018}
2019
2020static unw_rec_list *
e0c9811a 2021output_label_state (unsigned long label)
800eeca4 2022{
e0c9811a
JW
2023 unw_rec_list *ptr = alloc_record (label_state);
2024 ptr->r.record.b.label = label;
800eeca4
JW
2025 return ptr;
2026}
2027
2028static unw_rec_list *
e0c9811a
JW
2029output_copy_state (unsigned long label)
2030{
2031 unw_rec_list *ptr = alloc_record (copy_state);
2032 ptr->r.record.b.label = label;
2033 return ptr;
2034}
2035
2036static unw_rec_list *
2037output_spill_psprel (ab, reg, offset)
2038 unsigned int ab;
800eeca4
JW
2039 unsigned int reg;
2040 unsigned int offset;
2041{
2042 unw_rec_list *ptr = alloc_record (spill_psprel);
e0c9811a 2043 ptr->r.record.x.ab = ab;
800eeca4 2044 ptr->r.record.x.reg = reg;
e0c9811a 2045 ptr->r.record.x.pspoff = offset/4;
800eeca4
JW
2046 return ptr;
2047}
2048
2049static unw_rec_list *
e0c9811a
JW
2050output_spill_sprel (ab, reg, offset)
2051 unsigned int ab;
800eeca4
JW
2052 unsigned int reg;
2053 unsigned int offset;
2054{
2055 unw_rec_list *ptr = alloc_record (spill_sprel);
e0c9811a 2056 ptr->r.record.x.ab = ab;
800eeca4 2057 ptr->r.record.x.reg = reg;
e0c9811a 2058 ptr->r.record.x.spoff = offset/4;
800eeca4
JW
2059 return ptr;
2060}
2061
2062static unw_rec_list *
e0c9811a
JW
2063output_spill_psprel_p (ab, reg, offset, predicate)
2064 unsigned int ab;
800eeca4
JW
2065 unsigned int reg;
2066 unsigned int offset;
2067 unsigned int predicate;
2068{
2069 unw_rec_list *ptr = alloc_record (spill_psprel_p);
e0c9811a 2070 ptr->r.record.x.ab = ab;
800eeca4 2071 ptr->r.record.x.reg = reg;
e0c9811a 2072 ptr->r.record.x.pspoff = offset/4;
800eeca4
JW
2073 ptr->r.record.x.qp = predicate;
2074 return ptr;
2075}
2076
2077static unw_rec_list *
e0c9811a
JW
2078output_spill_sprel_p (ab, reg, offset, predicate)
2079 unsigned int ab;
800eeca4
JW
2080 unsigned int reg;
2081 unsigned int offset;
2082 unsigned int predicate;
2083{
2084 unw_rec_list *ptr = alloc_record (spill_sprel_p);
e0c9811a 2085 ptr->r.record.x.ab = ab;
800eeca4 2086 ptr->r.record.x.reg = reg;
e0c9811a 2087 ptr->r.record.x.spoff = offset/4;
800eeca4
JW
2088 ptr->r.record.x.qp = predicate;
2089 return ptr;
2090}
2091
2092static unw_rec_list *
e0c9811a
JW
2093output_spill_reg (ab, reg, targ_reg, xy)
2094 unsigned int ab;
800eeca4
JW
2095 unsigned int reg;
2096 unsigned int targ_reg;
2097 unsigned int xy;
2098{
2099 unw_rec_list *ptr = alloc_record (spill_reg);
e0c9811a 2100 ptr->r.record.x.ab = ab;
800eeca4
JW
2101 ptr->r.record.x.reg = reg;
2102 ptr->r.record.x.treg = targ_reg;
2103 ptr->r.record.x.xy = xy;
2104 return ptr;
2105}
2106
2107static unw_rec_list *
e0c9811a
JW
2108output_spill_reg_p (ab, reg, targ_reg, xy, predicate)
2109 unsigned int ab;
800eeca4
JW
2110 unsigned int reg;
2111 unsigned int targ_reg;
2112 unsigned int xy;
2113 unsigned int predicate;
2114{
2115 unw_rec_list *ptr = alloc_record (spill_reg_p);
e0c9811a 2116 ptr->r.record.x.ab = ab;
800eeca4
JW
2117 ptr->r.record.x.reg = reg;
2118 ptr->r.record.x.treg = targ_reg;
2119 ptr->r.record.x.xy = xy;
2120 ptr->r.record.x.qp = predicate;
2121 return ptr;
2122}
2123
2124/* Given a unw_rec_list process the correct format with the
2125 specified function. */
2126static void
2127process_one_record (ptr, f)
2128 unw_rec_list *ptr;
2129 vbyte_func f;
2130{
e0c9811a
JW
2131 unsigned long fr_mask, gr_mask;
2132
800eeca4
JW
2133 switch (ptr->r.type)
2134 {
e0c9811a
JW
2135 case gr_mem:
2136 case fr_mem:
2137 case br_mem:
2138 case frgr_mem:
2139 /* these are taken care of by prologue/prologue_gr */
2140 break;
2141
2142 case prologue_gr:
800eeca4 2143 case prologue:
e0c9811a
JW
2144 if (ptr->r.type == prologue_gr)
2145 output_R2_format (f, ptr->r.record.r.grmask,
2146 ptr->r.record.r.grsave, ptr->r.record.r.rlen);
2147 else
2148 output_R1_format (f, ptr->r.type, ptr->r.record.r.rlen);
2149
2150 /* output descriptor(s) for union of register spills (if any): */
2151 gr_mask = ptr->r.record.r.mask.gr_mem;
2152 fr_mask = ptr->r.record.r.mask.fr_mem;
2153 if (fr_mask)
2154 {
2155 if ((fr_mask & ~0xfUL) == 0)
2156 output_P6_format (f, fr_mem, fr_mask);
2157 else
2158 {
2159 output_P5_format (f, gr_mask, fr_mask);
2160 gr_mask = 0;
2161 }
2162 }
2163 if (gr_mask)
2164 output_P6_format (f, gr_mem, gr_mask);
2165 if (ptr->r.record.r.mask.br_mem)
2166 output_P1_format (f, ptr->r.record.r.mask.br_mem);
2167
2168 /* output imask descriptor if necessary: */
2169 if (ptr->r.record.r.mask.i)
2170 output_P4_format (f, ptr->r.record.r.mask.i,
2171 ptr->r.record.r.imask_size);
2172 break;
2173
800eeca4
JW
2174 case body:
2175 output_R1_format (f, ptr->r.type, ptr->r.record.r.rlen);
2176 break;
800eeca4
JW
2177 case mem_stack_f:
2178 case mem_stack_v:
2179 output_P7_format (f, ptr->r.type, ptr->r.record.p.t,
2180 ptr->r.record.p.size);
2181 break;
2182 case psp_gr:
2183 case rp_gr:
2184 case pfs_gr:
2185 case preds_gr:
2186 case unat_gr:
2187 case lc_gr:
2188 case fpsr_gr:
2189 case priunat_gr:
2190 case bsp_gr:
2191 case bspstore_gr:
2192 case rnat_gr:
2193 output_P3_format (f, ptr->r.type, ptr->r.record.p.gr);
2194 break;
2195 case rp_br:
2196 output_P3_format (f, rp_br, ptr->r.record.p.br);
2197 break;
2198 case psp_sprel:
2199 output_P7_format (f, psp_sprel, ptr->r.record.p.spoff, 0);
2200 break;
2201 case rp_when:
2202 case pfs_when:
2203 case preds_when:
2204 case unat_when:
2205 case lc_when:
2206 case fpsr_when:
2207 output_P7_format (f, ptr->r.type, ptr->r.record.p.t, 0);
2208 break;
2209 case rp_psprel:
2210 case pfs_psprel:
2211 case preds_psprel:
2212 case unat_psprel:
2213 case lc_psprel:
2214 case fpsr_psprel:
2215 case spill_base:
2216 output_P7_format (f, ptr->r.type, ptr->r.record.p.pspoff, 0);
2217 break;
2218 case rp_sprel:
2219 case pfs_sprel:
2220 case preds_sprel:
2221 case unat_sprel:
2222 case lc_sprel:
2223 case fpsr_sprel:
2224 case priunat_sprel:
2225 case bsp_sprel:
2226 case bspstore_sprel:
2227 case rnat_sprel:
2228 output_P8_format (f, ptr->r.type, ptr->r.record.p.spoff);
2229 break;
800eeca4
JW
2230 case gr_gr:
2231 output_P9_format (f, ptr->r.record.p.grmask, ptr->r.record.p.gr);
2232 break;
800eeca4
JW
2233 case br_gr:
2234 output_P2_format (f, ptr->r.record.p.brmask, ptr->r.record.p.gr);
2235 break;
2236 case spill_mask:
2237 as_bad ("spill_mask record unimplemented.");
2238 break;
2239 case priunat_when_gr:
2240 case priunat_when_mem:
2241 case bsp_when:
2242 case bspstore_when:
2243 case rnat_when:
2244 output_P8_format (f, ptr->r.type, ptr->r.record.p.t);
2245 break;
2246 case priunat_psprel:
2247 case bsp_psprel:
2248 case bspstore_psprel:
2249 case rnat_psprel:
2250 output_P8_format (f, ptr->r.type, ptr->r.record.p.pspoff);
2251 break;
e0c9811a
JW
2252 case unwabi:
2253 output_P10_format (f, ptr->r.record.p.abi, ptr->r.record.p.context);
2254 break;
800eeca4 2255 case epilogue:
e0c9811a 2256 output_B3_format (f, ptr->r.record.b.ecount, ptr->r.record.b.t);
800eeca4
JW
2257 break;
2258 case label_state:
800eeca4 2259 case copy_state:
e0c9811a 2260 output_B4_format (f, ptr->r.type, ptr->r.record.b.label);
800eeca4
JW
2261 break;
2262 case spill_psprel:
e0c9811a
JW
2263 output_X1_format (f, ptr->r.type, ptr->r.record.x.ab,
2264 ptr->r.record.x.reg, ptr->r.record.x.t,
2265 ptr->r.record.x.pspoff);
2266 break;
800eeca4 2267 case spill_sprel:
e0c9811a
JW
2268 output_X1_format (f, ptr->r.type, ptr->r.record.x.ab,
2269 ptr->r.record.x.reg, ptr->r.record.x.t,
2270 ptr->r.record.x.spoff);
2271 break;
800eeca4 2272 case spill_reg:
e0c9811a
JW
2273 output_X2_format (f, ptr->r.record.x.ab, ptr->r.record.x.reg,
2274 ptr->r.record.x.xy >> 1, ptr->r.record.x.xy,
2275 ptr->r.record.x.treg, ptr->r.record.x.t);
2276 break;
800eeca4 2277 case spill_psprel_p:
e0c9811a
JW
2278 output_X3_format (f, ptr->r.type, ptr->r.record.x.qp,
2279 ptr->r.record.x.ab, ptr->r.record.x.reg,
2280 ptr->r.record.x.t, ptr->r.record.x.pspoff);
2281 break;
800eeca4 2282 case spill_sprel_p:
e0c9811a
JW
2283 output_X3_format (f, ptr->r.type, ptr->r.record.x.qp,
2284 ptr->r.record.x.ab, ptr->r.record.x.reg,
2285 ptr->r.record.x.t, ptr->r.record.x.spoff);
2286 break;
800eeca4 2287 case spill_reg_p:
e0c9811a
JW
2288 output_X4_format (f, ptr->r.record.x.qp, ptr->r.record.x.ab,
2289 ptr->r.record.x.reg, ptr->r.record.x.xy >> 1,
2290 ptr->r.record.x.xy, ptr->r.record.x.treg,
2291 ptr->r.record.x.t);
800eeca4
JW
2292 break;
2293 default:
2294 as_bad ("record_type_not_valid");
2295 break;
2296 }
2297}
2298
2299/* Given a unw_rec_list list, process all the records with
2300 the specified function. */
2301static void
2302process_unw_records (list, f)
2303 unw_rec_list *list;
2304 vbyte_func f;
2305{
2306 unw_rec_list *ptr;
2307 for (ptr = list; ptr; ptr = ptr->next)
2308 process_one_record (ptr, f);
2309}
2310
2311/* Determine the size of a record list in bytes. */
2312static int
2313calc_record_size (list)
2314 unw_rec_list *list;
2315{
2316 vbyte_count = 0;
2317 process_unw_records (list, count_output);
2318 return vbyte_count;
2319}
2320
e0c9811a
JW
2321/* Update IMASK bitmask to reflect the fact that one or more registers
2322 of type TYPE are saved starting at instruction with index T. If N
2323 bits are set in REGMASK, it is assumed that instructions T through
2324 T+N-1 save these registers.
2325
2326 TYPE values:
2327 0: no save
2328 1: instruction saves next fp reg
2329 2: instruction saves next general reg
2330 3: instruction saves next branch reg */
2331static void
2332set_imask (region, regmask, t, type)
2333 unw_rec_list *region;
2334 unsigned long regmask;
2335 unsigned long t;
2336 unsigned int type;
2337{
2338 unsigned char *imask;
2339 unsigned long imask_size;
2340 unsigned int i;
2341 int pos;
2342
2343 imask = region->r.record.r.mask.i;
2344 imask_size = region->r.record.r.imask_size;
2345 if (!imask)
2346 {
2347 imask_size = (region->r.record.r.rlen*2 + 7)/8 + 1;
2348 imask = xmalloc (imask_size);
2349 memset (imask, 0, imask_size);
2350
2351 region->r.record.r.imask_size = imask_size;
2352 region->r.record.r.mask.i = imask;
2353 }
2354
2355 i = (t/4) + 1;
2356 pos = 2*(3 - t%4);
2357 while (regmask)
2358 {
2359 if (i >= imask_size)
2360 {
2361 as_bad ("Ignoring attempt to spill beyond end of region");
2362 return;
2363 }
2364
2365 imask[i] |= (type & 0x3) << pos;
2366
2367 regmask &= (regmask - 1);
2368 pos -= 2;
2369 if (pos < 0)
2370 {
2371 pos = 0;
2372 ++i;
2373 }
2374 }
2375}
2376
2377static int
2378count_bits (unsigned long mask)
2379{
2380 int n = 0;
2381
2382 while (mask)
2383 {
2384 mask &= mask - 1;
2385 ++n;
2386 }
2387 return n;
2388}
2389
2390unsigned long
2391slot_index (unsigned long slot_addr, unsigned long first_addr)
2392{
2393 return (3*((slot_addr >> 4) - (first_addr >> 4))
2394 + ((slot_addr & 0x3) - (first_addr & 0x3)));
2395}
2396
800eeca4
JW
2397/* Given a complete record list, process any records which have
2398 unresolved fields, (ie length counts for a prologue). After
2399 this has been run, all neccessary information should be available
2400 within each record to generate an image. */
2401static void
2402fixup_unw_records (list)
2403 unw_rec_list *list;
2404{
e0c9811a
JW
2405 unw_rec_list *ptr, *region = 0;
2406 unsigned long first_addr = 0, rlen = 0, t;
2407
800eeca4
JW
2408 for (ptr = list; ptr; ptr = ptr->next)
2409 {
2410 if (ptr->slot_number == SLOT_NUM_NOT_SET)
2411 as_bad (" Insn slot not set in unwind record.");
e0c9811a 2412 t = slot_index (ptr->slot_number, first_addr);
800eeca4
JW
2413 switch (ptr->r.type)
2414 {
2415 case prologue:
2416 case prologue_gr:
2417 case body:
2418 {
2419 unw_rec_list *last;
e0c9811a 2420 int size, dir_len = 0;
800eeca4 2421 unsigned long last_addr;
e0c9811a 2422
800eeca4
JW
2423 first_addr = ptr->slot_number;
2424 ptr->slot_number = 0;
2425 /* Find either the next body/prologue start, or the end of
2426 the list, and determine the size of the region. */
e0c9811a
JW
2427 last_addr = unwind.next_slot_number;
2428 for (last = ptr->next; last != NULL; last = last->next)
2429 if (last->r.type == prologue || last->r.type == prologue_gr
2430 || last->r.type == body)
800eeca4 2431 {
e0c9811a 2432 last_addr = last->slot_number;
800eeca4
JW
2433 break;
2434 }
e0c9811a
JW
2435 else if (!last->next)
2436 {
2437 /* In the absence of an explicit .body directive,
2438 the prologue ends after the last instruction
2439 covered by an unwind directive. */
2440 if (ptr->r.type != body)
2441 {
2442 last_addr = last->slot_number;
2443 switch (last->r.type)
2444 {
2445 case frgr_mem:
2446 dir_len = (count_bits (last->r.record.p.frmask)
2447 + count_bits (last->r.record.p.grmask));
2448 break;
2449 case fr_mem:
2450 case gr_mem:
2451 dir_len += count_bits (last->r.record.p.rmask);
2452 break;
2453 case br_mem:
2454 case br_gr:
2455 dir_len += count_bits (last->r.record.p.brmask);
2456 break;
2457 case gr_gr:
2458 dir_len += count_bits (last->r.record.p.grmask);
2459 break;
2460 default:
2461 dir_len = 1;
2462 break;
2463 }
2464 }
2465 break;
2466 }
2467 size = slot_index (last_addr, first_addr) + dir_len;
2468 rlen = ptr->r.record.r.rlen = size;
2469 region = ptr;
800eeca4
JW
2470 break;
2471 }
e0c9811a
JW
2472 case epilogue:
2473 ptr->r.record.b.t = rlen - 1 - t;
2474 break;
2475
800eeca4
JW
2476 case mem_stack_f:
2477 case mem_stack_v:
2478 case rp_when:
2479 case pfs_when:
2480 case preds_when:
2481 case unat_when:
2482 case lc_when:
2483 case fpsr_when:
2484 case priunat_when_gr:
2485 case priunat_when_mem:
2486 case bsp_when:
2487 case bspstore_when:
2488 case rnat_when:
e0c9811a
JW
2489 ptr->r.record.p.t = t;
2490 break;
2491
2492 case spill_reg:
2493 case spill_sprel:
2494 case spill_psprel:
2495 case spill_reg_p:
2496 case spill_sprel_p:
2497 case spill_psprel_p:
2498 ptr->r.record.x.t = t;
2499 break;
2500
2501 case frgr_mem:
2502 if (!region)
2503 {
2504 as_bad ("frgr_mem record before region record!\n");
2505 return;
2506 }
2507 region->r.record.r.mask.fr_mem |= ptr->r.record.p.frmask;
2508 region->r.record.r.mask.gr_mem |= ptr->r.record.p.grmask;
2509 set_imask (region, ptr->r.record.p.frmask, t, 1);
2510 set_imask (region, ptr->r.record.p.grmask, t, 2);
2511 break;
2512 case fr_mem:
2513 if (!region)
2514 {
2515 as_bad ("fr_mem record before region record!\n");
2516 return;
2517 }
2518 region->r.record.r.mask.fr_mem |= ptr->r.record.p.rmask;
2519 set_imask (region, ptr->r.record.p.rmask, t, 1);
2520 break;
2521 case gr_mem:
2522 if (!region)
2523 {
2524 as_bad ("gr_mem record before region record!\n");
2525 return;
2526 }
2527 region->r.record.r.mask.gr_mem |= ptr->r.record.p.rmask;
2528 set_imask (region, ptr->r.record.p.rmask, t, 2);
2529 break;
2530 case br_mem:
2531 if (!region)
2532 {
2533 as_bad ("br_mem record before region record!\n");
2534 return;
2535 }
2536 region->r.record.r.mask.br_mem |= ptr->r.record.p.brmask;
2537 set_imask (region, ptr->r.record.p.brmask, t, 3);
2538 break;
2539
2540 case gr_gr:
2541 if (!region)
2542 {
2543 as_bad ("gr_gr record before region record!\n");
2544 return;
2545 }
2546 set_imask (region, ptr->r.record.p.grmask, t, 2);
2547 break;
2548 case br_gr:
2549 if (!region)
2550 {
2551 as_bad ("br_gr record before region record!\n");
2552 return;
2553 }
2554 set_imask (region, ptr->r.record.p.brmask, t, 3);
2555 break;
2556
2557 default:
2558 break;
800eeca4
JW
2559 }
2560 }
2561}
2562
2563/* Generate an unwind image from a record list. Returns the number of
2564 bytes in the resulting image. The memory image itselof is returned
2565 in the 'ptr' parameter. */
2566static int
2567output_unw_records (list, ptr)
2568 unw_rec_list *list;
2569 void **ptr;
2570{
2571 int size, x, extra = 0;
2572 unsigned char *mem;
2573
2574 fixup_unw_records (list);
2575 size = calc_record_size (list);
2576
2577 /* pad to 8 byte boundry. */
2578 x = size % 8;
2579 if (x != 0)
2580 extra = 8 - x;
2581 /* Add 8 for the header + 8 more bytes for the personality offset. */
2582 mem = xmalloc (size + extra + 16);
2583
2584 vbyte_mem_ptr = mem + 8;
2585 /* Clear the padding area and personality. */
2586 memset (mem + 8 + size, 0 , extra + 8);
2587 /* Initialize the header area. */
e4c58b25
JW
2588 md_number_to_chars (mem, ( ((bfd_vma) 1 << 48) /* version */
2589 | ((bfd_vma) 3 << 32) /* U & E handler flags */
2590 | ((size + extra) / 8)), /* length (dwords) */
2591 8);
800eeca4
JW
2592
2593 process_unw_records (list, output_vbyte_mem);
2594
2595 *ptr = mem;
2596 return size + extra + 16;
2597}
2598
e0c9811a
JW
2599static int
2600convert_expr_to_ab_reg (e, ab, regp)
2601 expressionS *e;
2602 unsigned int *ab;
2603 unsigned int *regp;
2604{
2605 unsigned int reg;
2606
2607 if (e->X_op != O_register)
2608 return 0;
2609
2610 reg = e->X_add_number;
2611 if (reg >= REG_GR + 4 && reg <= REG_GR + 7)
2612 {
2613 *ab = 0;
2614 *regp = reg - REG_GR;
2615 }
2616 else if ((reg >= REG_FR + 2 && reg <= REG_FR + 5)
2617 || (reg >= REG_FR + 16 && reg <= REG_FR + 31))
2618 {
2619 *ab = 1;
2620 *regp = reg - REG_FR;
2621 }
2622 else if (reg >= REG_BR + 1 && reg <= REG_BR + 5)
2623 {
2624 *ab = 2;
2625 *regp = reg - REG_BR;
2626 }
2627 else
2628 {
2629 *ab = 3;
2630 switch (reg)
2631 {
2632 case REG_PR: *regp = 0; break;
2633 case REG_PSP: *regp = 1; break;
2634 case REG_PRIUNAT: *regp = 2; break;
2635 case REG_BR + 0: *regp = 3; break;
2636 case REG_AR + AR_BSP: *regp = 4; break;
2637 case REG_AR + AR_BSPSTORE: *regp = 5; break;
2638 case REG_AR + AR_RNAT: *regp = 6; break;
2639 case REG_AR + AR_UNAT: *regp = 7; break;
2640 case REG_AR + AR_FPSR: *regp = 8; break;
2641 case REG_AR + AR_PFS: *regp = 9; break;
2642 case REG_AR + AR_LC: *regp = 10; break;
2643
2644 default:
2645 return 0;
2646 }
2647 }
2648 return 1;
2649}
2650
2651static int
2652convert_expr_to_xy_reg (e, xy, regp)
2653 expressionS *e;
2654 unsigned int *xy;
2655 unsigned int *regp;
2656{
2657 unsigned int reg;
2658
2659 if (e->X_op != O_register)
2660 return 0;
2661
2662 reg = e->X_add_number;
2663
2664 if (reg >= REG_GR && reg <= REG_GR + 127)
2665 {
2666 *xy = 0;
2667 *regp = reg - REG_GR;
2668 }
2669 else if (reg >= REG_FR && reg <= REG_FR + 127)
2670 {
2671 *xy = 1;
2672 *regp = reg - REG_FR;
2673 }
2674 else if (reg >= REG_BR && reg <= REG_BR + 7)
2675 {
2676 *xy = 2;
2677 *regp = reg - REG_BR;
2678 }
2679 else
2680 return -1;
2681 return 1;
2682}
2683
800eeca4
JW
2684static void
2685dot_radix (dummy)
2686 int dummy;
2687{
2688 int radix;
2689
2690 SKIP_WHITESPACE ();
2691 radix = *input_line_pointer++;
2692
2693 if (radix != 'C' && !is_end_of_line[(unsigned char) radix])
2694 {
2695 as_bad ("Radix `%c' unsupported", *input_line_pointer);
2696 ignore_rest_of_line ();
2697 return;
2698 }
2699}
2700
2701/* .sbss, .bss etc. are macros that expand into ".section SECNAME". */
2702static void
2703dot_special_section (which)
2704 int which;
2705{
2706 set_section ((char *) special_section_name[which]);
2707}
2708
2709static void
2710add_unwind_entry (ptr)
2711 unw_rec_list *ptr;
2712{
e0c9811a
JW
2713 if (unwind.tail)
2714 unwind.tail->next = ptr;
800eeca4 2715 else
e0c9811a
JW
2716 unwind.list = ptr;
2717 unwind.tail = ptr;
800eeca4
JW
2718
2719 /* The current entry can in fact be a chain of unwind entries. */
e0c9811a
JW
2720 if (unwind.current_entry == NULL)
2721 unwind.current_entry = ptr;
800eeca4
JW
2722}
2723
2724static void
2725dot_fframe (dummy)
2726 int dummy;
2727{
2728 expressionS e;
e0c9811a 2729
800eeca4
JW
2730 parse_operand (&e);
2731
2732 if (e.X_op != O_constant)
2733 as_bad ("Operand to .fframe must be a constant");
2734 else
e0c9811a
JW
2735 add_unwind_entry (output_mem_stack_f (e.X_add_number));
2736}
2737
2738static void
2739dot_vframe (dummy)
2740 int dummy;
2741{
2742 expressionS e;
2743 unsigned reg;
2744
2745 parse_operand (&e);
2746 reg = e.X_add_number - REG_GR;
2747 if (e.X_op == O_register && reg < 128)
800eeca4 2748 {
e0c9811a
JW
2749 add_unwind_entry (output_mem_stack_v ());
2750 add_unwind_entry (output_psp_gr (reg));
800eeca4 2751 }
e0c9811a
JW
2752 else
2753 as_bad ("First operand to .vframe must be a general register");
800eeca4
JW
2754}
2755
2756static void
e0c9811a 2757dot_vframesp (dummy)
800eeca4
JW
2758 int dummy;
2759{
e0c9811a
JW
2760 expressionS e;
2761
2762 parse_operand (&e);
2763 if (e.X_op == O_constant)
2764 {
2765 add_unwind_entry (output_mem_stack_v ());
2766 add_unwind_entry (output_psp_sprel (e.X_add_number));
2767 }
2768 else
2769 as_bad ("First operand to .vframesp must be a general register");
2770}
2771
2772static void
2773dot_vframepsp (dummy)
2774 int dummy;
2775{
2776 expressionS e;
2777
2778 parse_operand (&e);
2779 if (e.X_op == O_constant)
2780 {
2781 add_unwind_entry (output_mem_stack_v ());
2782 add_unwind_entry (output_psp_sprel (e.X_add_number));
2783 }
2784 else
2785 as_bad ("First operand to .vframepsp must be a general register");
800eeca4
JW
2786}
2787
2788static void
2789dot_save (dummy)
2790 int dummy;
2791{
2792 expressionS e1, e2;
2793 int sep;
2794 int reg1, reg2;
2795
2796 sep = parse_operand (&e1);
2797 if (sep != ',')
2798 as_bad ("No second operand to .save");
2799 sep = parse_operand (&e2);
2800
e0c9811a 2801 reg1 = e1.X_add_number;
800eeca4
JW
2802 reg2 = e2.X_add_number - REG_GR;
2803
2804 /* Make sure its a valid ar.xxx reg, OR its br0, aka 'rp'. */
e0c9811a 2805 if (e1.X_op == O_register)
800eeca4
JW
2806 {
2807 if (e2.X_op == O_register && reg2 >=0 && reg2 < 128)
2808 {
2809 switch (reg1)
2810 {
e0c9811a 2811 case REG_AR + AR_BSP:
800eeca4
JW
2812 add_unwind_entry (output_bsp_when ());
2813 add_unwind_entry (output_bsp_gr (reg2));
2814 break;
e0c9811a 2815 case REG_AR + AR_BSPSTORE:
800eeca4
JW
2816 add_unwind_entry (output_bspstore_when ());
2817 add_unwind_entry (output_bspstore_gr (reg2));
2818 break;
e0c9811a 2819 case REG_AR + AR_RNAT:
800eeca4
JW
2820 add_unwind_entry (output_rnat_when ());
2821 add_unwind_entry (output_rnat_gr (reg2));
2822 break;
e0c9811a 2823 case REG_AR+AR_UNAT:
800eeca4
JW
2824 add_unwind_entry (output_unat_when ());
2825 add_unwind_entry (output_unat_gr (reg2));
2826 break;
e0c9811a 2827 case REG_AR+AR_FPSR:
800eeca4
JW
2828 add_unwind_entry (output_fpsr_when ());
2829 add_unwind_entry (output_fpsr_gr (reg2));
2830 break;
e0c9811a 2831 case REG_AR+AR_PFS:
800eeca4
JW
2832 add_unwind_entry (output_pfs_when ());
2833 add_unwind_entry (output_pfs_gr (reg2));
2834 break;
e0c9811a 2835 case REG_AR+AR_LC:
800eeca4
JW
2836 add_unwind_entry (output_lc_when ());
2837 add_unwind_entry (output_lc_gr (reg2));
2838 break;
e0c9811a 2839 case REG_BR:
800eeca4
JW
2840 add_unwind_entry (output_rp_when ());
2841 add_unwind_entry (output_rp_gr (reg2));
2842 break;
e0c9811a
JW
2843 case REG_PR:
2844 add_unwind_entry (output_preds_when ());
2845 add_unwind_entry (output_preds_gr (reg2));
2846 break;
2847 case REG_PRIUNAT:
2848 add_unwind_entry (output_priunat_when_gr ());
2849 add_unwind_entry (output_priunat_gr (reg2));
2850 break;
800eeca4 2851 default:
e0c9811a 2852 as_bad ("First operand not a valid register");
800eeca4
JW
2853 }
2854 }
2855 else
2856 as_bad (" Second operand not a valid register");
2857 }
2858 else
e0c9811a 2859 as_bad ("First operand not a register");
800eeca4
JW
2860}
2861
2862static void
2863dot_restore (dummy)
2864 int dummy;
2865{
e0c9811a
JW
2866 expressionS e1, e2;
2867 unsigned long ecount = 0;
2868 int sep;
2869
2870 sep = parse_operand (&e1);
2871 if (e1.X_op != O_register || e1.X_add_number != REG_GR + 12)
2872 {
2873 as_bad ("First operand to .restore must be stack pointer (sp)");
2874 return;
2875 }
2876
2877 if (sep == ',')
2878 {
2879 parse_operand (&e2);
2880 if (e1.X_op != O_constant)
2881 {
2882 as_bad ("Second operand to .restore must be constant");
2883 return;
2884 }
2885 ecount = e1.X_op;
2886 }
2887 add_unwind_entry (output_epilogue (ecount));
2888}
2889
2890static void
2891dot_restorereg (dummy)
2892 int dummy;
2893{
2894 unsigned int ab, reg;
2895 expressionS e;
2896
2897 parse_operand (&e);
2898
2899 if (!convert_expr_to_ab_reg (&e, &ab, &reg))
2900 {
2901 as_bad ("First operand to .restorereg must be a preserved register");
2902 return;
2903 }
2904 add_unwind_entry (output_spill_reg (ab, reg, 0, 0));
2905}
2906
2907static void
2908dot_restorereg_p (dummy)
2909 int dummy;
2910{
2911 unsigned int qp, ab, reg;
2912 expressionS e1, e2;
2913 int sep;
2914
2915 sep = parse_operand (&e1);
2916 if (sep != ',')
2917 {
2918 as_bad ("No second operand to .restorereg.p");
2919 return;
2920 }
2921
2922 parse_operand (&e2);
2923
2924 qp = e1.X_add_number - REG_P;
2925 if (e1.X_op != O_register || qp > 63)
2926 {
2927 as_bad ("First operand to .restorereg.p must be a predicate");
2928 return;
2929 }
2930
2931 if (!convert_expr_to_ab_reg (&e2, &ab, &reg))
2932 {
2933 as_bad ("Second operand to .restorereg.p must be a preserved register");
2934 return;
2935 }
2936 add_unwind_entry (output_spill_reg_p (ab, reg, 0, 0, qp));
800eeca4
JW
2937}
2938
2939static int
2940generate_unwind_image ()
2941{
2942 int size;
2943 unsigned char *unw_rec;
800eeca4
JW
2944
2945 /* Generate the unwind record. */
150f24a2 2946 size = output_unw_records (unwind.list, (void **) &unw_rec);
e0c9811a
JW
2947 if (size % 8 != 0)
2948 as_bad ("Unwind record is not a multiple of 8 bytes.");
800eeca4
JW
2949
2950 /* If there are unwind records, switch sections, and output the info. */
2951 if (size != 0)
2952 {
800eeca4 2953 unsigned char *where;
800eeca4 2954 expressionS exp;
800eeca4
JW
2955 set_section ((char *) special_section_name[SPECIAL_SECTION_UNWIND_INFO]);
2956
2957 /* Set expression which points to start of unwind descriptor area. */
e0c9811a 2958 unwind.info = expr_build_dot ();
800eeca4
JW
2959
2960 where = (unsigned char *)frag_more (size);
2961
2962 /* Issue a label for this address, and keep track of it to put it
2963 in the unwind section. */
2964
2965 /* Copy the information from the unwind record into this section. The
2966 data is already in the correct byte order. */
2967 memcpy (where, unw_rec, size);
2968 /* Add the personality address to the image. */
e0c9811a 2969 if (unwind.personality_routine != 0)
800eeca4
JW
2970 {
2971 exp.X_op = O_symbol;
e0c9811a 2972 exp.X_add_symbol = unwind.personality_routine;
800eeca4
JW
2973 exp.X_add_number = 0;
2974 fix_new_exp (frag_now, frag_now_fix () - 8, 8,
2975 &exp, 0, BFD_RELOC_IA64_LTOFF_FPTR64LSB);
e0c9811a 2976 unwind.personality_routine = 0;
800eeca4
JW
2977 }
2978 obj_elf_previous (0);
2979 }
2980
e0c9811a
JW
2981 free_list_records (unwind.list);
2982 unwind.list = unwind.tail = unwind.current_entry = NULL;
800eeca4
JW
2983
2984 return size;
2985}
2986
2987static void
2988dot_handlerdata (dummy)
2989 int dummy;
2990{
2991 generate_unwind_image ();
e0c9811a 2992 demand_empty_rest_of_line ();
800eeca4
JW
2993}
2994
2995static void
2996dot_unwentry (dummy)
2997 int dummy;
2998{
e0c9811a 2999 demand_empty_rest_of_line ();
800eeca4
JW
3000}
3001
3002static void
3003dot_altrp (dummy)
3004 int dummy;
3005{
e0c9811a
JW
3006 expressionS e;
3007 unsigned reg;
3008
3009 parse_operand (&e);
3010 reg = e.X_add_number - REG_BR;
3011 if (e.X_op == O_register && reg < 8)
3012 add_unwind_entry (output_rp_br (reg));
3013 else
3014 as_bad ("First operand not a valid branch register");
800eeca4
JW
3015}
3016
3017static void
e0c9811a
JW
3018dot_savemem (psprel)
3019 int psprel;
800eeca4
JW
3020{
3021 expressionS e1, e2;
3022 int sep;
3023 int reg1, val;
3024
3025 sep = parse_operand (&e1);
3026 if (sep != ',')
e0c9811a 3027 as_bad ("No second operand to .save%ssp", psprel ? "p" : "");
800eeca4
JW
3028 sep = parse_operand (&e2);
3029
e0c9811a 3030 reg1 = e1.X_add_number;
800eeca4
JW
3031 val = e2.X_add_number;
3032
3033 /* Make sure its a valid ar.xxx reg, OR its br0, aka 'rp'. */
e0c9811a 3034 if (e1.X_op == O_register)
800eeca4
JW
3035 {
3036 if (e2.X_op == O_constant)
3037 {
3038 switch (reg1)
3039 {
e0c9811a 3040 case REG_AR + AR_BSP:
800eeca4 3041 add_unwind_entry (output_bsp_when ());
e0c9811a
JW
3042 add_unwind_entry ((psprel
3043 ? output_bsp_psprel
3044 : output_bsp_sprel) (val));
800eeca4 3045 break;
e0c9811a 3046 case REG_AR + AR_BSPSTORE:
800eeca4 3047 add_unwind_entry (output_bspstore_when ());
e0c9811a
JW
3048 add_unwind_entry ((psprel
3049 ? output_bspstore_psprel
3050 : output_bspstore_sprel) (val));
800eeca4 3051 break;
e0c9811a 3052 case REG_AR + AR_RNAT:
800eeca4 3053 add_unwind_entry (output_rnat_when ());
e0c9811a
JW
3054 add_unwind_entry ((psprel
3055 ? output_rnat_psprel
3056 : output_rnat_sprel) (val));
800eeca4 3057 break;
e0c9811a 3058 case REG_AR + AR_UNAT:
800eeca4 3059 add_unwind_entry (output_unat_when ());
e0c9811a
JW
3060 add_unwind_entry ((psprel
3061 ? output_unat_psprel
3062 : output_unat_sprel) (val));
800eeca4 3063 break;
e0c9811a 3064 case REG_AR + AR_FPSR:
800eeca4 3065 add_unwind_entry (output_fpsr_when ());
e0c9811a
JW
3066 add_unwind_entry ((psprel
3067 ? output_fpsr_psprel
3068 : output_fpsr_sprel) (val));
800eeca4 3069 break;
e0c9811a 3070 case REG_AR + AR_PFS:
800eeca4 3071 add_unwind_entry (output_pfs_when ());
e0c9811a
JW
3072 add_unwind_entry ((psprel
3073 ? output_pfs_psprel
3074 : output_pfs_sprel) (val));
800eeca4 3075 break;
e0c9811a 3076 case REG_AR + AR_LC:
800eeca4 3077 add_unwind_entry (output_lc_when ());
e0c9811a
JW
3078 add_unwind_entry ((psprel
3079 ? output_lc_psprel
3080 : output_lc_sprel) (val));
800eeca4 3081 break;
e0c9811a 3082 case REG_BR:
800eeca4 3083 add_unwind_entry (output_rp_when ());
e0c9811a
JW
3084 add_unwind_entry ((psprel
3085 ? output_rp_psprel
3086 : output_rp_sprel) (val));
800eeca4 3087 break;
e0c9811a 3088 case REG_PR:
800eeca4 3089 add_unwind_entry (output_preds_when ());
e0c9811a
JW
3090 add_unwind_entry ((psprel
3091 ? output_preds_psprel
3092 : output_preds_sprel) (val));
3093 break;
3094 case REG_PRIUNAT:
3095 add_unwind_entry (output_priunat_when_mem ());
3096 add_unwind_entry ((psprel
3097 ? output_priunat_psprel
3098 : output_priunat_sprel) (val));
800eeca4
JW
3099 break;
3100 default:
e0c9811a 3101 as_bad ("First operand not a valid register");
800eeca4
JW
3102 }
3103 }
3104 else
3105 as_bad (" Second operand not a valid constant");
3106 }
3107 else
e0c9811a 3108 as_bad ("First operand not a register");
800eeca4
JW
3109}
3110
3111static void
3112dot_saveg (dummy)
3113 int dummy;
3114{
3115 expressionS e1, e2;
3116 int sep;
3117 sep = parse_operand (&e1);
3118 if (sep == ',')
3119 parse_operand (&e2);
3120
3121 if (e1.X_op != O_constant)
3122 as_bad ("First operand to .save.g must be a constant.");
3123 else
3124 {
3125 int grmask = e1.X_add_number;
3126 if (sep != ',')
3127 add_unwind_entry (output_gr_mem (grmask));
3128 else
3129 {
3130 int reg = e2.X_add_number - REG_GR;
3131 if (e2.X_op == O_register && reg >=0 && reg < 128)
3132 add_unwind_entry (output_gr_gr (grmask, reg));
3133 else
3134 as_bad ("Second operand is an invalid register.");
3135 }
3136 }
3137}
3138
3139static void
3140dot_savef (dummy)
3141 int dummy;
3142{
e0c9811a 3143 expressionS e1;
800eeca4
JW
3144 int sep;
3145 sep = parse_operand (&e1);
3146
3147 if (e1.X_op != O_constant)
3148 as_bad ("Operand to .save.f must be a constant.");
3149 else
e0c9811a 3150 add_unwind_entry (output_fr_mem (e1.X_add_number));
800eeca4
JW
3151}
3152
3153static void
3154dot_saveb (dummy)
3155 int dummy;
3156{
e0c9811a
JW
3157 expressionS e1, e2;
3158 unsigned int reg;
3159 unsigned char sep;
3160 int brmask;
3161
800eeca4 3162 sep = parse_operand (&e1);
800eeca4 3163 if (e1.X_op != O_constant)
800eeca4 3164 {
e0c9811a
JW
3165 as_bad ("First operand to .save.b must be a constant.");
3166 return;
800eeca4 3167 }
e0c9811a
JW
3168 brmask = e1.X_add_number;
3169
3170 if (sep == ',')
3171 {
3172 sep = parse_operand (&e2);
3173 reg = e2.X_add_number - REG_GR;
3174 if (e2.X_op != O_register || reg > 127)
3175 {
3176 as_bad ("Second operand to .save.b must be a general register.");
3177 return;
3178 }
3179 add_unwind_entry (output_br_gr (brmask, e2.X_add_number));
3180 }
3181 else
3182 add_unwind_entry (output_br_mem (brmask));
3183
3184 if (!is_end_of_line[sep] && !is_it_end_of_statement ())
3185 ignore_rest_of_line ();
800eeca4
JW
3186}
3187
3188static void
3189dot_savegf (dummy)
3190 int dummy;
3191{
3192 expressionS e1, e2;
3193 int sep;
3194 sep = parse_operand (&e1);
3195 if (sep == ',')
3196 parse_operand (&e2);
3197
3198 if (e1.X_op != O_constant || sep != ',' || e2.X_op != O_constant)
3199 as_bad ("Both operands of .save.gf must be constants.");
3200 else
3201 {
3202 int grmask = e1.X_add_number;
3203 int frmask = e2.X_add_number;
3204 add_unwind_entry (output_frgr_mem (grmask, frmask));
3205 }
3206}
3207
3208static void
3209dot_spill (dummy)
3210 int dummy;
3211{
3212 expressionS e;
e0c9811a
JW
3213 unsigned char sep;
3214
3215 sep = parse_operand (&e);
3216 if (!is_end_of_line[sep] && !is_it_end_of_statement ())
3217 ignore_rest_of_line ();
800eeca4
JW
3218
3219 if (e.X_op != O_constant)
3220 as_bad ("Operand to .spill must be a constant");
3221 else
e0c9811a
JW
3222 add_unwind_entry (output_spill_base (e.X_add_number));
3223}
3224
3225static void
3226dot_spillreg (dummy)
3227 int dummy;
3228{
3229 int sep, ab, xy, reg, treg;
3230 expressionS e1, e2;
3231
3232 sep = parse_operand (&e1);
3233 if (sep != ',')
3234 {
3235 as_bad ("No second operand to .spillreg");
3236 return;
3237 }
3238
3239 parse_operand (&e2);
3240
3241 if (!convert_expr_to_ab_reg (&e1, &ab, &reg))
800eeca4 3242 {
e0c9811a
JW
3243 as_bad ("First operand to .spillreg must be a preserved register");
3244 return;
800eeca4 3245 }
e0c9811a
JW
3246
3247 if (!convert_expr_to_xy_reg (&e2, &xy, &treg))
3248 {
3249 as_bad ("Second operand to .spillreg must be a register");
3250 return;
3251 }
3252
3253 add_unwind_entry (output_spill_reg (ab, reg, treg, xy));
3254}
3255
3256static void
3257dot_spillmem (psprel)
3258 int psprel;
3259{
3260 expressionS e1, e2;
3261 int sep, ab, reg;
3262
3263 sep = parse_operand (&e1);
3264 if (sep != ',')
3265 {
3266 as_bad ("Second operand missing");
3267 return;
3268 }
3269
3270 parse_operand (&e2);
3271
3272 if (!convert_expr_to_ab_reg (&e1, &ab, &reg))
3273 {
3274 as_bad ("First operand to .spill%s must be a preserved register",
3275 psprel ? "psp" : "sp");
3276 return;
3277 }
3278
3279 if (e2.X_op != O_constant)
3280 {
3281 as_bad ("Second operand to .spill%s must be a constant",
3282 psprel ? "psp" : "sp");
3283 return;
3284 }
3285
3286 if (psprel)
3287 add_unwind_entry (output_spill_psprel (ab, reg, e2.X_add_number));
3288 else
3289 add_unwind_entry (output_spill_sprel (ab, reg, e2.X_add_number));
3290}
3291
3292static void
3293dot_spillreg_p (dummy)
3294 int dummy;
3295{
3296 int sep, ab, xy, reg, treg;
3297 expressionS e1, e2, e3;
3298 unsigned int qp;
3299
3300 sep = parse_operand (&e1);
3301 if (sep != ',')
3302 {
3303 as_bad ("No second and third operand to .spillreg.p");
3304 return;
3305 }
3306
3307 sep = parse_operand (&e2);
3308 if (sep != ',')
3309 {
3310 as_bad ("No third operand to .spillreg.p");
3311 return;
3312 }
3313
3314 parse_operand (&e3);
3315
3316 qp = e1.X_add_number - REG_P;
3317
3318 if (e1.X_op != O_register || qp > 63)
3319 {
3320 as_bad ("First operand to .spillreg.p must be a predicate");
3321 return;
3322 }
3323
3324 if (!convert_expr_to_ab_reg (&e2, &ab, &reg))
3325 {
3326 as_bad ("Second operand to .spillreg.p must be a preserved register");
3327 return;
3328 }
3329
3330 if (!convert_expr_to_xy_reg (&e3, &xy, &treg))
3331 {
3332 as_bad ("Third operand to .spillreg.p must be a register");
3333 return;
3334 }
3335
3336 add_unwind_entry (output_spill_reg_p (ab, reg, treg, xy, qp));
3337}
3338
3339static void
3340dot_spillmem_p (psprel)
3341 int psprel;
3342{
3343 expressionS e1, e2, e3;
3344 int sep, ab, reg;
3345 unsigned int qp;
3346
3347 sep = parse_operand (&e1);
3348 if (sep != ',')
3349 {
3350 as_bad ("Second operand missing");
3351 return;
3352 }
3353
3354 parse_operand (&e2);
3355 if (sep != ',')
3356 {
3357 as_bad ("Second operand missing");
3358 return;
3359 }
3360
3361 parse_operand (&e3);
3362
3363 qp = e1.X_add_number - REG_P;
3364 if (e1.X_op != O_register || qp > 63)
3365 {
3366 as_bad ("First operand to .spill%s_p must be a predicate",
3367 psprel ? "psp" : "sp");
3368 return;
3369 }
3370
3371 if (!convert_expr_to_ab_reg (&e2, &ab, &reg))
3372 {
3373 as_bad ("Second operand to .spill%s_p must be a preserved register",
3374 psprel ? "psp" : "sp");
3375 return;
3376 }
3377
3378 if (e3.X_op != O_constant)
3379 {
3380 as_bad ("Third operand to .spill%s_p must be a constant",
3381 psprel ? "psp" : "sp");
3382 return;
3383 }
3384
3385 if (psprel)
3386 add_unwind_entry (output_spill_psprel_p (qp, ab, reg, e3.X_add_number));
3387 else
3388 add_unwind_entry (output_spill_sprel_p (qp, ab, reg, e3.X_add_number));
3389}
3390
3391static void
3392dot_label_state (dummy)
3393 int dummy;
3394{
3395 expressionS e;
3396
3397 parse_operand (&e);
3398 if (e.X_op != O_constant)
3399 {
3400 as_bad ("Operand to .label_state must be a constant");
3401 return;
3402 }
3403 add_unwind_entry (output_label_state (e.X_add_number));
3404}
3405
3406static void
3407dot_copy_state (dummy)
3408 int dummy;
3409{
3410 expressionS e;
3411
3412 parse_operand (&e);
3413 if (e.X_op != O_constant)
3414 {
3415 as_bad ("Operand to .copy_state must be a constant");
3416 return;
3417 }
3418 add_unwind_entry (output_copy_state (e.X_add_number));
800eeca4
JW
3419}
3420
3421static void
3422dot_unwabi (dummy)
3423 int dummy;
3424{
e0c9811a
JW
3425 expressionS e1, e2;
3426 unsigned char sep;
3427
3428 sep = parse_operand (&e1);
3429 if (sep != ',')
3430 {
3431 as_bad ("Second operand to .unwabi missing");
3432 return;
3433 }
3434 sep = parse_operand (&e2);
3435 if (!is_end_of_line[sep] && !is_it_end_of_statement ())
3436 ignore_rest_of_line ();
3437
3438 if (e1.X_op != O_constant)
3439 {
3440 as_bad ("First operand to .unwabi must be a constant");
3441 return;
3442 }
3443
3444 if (e2.X_op != O_constant)
3445 {
3446 as_bad ("Second operand to .unwabi must be a constant");
3447 return;
3448 }
3449
3450 add_unwind_entry (output_unwabi (e1.X_add_number, e2.X_add_number));
800eeca4
JW
3451}
3452
3453static void
3454dot_personality (dummy)
3455 int dummy;
3456{
3457 char *name, *p, c;
3458 SKIP_WHITESPACE ();
3459 name = input_line_pointer;
3460 c = get_symbol_end ();
3461 p = input_line_pointer;
e0c9811a 3462 unwind.personality_routine = symbol_find_or_make (name);
800eeca4
JW
3463 *p = c;
3464 SKIP_WHITESPACE ();
3465 demand_empty_rest_of_line ();
3466}
3467
3468static void
3469dot_proc (dummy)
3470 int dummy;
3471{
3472 char *name, *p, c;
3473 symbolS *sym;
3474
e0c9811a
JW
3475 unwind.proc_start = expr_build_dot ();
3476 /* Parse names of main and alternate entry points and mark them as
800eeca4
JW
3477 function symbols: */
3478 while (1)
3479 {
3480 SKIP_WHITESPACE ();
3481 name = input_line_pointer;
3482 c = get_symbol_end ();
3483 p = input_line_pointer;
3484 sym = symbol_find_or_make (name);
e0c9811a 3485 if (unwind.proc_start == 0)
800eeca4 3486 {
e0c9811a 3487 unwind.proc_start = sym;
800eeca4
JW
3488 }
3489 symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION;
3490 *p = c;
3491 SKIP_WHITESPACE ();
3492 if (*input_line_pointer != ',')
3493 break;
3494 ++input_line_pointer;
3495 }
3496 demand_empty_rest_of_line ();
3497 ia64_do_align (16);
3498
e0c9811a
JW
3499 unwind.list = unwind.tail = unwind.current_entry = NULL;
3500 unwind.personality_routine = 0;
800eeca4
JW
3501}
3502
3503static void
3504dot_body (dummy)
3505 int dummy;
3506{
e0c9811a 3507 unwind.prologue = 0;
800eeca4 3508 add_unwind_entry (output_body ());
e0c9811a 3509 demand_empty_rest_of_line ();
800eeca4
JW
3510}
3511
3512static void
3513dot_prologue (dummy)
3514 int dummy;
3515{
e0c9811a
JW
3516 unsigned char sep;
3517
3518 unwind.prologue = 1;
3519 if (!is_it_end_of_statement ())
800eeca4
JW
3520 {
3521 expressionS e1, e2;
800eeca4
JW
3522 sep = parse_operand (&e1);
3523 if (sep != ',')
3524 as_bad ("No second operand to .prologue");
3525 sep = parse_operand (&e2);
e0c9811a
JW
3526 if (!is_end_of_line[sep] && !is_it_end_of_statement ())
3527 ignore_rest_of_line ();
800eeca4
JW
3528
3529 if (e1.X_op == O_constant)
3530 {
3531 if (e2.X_op == O_constant)
3532 {
3533 int mask = e1.X_add_number;
3534 int reg = e2.X_add_number;
3535 add_unwind_entry (output_prologue_gr (mask, reg));
3536 }
3537 else
3538 as_bad ("Second operand not a constant");
3539 }
3540 else
3541 as_bad ("First operand not a constant");
3542 }
3543 else
3544 add_unwind_entry (output_prologue ());
3545}
3546
3547static void
3548dot_endp (dummy)
3549 int dummy;
3550{
3551 expressionS e;
3552 unsigned char *ptr;
800eeca4
JW
3553 long where;
3554 segT saved_seg;
3555 subsegT saved_subseg;
3556
3557 saved_seg = now_seg;
3558 saved_subseg = now_subseg;
3559
3560 expression (&e);
3561 demand_empty_rest_of_line ();
3562
3563 insn_group_break (1, 0, 0);
3564 ia64_flush_insns ();
3565
3566 /* If there was a .handlerdata, we haven't generated an image yet. */
e0c9811a 3567 if (unwind.info == 0)
800eeca4
JW
3568 {
3569 generate_unwind_image ();
3570 }
3571
3572 subseg_set (md.last_text_seg, 0);
e0c9811a 3573 unwind.proc_end = expr_build_dot ();
800eeca4
JW
3574
3575 set_section ((char *) special_section_name[SPECIAL_SECTION_UNWIND]);
3576 ptr = frag_more (24);
3577 where = frag_now_fix () - 24;
3578
3579 /* Issue the values of a) Proc Begin, b) Proc End, c) Unwind Record. */
3580 e.X_op = O_pseudo_fixup;
3581 e.X_op_symbol = pseudo_func[FUNC_SEG_RELATIVE].u.sym;
3582 e.X_add_number = 0;
e0c9811a 3583 e.X_add_symbol = unwind.proc_start;
800eeca4
JW
3584 ia64_cons_fix_new (frag_now, where, 8, &e);
3585
3586 e.X_op = O_pseudo_fixup;
3587 e.X_op_symbol = pseudo_func[FUNC_SEG_RELATIVE].u.sym;
3588 e.X_add_number = 0;
e0c9811a 3589 e.X_add_symbol = unwind.proc_end;
800eeca4
JW
3590 ia64_cons_fix_new (frag_now, where + 8, 8, &e);
3591
e0c9811a 3592 if (unwind.info != 0)
800eeca4
JW
3593 {
3594 e.X_op = O_pseudo_fixup;
3595 e.X_op_symbol = pseudo_func[FUNC_SEG_RELATIVE].u.sym;
3596 e.X_add_number = 0;
e0c9811a 3597 e.X_add_symbol = unwind.info;
800eeca4
JW
3598 ia64_cons_fix_new (frag_now, where + 16, 8, &e);
3599 }
3600 else
3601 md_number_to_chars (ptr + 16, 0, 8);
3602
3603 subseg_set (saved_seg, saved_subseg);
e0c9811a 3604 unwind.proc_start = unwind.proc_end = unwind.info = 0;
800eeca4
JW
3605}
3606
3607static void
3608dot_template (template)
3609 int template;
3610{
3611 CURR_SLOT.user_template = template;
3612}
3613
3614static void
3615dot_regstk (dummy)
3616 int dummy;
3617{
3618 int ins, locs, outs, rots;
3619
3620 if (is_it_end_of_statement ())
3621 ins = locs = outs = rots = 0;
3622 else
3623 {
3624 ins = get_absolute_expression ();
3625 if (*input_line_pointer++ != ',')
3626 goto err;
3627 locs = get_absolute_expression ();
3628 if (*input_line_pointer++ != ',')
3629 goto err;
3630 outs = get_absolute_expression ();
3631 if (*input_line_pointer++ != ',')
3632 goto err;
3633 rots = get_absolute_expression ();
3634 }
3635 set_regstack (ins, locs, outs, rots);
3636 return;
3637
3638 err:
3639 as_bad ("Comma expected");
3640 ignore_rest_of_line ();
3641}
3642
3643static void
3644dot_rot (type)
3645 int type;
3646{
3647 unsigned num_regs, num_alloced = 0;
3648 struct dynreg **drpp, *dr;
3649 int ch, base_reg = 0;
3650 char *name, *start;
3651 size_t len;
3652
3653 switch (type)
3654 {
3655 case DYNREG_GR: base_reg = REG_GR + 32; break;
3656 case DYNREG_FR: base_reg = REG_FR + 32; break;
3657 case DYNREG_PR: base_reg = REG_P + 16; break;
3658 default: break;
3659 }
3660
3661 /* first, remove existing names from hash table: */
3662 for (dr = md.dynreg[type]; dr && dr->num_regs; dr = dr->next)
3663 {
3664 hash_delete (md.dynreg_hash, dr->name);
3665 dr->num_regs = 0;
3666 }
3667
3668 drpp = &md.dynreg[type];
3669 while (1)
3670 {
3671 start = input_line_pointer;
3672 ch = get_symbol_end ();
3673 *input_line_pointer = ch;
3674 len = (input_line_pointer - start);
3675
3676 SKIP_WHITESPACE ();
3677 if (*input_line_pointer != '[')
3678 {
3679 as_bad ("Expected '['");
3680 goto err;
3681 }
3682 ++input_line_pointer; /* skip '[' */
3683
3684 num_regs = get_absolute_expression ();
3685
3686 if (*input_line_pointer++ != ']')
3687 {
3688 as_bad ("Expected ']'");
3689 goto err;
3690 }
3691 SKIP_WHITESPACE ();
3692
3693 num_alloced += num_regs;
3694 switch (type)
3695 {
3696 case DYNREG_GR:
3697 if (num_alloced > md.rot.num_regs)
3698 {
3699 as_bad ("Used more than the declared %d rotating registers",
3700 md.rot.num_regs);
3701 goto err;
3702 }
3703 break;
3704 case DYNREG_FR:
3705 if (num_alloced > 96)
3706 {
3707 as_bad ("Used more than the available 96 rotating registers");
3708 goto err;
3709 }
3710 break;
3711 case DYNREG_PR:
3712 if (num_alloced > 48)
3713 {
3714 as_bad ("Used more than the available 48 rotating registers");
3715 goto err;
3716 }
3717 break;
3718
3719 default:
3720 break;
3721 }
3722
3723 name = obstack_alloc (&notes, len + 1);
3724 memcpy (name, start, len);
3725 name[len] = '\0';
3726
3727 if (!*drpp)
3728 {
3729 *drpp = obstack_alloc (&notes, sizeof (*dr));
3730 memset (*drpp, 0, sizeof (*dr));
3731 }
3732
3733 dr = *drpp;
3734 dr->name = name;
3735 dr->num_regs = num_regs;
3736 dr->base = base_reg;
3737 drpp = &dr->next;
3738 base_reg += num_regs;
3739
3740 if (hash_insert (md.dynreg_hash, name, dr))
3741 {
3742 as_bad ("Attempt to redefine register set `%s'", name);
3743 goto err;
3744 }
3745
3746 if (*input_line_pointer != ',')
3747 break;
3748 ++input_line_pointer; /* skip comma */
3749 SKIP_WHITESPACE ();
3750 }
3751 demand_empty_rest_of_line ();
3752 return;
3753
3754 err:
3755 ignore_rest_of_line ();
3756}
3757
3758static void
3759dot_byteorder (byteorder)
3760 int byteorder;
3761{
3762 target_big_endian = byteorder;
3763}
3764
3765static void
3766dot_psr (dummy)
3767 int dummy;
3768{
3769 char *option;
3770 int ch;
3771
3772 while (1)
3773 {
3774 option = input_line_pointer;
3775 ch = get_symbol_end ();
3776 if (strcmp (option, "lsb") == 0)
3777 md.flags &= ~EF_IA_64_BE;
3778 else if (strcmp (option, "msb") == 0)
3779 md.flags |= EF_IA_64_BE;
3780 else if (strcmp (option, "abi32") == 0)
3781 md.flags &= ~EF_IA_64_ABI64;
3782 else if (strcmp (option, "abi64") == 0)
3783 md.flags |= EF_IA_64_ABI64;
3784 else
3785 as_bad ("Unknown psr option `%s'", option);
3786 *input_line_pointer = ch;
3787
3788 SKIP_WHITESPACE ();
3789 if (*input_line_pointer != ',')
3790 break;
3791
3792 ++input_line_pointer;
3793 SKIP_WHITESPACE ();
3794 }
3795 demand_empty_rest_of_line ();
3796}
3797
3798static void
3799dot_alias (dummy)
3800 int dummy;
3801{
3802 as_bad (".alias not implemented yet");
3803}
3804
3805static void
3806dot_ln (dummy)
3807 int dummy;
3808{
3809 new_logical_line (0, get_absolute_expression ());
3810 demand_empty_rest_of_line ();
3811}
3812
3813static char*
3814parse_section_name ()
3815{
3816 char *name;
3817 int len;
3818
3819 SKIP_WHITESPACE ();
3820 if (*input_line_pointer != '"')
3821 {
3822 as_bad ("Missing section name");
3823 ignore_rest_of_line ();
3824 return 0;
3825 }
3826 name = demand_copy_C_string (&len);
3827 if (!name)
3828 {
3829 ignore_rest_of_line ();
3830 return 0;
3831 }
3832 SKIP_WHITESPACE ();
3833 if (*input_line_pointer != ',')
3834 {
3835 as_bad ("Comma expected after section name");
3836 ignore_rest_of_line ();
3837 return 0;
3838 }
3839 ++input_line_pointer; /* skip comma */
3840 return name;
3841}
3842
3843static void
3844dot_xdata (size)
3845 int size;
3846{
3847 char *name = parse_section_name ();
3848 if (!name)
3849 return;
3850
3851 set_section (name);
3852 cons (size);
3853 obj_elf_previous (0);
3854}
3855
3856/* Why doesn't float_cons() call md_cons_align() the way cons() does? */
3857static void
3858stmt_float_cons (kind)
3859 int kind;
3860{
3861 size_t size;
3862
3863 switch (kind)
3864 {
3865 case 'd': size = 8; break;
3866 case 'x': size = 10; break;
3867
3868 case 'f':
3869 default:
3870 size = 4;
3871 break;
3872 }
3873 ia64_do_align (size);
3874 float_cons (kind);
3875}
3876
3877static void
3878stmt_cons_ua (size)
3879 int size;
3880{
3881 int saved_auto_align = md.auto_align;
3882
3883 md.auto_align = 0;
3884 cons (size);
3885 md.auto_align = saved_auto_align;
3886}
3887
3888static void
3889dot_xfloat_cons (kind)
3890 int kind;
3891{
3892 char *name = parse_section_name ();
3893 if (!name)
3894 return;
3895
3896 set_section (name);
3897 stmt_float_cons (kind);
3898 obj_elf_previous (0);
3899}
3900
3901static void
3902dot_xstringer (zero)
3903 int zero;
3904{
3905 char *name = parse_section_name ();
3906 if (!name)
3907 return;
3908
3909 set_section (name);
3910 stringer (zero);
3911 obj_elf_previous (0);
3912}
3913
3914static void
3915dot_xdata_ua (size)
3916 int size;
3917{
3918 int saved_auto_align = md.auto_align;
3919 char *name = parse_section_name ();
3920 if (!name)
3921 return;
3922
3923 set_section (name);
3924 md.auto_align = 0;
3925 cons (size);
3926 md.auto_align = saved_auto_align;
3927 obj_elf_previous (0);
3928}
3929
3930static void
3931dot_xfloat_cons_ua (kind)
3932 int kind;
3933{
3934 int saved_auto_align = md.auto_align;
3935 char *name = parse_section_name ();
3936 if (!name)
3937 return;
3938
3939 set_section (name);
3940 md.auto_align = 0;
3941 stmt_float_cons (kind);
3942 md.auto_align = saved_auto_align;
3943 obj_elf_previous (0);
3944}
3945
3946/* .reg.val <regname>,value */
3947static void
3948dot_reg_val (dummy)
3949 int dummy;
3950{
3951 expressionS reg;
3952
3953 expression (&reg);
3954 if (reg.X_op != O_register)
3955 {
3956 as_bad (_("Register name expected"));
3957 ignore_rest_of_line ();
3958 }
3959 else if (*input_line_pointer++ != ',')
3960 {
3961 as_bad (_("Comma expected"));
3962 ignore_rest_of_line ();
3963 }
3964 else
3965 {
3966 valueT value = get_absolute_expression ();
3967 int regno = reg.X_add_number;
3968 if (regno < REG_GR || regno > REG_GR+128)
3969 as_warn (_("Register value annotation ignored"));
3970 else
3971 {
3972 gr_values[regno-REG_GR].known = 1;
3973 gr_values[regno-REG_GR].value = value;
3974 gr_values[regno-REG_GR].path = md.path;
3975 }
3976 }
3977 demand_empty_rest_of_line ();
3978}
3979
3980/* select dv checking mode
3981 .auto
3982 .explicit
3983 .default
3984
3985 A stop is inserted when changing modes
3986 */
3987static void
3988dot_dv_mode (type)
3989 int type;
3990{
3991 if (md.manual_bundling)
3992 as_warn (_("Directive invalid within a bundle"));
3993
3994 if (type == 'E' || type == 'A')
3995 md.mode_explicitly_set = 0;
3996 else
3997 md.mode_explicitly_set = 1;
3998
3999 md.detect_dv = 1;
4000 switch (type)
4001 {
4002 case 'A':
4003 case 'a':
4004 if (md.explicit_mode)
4005 insn_group_break (1, 0, 0);
4006 md.explicit_mode = 0;
4007 break;
4008 case 'E':
4009 case 'e':
4010 if (!md.explicit_mode)
4011 insn_group_break (1, 0, 0);
4012 md.explicit_mode = 1;
4013 break;
4014 default:
4015 case 'd':
4016 if (md.explicit_mode != md.default_explicit_mode)
4017 insn_group_break (1, 0, 0);
4018 md.explicit_mode = md.default_explicit_mode;
4019 md.mode_explicitly_set = 0;
4020 break;
4021 }
4022}
4023
4024static void
4025print_prmask (mask)
4026 valueT mask;
4027{
4028 int regno;
4029 char *comma = "";
4030 for (regno = 0;regno < 64;regno++)
4031 {
4032 if (mask & ((valueT)1<<regno))
4033 {
4034 fprintf (stderr, "%s p%d", comma, regno);
4035 comma = ",";
4036 }
4037 }
4038}
4039
4040/*
4041 .pred.rel.clear [p1 [,p2 [,...]]] (also .pred.rel "clear")
4042 .pred.rel.imply p1, p2 (also .pred.rel "imply")
4043 .pred.rel.mutex p1, p2 [,...] (also .pred.rel "mutex")
4044 .pred.safe_across_calls p1 [, p2 [,...]]
4045 */
4046static void
4047dot_pred_rel (type)
4048 int type;
4049{
4050 valueT mask = 0;
4051 int count = 0;
4052 int p1 = -1, p2 = -1;
4053
4054 if (type == 0)
4055 {
4056 if (*input_line_pointer != '"')
4057 {
4058 as_bad (_("Missing predicate relation type"));
4059 ignore_rest_of_line ();
4060 return;
4061 }
4062 else
4063 {
4064 int len;
4065 char *form = demand_copy_C_string (&len);
4066 if (strcmp (form, "mutex") == 0)
4067 type = 'm';
4068 else if (strcmp (form, "clear") == 0)
4069 type = 'c';
4070 else if (strcmp (form, "imply") == 0)
4071 type = 'i';
4072 else
4073 {
4074 as_bad (_("Unrecognized predicate relation type"));
4075 ignore_rest_of_line ();
4076 return;
4077 }
4078 }
4079 if (*input_line_pointer == ',')
4080 ++input_line_pointer;
4081 SKIP_WHITESPACE ();
4082 }
4083
4084 SKIP_WHITESPACE ();
4085 while (1)
4086 {
4087 valueT bit = 1;
4088 int regno;
4089
4090 if (toupper (*input_line_pointer) != 'P'
4091 || (regno = atoi (++input_line_pointer)) < 0
4092 || regno > 63)
4093 {
4094 as_bad (_("Predicate register expected"));
4095 ignore_rest_of_line ();
4096 return;
4097 }
4098 while (isdigit (*input_line_pointer))
4099 ++input_line_pointer;
4100 if (p1 == -1)
4101 p1 = regno;
4102 else if (p2 == -1)
4103 p2 = regno;
4104 bit <<= regno;
4105 if (mask & bit)
4106 as_warn (_("Duplicate predicate register ignored"));
4107 mask |= bit; count++;
4108 /* see if it's a range */
4109 if (*input_line_pointer == '-')
4110 {
4111 valueT stop = 1;
4112 ++input_line_pointer;
4113
4114 if (toupper (*input_line_pointer) != 'P'
4115 || (regno = atoi (++input_line_pointer)) < 0
4116 || regno > 63)
4117 {
4118 as_bad (_("Predicate register expected"));
4119 ignore_rest_of_line ();
4120 return;
4121 }
4122 while (isdigit (*input_line_pointer))
4123 ++input_line_pointer;
4124 stop <<= regno;
4125 if (bit >= stop)
4126 {
4127 as_bad (_("Bad register range"));
4128 ignore_rest_of_line ();
4129 return;
4130 }
4131 while (bit < stop)
4132 {
4133 bit <<= 1;
4134 mask |= bit; count++;
4135 }
4136 SKIP_WHITESPACE ();
4137 }
4138 if (*input_line_pointer != ',')
4139 break;
4140 ++input_line_pointer;
4141 SKIP_WHITESPACE ();
4142 }
4143
4144 switch (type)
4145 {
4146 case 'c':
4147 if (count == 0)
4148 mask = ~(valueT)0;
4149 clear_qp_mutex (mask);
4150 clear_qp_implies (mask, (valueT)0);
4151 break;
4152 case 'i':
4153 if (count != 2 || p1 == -1 || p2 == -1)
4154 as_bad (_("Predicate source and target required"));
4155 else if (p1 == 0 || p2 == 0)
4156 as_bad (_("Use of p0 is not valid in this context"));
4157 else
4158 add_qp_imply (p1, p2);
4159 break;
4160 case 'm':
4161 if (count < 2)
4162 {
4163 as_bad (_("At least two PR arguments expected"));
4164 break;
4165 }
4166 else if (mask & 1)
4167 {
4168 as_bad (_("Use of p0 is not valid in this context"));
4169 break;
4170 }
4171 add_qp_mutex (mask);
4172 break;
4173 case 's':
4174 /* note that we don't override any existing relations */
4175 if (count == 0)
4176 {
4177 as_bad (_("At least one PR argument expected"));
4178 break;
4179 }
4180 if (md.debug_dv)
4181 {
4182 fprintf (stderr, "Safe across calls: ");
4183 print_prmask (mask);
4184 fprintf (stderr, "\n");
4185 }
4186 qp_safe_across_calls = mask;
4187 break;
4188 }
4189 demand_empty_rest_of_line ();
4190}
4191
4192/* .entry label [, label [, ...]]
4193 Hint to DV code that the given labels are to be considered entry points.
4194 Otherwise, only global labels are considered entry points.
4195 */
4196static void
4197dot_entry (dummy)
4198 int dummy;
4199{
4200 const char *err;
4201 char *name;
4202 int c;
4203 symbolS *symbolP;
4204
4205 do
4206 {
4207 name = input_line_pointer;
4208 c = get_symbol_end ();
4209 symbolP = symbol_find_or_make (name);
4210
4211 err = hash_insert (md.entry_hash, S_GET_NAME (symbolP), (PTR) symbolP);
4212 if (err)
4213 as_fatal (_("Inserting \"%s\" into entry hint table failed: %s"),
4214 name, err);
4215
4216 *input_line_pointer = c;
4217 SKIP_WHITESPACE ();
4218 c = *input_line_pointer;
4219 if (c == ',')
4220 {
4221 input_line_pointer++;
4222 SKIP_WHITESPACE ();
4223 if (*input_line_pointer == '\n')
4224 c = '\n';
4225 }
4226 }
4227 while (c == ',');
4228
4229 demand_empty_rest_of_line ();
4230}
4231
4232/* .mem.offset offset, base
4233 "base" is used to distinguish between offsets from a different base.
4234 */
4235static void
4236dot_mem_offset (dummy)
4237 int dummy;
4238{
4239 md.mem_offset.hint = 1;
4240 md.mem_offset.offset = get_absolute_expression ();
4241 if (*input_line_pointer != ',')
4242 {
4243 as_bad (_("Comma expected"));
4244 ignore_rest_of_line ();
4245 return;
4246 }
4247 ++input_line_pointer;
4248 md.mem_offset.base = get_absolute_expression ();
4249 demand_empty_rest_of_line ();
4250}
4251
4252/* ia64-specific pseudo-ops: */
4253const pseudo_typeS md_pseudo_table[] =
4254 {
4255 { "radix", dot_radix, 0 },
4256 { "lcomm", s_lcomm_bytes, 1 },
4257 { "bss", dot_special_section, SPECIAL_SECTION_BSS },
4258 { "sbss", dot_special_section, SPECIAL_SECTION_SBSS },
4259 { "sdata", dot_special_section, SPECIAL_SECTION_SDATA },
4260 { "rodata", dot_special_section, SPECIAL_SECTION_RODATA },
4261 { "comment", dot_special_section, SPECIAL_SECTION_COMMENT },
4262 { "ia_64.unwind", dot_special_section, SPECIAL_SECTION_UNWIND },
4263 { "ia_64.unwind_info", dot_special_section, SPECIAL_SECTION_UNWIND_INFO },
4264 { "proc", dot_proc, 0 },
4265 { "body", dot_body, 0 },
4266 { "prologue", dot_prologue, 0 },
4267 { "endp", dot_endp },
4268 { "file", dwarf2_directive_file },
4269 { "loc", dwarf2_directive_loc },
4270
4271 { "fframe", dot_fframe },
4272 { "vframe", dot_vframe },
e0c9811a
JW
4273 { "vframesp", dot_vframesp },
4274 { "vframepsp", dot_vframepsp },
800eeca4
JW
4275 { "save", dot_save },
4276 { "restore", dot_restore },
e0c9811a
JW
4277 { "restorereg", dot_restorereg },
4278 { "restorereg.p", dot_restorereg_p },
800eeca4
JW
4279 { "handlerdata", dot_handlerdata },
4280 { "unwentry", dot_unwentry },
e0c9811a
JW
4281 { "altrp", dot_altrp },
4282 { "savesp", dot_savemem, 0 },
4283 { "savepsp", dot_savemem, 1 },
800eeca4
JW
4284 { "save.g", dot_saveg },
4285 { "save.f", dot_savef },
4286 { "save.b", dot_saveb },
4287 { "save.gf", dot_savegf },
4288 { "spill", dot_spill },
e0c9811a
JW
4289 { "spillreg", dot_spillreg },
4290 { "spillsp", dot_spillmem, 0 },
4291 { "spillpsp", dot_spillmem, 1 },
4292 { "spillreg.p", dot_spillreg_p },
4293 { "spillsp.p", dot_spillmem_p, 0 },
4294 { "spillpsp.p", dot_spillmem_p, 1 },
4295 { "label_state", dot_label_state },
4296 { "copy_state", dot_copy_state },
800eeca4
JW
4297 { "unwabi", dot_unwabi },
4298 { "personality", dot_personality },
4299#if 0
4300 { "estate", dot_estate },
4301#endif
4302 { "mii", dot_template, 0x0 },
4303 { "mli", dot_template, 0x2 }, /* old format, for compatibility */
4304 { "mlx", dot_template, 0x2 },
4305 { "mmi", dot_template, 0x4 },
4306 { "mfi", dot_template, 0x6 },
4307 { "mmf", dot_template, 0x7 },
4308 { "mib", dot_template, 0x8 },
4309 { "mbb", dot_template, 0x9 },
4310 { "bbb", dot_template, 0xb },
4311 { "mmb", dot_template, 0xc },
4312 { "mfb", dot_template, 0xe },
4313#if 0
4314 { "lb", dot_scope, 0 },
4315 { "le", dot_scope, 1 },
4316#endif
4317 { "align", s_align_bytes, 0 },
4318 { "regstk", dot_regstk, 0 },
4319 { "rotr", dot_rot, DYNREG_GR },
4320 { "rotf", dot_rot, DYNREG_FR },
4321 { "rotp", dot_rot, DYNREG_PR },
4322 { "lsb", dot_byteorder, 0 },
4323 { "msb", dot_byteorder, 1 },
4324 { "psr", dot_psr, 0 },
4325 { "alias", dot_alias, 0 },
4326 { "ln", dot_ln, 0 }, /* source line info (for debugging) */
4327
4328 { "xdata1", dot_xdata, 1 },
4329 { "xdata2", dot_xdata, 2 },
4330 { "xdata4", dot_xdata, 4 },
4331 { "xdata8", dot_xdata, 8 },
4332 { "xreal4", dot_xfloat_cons, 'f' },
4333 { "xreal8", dot_xfloat_cons, 'd' },
4334 { "xreal10", dot_xfloat_cons, 'x' },
4335 { "xstring", dot_xstringer, 0 },
4336 { "xstringz", dot_xstringer, 1 },
4337
4338 /* unaligned versions: */
4339 { "xdata2.ua", dot_xdata_ua, 2 },
4340 { "xdata4.ua", dot_xdata_ua, 4 },
4341 { "xdata8.ua", dot_xdata_ua, 8 },
4342 { "xreal4.ua", dot_xfloat_cons_ua, 'f' },
4343 { "xreal8.ua", dot_xfloat_cons_ua, 'd' },
4344 { "xreal10.ua", dot_xfloat_cons_ua, 'x' },
4345
4346 /* annotations/DV checking support */
4347 { "entry", dot_entry, 0 },
4348 { "mem.offset", dot_mem_offset },
4349 { "pred.rel", dot_pred_rel, 0 },
4350 { "pred.rel.clear", dot_pred_rel, 'c' },
4351 { "pred.rel.imply", dot_pred_rel, 'i' },
4352 { "pred.rel.mutex", dot_pred_rel, 'm' },
4353 { "pred.safe_across_calls", dot_pred_rel, 's' },
4354 { "reg.val", dot_reg_val },
4355 { "auto", dot_dv_mode, 'a' },
4356 { "explicit", dot_dv_mode, 'e' },
4357 { "default", dot_dv_mode, 'd' },
4358
4359 { NULL, 0, 0 }
4360 };
4361
4362static const struct pseudo_opcode
4363 {
4364 const char *name;
4365 void (*handler) (int);
4366 int arg;
4367 }
4368pseudo_opcode[] =
4369 {
4370 /* these are more like pseudo-ops, but don't start with a dot */
4371 { "data1", cons, 1 },
4372 { "data2", cons, 2 },
4373 { "data4", cons, 4 },
4374 { "data8", cons, 8 },
4375 { "real4", stmt_float_cons, 'f' },
4376 { "real8", stmt_float_cons, 'd' },
4377 { "real10", stmt_float_cons, 'x' },
4378 { "string", stringer, 0 },
4379 { "stringz", stringer, 1 },
4380
4381 /* unaligned versions: */
4382 { "data2.ua", stmt_cons_ua, 2 },
4383 { "data4.ua", stmt_cons_ua, 4 },
4384 { "data8.ua", stmt_cons_ua, 8 },
4385 { "real4.ua", float_cons, 'f' },
4386 { "real8.ua", float_cons, 'd' },
4387 { "real10.ua", float_cons, 'x' },
4388 };
4389
4390/* Declare a register by creating a symbol for it and entering it in
4391 the symbol table. */
4392static symbolS*
4393declare_register (name, regnum)
4394 const char *name;
4395 int regnum;
4396{
4397 const char *err;
4398 symbolS *sym;
4399
4400 sym = symbol_new (name, reg_section, regnum, &zero_address_frag);
4401
4402 err = hash_insert (md.reg_hash, S_GET_NAME (sym), (PTR) sym);
4403 if (err)
4404 as_fatal ("Inserting \"%s\" into register table failed: %s",
4405 name, err);
4406
4407 return sym;
4408}
4409
4410static void
4411declare_register_set (prefix, num_regs, base_regnum)
4412 const char *prefix;
4413 int num_regs;
4414 int base_regnum;
4415{
4416 char name[8];
4417 int i;
4418
4419 for (i = 0; i < num_regs; ++i)
4420 {
4421 sprintf (name, "%s%u", prefix, i);
4422 declare_register (name, base_regnum + i);
4423 }
4424}
4425
4426static unsigned int
4427operand_width (opnd)
4428 enum ia64_opnd opnd;
4429{
4430 const struct ia64_operand *odesc = &elf64_ia64_operands[opnd];
4431 unsigned int bits = 0;
4432 int i;
4433
4434 bits = 0;
4435 for (i = 0; i < NELEMS (odesc->field) && odesc->field[i].bits; ++i)
4436 bits += odesc->field[i].bits;
4437
4438 return bits;
4439}
4440
4441static int
4442operand_match (idesc, index, e)
4443 const struct ia64_opcode *idesc;
4444 int index;
4445 expressionS *e;
4446{
4447 enum ia64_opnd opnd = idesc->operands[index];
4448 int bits, relocatable = 0;
4449 struct insn_fix *fix;
4450 bfd_signed_vma val;
4451
4452 switch (opnd)
4453 {
4454 /* constants: */
4455
4456 case IA64_OPND_AR_CCV:
4457 if (e->X_op == O_register && e->X_add_number == REG_AR + 32)
4458 return 1;
4459 break;
4460
4461 case IA64_OPND_AR_PFS:
4462 if (e->X_op == O_register && e->X_add_number == REG_AR + 64)
4463 return 1;
4464 break;
4465
4466 case IA64_OPND_GR0:
4467 if (e->X_op == O_register && e->X_add_number == REG_GR + 0)
4468 return 1;
4469 break;
4470
4471 case IA64_OPND_IP:
4472 if (e->X_op == O_register && e->X_add_number == REG_IP)
4473 return 1;
4474 break;
4475
4476 case IA64_OPND_PR:
4477 if (e->X_op == O_register && e->X_add_number == REG_PR)
4478 return 1;
4479 break;
4480
4481 case IA64_OPND_PR_ROT:
4482 if (e->X_op == O_register && e->X_add_number == REG_PR_ROT)
4483 return 1;
4484 break;
4485
4486 case IA64_OPND_PSR:
4487 if (e->X_op == O_register && e->X_add_number == REG_PSR)
4488 return 1;
4489 break;
4490
4491 case IA64_OPND_PSR_L:
4492 if (e->X_op == O_register && e->X_add_number == REG_PSR_L)
4493 return 1;
4494 break;
4495
4496 case IA64_OPND_PSR_UM:
4497 if (e->X_op == O_register && e->X_add_number == REG_PSR_UM)
4498 return 1;
4499 break;
4500
4501 case IA64_OPND_C1:
4502 if (e->X_op == O_constant && e->X_add_number == 1)
4503 return 1;
4504 break;
4505
4506 case IA64_OPND_C8:
4507 if (e->X_op == O_constant && e->X_add_number == 8)
4508 return 1;
4509 break;
4510
4511 case IA64_OPND_C16:
4512 if (e->X_op == O_constant && e->X_add_number == 16)
4513 return 1;
4514 break;
4515
4516 /* register operands: */
4517
4518 case IA64_OPND_AR3:
4519 if (e->X_op == O_register && e->X_add_number >= REG_AR
4520 && e->X_add_number < REG_AR + 128)
4521 return 1;
4522 break;
4523
4524 case IA64_OPND_B1:
4525 case IA64_OPND_B2:
4526 if (e->X_op == O_register && e->X_add_number >= REG_BR
4527 && e->X_add_number < REG_BR + 8)
4528 return 1;
4529 break;
4530
4531 case IA64_OPND_CR3:
4532 if (e->X_op == O_register && e->X_add_number >= REG_CR
4533 && e->X_add_number < REG_CR + 128)
4534 return 1;
4535 break;
4536
4537 case IA64_OPND_F1:
4538 case IA64_OPND_F2:
4539 case IA64_OPND_F3:
4540 case IA64_OPND_F4:
4541 if (e->X_op == O_register && e->X_add_number >= REG_FR
4542 && e->X_add_number < REG_FR + 128)
4543 return 1;
4544 break;
4545
4546 case IA64_OPND_P1:
4547 case IA64_OPND_P2:
4548 if (e->X_op == O_register && e->X_add_number >= REG_P
4549 && e->X_add_number < REG_P + 64)
4550 return 1;
4551 break;
4552
4553 case IA64_OPND_R1:
4554 case IA64_OPND_R2:
4555 case IA64_OPND_R3:
4556 if (e->X_op == O_register && e->X_add_number >= REG_GR
4557 && e->X_add_number < REG_GR + 128)
4558 return 1;
4559 break;
4560
4561 case IA64_OPND_R3_2:
4562 if (e->X_op == O_register && e->X_add_number >= REG_GR
4563 && e->X_add_number < REG_GR + 4)
4564 return 1;
4565 break;
4566
4567 /* indirect operands: */
4568 case IA64_OPND_CPUID_R3:
4569 case IA64_OPND_DBR_R3:
4570 case IA64_OPND_DTR_R3:
4571 case IA64_OPND_ITR_R3:
4572 case IA64_OPND_IBR_R3:
4573 case IA64_OPND_MSR_R3:
4574 case IA64_OPND_PKR_R3:
4575 case IA64_OPND_PMC_R3:
4576 case IA64_OPND_PMD_R3:
4577 case IA64_OPND_RR_R3:
4578 if (e->X_op == O_index && e->X_op_symbol
4579 && (S_GET_VALUE (e->X_op_symbol) - IND_CPUID
4580 == opnd - IA64_OPND_CPUID_R3))
4581 return 1;
4582 break;
4583
4584 case IA64_OPND_MR3:
4585 if (e->X_op == O_index && !e->X_op_symbol)
4586 return 1;
4587 break;
4588
4589 /* immediate operands: */
4590 case IA64_OPND_CNT2a:
4591 case IA64_OPND_LEN4:
4592 case IA64_OPND_LEN6:
4593 bits = operand_width (idesc->operands[index]);
4594 if (e->X_op == O_constant
4595 && (bfd_vma) (e->X_add_number - 1) < ((bfd_vma) 1 << bits))
4596 return 1;
4597 break;
4598
4599 case IA64_OPND_CNT2b:
4600 if (e->X_op == O_constant
4601 && (bfd_vma) (e->X_add_number - 1) < 3)
4602 return 1;
4603 break;
4604
4605 case IA64_OPND_CNT2c:
4606 val = e->X_add_number;
4607 if (e->X_op == O_constant
4608 && (val == 0 || val == 7 || val == 15 || val == 16))
4609 return 1;
4610 break;
4611
4612 case IA64_OPND_SOR:
4613 /* SOR must be an integer multiple of 8 */
4614 if (e->X_add_number & 0x7)
4615 break;
4616 case IA64_OPND_SOF:
4617 case IA64_OPND_SOL:
4618 if (e->X_op == O_constant &&
4619 (bfd_vma) e->X_add_number <= 96)
4620 return 1;
4621 break;
4622
4623 case IA64_OPND_IMMU62:
4624 if (e->X_op == O_constant)
4625 {
4626 if ((bfd_vma) e->X_add_number < ((bfd_vma) 1 << 62))
4627 return 1;
4628 }
4629 else
4630 {
4631 /* FIXME -- need 62-bit relocation type */
4632 as_bad (_("62-bit relocation not yet implemented"));
4633 }
4634 break;
4635
4636 case IA64_OPND_IMMU64:
4637 if (e->X_op == O_symbol || e->X_op == O_pseudo_fixup
4638 || e->X_op == O_subtract)
4639 {
4640 fix = CURR_SLOT.fixup + CURR_SLOT.num_fixups;
4641 fix->code = BFD_RELOC_IA64_IMM64;
4642 if (e->X_op != O_subtract)
4643 {
4644 fix->code = ia64_gen_real_reloc_type (e->X_op_symbol, fix->code);
4645 if (e->X_op == O_pseudo_fixup)
4646 e->X_op = O_symbol;
4647 }
4648
4649 fix->opnd = idesc->operands[index];
4650 fix->expr = *e;
4651 fix->is_pcrel = 0;
4652 ++CURR_SLOT.num_fixups;
4653 return 1;
4654 }
4655 else if (e->X_op == O_constant)
4656 return 1;
4657 break;
4658
4659 case IA64_OPND_CCNT5:
4660 case IA64_OPND_CNT5:
4661 case IA64_OPND_CNT6:
4662 case IA64_OPND_CPOS6a:
4663 case IA64_OPND_CPOS6b:
4664 case IA64_OPND_CPOS6c:
4665 case IA64_OPND_IMMU2:
4666 case IA64_OPND_IMMU7a:
4667 case IA64_OPND_IMMU7b:
800eeca4
JW
4668 case IA64_OPND_IMMU21:
4669 case IA64_OPND_IMMU24:
4670 case IA64_OPND_MBTYPE4:
4671 case IA64_OPND_MHTYPE8:
4672 case IA64_OPND_POS6:
4673 bits = operand_width (idesc->operands[index]);
4674 if (e->X_op == O_constant
4675 && (bfd_vma) e->X_add_number < ((bfd_vma) 1 << bits))
4676 return 1;
4677 break;
4678
bf3ca999
TW
4679 case IA64_OPND_IMMU9:
4680 bits = operand_width (idesc->operands[index]);
4681 if (e->X_op == O_constant
4682 && (bfd_vma) e->X_add_number < ((bfd_vma) 1 << bits))
4683 {
4684 int lobits = e->X_add_number & 0x3;
4685 if (((bfd_vma) e->X_add_number & 0x3C) != 0 && lobits == 0)
4686 e->X_add_number |= (bfd_vma)0x3;
4687 return 1;
4688 }
4689 break;
4690
800eeca4
JW
4691 case IA64_OPND_IMM44:
4692 /* least 16 bits must be zero */
4693 if ((e->X_add_number & 0xffff) != 0)
4694 as_warn (_("lower 16 bits of mask ignored"));
4695
4696 if (e->X_op == O_constant
4697 && ((e->X_add_number >= 0
4698 && e->X_add_number < ((bfd_vma) 1 << 44))
4699 || (e->X_add_number < 0
4700 && -e->X_add_number <= ((bfd_vma) 1 << 44))))
4701 {
4702 /* sign-extend */
4703 if (e->X_add_number >= 0
4704 && (e->X_add_number & ((bfd_vma) 1 << 43)) != 0)
4705 {
4706 e->X_add_number |= ~(((bfd_vma) 1 << 44) - 1);
4707 }
4708 return 1;
4709 }
4710 break;
4711
4712 case IA64_OPND_IMM17:
4713 /* bit 0 is a don't care (pr0 is hardwired to 1) */
4714 if (e->X_op == O_constant
4715 && ((e->X_add_number >= 0
4716 && e->X_add_number < ((bfd_vma) 1 << 17))
4717 || (e->X_add_number < 0
4718 && -e->X_add_number <= ((bfd_vma) 1 << 17))))
4719 {
4720 /* sign-extend */
4721 if (e->X_add_number >= 0
4722 && (e->X_add_number & ((bfd_vma) 1 << 16)) != 0)
4723 {
4724 e->X_add_number |= ~(((bfd_vma)1 << 17) - 1);
4725 }
4726 return 1;
4727 }
4728 break;
4729
4730 case IA64_OPND_IMM14:
4731 case IA64_OPND_IMM22:
4732 relocatable = 1;
4733 case IA64_OPND_IMM1:
4734 case IA64_OPND_IMM8:
4735 case IA64_OPND_IMM8U4:
4736 case IA64_OPND_IMM8M1:
4737 case IA64_OPND_IMM8M1U4:
4738 case IA64_OPND_IMM8M1U8:
4739 case IA64_OPND_IMM9a:
4740 case IA64_OPND_IMM9b:
4741 bits = operand_width (idesc->operands[index]);
4742 if (relocatable && (e->X_op == O_symbol
4743 || e->X_op == O_subtract
4744 || e->X_op == O_pseudo_fixup))
4745 {
4746 fix = CURR_SLOT.fixup + CURR_SLOT.num_fixups;
4747
4748 if (idesc->operands[index] == IA64_OPND_IMM14)
4749 fix->code = BFD_RELOC_IA64_IMM14;
4750 else
4751 fix->code = BFD_RELOC_IA64_IMM22;
4752
4753 if (e->X_op != O_subtract)
4754 {
4755 fix->code = ia64_gen_real_reloc_type (e->X_op_symbol, fix->code);
4756 if (e->X_op == O_pseudo_fixup)
4757 e->X_op = O_symbol;
4758 }
4759
4760 fix->opnd = idesc->operands[index];
4761 fix->expr = *e;
4762 fix->is_pcrel = 0;
4763 ++CURR_SLOT.num_fixups;
4764 return 1;
4765 }
4766 else if (e->X_op != O_constant
4767 && ! (e->X_op == O_big && opnd == IA64_OPND_IMM8M1U8))
4768 return 0;
4769
4770 if (opnd == IA64_OPND_IMM8M1U4)
4771 {
4772 /* Zero is not valid for unsigned compares that take an adjusted
4773 constant immediate range. */
4774 if (e->X_add_number == 0)
4775 return 0;
4776
4777 /* Sign-extend 32-bit unsigned numbers, so that the following range
4778 checks will work. */
4779 val = e->X_add_number;
4780 if (((val & (~(bfd_vma)0 << 32)) == 0)
4781 && ((val & ((bfd_vma)1 << 31)) != 0))
4782 val = ((val << 32) >> 32);
4783
4784 /* Check for 0x100000000. This is valid because
4785 0x100000000-1 is the same as ((uint32_t) -1). */
4786 if (val == ((bfd_signed_vma) 1 << 32))
4787 return 1;
4788
4789 val = val - 1;
4790 }
4791 else if (opnd == IA64_OPND_IMM8M1U8)
4792 {
4793 /* Zero is not valid for unsigned compares that take an adjusted
4794 constant immediate range. */
4795 if (e->X_add_number == 0)
4796 return 0;
4797
4798 /* Check for 0x10000000000000000. */
4799 if (e->X_op == O_big)
4800 {
4801 if (generic_bignum[0] == 0
4802 && generic_bignum[1] == 0
4803 && generic_bignum[2] == 0
4804 && generic_bignum[3] == 0
4805 && generic_bignum[4] == 1)
4806 return 1;
4807 else
4808 return 0;
4809 }
4810 else
4811 val = e->X_add_number - 1;
4812 }
4813 else if (opnd == IA64_OPND_IMM8M1)
4814 val = e->X_add_number - 1;
4815 else if (opnd == IA64_OPND_IMM8U4)
4816 {
4817 /* Sign-extend 32-bit unsigned numbers, so that the following range
4818 checks will work. */
4819 val = e->X_add_number;
4820 if (((val & (~(bfd_vma)0 << 32)) == 0)
4821 && ((val & ((bfd_vma)1 << 31)) != 0))
4822 val = ((val << 32) >> 32);
4823 }
4824 else
4825 val = e->X_add_number;
4826
4827 if ((val >= 0 && val < ((bfd_vma) 1 << (bits - 1)))
4828 || (val < 0 && -val <= ((bfd_vma) 1 << (bits - 1))))
4829 return 1;
4830 break;
4831
4832 case IA64_OPND_INC3:
4833 /* +/- 1, 4, 8, 16 */
4834 val = e->X_add_number;
4835 if (val < 0)
4836 val = -val;
4837 if (e->X_op == O_constant
4838 && (val == 1 || val == 4 || val == 8 || val == 16))
4839 return 1;
4840 break;
4841
4842 case IA64_OPND_TGT25:
4843 case IA64_OPND_TGT25b:
4844 case IA64_OPND_TGT25c:
4845 case IA64_OPND_TGT64:
4846 if (e->X_op == O_symbol)
4847 {
4848 fix = CURR_SLOT.fixup + CURR_SLOT.num_fixups;
4849 if (opnd == IA64_OPND_TGT25)
4850 fix->code = BFD_RELOC_IA64_PCREL21F;
4851 else if (opnd == IA64_OPND_TGT25b)
4852 fix->code = BFD_RELOC_IA64_PCREL21M;
4853 else if (opnd == IA64_OPND_TGT25c)
4854 fix->code = BFD_RELOC_IA64_PCREL21B;
c67e42c9
RH
4855 else if (opnd == IA64_OPND_TGT64)
4856 fix->code = BFD_RELOC_IA64_PCREL60B;
4857 else
4858 abort ();
4859
800eeca4
JW
4860 fix->code = ia64_gen_real_reloc_type (e->X_op_symbol, fix->code);
4861 fix->opnd = idesc->operands[index];
4862 fix->expr = *e;
4863 fix->is_pcrel = 1;
4864 ++CURR_SLOT.num_fixups;
4865 return 1;
4866 }
4867 case IA64_OPND_TAG13:
4868 case IA64_OPND_TAG13b:
4869 switch (e->X_op)
4870 {
4871 case O_constant:
4872 return 1;
4873
4874 case O_symbol:
4875 fix = CURR_SLOT.fixup + CURR_SLOT.num_fixups;
4876 fix->code = ia64_gen_real_reloc_type (e->X_op_symbol, 0);
4877 fix->opnd = idesc->operands[index];
4878 fix->expr = *e;
4879 fix->is_pcrel = 1;
4880 ++CURR_SLOT.num_fixups;
4881 return 1;
4882
4883 default:
4884 break;
4885 }
4886 break;
4887
4888 default:
4889 break;
4890 }
4891 return 0;
4892}
4893
4894static int
4895parse_operand (e)
4896 expressionS *e;
4897{
4898 int sep = '\0';
4899
4900 memset (e, 0, sizeof (*e));
4901 e->X_op = O_absent;
4902 SKIP_WHITESPACE ();
4903 if (*input_line_pointer != '}')
4904 expression (e);
4905 sep = *input_line_pointer++;
4906
4907 if (sep == '}')
4908 {
4909 if (!md.manual_bundling)
4910 as_warn ("Found '}' when manual bundling is off");
4911 else
4912 CURR_SLOT.manual_bundling_off = 1;
4913 md.manual_bundling = 0;
4914 sep = '\0';
4915 }
4916 return sep;
4917}
4918
4919/* Returns the next entry in the opcode table that matches the one in
4920 IDESC, and frees the entry in IDESC. If no matching entry is
4921 found, NULL is returned instead. */
4922
4923static struct ia64_opcode *
4924get_next_opcode (struct ia64_opcode *idesc)
4925{
4926 struct ia64_opcode *next = ia64_find_next_opcode (idesc);
4927 ia64_free_opcode (idesc);
4928 return next;
4929}
4930
4931/* Parse the operands for the opcode and find the opcode variant that
4932 matches the specified operands, or NULL if no match is possible. */
4933static struct ia64_opcode*
4934parse_operands (idesc)
4935 struct ia64_opcode *idesc;
4936{
4937 int i = 0, highest_unmatched_operand, num_operands = 0, num_outputs = 0;
4938 int sep = 0;
4939 enum ia64_opnd expected_operand = IA64_OPND_NIL;
4940 char mnemonic[129];
4941 char *first_arg = 0, *end, *saved_input_pointer;
4942 unsigned int sof;
4943
4944 assert (strlen (idesc->name) <= 128);
4945
4946 strcpy (mnemonic, idesc->name);
4947 if (idesc->operands[2] == IA64_OPND_SOF)
4948 {
4949 /* To make the common idiom "alloc loc?=ar.pfs,0,1,0,0" work, we
4950 can't parse the first operand until we have parsed the
4951 remaining operands of the "alloc" instruction. */
4952 SKIP_WHITESPACE ();
4953 first_arg = input_line_pointer;
4954 end = strchr (input_line_pointer, '=');
4955 if (!end)
4956 {
4957 as_bad ("Expected separator `='");
4958 return 0;
4959 }
4960 input_line_pointer = end + 1;
4961 ++i;
4962 ++num_outputs;
4963 }
4964
4965 for (; i < NELEMS (CURR_SLOT.opnd); ++i)
4966 {
4967 sep = parse_operand (CURR_SLOT.opnd + i);
4968 if (CURR_SLOT.opnd[i].X_op == O_absent)
4969 break;
4970
4971 ++num_operands;
4972
4973 if (sep != '=' && sep != ',')
4974 break;
4975
4976 if (sep == '=')
4977 {
4978 if (num_outputs > 0)
4979 as_bad ("Duplicate equal sign (=) in instruction");
4980 else
4981 num_outputs = i + 1;
4982 }
4983 }
4984 if (sep != '\0')
4985 {
4986 as_bad ("Illegal operand separator `%c'", sep);
4987 return 0;
4988 }
4989
4990 if (idesc->operands[2] == IA64_OPND_SOF)
4991 {
4992 /* map alloc r1=ar.pfs,i,l,o,r to alloc r1=ar.pfs,(i+l+o),(i+l),r */
4993 know (strcmp (idesc->name, "alloc") == 0);
4994 if (num_operands == 5 /* first_arg not included in this count! */
4995 && CURR_SLOT.opnd[2].X_op == O_constant
4996 && CURR_SLOT.opnd[3].X_op == O_constant
4997 && CURR_SLOT.opnd[4].X_op == O_constant
4998 && CURR_SLOT.opnd[5].X_op == O_constant)
4999 {
5000 sof = set_regstack (CURR_SLOT.opnd[2].X_add_number,
5001 CURR_SLOT.opnd[3].X_add_number,
5002 CURR_SLOT.opnd[4].X_add_number,
5003 CURR_SLOT.opnd[5].X_add_number);
5004
5005 /* now we can parse the first arg: */
5006 saved_input_pointer = input_line_pointer;
5007 input_line_pointer = first_arg;
5008 sep = parse_operand (CURR_SLOT.opnd + 0);
5009 if (sep != '=')
5010 --num_outputs; /* force error */
5011 input_line_pointer = saved_input_pointer;
5012
5013 CURR_SLOT.opnd[2].X_add_number = sof;
5014 CURR_SLOT.opnd[3].X_add_number
5015 = sof - CURR_SLOT.opnd[4].X_add_number;
5016 CURR_SLOT.opnd[4] = CURR_SLOT.opnd[5];
5017 }
5018 }
5019
5020 highest_unmatched_operand = 0;
5021 expected_operand = idesc->operands[0];
5022 for (; idesc; idesc = get_next_opcode (idesc))
5023 {
5024 if (num_outputs != idesc->num_outputs)
5025 continue; /* mismatch in # of outputs */
5026
5027 CURR_SLOT.num_fixups = 0;
5028 for (i = 0; i < num_operands && idesc->operands[i]; ++i)
5029 if (!operand_match (idesc, i, CURR_SLOT.opnd + i))
5030 break;
5031
5032 if (i != num_operands)
5033 {
5034 if (i > highest_unmatched_operand)
5035 {
5036 highest_unmatched_operand = i;
5037 expected_operand = idesc->operands[i];
5038 }
5039 continue;
5040 }
5041
5042 if (num_operands < NELEMS (idesc->operands)
5043 && idesc->operands[num_operands])
5044 continue; /* mismatch in number of arguments */
5045
5046 break;
5047 }
5048 if (!idesc)
5049 {
5050 if (expected_operand)
5051 as_bad ("Operand %u of `%s' should be %s",
5052 highest_unmatched_operand + 1, mnemonic,
5053 elf64_ia64_operands[expected_operand].desc);
5054 else
5055 as_bad ("Operand mismatch");
5056 return 0;
5057 }
5058 return idesc;
5059}
5060
5061static void
5062build_insn (slot, insnp)
5063 struct slot *slot;
5064 bfd_vma *insnp;
5065{
5066 const struct ia64_operand *odesc, *o2desc;
5067 struct ia64_opcode *idesc = slot->idesc;
5068 bfd_signed_vma insn, val;
5069 const char *err;
5070 int i;
5071
5072 insn = idesc->opcode | slot->qp_regno;
5073
5074 for (i = 0; i < NELEMS (idesc->operands) && idesc->operands[i]; ++i)
5075 {
c67e42c9
RH
5076 if (slot->opnd[i].X_op == O_register
5077 || slot->opnd[i].X_op == O_constant
5078 || slot->opnd[i].X_op == O_index)
5079 val = slot->opnd[i].X_add_number;
5080 else if (slot->opnd[i].X_op == O_big)
800eeca4 5081 {
c67e42c9
RH
5082 /* This must be the value 0x10000000000000000. */
5083 assert (idesc->operands[i] == IA64_OPND_IMM8M1U8);
5084 val = 0;
5085 }
5086 else
5087 val = 0;
5088
5089 switch (idesc->operands[i])
5090 {
5091 case IA64_OPND_IMMU64:
800eeca4
JW
5092 *insnp++ = (val >> 22) & 0x1ffffffffffLL;
5093 insn |= (((val & 0x7f) << 13) | (((val >> 7) & 0x1ff) << 27)
5094 | (((val >> 16) & 0x1f) << 22) | (((val >> 21) & 0x1) << 21)
5095 | (((val >> 63) & 0x1) << 36));
c67e42c9
RH
5096 continue;
5097
5098 case IA64_OPND_IMMU62:
5099 val &= 0x3fffffffffffffffULL;
800eeca4
JW
5100 if (val != slot->opnd[i].X_add_number)
5101 as_warn (_("Value truncated to 62 bits"));
5102 *insnp++ = (val >> 21) & 0x1ffffffffffLL;
5103 insn |= (((val & 0xfffff) << 6) | (((val >> 20) & 0x1) << 36));
c67e42c9 5104 continue;
800eeca4 5105
c67e42c9
RH
5106 case IA64_OPND_TGT64:
5107 val >>= 4;
5108 *insnp++ = ((val >> 20) & 0x7fffffffffLL) << 2;
5109 insn |= ((((val >> 59) & 0x1) << 36)
5110 | (((val >> 0) & 0xfffff) << 13));
5111 continue;
800eeca4 5112
c67e42c9
RH
5113 case IA64_OPND_AR3:
5114 val -= REG_AR;
5115 break;
5116
5117 case IA64_OPND_B1:
5118 case IA64_OPND_B2:
5119 val -= REG_BR;
5120 break;
5121
5122 case IA64_OPND_CR3:
5123 val -= REG_CR;
5124 break;
5125
5126 case IA64_OPND_F1:
5127 case IA64_OPND_F2:
5128 case IA64_OPND_F3:
5129 case IA64_OPND_F4:
5130 val -= REG_FR;
5131 break;
5132
5133 case IA64_OPND_P1:
5134 case IA64_OPND_P2:
5135 val -= REG_P;
5136 break;
5137
5138 case IA64_OPND_R1:
5139 case IA64_OPND_R2:
5140 case IA64_OPND_R3:
5141 case IA64_OPND_R3_2:
5142 case IA64_OPND_CPUID_R3:
5143 case IA64_OPND_DBR_R3:
5144 case IA64_OPND_DTR_R3:
5145 case IA64_OPND_ITR_R3:
5146 case IA64_OPND_IBR_R3:
5147 case IA64_OPND_MR3:
5148 case IA64_OPND_MSR_R3:
5149 case IA64_OPND_PKR_R3:
5150 case IA64_OPND_PMC_R3:
5151 case IA64_OPND_PMD_R3:
5152 case IA64_OPND_RR_R3:
5153 val -= REG_GR;
5154 break;
5155
5156 default:
5157 break;
5158 }
5159
5160 odesc = elf64_ia64_operands + idesc->operands[i];
5161 err = (*odesc->insert) (odesc, val, &insn);
5162 if (err)
5163 as_bad_where (slot->src_file, slot->src_line,
5164 "Bad operand value: %s", err);
5165 if (idesc->flags & IA64_OPCODE_PSEUDO)
5166 {
5167 if ((idesc->flags & IA64_OPCODE_F2_EQ_F3)
5168 && odesc == elf64_ia64_operands + IA64_OPND_F3)
5169 {
5170 o2desc = elf64_ia64_operands + IA64_OPND_F2;
5171 (*o2desc->insert) (o2desc, val, &insn);
800eeca4 5172 }
c67e42c9
RH
5173 if ((idesc->flags & IA64_OPCODE_LEN_EQ_64MCNT)
5174 && (odesc == elf64_ia64_operands + IA64_OPND_CPOS6a
5175 || odesc == elf64_ia64_operands + IA64_OPND_POS6))
800eeca4 5176 {
c67e42c9
RH
5177 o2desc = elf64_ia64_operands + IA64_OPND_LEN6;
5178 (*o2desc->insert) (o2desc, 64 - val, &insn);
800eeca4
JW
5179 }
5180 }
5181 }
5182 *insnp = insn;
5183}
5184
5185static void
5186emit_one_bundle ()
5187{
5188 unsigned int manual_bundling_on = 0, manual_bundling_off = 0;
5189 unsigned int manual_bundling = 0;
5190 enum ia64_unit required_unit, insn_unit = 0;
5191 enum ia64_insn_type type[3], insn_type;
5192 unsigned int template, orig_template;
5193 bfd_vma insn[3] = {-1, -1, -1};
5194 struct ia64_opcode *idesc;
5195 int end_of_insn_group = 0, user_template = -1;
5196 int n, i, j, first, curr;
e0c9811a 5197 unw_rec_list *ptr, *prev;
800eeca4
JW
5198 bfd_vma t0 = 0, t1 = 0;
5199 struct label_fix *lfix;
5200 struct insn_fix *ifix;
5201 char mnemonic[16];
5202 fixS *fix;
5203 char *f;
5204
5205 first = (md.curr_slot + NUM_SLOTS - md.num_slots_in_use) % NUM_SLOTS;
5206 know (first >= 0 & first < NUM_SLOTS);
5207 n = MIN (3, md.num_slots_in_use);
5208
5209 /* Determine template: user user_template if specified, best match
5210 otherwise: */
5211
5212 if (md.slot[first].user_template >= 0)
5213 user_template = template = md.slot[first].user_template;
5214 else
5215 {
5216 /* auto select appropriate template */
5217 memset (type, 0, sizeof (type));
5218 curr = first;
5219 for (i = 0; i < n; ++i)
5220 {
5221 type[i] = md.slot[curr].idesc->type;
5222 curr = (curr + 1) % NUM_SLOTS;
5223 }
5224 template = best_template[type[0]][type[1]][type[2]];
5225 }
5226
5227 /* initialize instructions with appropriate nops: */
5228 for (i = 0; i < 3; ++i)
5229 insn[i] = nop[ia64_templ_desc[template].exec_unit[i]];
5230
5231 f = frag_more (16);
5232
5233 /* now fill in slots with as many insns as possible: */
5234 curr = first;
5235 idesc = md.slot[curr].idesc;
5236 end_of_insn_group = 0;
5237 for (i = 0; i < 3 && md.num_slots_in_use > 0; ++i)
5238 {
e0c9811a
JW
5239 /* Set the slot number for prologue/body records now as those
5240 refer to the current point, not the point after the
5241 instruction has been issued: */
5242 prev = 0;
5243 for (ptr = md.slot[curr].unwind_record; ptr; ptr = ptr->next)
5244 {
5245 if (ptr->r.type == prologue || ptr->r.type == prologue_gr
5246 || ptr->r.type == body)
5247 {
5248 ptr->slot_number = (unsigned long) f + i;
5249 if (prev)
5250 prev->next = ptr->next;
5251 else
5252 md.slot[curr].unwind_record = ptr->next;
5253 }
5254 else
5255 prev = ptr;
5256 }
5257
800eeca4
JW
5258 if (idesc->flags & IA64_OPCODE_SLOT2)
5259 {
5260 if (manual_bundling && i != 2)
5261 as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line,
5262 "`%s' must be last in bundle", idesc->name);
5263 else
5264 i = 2;
5265 }
5266 if (idesc->flags & IA64_OPCODE_LAST)
5267 {
5268 int required_slot, required_template;
5269
5270 /* If we need a stop bit after an M slot, our only choice is
5271 template 5 (M;;MI). If we need a stop bit after a B
5272 slot, our only choice is to place it at the end of the
5273 bundle, because the only available templates are MIB,
5274 MBB, BBB, MMB, and MFB. We don't handle anything other
5275 than M and B slots because these are the only kind of
5276 instructions that can have the IA64_OPCODE_LAST bit set. */
5277 required_template = template;
5278 switch (idesc->type)
5279 {
5280 case IA64_TYPE_M:
5281 required_slot = 0;
5282 required_template = 5;
5283 break;
5284
5285 case IA64_TYPE_B:
5286 required_slot = 2;
5287 break;
5288
5289 default:
5290 as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line,
5291 "Internal error: don't know how to force %s to end"
5292 "of instruction group", idesc->name);
5293 required_slot = i;
5294 break;
5295 }
5296 if (manual_bundling && i != required_slot)
5297 as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line,
5298 "`%s' must be last in instruction group",
5299 idesc->name);
5300 if (required_slot < i)
5301 /* Can't fit this instruction. */
5302 break;
5303
5304 i = required_slot;
5305 if (required_template != template)
5306 {
5307 /* If we switch the template, we need to reset the NOPs
5308 after slot i. The slot-types of the instructions ahead
5309 of i never change, so we don't need to worry about
5310 changing NOPs in front of this slot. */
5311 for (j = i; j < 3; ++j)
5312 insn[j] = nop[ia64_templ_desc[required_template].exec_unit[j]];
5313 }
5314 template = required_template;
5315 }
5316 if (curr != first && md.slot[curr].label_fixups)
5317 {
5318 if (manual_bundling_on)
5319 as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line,
5320 "Label must be first in a bundle");
5321 /* This insn must go into the first slot of a bundle. */
5322 break;
5323 }
5324
5325 manual_bundling_on = md.slot[curr].manual_bundling_on;
5326 manual_bundling_off = md.slot[curr].manual_bundling_off;
5327
5328 if (manual_bundling_on)
5329 {
5330 if (curr == first)
5331 manual_bundling = 1;
5332 else
5333 break; /* need to start a new bundle */
5334 }
5335
5336 if (end_of_insn_group && md.num_slots_in_use >= 1)
5337 {
5338 /* We need an instruction group boundary in the middle of a
5339 bundle. See if we can switch to an other template with
5340 an appropriate boundary. */
5341
5342 orig_template = template;
5343 if (i == 1 && (user_template == 4
5344 || (user_template < 0
5345 && (ia64_templ_desc[template].exec_unit[0]
5346 == IA64_UNIT_M))))
5347 {
5348 template = 5;
5349 end_of_insn_group = 0;
5350 }
5351 else if (i == 2 && (user_template == 0
5352 || (user_template < 0
5353 && (ia64_templ_desc[template].exec_unit[1]
5354 == IA64_UNIT_I)))
5355 /* This test makes sure we don't switch the template if
5356 the next instruction is one that needs to be first in
5357 an instruction group. Since all those instructions are
5358 in the M group, there is no way such an instruction can
5359 fit in this bundle even if we switch the template. The
5360 reason we have to check for this is that otherwise we
5361 may end up generating "MI;;I M.." which has the deadly
5362 effect that the second M instruction is no longer the
5363 first in the bundle! --davidm 99/12/16 */
5364 && (idesc->flags & IA64_OPCODE_FIRST) == 0)
5365 {
5366 template = 1;
5367 end_of_insn_group = 0;
5368 }
5369 else if (curr != first)
5370 /* can't fit this insn */
5371 break;
5372
5373 if (template != orig_template)
5374 /* if we switch the template, we need to reset the NOPs
5375 after slot i. The slot-types of the instructions ahead
5376 of i never change, so we don't need to worry about
5377 changing NOPs in front of this slot. */
5378 for (j = i; j < 3; ++j)
5379 insn[j] = nop[ia64_templ_desc[template].exec_unit[j]];
5380 }
5381 required_unit = ia64_templ_desc[template].exec_unit[i];
5382
5383 /* resolve dynamic opcodes such as "break" and "nop": */
5384 if (idesc->type == IA64_TYPE_DYN)
5385 {
5386 if ((strcmp (idesc->name, "nop") == 0)
5387 || (strcmp (idesc->name, "break") == 0))
5388 insn_unit = required_unit;
5389 else if (strcmp (idesc->name, "chk.s") == 0)
5390 {
5391 insn_unit = IA64_UNIT_M;
5392 if (required_unit == IA64_UNIT_I)
5393 insn_unit = IA64_UNIT_I;
5394 }
5395 else
5396 as_fatal ("emit_one_bundle: unexpected dynamic op");
5397
5398 sprintf (mnemonic, "%s.%c", idesc->name, "?imbf??"[insn_unit]);
5399 md.slot[curr].idesc = idesc = ia64_find_opcode (mnemonic);
5400#if 0
5401 know (!idesc->next); /* no resolved dynamic ops have collisions */
5402#endif
5403 }
5404 else
5405 {
5406 insn_type = idesc->type;
5407 insn_unit = IA64_UNIT_NIL;
5408 switch (insn_type)
5409 {
5410 case IA64_TYPE_A:
5411 if (required_unit == IA64_UNIT_I || required_unit == IA64_UNIT_M)
5412 insn_unit = required_unit;
5413 break;
5414 case IA64_TYPE_X: insn_unit = IA64_UNIT_L; break;
5415 case IA64_TYPE_I: insn_unit = IA64_UNIT_I; break;
5416 case IA64_TYPE_M: insn_unit = IA64_UNIT_M; break;
5417 case IA64_TYPE_B: insn_unit = IA64_UNIT_B; break;
5418 case IA64_TYPE_F: insn_unit = IA64_UNIT_F; break;
5419 default: break;
5420 }
5421 }
5422
5423 if (insn_unit != required_unit)
5424 {
5425 if (required_unit == IA64_UNIT_L
5426 && insn_unit == IA64_UNIT_I
5427 && !(idesc->flags & IA64_OPCODE_X_IN_MLX))
5428 {
5429 /* we got ourselves an MLX template but the current
5430 instruction isn't an X-unit, or an I-unit instruction
5431 that can go into the X slot of an MLX template. Duh. */
5432 if (md.num_slots_in_use >= NUM_SLOTS)
5433 {
5434 as_bad_where (md.slot[curr].src_file,
5435 md.slot[curr].src_line,
5436 "`%s' can't go in X slot of "
5437 "MLX template", idesc->name);
5438 /* drop this insn so we don't livelock: */
5439 --md.num_slots_in_use;
5440 }
5441 break;
5442 }
5443 continue; /* try next slot */
5444 }
5445
5446 if (debug_type == DEBUG_DWARF2)
5447 {
5448 bfd_vma addr;
5449
5450 addr = frag_now->fr_address + frag_now_fix () - 16 + 1*i;
5451 dwarf2_gen_line_info (addr, &md.slot[curr].debug_line);
5452 }
5453
5454 build_insn (md.slot + curr, insn + i);
5455
5456 /* Set slot counts for unwind records. */
5457 while (md.slot[curr].unwind_record)
5458 {
e0c9811a 5459 md.slot[curr].unwind_record->slot_number = (unsigned long) f + i;
800eeca4
JW
5460 md.slot[curr].unwind_record = md.slot[curr].unwind_record->next;
5461 }
e0c9811a 5462 unwind.next_slot_number = (unsigned long) f + i + ((i == 2)?(0x10-2):1);
800eeca4
JW
5463 if (required_unit == IA64_UNIT_L)
5464 {
5465 know (i == 1);
5466 /* skip one slot for long/X-unit instructions */
5467 ++i;
5468 }
5469 --md.num_slots_in_use;
5470
5471 /* now is a good time to fix up the labels for this insn: */
5472 for (lfix = md.slot[curr].label_fixups; lfix; lfix = lfix->next)
5473 {
5474 S_SET_VALUE (lfix->sym, frag_now_fix () - 16);
5475 symbol_set_frag (lfix->sym, frag_now);
5476 }
5477
5478 for (j = 0; j < md.slot[curr].num_fixups; ++j)
5479 {
5480 ifix = md.slot[curr].fixup + j;
5481 fix = fix_new_exp (frag_now, frag_now_fix () - 16 + i, 4,
5482 &ifix->expr, ifix->is_pcrel, ifix->code);
5483 fix->tc_fix_data.opnd = ifix->opnd;
5484 fix->fx_plt = (fix->fx_r_type == BFD_RELOC_IA64_PLTOFF22);
5485 fix->fx_file = md.slot[curr].src_file;
5486 fix->fx_line = md.slot[curr].src_line;
5487 }
5488
5489 end_of_insn_group = md.slot[curr].end_of_insn_group;
5490
5491 /* clear slot: */
5492 ia64_free_opcode (md.slot[curr].idesc);
5493 memset (md.slot + curr, 0, sizeof (md.slot[curr]));
5494 md.slot[curr].user_template = -1;
5495
5496 if (manual_bundling_off)
5497 {
5498 manual_bundling = 0;
5499 break;
5500 }
5501 curr = (curr + 1) % NUM_SLOTS;
5502 idesc = md.slot[curr].idesc;
5503 }
5504 if (manual_bundling)
5505 {
5506 if (md.num_slots_in_use > 0)
5507 as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line,
5508 "`%s' does not fit into %s template",
5509 idesc->name, ia64_templ_desc[template].name);
5510 else
5511 as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line,
5512 "Missing '}' at end of file");
5513 }
5514 know (md.num_slots_in_use < NUM_SLOTS);
5515
5516 t0 = end_of_insn_group | (template << 1) | (insn[0] << 5) | (insn[1] << 46);
5517 t1 = ((insn[1] >> 18) & 0x7fffff) | (insn[2] << 23);
5518
5519 md_number_to_chars (f + 0, t0, 8);
5520 md_number_to_chars (f + 8, t1, 8);
5521}
5522
5523int
5524md_parse_option (c, arg)
5525 int c;
5526 char *arg;
5527{
5528 /* Switches from the Intel assembler. */
5529 switch (c)
5530 {
5531 case 'M':
5532 if (strcmp (arg, "ilp64") == 0
5533 || strcmp (arg, "lp64") == 0
5534 || strcmp (arg, "p64") == 0)
5535 {
5536 md.flags |= EF_IA_64_ABI64;
5537 }
5538 else if (strcmp (arg, "ilp32") == 0)
5539 {
5540 md.flags &= ~EF_IA_64_ABI64;
5541 }
5542 else if (strcmp (arg, "le") == 0)
5543 {
5544 md.flags &= ~EF_IA_64_BE;
5545 }
5546 else if (strcmp (arg, "be") == 0)
5547 {
5548 md.flags |= EF_IA_64_BE;
5549 }
5550 else
5551 return 0;
5552 break;
5553
5554 case 'N':
5555 if (strcmp (arg, "so") == 0)
5556 {
5557 /* Suppress signon message. */
5558 }
5559 else if (strcmp (arg, "pi") == 0)
5560 {
5561 /* Reject privileged instructions. FIXME */
5562 }
5563 else if (strcmp (arg, "us") == 0)
5564 {
5565 /* Allow union of signed and unsigned range. FIXME */
5566 }
5567 else if (strcmp (arg, "close_fcalls") == 0)
5568 {
5569 /* Do not resolve global function calls. */
5570 }
5571 else
5572 return 0;
5573 break;
5574
5575 case 'C':
5576 /* temp[="prefix"] Insert temporary labels into the object file
5577 symbol table prefixed by "prefix".
5578 Default prefix is ":temp:".
5579 */
5580 break;
5581
5582 case 'a':
5583 /* ??? Conflicts with gas' listing option. */
5584 /* indirect=<tgt> Assume unannotated indirect branches behavior
5585 according to <tgt> --
5586 exit: branch out from the current context (default)
5587 labels: all labels in context may be branch targets
5588 */
5589 break;
5590
5591 case 'x':
5592 /* -X conflicts with an ignored option, use -x instead */
5593 md.detect_dv = 1;
5594 if (!arg || strcmp (arg, "explicit") == 0)
5595 {
5596 /* set default mode to explicit */
5597 md.default_explicit_mode = 1;
5598 break;
5599 }
5600 else if (strcmp (arg, "auto") == 0)
5601 {
5602 md.default_explicit_mode = 0;
5603 }
5604 else if (strcmp (arg, "debug") == 0)
5605 {
5606 md.debug_dv = 1;
5607 }
5608 else if (strcmp (arg, "debugx") == 0)
5609 {
5610 md.default_explicit_mode = 1;
5611 md.debug_dv = 1;
5612 }
5613 else
5614 {
5615 as_bad (_("Unrecognized option '-x%s'"), arg);
5616 }
5617 break;
5618
5619 case 'S':
5620 /* nops Print nops statistics. */
5621 break;
5622
5623 default:
5624 return 0;
5625 }
5626
5627 return 1;
5628}
5629
5630void
5631md_show_usage (stream)
5632 FILE *stream;
5633{
5634 fputs(_("\
5635IA-64 options:\n\
5636 -Milp32|-Milp64|-Mlp64|-Mp64 select data model (default -Mlp64)\n\
5637 -Mle | -Mbe select little- or big-endian byte order (default -Mle)\n\
5638 -x | -xexplicit turn on dependency violation checking (default)\n\
5639 -xauto automagically remove dependency violations\n\
5640 -xdebug debug dependency violation checker\n"),
5641 stream);
5642}
5643
5644static inline int
5645match (int templ, int type, int slot)
5646{
5647 enum ia64_unit unit;
5648 int result;
5649
5650 unit = ia64_templ_desc[templ].exec_unit[slot];
5651 switch (type)
5652 {
5653 case IA64_TYPE_DYN: result = 1; break; /* for nop and break */
5654 case IA64_TYPE_A:
5655 result = (unit == IA64_UNIT_I || unit == IA64_UNIT_M);
5656 break;
5657 case IA64_TYPE_X: result = (unit == IA64_UNIT_L); break;
5658 case IA64_TYPE_I: result = (unit == IA64_UNIT_I); break;
5659 case IA64_TYPE_M: result = (unit == IA64_UNIT_M); break;
5660 case IA64_TYPE_B: result = (unit == IA64_UNIT_B); break;
5661 case IA64_TYPE_F: result = (unit == IA64_UNIT_F); break;
5662 default: result = 0; break;
5663 }
5664 return result;
5665}
5666
5667/* This function is called once, at assembler startup time. It sets
5668 up all the tables, etc. that the MD part of the assembler will need
5669 that can be determined before arguments are parsed. */
5670void
5671md_begin ()
5672{
5673 int i, j, k, t, total, ar_base, cr_base, goodness, best, regnum;
5674 const char *err;
5675 char name[8];
5676
5677 md.auto_align = 1;
5678 md.explicit_mode = md.default_explicit_mode;
5679
5680 bfd_set_section_alignment (stdoutput, text_section, 4);
5681
5682 target_big_endian = 0;
5683 pseudo_func[FUNC_FPTR_RELATIVE].u.sym =
5684 symbol_new (".<fptr>", undefined_section, FUNC_FPTR_RELATIVE,
5685 &zero_address_frag);
5686
5687 pseudo_func[FUNC_GP_RELATIVE].u.sym =
5688 symbol_new (".<gprel>", undefined_section, FUNC_GP_RELATIVE,
5689 &zero_address_frag);
5690
5691 pseudo_func[FUNC_LT_RELATIVE].u.sym =
5692 symbol_new (".<ltoff>", undefined_section, FUNC_LT_RELATIVE,
5693 &zero_address_frag);
5694
c67e42c9
RH
5695 pseudo_func[FUNC_PC_RELATIVE].u.sym =
5696 symbol_new (".<pcrel>", undefined_section, FUNC_PC_RELATIVE,
5697 &zero_address_frag);
5698
800eeca4
JW
5699 pseudo_func[FUNC_PLT_RELATIVE].u.sym =
5700 symbol_new (".<pltoff>", undefined_section, FUNC_PLT_RELATIVE,
5701 &zero_address_frag);
5702
5703 pseudo_func[FUNC_SEC_RELATIVE].u.sym =
5704 symbol_new (".<secrel>", undefined_section, FUNC_SEC_RELATIVE,
5705 &zero_address_frag);
5706
5707 pseudo_func[FUNC_SEG_RELATIVE].u.sym =
5708 symbol_new (".<segrel>", undefined_section, FUNC_SEG_RELATIVE,
5709 &zero_address_frag);
5710
5711 pseudo_func[FUNC_LTV_RELATIVE].u.sym =
5712 symbol_new (".<ltv>", undefined_section, FUNC_LTV_RELATIVE,
5713 &zero_address_frag);
5714
5715 pseudo_func[FUNC_LT_FPTR_RELATIVE].u.sym =
5716 symbol_new (".<ltoff.fptr>", undefined_section, FUNC_LT_FPTR_RELATIVE,
5717 &zero_address_frag);
5718
5719 /* compute the table of best templates: */
5720 for (i = 0; i < IA64_NUM_TYPES; ++i)
5721 for (j = 0; j < IA64_NUM_TYPES; ++j)
5722 for (k = 0; k < IA64_NUM_TYPES; ++k)
5723 {
5724 best = 0;
5725 for (t = 0; t < NELEMS (ia64_templ_desc); ++t)
5726 {
5727 goodness = 0;
5728 if (match (t, i, 0))
5729 {
5730 if (match (t, j, 1))
5731 {
5732 if (match (t, k, 2))
5733 goodness = 3;
5734 else
5735 goodness = 2;
5736 }
5737 else if (match (t, j, 2))
5738 goodness = 2;
5739 else
5740 goodness = 1;
5741 }
5742 else if (match (t, i, 1))
5743 {
5744 if (match (t, j, 2))
5745 goodness = 2;
5746 else
5747 goodness = 1;
5748 }
5749 else if (match (t, i, 2))
5750 goodness = 1;
5751
5752 if (goodness > best)
5753 {
5754 best = goodness;
5755 best_template[i][j][k] = t;
5756 }
5757 }
5758 }
5759
5760 for (i = 0; i < NUM_SLOTS; ++i)
5761 md.slot[i].user_template = -1;
5762
5763 md.pseudo_hash = hash_new ();
5764 for (i = 0; i < NELEMS (pseudo_opcode); ++i)
5765 {
5766 err = hash_insert (md.pseudo_hash, pseudo_opcode[i].name,
5767 (void *) (pseudo_opcode + i));
5768 if (err)
5769 as_fatal ("ia64.md_begin: can't hash `%s': %s",
5770 pseudo_opcode[i].name, err);
5771 }
5772
5773 md.reg_hash = hash_new ();
5774 md.dynreg_hash = hash_new ();
5775 md.const_hash = hash_new ();
5776 md.entry_hash = hash_new ();
5777
5778 /* general registers: */
5779
5780 total = 128;
5781 for (i = 0; i < total; ++i)
5782 {
5783 sprintf (name, "r%d", i - REG_GR);
5784 md.regsym[i] = declare_register (name, i);
5785 }
5786
5787 /* floating point registers: */
5788 total += 128;
5789 for (; i < total; ++i)
5790 {
5791 sprintf (name, "f%d", i - REG_FR);
5792 md.regsym[i] = declare_register (name, i);
5793 }
5794
5795 /* application registers: */
5796 total += 128;
5797 ar_base = i;
5798 for (; i < total; ++i)
5799 {
5800 sprintf (name, "ar%d", i - REG_AR);
5801 md.regsym[i] = declare_register (name, i);
5802 }
5803
5804 /* control registers: */
5805 total += 128;
5806 cr_base = i;
5807 for (; i < total; ++i)
5808 {
5809 sprintf (name, "cr%d", i - REG_CR);
5810 md.regsym[i] = declare_register (name, i);
5811 }
5812
5813 /* predicate registers: */
5814 total += 64;
5815 for (; i < total; ++i)
5816 {
5817 sprintf (name, "p%d", i - REG_P);
5818 md.regsym[i] = declare_register (name, i);
5819 }
5820
5821 /* branch registers: */
5822 total += 8;
5823 for (; i < total; ++i)
5824 {
5825 sprintf (name, "b%d", i - REG_BR);
5826 md.regsym[i] = declare_register (name, i);
5827 }
5828
5829 md.regsym[REG_IP] = declare_register ("ip", REG_IP);
5830 md.regsym[REG_CFM] = declare_register ("cfm", REG_CFM);
5831 md.regsym[REG_PR] = declare_register ("pr", REG_PR);
5832 md.regsym[REG_PR_ROT] = declare_register ("pr.rot", REG_PR_ROT);
5833 md.regsym[REG_PSR] = declare_register ("psr", REG_PSR);
5834 md.regsym[REG_PSR_L] = declare_register ("psr.l", REG_PSR_L);
5835 md.regsym[REG_PSR_UM] = declare_register ("psr.um", REG_PSR_UM);
5836
5837 for (i = 0; i < NELEMS (indirect_reg); ++i)
5838 {
5839 regnum = indirect_reg[i].regnum;
5840 md.regsym[regnum] = declare_register (indirect_reg[i].name, regnum);
5841 }
5842
5843 /* define synonyms for application registers: */
5844 for (i = REG_AR; i < REG_AR + NELEMS (ar); ++i)
5845 md.regsym[i] = declare_register (ar[i - REG_AR].name,
5846 REG_AR + ar[i - REG_AR].regnum);
5847
5848 /* define synonyms for control registers: */
5849 for (i = REG_CR; i < REG_CR + NELEMS (cr); ++i)
5850 md.regsym[i] = declare_register (cr[i - REG_CR].name,
5851 REG_CR + cr[i - REG_CR].regnum);
5852
5853 declare_register ("gp", REG_GR + 1);
5854 declare_register ("sp", REG_GR + 12);
5855 declare_register ("rp", REG_BR + 0);
5856
e0c9811a
JW
5857 /* pseudo-registers used to specify unwind info: */
5858 declare_register ("psp", REG_PSP);
5859
800eeca4
JW
5860 declare_register_set ("ret", 4, REG_GR + 8);
5861 declare_register_set ("farg", 8, REG_FR + 8);
5862 declare_register_set ("fret", 8, REG_FR + 8);
5863
5864 for (i = 0; i < NELEMS (const_bits); ++i)
5865 {
5866 err = hash_insert (md.const_hash, const_bits[i].name,
5867 (PTR) (const_bits + i));
5868 if (err)
5869 as_fatal ("Inserting \"%s\" into constant hash table failed: %s",
5870 name, err);
5871 }
5872
5873 /* Default to 64-bit mode. */
5874 md.flags = EF_IA_64_ABI64;
5875
5876 md.mem_offset.hint = 0;
5877 md.path = 0;
5878 md.maxpaths = 0;
5879 md.entry_labels = NULL;
5880}
5881
5882void
5883ia64_end_of_source ()
5884{
5885 /* terminate insn group upon reaching end of file: */
5886 insn_group_break (1, 0, 0);
5887
5888 /* emits slots we haven't written yet: */
5889 ia64_flush_insns ();
5890
5891 bfd_set_private_flags (stdoutput, md.flags);
5892
5893 if (debug_type == DEBUG_DWARF2)
5894 dwarf2_finish ();
5895
5896 md.mem_offset.hint = 0;
5897}
5898
5899void
5900ia64_start_line ()
5901{
5902 md.qp.X_op = O_absent;
5903
5904 if (ignore_input ())
5905 return;
5906
5907 if (input_line_pointer[0] == ';' && input_line_pointer[-1] == ';')
5908 {
5909 if (md.detect_dv && !md.explicit_mode)
5910 as_warn (_("Explicit stops are ignored in auto mode"));
5911 else
5912 insn_group_break (1, 0, 0);
5913 }
5914}
5915
5916int
5917ia64_unrecognized_line (ch)
5918 int ch;
5919{
5920 switch (ch)
5921 {
5922 case '(':
5923 expression (&md.qp);
5924 if (*input_line_pointer++ != ')')
5925 {
5926 as_bad ("Expected ')'");
5927 return 0;
5928 }
5929 if (md.qp.X_op != O_register)
5930 {
5931 as_bad ("Qualifying predicate expected");
5932 return 0;
5933 }
5934 if (md.qp.X_add_number < REG_P || md.qp.X_add_number >= REG_P + 64)
5935 {
5936 as_bad ("Predicate register expected");
5937 return 0;
5938 }
5939 return 1;
5940
5941 case '{':
5942 if (md.manual_bundling)
5943 as_warn ("Found '{' when manual bundling is already turned on");
5944 else
5945 CURR_SLOT.manual_bundling_on = 1;
5946 md.manual_bundling = 1;
5947
5948 /* bundling is only acceptable in explicit mode
5949 or when in default automatic mode */
5950 if (md.detect_dv && !md.explicit_mode)
5951 {
5952 if (!md.mode_explicitly_set
5953 && !md.default_explicit_mode)
5954 dot_dv_mode ('E');
5955 else
5956 as_warn (_("Found '{' after explicit switch to automatic mode"));
5957 }
5958 return 1;
5959
5960 case '}':
5961 if (!md.manual_bundling)
5962 as_warn ("Found '}' when manual bundling is off");
5963 else
5964 PREV_SLOT.manual_bundling_off = 1;
5965 md.manual_bundling = 0;
5966
5967 /* switch back to automatic mode, if applicable */
5968 if (md.detect_dv
5969 && md.explicit_mode
5970 && !md.mode_explicitly_set
5971 && !md.default_explicit_mode)
5972 dot_dv_mode ('A');
5973
5974 /* Allow '{' to follow on the same line. We also allow ";;", but that
5975 happens automatically because ';' is an end of line marker. */
5976 SKIP_WHITESPACE ();
5977 if (input_line_pointer[0] == '{')
5978 {
5979 input_line_pointer++;
5980 return ia64_unrecognized_line ('{');
5981 }
5982
5983 demand_empty_rest_of_line ();
5984 return 1;
5985
5986 default:
5987 break;
5988 }
5989 return 0; /* not a valid line */
5990}
5991
5992void
5993ia64_frob_label (sym)
5994 struct symbol *sym;
5995{
5996 struct label_fix *fix;
5997
5998 if (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE)
5999 {
6000 md.last_text_seg = now_seg;
6001 fix = obstack_alloc (&notes, sizeof (*fix));
6002 fix->sym = sym;
6003 fix->next = CURR_SLOT.label_fixups;
6004 CURR_SLOT.label_fixups = fix;
6005
6006 /* keep track of how many code entry points we've seen */
6007 if (md.path == md.maxpaths)
6008 {
6009 md.maxpaths += 20;
6010 md.entry_labels = (const char **)
6011 xrealloc ((void *)md.entry_labels, md.maxpaths * sizeof (char *));
6012 }
6013 md.entry_labels[md.path++] = S_GET_NAME (sym);
6014 }
6015}
6016
6017void
6018ia64_flush_pending_output ()
6019{
6020 if (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE)
6021 {
6022 /* ??? This causes many unnecessary stop bits to be emitted.
6023 Unfortunately, it isn't clear if it is safe to remove this. */
6024 insn_group_break (1, 0, 0);
6025 ia64_flush_insns ();
6026 }
6027}
6028
6029/* Do ia64-specific expression optimization. All that's done here is
6030 to transform index expressions that are either due to the indexing
6031 of rotating registers or due to the indexing of indirect register
6032 sets. */
6033int
6034ia64_optimize_expr (l, op, r)
6035 expressionS *l;
6036 operatorT op;
6037 expressionS *r;
6038{
6039 unsigned num_regs;
6040
6041 if (op == O_index)
6042 {
6043 if (l->X_op == O_register && r->X_op == O_constant)
6044 {
6045 num_regs = (l->X_add_number >> 16);
6046 if ((unsigned) r->X_add_number >= num_regs)
6047 {
6048 if (!num_regs)
6049 as_bad ("No current frame");
6050 else
6051 as_bad ("Index out of range 0..%u", num_regs - 1);
6052 r->X_add_number = 0;
6053 }
6054 l->X_add_number = (l->X_add_number & 0xffff) + r->X_add_number;
6055 return 1;
6056 }
6057 else if (l->X_op == O_register && r->X_op == O_register)
6058 {
6059 if (l->X_add_number < IND_CPUID || l->X_add_number > IND_RR
6060 || l->X_add_number == IND_MEM)
6061 {
6062 as_bad ("Indirect register set name expected");
6063 l->X_add_number = IND_CPUID;
6064 }
6065 l->X_op = O_index;
6066 l->X_op_symbol = md.regsym[l->X_add_number];
6067 l->X_add_number = r->X_add_number;
6068 return 1;
6069 }
6070 }
6071 return 0;
6072}
6073
6074int
6075ia64_parse_name (name, e)
6076 char *name;
6077 expressionS *e;
6078{
6079 struct const_desc *cdesc;
6080 struct dynreg *dr = 0;
6081 unsigned int regnum;
6082 struct symbol *sym;
6083 char *end;
6084
6085 /* first see if NAME is a known register name: */
6086 sym = hash_find (md.reg_hash, name);
6087 if (sym)
6088 {
6089 e->X_op = O_register;
6090 e->X_add_number = S_GET_VALUE (sym);
6091 return 1;
6092 }
6093
6094 cdesc = hash_find (md.const_hash, name);
6095 if (cdesc)
6096 {
6097 e->X_op = O_constant;
6098 e->X_add_number = cdesc->value;
6099 return 1;
6100 }
6101
6102 /* check for inN, locN, or outN: */
6103 switch (name[0])
6104 {
6105 case 'i':
6106 if (name[1] == 'n' && isdigit (name[2]))
6107 {
6108 dr = &md.in;
6109 name += 2;
6110 }
6111 break;
6112
6113 case 'l':
6114 if (name[1] == 'o' && name[2] == 'c' && isdigit (name[3]))
6115 {
6116 dr = &md.loc;
6117 name += 3;
6118 }
6119 break;
6120
6121 case 'o':
6122 if (name[1] == 'u' && name[2] == 't' && isdigit (name[3]))
6123 {
6124 dr = &md.out;
6125 name += 3;
6126 }
6127 break;
6128
6129 default:
6130 break;
6131 }
6132
6133 if (dr)
6134 {
6135 /* the name is inN, locN, or outN; parse the register number: */
6136 regnum = strtoul (name, &end, 10);
6137 if (end > name && *end == '\0')
6138 {
6139 if ((unsigned) regnum >= dr->num_regs)
6140 {
6141 if (!dr->num_regs)
6142 as_bad ("No current frame");
6143 else
6144 as_bad ("Register number out of range 0..%u", dr->num_regs-1);
6145 regnum = 0;
6146 }
6147 e->X_op = O_register;
6148 e->X_add_number = dr->base + regnum;
6149 return 1;
6150 }
6151 }
6152
6153 if ((dr = hash_find (md.dynreg_hash, name)))
6154 {
6155 /* We've got ourselves the name of a rotating register set.
6156 Store the base register number in the low 16 bits of
6157 X_add_number and the size of the register set in the top 16
6158 bits. */
6159 e->X_op = O_register;
6160 e->X_add_number = dr->base | (dr->num_regs << 16);
6161 return 1;
6162 }
6163 return 0;
6164}
6165
6166/* Remove the '#' suffix that indicates a symbol as opposed to a register. */
6167
6168char *
6169ia64_canonicalize_symbol_name (name)
6170 char *name;
6171{
6172 size_t len = strlen(name);
6173 if (len > 1 && name[len-1] == '#')
6174 name[len-1] = '\0';
6175 return name;
6176}
6177
6178static int
6179is_conditional_branch (idesc)
6180 struct ia64_opcode *idesc;
6181{
6182 return (strncmp (idesc->name, "br", 2) == 0
6183 && (strcmp (idesc->name, "br") == 0
6184 || strncmp (idesc->name, "br.cond", 7) == 0
6185 || strncmp (idesc->name, "br.call", 7) == 0
6186 || strncmp (idesc->name, "br.ret", 6) == 0
6187 || strcmp (idesc->name, "brl") == 0
6188 || strncmp (idesc->name, "brl.cond", 7) == 0
6189 || strncmp (idesc->name, "brl.call", 7) == 0
6190 || strncmp (idesc->name, "brl.ret", 6) == 0));
6191}
6192
6193/* Return whether the given opcode is a taken branch. If there's any doubt,
6194 returns zero */
6195static int
6196is_taken_branch (idesc)
6197 struct ia64_opcode *idesc;
6198{
6199 return ((is_conditional_branch (idesc) && CURR_SLOT.qp_regno == 0)
6200 || strncmp (idesc->name, "br.ia", 5) == 0);
6201}
6202
6203/* Return whether the given opcode is an interruption or rfi. If there's any
6204 doubt, returns zero */
6205static int
6206is_interruption_or_rfi (idesc)
6207 struct ia64_opcode *idesc;
6208{
6209 if (strcmp (idesc->name, "rfi") == 0)
6210 return 1;
6211 return 0;
6212}
6213
6214/* Returns the index of the given dependency in the opcode's list of chks, or
6215 -1 if there is no dependency. */
6216static int
6217depends_on (depind, idesc)
6218 int depind;
6219 struct ia64_opcode *idesc;
6220{
6221 int i;
6222 const struct ia64_opcode_dependency *dep = idesc->dependencies;
6223 for (i = 0;i < dep->nchks; i++)
6224 {
6225 if (depind == DEP(dep->chks[i]))
6226 return i;
6227 }
6228 return -1;
6229}
6230
6231/* Determine a set of specific resources used for a particular resource
6232 class. Returns the number of specific resources identified For those
6233 cases which are not determinable statically, the resource returned is
6234 marked nonspecific.
6235
6236 Meanings of value in 'NOTE':
6237 1) only read/write when the register number is explicitly encoded in the
6238 insn.
6239 2) only read CFM when accessing a rotating GR, FR, or PR. mov pr only
6240 accesses CFM when qualifying predicate is in the rotating region.
6241 3) general register value is used to specify an indirect register; not
6242 determinable statically.
6243 4) only read the given resource when bits 7:0 of the indirect index
6244 register value does not match the register number of the resource; not
6245 determinable statically.
6246 5) all rules are implementation specific.
6247 6) only when both the index specified by the reader and the index specified
6248 by the writer have the same value in bits 63:61; not determinable
6249 statically.
6250 7) only access the specified resource when the corresponding mask bit is
6251 set
6252 8) PSR.dfh is only read when these insns reference FR32-127. PSR.dfl is
6253 only read when these insns reference FR2-31
6254 9) PSR.mfl is only written when these insns write FR2-31. PSR.mfh is only
6255 written when these insns write FR32-127
6256 10) The PSR.bn bit is only accessed when one of GR16-31 is specified in the
6257 instruction
6258 11) The target predicates are written independently of PR[qp], but source
6259 registers are only read if PR[qp] is true. Since the state of PR[qp]
6260 cannot statically be determined, all source registers are marked used.
6261 12) This insn only reads the specified predicate register when that
6262 register is the PR[qp].
6263 13) This reference to ld-c only applies to teh GR whose value is loaded
6264 with data returned from memory, not the post-incremented address register.
6265 14) The RSE resource includes the implementation-specific RSE internal
6266 state resources. At least one (and possibly more) of these resources are
6267 read by each instruction listed in IC:rse-readers. At least one (and
6268 possibly more) of these resources are written by each insn listed in
6269 IC:rse-writers.
6270 15+16) Represents reserved instructions, which the assembler does not
6271 generate.
6272
6273 Memory resources (i.e. locations in memory) are *not* marked or tracked by
6274 this code; there are no dependency violations based on memory access.
6275
6276*/
6277
6278#define MAX_SPECS 256
6279#define DV_CHK 1
6280#define DV_REG 0
6281
6282static int
6283specify_resource (dep, idesc, type, specs, note, path)
6284 const struct ia64_dependency *dep;
6285 struct ia64_opcode *idesc;
6286 int type; /* is this a DV chk or a DV reg? */
6287 struct rsrc specs[MAX_SPECS]; /* returned specific resources */
6288 int note; /* resource note for this insn's usage */
6289 int path; /* which execution path to examine */
6290{
6291 int count = 0;
6292 int i;
6293 int rsrc_write = 0;
6294 struct rsrc tmpl;
6295
6296 if (dep->mode == IA64_DV_WAW
6297 || (dep->mode == IA64_DV_RAW && type == DV_REG)
6298 || (dep->mode == IA64_DV_WAR && type == DV_CHK))
6299 rsrc_write = 1;
6300
6301 /* template for any resources we identify */
6302 tmpl.dependency = dep;
6303 tmpl.note = note;
6304 tmpl.insn_srlz = tmpl.data_srlz = 0;
6305 tmpl.qp_regno = CURR_SLOT.qp_regno;
6306 tmpl.link_to_qp_branch = 1;
6307 tmpl.mem_offset.hint = 0;
6308 tmpl.specific = 1;
6309 tmpl.index = 0;
6310
6311#define UNHANDLED \
6312as_warn (_("Unhandled dependency %s for %s (%s), note %d"), \
6313dep->name, idesc->name, (rsrc_write?"write":"read"), note)
6314#define KNOWN(REG) (gr_values[REG].known && gr_values[REG].path >= path)
6315
6316 /* we don't need to track these */
6317 if (dep->semantics == IA64_DVS_NONE)
6318 return 0;
6319
6320 switch (dep->specifier)
6321 {
6322 case IA64_RS_AR_K:
6323 if (note == 1)
6324 {
6325 if (idesc->operands[!rsrc_write] == IA64_OPND_AR3)
6326 {
6327 int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_AR;
6328 if (regno >= 0 && regno <= 7)
6329 {
6330 specs[count] = tmpl;
6331 specs[count++].index = regno;
6332 }
6333 }
6334 }
6335 else if (note == 0)
6336 {
6337 for(i=0;i < 8;i++)
6338 {
6339 specs[count] = tmpl;
6340 specs[count++].index = i;
6341 }
6342 }
6343 else
6344 {
6345 UNHANDLED;
6346 }
6347 break;
6348
6349 case IA64_RS_AR_UNAT:
6350 /* This is a mov =AR or mov AR= instruction. */
6351 if (idesc->operands[!rsrc_write] == IA64_OPND_AR3)
6352 {
6353 int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_AR;
6354 if (regno == AR_UNAT)
6355 {
6356 specs[count++] = tmpl;
6357 }
6358 }
6359 else
6360 {
6361 /* This is a spill/fill, or other instruction that modifies the
6362 unat register. */
6363
6364 /* Unless we can determine the specific bits used, mark the whole
6365 thing; bits 8:3 of the memory address indicate the bit used in
6366 UNAT. The .mem.offset hint may be used to eliminate a small
6367 subset of conflicts. */
6368 specs[count] = tmpl;
6369 if (md.mem_offset.hint)
6370 {
6371 if (md.debug_dv)
6372 fprintf (stderr, " Using hint for spill/fill\n");
6373 /* the index isn't actually used, just set it to something
6374 approximating the bit index */
6375 specs[count].index = (md.mem_offset.offset >> 3) & 0x3F;
6376 specs[count].mem_offset.hint = 1;
6377 specs[count].mem_offset.offset = md.mem_offset.offset;
6378 specs[count++].mem_offset.base = md.mem_offset.base;
6379 }
6380 else
6381 {
6382 specs[count++].specific = 0;
6383 }
6384 }
6385 break;
6386
6387 case IA64_RS_AR:
6388 if (note == 1)
6389 {
6390 if (idesc->operands[!rsrc_write] == IA64_OPND_AR3)
6391 {
6392 int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_AR;
6393 if ((regno >= 8 && regno <= 15)
6394 || (regno >= 20 && regno <= 23)
6395 || (regno >= 31 && regno <= 39)
6396 || (regno >= 41 && regno <= 47)
6397 || (regno >= 67 && regno <= 111))
6398 {
6399 specs[count] = tmpl;
6400 specs[count++].index = regno;
6401 }
6402 }
6403 }
6404 else
6405 {
6406 UNHANDLED;
6407 }
6408 break;
6409
6410 case IA64_RS_ARb:
6411 if (note == 1)
6412 {
6413 if (idesc->operands[!rsrc_write] == IA64_OPND_AR3)
6414 {
6415 int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_AR;
6416 if ((regno >= 48 && regno <= 63)
6417 || (regno >= 112 && regno <= 127))
6418 {
6419 specs[count] = tmpl;
6420 specs[count++].index = regno;
6421 }
6422 }
6423 }
6424 else if (note == 0)
6425 {
6426 for (i=48;i < 64;i++)
6427 {
6428 specs[count] = tmpl;
6429 specs[count++].index = i;
6430 }
6431 for (i=112;i < 128;i++)
6432 {
6433 specs[count] = tmpl;
6434 specs[count++].index = i;
6435 }
6436 }
6437 else
6438 {
6439 UNHANDLED;
6440 }
6441 break;
6442
6443 case IA64_RS_BR:
6444 if (note != 1)
6445 {
6446 UNHANDLED;
6447 }
6448 else
6449 {
6450 if (rsrc_write)
6451 {
6452 for (i=0;i < idesc->num_outputs;i++)
6453 if (idesc->operands[i] == IA64_OPND_B1
6454 || idesc->operands[i] == IA64_OPND_B2)
6455 {
6456 specs[count] = tmpl;
6457 specs[count++].index =
6458 CURR_SLOT.opnd[i].X_add_number - REG_BR;
6459 }
6460 }
6461 else
6462 {
6463 for (i = idesc->num_outputs;i < NELEMS(idesc->operands);i++)
6464 if (idesc->operands[i] == IA64_OPND_B1
6465 || idesc->operands[i] == IA64_OPND_B2)
6466 {
6467 specs[count] = tmpl;
6468 specs[count++].index =
6469 CURR_SLOT.opnd[i].X_add_number - REG_BR;
6470 }
6471 }
6472 }
6473 break;
6474
6475 case IA64_RS_CPUID: /* four or more registers */
6476 if (note == 3)
6477 {
6478 if (idesc->operands[!rsrc_write] == IA64_OPND_CPUID_R3)
6479 {
6480 int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_GR;
6481 if (regno >= 0 && regno < NELEMS(gr_values)
6482 && KNOWN(regno))
6483 {
6484 specs[count] = tmpl;
6485 specs[count++].index = gr_values[regno].value & 0xFF;
6486 }
6487 else
6488 {
6489 specs[count] = tmpl;
6490 specs[count++].specific = 0;
6491 }
6492 }
6493 }
6494 else
6495 {
6496 UNHANDLED;
6497 }
6498 break;
6499
6500 case IA64_RS_DBR: /* four or more registers */
6501 if (note == 3)
6502 {
6503 if (idesc->operands[!rsrc_write] == IA64_OPND_DBR_R3)
6504 {
6505 int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_GR;
6506 if (regno >= 0 && regno < NELEMS(gr_values)
6507 && KNOWN(regno))
6508 {
6509 specs[count] = tmpl;
6510 specs[count++].index = gr_values[regno].value & 0xFF;
6511 }
6512 else
6513 {
6514 specs[count] = tmpl;
6515 specs[count++].specific = 0;
6516 }
6517 }
6518 }
6519 else if (note == 0 && !rsrc_write)
6520 {
6521 specs[count] = tmpl;
6522 specs[count++].specific = 0;
6523 }
6524 else
6525 {
6526 UNHANDLED;
6527 }
6528 break;
6529
6530 case IA64_RS_IBR: /* four or more registers */
6531 if (note == 3)
6532 {
6533 if (idesc->operands[!rsrc_write] == IA64_OPND_IBR_R3)
6534 {
6535 int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_GR;
6536 if (regno >= 0 && regno < NELEMS(gr_values)
6537 && KNOWN(regno))
6538 {
6539 specs[count] = tmpl;
6540 specs[count++].index = gr_values[regno].value & 0xFF;
6541 }
6542 else
6543 {
6544 specs[count] = tmpl;
6545 specs[count++].specific = 0;
6546 }
6547 }
6548 }
6549 else
6550 {
6551 UNHANDLED;
6552 }
6553 break;
6554
6555 case IA64_RS_MSR:
6556 if (note == 5)
6557 {
6558 /* These are implementation specific. Force all references to
6559 conflict with all other references. */
6560 specs[count] = tmpl;
6561 specs[count++].specific = 0;
6562 }
6563 else
6564 {
6565 UNHANDLED;
6566 }
6567 break;
6568
6569 case IA64_RS_PKR: /* 16 or more registers */
6570 if (note == 3 || note == 4)
6571 {
6572 if (idesc->operands[!rsrc_write] == IA64_OPND_PKR_R3)
6573 {
6574 int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_GR;
6575 if (regno >= 0 && regno < NELEMS(gr_values)
6576 && KNOWN(regno))
6577 {
6578 if (note == 3)
6579 {
6580 specs[count] = tmpl;
6581 specs[count++].index = gr_values[regno].value & 0xFF;
6582 }
6583 else for (i=0;i < NELEMS(gr_values);i++)
6584 {
6585 /* uses all registers *except* the one in R3 */
6586 if (i != (gr_values[regno].value & 0xFF))
6587 {
6588 specs[count] = tmpl;
6589 specs[count++].index = i;
6590 }
6591 }
6592 }
6593 else
6594 {
6595 specs[count] = tmpl;
6596 specs[count++].specific = 0;
6597 }
6598 }
6599 }
6600 else if (note == 0)
6601 {
6602 /* probe et al. */
6603 specs[count] = tmpl;
6604 specs[count++].specific = 0;
6605 }
6606 break;
6607
6608 case IA64_RS_PMC: /* four or more registers */
6609 if (note == 3)
6610 {
6611 if (idesc->operands[!rsrc_write] == IA64_OPND_PMC_R3
6612 || (!rsrc_write && idesc->operands[1] == IA64_OPND_PMD_R3))
6613
6614 {
6615 int index = ((idesc->operands[1] == IA64_OPND_R3 && !rsrc_write)
6616 ? 1 : !rsrc_write);
6617 int regno = CURR_SLOT.opnd[index].X_add_number - REG_GR;
6618 if (regno >= 0 && regno < NELEMS(gr_values)
6619 && KNOWN(regno))
6620 {
6621 specs[count] = tmpl;
6622 specs[count++].index = gr_values[regno].value & 0xFF;
6623 }
6624 else
6625 {
6626 specs[count] = tmpl;
6627 specs[count++].specific = 0;
6628 }
6629 }
6630 }
6631 else
6632 {
6633 UNHANDLED;
6634 }
6635 break;
6636
6637 case IA64_RS_PMD: /* four or more registers */
6638 if (note == 3)
6639 {
6640 if (idesc->operands[!rsrc_write] == IA64_OPND_PMD_R3)
6641 {
6642 int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_GR;
6643 if (regno >= 0 && regno < NELEMS(gr_values)
6644 && KNOWN(regno))
6645 {
6646 specs[count] = tmpl;
6647 specs[count++].index = gr_values[regno].value & 0xFF;
6648 }
6649 else
6650 {
6651 specs[count] = tmpl;
6652 specs[count++].specific = 0;
6653 }
6654 }
6655 }
6656 else
6657 {
6658 UNHANDLED;
6659 }
6660 break;
6661
6662 case IA64_RS_RR: /* eight registers */
6663 if (note == 6)
6664 {
6665 if (idesc->operands[!rsrc_write] == IA64_OPND_RR_R3)
6666 {
6667 int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_GR;
6668 if (regno >= 0 && regno < NELEMS(gr_values)
6669 && KNOWN(regno))
6670 {
6671 specs[count] = tmpl;
6672 specs[count++].index = (gr_values[regno].value >> 61) & 0x7;
6673 }
6674 else
6675 {
6676 specs[count] = tmpl;
6677 specs[count++].specific = 0;
6678 }
6679 }
6680 }
6681 else if (note == 0 && !rsrc_write)
6682 {
6683 specs[count] = tmpl;
6684 specs[count++].specific = 0;
6685 }
6686 else
6687 {
6688 UNHANDLED;
6689 }
6690 break;
6691
6692 case IA64_RS_CR_IRR:
6693 if (note == 0)
6694 {
6695 /* handle mov-from-CR-IVR; it's a read that writes CR[IRR] */
6696 int regno = CURR_SLOT.opnd[1].X_add_number - REG_CR;
6697 if (rsrc_write
6698 && idesc->operands[1] == IA64_OPND_CR3
6699 && regno == CR_IVR)
6700 {
6701 for(i=0;i < 4;i++)
6702 {
6703 specs[count] = tmpl;
6704 specs[count++].index = CR_IRR0 + i;
6705 }
6706 }
6707 }
6708 else if (note == 1)
6709 {
6710 int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_CR;
6711 if (idesc->operands[!rsrc_write] == IA64_OPND_CR3
6712 && regno >= CR_IRR0
6713 && regno <= CR_IRR3)
6714 {
6715 specs[count] = tmpl;
6716 specs[count++].index = regno;
6717 }
6718 }
6719 else
6720 {
6721 UNHANDLED;
6722 }
6723 break;
6724
6725 case IA64_RS_CR_LRR:
6726 if (note != 1)
6727 {
6728 UNHANDLED;
6729 }
6730 else
6731 {
6732 int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_CR;
6733 if (idesc->operands[!rsrc_write] == IA64_OPND_CR3
6734 && (regno == CR_LRR0 || regno == CR_LRR1))
6735 {
6736 specs[count] = tmpl;
6737 specs[count++].index = regno;
6738 }
6739 }
6740 break;
6741
6742 case IA64_RS_CR:
6743 if (note == 1)
6744 {
6745 if (idesc->operands[!rsrc_write] == IA64_OPND_CR3)
6746 {
6747 specs[count] = tmpl;
6748 specs[count++].index =
6749 CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_CR;
6750 }
6751 }
6752 else
6753 {
6754 UNHANDLED;
6755 }
6756 break;
6757
6758 case IA64_RS_FR:
6759 case IA64_RS_FRb:
6760 if (note != 1)
6761 {
6762 UNHANDLED;
6763 }
6764 else if (rsrc_write)
6765 {
6766 if (dep->specifier == IA64_RS_FRb
6767 && idesc->operands[0] == IA64_OPND_F1)
6768 {
6769 specs[count] = tmpl;
6770 specs[count++].index = CURR_SLOT.opnd[0].X_add_number - REG_FR;
6771 }
6772 }
6773 else
6774 {
6775 for (i=idesc->num_outputs;i < NELEMS(idesc->operands);i++)
6776 {
6777 if (idesc->operands[i] == IA64_OPND_F2
6778 || idesc->operands[i] == IA64_OPND_F3
6779 || idesc->operands[i] == IA64_OPND_F4)
6780 {
6781 specs[count] = tmpl;
6782 specs[count++].index =
6783 CURR_SLOT.opnd[i].X_add_number - REG_FR;
6784 }
6785 }
6786 }
6787 break;
6788
6789 case IA64_RS_GR:
6790 if (note == 13)
6791 {
6792 /* This reference applies only to the GR whose value is loaded with
6793 data returned from memory */
6794 specs[count] = tmpl;
6795 specs[count++].index = CURR_SLOT.opnd[0].X_add_number - REG_GR;
6796 }
6797 else if (note == 1)
6798 {
6799 if (rsrc_write)
6800 {
6801 for (i=0;i < idesc->num_outputs;i++)
6802 {
6803 if (idesc->operands[i] == IA64_OPND_R1
6804 || idesc->operands[i] == IA64_OPND_R2
6805 || idesc->operands[i] == IA64_OPND_R3)
6806 {
6807 specs[count] = tmpl;
6808 specs[count++].index =
6809 CURR_SLOT.opnd[i].X_add_number - REG_GR;
6810 }
6811 }
6812 }
6813 else
6814 {
6815 /* Look for anything that reads a GR */
6816 for (i=0;i < NELEMS(idesc->operands);i++)
6817 {
6818 if (idesc->operands[i] == IA64_OPND_MR3
6819 || idesc->operands[i] == IA64_OPND_CPUID_R3
6820 || idesc->operands[i] == IA64_OPND_DBR_R3
6821 || idesc->operands[i] == IA64_OPND_IBR_R3
6822 || idesc->operands[i] == IA64_OPND_MSR_R3
6823 || idesc->operands[i] == IA64_OPND_PKR_R3
6824 || idesc->operands[i] == IA64_OPND_PMC_R3
6825 || idesc->operands[i] == IA64_OPND_PMD_R3
6826 || idesc->operands[i] == IA64_OPND_RR_R3
6827 || ((i >= idesc->num_outputs)
6828 && (idesc->operands[i] == IA64_OPND_R1
6829 || idesc->operands[i] == IA64_OPND_R2
6830 || idesc->operands[i] == IA64_OPND_R3)))
6831 {
6832 specs[count] = tmpl;
6833 specs[count++].index =
6834 CURR_SLOT.opnd[i].X_add_number - REG_GR;
6835 }
6836 }
6837 }
6838 }
6839 else
6840 {
6841 UNHANDLED;
6842 }
6843 break;
6844
6845 case IA64_RS_PR:
6846 if (note == 0)
6847 {
6848 if (idesc->operands[0] == IA64_OPND_PR_ROT)
6849 {
6850 for (i=16;i < 63;i++)
6851 {
6852 specs[count] = tmpl;
6853 specs[count++].index = i;
6854 }
6855 }
6856 else
6857 {
6858 for (i=1;i < 63;i++)
6859 {
6860 specs[count] = tmpl;
6861 specs[count++].index = i;
6862 }
6863 }
6864 }
6865 else if (note == 7)
6866 {
6867 valueT mask = 0;
6868 /* mark only those registers indicated by the mask */
6869 if (rsrc_write
6870 && idesc->operands[0] == IA64_OPND_PR)
6871 {
6872 mask = CURR_SLOT.opnd[2].X_add_number;
6873 if (mask & ((valueT)1<<16))
6874 mask |= ~(valueT)0xffff;
6875 for (i=1;i < 63;i++)
6876 {
6877 if (mask & ((valueT)1<<i))
6878 {
6879 specs[count] = tmpl;
6880 specs[count++].index = i;
6881 }
6882 }
6883 }
6884 else if (rsrc_write
6885 && idesc->operands[0] == IA64_OPND_PR_ROT)
6886 {
6887 for (i=16;i < 63;i++)
6888 {
6889 specs[count] = tmpl;
6890 specs[count++].index = i;
6891 }
6892 }
6893 else
6894 {
6895 UNHANDLED;
6896 }
6897 }
6898 else if (note == 11) /* note 11 implies note 1 as well */
6899 {
6900 if (rsrc_write)
6901 {
6902 for (i=0;i < idesc->num_outputs;i++)
6903 {
6904 if (idesc->operands[i] == IA64_OPND_P1
6905 || idesc->operands[i] == IA64_OPND_P2)
6906 {
6907 int regno = CURR_SLOT.opnd[i].X_add_number - REG_P;
6908 if (regno != 0)
6909 {
6910 specs[count] = tmpl;
6911 specs[count++].index = regno;
6912 }
6913 }
6914 }
6915 }
6916 else
6917 {
6918 UNHANDLED;
6919 }
6920 }
6921 else if (note == 12)
6922 {
6923 if (CURR_SLOT.qp_regno != 0)
6924 {
6925 specs[count] = tmpl;
6926 specs[count++].index = CURR_SLOT.qp_regno;
6927 }
6928 }
6929 else if (note == 1)
6930 {
6931 if (rsrc_write)
6932 {
6933 int p1 = CURR_SLOT.opnd[0].X_add_number - REG_P;
6934 int p2 = CURR_SLOT.opnd[1].X_add_number - REG_P;
6935 if ((idesc->operands[0] == IA64_OPND_P1
6936 || idesc->operands[0] == IA64_OPND_P2)
6937 && p1 != 0 && p1 != 63)
6938 {
6939 specs[count] = tmpl;
6940 specs[count++].index = p1;
6941 }
6942 if ((idesc->operands[1] == IA64_OPND_P1
6943 || idesc->operands[1] == IA64_OPND_P2)
6944 && p2 != 0 && p2 != 63)
6945 {
6946 specs[count] = tmpl;
6947 specs[count++].index = p2;
6948 }
6949 }
6950 else
6951 {
6952 if (CURR_SLOT.qp_regno != 0)
6953 {
6954 specs[count] = tmpl;
6955 specs[count++].index = CURR_SLOT.qp_regno;
6956 }
6957 if (idesc->operands[1] == IA64_OPND_PR)
6958 {
6959 for (i=1;i < 63;i++)
6960 {
6961 specs[count] = tmpl;
6962 specs[count++].index = i;
6963 }
6964 }
6965 }
6966 }
6967 else
6968 {
6969 UNHANDLED;
6970 }
6971 break;
6972
6973 case IA64_RS_PSR:
6974 /* Verify that the instruction is using the PSR bit indicated in
6975 dep->regindex */
6976 if (note == 0)
6977 {
6978 if (idesc->operands[!rsrc_write] == IA64_OPND_PSR_UM)
6979 {
6980 if (dep->regindex < 6)
6981 {
6982 specs[count++] = tmpl;
6983 }
6984 }
6985 else if (idesc->operands[!rsrc_write] == IA64_OPND_PSR)
6986 {
6987 if (dep->regindex < 32
6988 || dep->regindex == 35
6989 || dep->regindex == 36
6990 || (!rsrc_write && dep->regindex == PSR_CPL))
6991 {
6992 specs[count++] = tmpl;
6993 }
6994 }
6995 else if (idesc->operands[!rsrc_write] == IA64_OPND_PSR_L)
6996 {
6997 if (dep->regindex < 32
6998 || dep->regindex == 35
6999 || dep->regindex == 36
7000 || (rsrc_write && dep->regindex == PSR_CPL))
7001 {
7002 specs[count++] = tmpl;
7003 }
7004 }
7005 else
7006 {
7007 /* Several PSR bits have very specific dependencies. */
7008 switch (dep->regindex)
7009 {
7010 default:
7011 specs[count++] = tmpl;
7012 break;
7013 case PSR_IC:
7014 if (rsrc_write)
7015 {
7016 specs[count++] = tmpl;
7017 }
7018 else
7019 {
7020 /* Only certain CR accesses use PSR.ic */
7021 if (idesc->operands[0] == IA64_OPND_CR3
7022 || idesc->operands[1] == IA64_OPND_CR3)
7023 {
7024 int index =
7025 ((idesc->operands[0] == IA64_OPND_CR3)
7026 ? 0 : 1);
7027 int regno =
7028 CURR_SLOT.opnd[index].X_add_number - REG_CR;
7029
7030 switch (regno)
7031 {
7032 default:
7033 break;
7034 case CR_ITIR:
7035 case CR_IFS:
7036 case CR_IIM:
7037 case CR_IIP:
7038 case CR_IPSR:
7039 case CR_ISR:
7040 case CR_IFA:
7041 case CR_IHA:
7042 case CR_IIPA:
7043 specs[count++] = tmpl;
7044 break;
7045 }
7046 }
7047 }
7048 break;
7049 case PSR_CPL:
7050 if (rsrc_write)
7051 {
7052 specs[count++] = tmpl;
7053 }
7054 else
7055 {
7056 /* Only some AR accesses use cpl */
7057 if (idesc->operands[0] == IA64_OPND_AR3
7058 || idesc->operands[1] == IA64_OPND_AR3)
7059 {
7060 int index =
7061 ((idesc->operands[0] == IA64_OPND_AR3)
7062 ? 0 : 1);
7063 int regno =
7064 CURR_SLOT.opnd[index].X_add_number - REG_AR;
7065
7066 if (regno == AR_ITC
7067 || (index == 0
7068 && (regno == AR_ITC
7069 || regno == AR_RSC
7070 || (regno >= AR_K0
7071 && regno <= AR_K7))))
7072 {
7073 specs[count++] = tmpl;
7074 }
7075 }
7076 else
7077 {
7078 specs[count++] = tmpl;
7079 }
7080 break;
7081 }
7082 }
7083 }
7084 }
7085 else if (note == 7)
7086 {
7087 valueT mask = 0;
7088 if (idesc->operands[0] == IA64_OPND_IMMU24)
7089 {
7090 mask = CURR_SLOT.opnd[0].X_add_number;
7091 }
7092 else
7093 {
7094 UNHANDLED;
7095 }
7096 if (mask & ((valueT)1<<dep->regindex))
7097 {
7098 specs[count++] = tmpl;
7099 }
7100 }
7101 else if (note == 8)
7102 {
7103 int min = dep->regindex == PSR_DFL ? 2 : 32;
7104 int max = dep->regindex == PSR_DFL ? 31 : 127;
7105 /* dfh is read on FR32-127; dfl is read on FR2-31 */
7106 for (i=0;i < NELEMS(idesc->operands);i++)
7107 {
7108 if (idesc->operands[i] == IA64_OPND_F1
7109 || idesc->operands[i] == IA64_OPND_F2
7110 || idesc->operands[i] == IA64_OPND_F3
7111 || idesc->operands[i] == IA64_OPND_F4)
7112 {
7113 int reg = CURR_SLOT.opnd[i].X_add_number - REG_FR;
7114 if (reg >= min && reg <= max)
7115 {
7116 specs[count++] = tmpl;
7117 }
7118 }
7119 }
7120 }
7121 else if (note == 9)
7122 {
7123 int min = dep->regindex == PSR_MFL ? 2 : 32;
7124 int max = dep->regindex == PSR_MFL ? 31 : 127;
7125 /* mfh is read on writes to FR32-127; mfl is read on writes to
7126 FR2-31 */
7127 for (i=0;i < idesc->num_outputs;i++)
7128 {
7129 if (idesc->operands[i] == IA64_OPND_F1)
7130 {
7131 int reg = CURR_SLOT.opnd[i].X_add_number - REG_FR;
7132 if (reg >= min && reg <= max)
7133 {
7134 specs[count++] = tmpl;
7135 }
7136 }
7137 }
7138 }
7139 else if (note == 10)
7140 {
7141 for (i=0;i < NELEMS(idesc->operands);i++)
7142 {
7143 if (idesc->operands[i] == IA64_OPND_R1
7144 || idesc->operands[i] == IA64_OPND_R2
7145 || idesc->operands[i] == IA64_OPND_R3)
7146 {
7147 int regno = CURR_SLOT.opnd[i].X_add_number - REG_GR;
7148 if (regno >= 16 && regno <= 31)
7149 {
7150 specs[count++] = tmpl;
7151 }
7152 }
7153 }
7154 }
7155 else
7156 {
7157 UNHANDLED;
7158 }
7159 break;
7160
7161 case IA64_RS_AR_FPSR:
7162 if (idesc->operands[!rsrc_write] == IA64_OPND_AR3)
7163 {
7164 int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_AR;
7165 if (regno == AR_FPSR)
7166 {
7167 specs[count++] = tmpl;
7168 }
7169 }
7170 else
7171 {
7172 specs[count++] = tmpl;
7173 }
7174 break;
7175
7176 case IA64_RS_ARX:
7177 /* Handle all AR[REG] resources */
7178 if (note == 0 || note == 1)
7179 {
7180 int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_AR;
7181 if (idesc->operands[!rsrc_write] == IA64_OPND_AR3
7182 && regno == dep->regindex)
7183 {
7184 specs[count++] = tmpl;
7185 }
7186 /* other AR[REG] resources may be affected by AR accesses */
7187 else if (idesc->operands[0] == IA64_OPND_AR3)
7188 {
7189 /* AR[] writes */
7190 regno = CURR_SLOT.opnd[0].X_add_number - REG_AR;
7191 switch (dep->regindex)
7192 {
7193 default:
7194 break;
7195 case AR_BSP:
7196 case AR_RNAT:
7197 if (regno == AR_BSPSTORE)
7198 {
7199 specs[count++] = tmpl;
7200 }
7201 case AR_RSC:
7202 if (!rsrc_write &&
7203 (regno == AR_BSPSTORE
7204 || regno == AR_RNAT))
7205 {
7206 specs[count++] = tmpl;
7207 }
7208 break;
7209 }
7210 }
7211 else if (idesc->operands[1] == IA64_OPND_AR3)
7212 {
7213 /* AR[] reads */
7214 regno = CURR_SLOT.opnd[1].X_add_number - REG_AR;
7215 switch (dep->regindex)
7216 {
7217 default:
7218 break;
7219 case AR_RSC:
7220 if (regno == AR_BSPSTORE || regno == AR_RNAT)
7221 {
7222 specs[count++] = tmpl;
7223 }
7224 break;
7225 }
7226 }
7227 else
7228 {
7229 specs[count++] = tmpl;
7230 }
7231 }
7232 else
7233 {
7234 UNHANDLED;
7235 }
7236 break;
7237
7238 case IA64_RS_CRX:
7239 /* Handle all CR[REG] resources */
7240 if (note == 0 || note == 1)
7241 {
7242 if (idesc->operands[!rsrc_write] == IA64_OPND_CR3)
7243 {
7244 int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_CR;
7245 if (regno == dep->regindex)
7246 {
7247 specs[count++] = tmpl;
7248 }
7249 else if (!rsrc_write)
7250 {
7251 /* Reads from CR[IVR] affect other resources. */
7252 if (regno == CR_IVR)
7253 {
7254 if ((dep->regindex >= CR_IRR0
7255 && dep->regindex <= CR_IRR3)
7256 || dep->regindex == CR_TPR)
7257 {
7258 specs[count++] = tmpl;
7259 }
7260 }
7261 }
7262 }
7263 else
7264 {
7265 specs[count++] = tmpl;
7266 }
7267 }
7268 else
7269 {
7270 UNHANDLED;
7271 }
7272 break;
7273
7274 case IA64_RS_INSERVICE:
7275 /* look for write of EOI (67) or read of IVR (65) */
7276 if ((idesc->operands[0] == IA64_OPND_CR3
7277 && CURR_SLOT.opnd[0].X_add_number - REG_CR == CR_EOI)
7278 || (idesc->operands[1] == IA64_OPND_CR3
7279 && CURR_SLOT.opnd[1].X_add_number - REG_CR == CR_IVR))
7280 {
7281 specs[count++] = tmpl;
7282 }
7283 break;
7284
7285 case IA64_RS_GR0:
7286 if (note == 1)
7287 {
7288 specs[count++] = tmpl;
7289 }
7290 else
7291 {
7292 UNHANDLED;
7293 }
7294 break;
7295
7296 case IA64_RS_CFM:
7297 if (note != 2)
7298 {
7299 specs[count++] = tmpl;
7300 }
7301 else
7302 {
7303 /* Check if any of the registers accessed are in the rotating region.
7304 mov to/from pr accesses CFM only when qp_regno is in the rotating
7305 region */
7306 for (i=0;i < NELEMS(idesc->operands);i++)
7307 {
7308 if (idesc->operands[i] == IA64_OPND_R1
7309 || idesc->operands[i] == IA64_OPND_R2
7310 || idesc->operands[i] == IA64_OPND_R3)
7311 {
7312 int num = CURR_SLOT.opnd[i].X_add_number - REG_GR;
7313 /* Assumes that md.rot.num_regs is always valid */
7314 if (md.rot.num_regs > 0
7315 && num > 31
7316 && num < 31 + md.rot.num_regs)
7317 {
7318 specs[count] = tmpl;
7319 specs[count++].specific = 0;
7320 }
7321 }
7322 else if (idesc->operands[i] == IA64_OPND_F1
7323 || idesc->operands[i] == IA64_OPND_F2
7324 || idesc->operands[i] == IA64_OPND_F3
7325 || idesc->operands[i] == IA64_OPND_F4)
7326 {
7327 int num = CURR_SLOT.opnd[i].X_add_number - REG_FR;
7328 if (num > 31)
7329 {
7330 specs[count] = tmpl;
7331 specs[count++].specific = 0;
7332 }
7333 }
7334 else if (idesc->operands[i] == IA64_OPND_P1
7335 || idesc->operands[i] == IA64_OPND_P2)
7336 {
7337 int num = CURR_SLOT.opnd[i].X_add_number - REG_P;
7338 if (num > 15)
7339 {
7340 specs[count] = tmpl;
7341 specs[count++].specific = 0;
7342 }
7343 }
7344 }
7345 if (CURR_SLOT.qp_regno > 15)
7346 {
7347 specs[count] = tmpl;
7348 specs[count++].specific = 0;
7349 }
7350 }
7351 break;
7352
7353 case IA64_RS_PR63:
7354 if (note == 0)
7355 {
7356 specs[count++] = tmpl;
7357 }
7358 else if (note == 11)
7359 {
7360 if ((idesc->operands[0] == IA64_OPND_P1
7361 && CURR_SLOT.opnd[0].X_add_number - REG_P == 63)
7362 || (idesc->operands[1] == IA64_OPND_P2
7363 && CURR_SLOT.opnd[1].X_add_number - REG_P == 63))
7364 {
7365 specs[count++] = tmpl;
7366 }
7367 }
7368 else if (note == 12)
7369 {
7370 if (CURR_SLOT.qp_regno == 63)
7371 {
7372 specs[count++] = tmpl;
7373 }
7374 }
7375 else if (note == 7)
7376 {
7377 valueT mask = 0;
7378 if (idesc->operands[2] == IA64_OPND_IMM17)
7379 mask = CURR_SLOT.opnd[2].X_add_number;
7380 if (mask & ((valueT)1<<63))
7381 {
7382 specs[count++] = tmpl;
7383 }
7384 }
7385 else if (note == 1)
7386 {
7387 if (rsrc_write)
7388 {
7389 for (i=0;i < idesc->num_outputs;i++)
7390 if ((idesc->operands[i] == IA64_OPND_P1
7391 || idesc->operands[i] == IA64_OPND_P2)
7392 && CURR_SLOT.opnd[i].X_add_number - REG_P == 63)
7393 {
7394 specs[count++] = tmpl;
7395 }
7396 }
7397 else
7398 {
7399 if (CURR_SLOT.qp_regno == 63)
7400 {
7401 specs[count++] = tmpl;
7402 }
7403 }
7404 }
7405 else
7406 {
7407 UNHANDLED;
7408 }
7409 break;
7410
7411 case IA64_RS_RSE:
7412 /* FIXME we can identify some individual RSE written resources, but RSE
7413 read resources have not yet been completely identified, so for now
7414 treat RSE as a single resource */
7415 if (strncmp (idesc->name, "mov", 3) == 0)
7416 {
7417 if (rsrc_write)
7418 {
7419 if (idesc->operands[0] == IA64_OPND_AR3
7420 && CURR_SLOT.opnd[0].X_add_number - REG_AR == AR_BSPSTORE)
7421 {
7422 specs[count] = tmpl;
7423 specs[count++].index = 0; /* IA64_RSE_BSPLOAD/RNATBITINDEX */
7424 }
7425 }
7426 else
7427 {
7428 if (idesc->operands[0] == IA64_OPND_AR3)
7429 {
7430 if (CURR_SLOT.opnd[0].X_add_number - REG_AR == AR_BSPSTORE
7431 || CURR_SLOT.opnd[0].X_add_number - REG_AR == AR_RNAT)
7432 {
7433 specs[count++] = tmpl;
7434 }
7435 }
7436 else if (idesc->operands[1] == IA64_OPND_AR3)
7437 {
7438 if (CURR_SLOT.opnd[1].X_add_number - REG_AR == AR_BSP
7439 || CURR_SLOT.opnd[1].X_add_number - REG_AR == AR_BSPSTORE
7440 || CURR_SLOT.opnd[1].X_add_number - REG_AR == AR_RNAT)
7441 {
7442 specs[count++] = tmpl;
7443 }
7444 }
7445 }
7446 }
7447 else
7448 {
7449 specs[count++] = tmpl;
7450 }
7451 break;
7452
7453 case IA64_RS_ANY:
7454 /* FIXME -- do any of these need to be non-specific? */
7455 specs[count++] = tmpl;
7456 break;
7457
7458 default:
7459 as_bad (_("Unrecognized dependency specifier %d\n"), dep->specifier);
7460 break;
7461 }
7462
7463 return count;
7464}
7465
7466/* Clear branch flags on marked resources. This breaks the link between the
7467 QP of the marking instruction and a subsequent branch on the same QP.
7468*/
7469static void
7470clear_qp_branch_flag (mask)
7471 valueT mask;
7472{
7473 int i;
7474 for (i = 0;i < regdepslen;i++)
7475 {
7476 valueT bit = ((valueT)1 << regdeps[i].qp_regno);
7477 if ((bit & mask) != 0)
7478 {
7479 regdeps[i].link_to_qp_branch = 0;
7480 }
7481 }
7482}
7483
7484/* Remove any mutexes which contain any of the PRs indicated in the mask.
7485
7486 Any changes to a PR clears the mutex relations which include that PR.
7487*/
7488static void
7489clear_qp_mutex (mask)
7490 valueT mask;
7491{
7492 int i;
7493
7494 i = 0;
7495 while (i < qp_mutexeslen)
7496 {
7497 if ((qp_mutexes[i].prmask & mask) != 0)
7498 {
7499 if (md.debug_dv)
7500 {
7501 fprintf (stderr, " Clearing mutex relation");
7502 print_prmask (qp_mutexes[i].prmask);
7503 fprintf (stderr, "\n");
7504 }
7505 qp_mutexes[i] = qp_mutexes[--qp_mutexeslen];
7506 }
7507 else
7508 ++i;
7509 }
7510}
7511
7512/* Clear implies relations which contain PRs in the given masks.
7513 P1_MASK indicates the source of the implies relation, while P2_MASK
7514 indicates the implied PR.
7515*/
7516static void
7517clear_qp_implies (p1_mask, p2_mask)
7518 valueT p1_mask;
7519 valueT p2_mask;
7520{
7521 int i;
7522
7523 i = 0;
7524 while (i < qp_implieslen)
7525 {
7526 if ((((valueT)1 << qp_implies[i].p1) & p1_mask) != 0
7527 || (((valueT)1 << qp_implies[i].p2) & p2_mask) != 0)
7528 {
7529 if (md.debug_dv)
7530 fprintf (stderr, "Clearing implied relation PR%d->PR%d\n",
7531 qp_implies[i].p1, qp_implies[i].p2);
7532 qp_implies[i] = qp_implies[--qp_implieslen];
7533 }
7534 else
7535 ++i;
7536 }
7537}
7538
7539/* add the PRs specified to the list of implied relations */
7540static void
7541add_qp_imply (p1, p2)
7542 int p1, p2;
7543{
7544 valueT mask;
7545 valueT bit;
7546 int i;
7547
7548 /* p0 is not meaningful here */
7549 if (p1 == 0 || p2 == 0)
7550 abort ();
7551
7552 if (p1 == p2)
7553 return;
7554
7555 /* if it exists already, ignore it */
7556 for (i=0;i < qp_implieslen;i++)
7557 {
7558 if (qp_implies[i].p1 == p1
7559 && qp_implies[i].p2 == p2
7560 && qp_implies[i].path == md.path
7561 && !qp_implies[i].p2_branched)
7562 return;
7563 }
7564
7565 if (qp_implieslen == qp_impliestotlen)
7566 {
7567 qp_impliestotlen += 20;
7568 qp_implies = (struct qp_imply *)
7569 xrealloc ((void *)qp_implies,
7570 qp_impliestotlen * sizeof (struct qp_imply));
7571 }
7572 if (md.debug_dv)
7573 fprintf (stderr, " Registering PR%d implies PR%d\n", p1, p2);
7574 qp_implies[qp_implieslen].p1 = p1;
7575 qp_implies[qp_implieslen].p2 = p2;
7576 qp_implies[qp_implieslen].path = md.path;
7577 qp_implies[qp_implieslen++].p2_branched = 0;
7578
7579 /* Add in the implied transitive relations; for everything that p2 implies,
7580 make p1 imply that, too; for everything that implies p1, make it imply p2
7581 as well. */
7582 for (i=0;i < qp_implieslen;i++)
7583 {
7584 if (qp_implies[i].p1 == p2)
7585 add_qp_imply (p1, qp_implies[i].p2);
7586 if (qp_implies[i].p2 == p1)
7587 add_qp_imply (qp_implies[i].p1, p2);
7588 }
7589 /* Add in mutex relations implied by this implies relation; for each mutex
7590 relation containing p2, duplicate it and replace p2 with p1. */
7591 bit = (valueT)1 << p1;
7592 mask = (valueT)1 << p2;
7593 for (i=0;i < qp_mutexeslen;i++)
7594 {
7595 if (qp_mutexes[i].prmask & mask)
7596 add_qp_mutex ((qp_mutexes[i].prmask & ~mask) | bit);
7597 }
7598}
7599
7600
7601/* Add the PRs specified in the mask to the mutex list; this means that only
7602 one of the PRs can be true at any time. PR0 should never be included in
7603 the mask. */
7604static void
7605add_qp_mutex (mask)
7606 valueT mask;
7607{
7608 if (mask & 0x1)
7609 abort ();
7610
7611 if (qp_mutexeslen == qp_mutexestotlen)
7612 {
7613 qp_mutexestotlen += 20;
7614 qp_mutexes = (struct qpmutex *)
7615 xrealloc ((void *)qp_mutexes,
7616 qp_mutexestotlen * sizeof (struct qpmutex));
7617 }
7618 if (md.debug_dv)
7619 {
7620 fprintf (stderr, " Registering mutex on");
7621 print_prmask (mask);
7622 fprintf (stderr, "\n");
7623 }
7624 qp_mutexes[qp_mutexeslen].path = md.path;
7625 qp_mutexes[qp_mutexeslen++].prmask = mask;
7626}
7627
7628static void
7629clear_register_values ()
7630{
7631 int i;
7632 if (md.debug_dv)
7633 fprintf (stderr, " Clearing register values\n");
7634 for (i=1;i < NELEMS(gr_values);i++)
7635 gr_values[i].known = 0;
7636}
7637
7638/* Keep track of register values/changes which affect DV tracking.
7639
7640 optimization note: should add a flag to classes of insns where otherwise we
7641 have to examine a group of strings to identify them.
7642
7643 */
7644static void
7645note_register_values (idesc)
7646 struct ia64_opcode *idesc;
7647{
7648 valueT qp_changemask = 0;
7649 int i;
7650
7651 /* invalidate values for registers being written to */
7652 for (i=0;i < idesc->num_outputs;i++)
7653 {
7654 if (idesc->operands[i] == IA64_OPND_R1
7655 || idesc->operands[i] == IA64_OPND_R2
7656 || idesc->operands[i] == IA64_OPND_R3)
7657 {
7658 int regno = CURR_SLOT.opnd[i].X_add_number - REG_GR;
7659 if (regno > 0 && regno < NELEMS(gr_values))
7660 gr_values[regno].known = 0;
7661 }
7662 else if (idesc->operands[i] == IA64_OPND_P1
7663 || idesc->operands[i] == IA64_OPND_P2)
7664 {
7665 int regno = CURR_SLOT.opnd[i].X_add_number - REG_P;
7666 qp_changemask |= (valueT)1 << regno;
7667 }
7668 else if (idesc->operands[i] == IA64_OPND_PR)
7669 {
7670 if (idesc->operands[2] & (valueT)0x10000)
7671 qp_changemask = ~(valueT)0x1FFFF | idesc->operands[2];
7672 else
7673 qp_changemask = idesc->operands[2];
7674 break;
7675 }
7676 else if (idesc->operands[i] == IA64_OPND_PR_ROT)
7677 {
7678 if (idesc->operands[1] & ((valueT)1 << 43))
7679 qp_changemask = ~(valueT)0xFFFFFFFFFFF | idesc->operands[1];
7680 else
7681 qp_changemask = idesc->operands[1];
7682 qp_changemask &= ~(valueT)0xFFFF;
7683 break;
7684 }
7685 }
7686
7687 /* Always clear qp branch flags on any PR change */
7688 /* FIXME there may be exceptions for certain compares */
7689 clear_qp_branch_flag (qp_changemask);
7690
7691 /* invalidate rotating registers on insns which affect RRBs in CFM */
7692 if (idesc->flags & IA64_OPCODE_MOD_RRBS)
7693 {
7694 qp_changemask |= ~(valueT)0xFFFF;
7695 if (strcmp (idesc->name, "clrrrb.pr") != 0)
7696 {
7697 for (i=32;i < 32+md.rot.num_regs;i++)
7698 gr_values[i].known = 0;
7699 }
7700 clear_qp_mutex (qp_changemask);
7701 clear_qp_implies (qp_changemask, qp_changemask);
7702 }
7703 /* after a call, all register values are undefined, except those marked
7704 as "safe" */
7705 else if (strncmp (idesc->name, "br.call", 6) == 0
7706 || strncmp (idesc->name, "brl.call", 7) == 0)
7707 {
7708 // FIXME keep GR values which are marked as "safe_across_calls"
7709 clear_register_values ();
7710 clear_qp_mutex (~qp_safe_across_calls);
7711 clear_qp_implies (~qp_safe_across_calls, ~qp_safe_across_calls);
7712 clear_qp_branch_flag (~qp_safe_across_calls);
7713 }
7714 /* Look for mutex and implies relations */
7715 else if ((idesc->operands[0] == IA64_OPND_P1
7716 || idesc->operands[0] == IA64_OPND_P2)
7717 && (idesc->operands[1] == IA64_OPND_P1
7718 || idesc->operands[1] == IA64_OPND_P2))
7719 {
7720 int p1 = CURR_SLOT.opnd[0].X_add_number - REG_P;
7721 int p2 = CURR_SLOT.opnd[1].X_add_number - REG_P;
7722 valueT p1mask = (valueT)1 << p1;
7723 valueT p2mask = (valueT)1 << p2;
7724
7725 /* if one of the PRs is PR0, we can't really do anything */
7726 if (p1 == 0 || p2 == 0)
7727 {
7728 if (md.debug_dv)
7729 fprintf (stderr, " Ignoring PRs due to inclusion of p0\n");
7730 }
7731 /* In general, clear mutexes and implies which include P1 or P2,
7732 with the following exceptions */
7733 else if (strstr (idesc->name, ".or.andcm") != NULL)
7734 {
7735 add_qp_mutex (p1mask | p2mask);
7736 clear_qp_implies (p2mask, p1mask);
7737 }
7738 else if (strstr (idesc->name, ".and.orcm") != NULL)
7739 {
7740 add_qp_mutex (p1mask | p2mask);
7741 clear_qp_implies (p1mask, p2mask);
7742 }
7743 else if (strstr (idesc->name, ".and") != NULL)
7744 {
7745 clear_qp_implies (0, p1mask | p2mask);
7746 }
7747 else if (strstr (idesc->name, ".or") != NULL)
7748 {
7749 clear_qp_mutex (p1mask | p2mask);
7750 clear_qp_implies (p1mask | p2mask, 0);
7751 }
7752 else
7753 {
7754 clear_qp_implies (p1mask | p2mask, p1mask | p2mask);
7755 if (strstr (idesc->name, ".unc") != NULL)
7756 {
7757 add_qp_mutex (p1mask | p2mask);
7758 if (CURR_SLOT.qp_regno != 0)
7759 {
7760 add_qp_imply (CURR_SLOT.opnd[0].X_add_number - REG_P,
7761 CURR_SLOT.qp_regno);
7762 add_qp_imply (CURR_SLOT.opnd[1].X_add_number - REG_P,
7763 CURR_SLOT.qp_regno);
7764 }
7765 }
7766 else if (CURR_SLOT.qp_regno == 0)
7767 {
7768 add_qp_mutex (p1mask | p2mask);
7769 }
7770 else
7771 {
7772 clear_qp_mutex (p1mask | p2mask);
7773 }
7774 }
7775 }
7776 /* Look for mov imm insns into GRs */
7777 else if (idesc->operands[0] == IA64_OPND_R1
7778 && (idesc->operands[1] == IA64_OPND_IMM22
7779 || idesc->operands[1] == IA64_OPND_IMMU64)
7780 && (strcmp(idesc->name, "mov") == 0
7781 || strcmp(idesc->name, "movl") == 0))
7782 {
7783 int regno = CURR_SLOT.opnd[0].X_add_number - REG_GR;
7784 if (regno > 0 && regno < NELEMS(gr_values))
7785 {
7786 gr_values[regno].known = 1;
7787 gr_values[regno].value = CURR_SLOT.opnd[1].X_add_number;
7788 gr_values[regno].path = md.path;
7789 if (md.debug_dv)
7790 fprintf (stderr, " Know gr%d = 0x%llx\n",
7791 regno, gr_values[regno].value);
7792 }
7793 }
7794 else
7795 {
7796 clear_qp_mutex (qp_changemask);
7797 clear_qp_implies (qp_changemask, qp_changemask);
7798 }
7799}
7800
7801/* Return whether the given predicate registers are currently mutex */
7802static int
7803qp_mutex (p1, p2, path)
7804 int p1;
7805 int p2;
7806 int path;
7807{
7808 int i;
7809 valueT mask;
7810
7811 if (p1 != p2)
7812 {
7813 mask = ((valueT)1<<p1) | (valueT)1<<p2;
7814 for (i=0;i < qp_mutexeslen;i++)
7815 {
7816 if (qp_mutexes[i].path >= path
7817 && (qp_mutexes[i].prmask & mask) == mask)
7818 return 1;
7819 }
7820 }
7821 return 0;
7822}
7823
7824/* Return whether the given resource is in the given insn's list of chks
7825 Return 1 if the conflict is absolutely determined, 2 if it's a potential
7826 conflict.
7827 */
7828static int
7829resources_match (rs, idesc, note, qp_regno, path)
7830 struct rsrc *rs;
7831 struct ia64_opcode *idesc;
7832 int note;
7833 int qp_regno;
7834 int path;
7835{
7836 struct rsrc specs[MAX_SPECS];
7837 int count;
7838
7839 /* If the marked resource's qp_regno and the given qp_regno are mutex,
7840 we don't need to check. One exception is note 11, which indicates that
7841 target predicates are written regardless of PR[qp]. */
7842 if (qp_mutex (rs->qp_regno, qp_regno, path)
7843 && note != 11)
7844 return 0;
7845
7846 count = specify_resource (rs->dependency, idesc, DV_CHK, specs, note, path);
7847 while (count-- > 0)
7848 {
7849 /* UNAT checking is a bit more specific than other resources */
7850 if (rs->dependency->specifier == IA64_RS_AR_UNAT
7851 && specs[count].mem_offset.hint
7852 && rs->mem_offset.hint)
7853 {
7854 if (rs->mem_offset.base == specs[count].mem_offset.base)
7855 {
7856 if (((rs->mem_offset.offset >> 3) & 0x3F) ==
7857 ((specs[count].mem_offset.offset >> 3) & 0x3F))
7858 return 1;
7859 else
7860 continue;
7861 }
7862 }
7863
7864 /* If either resource is not specific, conservatively assume a conflict
7865 */
7866 if (!specs[count].specific || !rs->specific)
7867 return 2;
7868 else if (specs[count].index == rs->index)
7869 return 1;
7870 }
7871#if 0
7872 if (md.debug_dv)
7873 fprintf (stderr, " No %s conflicts\n", rs->dependency->name);
7874#endif
7875
7876 return 0;
7877}
7878
7879/* Indicate an instruction group break; if INSERT_STOP is non-zero, then
7880 insert a stop to create the break. Update all resource dependencies
7881 appropriately. If QP_REGNO is non-zero, only apply the break to resources
7882 which use the same QP_REGNO and have the link_to_qp_branch flag set.
7883 If SAVE_CURRENT is non-zero, don't affect resources marked by the current
7884 instruction.
7885*/
7886
7887static void
7888insn_group_break (insert_stop, qp_regno, save_current)
7889 int insert_stop;
7890 int qp_regno;
7891 int save_current;
7892{
7893 int i;
7894
7895 if (insert_stop && md.num_slots_in_use > 0)
7896 PREV_SLOT.end_of_insn_group = 1;
7897
7898 if (md.debug_dv)
7899 {
7900 fprintf (stderr, " Insn group break%s",
7901 (insert_stop ? " (w/stop)" : ""));
7902 if (qp_regno != 0)
7903 fprintf (stderr, " effective for QP=%d", qp_regno);
7904 fprintf (stderr, "\n");
7905 }
7906
7907 i = 0;
7908 while (i < regdepslen)
7909 {
7910 const struct ia64_dependency *dep = regdeps[i].dependency;
7911
7912 if (qp_regno != 0
7913 && regdeps[i].qp_regno != qp_regno)
7914 {
7915 ++i;
7916 continue;
7917 }
7918
7919 if (save_current
7920 && CURR_SLOT.src_file == regdeps[i].file
7921 && CURR_SLOT.src_line == regdeps[i].line)
7922 {
7923 ++i;
7924 continue;
7925 }
7926
7927 /* clear dependencies which are automatically cleared by a stop, or
7928 those that have reached the appropriate state of insn serialization */
7929 if (dep->semantics == IA64_DVS_IMPLIED
7930 || dep->semantics == IA64_DVS_IMPLIEDF
7931 || regdeps[i].insn_srlz == STATE_SRLZ)
7932 {
7933 print_dependency ("Removing", i);
7934 regdeps[i] = regdeps[--regdepslen];
7935 }
7936 else
7937 {
7938 if (dep->semantics == IA64_DVS_DATA
7939 || dep->semantics == IA64_DVS_INSTR
7940 || dep->semantics == IA64_DVS_SPECIFIC)
7941 {
7942 if (regdeps[i].insn_srlz == STATE_NONE)
7943 regdeps[i].insn_srlz = STATE_STOP;
7944 if (regdeps[i].data_srlz == STATE_NONE)
7945 regdeps[i].data_srlz = STATE_STOP;
7946 }
7947 ++i;
7948 }
7949 }
7950}
7951
7952/* Add the given resource usage spec to the list of active dependencies */
7953static void
7954mark_resource (idesc, dep, spec, depind, path)
7955 struct ia64_opcode *idesc;
7956 const struct ia64_dependency *dep;
7957 struct rsrc *spec;
7958 int depind;
7959 int path;
7960{
7961 if (regdepslen == regdepstotlen)
7962 {
7963 regdepstotlen += 20;
7964 regdeps = (struct rsrc *)
7965 xrealloc ((void *)regdeps,
7966 regdepstotlen * sizeof(struct rsrc));
7967 }
7968
7969 regdeps[regdepslen] = *spec;
7970 regdeps[regdepslen].depind = depind;
7971 regdeps[regdepslen].path = path;
7972 regdeps[regdepslen].file = CURR_SLOT.src_file;
7973 regdeps[regdepslen].line = CURR_SLOT.src_line;
7974
7975 print_dependency ("Adding", regdepslen);
7976
7977 ++regdepslen;
7978}
7979
7980static void
7981print_dependency (action, depind)
7982 const char *action;
7983 int depind;
7984{
7985 if (md.debug_dv)
7986 {
7987 fprintf (stderr, " %s %s '%s'",
7988 action, dv_mode[(regdeps[depind].dependency)->mode],
7989 (regdeps[depind].dependency)->name);
7990 if (regdeps[depind].specific && regdeps[depind].index != 0)
7991 fprintf (stderr, " (%d)", regdeps[depind].index);
7992 if (regdeps[depind].mem_offset.hint)
7993 fprintf (stderr, " 0x%llx+0x%llx",
7994 regdeps[depind].mem_offset.base,
7995 regdeps[depind].mem_offset.offset);
7996 fprintf (stderr, "\n");
7997 }
7998}
7999
8000static void
8001instruction_serialization ()
8002{
8003 int i;
8004 if (md.debug_dv)
8005 fprintf (stderr, " Instruction serialization\n");
8006 for (i=0;i < regdepslen;i++)
8007 if (regdeps[i].insn_srlz == STATE_STOP)
8008 regdeps[i].insn_srlz = STATE_SRLZ;
8009}
8010
8011static void
8012data_serialization ()
8013{
8014 int i = 0;
8015 if (md.debug_dv)
8016 fprintf (stderr, " Data serialization\n");
8017 while (i < regdepslen)
8018 {
8019 if (regdeps[i].data_srlz == STATE_STOP
8020 /* Note: as of 991210, all "other" dependencies are cleared by a
8021 data serialization. This might change with new tables */
8022 || (regdeps[i].dependency)->semantics == IA64_DVS_OTHER)
8023 {
8024 print_dependency ("Removing", i);
8025 regdeps[i] = regdeps[--regdepslen];
8026 }
8027 else
8028 ++i;
8029 }
8030}
8031
8032/* Insert stops and serializations as needed to avoid DVs */
8033static void
8034remove_marked_resource (rs)
8035 struct rsrc *rs;
8036{
8037 switch (rs->dependency->semantics)
8038 {
8039 case IA64_DVS_SPECIFIC:
8040 if (md.debug_dv)
8041 fprintf (stderr, "Implementation-specific, assume worst case...\n");
8042 /* ...fall through... */
8043 case IA64_DVS_INSTR:
8044 if (md.debug_dv)
8045 fprintf (stderr, "Inserting instr serialization\n");
8046 if (rs->insn_srlz < STATE_STOP)
8047 insn_group_break (1, 0, 0);
8048 if (rs->insn_srlz < STATE_SRLZ)
8049 {
8050 int oldqp = CURR_SLOT.qp_regno;
8051 struct ia64_opcode *oldidesc = CURR_SLOT.idesc;
8052 /* Manually jam a srlz.i insn into the stream */
8053 CURR_SLOT.qp_regno = 0;
8054 CURR_SLOT.idesc = ia64_find_opcode ("srlz.i");
8055 instruction_serialization ();
8056 md.curr_slot = (md.curr_slot + 1) % NUM_SLOTS;
8057 if (++md.num_slots_in_use >= NUM_SLOTS)
8058 emit_one_bundle ();
8059 CURR_SLOT.qp_regno = oldqp;
8060 CURR_SLOT.idesc = oldidesc;
8061 }
8062 insn_group_break (1, 0, 0);
8063 break;
8064 case IA64_DVS_OTHER: /* as of rev2 (991220) of the DV tables, all
8065 "other" types of DV are eliminated
8066 by a data serialization */
8067 case IA64_DVS_DATA:
8068 if (md.debug_dv)
8069 fprintf (stderr, "Inserting data serialization\n");
8070 if (rs->data_srlz < STATE_STOP)
8071 insn_group_break (1, 0, 0);
8072 {
8073 int oldqp = CURR_SLOT.qp_regno;
8074 struct ia64_opcode *oldidesc = CURR_SLOT.idesc;
8075 /* Manually jam a srlz.d insn into the stream */
8076 CURR_SLOT.qp_regno = 0;
8077 CURR_SLOT.idesc = ia64_find_opcode ("srlz.d");
8078 data_serialization ();
8079 md.curr_slot = (md.curr_slot + 1) % NUM_SLOTS;
8080 if (++md.num_slots_in_use >= NUM_SLOTS)
8081 emit_one_bundle ();
8082 CURR_SLOT.qp_regno = oldqp;
8083 CURR_SLOT.idesc = oldidesc;
8084 }
8085 break;
8086 case IA64_DVS_IMPLIED:
8087 case IA64_DVS_IMPLIEDF:
8088 if (md.debug_dv)
8089 fprintf (stderr, "Inserting stop\n");
8090 insn_group_break (1, 0, 0);
8091 break;
8092 default:
8093 break;
8094 }
8095}
8096
8097/* Check the resources used by the given opcode against the current dependency
8098 list.
8099
8100 The check is run once for each execution path encountered. In this case,
8101 a unique execution path is the sequence of instructions following a code
8102 entry point, e.g. the following has three execution paths, one starting
8103 at L0, one at L1, and one at L2.
8104
8105 L0: nop
8106 L1: add
8107 L2: add
8108 br.ret
8109*/
8110static void
8111check_dependencies (idesc)
8112 struct ia64_opcode *idesc;
8113{
8114 const struct ia64_opcode_dependency *opdeps = idesc->dependencies;
8115 int path;
8116 int i;
8117
8118 /* Note that the number of marked resources may change within the
8119 loop if in auto mode. */
8120 i = 0;
8121 while (i < regdepslen)
8122 {
8123 struct rsrc *rs = &regdeps[i];
8124 const struct ia64_dependency *dep = rs->dependency;
8125 int chkind;
8126 int note;
8127 int start_over = 0;
8128
8129 if (dep->semantics == IA64_DVS_NONE
8130 || (chkind = depends_on (rs->depind, idesc)) == -1)
8131 {
8132 ++i; continue;
8133 }
8134
8135 note = NOTE(opdeps->chks[chkind]);
8136
8137 /* Check this resource against each execution path seen thus far */
8138 for (path=0;path <= md.path;path++)
8139 {
8140 int matchtype;
8141
8142 /* If the dependency wasn't on the path being checked, ignore it */
8143 if (rs->path < path)
8144 continue;
8145
8146 /* If the QP for this insn implies a QP which has branched, don't
8147 bother checking. Ed. NOTE: I don't think this check is terribly
8148 useful; what's the point of generating code which will only be
8149 reached if its QP is zero?
8150 This code was specifically inserted to handle the following code,
8151 based on notes from Intel's DV checking code, where p1 implies p2.
8152
8153 mov r4 = 2
8154 (p2) br.cond L
8155 (p1) mov r4 = 7
8156
8157 */
8158 if (CURR_SLOT.qp_regno != 0)
8159 {
8160 int skip = 0;
8161 int implies;
8162 for (implies=0;implies < qp_implieslen;implies++)
8163 {
8164 if (qp_implies[implies].path >= path
8165 && qp_implies[implies].p1 == CURR_SLOT.qp_regno
8166 && qp_implies[implies].p2_branched)
8167 {
8168 skip = 1;
8169 break;
8170 }
8171 }
8172 if (skip)
8173 continue;
8174 }
8175
8176 if ((matchtype = resources_match (rs, idesc, note,
8177 CURR_SLOT.qp_regno, path)) != 0)
8178 {
8179 char msg[1024];
8180 char pathmsg[256] = "";
8181 char indexmsg[256] = "";
8182 int certain = (matchtype == 1 && CURR_SLOT.qp_regno == 0);
8183
8184 if (path != 0)
8185 sprintf (pathmsg, " when entry is at label '%s'",
8186 md.entry_labels[path-1]);
8187 if (rs->specific && rs->index != 0)
8188 sprintf (indexmsg, ", specific resource number is %d",
8189 rs->index);
8190 sprintf (msg, "Use of '%s' %s %s dependency '%s' (%s)%s%s",
8191 idesc->name,
8192 (certain ? "violates" : "may violate"),
8193 dv_mode[dep->mode], dep->name,
8194 dv_sem[dep->semantics],
8195 pathmsg, indexmsg);
8196
8197 if (md.explicit_mode)
8198 {
8199 as_warn ("%s", msg);
8200 if (path < md.path)
8201 as_warn (_("Only the first path encountering the conflict "
8202 "is reported"));
8203 as_warn_where (rs->file, rs->line,
8204 _("This is the location of the "
8205 "conflicting usage"));
8206 /* Don't bother checking other paths, to avoid duplicating
8207 the same warning */
8208 break;
8209 }
8210 else
8211 {
8212 if (md.debug_dv)
8213 fprintf(stderr, "%s @ %s:%d\n", msg, rs->file, rs->line);
8214
8215 remove_marked_resource (rs);
8216
8217 /* since the set of dependencies has changed, start over */
8218 /* FIXME -- since we're removing dvs as we go, we
8219 probably don't really need to start over... */
8220 start_over = 1;
8221 break;
8222 }
8223 }
8224 }
8225 if (start_over)
8226 i = 0;
8227 else
8228 ++i;
8229 }
8230}
8231
8232/* register new dependencies based on the given opcode */
8233static void
8234mark_resources (idesc)
8235 struct ia64_opcode *idesc;
8236{
8237 int i;
8238 const struct ia64_opcode_dependency *opdeps = idesc->dependencies;
8239 int add_only_qp_reads = 0;
8240
8241 /* A conditional branch only uses its resources if it is taken; if it is
8242 taken, we stop following that path. The other branch types effectively
8243 *always* write their resources. If it's not taken, register only QP
8244 reads. */
8245 if (is_conditional_branch (idesc) || is_interruption_or_rfi (idesc))
8246 {
8247 add_only_qp_reads = 1;
8248 }
8249
8250 if (md.debug_dv)
8251 fprintf (stderr, "Registering '%s' resource usage\n", idesc->name);
8252
8253 for (i=0;i < opdeps->nregs;i++)
8254 {
8255 const struct ia64_dependency *dep;
8256 struct rsrc specs[MAX_SPECS];
8257 int note;
8258 int path;
8259 int count;
8260
8261 dep = ia64_find_dependency (opdeps->regs[i]);
8262 note = NOTE(opdeps->regs[i]);
8263
8264 if (add_only_qp_reads
8265 && !(dep->mode == IA64_DV_WAR
8266 && (dep->specifier == IA64_RS_PR
8267 || dep->specifier == IA64_RS_PR63)))
8268 continue;
8269
8270 count = specify_resource (dep, idesc, DV_REG, specs, note, md.path);
8271
8272#if 0
8273 if (md.debug_dv && !count)
8274 fprintf (stderr, " No %s %s usage found (path %d)\n",
8275 dv_mode[dep->mode], dep->name, md.path);
8276#endif
8277
8278 while (count-- > 0)
8279 {
8280 mark_resource (idesc, dep, &specs[count],
8281 DEP(opdeps->regs[i]), md.path);
8282 }
8283
8284 /* The execution path may affect register values, which may in turn
8285 affect which indirect-access resources are accessed. */
8286 switch (dep->specifier)
8287 {
8288 default:
8289 break;
8290 case IA64_RS_CPUID:
8291 case IA64_RS_DBR:
8292 case IA64_RS_IBR:
8293 case IA64_RS_MSR:
8294 case IA64_RS_PKR:
8295 case IA64_RS_PMC:
8296 case IA64_RS_PMD:
8297 case IA64_RS_RR:
8298 for (path=0;path < md.path;path++)
8299 {
8300 count = specify_resource (dep, idesc, DV_REG, specs, note, path);
8301 while (count-- > 0)
8302 mark_resource (idesc, dep, &specs[count],
8303 DEP(opdeps->regs[i]), path);
8304 }
8305 break;
8306 }
8307 }
8308}
8309
8310/* remove dependencies when they no longer apply */
8311static void
8312update_dependencies (idesc)
8313 struct ia64_opcode *idesc;
8314{
8315 int i;
8316
8317 if (strcmp (idesc->name, "srlz.i") == 0)
8318 {
8319 instruction_serialization ();
8320 }
8321 else if (strcmp (idesc->name, "srlz.d") == 0)
8322 {
8323 data_serialization ();
8324 }
8325 else if (is_interruption_or_rfi (idesc)
8326 || is_taken_branch (idesc))
8327 {
8328 /* although technically the taken branch doesn't clear dependencies
8329 which require a srlz.[id], we don't follow the branch; the next
8330 instruction is assumed to start with a clean slate */
8331 regdepslen = 0;
8332 clear_register_values ();
8333 clear_qp_mutex (~(valueT)0);
8334 clear_qp_implies (~(valueT)0, ~(valueT)0);
8335 md.path = 0;
8336 }
8337 else if (is_conditional_branch (idesc)
8338 && CURR_SLOT.qp_regno != 0)
8339 {
8340 int is_call = strstr (idesc->name, ".call") != NULL;
8341
8342 for (i=0;i < qp_implieslen;i++)
8343 {
8344 /* if the conditional branch's predicate is implied by the predicate
8345 in an existing dependency, remove that dependency */
8346 if (qp_implies[i].p2 == CURR_SLOT.qp_regno)
8347 {
8348 int depind = 0;
8349 /* note that this implied predicate takes a branch so that if
8350 a later insn generates a DV but its predicate implies this
8351 one, we can avoid the false DV warning */
8352 qp_implies[i].p2_branched = 1;
8353 while (depind < regdepslen)
8354 {
8355 if (regdeps[depind].qp_regno == qp_implies[i].p1)
8356 {
8357 print_dependency ("Removing", depind);
8358 regdeps[depind] = regdeps[--regdepslen];
8359 }
8360 else
8361 ++depind;
8362 }
8363 }
8364 }
8365 /* Any marked resources which have this same predicate should be
8366 cleared, provided that the QP hasn't been modified between the
8367 marking instruction and the branch.
8368 */
8369 if (is_call)
8370 {
8371 insn_group_break (0, CURR_SLOT.qp_regno, 1);
8372 }
8373 else
8374 {
8375 i = 0;
8376 while (i < regdepslen)
8377 {
8378 if (regdeps[i].qp_regno == CURR_SLOT.qp_regno
8379 && regdeps[i].link_to_qp_branch
8380 && (regdeps[i].file != CURR_SLOT.src_file
8381 || regdeps[i].line != CURR_SLOT.src_line))
8382 {
8383 /* Treat like a taken branch */
8384 print_dependency ("Removing", i);
8385 regdeps[i] = regdeps[--regdepslen];
8386 }
8387 else
8388 ++i;
8389 }
8390 }
8391 }
8392}
8393
8394/* Examine the current instruction for dependency violations. */
8395static int
8396check_dv (idesc)
8397 struct ia64_opcode *idesc;
8398{
8399 if (md.debug_dv)
8400 {
8401 fprintf (stderr, "Checking %s for violations (line %d, %d/%d)\n",
8402 idesc->name, CURR_SLOT.src_line,
8403 idesc->dependencies->nchks,
8404 idesc->dependencies->nregs);
8405 }
8406
8407 /* Look through the list of currently marked resources; if the current
8408 instruction has the dependency in its chks list which uses that resource,
8409 check against the specific resources used.
8410 */
8411 check_dependencies (idesc);
8412
8413 /*
8414 Look up the instruction's regdeps (RAW writes, WAW writes, and WAR reads),
8415 then add them to the list of marked resources.
8416 */
8417 mark_resources (idesc);
8418
8419 /* There are several types of dependency semantics, and each has its own
8420 requirements for being cleared
8421
8422 Instruction serialization (insns separated by interruption, rfi, or
8423 writer + srlz.i + reader, all in separate groups) clears DVS_INSTR.
8424
8425 Data serialization (instruction serialization, or writer + srlz.d +
8426 reader, where writer and srlz.d are in separate groups) clears
8427 DVS_DATA. (This also clears DVS_OTHER, but that is not guaranteed to
8428 always be the case).
8429
8430 Instruction group break (groups separated by stop, taken branch,
8431 interruption or rfi) clears DVS_IMPLIED and DVS_IMPLIEDF.
8432 */
8433 update_dependencies (idesc);
8434
8435 /* Sometimes, knowing a register value allows us to avoid giving a false DV
8436 warning. Keep track of as many as possible that are useful. */
8437 note_register_values (idesc);
8438
8439 /* We don't need or want this anymore. */
8440 md.mem_offset.hint = 0;
8441
8442 return 0;
8443}
8444
8445/* Translate one line of assembly. Pseudo ops and labels do not show
8446 here. */
8447void
8448md_assemble (str)
8449 char *str;
8450{
8451 char *saved_input_line_pointer, *mnemonic;
8452 const struct pseudo_opcode *pdesc;
8453 struct ia64_opcode *idesc;
8454 unsigned char qp_regno;
8455 unsigned int flags;
8456 int ch;
8457
8458 saved_input_line_pointer = input_line_pointer;
8459 input_line_pointer = str;
8460
8461 /* extract the opcode (mnemonic): */
8462
8463 mnemonic = input_line_pointer;
8464 ch = get_symbol_end ();
8465 pdesc = (struct pseudo_opcode *) hash_find (md.pseudo_hash, mnemonic);
8466 if (pdesc)
8467 {
8468 *input_line_pointer = ch;
8469 (*pdesc->handler) (pdesc->arg);
8470 goto done;
8471 }
8472
8473 /* find the instruction descriptor matching the arguments: */
8474
8475 idesc = ia64_find_opcode (mnemonic);
8476 *input_line_pointer = ch;
8477 if (!idesc)
8478 {
8479 as_bad ("Unknown opcode `%s'", mnemonic);
8480 goto done;
8481 }
8482
8483 idesc = parse_operands (idesc);
8484 if (!idesc)
8485 goto done;
8486
8487 /* Handle the dynamic ops we can handle now: */
8488 if (idesc->type == IA64_TYPE_DYN)
8489 {
8490 if (strcmp (idesc->name, "add") == 0)
8491 {
8492 if (CURR_SLOT.opnd[2].X_op == O_register
8493 && CURR_SLOT.opnd[2].X_add_number < 4)
8494 mnemonic = "addl";
8495 else
8496 mnemonic = "adds";
8497 idesc = ia64_find_opcode (mnemonic);
8498#if 0
8499 know (!idesc->next);
8500#endif
8501 }
8502 else if (strcmp (idesc->name, "mov") == 0)
8503 {
8504 enum ia64_opnd opnd1, opnd2;
8505 int rop;
8506
8507 opnd1 = idesc->operands[0];
8508 opnd2 = idesc->operands[1];
8509 if (opnd1 == IA64_OPND_AR3)
8510 rop = 0;
8511 else if (opnd2 == IA64_OPND_AR3)
8512 rop = 1;
8513 else
8514 abort ();
8515 if (CURR_SLOT.opnd[rop].X_op == O_register
8516 && ar_is_in_integer_unit (CURR_SLOT.opnd[rop].X_add_number))
8517 mnemonic = "mov.i";
8518 else
8519 mnemonic = "mov.m";
8520 idesc = ia64_find_opcode (mnemonic);
8521 while (idesc != NULL
8522 && (idesc->operands[0] != opnd1
8523 || idesc->operands[1] != opnd2))
8524 idesc = get_next_opcode (idesc);
8525 }
8526 }
8527
8528 qp_regno = 0;
8529 if (md.qp.X_op == O_register)
8530 qp_regno = md.qp.X_add_number - REG_P;
8531
8532 flags = idesc->flags;
8533
8534 if ((flags & IA64_OPCODE_FIRST) != 0)
8535 insn_group_break (1, 0, 0);
8536
8537 if ((flags & IA64_OPCODE_NO_PRED) != 0 && qp_regno != 0)
8538 {
8539 as_bad ("`%s' cannot be predicated", idesc->name);
8540 goto done;
8541 }
8542
8543 /* build the instruction: */
8544 CURR_SLOT.qp_regno = qp_regno;
8545 CURR_SLOT.idesc = idesc;
8546 as_where (&CURR_SLOT.src_file, &CURR_SLOT.src_line);
8547 if (debug_type == DEBUG_DWARF2)
8548 dwarf2_where (&CURR_SLOT.debug_line);
8549
8550 /* Add unwind entry, if there is one. */
e0c9811a 8551 if (unwind.current_entry)
800eeca4 8552 {
e0c9811a
JW
8553 CURR_SLOT.unwind_record = unwind.current_entry;
8554 unwind.current_entry = NULL;
800eeca4
JW
8555 }
8556
8557 /* check for dependency violations */
8558 if (md.detect_dv)
8559 check_dv(idesc);
8560
8561 md.curr_slot = (md.curr_slot + 1) % NUM_SLOTS;
8562 if (++md.num_slots_in_use >= NUM_SLOTS)
8563 emit_one_bundle ();
8564
8565 if ((flags & IA64_OPCODE_LAST) != 0)
8566 insn_group_break (1, 0, 0);
8567
8568 md.last_text_seg = now_seg;
8569
8570 done:
8571 input_line_pointer = saved_input_line_pointer;
8572}
8573
8574/* Called when symbol NAME cannot be found in the symbol table.
8575 Should be used for dynamic valued symbols only. */
8576symbolS*
8577md_undefined_symbol (name)
8578 char *name;
8579{
8580 return 0;
8581}
8582
8583/* Called for any expression that can not be recognized. When the
8584 function is called, `input_line_pointer' will point to the start of
8585 the expression. */
8586void
8587md_operand (e)
8588 expressionS *e;
8589{
8590 enum pseudo_type pseudo_type;
e0c9811a 8591 const char *name;
800eeca4
JW
8592 size_t len;
8593 int ch, i;
8594
8595 switch (*input_line_pointer)
8596 {
8597 case '@':
8598 /* find what relocation pseudo-function we're dealing with: */
8599 pseudo_type = 0;
8600 ch = *++input_line_pointer;
8601 for (i = 0; i < NELEMS (pseudo_func); ++i)
8602 if (pseudo_func[i].name && pseudo_func[i].name[0] == ch)
8603 {
8604 len = strlen (pseudo_func[i].name);
8605 if (strncmp (pseudo_func[i].name + 1,
8606 input_line_pointer + 1, len - 1) == 0
8607 && !is_part_of_name (input_line_pointer[len]))
8608 {
8609 input_line_pointer += len;
8610 pseudo_type = pseudo_func[i].type;
8611 break;
8612 }
8613 }
8614 switch (pseudo_type)
8615 {
8616 case PSEUDO_FUNC_RELOC:
8617 SKIP_WHITESPACE ();
8618 if (*input_line_pointer != '(')
8619 {
8620 as_bad ("Expected '('");
8621 goto err;
8622 }
8623 ++input_line_pointer; /* skip '(' */
8624 expression (e);
8625 if (*input_line_pointer++ != ')')
8626 {
8627 as_bad ("Missing ')'");
8628 goto err;
8629 }
8630 if (e->X_op != O_symbol)
8631 {
8632 if (e->X_op != O_pseudo_fixup)
8633 {
8634 as_bad ("Not a symbolic expression");
8635 goto err;
8636 }
8637 if (S_GET_VALUE (e->X_op_symbol) == FUNC_FPTR_RELATIVE
8638 && i == FUNC_LT_RELATIVE)
8639 i = FUNC_LT_FPTR_RELATIVE;
8640 else
8641 {
8642 as_bad ("Illegal combination of relocation functions");
8643 goto err;
8644 }
8645 }
8646 /* make sure gas doesn't get rid of local symbols that are used
8647 in relocs: */
8648 e->X_op = O_pseudo_fixup;
8649 e->X_op_symbol = pseudo_func[i].u.sym;
8650 break;
8651
8652 case PSEUDO_FUNC_CONST:
8653 e->X_op = O_constant;
8654 e->X_add_number = pseudo_func[i].u.ival;
8655 break;
8656
e0c9811a
JW
8657 case PSEUDO_FUNC_REG:
8658 e->X_op = O_register;
8659 e->X_add_number = pseudo_func[i].u.ival;
8660 break;
8661
800eeca4 8662 default:
e0c9811a
JW
8663 name = input_line_pointer - 1;
8664 get_symbol_end ();
8665 as_bad ("Unknown pseudo function `%s'", name);
800eeca4
JW
8666 goto err;
8667 }
8668 break;
8669
8670 case '[':
8671 ++input_line_pointer;
8672 expression (e);
8673 if (*input_line_pointer != ']')
8674 {
8675 as_bad ("Closing bracket misssing");
8676 goto err;
8677 }
8678 else
8679 {
8680 if (e->X_op != O_register)
8681 as_bad ("Register expected as index");
8682
8683 ++input_line_pointer;
8684 e->X_op = O_index;
8685 }
8686 break;
8687
8688 default:
8689 break;
8690 }
8691 return;
8692
8693 err:
8694 ignore_rest_of_line ();
8695}
8696
8697/* Return 1 if it's OK to adjust a reloc by replacing the symbol with
8698 a section symbol plus some offset. For relocs involving @fptr(),
8699 directives we don't want such adjustments since we need to have the
8700 original symbol's name in the reloc. */
8701int
8702ia64_fix_adjustable (fix)
8703 fixS *fix;
8704{
8705 /* Prevent all adjustments to global symbols */
8706 if (S_IS_EXTERN (fix->fx_addsy) || S_IS_WEAK (fix->fx_addsy))
8707 return 0;
8708
8709 switch (fix->fx_r_type)
8710 {
8711 case BFD_RELOC_IA64_FPTR64I:
8712 case BFD_RELOC_IA64_FPTR32MSB:
8713 case BFD_RELOC_IA64_FPTR32LSB:
8714 case BFD_RELOC_IA64_FPTR64MSB:
8715 case BFD_RELOC_IA64_FPTR64LSB:
8716 case BFD_RELOC_IA64_LTOFF_FPTR22:
8717 case BFD_RELOC_IA64_LTOFF_FPTR64I:
8718 return 0;
8719 default:
8720 break;
8721 }
8722
8723 return 1;
8724}
8725
8726int
8727ia64_force_relocation (fix)
8728 fixS *fix;
8729{
8730 switch (fix->fx_r_type)
8731 {
8732 case BFD_RELOC_IA64_FPTR64I:
8733 case BFD_RELOC_IA64_FPTR32MSB:
8734 case BFD_RELOC_IA64_FPTR32LSB:
8735 case BFD_RELOC_IA64_FPTR64MSB:
8736 case BFD_RELOC_IA64_FPTR64LSB:
8737
8738 case BFD_RELOC_IA64_LTOFF22:
8739 case BFD_RELOC_IA64_LTOFF64I:
8740 case BFD_RELOC_IA64_LTOFF_FPTR22:
8741 case BFD_RELOC_IA64_LTOFF_FPTR64I:
8742 case BFD_RELOC_IA64_PLTOFF22:
8743 case BFD_RELOC_IA64_PLTOFF64I:
8744 case BFD_RELOC_IA64_PLTOFF64MSB:
8745 case BFD_RELOC_IA64_PLTOFF64LSB:
8746 return 1;
8747
8748 default:
8749 return 0;
8750 }
8751 return 0;
8752}
8753
8754/* Decide from what point a pc-relative relocation is relative to,
8755 relative to the pc-relative fixup. Er, relatively speaking. */
8756long
8757ia64_pcrel_from_section (fix, sec)
8758 fixS *fix;
8759 segT sec;
8760{
8761 unsigned long off = fix->fx_frag->fr_address + fix->fx_where;
8762
8763 if (bfd_get_section_flags (stdoutput, sec) & SEC_CODE)
8764 off &= ~0xfUL;
8765
8766 return off;
8767}
8768
8769/* This is called whenever some data item (not an instruction) needs a
8770 fixup. We pick the right reloc code depending on the byteorder
8771 currently in effect. */
8772void
8773ia64_cons_fix_new (f, where, nbytes, exp)
8774 fragS *f;
8775 int where;
8776 int nbytes;
8777 expressionS *exp;
8778{
8779 bfd_reloc_code_real_type code;
8780 fixS *fix;
8781
8782 switch (nbytes)
8783 {
8784 /* There are no reloc for 8 and 16 bit quantities, but we allow
8785 them here since they will work fine as long as the expression
8786 is fully defined at the end of the pass over the source file. */
8787 case 1: code = BFD_RELOC_8; break;
8788 case 2: code = BFD_RELOC_16; break;
8789 case 4:
8790 if (target_big_endian)
8791 code = BFD_RELOC_IA64_DIR32MSB;
8792 else
8793 code = BFD_RELOC_IA64_DIR32LSB;
8794 break;
8795
8796 case 8:
8797 if (target_big_endian)
8798 code = BFD_RELOC_IA64_DIR64MSB;
8799 else
8800 code = BFD_RELOC_IA64_DIR64LSB;
8801 break;
8802
8803 default:
8804 as_bad ("Unsupported fixup size %d", nbytes);
8805 ignore_rest_of_line ();
8806 return;
8807 }
8808 if (exp->X_op == O_pseudo_fixup)
8809 {
8810 /* ??? */
8811 exp->X_op = O_symbol;
8812 code = ia64_gen_real_reloc_type (exp->X_op_symbol, code);
8813 }
8814 fix = fix_new_exp (f, where, nbytes, exp, 0, code);
8815 /* We need to store the byte order in effect in case we're going
8816 to fix an 8 or 16 bit relocation (for which there no real
8817 relocs available). See md_apply_fix(). */
8818 fix->tc_fix_data.bigendian = target_big_endian;
8819}
8820
8821/* Return the actual relocation we wish to associate with the pseudo
8822 reloc described by SYM and R_TYPE. SYM should be one of the
8823 symbols in the pseudo_func array, or NULL. */
8824
8825static bfd_reloc_code_real_type
8826ia64_gen_real_reloc_type (sym, r_type)
8827 struct symbol *sym;
8828 bfd_reloc_code_real_type r_type;
8829{
8830 bfd_reloc_code_real_type new = 0;
8831
8832 if (sym == NULL)
8833 {
8834 return r_type;
8835 }
8836
8837 switch (S_GET_VALUE (sym))
8838 {
8839 case FUNC_FPTR_RELATIVE:
8840 switch (r_type)
8841 {
8842 case BFD_RELOC_IA64_IMM64: new = BFD_RELOC_IA64_FPTR64I; break;
8843 case BFD_RELOC_IA64_DIR32MSB: new = BFD_RELOC_IA64_FPTR32MSB; break;
8844 case BFD_RELOC_IA64_DIR32LSB: new = BFD_RELOC_IA64_FPTR32LSB; break;
8845 case BFD_RELOC_IA64_DIR64MSB: new = BFD_RELOC_IA64_FPTR64MSB; break;
8846 case BFD_RELOC_IA64_DIR64LSB: new = BFD_RELOC_IA64_FPTR64LSB; break;
8847 default: break;
8848 }
8849 break;
8850
8851 case FUNC_GP_RELATIVE:
8852 switch (r_type)
8853 {
8854 case BFD_RELOC_IA64_IMM22: new = BFD_RELOC_IA64_GPREL22; break;
8855 case BFD_RELOC_IA64_IMM64: new = BFD_RELOC_IA64_GPREL64I; break;
8856 case BFD_RELOC_IA64_DIR32MSB: new = BFD_RELOC_IA64_GPREL32MSB; break;
8857 case BFD_RELOC_IA64_DIR32LSB: new = BFD_RELOC_IA64_GPREL32LSB; break;
8858 case BFD_RELOC_IA64_DIR64MSB: new = BFD_RELOC_IA64_GPREL64MSB; break;
8859 case BFD_RELOC_IA64_DIR64LSB: new = BFD_RELOC_IA64_GPREL64LSB; break;
8860 default: break;
8861 }
8862 break;
8863
8864 case FUNC_LT_RELATIVE:
8865 switch (r_type)
8866 {
8867 case BFD_RELOC_IA64_IMM22: new = BFD_RELOC_IA64_LTOFF22; break;
8868 case BFD_RELOC_IA64_IMM64: new = BFD_RELOC_IA64_LTOFF64I; break;
8869 default: break;
8870 }
8871 break;
8872
c67e42c9
RH
8873 case FUNC_PC_RELATIVE:
8874 switch (r_type)
8875 {
8876 case BFD_RELOC_IA64_IMM22: new = BFD_RELOC_IA64_PCREL22; break;
8877 case BFD_RELOC_IA64_IMM64: new = BFD_RELOC_IA64_PCREL64I; break;
8878 case BFD_RELOC_IA64_DIR32MSB: new = BFD_RELOC_IA64_PCREL32MSB; break;
8879 case BFD_RELOC_IA64_DIR32LSB: new = BFD_RELOC_IA64_PCREL32LSB; break;
8880 case BFD_RELOC_IA64_DIR64MSB: new = BFD_RELOC_IA64_PCREL64MSB; break;
8881 case BFD_RELOC_IA64_DIR64LSB: new = BFD_RELOC_IA64_PCREL64LSB; break;
8882 default: break;
8883 }
8884 break;
8885
800eeca4
JW
8886 case FUNC_PLT_RELATIVE:
8887 switch (r_type)
8888 {
8889 case BFD_RELOC_IA64_IMM22: new = BFD_RELOC_IA64_PLTOFF22; break;
8890 case BFD_RELOC_IA64_IMM64: new = BFD_RELOC_IA64_PLTOFF64I; break;
8891 case BFD_RELOC_IA64_DIR64MSB: new = BFD_RELOC_IA64_PLTOFF64MSB;break;
8892 case BFD_RELOC_IA64_DIR64LSB: new = BFD_RELOC_IA64_PLTOFF64LSB;break;
8893 default: break;
8894 }
8895 break;
8896
8897 case FUNC_SEC_RELATIVE:
8898 switch (r_type)
8899 {
8900 case BFD_RELOC_IA64_DIR32MSB: new = BFD_RELOC_IA64_SECREL32MSB;break;
8901 case BFD_RELOC_IA64_DIR32LSB: new = BFD_RELOC_IA64_SECREL32LSB;break;
8902 case BFD_RELOC_IA64_DIR64MSB: new = BFD_RELOC_IA64_SECREL64MSB;break;
8903 case BFD_RELOC_IA64_DIR64LSB: new = BFD_RELOC_IA64_SECREL64LSB;break;
8904 default: break;
8905 }
8906 break;
8907
8908 case FUNC_SEG_RELATIVE:
8909 switch (r_type)
8910 {
8911 case BFD_RELOC_IA64_DIR32MSB: new = BFD_RELOC_IA64_SEGREL32MSB;break;
8912 case BFD_RELOC_IA64_DIR32LSB: new = BFD_RELOC_IA64_SEGREL32LSB;break;
8913 case BFD_RELOC_IA64_DIR64MSB: new = BFD_RELOC_IA64_SEGREL64MSB;break;
8914 case BFD_RELOC_IA64_DIR64LSB: new = BFD_RELOC_IA64_SEGREL64LSB;break;
8915 default: break;
8916 }
8917 break;
8918
8919 case FUNC_LTV_RELATIVE:
8920 switch (r_type)
8921 {
8922 case BFD_RELOC_IA64_DIR32MSB: new = BFD_RELOC_IA64_LTV32MSB; break;
8923 case BFD_RELOC_IA64_DIR32LSB: new = BFD_RELOC_IA64_LTV32LSB; break;
8924 case BFD_RELOC_IA64_DIR64MSB: new = BFD_RELOC_IA64_LTV64MSB; break;
8925 case BFD_RELOC_IA64_DIR64LSB: new = BFD_RELOC_IA64_LTV64LSB; break;
8926 default: break;
8927 }
8928 break;
8929
8930 case FUNC_LT_FPTR_RELATIVE:
8931 switch (r_type)
8932 {
8933 case BFD_RELOC_IA64_IMM22:
8934 new = BFD_RELOC_IA64_LTOFF_FPTR22; break;
8935 case BFD_RELOC_IA64_IMM64:
8936 new = BFD_RELOC_IA64_LTOFF_FPTR64I; break;
8937 default:
8938 break;
8939 }
8940 break;
8941 default:
8942 abort ();
8943 }
8944 /* Hmmmm. Should this ever occur? */
8945 if (new)
8946 return new;
8947 else
8948 return r_type;
8949}
8950
8951/* Here is where generate the appropriate reloc for pseudo relocation
8952 functions. */
8953void
8954ia64_validate_fix (fix)
8955 fixS *fix;
8956{
8957 switch (fix->fx_r_type)
8958 {
8959 case BFD_RELOC_IA64_FPTR64I:
8960 case BFD_RELOC_IA64_FPTR32MSB:
8961 case BFD_RELOC_IA64_FPTR64LSB:
8962 case BFD_RELOC_IA64_LTOFF_FPTR22:
8963 case BFD_RELOC_IA64_LTOFF_FPTR64I:
8964 if (fix->fx_offset != 0)
8965 as_bad_where (fix->fx_file, fix->fx_line,
8966 "No addend allowed in @fptr() relocation");
8967 break;
8968 default:
8969 break;
8970 }
8971
8972 return;
8973}
8974
8975static void
8976fix_insn (fix, odesc, value)
8977 fixS *fix;
8978 const struct ia64_operand *odesc;
8979 valueT value;
8980{
8981 bfd_vma insn[3], t0, t1, control_bits;
8982 const char *err;
8983 char *fixpos;
8984 long slot;
8985
8986 slot = fix->fx_where & 0x3;
8987 fixpos = fix->fx_frag->fr_literal + (fix->fx_where - slot);
8988
c67e42c9 8989 /* Bundles are always in little-endian byte order */
800eeca4
JW
8990 t0 = bfd_getl64 (fixpos);
8991 t1 = bfd_getl64 (fixpos + 8);
8992 control_bits = t0 & 0x1f;
8993 insn[0] = (t0 >> 5) & 0x1ffffffffffLL;
8994 insn[1] = ((t0 >> 46) & 0x3ffff) | ((t1 & 0x7fffff) << 18);
8995 insn[2] = (t1 >> 23) & 0x1ffffffffffLL;
8996
c67e42c9
RH
8997 err = NULL;
8998 if (odesc - elf64_ia64_operands == IA64_OPND_IMMU64)
800eeca4 8999 {
c67e42c9
RH
9000 insn[1] = (value >> 22) & 0x1ffffffffffLL;
9001 insn[2] |= (((value & 0x7f) << 13)
9002 | (((value >> 7) & 0x1ff) << 27)
9003 | (((value >> 16) & 0x1f) << 22)
9004 | (((value >> 21) & 0x1) << 21)
9005 | (((value >> 63) & 0x1) << 36));
800eeca4 9006 }
c67e42c9
RH
9007 else if (odesc - elf64_ia64_operands == IA64_OPND_IMMU62)
9008 {
9009 if (value & ~0x3fffffffffffffffULL)
9010 err = "integer operand out of range";
9011 insn[1] = (value >> 21) & 0x1ffffffffffLL;
9012 insn[2] |= (((value & 0xfffff) << 6) | (((value >> 20) & 0x1) << 36));
9013 }
9014 else if (odesc - elf64_ia64_operands == IA64_OPND_TGT64)
9015 {
9016 value >>= 4;
9017 insn[1] = ((value >> 20) & 0x7fffffffffLL) << 2;
9018 insn[2] |= ((((value >> 59) & 0x1) << 36)
9019 | (((value >> 0) & 0xfffff) << 13));
9020 }
9021 else
9022 err = (*odesc->insert) (odesc, value, insn + slot);
9023
9024 if (err)
9025 as_bad_where (fix->fx_file, fix->fx_line, err);
800eeca4
JW
9026
9027 t0 = control_bits | (insn[0] << 5) | (insn[1] << 46);
9028 t1 = ((insn[1] >> 18) & 0x7fffff) | (insn[2] << 23);
9029 md_number_to_chars (fixpos + 0, t0, 8);
9030 md_number_to_chars (fixpos + 8, t1, 8);
800eeca4
JW
9031}
9032
9033/* Attempt to simplify or even eliminate a fixup. The return value is
9034 ignored; perhaps it was once meaningful, but now it is historical.
9035 To indicate that a fixup has been eliminated, set FIXP->FX_DONE.
9036
9037 If fixp->fx_addsy is non-NULL, we'll have to generate a reloc entry
9038 (if possible). */
9039int
9040md_apply_fix3 (fix, valuep, seg)
9041 fixS *fix;
9042 valueT *valuep;
9043 segT seg;
9044{
9045 char *fixpos;
9046 valueT value = *valuep;
9047 int adjust = 0;
9048
9049 fixpos = fix->fx_frag->fr_literal + fix->fx_where;
9050
9051 if (fix->fx_pcrel)
9052 {
9053 switch (fix->fx_r_type)
9054 {
9055 case BFD_RELOC_IA64_DIR32MSB:
9056 fix->fx_r_type = BFD_RELOC_IA64_PCREL32MSB;
9057 adjust = 1;
9058 break;
9059
9060 case BFD_RELOC_IA64_DIR32LSB:
9061 fix->fx_r_type = BFD_RELOC_IA64_PCREL32LSB;
9062 adjust = 1;
9063 break;
9064
9065 case BFD_RELOC_IA64_DIR64MSB:
9066 fix->fx_r_type = BFD_RELOC_IA64_PCREL64MSB;
9067 adjust = 1;
9068 break;
9069
9070 case BFD_RELOC_IA64_DIR64LSB:
9071 fix->fx_r_type = BFD_RELOC_IA64_PCREL64LSB;
9072 adjust = 1;
9073 break;
9074
9075 default:
9076 break;
9077 }
9078 }
9079 if (fix->fx_addsy)
9080 {
9081 switch (fix->fx_r_type)
9082 {
9083 case 0:
9084 as_bad_where (fix->fx_file, fix->fx_line,
9085 "%s must have a constant value",
9086 elf64_ia64_operands[fix->tc_fix_data.opnd].desc);
9087 break;
9088
9089 default:
9090 break;
9091 }
9092
9093 /* ??? This is a hack copied from tc-i386.c to make PCREL relocs
9094 work. There should be a better way to handle this. */
9095 if (adjust)
9096 fix->fx_offset += fix->fx_where + fix->fx_frag->fr_address;
9097 }
9098 else if (fix->tc_fix_data.opnd == IA64_OPND_NIL)
9099 {
9100 if (fix->tc_fix_data.bigendian)
9101 number_to_chars_bigendian (fixpos, value, fix->fx_size);
9102 else
9103 number_to_chars_littleendian (fixpos, value, fix->fx_size);
9104 fix->fx_done = 1;
9105 return 1;
9106 }
9107 else
9108 {
9109 fix_insn (fix, elf64_ia64_operands + fix->tc_fix_data.opnd, value);
9110 fix->fx_done = 1;
9111 return 1;
9112 }
9113 return 1;
9114}
9115
9116/* Generate the BFD reloc to be stuck in the object file from the
9117 fixup used internally in the assembler. */
9118arelent*
9119tc_gen_reloc (sec, fixp)
9120 asection *sec;
9121 fixS *fixp;
9122{
9123 arelent *reloc;
9124
9125 reloc = xmalloc (sizeof (*reloc));
9126 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
9127 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
9128 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
9129 reloc->addend = fixp->fx_offset;
9130 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
9131
9132 if (!reloc->howto)
9133 {
9134 as_bad_where (fixp->fx_file, fixp->fx_line,
9135 "Cannot represent %s relocation in object file",
9136 bfd_get_reloc_code_name (fixp->fx_r_type));
9137 }
9138 return reloc;
9139}
9140
9141/* Turn a string in input_line_pointer into a floating point constant
9142 of type type, and store the appropriate bytes in *lit. The number
9143 of LITTLENUMS emitted is stored in *size. An error message is
9144 returned, or NULL on OK. */
9145
9146#define MAX_LITTLENUMS 5
9147
9148char*
9149md_atof (type, lit, size)
9150 int type;
9151 char *lit;
9152 int *size;
9153{
9154 LITTLENUM_TYPE words[MAX_LITTLENUMS];
9155 LITTLENUM_TYPE *word;
9156 char *t;
9157 int prec;
9158
9159 switch (type)
9160 {
9161 /* IEEE floats */
9162 case 'f':
9163 case 'F':
9164 case 's':
9165 case 'S':
9166 prec = 2;
9167 break;
9168
9169 case 'd':
9170 case 'D':
9171 case 'r':
9172 case 'R':
9173 prec = 4;
9174 break;
9175
9176 case 'x':
9177 case 'X':
9178 case 'p':
9179 case 'P':
9180 prec = 5;
9181 break;
9182
9183 default:
9184 *size = 0;
9185 return "Bad call to MD_ATOF()";
9186 }
9187 t = atof_ieee (input_line_pointer, type, words);
9188 if (t)
9189 input_line_pointer = t;
9190 *size = prec * sizeof (LITTLENUM_TYPE);
9191
9192 for (word = words + prec - 1; prec--;)
9193 {
9194 md_number_to_chars (lit, (long) (*word--), sizeof (LITTLENUM_TYPE));
9195 lit += sizeof (LITTLENUM_TYPE);
9196 }
9197 return 0;
9198}
9199
9200/* Round up a section's size to the appropriate boundary. */
9201valueT
9202md_section_align (seg, size)
9203 segT seg;
9204 valueT size;
9205{
9206 int align = bfd_get_section_alignment (stdoutput, seg);
9207 valueT mask = ((valueT)1 << align) - 1;
9208
9209 return (size + mask) & ~mask;
9210}
9211
9212/* Handle ia64 specific semantics of the align directive. */
9213
9214int
9215ia64_md_do_align (n, fill, len, max)
9216 int n;
9217 const char *fill;
9218 int len;
9219 int max;
9220{
9221 /* Fill any pending bundle with nops. */
9222 if (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE)
9223 ia64_flush_insns ();
9224
9225 /* When we align code in a text section, emit a bundle of 3 nops instead of
9226 zero bytes. We can only do this if a multiple of 16 bytes was requested.
9227 N is log base 2 of the requested alignment. */
9228 if (fill == NULL
9229 && bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE
9230 && n > 4)
9231 {
9232 /* Use mfi bundle of nops with no stop bits. */
9233 static const unsigned char be_nop[]
9234 = { 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
9235 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c};
9236 static const unsigned char le_nop[]
9237 = { 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
9238 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00};
9239
9240 /* Make sure we are on a 16-byte boundary, in case someone has been
9241 putting data into a text section. */
9242 frag_align (4, 0, 0);
9243
9244 if (target_big_endian)
9245 frag_align_pattern (n, be_nop, 16, max);
9246 else
9247 frag_align_pattern (n, le_nop, 16, max);
9248 return 1;
9249 }
9250
9251 return 0;
9252}
This page took 0.972819 seconds and 4 git commands to generate.