1 /* tc-ia64.c -- Assembler for the HP/Intel IA-64 architecture.
2 Copyright (C) 1998, 1999, 2000 Free Software Foundation.
3 Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
5 This file is part of GAS, the GNU Assembler.
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)
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.
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. */
35 - labels are wrong if automatic alignment is introduced
36 (e.g., checkout the second real10 definition in test-data.s)
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
46 #include "dwarf2dbg.h"
49 #include "opcode/ia64.h"
53 #define NELEMS(a) ((int) (sizeof (a)/sizeof ((a)[0])))
54 #define MIN(a,b) ((a) < (b) ? (a) : (b))
57 #define PREV_SLOT md.slot[(md.curr_slot + NUM_SLOTS - 1) % NUM_SLOTS]
58 #define CURR_SLOT md.slot[md.curr_slot]
60 #define O_pseudo_fixup (O_max + 1)
64 SPECIAL_SECTION_BSS
= 0,
66 SPECIAL_SECTION_SDATA
,
67 SPECIAL_SECTION_RODATA
,
68 SPECIAL_SECTION_COMMENT
,
69 SPECIAL_SECTION_UNWIND
,
70 SPECIAL_SECTION_UNWIND_INFO
83 FUNC_LT_FPTR_RELATIVE
,
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),
101 /* The following are pseudo-registers for use by gas only. */
113 /* The following pseudo-registers are used for unwind directives only: */
121 DYNREG_GR
= 0, /* dynamic general purpose register */
122 DYNREG_FR
, /* dynamic floating point register */
123 DYNREG_PR
, /* dynamic predicate register */
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
133 struct label_fix
*next
;
137 extern int target_big_endian
;
139 /* Characters which always start a comment. */
140 const char comment_chars
[] = "";
142 /* Characters which start a comment at the beginning of a line. */
143 const char line_comment_chars
[] = "#";
145 /* Characters which may be used to separate multiple commands on a
147 const char line_separator_chars
[] = ";";
149 /* Characters which are used to indicate an exponent in a floating
151 const char EXP_CHARS
[] = "eE";
153 /* Characters which mean that a number is a floating point constant,
155 const char FLT_CHARS
[] = "rRsSfFdDxXpP";
157 /* ia64-specific option processing: */
159 const char *md_shortopts
= "m:N:x::";
161 struct option md_longopts
[] =
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
}
169 size_t md_longopts_size
= sizeof (md_longopts
);
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 */
179 symbolS
*regsym
[REG_NUM
];
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. */
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? */
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. */
199 int num_slots_in_use
;
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. */
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 */
219 fixup
[2]; /* at most two fixups per insn */
220 struct ia64_opcode
*idesc
;
221 struct label_fix
*label_fixups
;
222 struct label_fix
*tag_fixups
;
223 struct unw_rec_list
*unwind_record
; /* Unwind directive. */
226 unsigned int src_line
;
227 struct dwarf2_line_info debug_line
;
235 struct dynreg
*next
; /* next dynamic register */
237 unsigned short base
; /* the base register number */
238 unsigned short num_regs
; /* # of registers in this set */
240 *dynreg
[DYNREG_NUM_TYPES
], in
, loc
, out
, rot
;
242 flagword flags
; /* ELF-header flags */
245 unsigned hint
:1; /* is this hint currently valid? */
246 bfd_vma offset
; /* mem.offset offset */
247 bfd_vma base
; /* mem.offset base */
250 int path
; /* number of alt. entry points seen */
251 const char **entry_labels
; /* labels of all alternate paths in
252 the current DV-checking block. */
253 int maxpaths
; /* size currently allocated for
258 /* application registers: */
264 #define AR_BSPSTORE 18
279 {"ar.k0", 0}, {"ar.k1", 1}, {"ar.k2", 2}, {"ar.k3", 3},
280 {"ar.k4", 4}, {"ar.k5", 5}, {"ar.k6", 6}, {"ar.k7", 7},
281 {"ar.rsc", 16}, {"ar.bsp", 17},
282 {"ar.bspstore", 18}, {"ar.rnat", 19},
283 {"ar.fcr", 21}, {"ar.eflag", 24},
284 {"ar.csd", 25}, {"ar.ssd", 26},
285 {"ar.cflg", 27}, {"ar.fsr", 28},
286 {"ar.fir", 29}, {"ar.fdr", 30},
287 {"ar.ccv", 32}, {"ar.unat", 36},
288 {"ar.fpsr", 40}, {"ar.itc", 44},
289 {"ar.pfs", 64}, {"ar.lc", 65},
310 /* control registers: */
352 static const struct const_desc
359 /* PSR constant masks: */
362 {"psr.be", ((valueT
) 1) << 1},
363 {"psr.up", ((valueT
) 1) << 2},
364 {"psr.ac", ((valueT
) 1) << 3},
365 {"psr.mfl", ((valueT
) 1) << 4},
366 {"psr.mfh", ((valueT
) 1) << 5},
368 {"psr.ic", ((valueT
) 1) << 13},
369 {"psr.i", ((valueT
) 1) << 14},
370 {"psr.pk", ((valueT
) 1) << 15},
372 {"psr.dt", ((valueT
) 1) << 17},
373 {"psr.dfl", ((valueT
) 1) << 18},
374 {"psr.dfh", ((valueT
) 1) << 19},
375 {"psr.sp", ((valueT
) 1) << 20},
376 {"psr.pp", ((valueT
) 1) << 21},
377 {"psr.di", ((valueT
) 1) << 22},
378 {"psr.si", ((valueT
) 1) << 23},
379 {"psr.db", ((valueT
) 1) << 24},
380 {"psr.lp", ((valueT
) 1) << 25},
381 {"psr.tb", ((valueT
) 1) << 26},
382 {"psr.rt", ((valueT
) 1) << 27},
383 /* 28-31: reserved */
384 /* 32-33: cpl (current privilege level) */
385 {"psr.is", ((valueT
) 1) << 34},
386 {"psr.mc", ((valueT
) 1) << 35},
387 {"psr.it", ((valueT
) 1) << 36},
388 {"psr.id", ((valueT
) 1) << 37},
389 {"psr.da", ((valueT
) 1) << 38},
390 {"psr.dd", ((valueT
) 1) << 39},
391 {"psr.ss", ((valueT
) 1) << 40},
392 /* 41-42: ri (restart instruction) */
393 {"psr.ed", ((valueT
) 1) << 43},
394 {"psr.bn", ((valueT
) 1) << 44},
397 /* indirect register-sets/memory: */
406 { "CPUID", IND_CPUID
},
407 { "cpuid", IND_CPUID
},
419 /* Pseudo functions used to indicate relocation types (these functions
420 start with an at sign (@). */
442 /* reloc pseudo functions (these must come first!): */
443 { "fptr", PSEUDO_FUNC_RELOC
},
444 { "gprel", PSEUDO_FUNC_RELOC
},
445 { "ltoff", PSEUDO_FUNC_RELOC
},
446 { "pcrel", PSEUDO_FUNC_RELOC
},
447 { "pltoff", PSEUDO_FUNC_RELOC
},
448 { "secrel", PSEUDO_FUNC_RELOC
},
449 { "segrel", PSEUDO_FUNC_RELOC
},
450 { "ltv", PSEUDO_FUNC_RELOC
},
451 { 0, }, /* placeholder for FUNC_LT_FPTR_RELATIVE */
453 /* mbtype4 constants: */
454 { "alt", PSEUDO_FUNC_CONST
, { 0xa } },
455 { "brcst", PSEUDO_FUNC_CONST
, { 0x0 } },
456 { "mix", PSEUDO_FUNC_CONST
, { 0x8 } },
457 { "rev", PSEUDO_FUNC_CONST
, { 0xb } },
458 { "shuf", PSEUDO_FUNC_CONST
, { 0x9 } },
460 /* fclass constants: */
461 { "nat", PSEUDO_FUNC_CONST
, { 0x100 } },
462 { "qnan", PSEUDO_FUNC_CONST
, { 0x080 } },
463 { "snan", PSEUDO_FUNC_CONST
, { 0x040 } },
464 { "pos", PSEUDO_FUNC_CONST
, { 0x001 } },
465 { "neg", PSEUDO_FUNC_CONST
, { 0x002 } },
466 { "zero", PSEUDO_FUNC_CONST
, { 0x004 } },
467 { "unorm", PSEUDO_FUNC_CONST
, { 0x008 } },
468 { "norm", PSEUDO_FUNC_CONST
, { 0x010 } },
469 { "inf", PSEUDO_FUNC_CONST
, { 0x020 } },
471 { "natval", PSEUDO_FUNC_CONST
, { 0x100 } }, /* old usage */
473 /* unwind-related constants: */
474 { "svr4", PSEUDO_FUNC_CONST
, { 0 } },
475 { "hpux", PSEUDO_FUNC_CONST
, { 1 } },
476 { "nt", PSEUDO_FUNC_CONST
, { 2 } },
478 /* unwind-related registers: */
479 { "priunat",PSEUDO_FUNC_REG
, { REG_PRIUNAT
} }
482 /* 41-bit nop opcodes (one per unit): */
483 static const bfd_vma nop
[IA64_NUM_UNITS
] =
485 0x0000000000LL
, /* NIL => break 0 */
486 0x0008000000LL
, /* I-unit nop */
487 0x0008000000LL
, /* M-unit nop */
488 0x4000000000LL
, /* B-unit nop */
489 0x0008000000LL
, /* F-unit nop */
490 0x0008000000LL
, /* L-"unit" nop */
491 0x0008000000LL
, /* X-unit nop */
494 /* Can't be `const' as it's passed to input routines (which have the
495 habit of setting temporary sentinels. */
496 static char special_section_name
[][20] =
498 {".bss"}, {".sbss"}, {".sdata"}, {".rodata"}, {".comment"},
499 {".IA_64.unwind"}, {".IA_64.unwind_info"}
502 /* The best template for a particular sequence of up to three
504 #define N IA64_NUM_TYPES
505 static unsigned char best_template
[N
][N
][N
];
508 /* Resource dependencies currently in effect */
510 int depind
; /* dependency index */
511 const struct ia64_dependency
*dependency
; /* actual dependency */
512 unsigned specific
:1, /* is this a specific bit/regno? */
513 link_to_qp_branch
:1; /* will a branch on the same QP clear it?*/
514 int index
; /* specific regno/bit within dependency */
515 int note
; /* optional qualifying note (0 if none) */
519 int insn_srlz
; /* current insn serialization state */
520 int data_srlz
; /* current data serialization state */
521 int qp_regno
; /* qualifying predicate for this usage */
522 char *file
; /* what file marked this dependency */
523 int line
; /* what line marked this dependency */
524 struct mem_offset mem_offset
; /* optional memory offset hint */
525 enum { CMP_NONE
, CMP_OR
, CMP_AND
} cmp_type
; /* OR or AND compare? */
526 int path
; /* corresponding code entry index */
528 static int regdepslen
= 0;
529 static int regdepstotlen
= 0;
530 static const char *dv_mode
[] = { "RAW", "WAW", "WAR" };
531 static const char *dv_sem
[] = { "none", "implied", "impliedf",
532 "data", "instr", "specific", "stop", "other" };
533 static const char *dv_cmp_type
[] = { "none", "OR", "AND" };
535 /* Current state of PR mutexation */
536 static struct qpmutex
{
539 } *qp_mutexes
= NULL
; /* QP mutex bitmasks */
540 static int qp_mutexeslen
= 0;
541 static int qp_mutexestotlen
= 0;
542 static valueT qp_safe_across_calls
= 0;
544 /* Current state of PR implications */
545 static struct qp_imply
{
548 unsigned p2_branched
:1;
550 } *qp_implies
= NULL
;
551 static int qp_implieslen
= 0;
552 static int qp_impliestotlen
= 0;
554 /* Keep track of static GR values so that indirect register usage can
555 sometimes be tracked. */
560 } gr_values
[128] = {{ 1, 0 }};
562 /* These are the routines required to output the various types of
565 typedef struct unw_rec_list
{
567 unsigned long slot_number
;
568 struct unw_rec_list
*next
;
571 #define SLOT_NUM_NOT_SET -1
575 unsigned long next_slot_number
;
577 /* Maintain a list of unwind entries for the current function. */
581 /* Any unwind entires that should be attached to the current slot
582 that an insn is being constructed for. */
583 unw_rec_list
*current_entry
;
585 /* These are used to create the unwind table entry for this function. */
588 symbolS
*info
; /* pointer to unwind info */
589 symbolS
*personality_routine
;
591 /* TRUE if processing unwind directives in a prologue region. */
596 typedef void (*vbyte_func
) PARAMS ((int, char *, char *));
598 /* Forward delarations: */
599 static int ar_is_in_integer_unit
PARAMS ((int regnum
));
600 static void set_section
PARAMS ((char *name
));
601 static unsigned int set_regstack
PARAMS ((unsigned int, unsigned int,
602 unsigned int, unsigned int));
603 static void dot_radix
PARAMS ((int));
604 static void dot_special_section
PARAMS ((int));
605 static void dot_proc
PARAMS ((int));
606 static void dot_fframe
PARAMS ((int));
607 static void dot_vframe
PARAMS ((int));
608 static void dot_vframesp
PARAMS ((int));
609 static void dot_vframepsp
PARAMS ((int));
610 static void dot_save
PARAMS ((int));
611 static void dot_restore
PARAMS ((int));
612 static void dot_restorereg
PARAMS ((int));
613 static void dot_restorereg_p
PARAMS ((int));
614 static void dot_handlerdata
PARAMS ((int));
615 static void dot_unwentry
PARAMS ((int));
616 static void dot_altrp
PARAMS ((int));
617 static void dot_savemem
PARAMS ((int));
618 static void dot_saveg
PARAMS ((int));
619 static void dot_savef
PARAMS ((int));
620 static void dot_saveb
PARAMS ((int));
621 static void dot_savegf
PARAMS ((int));
622 static void dot_spill
PARAMS ((int));
623 static void dot_spillreg
PARAMS ((int));
624 static void dot_spillmem
PARAMS ((int));
625 static void dot_spillreg_p
PARAMS ((int));
626 static void dot_spillmem_p
PARAMS ((int));
627 static void dot_label_state
PARAMS ((int));
628 static void dot_copy_state
PARAMS ((int));
629 static void dot_unwabi
PARAMS ((int));
630 static void dot_personality
PARAMS ((int));
631 static void dot_body
PARAMS ((int));
632 static void dot_prologue
PARAMS ((int));
633 static void dot_endp
PARAMS ((int));
634 static void dot_template
PARAMS ((int));
635 static void dot_regstk
PARAMS ((int));
636 static void dot_rot
PARAMS ((int));
637 static void dot_byteorder
PARAMS ((int));
638 static void dot_psr
PARAMS ((int));
639 static void dot_alias
PARAMS ((int));
640 static void dot_ln
PARAMS ((int));
641 static char *parse_section_name
PARAMS ((void));
642 static void dot_xdata
PARAMS ((int));
643 static void stmt_float_cons
PARAMS ((int));
644 static void stmt_cons_ua
PARAMS ((int));
645 static void dot_xfloat_cons
PARAMS ((int));
646 static void dot_xstringer
PARAMS ((int));
647 static void dot_xdata_ua
PARAMS ((int));
648 static void dot_xfloat_cons_ua
PARAMS ((int));
649 static void print_prmask
PARAMS ((valueT mask
));
650 static void dot_pred_rel
PARAMS ((int));
651 static void dot_reg_val
PARAMS ((int));
652 static void dot_dv_mode
PARAMS ((int));
653 static void dot_entry
PARAMS ((int));
654 static void dot_mem_offset
PARAMS ((int));
655 static void add_unwind_entry
PARAMS((unw_rec_list
*ptr
));
656 static symbolS
*declare_register
PARAMS ((const char *name
, int regnum
));
657 static void declare_register_set
PARAMS ((const char *, int, int));
658 static unsigned int operand_width
PARAMS ((enum ia64_opnd
));
659 static int operand_match
PARAMS ((const struct ia64_opcode
*idesc
,
660 int index
, expressionS
*e
));
661 static int parse_operand
PARAMS ((expressionS
*e
));
662 static struct ia64_opcode
* parse_operands
PARAMS ((struct ia64_opcode
*));
663 static void build_insn
PARAMS ((struct slot
*, bfd_vma
*));
664 static void emit_one_bundle
PARAMS ((void));
665 static void fix_insn
PARAMS ((fixS
*, const struct ia64_operand
*, valueT
));
666 static bfd_reloc_code_real_type ia64_gen_real_reloc_type
PARAMS ((struct symbol
*sym
,
667 bfd_reloc_code_real_type r_type
));
668 static void insn_group_break
PARAMS ((int, int, int));
669 static void mark_resource
PARAMS ((struct ia64_opcode
*, const struct ia64_dependency
*,
670 struct rsrc
*, int depind
, int path
));
671 static void add_qp_mutex
PARAMS((valueT mask
));
672 static void add_qp_imply
PARAMS((int p1
, int p2
));
673 static void clear_qp_branch_flag
PARAMS((valueT mask
));
674 static void clear_qp_mutex
PARAMS((valueT mask
));
675 static void clear_qp_implies
PARAMS((valueT p1_mask
, valueT p2_mask
));
676 static void clear_register_values
PARAMS ((void));
677 static void print_dependency
PARAMS ((const char *action
, int depind
));
678 static void instruction_serialization
PARAMS ((void));
679 static void data_serialization
PARAMS ((void));
680 static void remove_marked_resource
PARAMS ((struct rsrc
*));
681 static int is_conditional_branch
PARAMS ((struct ia64_opcode
*));
682 static int is_taken_branch
PARAMS ((struct ia64_opcode
*));
683 static int is_interruption_or_rfi
PARAMS ((struct ia64_opcode
*));
684 static int depends_on
PARAMS ((int, struct ia64_opcode
*));
685 static int specify_resource
PARAMS ((const struct ia64_dependency
*,
686 struct ia64_opcode
*, int, struct rsrc
[], int, int));
687 static int check_dv
PARAMS((struct ia64_opcode
*idesc
));
688 static void check_dependencies
PARAMS((struct ia64_opcode
*));
689 static void mark_resources
PARAMS((struct ia64_opcode
*));
690 static void update_dependencies
PARAMS((struct ia64_opcode
*));
691 static void note_register_values
PARAMS((struct ia64_opcode
*));
692 static int qp_mutex
PARAMS ((int, int, int));
693 static int resources_match
PARAMS ((struct rsrc
*, struct ia64_opcode
*, int, int, int));
694 static void output_vbyte_mem
PARAMS ((int, char *, char *));
695 static void count_output
PARAMS ((int, char *, char *));
696 static void output_R1_format
PARAMS ((vbyte_func
, unw_record_type
, int));
697 static void output_R2_format
PARAMS ((vbyte_func
, int, int, unsigned long));
698 static void output_R3_format
PARAMS ((vbyte_func
, unw_record_type
, unsigned long));
699 static void output_P1_format
PARAMS ((vbyte_func
, int));
700 static void output_P2_format
PARAMS ((vbyte_func
, int, int));
701 static void output_P3_format
PARAMS ((vbyte_func
, unw_record_type
, int));
702 static void output_P4_format
PARAMS ((vbyte_func
, unsigned char *, unsigned long));
703 static void output_P5_format
PARAMS ((vbyte_func
, int, unsigned long));
704 static void output_P6_format
PARAMS ((vbyte_func
, unw_record_type
, int));
705 static void output_P7_format
PARAMS ((vbyte_func
, unw_record_type
, unsigned long, unsigned long));
706 static void output_P8_format
PARAMS ((vbyte_func
, unw_record_type
, unsigned long));
707 static void output_P9_format
PARAMS ((vbyte_func
, int, int));
708 static void output_P10_format
PARAMS ((vbyte_func
, int, int));
709 static void output_B1_format
PARAMS ((vbyte_func
, unw_record_type
, unsigned long));
710 static void output_B2_format
PARAMS ((vbyte_func
, unsigned long, unsigned long));
711 static void output_B3_format
PARAMS ((vbyte_func
, unsigned long, unsigned long));
712 static void output_B4_format
PARAMS ((vbyte_func
, unw_record_type
, unsigned long));
713 static char format_ab_reg
PARAMS ((int, int));
714 static void output_X1_format
PARAMS ((vbyte_func
, unw_record_type
, int, int, unsigned long,
716 static void output_X2_format
PARAMS ((vbyte_func
, int, int, int, int, int, unsigned long));
717 static void output_X3_format
PARAMS ((vbyte_func
, unw_record_type
, int, int, int, unsigned long,
719 static void output_X4_format
PARAMS ((vbyte_func
, int, int, int, int, int, int, unsigned long));
720 static void free_list_records
PARAMS ((unw_rec_list
*));
721 static unw_rec_list
*output_prologue
PARAMS ((void));
722 static unw_rec_list
*output_prologue_gr
PARAMS ((unsigned int, unsigned int));
723 static unw_rec_list
*output_body
PARAMS ((void));
724 static unw_rec_list
*output_mem_stack_f
PARAMS ((unsigned int));
725 static unw_rec_list
*output_mem_stack_v
PARAMS ((void));
726 static unw_rec_list
*output_psp_gr
PARAMS ((unsigned int));
727 static unw_rec_list
*output_psp_sprel
PARAMS ((unsigned int));
728 static unw_rec_list
*output_rp_when
PARAMS ((void));
729 static unw_rec_list
*output_rp_gr
PARAMS ((unsigned int));
730 static unw_rec_list
*output_rp_br
PARAMS ((unsigned int));
731 static unw_rec_list
*output_rp_psprel
PARAMS ((unsigned int));
732 static unw_rec_list
*output_rp_sprel
PARAMS ((unsigned int));
733 static unw_rec_list
*output_pfs_when
PARAMS ((void));
734 static unw_rec_list
*output_pfs_gr
PARAMS ((unsigned int));
735 static unw_rec_list
*output_pfs_psprel
PARAMS ((unsigned int));
736 static unw_rec_list
*output_pfs_sprel
PARAMS ((unsigned int));
737 static unw_rec_list
*output_preds_when
PARAMS ((void));
738 static unw_rec_list
*output_preds_gr
PARAMS ((unsigned int));
739 static unw_rec_list
*output_preds_psprel
PARAMS ((unsigned int));
740 static unw_rec_list
*output_preds_sprel
PARAMS ((unsigned int));
741 static unw_rec_list
*output_fr_mem
PARAMS ((unsigned int));
742 static unw_rec_list
*output_frgr_mem
PARAMS ((unsigned int, unsigned int));
743 static unw_rec_list
*output_gr_gr
PARAMS ((unsigned int, unsigned int));
744 static unw_rec_list
*output_gr_mem
PARAMS ((unsigned int));
745 static unw_rec_list
*output_br_mem
PARAMS ((unsigned int));
746 static unw_rec_list
*output_br_gr
PARAMS ((unsigned int, unsigned int));
747 static unw_rec_list
*output_spill_base
PARAMS ((unsigned int));
748 static unw_rec_list
*output_unat_when
PARAMS ((void));
749 static unw_rec_list
*output_unat_gr
PARAMS ((unsigned int));
750 static unw_rec_list
*output_unat_psprel
PARAMS ((unsigned int));
751 static unw_rec_list
*output_unat_sprel
PARAMS ((unsigned int));
752 static unw_rec_list
*output_lc_when
PARAMS ((void));
753 static unw_rec_list
*output_lc_gr
PARAMS ((unsigned int));
754 static unw_rec_list
*output_lc_psprel
PARAMS ((unsigned int));
755 static unw_rec_list
*output_lc_sprel
PARAMS ((unsigned int));
756 static unw_rec_list
*output_fpsr_when
PARAMS ((void));
757 static unw_rec_list
*output_fpsr_gr
PARAMS ((unsigned int));
758 static unw_rec_list
*output_fpsr_psprel
PARAMS ((unsigned int));
759 static unw_rec_list
*output_fpsr_sprel
PARAMS ((unsigned int));
760 static unw_rec_list
*output_priunat_when_gr
PARAMS ((void));
761 static unw_rec_list
*output_priunat_when_mem
PARAMS ((void));
762 static unw_rec_list
*output_priunat_gr
PARAMS ((unsigned int));
763 static unw_rec_list
*output_priunat_psprel
PARAMS ((unsigned int));
764 static unw_rec_list
*output_priunat_sprel
PARAMS ((unsigned int));
765 static unw_rec_list
*output_bsp_when
PARAMS ((void));
766 static unw_rec_list
*output_bsp_gr
PARAMS ((unsigned int));
767 static unw_rec_list
*output_bsp_psprel
PARAMS ((unsigned int));
768 static unw_rec_list
*output_bsp_sprel
PARAMS ((unsigned int));
769 static unw_rec_list
*output_bspstore_when
PARAMS ((void));
770 static unw_rec_list
*output_bspstore_gr
PARAMS ((unsigned int));
771 static unw_rec_list
*output_bspstore_psprel
PARAMS ((unsigned int));
772 static unw_rec_list
*output_bspstore_sprel
PARAMS ((unsigned int));
773 static unw_rec_list
*output_rnat_when
PARAMS ((void));
774 static unw_rec_list
*output_rnat_gr
PARAMS ((unsigned int));
775 static unw_rec_list
*output_rnat_psprel
PARAMS ((unsigned int));
776 static unw_rec_list
*output_rnat_sprel
PARAMS ((unsigned int));
777 static unw_rec_list
*output_unwabi
PARAMS ((unsigned long, unsigned long));
778 static unw_rec_list
*output_epilogue
PARAMS ((unsigned long));
779 static unw_rec_list
*output_label_state
PARAMS ((unsigned long));
780 static unw_rec_list
*output_copy_state
PARAMS ((unsigned long));
781 static unw_rec_list
*output_spill_psprel
PARAMS ((unsigned int, unsigned int, unsigned int));
782 static unw_rec_list
*output_spill_sprel
PARAMS ((unsigned int, unsigned int, unsigned int));
783 static unw_rec_list
*output_spill_psprel_p
PARAMS ((unsigned int, unsigned int, unsigned int,
785 static unw_rec_list
*output_spill_sprel_p
PARAMS ((unsigned int, unsigned int, unsigned int,
787 static unw_rec_list
*output_spill_reg
PARAMS ((unsigned int, unsigned int, unsigned int,
789 static unw_rec_list
*output_spill_reg_p
PARAMS ((unsigned int, unsigned int, unsigned int,
790 unsigned int, unsigned int));
791 static void process_one_record
PARAMS ((unw_rec_list
*, vbyte_func
));
792 static void process_unw_records
PARAMS ((unw_rec_list
*, vbyte_func
));
793 static int calc_record_size
PARAMS ((unw_rec_list
*));
794 static void set_imask
PARAMS ((unw_rec_list
*, unsigned long, unsigned long, unsigned int));
795 static int count_bits
PARAMS ((unsigned long));
796 static unsigned long slot_index
PARAMS ((unsigned long, unsigned long));
797 static void fixup_unw_records
PARAMS ((unw_rec_list
*));
798 static int output_unw_records
PARAMS ((unw_rec_list
*, void **));
799 static int convert_expr_to_ab_reg
PARAMS ((expressionS
*, unsigned int *, unsigned int *));
800 static int convert_expr_to_xy_reg
PARAMS ((expressionS
*, unsigned int *, unsigned int *));
801 static int generate_unwind_image
PARAMS ((void));
803 /* Determine if application register REGNUM resides in the integer
804 unit (as opposed to the memory unit). */
806 ar_is_in_integer_unit (reg
)
811 return (reg
== 64 /* pfs */
812 || reg
== 65 /* lc */
813 || reg
== 66 /* ec */
814 /* ??? ias accepts and puts these in the integer unit. */
815 || (reg
>= 112 && reg
<= 127));
818 /* Switch to section NAME and create section if necessary. It's
819 rather ugly that we have to manipulate input_line_pointer but I
820 don't see any other way to accomplish the same thing without
821 changing obj-elf.c (which may be the Right Thing, in the end). */
826 char *saved_input_line_pointer
;
828 saved_input_line_pointer
= input_line_pointer
;
829 input_line_pointer
= name
;
831 input_line_pointer
= saved_input_line_pointer
;
834 /* Map SHF_IA_64_SHORT to SEC_SMALL_DATA. */
837 ia64_elf_section_flags (flags
, attr
, type
)
841 if (attr
& SHF_IA_64_SHORT
)
842 flags
|= SEC_SMALL_DATA
;
847 set_regstack (ins
, locs
, outs
, rots
)
848 unsigned int ins
, locs
, outs
, rots
;
853 sof
= ins
+ locs
+ outs
;
856 as_bad ("Size of frame exceeds maximum of 96 registers");
861 as_warn ("Size of rotating registers exceeds frame size");
864 md
.in
.base
= REG_GR
+ 32;
865 md
.loc
.base
= md
.in
.base
+ ins
;
866 md
.out
.base
= md
.loc
.base
+ locs
;
868 md
.in
.num_regs
= ins
;
869 md
.loc
.num_regs
= locs
;
870 md
.out
.num_regs
= outs
;
871 md
.rot
.num_regs
= rots
;
878 struct label_fix
*lfix
;
880 subsegT saved_subseg
;
882 if (!md
.last_text_seg
)
886 saved_subseg
= now_subseg
;
888 subseg_set (md
.last_text_seg
, 0);
890 while (md
.num_slots_in_use
> 0)
891 emit_one_bundle (); /* force out queued instructions */
893 /* In case there are labels following the last instruction, resolve
895 for (lfix
= CURR_SLOT
.label_fixups
; lfix
; lfix
= lfix
->next
)
897 S_SET_VALUE (lfix
->sym
, frag_now_fix ());
898 symbol_set_frag (lfix
->sym
, frag_now
);
900 CURR_SLOT
.label_fixups
= 0;
901 for (lfix
= CURR_SLOT
.tag_fixups
; lfix
; lfix
= lfix
->next
)
903 S_SET_VALUE (lfix
->sym
, frag_now_fix ());
904 symbol_set_frag (lfix
->sym
, frag_now
);
906 CURR_SLOT
.tag_fixups
= 0;
908 subseg_set (saved_seg
, saved_subseg
);
910 if (md
.qp
.X_op
== O_register
)
911 as_bad ("qualifying predicate not followed by instruction");
915 ia64_do_align (nbytes
)
918 char *saved_input_line_pointer
= input_line_pointer
;
920 input_line_pointer
= "";
921 s_align_bytes (nbytes
);
922 input_line_pointer
= saved_input_line_pointer
;
926 ia64_cons_align (nbytes
)
931 char *saved_input_line_pointer
= input_line_pointer
;
932 input_line_pointer
= "";
933 s_align_bytes (nbytes
);
934 input_line_pointer
= saved_input_line_pointer
;
938 /* Output COUNT bytes to a memory location. */
939 static unsigned char *vbyte_mem_ptr
= NULL
;
942 output_vbyte_mem (count
, ptr
, comment
)
948 if (vbyte_mem_ptr
== NULL
)
953 for (x
= 0; x
< count
; x
++)
954 *(vbyte_mem_ptr
++) = ptr
[x
];
957 /* Count the number of bytes required for records. */
958 static int vbyte_count
= 0;
960 count_output (count
, ptr
, comment
)
965 vbyte_count
+= count
;
969 output_R1_format (f
, rtype
, rlen
)
971 unw_record_type rtype
;
978 output_R3_format (f
, rtype
, rlen
);
984 else if (rtype
!= prologue
)
985 as_bad ("record type is not valid");
987 byte
= UNW_R1
| (r
<< 5) | (rlen
& 0x1f);
988 (*f
) (1, &byte
, NULL
);
992 output_R2_format (f
, mask
, grsave
, rlen
)
999 mask
= (mask
& 0x0f);
1000 grsave
= (grsave
& 0x7f);
1002 bytes
[0] = (UNW_R2
| (mask
>> 1));
1003 bytes
[1] = (((mask
& 0x01) << 7) | grsave
);
1004 count
+= output_leb128 (bytes
+ 2, rlen
, 0);
1005 (*f
) (count
, bytes
, NULL
);
1009 output_R3_format (f
, rtype
, rlen
)
1011 unw_record_type rtype
;
1018 output_R1_format (f
, rtype
, rlen
);
1024 else if (rtype
!= prologue
)
1025 as_bad ("record type is not valid");
1026 bytes
[0] = (UNW_R3
| r
);
1027 count
= output_leb128 (bytes
+ 1, rlen
, 0);
1028 (*f
) (count
+ 1, bytes
, NULL
);
1032 output_P1_format (f
, brmask
)
1037 byte
= UNW_P1
| (brmask
& 0x1f);
1038 (*f
) (1, &byte
, NULL
);
1042 output_P2_format (f
, brmask
, gr
)
1048 brmask
= (brmask
& 0x1f);
1049 bytes
[0] = UNW_P2
| (brmask
>> 1);
1050 bytes
[1] = (((brmask
& 1) << 7) | gr
);
1051 (*f
) (2, bytes
, NULL
);
1055 output_P3_format (f
, rtype
, reg
)
1057 unw_record_type rtype
;
1102 as_bad ("Invalid record type for P3 format.");
1104 bytes
[0] = (UNW_P3
| (r
>> 1));
1105 bytes
[1] = (((r
& 1) << 7) | reg
);
1106 (*f
) (2, bytes
, NULL
);
1110 output_P4_format (f
, imask
, imask_size
)
1112 unsigned char *imask
;
1113 unsigned long imask_size
;
1116 (*f
) (imask_size
, imask
, NULL
);
1120 output_P5_format (f
, grmask
, frmask
)
1123 unsigned long frmask
;
1126 grmask
= (grmask
& 0x0f);
1129 bytes
[1] = ((grmask
<< 4) | ((frmask
& 0x000f0000) >> 16));
1130 bytes
[2] = ((frmask
& 0x0000ff00) >> 8);
1131 bytes
[3] = (frmask
& 0x000000ff);
1132 (*f
) (4, bytes
, NULL
);
1136 output_P6_format (f
, rtype
, rmask
)
1138 unw_record_type rtype
;
1144 if (rtype
== gr_mem
)
1146 else if (rtype
!= fr_mem
)
1147 as_bad ("Invalid record type for format P6");
1148 byte
= (UNW_P6
| (r
<< 4) | (rmask
& 0x0f));
1149 (*f
) (1, &byte
, NULL
);
1153 output_P7_format (f
, rtype
, w1
, w2
)
1155 unw_record_type rtype
;
1162 count
+= output_leb128 (bytes
+ 1, w1
, 0);
1167 count
+= output_leb128 (bytes
+ count
, w2
>> 4, 0);
1217 bytes
[0] = (UNW_P7
| r
);
1218 (*f
) (count
, bytes
, NULL
);
1222 output_P8_format (f
, rtype
, t
)
1224 unw_record_type rtype
;
1263 case bspstore_psprel
:
1266 case bspstore_sprel
:
1278 case priunat_when_gr
:
1281 case priunat_psprel
:
1287 case priunat_when_mem
:
1294 count
+= output_leb128 (bytes
+ 2, t
, 0);
1295 (*f
) (count
, bytes
, NULL
);
1299 output_P9_format (f
, grmask
, gr
)
1306 bytes
[1] = (grmask
& 0x0f);
1307 bytes
[2] = (gr
& 0x7f);
1308 (*f
) (3, bytes
, NULL
);
1312 output_P10_format (f
, abi
, context
)
1319 bytes
[1] = (abi
& 0xff);
1320 bytes
[2] = (context
& 0xff);
1321 (*f
) (3, bytes
, NULL
);
1325 output_B1_format (f
, rtype
, label
)
1327 unw_record_type rtype
;
1328 unsigned long label
;
1334 output_B4_format (f
, rtype
, label
);
1337 if (rtype
== copy_state
)
1339 else if (rtype
!= label_state
)
1340 as_bad ("Invalid record type for format B1");
1342 byte
= (UNW_B1
| (r
<< 5) | (label
& 0x1f));
1343 (*f
) (1, &byte
, NULL
);
1347 output_B2_format (f
, ecount
, t
)
1349 unsigned long ecount
;
1356 output_B3_format (f
, ecount
, t
);
1359 bytes
[0] = (UNW_B2
| (ecount
& 0x1f));
1360 count
+= output_leb128 (bytes
+ 1, t
, 0);
1361 (*f
) (count
, bytes
, NULL
);
1365 output_B3_format (f
, ecount
, t
)
1367 unsigned long ecount
;
1374 output_B2_format (f
, ecount
, t
);
1378 count
+= output_leb128 (bytes
+ 1, t
, 0);
1379 count
+= output_leb128 (bytes
+ count
, ecount
, 0);
1380 (*f
) (count
, bytes
, NULL
);
1384 output_B4_format (f
, rtype
, label
)
1386 unw_record_type rtype
;
1387 unsigned long label
;
1394 output_B1_format (f
, rtype
, label
);
1398 if (rtype
== copy_state
)
1400 else if (rtype
!= label_state
)
1401 as_bad ("Invalid record type for format B1");
1403 bytes
[0] = (UNW_B4
| (r
<< 3));
1404 count
+= output_leb128 (bytes
+ 1, label
, 0);
1405 (*f
) (count
, bytes
, NULL
);
1409 format_ab_reg (ab
, reg
)
1416 ret
= (ab
<< 5) | reg
;
1421 output_X1_format (f
, rtype
, ab
, reg
, t
, w1
)
1423 unw_record_type rtype
;
1433 if (rtype
== spill_sprel
)
1435 else if (rtype
!= spill_psprel
)
1436 as_bad ("Invalid record type for format X1");
1437 bytes
[1] = ((r
<< 7) | format_ab_reg (ab
, reg
));
1438 count
+= output_leb128 (bytes
+ 2, t
, 0);
1439 count
+= output_leb128 (bytes
+ count
, w1
, 0);
1440 (*f
) (count
, bytes
, NULL
);
1444 output_X2_format (f
, ab
, reg
, x
, y
, treg
, t
)
1453 bytes
[1] = (((x
& 1) << 7) | format_ab_reg (ab
, reg
));
1454 bytes
[2] = (((y
& 1) << 7) | (treg
& 0x7f));
1455 count
+= output_leb128 (bytes
+ 3, t
, 0);
1456 (*f
) (count
, bytes
, NULL
);
1460 output_X3_format (f
, rtype
, qp
, ab
, reg
, t
, w1
)
1462 unw_record_type rtype
;
1473 if (rtype
== spill_sprel_p
)
1475 else if (rtype
!= spill_psprel_p
)
1476 as_bad ("Invalid record type for format X3");
1477 bytes
[1] = ((r
<< 7) | (qp
& 0x3f));
1478 bytes
[2] = format_ab_reg (ab
, reg
);
1479 count
+= output_leb128 (bytes
+ 3, t
, 0);
1480 count
+= output_leb128 (bytes
+ count
, w1
, 0);
1481 (*f
) (count
, bytes
, NULL
);
1485 output_X4_format (f
, qp
, ab
, reg
, x
, y
, treg
, t
)
1495 bytes
[1] = (qp
& 0x3f);
1496 bytes
[2] = (((x
& 1) << 7) | format_ab_reg (ab
, reg
));
1497 bytes
[3] = (((y
& 1) << 7) | (treg
& 0x7f));
1498 count
+= output_leb128 (bytes
+ 4, t
, 0);
1499 (*f
) (count
, bytes
, NULL
);
1502 /* This function allocates a record list structure, and initializes fields. */
1504 static unw_rec_list
*
1505 alloc_record (unw_record_type t
)
1508 ptr
= xmalloc (sizeof (*ptr
));
1510 ptr
->slot_number
= SLOT_NUM_NOT_SET
;
1515 /* This function frees an entire list of record structures. */
1518 free_list_records (unw_rec_list
*first
)
1521 for (ptr
= first
; ptr
!= NULL
;)
1523 unw_rec_list
*tmp
= ptr
;
1525 if ((tmp
->r
.type
== prologue
|| tmp
->r
.type
== prologue_gr
)
1526 && tmp
->r
.record
.r
.mask
.i
)
1527 free (tmp
->r
.record
.r
.mask
.i
);
1534 static unw_rec_list
*
1537 unw_rec_list
*ptr
= alloc_record (prologue
);
1538 memset (&ptr
->r
.record
.r
.mask
, 0, sizeof (ptr
->r
.record
.r
.mask
));
1542 static unw_rec_list
*
1543 output_prologue_gr (saved_mask
, reg
)
1544 unsigned int saved_mask
;
1547 unw_rec_list
*ptr
= alloc_record (prologue_gr
);
1548 memset (&ptr
->r
.record
.r
.mask
, 0, sizeof (ptr
->r
.record
.r
.mask
));
1549 ptr
->r
.record
.r
.grmask
= saved_mask
;
1550 ptr
->r
.record
.r
.grsave
= reg
;
1554 static unw_rec_list
*
1557 unw_rec_list
*ptr
= alloc_record (body
);
1561 static unw_rec_list
*
1562 output_mem_stack_f (size
)
1565 unw_rec_list
*ptr
= alloc_record (mem_stack_f
);
1566 ptr
->r
.record
.p
.size
= size
;
1570 static unw_rec_list
*
1571 output_mem_stack_v ()
1573 unw_rec_list
*ptr
= alloc_record (mem_stack_v
);
1577 static unw_rec_list
*
1581 unw_rec_list
*ptr
= alloc_record (psp_gr
);
1582 ptr
->r
.record
.p
.gr
= gr
;
1586 static unw_rec_list
*
1587 output_psp_sprel (offset
)
1588 unsigned int offset
;
1590 unw_rec_list
*ptr
= alloc_record (psp_sprel
);
1591 ptr
->r
.record
.p
.spoff
= offset
/ 4;
1595 static unw_rec_list
*
1598 unw_rec_list
*ptr
= alloc_record (rp_when
);
1602 static unw_rec_list
*
1606 unw_rec_list
*ptr
= alloc_record (rp_gr
);
1607 ptr
->r
.record
.p
.gr
= gr
;
1611 static unw_rec_list
*
1615 unw_rec_list
*ptr
= alloc_record (rp_br
);
1616 ptr
->r
.record
.p
.br
= br
;
1620 static unw_rec_list
*
1621 output_rp_psprel (offset
)
1622 unsigned int offset
;
1624 unw_rec_list
*ptr
= alloc_record (rp_psprel
);
1625 ptr
->r
.record
.p
.pspoff
= offset
/ 4;
1629 static unw_rec_list
*
1630 output_rp_sprel (offset
)
1631 unsigned int offset
;
1633 unw_rec_list
*ptr
= alloc_record (rp_sprel
);
1634 ptr
->r
.record
.p
.spoff
= offset
/ 4;
1638 static unw_rec_list
*
1641 unw_rec_list
*ptr
= alloc_record (pfs_when
);
1645 static unw_rec_list
*
1649 unw_rec_list
*ptr
= alloc_record (pfs_gr
);
1650 ptr
->r
.record
.p
.gr
= gr
;
1654 static unw_rec_list
*
1655 output_pfs_psprel (offset
)
1656 unsigned int offset
;
1658 unw_rec_list
*ptr
= alloc_record (pfs_psprel
);
1659 ptr
->r
.record
.p
.pspoff
= offset
/ 4;
1663 static unw_rec_list
*
1664 output_pfs_sprel (offset
)
1665 unsigned int offset
;
1667 unw_rec_list
*ptr
= alloc_record (pfs_sprel
);
1668 ptr
->r
.record
.p
.spoff
= offset
/ 4;
1672 static unw_rec_list
*
1673 output_preds_when ()
1675 unw_rec_list
*ptr
= alloc_record (preds_when
);
1679 static unw_rec_list
*
1680 output_preds_gr (gr
)
1683 unw_rec_list
*ptr
= alloc_record (preds_gr
);
1684 ptr
->r
.record
.p
.gr
= gr
;
1688 static unw_rec_list
*
1689 output_preds_psprel (offset
)
1690 unsigned int offset
;
1692 unw_rec_list
*ptr
= alloc_record (preds_psprel
);
1693 ptr
->r
.record
.p
.pspoff
= offset
/ 4;
1697 static unw_rec_list
*
1698 output_preds_sprel (offset
)
1699 unsigned int offset
;
1701 unw_rec_list
*ptr
= alloc_record (preds_sprel
);
1702 ptr
->r
.record
.p
.spoff
= offset
/ 4;
1706 static unw_rec_list
*
1707 output_fr_mem (mask
)
1710 unw_rec_list
*ptr
= alloc_record (fr_mem
);
1711 ptr
->r
.record
.p
.rmask
= mask
;
1715 static unw_rec_list
*
1716 output_frgr_mem (gr_mask
, fr_mask
)
1717 unsigned int gr_mask
;
1718 unsigned int fr_mask
;
1720 unw_rec_list
*ptr
= alloc_record (frgr_mem
);
1721 ptr
->r
.record
.p
.grmask
= gr_mask
;
1722 ptr
->r
.record
.p
.frmask
= fr_mask
;
1726 static unw_rec_list
*
1727 output_gr_gr (mask
, reg
)
1731 unw_rec_list
*ptr
= alloc_record (gr_gr
);
1732 ptr
->r
.record
.p
.grmask
= mask
;
1733 ptr
->r
.record
.p
.gr
= reg
;
1737 static unw_rec_list
*
1738 output_gr_mem (mask
)
1741 unw_rec_list
*ptr
= alloc_record (gr_mem
);
1742 ptr
->r
.record
.p
.rmask
= mask
;
1746 static unw_rec_list
*
1747 output_br_mem (unsigned int mask
)
1749 unw_rec_list
*ptr
= alloc_record (br_mem
);
1750 ptr
->r
.record
.p
.brmask
= mask
;
1754 static unw_rec_list
*
1755 output_br_gr (save_mask
, reg
)
1756 unsigned int save_mask
;
1759 unw_rec_list
*ptr
= alloc_record (br_gr
);
1760 ptr
->r
.record
.p
.brmask
= save_mask
;
1761 ptr
->r
.record
.p
.gr
= reg
;
1765 static unw_rec_list
*
1766 output_spill_base (offset
)
1767 unsigned int offset
;
1769 unw_rec_list
*ptr
= alloc_record (spill_base
);
1770 ptr
->r
.record
.p
.pspoff
= offset
/ 4;
1774 static unw_rec_list
*
1777 unw_rec_list
*ptr
= alloc_record (unat_when
);
1781 static unw_rec_list
*
1785 unw_rec_list
*ptr
= alloc_record (unat_gr
);
1786 ptr
->r
.record
.p
.gr
= gr
;
1790 static unw_rec_list
*
1791 output_unat_psprel (offset
)
1792 unsigned int offset
;
1794 unw_rec_list
*ptr
= alloc_record (unat_psprel
);
1795 ptr
->r
.record
.p
.pspoff
= offset
/ 4;
1799 static unw_rec_list
*
1800 output_unat_sprel (offset
)
1801 unsigned int offset
;
1803 unw_rec_list
*ptr
= alloc_record (unat_sprel
);
1804 ptr
->r
.record
.p
.spoff
= offset
/ 4;
1808 static unw_rec_list
*
1811 unw_rec_list
*ptr
= alloc_record (lc_when
);
1815 static unw_rec_list
*
1819 unw_rec_list
*ptr
= alloc_record (lc_gr
);
1820 ptr
->r
.record
.p
.gr
= gr
;
1824 static unw_rec_list
*
1825 output_lc_psprel (offset
)
1826 unsigned int offset
;
1828 unw_rec_list
*ptr
= alloc_record (lc_psprel
);
1829 ptr
->r
.record
.p
.pspoff
= offset
/ 4;
1833 static unw_rec_list
*
1834 output_lc_sprel (offset
)
1835 unsigned int offset
;
1837 unw_rec_list
*ptr
= alloc_record (lc_sprel
);
1838 ptr
->r
.record
.p
.spoff
= offset
/ 4;
1842 static unw_rec_list
*
1845 unw_rec_list
*ptr
= alloc_record (fpsr_when
);
1849 static unw_rec_list
*
1853 unw_rec_list
*ptr
= alloc_record (fpsr_gr
);
1854 ptr
->r
.record
.p
.gr
= gr
;
1858 static unw_rec_list
*
1859 output_fpsr_psprel (offset
)
1860 unsigned int offset
;
1862 unw_rec_list
*ptr
= alloc_record (fpsr_psprel
);
1863 ptr
->r
.record
.p
.pspoff
= offset
/ 4;
1867 static unw_rec_list
*
1868 output_fpsr_sprel (offset
)
1869 unsigned int offset
;
1871 unw_rec_list
*ptr
= alloc_record (fpsr_sprel
);
1872 ptr
->r
.record
.p
.spoff
= offset
/ 4;
1876 static unw_rec_list
*
1877 output_priunat_when_gr ()
1879 unw_rec_list
*ptr
= alloc_record (priunat_when_gr
);
1883 static unw_rec_list
*
1884 output_priunat_when_mem ()
1886 unw_rec_list
*ptr
= alloc_record (priunat_when_mem
);
1890 static unw_rec_list
*
1891 output_priunat_gr (gr
)
1894 unw_rec_list
*ptr
= alloc_record (priunat_gr
);
1895 ptr
->r
.record
.p
.gr
= gr
;
1899 static unw_rec_list
*
1900 output_priunat_psprel (offset
)
1901 unsigned int offset
;
1903 unw_rec_list
*ptr
= alloc_record (priunat_psprel
);
1904 ptr
->r
.record
.p
.pspoff
= offset
/ 4;
1908 static unw_rec_list
*
1909 output_priunat_sprel (offset
)
1910 unsigned int offset
;
1912 unw_rec_list
*ptr
= alloc_record (priunat_sprel
);
1913 ptr
->r
.record
.p
.spoff
= offset
/ 4;
1917 static unw_rec_list
*
1920 unw_rec_list
*ptr
= alloc_record (bsp_when
);
1924 static unw_rec_list
*
1928 unw_rec_list
*ptr
= alloc_record (bsp_gr
);
1929 ptr
->r
.record
.p
.gr
= gr
;
1933 static unw_rec_list
*
1934 output_bsp_psprel (offset
)
1935 unsigned int offset
;
1937 unw_rec_list
*ptr
= alloc_record (bsp_psprel
);
1938 ptr
->r
.record
.p
.pspoff
= offset
/ 4;
1942 static unw_rec_list
*
1943 output_bsp_sprel (offset
)
1944 unsigned int offset
;
1946 unw_rec_list
*ptr
= alloc_record (bsp_sprel
);
1947 ptr
->r
.record
.p
.spoff
= offset
/ 4;
1951 static unw_rec_list
*
1952 output_bspstore_when ()
1954 unw_rec_list
*ptr
= alloc_record (bspstore_when
);
1958 static unw_rec_list
*
1959 output_bspstore_gr (gr
)
1962 unw_rec_list
*ptr
= alloc_record (bspstore_gr
);
1963 ptr
->r
.record
.p
.gr
= gr
;
1967 static unw_rec_list
*
1968 output_bspstore_psprel (offset
)
1969 unsigned int offset
;
1971 unw_rec_list
*ptr
= alloc_record (bspstore_psprel
);
1972 ptr
->r
.record
.p
.pspoff
= offset
/ 4;
1976 static unw_rec_list
*
1977 output_bspstore_sprel (offset
)
1978 unsigned int offset
;
1980 unw_rec_list
*ptr
= alloc_record (bspstore_sprel
);
1981 ptr
->r
.record
.p
.spoff
= offset
/ 4;
1985 static unw_rec_list
*
1988 unw_rec_list
*ptr
= alloc_record (rnat_when
);
1992 static unw_rec_list
*
1996 unw_rec_list
*ptr
= alloc_record (rnat_gr
);
1997 ptr
->r
.record
.p
.gr
= gr
;
2001 static unw_rec_list
*
2002 output_rnat_psprel (offset
)
2003 unsigned int offset
;
2005 unw_rec_list
*ptr
= alloc_record (rnat_psprel
);
2006 ptr
->r
.record
.p
.pspoff
= offset
/ 4;
2010 static unw_rec_list
*
2011 output_rnat_sprel (offset
)
2012 unsigned int offset
;
2014 unw_rec_list
*ptr
= alloc_record (rnat_sprel
);
2015 ptr
->r
.record
.p
.spoff
= offset
/ 4;
2019 static unw_rec_list
*
2020 output_unwabi (abi
, context
)
2022 unsigned long context
;
2024 unw_rec_list
*ptr
= alloc_record (unwabi
);
2025 ptr
->r
.record
.p
.abi
= abi
;
2026 ptr
->r
.record
.p
.context
= context
;
2030 static unw_rec_list
*
2031 output_epilogue (unsigned long ecount
)
2033 unw_rec_list
*ptr
= alloc_record (epilogue
);
2034 ptr
->r
.record
.b
.ecount
= ecount
;
2038 static unw_rec_list
*
2039 output_label_state (unsigned long label
)
2041 unw_rec_list
*ptr
= alloc_record (label_state
);
2042 ptr
->r
.record
.b
.label
= label
;
2046 static unw_rec_list
*
2047 output_copy_state (unsigned long label
)
2049 unw_rec_list
*ptr
= alloc_record (copy_state
);
2050 ptr
->r
.record
.b
.label
= label
;
2054 static unw_rec_list
*
2055 output_spill_psprel (ab
, reg
, offset
)
2058 unsigned int offset
;
2060 unw_rec_list
*ptr
= alloc_record (spill_psprel
);
2061 ptr
->r
.record
.x
.ab
= ab
;
2062 ptr
->r
.record
.x
.reg
= reg
;
2063 ptr
->r
.record
.x
.pspoff
= offset
/ 4;
2067 static unw_rec_list
*
2068 output_spill_sprel (ab
, reg
, offset
)
2071 unsigned int offset
;
2073 unw_rec_list
*ptr
= alloc_record (spill_sprel
);
2074 ptr
->r
.record
.x
.ab
= ab
;
2075 ptr
->r
.record
.x
.reg
= reg
;
2076 ptr
->r
.record
.x
.spoff
= offset
/ 4;
2080 static unw_rec_list
*
2081 output_spill_psprel_p (ab
, reg
, offset
, predicate
)
2084 unsigned int offset
;
2085 unsigned int predicate
;
2087 unw_rec_list
*ptr
= alloc_record (spill_psprel_p
);
2088 ptr
->r
.record
.x
.ab
= ab
;
2089 ptr
->r
.record
.x
.reg
= reg
;
2090 ptr
->r
.record
.x
.pspoff
= offset
/ 4;
2091 ptr
->r
.record
.x
.qp
= predicate
;
2095 static unw_rec_list
*
2096 output_spill_sprel_p (ab
, reg
, offset
, predicate
)
2099 unsigned int offset
;
2100 unsigned int predicate
;
2102 unw_rec_list
*ptr
= alloc_record (spill_sprel_p
);
2103 ptr
->r
.record
.x
.ab
= ab
;
2104 ptr
->r
.record
.x
.reg
= reg
;
2105 ptr
->r
.record
.x
.spoff
= offset
/ 4;
2106 ptr
->r
.record
.x
.qp
= predicate
;
2110 static unw_rec_list
*
2111 output_spill_reg (ab
, reg
, targ_reg
, xy
)
2114 unsigned int targ_reg
;
2117 unw_rec_list
*ptr
= alloc_record (spill_reg
);
2118 ptr
->r
.record
.x
.ab
= ab
;
2119 ptr
->r
.record
.x
.reg
= reg
;
2120 ptr
->r
.record
.x
.treg
= targ_reg
;
2121 ptr
->r
.record
.x
.xy
= xy
;
2125 static unw_rec_list
*
2126 output_spill_reg_p (ab
, reg
, targ_reg
, xy
, predicate
)
2129 unsigned int targ_reg
;
2131 unsigned int predicate
;
2133 unw_rec_list
*ptr
= alloc_record (spill_reg_p
);
2134 ptr
->r
.record
.x
.ab
= ab
;
2135 ptr
->r
.record
.x
.reg
= reg
;
2136 ptr
->r
.record
.x
.treg
= targ_reg
;
2137 ptr
->r
.record
.x
.xy
= xy
;
2138 ptr
->r
.record
.x
.qp
= predicate
;
2142 /* Given a unw_rec_list process the correct format with the
2143 specified function. */
2146 process_one_record (ptr
, f
)
2150 unsigned long fr_mask
, gr_mask
;
2152 switch (ptr
->r
.type
)
2158 /* These are taken care of by prologue/prologue_gr. */
2163 if (ptr
->r
.type
== prologue_gr
)
2164 output_R2_format (f
, ptr
->r
.record
.r
.grmask
,
2165 ptr
->r
.record
.r
.grsave
, ptr
->r
.record
.r
.rlen
);
2167 output_R1_format (f
, ptr
->r
.type
, ptr
->r
.record
.r
.rlen
);
2169 /* Output descriptor(s) for union of register spills (if any). */
2170 gr_mask
= ptr
->r
.record
.r
.mask
.gr_mem
;
2171 fr_mask
= ptr
->r
.record
.r
.mask
.fr_mem
;
2174 if ((fr_mask
& ~0xfUL
) == 0)
2175 output_P6_format (f
, fr_mem
, fr_mask
);
2178 output_P5_format (f
, gr_mask
, fr_mask
);
2183 output_P6_format (f
, gr_mem
, gr_mask
);
2184 if (ptr
->r
.record
.r
.mask
.br_mem
)
2185 output_P1_format (f
, ptr
->r
.record
.r
.mask
.br_mem
);
2187 /* output imask descriptor if necessary: */
2188 if (ptr
->r
.record
.r
.mask
.i
)
2189 output_P4_format (f
, ptr
->r
.record
.r
.mask
.i
,
2190 ptr
->r
.record
.r
.imask_size
);
2194 output_R1_format (f
, ptr
->r
.type
, ptr
->r
.record
.r
.rlen
);
2198 output_P7_format (f
, ptr
->r
.type
, ptr
->r
.record
.p
.t
,
2199 ptr
->r
.record
.p
.size
);
2212 output_P3_format (f
, ptr
->r
.type
, ptr
->r
.record
.p
.gr
);
2215 output_P3_format (f
, rp_br
, ptr
->r
.record
.p
.br
);
2218 output_P7_format (f
, psp_sprel
, ptr
->r
.record
.p
.spoff
, 0);
2226 output_P7_format (f
, ptr
->r
.type
, ptr
->r
.record
.p
.t
, 0);
2235 output_P7_format (f
, ptr
->r
.type
, ptr
->r
.record
.p
.pspoff
, 0);
2245 case bspstore_sprel
:
2247 output_P8_format (f
, ptr
->r
.type
, ptr
->r
.record
.p
.spoff
);
2250 output_P9_format (f
, ptr
->r
.record
.p
.grmask
, ptr
->r
.record
.p
.gr
);
2253 output_P2_format (f
, ptr
->r
.record
.p
.brmask
, ptr
->r
.record
.p
.gr
);
2256 as_bad ("spill_mask record unimplemented.");
2258 case priunat_when_gr
:
2259 case priunat_when_mem
:
2263 output_P8_format (f
, ptr
->r
.type
, ptr
->r
.record
.p
.t
);
2265 case priunat_psprel
:
2267 case bspstore_psprel
:
2269 output_P8_format (f
, ptr
->r
.type
, ptr
->r
.record
.p
.pspoff
);
2272 output_P10_format (f
, ptr
->r
.record
.p
.abi
, ptr
->r
.record
.p
.context
);
2275 output_B3_format (f
, ptr
->r
.record
.b
.ecount
, ptr
->r
.record
.b
.t
);
2279 output_B4_format (f
, ptr
->r
.type
, ptr
->r
.record
.b
.label
);
2282 output_X1_format (f
, ptr
->r
.type
, ptr
->r
.record
.x
.ab
,
2283 ptr
->r
.record
.x
.reg
, ptr
->r
.record
.x
.t
,
2284 ptr
->r
.record
.x
.pspoff
);
2287 output_X1_format (f
, ptr
->r
.type
, ptr
->r
.record
.x
.ab
,
2288 ptr
->r
.record
.x
.reg
, ptr
->r
.record
.x
.t
,
2289 ptr
->r
.record
.x
.spoff
);
2292 output_X2_format (f
, ptr
->r
.record
.x
.ab
, ptr
->r
.record
.x
.reg
,
2293 ptr
->r
.record
.x
.xy
>> 1, ptr
->r
.record
.x
.xy
,
2294 ptr
->r
.record
.x
.treg
, ptr
->r
.record
.x
.t
);
2296 case spill_psprel_p
:
2297 output_X3_format (f
, ptr
->r
.type
, ptr
->r
.record
.x
.qp
,
2298 ptr
->r
.record
.x
.ab
, ptr
->r
.record
.x
.reg
,
2299 ptr
->r
.record
.x
.t
, ptr
->r
.record
.x
.pspoff
);
2302 output_X3_format (f
, ptr
->r
.type
, ptr
->r
.record
.x
.qp
,
2303 ptr
->r
.record
.x
.ab
, ptr
->r
.record
.x
.reg
,
2304 ptr
->r
.record
.x
.t
, ptr
->r
.record
.x
.spoff
);
2307 output_X4_format (f
, ptr
->r
.record
.x
.qp
, ptr
->r
.record
.x
.ab
,
2308 ptr
->r
.record
.x
.reg
, ptr
->r
.record
.x
.xy
>> 1,
2309 ptr
->r
.record
.x
.xy
, ptr
->r
.record
.x
.treg
,
2313 as_bad ("record_type_not_valid");
2318 /* Given a unw_rec_list list, process all the records with
2319 the specified function. */
2321 process_unw_records (list
, f
)
2326 for (ptr
= list
; ptr
; ptr
= ptr
->next
)
2327 process_one_record (ptr
, f
);
2330 /* Determine the size of a record list in bytes. */
2332 calc_record_size (list
)
2336 process_unw_records (list
, count_output
);
2340 /* Update IMASK bitmask to reflect the fact that one or more registers
2341 of type TYPE are saved starting at instruction with index T. If N
2342 bits are set in REGMASK, it is assumed that instructions T through
2343 T+N-1 save these registers.
2347 1: instruction saves next fp reg
2348 2: instruction saves next general reg
2349 3: instruction saves next branch reg */
2351 set_imask (region
, regmask
, t
, type
)
2352 unw_rec_list
*region
;
2353 unsigned long regmask
;
2357 unsigned char *imask
;
2358 unsigned long imask_size
;
2362 imask
= region
->r
.record
.r
.mask
.i
;
2363 imask_size
= region
->r
.record
.r
.imask_size
;
2366 imask_size
= (region
->r
.record
.r
.rlen
* 2 + 7) / 8 + 1;
2367 imask
= xmalloc (imask_size
);
2368 memset (imask
, 0, imask_size
);
2370 region
->r
.record
.r
.imask_size
= imask_size
;
2371 region
->r
.record
.r
.mask
.i
= imask
;
2375 pos
= 2 * (3 - t
% 4);
2378 if (i
>= imask_size
)
2380 as_bad ("Ignoring attempt to spill beyond end of region");
2384 imask
[i
] |= (type
& 0x3) << pos
;
2386 regmask
&= (regmask
- 1);
2397 count_bits (unsigned long mask
)
2410 slot_index (unsigned long slot_addr
, unsigned long first_addr
)
2412 return (3 * ((slot_addr
>> 4) - (first_addr
>> 4))
2413 + ((slot_addr
& 0x3) - (first_addr
& 0x3)));
2416 /* Given a complete record list, process any records which have
2417 unresolved fields, (ie length counts for a prologue). After
2418 this has been run, all neccessary information should be available
2419 within each record to generate an image. */
2422 fixup_unw_records (list
)
2425 unw_rec_list
*ptr
, *region
= 0;
2426 unsigned long first_addr
= 0, rlen
= 0, t
;
2428 for (ptr
= list
; ptr
; ptr
= ptr
->next
)
2430 if (ptr
->slot_number
== SLOT_NUM_NOT_SET
)
2431 as_bad (" Insn slot not set in unwind record.");
2432 t
= slot_index (ptr
->slot_number
, first_addr
);
2433 switch (ptr
->r
.type
)
2440 int size
, dir_len
= 0;
2441 unsigned long last_addr
;
2443 first_addr
= ptr
->slot_number
;
2444 ptr
->slot_number
= 0;
2445 /* Find either the next body/prologue start, or the end of
2446 the list, and determine the size of the region. */
2447 last_addr
= unwind
.next_slot_number
;
2448 for (last
= ptr
->next
; last
!= NULL
; last
= last
->next
)
2449 if (last
->r
.type
== prologue
|| last
->r
.type
== prologue_gr
2450 || last
->r
.type
== body
)
2452 last_addr
= last
->slot_number
;
2455 else if (!last
->next
)
2457 /* In the absence of an explicit .body directive,
2458 the prologue ends after the last instruction
2459 covered by an unwind directive. */
2460 if (ptr
->r
.type
!= body
)
2462 last_addr
= last
->slot_number
;
2463 switch (last
->r
.type
)
2466 dir_len
= (count_bits (last
->r
.record
.p
.frmask
)
2467 + count_bits (last
->r
.record
.p
.grmask
));
2471 dir_len
+= count_bits (last
->r
.record
.p
.rmask
);
2475 dir_len
+= count_bits (last
->r
.record
.p
.brmask
);
2478 dir_len
+= count_bits (last
->r
.record
.p
.grmask
);
2487 size
= slot_index (last_addr
, first_addr
) + dir_len
;
2488 rlen
= ptr
->r
.record
.r
.rlen
= size
;
2493 ptr
->r
.record
.b
.t
= rlen
- 1 - t
;
2504 case priunat_when_gr
:
2505 case priunat_when_mem
:
2509 ptr
->r
.record
.p
.t
= t
;
2517 case spill_psprel_p
:
2518 ptr
->r
.record
.x
.t
= t
;
2524 as_bad ("frgr_mem record before region record!\n");
2527 region
->r
.record
.r
.mask
.fr_mem
|= ptr
->r
.record
.p
.frmask
;
2528 region
->r
.record
.r
.mask
.gr_mem
|= ptr
->r
.record
.p
.grmask
;
2529 set_imask (region
, ptr
->r
.record
.p
.frmask
, t
, 1);
2530 set_imask (region
, ptr
->r
.record
.p
.grmask
, t
, 2);
2535 as_bad ("fr_mem record before region record!\n");
2538 region
->r
.record
.r
.mask
.fr_mem
|= ptr
->r
.record
.p
.rmask
;
2539 set_imask (region
, ptr
->r
.record
.p
.rmask
, t
, 1);
2544 as_bad ("gr_mem record before region record!\n");
2547 region
->r
.record
.r
.mask
.gr_mem
|= ptr
->r
.record
.p
.rmask
;
2548 set_imask (region
, ptr
->r
.record
.p
.rmask
, t
, 2);
2553 as_bad ("br_mem record before region record!\n");
2556 region
->r
.record
.r
.mask
.br_mem
|= ptr
->r
.record
.p
.brmask
;
2557 set_imask (region
, ptr
->r
.record
.p
.brmask
, t
, 3);
2563 as_bad ("gr_gr record before region record!\n");
2566 set_imask (region
, ptr
->r
.record
.p
.grmask
, t
, 2);
2571 as_bad ("br_gr record before region record!\n");
2574 set_imask (region
, ptr
->r
.record
.p
.brmask
, t
, 3);
2583 /* Generate an unwind image from a record list. Returns the number of
2584 bytes in the resulting image. The memory image itselof is returned
2585 in the 'ptr' parameter. */
2587 output_unw_records (list
, ptr
)
2591 int size
, x
, extra
= 0;
2594 fixup_unw_records (list
);
2595 size
= calc_record_size (list
);
2597 /* pad to 8 byte boundry. */
2601 /* Add 8 for the header + 8 more bytes for the personality offset. */
2602 mem
= xmalloc (size
+ extra
+ 16);
2604 vbyte_mem_ptr
= mem
+ 8;
2605 /* Clear the padding area and personality. */
2606 memset (mem
+ 8 + size
, 0 , extra
+ 8);
2607 /* Initialize the header area. */
2608 md_number_to_chars (mem
, (((bfd_vma
) 1 << 48) /* version */
2609 | (unwind
.personality_routine
2610 ? ((bfd_vma
) 3 << 32) /* U & E handler flags */
2612 | ((size
+ extra
) / 8)), /* length (dwords) */
2615 process_unw_records (list
, output_vbyte_mem
);
2618 return size
+ extra
+ 16;
2622 convert_expr_to_ab_reg (e
, ab
, regp
)
2629 if (e
->X_op
!= O_register
)
2632 reg
= e
->X_add_number
;
2633 if (reg
>= REG_GR
+ 4 && reg
<= REG_GR
+ 7)
2636 *regp
= reg
- REG_GR
;
2638 else if ((reg
>= REG_FR
+ 2 && reg
<= REG_FR
+ 5)
2639 || (reg
>= REG_FR
+ 16 && reg
<= REG_FR
+ 31))
2642 *regp
= reg
- REG_FR
;
2644 else if (reg
>= REG_BR
+ 1 && reg
<= REG_BR
+ 5)
2647 *regp
= reg
- REG_BR
;
2654 case REG_PR
: *regp
= 0; break;
2655 case REG_PSP
: *regp
= 1; break;
2656 case REG_PRIUNAT
: *regp
= 2; break;
2657 case REG_BR
+ 0: *regp
= 3; break;
2658 case REG_AR
+ AR_BSP
: *regp
= 4; break;
2659 case REG_AR
+ AR_BSPSTORE
: *regp
= 5; break;
2660 case REG_AR
+ AR_RNAT
: *regp
= 6; break;
2661 case REG_AR
+ AR_UNAT
: *regp
= 7; break;
2662 case REG_AR
+ AR_FPSR
: *regp
= 8; break;
2663 case REG_AR
+ AR_PFS
: *regp
= 9; break;
2664 case REG_AR
+ AR_LC
: *regp
= 10; break;
2674 convert_expr_to_xy_reg (e
, xy
, regp
)
2681 if (e
->X_op
!= O_register
)
2684 reg
= e
->X_add_number
;
2686 if (reg
>= REG_GR
&& reg
<= REG_GR
+ 127)
2689 *regp
= reg
- REG_GR
;
2691 else if (reg
>= REG_FR
&& reg
<= REG_FR
+ 127)
2694 *regp
= reg
- REG_FR
;
2696 else if (reg
>= REG_BR
&& reg
<= REG_BR
+ 7)
2699 *regp
= reg
- REG_BR
;
2713 radix
= *input_line_pointer
++;
2715 if (radix
!= 'C' && !is_end_of_line
[(unsigned char) radix
])
2717 as_bad ("Radix `%c' unsupported", *input_line_pointer
);
2718 ignore_rest_of_line ();
2723 /* .sbss, .bss etc. are macros that expand into ".section SECNAME". */
2725 dot_special_section (which
)
2728 set_section ((char *) special_section_name
[which
]);
2732 add_unwind_entry (ptr
)
2736 unwind
.tail
->next
= ptr
;
2741 /* The current entry can in fact be a chain of unwind entries. */
2742 if (unwind
.current_entry
== NULL
)
2743 unwind
.current_entry
= ptr
;
2754 if (e
.X_op
!= O_constant
)
2755 as_bad ("Operand to .fframe must be a constant");
2757 add_unwind_entry (output_mem_stack_f (e
.X_add_number
));
2768 reg
= e
.X_add_number
- REG_GR
;
2769 if (e
.X_op
== O_register
&& reg
< 128)
2771 add_unwind_entry (output_mem_stack_v ());
2772 if (! (unwind
.prologue_mask
& 2))
2773 add_unwind_entry (output_psp_gr (reg
));
2776 as_bad ("First operand to .vframe must be a general register");
2780 dot_vframesp (dummy
)
2786 if (e
.X_op
== O_constant
)
2788 add_unwind_entry (output_mem_stack_v ());
2789 add_unwind_entry (output_psp_sprel (e
.X_add_number
));
2792 as_bad ("First operand to .vframesp must be a general register");
2796 dot_vframepsp (dummy
)
2802 if (e
.X_op
== O_constant
)
2804 add_unwind_entry (output_mem_stack_v ());
2805 add_unwind_entry (output_psp_sprel (e
.X_add_number
));
2808 as_bad ("First operand to .vframepsp must be a general register");
2819 sep
= parse_operand (&e1
);
2821 as_bad ("No second operand to .save");
2822 sep
= parse_operand (&e2
);
2824 reg1
= e1
.X_add_number
;
2825 reg2
= e2
.X_add_number
- REG_GR
;
2827 /* Make sure its a valid ar.xxx reg, OR its br0, aka 'rp'. */
2828 if (e1
.X_op
== O_register
)
2830 if (e2
.X_op
== O_register
&& reg2
>= 0 && reg2
< 128)
2834 case REG_AR
+ AR_BSP
:
2835 add_unwind_entry (output_bsp_when ());
2836 add_unwind_entry (output_bsp_gr (reg2
));
2838 case REG_AR
+ AR_BSPSTORE
:
2839 add_unwind_entry (output_bspstore_when ());
2840 add_unwind_entry (output_bspstore_gr (reg2
));
2842 case REG_AR
+ AR_RNAT
:
2843 add_unwind_entry (output_rnat_when ());
2844 add_unwind_entry (output_rnat_gr (reg2
));
2846 case REG_AR
+ AR_UNAT
:
2847 add_unwind_entry (output_unat_when ());
2848 add_unwind_entry (output_unat_gr (reg2
));
2850 case REG_AR
+ AR_FPSR
:
2851 add_unwind_entry (output_fpsr_when ());
2852 add_unwind_entry (output_fpsr_gr (reg2
));
2854 case REG_AR
+ AR_PFS
:
2855 add_unwind_entry (output_pfs_when ());
2856 if (! (unwind
.prologue_mask
& 4))
2857 add_unwind_entry (output_pfs_gr (reg2
));
2859 case REG_AR
+ AR_LC
:
2860 add_unwind_entry (output_lc_when ());
2861 add_unwind_entry (output_lc_gr (reg2
));
2864 add_unwind_entry (output_rp_when ());
2865 if (! (unwind
.prologue_mask
& 8))
2866 add_unwind_entry (output_rp_gr (reg2
));
2869 add_unwind_entry (output_preds_when ());
2870 if (! (unwind
.prologue_mask
& 1))
2871 add_unwind_entry (output_preds_gr (reg2
));
2874 add_unwind_entry (output_priunat_when_gr ());
2875 add_unwind_entry (output_priunat_gr (reg2
));
2878 as_bad ("First operand not a valid register");
2882 as_bad (" Second operand not a valid register");
2885 as_bad ("First operand not a register");
2893 unsigned long ecount
= 0;
2896 sep
= parse_operand (&e1
);
2897 if (e1
.X_op
!= O_register
|| e1
.X_add_number
!= REG_GR
+ 12)
2899 as_bad ("First operand to .restore must be stack pointer (sp)");
2905 parse_operand (&e2
);
2906 if (e1
.X_op
!= O_constant
)
2908 as_bad ("Second operand to .restore must be constant");
2913 add_unwind_entry (output_epilogue (ecount
));
2917 dot_restorereg (dummy
)
2920 unsigned int ab
, reg
;
2925 if (!convert_expr_to_ab_reg (&e
, &ab
, ®
))
2927 as_bad ("First operand to .restorereg must be a preserved register");
2930 add_unwind_entry (output_spill_reg (ab
, reg
, 0, 0));
2934 dot_restorereg_p (dummy
)
2937 unsigned int qp
, ab
, reg
;
2941 sep
= parse_operand (&e1
);
2944 as_bad ("No second operand to .restorereg.p");
2948 parse_operand (&e2
);
2950 qp
= e1
.X_add_number
- REG_P
;
2951 if (e1
.X_op
!= O_register
|| qp
> 63)
2953 as_bad ("First operand to .restorereg.p must be a predicate");
2957 if (!convert_expr_to_ab_reg (&e2
, &ab
, ®
))
2959 as_bad ("Second operand to .restorereg.p must be a preserved register");
2962 add_unwind_entry (output_spill_reg_p (ab
, reg
, 0, 0, qp
));
2966 generate_unwind_image ()
2969 unsigned char *unw_rec
;
2971 /* Force out pending instructions, to make sure all unwind records have
2972 a valid slot_number field. */
2973 ia64_flush_insns ();
2975 /* Generate the unwind record. */
2976 size
= output_unw_records (unwind
.list
, (void **) &unw_rec
);
2978 as_bad ("Unwind record is not a multiple of 8 bytes.");
2980 /* If there are unwind records, switch sections, and output the info. */
2983 unsigned char *where
;
2985 set_section ((char *) special_section_name
[SPECIAL_SECTION_UNWIND_INFO
]);
2987 /* Set expression which points to start of unwind descriptor area. */
2988 unwind
.info
= expr_build_dot ();
2990 where
= (unsigned char *) frag_more (size
);
2992 /* Issue a label for this address, and keep track of it to put it
2993 in the unwind section. */
2995 /* Copy the information from the unwind record into this section. The
2996 data is already in the correct byte order. */
2997 memcpy (where
, unw_rec
, size
);
2998 /* Add the personality address to the image. */
2999 if (unwind
.personality_routine
!= 0)
3001 exp
.X_op
= O_symbol
;
3002 exp
.X_add_symbol
= unwind
.personality_routine
;
3003 exp
.X_add_number
= 0;
3004 fix_new_exp (frag_now
, frag_now_fix () - 8, 8,
3005 &exp
, 0, BFD_RELOC_IA64_LTOFF_FPTR64LSB
);
3006 unwind
.personality_routine
= 0;
3008 obj_elf_previous (0);
3011 free_list_records (unwind
.list
);
3012 unwind
.list
= unwind
.tail
= unwind
.current_entry
= NULL
;
3018 dot_handlerdata (dummy
)
3021 generate_unwind_image ();
3022 demand_empty_rest_of_line ();
3026 dot_unwentry (dummy
)
3029 demand_empty_rest_of_line ();
3040 reg
= e
.X_add_number
- REG_BR
;
3041 if (e
.X_op
== O_register
&& reg
< 8)
3042 add_unwind_entry (output_rp_br (reg
));
3044 as_bad ("First operand not a valid branch register");
3048 dot_savemem (psprel
)
3055 sep
= parse_operand (&e1
);
3057 as_bad ("No second operand to .save%ssp", psprel
? "p" : "");
3058 sep
= parse_operand (&e2
);
3060 reg1
= e1
.X_add_number
;
3061 val
= e2
.X_add_number
;
3063 /* Make sure its a valid ar.xxx reg, OR its br0, aka 'rp'. */
3064 if (e1
.X_op
== O_register
)
3066 if (e2
.X_op
== O_constant
)
3070 case REG_AR
+ AR_BSP
:
3071 add_unwind_entry (output_bsp_when ());
3072 add_unwind_entry ((psprel
3074 : output_bsp_sprel
) (val
));
3076 case REG_AR
+ AR_BSPSTORE
:
3077 add_unwind_entry (output_bspstore_when ());
3078 add_unwind_entry ((psprel
3079 ? output_bspstore_psprel
3080 : output_bspstore_sprel
) (val
));
3082 case REG_AR
+ AR_RNAT
:
3083 add_unwind_entry (output_rnat_when ());
3084 add_unwind_entry ((psprel
3085 ? output_rnat_psprel
3086 : output_rnat_sprel
) (val
));
3088 case REG_AR
+ AR_UNAT
:
3089 add_unwind_entry (output_unat_when ());
3090 add_unwind_entry ((psprel
3091 ? output_unat_psprel
3092 : output_unat_sprel
) (val
));
3094 case REG_AR
+ AR_FPSR
:
3095 add_unwind_entry (output_fpsr_when ());
3096 add_unwind_entry ((psprel
3097 ? output_fpsr_psprel
3098 : output_fpsr_sprel
) (val
));
3100 case REG_AR
+ AR_PFS
:
3101 add_unwind_entry (output_pfs_when ());
3102 add_unwind_entry ((psprel
3104 : output_pfs_sprel
) (val
));
3106 case REG_AR
+ AR_LC
:
3107 add_unwind_entry (output_lc_when ());
3108 add_unwind_entry ((psprel
3110 : output_lc_sprel
) (val
));
3113 add_unwind_entry (output_rp_when ());
3114 add_unwind_entry ((psprel
3116 : output_rp_sprel
) (val
));
3119 add_unwind_entry (output_preds_when ());
3120 add_unwind_entry ((psprel
3121 ? output_preds_psprel
3122 : output_preds_sprel
) (val
));
3125 add_unwind_entry (output_priunat_when_mem ());
3126 add_unwind_entry ((psprel
3127 ? output_priunat_psprel
3128 : output_priunat_sprel
) (val
));
3131 as_bad ("First operand not a valid register");
3135 as_bad (" Second operand not a valid constant");
3138 as_bad ("First operand not a register");
3147 sep
= parse_operand (&e1
);
3149 parse_operand (&e2
);
3151 if (e1
.X_op
!= O_constant
)
3152 as_bad ("First operand to .save.g must be a constant.");
3155 int grmask
= e1
.X_add_number
;
3157 add_unwind_entry (output_gr_mem (grmask
));
3160 int reg
= e2
.X_add_number
- REG_GR
;
3161 if (e2
.X_op
== O_register
&& reg
>= 0 && reg
< 128)
3162 add_unwind_entry (output_gr_gr (grmask
, reg
));
3164 as_bad ("Second operand is an invalid register.");
3175 sep
= parse_operand (&e1
);
3177 if (e1
.X_op
!= O_constant
)
3178 as_bad ("Operand to .save.f must be a constant.");
3180 add_unwind_entry (output_fr_mem (e1
.X_add_number
));
3192 sep
= parse_operand (&e1
);
3193 if (e1
.X_op
!= O_constant
)
3195 as_bad ("First operand to .save.b must be a constant.");
3198 brmask
= e1
.X_add_number
;
3202 sep
= parse_operand (&e2
);
3203 reg
= e2
.X_add_number
- REG_GR
;
3204 if (e2
.X_op
!= O_register
|| reg
> 127)
3206 as_bad ("Second operand to .save.b must be a general register.");
3209 add_unwind_entry (output_br_gr (brmask
, e2
.X_add_number
));
3212 add_unwind_entry (output_br_mem (brmask
));
3214 if (!is_end_of_line
[sep
] && !is_it_end_of_statement ())
3215 ignore_rest_of_line ();
3224 sep
= parse_operand (&e1
);
3226 parse_operand (&e2
);
3228 if (e1
.X_op
!= O_constant
|| sep
!= ',' || e2
.X_op
!= O_constant
)
3229 as_bad ("Both operands of .save.gf must be constants.");
3232 int grmask
= e1
.X_add_number
;
3233 int frmask
= e2
.X_add_number
;
3234 add_unwind_entry (output_frgr_mem (grmask
, frmask
));
3245 sep
= parse_operand (&e
);
3246 if (!is_end_of_line
[sep
] && !is_it_end_of_statement ())
3247 ignore_rest_of_line ();
3249 if (e
.X_op
!= O_constant
)
3250 as_bad ("Operand to .spill must be a constant");
3252 add_unwind_entry (output_spill_base (e
.X_add_number
));
3256 dot_spillreg (dummy
)
3259 int sep
, ab
, xy
, reg
, treg
;
3262 sep
= parse_operand (&e1
);
3265 as_bad ("No second operand to .spillreg");
3269 parse_operand (&e2
);
3271 if (!convert_expr_to_ab_reg (&e1
, &ab
, ®
))
3273 as_bad ("First operand to .spillreg must be a preserved register");
3277 if (!convert_expr_to_xy_reg (&e2
, &xy
, &treg
))
3279 as_bad ("Second operand to .spillreg must be a register");
3283 add_unwind_entry (output_spill_reg (ab
, reg
, treg
, xy
));
3287 dot_spillmem (psprel
)
3293 sep
= parse_operand (&e1
);
3296 as_bad ("Second operand missing");
3300 parse_operand (&e2
);
3302 if (!convert_expr_to_ab_reg (&e1
, &ab
, ®
))
3304 as_bad ("First operand to .spill%s must be a preserved register",
3305 psprel
? "psp" : "sp");
3309 if (e2
.X_op
!= O_constant
)
3311 as_bad ("Second operand to .spill%s must be a constant",
3312 psprel
? "psp" : "sp");
3317 add_unwind_entry (output_spill_psprel (ab
, reg
, e2
.X_add_number
));
3319 add_unwind_entry (output_spill_sprel (ab
, reg
, e2
.X_add_number
));
3323 dot_spillreg_p (dummy
)
3326 int sep
, ab
, xy
, reg
, treg
;
3327 expressionS e1
, e2
, e3
;
3330 sep
= parse_operand (&e1
);
3333 as_bad ("No second and third operand to .spillreg.p");
3337 sep
= parse_operand (&e2
);
3340 as_bad ("No third operand to .spillreg.p");
3344 parse_operand (&e3
);
3346 qp
= e1
.X_add_number
- REG_P
;
3348 if (e1
.X_op
!= O_register
|| qp
> 63)
3350 as_bad ("First operand to .spillreg.p must be a predicate");
3354 if (!convert_expr_to_ab_reg (&e2
, &ab
, ®
))
3356 as_bad ("Second operand to .spillreg.p must be a preserved register");
3360 if (!convert_expr_to_xy_reg (&e3
, &xy
, &treg
))
3362 as_bad ("Third operand to .spillreg.p must be a register");
3366 add_unwind_entry (output_spill_reg_p (ab
, reg
, treg
, xy
, qp
));
3370 dot_spillmem_p (psprel
)
3373 expressionS e1
, e2
, e3
;
3377 sep
= parse_operand (&e1
);
3380 as_bad ("Second operand missing");
3384 parse_operand (&e2
);
3387 as_bad ("Second operand missing");
3391 parse_operand (&e3
);
3393 qp
= e1
.X_add_number
- REG_P
;
3394 if (e1
.X_op
!= O_register
|| qp
> 63)
3396 as_bad ("First operand to .spill%s_p must be a predicate",
3397 psprel
? "psp" : "sp");
3401 if (!convert_expr_to_ab_reg (&e2
, &ab
, ®
))
3403 as_bad ("Second operand to .spill%s_p must be a preserved register",
3404 psprel
? "psp" : "sp");
3408 if (e3
.X_op
!= O_constant
)
3410 as_bad ("Third operand to .spill%s_p must be a constant",
3411 psprel
? "psp" : "sp");
3416 add_unwind_entry (output_spill_psprel_p (qp
, ab
, reg
, e3
.X_add_number
));
3418 add_unwind_entry (output_spill_sprel_p (qp
, ab
, reg
, e3
.X_add_number
));
3422 dot_label_state (dummy
)
3428 if (e
.X_op
!= O_constant
)
3430 as_bad ("Operand to .label_state must be a constant");
3433 add_unwind_entry (output_label_state (e
.X_add_number
));
3437 dot_copy_state (dummy
)
3443 if (e
.X_op
!= O_constant
)
3445 as_bad ("Operand to .copy_state must be a constant");
3448 add_unwind_entry (output_copy_state (e
.X_add_number
));
3458 sep
= parse_operand (&e1
);
3461 as_bad ("Second operand to .unwabi missing");
3464 sep
= parse_operand (&e2
);
3465 if (!is_end_of_line
[sep
] && !is_it_end_of_statement ())
3466 ignore_rest_of_line ();
3468 if (e1
.X_op
!= O_constant
)
3470 as_bad ("First operand to .unwabi must be a constant");
3474 if (e2
.X_op
!= O_constant
)
3476 as_bad ("Second operand to .unwabi must be a constant");
3480 add_unwind_entry (output_unwabi (e1
.X_add_number
, e2
.X_add_number
));
3484 dot_personality (dummy
)
3489 name
= input_line_pointer
;
3490 c
= get_symbol_end ();
3491 p
= input_line_pointer
;
3492 unwind
.personality_routine
= symbol_find_or_make (name
);
3495 demand_empty_rest_of_line ();
3505 unwind
.proc_start
= expr_build_dot ();
3506 /* Parse names of main and alternate entry points and mark them as
3507 function symbols: */
3511 name
= input_line_pointer
;
3512 c
= get_symbol_end ();
3513 p
= input_line_pointer
;
3514 sym
= symbol_find_or_make (name
);
3515 if (unwind
.proc_start
== 0)
3517 unwind
.proc_start
= sym
;
3519 symbol_get_bfdsym (sym
)->flags
|= BSF_FUNCTION
;
3522 if (*input_line_pointer
!= ',')
3524 ++input_line_pointer
;
3526 demand_empty_rest_of_line ();
3529 unwind
.list
= unwind
.tail
= unwind
.current_entry
= NULL
;
3530 unwind
.personality_routine
= 0;
3537 unwind
.prologue
= 0;
3538 unwind
.prologue_mask
= 0;
3540 add_unwind_entry (output_body ());
3541 demand_empty_rest_of_line ();
3545 dot_prologue (dummy
)
3549 int mask
= 0, grsave
;
3551 if (!is_it_end_of_statement ())
3554 sep
= parse_operand (&e1
);
3556 as_bad ("No second operand to .prologue");
3557 sep
= parse_operand (&e2
);
3558 if (!is_end_of_line
[sep
] && !is_it_end_of_statement ())
3559 ignore_rest_of_line ();
3561 if (e1
.X_op
== O_constant
)
3563 mask
= e1
.X_add_number
;
3565 if (e2
.X_op
== O_constant
)
3566 grsave
= e2
.X_add_number
;
3567 else if (e2
.X_op
== O_register
3568 && (grsave
= e2
.X_add_number
- REG_GR
) < 128)
3571 as_bad ("Second operand not a constant or general register");
3573 add_unwind_entry (output_prologue_gr (mask
, grsave
));
3576 as_bad ("First operand not a constant");
3579 add_unwind_entry (output_prologue ());
3581 unwind
.prologue
= 1;
3582 unwind
.prologue_mask
= mask
;
3591 int bytes_per_address
;
3594 subsegT saved_subseg
;
3596 saved_seg
= now_seg
;
3597 saved_subseg
= now_subseg
;
3600 demand_empty_rest_of_line ();
3602 insn_group_break (1, 0, 0);
3604 /* If there was a .handlerdata, we haven't generated an image yet. */
3605 if (unwind
.info
== 0)
3607 generate_unwind_image ();
3610 subseg_set (md
.last_text_seg
, 0);
3611 unwind
.proc_end
= expr_build_dot ();
3613 set_section ((char *) special_section_name
[SPECIAL_SECTION_UNWIND
]);
3614 ptr
= frag_more (24);
3615 where
= frag_now_fix () - 24;
3616 bytes_per_address
= bfd_arch_bits_per_address (stdoutput
) / 8;
3618 /* Issue the values of a) Proc Begin, b) Proc End, c) Unwind Record. */
3619 e
.X_op
= O_pseudo_fixup
;
3620 e
.X_op_symbol
= pseudo_func
[FUNC_SEG_RELATIVE
].u
.sym
;
3622 e
.X_add_symbol
= unwind
.proc_start
;
3623 ia64_cons_fix_new (frag_now
, where
, bytes_per_address
, &e
);
3625 e
.X_op
= O_pseudo_fixup
;
3626 e
.X_op_symbol
= pseudo_func
[FUNC_SEG_RELATIVE
].u
.sym
;
3628 e
.X_add_symbol
= unwind
.proc_end
;
3629 ia64_cons_fix_new (frag_now
, where
+ bytes_per_address
, bytes_per_address
, &e
);
3631 if (unwind
.info
!= 0)
3633 e
.X_op
= O_pseudo_fixup
;
3634 e
.X_op_symbol
= pseudo_func
[FUNC_SEG_RELATIVE
].u
.sym
;
3636 e
.X_add_symbol
= unwind
.info
;
3637 ia64_cons_fix_new (frag_now
, where
+ (bytes_per_address
* 2), bytes_per_address
, &e
);
3640 md_number_to_chars (ptr
+ (bytes_per_address
* 2), 0, bytes_per_address
);
3642 subseg_set (saved_seg
, saved_subseg
);
3643 unwind
.proc_start
= unwind
.proc_end
= unwind
.info
= 0;
3647 dot_template (template)
3650 CURR_SLOT
.user_template
= template;
3657 int ins
, locs
, outs
, rots
;
3659 if (is_it_end_of_statement ())
3660 ins
= locs
= outs
= rots
= 0;
3663 ins
= get_absolute_expression ();
3664 if (*input_line_pointer
++ != ',')
3666 locs
= get_absolute_expression ();
3667 if (*input_line_pointer
++ != ',')
3669 outs
= get_absolute_expression ();
3670 if (*input_line_pointer
++ != ',')
3672 rots
= get_absolute_expression ();
3674 set_regstack (ins
, locs
, outs
, rots
);
3678 as_bad ("Comma expected");
3679 ignore_rest_of_line ();
3686 unsigned num_regs
, num_alloced
= 0;
3687 struct dynreg
**drpp
, *dr
;
3688 int ch
, base_reg
= 0;
3694 case DYNREG_GR
: base_reg
= REG_GR
+ 32; break;
3695 case DYNREG_FR
: base_reg
= REG_FR
+ 32; break;
3696 case DYNREG_PR
: base_reg
= REG_P
+ 16; break;
3700 /* First, remove existing names from hash table. */
3701 for (dr
= md
.dynreg
[type
]; dr
&& dr
->num_regs
; dr
= dr
->next
)
3703 hash_delete (md
.dynreg_hash
, dr
->name
);
3707 drpp
= &md
.dynreg
[type
];
3710 start
= input_line_pointer
;
3711 ch
= get_symbol_end ();
3712 *input_line_pointer
= ch
;
3713 len
= (input_line_pointer
- start
);
3716 if (*input_line_pointer
!= '[')
3718 as_bad ("Expected '['");
3721 ++input_line_pointer
; /* skip '[' */
3723 num_regs
= get_absolute_expression ();
3725 if (*input_line_pointer
++ != ']')
3727 as_bad ("Expected ']'");
3732 num_alloced
+= num_regs
;
3736 if (num_alloced
> md
.rot
.num_regs
)
3738 as_bad ("Used more than the declared %d rotating registers",
3744 if (num_alloced
> 96)
3746 as_bad ("Used more than the available 96 rotating registers");
3751 if (num_alloced
> 48)
3753 as_bad ("Used more than the available 48 rotating registers");
3762 name
= obstack_alloc (¬es
, len
+ 1);
3763 memcpy (name
, start
, len
);
3768 *drpp
= obstack_alloc (¬es
, sizeof (*dr
));
3769 memset (*drpp
, 0, sizeof (*dr
));
3774 dr
->num_regs
= num_regs
;
3775 dr
->base
= base_reg
;
3777 base_reg
+= num_regs
;
3779 if (hash_insert (md
.dynreg_hash
, name
, dr
))
3781 as_bad ("Attempt to redefine register set `%s'", name
);
3785 if (*input_line_pointer
!= ',')
3787 ++input_line_pointer
; /* skip comma */
3790 demand_empty_rest_of_line ();
3794 ignore_rest_of_line ();
3798 dot_byteorder (byteorder
)
3801 target_big_endian
= byteorder
;
3813 option
= input_line_pointer
;
3814 ch
= get_symbol_end ();
3815 if (strcmp (option
, "lsb") == 0)
3816 md
.flags
&= ~EF_IA_64_BE
;
3817 else if (strcmp (option
, "msb") == 0)
3818 md
.flags
|= EF_IA_64_BE
;
3819 else if (strcmp (option
, "abi32") == 0)
3820 md
.flags
&= ~EF_IA_64_ABI64
;
3821 else if (strcmp (option
, "abi64") == 0)
3822 md
.flags
|= EF_IA_64_ABI64
;
3824 as_bad ("Unknown psr option `%s'", option
);
3825 *input_line_pointer
= ch
;
3828 if (*input_line_pointer
!= ',')
3831 ++input_line_pointer
;
3834 demand_empty_rest_of_line ();
3841 as_bad (".alias not implemented yet");
3848 new_logical_line (0, get_absolute_expression ());
3849 demand_empty_rest_of_line ();
3853 parse_section_name ()
3859 if (*input_line_pointer
!= '"')
3861 as_bad ("Missing section name");
3862 ignore_rest_of_line ();
3865 name
= demand_copy_C_string (&len
);
3868 ignore_rest_of_line ();
3872 if (*input_line_pointer
!= ',')
3874 as_bad ("Comma expected after section name");
3875 ignore_rest_of_line ();
3878 ++input_line_pointer
; /* skip comma */
3886 char *name
= parse_section_name ();
3892 obj_elf_previous (0);
3895 /* Why doesn't float_cons() call md_cons_align() the way cons() does? */
3898 stmt_float_cons (kind
)
3905 case 'd': size
= 8; break;
3906 case 'x': size
= 10; break;
3913 ia64_do_align (size
);
3921 int saved_auto_align
= md
.auto_align
;
3925 md
.auto_align
= saved_auto_align
;
3929 dot_xfloat_cons (kind
)
3932 char *name
= parse_section_name ();
3937 stmt_float_cons (kind
);
3938 obj_elf_previous (0);
3942 dot_xstringer (zero
)
3945 char *name
= parse_section_name ();
3951 obj_elf_previous (0);
3958 int saved_auto_align
= md
.auto_align
;
3959 char *name
= parse_section_name ();
3966 md
.auto_align
= saved_auto_align
;
3967 obj_elf_previous (0);
3971 dot_xfloat_cons_ua (kind
)
3974 int saved_auto_align
= md
.auto_align
;
3975 char *name
= parse_section_name ();
3981 stmt_float_cons (kind
);
3982 md
.auto_align
= saved_auto_align
;
3983 obj_elf_previous (0);
3986 /* .reg.val <regname>,value */
3995 if (reg
.X_op
!= O_register
)
3997 as_bad (_("Register name expected"));
3998 ignore_rest_of_line ();
4000 else if (*input_line_pointer
++ != ',')
4002 as_bad (_("Comma expected"));
4003 ignore_rest_of_line ();
4007 valueT value
= get_absolute_expression ();
4008 int regno
= reg
.X_add_number
;
4009 if (regno
< REG_GR
|| regno
> REG_GR
+ 128)
4010 as_warn (_("Register value annotation ignored"));
4013 gr_values
[regno
- REG_GR
].known
= 1;
4014 gr_values
[regno
- REG_GR
].value
= value
;
4015 gr_values
[regno
- REG_GR
].path
= md
.path
;
4018 demand_empty_rest_of_line ();
4021 /* select dv checking mode
4026 A stop is inserted when changing modes
4033 if (md
.manual_bundling
)
4034 as_warn (_("Directive invalid within a bundle"));
4036 if (type
== 'E' || type
== 'A')
4037 md
.mode_explicitly_set
= 0;
4039 md
.mode_explicitly_set
= 1;
4046 if (md
.explicit_mode
)
4047 insn_group_break (1, 0, 0);
4048 md
.explicit_mode
= 0;
4052 if (!md
.explicit_mode
)
4053 insn_group_break (1, 0, 0);
4054 md
.explicit_mode
= 1;
4058 if (md
.explicit_mode
!= md
.default_explicit_mode
)
4059 insn_group_break (1, 0, 0);
4060 md
.explicit_mode
= md
.default_explicit_mode
;
4061 md
.mode_explicitly_set
= 0;
4072 for (regno
= 0; regno
< 64; regno
++)
4074 if (mask
& ((valueT
) 1 << regno
))
4076 fprintf (stderr
, "%s p%d", comma
, regno
);
4083 .pred.rel.clear [p1 [,p2 [,...]]] (also .pred.rel "clear")
4084 .pred.rel.imply p1, p2 (also .pred.rel "imply")
4085 .pred.rel.mutex p1, p2 [,...] (also .pred.rel "mutex")
4086 .pred.safe_across_calls p1 [, p2 [,...]]
4095 int p1
= -1, p2
= -1;
4099 if (*input_line_pointer
!= '"')
4101 as_bad (_("Missing predicate relation type"));
4102 ignore_rest_of_line ();
4108 char *form
= demand_copy_C_string (&len
);
4109 if (strcmp (form
, "mutex") == 0)
4111 else if (strcmp (form
, "clear") == 0)
4113 else if (strcmp (form
, "imply") == 0)
4117 as_bad (_("Unrecognized predicate relation type"));
4118 ignore_rest_of_line ();
4122 if (*input_line_pointer
== ',')
4123 ++input_line_pointer
;
4133 if (toupper (*input_line_pointer
) != 'P'
4134 || (regno
= atoi (++input_line_pointer
)) < 0
4137 as_bad (_("Predicate register expected"));
4138 ignore_rest_of_line ();
4141 while (isdigit (*input_line_pointer
))
4142 ++input_line_pointer
;
4149 as_warn (_("Duplicate predicate register ignored"));
4152 /* See if it's a range. */
4153 if (*input_line_pointer
== '-')
4156 ++input_line_pointer
;
4158 if (toupper (*input_line_pointer
) != 'P'
4159 || (regno
= atoi (++input_line_pointer
)) < 0
4162 as_bad (_("Predicate register expected"));
4163 ignore_rest_of_line ();
4166 while (isdigit (*input_line_pointer
))
4167 ++input_line_pointer
;
4171 as_bad (_("Bad register range"));
4172 ignore_rest_of_line ();
4183 if (*input_line_pointer
!= ',')
4185 ++input_line_pointer
;
4194 clear_qp_mutex (mask
);
4195 clear_qp_implies (mask
, (valueT
) 0);
4198 if (count
!= 2 || p1
== -1 || p2
== -1)
4199 as_bad (_("Predicate source and target required"));
4200 else if (p1
== 0 || p2
== 0)
4201 as_bad (_("Use of p0 is not valid in this context"));
4203 add_qp_imply (p1
, p2
);
4208 as_bad (_("At least two PR arguments expected"));
4213 as_bad (_("Use of p0 is not valid in this context"));
4216 add_qp_mutex (mask
);
4219 /* note that we don't override any existing relations */
4222 as_bad (_("At least one PR argument expected"));
4227 fprintf (stderr
, "Safe across calls: ");
4228 print_prmask (mask
);
4229 fprintf (stderr
, "\n");
4231 qp_safe_across_calls
= mask
;
4234 demand_empty_rest_of_line ();
4237 /* .entry label [, label [, ...]]
4238 Hint to DV code that the given labels are to be considered entry points.
4239 Otherwise, only global labels are considered entry points. */
4252 name
= input_line_pointer
;
4253 c
= get_symbol_end ();
4254 symbolP
= symbol_find_or_make (name
);
4256 err
= hash_insert (md
.entry_hash
, S_GET_NAME (symbolP
), (PTR
) symbolP
);
4258 as_fatal (_("Inserting \"%s\" into entry hint table failed: %s"),
4261 *input_line_pointer
= c
;
4263 c
= *input_line_pointer
;
4266 input_line_pointer
++;
4268 if (*input_line_pointer
== '\n')
4274 demand_empty_rest_of_line ();
4277 /* .mem.offset offset, base
4278 "base" is used to distinguish between offsets from a different base. */
4281 dot_mem_offset (dummy
)
4284 md
.mem_offset
.hint
= 1;
4285 md
.mem_offset
.offset
= get_absolute_expression ();
4286 if (*input_line_pointer
!= ',')
4288 as_bad (_("Comma expected"));
4289 ignore_rest_of_line ();
4292 ++input_line_pointer
;
4293 md
.mem_offset
.base
= get_absolute_expression ();
4294 demand_empty_rest_of_line ();
4297 /* ia64-specific pseudo-ops: */
4298 const pseudo_typeS md_pseudo_table
[] =
4300 { "radix", dot_radix
, 0 },
4301 { "lcomm", s_lcomm_bytes
, 1 },
4302 { "bss", dot_special_section
, SPECIAL_SECTION_BSS
},
4303 { "sbss", dot_special_section
, SPECIAL_SECTION_SBSS
},
4304 { "sdata", dot_special_section
, SPECIAL_SECTION_SDATA
},
4305 { "rodata", dot_special_section
, SPECIAL_SECTION_RODATA
},
4306 { "comment", dot_special_section
, SPECIAL_SECTION_COMMENT
},
4307 { "ia_64.unwind", dot_special_section
, SPECIAL_SECTION_UNWIND
},
4308 { "ia_64.unwind_info", dot_special_section
, SPECIAL_SECTION_UNWIND_INFO
},
4309 { "proc", dot_proc
, 0 },
4310 { "body", dot_body
, 0 },
4311 { "prologue", dot_prologue
, 0 },
4312 { "endp", dot_endp
},
4313 { "file", dwarf2_directive_file
},
4314 { "loc", dwarf2_directive_loc
},
4316 { "fframe", dot_fframe
},
4317 { "vframe", dot_vframe
},
4318 { "vframesp", dot_vframesp
},
4319 { "vframepsp", dot_vframepsp
},
4320 { "save", dot_save
},
4321 { "restore", dot_restore
},
4322 { "restorereg", dot_restorereg
},
4323 { "restorereg.p", dot_restorereg_p
},
4324 { "handlerdata", dot_handlerdata
},
4325 { "unwentry", dot_unwentry
},
4326 { "altrp", dot_altrp
},
4327 { "savesp", dot_savemem
, 0 },
4328 { "savepsp", dot_savemem
, 1 },
4329 { "save.g", dot_saveg
},
4330 { "save.f", dot_savef
},
4331 { "save.b", dot_saveb
},
4332 { "save.gf", dot_savegf
},
4333 { "spill", dot_spill
},
4334 { "spillreg", dot_spillreg
},
4335 { "spillsp", dot_spillmem
, 0 },
4336 { "spillpsp", dot_spillmem
, 1 },
4337 { "spillreg.p", dot_spillreg_p
},
4338 { "spillsp.p", dot_spillmem_p
, 0 },
4339 { "spillpsp.p", dot_spillmem_p
, 1 },
4340 { "label_state", dot_label_state
},
4341 { "copy_state", dot_copy_state
},
4342 { "unwabi", dot_unwabi
},
4343 { "personality", dot_personality
},
4345 { "estate", dot_estate
},
4347 { "mii", dot_template
, 0x0 },
4348 { "mli", dot_template
, 0x2 }, /* old format, for compatibility */
4349 { "mlx", dot_template
, 0x2 },
4350 { "mmi", dot_template
, 0x4 },
4351 { "mfi", dot_template
, 0x6 },
4352 { "mmf", dot_template
, 0x7 },
4353 { "mib", dot_template
, 0x8 },
4354 { "mbb", dot_template
, 0x9 },
4355 { "bbb", dot_template
, 0xb },
4356 { "mmb", dot_template
, 0xc },
4357 { "mfb", dot_template
, 0xe },
4359 { "lb", dot_scope
, 0 },
4360 { "le", dot_scope
, 1 },
4362 { "align", s_align_bytes
, 0 },
4363 { "regstk", dot_regstk
, 0 },
4364 { "rotr", dot_rot
, DYNREG_GR
},
4365 { "rotf", dot_rot
, DYNREG_FR
},
4366 { "rotp", dot_rot
, DYNREG_PR
},
4367 { "lsb", dot_byteorder
, 0 },
4368 { "msb", dot_byteorder
, 1 },
4369 { "psr", dot_psr
, 0 },
4370 { "alias", dot_alias
, 0 },
4371 { "ln", dot_ln
, 0 }, /* source line info (for debugging) */
4373 { "xdata1", dot_xdata
, 1 },
4374 { "xdata2", dot_xdata
, 2 },
4375 { "xdata4", dot_xdata
, 4 },
4376 { "xdata8", dot_xdata
, 8 },
4377 { "xreal4", dot_xfloat_cons
, 'f' },
4378 { "xreal8", dot_xfloat_cons
, 'd' },
4379 { "xreal10", dot_xfloat_cons
, 'x' },
4380 { "xstring", dot_xstringer
, 0 },
4381 { "xstringz", dot_xstringer
, 1 },
4383 /* unaligned versions: */
4384 { "xdata2.ua", dot_xdata_ua
, 2 },
4385 { "xdata4.ua", dot_xdata_ua
, 4 },
4386 { "xdata8.ua", dot_xdata_ua
, 8 },
4387 { "xreal4.ua", dot_xfloat_cons_ua
, 'f' },
4388 { "xreal8.ua", dot_xfloat_cons_ua
, 'd' },
4389 { "xreal10.ua", dot_xfloat_cons_ua
, 'x' },
4391 /* annotations/DV checking support */
4392 { "entry", dot_entry
, 0 },
4393 { "mem.offset", dot_mem_offset
},
4394 { "pred.rel", dot_pred_rel
, 0 },
4395 { "pred.rel.clear", dot_pred_rel
, 'c' },
4396 { "pred.rel.imply", dot_pred_rel
, 'i' },
4397 { "pred.rel.mutex", dot_pred_rel
, 'm' },
4398 { "pred.safe_across_calls", dot_pred_rel
, 's' },
4399 { "reg.val", dot_reg_val
},
4400 { "auto", dot_dv_mode
, 'a' },
4401 { "explicit", dot_dv_mode
, 'e' },
4402 { "default", dot_dv_mode
, 'd' },
4407 static const struct pseudo_opcode
4410 void (*handler
) (int);
4415 /* these are more like pseudo-ops, but don't start with a dot */
4416 { "data1", cons
, 1 },
4417 { "data2", cons
, 2 },
4418 { "data4", cons
, 4 },
4419 { "data8", cons
, 8 },
4420 { "real4", stmt_float_cons
, 'f' },
4421 { "real8", stmt_float_cons
, 'd' },
4422 { "real10", stmt_float_cons
, 'x' },
4423 { "string", stringer
, 0 },
4424 { "stringz", stringer
, 1 },
4426 /* unaligned versions: */
4427 { "data2.ua", stmt_cons_ua
, 2 },
4428 { "data4.ua", stmt_cons_ua
, 4 },
4429 { "data8.ua", stmt_cons_ua
, 8 },
4430 { "real4.ua", float_cons
, 'f' },
4431 { "real8.ua", float_cons
, 'd' },
4432 { "real10.ua", float_cons
, 'x' },
4435 /* Declare a register by creating a symbol for it and entering it in
4436 the symbol table. */
4439 declare_register (name
, regnum
)
4446 sym
= symbol_new (name
, reg_section
, regnum
, &zero_address_frag
);
4448 err
= hash_insert (md
.reg_hash
, S_GET_NAME (sym
), (PTR
) sym
);
4450 as_fatal ("Inserting \"%s\" into register table failed: %s",
4457 declare_register_set (prefix
, num_regs
, base_regnum
)
4465 for (i
= 0; i
< num_regs
; ++i
)
4467 sprintf (name
, "%s%u", prefix
, i
);
4468 declare_register (name
, base_regnum
+ i
);
4473 operand_width (opnd
)
4474 enum ia64_opnd opnd
;
4476 const struct ia64_operand
*odesc
= &elf64_ia64_operands
[opnd
];
4477 unsigned int bits
= 0;
4481 for (i
= 0; i
< NELEMS (odesc
->field
) && odesc
->field
[i
].bits
; ++i
)
4482 bits
+= odesc
->field
[i
].bits
;
4488 operand_match (idesc
, index
, e
)
4489 const struct ia64_opcode
*idesc
;
4493 enum ia64_opnd opnd
= idesc
->operands
[index
];
4494 int bits
, relocatable
= 0;
4495 struct insn_fix
*fix
;
4502 case IA64_OPND_AR_CCV
:
4503 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_AR
+ 32)
4507 case IA64_OPND_AR_PFS
:
4508 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_AR
+ 64)
4513 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_GR
+ 0)
4518 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_IP
)
4523 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_PR
)
4527 case IA64_OPND_PR_ROT
:
4528 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_PR_ROT
)
4533 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_PSR
)
4537 case IA64_OPND_PSR_L
:
4538 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_PSR_L
)
4542 case IA64_OPND_PSR_UM
:
4543 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_PSR_UM
)
4548 if (e
->X_op
== O_constant
&& e
->X_add_number
== 1)
4553 if (e
->X_op
== O_constant
&& e
->X_add_number
== 8)
4558 if (e
->X_op
== O_constant
&& e
->X_add_number
== 16)
4562 /* register operands: */
4565 if (e
->X_op
== O_register
&& e
->X_add_number
>= REG_AR
4566 && e
->X_add_number
< REG_AR
+ 128)
4572 if (e
->X_op
== O_register
&& e
->X_add_number
>= REG_BR
4573 && e
->X_add_number
< REG_BR
+ 8)
4578 if (e
->X_op
== O_register
&& e
->X_add_number
>= REG_CR
4579 && e
->X_add_number
< REG_CR
+ 128)
4587 if (e
->X_op
== O_register
&& e
->X_add_number
>= REG_FR
4588 && e
->X_add_number
< REG_FR
+ 128)
4594 if (e
->X_op
== O_register
&& e
->X_add_number
>= REG_P
4595 && e
->X_add_number
< REG_P
+ 64)
4602 if (e
->X_op
== O_register
&& e
->X_add_number
>= REG_GR
4603 && e
->X_add_number
< REG_GR
+ 128)
4607 case IA64_OPND_R3_2
:
4608 if (e
->X_op
== O_register
&& e
->X_add_number
>= REG_GR
4609 && e
->X_add_number
< REG_GR
+ 4)
4613 /* indirect operands: */
4614 case IA64_OPND_CPUID_R3
:
4615 case IA64_OPND_DBR_R3
:
4616 case IA64_OPND_DTR_R3
:
4617 case IA64_OPND_ITR_R3
:
4618 case IA64_OPND_IBR_R3
:
4619 case IA64_OPND_MSR_R3
:
4620 case IA64_OPND_PKR_R3
:
4621 case IA64_OPND_PMC_R3
:
4622 case IA64_OPND_PMD_R3
:
4623 case IA64_OPND_RR_R3
:
4624 if (e
->X_op
== O_index
&& e
->X_op_symbol
4625 && (S_GET_VALUE (e
->X_op_symbol
) - IND_CPUID
4626 == opnd
- IA64_OPND_CPUID_R3
))
4631 if (e
->X_op
== O_index
&& !e
->X_op_symbol
)
4635 /* immediate operands: */
4636 case IA64_OPND_CNT2a
:
4637 case IA64_OPND_LEN4
:
4638 case IA64_OPND_LEN6
:
4639 bits
= operand_width (idesc
->operands
[index
]);
4640 if (e
->X_op
== O_constant
4641 && (bfd_vma
) (e
->X_add_number
- 1) < ((bfd_vma
) 1 << bits
))
4645 case IA64_OPND_CNT2b
:
4646 if (e
->X_op
== O_constant
4647 && (bfd_vma
) (e
->X_add_number
- 1) < 3)
4651 case IA64_OPND_CNT2c
:
4652 val
= e
->X_add_number
;
4653 if (e
->X_op
== O_constant
4654 && (val
== 0 || val
== 7 || val
== 15 || val
== 16))
4659 /* SOR must be an integer multiple of 8 */
4660 if (e
->X_add_number
& 0x7)
4664 if (e
->X_op
== O_constant
&&
4665 (bfd_vma
) e
->X_add_number
<= 96)
4669 case IA64_OPND_IMMU62
:
4670 if (e
->X_op
== O_constant
)
4672 if ((bfd_vma
) e
->X_add_number
< ((bfd_vma
) 1 << 62))
4677 /* FIXME -- need 62-bit relocation type */
4678 as_bad (_("62-bit relocation not yet implemented"));
4682 case IA64_OPND_IMMU64
:
4683 if (e
->X_op
== O_symbol
|| e
->X_op
== O_pseudo_fixup
4684 || e
->X_op
== O_subtract
)
4686 fix
= CURR_SLOT
.fixup
+ CURR_SLOT
.num_fixups
;
4687 fix
->code
= BFD_RELOC_IA64_IMM64
;
4688 if (e
->X_op
!= O_subtract
)
4690 fix
->code
= ia64_gen_real_reloc_type (e
->X_op_symbol
, fix
->code
);
4691 if (e
->X_op
== O_pseudo_fixup
)
4695 fix
->opnd
= idesc
->operands
[index
];
4698 ++CURR_SLOT
.num_fixups
;
4701 else if (e
->X_op
== O_constant
)
4705 case IA64_OPND_CCNT5
:
4706 case IA64_OPND_CNT5
:
4707 case IA64_OPND_CNT6
:
4708 case IA64_OPND_CPOS6a
:
4709 case IA64_OPND_CPOS6b
:
4710 case IA64_OPND_CPOS6c
:
4711 case IA64_OPND_IMMU2
:
4712 case IA64_OPND_IMMU7a
:
4713 case IA64_OPND_IMMU7b
:
4714 case IA64_OPND_IMMU21
:
4715 case IA64_OPND_IMMU24
:
4716 case IA64_OPND_MBTYPE4
:
4717 case IA64_OPND_MHTYPE8
:
4718 case IA64_OPND_POS6
:
4719 bits
= operand_width (idesc
->operands
[index
]);
4720 if (e
->X_op
== O_constant
4721 && (bfd_vma
) e
->X_add_number
< ((bfd_vma
) 1 << bits
))
4725 case IA64_OPND_IMMU9
:
4726 bits
= operand_width (idesc
->operands
[index
]);
4727 if (e
->X_op
== O_constant
4728 && (bfd_vma
) e
->X_add_number
< ((bfd_vma
) 1 << bits
))
4730 int lobits
= e
->X_add_number
& 0x3;
4731 if (((bfd_vma
) e
->X_add_number
& 0x3C) != 0 && lobits
== 0)
4732 e
->X_add_number
|= (bfd_vma
) 0x3;
4737 case IA64_OPND_IMM44
:
4738 /* least 16 bits must be zero */
4739 if ((e
->X_add_number
& 0xffff) != 0)
4740 as_warn (_("lower 16 bits of mask ignored"));
4742 if (e
->X_op
== O_constant
4743 && ((e
->X_add_number
>= 0
4744 && e
->X_add_number
< ((bfd_vma
) 1 << 44))
4745 || (e
->X_add_number
< 0
4746 && -e
->X_add_number
<= ((bfd_vma
) 1 << 44))))
4749 if (e
->X_add_number
>= 0
4750 && (e
->X_add_number
& ((bfd_vma
) 1 << 43)) != 0)
4752 e
->X_add_number
|= ~(((bfd_vma
) 1 << 44) - 1);
4758 case IA64_OPND_IMM17
:
4759 /* bit 0 is a don't care (pr0 is hardwired to 1) */
4760 if (e
->X_op
== O_constant
4761 && ((e
->X_add_number
>= 0
4762 && e
->X_add_number
< ((bfd_vma
) 1 << 17))
4763 || (e
->X_add_number
< 0
4764 && -e
->X_add_number
<= ((bfd_vma
) 1 << 17))))
4767 if (e
->X_add_number
>= 0
4768 && (e
->X_add_number
& ((bfd_vma
) 1 << 16)) != 0)
4770 e
->X_add_number
|= ~(((bfd_vma
) 1 << 17) - 1);
4776 case IA64_OPND_IMM14
:
4777 case IA64_OPND_IMM22
:
4779 case IA64_OPND_IMM1
:
4780 case IA64_OPND_IMM8
:
4781 case IA64_OPND_IMM8U4
:
4782 case IA64_OPND_IMM8M1
:
4783 case IA64_OPND_IMM8M1U4
:
4784 case IA64_OPND_IMM8M1U8
:
4785 case IA64_OPND_IMM9a
:
4786 case IA64_OPND_IMM9b
:
4787 bits
= operand_width (idesc
->operands
[index
]);
4788 if (relocatable
&& (e
->X_op
== O_symbol
4789 || e
->X_op
== O_subtract
4790 || e
->X_op
== O_pseudo_fixup
))
4792 fix
= CURR_SLOT
.fixup
+ CURR_SLOT
.num_fixups
;
4794 if (idesc
->operands
[index
] == IA64_OPND_IMM14
)
4795 fix
->code
= BFD_RELOC_IA64_IMM14
;
4797 fix
->code
= BFD_RELOC_IA64_IMM22
;
4799 if (e
->X_op
!= O_subtract
)
4801 fix
->code
= ia64_gen_real_reloc_type (e
->X_op_symbol
, fix
->code
);
4802 if (e
->X_op
== O_pseudo_fixup
)
4806 fix
->opnd
= idesc
->operands
[index
];
4809 ++CURR_SLOT
.num_fixups
;
4812 else if (e
->X_op
!= O_constant
4813 && ! (e
->X_op
== O_big
&& opnd
== IA64_OPND_IMM8M1U8
))
4816 if (opnd
== IA64_OPND_IMM8M1U4
)
4818 /* Zero is not valid for unsigned compares that take an adjusted
4819 constant immediate range. */
4820 if (e
->X_add_number
== 0)
4823 /* Sign-extend 32-bit unsigned numbers, so that the following range
4824 checks will work. */
4825 val
= e
->X_add_number
;
4826 if (((val
& (~(bfd_vma
) 0 << 32)) == 0)
4827 && ((val
& ((bfd_vma
) 1 << 31)) != 0))
4828 val
= ((val
<< 32) >> 32);
4830 /* Check for 0x100000000. This is valid because
4831 0x100000000-1 is the same as ((uint32_t) -1). */
4832 if (val
== ((bfd_signed_vma
) 1 << 32))
4837 else if (opnd
== IA64_OPND_IMM8M1U8
)
4839 /* Zero is not valid for unsigned compares that take an adjusted
4840 constant immediate range. */
4841 if (e
->X_add_number
== 0)
4844 /* Check for 0x10000000000000000. */
4845 if (e
->X_op
== O_big
)
4847 if (generic_bignum
[0] == 0
4848 && generic_bignum
[1] == 0
4849 && generic_bignum
[2] == 0
4850 && generic_bignum
[3] == 0
4851 && generic_bignum
[4] == 1)
4857 val
= e
->X_add_number
- 1;
4859 else if (opnd
== IA64_OPND_IMM8M1
)
4860 val
= e
->X_add_number
- 1;
4861 else if (opnd
== IA64_OPND_IMM8U4
)
4863 /* Sign-extend 32-bit unsigned numbers, so that the following range
4864 checks will work. */
4865 val
= e
->X_add_number
;
4866 if (((val
& (~(bfd_vma
) 0 << 32)) == 0)
4867 && ((val
& ((bfd_vma
) 1 << 31)) != 0))
4868 val
= ((val
<< 32) >> 32);
4871 val
= e
->X_add_number
;
4873 if ((val
>= 0 && val
< ((bfd_vma
) 1 << (bits
- 1)))
4874 || (val
< 0 && -val
<= ((bfd_vma
) 1 << (bits
- 1))))
4878 case IA64_OPND_INC3
:
4879 /* +/- 1, 4, 8, 16 */
4880 val
= e
->X_add_number
;
4883 if (e
->X_op
== O_constant
4884 && (val
== 1 || val
== 4 || val
== 8 || val
== 16))
4888 case IA64_OPND_TGT25
:
4889 case IA64_OPND_TGT25b
:
4890 case IA64_OPND_TGT25c
:
4891 case IA64_OPND_TGT64
:
4892 if (e
->X_op
== O_symbol
)
4894 fix
= CURR_SLOT
.fixup
+ CURR_SLOT
.num_fixups
;
4895 if (opnd
== IA64_OPND_TGT25
)
4896 fix
->code
= BFD_RELOC_IA64_PCREL21F
;
4897 else if (opnd
== IA64_OPND_TGT25b
)
4898 fix
->code
= BFD_RELOC_IA64_PCREL21M
;
4899 else if (opnd
== IA64_OPND_TGT25c
)
4900 fix
->code
= BFD_RELOC_IA64_PCREL21B
;
4901 else if (opnd
== IA64_OPND_TGT64
)
4902 fix
->code
= BFD_RELOC_IA64_PCREL60B
;
4906 fix
->code
= ia64_gen_real_reloc_type (e
->X_op_symbol
, fix
->code
);
4907 fix
->opnd
= idesc
->operands
[index
];
4910 ++CURR_SLOT
.num_fixups
;
4913 case IA64_OPND_TAG13
:
4914 case IA64_OPND_TAG13b
:
4921 fix
= CURR_SLOT
.fixup
+ CURR_SLOT
.num_fixups
;
4922 fix
->code
= ia64_gen_real_reloc_type (e
->X_op_symbol
, 0);
4923 fix
->opnd
= idesc
->operands
[index
];
4926 ++CURR_SLOT
.num_fixups
;
4946 memset (e
, 0, sizeof (*e
));
4949 if (*input_line_pointer
!= '}')
4951 sep
= *input_line_pointer
++;
4955 if (!md
.manual_bundling
)
4956 as_warn ("Found '}' when manual bundling is off");
4958 CURR_SLOT
.manual_bundling_off
= 1;
4959 md
.manual_bundling
= 0;
4965 /* Returns the next entry in the opcode table that matches the one in
4966 IDESC, and frees the entry in IDESC. If no matching entry is
4967 found, NULL is returned instead. */
4969 static struct ia64_opcode
*
4970 get_next_opcode (struct ia64_opcode
*idesc
)
4972 struct ia64_opcode
*next
= ia64_find_next_opcode (idesc
);
4973 ia64_free_opcode (idesc
);
4977 /* Parse the operands for the opcode and find the opcode variant that
4978 matches the specified operands, or NULL if no match is possible. */
4980 static struct ia64_opcode
*
4981 parse_operands (idesc
)
4982 struct ia64_opcode
*idesc
;
4984 int i
= 0, highest_unmatched_operand
, num_operands
= 0, num_outputs
= 0;
4986 enum ia64_opnd expected_operand
= IA64_OPND_NIL
;
4988 char *first_arg
= 0, *end
, *saved_input_pointer
;
4991 assert (strlen (idesc
->name
) <= 128);
4993 strcpy (mnemonic
, idesc
->name
);
4994 if (idesc
->operands
[2] == IA64_OPND_SOF
)
4996 /* To make the common idiom "alloc loc?=ar.pfs,0,1,0,0" work, we
4997 can't parse the first operand until we have parsed the
4998 remaining operands of the "alloc" instruction. */
5000 first_arg
= input_line_pointer
;
5001 end
= strchr (input_line_pointer
, '=');
5004 as_bad ("Expected separator `='");
5007 input_line_pointer
= end
+ 1;
5012 for (; i
< NELEMS (CURR_SLOT
.opnd
); ++i
)
5014 sep
= parse_operand (CURR_SLOT
.opnd
+ i
);
5015 if (CURR_SLOT
.opnd
[i
].X_op
== O_absent
)
5020 if (sep
!= '=' && sep
!= ',')
5025 if (num_outputs
> 0)
5026 as_bad ("Duplicate equal sign (=) in instruction");
5028 num_outputs
= i
+ 1;
5033 as_bad ("Illegal operand separator `%c'", sep
);
5037 if (idesc
->operands
[2] == IA64_OPND_SOF
)
5039 /* map alloc r1=ar.pfs,i,l,o,r to alloc r1=ar.pfs,(i+l+o),(i+l),r */
5040 know (strcmp (idesc
->name
, "alloc") == 0);
5041 if (num_operands
== 5 /* first_arg not included in this count! */
5042 && CURR_SLOT
.opnd
[2].X_op
== O_constant
5043 && CURR_SLOT
.opnd
[3].X_op
== O_constant
5044 && CURR_SLOT
.opnd
[4].X_op
== O_constant
5045 && CURR_SLOT
.opnd
[5].X_op
== O_constant
)
5047 sof
= set_regstack (CURR_SLOT
.opnd
[2].X_add_number
,
5048 CURR_SLOT
.opnd
[3].X_add_number
,
5049 CURR_SLOT
.opnd
[4].X_add_number
,
5050 CURR_SLOT
.opnd
[5].X_add_number
);
5052 /* now we can parse the first arg: */
5053 saved_input_pointer
= input_line_pointer
;
5054 input_line_pointer
= first_arg
;
5055 sep
= parse_operand (CURR_SLOT
.opnd
+ 0);
5057 --num_outputs
; /* force error */
5058 input_line_pointer
= saved_input_pointer
;
5060 CURR_SLOT
.opnd
[2].X_add_number
= sof
;
5061 CURR_SLOT
.opnd
[3].X_add_number
5062 = sof
- CURR_SLOT
.opnd
[4].X_add_number
;
5063 CURR_SLOT
.opnd
[4] = CURR_SLOT
.opnd
[5];
5067 highest_unmatched_operand
= 0;
5068 expected_operand
= idesc
->operands
[0];
5069 for (; idesc
; idesc
= get_next_opcode (idesc
))
5071 if (num_outputs
!= idesc
->num_outputs
)
5072 continue; /* mismatch in # of outputs */
5074 CURR_SLOT
.num_fixups
= 0;
5075 for (i
= 0; i
< num_operands
&& idesc
->operands
[i
]; ++i
)
5076 if (!operand_match (idesc
, i
, CURR_SLOT
.opnd
+ i
))
5079 if (i
!= num_operands
)
5081 if (i
> highest_unmatched_operand
)
5083 highest_unmatched_operand
= i
;
5084 expected_operand
= idesc
->operands
[i
];
5089 if (num_operands
< NELEMS (idesc
->operands
)
5090 && idesc
->operands
[num_operands
])
5091 continue; /* mismatch in number of arguments */
5097 if (expected_operand
)
5098 as_bad ("Operand %u of `%s' should be %s",
5099 highest_unmatched_operand
+ 1, mnemonic
,
5100 elf64_ia64_operands
[expected_operand
].desc
);
5102 as_bad ("Operand mismatch");
5109 build_insn (slot
, insnp
)
5113 const struct ia64_operand
*odesc
, *o2desc
;
5114 struct ia64_opcode
*idesc
= slot
->idesc
;
5115 bfd_signed_vma insn
, val
;
5119 insn
= idesc
->opcode
| slot
->qp_regno
;
5121 for (i
= 0; i
< NELEMS (idesc
->operands
) && idesc
->operands
[i
]; ++i
)
5123 if (slot
->opnd
[i
].X_op
== O_register
5124 || slot
->opnd
[i
].X_op
== O_constant
5125 || slot
->opnd
[i
].X_op
== O_index
)
5126 val
= slot
->opnd
[i
].X_add_number
;
5127 else if (slot
->opnd
[i
].X_op
== O_big
)
5129 /* This must be the value 0x10000000000000000. */
5130 assert (idesc
->operands
[i
] == IA64_OPND_IMM8M1U8
);
5136 switch (idesc
->operands
[i
])
5138 case IA64_OPND_IMMU64
:
5139 *insnp
++ = (val
>> 22) & 0x1ffffffffffLL
;
5140 insn
|= (((val
& 0x7f) << 13) | (((val
>> 7) & 0x1ff) << 27)
5141 | (((val
>> 16) & 0x1f) << 22) | (((val
>> 21) & 0x1) << 21)
5142 | (((val
>> 63) & 0x1) << 36));
5145 case IA64_OPND_IMMU62
:
5146 val
&= 0x3fffffffffffffffULL
;
5147 if (val
!= slot
->opnd
[i
].X_add_number
)
5148 as_warn (_("Value truncated to 62 bits"));
5149 *insnp
++ = (val
>> 21) & 0x1ffffffffffLL
;
5150 insn
|= (((val
& 0xfffff) << 6) | (((val
>> 20) & 0x1) << 36));
5153 case IA64_OPND_TGT64
:
5155 *insnp
++ = ((val
>> 20) & 0x7fffffffffLL
) << 2;
5156 insn
|= ((((val
>> 59) & 0x1) << 36)
5157 | (((val
>> 0) & 0xfffff) << 13));
5188 case IA64_OPND_R3_2
:
5189 case IA64_OPND_CPUID_R3
:
5190 case IA64_OPND_DBR_R3
:
5191 case IA64_OPND_DTR_R3
:
5192 case IA64_OPND_ITR_R3
:
5193 case IA64_OPND_IBR_R3
:
5195 case IA64_OPND_MSR_R3
:
5196 case IA64_OPND_PKR_R3
:
5197 case IA64_OPND_PMC_R3
:
5198 case IA64_OPND_PMD_R3
:
5199 case IA64_OPND_RR_R3
:
5207 odesc
= elf64_ia64_operands
+ idesc
->operands
[i
];
5208 err
= (*odesc
->insert
) (odesc
, val
, &insn
);
5210 as_bad_where (slot
->src_file
, slot
->src_line
,
5211 "Bad operand value: %s", err
);
5212 if (idesc
->flags
& IA64_OPCODE_PSEUDO
)
5214 if ((idesc
->flags
& IA64_OPCODE_F2_EQ_F3
)
5215 && odesc
== elf64_ia64_operands
+ IA64_OPND_F3
)
5217 o2desc
= elf64_ia64_operands
+ IA64_OPND_F2
;
5218 (*o2desc
->insert
) (o2desc
, val
, &insn
);
5220 if ((idesc
->flags
& IA64_OPCODE_LEN_EQ_64MCNT
)
5221 && (odesc
== elf64_ia64_operands
+ IA64_OPND_CPOS6a
5222 || odesc
== elf64_ia64_operands
+ IA64_OPND_POS6
))
5224 o2desc
= elf64_ia64_operands
+ IA64_OPND_LEN6
;
5225 (*o2desc
->insert
) (o2desc
, 64 - val
, &insn
);
5235 unsigned int manual_bundling_on
= 0, manual_bundling_off
= 0;
5236 unsigned int manual_bundling
= 0;
5237 enum ia64_unit required_unit
, insn_unit
= 0;
5238 enum ia64_insn_type type
[3], insn_type
;
5239 unsigned int template, orig_template
;
5240 bfd_vma insn
[3] = { -1, -1, -1 };
5241 struct ia64_opcode
*idesc
;
5242 int end_of_insn_group
= 0, user_template
= -1;
5243 int n
, i
, j
, first
, curr
;
5244 unw_rec_list
*ptr
, *prev
;
5245 bfd_vma t0
= 0, t1
= 0;
5246 struct label_fix
*lfix
;
5247 struct insn_fix
*ifix
;
5252 first
= (md
.curr_slot
+ NUM_SLOTS
- md
.num_slots_in_use
) % NUM_SLOTS
;
5253 know (first
>= 0 & first
< NUM_SLOTS
);
5254 n
= MIN (3, md
.num_slots_in_use
);
5256 /* Determine template: user user_template if specified, best match
5259 if (md
.slot
[first
].user_template
>= 0)
5260 user_template
= template = md
.slot
[first
].user_template
;
5263 /* Auto select appropriate template. */
5264 memset (type
, 0, sizeof (type
));
5266 for (i
= 0; i
< n
; ++i
)
5268 if (md
.slot
[curr
].label_fixups
&& i
!= 0)
5270 type
[i
] = md
.slot
[curr
].idesc
->type
;
5271 curr
= (curr
+ 1) % NUM_SLOTS
;
5273 template = best_template
[type
[0]][type
[1]][type
[2]];
5276 /* initialize instructions with appropriate nops: */
5277 for (i
= 0; i
< 3; ++i
)
5278 insn
[i
] = nop
[ia64_templ_desc
[template].exec_unit
[i
]];
5282 /* now fill in slots with as many insns as possible: */
5284 idesc
= md
.slot
[curr
].idesc
;
5285 end_of_insn_group
= 0;
5286 for (i
= 0; i
< 3 && md
.num_slots_in_use
> 0; ++i
)
5288 /* Set the slot number for prologue/body records now as those
5289 refer to the current point, not the point after the
5290 instruction has been issued: */
5291 /* Don't try to delete prologue/body records here, as that will cause
5292 them to also be deleted from the master list of unwind records. */
5293 for (ptr
= md
.slot
[curr
].unwind_record
; ptr
; ptr
= ptr
->next
)
5294 if (ptr
->r
.type
== prologue
|| ptr
->r
.type
== prologue_gr
5295 || ptr
->r
.type
== body
)
5296 ptr
->slot_number
= (unsigned long) f
+ i
;
5298 if (idesc
->flags
& IA64_OPCODE_SLOT2
)
5300 if (manual_bundling
&& i
!= 2)
5301 as_bad_where (md
.slot
[curr
].src_file
, md
.slot
[curr
].src_line
,
5302 "`%s' must be last in bundle", idesc
->name
);
5306 if (idesc
->flags
& IA64_OPCODE_LAST
)
5308 int required_slot
, required_template
;
5310 /* If we need a stop bit after an M slot, our only choice is
5311 template 5 (M;;MI). If we need a stop bit after a B
5312 slot, our only choice is to place it at the end of the
5313 bundle, because the only available templates are MIB,
5314 MBB, BBB, MMB, and MFB. We don't handle anything other
5315 than M and B slots because these are the only kind of
5316 instructions that can have the IA64_OPCODE_LAST bit set. */
5317 required_template
= template;
5318 switch (idesc
->type
)
5322 required_template
= 5;
5330 as_bad_where (md
.slot
[curr
].src_file
, md
.slot
[curr
].src_line
,
5331 "Internal error: don't know how to force %s to end"
5332 "of instruction group", idesc
->name
);
5336 if (manual_bundling
&& i
!= required_slot
)
5337 as_bad_where (md
.slot
[curr
].src_file
, md
.slot
[curr
].src_line
,
5338 "`%s' must be last in instruction group",
5340 if (required_slot
< i
)
5341 /* Can't fit this instruction. */
5345 if (required_template
!= template)
5347 /* If we switch the template, we need to reset the NOPs
5348 after slot i. The slot-types of the instructions ahead
5349 of i never change, so we don't need to worry about
5350 changing NOPs in front of this slot. */
5351 for (j
= i
; j
< 3; ++j
)
5352 insn
[j
] = nop
[ia64_templ_desc
[required_template
].exec_unit
[j
]];
5354 template = required_template
;
5356 if (curr
!= first
&& md
.slot
[curr
].label_fixups
)
5358 if (manual_bundling_on
)
5359 as_bad_where (md
.slot
[curr
].src_file
, md
.slot
[curr
].src_line
,
5360 "Label must be first in a bundle");
5361 /* This insn must go into the first slot of a bundle. */
5365 manual_bundling_on
= md
.slot
[curr
].manual_bundling_on
;
5366 manual_bundling_off
= md
.slot
[curr
].manual_bundling_off
;
5368 if (manual_bundling_on
)
5371 manual_bundling
= 1;
5373 break; /* need to start a new bundle */
5376 if (end_of_insn_group
&& md
.num_slots_in_use
>= 1)
5378 /* We need an instruction group boundary in the middle of a
5379 bundle. See if we can switch to an other template with
5380 an appropriate boundary. */
5382 orig_template
= template;
5383 if (i
== 1 && (user_template
== 4
5384 || (user_template
< 0
5385 && (ia64_templ_desc
[template].exec_unit
[0]
5389 end_of_insn_group
= 0;
5391 else if (i
== 2 && (user_template
== 0
5392 || (user_template
< 0
5393 && (ia64_templ_desc
[template].exec_unit
[1]
5395 /* This test makes sure we don't switch the template if
5396 the next instruction is one that needs to be first in
5397 an instruction group. Since all those instructions are
5398 in the M group, there is no way such an instruction can
5399 fit in this bundle even if we switch the template. The
5400 reason we have to check for this is that otherwise we
5401 may end up generating "MI;;I M.." which has the deadly
5402 effect that the second M instruction is no longer the
5403 first in the bundle! --davidm 99/12/16 */
5404 && (idesc
->flags
& IA64_OPCODE_FIRST
) == 0)
5407 end_of_insn_group
= 0;
5409 else if (curr
!= first
)
5410 /* can't fit this insn */
5413 if (template != orig_template
)
5414 /* if we switch the template, we need to reset the NOPs
5415 after slot i. The slot-types of the instructions ahead
5416 of i never change, so we don't need to worry about
5417 changing NOPs in front of this slot. */
5418 for (j
= i
; j
< 3; ++j
)
5419 insn
[j
] = nop
[ia64_templ_desc
[template].exec_unit
[j
]];
5421 required_unit
= ia64_templ_desc
[template].exec_unit
[i
];
5423 /* resolve dynamic opcodes such as "break" and "nop": */
5424 if (idesc
->type
== IA64_TYPE_DYN
)
5426 if ((strcmp (idesc
->name
, "nop") == 0)
5427 || (strcmp (idesc
->name
, "break") == 0))
5428 insn_unit
= required_unit
;
5429 else if (strcmp (idesc
->name
, "chk.s") == 0)
5431 insn_unit
= IA64_UNIT_M
;
5432 if (required_unit
== IA64_UNIT_I
)
5433 insn_unit
= IA64_UNIT_I
;
5436 as_fatal ("emit_one_bundle: unexpected dynamic op");
5438 sprintf (mnemonic
, "%s.%c", idesc
->name
, "?imbf??"[insn_unit
]);
5439 ia64_free_opcode (idesc
);
5440 md
.slot
[curr
].idesc
= idesc
= ia64_find_opcode (mnemonic
);
5442 know (!idesc
->next
); /* no resolved dynamic ops have collisions */
5447 insn_type
= idesc
->type
;
5448 insn_unit
= IA64_UNIT_NIL
;
5452 if (required_unit
== IA64_UNIT_I
|| required_unit
== IA64_UNIT_M
)
5453 insn_unit
= required_unit
;
5455 case IA64_TYPE_X
: insn_unit
= IA64_UNIT_L
; break;
5456 case IA64_TYPE_I
: insn_unit
= IA64_UNIT_I
; break;
5457 case IA64_TYPE_M
: insn_unit
= IA64_UNIT_M
; break;
5458 case IA64_TYPE_B
: insn_unit
= IA64_UNIT_B
; break;
5459 case IA64_TYPE_F
: insn_unit
= IA64_UNIT_F
; break;
5464 if (insn_unit
!= required_unit
)
5466 if (required_unit
== IA64_UNIT_L
5467 && insn_unit
== IA64_UNIT_I
5468 && !(idesc
->flags
& IA64_OPCODE_X_IN_MLX
))
5470 /* we got ourselves an MLX template but the current
5471 instruction isn't an X-unit, or an I-unit instruction
5472 that can go into the X slot of an MLX template. Duh. */
5473 if (md
.num_slots_in_use
>= NUM_SLOTS
)
5475 as_bad_where (md
.slot
[curr
].src_file
,
5476 md
.slot
[curr
].src_line
,
5477 "`%s' can't go in X slot of "
5478 "MLX template", idesc
->name
);
5479 /* drop this insn so we don't livelock: */
5480 --md
.num_slots_in_use
;
5484 continue; /* try next slot */
5487 if (debug_type
== DEBUG_DWARF2
)
5491 addr
= frag_now
->fr_address
+ frag_now_fix () - 16 + i
;
5492 dwarf2_gen_line_info (addr
, &md
.slot
[curr
].debug_line
);
5495 build_insn (md
.slot
+ curr
, insn
+ i
);
5497 /* Set slot counts for non prologue/body unwind records. */
5498 for (ptr
= md
.slot
[curr
].unwind_record
; ptr
; ptr
= ptr
->next
)
5499 if (ptr
->r
.type
!= prologue
&& ptr
->r
.type
!= prologue_gr
5500 && ptr
->r
.type
!= body
)
5501 ptr
->slot_number
= (unsigned long) f
+ i
;
5502 md
.slot
[curr
].unwind_record
= NULL
;
5503 unwind
.next_slot_number
= (unsigned long) f
+ i
+ ((i
== 2)?(0x10-2):1);
5505 if (required_unit
== IA64_UNIT_L
)
5508 /* skip one slot for long/X-unit instructions */
5511 --md
.num_slots_in_use
;
5513 /* now is a good time to fix up the labels for this insn: */
5514 for (lfix
= md
.slot
[curr
].label_fixups
; lfix
; lfix
= lfix
->next
)
5516 S_SET_VALUE (lfix
->sym
, frag_now_fix () - 16);
5517 symbol_set_frag (lfix
->sym
, frag_now
);
5519 /* and fix up the tags also. */
5520 for (lfix
= md
.slot
[curr
].tag_fixups
; lfix
; lfix
= lfix
->next
)
5522 S_SET_VALUE (lfix
->sym
, frag_now_fix () - 16 + i
);
5523 symbol_set_frag (lfix
->sym
, frag_now
);
5526 for (j
= 0; j
< md
.slot
[curr
].num_fixups
; ++j
)
5528 ifix
= md
.slot
[curr
].fixup
+ j
;
5529 fix
= fix_new_exp (frag_now
, frag_now_fix () - 16 + i
, 4,
5530 &ifix
->expr
, ifix
->is_pcrel
, ifix
->code
);
5531 fix
->tc_fix_data
.opnd
= ifix
->opnd
;
5532 fix
->fx_plt
= (fix
->fx_r_type
== BFD_RELOC_IA64_PLTOFF22
);
5533 fix
->fx_file
= md
.slot
[curr
].src_file
;
5534 fix
->fx_line
= md
.slot
[curr
].src_line
;
5537 end_of_insn_group
= md
.slot
[curr
].end_of_insn_group
;
5540 ia64_free_opcode (md
.slot
[curr
].idesc
);
5541 memset (md
.slot
+ curr
, 0, sizeof (md
.slot
[curr
]));
5542 md
.slot
[curr
].user_template
= -1;
5544 if (manual_bundling_off
)
5546 manual_bundling
= 0;
5549 curr
= (curr
+ 1) % NUM_SLOTS
;
5550 idesc
= md
.slot
[curr
].idesc
;
5552 if (manual_bundling
)
5554 if (md
.num_slots_in_use
> 0)
5555 as_bad_where (md
.slot
[curr
].src_file
, md
.slot
[curr
].src_line
,
5556 "`%s' does not fit into %s template",
5557 idesc
->name
, ia64_templ_desc
[template].name
);
5559 as_bad_where (md
.slot
[curr
].src_file
, md
.slot
[curr
].src_line
,
5560 "Missing '}' at end of file");
5562 know (md
.num_slots_in_use
< NUM_SLOTS
);
5564 t0
= end_of_insn_group
| (template << 1) | (insn
[0] << 5) | (insn
[1] << 46);
5565 t1
= ((insn
[1] >> 18) & 0x7fffff) | (insn
[2] << 23);
5567 number_to_chars_littleendian (f
+ 0, t0
, 8);
5568 number_to_chars_littleendian (f
+ 8, t1
, 8);
5572 md_parse_option (c
, arg
)
5578 /* Switches from the Intel assembler. */
5580 if (strcmp (arg
, "ilp64") == 0
5581 || strcmp (arg
, "lp64") == 0
5582 || strcmp (arg
, "p64") == 0)
5584 md
.flags
|= EF_IA_64_ABI64
;
5586 else if (strcmp (arg
, "ilp32") == 0)
5588 md
.flags
&= ~EF_IA_64_ABI64
;
5590 else if (strcmp (arg
, "le") == 0)
5592 md
.flags
&= ~EF_IA_64_BE
;
5594 else if (strcmp (arg
, "be") == 0)
5596 md
.flags
|= EF_IA_64_BE
;
5603 if (strcmp (arg
, "so") == 0)
5605 /* Suppress signon message. */
5607 else if (strcmp (arg
, "pi") == 0)
5609 /* Reject privileged instructions. FIXME */
5611 else if (strcmp (arg
, "us") == 0)
5613 /* Allow union of signed and unsigned range. FIXME */
5615 else if (strcmp (arg
, "close_fcalls") == 0)
5617 /* Do not resolve global function calls. */
5624 /* temp[="prefix"] Insert temporary labels into the object file
5625 symbol table prefixed by "prefix".
5626 Default prefix is ":temp:".
5631 /* ??? Conflicts with gas' listing option. */
5632 /* indirect=<tgt> Assume unannotated indirect branches behavior
5633 according to <tgt> --
5634 exit: branch out from the current context (default)
5635 labels: all labels in context may be branch targets
5640 /* -X conflicts with an ignored option, use -x instead */
5642 if (!arg
|| strcmp (arg
, "explicit") == 0)
5644 /* set default mode to explicit */
5645 md
.default_explicit_mode
= 1;
5648 else if (strcmp (arg
, "auto") == 0)
5650 md
.default_explicit_mode
= 0;
5652 else if (strcmp (arg
, "debug") == 0)
5656 else if (strcmp (arg
, "debugx") == 0)
5658 md
.default_explicit_mode
= 1;
5663 as_bad (_("Unrecognized option '-x%s'"), arg
);
5668 /* nops Print nops statistics. */
5671 /* GNU specific switches for gcc. */
5672 case OPTION_MCONSTANT_GP
:
5673 md
.flags
|= EF_IA_64_CONS_GP
;
5676 case OPTION_MAUTO_PIC
:
5677 md
.flags
|= EF_IA_64_NOFUNCDESC_CONS_GP
;
5688 md_show_usage (stream
)
5693 -milp32|-milp64|-mlp64|-mp64 select data model (default -mlp64)\n\
5694 -mle | -mbe select little- or big-endian byte order (default -mle)\n\
5695 -x | -xexplicit turn on dependency violation checking (default)\n\
5696 -xauto automagically remove dependency violations\n\
5697 -xdebug debug dependency violation checker\n"),
5701 /* Return true if TYPE fits in TEMPL at SLOT. */
5704 match (int templ
, int type
, int slot
)
5706 enum ia64_unit unit
;
5709 unit
= ia64_templ_desc
[templ
].exec_unit
[slot
];
5712 case IA64_TYPE_DYN
: result
= 1; break; /* for nop and break */
5714 result
= (unit
== IA64_UNIT_I
|| unit
== IA64_UNIT_M
);
5716 case IA64_TYPE_X
: result
= (unit
== IA64_UNIT_L
); break;
5717 case IA64_TYPE_I
: result
= (unit
== IA64_UNIT_I
); break;
5718 case IA64_TYPE_M
: result
= (unit
== IA64_UNIT_M
); break;
5719 case IA64_TYPE_B
: result
= (unit
== IA64_UNIT_B
); break;
5720 case IA64_TYPE_F
: result
= (unit
== IA64_UNIT_F
); break;
5721 default: result
= 0; break;
5726 /* Add a bit of extra goodness if a nop of type F or B would fit
5727 in TEMPL at SLOT. */
5730 extra_goodness (int templ
, int slot
)
5732 if (slot
== 1 && match (templ
, IA64_TYPE_F
, slot
))
5734 if (slot
== 2 && match (templ
, IA64_TYPE_B
, slot
))
5739 /* This function is called once, at assembler startup time. It sets
5740 up all the tables, etc. that the MD part of the assembler will need
5741 that can be determined before arguments are parsed. */
5745 int i
, j
, k
, t
, total
, ar_base
, cr_base
, goodness
, best
, regnum
, ok
;
5750 md
.explicit_mode
= md
.default_explicit_mode
;
5752 bfd_set_section_alignment (stdoutput
, text_section
, 4);
5754 target_big_endian
= TARGET_BYTES_BIG_ENDIAN
;
5755 pseudo_func
[FUNC_FPTR_RELATIVE
].u
.sym
=
5756 symbol_new (".<fptr>", undefined_section
, FUNC_FPTR_RELATIVE
,
5757 &zero_address_frag
);
5759 pseudo_func
[FUNC_GP_RELATIVE
].u
.sym
=
5760 symbol_new (".<gprel>", undefined_section
, FUNC_GP_RELATIVE
,
5761 &zero_address_frag
);
5763 pseudo_func
[FUNC_LT_RELATIVE
].u
.sym
=
5764 symbol_new (".<ltoff>", undefined_section
, FUNC_LT_RELATIVE
,
5765 &zero_address_frag
);
5767 pseudo_func
[FUNC_PC_RELATIVE
].u
.sym
=
5768 symbol_new (".<pcrel>", undefined_section
, FUNC_PC_RELATIVE
,
5769 &zero_address_frag
);
5771 pseudo_func
[FUNC_PLT_RELATIVE
].u
.sym
=
5772 symbol_new (".<pltoff>", undefined_section
, FUNC_PLT_RELATIVE
,
5773 &zero_address_frag
);
5775 pseudo_func
[FUNC_SEC_RELATIVE
].u
.sym
=
5776 symbol_new (".<secrel>", undefined_section
, FUNC_SEC_RELATIVE
,
5777 &zero_address_frag
);
5779 pseudo_func
[FUNC_SEG_RELATIVE
].u
.sym
=
5780 symbol_new (".<segrel>", undefined_section
, FUNC_SEG_RELATIVE
,
5781 &zero_address_frag
);
5783 pseudo_func
[FUNC_LTV_RELATIVE
].u
.sym
=
5784 symbol_new (".<ltv>", undefined_section
, FUNC_LTV_RELATIVE
,
5785 &zero_address_frag
);
5787 pseudo_func
[FUNC_LT_FPTR_RELATIVE
].u
.sym
=
5788 symbol_new (".<ltoff.fptr>", undefined_section
, FUNC_LT_FPTR_RELATIVE
,
5789 &zero_address_frag
);
5791 /* Compute the table of best templates. We compute goodness as a
5792 base 4 value, in which each match counts for 3, each F counts
5793 for 2, each B counts for 1. This should maximize the number of
5794 F and B nops in the chosen bundles, which is good because these
5795 pipelines are least likely to be overcommitted. */
5796 for (i
= 0; i
< IA64_NUM_TYPES
; ++i
)
5797 for (j
= 0; j
< IA64_NUM_TYPES
; ++j
)
5798 for (k
= 0; k
< IA64_NUM_TYPES
; ++k
)
5801 for (t
= 0; t
< NELEMS (ia64_templ_desc
); ++t
)
5804 if (match (t
, i
, 0))
5806 if (match (t
, j
, 1))
5808 if (match (t
, k
, 2))
5809 goodness
= 3 + 3 + 3;
5811 goodness
= 3 + 3 + extra_goodness (t
, 2);
5813 else if (match (t
, j
, 2))
5814 goodness
= 3 + 3 + extra_goodness (t
, 1);
5818 goodness
+= extra_goodness (t
, 1);
5819 goodness
+= extra_goodness (t
, 2);
5822 else if (match (t
, i
, 1))
5824 if (match (t
, j
, 2))
5827 goodness
= 3 + extra_goodness (t
, 2);
5829 else if (match (t
, i
, 2))
5830 goodness
= 3 + extra_goodness (t
, 1);
5832 if (goodness
> best
)
5835 best_template
[i
][j
][k
] = t
;
5840 for (i
= 0; i
< NUM_SLOTS
; ++i
)
5841 md
.slot
[i
].user_template
= -1;
5843 md
.pseudo_hash
= hash_new ();
5844 for (i
= 0; i
< NELEMS (pseudo_opcode
); ++i
)
5846 err
= hash_insert (md
.pseudo_hash
, pseudo_opcode
[i
].name
,
5847 (void *) (pseudo_opcode
+ i
));
5849 as_fatal ("ia64.md_begin: can't hash `%s': %s",
5850 pseudo_opcode
[i
].name
, err
);
5853 md
.reg_hash
= hash_new ();
5854 md
.dynreg_hash
= hash_new ();
5855 md
.const_hash
= hash_new ();
5856 md
.entry_hash
= hash_new ();
5858 /* general registers: */
5861 for (i
= 0; i
< total
; ++i
)
5863 sprintf (name
, "r%d", i
- REG_GR
);
5864 md
.regsym
[i
] = declare_register (name
, i
);
5867 /* floating point registers: */
5869 for (; i
< total
; ++i
)
5871 sprintf (name
, "f%d", i
- REG_FR
);
5872 md
.regsym
[i
] = declare_register (name
, i
);
5875 /* application registers: */
5878 for (; i
< total
; ++i
)
5880 sprintf (name
, "ar%d", i
- REG_AR
);
5881 md
.regsym
[i
] = declare_register (name
, i
);
5884 /* control registers: */
5887 for (; i
< total
; ++i
)
5889 sprintf (name
, "cr%d", i
- REG_CR
);
5890 md
.regsym
[i
] = declare_register (name
, i
);
5893 /* predicate registers: */
5895 for (; i
< total
; ++i
)
5897 sprintf (name
, "p%d", i
- REG_P
);
5898 md
.regsym
[i
] = declare_register (name
, i
);
5901 /* branch registers: */
5903 for (; i
< total
; ++i
)
5905 sprintf (name
, "b%d", i
- REG_BR
);
5906 md
.regsym
[i
] = declare_register (name
, i
);
5909 md
.regsym
[REG_IP
] = declare_register ("ip", REG_IP
);
5910 md
.regsym
[REG_CFM
] = declare_register ("cfm", REG_CFM
);
5911 md
.regsym
[REG_PR
] = declare_register ("pr", REG_PR
);
5912 md
.regsym
[REG_PR_ROT
] = declare_register ("pr.rot", REG_PR_ROT
);
5913 md
.regsym
[REG_PSR
] = declare_register ("psr", REG_PSR
);
5914 md
.regsym
[REG_PSR_L
] = declare_register ("psr.l", REG_PSR_L
);
5915 md
.regsym
[REG_PSR_UM
] = declare_register ("psr.um", REG_PSR_UM
);
5917 for (i
= 0; i
< NELEMS (indirect_reg
); ++i
)
5919 regnum
= indirect_reg
[i
].regnum
;
5920 md
.regsym
[regnum
] = declare_register (indirect_reg
[i
].name
, regnum
);
5923 /* define synonyms for application registers: */
5924 for (i
= REG_AR
; i
< REG_AR
+ NELEMS (ar
); ++i
)
5925 md
.regsym
[i
] = declare_register (ar
[i
- REG_AR
].name
,
5926 REG_AR
+ ar
[i
- REG_AR
].regnum
);
5928 /* define synonyms for control registers: */
5929 for (i
= REG_CR
; i
< REG_CR
+ NELEMS (cr
); ++i
)
5930 md
.regsym
[i
] = declare_register (cr
[i
- REG_CR
].name
,
5931 REG_CR
+ cr
[i
- REG_CR
].regnum
);
5933 declare_register ("gp", REG_GR
+ 1);
5934 declare_register ("sp", REG_GR
+ 12);
5935 declare_register ("rp", REG_BR
+ 0);
5937 /* pseudo-registers used to specify unwind info: */
5938 declare_register ("psp", REG_PSP
);
5940 declare_register_set ("ret", 4, REG_GR
+ 8);
5941 declare_register_set ("farg", 8, REG_FR
+ 8);
5942 declare_register_set ("fret", 8, REG_FR
+ 8);
5944 for (i
= 0; i
< NELEMS (const_bits
); ++i
)
5946 err
= hash_insert (md
.const_hash
, const_bits
[i
].name
,
5947 (PTR
) (const_bits
+ i
));
5949 as_fatal ("Inserting \"%s\" into constant hash table failed: %s",
5953 /* Set the architecture and machine depending on defaults and command line
5955 if (md
.flags
& EF_IA_64_ABI64
)
5956 ok
= bfd_set_arch_mach (stdoutput
, bfd_arch_ia64
, bfd_mach_ia64_elf64
);
5958 ok
= bfd_set_arch_mach (stdoutput
, bfd_arch_ia64
, bfd_mach_ia64_elf32
);
5961 as_warn (_("Could not set architecture and machine"));
5963 md
.mem_offset
.hint
= 0;
5966 md
.entry_labels
= NULL
;
5969 /* Set the elf type to 64 bit ABI by default. Cannot do this in md_begin
5970 because that is called after md_parse_option which is where we do the
5971 dynamic changing of md.flags based on -mlp64 or -milp32. Also, set the
5972 default endianness. */
5975 ia64_init (argc
, argv
)
5979 md
.flags
= EF_IA_64_ABI64
;
5980 if (TARGET_BYTES_BIG_ENDIAN
)
5981 md
.flags
|= EF_IA_64_BE
;
5984 /* Return a string for the target object file format. */
5987 ia64_target_format ()
5989 if (OUTPUT_FLAVOR
== bfd_target_elf_flavour
)
5991 if (md
.flags
& EF_IA_64_ABI64
)
5992 return "elf64-ia64-big";
5994 return "elf32-ia64-big";
5997 return "unknown-format";
6001 ia64_end_of_source ()
6003 /* terminate insn group upon reaching end of file: */
6004 insn_group_break (1, 0, 0);
6006 /* emits slots we haven't written yet: */
6007 ia64_flush_insns ();
6009 bfd_set_private_flags (stdoutput
, md
.flags
);
6011 if (debug_type
== DEBUG_DWARF2
)
6014 md
.mem_offset
.hint
= 0;
6020 if (md
.qp
.X_op
== O_register
)
6021 as_bad ("qualifying predicate not followed by instruction");
6022 md
.qp
.X_op
= O_absent
;
6024 if (ignore_input ())
6027 if (input_line_pointer
[0] == ';' && input_line_pointer
[-1] == ';')
6029 if (md
.detect_dv
&& !md
.explicit_mode
)
6030 as_warn (_("Explicit stops are ignored in auto mode"));
6032 insn_group_break (1, 0, 0);
6036 /* This is a hook for ia64_frob_label, so that it can distinguish tags from
6038 static int defining_tag
= 0;
6041 ia64_unrecognized_line (ch
)
6047 expression (&md
.qp
);
6048 if (*input_line_pointer
++ != ')')
6050 as_bad ("Expected ')'");
6053 if (md
.qp
.X_op
!= O_register
)
6055 as_bad ("Qualifying predicate expected");
6058 if (md
.qp
.X_add_number
< REG_P
|| md
.qp
.X_add_number
>= REG_P
+ 64)
6060 as_bad ("Predicate register expected");
6066 if (md
.manual_bundling
)
6067 as_warn ("Found '{' when manual bundling is already turned on");
6069 CURR_SLOT
.manual_bundling_on
= 1;
6070 md
.manual_bundling
= 1;
6072 /* Bundling is only acceptable in explicit mode
6073 or when in default automatic mode. */
6074 if (md
.detect_dv
&& !md
.explicit_mode
)
6076 if (!md
.mode_explicitly_set
6077 && !md
.default_explicit_mode
)
6080 as_warn (_("Found '{' after explicit switch to automatic mode"));
6085 if (!md
.manual_bundling
)
6086 as_warn ("Found '}' when manual bundling is off");
6088 PREV_SLOT
.manual_bundling_off
= 1;
6089 md
.manual_bundling
= 0;
6091 /* switch back to automatic mode, if applicable */
6094 && !md
.mode_explicitly_set
6095 && !md
.default_explicit_mode
)
6098 /* Allow '{' to follow on the same line. We also allow ";;", but that
6099 happens automatically because ';' is an end of line marker. */
6101 if (input_line_pointer
[0] == '{')
6103 input_line_pointer
++;
6104 return ia64_unrecognized_line ('{');
6107 demand_empty_rest_of_line ();
6116 if (md
.qp
.X_op
== O_register
)
6118 as_bad ("Tag must come before qualifying predicate.");
6121 s
= input_line_pointer
;
6122 c
= get_symbol_end ();
6125 /* Put ':' back for error messages' sake. */
6126 *input_line_pointer
++ = ':';
6127 as_bad ("Expected ':'");
6133 /* Put ':' back for error messages' sake. */
6134 *input_line_pointer
++ = ':';
6135 if (*input_line_pointer
++ != ']')
6137 as_bad ("Expected ']'");
6142 as_bad ("Tag name expected");
6152 /* Not a valid line. */
6157 ia64_frob_label (sym
)
6160 struct label_fix
*fix
;
6162 /* Tags need special handling since they are not bundle breaks like
6166 fix
= obstack_alloc (¬es
, sizeof (*fix
));
6168 fix
->next
= CURR_SLOT
.tag_fixups
;
6169 CURR_SLOT
.tag_fixups
= fix
;
6174 if (bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
)
6176 md
.last_text_seg
= now_seg
;
6177 fix
= obstack_alloc (¬es
, sizeof (*fix
));
6179 fix
->next
= CURR_SLOT
.label_fixups
;
6180 CURR_SLOT
.label_fixups
= fix
;
6182 /* Keep track of how many code entry points we've seen. */
6183 if (md
.path
== md
.maxpaths
)
6186 md
.entry_labels
= (const char **)
6187 xrealloc ((void *) md
.entry_labels
,
6188 md
.maxpaths
* sizeof (char *));
6190 md
.entry_labels
[md
.path
++] = S_GET_NAME (sym
);
6195 ia64_flush_pending_output ()
6197 if (bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
)
6199 /* ??? This causes many unnecessary stop bits to be emitted.
6200 Unfortunately, it isn't clear if it is safe to remove this. */
6201 insn_group_break (1, 0, 0);
6202 ia64_flush_insns ();
6206 /* Do ia64-specific expression optimization. All that's done here is
6207 to transform index expressions that are either due to the indexing
6208 of rotating registers or due to the indexing of indirect register
6211 ia64_optimize_expr (l
, op
, r
)
6220 if (l
->X_op
== O_register
&& r
->X_op
== O_constant
)
6222 num_regs
= (l
->X_add_number
>> 16);
6223 if ((unsigned) r
->X_add_number
>= num_regs
)
6226 as_bad ("No current frame");
6228 as_bad ("Index out of range 0..%u", num_regs
- 1);
6229 r
->X_add_number
= 0;
6231 l
->X_add_number
= (l
->X_add_number
& 0xffff) + r
->X_add_number
;
6234 else if (l
->X_op
== O_register
&& r
->X_op
== O_register
)
6236 if (l
->X_add_number
< IND_CPUID
|| l
->X_add_number
> IND_RR
6237 || l
->X_add_number
== IND_MEM
)
6239 as_bad ("Indirect register set name expected");
6240 l
->X_add_number
= IND_CPUID
;
6243 l
->X_op_symbol
= md
.regsym
[l
->X_add_number
];
6244 l
->X_add_number
= r
->X_add_number
;
6252 ia64_parse_name (name
, e
)
6256 struct const_desc
*cdesc
;
6257 struct dynreg
*dr
= 0;
6258 unsigned int regnum
;
6262 /* first see if NAME is a known register name: */
6263 sym
= hash_find (md
.reg_hash
, name
);
6266 e
->X_op
= O_register
;
6267 e
->X_add_number
= S_GET_VALUE (sym
);
6271 cdesc
= hash_find (md
.const_hash
, name
);
6274 e
->X_op
= O_constant
;
6275 e
->X_add_number
= cdesc
->value
;
6279 /* check for inN, locN, or outN: */
6283 if (name
[1] == 'n' && isdigit (name
[2]))
6291 if (name
[1] == 'o' && name
[2] == 'c' && isdigit (name
[3]))
6299 if (name
[1] == 'u' && name
[2] == 't' && isdigit (name
[3]))
6312 /* The name is inN, locN, or outN; parse the register number. */
6313 regnum
= strtoul (name
, &end
, 10);
6314 if (end
> name
&& *end
== '\0')
6316 if ((unsigned) regnum
>= dr
->num_regs
)
6319 as_bad ("No current frame");
6321 as_bad ("Register number out of range 0..%u",
6325 e
->X_op
= O_register
;
6326 e
->X_add_number
= dr
->base
+ regnum
;
6331 if ((dr
= hash_find (md
.dynreg_hash
, name
)))
6333 /* We've got ourselves the name of a rotating register set.
6334 Store the base register number in the low 16 bits of
6335 X_add_number and the size of the register set in the top 16
6337 e
->X_op
= O_register
;
6338 e
->X_add_number
= dr
->base
| (dr
->num_regs
<< 16);
6344 /* Remove the '#' suffix that indicates a symbol as opposed to a register. */
6347 ia64_canonicalize_symbol_name (name
)
6350 size_t len
= strlen (name
);
6351 if (len
> 1 && name
[len
- 1] == '#')
6352 name
[len
- 1] = '\0';
6357 is_conditional_branch (idesc
)
6358 struct ia64_opcode
*idesc
;
6360 return (strncmp (idesc
->name
, "br", 2) == 0
6361 && (strcmp (idesc
->name
, "br") == 0
6362 || strncmp (idesc
->name
, "br.cond", 7) == 0
6363 || strncmp (idesc
->name
, "br.call", 7) == 0
6364 || strncmp (idesc
->name
, "br.ret", 6) == 0
6365 || strcmp (idesc
->name
, "brl") == 0
6366 || strncmp (idesc
->name
, "brl.cond", 7) == 0
6367 || strncmp (idesc
->name
, "brl.call", 7) == 0
6368 || strncmp (idesc
->name
, "brl.ret", 6) == 0));
6371 /* Return whether the given opcode is a taken branch. If there's any doubt,
6375 is_taken_branch (idesc
)
6376 struct ia64_opcode
*idesc
;
6378 return ((is_conditional_branch (idesc
) && CURR_SLOT
.qp_regno
== 0)
6379 || strncmp (idesc
->name
, "br.ia", 5) == 0);
6382 /* Return whether the given opcode is an interruption or rfi. If there's any
6383 doubt, returns zero. */
6386 is_interruption_or_rfi (idesc
)
6387 struct ia64_opcode
*idesc
;
6389 if (strcmp (idesc
->name
, "rfi") == 0)
6394 /* Returns the index of the given dependency in the opcode's list of chks, or
6395 -1 if there is no dependency. */
6398 depends_on (depind
, idesc
)
6400 struct ia64_opcode
*idesc
;
6403 const struct ia64_opcode_dependency
*dep
= idesc
->dependencies
;
6404 for (i
= 0; i
< dep
->nchks
; i
++)
6406 if (depind
== DEP (dep
->chks
[i
]))
6412 /* Determine a set of specific resources used for a particular resource
6413 class. Returns the number of specific resources identified For those
6414 cases which are not determinable statically, the resource returned is
6417 Meanings of value in 'NOTE':
6418 1) only read/write when the register number is explicitly encoded in the
6420 2) only read CFM when accessing a rotating GR, FR, or PR. mov pr only
6421 accesses CFM when qualifying predicate is in the rotating region.
6422 3) general register value is used to specify an indirect register; not
6423 determinable statically.
6424 4) only read the given resource when bits 7:0 of the indirect index
6425 register value does not match the register number of the resource; not
6426 determinable statically.
6427 5) all rules are implementation specific.
6428 6) only when both the index specified by the reader and the index specified
6429 by the writer have the same value in bits 63:61; not determinable
6431 7) only access the specified resource when the corresponding mask bit is
6433 8) PSR.dfh is only read when these insns reference FR32-127. PSR.dfl is
6434 only read when these insns reference FR2-31
6435 9) PSR.mfl is only written when these insns write FR2-31. PSR.mfh is only
6436 written when these insns write FR32-127
6437 10) The PSR.bn bit is only accessed when one of GR16-31 is specified in the
6439 11) The target predicates are written independently of PR[qp], but source
6440 registers are only read if PR[qp] is true. Since the state of PR[qp]
6441 cannot statically be determined, all source registers are marked used.
6442 12) This insn only reads the specified predicate register when that
6443 register is the PR[qp].
6444 13) This reference to ld-c only applies to teh GR whose value is loaded
6445 with data returned from memory, not the post-incremented address register.
6446 14) The RSE resource includes the implementation-specific RSE internal
6447 state resources. At least one (and possibly more) of these resources are
6448 read by each instruction listed in IC:rse-readers. At least one (and
6449 possibly more) of these resources are written by each insn listed in
6451 15+16) Represents reserved instructions, which the assembler does not
6454 Memory resources (i.e. locations in memory) are *not* marked or tracked by
6455 this code; there are no dependency violations based on memory access.
6458 #define MAX_SPECS 256
6463 specify_resource (dep
, idesc
, type
, specs
, note
, path
)
6464 const struct ia64_dependency
*dep
;
6465 struct ia64_opcode
*idesc
;
6466 int type
; /* is this a DV chk or a DV reg? */
6467 struct rsrc specs
[MAX_SPECS
]; /* returned specific resources */
6468 int note
; /* resource note for this insn's usage */
6469 int path
; /* which execution path to examine */
6476 if (dep
->mode
== IA64_DV_WAW
6477 || (dep
->mode
== IA64_DV_RAW
&& type
== DV_REG
)
6478 || (dep
->mode
== IA64_DV_WAR
&& type
== DV_CHK
))
6481 /* template for any resources we identify */
6482 tmpl
.dependency
= dep
;
6484 tmpl
.insn_srlz
= tmpl
.data_srlz
= 0;
6485 tmpl
.qp_regno
= CURR_SLOT
.qp_regno
;
6486 tmpl
.link_to_qp_branch
= 1;
6487 tmpl
.mem_offset
.hint
= 0;
6490 tmpl
.cmp_type
= CMP_NONE
;
6493 as_warn (_("Unhandled dependency %s for %s (%s), note %d"), \
6494 dep->name, idesc->name, (rsrc_write?"write":"read"), note)
6495 #define KNOWN(REG) (gr_values[REG].known && gr_values[REG].path >= path)
6497 /* we don't need to track these */
6498 if (dep
->semantics
== IA64_DVS_NONE
)
6501 switch (dep
->specifier
)
6506 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_AR3
)
6508 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_AR
;
6509 if (regno
>= 0 && regno
<= 7)
6511 specs
[count
] = tmpl
;
6512 specs
[count
++].index
= regno
;
6518 for (i
= 0; i
< 8; i
++)
6520 specs
[count
] = tmpl
;
6521 specs
[count
++].index
= i
;
6530 case IA64_RS_AR_UNAT
:
6531 /* This is a mov =AR or mov AR= instruction. */
6532 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_AR3
)
6534 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_AR
;
6535 if (regno
== AR_UNAT
)
6537 specs
[count
++] = tmpl
;
6542 /* This is a spill/fill, or other instruction that modifies the
6545 /* Unless we can determine the specific bits used, mark the whole
6546 thing; bits 8:3 of the memory address indicate the bit used in
6547 UNAT. The .mem.offset hint may be used to eliminate a small
6548 subset of conflicts. */
6549 specs
[count
] = tmpl
;
6550 if (md
.mem_offset
.hint
)
6553 fprintf (stderr
, " Using hint for spill/fill\n");
6554 /* The index isn't actually used, just set it to something
6555 approximating the bit index. */
6556 specs
[count
].index
= (md
.mem_offset
.offset
>> 3) & 0x3F;
6557 specs
[count
].mem_offset
.hint
= 1;
6558 specs
[count
].mem_offset
.offset
= md
.mem_offset
.offset
;
6559 specs
[count
++].mem_offset
.base
= md
.mem_offset
.base
;
6563 specs
[count
++].specific
= 0;
6571 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_AR3
)
6573 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_AR
;
6574 if ((regno
>= 8 && regno
<= 15)
6575 || (regno
>= 20 && regno
<= 23)
6576 || (regno
>= 31 && regno
<= 39)
6577 || (regno
>= 41 && regno
<= 47)
6578 || (regno
>= 67 && regno
<= 111))
6580 specs
[count
] = tmpl
;
6581 specs
[count
++].index
= regno
;
6594 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_AR3
)
6596 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_AR
;
6597 if ((regno
>= 48 && regno
<= 63)
6598 || (regno
>= 112 && regno
<= 127))
6600 specs
[count
] = tmpl
;
6601 specs
[count
++].index
= regno
;
6607 for (i
= 48; i
< 64; i
++)
6609 specs
[count
] = tmpl
;
6610 specs
[count
++].index
= i
;
6612 for (i
= 112; i
< 128; i
++)
6614 specs
[count
] = tmpl
;
6615 specs
[count
++].index
= i
;
6633 for (i
= 0; i
< idesc
->num_outputs
; i
++)
6634 if (idesc
->operands
[i
] == IA64_OPND_B1
6635 || idesc
->operands
[i
] == IA64_OPND_B2
)
6637 specs
[count
] = tmpl
;
6638 specs
[count
++].index
=
6639 CURR_SLOT
.opnd
[i
].X_add_number
- REG_BR
;
6644 for (i
= idesc
->num_outputs
;i
< NELEMS (idesc
->operands
); i
++)
6645 if (idesc
->operands
[i
] == IA64_OPND_B1
6646 || idesc
->operands
[i
] == IA64_OPND_B2
)
6648 specs
[count
] = tmpl
;
6649 specs
[count
++].index
=
6650 CURR_SLOT
.opnd
[i
].X_add_number
- REG_BR
;
6656 case IA64_RS_CPUID
: /* four or more registers */
6659 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_CPUID_R3
)
6661 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_GR
;
6662 if (regno
>= 0 && regno
< NELEMS (gr_values
)
6665 specs
[count
] = tmpl
;
6666 specs
[count
++].index
= gr_values
[regno
].value
& 0xFF;
6670 specs
[count
] = tmpl
;
6671 specs
[count
++].specific
= 0;
6681 case IA64_RS_DBR
: /* four or more registers */
6684 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_DBR_R3
)
6686 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_GR
;
6687 if (regno
>= 0 && regno
< NELEMS (gr_values
)
6690 specs
[count
] = tmpl
;
6691 specs
[count
++].index
= gr_values
[regno
].value
& 0xFF;
6695 specs
[count
] = tmpl
;
6696 specs
[count
++].specific
= 0;
6700 else if (note
== 0 && !rsrc_write
)
6702 specs
[count
] = tmpl
;
6703 specs
[count
++].specific
= 0;
6711 case IA64_RS_IBR
: /* four or more registers */
6714 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_IBR_R3
)
6716 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_GR
;
6717 if (regno
>= 0 && regno
< NELEMS (gr_values
)
6720 specs
[count
] = tmpl
;
6721 specs
[count
++].index
= gr_values
[regno
].value
& 0xFF;
6725 specs
[count
] = tmpl
;
6726 specs
[count
++].specific
= 0;
6739 /* These are implementation specific. Force all references to
6740 conflict with all other references. */
6741 specs
[count
] = tmpl
;
6742 specs
[count
++].specific
= 0;
6750 case IA64_RS_PKR
: /* 16 or more registers */
6751 if (note
== 3 || note
== 4)
6753 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_PKR_R3
)
6755 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_GR
;
6756 if (regno
>= 0 && regno
< NELEMS (gr_values
)
6761 specs
[count
] = tmpl
;
6762 specs
[count
++].index
= gr_values
[regno
].value
& 0xFF;
6765 for (i
= 0; i
< NELEMS (gr_values
); i
++)
6767 /* Uses all registers *except* the one in R3. */
6768 if (i
!= (gr_values
[regno
].value
& 0xFF))
6770 specs
[count
] = tmpl
;
6771 specs
[count
++].index
= i
;
6777 specs
[count
] = tmpl
;
6778 specs
[count
++].specific
= 0;
6785 specs
[count
] = tmpl
;
6786 specs
[count
++].specific
= 0;
6790 case IA64_RS_PMC
: /* four or more registers */
6793 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_PMC_R3
6794 || (!rsrc_write
&& idesc
->operands
[1] == IA64_OPND_PMD_R3
))
6797 int index
= ((idesc
->operands
[1] == IA64_OPND_R3
&& !rsrc_write
)
6799 int regno
= CURR_SLOT
.opnd
[index
].X_add_number
- REG_GR
;
6800 if (regno
>= 0 && regno
< NELEMS (gr_values
)
6803 specs
[count
] = tmpl
;
6804 specs
[count
++].index
= gr_values
[regno
].value
& 0xFF;
6808 specs
[count
] = tmpl
;
6809 specs
[count
++].specific
= 0;
6819 case IA64_RS_PMD
: /* four or more registers */
6822 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_PMD_R3
)
6824 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_GR
;
6825 if (regno
>= 0 && regno
< NELEMS (gr_values
)
6828 specs
[count
] = tmpl
;
6829 specs
[count
++].index
= gr_values
[regno
].value
& 0xFF;
6833 specs
[count
] = tmpl
;
6834 specs
[count
++].specific
= 0;
6844 case IA64_RS_RR
: /* eight registers */
6847 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_RR_R3
)
6849 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_GR
;
6850 if (regno
>= 0 && regno
< NELEMS (gr_values
)
6853 specs
[count
] = tmpl
;
6854 specs
[count
++].index
= (gr_values
[regno
].value
>> 61) & 0x7;
6858 specs
[count
] = tmpl
;
6859 specs
[count
++].specific
= 0;
6863 else if (note
== 0 && !rsrc_write
)
6865 specs
[count
] = tmpl
;
6866 specs
[count
++].specific
= 0;
6874 case IA64_RS_CR_IRR
:
6877 /* handle mov-from-CR-IVR; it's a read that writes CR[IRR] */
6878 int regno
= CURR_SLOT
.opnd
[1].X_add_number
- REG_CR
;
6880 && idesc
->operands
[1] == IA64_OPND_CR3
6883 for (i
= 0; i
< 4; i
++)
6885 specs
[count
] = tmpl
;
6886 specs
[count
++].index
= CR_IRR0
+ i
;
6892 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_CR
;
6893 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_CR3
6895 && regno
<= CR_IRR3
)
6897 specs
[count
] = tmpl
;
6898 specs
[count
++].index
= regno
;
6907 case IA64_RS_CR_LRR
:
6914 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_CR
;
6915 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_CR3
6916 && (regno
== CR_LRR0
|| regno
== CR_LRR1
))
6918 specs
[count
] = tmpl
;
6919 specs
[count
++].index
= regno
;
6927 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_CR3
)
6929 specs
[count
] = tmpl
;
6930 specs
[count
++].index
=
6931 CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_CR
;
6946 else if (rsrc_write
)
6948 if (dep
->specifier
== IA64_RS_FRb
6949 && idesc
->operands
[0] == IA64_OPND_F1
)
6951 specs
[count
] = tmpl
;
6952 specs
[count
++].index
= CURR_SLOT
.opnd
[0].X_add_number
- REG_FR
;
6957 for (i
= idesc
->num_outputs
; i
< NELEMS (idesc
->operands
); i
++)
6959 if (idesc
->operands
[i
] == IA64_OPND_F2
6960 || idesc
->operands
[i
] == IA64_OPND_F3
6961 || idesc
->operands
[i
] == IA64_OPND_F4
)
6963 specs
[count
] = tmpl
;
6964 specs
[count
++].index
=
6965 CURR_SLOT
.opnd
[i
].X_add_number
- REG_FR
;
6974 /* This reference applies only to the GR whose value is loaded with
6975 data returned from memory. */
6976 specs
[count
] = tmpl
;
6977 specs
[count
++].index
= CURR_SLOT
.opnd
[0].X_add_number
- REG_GR
;
6983 for (i
= 0; i
< idesc
->num_outputs
; i
++)
6984 if (idesc
->operands
[i
] == IA64_OPND_R1
6985 || idesc
->operands
[i
] == IA64_OPND_R2
6986 || idesc
->operands
[i
] == IA64_OPND_R3
)
6988 specs
[count
] = tmpl
;
6989 specs
[count
++].index
=
6990 CURR_SLOT
.opnd
[i
].X_add_number
- REG_GR
;
6992 if (idesc
->flags
& IA64_OPCODE_POSTINC
)
6993 for (i
= 0; i
< NELEMS (idesc
->operands
); i
++)
6994 if (idesc
->operands
[i
] == IA64_OPND_MR3
)
6996 specs
[count
] = tmpl
;
6997 specs
[count
++].index
=
6998 CURR_SLOT
.opnd
[i
].X_add_number
- REG_GR
;
7003 /* Look for anything that reads a GR. */
7004 for (i
= 0; i
< NELEMS (idesc
->operands
); i
++)
7006 if (idesc
->operands
[i
] == IA64_OPND_MR3
7007 || idesc
->operands
[i
] == IA64_OPND_CPUID_R3
7008 || idesc
->operands
[i
] == IA64_OPND_DBR_R3
7009 || idesc
->operands
[i
] == IA64_OPND_IBR_R3
7010 || idesc
->operands
[i
] == IA64_OPND_MSR_R3
7011 || idesc
->operands
[i
] == IA64_OPND_PKR_R3
7012 || idesc
->operands
[i
] == IA64_OPND_PMC_R3
7013 || idesc
->operands
[i
] == IA64_OPND_PMD_R3
7014 || idesc
->operands
[i
] == IA64_OPND_RR_R3
7015 || ((i
>= idesc
->num_outputs
)
7016 && (idesc
->operands
[i
] == IA64_OPND_R1
7017 || idesc
->operands
[i
] == IA64_OPND_R2
7018 || idesc
->operands
[i
] == IA64_OPND_R3
7019 /* addl source register. */
7020 || idesc
->operands
[i
] == IA64_OPND_R3_2
)))
7022 specs
[count
] = tmpl
;
7023 specs
[count
++].index
=
7024 CURR_SLOT
.opnd
[i
].X_add_number
- REG_GR
;
7035 /* This is the same as IA64_RS_PRr, except that the register range is
7036 from 1 - 15, and there are no rotating register reads/writes here. */
7040 for (i
= 1; i
< 16; i
++)
7042 specs
[count
] = tmpl
;
7043 specs
[count
++].index
= i
;
7049 /* Mark only those registers indicated by the mask. */
7052 mask
= CURR_SLOT
.opnd
[2].X_add_number
;
7053 for (i
= 1; i
< 16; i
++)
7054 if (mask
& ((valueT
) 1 << i
))
7056 specs
[count
] = tmpl
;
7057 specs
[count
++].index
= i
;
7065 else if (note
== 11) /* note 11 implies note 1 as well */
7069 for (i
= 0; i
< idesc
->num_outputs
; i
++)
7071 if (idesc
->operands
[i
] == IA64_OPND_P1
7072 || idesc
->operands
[i
] == IA64_OPND_P2
)
7074 int regno
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_P
;
7075 if (regno
>= 1 && regno
< 16)
7077 specs
[count
] = tmpl
;
7078 specs
[count
++].index
= regno
;
7088 else if (note
== 12)
7090 if (CURR_SLOT
.qp_regno
>= 1 && CURR_SLOT
.qp_regno
< 16)
7092 specs
[count
] = tmpl
;
7093 specs
[count
++].index
= CURR_SLOT
.qp_regno
;
7100 int p1
= CURR_SLOT
.opnd
[0].X_add_number
- REG_P
;
7101 int p2
= CURR_SLOT
.opnd
[1].X_add_number
- REG_P
;
7102 int or_andcm
= strstr(idesc
->name
, "or.andcm") != NULL
;
7103 int and_orcm
= strstr(idesc
->name
, "and.orcm") != NULL
;
7105 if ((idesc
->operands
[0] == IA64_OPND_P1
7106 || idesc
->operands
[0] == IA64_OPND_P2
)
7107 && p1
>= 1 && p1
< 16)
7109 specs
[count
] = tmpl
;
7110 specs
[count
].cmp_type
=
7111 (or_andcm
? CMP_OR
: (and_orcm
? CMP_AND
: CMP_NONE
));
7112 specs
[count
++].index
= p1
;
7114 if ((idesc
->operands
[1] == IA64_OPND_P1
7115 || idesc
->operands
[1] == IA64_OPND_P2
)
7116 && p2
>= 1 && p2
< 16)
7118 specs
[count
] = tmpl
;
7119 specs
[count
].cmp_type
=
7120 (or_andcm
? CMP_AND
: (and_orcm
? CMP_OR
: CMP_NONE
));
7121 specs
[count
++].index
= p2
;
7126 if (CURR_SLOT
.qp_regno
>= 1 && CURR_SLOT
.qp_regno
< 16)
7128 specs
[count
] = tmpl
;
7129 specs
[count
++].index
= CURR_SLOT
.qp_regno
;
7131 if (idesc
->operands
[1] == IA64_OPND_PR
)
7133 for (i
= 1; i
< 16; i
++)
7135 specs
[count
] = tmpl
;
7136 specs
[count
++].index
= i
;
7147 /* This is the general case for PRs. IA64_RS_PR and IA64_RS_PR63 are
7148 simplified cases of this. */
7152 for (i
= 16; i
< 63; i
++)
7154 specs
[count
] = tmpl
;
7155 specs
[count
++].index
= i
;
7161 /* Mark only those registers indicated by the mask. */
7163 && idesc
->operands
[0] == IA64_OPND_PR
)
7165 mask
= CURR_SLOT
.opnd
[2].X_add_number
;
7166 if (mask
& ((valueT
) 1<<16))
7167 for (i
= 16; i
< 63; i
++)
7169 specs
[count
] = tmpl
;
7170 specs
[count
++].index
= i
;
7174 && idesc
->operands
[0] == IA64_OPND_PR_ROT
)
7176 for (i
= 16; i
< 63; i
++)
7178 specs
[count
] = tmpl
;
7179 specs
[count
++].index
= i
;
7187 else if (note
== 11) /* note 11 implies note 1 as well */
7191 for (i
= 0; i
< idesc
->num_outputs
; i
++)
7193 if (idesc
->operands
[i
] == IA64_OPND_P1
7194 || idesc
->operands
[i
] == IA64_OPND_P2
)
7196 int regno
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_P
;
7197 if (regno
>= 16 && regno
< 63)
7199 specs
[count
] = tmpl
;
7200 specs
[count
++].index
= regno
;
7210 else if (note
== 12)
7212 if (CURR_SLOT
.qp_regno
>= 16 && CURR_SLOT
.qp_regno
< 63)
7214 specs
[count
] = tmpl
;
7215 specs
[count
++].index
= CURR_SLOT
.qp_regno
;
7222 int p1
= CURR_SLOT
.opnd
[0].X_add_number
- REG_P
;
7223 int p2
= CURR_SLOT
.opnd
[1].X_add_number
- REG_P
;
7224 int or_andcm
= strstr(idesc
->name
, "or.andcm") != NULL
;
7225 int and_orcm
= strstr(idesc
->name
, "and.orcm") != NULL
;
7227 if ((idesc
->operands
[0] == IA64_OPND_P1
7228 || idesc
->operands
[0] == IA64_OPND_P2
)
7229 && p1
>= 16 && p1
< 63)
7231 specs
[count
] = tmpl
;
7232 specs
[count
].cmp_type
=
7233 (or_andcm
? CMP_OR
: (and_orcm
? CMP_AND
: CMP_NONE
));
7234 specs
[count
++].index
= p1
;
7236 if ((idesc
->operands
[1] == IA64_OPND_P1
7237 || idesc
->operands
[1] == IA64_OPND_P2
)
7238 && p2
>= 16 && p2
< 63)
7240 specs
[count
] = tmpl
;
7241 specs
[count
].cmp_type
=
7242 (or_andcm
? CMP_AND
: (and_orcm
? CMP_OR
: CMP_NONE
));
7243 specs
[count
++].index
= p2
;
7248 if (CURR_SLOT
.qp_regno
>= 16 && CURR_SLOT
.qp_regno
< 63)
7250 specs
[count
] = tmpl
;
7251 specs
[count
++].index
= CURR_SLOT
.qp_regno
;
7253 if (idesc
->operands
[1] == IA64_OPND_PR
)
7255 for (i
= 16; i
< 63; i
++)
7257 specs
[count
] = tmpl
;
7258 specs
[count
++].index
= i
;
7270 /* Verify that the instruction is using the PSR bit indicated in
7274 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_PSR_UM
)
7276 if (dep
->regindex
< 6)
7278 specs
[count
++] = tmpl
;
7281 else if (idesc
->operands
[!rsrc_write
] == IA64_OPND_PSR
)
7283 if (dep
->regindex
< 32
7284 || dep
->regindex
== 35
7285 || dep
->regindex
== 36
7286 || (!rsrc_write
&& dep
->regindex
== PSR_CPL
))
7288 specs
[count
++] = tmpl
;
7291 else if (idesc
->operands
[!rsrc_write
] == IA64_OPND_PSR_L
)
7293 if (dep
->regindex
< 32
7294 || dep
->regindex
== 35
7295 || dep
->regindex
== 36
7296 || (rsrc_write
&& dep
->regindex
== PSR_CPL
))
7298 specs
[count
++] = tmpl
;
7303 /* Several PSR bits have very specific dependencies. */
7304 switch (dep
->regindex
)
7307 specs
[count
++] = tmpl
;
7312 specs
[count
++] = tmpl
;
7316 /* Only certain CR accesses use PSR.ic */
7317 if (idesc
->operands
[0] == IA64_OPND_CR3
7318 || idesc
->operands
[1] == IA64_OPND_CR3
)
7321 ((idesc
->operands
[0] == IA64_OPND_CR3
)
7324 CURR_SLOT
.opnd
[index
].X_add_number
- REG_CR
;
7339 specs
[count
++] = tmpl
;
7348 specs
[count
++] = tmpl
;
7352 /* Only some AR accesses use cpl */
7353 if (idesc
->operands
[0] == IA64_OPND_AR3
7354 || idesc
->operands
[1] == IA64_OPND_AR3
)
7357 ((idesc
->operands
[0] == IA64_OPND_AR3
)
7360 CURR_SLOT
.opnd
[index
].X_add_number
- REG_AR
;
7367 && regno
<= AR_K7
))))
7369 specs
[count
++] = tmpl
;
7374 specs
[count
++] = tmpl
;
7384 if (idesc
->operands
[0] == IA64_OPND_IMMU24
)
7386 mask
= CURR_SLOT
.opnd
[0].X_add_number
;
7392 if (mask
& ((valueT
) 1 << dep
->regindex
))
7394 specs
[count
++] = tmpl
;
7399 int min
= dep
->regindex
== PSR_DFL
? 2 : 32;
7400 int max
= dep
->regindex
== PSR_DFL
? 31 : 127;
7401 /* dfh is read on FR32-127; dfl is read on FR2-31 */
7402 for (i
= 0; i
< NELEMS (idesc
->operands
); i
++)
7404 if (idesc
->operands
[i
] == IA64_OPND_F1
7405 || idesc
->operands
[i
] == IA64_OPND_F2
7406 || idesc
->operands
[i
] == IA64_OPND_F3
7407 || idesc
->operands
[i
] == IA64_OPND_F4
)
7409 int reg
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_FR
;
7410 if (reg
>= min
&& reg
<= max
)
7412 specs
[count
++] = tmpl
;
7419 int min
= dep
->regindex
== PSR_MFL
? 2 : 32;
7420 int max
= dep
->regindex
== PSR_MFL
? 31 : 127;
7421 /* mfh is read on writes to FR32-127; mfl is read on writes to
7423 for (i
= 0; i
< idesc
->num_outputs
; i
++)
7425 if (idesc
->operands
[i
] == IA64_OPND_F1
)
7427 int reg
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_FR
;
7428 if (reg
>= min
&& reg
<= max
)
7430 specs
[count
++] = tmpl
;
7435 else if (note
== 10)
7437 for (i
= 0; i
< NELEMS (idesc
->operands
); i
++)
7439 if (idesc
->operands
[i
] == IA64_OPND_R1
7440 || idesc
->operands
[i
] == IA64_OPND_R2
7441 || idesc
->operands
[i
] == IA64_OPND_R3
)
7443 int regno
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_GR
;
7444 if (regno
>= 16 && regno
<= 31)
7446 specs
[count
++] = tmpl
;
7457 case IA64_RS_AR_FPSR
:
7458 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_AR3
)
7460 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_AR
;
7461 if (regno
== AR_FPSR
)
7463 specs
[count
++] = tmpl
;
7468 specs
[count
++] = tmpl
;
7473 /* Handle all AR[REG] resources */
7474 if (note
== 0 || note
== 1)
7476 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_AR
;
7477 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_AR3
7478 && regno
== dep
->regindex
)
7480 specs
[count
++] = tmpl
;
7482 /* other AR[REG] resources may be affected by AR accesses */
7483 else if (idesc
->operands
[0] == IA64_OPND_AR3
)
7486 regno
= CURR_SLOT
.opnd
[0].X_add_number
- REG_AR
;
7487 switch (dep
->regindex
)
7493 if (regno
== AR_BSPSTORE
)
7495 specs
[count
++] = tmpl
;
7499 (regno
== AR_BSPSTORE
7500 || regno
== AR_RNAT
))
7502 specs
[count
++] = tmpl
;
7507 else if (idesc
->operands
[1] == IA64_OPND_AR3
)
7510 regno
= CURR_SLOT
.opnd
[1].X_add_number
- REG_AR
;
7511 switch (dep
->regindex
)
7516 if (regno
== AR_BSPSTORE
|| regno
== AR_RNAT
)
7518 specs
[count
++] = tmpl
;
7525 specs
[count
++] = tmpl
;
7535 /* Handle all CR[REG] resources */
7536 if (note
== 0 || note
== 1)
7538 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_CR3
)
7540 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_CR
;
7541 if (regno
== dep
->regindex
)
7543 specs
[count
++] = tmpl
;
7545 else if (!rsrc_write
)
7547 /* Reads from CR[IVR] affect other resources. */
7548 if (regno
== CR_IVR
)
7550 if ((dep
->regindex
>= CR_IRR0
7551 && dep
->regindex
<= CR_IRR3
)
7552 || dep
->regindex
== CR_TPR
)
7554 specs
[count
++] = tmpl
;
7561 specs
[count
++] = tmpl
;
7570 case IA64_RS_INSERVICE
:
7571 /* look for write of EOI (67) or read of IVR (65) */
7572 if ((idesc
->operands
[0] == IA64_OPND_CR3
7573 && CURR_SLOT
.opnd
[0].X_add_number
- REG_CR
== CR_EOI
)
7574 || (idesc
->operands
[1] == IA64_OPND_CR3
7575 && CURR_SLOT
.opnd
[1].X_add_number
- REG_CR
== CR_IVR
))
7577 specs
[count
++] = tmpl
;
7584 specs
[count
++] = tmpl
;
7595 specs
[count
++] = tmpl
;
7599 /* Check if any of the registers accessed are in the rotating region.
7600 mov to/from pr accesses CFM only when qp_regno is in the rotating
7602 for (i
= 0; i
< NELEMS (idesc
->operands
); i
++)
7604 if (idesc
->operands
[i
] == IA64_OPND_R1
7605 || idesc
->operands
[i
] == IA64_OPND_R2
7606 || idesc
->operands
[i
] == IA64_OPND_R3
)
7608 int num
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_GR
;
7609 /* Assumes that md.rot.num_regs is always valid */
7610 if (md
.rot
.num_regs
> 0
7612 && num
< 31 + md
.rot
.num_regs
)
7614 specs
[count
] = tmpl
;
7615 specs
[count
++].specific
= 0;
7618 else if (idesc
->operands
[i
] == IA64_OPND_F1
7619 || idesc
->operands
[i
] == IA64_OPND_F2
7620 || idesc
->operands
[i
] == IA64_OPND_F3
7621 || idesc
->operands
[i
] == IA64_OPND_F4
)
7623 int num
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_FR
;
7626 specs
[count
] = tmpl
;
7627 specs
[count
++].specific
= 0;
7630 else if (idesc
->operands
[i
] == IA64_OPND_P1
7631 || idesc
->operands
[i
] == IA64_OPND_P2
)
7633 int num
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_P
;
7636 specs
[count
] = tmpl
;
7637 specs
[count
++].specific
= 0;
7641 if (CURR_SLOT
.qp_regno
> 15)
7643 specs
[count
] = tmpl
;
7644 specs
[count
++].specific
= 0;
7649 /* This is the same as IA64_RS_PRr, except simplified to account for
7650 the fact that there is only one register. */
7654 specs
[count
++] = tmpl
;
7659 if (idesc
->operands
[2] == IA64_OPND_IMM17
)
7660 mask
= CURR_SLOT
.opnd
[2].X_add_number
;
7661 if (mask
& ((valueT
) 1 << 63))
7662 specs
[count
++] = tmpl
;
7664 else if (note
== 11)
7666 if ((idesc
->operands
[0] == IA64_OPND_P1
7667 && CURR_SLOT
.opnd
[0].X_add_number
- REG_P
== 63)
7668 || (idesc
->operands
[1] == IA64_OPND_P2
7669 && CURR_SLOT
.opnd
[1].X_add_number
- REG_P
== 63))
7671 specs
[count
++] = tmpl
;
7674 else if (note
== 12)
7676 if (CURR_SLOT
.qp_regno
== 63)
7678 specs
[count
++] = tmpl
;
7685 int p1
= CURR_SLOT
.opnd
[0].X_add_number
- REG_P
;
7686 int p2
= CURR_SLOT
.opnd
[1].X_add_number
- REG_P
;
7687 int or_andcm
= strstr(idesc
->name
, "or.andcm") != NULL
;
7688 int and_orcm
= strstr(idesc
->name
, "and.orcm") != NULL
;
7691 && (idesc
->operands
[0] == IA64_OPND_P1
7692 || idesc
->operands
[0] == IA64_OPND_P2
))
7694 specs
[count
] = tmpl
;
7695 specs
[count
++].cmp_type
=
7696 (or_andcm
? CMP_OR
: (and_orcm
? CMP_AND
: CMP_NONE
));
7699 && (idesc
->operands
[1] == IA64_OPND_P1
7700 || idesc
->operands
[1] == IA64_OPND_P2
))
7702 specs
[count
] = tmpl
;
7703 specs
[count
++].cmp_type
=
7704 (or_andcm
? CMP_AND
: (and_orcm
? CMP_OR
: CMP_NONE
));
7709 if (CURR_SLOT
.qp_regno
== 63)
7711 specs
[count
++] = tmpl
;
7722 /* FIXME we can identify some individual RSE written resources, but RSE
7723 read resources have not yet been completely identified, so for now
7724 treat RSE as a single resource */
7725 if (strncmp (idesc
->name
, "mov", 3) == 0)
7729 if (idesc
->operands
[0] == IA64_OPND_AR3
7730 && CURR_SLOT
.opnd
[0].X_add_number
- REG_AR
== AR_BSPSTORE
)
7732 specs
[count
] = tmpl
;
7733 specs
[count
++].index
= 0; /* IA64_RSE_BSPLOAD/RNATBITINDEX */
7738 if (idesc
->operands
[0] == IA64_OPND_AR3
)
7740 if (CURR_SLOT
.opnd
[0].X_add_number
- REG_AR
== AR_BSPSTORE
7741 || CURR_SLOT
.opnd
[0].X_add_number
- REG_AR
== AR_RNAT
)
7743 specs
[count
++] = tmpl
;
7746 else if (idesc
->operands
[1] == IA64_OPND_AR3
)
7748 if (CURR_SLOT
.opnd
[1].X_add_number
- REG_AR
== AR_BSP
7749 || CURR_SLOT
.opnd
[1].X_add_number
- REG_AR
== AR_BSPSTORE
7750 || CURR_SLOT
.opnd
[1].X_add_number
- REG_AR
== AR_RNAT
)
7752 specs
[count
++] = tmpl
;
7759 specs
[count
++] = tmpl
;
7764 /* FIXME -- do any of these need to be non-specific? */
7765 specs
[count
++] = tmpl
;
7769 as_bad (_("Unrecognized dependency specifier %d\n"), dep
->specifier
);
7776 /* Clear branch flags on marked resources. This breaks the link between the
7777 QP of the marking instruction and a subsequent branch on the same QP. */
7780 clear_qp_branch_flag (mask
)
7784 for (i
= 0; i
< regdepslen
; i
++)
7786 valueT bit
= ((valueT
) 1 << regdeps
[i
].qp_regno
);
7787 if ((bit
& mask
) != 0)
7789 regdeps
[i
].link_to_qp_branch
= 0;
7794 /* Remove any mutexes which contain any of the PRs indicated in the mask.
7796 Any changes to a PR clears the mutex relations which include that PR. */
7799 clear_qp_mutex (mask
)
7805 while (i
< qp_mutexeslen
)
7807 if ((qp_mutexes
[i
].prmask
& mask
) != 0)
7811 fprintf (stderr
, " Clearing mutex relation");
7812 print_prmask (qp_mutexes
[i
].prmask
);
7813 fprintf (stderr
, "\n");
7815 qp_mutexes
[i
] = qp_mutexes
[--qp_mutexeslen
];
7822 /* Clear implies relations which contain PRs in the given masks.
7823 P1_MASK indicates the source of the implies relation, while P2_MASK
7824 indicates the implied PR. */
7827 clear_qp_implies (p1_mask
, p2_mask
)
7834 while (i
< qp_implieslen
)
7836 if ((((valueT
) 1 << qp_implies
[i
].p1
) & p1_mask
) != 0
7837 || (((valueT
) 1 << qp_implies
[i
].p2
) & p2_mask
) != 0)
7840 fprintf (stderr
, "Clearing implied relation PR%d->PR%d\n",
7841 qp_implies
[i
].p1
, qp_implies
[i
].p2
);
7842 qp_implies
[i
] = qp_implies
[--qp_implieslen
];
7849 /* Add the PRs specified to the list of implied relations. */
7852 add_qp_imply (p1
, p2
)
7859 /* p0 is not meaningful here. */
7860 if (p1
== 0 || p2
== 0)
7866 /* If it exists already, ignore it. */
7867 for (i
= 0; i
< qp_implieslen
; i
++)
7869 if (qp_implies
[i
].p1
== p1
7870 && qp_implies
[i
].p2
== p2
7871 && qp_implies
[i
].path
== md
.path
7872 && !qp_implies
[i
].p2_branched
)
7876 if (qp_implieslen
== qp_impliestotlen
)
7878 qp_impliestotlen
+= 20;
7879 qp_implies
= (struct qp_imply
*)
7880 xrealloc ((void *) qp_implies
,
7881 qp_impliestotlen
* sizeof (struct qp_imply
));
7884 fprintf (stderr
, " Registering PR%d implies PR%d\n", p1
, p2
);
7885 qp_implies
[qp_implieslen
].p1
= p1
;
7886 qp_implies
[qp_implieslen
].p2
= p2
;
7887 qp_implies
[qp_implieslen
].path
= md
.path
;
7888 qp_implies
[qp_implieslen
++].p2_branched
= 0;
7890 /* Add in the implied transitive relations; for everything that p2 implies,
7891 make p1 imply that, too; for everything that implies p1, make it imply p2
7893 for (i
= 0; i
< qp_implieslen
; i
++)
7895 if (qp_implies
[i
].p1
== p2
)
7896 add_qp_imply (p1
, qp_implies
[i
].p2
);
7897 if (qp_implies
[i
].p2
== p1
)
7898 add_qp_imply (qp_implies
[i
].p1
, p2
);
7900 /* Add in mutex relations implied by this implies relation; for each mutex
7901 relation containing p2, duplicate it and replace p2 with p1. */
7902 bit
= (valueT
) 1 << p1
;
7903 mask
= (valueT
) 1 << p2
;
7904 for (i
= 0; i
< qp_mutexeslen
; i
++)
7906 if (qp_mutexes
[i
].prmask
& mask
)
7907 add_qp_mutex ((qp_mutexes
[i
].prmask
& ~mask
) | bit
);
7911 /* Add the PRs specified in the mask to the mutex list; this means that only
7912 one of the PRs can be true at any time. PR0 should never be included in
7922 if (qp_mutexeslen
== qp_mutexestotlen
)
7924 qp_mutexestotlen
+= 20;
7925 qp_mutexes
= (struct qpmutex
*)
7926 xrealloc ((void *) qp_mutexes
,
7927 qp_mutexestotlen
* sizeof (struct qpmutex
));
7931 fprintf (stderr
, " Registering mutex on");
7932 print_prmask (mask
);
7933 fprintf (stderr
, "\n");
7935 qp_mutexes
[qp_mutexeslen
].path
= md
.path
;
7936 qp_mutexes
[qp_mutexeslen
++].prmask
= mask
;
7940 clear_register_values ()
7944 fprintf (stderr
, " Clearing register values\n");
7945 for (i
= 1; i
< NELEMS (gr_values
); i
++)
7946 gr_values
[i
].known
= 0;
7949 /* Keep track of register values/changes which affect DV tracking.
7951 optimization note: should add a flag to classes of insns where otherwise we
7952 have to examine a group of strings to identify them. */
7955 note_register_values (idesc
)
7956 struct ia64_opcode
*idesc
;
7958 valueT qp_changemask
= 0;
7961 /* Invalidate values for registers being written to. */
7962 for (i
= 0; i
< idesc
->num_outputs
; i
++)
7964 if (idesc
->operands
[i
] == IA64_OPND_R1
7965 || idesc
->operands
[i
] == IA64_OPND_R2
7966 || idesc
->operands
[i
] == IA64_OPND_R3
)
7968 int regno
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_GR
;
7969 if (regno
> 0 && regno
< NELEMS (gr_values
))
7970 gr_values
[regno
].known
= 0;
7972 else if (idesc
->operands
[i
] == IA64_OPND_R3_2
)
7974 int regno
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_GR
;
7975 if (regno
> 0 && regno
< 4)
7976 gr_values
[regno
].known
= 0;
7978 else if (idesc
->operands
[i
] == IA64_OPND_P1
7979 || idesc
->operands
[i
] == IA64_OPND_P2
)
7981 int regno
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_P
;
7982 qp_changemask
|= (valueT
) 1 << regno
;
7984 else if (idesc
->operands
[i
] == IA64_OPND_PR
)
7986 if (idesc
->operands
[2] & (valueT
) 0x10000)
7987 qp_changemask
= ~(valueT
) 0x1FFFF | idesc
->operands
[2];
7989 qp_changemask
= idesc
->operands
[2];
7992 else if (idesc
->operands
[i
] == IA64_OPND_PR_ROT
)
7994 if (idesc
->operands
[1] & ((valueT
) 1 << 43))
7995 qp_changemask
= ~(valueT
) 0xFFFFFFFFFFF | idesc
->operands
[1];
7997 qp_changemask
= idesc
->operands
[1];
7998 qp_changemask
&= ~(valueT
) 0xFFFF;
8003 /* Always clear qp branch flags on any PR change. */
8004 /* FIXME there may be exceptions for certain compares. */
8005 clear_qp_branch_flag (qp_changemask
);
8007 /* Invalidate rotating registers on insns which affect RRBs in CFM. */
8008 if (idesc
->flags
& IA64_OPCODE_MOD_RRBS
)
8010 qp_changemask
|= ~(valueT
) 0xFFFF;
8011 if (strcmp (idesc
->name
, "clrrrb.pr") != 0)
8013 for (i
= 32; i
< 32 + md
.rot
.num_regs
; i
++)
8014 gr_values
[i
].known
= 0;
8016 clear_qp_mutex (qp_changemask
);
8017 clear_qp_implies (qp_changemask
, qp_changemask
);
8019 /* After a call, all register values are undefined, except those marked
8021 else if (strncmp (idesc
->name
, "br.call", 6) == 0
8022 || strncmp (idesc
->name
, "brl.call", 7) == 0)
8024 /* FIXME keep GR values which are marked as "safe_across_calls" */
8025 clear_register_values ();
8026 clear_qp_mutex (~qp_safe_across_calls
);
8027 clear_qp_implies (~qp_safe_across_calls
, ~qp_safe_across_calls
);
8028 clear_qp_branch_flag (~qp_safe_across_calls
);
8030 else if (is_interruption_or_rfi (idesc
)
8031 || is_taken_branch (idesc
))
8033 clear_register_values ();
8034 clear_qp_mutex (~(valueT
) 0);
8035 clear_qp_implies (~(valueT
) 0, ~(valueT
) 0);
8037 /* Look for mutex and implies relations. */
8038 else if ((idesc
->operands
[0] == IA64_OPND_P1
8039 || idesc
->operands
[0] == IA64_OPND_P2
)
8040 && (idesc
->operands
[1] == IA64_OPND_P1
8041 || idesc
->operands
[1] == IA64_OPND_P2
))
8043 int p1
= CURR_SLOT
.opnd
[0].X_add_number
- REG_P
;
8044 int p2
= CURR_SLOT
.opnd
[1].X_add_number
- REG_P
;
8045 valueT p1mask
= (valueT
) 1 << p1
;
8046 valueT p2mask
= (valueT
) 1 << p2
;
8048 /* If one of the PRs is PR0, we can't really do anything. */
8049 if (p1
== 0 || p2
== 0)
8052 fprintf (stderr
, " Ignoring PRs due to inclusion of p0\n");
8054 /* In general, clear mutexes and implies which include P1 or P2,
8055 with the following exceptions. */
8056 else if (strstr (idesc
->name
, ".or.andcm") != NULL
)
8058 add_qp_mutex (p1mask
| p2mask
);
8059 clear_qp_implies (p2mask
, p1mask
);
8061 else if (strstr (idesc
->name
, ".and.orcm") != NULL
)
8063 add_qp_mutex (p1mask
| p2mask
);
8064 clear_qp_implies (p1mask
, p2mask
);
8066 else if (strstr (idesc
->name
, ".and") != NULL
)
8068 clear_qp_implies (0, p1mask
| p2mask
);
8070 else if (strstr (idesc
->name
, ".or") != NULL
)
8072 clear_qp_mutex (p1mask
| p2mask
);
8073 clear_qp_implies (p1mask
| p2mask
, 0);
8077 clear_qp_implies (p1mask
| p2mask
, p1mask
| p2mask
);
8078 if (strstr (idesc
->name
, ".unc") != NULL
)
8080 add_qp_mutex (p1mask
| p2mask
);
8081 if (CURR_SLOT
.qp_regno
!= 0)
8083 add_qp_imply (CURR_SLOT
.opnd
[0].X_add_number
- REG_P
,
8084 CURR_SLOT
.qp_regno
);
8085 add_qp_imply (CURR_SLOT
.opnd
[1].X_add_number
- REG_P
,
8086 CURR_SLOT
.qp_regno
);
8089 else if (CURR_SLOT
.qp_regno
== 0)
8091 add_qp_mutex (p1mask
| p2mask
);
8095 clear_qp_mutex (p1mask
| p2mask
);
8099 /* Look for mov imm insns into GRs. */
8100 else if (idesc
->operands
[0] == IA64_OPND_R1
8101 && (idesc
->operands
[1] == IA64_OPND_IMM22
8102 || idesc
->operands
[1] == IA64_OPND_IMMU64
)
8103 && (strcmp (idesc
->name
, "mov") == 0
8104 || strcmp (idesc
->name
, "movl") == 0))
8106 int regno
= CURR_SLOT
.opnd
[0].X_add_number
- REG_GR
;
8107 if (regno
> 0 && regno
< NELEMS (gr_values
))
8109 gr_values
[regno
].known
= 1;
8110 gr_values
[regno
].value
= CURR_SLOT
.opnd
[1].X_add_number
;
8111 gr_values
[regno
].path
= md
.path
;
8113 fprintf (stderr
, " Know gr%d = 0x%llx\n",
8114 regno
, gr_values
[regno
].value
);
8119 clear_qp_mutex (qp_changemask
);
8120 clear_qp_implies (qp_changemask
, qp_changemask
);
8124 /* Return whether the given predicate registers are currently mutex. */
8127 qp_mutex (p1
, p2
, path
)
8137 mask
= ((valueT
) 1 << p1
) | (valueT
) 1 << p2
;
8138 for (i
= 0; i
< qp_mutexeslen
; i
++)
8140 if (qp_mutexes
[i
].path
>= path
8141 && (qp_mutexes
[i
].prmask
& mask
) == mask
)
8148 /* Return whether the given resource is in the given insn's list of chks
8149 Return 1 if the conflict is absolutely determined, 2 if it's a potential
8153 resources_match (rs
, idesc
, note
, qp_regno
, path
)
8155 struct ia64_opcode
*idesc
;
8160 struct rsrc specs
[MAX_SPECS
];
8163 /* If the marked resource's qp_regno and the given qp_regno are mutex,
8164 we don't need to check. One exception is note 11, which indicates that
8165 target predicates are written regardless of PR[qp]. */
8166 if (qp_mutex (rs
->qp_regno
, qp_regno
, path
)
8170 count
= specify_resource (rs
->dependency
, idesc
, DV_CHK
, specs
, note
, path
);
8173 /* UNAT checking is a bit more specific than other resources */
8174 if (rs
->dependency
->specifier
== IA64_RS_AR_UNAT
8175 && specs
[count
].mem_offset
.hint
8176 && rs
->mem_offset
.hint
)
8178 if (rs
->mem_offset
.base
== specs
[count
].mem_offset
.base
)
8180 if (((rs
->mem_offset
.offset
>> 3) & 0x3F) ==
8181 ((specs
[count
].mem_offset
.offset
>> 3) & 0x3F))
8188 /* Skip apparent PR write conflicts where both writes are an AND or both
8189 writes are an OR. */
8190 if (rs
->dependency
->specifier
== IA64_RS_PR
8191 || rs
->dependency
->specifier
== IA64_RS_PRr
8192 || rs
->dependency
->specifier
== IA64_RS_PR63
)
8194 if (specs
[count
].cmp_type
!= CMP_NONE
8195 && specs
[count
].cmp_type
== rs
->cmp_type
)
8198 fprintf (stderr
, " %s on parallel compare allowed (PR%d)\n",
8199 dv_mode
[rs
->dependency
->mode
],
8200 rs
->dependency
->specifier
!= IA64_RS_PR63
?
8201 specs
[count
].index
: 63);
8206 " %s on parallel compare conflict %s vs %s on PR%d\n",
8207 dv_mode
[rs
->dependency
->mode
],
8208 dv_cmp_type
[rs
->cmp_type
],
8209 dv_cmp_type
[specs
[count
].cmp_type
],
8210 rs
->dependency
->specifier
!= IA64_RS_PR63
?
8211 specs
[count
].index
: 63);
8215 /* If either resource is not specific, conservatively assume a conflict
8217 if (!specs
[count
].specific
|| !rs
->specific
)
8219 else if (specs
[count
].index
== rs
->index
)
8224 fprintf (stderr
, " No %s conflicts\n", rs
->dependency
->name
);
8230 /* Indicate an instruction group break; if INSERT_STOP is non-zero, then
8231 insert a stop to create the break. Update all resource dependencies
8232 appropriately. If QP_REGNO is non-zero, only apply the break to resources
8233 which use the same QP_REGNO and have the link_to_qp_branch flag set.
8234 If SAVE_CURRENT is non-zero, don't affect resources marked by the current
8238 insn_group_break (insert_stop
, qp_regno
, save_current
)
8245 if (insert_stop
&& md
.num_slots_in_use
> 0)
8246 PREV_SLOT
.end_of_insn_group
= 1;
8250 fprintf (stderr
, " Insn group break%s",
8251 (insert_stop
? " (w/stop)" : ""));
8253 fprintf (stderr
, " effective for QP=%d", qp_regno
);
8254 fprintf (stderr
, "\n");
8258 while (i
< regdepslen
)
8260 const struct ia64_dependency
*dep
= regdeps
[i
].dependency
;
8263 && regdeps
[i
].qp_regno
!= qp_regno
)
8270 && CURR_SLOT
.src_file
== regdeps
[i
].file
8271 && CURR_SLOT
.src_line
== regdeps
[i
].line
)
8277 /* clear dependencies which are automatically cleared by a stop, or
8278 those that have reached the appropriate state of insn serialization */
8279 if (dep
->semantics
== IA64_DVS_IMPLIED
8280 || dep
->semantics
== IA64_DVS_IMPLIEDF
8281 || regdeps
[i
].insn_srlz
== STATE_SRLZ
)
8283 print_dependency ("Removing", i
);
8284 regdeps
[i
] = regdeps
[--regdepslen
];
8288 if (dep
->semantics
== IA64_DVS_DATA
8289 || dep
->semantics
== IA64_DVS_INSTR
8290 || dep
->semantics
== IA64_DVS_SPECIFIC
)
8292 if (regdeps
[i
].insn_srlz
== STATE_NONE
)
8293 regdeps
[i
].insn_srlz
= STATE_STOP
;
8294 if (regdeps
[i
].data_srlz
== STATE_NONE
)
8295 regdeps
[i
].data_srlz
= STATE_STOP
;
8302 /* Add the given resource usage spec to the list of active dependencies. */
8305 mark_resource (idesc
, dep
, spec
, depind
, path
)
8306 struct ia64_opcode
*idesc
;
8307 const struct ia64_dependency
*dep
;
8312 if (regdepslen
== regdepstotlen
)
8314 regdepstotlen
+= 20;
8315 regdeps
= (struct rsrc
*)
8316 xrealloc ((void *) regdeps
,
8317 regdepstotlen
* sizeof(struct rsrc
));
8320 regdeps
[regdepslen
] = *spec
;
8321 regdeps
[regdepslen
].depind
= depind
;
8322 regdeps
[regdepslen
].path
= path
;
8323 regdeps
[regdepslen
].file
= CURR_SLOT
.src_file
;
8324 regdeps
[regdepslen
].line
= CURR_SLOT
.src_line
;
8326 print_dependency ("Adding", regdepslen
);
8332 print_dependency (action
, depind
)
8338 fprintf (stderr
, " %s %s '%s'",
8339 action
, dv_mode
[(regdeps
[depind
].dependency
)->mode
],
8340 (regdeps
[depind
].dependency
)->name
);
8341 if (regdeps
[depind
].specific
&& regdeps
[depind
].index
!= 0)
8342 fprintf (stderr
, " (%d)", regdeps
[depind
].index
);
8343 if (regdeps
[depind
].mem_offset
.hint
)
8344 fprintf (stderr
, " 0x%llx+0x%llx",
8345 regdeps
[depind
].mem_offset
.base
,
8346 regdeps
[depind
].mem_offset
.offset
);
8347 fprintf (stderr
, "\n");
8352 instruction_serialization ()
8356 fprintf (stderr
, " Instruction serialization\n");
8357 for (i
= 0; i
< regdepslen
; i
++)
8358 if (regdeps
[i
].insn_srlz
== STATE_STOP
)
8359 regdeps
[i
].insn_srlz
= STATE_SRLZ
;
8363 data_serialization ()
8367 fprintf (stderr
, " Data serialization\n");
8368 while (i
< regdepslen
)
8370 if (regdeps
[i
].data_srlz
== STATE_STOP
8371 /* Note: as of 991210, all "other" dependencies are cleared by a
8372 data serialization. This might change with new tables */
8373 || (regdeps
[i
].dependency
)->semantics
== IA64_DVS_OTHER
)
8375 print_dependency ("Removing", i
);
8376 regdeps
[i
] = regdeps
[--regdepslen
];
8383 /* Insert stops and serializations as needed to avoid DVs. */
8386 remove_marked_resource (rs
)
8389 switch (rs
->dependency
->semantics
)
8391 case IA64_DVS_SPECIFIC
:
8393 fprintf (stderr
, "Implementation-specific, assume worst case...\n");
8394 /* ...fall through... */
8395 case IA64_DVS_INSTR
:
8397 fprintf (stderr
, "Inserting instr serialization\n");
8398 if (rs
->insn_srlz
< STATE_STOP
)
8399 insn_group_break (1, 0, 0);
8400 if (rs
->insn_srlz
< STATE_SRLZ
)
8402 int oldqp
= CURR_SLOT
.qp_regno
;
8403 struct ia64_opcode
*oldidesc
= CURR_SLOT
.idesc
;
8404 /* Manually jam a srlz.i insn into the stream */
8405 CURR_SLOT
.qp_regno
= 0;
8406 CURR_SLOT
.idesc
= ia64_find_opcode ("srlz.i");
8407 instruction_serialization ();
8408 md
.curr_slot
= (md
.curr_slot
+ 1) % NUM_SLOTS
;
8409 if (++md
.num_slots_in_use
>= NUM_SLOTS
)
8411 CURR_SLOT
.qp_regno
= oldqp
;
8412 CURR_SLOT
.idesc
= oldidesc
;
8414 insn_group_break (1, 0, 0);
8416 case IA64_DVS_OTHER
: /* as of rev2 (991220) of the DV tables, all
8417 "other" types of DV are eliminated
8418 by a data serialization */
8421 fprintf (stderr
, "Inserting data serialization\n");
8422 if (rs
->data_srlz
< STATE_STOP
)
8423 insn_group_break (1, 0, 0);
8425 int oldqp
= CURR_SLOT
.qp_regno
;
8426 struct ia64_opcode
*oldidesc
= CURR_SLOT
.idesc
;
8427 /* Manually jam a srlz.d insn into the stream */
8428 CURR_SLOT
.qp_regno
= 0;
8429 CURR_SLOT
.idesc
= ia64_find_opcode ("srlz.d");
8430 data_serialization ();
8431 md
.curr_slot
= (md
.curr_slot
+ 1) % NUM_SLOTS
;
8432 if (++md
.num_slots_in_use
>= NUM_SLOTS
)
8434 CURR_SLOT
.qp_regno
= oldqp
;
8435 CURR_SLOT
.idesc
= oldidesc
;
8438 case IA64_DVS_IMPLIED
:
8439 case IA64_DVS_IMPLIEDF
:
8441 fprintf (stderr
, "Inserting stop\n");
8442 insn_group_break (1, 0, 0);
8449 /* Check the resources used by the given opcode against the current dependency
8452 The check is run once for each execution path encountered. In this case,
8453 a unique execution path is the sequence of instructions following a code
8454 entry point, e.g. the following has three execution paths, one starting
8455 at L0, one at L1, and one at L2.
8464 check_dependencies (idesc
)
8465 struct ia64_opcode
*idesc
;
8467 const struct ia64_opcode_dependency
*opdeps
= idesc
->dependencies
;
8471 /* Note that the number of marked resources may change within the
8472 loop if in auto mode. */
8474 while (i
< regdepslen
)
8476 struct rsrc
*rs
= ®deps
[i
];
8477 const struct ia64_dependency
*dep
= rs
->dependency
;
8482 if (dep
->semantics
== IA64_DVS_NONE
8483 || (chkind
= depends_on (rs
->depind
, idesc
)) == -1)
8489 note
= NOTE (opdeps
->chks
[chkind
]);
8491 /* Check this resource against each execution path seen thus far. */
8492 for (path
= 0; path
<= md
.path
; path
++)
8496 /* If the dependency wasn't on the path being checked, ignore it. */
8497 if (rs
->path
< path
)
8500 /* If the QP for this insn implies a QP which has branched, don't
8501 bother checking. Ed. NOTE: I don't think this check is terribly
8502 useful; what's the point of generating code which will only be
8503 reached if its QP is zero?
8504 This code was specifically inserted to handle the following code,
8505 based on notes from Intel's DV checking code, where p1 implies p2.
8511 if (CURR_SLOT
.qp_regno
!= 0)
8515 for (implies
= 0; implies
< qp_implieslen
; implies
++)
8517 if (qp_implies
[implies
].path
>= path
8518 && qp_implies
[implies
].p1
== CURR_SLOT
.qp_regno
8519 && qp_implies
[implies
].p2_branched
)
8529 if ((matchtype
= resources_match (rs
, idesc
, note
,
8530 CURR_SLOT
.qp_regno
, path
)) != 0)
8533 char pathmsg
[256] = "";
8534 char indexmsg
[256] = "";
8535 int certain
= (matchtype
== 1 && CURR_SLOT
.qp_regno
== 0);
8538 sprintf (pathmsg
, " when entry is at label '%s'",
8539 md
.entry_labels
[path
- 1]);
8540 if (rs
->specific
&& rs
->index
!= 0)
8541 sprintf (indexmsg
, ", specific resource number is %d",
8543 sprintf (msg
, "Use of '%s' %s %s dependency '%s' (%s)%s%s",
8545 (certain
? "violates" : "may violate"),
8546 dv_mode
[dep
->mode
], dep
->name
,
8547 dv_sem
[dep
->semantics
],
8550 if (md
.explicit_mode
)
8552 as_warn ("%s", msg
);
8554 as_warn (_("Only the first path encountering the conflict "
8556 as_warn_where (rs
->file
, rs
->line
,
8557 _("This is the location of the "
8558 "conflicting usage"));
8559 /* Don't bother checking other paths, to avoid duplicating
8566 fprintf (stderr
, "%s @ %s:%d\n", msg
, rs
->file
, rs
->line
);
8568 remove_marked_resource (rs
);
8570 /* since the set of dependencies has changed, start over */
8571 /* FIXME -- since we're removing dvs as we go, we
8572 probably don't really need to start over... */
8585 /* Register new dependencies based on the given opcode. */
8588 mark_resources (idesc
)
8589 struct ia64_opcode
*idesc
;
8592 const struct ia64_opcode_dependency
*opdeps
= idesc
->dependencies
;
8593 int add_only_qp_reads
= 0;
8595 /* A conditional branch only uses its resources if it is taken; if it is
8596 taken, we stop following that path. The other branch types effectively
8597 *always* write their resources. If it's not taken, register only QP
8599 if (is_conditional_branch (idesc
) || is_interruption_or_rfi (idesc
))
8601 add_only_qp_reads
= 1;
8605 fprintf (stderr
, "Registering '%s' resource usage\n", idesc
->name
);
8607 for (i
= 0; i
< opdeps
->nregs
; i
++)
8609 const struct ia64_dependency
*dep
;
8610 struct rsrc specs
[MAX_SPECS
];
8615 dep
= ia64_find_dependency (opdeps
->regs
[i
]);
8616 note
= NOTE (opdeps
->regs
[i
]);
8618 if (add_only_qp_reads
8619 && !(dep
->mode
== IA64_DV_WAR
8620 && (dep
->specifier
== IA64_RS_PR
8621 || dep
->specifier
== IA64_RS_PRr
8622 || dep
->specifier
== IA64_RS_PR63
)))
8625 count
= specify_resource (dep
, idesc
, DV_REG
, specs
, note
, md
.path
);
8628 if (md
.debug_dv
&& !count
)
8629 fprintf (stderr
, " No %s %s usage found (path %d)\n",
8630 dv_mode
[dep
->mode
], dep
->name
, md
.path
);
8635 mark_resource (idesc
, dep
, &specs
[count
],
8636 DEP (opdeps
->regs
[i
]), md
.path
);
8639 /* The execution path may affect register values, which may in turn
8640 affect which indirect-access resources are accessed. */
8641 switch (dep
->specifier
)
8653 for (path
= 0; path
< md
.path
; path
++)
8655 count
= specify_resource (dep
, idesc
, DV_REG
, specs
, note
, path
);
8657 mark_resource (idesc
, dep
, &specs
[count
],
8658 DEP (opdeps
->regs
[i
]), path
);
8665 /* Remove dependencies when they no longer apply. */
8668 update_dependencies (idesc
)
8669 struct ia64_opcode
*idesc
;
8673 if (strcmp (idesc
->name
, "srlz.i") == 0)
8675 instruction_serialization ();
8677 else if (strcmp (idesc
->name
, "srlz.d") == 0)
8679 data_serialization ();
8681 else if (is_interruption_or_rfi (idesc
)
8682 || is_taken_branch (idesc
))
8684 /* Although technically the taken branch doesn't clear dependencies
8685 which require a srlz.[id], we don't follow the branch; the next
8686 instruction is assumed to start with a clean slate. */
8690 else if (is_conditional_branch (idesc
)
8691 && CURR_SLOT
.qp_regno
!= 0)
8693 int is_call
= strstr (idesc
->name
, ".call") != NULL
;
8695 for (i
= 0; i
< qp_implieslen
; i
++)
8697 /* If the conditional branch's predicate is implied by the predicate
8698 in an existing dependency, remove that dependency. */
8699 if (qp_implies
[i
].p2
== CURR_SLOT
.qp_regno
)
8702 /* Note that this implied predicate takes a branch so that if
8703 a later insn generates a DV but its predicate implies this
8704 one, we can avoid the false DV warning. */
8705 qp_implies
[i
].p2_branched
= 1;
8706 while (depind
< regdepslen
)
8708 if (regdeps
[depind
].qp_regno
== qp_implies
[i
].p1
)
8710 print_dependency ("Removing", depind
);
8711 regdeps
[depind
] = regdeps
[--regdepslen
];
8718 /* Any marked resources which have this same predicate should be
8719 cleared, provided that the QP hasn't been modified between the
8720 marking instruction and the branch. */
8723 insn_group_break (0, CURR_SLOT
.qp_regno
, 1);
8728 while (i
< regdepslen
)
8730 if (regdeps
[i
].qp_regno
== CURR_SLOT
.qp_regno
8731 && regdeps
[i
].link_to_qp_branch
8732 && (regdeps
[i
].file
!= CURR_SLOT
.src_file
8733 || regdeps
[i
].line
!= CURR_SLOT
.src_line
))
8735 /* Treat like a taken branch */
8736 print_dependency ("Removing", i
);
8737 regdeps
[i
] = regdeps
[--regdepslen
];
8746 /* Examine the current instruction for dependency violations. */
8750 struct ia64_opcode
*idesc
;
8754 fprintf (stderr
, "Checking %s for violations (line %d, %d/%d)\n",
8755 idesc
->name
, CURR_SLOT
.src_line
,
8756 idesc
->dependencies
->nchks
,
8757 idesc
->dependencies
->nregs
);
8760 /* Look through the list of currently marked resources; if the current
8761 instruction has the dependency in its chks list which uses that resource,
8762 check against the specific resources used. */
8763 check_dependencies (idesc
);
8765 /* Look up the instruction's regdeps (RAW writes, WAW writes, and WAR reads),
8766 then add them to the list of marked resources. */
8767 mark_resources (idesc
);
8769 /* There are several types of dependency semantics, and each has its own
8770 requirements for being cleared
8772 Instruction serialization (insns separated by interruption, rfi, or
8773 writer + srlz.i + reader, all in separate groups) clears DVS_INSTR.
8775 Data serialization (instruction serialization, or writer + srlz.d +
8776 reader, where writer and srlz.d are in separate groups) clears
8777 DVS_DATA. (This also clears DVS_OTHER, but that is not guaranteed to
8778 always be the case).
8780 Instruction group break (groups separated by stop, taken branch,
8781 interruption or rfi) clears DVS_IMPLIED and DVS_IMPLIEDF.
8783 update_dependencies (idesc
);
8785 /* Sometimes, knowing a register value allows us to avoid giving a false DV
8786 warning. Keep track of as many as possible that are useful. */
8787 note_register_values (idesc
);
8789 /* We don't need or want this anymore. */
8790 md
.mem_offset
.hint
= 0;
8795 /* Translate one line of assembly. Pseudo ops and labels do not show
8801 char *saved_input_line_pointer
, *mnemonic
;
8802 const struct pseudo_opcode
*pdesc
;
8803 struct ia64_opcode
*idesc
;
8804 unsigned char qp_regno
;
8808 saved_input_line_pointer
= input_line_pointer
;
8809 input_line_pointer
= str
;
8811 /* extract the opcode (mnemonic): */
8813 mnemonic
= input_line_pointer
;
8814 ch
= get_symbol_end ();
8815 pdesc
= (struct pseudo_opcode
*) hash_find (md
.pseudo_hash
, mnemonic
);
8818 *input_line_pointer
= ch
;
8819 (*pdesc
->handler
) (pdesc
->arg
);
8823 /* Find the instruction descriptor matching the arguments. */
8825 idesc
= ia64_find_opcode (mnemonic
);
8826 *input_line_pointer
= ch
;
8829 as_bad ("Unknown opcode `%s'", mnemonic
);
8833 idesc
= parse_operands (idesc
);
8837 /* Handle the dynamic ops we can handle now: */
8838 if (idesc
->type
== IA64_TYPE_DYN
)
8840 if (strcmp (idesc
->name
, "add") == 0)
8842 if (CURR_SLOT
.opnd
[2].X_op
== O_register
8843 && CURR_SLOT
.opnd
[2].X_add_number
< 4)
8847 ia64_free_opcode (idesc
);
8848 idesc
= ia64_find_opcode (mnemonic
);
8850 know (!idesc
->next
);
8853 else if (strcmp (idesc
->name
, "mov") == 0)
8855 enum ia64_opnd opnd1
, opnd2
;
8858 opnd1
= idesc
->operands
[0];
8859 opnd2
= idesc
->operands
[1];
8860 if (opnd1
== IA64_OPND_AR3
)
8862 else if (opnd2
== IA64_OPND_AR3
)
8866 if (CURR_SLOT
.opnd
[rop
].X_op
== O_register
8867 && ar_is_in_integer_unit (CURR_SLOT
.opnd
[rop
].X_add_number
))
8871 ia64_free_opcode (idesc
);
8872 idesc
= ia64_find_opcode (mnemonic
);
8873 while (idesc
!= NULL
8874 && (idesc
->operands
[0] != opnd1
8875 || idesc
->operands
[1] != opnd2
))
8876 idesc
= get_next_opcode (idesc
);
8881 if (md
.qp
.X_op
== O_register
)
8883 qp_regno
= md
.qp
.X_add_number
- REG_P
;
8884 md
.qp
.X_op
= O_absent
;
8887 flags
= idesc
->flags
;
8889 if ((flags
& IA64_OPCODE_FIRST
) != 0)
8890 insn_group_break (1, 0, 0);
8892 if ((flags
& IA64_OPCODE_NO_PRED
) != 0 && qp_regno
!= 0)
8894 as_bad ("`%s' cannot be predicated", idesc
->name
);
8898 /* Build the instruction. */
8899 CURR_SLOT
.qp_regno
= qp_regno
;
8900 CURR_SLOT
.idesc
= idesc
;
8901 as_where (&CURR_SLOT
.src_file
, &CURR_SLOT
.src_line
);
8902 if (debug_type
== DEBUG_DWARF2
)
8903 dwarf2_where (&CURR_SLOT
.debug_line
);
8905 /* Add unwind entry, if there is one. */
8906 if (unwind
.current_entry
)
8908 CURR_SLOT
.unwind_record
= unwind
.current_entry
;
8909 unwind
.current_entry
= NULL
;
8912 /* Check for dependency violations. */
8916 md
.curr_slot
= (md
.curr_slot
+ 1) % NUM_SLOTS
;
8917 if (++md
.num_slots_in_use
>= NUM_SLOTS
)
8920 if ((flags
& IA64_OPCODE_LAST
) != 0)
8921 insn_group_break (1, 0, 0);
8923 md
.last_text_seg
= now_seg
;
8926 input_line_pointer
= saved_input_line_pointer
;
8929 /* Called when symbol NAME cannot be found in the symbol table.
8930 Should be used for dynamic valued symbols only. */
8933 md_undefined_symbol (name
)
8939 /* Called for any expression that can not be recognized. When the
8940 function is called, `input_line_pointer' will point to the start of
8947 enum pseudo_type pseudo_type
;
8952 switch (*input_line_pointer
)
8955 /* Find what relocation pseudo-function we're dealing with. */
8957 ch
= *++input_line_pointer
;
8958 for (i
= 0; i
< NELEMS (pseudo_func
); ++i
)
8959 if (pseudo_func
[i
].name
&& pseudo_func
[i
].name
[0] == ch
)
8961 len
= strlen (pseudo_func
[i
].name
);
8962 if (strncmp (pseudo_func
[i
].name
+ 1,
8963 input_line_pointer
+ 1, len
- 1) == 0
8964 && !is_part_of_name (input_line_pointer
[len
]))
8966 input_line_pointer
+= len
;
8967 pseudo_type
= pseudo_func
[i
].type
;
8971 switch (pseudo_type
)
8973 case PSEUDO_FUNC_RELOC
:
8975 if (*input_line_pointer
!= '(')
8977 as_bad ("Expected '('");
8981 ++input_line_pointer
;
8983 if (*input_line_pointer
++ != ')')
8985 as_bad ("Missing ')'");
8988 if (e
->X_op
!= O_symbol
)
8990 if (e
->X_op
!= O_pseudo_fixup
)
8992 as_bad ("Not a symbolic expression");
8995 if (S_GET_VALUE (e
->X_op_symbol
) == FUNC_FPTR_RELATIVE
8996 && i
== FUNC_LT_RELATIVE
)
8997 i
= FUNC_LT_FPTR_RELATIVE
;
9000 as_bad ("Illegal combination of relocation functions");
9004 /* Make sure gas doesn't get rid of local symbols that are used
9006 e
->X_op
= O_pseudo_fixup
;
9007 e
->X_op_symbol
= pseudo_func
[i
].u
.sym
;
9010 case PSEUDO_FUNC_CONST
:
9011 e
->X_op
= O_constant
;
9012 e
->X_add_number
= pseudo_func
[i
].u
.ival
;
9015 case PSEUDO_FUNC_REG
:
9016 e
->X_op
= O_register
;
9017 e
->X_add_number
= pseudo_func
[i
].u
.ival
;
9021 name
= input_line_pointer
- 1;
9023 as_bad ("Unknown pseudo function `%s'", name
);
9029 ++input_line_pointer
;
9031 if (*input_line_pointer
!= ']')
9033 as_bad ("Closing bracket misssing");
9038 if (e
->X_op
!= O_register
)
9039 as_bad ("Register expected as index");
9041 ++input_line_pointer
;
9052 ignore_rest_of_line ();
9055 /* Return 1 if it's OK to adjust a reloc by replacing the symbol with
9056 a section symbol plus some offset. For relocs involving @fptr(),
9057 directives we don't want such adjustments since we need to have the
9058 original symbol's name in the reloc. */
9060 ia64_fix_adjustable (fix
)
9063 /* Prevent all adjustments to global symbols */
9064 if (S_IS_EXTERN (fix
->fx_addsy
) || S_IS_WEAK (fix
->fx_addsy
))
9067 switch (fix
->fx_r_type
)
9069 case BFD_RELOC_IA64_FPTR64I
:
9070 case BFD_RELOC_IA64_FPTR32MSB
:
9071 case BFD_RELOC_IA64_FPTR32LSB
:
9072 case BFD_RELOC_IA64_FPTR64MSB
:
9073 case BFD_RELOC_IA64_FPTR64LSB
:
9074 case BFD_RELOC_IA64_LTOFF_FPTR22
:
9075 case BFD_RELOC_IA64_LTOFF_FPTR64I
:
9085 ia64_force_relocation (fix
)
9088 switch (fix
->fx_r_type
)
9090 case BFD_RELOC_IA64_FPTR64I
:
9091 case BFD_RELOC_IA64_FPTR32MSB
:
9092 case BFD_RELOC_IA64_FPTR32LSB
:
9093 case BFD_RELOC_IA64_FPTR64MSB
:
9094 case BFD_RELOC_IA64_FPTR64LSB
:
9096 case BFD_RELOC_IA64_LTOFF22
:
9097 case BFD_RELOC_IA64_LTOFF64I
:
9098 case BFD_RELOC_IA64_LTOFF_FPTR22
:
9099 case BFD_RELOC_IA64_LTOFF_FPTR64I
:
9100 case BFD_RELOC_IA64_PLTOFF22
:
9101 case BFD_RELOC_IA64_PLTOFF64I
:
9102 case BFD_RELOC_IA64_PLTOFF64MSB
:
9103 case BFD_RELOC_IA64_PLTOFF64LSB
:
9112 /* Decide from what point a pc-relative relocation is relative to,
9113 relative to the pc-relative fixup. Er, relatively speaking. */
9115 ia64_pcrel_from_section (fix
, sec
)
9119 unsigned long off
= fix
->fx_frag
->fr_address
+ fix
->fx_where
;
9121 if (bfd_get_section_flags (stdoutput
, sec
) & SEC_CODE
)
9127 /* This is called whenever some data item (not an instruction) needs a
9128 fixup. We pick the right reloc code depending on the byteorder
9129 currently in effect. */
9131 ia64_cons_fix_new (f
, where
, nbytes
, exp
)
9137 bfd_reloc_code_real_type code
;
9142 /* There are no reloc for 8 and 16 bit quantities, but we allow
9143 them here since they will work fine as long as the expression
9144 is fully defined at the end of the pass over the source file. */
9145 case 1: code
= BFD_RELOC_8
; break;
9146 case 2: code
= BFD_RELOC_16
; break;
9148 if (target_big_endian
)
9149 code
= BFD_RELOC_IA64_DIR32MSB
;
9151 code
= BFD_RELOC_IA64_DIR32LSB
;
9155 if (target_big_endian
)
9156 code
= BFD_RELOC_IA64_DIR64MSB
;
9158 code
= BFD_RELOC_IA64_DIR64LSB
;
9162 as_bad ("Unsupported fixup size %d", nbytes
);
9163 ignore_rest_of_line ();
9166 if (exp
->X_op
== O_pseudo_fixup
)
9169 exp
->X_op
= O_symbol
;
9170 code
= ia64_gen_real_reloc_type (exp
->X_op_symbol
, code
);
9172 fix
= fix_new_exp (f
, where
, nbytes
, exp
, 0, code
);
9173 /* We need to store the byte order in effect in case we're going
9174 to fix an 8 or 16 bit relocation (for which there no real
9175 relocs available). See md_apply_fix(). */
9176 fix
->tc_fix_data
.bigendian
= target_big_endian
;
9179 /* Return the actual relocation we wish to associate with the pseudo
9180 reloc described by SYM and R_TYPE. SYM should be one of the
9181 symbols in the pseudo_func array, or NULL. */
9183 static bfd_reloc_code_real_type
9184 ia64_gen_real_reloc_type (sym
, r_type
)
9186 bfd_reloc_code_real_type r_type
;
9188 bfd_reloc_code_real_type
new = 0;
9195 switch (S_GET_VALUE (sym
))
9197 case FUNC_FPTR_RELATIVE
:
9200 case BFD_RELOC_IA64_IMM64
: new = BFD_RELOC_IA64_FPTR64I
; break;
9201 case BFD_RELOC_IA64_DIR32MSB
: new = BFD_RELOC_IA64_FPTR32MSB
; break;
9202 case BFD_RELOC_IA64_DIR32LSB
: new = BFD_RELOC_IA64_FPTR32LSB
; break;
9203 case BFD_RELOC_IA64_DIR64MSB
: new = BFD_RELOC_IA64_FPTR64MSB
; break;
9204 case BFD_RELOC_IA64_DIR64LSB
: new = BFD_RELOC_IA64_FPTR64LSB
; break;
9209 case FUNC_GP_RELATIVE
:
9212 case BFD_RELOC_IA64_IMM22
: new = BFD_RELOC_IA64_GPREL22
; break;
9213 case BFD_RELOC_IA64_IMM64
: new = BFD_RELOC_IA64_GPREL64I
; break;
9214 case BFD_RELOC_IA64_DIR32MSB
: new = BFD_RELOC_IA64_GPREL32MSB
; break;
9215 case BFD_RELOC_IA64_DIR32LSB
: new = BFD_RELOC_IA64_GPREL32LSB
; break;
9216 case BFD_RELOC_IA64_DIR64MSB
: new = BFD_RELOC_IA64_GPREL64MSB
; break;
9217 case BFD_RELOC_IA64_DIR64LSB
: new = BFD_RELOC_IA64_GPREL64LSB
; break;
9222 case FUNC_LT_RELATIVE
:
9225 case BFD_RELOC_IA64_IMM22
: new = BFD_RELOC_IA64_LTOFF22
; break;
9226 case BFD_RELOC_IA64_IMM64
: new = BFD_RELOC_IA64_LTOFF64I
; break;
9231 case FUNC_PC_RELATIVE
:
9234 case BFD_RELOC_IA64_IMM22
: new = BFD_RELOC_IA64_PCREL22
; break;
9235 case BFD_RELOC_IA64_IMM64
: new = BFD_RELOC_IA64_PCREL64I
; break;
9236 case BFD_RELOC_IA64_DIR32MSB
: new = BFD_RELOC_IA64_PCREL32MSB
; break;
9237 case BFD_RELOC_IA64_DIR32LSB
: new = BFD_RELOC_IA64_PCREL32LSB
; break;
9238 case BFD_RELOC_IA64_DIR64MSB
: new = BFD_RELOC_IA64_PCREL64MSB
; break;
9239 case BFD_RELOC_IA64_DIR64LSB
: new = BFD_RELOC_IA64_PCREL64LSB
; break;
9244 case FUNC_PLT_RELATIVE
:
9247 case BFD_RELOC_IA64_IMM22
: new = BFD_RELOC_IA64_PLTOFF22
; break;
9248 case BFD_RELOC_IA64_IMM64
: new = BFD_RELOC_IA64_PLTOFF64I
; break;
9249 case BFD_RELOC_IA64_DIR64MSB
: new = BFD_RELOC_IA64_PLTOFF64MSB
;break;
9250 case BFD_RELOC_IA64_DIR64LSB
: new = BFD_RELOC_IA64_PLTOFF64LSB
;break;
9255 case FUNC_SEC_RELATIVE
:
9258 case BFD_RELOC_IA64_DIR32MSB
: new = BFD_RELOC_IA64_SECREL32MSB
;break;
9259 case BFD_RELOC_IA64_DIR32LSB
: new = BFD_RELOC_IA64_SECREL32LSB
;break;
9260 case BFD_RELOC_IA64_DIR64MSB
: new = BFD_RELOC_IA64_SECREL64MSB
;break;
9261 case BFD_RELOC_IA64_DIR64LSB
: new = BFD_RELOC_IA64_SECREL64LSB
;break;
9266 case FUNC_SEG_RELATIVE
:
9269 case BFD_RELOC_IA64_DIR32MSB
: new = BFD_RELOC_IA64_SEGREL32MSB
;break;
9270 case BFD_RELOC_IA64_DIR32LSB
: new = BFD_RELOC_IA64_SEGREL32LSB
;break;
9271 case BFD_RELOC_IA64_DIR64MSB
: new = BFD_RELOC_IA64_SEGREL64MSB
;break;
9272 case BFD_RELOC_IA64_DIR64LSB
: new = BFD_RELOC_IA64_SEGREL64LSB
;break;
9277 case FUNC_LTV_RELATIVE
:
9280 case BFD_RELOC_IA64_DIR32MSB
: new = BFD_RELOC_IA64_LTV32MSB
; break;
9281 case BFD_RELOC_IA64_DIR32LSB
: new = BFD_RELOC_IA64_LTV32LSB
; break;
9282 case BFD_RELOC_IA64_DIR64MSB
: new = BFD_RELOC_IA64_LTV64MSB
; break;
9283 case BFD_RELOC_IA64_DIR64LSB
: new = BFD_RELOC_IA64_LTV64LSB
; break;
9288 case FUNC_LT_FPTR_RELATIVE
:
9291 case BFD_RELOC_IA64_IMM22
:
9292 new = BFD_RELOC_IA64_LTOFF_FPTR22
; break;
9293 case BFD_RELOC_IA64_IMM64
:
9294 new = BFD_RELOC_IA64_LTOFF_FPTR64I
; break;
9302 /* Hmmmm. Should this ever occur? */
9309 /* Here is where generate the appropriate reloc for pseudo relocation
9312 ia64_validate_fix (fix
)
9315 switch (fix
->fx_r_type
)
9317 case BFD_RELOC_IA64_FPTR64I
:
9318 case BFD_RELOC_IA64_FPTR32MSB
:
9319 case BFD_RELOC_IA64_FPTR64LSB
:
9320 case BFD_RELOC_IA64_LTOFF_FPTR22
:
9321 case BFD_RELOC_IA64_LTOFF_FPTR64I
:
9322 if (fix
->fx_offset
!= 0)
9323 as_bad_where (fix
->fx_file
, fix
->fx_line
,
9324 "No addend allowed in @fptr() relocation");
9334 fix_insn (fix
, odesc
, value
)
9336 const struct ia64_operand
*odesc
;
9339 bfd_vma insn
[3], t0
, t1
, control_bits
;
9344 slot
= fix
->fx_where
& 0x3;
9345 fixpos
= fix
->fx_frag
->fr_literal
+ (fix
->fx_where
- slot
);
9347 /* Bundles are always in little-endian byte order */
9348 t0
= bfd_getl64 (fixpos
);
9349 t1
= bfd_getl64 (fixpos
+ 8);
9350 control_bits
= t0
& 0x1f;
9351 insn
[0] = (t0
>> 5) & 0x1ffffffffffLL
;
9352 insn
[1] = ((t0
>> 46) & 0x3ffff) | ((t1
& 0x7fffff) << 18);
9353 insn
[2] = (t1
>> 23) & 0x1ffffffffffLL
;
9356 if (odesc
- elf64_ia64_operands
== IA64_OPND_IMMU64
)
9358 insn
[1] = (value
>> 22) & 0x1ffffffffffLL
;
9359 insn
[2] |= (((value
& 0x7f) << 13)
9360 | (((value
>> 7) & 0x1ff) << 27)
9361 | (((value
>> 16) & 0x1f) << 22)
9362 | (((value
>> 21) & 0x1) << 21)
9363 | (((value
>> 63) & 0x1) << 36));
9365 else if (odesc
- elf64_ia64_operands
== IA64_OPND_IMMU62
)
9367 if (value
& ~0x3fffffffffffffffULL
)
9368 err
= "integer operand out of range";
9369 insn
[1] = (value
>> 21) & 0x1ffffffffffLL
;
9370 insn
[2] |= (((value
& 0xfffff) << 6) | (((value
>> 20) & 0x1) << 36));
9372 else if (odesc
- elf64_ia64_operands
== IA64_OPND_TGT64
)
9375 insn
[1] = ((value
>> 20) & 0x7fffffffffLL
) << 2;
9376 insn
[2] |= ((((value
>> 59) & 0x1) << 36)
9377 | (((value
>> 0) & 0xfffff) << 13));
9380 err
= (*odesc
->insert
) (odesc
, value
, insn
+ slot
);
9383 as_bad_where (fix
->fx_file
, fix
->fx_line
, err
);
9385 t0
= control_bits
| (insn
[0] << 5) | (insn
[1] << 46);
9386 t1
= ((insn
[1] >> 18) & 0x7fffff) | (insn
[2] << 23);
9387 number_to_chars_littleendian (fixpos
+ 0, t0
, 8);
9388 number_to_chars_littleendian (fixpos
+ 8, t1
, 8);
9391 /* Attempt to simplify or even eliminate a fixup. The return value is
9392 ignored; perhaps it was once meaningful, but now it is historical.
9393 To indicate that a fixup has been eliminated, set FIXP->FX_DONE.
9395 If fixp->fx_addsy is non-NULL, we'll have to generate a reloc entry
9398 md_apply_fix3 (fix
, valuep
, seg
)
9404 valueT value
= *valuep
;
9407 fixpos
= fix
->fx_frag
->fr_literal
+ fix
->fx_where
;
9411 switch (fix
->fx_r_type
)
9413 case BFD_RELOC_IA64_DIR32MSB
:
9414 fix
->fx_r_type
= BFD_RELOC_IA64_PCREL32MSB
;
9418 case BFD_RELOC_IA64_DIR32LSB
:
9419 fix
->fx_r_type
= BFD_RELOC_IA64_PCREL32LSB
;
9423 case BFD_RELOC_IA64_DIR64MSB
:
9424 fix
->fx_r_type
= BFD_RELOC_IA64_PCREL64MSB
;
9428 case BFD_RELOC_IA64_DIR64LSB
:
9429 fix
->fx_r_type
= BFD_RELOC_IA64_PCREL64LSB
;
9439 switch (fix
->fx_r_type
)
9442 as_bad_where (fix
->fx_file
, fix
->fx_line
,
9443 "%s must have a constant value",
9444 elf64_ia64_operands
[fix
->tc_fix_data
.opnd
].desc
);
9451 /* ??? This is a hack copied from tc-i386.c to make PCREL relocs
9452 work. There should be a better way to handle this. */
9454 fix
->fx_offset
+= fix
->fx_where
+ fix
->fx_frag
->fr_address
;
9456 else if (fix
->tc_fix_data
.opnd
== IA64_OPND_NIL
)
9458 if (fix
->tc_fix_data
.bigendian
)
9459 number_to_chars_bigendian (fixpos
, value
, fix
->fx_size
);
9461 number_to_chars_littleendian (fixpos
, value
, fix
->fx_size
);
9467 fix_insn (fix
, elf64_ia64_operands
+ fix
->tc_fix_data
.opnd
, value
);
9474 /* Generate the BFD reloc to be stuck in the object file from the
9475 fixup used internally in the assembler. */
9478 tc_gen_reloc (sec
, fixp
)
9484 reloc
= xmalloc (sizeof (*reloc
));
9485 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
9486 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
9487 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
9488 reloc
->addend
= fixp
->fx_offset
;
9489 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
9493 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
9494 "Cannot represent %s relocation in object file",
9495 bfd_get_reloc_code_name (fixp
->fx_r_type
));
9500 /* Turn a string in input_line_pointer into a floating point constant
9501 of type TYPE, and store the appropriate bytes in *LIT. The number
9502 of LITTLENUMS emitted is stored in *SIZE. An error message is
9503 returned, or NULL on OK. */
9505 #define MAX_LITTLENUMS 5
9508 md_atof (type
, lit
, size
)
9513 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
9514 LITTLENUM_TYPE
*word
;
9544 return "Bad call to MD_ATOF()";
9546 t
= atof_ieee (input_line_pointer
, type
, words
);
9548 input_line_pointer
= t
;
9549 *size
= prec
* sizeof (LITTLENUM_TYPE
);
9551 for (word
= words
+ prec
- 1; prec
--;)
9553 md_number_to_chars (lit
, (long) (*word
--), sizeof (LITTLENUM_TYPE
));
9554 lit
+= sizeof (LITTLENUM_TYPE
);
9559 /* Round up a section's size to the appropriate boundary. */
9561 md_section_align (seg
, size
)
9565 int align
= bfd_get_section_alignment (stdoutput
, seg
);
9566 valueT mask
= ((valueT
) 1 << align
) - 1;
9568 return (size
+ mask
) & ~mask
;
9571 /* Handle ia64 specific semantics of the align directive. */
9574 ia64_md_do_align (n
, fill
, len
, max
)
9580 /* Fill any pending bundle with nops. */
9581 if (bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
)
9582 ia64_flush_insns ();
9584 /* When we align code in a text section, emit a bundle of 3 nops instead of
9585 zero bytes. We can only do this if a multiple of 16 bytes was requested.
9586 N is log base 2 of the requested alignment. */
9588 && bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
9591 /* Use mfi bundle of nops with no stop bits. */
9592 static const unsigned char be_nop
[]
9593 = { 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
9594 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c};
9595 static const unsigned char le_nop
[]
9596 = { 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
9597 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00};
9599 /* Make sure we are on a 16-byte boundary, in case someone has been
9600 putting data into a text section. */
9601 frag_align (4, 0, 0);
9603 if (target_big_endian
)
9604 frag_align_pattern (n
, be_nop
, 16, max
);
9606 frag_align_pattern (n
, le_nop
, 16, max
);