* armemu.c (Multiply64): Fix computation of flag N.
[deliverable/binutils-gdb.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 <davidm@hpl.hp.com>
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 2944
10850f29
JW
2945 /* Force out pending instructions, to make sure all unwind records have
2946 a valid slot_number field. */
2947 ia64_flush_insns ();
2948
800eeca4 2949 /* Generate the unwind record. */
150f24a2 2950 size = output_unw_records (unwind.list, (void **) &unw_rec);
e0c9811a
JW
2951 if (size % 8 != 0)
2952 as_bad ("Unwind record is not a multiple of 8 bytes.");
800eeca4
JW
2953
2954 /* If there are unwind records, switch sections, and output the info. */
2955 if (size != 0)
2956 {
800eeca4 2957 unsigned char *where;
800eeca4 2958 expressionS exp;
800eeca4
JW
2959 set_section ((char *) special_section_name[SPECIAL_SECTION_UNWIND_INFO]);
2960
2961 /* Set expression which points to start of unwind descriptor area. */
e0c9811a 2962 unwind.info = expr_build_dot ();
800eeca4
JW
2963
2964 where = (unsigned char *)frag_more (size);
2965
2966 /* Issue a label for this address, and keep track of it to put it
2967 in the unwind section. */
2968
2969 /* Copy the information from the unwind record into this section. The
2970 data is already in the correct byte order. */
2971 memcpy (where, unw_rec, size);
2972 /* Add the personality address to the image. */
e0c9811a 2973 if (unwind.personality_routine != 0)
800eeca4
JW
2974 {
2975 exp.X_op = O_symbol;
e0c9811a 2976 exp.X_add_symbol = unwind.personality_routine;
800eeca4
JW
2977 exp.X_add_number = 0;
2978 fix_new_exp (frag_now, frag_now_fix () - 8, 8,
2979 &exp, 0, BFD_RELOC_IA64_LTOFF_FPTR64LSB);
e0c9811a 2980 unwind.personality_routine = 0;
800eeca4
JW
2981 }
2982 obj_elf_previous (0);
2983 }
2984
e0c9811a
JW
2985 free_list_records (unwind.list);
2986 unwind.list = unwind.tail = unwind.current_entry = NULL;
800eeca4
JW
2987
2988 return size;
2989}
2990
2991static void
2992dot_handlerdata (dummy)
2993 int dummy;
2994{
2995 generate_unwind_image ();
e0c9811a 2996 demand_empty_rest_of_line ();
800eeca4
JW
2997}
2998
2999static void
3000dot_unwentry (dummy)
3001 int dummy;
3002{
e0c9811a 3003 demand_empty_rest_of_line ();
800eeca4
JW
3004}
3005
3006static void
3007dot_altrp (dummy)
3008 int dummy;
3009{
e0c9811a
JW
3010 expressionS e;
3011 unsigned reg;
3012
3013 parse_operand (&e);
3014 reg = e.X_add_number - REG_BR;
3015 if (e.X_op == O_register && reg < 8)
3016 add_unwind_entry (output_rp_br (reg));
3017 else
3018 as_bad ("First operand not a valid branch register");
800eeca4
JW
3019}
3020
3021static void
e0c9811a
JW
3022dot_savemem (psprel)
3023 int psprel;
800eeca4
JW
3024{
3025 expressionS e1, e2;
3026 int sep;
3027 int reg1, val;
3028
3029 sep = parse_operand (&e1);
3030 if (sep != ',')
e0c9811a 3031 as_bad ("No second operand to .save%ssp", psprel ? "p" : "");
800eeca4
JW
3032 sep = parse_operand (&e2);
3033
e0c9811a 3034 reg1 = e1.X_add_number;
800eeca4
JW
3035 val = e2.X_add_number;
3036
3037 /* Make sure its a valid ar.xxx reg, OR its br0, aka 'rp'. */
e0c9811a 3038 if (e1.X_op == O_register)
800eeca4
JW
3039 {
3040 if (e2.X_op == O_constant)
3041 {
3042 switch (reg1)
3043 {
e0c9811a 3044 case REG_AR + AR_BSP:
800eeca4 3045 add_unwind_entry (output_bsp_when ());
e0c9811a
JW
3046 add_unwind_entry ((psprel
3047 ? output_bsp_psprel
3048 : output_bsp_sprel) (val));
800eeca4 3049 break;
e0c9811a 3050 case REG_AR + AR_BSPSTORE:
800eeca4 3051 add_unwind_entry (output_bspstore_when ());
e0c9811a
JW
3052 add_unwind_entry ((psprel
3053 ? output_bspstore_psprel
3054 : output_bspstore_sprel) (val));
800eeca4 3055 break;
e0c9811a 3056 case REG_AR + AR_RNAT:
800eeca4 3057 add_unwind_entry (output_rnat_when ());
e0c9811a
JW
3058 add_unwind_entry ((psprel
3059 ? output_rnat_psprel
3060 : output_rnat_sprel) (val));
800eeca4 3061 break;
e0c9811a 3062 case REG_AR + AR_UNAT:
800eeca4 3063 add_unwind_entry (output_unat_when ());
e0c9811a
JW
3064 add_unwind_entry ((psprel
3065 ? output_unat_psprel
3066 : output_unat_sprel) (val));
800eeca4 3067 break;
e0c9811a 3068 case REG_AR + AR_FPSR:
800eeca4 3069 add_unwind_entry (output_fpsr_when ());
e0c9811a
JW
3070 add_unwind_entry ((psprel
3071 ? output_fpsr_psprel
3072 : output_fpsr_sprel) (val));
800eeca4 3073 break;
e0c9811a 3074 case REG_AR + AR_PFS:
800eeca4 3075 add_unwind_entry (output_pfs_when ());
e0c9811a
JW
3076 add_unwind_entry ((psprel
3077 ? output_pfs_psprel
3078 : output_pfs_sprel) (val));
800eeca4 3079 break;
e0c9811a 3080 case REG_AR + AR_LC:
800eeca4 3081 add_unwind_entry (output_lc_when ());
e0c9811a
JW
3082 add_unwind_entry ((psprel
3083 ? output_lc_psprel
3084 : output_lc_sprel) (val));
800eeca4 3085 break;
e0c9811a 3086 case REG_BR:
800eeca4 3087 add_unwind_entry (output_rp_when ());
e0c9811a
JW
3088 add_unwind_entry ((psprel
3089 ? output_rp_psprel
3090 : output_rp_sprel) (val));
800eeca4 3091 break;
e0c9811a 3092 case REG_PR:
800eeca4 3093 add_unwind_entry (output_preds_when ());
e0c9811a
JW
3094 add_unwind_entry ((psprel
3095 ? output_preds_psprel
3096 : output_preds_sprel) (val));
3097 break;
3098 case REG_PRIUNAT:
3099 add_unwind_entry (output_priunat_when_mem ());
3100 add_unwind_entry ((psprel
3101 ? output_priunat_psprel
3102 : output_priunat_sprel) (val));
800eeca4
JW
3103 break;
3104 default:
e0c9811a 3105 as_bad ("First operand not a valid register");
800eeca4
JW
3106 }
3107 }
3108 else
3109 as_bad (" Second operand not a valid constant");
3110 }
3111 else
e0c9811a 3112 as_bad ("First operand not a register");
800eeca4
JW
3113}
3114
3115static void
3116dot_saveg (dummy)
3117 int dummy;
3118{
3119 expressionS e1, e2;
3120 int sep;
3121 sep = parse_operand (&e1);
3122 if (sep == ',')
3123 parse_operand (&e2);
3124
3125 if (e1.X_op != O_constant)
3126 as_bad ("First operand to .save.g must be a constant.");
3127 else
3128 {
3129 int grmask = e1.X_add_number;
3130 if (sep != ',')
3131 add_unwind_entry (output_gr_mem (grmask));
3132 else
3133 {
3134 int reg = e2.X_add_number - REG_GR;
3135 if (e2.X_op == O_register && reg >=0 && reg < 128)
3136 add_unwind_entry (output_gr_gr (grmask, reg));
3137 else
3138 as_bad ("Second operand is an invalid register.");
3139 }
3140 }
3141}
3142
3143static void
3144dot_savef (dummy)
3145 int dummy;
3146{
e0c9811a 3147 expressionS e1;
800eeca4
JW
3148 int sep;
3149 sep = parse_operand (&e1);
3150
3151 if (e1.X_op != O_constant)
3152 as_bad ("Operand to .save.f must be a constant.");
3153 else
e0c9811a 3154 add_unwind_entry (output_fr_mem (e1.X_add_number));
800eeca4
JW
3155}
3156
3157static void
3158dot_saveb (dummy)
3159 int dummy;
3160{
e0c9811a
JW
3161 expressionS e1, e2;
3162 unsigned int reg;
3163 unsigned char sep;
3164 int brmask;
3165
800eeca4 3166 sep = parse_operand (&e1);
800eeca4 3167 if (e1.X_op != O_constant)
800eeca4 3168 {
e0c9811a
JW
3169 as_bad ("First operand to .save.b must be a constant.");
3170 return;
800eeca4 3171 }
e0c9811a
JW
3172 brmask = e1.X_add_number;
3173
3174 if (sep == ',')
3175 {
3176 sep = parse_operand (&e2);
3177 reg = e2.X_add_number - REG_GR;
3178 if (e2.X_op != O_register || reg > 127)
3179 {
3180 as_bad ("Second operand to .save.b must be a general register.");
3181 return;
3182 }
3183 add_unwind_entry (output_br_gr (brmask, e2.X_add_number));
3184 }
3185 else
3186 add_unwind_entry (output_br_mem (brmask));
3187
3188 if (!is_end_of_line[sep] && !is_it_end_of_statement ())
3189 ignore_rest_of_line ();
800eeca4
JW
3190}
3191
3192static void
3193dot_savegf (dummy)
3194 int dummy;
3195{
3196 expressionS e1, e2;
3197 int sep;
3198 sep = parse_operand (&e1);
3199 if (sep == ',')
3200 parse_operand (&e2);
3201
3202 if (e1.X_op != O_constant || sep != ',' || e2.X_op != O_constant)
3203 as_bad ("Both operands of .save.gf must be constants.");
3204 else
3205 {
3206 int grmask = e1.X_add_number;
3207 int frmask = e2.X_add_number;
3208 add_unwind_entry (output_frgr_mem (grmask, frmask));
3209 }
3210}
3211
3212static void
3213dot_spill (dummy)
3214 int dummy;
3215{
3216 expressionS e;
e0c9811a
JW
3217 unsigned char sep;
3218
3219 sep = parse_operand (&e);
3220 if (!is_end_of_line[sep] && !is_it_end_of_statement ())
3221 ignore_rest_of_line ();
800eeca4
JW
3222
3223 if (e.X_op != O_constant)
3224 as_bad ("Operand to .spill must be a constant");
3225 else
e0c9811a
JW
3226 add_unwind_entry (output_spill_base (e.X_add_number));
3227}
3228
3229static void
3230dot_spillreg (dummy)
3231 int dummy;
3232{
3233 int sep, ab, xy, reg, treg;
3234 expressionS e1, e2;
3235
3236 sep = parse_operand (&e1);
3237 if (sep != ',')
3238 {
3239 as_bad ("No second operand to .spillreg");
3240 return;
3241 }
3242
3243 parse_operand (&e2);
3244
3245 if (!convert_expr_to_ab_reg (&e1, &ab, &reg))
800eeca4 3246 {
e0c9811a
JW
3247 as_bad ("First operand to .spillreg must be a preserved register");
3248 return;
800eeca4 3249 }
e0c9811a
JW
3250
3251 if (!convert_expr_to_xy_reg (&e2, &xy, &treg))
3252 {
3253 as_bad ("Second operand to .spillreg must be a register");
3254 return;
3255 }
3256
3257 add_unwind_entry (output_spill_reg (ab, reg, treg, xy));
3258}
3259
3260static void
3261dot_spillmem (psprel)
3262 int psprel;
3263{
3264 expressionS e1, e2;
3265 int sep, ab, reg;
3266
3267 sep = parse_operand (&e1);
3268 if (sep != ',')
3269 {
3270 as_bad ("Second operand missing");
3271 return;
3272 }
3273
3274 parse_operand (&e2);
3275
3276 if (!convert_expr_to_ab_reg (&e1, &ab, &reg))
3277 {
3278 as_bad ("First operand to .spill%s must be a preserved register",
3279 psprel ? "psp" : "sp");
3280 return;
3281 }
3282
3283 if (e2.X_op != O_constant)
3284 {
3285 as_bad ("Second operand to .spill%s must be a constant",
3286 psprel ? "psp" : "sp");
3287 return;
3288 }
3289
3290 if (psprel)
3291 add_unwind_entry (output_spill_psprel (ab, reg, e2.X_add_number));
3292 else
3293 add_unwind_entry (output_spill_sprel (ab, reg, e2.X_add_number));
3294}
3295
3296static void
3297dot_spillreg_p (dummy)
3298 int dummy;
3299{
3300 int sep, ab, xy, reg, treg;
3301 expressionS e1, e2, e3;
3302 unsigned int qp;
3303
3304 sep = parse_operand (&e1);
3305 if (sep != ',')
3306 {
3307 as_bad ("No second and third operand to .spillreg.p");
3308 return;
3309 }
3310
3311 sep = parse_operand (&e2);
3312 if (sep != ',')
3313 {
3314 as_bad ("No third operand to .spillreg.p");
3315 return;
3316 }
3317
3318 parse_operand (&e3);
3319
3320 qp = e1.X_add_number - REG_P;
3321
3322 if (e1.X_op != O_register || qp > 63)
3323 {
3324 as_bad ("First operand to .spillreg.p must be a predicate");
3325 return;
3326 }
3327
3328 if (!convert_expr_to_ab_reg (&e2, &ab, &reg))
3329 {
3330 as_bad ("Second operand to .spillreg.p must be a preserved register");
3331 return;
3332 }
3333
3334 if (!convert_expr_to_xy_reg (&e3, &xy, &treg))
3335 {
3336 as_bad ("Third operand to .spillreg.p must be a register");
3337 return;
3338 }
3339
3340 add_unwind_entry (output_spill_reg_p (ab, reg, treg, xy, qp));
3341}
3342
3343static void
3344dot_spillmem_p (psprel)
3345 int psprel;
3346{
3347 expressionS e1, e2, e3;
3348 int sep, ab, reg;
3349 unsigned int qp;
3350
3351 sep = parse_operand (&e1);
3352 if (sep != ',')
3353 {
3354 as_bad ("Second operand missing");
3355 return;
3356 }
3357
3358 parse_operand (&e2);
3359 if (sep != ',')
3360 {
3361 as_bad ("Second operand missing");
3362 return;
3363 }
3364
3365 parse_operand (&e3);
3366
3367 qp = e1.X_add_number - REG_P;
3368 if (e1.X_op != O_register || qp > 63)
3369 {
3370 as_bad ("First operand to .spill%s_p must be a predicate",
3371 psprel ? "psp" : "sp");
3372 return;
3373 }
3374
3375 if (!convert_expr_to_ab_reg (&e2, &ab, &reg))
3376 {
3377 as_bad ("Second operand to .spill%s_p must be a preserved register",
3378 psprel ? "psp" : "sp");
3379 return;
3380 }
3381
3382 if (e3.X_op != O_constant)
3383 {
3384 as_bad ("Third operand to .spill%s_p must be a constant",
3385 psprel ? "psp" : "sp");
3386 return;
3387 }
3388
3389 if (psprel)
3390 add_unwind_entry (output_spill_psprel_p (qp, ab, reg, e3.X_add_number));
3391 else
3392 add_unwind_entry (output_spill_sprel_p (qp, ab, reg, e3.X_add_number));
3393}
3394
3395static void
3396dot_label_state (dummy)
3397 int dummy;
3398{
3399 expressionS e;
3400
3401 parse_operand (&e);
3402 if (e.X_op != O_constant)
3403 {
3404 as_bad ("Operand to .label_state must be a constant");
3405 return;
3406 }
3407 add_unwind_entry (output_label_state (e.X_add_number));
3408}
3409
3410static void
3411dot_copy_state (dummy)
3412 int dummy;
3413{
3414 expressionS e;
3415
3416 parse_operand (&e);
3417 if (e.X_op != O_constant)
3418 {
3419 as_bad ("Operand to .copy_state must be a constant");
3420 return;
3421 }
3422 add_unwind_entry (output_copy_state (e.X_add_number));
800eeca4
JW
3423}
3424
3425static void
3426dot_unwabi (dummy)
3427 int dummy;
3428{
e0c9811a
JW
3429 expressionS e1, e2;
3430 unsigned char sep;
3431
3432 sep = parse_operand (&e1);
3433 if (sep != ',')
3434 {
3435 as_bad ("Second operand to .unwabi missing");
3436 return;
3437 }
3438 sep = parse_operand (&e2);
3439 if (!is_end_of_line[sep] && !is_it_end_of_statement ())
3440 ignore_rest_of_line ();
3441
3442 if (e1.X_op != O_constant)
3443 {
3444 as_bad ("First operand to .unwabi must be a constant");
3445 return;
3446 }
3447
3448 if (e2.X_op != O_constant)
3449 {
3450 as_bad ("Second operand to .unwabi must be a constant");
3451 return;
3452 }
3453
3454 add_unwind_entry (output_unwabi (e1.X_add_number, e2.X_add_number));
800eeca4
JW
3455}
3456
3457static void
3458dot_personality (dummy)
3459 int dummy;
3460{
3461 char *name, *p, c;
3462 SKIP_WHITESPACE ();
3463 name = input_line_pointer;
3464 c = get_symbol_end ();
3465 p = input_line_pointer;
e0c9811a 3466 unwind.personality_routine = symbol_find_or_make (name);
800eeca4
JW
3467 *p = c;
3468 SKIP_WHITESPACE ();
3469 demand_empty_rest_of_line ();
3470}
3471
3472static void
3473dot_proc (dummy)
3474 int dummy;
3475{
3476 char *name, *p, c;
3477 symbolS *sym;
3478
e0c9811a
JW
3479 unwind.proc_start = expr_build_dot ();
3480 /* Parse names of main and alternate entry points and mark them as
800eeca4
JW
3481 function symbols: */
3482 while (1)
3483 {
3484 SKIP_WHITESPACE ();
3485 name = input_line_pointer;
3486 c = get_symbol_end ();
3487 p = input_line_pointer;
3488 sym = symbol_find_or_make (name);
e0c9811a 3489 if (unwind.proc_start == 0)
800eeca4 3490 {
e0c9811a 3491 unwind.proc_start = sym;
800eeca4
JW
3492 }
3493 symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION;
3494 *p = c;
3495 SKIP_WHITESPACE ();
3496 if (*input_line_pointer != ',')
3497 break;
3498 ++input_line_pointer;
3499 }
3500 demand_empty_rest_of_line ();
3501 ia64_do_align (16);
3502
e0c9811a
JW
3503 unwind.list = unwind.tail = unwind.current_entry = NULL;
3504 unwind.personality_routine = 0;
800eeca4
JW
3505}
3506
3507static void
3508dot_body (dummy)
3509 int dummy;
3510{
e0c9811a 3511 unwind.prologue = 0;
800eeca4 3512 add_unwind_entry (output_body ());
e0c9811a 3513 demand_empty_rest_of_line ();
800eeca4
JW
3514}
3515
3516static void
3517dot_prologue (dummy)
3518 int dummy;
3519{
e0c9811a
JW
3520 unsigned char sep;
3521
3522 unwind.prologue = 1;
3523 if (!is_it_end_of_statement ())
800eeca4
JW
3524 {
3525 expressionS e1, e2;
800eeca4
JW
3526 sep = parse_operand (&e1);
3527 if (sep != ',')
3528 as_bad ("No second operand to .prologue");
3529 sep = parse_operand (&e2);
e0c9811a
JW
3530 if (!is_end_of_line[sep] && !is_it_end_of_statement ())
3531 ignore_rest_of_line ();
800eeca4
JW
3532
3533 if (e1.X_op == O_constant)
3534 {
3535 if (e2.X_op == O_constant)
3536 {
3537 int mask = e1.X_add_number;
3538 int reg = e2.X_add_number;
3539 add_unwind_entry (output_prologue_gr (mask, reg));
3540 }
3541 else
3542 as_bad ("Second operand not a constant");
3543 }
3544 else
3545 as_bad ("First operand not a constant");
3546 }
3547 else
3548 add_unwind_entry (output_prologue ());
3549}
3550
3551static void
3552dot_endp (dummy)
3553 int dummy;
3554{
3555 expressionS e;
3556 unsigned char *ptr;
800eeca4
JW
3557 long where;
3558 segT saved_seg;
3559 subsegT saved_subseg;
3560
3561 saved_seg = now_seg;
3562 saved_subseg = now_subseg;
3563
3564 expression (&e);
3565 demand_empty_rest_of_line ();
3566
3567 insn_group_break (1, 0, 0);
800eeca4
JW
3568
3569 /* If there was a .handlerdata, we haven't generated an image yet. */
e0c9811a 3570 if (unwind.info == 0)
800eeca4
JW
3571 {
3572 generate_unwind_image ();
3573 }
3574
3575 subseg_set (md.last_text_seg, 0);
e0c9811a 3576 unwind.proc_end = expr_build_dot ();
800eeca4
JW
3577
3578 set_section ((char *) special_section_name[SPECIAL_SECTION_UNWIND]);
3579 ptr = frag_more (24);
3580 where = frag_now_fix () - 24;
3581
3582 /* Issue the values of a) Proc Begin, b) Proc End, c) Unwind Record. */
3583 e.X_op = O_pseudo_fixup;
3584 e.X_op_symbol = pseudo_func[FUNC_SEG_RELATIVE].u.sym;
3585 e.X_add_number = 0;
e0c9811a 3586 e.X_add_symbol = unwind.proc_start;
800eeca4
JW
3587 ia64_cons_fix_new (frag_now, where, 8, &e);
3588
3589 e.X_op = O_pseudo_fixup;
3590 e.X_op_symbol = pseudo_func[FUNC_SEG_RELATIVE].u.sym;
3591 e.X_add_number = 0;
e0c9811a 3592 e.X_add_symbol = unwind.proc_end;
800eeca4
JW
3593 ia64_cons_fix_new (frag_now, where + 8, 8, &e);
3594
e0c9811a 3595 if (unwind.info != 0)
800eeca4
JW
3596 {
3597 e.X_op = O_pseudo_fixup;
3598 e.X_op_symbol = pseudo_func[FUNC_SEG_RELATIVE].u.sym;
3599 e.X_add_number = 0;
e0c9811a 3600 e.X_add_symbol = unwind.info;
800eeca4
JW
3601 ia64_cons_fix_new (frag_now, where + 16, 8, &e);
3602 }
3603 else
3604 md_number_to_chars (ptr + 16, 0, 8);
3605
3606 subseg_set (saved_seg, saved_subseg);
e0c9811a 3607 unwind.proc_start = unwind.proc_end = unwind.info = 0;
800eeca4
JW
3608}
3609
3610static void
3611dot_template (template)
3612 int template;
3613{
3614 CURR_SLOT.user_template = template;
3615}
3616
3617static void
3618dot_regstk (dummy)
3619 int dummy;
3620{
3621 int ins, locs, outs, rots;
3622
3623 if (is_it_end_of_statement ())
3624 ins = locs = outs = rots = 0;
3625 else
3626 {
3627 ins = get_absolute_expression ();
3628 if (*input_line_pointer++ != ',')
3629 goto err;
3630 locs = get_absolute_expression ();
3631 if (*input_line_pointer++ != ',')
3632 goto err;
3633 outs = get_absolute_expression ();
3634 if (*input_line_pointer++ != ',')
3635 goto err;
3636 rots = get_absolute_expression ();
3637 }
3638 set_regstack (ins, locs, outs, rots);
3639 return;
3640
3641 err:
3642 as_bad ("Comma expected");
3643 ignore_rest_of_line ();
3644}
3645
3646static void
3647dot_rot (type)
3648 int type;
3649{
3650 unsigned num_regs, num_alloced = 0;
3651 struct dynreg **drpp, *dr;
3652 int ch, base_reg = 0;
3653 char *name, *start;
3654 size_t len;
3655
3656 switch (type)
3657 {
3658 case DYNREG_GR: base_reg = REG_GR + 32; break;
3659 case DYNREG_FR: base_reg = REG_FR + 32; break;
3660 case DYNREG_PR: base_reg = REG_P + 16; break;
3661 default: break;
3662 }
3663
3664 /* first, remove existing names from hash table: */
3665 for (dr = md.dynreg[type]; dr && dr->num_regs; dr = dr->next)
3666 {
3667 hash_delete (md.dynreg_hash, dr->name);
3668 dr->num_regs = 0;
3669 }
3670
3671 drpp = &md.dynreg[type];
3672 while (1)
3673 {
3674 start = input_line_pointer;
3675 ch = get_symbol_end ();
3676 *input_line_pointer = ch;
3677 len = (input_line_pointer - start);
3678
3679 SKIP_WHITESPACE ();
3680 if (*input_line_pointer != '[')
3681 {
3682 as_bad ("Expected '['");
3683 goto err;
3684 }
3685 ++input_line_pointer; /* skip '[' */
3686
3687 num_regs = get_absolute_expression ();
3688
3689 if (*input_line_pointer++ != ']')
3690 {
3691 as_bad ("Expected ']'");
3692 goto err;
3693 }
3694 SKIP_WHITESPACE ();
3695
3696 num_alloced += num_regs;
3697 switch (type)
3698 {
3699 case DYNREG_GR:
3700 if (num_alloced > md.rot.num_regs)
3701 {
3702 as_bad ("Used more than the declared %d rotating registers",
3703 md.rot.num_regs);
3704 goto err;
3705 }
3706 break;
3707 case DYNREG_FR:
3708 if (num_alloced > 96)
3709 {
3710 as_bad ("Used more than the available 96 rotating registers");
3711 goto err;
3712 }
3713 break;
3714 case DYNREG_PR:
3715 if (num_alloced > 48)
3716 {
3717 as_bad ("Used more than the available 48 rotating registers");
3718 goto err;
3719 }
3720 break;
3721
3722 default:
3723 break;
3724 }
3725
3726 name = obstack_alloc (&notes, len + 1);
3727 memcpy (name, start, len);
3728 name[len] = '\0';
3729
3730 if (!*drpp)
3731 {
3732 *drpp = obstack_alloc (&notes, sizeof (*dr));
3733 memset (*drpp, 0, sizeof (*dr));
3734 }
3735
3736 dr = *drpp;
3737 dr->name = name;
3738 dr->num_regs = num_regs;
3739 dr->base = base_reg;
3740 drpp = &dr->next;
3741 base_reg += num_regs;
3742
3743 if (hash_insert (md.dynreg_hash, name, dr))
3744 {
3745 as_bad ("Attempt to redefine register set `%s'", name);
3746 goto err;
3747 }
3748
3749 if (*input_line_pointer != ',')
3750 break;
3751 ++input_line_pointer; /* skip comma */
3752 SKIP_WHITESPACE ();
3753 }
3754 demand_empty_rest_of_line ();
3755 return;
3756
3757 err:
3758 ignore_rest_of_line ();
3759}
3760
3761static void
3762dot_byteorder (byteorder)
3763 int byteorder;
3764{
3765 target_big_endian = byteorder;
3766}
3767
3768static void
3769dot_psr (dummy)
3770 int dummy;
3771{
3772 char *option;
3773 int ch;
3774
3775 while (1)
3776 {
3777 option = input_line_pointer;
3778 ch = get_symbol_end ();
3779 if (strcmp (option, "lsb") == 0)
3780 md.flags &= ~EF_IA_64_BE;
3781 else if (strcmp (option, "msb") == 0)
3782 md.flags |= EF_IA_64_BE;
3783 else if (strcmp (option, "abi32") == 0)
3784 md.flags &= ~EF_IA_64_ABI64;
3785 else if (strcmp (option, "abi64") == 0)
3786 md.flags |= EF_IA_64_ABI64;
3787 else
3788 as_bad ("Unknown psr option `%s'", option);
3789 *input_line_pointer = ch;
3790
3791 SKIP_WHITESPACE ();
3792 if (*input_line_pointer != ',')
3793 break;
3794
3795 ++input_line_pointer;
3796 SKIP_WHITESPACE ();
3797 }
3798 demand_empty_rest_of_line ();
3799}
3800
3801static void
3802dot_alias (dummy)
3803 int dummy;
3804{
3805 as_bad (".alias not implemented yet");
3806}
3807
3808static void
3809dot_ln (dummy)
3810 int dummy;
3811{
3812 new_logical_line (0, get_absolute_expression ());
3813 demand_empty_rest_of_line ();
3814}
3815
3816static char*
3817parse_section_name ()
3818{
3819 char *name;
3820 int len;
3821
3822 SKIP_WHITESPACE ();
3823 if (*input_line_pointer != '"')
3824 {
3825 as_bad ("Missing section name");
3826 ignore_rest_of_line ();
3827 return 0;
3828 }
3829 name = demand_copy_C_string (&len);
3830 if (!name)
3831 {
3832 ignore_rest_of_line ();
3833 return 0;
3834 }
3835 SKIP_WHITESPACE ();
3836 if (*input_line_pointer != ',')
3837 {
3838 as_bad ("Comma expected after section name");
3839 ignore_rest_of_line ();
3840 return 0;
3841 }
3842 ++input_line_pointer; /* skip comma */
3843 return name;
3844}
3845
3846static void
3847dot_xdata (size)
3848 int size;
3849{
3850 char *name = parse_section_name ();
3851 if (!name)
3852 return;
3853
3854 set_section (name);
3855 cons (size);
3856 obj_elf_previous (0);
3857}
3858
3859/* Why doesn't float_cons() call md_cons_align() the way cons() does? */
3860static void
3861stmt_float_cons (kind)
3862 int kind;
3863{
3864 size_t size;
3865
3866 switch (kind)
3867 {
3868 case 'd': size = 8; break;
3869 case 'x': size = 10; break;
3870
3871 case 'f':
3872 default:
3873 size = 4;
3874 break;
3875 }
3876 ia64_do_align (size);
3877 float_cons (kind);
3878}
3879
3880static void
3881stmt_cons_ua (size)
3882 int size;
3883{
3884 int saved_auto_align = md.auto_align;
3885
3886 md.auto_align = 0;
3887 cons (size);
3888 md.auto_align = saved_auto_align;
3889}
3890
3891static void
3892dot_xfloat_cons (kind)
3893 int kind;
3894{
3895 char *name = parse_section_name ();
3896 if (!name)
3897 return;
3898
3899 set_section (name);
3900 stmt_float_cons (kind);
3901 obj_elf_previous (0);
3902}
3903
3904static void
3905dot_xstringer (zero)
3906 int zero;
3907{
3908 char *name = parse_section_name ();
3909 if (!name)
3910 return;
3911
3912 set_section (name);
3913 stringer (zero);
3914 obj_elf_previous (0);
3915}
3916
3917static void
3918dot_xdata_ua (size)
3919 int size;
3920{
3921 int saved_auto_align = md.auto_align;
3922 char *name = parse_section_name ();
3923 if (!name)
3924 return;
3925
3926 set_section (name);
3927 md.auto_align = 0;
3928 cons (size);
3929 md.auto_align = saved_auto_align;
3930 obj_elf_previous (0);
3931}
3932
3933static void
3934dot_xfloat_cons_ua (kind)
3935 int kind;
3936{
3937 int saved_auto_align = md.auto_align;
3938 char *name = parse_section_name ();
3939 if (!name)
3940 return;
3941
3942 set_section (name);
3943 md.auto_align = 0;
3944 stmt_float_cons (kind);
3945 md.auto_align = saved_auto_align;
3946 obj_elf_previous (0);
3947}
3948
3949/* .reg.val <regname>,value */
3950static void
3951dot_reg_val (dummy)
3952 int dummy;
3953{
3954 expressionS reg;
3955
3956 expression (&reg);
3957 if (reg.X_op != O_register)
3958 {
3959 as_bad (_("Register name expected"));
3960 ignore_rest_of_line ();
3961 }
3962 else if (*input_line_pointer++ != ',')
3963 {
3964 as_bad (_("Comma expected"));
3965 ignore_rest_of_line ();
3966 }
3967 else
3968 {
3969 valueT value = get_absolute_expression ();
3970 int regno = reg.X_add_number;
3971 if (regno < REG_GR || regno > REG_GR+128)
3972 as_warn (_("Register value annotation ignored"));
3973 else
3974 {
3975 gr_values[regno-REG_GR].known = 1;
3976 gr_values[regno-REG_GR].value = value;
3977 gr_values[regno-REG_GR].path = md.path;
3978 }
3979 }
3980 demand_empty_rest_of_line ();
3981}
3982
3983/* select dv checking mode
3984 .auto
3985 .explicit
3986 .default
3987
3988 A stop is inserted when changing modes
3989 */
3990static void
3991dot_dv_mode (type)
3992 int type;
3993{
3994 if (md.manual_bundling)
3995 as_warn (_("Directive invalid within a bundle"));
3996
3997 if (type == 'E' || type == 'A')
3998 md.mode_explicitly_set = 0;
3999 else
4000 md.mode_explicitly_set = 1;
4001
4002 md.detect_dv = 1;
4003 switch (type)
4004 {
4005 case 'A':
4006 case 'a':
4007 if (md.explicit_mode)
4008 insn_group_break (1, 0, 0);
4009 md.explicit_mode = 0;
4010 break;
4011 case 'E':
4012 case 'e':
4013 if (!md.explicit_mode)
4014 insn_group_break (1, 0, 0);
4015 md.explicit_mode = 1;
4016 break;
4017 default:
4018 case 'd':
4019 if (md.explicit_mode != md.default_explicit_mode)
4020 insn_group_break (1, 0, 0);
4021 md.explicit_mode = md.default_explicit_mode;
4022 md.mode_explicitly_set = 0;
4023 break;
4024 }
4025}
4026
4027static void
4028print_prmask (mask)
4029 valueT mask;
4030{
4031 int regno;
4032 char *comma = "";
4033 for (regno = 0;regno < 64;regno++)
4034 {
4035 if (mask & ((valueT)1<<regno))
4036 {
4037 fprintf (stderr, "%s p%d", comma, regno);
4038 comma = ",";
4039 }
4040 }
4041}
4042
4043/*
4044 .pred.rel.clear [p1 [,p2 [,...]]] (also .pred.rel "clear")
4045 .pred.rel.imply p1, p2 (also .pred.rel "imply")
4046 .pred.rel.mutex p1, p2 [,...] (also .pred.rel "mutex")
4047 .pred.safe_across_calls p1 [, p2 [,...]]
4048 */
4049static void
4050dot_pred_rel (type)
4051 int type;
4052{
4053 valueT mask = 0;
4054 int count = 0;
4055 int p1 = -1, p2 = -1;
4056
4057 if (type == 0)
4058 {
4059 if (*input_line_pointer != '"')
4060 {
4061 as_bad (_("Missing predicate relation type"));
4062 ignore_rest_of_line ();
4063 return;
4064 }
4065 else
4066 {
4067 int len;
4068 char *form = demand_copy_C_string (&len);
4069 if (strcmp (form, "mutex") == 0)
4070 type = 'm';
4071 else if (strcmp (form, "clear") == 0)
4072 type = 'c';
4073 else if (strcmp (form, "imply") == 0)
4074 type = 'i';
4075 else
4076 {
4077 as_bad (_("Unrecognized predicate relation type"));
4078 ignore_rest_of_line ();
4079 return;
4080 }
4081 }
4082 if (*input_line_pointer == ',')
4083 ++input_line_pointer;
4084 SKIP_WHITESPACE ();
4085 }
4086
4087 SKIP_WHITESPACE ();
4088 while (1)
4089 {
4090 valueT bit = 1;
4091 int regno;
4092
4093 if (toupper (*input_line_pointer) != 'P'
4094 || (regno = atoi (++input_line_pointer)) < 0
4095 || regno > 63)
4096 {
4097 as_bad (_("Predicate register expected"));
4098 ignore_rest_of_line ();
4099 return;
4100 }
4101 while (isdigit (*input_line_pointer))
4102 ++input_line_pointer;
4103 if (p1 == -1)
4104 p1 = regno;
4105 else if (p2 == -1)
4106 p2 = regno;
4107 bit <<= regno;
4108 if (mask & bit)
4109 as_warn (_("Duplicate predicate register ignored"));
4110 mask |= bit; count++;
4111 /* see if it's a range */
4112 if (*input_line_pointer == '-')
4113 {
4114 valueT stop = 1;
4115 ++input_line_pointer;
4116
4117 if (toupper (*input_line_pointer) != 'P'
4118 || (regno = atoi (++input_line_pointer)) < 0
4119 || regno > 63)
4120 {
4121 as_bad (_("Predicate register expected"));
4122 ignore_rest_of_line ();
4123 return;
4124 }
4125 while (isdigit (*input_line_pointer))
4126 ++input_line_pointer;
4127 stop <<= regno;
4128 if (bit >= stop)
4129 {
4130 as_bad (_("Bad register range"));
4131 ignore_rest_of_line ();
4132 return;
4133 }
4134 while (bit < stop)
4135 {
4136 bit <<= 1;
4137 mask |= bit; count++;
4138 }
4139 SKIP_WHITESPACE ();
4140 }
4141 if (*input_line_pointer != ',')
4142 break;
4143 ++input_line_pointer;
4144 SKIP_WHITESPACE ();
4145 }
4146
4147 switch (type)
4148 {
4149 case 'c':
4150 if (count == 0)
4151 mask = ~(valueT)0;
4152 clear_qp_mutex (mask);
4153 clear_qp_implies (mask, (valueT)0);
4154 break;
4155 case 'i':
4156 if (count != 2 || p1 == -1 || p2 == -1)
4157 as_bad (_("Predicate source and target required"));
4158 else if (p1 == 0 || p2 == 0)
4159 as_bad (_("Use of p0 is not valid in this context"));
4160 else
4161 add_qp_imply (p1, p2);
4162 break;
4163 case 'm':
4164 if (count < 2)
4165 {
4166 as_bad (_("At least two PR arguments expected"));
4167 break;
4168 }
4169 else if (mask & 1)
4170 {
4171 as_bad (_("Use of p0 is not valid in this context"));
4172 break;
4173 }
4174 add_qp_mutex (mask);
4175 break;
4176 case 's':
4177 /* note that we don't override any existing relations */
4178 if (count == 0)
4179 {
4180 as_bad (_("At least one PR argument expected"));
4181 break;
4182 }
4183 if (md.debug_dv)
4184 {
4185 fprintf (stderr, "Safe across calls: ");
4186 print_prmask (mask);
4187 fprintf (stderr, "\n");
4188 }
4189 qp_safe_across_calls = mask;
4190 break;
4191 }
4192 demand_empty_rest_of_line ();
4193}
4194
4195/* .entry label [, label [, ...]]
4196 Hint to DV code that the given labels are to be considered entry points.
4197 Otherwise, only global labels are considered entry points.
4198 */
4199static void
4200dot_entry (dummy)
4201 int dummy;
4202{
4203 const char *err;
4204 char *name;
4205 int c;
4206 symbolS *symbolP;
4207
4208 do
4209 {
4210 name = input_line_pointer;
4211 c = get_symbol_end ();
4212 symbolP = symbol_find_or_make (name);
4213
4214 err = hash_insert (md.entry_hash, S_GET_NAME (symbolP), (PTR) symbolP);
4215 if (err)
4216 as_fatal (_("Inserting \"%s\" into entry hint table failed: %s"),
4217 name, err);
4218
4219 *input_line_pointer = c;
4220 SKIP_WHITESPACE ();
4221 c = *input_line_pointer;
4222 if (c == ',')
4223 {
4224 input_line_pointer++;
4225 SKIP_WHITESPACE ();
4226 if (*input_line_pointer == '\n')
4227 c = '\n';
4228 }
4229 }
4230 while (c == ',');
4231
4232 demand_empty_rest_of_line ();
4233}
4234
4235/* .mem.offset offset, base
4236 "base" is used to distinguish between offsets from a different base.
4237 */
4238static void
4239dot_mem_offset (dummy)
4240 int dummy;
4241{
4242 md.mem_offset.hint = 1;
4243 md.mem_offset.offset = get_absolute_expression ();
4244 if (*input_line_pointer != ',')
4245 {
4246 as_bad (_("Comma expected"));
4247 ignore_rest_of_line ();
4248 return;
4249 }
4250 ++input_line_pointer;
4251 md.mem_offset.base = get_absolute_expression ();
4252 demand_empty_rest_of_line ();
4253}
4254
4255/* ia64-specific pseudo-ops: */
4256const pseudo_typeS md_pseudo_table[] =
4257 {
4258 { "radix", dot_radix, 0 },
4259 { "lcomm", s_lcomm_bytes, 1 },
4260 { "bss", dot_special_section, SPECIAL_SECTION_BSS },
4261 { "sbss", dot_special_section, SPECIAL_SECTION_SBSS },
4262 { "sdata", dot_special_section, SPECIAL_SECTION_SDATA },
4263 { "rodata", dot_special_section, SPECIAL_SECTION_RODATA },
4264 { "comment", dot_special_section, SPECIAL_SECTION_COMMENT },
4265 { "ia_64.unwind", dot_special_section, SPECIAL_SECTION_UNWIND },
4266 { "ia_64.unwind_info", dot_special_section, SPECIAL_SECTION_UNWIND_INFO },
4267 { "proc", dot_proc, 0 },
4268 { "body", dot_body, 0 },
4269 { "prologue", dot_prologue, 0 },
4270 { "endp", dot_endp },
4271 { "file", dwarf2_directive_file },
4272 { "loc", dwarf2_directive_loc },
4273
4274 { "fframe", dot_fframe },
4275 { "vframe", dot_vframe },
e0c9811a
JW
4276 { "vframesp", dot_vframesp },
4277 { "vframepsp", dot_vframepsp },
800eeca4
JW
4278 { "save", dot_save },
4279 { "restore", dot_restore },
e0c9811a
JW
4280 { "restorereg", dot_restorereg },
4281 { "restorereg.p", dot_restorereg_p },
800eeca4
JW
4282 { "handlerdata", dot_handlerdata },
4283 { "unwentry", dot_unwentry },
e0c9811a
JW
4284 { "altrp", dot_altrp },
4285 { "savesp", dot_savemem, 0 },
4286 { "savepsp", dot_savemem, 1 },
800eeca4
JW
4287 { "save.g", dot_saveg },
4288 { "save.f", dot_savef },
4289 { "save.b", dot_saveb },
4290 { "save.gf", dot_savegf },
4291 { "spill", dot_spill },
e0c9811a
JW
4292 { "spillreg", dot_spillreg },
4293 { "spillsp", dot_spillmem, 0 },
4294 { "spillpsp", dot_spillmem, 1 },
4295 { "spillreg.p", dot_spillreg_p },
4296 { "spillsp.p", dot_spillmem_p, 0 },
4297 { "spillpsp.p", dot_spillmem_p, 1 },
4298 { "label_state", dot_label_state },
4299 { "copy_state", dot_copy_state },
800eeca4
JW
4300 { "unwabi", dot_unwabi },
4301 { "personality", dot_personality },
4302#if 0
4303 { "estate", dot_estate },
4304#endif
4305 { "mii", dot_template, 0x0 },
4306 { "mli", dot_template, 0x2 }, /* old format, for compatibility */
4307 { "mlx", dot_template, 0x2 },
4308 { "mmi", dot_template, 0x4 },
4309 { "mfi", dot_template, 0x6 },
4310 { "mmf", dot_template, 0x7 },
4311 { "mib", dot_template, 0x8 },
4312 { "mbb", dot_template, 0x9 },
4313 { "bbb", dot_template, 0xb },
4314 { "mmb", dot_template, 0xc },
4315 { "mfb", dot_template, 0xe },
4316#if 0
4317 { "lb", dot_scope, 0 },
4318 { "le", dot_scope, 1 },
4319#endif
4320 { "align", s_align_bytes, 0 },
4321 { "regstk", dot_regstk, 0 },
4322 { "rotr", dot_rot, DYNREG_GR },
4323 { "rotf", dot_rot, DYNREG_FR },
4324 { "rotp", dot_rot, DYNREG_PR },
4325 { "lsb", dot_byteorder, 0 },
4326 { "msb", dot_byteorder, 1 },
4327 { "psr", dot_psr, 0 },
4328 { "alias", dot_alias, 0 },
4329 { "ln", dot_ln, 0 }, /* source line info (for debugging) */
4330
4331 { "xdata1", dot_xdata, 1 },
4332 { "xdata2", dot_xdata, 2 },
4333 { "xdata4", dot_xdata, 4 },
4334 { "xdata8", dot_xdata, 8 },
4335 { "xreal4", dot_xfloat_cons, 'f' },
4336 { "xreal8", dot_xfloat_cons, 'd' },
4337 { "xreal10", dot_xfloat_cons, 'x' },
4338 { "xstring", dot_xstringer, 0 },
4339 { "xstringz", dot_xstringer, 1 },
4340
4341 /* unaligned versions: */
4342 { "xdata2.ua", dot_xdata_ua, 2 },
4343 { "xdata4.ua", dot_xdata_ua, 4 },
4344 { "xdata8.ua", dot_xdata_ua, 8 },
4345 { "xreal4.ua", dot_xfloat_cons_ua, 'f' },
4346 { "xreal8.ua", dot_xfloat_cons_ua, 'd' },
4347 { "xreal10.ua", dot_xfloat_cons_ua, 'x' },
4348
4349 /* annotations/DV checking support */
4350 { "entry", dot_entry, 0 },
4351 { "mem.offset", dot_mem_offset },
4352 { "pred.rel", dot_pred_rel, 0 },
4353 { "pred.rel.clear", dot_pred_rel, 'c' },
4354 { "pred.rel.imply", dot_pred_rel, 'i' },
4355 { "pred.rel.mutex", dot_pred_rel, 'm' },
4356 { "pred.safe_across_calls", dot_pred_rel, 's' },
4357 { "reg.val", dot_reg_val },
4358 { "auto", dot_dv_mode, 'a' },
4359 { "explicit", dot_dv_mode, 'e' },
4360 { "default", dot_dv_mode, 'd' },
4361
4362 { NULL, 0, 0 }
4363 };
4364
4365static const struct pseudo_opcode
4366 {
4367 const char *name;
4368 void (*handler) (int);
4369 int arg;
4370 }
4371pseudo_opcode[] =
4372 {
4373 /* these are more like pseudo-ops, but don't start with a dot */
4374 { "data1", cons, 1 },
4375 { "data2", cons, 2 },
4376 { "data4", cons, 4 },
4377 { "data8", cons, 8 },
4378 { "real4", stmt_float_cons, 'f' },
4379 { "real8", stmt_float_cons, 'd' },
4380 { "real10", stmt_float_cons, 'x' },
4381 { "string", stringer, 0 },
4382 { "stringz", stringer, 1 },
4383
4384 /* unaligned versions: */
4385 { "data2.ua", stmt_cons_ua, 2 },
4386 { "data4.ua", stmt_cons_ua, 4 },
4387 { "data8.ua", stmt_cons_ua, 8 },
4388 { "real4.ua", float_cons, 'f' },
4389 { "real8.ua", float_cons, 'd' },
4390 { "real10.ua", float_cons, 'x' },
4391 };
4392
4393/* Declare a register by creating a symbol for it and entering it in
4394 the symbol table. */
4395static symbolS*
4396declare_register (name, regnum)
4397 const char *name;
4398 int regnum;
4399{
4400 const char *err;
4401 symbolS *sym;
4402
4403 sym = symbol_new (name, reg_section, regnum, &zero_address_frag);
4404
4405 err = hash_insert (md.reg_hash, S_GET_NAME (sym), (PTR) sym);
4406 if (err)
4407 as_fatal ("Inserting \"%s\" into register table failed: %s",
4408 name, err);
4409
4410 return sym;
4411}
4412
4413static void
4414declare_register_set (prefix, num_regs, base_regnum)
4415 const char *prefix;
4416 int num_regs;
4417 int base_regnum;
4418{
4419 char name[8];
4420 int i;
4421
4422 for (i = 0; i < num_regs; ++i)
4423 {
4424 sprintf (name, "%s%u", prefix, i);
4425 declare_register (name, base_regnum + i);
4426 }
4427}
4428
4429static unsigned int
4430operand_width (opnd)
4431 enum ia64_opnd opnd;
4432{
4433 const struct ia64_operand *odesc = &elf64_ia64_operands[opnd];
4434 unsigned int bits = 0;
4435 int i;
4436
4437 bits = 0;
4438 for (i = 0; i < NELEMS (odesc->field) && odesc->field[i].bits; ++i)
4439 bits += odesc->field[i].bits;
4440
4441 return bits;
4442}
4443
4444static int
4445operand_match (idesc, index, e)
4446 const struct ia64_opcode *idesc;
4447 int index;
4448 expressionS *e;
4449{
4450 enum ia64_opnd opnd = idesc->operands[index];
4451 int bits, relocatable = 0;
4452 struct insn_fix *fix;
4453 bfd_signed_vma val;
4454
4455 switch (opnd)
4456 {
4457 /* constants: */
4458
4459 case IA64_OPND_AR_CCV:
4460 if (e->X_op == O_register && e->X_add_number == REG_AR + 32)
4461 return 1;
4462 break;
4463
4464 case IA64_OPND_AR_PFS:
4465 if (e->X_op == O_register && e->X_add_number == REG_AR + 64)
4466 return 1;
4467 break;
4468
4469 case IA64_OPND_GR0:
4470 if (e->X_op == O_register && e->X_add_number == REG_GR + 0)
4471 return 1;
4472 break;
4473
4474 case IA64_OPND_IP:
4475 if (e->X_op == O_register && e->X_add_number == REG_IP)
4476 return 1;
4477 break;
4478
4479 case IA64_OPND_PR:
4480 if (e->X_op == O_register && e->X_add_number == REG_PR)
4481 return 1;
4482 break;
4483
4484 case IA64_OPND_PR_ROT:
4485 if (e->X_op == O_register && e->X_add_number == REG_PR_ROT)
4486 return 1;
4487 break;
4488
4489 case IA64_OPND_PSR:
4490 if (e->X_op == O_register && e->X_add_number == REG_PSR)
4491 return 1;
4492 break;
4493
4494 case IA64_OPND_PSR_L:
4495 if (e->X_op == O_register && e->X_add_number == REG_PSR_L)
4496 return 1;
4497 break;
4498
4499 case IA64_OPND_PSR_UM:
4500 if (e->X_op == O_register && e->X_add_number == REG_PSR_UM)
4501 return 1;
4502 break;
4503
4504 case IA64_OPND_C1:
4505 if (e->X_op == O_constant && e->X_add_number == 1)
4506 return 1;
4507 break;
4508
4509 case IA64_OPND_C8:
4510 if (e->X_op == O_constant && e->X_add_number == 8)
4511 return 1;
4512 break;
4513
4514 case IA64_OPND_C16:
4515 if (e->X_op == O_constant && e->X_add_number == 16)
4516 return 1;
4517 break;
4518
4519 /* register operands: */
4520
4521 case IA64_OPND_AR3:
4522 if (e->X_op == O_register && e->X_add_number >= REG_AR
4523 && e->X_add_number < REG_AR + 128)
4524 return 1;
4525 break;
4526
4527 case IA64_OPND_B1:
4528 case IA64_OPND_B2:
4529 if (e->X_op == O_register && e->X_add_number >= REG_BR
4530 && e->X_add_number < REG_BR + 8)
4531 return 1;
4532 break;
4533
4534 case IA64_OPND_CR3:
4535 if (e->X_op == O_register && e->X_add_number >= REG_CR
4536 && e->X_add_number < REG_CR + 128)
4537 return 1;
4538 break;
4539
4540 case IA64_OPND_F1:
4541 case IA64_OPND_F2:
4542 case IA64_OPND_F3:
4543 case IA64_OPND_F4:
4544 if (e->X_op == O_register && e->X_add_number >= REG_FR
4545 && e->X_add_number < REG_FR + 128)
4546 return 1;
4547 break;
4548
4549 case IA64_OPND_P1:
4550 case IA64_OPND_P2:
4551 if (e->X_op == O_register && e->X_add_number >= REG_P
4552 && e->X_add_number < REG_P + 64)
4553 return 1;
4554 break;
4555
4556 case IA64_OPND_R1:
4557 case IA64_OPND_R2:
4558 case IA64_OPND_R3:
4559 if (e->X_op == O_register && e->X_add_number >= REG_GR
4560 && e->X_add_number < REG_GR + 128)
4561 return 1;
4562 break;
4563
4564 case IA64_OPND_R3_2:
4565 if (e->X_op == O_register && e->X_add_number >= REG_GR
4566 && e->X_add_number < REG_GR + 4)
4567 return 1;
4568 break;
4569
4570 /* indirect operands: */
4571 case IA64_OPND_CPUID_R3:
4572 case IA64_OPND_DBR_R3:
4573 case IA64_OPND_DTR_R3:
4574 case IA64_OPND_ITR_R3:
4575 case IA64_OPND_IBR_R3:
4576 case IA64_OPND_MSR_R3:
4577 case IA64_OPND_PKR_R3:
4578 case IA64_OPND_PMC_R3:
4579 case IA64_OPND_PMD_R3:
4580 case IA64_OPND_RR_R3:
4581 if (e->X_op == O_index && e->X_op_symbol
4582 && (S_GET_VALUE (e->X_op_symbol) - IND_CPUID
4583 == opnd - IA64_OPND_CPUID_R3))
4584 return 1;
4585 break;
4586
4587 case IA64_OPND_MR3:
4588 if (e->X_op == O_index && !e->X_op_symbol)
4589 return 1;
4590 break;
4591
4592 /* immediate operands: */
4593 case IA64_OPND_CNT2a:
4594 case IA64_OPND_LEN4:
4595 case IA64_OPND_LEN6:
4596 bits = operand_width (idesc->operands[index]);
4597 if (e->X_op == O_constant
4598 && (bfd_vma) (e->X_add_number - 1) < ((bfd_vma) 1 << bits))
4599 return 1;
4600 break;
4601
4602 case IA64_OPND_CNT2b:
4603 if (e->X_op == O_constant
4604 && (bfd_vma) (e->X_add_number - 1) < 3)
4605 return 1;
4606 break;
4607
4608 case IA64_OPND_CNT2c:
4609 val = e->X_add_number;
4610 if (e->X_op == O_constant
4611 && (val == 0 || val == 7 || val == 15 || val == 16))
4612 return 1;
4613 break;
4614
4615 case IA64_OPND_SOR:
4616 /* SOR must be an integer multiple of 8 */
4617 if (e->X_add_number & 0x7)
4618 break;
4619 case IA64_OPND_SOF:
4620 case IA64_OPND_SOL:
4621 if (e->X_op == O_constant &&
4622 (bfd_vma) e->X_add_number <= 96)
4623 return 1;
4624 break;
4625
4626 case IA64_OPND_IMMU62:
4627 if (e->X_op == O_constant)
4628 {
4629 if ((bfd_vma) e->X_add_number < ((bfd_vma) 1 << 62))
4630 return 1;
4631 }
4632 else
4633 {
4634 /* FIXME -- need 62-bit relocation type */
4635 as_bad (_("62-bit relocation not yet implemented"));
4636 }
4637 break;
4638
4639 case IA64_OPND_IMMU64:
4640 if (e->X_op == O_symbol || e->X_op == O_pseudo_fixup
4641 || e->X_op == O_subtract)
4642 {
4643 fix = CURR_SLOT.fixup + CURR_SLOT.num_fixups;
4644 fix->code = BFD_RELOC_IA64_IMM64;
4645 if (e->X_op != O_subtract)
4646 {
4647 fix->code = ia64_gen_real_reloc_type (e->X_op_symbol, fix->code);
4648 if (e->X_op == O_pseudo_fixup)
4649 e->X_op = O_symbol;
4650 }
4651
4652 fix->opnd = idesc->operands[index];
4653 fix->expr = *e;
4654 fix->is_pcrel = 0;
4655 ++CURR_SLOT.num_fixups;
4656 return 1;
4657 }
4658 else if (e->X_op == O_constant)
4659 return 1;
4660 break;
4661
4662 case IA64_OPND_CCNT5:
4663 case IA64_OPND_CNT5:
4664 case IA64_OPND_CNT6:
4665 case IA64_OPND_CPOS6a:
4666 case IA64_OPND_CPOS6b:
4667 case IA64_OPND_CPOS6c:
4668 case IA64_OPND_IMMU2:
4669 case IA64_OPND_IMMU7a:
4670 case IA64_OPND_IMMU7b:
800eeca4
JW
4671 case IA64_OPND_IMMU21:
4672 case IA64_OPND_IMMU24:
4673 case IA64_OPND_MBTYPE4:
4674 case IA64_OPND_MHTYPE8:
4675 case IA64_OPND_POS6:
4676 bits = operand_width (idesc->operands[index]);
4677 if (e->X_op == O_constant
4678 && (bfd_vma) e->X_add_number < ((bfd_vma) 1 << bits))
4679 return 1;
4680 break;
4681
bf3ca999
TW
4682 case IA64_OPND_IMMU9:
4683 bits = operand_width (idesc->operands[index]);
4684 if (e->X_op == O_constant
4685 && (bfd_vma) e->X_add_number < ((bfd_vma) 1 << bits))
4686 {
4687 int lobits = e->X_add_number & 0x3;
4688 if (((bfd_vma) e->X_add_number & 0x3C) != 0 && lobits == 0)
4689 e->X_add_number |= (bfd_vma)0x3;
4690 return 1;
4691 }
4692 break;
4693
800eeca4
JW
4694 case IA64_OPND_IMM44:
4695 /* least 16 bits must be zero */
4696 if ((e->X_add_number & 0xffff) != 0)
4697 as_warn (_("lower 16 bits of mask ignored"));
4698
4699 if (e->X_op == O_constant
4700 && ((e->X_add_number >= 0
4701 && e->X_add_number < ((bfd_vma) 1 << 44))
4702 || (e->X_add_number < 0
4703 && -e->X_add_number <= ((bfd_vma) 1 << 44))))
4704 {
4705 /* sign-extend */
4706 if (e->X_add_number >= 0
4707 && (e->X_add_number & ((bfd_vma) 1 << 43)) != 0)
4708 {
4709 e->X_add_number |= ~(((bfd_vma) 1 << 44) - 1);
4710 }
4711 return 1;
4712 }
4713 break;
4714
4715 case IA64_OPND_IMM17:
4716 /* bit 0 is a don't care (pr0 is hardwired to 1) */
4717 if (e->X_op == O_constant
4718 && ((e->X_add_number >= 0
4719 && e->X_add_number < ((bfd_vma) 1 << 17))
4720 || (e->X_add_number < 0
4721 && -e->X_add_number <= ((bfd_vma) 1 << 17))))
4722 {
4723 /* sign-extend */
4724 if (e->X_add_number >= 0
4725 && (e->X_add_number & ((bfd_vma) 1 << 16)) != 0)
4726 {
4727 e->X_add_number |= ~(((bfd_vma)1 << 17) - 1);
4728 }
4729 return 1;
4730 }
4731 break;
4732
4733 case IA64_OPND_IMM14:
4734 case IA64_OPND_IMM22:
4735 relocatable = 1;
4736 case IA64_OPND_IMM1:
4737 case IA64_OPND_IMM8:
4738 case IA64_OPND_IMM8U4:
4739 case IA64_OPND_IMM8M1:
4740 case IA64_OPND_IMM8M1U4:
4741 case IA64_OPND_IMM8M1U8:
4742 case IA64_OPND_IMM9a:
4743 case IA64_OPND_IMM9b:
4744 bits = operand_width (idesc->operands[index]);
4745 if (relocatable && (e->X_op == O_symbol
4746 || e->X_op == O_subtract
4747 || e->X_op == O_pseudo_fixup))
4748 {
4749 fix = CURR_SLOT.fixup + CURR_SLOT.num_fixups;
4750
4751 if (idesc->operands[index] == IA64_OPND_IMM14)
4752 fix->code = BFD_RELOC_IA64_IMM14;
4753 else
4754 fix->code = BFD_RELOC_IA64_IMM22;
4755
4756 if (e->X_op != O_subtract)
4757 {
4758 fix->code = ia64_gen_real_reloc_type (e->X_op_symbol, fix->code);
4759 if (e->X_op == O_pseudo_fixup)
4760 e->X_op = O_symbol;
4761 }
4762
4763 fix->opnd = idesc->operands[index];
4764 fix->expr = *e;
4765 fix->is_pcrel = 0;
4766 ++CURR_SLOT.num_fixups;
4767 return 1;
4768 }
4769 else if (e->X_op != O_constant
4770 && ! (e->X_op == O_big && opnd == IA64_OPND_IMM8M1U8))
4771 return 0;
4772
4773 if (opnd == IA64_OPND_IMM8M1U4)
4774 {
4775 /* Zero is not valid for unsigned compares that take an adjusted
4776 constant immediate range. */
4777 if (e->X_add_number == 0)
4778 return 0;
4779
4780 /* Sign-extend 32-bit unsigned numbers, so that the following range
4781 checks will work. */
4782 val = e->X_add_number;
4783 if (((val & (~(bfd_vma)0 << 32)) == 0)
4784 && ((val & ((bfd_vma)1 << 31)) != 0))
4785 val = ((val << 32) >> 32);
4786
4787 /* Check for 0x100000000. This is valid because
4788 0x100000000-1 is the same as ((uint32_t) -1). */
4789 if (val == ((bfd_signed_vma) 1 << 32))
4790 return 1;
4791
4792 val = val - 1;
4793 }
4794 else if (opnd == IA64_OPND_IMM8M1U8)
4795 {
4796 /* Zero is not valid for unsigned compares that take an adjusted
4797 constant immediate range. */
4798 if (e->X_add_number == 0)
4799 return 0;
4800
4801 /* Check for 0x10000000000000000. */
4802 if (e->X_op == O_big)
4803 {
4804 if (generic_bignum[0] == 0
4805 && generic_bignum[1] == 0
4806 && generic_bignum[2] == 0
4807 && generic_bignum[3] == 0
4808 && generic_bignum[4] == 1)
4809 return 1;
4810 else
4811 return 0;
4812 }
4813 else
4814 val = e->X_add_number - 1;
4815 }
4816 else if (opnd == IA64_OPND_IMM8M1)
4817 val = e->X_add_number - 1;
4818 else if (opnd == IA64_OPND_IMM8U4)
4819 {
4820 /* Sign-extend 32-bit unsigned numbers, so that the following range
4821 checks will work. */
4822 val = e->X_add_number;
4823 if (((val & (~(bfd_vma)0 << 32)) == 0)
4824 && ((val & ((bfd_vma)1 << 31)) != 0))
4825 val = ((val << 32) >> 32);
4826 }
4827 else
4828 val = e->X_add_number;
4829
4830 if ((val >= 0 && val < ((bfd_vma) 1 << (bits - 1)))
4831 || (val < 0 && -val <= ((bfd_vma) 1 << (bits - 1))))
4832 return 1;
4833 break;
4834
4835 case IA64_OPND_INC3:
4836 /* +/- 1, 4, 8, 16 */
4837 val = e->X_add_number;
4838 if (val < 0)
4839 val = -val;
4840 if (e->X_op == O_constant
4841 && (val == 1 || val == 4 || val == 8 || val == 16))
4842 return 1;
4843 break;
4844
4845 case IA64_OPND_TGT25:
4846 case IA64_OPND_TGT25b:
4847 case IA64_OPND_TGT25c:
4848 case IA64_OPND_TGT64:
4849 if (e->X_op == O_symbol)
4850 {
4851 fix = CURR_SLOT.fixup + CURR_SLOT.num_fixups;
4852 if (opnd == IA64_OPND_TGT25)
4853 fix->code = BFD_RELOC_IA64_PCREL21F;
4854 else if (opnd == IA64_OPND_TGT25b)
4855 fix->code = BFD_RELOC_IA64_PCREL21M;
4856 else if (opnd == IA64_OPND_TGT25c)
4857 fix->code = BFD_RELOC_IA64_PCREL21B;
c67e42c9
RH
4858 else if (opnd == IA64_OPND_TGT64)
4859 fix->code = BFD_RELOC_IA64_PCREL60B;
4860 else
4861 abort ();
4862
800eeca4
JW
4863 fix->code = ia64_gen_real_reloc_type (e->X_op_symbol, fix->code);
4864 fix->opnd = idesc->operands[index];
4865 fix->expr = *e;
4866 fix->is_pcrel = 1;
4867 ++CURR_SLOT.num_fixups;
4868 return 1;
4869 }
4870 case IA64_OPND_TAG13:
4871 case IA64_OPND_TAG13b:
4872 switch (e->X_op)
4873 {
4874 case O_constant:
4875 return 1;
4876
4877 case O_symbol:
4878 fix = CURR_SLOT.fixup + CURR_SLOT.num_fixups;
4879 fix->code = ia64_gen_real_reloc_type (e->X_op_symbol, 0);
4880 fix->opnd = idesc->operands[index];
4881 fix->expr = *e;
4882 fix->is_pcrel = 1;
4883 ++CURR_SLOT.num_fixups;
4884 return 1;
4885
4886 default:
4887 break;
4888 }
4889 break;
4890
4891 default:
4892 break;
4893 }
4894 return 0;
4895}
4896
4897static int
4898parse_operand (e)
4899 expressionS *e;
4900{
4901 int sep = '\0';
4902
4903 memset (e, 0, sizeof (*e));
4904 e->X_op = O_absent;
4905 SKIP_WHITESPACE ();
4906 if (*input_line_pointer != '}')
4907 expression (e);
4908 sep = *input_line_pointer++;
4909
4910 if (sep == '}')
4911 {
4912 if (!md.manual_bundling)
4913 as_warn ("Found '}' when manual bundling is off");
4914 else
4915 CURR_SLOT.manual_bundling_off = 1;
4916 md.manual_bundling = 0;
4917 sep = '\0';
4918 }
4919 return sep;
4920}
4921
4922/* Returns the next entry in the opcode table that matches the one in
4923 IDESC, and frees the entry in IDESC. If no matching entry is
4924 found, NULL is returned instead. */
4925
4926static struct ia64_opcode *
4927get_next_opcode (struct ia64_opcode *idesc)
4928{
4929 struct ia64_opcode *next = ia64_find_next_opcode (idesc);
4930 ia64_free_opcode (idesc);
4931 return next;
4932}
4933
4934/* Parse the operands for the opcode and find the opcode variant that
4935 matches the specified operands, or NULL if no match is possible. */
4936static struct ia64_opcode*
4937parse_operands (idesc)
4938 struct ia64_opcode *idesc;
4939{
4940 int i = 0, highest_unmatched_operand, num_operands = 0, num_outputs = 0;
4941 int sep = 0;
4942 enum ia64_opnd expected_operand = IA64_OPND_NIL;
4943 char mnemonic[129];
4944 char *first_arg = 0, *end, *saved_input_pointer;
4945 unsigned int sof;
4946
4947 assert (strlen (idesc->name) <= 128);
4948
4949 strcpy (mnemonic, idesc->name);
4950 if (idesc->operands[2] == IA64_OPND_SOF)
4951 {
4952 /* To make the common idiom "alloc loc?=ar.pfs,0,1,0,0" work, we
4953 can't parse the first operand until we have parsed the
4954 remaining operands of the "alloc" instruction. */
4955 SKIP_WHITESPACE ();
4956 first_arg = input_line_pointer;
4957 end = strchr (input_line_pointer, '=');
4958 if (!end)
4959 {
4960 as_bad ("Expected separator `='");
4961 return 0;
4962 }
4963 input_line_pointer = end + 1;
4964 ++i;
4965 ++num_outputs;
4966 }
4967
4968 for (; i < NELEMS (CURR_SLOT.opnd); ++i)
4969 {
4970 sep = parse_operand (CURR_SLOT.opnd + i);
4971 if (CURR_SLOT.opnd[i].X_op == O_absent)
4972 break;
4973
4974 ++num_operands;
4975
4976 if (sep != '=' && sep != ',')
4977 break;
4978
4979 if (sep == '=')
4980 {
4981 if (num_outputs > 0)
4982 as_bad ("Duplicate equal sign (=) in instruction");
4983 else
4984 num_outputs = i + 1;
4985 }
4986 }
4987 if (sep != '\0')
4988 {
4989 as_bad ("Illegal operand separator `%c'", sep);
4990 return 0;
4991 }
4992
4993 if (idesc->operands[2] == IA64_OPND_SOF)
4994 {
4995 /* map alloc r1=ar.pfs,i,l,o,r to alloc r1=ar.pfs,(i+l+o),(i+l),r */
4996 know (strcmp (idesc->name, "alloc") == 0);
4997 if (num_operands == 5 /* first_arg not included in this count! */
4998 && CURR_SLOT.opnd[2].X_op == O_constant
4999 && CURR_SLOT.opnd[3].X_op == O_constant
5000 && CURR_SLOT.opnd[4].X_op == O_constant
5001 && CURR_SLOT.opnd[5].X_op == O_constant)
5002 {
5003 sof = set_regstack (CURR_SLOT.opnd[2].X_add_number,
5004 CURR_SLOT.opnd[3].X_add_number,
5005 CURR_SLOT.opnd[4].X_add_number,
5006 CURR_SLOT.opnd[5].X_add_number);
5007
5008 /* now we can parse the first arg: */
5009 saved_input_pointer = input_line_pointer;
5010 input_line_pointer = first_arg;
5011 sep = parse_operand (CURR_SLOT.opnd + 0);
5012 if (sep != '=')
5013 --num_outputs; /* force error */
5014 input_line_pointer = saved_input_pointer;
5015
5016 CURR_SLOT.opnd[2].X_add_number = sof;
5017 CURR_SLOT.opnd[3].X_add_number
5018 = sof - CURR_SLOT.opnd[4].X_add_number;
5019 CURR_SLOT.opnd[4] = CURR_SLOT.opnd[5];
5020 }
5021 }
5022
5023 highest_unmatched_operand = 0;
5024 expected_operand = idesc->operands[0];
5025 for (; idesc; idesc = get_next_opcode (idesc))
5026 {
5027 if (num_outputs != idesc->num_outputs)
5028 continue; /* mismatch in # of outputs */
5029
5030 CURR_SLOT.num_fixups = 0;
5031 for (i = 0; i < num_operands && idesc->operands[i]; ++i)
5032 if (!operand_match (idesc, i, CURR_SLOT.opnd + i))
5033 break;
5034
5035 if (i != num_operands)
5036 {
5037 if (i > highest_unmatched_operand)
5038 {
5039 highest_unmatched_operand = i;
5040 expected_operand = idesc->operands[i];
5041 }
5042 continue;
5043 }
5044
5045 if (num_operands < NELEMS (idesc->operands)
5046 && idesc->operands[num_operands])
5047 continue; /* mismatch in number of arguments */
5048
5049 break;
5050 }
5051 if (!idesc)
5052 {
5053 if (expected_operand)
5054 as_bad ("Operand %u of `%s' should be %s",
5055 highest_unmatched_operand + 1, mnemonic,
5056 elf64_ia64_operands[expected_operand].desc);
5057 else
5058 as_bad ("Operand mismatch");
5059 return 0;
5060 }
5061 return idesc;
5062}
5063
5064static void
5065build_insn (slot, insnp)
5066 struct slot *slot;
5067 bfd_vma *insnp;
5068{
5069 const struct ia64_operand *odesc, *o2desc;
5070 struct ia64_opcode *idesc = slot->idesc;
5071 bfd_signed_vma insn, val;
5072 const char *err;
5073 int i;
5074
5075 insn = idesc->opcode | slot->qp_regno;
5076
5077 for (i = 0; i < NELEMS (idesc->operands) && idesc->operands[i]; ++i)
5078 {
c67e42c9
RH
5079 if (slot->opnd[i].X_op == O_register
5080 || slot->opnd[i].X_op == O_constant
5081 || slot->opnd[i].X_op == O_index)
5082 val = slot->opnd[i].X_add_number;
5083 else if (slot->opnd[i].X_op == O_big)
800eeca4 5084 {
c67e42c9
RH
5085 /* This must be the value 0x10000000000000000. */
5086 assert (idesc->operands[i] == IA64_OPND_IMM8M1U8);
5087 val = 0;
5088 }
5089 else
5090 val = 0;
5091
5092 switch (idesc->operands[i])
5093 {
5094 case IA64_OPND_IMMU64:
800eeca4
JW
5095 *insnp++ = (val >> 22) & 0x1ffffffffffLL;
5096 insn |= (((val & 0x7f) << 13) | (((val >> 7) & 0x1ff) << 27)
5097 | (((val >> 16) & 0x1f) << 22) | (((val >> 21) & 0x1) << 21)
5098 | (((val >> 63) & 0x1) << 36));
c67e42c9
RH
5099 continue;
5100
5101 case IA64_OPND_IMMU62:
5102 val &= 0x3fffffffffffffffULL;
800eeca4
JW
5103 if (val != slot->opnd[i].X_add_number)
5104 as_warn (_("Value truncated to 62 bits"));
5105 *insnp++ = (val >> 21) & 0x1ffffffffffLL;
5106 insn |= (((val & 0xfffff) << 6) | (((val >> 20) & 0x1) << 36));
c67e42c9 5107 continue;
800eeca4 5108
c67e42c9
RH
5109 case IA64_OPND_TGT64:
5110 val >>= 4;
5111 *insnp++ = ((val >> 20) & 0x7fffffffffLL) << 2;
5112 insn |= ((((val >> 59) & 0x1) << 36)
5113 | (((val >> 0) & 0xfffff) << 13));
5114 continue;
800eeca4 5115
c67e42c9
RH
5116 case IA64_OPND_AR3:
5117 val -= REG_AR;
5118 break;
5119
5120 case IA64_OPND_B1:
5121 case IA64_OPND_B2:
5122 val -= REG_BR;
5123 break;
5124
5125 case IA64_OPND_CR3:
5126 val -= REG_CR;
5127 break;
5128
5129 case IA64_OPND_F1:
5130 case IA64_OPND_F2:
5131 case IA64_OPND_F3:
5132 case IA64_OPND_F4:
5133 val -= REG_FR;
5134 break;
5135
5136 case IA64_OPND_P1:
5137 case IA64_OPND_P2:
5138 val -= REG_P;
5139 break;
5140
5141 case IA64_OPND_R1:
5142 case IA64_OPND_R2:
5143 case IA64_OPND_R3:
5144 case IA64_OPND_R3_2:
5145 case IA64_OPND_CPUID_R3:
5146 case IA64_OPND_DBR_R3:
5147 case IA64_OPND_DTR_R3:
5148 case IA64_OPND_ITR_R3:
5149 case IA64_OPND_IBR_R3:
5150 case IA64_OPND_MR3:
5151 case IA64_OPND_MSR_R3:
5152 case IA64_OPND_PKR_R3:
5153 case IA64_OPND_PMC_R3:
5154 case IA64_OPND_PMD_R3:
5155 case IA64_OPND_RR_R3:
5156 val -= REG_GR;
5157 break;
5158
5159 default:
5160 break;
5161 }
5162
5163 odesc = elf64_ia64_operands + idesc->operands[i];
5164 err = (*odesc->insert) (odesc, val, &insn);
5165 if (err)
5166 as_bad_where (slot->src_file, slot->src_line,
5167 "Bad operand value: %s", err);
5168 if (idesc->flags & IA64_OPCODE_PSEUDO)
5169 {
5170 if ((idesc->flags & IA64_OPCODE_F2_EQ_F3)
5171 && odesc == elf64_ia64_operands + IA64_OPND_F3)
5172 {
5173 o2desc = elf64_ia64_operands + IA64_OPND_F2;
5174 (*o2desc->insert) (o2desc, val, &insn);
800eeca4 5175 }
c67e42c9
RH
5176 if ((idesc->flags & IA64_OPCODE_LEN_EQ_64MCNT)
5177 && (odesc == elf64_ia64_operands + IA64_OPND_CPOS6a
5178 || odesc == elf64_ia64_operands + IA64_OPND_POS6))
800eeca4 5179 {
c67e42c9
RH
5180 o2desc = elf64_ia64_operands + IA64_OPND_LEN6;
5181 (*o2desc->insert) (o2desc, 64 - val, &insn);
800eeca4
JW
5182 }
5183 }
5184 }
5185 *insnp = insn;
5186}
5187
5188static void
5189emit_one_bundle ()
5190{
5191 unsigned int manual_bundling_on = 0, manual_bundling_off = 0;
5192 unsigned int manual_bundling = 0;
5193 enum ia64_unit required_unit, insn_unit = 0;
5194 enum ia64_insn_type type[3], insn_type;
5195 unsigned int template, orig_template;
5196 bfd_vma insn[3] = {-1, -1, -1};
5197 struct ia64_opcode *idesc;
5198 int end_of_insn_group = 0, user_template = -1;
5199 int n, i, j, first, curr;
e0c9811a 5200 unw_rec_list *ptr, *prev;
800eeca4
JW
5201 bfd_vma t0 = 0, t1 = 0;
5202 struct label_fix *lfix;
5203 struct insn_fix *ifix;
5204 char mnemonic[16];
5205 fixS *fix;
5206 char *f;
5207
5208 first = (md.curr_slot + NUM_SLOTS - md.num_slots_in_use) % NUM_SLOTS;
5209 know (first >= 0 & first < NUM_SLOTS);
5210 n = MIN (3, md.num_slots_in_use);
5211
5212 /* Determine template: user user_template if specified, best match
5213 otherwise: */
5214
5215 if (md.slot[first].user_template >= 0)
5216 user_template = template = md.slot[first].user_template;
5217 else
5218 {
5219 /* auto select appropriate template */
5220 memset (type, 0, sizeof (type));
5221 curr = first;
5222 for (i = 0; i < n; ++i)
5223 {
5224 type[i] = md.slot[curr].idesc->type;
5225 curr = (curr + 1) % NUM_SLOTS;
5226 }
5227 template = best_template[type[0]][type[1]][type[2]];
5228 }
5229
5230 /* initialize instructions with appropriate nops: */
5231 for (i = 0; i < 3; ++i)
5232 insn[i] = nop[ia64_templ_desc[template].exec_unit[i]];
5233
5234 f = frag_more (16);
5235
5236 /* now fill in slots with as many insns as possible: */
5237 curr = first;
5238 idesc = md.slot[curr].idesc;
5239 end_of_insn_group = 0;
5240 for (i = 0; i < 3 && md.num_slots_in_use > 0; ++i)
5241 {
e0c9811a
JW
5242 /* Set the slot number for prologue/body records now as those
5243 refer to the current point, not the point after the
5244 instruction has been issued: */
10850f29
JW
5245 /* Don't try to delete prologue/body records here, as that will cause
5246 them to also be deleted from the master list of unwind records. */
e0c9811a 5247 for (ptr = md.slot[curr].unwind_record; ptr; ptr = ptr->next)
10850f29
JW
5248 if (ptr->r.type == prologue || ptr->r.type == prologue_gr
5249 || ptr->r.type == body)
5250 ptr->slot_number = (unsigned long) f + i;
e0c9811a 5251
800eeca4
JW
5252 if (idesc->flags & IA64_OPCODE_SLOT2)
5253 {
5254 if (manual_bundling && i != 2)
5255 as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line,
5256 "`%s' must be last in bundle", idesc->name);
5257 else
5258 i = 2;
5259 }
5260 if (idesc->flags & IA64_OPCODE_LAST)
5261 {
5262 int required_slot, required_template;
5263
5264 /* If we need a stop bit after an M slot, our only choice is
5265 template 5 (M;;MI). If we need a stop bit after a B
5266 slot, our only choice is to place it at the end of the
5267 bundle, because the only available templates are MIB,
5268 MBB, BBB, MMB, and MFB. We don't handle anything other
5269 than M and B slots because these are the only kind of
5270 instructions that can have the IA64_OPCODE_LAST bit set. */
5271 required_template = template;
5272 switch (idesc->type)
5273 {
5274 case IA64_TYPE_M:
5275 required_slot = 0;
5276 required_template = 5;
5277 break;
5278
5279 case IA64_TYPE_B:
5280 required_slot = 2;
5281 break;
5282
5283 default:
5284 as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line,
5285 "Internal error: don't know how to force %s to end"
5286 "of instruction group", idesc->name);
5287 required_slot = i;
5288 break;
5289 }
5290 if (manual_bundling && i != required_slot)
5291 as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line,
5292 "`%s' must be last in instruction group",
5293 idesc->name);
5294 if (required_slot < i)
5295 /* Can't fit this instruction. */
5296 break;
5297
5298 i = required_slot;
5299 if (required_template != template)
5300 {
5301 /* If we switch the template, we need to reset the NOPs
5302 after slot i. The slot-types of the instructions ahead
5303 of i never change, so we don't need to worry about
5304 changing NOPs in front of this slot. */
5305 for (j = i; j < 3; ++j)
5306 insn[j] = nop[ia64_templ_desc[required_template].exec_unit[j]];
5307 }
5308 template = required_template;
5309 }
5310 if (curr != first && md.slot[curr].label_fixups)
5311 {
5312 if (manual_bundling_on)
5313 as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line,
5314 "Label must be first in a bundle");
5315 /* This insn must go into the first slot of a bundle. */
5316 break;
5317 }
5318
5319 manual_bundling_on = md.slot[curr].manual_bundling_on;
5320 manual_bundling_off = md.slot[curr].manual_bundling_off;
5321
5322 if (manual_bundling_on)
5323 {
5324 if (curr == first)
5325 manual_bundling = 1;
5326 else
5327 break; /* need to start a new bundle */
5328 }
5329
5330 if (end_of_insn_group && md.num_slots_in_use >= 1)
5331 {
5332 /* We need an instruction group boundary in the middle of a
5333 bundle. See if we can switch to an other template with
5334 an appropriate boundary. */
5335
5336 orig_template = template;
5337 if (i == 1 && (user_template == 4
5338 || (user_template < 0
5339 && (ia64_templ_desc[template].exec_unit[0]
5340 == IA64_UNIT_M))))
5341 {
5342 template = 5;
5343 end_of_insn_group = 0;
5344 }
5345 else if (i == 2 && (user_template == 0
5346 || (user_template < 0
5347 && (ia64_templ_desc[template].exec_unit[1]
5348 == IA64_UNIT_I)))
5349 /* This test makes sure we don't switch the template if
5350 the next instruction is one that needs to be first in
5351 an instruction group. Since all those instructions are
5352 in the M group, there is no way such an instruction can
5353 fit in this bundle even if we switch the template. The
5354 reason we have to check for this is that otherwise we
5355 may end up generating "MI;;I M.." which has the deadly
5356 effect that the second M instruction is no longer the
5357 first in the bundle! --davidm 99/12/16 */
5358 && (idesc->flags & IA64_OPCODE_FIRST) == 0)
5359 {
5360 template = 1;
5361 end_of_insn_group = 0;
5362 }
5363 else if (curr != first)
5364 /* can't fit this insn */
5365 break;
5366
5367 if (template != orig_template)
5368 /* if we switch the template, we need to reset the NOPs
5369 after slot i. The slot-types of the instructions ahead
5370 of i never change, so we don't need to worry about
5371 changing NOPs in front of this slot. */
5372 for (j = i; j < 3; ++j)
5373 insn[j] = nop[ia64_templ_desc[template].exec_unit[j]];
5374 }
5375 required_unit = ia64_templ_desc[template].exec_unit[i];
5376
5377 /* resolve dynamic opcodes such as "break" and "nop": */
5378 if (idesc->type == IA64_TYPE_DYN)
5379 {
5380 if ((strcmp (idesc->name, "nop") == 0)
5381 || (strcmp (idesc->name, "break") == 0))
5382 insn_unit = required_unit;
5383 else if (strcmp (idesc->name, "chk.s") == 0)
5384 {
5385 insn_unit = IA64_UNIT_M;
5386 if (required_unit == IA64_UNIT_I)
5387 insn_unit = IA64_UNIT_I;
5388 }
5389 else
5390 as_fatal ("emit_one_bundle: unexpected dynamic op");
5391
5392 sprintf (mnemonic, "%s.%c", idesc->name, "?imbf??"[insn_unit]);
5393 md.slot[curr].idesc = idesc = ia64_find_opcode (mnemonic);
5394#if 0
5395 know (!idesc->next); /* no resolved dynamic ops have collisions */
5396#endif
5397 }
5398 else
5399 {
5400 insn_type = idesc->type;
5401 insn_unit = IA64_UNIT_NIL;
5402 switch (insn_type)
5403 {
5404 case IA64_TYPE_A:
5405 if (required_unit == IA64_UNIT_I || required_unit == IA64_UNIT_M)
5406 insn_unit = required_unit;
5407 break;
5408 case IA64_TYPE_X: insn_unit = IA64_UNIT_L; break;
5409 case IA64_TYPE_I: insn_unit = IA64_UNIT_I; break;
5410 case IA64_TYPE_M: insn_unit = IA64_UNIT_M; break;
5411 case IA64_TYPE_B: insn_unit = IA64_UNIT_B; break;
5412 case IA64_TYPE_F: insn_unit = IA64_UNIT_F; break;
5413 default: break;
5414 }
5415 }
5416
5417 if (insn_unit != required_unit)
5418 {
5419 if (required_unit == IA64_UNIT_L
5420 && insn_unit == IA64_UNIT_I
5421 && !(idesc->flags & IA64_OPCODE_X_IN_MLX))
5422 {
5423 /* we got ourselves an MLX template but the current
5424 instruction isn't an X-unit, or an I-unit instruction
5425 that can go into the X slot of an MLX template. Duh. */
5426 if (md.num_slots_in_use >= NUM_SLOTS)
5427 {
5428 as_bad_where (md.slot[curr].src_file,
5429 md.slot[curr].src_line,
5430 "`%s' can't go in X slot of "
5431 "MLX template", idesc->name);
5432 /* drop this insn so we don't livelock: */
5433 --md.num_slots_in_use;
5434 }
5435 break;
5436 }
5437 continue; /* try next slot */
5438 }
5439
5440 if (debug_type == DEBUG_DWARF2)
5441 {
5442 bfd_vma addr;
5443
5444 addr = frag_now->fr_address + frag_now_fix () - 16 + 1*i;
5445 dwarf2_gen_line_info (addr, &md.slot[curr].debug_line);
5446 }
5447
5448 build_insn (md.slot + curr, insn + i);
5449
10850f29
JW
5450 /* Set slot counts for non prologue/body unwind records. */
5451 for (ptr = md.slot[curr].unwind_record; ptr; ptr = ptr->next)
5452 if (ptr->r.type != prologue && ptr->r.type != prologue_gr
5453 && ptr->r.type != body)
5454 ptr->slot_number = (unsigned long) f + i;
5455 md.slot[curr].unwind_record = NULL;
e0c9811a 5456 unwind.next_slot_number = (unsigned long) f + i + ((i == 2)?(0x10-2):1);
10850f29 5457
800eeca4
JW
5458 if (required_unit == IA64_UNIT_L)
5459 {
5460 know (i == 1);
5461 /* skip one slot for long/X-unit instructions */
5462 ++i;
5463 }
5464 --md.num_slots_in_use;
5465
5466 /* now is a good time to fix up the labels for this insn: */
5467 for (lfix = md.slot[curr].label_fixups; lfix; lfix = lfix->next)
5468 {
5469 S_SET_VALUE (lfix->sym, frag_now_fix () - 16);
5470 symbol_set_frag (lfix->sym, frag_now);
5471 }
5472
5473 for (j = 0; j < md.slot[curr].num_fixups; ++j)
5474 {
5475 ifix = md.slot[curr].fixup + j;
5476 fix = fix_new_exp (frag_now, frag_now_fix () - 16 + i, 4,
5477 &ifix->expr, ifix->is_pcrel, ifix->code);
5478 fix->tc_fix_data.opnd = ifix->opnd;
5479 fix->fx_plt = (fix->fx_r_type == BFD_RELOC_IA64_PLTOFF22);
5480 fix->fx_file = md.slot[curr].src_file;
5481 fix->fx_line = md.slot[curr].src_line;
5482 }
5483
5484 end_of_insn_group = md.slot[curr].end_of_insn_group;
5485
5486 /* clear slot: */
5487 ia64_free_opcode (md.slot[curr].idesc);
5488 memset (md.slot + curr, 0, sizeof (md.slot[curr]));
5489 md.slot[curr].user_template = -1;
5490
5491 if (manual_bundling_off)
5492 {
5493 manual_bundling = 0;
5494 break;
5495 }
5496 curr = (curr + 1) % NUM_SLOTS;
5497 idesc = md.slot[curr].idesc;
5498 }
5499 if (manual_bundling)
5500 {
5501 if (md.num_slots_in_use > 0)
5502 as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line,
5503 "`%s' does not fit into %s template",
5504 idesc->name, ia64_templ_desc[template].name);
5505 else
5506 as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line,
5507 "Missing '}' at end of file");
5508 }
5509 know (md.num_slots_in_use < NUM_SLOTS);
5510
5511 t0 = end_of_insn_group | (template << 1) | (insn[0] << 5) | (insn[1] << 46);
5512 t1 = ((insn[1] >> 18) & 0x7fffff) | (insn[2] << 23);
5513
5514 md_number_to_chars (f + 0, t0, 8);
5515 md_number_to_chars (f + 8, t1, 8);
5516}
5517
5518int
5519md_parse_option (c, arg)
5520 int c;
5521 char *arg;
5522{
5523 /* Switches from the Intel assembler. */
5524 switch (c)
5525 {
5526 case 'M':
5527 if (strcmp (arg, "ilp64") == 0
5528 || strcmp (arg, "lp64") == 0
5529 || strcmp (arg, "p64") == 0)
5530 {
5531 md.flags |= EF_IA_64_ABI64;
5532 }
5533 else if (strcmp (arg, "ilp32") == 0)
5534 {
5535 md.flags &= ~EF_IA_64_ABI64;
5536 }
5537 else if (strcmp (arg, "le") == 0)
5538 {
5539 md.flags &= ~EF_IA_64_BE;
5540 }
5541 else if (strcmp (arg, "be") == 0)
5542 {
5543 md.flags |= EF_IA_64_BE;
5544 }
5545 else
5546 return 0;
5547 break;
5548
5549 case 'N':
5550 if (strcmp (arg, "so") == 0)
5551 {
5552 /* Suppress signon message. */
5553 }
5554 else if (strcmp (arg, "pi") == 0)
5555 {
5556 /* Reject privileged instructions. FIXME */
5557 }
5558 else if (strcmp (arg, "us") == 0)
5559 {
5560 /* Allow union of signed and unsigned range. FIXME */
5561 }
5562 else if (strcmp (arg, "close_fcalls") == 0)
5563 {
5564 /* Do not resolve global function calls. */
5565 }
5566 else
5567 return 0;
5568 break;
5569
5570 case 'C':
5571 /* temp[="prefix"] Insert temporary labels into the object file
5572 symbol table prefixed by "prefix".
5573 Default prefix is ":temp:".
5574 */
5575 break;
5576
5577 case 'a':
5578 /* ??? Conflicts with gas' listing option. */
5579 /* indirect=<tgt> Assume unannotated indirect branches behavior
5580 according to <tgt> --
5581 exit: branch out from the current context (default)
5582 labels: all labels in context may be branch targets
5583 */
5584 break;
5585
5586 case 'x':
5587 /* -X conflicts with an ignored option, use -x instead */
5588 md.detect_dv = 1;
5589 if (!arg || strcmp (arg, "explicit") == 0)
5590 {
5591 /* set default mode to explicit */
5592 md.default_explicit_mode = 1;
5593 break;
5594 }
5595 else if (strcmp (arg, "auto") == 0)
5596 {
5597 md.default_explicit_mode = 0;
5598 }
5599 else if (strcmp (arg, "debug") == 0)
5600 {
5601 md.debug_dv = 1;
5602 }
5603 else if (strcmp (arg, "debugx") == 0)
5604 {
5605 md.default_explicit_mode = 1;
5606 md.debug_dv = 1;
5607 }
5608 else
5609 {
5610 as_bad (_("Unrecognized option '-x%s'"), arg);
5611 }
5612 break;
5613
5614 case 'S':
5615 /* nops Print nops statistics. */
5616 break;
5617
5618 default:
5619 return 0;
5620 }
5621
5622 return 1;
5623}
5624
5625void
5626md_show_usage (stream)
5627 FILE *stream;
5628{
5629 fputs(_("\
5630IA-64 options:\n\
5631 -Milp32|-Milp64|-Mlp64|-Mp64 select data model (default -Mlp64)\n\
5632 -Mle | -Mbe select little- or big-endian byte order (default -Mle)\n\
5633 -x | -xexplicit turn on dependency violation checking (default)\n\
5634 -xauto automagically remove dependency violations\n\
5635 -xdebug debug dependency violation checker\n"),
5636 stream);
5637}
5638
5639static inline int
5640match (int templ, int type, int slot)
5641{
5642 enum ia64_unit unit;
5643 int result;
5644
5645 unit = ia64_templ_desc[templ].exec_unit[slot];
5646 switch (type)
5647 {
5648 case IA64_TYPE_DYN: result = 1; break; /* for nop and break */
5649 case IA64_TYPE_A:
5650 result = (unit == IA64_UNIT_I || unit == IA64_UNIT_M);
5651 break;
5652 case IA64_TYPE_X: result = (unit == IA64_UNIT_L); break;
5653 case IA64_TYPE_I: result = (unit == IA64_UNIT_I); break;
5654 case IA64_TYPE_M: result = (unit == IA64_UNIT_M); break;
5655 case IA64_TYPE_B: result = (unit == IA64_UNIT_B); break;
5656 case IA64_TYPE_F: result = (unit == IA64_UNIT_F); break;
5657 default: result = 0; break;
5658 }
5659 return result;
5660}
5661
5662/* This function is called once, at assembler startup time. It sets
5663 up all the tables, etc. that the MD part of the assembler will need
5664 that can be determined before arguments are parsed. */
5665void
5666md_begin ()
5667{
5668 int i, j, k, t, total, ar_base, cr_base, goodness, best, regnum;
5669 const char *err;
5670 char name[8];
5671
5672 md.auto_align = 1;
5673 md.explicit_mode = md.default_explicit_mode;
5674
5675 bfd_set_section_alignment (stdoutput, text_section, 4);
5676
5677 target_big_endian = 0;
5678 pseudo_func[FUNC_FPTR_RELATIVE].u.sym =
5679 symbol_new (".<fptr>", undefined_section, FUNC_FPTR_RELATIVE,
5680 &zero_address_frag);
5681
5682 pseudo_func[FUNC_GP_RELATIVE].u.sym =
5683 symbol_new (".<gprel>", undefined_section, FUNC_GP_RELATIVE,
5684 &zero_address_frag);
5685
5686 pseudo_func[FUNC_LT_RELATIVE].u.sym =
5687 symbol_new (".<ltoff>", undefined_section, FUNC_LT_RELATIVE,
5688 &zero_address_frag);
5689
c67e42c9
RH
5690 pseudo_func[FUNC_PC_RELATIVE].u.sym =
5691 symbol_new (".<pcrel>", undefined_section, FUNC_PC_RELATIVE,
5692 &zero_address_frag);
5693
800eeca4
JW
5694 pseudo_func[FUNC_PLT_RELATIVE].u.sym =
5695 symbol_new (".<pltoff>", undefined_section, FUNC_PLT_RELATIVE,
5696 &zero_address_frag);
5697
5698 pseudo_func[FUNC_SEC_RELATIVE].u.sym =
5699 symbol_new (".<secrel>", undefined_section, FUNC_SEC_RELATIVE,
5700 &zero_address_frag);
5701
5702 pseudo_func[FUNC_SEG_RELATIVE].u.sym =
5703 symbol_new (".<segrel>", undefined_section, FUNC_SEG_RELATIVE,
5704 &zero_address_frag);
5705
5706 pseudo_func[FUNC_LTV_RELATIVE].u.sym =
5707 symbol_new (".<ltv>", undefined_section, FUNC_LTV_RELATIVE,
5708 &zero_address_frag);
5709
5710 pseudo_func[FUNC_LT_FPTR_RELATIVE].u.sym =
5711 symbol_new (".<ltoff.fptr>", undefined_section, FUNC_LT_FPTR_RELATIVE,
5712 &zero_address_frag);
5713
5714 /* compute the table of best templates: */
5715 for (i = 0; i < IA64_NUM_TYPES; ++i)
5716 for (j = 0; j < IA64_NUM_TYPES; ++j)
5717 for (k = 0; k < IA64_NUM_TYPES; ++k)
5718 {
5719 best = 0;
5720 for (t = 0; t < NELEMS (ia64_templ_desc); ++t)
5721 {
5722 goodness = 0;
5723 if (match (t, i, 0))
5724 {
5725 if (match (t, j, 1))
5726 {
5727 if (match (t, k, 2))
5728 goodness = 3;
5729 else
5730 goodness = 2;
5731 }
5732 else if (match (t, j, 2))
5733 goodness = 2;
5734 else
5735 goodness = 1;
5736 }
5737 else if (match (t, i, 1))
5738 {
5739 if (match (t, j, 2))
5740 goodness = 2;
5741 else
5742 goodness = 1;
5743 }
5744 else if (match (t, i, 2))
5745 goodness = 1;
5746
5747 if (goodness > best)
5748 {
5749 best = goodness;
5750 best_template[i][j][k] = t;
5751 }
5752 }
5753 }
5754
5755 for (i = 0; i < NUM_SLOTS; ++i)
5756 md.slot[i].user_template = -1;
5757
5758 md.pseudo_hash = hash_new ();
5759 for (i = 0; i < NELEMS (pseudo_opcode); ++i)
5760 {
5761 err = hash_insert (md.pseudo_hash, pseudo_opcode[i].name,
5762 (void *) (pseudo_opcode + i));
5763 if (err)
5764 as_fatal ("ia64.md_begin: can't hash `%s': %s",
5765 pseudo_opcode[i].name, err);
5766 }
5767
5768 md.reg_hash = hash_new ();
5769 md.dynreg_hash = hash_new ();
5770 md.const_hash = hash_new ();
5771 md.entry_hash = hash_new ();
5772
5773 /* general registers: */
5774
5775 total = 128;
5776 for (i = 0; i < total; ++i)
5777 {
5778 sprintf (name, "r%d", i - REG_GR);
5779 md.regsym[i] = declare_register (name, i);
5780 }
5781
5782 /* floating point registers: */
5783 total += 128;
5784 for (; i < total; ++i)
5785 {
5786 sprintf (name, "f%d", i - REG_FR);
5787 md.regsym[i] = declare_register (name, i);
5788 }
5789
5790 /* application registers: */
5791 total += 128;
5792 ar_base = i;
5793 for (; i < total; ++i)
5794 {
5795 sprintf (name, "ar%d", i - REG_AR);
5796 md.regsym[i] = declare_register (name, i);
5797 }
5798
5799 /* control registers: */
5800 total += 128;
5801 cr_base = i;
5802 for (; i < total; ++i)
5803 {
5804 sprintf (name, "cr%d", i - REG_CR);
5805 md.regsym[i] = declare_register (name, i);
5806 }
5807
5808 /* predicate registers: */
5809 total += 64;
5810 for (; i < total; ++i)
5811 {
5812 sprintf (name, "p%d", i - REG_P);
5813 md.regsym[i] = declare_register (name, i);
5814 }
5815
5816 /* branch registers: */
5817 total += 8;
5818 for (; i < total; ++i)
5819 {
5820 sprintf (name, "b%d", i - REG_BR);
5821 md.regsym[i] = declare_register (name, i);
5822 }
5823
5824 md.regsym[REG_IP] = declare_register ("ip", REG_IP);
5825 md.regsym[REG_CFM] = declare_register ("cfm", REG_CFM);
5826 md.regsym[REG_PR] = declare_register ("pr", REG_PR);
5827 md.regsym[REG_PR_ROT] = declare_register ("pr.rot", REG_PR_ROT);
5828 md.regsym[REG_PSR] = declare_register ("psr", REG_PSR);
5829 md.regsym[REG_PSR_L] = declare_register ("psr.l", REG_PSR_L);
5830 md.regsym[REG_PSR_UM] = declare_register ("psr.um", REG_PSR_UM);
5831
5832 for (i = 0; i < NELEMS (indirect_reg); ++i)
5833 {
5834 regnum = indirect_reg[i].regnum;
5835 md.regsym[regnum] = declare_register (indirect_reg[i].name, regnum);
5836 }
5837
5838 /* define synonyms for application registers: */
5839 for (i = REG_AR; i < REG_AR + NELEMS (ar); ++i)
5840 md.regsym[i] = declare_register (ar[i - REG_AR].name,
5841 REG_AR + ar[i - REG_AR].regnum);
5842
5843 /* define synonyms for control registers: */
5844 for (i = REG_CR; i < REG_CR + NELEMS (cr); ++i)
5845 md.regsym[i] = declare_register (cr[i - REG_CR].name,
5846 REG_CR + cr[i - REG_CR].regnum);
5847
5848 declare_register ("gp", REG_GR + 1);
5849 declare_register ("sp", REG_GR + 12);
5850 declare_register ("rp", REG_BR + 0);
5851
e0c9811a
JW
5852 /* pseudo-registers used to specify unwind info: */
5853 declare_register ("psp", REG_PSP);
5854
800eeca4
JW
5855 declare_register_set ("ret", 4, REG_GR + 8);
5856 declare_register_set ("farg", 8, REG_FR + 8);
5857 declare_register_set ("fret", 8, REG_FR + 8);
5858
5859 for (i = 0; i < NELEMS (const_bits); ++i)
5860 {
5861 err = hash_insert (md.const_hash, const_bits[i].name,
5862 (PTR) (const_bits + i));
5863 if (err)
5864 as_fatal ("Inserting \"%s\" into constant hash table failed: %s",
5865 name, err);
5866 }
5867
5868 /* Default to 64-bit mode. */
5869 md.flags = EF_IA_64_ABI64;
5870
5871 md.mem_offset.hint = 0;
5872 md.path = 0;
5873 md.maxpaths = 0;
5874 md.entry_labels = NULL;
5875}
5876
5877void
5878ia64_end_of_source ()
5879{
5880 /* terminate insn group upon reaching end of file: */
5881 insn_group_break (1, 0, 0);
5882
5883 /* emits slots we haven't written yet: */
5884 ia64_flush_insns ();
5885
5886 bfd_set_private_flags (stdoutput, md.flags);
5887
5888 if (debug_type == DEBUG_DWARF2)
5889 dwarf2_finish ();
5890
5891 md.mem_offset.hint = 0;
5892}
5893
5894void
5895ia64_start_line ()
5896{
5897 md.qp.X_op = O_absent;
5898
5899 if (ignore_input ())
5900 return;
5901
5902 if (input_line_pointer[0] == ';' && input_line_pointer[-1] == ';')
5903 {
5904 if (md.detect_dv && !md.explicit_mode)
5905 as_warn (_("Explicit stops are ignored in auto mode"));
5906 else
5907 insn_group_break (1, 0, 0);
5908 }
5909}
5910
5911int
5912ia64_unrecognized_line (ch)
5913 int ch;
5914{
5915 switch (ch)
5916 {
5917 case '(':
5918 expression (&md.qp);
5919 if (*input_line_pointer++ != ')')
5920 {
5921 as_bad ("Expected ')'");
5922 return 0;
5923 }
5924 if (md.qp.X_op != O_register)
5925 {
5926 as_bad ("Qualifying predicate expected");
5927 return 0;
5928 }
5929 if (md.qp.X_add_number < REG_P || md.qp.X_add_number >= REG_P + 64)
5930 {
5931 as_bad ("Predicate register expected");
5932 return 0;
5933 }
5934 return 1;
5935
5936 case '{':
5937 if (md.manual_bundling)
5938 as_warn ("Found '{' when manual bundling is already turned on");
5939 else
5940 CURR_SLOT.manual_bundling_on = 1;
5941 md.manual_bundling = 1;
5942
5943 /* bundling is only acceptable in explicit mode
5944 or when in default automatic mode */
5945 if (md.detect_dv && !md.explicit_mode)
5946 {
5947 if (!md.mode_explicitly_set
5948 && !md.default_explicit_mode)
5949 dot_dv_mode ('E');
5950 else
5951 as_warn (_("Found '{' after explicit switch to automatic mode"));
5952 }
5953 return 1;
5954
5955 case '}':
5956 if (!md.manual_bundling)
5957 as_warn ("Found '}' when manual bundling is off");
5958 else
5959 PREV_SLOT.manual_bundling_off = 1;
5960 md.manual_bundling = 0;
5961
5962 /* switch back to automatic mode, if applicable */
5963 if (md.detect_dv
5964 && md.explicit_mode
5965 && !md.mode_explicitly_set
5966 && !md.default_explicit_mode)
5967 dot_dv_mode ('A');
5968
5969 /* Allow '{' to follow on the same line. We also allow ";;", but that
5970 happens automatically because ';' is an end of line marker. */
5971 SKIP_WHITESPACE ();
5972 if (input_line_pointer[0] == '{')
5973 {
5974 input_line_pointer++;
5975 return ia64_unrecognized_line ('{');
5976 }
5977
5978 demand_empty_rest_of_line ();
5979 return 1;
5980
5981 default:
5982 break;
5983 }
5984 return 0; /* not a valid line */
5985}
5986
5987void
5988ia64_frob_label (sym)
5989 struct symbol *sym;
5990{
5991 struct label_fix *fix;
5992
5993 if (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE)
5994 {
5995 md.last_text_seg = now_seg;
5996 fix = obstack_alloc (&notes, sizeof (*fix));
5997 fix->sym = sym;
5998 fix->next = CURR_SLOT.label_fixups;
5999 CURR_SLOT.label_fixups = fix;
6000
6001 /* keep track of how many code entry points we've seen */
6002 if (md.path == md.maxpaths)
6003 {
6004 md.maxpaths += 20;
6005 md.entry_labels = (const char **)
6006 xrealloc ((void *)md.entry_labels, md.maxpaths * sizeof (char *));
6007 }
6008 md.entry_labels[md.path++] = S_GET_NAME (sym);
6009 }
6010}
6011
6012void
6013ia64_flush_pending_output ()
6014{
6015 if (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE)
6016 {
6017 /* ??? This causes many unnecessary stop bits to be emitted.
6018 Unfortunately, it isn't clear if it is safe to remove this. */
6019 insn_group_break (1, 0, 0);
6020 ia64_flush_insns ();
6021 }
6022}
6023
6024/* Do ia64-specific expression optimization. All that's done here is
6025 to transform index expressions that are either due to the indexing
6026 of rotating registers or due to the indexing of indirect register
6027 sets. */
6028int
6029ia64_optimize_expr (l, op, r)
6030 expressionS *l;
6031 operatorT op;
6032 expressionS *r;
6033{
6034 unsigned num_regs;
6035
6036 if (op == O_index)
6037 {
6038 if (l->X_op == O_register && r->X_op == O_constant)
6039 {
6040 num_regs = (l->X_add_number >> 16);
6041 if ((unsigned) r->X_add_number >= num_regs)
6042 {
6043 if (!num_regs)
6044 as_bad ("No current frame");
6045 else
6046 as_bad ("Index out of range 0..%u", num_regs - 1);
6047 r->X_add_number = 0;
6048 }
6049 l->X_add_number = (l->X_add_number & 0xffff) + r->X_add_number;
6050 return 1;
6051 }
6052 else if (l->X_op == O_register && r->X_op == O_register)
6053 {
6054 if (l->X_add_number < IND_CPUID || l->X_add_number > IND_RR
6055 || l->X_add_number == IND_MEM)
6056 {
6057 as_bad ("Indirect register set name expected");
6058 l->X_add_number = IND_CPUID;
6059 }
6060 l->X_op = O_index;
6061 l->X_op_symbol = md.regsym[l->X_add_number];
6062 l->X_add_number = r->X_add_number;
6063 return 1;
6064 }
6065 }
6066 return 0;
6067}
6068
6069int
6070ia64_parse_name (name, e)
6071 char *name;
6072 expressionS *e;
6073{
6074 struct const_desc *cdesc;
6075 struct dynreg *dr = 0;
6076 unsigned int regnum;
6077 struct symbol *sym;
6078 char *end;
6079
6080 /* first see if NAME is a known register name: */
6081 sym = hash_find (md.reg_hash, name);
6082 if (sym)
6083 {
6084 e->X_op = O_register;
6085 e->X_add_number = S_GET_VALUE (sym);
6086 return 1;
6087 }
6088
6089 cdesc = hash_find (md.const_hash, name);
6090 if (cdesc)
6091 {
6092 e->X_op = O_constant;
6093 e->X_add_number = cdesc->value;
6094 return 1;
6095 }
6096
6097 /* check for inN, locN, or outN: */
6098 switch (name[0])
6099 {
6100 case 'i':
6101 if (name[1] == 'n' && isdigit (name[2]))
6102 {
6103 dr = &md.in;
6104 name += 2;
6105 }
6106 break;
6107
6108 case 'l':
6109 if (name[1] == 'o' && name[2] == 'c' && isdigit (name[3]))
6110 {
6111 dr = &md.loc;
6112 name += 3;
6113 }
6114 break;
6115
6116 case 'o':
6117 if (name[1] == 'u' && name[2] == 't' && isdigit (name[3]))
6118 {
6119 dr = &md.out;
6120 name += 3;
6121 }
6122 break;
6123
6124 default:
6125 break;
6126 }
6127
6128 if (dr)
6129 {
6130 /* the name is inN, locN, or outN; parse the register number: */
6131 regnum = strtoul (name, &end, 10);
6132 if (end > name && *end == '\0')
6133 {
6134 if ((unsigned) regnum >= dr->num_regs)
6135 {
6136 if (!dr->num_regs)
6137 as_bad ("No current frame");
6138 else
6139 as_bad ("Register number out of range 0..%u", dr->num_regs-1);
6140 regnum = 0;
6141 }
6142 e->X_op = O_register;
6143 e->X_add_number = dr->base + regnum;
6144 return 1;
6145 }
6146 }
6147
6148 if ((dr = hash_find (md.dynreg_hash, name)))
6149 {
6150 /* We've got ourselves the name of a rotating register set.
6151 Store the base register number in the low 16 bits of
6152 X_add_number and the size of the register set in the top 16
6153 bits. */
6154 e->X_op = O_register;
6155 e->X_add_number = dr->base | (dr->num_regs << 16);
6156 return 1;
6157 }
6158 return 0;
6159}
6160
6161/* Remove the '#' suffix that indicates a symbol as opposed to a register. */
6162
6163char *
6164ia64_canonicalize_symbol_name (name)
6165 char *name;
6166{
6167 size_t len = strlen(name);
6168 if (len > 1 && name[len-1] == '#')
6169 name[len-1] = '\0';
6170 return name;
6171}
6172
6173static int
6174is_conditional_branch (idesc)
6175 struct ia64_opcode *idesc;
6176{
6177 return (strncmp (idesc->name, "br", 2) == 0
6178 && (strcmp (idesc->name, "br") == 0
6179 || strncmp (idesc->name, "br.cond", 7) == 0
6180 || strncmp (idesc->name, "br.call", 7) == 0
6181 || strncmp (idesc->name, "br.ret", 6) == 0
6182 || strcmp (idesc->name, "brl") == 0
6183 || strncmp (idesc->name, "brl.cond", 7) == 0
6184 || strncmp (idesc->name, "brl.call", 7) == 0
6185 || strncmp (idesc->name, "brl.ret", 6) == 0));
6186}
6187
6188/* Return whether the given opcode is a taken branch. If there's any doubt,
6189 returns zero */
6190static int
6191is_taken_branch (idesc)
6192 struct ia64_opcode *idesc;
6193{
6194 return ((is_conditional_branch (idesc) && CURR_SLOT.qp_regno == 0)
6195 || strncmp (idesc->name, "br.ia", 5) == 0);
6196}
6197
6198/* Return whether the given opcode is an interruption or rfi. If there's any
6199 doubt, returns zero */
6200static int
6201is_interruption_or_rfi (idesc)
6202 struct ia64_opcode *idesc;
6203{
6204 if (strcmp (idesc->name, "rfi") == 0)
6205 return 1;
6206 return 0;
6207}
6208
6209/* Returns the index of the given dependency in the opcode's list of chks, or
6210 -1 if there is no dependency. */
6211static int
6212depends_on (depind, idesc)
6213 int depind;
6214 struct ia64_opcode *idesc;
6215{
6216 int i;
6217 const struct ia64_opcode_dependency *dep = idesc->dependencies;
6218 for (i = 0;i < dep->nchks; i++)
6219 {
6220 if (depind == DEP(dep->chks[i]))
6221 return i;
6222 }
6223 return -1;
6224}
6225
6226/* Determine a set of specific resources used for a particular resource
6227 class. Returns the number of specific resources identified For those
6228 cases which are not determinable statically, the resource returned is
6229 marked nonspecific.
6230
6231 Meanings of value in 'NOTE':
6232 1) only read/write when the register number is explicitly encoded in the
6233 insn.
6234 2) only read CFM when accessing a rotating GR, FR, or PR. mov pr only
6235 accesses CFM when qualifying predicate is in the rotating region.
6236 3) general register value is used to specify an indirect register; not
6237 determinable statically.
6238 4) only read the given resource when bits 7:0 of the indirect index
6239 register value does not match the register number of the resource; not
6240 determinable statically.
6241 5) all rules are implementation specific.
6242 6) only when both the index specified by the reader and the index specified
6243 by the writer have the same value in bits 63:61; not determinable
6244 statically.
6245 7) only access the specified resource when the corresponding mask bit is
6246 set
6247 8) PSR.dfh is only read when these insns reference FR32-127. PSR.dfl is
6248 only read when these insns reference FR2-31
6249 9) PSR.mfl is only written when these insns write FR2-31. PSR.mfh is only
6250 written when these insns write FR32-127
6251 10) The PSR.bn bit is only accessed when one of GR16-31 is specified in the
6252 instruction
6253 11) The target predicates are written independently of PR[qp], but source
6254 registers are only read if PR[qp] is true. Since the state of PR[qp]
6255 cannot statically be determined, all source registers are marked used.
6256 12) This insn only reads the specified predicate register when that
6257 register is the PR[qp].
6258 13) This reference to ld-c only applies to teh GR whose value is loaded
6259 with data returned from memory, not the post-incremented address register.
6260 14) The RSE resource includes the implementation-specific RSE internal
6261 state resources. At least one (and possibly more) of these resources are
6262 read by each instruction listed in IC:rse-readers. At least one (and
6263 possibly more) of these resources are written by each insn listed in
6264 IC:rse-writers.
6265 15+16) Represents reserved instructions, which the assembler does not
6266 generate.
6267
6268 Memory resources (i.e. locations in memory) are *not* marked or tracked by
6269 this code; there are no dependency violations based on memory access.
6270
6271*/
6272
6273#define MAX_SPECS 256
6274#define DV_CHK 1
6275#define DV_REG 0
6276
6277static int
6278specify_resource (dep, idesc, type, specs, note, path)
6279 const struct ia64_dependency *dep;
6280 struct ia64_opcode *idesc;
6281 int type; /* is this a DV chk or a DV reg? */
6282 struct rsrc specs[MAX_SPECS]; /* returned specific resources */
6283 int note; /* resource note for this insn's usage */
6284 int path; /* which execution path to examine */
6285{
6286 int count = 0;
6287 int i;
6288 int rsrc_write = 0;
6289 struct rsrc tmpl;
6290
6291 if (dep->mode == IA64_DV_WAW
6292 || (dep->mode == IA64_DV_RAW && type == DV_REG)
6293 || (dep->mode == IA64_DV_WAR && type == DV_CHK))
6294 rsrc_write = 1;
6295
6296 /* template for any resources we identify */
6297 tmpl.dependency = dep;
6298 tmpl.note = note;
6299 tmpl.insn_srlz = tmpl.data_srlz = 0;
6300 tmpl.qp_regno = CURR_SLOT.qp_regno;
6301 tmpl.link_to_qp_branch = 1;
6302 tmpl.mem_offset.hint = 0;
6303 tmpl.specific = 1;
6304 tmpl.index = 0;
6305
6306#define UNHANDLED \
6307as_warn (_("Unhandled dependency %s for %s (%s), note %d"), \
6308dep->name, idesc->name, (rsrc_write?"write":"read"), note)
6309#define KNOWN(REG) (gr_values[REG].known && gr_values[REG].path >= path)
6310
6311 /* we don't need to track these */
6312 if (dep->semantics == IA64_DVS_NONE)
6313 return 0;
6314
6315 switch (dep->specifier)
6316 {
6317 case IA64_RS_AR_K:
6318 if (note == 1)
6319 {
6320 if (idesc->operands[!rsrc_write] == IA64_OPND_AR3)
6321 {
6322 int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_AR;
6323 if (regno >= 0 && regno <= 7)
6324 {
6325 specs[count] = tmpl;
6326 specs[count++].index = regno;
6327 }
6328 }
6329 }
6330 else if (note == 0)
6331 {
6332 for(i=0;i < 8;i++)
6333 {
6334 specs[count] = tmpl;
6335 specs[count++].index = i;
6336 }
6337 }
6338 else
6339 {
6340 UNHANDLED;
6341 }
6342 break;
6343
6344 case IA64_RS_AR_UNAT:
6345 /* This is a mov =AR or mov AR= instruction. */
6346 if (idesc->operands[!rsrc_write] == IA64_OPND_AR3)
6347 {
6348 int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_AR;
6349 if (regno == AR_UNAT)
6350 {
6351 specs[count++] = tmpl;
6352 }
6353 }
6354 else
6355 {
6356 /* This is a spill/fill, or other instruction that modifies the
6357 unat register. */
6358
6359 /* Unless we can determine the specific bits used, mark the whole
6360 thing; bits 8:3 of the memory address indicate the bit used in
6361 UNAT. The .mem.offset hint may be used to eliminate a small
6362 subset of conflicts. */
6363 specs[count] = tmpl;
6364 if (md.mem_offset.hint)
6365 {
6366 if (md.debug_dv)
6367 fprintf (stderr, " Using hint for spill/fill\n");
6368 /* the index isn't actually used, just set it to something
6369 approximating the bit index */
6370 specs[count].index = (md.mem_offset.offset >> 3) & 0x3F;
6371 specs[count].mem_offset.hint = 1;
6372 specs[count].mem_offset.offset = md.mem_offset.offset;
6373 specs[count++].mem_offset.base = md.mem_offset.base;
6374 }
6375 else
6376 {
6377 specs[count++].specific = 0;
6378 }
6379 }
6380 break;
6381
6382 case IA64_RS_AR:
6383 if (note == 1)
6384 {
6385 if (idesc->operands[!rsrc_write] == IA64_OPND_AR3)
6386 {
6387 int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_AR;
6388 if ((regno >= 8 && regno <= 15)
6389 || (regno >= 20 && regno <= 23)
6390 || (regno >= 31 && regno <= 39)
6391 || (regno >= 41 && regno <= 47)
6392 || (regno >= 67 && regno <= 111))
6393 {
6394 specs[count] = tmpl;
6395 specs[count++].index = regno;
6396 }
6397 }
6398 }
6399 else
6400 {
6401 UNHANDLED;
6402 }
6403 break;
6404
6405 case IA64_RS_ARb:
6406 if (note == 1)
6407 {
6408 if (idesc->operands[!rsrc_write] == IA64_OPND_AR3)
6409 {
6410 int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_AR;
6411 if ((regno >= 48 && regno <= 63)
6412 || (regno >= 112 && regno <= 127))
6413 {
6414 specs[count] = tmpl;
6415 specs[count++].index = regno;
6416 }
6417 }
6418 }
6419 else if (note == 0)
6420 {
6421 for (i=48;i < 64;i++)
6422 {
6423 specs[count] = tmpl;
6424 specs[count++].index = i;
6425 }
6426 for (i=112;i < 128;i++)
6427 {
6428 specs[count] = tmpl;
6429 specs[count++].index = i;
6430 }
6431 }
6432 else
6433 {
6434 UNHANDLED;
6435 }
6436 break;
6437
6438 case IA64_RS_BR:
6439 if (note != 1)
6440 {
6441 UNHANDLED;
6442 }
6443 else
6444 {
6445 if (rsrc_write)
6446 {
6447 for (i=0;i < idesc->num_outputs;i++)
6448 if (idesc->operands[i] == IA64_OPND_B1
6449 || idesc->operands[i] == IA64_OPND_B2)
6450 {
6451 specs[count] = tmpl;
6452 specs[count++].index =
6453 CURR_SLOT.opnd[i].X_add_number - REG_BR;
6454 }
6455 }
6456 else
6457 {
6458 for (i = idesc->num_outputs;i < NELEMS(idesc->operands);i++)
6459 if (idesc->operands[i] == IA64_OPND_B1
6460 || idesc->operands[i] == IA64_OPND_B2)
6461 {
6462 specs[count] = tmpl;
6463 specs[count++].index =
6464 CURR_SLOT.opnd[i].X_add_number - REG_BR;
6465 }
6466 }
6467 }
6468 break;
6469
6470 case IA64_RS_CPUID: /* four or more registers */
6471 if (note == 3)
6472 {
6473 if (idesc->operands[!rsrc_write] == IA64_OPND_CPUID_R3)
6474 {
6475 int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_GR;
6476 if (regno >= 0 && regno < NELEMS(gr_values)
6477 && KNOWN(regno))
6478 {
6479 specs[count] = tmpl;
6480 specs[count++].index = gr_values[regno].value & 0xFF;
6481 }
6482 else
6483 {
6484 specs[count] = tmpl;
6485 specs[count++].specific = 0;
6486 }
6487 }
6488 }
6489 else
6490 {
6491 UNHANDLED;
6492 }
6493 break;
6494
6495 case IA64_RS_DBR: /* four or more registers */
6496 if (note == 3)
6497 {
6498 if (idesc->operands[!rsrc_write] == IA64_OPND_DBR_R3)
6499 {
6500 int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_GR;
6501 if (regno >= 0 && regno < NELEMS(gr_values)
6502 && KNOWN(regno))
6503 {
6504 specs[count] = tmpl;
6505 specs[count++].index = gr_values[regno].value & 0xFF;
6506 }
6507 else
6508 {
6509 specs[count] = tmpl;
6510 specs[count++].specific = 0;
6511 }
6512 }
6513 }
6514 else if (note == 0 && !rsrc_write)
6515 {
6516 specs[count] = tmpl;
6517 specs[count++].specific = 0;
6518 }
6519 else
6520 {
6521 UNHANDLED;
6522 }
6523 break;
6524
6525 case IA64_RS_IBR: /* four or more registers */
6526 if (note == 3)
6527 {
6528 if (idesc->operands[!rsrc_write] == IA64_OPND_IBR_R3)
6529 {
6530 int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_GR;
6531 if (regno >= 0 && regno < NELEMS(gr_values)
6532 && KNOWN(regno))
6533 {
6534 specs[count] = tmpl;
6535 specs[count++].index = gr_values[regno].value & 0xFF;
6536 }
6537 else
6538 {
6539 specs[count] = tmpl;
6540 specs[count++].specific = 0;
6541 }
6542 }
6543 }
6544 else
6545 {
6546 UNHANDLED;
6547 }
6548 break;
6549
6550 case IA64_RS_MSR:
6551 if (note == 5)
6552 {
6553 /* These are implementation specific. Force all references to
6554 conflict with all other references. */
6555 specs[count] = tmpl;
6556 specs[count++].specific = 0;
6557 }
6558 else
6559 {
6560 UNHANDLED;
6561 }
6562 break;
6563
6564 case IA64_RS_PKR: /* 16 or more registers */
6565 if (note == 3 || note == 4)
6566 {
6567 if (idesc->operands[!rsrc_write] == IA64_OPND_PKR_R3)
6568 {
6569 int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_GR;
6570 if (regno >= 0 && regno < NELEMS(gr_values)
6571 && KNOWN(regno))
6572 {
6573 if (note == 3)
6574 {
6575 specs[count] = tmpl;
6576 specs[count++].index = gr_values[regno].value & 0xFF;
6577 }
6578 else for (i=0;i < NELEMS(gr_values);i++)
6579 {
6580 /* uses all registers *except* the one in R3 */
6581 if (i != (gr_values[regno].value & 0xFF))
6582 {
6583 specs[count] = tmpl;
6584 specs[count++].index = i;
6585 }
6586 }
6587 }
6588 else
6589 {
6590 specs[count] = tmpl;
6591 specs[count++].specific = 0;
6592 }
6593 }
6594 }
6595 else if (note == 0)
6596 {
6597 /* probe et al. */
6598 specs[count] = tmpl;
6599 specs[count++].specific = 0;
6600 }
6601 break;
6602
6603 case IA64_RS_PMC: /* four or more registers */
6604 if (note == 3)
6605 {
6606 if (idesc->operands[!rsrc_write] == IA64_OPND_PMC_R3
6607 || (!rsrc_write && idesc->operands[1] == IA64_OPND_PMD_R3))
6608
6609 {
6610 int index = ((idesc->operands[1] == IA64_OPND_R3 && !rsrc_write)
6611 ? 1 : !rsrc_write);
6612 int regno = CURR_SLOT.opnd[index].X_add_number - REG_GR;
6613 if (regno >= 0 && regno < NELEMS(gr_values)
6614 && KNOWN(regno))
6615 {
6616 specs[count] = tmpl;
6617 specs[count++].index = gr_values[regno].value & 0xFF;
6618 }
6619 else
6620 {
6621 specs[count] = tmpl;
6622 specs[count++].specific = 0;
6623 }
6624 }
6625 }
6626 else
6627 {
6628 UNHANDLED;
6629 }
6630 break;
6631
6632 case IA64_RS_PMD: /* four or more registers */
6633 if (note == 3)
6634 {
6635 if (idesc->operands[!rsrc_write] == IA64_OPND_PMD_R3)
6636 {
6637 int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_GR;
6638 if (regno >= 0 && regno < NELEMS(gr_values)
6639 && KNOWN(regno))
6640 {
6641 specs[count] = tmpl;
6642 specs[count++].index = gr_values[regno].value & 0xFF;
6643 }
6644 else
6645 {
6646 specs[count] = tmpl;
6647 specs[count++].specific = 0;
6648 }
6649 }
6650 }
6651 else
6652 {
6653 UNHANDLED;
6654 }
6655 break;
6656
6657 case IA64_RS_RR: /* eight registers */
6658 if (note == 6)
6659 {
6660 if (idesc->operands[!rsrc_write] == IA64_OPND_RR_R3)
6661 {
6662 int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_GR;
6663 if (regno >= 0 && regno < NELEMS(gr_values)
6664 && KNOWN(regno))
6665 {
6666 specs[count] = tmpl;
6667 specs[count++].index = (gr_values[regno].value >> 61) & 0x7;
6668 }
6669 else
6670 {
6671 specs[count] = tmpl;
6672 specs[count++].specific = 0;
6673 }
6674 }
6675 }
6676 else if (note == 0 && !rsrc_write)
6677 {
6678 specs[count] = tmpl;
6679 specs[count++].specific = 0;
6680 }
6681 else
6682 {
6683 UNHANDLED;
6684 }
6685 break;
6686
6687 case IA64_RS_CR_IRR:
6688 if (note == 0)
6689 {
6690 /* handle mov-from-CR-IVR; it's a read that writes CR[IRR] */
6691 int regno = CURR_SLOT.opnd[1].X_add_number - REG_CR;
6692 if (rsrc_write
6693 && idesc->operands[1] == IA64_OPND_CR3
6694 && regno == CR_IVR)
6695 {
6696 for(i=0;i < 4;i++)
6697 {
6698 specs[count] = tmpl;
6699 specs[count++].index = CR_IRR0 + i;
6700 }
6701 }
6702 }
6703 else if (note == 1)
6704 {
6705 int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_CR;
6706 if (idesc->operands[!rsrc_write] == IA64_OPND_CR3
6707 && regno >= CR_IRR0
6708 && regno <= CR_IRR3)
6709 {
6710 specs[count] = tmpl;
6711 specs[count++].index = regno;
6712 }
6713 }
6714 else
6715 {
6716 UNHANDLED;
6717 }
6718 break;
6719
6720 case IA64_RS_CR_LRR:
6721 if (note != 1)
6722 {
6723 UNHANDLED;
6724 }
6725 else
6726 {
6727 int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_CR;
6728 if (idesc->operands[!rsrc_write] == IA64_OPND_CR3
6729 && (regno == CR_LRR0 || regno == CR_LRR1))
6730 {
6731 specs[count] = tmpl;
6732 specs[count++].index = regno;
6733 }
6734 }
6735 break;
6736
6737 case IA64_RS_CR:
6738 if (note == 1)
6739 {
6740 if (idesc->operands[!rsrc_write] == IA64_OPND_CR3)
6741 {
6742 specs[count] = tmpl;
6743 specs[count++].index =
6744 CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_CR;
6745 }
6746 }
6747 else
6748 {
6749 UNHANDLED;
6750 }
6751 break;
6752
6753 case IA64_RS_FR:
6754 case IA64_RS_FRb:
6755 if (note != 1)
6756 {
6757 UNHANDLED;
6758 }
6759 else if (rsrc_write)
6760 {
6761 if (dep->specifier == IA64_RS_FRb
6762 && idesc->operands[0] == IA64_OPND_F1)
6763 {
6764 specs[count] = tmpl;
6765 specs[count++].index = CURR_SLOT.opnd[0].X_add_number - REG_FR;
6766 }
6767 }
6768 else
6769 {
6770 for (i=idesc->num_outputs;i < NELEMS(idesc->operands);i++)
6771 {
6772 if (idesc->operands[i] == IA64_OPND_F2
6773 || idesc->operands[i] == IA64_OPND_F3
6774 || idesc->operands[i] == IA64_OPND_F4)
6775 {
6776 specs[count] = tmpl;
6777 specs[count++].index =
6778 CURR_SLOT.opnd[i].X_add_number - REG_FR;
6779 }
6780 }
6781 }
6782 break;
6783
6784 case IA64_RS_GR:
6785 if (note == 13)
6786 {
6787 /* This reference applies only to the GR whose value is loaded with
6788 data returned from memory */
6789 specs[count] = tmpl;
6790 specs[count++].index = CURR_SLOT.opnd[0].X_add_number - REG_GR;
6791 }
6792 else if (note == 1)
6793 {
6794 if (rsrc_write)
6795 {
6796 for (i=0;i < idesc->num_outputs;i++)
6797 {
6798 if (idesc->operands[i] == IA64_OPND_R1
6799 || idesc->operands[i] == IA64_OPND_R2
6800 || idesc->operands[i] == IA64_OPND_R3)
6801 {
6802 specs[count] = tmpl;
6803 specs[count++].index =
6804 CURR_SLOT.opnd[i].X_add_number - REG_GR;
6805 }
6806 }
6807 }
6808 else
6809 {
6810 /* Look for anything that reads a GR */
6811 for (i=0;i < NELEMS(idesc->operands);i++)
6812 {
6813 if (idesc->operands[i] == IA64_OPND_MR3
6814 || idesc->operands[i] == IA64_OPND_CPUID_R3
6815 || idesc->operands[i] == IA64_OPND_DBR_R3
6816 || idesc->operands[i] == IA64_OPND_IBR_R3
6817 || idesc->operands[i] == IA64_OPND_MSR_R3
6818 || idesc->operands[i] == IA64_OPND_PKR_R3
6819 || idesc->operands[i] == IA64_OPND_PMC_R3
6820 || idesc->operands[i] == IA64_OPND_PMD_R3
6821 || idesc->operands[i] == IA64_OPND_RR_R3
6822 || ((i >= idesc->num_outputs)
6823 && (idesc->operands[i] == IA64_OPND_R1
6824 || idesc->operands[i] == IA64_OPND_R2
6825 || idesc->operands[i] == IA64_OPND_R3)))
6826 {
6827 specs[count] = tmpl;
6828 specs[count++].index =
6829 CURR_SLOT.opnd[i].X_add_number - REG_GR;
6830 }
6831 }
6832 }
6833 }
6834 else
6835 {
6836 UNHANDLED;
6837 }
6838 break;
6839
6840 case IA64_RS_PR:
6841 if (note == 0)
6842 {
6843 if (idesc->operands[0] == IA64_OPND_PR_ROT)
6844 {
6845 for (i=16;i < 63;i++)
6846 {
6847 specs[count] = tmpl;
6848 specs[count++].index = i;
6849 }
6850 }
6851 else
6852 {
6853 for (i=1;i < 63;i++)
6854 {
6855 specs[count] = tmpl;
6856 specs[count++].index = i;
6857 }
6858 }
6859 }
6860 else if (note == 7)
6861 {
6862 valueT mask = 0;
6863 /* mark only those registers indicated by the mask */
6864 if (rsrc_write
6865 && idesc->operands[0] == IA64_OPND_PR)
6866 {
6867 mask = CURR_SLOT.opnd[2].X_add_number;
6868 if (mask & ((valueT)1<<16))
6869 mask |= ~(valueT)0xffff;
6870 for (i=1;i < 63;i++)
6871 {
6872 if (mask & ((valueT)1<<i))
6873 {
6874 specs[count] = tmpl;
6875 specs[count++].index = i;
6876 }
6877 }
6878 }
6879 else if (rsrc_write
6880 && idesc->operands[0] == IA64_OPND_PR_ROT)
6881 {
6882 for (i=16;i < 63;i++)
6883 {
6884 specs[count] = tmpl;
6885 specs[count++].index = i;
6886 }
6887 }
6888 else
6889 {
6890 UNHANDLED;
6891 }
6892 }
6893 else if (note == 11) /* note 11 implies note 1 as well */
6894 {
6895 if (rsrc_write)
6896 {
6897 for (i=0;i < idesc->num_outputs;i++)
6898 {
6899 if (idesc->operands[i] == IA64_OPND_P1
6900 || idesc->operands[i] == IA64_OPND_P2)
6901 {
6902 int regno = CURR_SLOT.opnd[i].X_add_number - REG_P;
6903 if (regno != 0)
6904 {
6905 specs[count] = tmpl;
6906 specs[count++].index = regno;
6907 }
6908 }
6909 }
6910 }
6911 else
6912 {
6913 UNHANDLED;
6914 }
6915 }
6916 else if (note == 12)
6917 {
6918 if (CURR_SLOT.qp_regno != 0)
6919 {
6920 specs[count] = tmpl;
6921 specs[count++].index = CURR_SLOT.qp_regno;
6922 }
6923 }
6924 else if (note == 1)
6925 {
6926 if (rsrc_write)
6927 {
6928 int p1 = CURR_SLOT.opnd[0].X_add_number - REG_P;
6929 int p2 = CURR_SLOT.opnd[1].X_add_number - REG_P;
6930 if ((idesc->operands[0] == IA64_OPND_P1
6931 || idesc->operands[0] == IA64_OPND_P2)
6932 && p1 != 0 && p1 != 63)
6933 {
6934 specs[count] = tmpl;
6935 specs[count++].index = p1;
6936 }
6937 if ((idesc->operands[1] == IA64_OPND_P1
6938 || idesc->operands[1] == IA64_OPND_P2)
6939 && p2 != 0 && p2 != 63)
6940 {
6941 specs[count] = tmpl;
6942 specs[count++].index = p2;
6943 }
6944 }
6945 else
6946 {
6947 if (CURR_SLOT.qp_regno != 0)
6948 {
6949 specs[count] = tmpl;
6950 specs[count++].index = CURR_SLOT.qp_regno;
6951 }
6952 if (idesc->operands[1] == IA64_OPND_PR)
6953 {
6954 for (i=1;i < 63;i++)
6955 {
6956 specs[count] = tmpl;
6957 specs[count++].index = i;
6958 }
6959 }
6960 }
6961 }
6962 else
6963 {
6964 UNHANDLED;
6965 }
6966 break;
6967
6968 case IA64_RS_PSR:
6969 /* Verify that the instruction is using the PSR bit indicated in
6970 dep->regindex */
6971 if (note == 0)
6972 {
6973 if (idesc->operands[!rsrc_write] == IA64_OPND_PSR_UM)
6974 {
6975 if (dep->regindex < 6)
6976 {
6977 specs[count++] = tmpl;
6978 }
6979 }
6980 else if (idesc->operands[!rsrc_write] == IA64_OPND_PSR)
6981 {
6982 if (dep->regindex < 32
6983 || dep->regindex == 35
6984 || dep->regindex == 36
6985 || (!rsrc_write && dep->regindex == PSR_CPL))
6986 {
6987 specs[count++] = tmpl;
6988 }
6989 }
6990 else if (idesc->operands[!rsrc_write] == IA64_OPND_PSR_L)
6991 {
6992 if (dep->regindex < 32
6993 || dep->regindex == 35
6994 || dep->regindex == 36
6995 || (rsrc_write && dep->regindex == PSR_CPL))
6996 {
6997 specs[count++] = tmpl;
6998 }
6999 }
7000 else
7001 {
7002 /* Several PSR bits have very specific dependencies. */
7003 switch (dep->regindex)
7004 {
7005 default:
7006 specs[count++] = tmpl;
7007 break;
7008 case PSR_IC:
7009 if (rsrc_write)
7010 {
7011 specs[count++] = tmpl;
7012 }
7013 else
7014 {
7015 /* Only certain CR accesses use PSR.ic */
7016 if (idesc->operands[0] == IA64_OPND_CR3
7017 || idesc->operands[1] == IA64_OPND_CR3)
7018 {
7019 int index =
7020 ((idesc->operands[0] == IA64_OPND_CR3)
7021 ? 0 : 1);
7022 int regno =
7023 CURR_SLOT.opnd[index].X_add_number - REG_CR;
7024
7025 switch (regno)
7026 {
7027 default:
7028 break;
7029 case CR_ITIR:
7030 case CR_IFS:
7031 case CR_IIM:
7032 case CR_IIP:
7033 case CR_IPSR:
7034 case CR_ISR:
7035 case CR_IFA:
7036 case CR_IHA:
7037 case CR_IIPA:
7038 specs[count++] = tmpl;
7039 break;
7040 }
7041 }
7042 }
7043 break;
7044 case PSR_CPL:
7045 if (rsrc_write)
7046 {
7047 specs[count++] = tmpl;
7048 }
7049 else
7050 {
7051 /* Only some AR accesses use cpl */
7052 if (idesc->operands[0] == IA64_OPND_AR3
7053 || idesc->operands[1] == IA64_OPND_AR3)
7054 {
7055 int index =
7056 ((idesc->operands[0] == IA64_OPND_AR3)
7057 ? 0 : 1);
7058 int regno =
7059 CURR_SLOT.opnd[index].X_add_number - REG_AR;
7060
7061 if (regno == AR_ITC
7062 || (index == 0
7063 && (regno == AR_ITC
7064 || regno == AR_RSC
7065 || (regno >= AR_K0
7066 && regno <= AR_K7))))
7067 {
7068 specs[count++] = tmpl;
7069 }
7070 }
7071 else
7072 {
7073 specs[count++] = tmpl;
7074 }
7075 break;
7076 }
7077 }
7078 }
7079 }
7080 else if (note == 7)
7081 {
7082 valueT mask = 0;
7083 if (idesc->operands[0] == IA64_OPND_IMMU24)
7084 {
7085 mask = CURR_SLOT.opnd[0].X_add_number;
7086 }
7087 else
7088 {
7089 UNHANDLED;
7090 }
7091 if (mask & ((valueT)1<<dep->regindex))
7092 {
7093 specs[count++] = tmpl;
7094 }
7095 }
7096 else if (note == 8)
7097 {
7098 int min = dep->regindex == PSR_DFL ? 2 : 32;
7099 int max = dep->regindex == PSR_DFL ? 31 : 127;
7100 /* dfh is read on FR32-127; dfl is read on FR2-31 */
7101 for (i=0;i < NELEMS(idesc->operands);i++)
7102 {
7103 if (idesc->operands[i] == IA64_OPND_F1
7104 || idesc->operands[i] == IA64_OPND_F2
7105 || idesc->operands[i] == IA64_OPND_F3
7106 || idesc->operands[i] == IA64_OPND_F4)
7107 {
7108 int reg = CURR_SLOT.opnd[i].X_add_number - REG_FR;
7109 if (reg >= min && reg <= max)
7110 {
7111 specs[count++] = tmpl;
7112 }
7113 }
7114 }
7115 }
7116 else if (note == 9)
7117 {
7118 int min = dep->regindex == PSR_MFL ? 2 : 32;
7119 int max = dep->regindex == PSR_MFL ? 31 : 127;
7120 /* mfh is read on writes to FR32-127; mfl is read on writes to
7121 FR2-31 */
7122 for (i=0;i < idesc->num_outputs;i++)
7123 {
7124 if (idesc->operands[i] == IA64_OPND_F1)
7125 {
7126 int reg = CURR_SLOT.opnd[i].X_add_number - REG_FR;
7127 if (reg >= min && reg <= max)
7128 {
7129 specs[count++] = tmpl;
7130 }
7131 }
7132 }
7133 }
7134 else if (note == 10)
7135 {
7136 for (i=0;i < NELEMS(idesc->operands);i++)
7137 {
7138 if (idesc->operands[i] == IA64_OPND_R1
7139 || idesc->operands[i] == IA64_OPND_R2
7140 || idesc->operands[i] == IA64_OPND_R3)
7141 {
7142 int regno = CURR_SLOT.opnd[i].X_add_number - REG_GR;
7143 if (regno >= 16 && regno <= 31)
7144 {
7145 specs[count++] = tmpl;
7146 }
7147 }
7148 }
7149 }
7150 else
7151 {
7152 UNHANDLED;
7153 }
7154 break;
7155
7156 case IA64_RS_AR_FPSR:
7157 if (idesc->operands[!rsrc_write] == IA64_OPND_AR3)
7158 {
7159 int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_AR;
7160 if (regno == AR_FPSR)
7161 {
7162 specs[count++] = tmpl;
7163 }
7164 }
7165 else
7166 {
7167 specs[count++] = tmpl;
7168 }
7169 break;
7170
7171 case IA64_RS_ARX:
7172 /* Handle all AR[REG] resources */
7173 if (note == 0 || note == 1)
7174 {
7175 int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_AR;
7176 if (idesc->operands[!rsrc_write] == IA64_OPND_AR3
7177 && regno == dep->regindex)
7178 {
7179 specs[count++] = tmpl;
7180 }
7181 /* other AR[REG] resources may be affected by AR accesses */
7182 else if (idesc->operands[0] == IA64_OPND_AR3)
7183 {
7184 /* AR[] writes */
7185 regno = CURR_SLOT.opnd[0].X_add_number - REG_AR;
7186 switch (dep->regindex)
7187 {
7188 default:
7189 break;
7190 case AR_BSP:
7191 case AR_RNAT:
7192 if (regno == AR_BSPSTORE)
7193 {
7194 specs[count++] = tmpl;
7195 }
7196 case AR_RSC:
7197 if (!rsrc_write &&
7198 (regno == AR_BSPSTORE
7199 || regno == AR_RNAT))
7200 {
7201 specs[count++] = tmpl;
7202 }
7203 break;
7204 }
7205 }
7206 else if (idesc->operands[1] == IA64_OPND_AR3)
7207 {
7208 /* AR[] reads */
7209 regno = CURR_SLOT.opnd[1].X_add_number - REG_AR;
7210 switch (dep->regindex)
7211 {
7212 default:
7213 break;
7214 case AR_RSC:
7215 if (regno == AR_BSPSTORE || regno == AR_RNAT)
7216 {
7217 specs[count++] = tmpl;
7218 }
7219 break;
7220 }
7221 }
7222 else
7223 {
7224 specs[count++] = tmpl;
7225 }
7226 }
7227 else
7228 {
7229 UNHANDLED;
7230 }
7231 break;
7232
7233 case IA64_RS_CRX:
7234 /* Handle all CR[REG] resources */
7235 if (note == 0 || note == 1)
7236 {
7237 if (idesc->operands[!rsrc_write] == IA64_OPND_CR3)
7238 {
7239 int regno = CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_CR;
7240 if (regno == dep->regindex)
7241 {
7242 specs[count++] = tmpl;
7243 }
7244 else if (!rsrc_write)
7245 {
7246 /* Reads from CR[IVR] affect other resources. */
7247 if (regno == CR_IVR)
7248 {
7249 if ((dep->regindex >= CR_IRR0
7250 && dep->regindex <= CR_IRR3)
7251 || dep->regindex == CR_TPR)
7252 {
7253 specs[count++] = tmpl;
7254 }
7255 }
7256 }
7257 }
7258 else
7259 {
7260 specs[count++] = tmpl;
7261 }
7262 }
7263 else
7264 {
7265 UNHANDLED;
7266 }
7267 break;
7268
7269 case IA64_RS_INSERVICE:
7270 /* look for write of EOI (67) or read of IVR (65) */
7271 if ((idesc->operands[0] == IA64_OPND_CR3
7272 && CURR_SLOT.opnd[0].X_add_number - REG_CR == CR_EOI)
7273 || (idesc->operands[1] == IA64_OPND_CR3
7274 && CURR_SLOT.opnd[1].X_add_number - REG_CR == CR_IVR))
7275 {
7276 specs[count++] = tmpl;
7277 }
7278 break;
7279
7280 case IA64_RS_GR0:
7281 if (note == 1)
7282 {
7283 specs[count++] = tmpl;
7284 }
7285 else
7286 {
7287 UNHANDLED;
7288 }
7289 break;
7290
7291 case IA64_RS_CFM:
7292 if (note != 2)
7293 {
7294 specs[count++] = tmpl;
7295 }
7296 else
7297 {
7298 /* Check if any of the registers accessed are in the rotating region.
7299 mov to/from pr accesses CFM only when qp_regno is in the rotating
7300 region */
7301 for (i=0;i < NELEMS(idesc->operands);i++)
7302 {
7303 if (idesc->operands[i] == IA64_OPND_R1
7304 || idesc->operands[i] == IA64_OPND_R2
7305 || idesc->operands[i] == IA64_OPND_R3)
7306 {
7307 int num = CURR_SLOT.opnd[i].X_add_number - REG_GR;
7308 /* Assumes that md.rot.num_regs is always valid */
7309 if (md.rot.num_regs > 0
7310 && num > 31
7311 && num < 31 + md.rot.num_regs)
7312 {
7313 specs[count] = tmpl;
7314 specs[count++].specific = 0;
7315 }
7316 }
7317 else if (idesc->operands[i] == IA64_OPND_F1
7318 || idesc->operands[i] == IA64_OPND_F2
7319 || idesc->operands[i] == IA64_OPND_F3
7320 || idesc->operands[i] == IA64_OPND_F4)
7321 {
7322 int num = CURR_SLOT.opnd[i].X_add_number - REG_FR;
7323 if (num > 31)
7324 {
7325 specs[count] = tmpl;
7326 specs[count++].specific = 0;
7327 }
7328 }
7329 else if (idesc->operands[i] == IA64_OPND_P1
7330 || idesc->operands[i] == IA64_OPND_P2)
7331 {
7332 int num = CURR_SLOT.opnd[i].X_add_number - REG_P;
7333 if (num > 15)
7334 {
7335 specs[count] = tmpl;
7336 specs[count++].specific = 0;
7337 }
7338 }
7339 }
7340 if (CURR_SLOT.qp_regno > 15)
7341 {
7342 specs[count] = tmpl;
7343 specs[count++].specific = 0;
7344 }
7345 }
7346 break;
7347
7348 case IA64_RS_PR63:
7349 if (note == 0)
7350 {
7351 specs[count++] = tmpl;
7352 }
7353 else if (note == 11)
7354 {
7355 if ((idesc->operands[0] == IA64_OPND_P1
7356 && CURR_SLOT.opnd[0].X_add_number - REG_P == 63)
7357 || (idesc->operands[1] == IA64_OPND_P2
7358 && CURR_SLOT.opnd[1].X_add_number - REG_P == 63))
7359 {
7360 specs[count++] = tmpl;
7361 }
7362 }
7363 else if (note == 12)
7364 {
7365 if (CURR_SLOT.qp_regno == 63)
7366 {
7367 specs[count++] = tmpl;
7368 }
7369 }
7370 else if (note == 7)
7371 {
7372 valueT mask = 0;
7373 if (idesc->operands[2] == IA64_OPND_IMM17)
7374 mask = CURR_SLOT.opnd[2].X_add_number;
7375 if (mask & ((valueT)1<<63))
7376 {
7377 specs[count++] = tmpl;
7378 }
7379 }
7380 else if (note == 1)
7381 {
7382 if (rsrc_write)
7383 {
7384 for (i=0;i < idesc->num_outputs;i++)
7385 if ((idesc->operands[i] == IA64_OPND_P1
7386 || idesc->operands[i] == IA64_OPND_P2)
7387 && CURR_SLOT.opnd[i].X_add_number - REG_P == 63)
7388 {
7389 specs[count++] = tmpl;
7390 }
7391 }
7392 else
7393 {
7394 if (CURR_SLOT.qp_regno == 63)
7395 {
7396 specs[count++] = tmpl;
7397 }
7398 }
7399 }
7400 else
7401 {
7402 UNHANDLED;
7403 }
7404 break;
7405
7406 case IA64_RS_RSE:
7407 /* FIXME we can identify some individual RSE written resources, but RSE
7408 read resources have not yet been completely identified, so for now
7409 treat RSE as a single resource */
7410 if (strncmp (idesc->name, "mov", 3) == 0)
7411 {
7412 if (rsrc_write)
7413 {
7414 if (idesc->operands[0] == IA64_OPND_AR3
7415 && CURR_SLOT.opnd[0].X_add_number - REG_AR == AR_BSPSTORE)
7416 {
7417 specs[count] = tmpl;
7418 specs[count++].index = 0; /* IA64_RSE_BSPLOAD/RNATBITINDEX */
7419 }
7420 }
7421 else
7422 {
7423 if (idesc->operands[0] == IA64_OPND_AR3)
7424 {
7425 if (CURR_SLOT.opnd[0].X_add_number - REG_AR == AR_BSPSTORE
7426 || CURR_SLOT.opnd[0].X_add_number - REG_AR == AR_RNAT)
7427 {
7428 specs[count++] = tmpl;
7429 }
7430 }
7431 else if (idesc->operands[1] == IA64_OPND_AR3)
7432 {
7433 if (CURR_SLOT.opnd[1].X_add_number - REG_AR == AR_BSP
7434 || CURR_SLOT.opnd[1].X_add_number - REG_AR == AR_BSPSTORE
7435 || CURR_SLOT.opnd[1].X_add_number - REG_AR == AR_RNAT)
7436 {
7437 specs[count++] = tmpl;
7438 }
7439 }
7440 }
7441 }
7442 else
7443 {
7444 specs[count++] = tmpl;
7445 }
7446 break;
7447
7448 case IA64_RS_ANY:
7449 /* FIXME -- do any of these need to be non-specific? */
7450 specs[count++] = tmpl;
7451 break;
7452
7453 default:
7454 as_bad (_("Unrecognized dependency specifier %d\n"), dep->specifier);
7455 break;
7456 }
7457
7458 return count;
7459}
7460
7461/* Clear branch flags on marked resources. This breaks the link between the
7462 QP of the marking instruction and a subsequent branch on the same QP.
7463*/
7464static void
7465clear_qp_branch_flag (mask)
7466 valueT mask;
7467{
7468 int i;
7469 for (i = 0;i < regdepslen;i++)
7470 {
7471 valueT bit = ((valueT)1 << regdeps[i].qp_regno);
7472 if ((bit & mask) != 0)
7473 {
7474 regdeps[i].link_to_qp_branch = 0;
7475 }
7476 }
7477}
7478
7479/* Remove any mutexes which contain any of the PRs indicated in the mask.
7480
7481 Any changes to a PR clears the mutex relations which include that PR.
7482*/
7483static void
7484clear_qp_mutex (mask)
7485 valueT mask;
7486{
7487 int i;
7488
7489 i = 0;
7490 while (i < qp_mutexeslen)
7491 {
7492 if ((qp_mutexes[i].prmask & mask) != 0)
7493 {
7494 if (md.debug_dv)
7495 {
7496 fprintf (stderr, " Clearing mutex relation");
7497 print_prmask (qp_mutexes[i].prmask);
7498 fprintf (stderr, "\n");
7499 }
7500 qp_mutexes[i] = qp_mutexes[--qp_mutexeslen];
7501 }
7502 else
7503 ++i;
7504 }
7505}
7506
7507/* Clear implies relations which contain PRs in the given masks.
7508 P1_MASK indicates the source of the implies relation, while P2_MASK
7509 indicates the implied PR.
7510*/
7511static void
7512clear_qp_implies (p1_mask, p2_mask)
7513 valueT p1_mask;
7514 valueT p2_mask;
7515{
7516 int i;
7517
7518 i = 0;
7519 while (i < qp_implieslen)
7520 {
7521 if ((((valueT)1 << qp_implies[i].p1) & p1_mask) != 0
7522 || (((valueT)1 << qp_implies[i].p2) & p2_mask) != 0)
7523 {
7524 if (md.debug_dv)
7525 fprintf (stderr, "Clearing implied relation PR%d->PR%d\n",
7526 qp_implies[i].p1, qp_implies[i].p2);
7527 qp_implies[i] = qp_implies[--qp_implieslen];
7528 }
7529 else
7530 ++i;
7531 }
7532}
7533
7534/* add the PRs specified to the list of implied relations */
7535static void
7536add_qp_imply (p1, p2)
7537 int p1, p2;
7538{
7539 valueT mask;
7540 valueT bit;
7541 int i;
7542
7543 /* p0 is not meaningful here */
7544 if (p1 == 0 || p2 == 0)
7545 abort ();
7546
7547 if (p1 == p2)
7548 return;
7549
7550 /* if it exists already, ignore it */
7551 for (i=0;i < qp_implieslen;i++)
7552 {
7553 if (qp_implies[i].p1 == p1
7554 && qp_implies[i].p2 == p2
7555 && qp_implies[i].path == md.path
7556 && !qp_implies[i].p2_branched)
7557 return;
7558 }
7559
7560 if (qp_implieslen == qp_impliestotlen)
7561 {
7562 qp_impliestotlen += 20;
7563 qp_implies = (struct qp_imply *)
7564 xrealloc ((void *)qp_implies,
7565 qp_impliestotlen * sizeof (struct qp_imply));
7566 }
7567 if (md.debug_dv)
7568 fprintf (stderr, " Registering PR%d implies PR%d\n", p1, p2);
7569 qp_implies[qp_implieslen].p1 = p1;
7570 qp_implies[qp_implieslen].p2 = p2;
7571 qp_implies[qp_implieslen].path = md.path;
7572 qp_implies[qp_implieslen++].p2_branched = 0;
7573
7574 /* Add in the implied transitive relations; for everything that p2 implies,
7575 make p1 imply that, too; for everything that implies p1, make it imply p2
7576 as well. */
7577 for (i=0;i < qp_implieslen;i++)
7578 {
7579 if (qp_implies[i].p1 == p2)
7580 add_qp_imply (p1, qp_implies[i].p2);
7581 if (qp_implies[i].p2 == p1)
7582 add_qp_imply (qp_implies[i].p1, p2);
7583 }
7584 /* Add in mutex relations implied by this implies relation; for each mutex
7585 relation containing p2, duplicate it and replace p2 with p1. */
7586 bit = (valueT)1 << p1;
7587 mask = (valueT)1 << p2;
7588 for (i=0;i < qp_mutexeslen;i++)
7589 {
7590 if (qp_mutexes[i].prmask & mask)
7591 add_qp_mutex ((qp_mutexes[i].prmask & ~mask) | bit);
7592 }
7593}
7594
7595
7596/* Add the PRs specified in the mask to the mutex list; this means that only
7597 one of the PRs can be true at any time. PR0 should never be included in
7598 the mask. */
7599static void
7600add_qp_mutex (mask)
7601 valueT mask;
7602{
7603 if (mask & 0x1)
7604 abort ();
7605
7606 if (qp_mutexeslen == qp_mutexestotlen)
7607 {
7608 qp_mutexestotlen += 20;
7609 qp_mutexes = (struct qpmutex *)
7610 xrealloc ((void *)qp_mutexes,
7611 qp_mutexestotlen * sizeof (struct qpmutex));
7612 }
7613 if (md.debug_dv)
7614 {
7615 fprintf (stderr, " Registering mutex on");
7616 print_prmask (mask);
7617 fprintf (stderr, "\n");
7618 }
7619 qp_mutexes[qp_mutexeslen].path = md.path;
7620 qp_mutexes[qp_mutexeslen++].prmask = mask;
7621}
7622
7623static void
7624clear_register_values ()
7625{
7626 int i;
7627 if (md.debug_dv)
7628 fprintf (stderr, " Clearing register values\n");
7629 for (i=1;i < NELEMS(gr_values);i++)
7630 gr_values[i].known = 0;
7631}
7632
7633/* Keep track of register values/changes which affect DV tracking.
7634
7635 optimization note: should add a flag to classes of insns where otherwise we
7636 have to examine a group of strings to identify them.
7637
7638 */
7639static void
7640note_register_values (idesc)
7641 struct ia64_opcode *idesc;
7642{
7643 valueT qp_changemask = 0;
7644 int i;
7645
7646 /* invalidate values for registers being written to */
7647 for (i=0;i < idesc->num_outputs;i++)
7648 {
7649 if (idesc->operands[i] == IA64_OPND_R1
7650 || idesc->operands[i] == IA64_OPND_R2
7651 || idesc->operands[i] == IA64_OPND_R3)
7652 {
7653 int regno = CURR_SLOT.opnd[i].X_add_number - REG_GR;
7654 if (regno > 0 && regno < NELEMS(gr_values))
7655 gr_values[regno].known = 0;
7656 }
7657 else if (idesc->operands[i] == IA64_OPND_P1
7658 || idesc->operands[i] == IA64_OPND_P2)
7659 {
7660 int regno = CURR_SLOT.opnd[i].X_add_number - REG_P;
7661 qp_changemask |= (valueT)1 << regno;
7662 }
7663 else if (idesc->operands[i] == IA64_OPND_PR)
7664 {
7665 if (idesc->operands[2] & (valueT)0x10000)
7666 qp_changemask = ~(valueT)0x1FFFF | idesc->operands[2];
7667 else
7668 qp_changemask = idesc->operands[2];
7669 break;
7670 }
7671 else if (idesc->operands[i] == IA64_OPND_PR_ROT)
7672 {
7673 if (idesc->operands[1] & ((valueT)1 << 43))
7674 qp_changemask = ~(valueT)0xFFFFFFFFFFF | idesc->operands[1];
7675 else
7676 qp_changemask = idesc->operands[1];
7677 qp_changemask &= ~(valueT)0xFFFF;
7678 break;
7679 }
7680 }
7681
7682 /* Always clear qp branch flags on any PR change */
7683 /* FIXME there may be exceptions for certain compares */
7684 clear_qp_branch_flag (qp_changemask);
7685
7686 /* invalidate rotating registers on insns which affect RRBs in CFM */
7687 if (idesc->flags & IA64_OPCODE_MOD_RRBS)
7688 {
7689 qp_changemask |= ~(valueT)0xFFFF;
7690 if (strcmp (idesc->name, "clrrrb.pr") != 0)
7691 {
7692 for (i=32;i < 32+md.rot.num_regs;i++)
7693 gr_values[i].known = 0;
7694 }
7695 clear_qp_mutex (qp_changemask);
7696 clear_qp_implies (qp_changemask, qp_changemask);
7697 }
7698 /* after a call, all register values are undefined, except those marked
7699 as "safe" */
7700 else if (strncmp (idesc->name, "br.call", 6) == 0
7701 || strncmp (idesc->name, "brl.call", 7) == 0)
7702 {
7703 // FIXME keep GR values which are marked as "safe_across_calls"
7704 clear_register_values ();
7705 clear_qp_mutex (~qp_safe_across_calls);
7706 clear_qp_implies (~qp_safe_across_calls, ~qp_safe_across_calls);
7707 clear_qp_branch_flag (~qp_safe_across_calls);
7708 }
7709 /* Look for mutex and implies relations */
7710 else if ((idesc->operands[0] == IA64_OPND_P1
7711 || idesc->operands[0] == IA64_OPND_P2)
7712 && (idesc->operands[1] == IA64_OPND_P1
7713 || idesc->operands[1] == IA64_OPND_P2))
7714 {
7715 int p1 = CURR_SLOT.opnd[0].X_add_number - REG_P;
7716 int p2 = CURR_SLOT.opnd[1].X_add_number - REG_P;
7717 valueT p1mask = (valueT)1 << p1;
7718 valueT p2mask = (valueT)1 << p2;
7719
7720 /* if one of the PRs is PR0, we can't really do anything */
7721 if (p1 == 0 || p2 == 0)
7722 {
7723 if (md.debug_dv)
7724 fprintf (stderr, " Ignoring PRs due to inclusion of p0\n");
7725 }
7726 /* In general, clear mutexes and implies which include P1 or P2,
7727 with the following exceptions */
7728 else if (strstr (idesc->name, ".or.andcm") != NULL)
7729 {
7730 add_qp_mutex (p1mask | p2mask);
7731 clear_qp_implies (p2mask, p1mask);
7732 }
7733 else if (strstr (idesc->name, ".and.orcm") != NULL)
7734 {
7735 add_qp_mutex (p1mask | p2mask);
7736 clear_qp_implies (p1mask, p2mask);
7737 }
7738 else if (strstr (idesc->name, ".and") != NULL)
7739 {
7740 clear_qp_implies (0, p1mask | p2mask);
7741 }
7742 else if (strstr (idesc->name, ".or") != NULL)
7743 {
7744 clear_qp_mutex (p1mask | p2mask);
7745 clear_qp_implies (p1mask | p2mask, 0);
7746 }
7747 else
7748 {
7749 clear_qp_implies (p1mask | p2mask, p1mask | p2mask);
7750 if (strstr (idesc->name, ".unc") != NULL)
7751 {
7752 add_qp_mutex (p1mask | p2mask);
7753 if (CURR_SLOT.qp_regno != 0)
7754 {
7755 add_qp_imply (CURR_SLOT.opnd[0].X_add_number - REG_P,
7756 CURR_SLOT.qp_regno);
7757 add_qp_imply (CURR_SLOT.opnd[1].X_add_number - REG_P,
7758 CURR_SLOT.qp_regno);
7759 }
7760 }
7761 else if (CURR_SLOT.qp_regno == 0)
7762 {
7763 add_qp_mutex (p1mask | p2mask);
7764 }
7765 else
7766 {
7767 clear_qp_mutex (p1mask | p2mask);
7768 }
7769 }
7770 }
7771 /* Look for mov imm insns into GRs */
7772 else if (idesc->operands[0] == IA64_OPND_R1
7773 && (idesc->operands[1] == IA64_OPND_IMM22
7774 || idesc->operands[1] == IA64_OPND_IMMU64)
7775 && (strcmp(idesc->name, "mov") == 0
7776 || strcmp(idesc->name, "movl") == 0))
7777 {
7778 int regno = CURR_SLOT.opnd[0].X_add_number - REG_GR;
7779 if (regno > 0 && regno < NELEMS(gr_values))
7780 {
7781 gr_values[regno].known = 1;
7782 gr_values[regno].value = CURR_SLOT.opnd[1].X_add_number;
7783 gr_values[regno].path = md.path;
7784 if (md.debug_dv)
7785 fprintf (stderr, " Know gr%d = 0x%llx\n",
7786 regno, gr_values[regno].value);
7787 }
7788 }
7789 else
7790 {
7791 clear_qp_mutex (qp_changemask);
7792 clear_qp_implies (qp_changemask, qp_changemask);
7793 }
7794}
7795
7796/* Return whether the given predicate registers are currently mutex */
7797static int
7798qp_mutex (p1, p2, path)
7799 int p1;
7800 int p2;
7801 int path;
7802{
7803 int i;
7804 valueT mask;
7805
7806 if (p1 != p2)
7807 {
7808 mask = ((valueT)1<<p1) | (valueT)1<<p2;
7809 for (i=0;i < qp_mutexeslen;i++)
7810 {
7811 if (qp_mutexes[i].path >= path
7812 && (qp_mutexes[i].prmask & mask) == mask)
7813 return 1;
7814 }
7815 }
7816 return 0;
7817}
7818
7819/* Return whether the given resource is in the given insn's list of chks
7820 Return 1 if the conflict is absolutely determined, 2 if it's a potential
7821 conflict.
7822 */
7823static int
7824resources_match (rs, idesc, note, qp_regno, path)
7825 struct rsrc *rs;
7826 struct ia64_opcode *idesc;
7827 int note;
7828 int qp_regno;
7829 int path;
7830{
7831 struct rsrc specs[MAX_SPECS];
7832 int count;
7833
7834 /* If the marked resource's qp_regno and the given qp_regno are mutex,
7835 we don't need to check. One exception is note 11, which indicates that
7836 target predicates are written regardless of PR[qp]. */
7837 if (qp_mutex (rs->qp_regno, qp_regno, path)
7838 && note != 11)
7839 return 0;
7840
7841 count = specify_resource (rs->dependency, idesc, DV_CHK, specs, note, path);
7842 while (count-- > 0)
7843 {
7844 /* UNAT checking is a bit more specific than other resources */
7845 if (rs->dependency->specifier == IA64_RS_AR_UNAT
7846 && specs[count].mem_offset.hint
7847 && rs->mem_offset.hint)
7848 {
7849 if (rs->mem_offset.base == specs[count].mem_offset.base)
7850 {
7851 if (((rs->mem_offset.offset >> 3) & 0x3F) ==
7852 ((specs[count].mem_offset.offset >> 3) & 0x3F))
7853 return 1;
7854 else
7855 continue;
7856 }
7857 }
7858
7859 /* If either resource is not specific, conservatively assume a conflict
7860 */
7861 if (!specs[count].specific || !rs->specific)
7862 return 2;
7863 else if (specs[count].index == rs->index)
7864 return 1;
7865 }
7866#if 0
7867 if (md.debug_dv)
7868 fprintf (stderr, " No %s conflicts\n", rs->dependency->name);
7869#endif
7870
7871 return 0;
7872}
7873
7874/* Indicate an instruction group break; if INSERT_STOP is non-zero, then
7875 insert a stop to create the break. Update all resource dependencies
7876 appropriately. If QP_REGNO is non-zero, only apply the break to resources
7877 which use the same QP_REGNO and have the link_to_qp_branch flag set.
7878 If SAVE_CURRENT is non-zero, don't affect resources marked by the current
7879 instruction.
7880*/
7881
7882static void
7883insn_group_break (insert_stop, qp_regno, save_current)
7884 int insert_stop;
7885 int qp_regno;
7886 int save_current;
7887{
7888 int i;
7889
7890 if (insert_stop && md.num_slots_in_use > 0)
7891 PREV_SLOT.end_of_insn_group = 1;
7892
7893 if (md.debug_dv)
7894 {
7895 fprintf (stderr, " Insn group break%s",
7896 (insert_stop ? " (w/stop)" : ""));
7897 if (qp_regno != 0)
7898 fprintf (stderr, " effective for QP=%d", qp_regno);
7899 fprintf (stderr, "\n");
7900 }
7901
7902 i = 0;
7903 while (i < regdepslen)
7904 {
7905 const struct ia64_dependency *dep = regdeps[i].dependency;
7906
7907 if (qp_regno != 0
7908 && regdeps[i].qp_regno != qp_regno)
7909 {
7910 ++i;
7911 continue;
7912 }
7913
7914 if (save_current
7915 && CURR_SLOT.src_file == regdeps[i].file
7916 && CURR_SLOT.src_line == regdeps[i].line)
7917 {
7918 ++i;
7919 continue;
7920 }
7921
7922 /* clear dependencies which are automatically cleared by a stop, or
7923 those that have reached the appropriate state of insn serialization */
7924 if (dep->semantics == IA64_DVS_IMPLIED
7925 || dep->semantics == IA64_DVS_IMPLIEDF
7926 || regdeps[i].insn_srlz == STATE_SRLZ)
7927 {
7928 print_dependency ("Removing", i);
7929 regdeps[i] = regdeps[--regdepslen];
7930 }
7931 else
7932 {
7933 if (dep->semantics == IA64_DVS_DATA
7934 || dep->semantics == IA64_DVS_INSTR
7935 || dep->semantics == IA64_DVS_SPECIFIC)
7936 {
7937 if (regdeps[i].insn_srlz == STATE_NONE)
7938 regdeps[i].insn_srlz = STATE_STOP;
7939 if (regdeps[i].data_srlz == STATE_NONE)
7940 regdeps[i].data_srlz = STATE_STOP;
7941 }
7942 ++i;
7943 }
7944 }
7945}
7946
7947/* Add the given resource usage spec to the list of active dependencies */
7948static void
7949mark_resource (idesc, dep, spec, depind, path)
7950 struct ia64_opcode *idesc;
7951 const struct ia64_dependency *dep;
7952 struct rsrc *spec;
7953 int depind;
7954 int path;
7955{
7956 if (regdepslen == regdepstotlen)
7957 {
7958 regdepstotlen += 20;
7959 regdeps = (struct rsrc *)
7960 xrealloc ((void *)regdeps,
7961 regdepstotlen * sizeof(struct rsrc));
7962 }
7963
7964 regdeps[regdepslen] = *spec;
7965 regdeps[regdepslen].depind = depind;
7966 regdeps[regdepslen].path = path;
7967 regdeps[regdepslen].file = CURR_SLOT.src_file;
7968 regdeps[regdepslen].line = CURR_SLOT.src_line;
7969
7970 print_dependency ("Adding", regdepslen);
7971
7972 ++regdepslen;
7973}
7974
7975static void
7976print_dependency (action, depind)
7977 const char *action;
7978 int depind;
7979{
7980 if (md.debug_dv)
7981 {
7982 fprintf (stderr, " %s %s '%s'",
7983 action, dv_mode[(regdeps[depind].dependency)->mode],
7984 (regdeps[depind].dependency)->name);
7985 if (regdeps[depind].specific && regdeps[depind].index != 0)
7986 fprintf (stderr, " (%d)", regdeps[depind].index);
7987 if (regdeps[depind].mem_offset.hint)
7988 fprintf (stderr, " 0x%llx+0x%llx",
7989 regdeps[depind].mem_offset.base,
7990 regdeps[depind].mem_offset.offset);
7991 fprintf (stderr, "\n");
7992 }
7993}
7994
7995static void
7996instruction_serialization ()
7997{
7998 int i;
7999 if (md.debug_dv)
8000 fprintf (stderr, " Instruction serialization\n");
8001 for (i=0;i < regdepslen;i++)
8002 if (regdeps[i].insn_srlz == STATE_STOP)
8003 regdeps[i].insn_srlz = STATE_SRLZ;
8004}
8005
8006static void
8007data_serialization ()
8008{
8009 int i = 0;
8010 if (md.debug_dv)
8011 fprintf (stderr, " Data serialization\n");
8012 while (i < regdepslen)
8013 {
8014 if (regdeps[i].data_srlz == STATE_STOP
8015 /* Note: as of 991210, all "other" dependencies are cleared by a
8016 data serialization. This might change with new tables */
8017 || (regdeps[i].dependency)->semantics == IA64_DVS_OTHER)
8018 {
8019 print_dependency ("Removing", i);
8020 regdeps[i] = regdeps[--regdepslen];
8021 }
8022 else
8023 ++i;
8024 }
8025}
8026
8027/* Insert stops and serializations as needed to avoid DVs */
8028static void
8029remove_marked_resource (rs)
8030 struct rsrc *rs;
8031{
8032 switch (rs->dependency->semantics)
8033 {
8034 case IA64_DVS_SPECIFIC:
8035 if (md.debug_dv)
8036 fprintf (stderr, "Implementation-specific, assume worst case...\n");
8037 /* ...fall through... */
8038 case IA64_DVS_INSTR:
8039 if (md.debug_dv)
8040 fprintf (stderr, "Inserting instr serialization\n");
8041 if (rs->insn_srlz < STATE_STOP)
8042 insn_group_break (1, 0, 0);
8043 if (rs->insn_srlz < STATE_SRLZ)
8044 {
8045 int oldqp = CURR_SLOT.qp_regno;
8046 struct ia64_opcode *oldidesc = CURR_SLOT.idesc;
8047 /* Manually jam a srlz.i insn into the stream */
8048 CURR_SLOT.qp_regno = 0;
8049 CURR_SLOT.idesc = ia64_find_opcode ("srlz.i");
8050 instruction_serialization ();
8051 md.curr_slot = (md.curr_slot + 1) % NUM_SLOTS;
8052 if (++md.num_slots_in_use >= NUM_SLOTS)
8053 emit_one_bundle ();
8054 CURR_SLOT.qp_regno = oldqp;
8055 CURR_SLOT.idesc = oldidesc;
8056 }
8057 insn_group_break (1, 0, 0);
8058 break;
8059 case IA64_DVS_OTHER: /* as of rev2 (991220) of the DV tables, all
8060 "other" types of DV are eliminated
8061 by a data serialization */
8062 case IA64_DVS_DATA:
8063 if (md.debug_dv)
8064 fprintf (stderr, "Inserting data serialization\n");
8065 if (rs->data_srlz < STATE_STOP)
8066 insn_group_break (1, 0, 0);
8067 {
8068 int oldqp = CURR_SLOT.qp_regno;
8069 struct ia64_opcode *oldidesc = CURR_SLOT.idesc;
8070 /* Manually jam a srlz.d insn into the stream */
8071 CURR_SLOT.qp_regno = 0;
8072 CURR_SLOT.idesc = ia64_find_opcode ("srlz.d");
8073 data_serialization ();
8074 md.curr_slot = (md.curr_slot + 1) % NUM_SLOTS;
8075 if (++md.num_slots_in_use >= NUM_SLOTS)
8076 emit_one_bundle ();
8077 CURR_SLOT.qp_regno = oldqp;
8078 CURR_SLOT.idesc = oldidesc;
8079 }
8080 break;
8081 case IA64_DVS_IMPLIED:
8082 case IA64_DVS_IMPLIEDF:
8083 if (md.debug_dv)
8084 fprintf (stderr, "Inserting stop\n");
8085 insn_group_break (1, 0, 0);
8086 break;
8087 default:
8088 break;
8089 }
8090}
8091
8092/* Check the resources used by the given opcode against the current dependency
8093 list.
8094
8095 The check is run once for each execution path encountered. In this case,
8096 a unique execution path is the sequence of instructions following a code
8097 entry point, e.g. the following has three execution paths, one starting
8098 at L0, one at L1, and one at L2.
8099
8100 L0: nop
8101 L1: add
8102 L2: add
8103 br.ret
8104*/
8105static void
8106check_dependencies (idesc)
8107 struct ia64_opcode *idesc;
8108{
8109 const struct ia64_opcode_dependency *opdeps = idesc->dependencies;
8110 int path;
8111 int i;
8112
8113 /* Note that the number of marked resources may change within the
8114 loop if in auto mode. */
8115 i = 0;
8116 while (i < regdepslen)
8117 {
8118 struct rsrc *rs = &regdeps[i];
8119 const struct ia64_dependency *dep = rs->dependency;
8120 int chkind;
8121 int note;
8122 int start_over = 0;
8123
8124 if (dep->semantics == IA64_DVS_NONE
8125 || (chkind = depends_on (rs->depind, idesc)) == -1)
8126 {
8127 ++i; continue;
8128 }
8129
8130 note = NOTE(opdeps->chks[chkind]);
8131
8132 /* Check this resource against each execution path seen thus far */
8133 for (path=0;path <= md.path;path++)
8134 {
8135 int matchtype;
8136
8137 /* If the dependency wasn't on the path being checked, ignore it */
8138 if (rs->path < path)
8139 continue;
8140
8141 /* If the QP for this insn implies a QP which has branched, don't
8142 bother checking. Ed. NOTE: I don't think this check is terribly
8143 useful; what's the point of generating code which will only be
8144 reached if its QP is zero?
8145 This code was specifically inserted to handle the following code,
8146 based on notes from Intel's DV checking code, where p1 implies p2.
8147
8148 mov r4 = 2
8149 (p2) br.cond L
8150 (p1) mov r4 = 7
8151
8152 */
8153 if (CURR_SLOT.qp_regno != 0)
8154 {
8155 int skip = 0;
8156 int implies;
8157 for (implies=0;implies < qp_implieslen;implies++)
8158 {
8159 if (qp_implies[implies].path >= path
8160 && qp_implies[implies].p1 == CURR_SLOT.qp_regno
8161 && qp_implies[implies].p2_branched)
8162 {
8163 skip = 1;
8164 break;
8165 }
8166 }
8167 if (skip)
8168 continue;
8169 }
8170
8171 if ((matchtype = resources_match (rs, idesc, note,
8172 CURR_SLOT.qp_regno, path)) != 0)
8173 {
8174 char msg[1024];
8175 char pathmsg[256] = "";
8176 char indexmsg[256] = "";
8177 int certain = (matchtype == 1 && CURR_SLOT.qp_regno == 0);
8178
8179 if (path != 0)
8180 sprintf (pathmsg, " when entry is at label '%s'",
8181 md.entry_labels[path-1]);
8182 if (rs->specific && rs->index != 0)
8183 sprintf (indexmsg, ", specific resource number is %d",
8184 rs->index);
8185 sprintf (msg, "Use of '%s' %s %s dependency '%s' (%s)%s%s",
8186 idesc->name,
8187 (certain ? "violates" : "may violate"),
8188 dv_mode[dep->mode], dep->name,
8189 dv_sem[dep->semantics],
8190 pathmsg, indexmsg);
8191
8192 if (md.explicit_mode)
8193 {
8194 as_warn ("%s", msg);
8195 if (path < md.path)
8196 as_warn (_("Only the first path encountering the conflict "
8197 "is reported"));
8198 as_warn_where (rs->file, rs->line,
8199 _("This is the location of the "
8200 "conflicting usage"));
8201 /* Don't bother checking other paths, to avoid duplicating
8202 the same warning */
8203 break;
8204 }
8205 else
8206 {
8207 if (md.debug_dv)
8208 fprintf(stderr, "%s @ %s:%d\n", msg, rs->file, rs->line);
8209
8210 remove_marked_resource (rs);
8211
8212 /* since the set of dependencies has changed, start over */
8213 /* FIXME -- since we're removing dvs as we go, we
8214 probably don't really need to start over... */
8215 start_over = 1;
8216 break;
8217 }
8218 }
8219 }
8220 if (start_over)
8221 i = 0;
8222 else
8223 ++i;
8224 }
8225}
8226
8227/* register new dependencies based on the given opcode */
8228static void
8229mark_resources (idesc)
8230 struct ia64_opcode *idesc;
8231{
8232 int i;
8233 const struct ia64_opcode_dependency *opdeps = idesc->dependencies;
8234 int add_only_qp_reads = 0;
8235
8236 /* A conditional branch only uses its resources if it is taken; if it is
8237 taken, we stop following that path. The other branch types effectively
8238 *always* write their resources. If it's not taken, register only QP
8239 reads. */
8240 if (is_conditional_branch (idesc) || is_interruption_or_rfi (idesc))
8241 {
8242 add_only_qp_reads = 1;
8243 }
8244
8245 if (md.debug_dv)
8246 fprintf (stderr, "Registering '%s' resource usage\n", idesc->name);
8247
8248 for (i=0;i < opdeps->nregs;i++)
8249 {
8250 const struct ia64_dependency *dep;
8251 struct rsrc specs[MAX_SPECS];
8252 int note;
8253 int path;
8254 int count;
8255
8256 dep = ia64_find_dependency (opdeps->regs[i]);
8257 note = NOTE(opdeps->regs[i]);
8258
8259 if (add_only_qp_reads
8260 && !(dep->mode == IA64_DV_WAR
8261 && (dep->specifier == IA64_RS_PR
8262 || dep->specifier == IA64_RS_PR63)))
8263 continue;
8264
8265 count = specify_resource (dep, idesc, DV_REG, specs, note, md.path);
8266
8267#if 0
8268 if (md.debug_dv && !count)
8269 fprintf (stderr, " No %s %s usage found (path %d)\n",
8270 dv_mode[dep->mode], dep->name, md.path);
8271#endif
8272
8273 while (count-- > 0)
8274 {
8275 mark_resource (idesc, dep, &specs[count],
8276 DEP(opdeps->regs[i]), md.path);
8277 }
8278
8279 /* The execution path may affect register values, which may in turn
8280 affect which indirect-access resources are accessed. */
8281 switch (dep->specifier)
8282 {
8283 default:
8284 break;
8285 case IA64_RS_CPUID:
8286 case IA64_RS_DBR:
8287 case IA64_RS_IBR:
8288 case IA64_RS_MSR:
8289 case IA64_RS_PKR:
8290 case IA64_RS_PMC:
8291 case IA64_RS_PMD:
8292 case IA64_RS_RR:
8293 for (path=0;path < md.path;path++)
8294 {
8295 count = specify_resource (dep, idesc, DV_REG, specs, note, path);
8296 while (count-- > 0)
8297 mark_resource (idesc, dep, &specs[count],
8298 DEP(opdeps->regs[i]), path);
8299 }
8300 break;
8301 }
8302 }
8303}
8304
8305/* remove dependencies when they no longer apply */
8306static void
8307update_dependencies (idesc)
8308 struct ia64_opcode *idesc;
8309{
8310 int i;
8311
8312 if (strcmp (idesc->name, "srlz.i") == 0)
8313 {
8314 instruction_serialization ();
8315 }
8316 else if (strcmp (idesc->name, "srlz.d") == 0)
8317 {
8318 data_serialization ();
8319 }
8320 else if (is_interruption_or_rfi (idesc)
8321 || is_taken_branch (idesc))
8322 {
8323 /* although technically the taken branch doesn't clear dependencies
8324 which require a srlz.[id], we don't follow the branch; the next
8325 instruction is assumed to start with a clean slate */
8326 regdepslen = 0;
8327 clear_register_values ();
8328 clear_qp_mutex (~(valueT)0);
8329 clear_qp_implies (~(valueT)0, ~(valueT)0);
8330 md.path = 0;
8331 }
8332 else if (is_conditional_branch (idesc)
8333 && CURR_SLOT.qp_regno != 0)
8334 {
8335 int is_call = strstr (idesc->name, ".call") != NULL;
8336
8337 for (i=0;i < qp_implieslen;i++)
8338 {
8339 /* if the conditional branch's predicate is implied by the predicate
8340 in an existing dependency, remove that dependency */
8341 if (qp_implies[i].p2 == CURR_SLOT.qp_regno)
8342 {
8343 int depind = 0;
8344 /* note that this implied predicate takes a branch so that if
8345 a later insn generates a DV but its predicate implies this
8346 one, we can avoid the false DV warning */
8347 qp_implies[i].p2_branched = 1;
8348 while (depind < regdepslen)
8349 {
8350 if (regdeps[depind].qp_regno == qp_implies[i].p1)
8351 {
8352 print_dependency ("Removing", depind);
8353 regdeps[depind] = regdeps[--regdepslen];
8354 }
8355 else
8356 ++depind;
8357 }
8358 }
8359 }
8360 /* Any marked resources which have this same predicate should be
8361 cleared, provided that the QP hasn't been modified between the
8362 marking instruction and the branch.
8363 */
8364 if (is_call)
8365 {
8366 insn_group_break (0, CURR_SLOT.qp_regno, 1);
8367 }
8368 else
8369 {
8370 i = 0;
8371 while (i < regdepslen)
8372 {
8373 if (regdeps[i].qp_regno == CURR_SLOT.qp_regno
8374 && regdeps[i].link_to_qp_branch
8375 && (regdeps[i].file != CURR_SLOT.src_file
8376 || regdeps[i].line != CURR_SLOT.src_line))
8377 {
8378 /* Treat like a taken branch */
8379 print_dependency ("Removing", i);
8380 regdeps[i] = regdeps[--regdepslen];
8381 }
8382 else
8383 ++i;
8384 }
8385 }
8386 }
8387}
8388
8389/* Examine the current instruction for dependency violations. */
8390static int
8391check_dv (idesc)
8392 struct ia64_opcode *idesc;
8393{
8394 if (md.debug_dv)
8395 {
8396 fprintf (stderr, "Checking %s for violations (line %d, %d/%d)\n",
8397 idesc->name, CURR_SLOT.src_line,
8398 idesc->dependencies->nchks,
8399 idesc->dependencies->nregs);
8400 }
8401
8402 /* Look through the list of currently marked resources; if the current
8403 instruction has the dependency in its chks list which uses that resource,
8404 check against the specific resources used.
8405 */
8406 check_dependencies (idesc);
8407
8408 /*
8409 Look up the instruction's regdeps (RAW writes, WAW writes, and WAR reads),
8410 then add them to the list of marked resources.
8411 */
8412 mark_resources (idesc);
8413
8414 /* There are several types of dependency semantics, and each has its own
8415 requirements for being cleared
8416
8417 Instruction serialization (insns separated by interruption, rfi, or
8418 writer + srlz.i + reader, all in separate groups) clears DVS_INSTR.
8419
8420 Data serialization (instruction serialization, or writer + srlz.d +
8421 reader, where writer and srlz.d are in separate groups) clears
8422 DVS_DATA. (This also clears DVS_OTHER, but that is not guaranteed to
8423 always be the case).
8424
8425 Instruction group break (groups separated by stop, taken branch,
8426 interruption or rfi) clears DVS_IMPLIED and DVS_IMPLIEDF.
8427 */
8428 update_dependencies (idesc);
8429
8430 /* Sometimes, knowing a register value allows us to avoid giving a false DV
8431 warning. Keep track of as many as possible that are useful. */
8432 note_register_values (idesc);
8433
8434 /* We don't need or want this anymore. */
8435 md.mem_offset.hint = 0;
8436
8437 return 0;
8438}
8439
8440/* Translate one line of assembly. Pseudo ops and labels do not show
8441 here. */
8442void
8443md_assemble (str)
8444 char *str;
8445{
8446 char *saved_input_line_pointer, *mnemonic;
8447 const struct pseudo_opcode *pdesc;
8448 struct ia64_opcode *idesc;
8449 unsigned char qp_regno;
8450 unsigned int flags;
8451 int ch;
8452
8453 saved_input_line_pointer = input_line_pointer;
8454 input_line_pointer = str;
8455
8456 /* extract the opcode (mnemonic): */
8457
8458 mnemonic = input_line_pointer;
8459 ch = get_symbol_end ();
8460 pdesc = (struct pseudo_opcode *) hash_find (md.pseudo_hash, mnemonic);
8461 if (pdesc)
8462 {
8463 *input_line_pointer = ch;
8464 (*pdesc->handler) (pdesc->arg);
8465 goto done;
8466 }
8467
8468 /* find the instruction descriptor matching the arguments: */
8469
8470 idesc = ia64_find_opcode (mnemonic);
8471 *input_line_pointer = ch;
8472 if (!idesc)
8473 {
8474 as_bad ("Unknown opcode `%s'", mnemonic);
8475 goto done;
8476 }
8477
8478 idesc = parse_operands (idesc);
8479 if (!idesc)
8480 goto done;
8481
8482 /* Handle the dynamic ops we can handle now: */
8483 if (idesc->type == IA64_TYPE_DYN)
8484 {
8485 if (strcmp (idesc->name, "add") == 0)
8486 {
8487 if (CURR_SLOT.opnd[2].X_op == O_register
8488 && CURR_SLOT.opnd[2].X_add_number < 4)
8489 mnemonic = "addl";
8490 else
8491 mnemonic = "adds";
8492 idesc = ia64_find_opcode (mnemonic);
8493#if 0
8494 know (!idesc->next);
8495#endif
8496 }
8497 else if (strcmp (idesc->name, "mov") == 0)
8498 {
8499 enum ia64_opnd opnd1, opnd2;
8500 int rop;
8501
8502 opnd1 = idesc->operands[0];
8503 opnd2 = idesc->operands[1];
8504 if (opnd1 == IA64_OPND_AR3)
8505 rop = 0;
8506 else if (opnd2 == IA64_OPND_AR3)
8507 rop = 1;
8508 else
8509 abort ();
8510 if (CURR_SLOT.opnd[rop].X_op == O_register
8511 && ar_is_in_integer_unit (CURR_SLOT.opnd[rop].X_add_number))
8512 mnemonic = "mov.i";
8513 else
8514 mnemonic = "mov.m";
8515 idesc = ia64_find_opcode (mnemonic);
8516 while (idesc != NULL
8517 && (idesc->operands[0] != opnd1
8518 || idesc->operands[1] != opnd2))
8519 idesc = get_next_opcode (idesc);
8520 }
8521 }
8522
8523 qp_regno = 0;
8524 if (md.qp.X_op == O_register)
8525 qp_regno = md.qp.X_add_number - REG_P;
8526
8527 flags = idesc->flags;
8528
8529 if ((flags & IA64_OPCODE_FIRST) != 0)
8530 insn_group_break (1, 0, 0);
8531
8532 if ((flags & IA64_OPCODE_NO_PRED) != 0 && qp_regno != 0)
8533 {
8534 as_bad ("`%s' cannot be predicated", idesc->name);
8535 goto done;
8536 }
8537
8538 /* build the instruction: */
8539 CURR_SLOT.qp_regno = qp_regno;
8540 CURR_SLOT.idesc = idesc;
8541 as_where (&CURR_SLOT.src_file, &CURR_SLOT.src_line);
8542 if (debug_type == DEBUG_DWARF2)
8543 dwarf2_where (&CURR_SLOT.debug_line);
8544
8545 /* Add unwind entry, if there is one. */
e0c9811a 8546 if (unwind.current_entry)
800eeca4 8547 {
e0c9811a
JW
8548 CURR_SLOT.unwind_record = unwind.current_entry;
8549 unwind.current_entry = NULL;
800eeca4
JW
8550 }
8551
8552 /* check for dependency violations */
8553 if (md.detect_dv)
8554 check_dv(idesc);
8555
8556 md.curr_slot = (md.curr_slot + 1) % NUM_SLOTS;
8557 if (++md.num_slots_in_use >= NUM_SLOTS)
8558 emit_one_bundle ();
8559
8560 if ((flags & IA64_OPCODE_LAST) != 0)
8561 insn_group_break (1, 0, 0);
8562
8563 md.last_text_seg = now_seg;
8564
8565 done:
8566 input_line_pointer = saved_input_line_pointer;
8567}
8568
8569/* Called when symbol NAME cannot be found in the symbol table.
8570 Should be used for dynamic valued symbols only. */
8571symbolS*
8572md_undefined_symbol (name)
8573 char *name;
8574{
8575 return 0;
8576}
8577
8578/* Called for any expression that can not be recognized. When the
8579 function is called, `input_line_pointer' will point to the start of
8580 the expression. */
8581void
8582md_operand (e)
8583 expressionS *e;
8584{
8585 enum pseudo_type pseudo_type;
e0c9811a 8586 const char *name;
800eeca4
JW
8587 size_t len;
8588 int ch, i;
8589
8590 switch (*input_line_pointer)
8591 {
8592 case '@':
8593 /* find what relocation pseudo-function we're dealing with: */
8594 pseudo_type = 0;
8595 ch = *++input_line_pointer;
8596 for (i = 0; i < NELEMS (pseudo_func); ++i)
8597 if (pseudo_func[i].name && pseudo_func[i].name[0] == ch)
8598 {
8599 len = strlen (pseudo_func[i].name);
8600 if (strncmp (pseudo_func[i].name + 1,
8601 input_line_pointer + 1, len - 1) == 0
8602 && !is_part_of_name (input_line_pointer[len]))
8603 {
8604 input_line_pointer += len;
8605 pseudo_type = pseudo_func[i].type;
8606 break;
8607 }
8608 }
8609 switch (pseudo_type)
8610 {
8611 case PSEUDO_FUNC_RELOC:
8612 SKIP_WHITESPACE ();
8613 if (*input_line_pointer != '(')
8614 {
8615 as_bad ("Expected '('");
8616 goto err;
8617 }
8618 ++input_line_pointer; /* skip '(' */
8619 expression (e);
8620 if (*input_line_pointer++ != ')')
8621 {
8622 as_bad ("Missing ')'");
8623 goto err;
8624 }
8625 if (e->X_op != O_symbol)
8626 {
8627 if (e->X_op != O_pseudo_fixup)
8628 {
8629 as_bad ("Not a symbolic expression");
8630 goto err;
8631 }
8632 if (S_GET_VALUE (e->X_op_symbol) == FUNC_FPTR_RELATIVE
8633 && i == FUNC_LT_RELATIVE)
8634 i = FUNC_LT_FPTR_RELATIVE;
8635 else
8636 {
8637 as_bad ("Illegal combination of relocation functions");
8638 goto err;
8639 }
8640 }
8641 /* make sure gas doesn't get rid of local symbols that are used
8642 in relocs: */
8643 e->X_op = O_pseudo_fixup;
8644 e->X_op_symbol = pseudo_func[i].u.sym;
8645 break;
8646
8647 case PSEUDO_FUNC_CONST:
8648 e->X_op = O_constant;
8649 e->X_add_number = pseudo_func[i].u.ival;
8650 break;
8651
e0c9811a
JW
8652 case PSEUDO_FUNC_REG:
8653 e->X_op = O_register;
8654 e->X_add_number = pseudo_func[i].u.ival;
8655 break;
8656
800eeca4 8657 default:
e0c9811a
JW
8658 name = input_line_pointer - 1;
8659 get_symbol_end ();
8660 as_bad ("Unknown pseudo function `%s'", name);
800eeca4
JW
8661 goto err;
8662 }
8663 break;
8664
8665 case '[':
8666 ++input_line_pointer;
8667 expression (e);
8668 if (*input_line_pointer != ']')
8669 {
8670 as_bad ("Closing bracket misssing");
8671 goto err;
8672 }
8673 else
8674 {
8675 if (e->X_op != O_register)
8676 as_bad ("Register expected as index");
8677
8678 ++input_line_pointer;
8679 e->X_op = O_index;
8680 }
8681 break;
8682
8683 default:
8684 break;
8685 }
8686 return;
8687
8688 err:
8689 ignore_rest_of_line ();
8690}
8691
8692/* Return 1 if it's OK to adjust a reloc by replacing the symbol with
8693 a section symbol plus some offset. For relocs involving @fptr(),
8694 directives we don't want such adjustments since we need to have the
8695 original symbol's name in the reloc. */
8696int
8697ia64_fix_adjustable (fix)
8698 fixS *fix;
8699{
8700 /* Prevent all adjustments to global symbols */
8701 if (S_IS_EXTERN (fix->fx_addsy) || S_IS_WEAK (fix->fx_addsy))
8702 return 0;
8703
8704 switch (fix->fx_r_type)
8705 {
8706 case BFD_RELOC_IA64_FPTR64I:
8707 case BFD_RELOC_IA64_FPTR32MSB:
8708 case BFD_RELOC_IA64_FPTR32LSB:
8709 case BFD_RELOC_IA64_FPTR64MSB:
8710 case BFD_RELOC_IA64_FPTR64LSB:
8711 case BFD_RELOC_IA64_LTOFF_FPTR22:
8712 case BFD_RELOC_IA64_LTOFF_FPTR64I:
8713 return 0;
8714 default:
8715 break;
8716 }
8717
8718 return 1;
8719}
8720
8721int
8722ia64_force_relocation (fix)
8723 fixS *fix;
8724{
8725 switch (fix->fx_r_type)
8726 {
8727 case BFD_RELOC_IA64_FPTR64I:
8728 case BFD_RELOC_IA64_FPTR32MSB:
8729 case BFD_RELOC_IA64_FPTR32LSB:
8730 case BFD_RELOC_IA64_FPTR64MSB:
8731 case BFD_RELOC_IA64_FPTR64LSB:
8732
8733 case BFD_RELOC_IA64_LTOFF22:
8734 case BFD_RELOC_IA64_LTOFF64I:
8735 case BFD_RELOC_IA64_LTOFF_FPTR22:
8736 case BFD_RELOC_IA64_LTOFF_FPTR64I:
8737 case BFD_RELOC_IA64_PLTOFF22:
8738 case BFD_RELOC_IA64_PLTOFF64I:
8739 case BFD_RELOC_IA64_PLTOFF64MSB:
8740 case BFD_RELOC_IA64_PLTOFF64LSB:
8741 return 1;
8742
8743 default:
8744 return 0;
8745 }
8746 return 0;
8747}
8748
8749/* Decide from what point a pc-relative relocation is relative to,
8750 relative to the pc-relative fixup. Er, relatively speaking. */
8751long
8752ia64_pcrel_from_section (fix, sec)
8753 fixS *fix;
8754 segT sec;
8755{
8756 unsigned long off = fix->fx_frag->fr_address + fix->fx_where;
8757
8758 if (bfd_get_section_flags (stdoutput, sec) & SEC_CODE)
8759 off &= ~0xfUL;
8760
8761 return off;
8762}
8763
8764/* This is called whenever some data item (not an instruction) needs a
8765 fixup. We pick the right reloc code depending on the byteorder
8766 currently in effect. */
8767void
8768ia64_cons_fix_new (f, where, nbytes, exp)
8769 fragS *f;
8770 int where;
8771 int nbytes;
8772 expressionS *exp;
8773{
8774 bfd_reloc_code_real_type code;
8775 fixS *fix;
8776
8777 switch (nbytes)
8778 {
8779 /* There are no reloc for 8 and 16 bit quantities, but we allow
8780 them here since they will work fine as long as the expression
8781 is fully defined at the end of the pass over the source file. */
8782 case 1: code = BFD_RELOC_8; break;
8783 case 2: code = BFD_RELOC_16; break;
8784 case 4:
8785 if (target_big_endian)
8786 code = BFD_RELOC_IA64_DIR32MSB;
8787 else
8788 code = BFD_RELOC_IA64_DIR32LSB;
8789 break;
8790
8791 case 8:
8792 if (target_big_endian)
8793 code = BFD_RELOC_IA64_DIR64MSB;
8794 else
8795 code = BFD_RELOC_IA64_DIR64LSB;
8796 break;
8797
8798 default:
8799 as_bad ("Unsupported fixup size %d", nbytes);
8800 ignore_rest_of_line ();
8801 return;
8802 }
8803 if (exp->X_op == O_pseudo_fixup)
8804 {
8805 /* ??? */
8806 exp->X_op = O_symbol;
8807 code = ia64_gen_real_reloc_type (exp->X_op_symbol, code);
8808 }
8809 fix = fix_new_exp (f, where, nbytes, exp, 0, code);
8810 /* We need to store the byte order in effect in case we're going
8811 to fix an 8 or 16 bit relocation (for which there no real
8812 relocs available). See md_apply_fix(). */
8813 fix->tc_fix_data.bigendian = target_big_endian;
8814}
8815
8816/* Return the actual relocation we wish to associate with the pseudo
8817 reloc described by SYM and R_TYPE. SYM should be one of the
8818 symbols in the pseudo_func array, or NULL. */
8819
8820static bfd_reloc_code_real_type
8821ia64_gen_real_reloc_type (sym, r_type)
8822 struct symbol *sym;
8823 bfd_reloc_code_real_type r_type;
8824{
8825 bfd_reloc_code_real_type new = 0;
8826
8827 if (sym == NULL)
8828 {
8829 return r_type;
8830 }
8831
8832 switch (S_GET_VALUE (sym))
8833 {
8834 case FUNC_FPTR_RELATIVE:
8835 switch (r_type)
8836 {
8837 case BFD_RELOC_IA64_IMM64: new = BFD_RELOC_IA64_FPTR64I; break;
8838 case BFD_RELOC_IA64_DIR32MSB: new = BFD_RELOC_IA64_FPTR32MSB; break;
8839 case BFD_RELOC_IA64_DIR32LSB: new = BFD_RELOC_IA64_FPTR32LSB; break;
8840 case BFD_RELOC_IA64_DIR64MSB: new = BFD_RELOC_IA64_FPTR64MSB; break;
8841 case BFD_RELOC_IA64_DIR64LSB: new = BFD_RELOC_IA64_FPTR64LSB; break;
8842 default: break;
8843 }
8844 break;
8845
8846 case FUNC_GP_RELATIVE:
8847 switch (r_type)
8848 {
8849 case BFD_RELOC_IA64_IMM22: new = BFD_RELOC_IA64_GPREL22; break;
8850 case BFD_RELOC_IA64_IMM64: new = BFD_RELOC_IA64_GPREL64I; break;
8851 case BFD_RELOC_IA64_DIR32MSB: new = BFD_RELOC_IA64_GPREL32MSB; break;
8852 case BFD_RELOC_IA64_DIR32LSB: new = BFD_RELOC_IA64_GPREL32LSB; break;
8853 case BFD_RELOC_IA64_DIR64MSB: new = BFD_RELOC_IA64_GPREL64MSB; break;
8854 case BFD_RELOC_IA64_DIR64LSB: new = BFD_RELOC_IA64_GPREL64LSB; break;
8855 default: break;
8856 }
8857 break;
8858
8859 case FUNC_LT_RELATIVE:
8860 switch (r_type)
8861 {
8862 case BFD_RELOC_IA64_IMM22: new = BFD_RELOC_IA64_LTOFF22; break;
8863 case BFD_RELOC_IA64_IMM64: new = BFD_RELOC_IA64_LTOFF64I; break;
8864 default: break;
8865 }
8866 break;
8867
c67e42c9
RH
8868 case FUNC_PC_RELATIVE:
8869 switch (r_type)
8870 {
8871 case BFD_RELOC_IA64_IMM22: new = BFD_RELOC_IA64_PCREL22; break;
8872 case BFD_RELOC_IA64_IMM64: new = BFD_RELOC_IA64_PCREL64I; break;
8873 case BFD_RELOC_IA64_DIR32MSB: new = BFD_RELOC_IA64_PCREL32MSB; break;
8874 case BFD_RELOC_IA64_DIR32LSB: new = BFD_RELOC_IA64_PCREL32LSB; break;
8875 case BFD_RELOC_IA64_DIR64MSB: new = BFD_RELOC_IA64_PCREL64MSB; break;
8876 case BFD_RELOC_IA64_DIR64LSB: new = BFD_RELOC_IA64_PCREL64LSB; break;
8877 default: break;
8878 }
8879 break;
8880
800eeca4
JW
8881 case FUNC_PLT_RELATIVE:
8882 switch (r_type)
8883 {
8884 case BFD_RELOC_IA64_IMM22: new = BFD_RELOC_IA64_PLTOFF22; break;
8885 case BFD_RELOC_IA64_IMM64: new = BFD_RELOC_IA64_PLTOFF64I; break;
8886 case BFD_RELOC_IA64_DIR64MSB: new = BFD_RELOC_IA64_PLTOFF64MSB;break;
8887 case BFD_RELOC_IA64_DIR64LSB: new = BFD_RELOC_IA64_PLTOFF64LSB;break;
8888 default: break;
8889 }
8890 break;
8891
8892 case FUNC_SEC_RELATIVE:
8893 switch (r_type)
8894 {
8895 case BFD_RELOC_IA64_DIR32MSB: new = BFD_RELOC_IA64_SECREL32MSB;break;
8896 case BFD_RELOC_IA64_DIR32LSB: new = BFD_RELOC_IA64_SECREL32LSB;break;
8897 case BFD_RELOC_IA64_DIR64MSB: new = BFD_RELOC_IA64_SECREL64MSB;break;
8898 case BFD_RELOC_IA64_DIR64LSB: new = BFD_RELOC_IA64_SECREL64LSB;break;
8899 default: break;
8900 }
8901 break;
8902
8903 case FUNC_SEG_RELATIVE:
8904 switch (r_type)
8905 {
8906 case BFD_RELOC_IA64_DIR32MSB: new = BFD_RELOC_IA64_SEGREL32MSB;break;
8907 case BFD_RELOC_IA64_DIR32LSB: new = BFD_RELOC_IA64_SEGREL32LSB;break;
8908 case BFD_RELOC_IA64_DIR64MSB: new = BFD_RELOC_IA64_SEGREL64MSB;break;
8909 case BFD_RELOC_IA64_DIR64LSB: new = BFD_RELOC_IA64_SEGREL64LSB;break;
8910 default: break;
8911 }
8912 break;
8913
8914 case FUNC_LTV_RELATIVE:
8915 switch (r_type)
8916 {
8917 case BFD_RELOC_IA64_DIR32MSB: new = BFD_RELOC_IA64_LTV32MSB; break;
8918 case BFD_RELOC_IA64_DIR32LSB: new = BFD_RELOC_IA64_LTV32LSB; break;
8919 case BFD_RELOC_IA64_DIR64MSB: new = BFD_RELOC_IA64_LTV64MSB; break;
8920 case BFD_RELOC_IA64_DIR64LSB: new = BFD_RELOC_IA64_LTV64LSB; break;
8921 default: break;
8922 }
8923 break;
8924
8925 case FUNC_LT_FPTR_RELATIVE:
8926 switch (r_type)
8927 {
8928 case BFD_RELOC_IA64_IMM22:
8929 new = BFD_RELOC_IA64_LTOFF_FPTR22; break;
8930 case BFD_RELOC_IA64_IMM64:
8931 new = BFD_RELOC_IA64_LTOFF_FPTR64I; break;
8932 default:
8933 break;
8934 }
8935 break;
8936 default:
8937 abort ();
8938 }
8939 /* Hmmmm. Should this ever occur? */
8940 if (new)
8941 return new;
8942 else
8943 return r_type;
8944}
8945
8946/* Here is where generate the appropriate reloc for pseudo relocation
8947 functions. */
8948void
8949ia64_validate_fix (fix)
8950 fixS *fix;
8951{
8952 switch (fix->fx_r_type)
8953 {
8954 case BFD_RELOC_IA64_FPTR64I:
8955 case BFD_RELOC_IA64_FPTR32MSB:
8956 case BFD_RELOC_IA64_FPTR64LSB:
8957 case BFD_RELOC_IA64_LTOFF_FPTR22:
8958 case BFD_RELOC_IA64_LTOFF_FPTR64I:
8959 if (fix->fx_offset != 0)
8960 as_bad_where (fix->fx_file, fix->fx_line,
8961 "No addend allowed in @fptr() relocation");
8962 break;
8963 default:
8964 break;
8965 }
8966
8967 return;
8968}
8969
8970static void
8971fix_insn (fix, odesc, value)
8972 fixS *fix;
8973 const struct ia64_operand *odesc;
8974 valueT value;
8975{
8976 bfd_vma insn[3], t0, t1, control_bits;
8977 const char *err;
8978 char *fixpos;
8979 long slot;
8980
8981 slot = fix->fx_where & 0x3;
8982 fixpos = fix->fx_frag->fr_literal + (fix->fx_where - slot);
8983
c67e42c9 8984 /* Bundles are always in little-endian byte order */
800eeca4
JW
8985 t0 = bfd_getl64 (fixpos);
8986 t1 = bfd_getl64 (fixpos + 8);
8987 control_bits = t0 & 0x1f;
8988 insn[0] = (t0 >> 5) & 0x1ffffffffffLL;
8989 insn[1] = ((t0 >> 46) & 0x3ffff) | ((t1 & 0x7fffff) << 18);
8990 insn[2] = (t1 >> 23) & 0x1ffffffffffLL;
8991
c67e42c9
RH
8992 err = NULL;
8993 if (odesc - elf64_ia64_operands == IA64_OPND_IMMU64)
800eeca4 8994 {
c67e42c9
RH
8995 insn[1] = (value >> 22) & 0x1ffffffffffLL;
8996 insn[2] |= (((value & 0x7f) << 13)
8997 | (((value >> 7) & 0x1ff) << 27)
8998 | (((value >> 16) & 0x1f) << 22)
8999 | (((value >> 21) & 0x1) << 21)
9000 | (((value >> 63) & 0x1) << 36));
800eeca4 9001 }
c67e42c9
RH
9002 else if (odesc - elf64_ia64_operands == IA64_OPND_IMMU62)
9003 {
9004 if (value & ~0x3fffffffffffffffULL)
9005 err = "integer operand out of range";
9006 insn[1] = (value >> 21) & 0x1ffffffffffLL;
9007 insn[2] |= (((value & 0xfffff) << 6) | (((value >> 20) & 0x1) << 36));
9008 }
9009 else if (odesc - elf64_ia64_operands == IA64_OPND_TGT64)
9010 {
9011 value >>= 4;
9012 insn[1] = ((value >> 20) & 0x7fffffffffLL) << 2;
9013 insn[2] |= ((((value >> 59) & 0x1) << 36)
9014 | (((value >> 0) & 0xfffff) << 13));
9015 }
9016 else
9017 err = (*odesc->insert) (odesc, value, insn + slot);
9018
9019 if (err)
9020 as_bad_where (fix->fx_file, fix->fx_line, err);
800eeca4
JW
9021
9022 t0 = control_bits | (insn[0] << 5) | (insn[1] << 46);
9023 t1 = ((insn[1] >> 18) & 0x7fffff) | (insn[2] << 23);
9024 md_number_to_chars (fixpos + 0, t0, 8);
9025 md_number_to_chars (fixpos + 8, t1, 8);
800eeca4
JW
9026}
9027
9028/* Attempt to simplify or even eliminate a fixup. The return value is
9029 ignored; perhaps it was once meaningful, but now it is historical.
9030 To indicate that a fixup has been eliminated, set FIXP->FX_DONE.
9031
9032 If fixp->fx_addsy is non-NULL, we'll have to generate a reloc entry
9033 (if possible). */
9034int
9035md_apply_fix3 (fix, valuep, seg)
9036 fixS *fix;
9037 valueT *valuep;
9038 segT seg;
9039{
9040 char *fixpos;
9041 valueT value = *valuep;
9042 int adjust = 0;
9043
9044 fixpos = fix->fx_frag->fr_literal + fix->fx_where;
9045
9046 if (fix->fx_pcrel)
9047 {
9048 switch (fix->fx_r_type)
9049 {
9050 case BFD_RELOC_IA64_DIR32MSB:
9051 fix->fx_r_type = BFD_RELOC_IA64_PCREL32MSB;
9052 adjust = 1;
9053 break;
9054
9055 case BFD_RELOC_IA64_DIR32LSB:
9056 fix->fx_r_type = BFD_RELOC_IA64_PCREL32LSB;
9057 adjust = 1;
9058 break;
9059
9060 case BFD_RELOC_IA64_DIR64MSB:
9061 fix->fx_r_type = BFD_RELOC_IA64_PCREL64MSB;
9062 adjust = 1;
9063 break;
9064
9065 case BFD_RELOC_IA64_DIR64LSB:
9066 fix->fx_r_type = BFD_RELOC_IA64_PCREL64LSB;
9067 adjust = 1;
9068 break;
9069
9070 default:
9071 break;
9072 }
9073 }
9074 if (fix->fx_addsy)
9075 {
9076 switch (fix->fx_r_type)
9077 {
9078 case 0:
9079 as_bad_where (fix->fx_file, fix->fx_line,
9080 "%s must have a constant value",
9081 elf64_ia64_operands[fix->tc_fix_data.opnd].desc);
9082 break;
9083
9084 default:
9085 break;
9086 }
9087
9088 /* ??? This is a hack copied from tc-i386.c to make PCREL relocs
9089 work. There should be a better way to handle this. */
9090 if (adjust)
9091 fix->fx_offset += fix->fx_where + fix->fx_frag->fr_address;
9092 }
9093 else if (fix->tc_fix_data.opnd == IA64_OPND_NIL)
9094 {
9095 if (fix->tc_fix_data.bigendian)
9096 number_to_chars_bigendian (fixpos, value, fix->fx_size);
9097 else
9098 number_to_chars_littleendian (fixpos, value, fix->fx_size);
9099 fix->fx_done = 1;
9100 return 1;
9101 }
9102 else
9103 {
9104 fix_insn (fix, elf64_ia64_operands + fix->tc_fix_data.opnd, value);
9105 fix->fx_done = 1;
9106 return 1;
9107 }
9108 return 1;
9109}
9110
9111/* Generate the BFD reloc to be stuck in the object file from the
9112 fixup used internally in the assembler. */
9113arelent*
9114tc_gen_reloc (sec, fixp)
9115 asection *sec;
9116 fixS *fixp;
9117{
9118 arelent *reloc;
9119
9120 reloc = xmalloc (sizeof (*reloc));
9121 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
9122 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
9123 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
9124 reloc->addend = fixp->fx_offset;
9125 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
9126
9127 if (!reloc->howto)
9128 {
9129 as_bad_where (fixp->fx_file, fixp->fx_line,
9130 "Cannot represent %s relocation in object file",
9131 bfd_get_reloc_code_name (fixp->fx_r_type));
9132 }
9133 return reloc;
9134}
9135
9136/* Turn a string in input_line_pointer into a floating point constant
9137 of type type, and store the appropriate bytes in *lit. The number
9138 of LITTLENUMS emitted is stored in *size. An error message is
9139 returned, or NULL on OK. */
9140
9141#define MAX_LITTLENUMS 5
9142
9143char*
9144md_atof (type, lit, size)
9145 int type;
9146 char *lit;
9147 int *size;
9148{
9149 LITTLENUM_TYPE words[MAX_LITTLENUMS];
9150 LITTLENUM_TYPE *word;
9151 char *t;
9152 int prec;
9153
9154 switch (type)
9155 {
9156 /* IEEE floats */
9157 case 'f':
9158 case 'F':
9159 case 's':
9160 case 'S':
9161 prec = 2;
9162 break;
9163
9164 case 'd':
9165 case 'D':
9166 case 'r':
9167 case 'R':
9168 prec = 4;
9169 break;
9170
9171 case 'x':
9172 case 'X':
9173 case 'p':
9174 case 'P':
9175 prec = 5;
9176 break;
9177
9178 default:
9179 *size = 0;
9180 return "Bad call to MD_ATOF()";
9181 }
9182 t = atof_ieee (input_line_pointer, type, words);
9183 if (t)
9184 input_line_pointer = t;
9185 *size = prec * sizeof (LITTLENUM_TYPE);
9186
9187 for (word = words + prec - 1; prec--;)
9188 {
9189 md_number_to_chars (lit, (long) (*word--), sizeof (LITTLENUM_TYPE));
9190 lit += sizeof (LITTLENUM_TYPE);
9191 }
9192 return 0;
9193}
9194
9195/* Round up a section's size to the appropriate boundary. */
9196valueT
9197md_section_align (seg, size)
9198 segT seg;
9199 valueT size;
9200{
9201 int align = bfd_get_section_alignment (stdoutput, seg);
9202 valueT mask = ((valueT)1 << align) - 1;
9203
9204 return (size + mask) & ~mask;
9205}
9206
9207/* Handle ia64 specific semantics of the align directive. */
9208
9209int
9210ia64_md_do_align (n, fill, len, max)
9211 int n;
9212 const char *fill;
9213 int len;
9214 int max;
9215{
9216 /* Fill any pending bundle with nops. */
9217 if (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE)
9218 ia64_flush_insns ();
9219
9220 /* When we align code in a text section, emit a bundle of 3 nops instead of
9221 zero bytes. We can only do this if a multiple of 16 bytes was requested.
9222 N is log base 2 of the requested alignment. */
9223 if (fill == NULL
9224 && bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE
9225 && n > 4)
9226 {
9227 /* Use mfi bundle of nops with no stop bits. */
9228 static const unsigned char be_nop[]
9229 = { 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
9230 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c};
9231 static const unsigned char le_nop[]
9232 = { 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
9233 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00};
9234
9235 /* Make sure we are on a 16-byte boundary, in case someone has been
9236 putting data into a text section. */
9237 frag_align (4, 0, 0);
9238
9239 if (target_big_endian)
9240 frag_align_pattern (n, be_nop, 16, max);
9241 else
9242 frag_align_pattern (n, le_nop, 16, max);
9243 return 1;
9244 }
9245
9246 return 0;
9247}
This page took 0.413622 seconds and 4 git commands to generate.