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