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 { NULL
, no_argument
, NULL
, 0}
166 size_t md_longopts_size
= sizeof (md_longopts
);
170 struct hash_control
*pseudo_hash
; /* pseudo opcode hash table */
171 struct hash_control
*reg_hash
; /* register name hash table */
172 struct hash_control
*dynreg_hash
; /* dynamic register hash table */
173 struct hash_control
*const_hash
; /* constant hash table */
174 struct hash_control
*entry_hash
; /* code entry hint hash table */
176 symbolS
*regsym
[REG_NUM
];
178 /* If X_op is != O_absent, the registername for the instruction's
179 qualifying predicate. If NULL, p0 is assumed for instructions
180 that are predicatable. */
187 explicit_mode
: 1, /* which mode we're in */
188 default_explicit_mode
: 1, /* which mode is the default */
189 mode_explicitly_set
: 1, /* was the current mode explicitly set? */
192 /* Each bundle consists of up to three instructions. We keep
193 track of four most recent instructions so we can correctly set
194 the end_of_insn_group for the last instruction in a bundle. */
196 int num_slots_in_use
;
200 end_of_insn_group
: 1,
201 manual_bundling_on
: 1,
202 manual_bundling_off
: 1;
203 signed char user_template
; /* user-selected template, if any */
204 unsigned char qp_regno
; /* qualifying predicate */
205 /* This duplicates a good fraction of "struct fix" but we
206 can't use a "struct fix" instead since we can't call
207 fix_new_exp() until we know the address of the instruction. */
211 bfd_reloc_code_real_type code
;
212 enum ia64_opnd opnd
; /* type of operand in need of fix */
213 unsigned int is_pcrel
: 1; /* is operand pc-relative? */
214 expressionS expr
; /* the value to be inserted */
216 fixup
[2]; /* at most two fixups per insn */
217 struct ia64_opcode
*idesc
;
218 struct label_fix
*label_fixups
;
219 struct unw_rec_list
*unwind_record
; /* Unwind directive. */
222 unsigned int src_line
;
223 struct dwarf2_line_info debug_line
;
231 struct dynreg
*next
; /* next dynamic register */
233 unsigned short base
; /* the base register number */
234 unsigned short num_regs
; /* # of registers in this set */
236 *dynreg
[DYNREG_NUM_TYPES
], in
, loc
, out
, rot
;
238 flagword flags
; /* ELF-header flags */
241 unsigned hint
:1; /* is this hint currently valid? */
242 bfd_vma offset
; /* mem.offset offset */
243 bfd_vma base
; /* mem.offset base */
246 int path
; /* number of alt. entry points seen */
247 const char **entry_labels
; /* labels of all alternate paths in
248 the current DV-checking block. */
249 int maxpaths
; /* size currently allocated for
254 /* application registers: */
260 #define AR_BSPSTORE 18
275 {"ar.k0", 0}, {"ar.k1", 1}, {"ar.k2", 2}, {"ar.k3", 3},
276 {"ar.k4", 4}, {"ar.k5", 5}, {"ar.k6", 6}, {"ar.k7", 7},
277 {"ar.rsc", 16}, {"ar.bsp", 17},
278 {"ar.bspstore", 18}, {"ar.rnat", 19},
279 {"ar.fcr", 21}, {"ar.eflag", 24},
280 {"ar.csd", 25}, {"ar.ssd", 26},
281 {"ar.cflg", 27}, {"ar.fsr", 28},
282 {"ar.fir", 29}, {"ar.fdr", 30},
283 {"ar.ccv", 32}, {"ar.unat", 36},
284 {"ar.fpsr", 40}, {"ar.itc", 44},
285 {"ar.pfs", 64}, {"ar.lc", 65},
306 /* control registers: */
348 static const struct const_desc
355 /* PSR constant masks: */
358 {"psr.be", ((valueT
) 1) << 1},
359 {"psr.up", ((valueT
) 1) << 2},
360 {"psr.ac", ((valueT
) 1) << 3},
361 {"psr.mfl", ((valueT
) 1) << 4},
362 {"psr.mfh", ((valueT
) 1) << 5},
364 {"psr.ic", ((valueT
) 1) << 13},
365 {"psr.i", ((valueT
) 1) << 14},
366 {"psr.pk", ((valueT
) 1) << 15},
368 {"psr.dt", ((valueT
) 1) << 17},
369 {"psr.dfl", ((valueT
) 1) << 18},
370 {"psr.dfh", ((valueT
) 1) << 19},
371 {"psr.sp", ((valueT
) 1) << 20},
372 {"psr.pp", ((valueT
) 1) << 21},
373 {"psr.di", ((valueT
) 1) << 22},
374 {"psr.si", ((valueT
) 1) << 23},
375 {"psr.db", ((valueT
) 1) << 24},
376 {"psr.lp", ((valueT
) 1) << 25},
377 {"psr.tb", ((valueT
) 1) << 26},
378 {"psr.rt", ((valueT
) 1) << 27},
379 /* 28-31: reserved */
380 /* 32-33: cpl (current privilege level) */
381 {"psr.is", ((valueT
) 1) << 34},
382 {"psr.mc", ((valueT
) 1) << 35},
383 {"psr.it", ((valueT
) 1) << 36},
384 {"psr.id", ((valueT
) 1) << 37},
385 {"psr.da", ((valueT
) 1) << 38},
386 {"psr.dd", ((valueT
) 1) << 39},
387 {"psr.ss", ((valueT
) 1) << 40},
388 /* 41-42: ri (restart instruction) */
389 {"psr.ed", ((valueT
) 1) << 43},
390 {"psr.bn", ((valueT
) 1) << 44},
393 /* indirect register-sets/memory: */
402 { "CPUID", IND_CPUID
},
403 { "cpuid", IND_CPUID
},
415 /* Pseudo functions used to indicate relocation types (these functions
416 start with an at sign (@). */
438 /* reloc pseudo functions (these must come first!): */
439 { "fptr", PSEUDO_FUNC_RELOC
},
440 { "gprel", PSEUDO_FUNC_RELOC
},
441 { "ltoff", PSEUDO_FUNC_RELOC
},
442 { "pcrel", PSEUDO_FUNC_RELOC
},
443 { "pltoff", PSEUDO_FUNC_RELOC
},
444 { "secrel", PSEUDO_FUNC_RELOC
},
445 { "segrel", PSEUDO_FUNC_RELOC
},
446 { "ltv", PSEUDO_FUNC_RELOC
},
447 { 0, }, /* placeholder for FUNC_LT_FPTR_RELATIVE */
449 /* mbtype4 constants: */
450 { "alt", PSEUDO_FUNC_CONST
, { 0xa } },
451 { "brcst", PSEUDO_FUNC_CONST
, { 0x0 } },
452 { "mix", PSEUDO_FUNC_CONST
, { 0x8 } },
453 { "rev", PSEUDO_FUNC_CONST
, { 0xb } },
454 { "shuf", PSEUDO_FUNC_CONST
, { 0x9 } },
456 /* fclass constants: */
457 { "nat", PSEUDO_FUNC_CONST
, { 0x100 } },
458 { "qnan", PSEUDO_FUNC_CONST
, { 0x080 } },
459 { "snan", PSEUDO_FUNC_CONST
, { 0x040 } },
460 { "pos", PSEUDO_FUNC_CONST
, { 0x001 } },
461 { "neg", PSEUDO_FUNC_CONST
, { 0x002 } },
462 { "zero", PSEUDO_FUNC_CONST
, { 0x004 } },
463 { "unorm", PSEUDO_FUNC_CONST
, { 0x008 } },
464 { "norm", PSEUDO_FUNC_CONST
, { 0x010 } },
465 { "inf", PSEUDO_FUNC_CONST
, { 0x020 } },
467 { "natval", PSEUDO_FUNC_CONST
, { 0x100 } }, /* old usage */
469 /* unwind-related constants: */
470 { "svr4", PSEUDO_FUNC_CONST
, { 0 } },
471 { "hpux", PSEUDO_FUNC_CONST
, { 1 } },
472 { "nt", PSEUDO_FUNC_CONST
, { 2 } },
474 /* unwind-related registers: */
475 { "priunat",PSEUDO_FUNC_REG
, { REG_PRIUNAT
} }
478 /* 41-bit nop opcodes (one per unit): */
479 static const bfd_vma nop
[IA64_NUM_UNITS
] =
481 0x0000000000LL
, /* NIL => break 0 */
482 0x0008000000LL
, /* I-unit nop */
483 0x0008000000LL
, /* M-unit nop */
484 0x4000000000LL
, /* B-unit nop */
485 0x0008000000LL
, /* F-unit nop */
486 0x0008000000LL
, /* L-"unit" nop */
487 0x0008000000LL
, /* X-unit nop */
490 /* Can't be `const' as it's passed to input routines (which have the
491 habit of setting temporary sentinels. */
492 static char special_section_name
[][20] =
494 {".bss"}, {".sbss"}, {".sdata"}, {".rodata"}, {".comment"},
495 {".IA_64.unwind"}, {".IA_64.unwind_info"}
498 /* The best template for a particular sequence of up to three
500 #define N IA64_NUM_TYPES
501 static unsigned char best_template
[N
][N
][N
];
504 /* Resource dependencies currently in effect */
506 int depind
; /* dependency index */
507 const struct ia64_dependency
*dependency
; /* actual dependency */
508 unsigned specific
:1, /* is this a specific bit/regno? */
509 link_to_qp_branch
:1; /* will a branch on the same QP clear it?*/
510 int index
; /* specific regno/bit within dependency */
511 int note
; /* optional qualifying note (0 if none) */
515 int insn_srlz
; /* current insn serialization state */
516 int data_srlz
; /* current data serialization state */
517 int qp_regno
; /* qualifying predicate for this usage */
518 char *file
; /* what file marked this dependency */
519 int line
; /* what line marked this dependency */
520 struct mem_offset mem_offset
; /* optional memory offset hint */
521 int path
; /* corresponding code entry index */
523 static int regdepslen
= 0;
524 static int regdepstotlen
= 0;
525 static const char *dv_mode
[] = { "RAW", "WAW", "WAR" };
526 static const char *dv_sem
[] = { "none", "implied", "impliedf",
527 "data", "instr", "specific", "other" };
529 /* Current state of PR mutexation */
530 static struct qpmutex
{
533 } *qp_mutexes
= NULL
; /* QP mutex bitmasks */
534 static int qp_mutexeslen
= 0;
535 static int qp_mutexestotlen
= 0;
536 static valueT qp_safe_across_calls
= 0;
538 /* Current state of PR implications */
539 static struct qp_imply
{
542 unsigned p2_branched
:1;
544 } *qp_implies
= NULL
;
545 static int qp_implieslen
= 0;
546 static int qp_impliestotlen
= 0;
548 /* Keep track of static GR values so that indirect register usage can
549 sometimes be tracked. */
554 } gr_values
[128] = {{ 1, 0 }};
556 /* These are the routines required to output the various types of
559 typedef struct unw_rec_list
{
561 unsigned long slot_number
;
562 struct unw_rec_list
*next
;
565 #define SLOT_NUM_NOT_SET -1
569 unsigned long next_slot_number
;
571 /* Maintain a list of unwind entries for the current function. */
575 /* Any unwind entires that should be attached to the current slot
576 that an insn is being constructed for. */
577 unw_rec_list
*current_entry
;
579 /* These are used to create the unwind table entry for this function. */
582 symbolS
*info
; /* pointer to unwind info */
583 symbolS
*personality_routine
;
585 /* TRUE if processing unwind directives in a prologue region. */
589 typedef void (*vbyte_func
) PARAMS ((int, char *, char *));
591 /* Forward delarations: */
592 static int ar_is_in_integer_unit
PARAMS ((int regnum
));
593 static void set_section
PARAMS ((char *name
));
594 static unsigned int set_regstack
PARAMS ((unsigned int, unsigned int,
595 unsigned int, unsigned int));
596 static void dot_radix
PARAMS ((int));
597 static void dot_special_section
PARAMS ((int));
598 static void dot_proc
PARAMS ((int));
599 static void dot_fframe
PARAMS ((int));
600 static void dot_vframe
PARAMS ((int));
601 static void dot_save
PARAMS ((int));
602 static void dot_restore
PARAMS ((int));
603 static void dot_handlerdata
PARAMS ((int));
604 static void dot_unwentry
PARAMS ((int));
605 static void dot_altrp
PARAMS ((int));
606 static void dot_savemem
PARAMS ((int));
607 static void dot_saveg
PARAMS ((int));
608 static void dot_savef
PARAMS ((int));
609 static void dot_saveb
PARAMS ((int));
610 static void dot_savegf
PARAMS ((int));
611 static void dot_spill
PARAMS ((int));
612 static void dot_unwabi
PARAMS ((int));
613 static void dot_personality
PARAMS ((int));
614 static void dot_body
PARAMS ((int));
615 static void dot_prologue
PARAMS ((int));
616 static void dot_endp
PARAMS ((int));
617 static void dot_template
PARAMS ((int));
618 static void dot_regstk
PARAMS ((int));
619 static void dot_rot
PARAMS ((int));
620 static void dot_byteorder
PARAMS ((int));
621 static void dot_psr
PARAMS ((int));
622 static void dot_alias
PARAMS ((int));
623 static void dot_ln
PARAMS ((int));
624 static char *parse_section_name
PARAMS ((void));
625 static void dot_xdata
PARAMS ((int));
626 static void stmt_float_cons
PARAMS ((int));
627 static void stmt_cons_ua
PARAMS ((int));
628 static void dot_xfloat_cons
PARAMS ((int));
629 static void dot_xstringer
PARAMS ((int));
630 static void dot_xdata_ua
PARAMS ((int));
631 static void dot_xfloat_cons_ua
PARAMS ((int));
632 static void dot_pred_rel
PARAMS ((int));
633 static void dot_reg_val
PARAMS ((int));
634 static void dot_dv_mode
PARAMS ((int));
635 static void dot_entry
PARAMS ((int));
636 static void dot_mem_offset
PARAMS ((int));
637 static void add_unwind_entry
PARAMS((unw_rec_list
*ptr
));
638 static symbolS
* declare_register
PARAMS ((const char *name
, int regnum
));
639 static void declare_register_set
PARAMS ((const char *, int, int));
640 static unsigned int operand_width
PARAMS ((enum ia64_opnd
));
641 static int operand_match
PARAMS ((const struct ia64_opcode
*idesc
,
642 int index
, expressionS
*e
));
643 static int parse_operand
PARAMS ((expressionS
*e
));
644 static struct ia64_opcode
* parse_operands
PARAMS ((struct ia64_opcode
*));
645 static void build_insn
PARAMS ((struct slot
*, bfd_vma
*));
646 static void emit_one_bundle
PARAMS ((void));
647 static void fix_insn
PARAMS ((fixS
*, const struct ia64_operand
*, valueT
));
648 static bfd_reloc_code_real_type ia64_gen_real_reloc_type
PARAMS ((struct symbol
*sym
,
649 bfd_reloc_code_real_type r_type
));
650 static void insn_group_break
PARAMS ((int, int, int));
651 static void add_qp_mutex
PARAMS((valueT mask
));
652 static void add_qp_imply
PARAMS((int p1
, int p2
));
653 static void clear_qp_branch_flag
PARAMS((valueT mask
));
654 static void clear_qp_mutex
PARAMS((valueT mask
));
655 static void clear_qp_implies
PARAMS((valueT p1_mask
, valueT p2_mask
));
656 static void clear_register_values
PARAMS ((void));
657 static void print_dependency
PARAMS ((const char *action
, int depind
));
658 static int is_conditional_branch
PARAMS ((struct ia64_opcode
*));
659 static int is_interruption_or_rfi
PARAMS ((struct ia64_opcode
*));
660 static int check_dv
PARAMS((struct ia64_opcode
*idesc
));
661 static void check_dependencies
PARAMS((struct ia64_opcode
*));
662 static void mark_resources
PARAMS((struct ia64_opcode
*));
663 static void update_dependencies
PARAMS((struct ia64_opcode
*));
664 static void note_register_values
PARAMS((struct ia64_opcode
*));
665 static void output_R3_format
PARAMS ((vbyte_func
, unw_record_type
, unsigned long));
666 static void output_B3_format
PARAMS ((vbyte_func
, unsigned long, unsigned long));
667 static void output_B4_format
PARAMS ((vbyte_func
, unw_record_type
, unsigned long));
669 /* Determine if application register REGNUM resides in the integer
670 unit (as opposed to the memory unit). */
672 ar_is_in_integer_unit (reg
)
677 return (reg
== 64 /* pfs */
678 || reg
== 65 /* lc */
679 || reg
== 66 /* ec */
680 /* ??? ias accepts and puts these in the integer unit. */
681 || (reg
>= 112 && reg
<= 127));
684 /* Switch to section NAME and create section if necessary. It's
685 rather ugly that we have to manipulate input_line_pointer but I
686 don't see any other way to accomplish the same thing without
687 changing obj-elf.c (which may be the Right Thing, in the end). */
692 char *saved_input_line_pointer
;
694 saved_input_line_pointer
= input_line_pointer
;
695 input_line_pointer
= name
;
697 input_line_pointer
= saved_input_line_pointer
;
700 /* Map SHF_IA_64_SHORT to SEC_SMALL_DATA. */
703 ia64_elf_section_flags (flags
, attr
, type
)
707 if (attr
& SHF_IA_64_SHORT
)
708 flags
|= SEC_SMALL_DATA
;
713 set_regstack (ins
, locs
, outs
, rots
)
714 unsigned int ins
, locs
, outs
, rots
;
716 unsigned int sof
; /* size of frame */
718 sof
= ins
+ locs
+ outs
;
721 as_bad ("Size of frame exceeds maximum of 96 registers");
726 as_warn ("Size of rotating registers exceeds frame size");
729 md
.in
.base
= REG_GR
+ 32;
730 md
.loc
.base
= md
.in
.base
+ ins
;
731 md
.out
.base
= md
.loc
.base
+ locs
;
733 md
.in
.num_regs
= ins
;
734 md
.loc
.num_regs
= locs
;
735 md
.out
.num_regs
= outs
;
736 md
.rot
.num_regs
= rots
;
743 struct label_fix
*lfix
;
745 subsegT saved_subseg
;
747 if (!md
.last_text_seg
)
751 saved_subseg
= now_subseg
;
753 subseg_set (md
.last_text_seg
, 0);
755 while (md
.num_slots_in_use
> 0)
756 emit_one_bundle (); /* force out queued instructions */
758 /* In case there are labels following the last instruction, resolve
760 for (lfix
= CURR_SLOT
.label_fixups
; lfix
; lfix
= lfix
->next
)
762 S_SET_VALUE (lfix
->sym
, frag_now_fix ());
763 symbol_set_frag (lfix
->sym
, frag_now
);
765 CURR_SLOT
.label_fixups
= 0;
767 subseg_set (saved_seg
, saved_subseg
);
771 ia64_do_align (nbytes
)
774 char *saved_input_line_pointer
= input_line_pointer
;
776 input_line_pointer
= "";
777 s_align_bytes (nbytes
);
778 input_line_pointer
= saved_input_line_pointer
;
782 ia64_cons_align (nbytes
)
787 char *saved_input_line_pointer
= input_line_pointer
;
788 input_line_pointer
= "";
789 s_align_bytes (nbytes
);
790 input_line_pointer
= saved_input_line_pointer
;
794 /* Output COUNT bytes to a memory location. */
795 static unsigned char *vbyte_mem_ptr
= NULL
;
798 output_vbyte_mem (count
, ptr
, comment
)
804 if (vbyte_mem_ptr
== NULL
)
809 for (x
= 0; x
< count
; x
++)
810 *(vbyte_mem_ptr
++) = ptr
[x
];
813 /* Count the number of bytes required for records. */
814 static int vbyte_count
= 0;
816 count_output (count
, ptr
, comment
)
821 vbyte_count
+= count
;
825 output_R1_format (f
, rtype
, rlen
)
827 unw_record_type rtype
;
834 output_R3_format (f
, rtype
, rlen
);
840 else if (rtype
!= prologue
)
841 as_bad ("record type is not valid");
843 byte
= UNW_R1
| (r
<< 5) | (rlen
& 0x1f);
844 (*f
) (1, &byte
, NULL
);
848 output_R2_format (f
, mask
, grsave
, rlen
)
855 mask
= (mask
& 0x0f);
856 grsave
= (grsave
& 0x7f);
858 bytes
[0] = (UNW_R2
| (mask
>> 1));
859 bytes
[1] = (((mask
& 0x01) << 7) | grsave
);
860 count
+= output_leb128 (bytes
+ 2, rlen
, 0);
861 (*f
) (count
, bytes
, NULL
);
865 output_R3_format (f
, rtype
, rlen
)
867 unw_record_type rtype
;
874 output_R1_format (f
, rtype
, rlen
);
880 else if (rtype
!= prologue
)
881 as_bad ("record type is not valid");
882 bytes
[0] = (UNW_R3
| r
);
883 count
= output_leb128 (bytes
+ 1, rlen
, 0);
884 (*f
) (count
+ 1, bytes
, NULL
);
888 output_P1_format (f
, brmask
)
893 byte
= UNW_P1
| (brmask
& 0x1f);
894 (*f
) (1, &byte
, NULL
);
898 output_P2_format (f
, brmask
, gr
)
904 brmask
= (brmask
& 0x1f);
905 bytes
[0] = UNW_P2
| (brmask
>> 1);
906 bytes
[1] = (((brmask
& 1) << 7) | gr
);
907 (*f
) (2, bytes
, NULL
);
911 output_P3_format (f
, rtype
, reg
)
913 unw_record_type rtype
;
958 as_bad ("Invalid record type for P3 format.");
960 bytes
[0] = (UNW_P3
| (r
>> 1));
961 bytes
[1] = (((r
& 1) << 7) | reg
);
962 (*f
) (2, bytes
, NULL
);
967 output_P4_format (f
, imask
, imask_size
)
969 unsigned char *imask
;
970 unsigned long imask_size
;
973 (*f
) (imask_size
, imask
, NULL
);
977 output_P5_format (f
, grmask
, frmask
)
980 unsigned long frmask
;
983 grmask
= (grmask
& 0x0f);
986 bytes
[1] = ((grmask
<< 4) | ((frmask
& 0x000f0000) >> 16));
987 bytes
[2] = ((frmask
& 0x0000ff00) >> 8);
988 bytes
[3] = (frmask
& 0x000000ff);
989 (*f
) (4, bytes
, NULL
);
993 output_P6_format (f
, rtype
, rmask
)
995 unw_record_type rtype
;
1001 if (rtype
== gr_mem
)
1003 else if (rtype
!= fr_mem
)
1004 as_bad ("Invalid record type for format P6");
1005 byte
= (UNW_P6
| (r
<< 4) | (rmask
& 0x0f));
1006 (*f
) (1, &byte
, NULL
);
1010 output_P7_format (f
, rtype
, w1
, w2
)
1012 unw_record_type rtype
;
1019 count
+= output_leb128 (bytes
+ 1, w1
, 0);
1024 count
+= output_leb128 (bytes
+ count
, w2
>> 4, 0);
1074 bytes
[0] = (UNW_P7
| r
);
1075 (*f
) (count
, bytes
, NULL
);
1079 output_P8_format (f
, rtype
, t
)
1081 unw_record_type rtype
;
1120 case bspstore_psprel
:
1123 case bspstore_sprel
:
1135 case priunat_when_gr
:
1138 case priunat_psprel
:
1144 case priunat_when_mem
:
1151 count
+= output_leb128 (bytes
+ 2, t
, 0);
1152 (*f
) (count
, bytes
, NULL
);
1156 output_P9_format (f
, grmask
, gr
)
1163 bytes
[1] = (grmask
& 0x0f);
1164 bytes
[2] = (gr
& 0x7f);
1165 (*f
) (3, bytes
, NULL
);
1169 output_P10_format (f
, abi
, context
)
1176 bytes
[1] = (abi
& 0xff);
1177 bytes
[2] = (context
& 0xff);
1178 (*f
) (3, bytes
, NULL
);
1182 output_B1_format (f
, rtype
, label
)
1184 unw_record_type rtype
;
1185 unsigned long label
;
1191 output_B4_format (f
, rtype
, label
);
1194 if (rtype
== copy_state
)
1196 else if (rtype
!= label_state
)
1197 as_bad ("Invalid record type for format B1");
1199 byte
= (UNW_B1
| (r
<< 5) | (label
& 0x1f));
1200 (*f
) (1, &byte
, NULL
);
1204 output_B2_format (f
, ecount
, t
)
1206 unsigned long ecount
;
1213 output_B3_format (f
, ecount
, t
);
1216 bytes
[0] = (UNW_B2
| (ecount
& 0x1f));
1217 count
+= output_leb128 (bytes
+ 1, t
, 0);
1218 (*f
) (count
, bytes
, NULL
);
1222 output_B3_format (f
, ecount
, t
)
1224 unsigned long ecount
;
1231 output_B2_format (f
, ecount
, t
);
1235 count
+= output_leb128 (bytes
+ 1, t
, 0);
1236 count
+= output_leb128 (bytes
+ count
, ecount
, 0);
1237 (*f
) (count
, bytes
, NULL
);
1241 output_B4_format (f
, rtype
, label
)
1243 unw_record_type rtype
;
1244 unsigned long label
;
1251 output_B1_format (f
, rtype
, label
);
1255 if (rtype
== copy_state
)
1257 else if (rtype
!= label_state
)
1258 as_bad ("Invalid record type for format B1");
1260 bytes
[0] = (UNW_B4
| (r
<< 3));
1261 count
+= output_leb128 (bytes
+ 1, label
, 0);
1262 (*f
) (count
, bytes
, NULL
);
1266 format_ab_reg (ab
, reg
)
1273 ret
= (ab
<< 5) | reg
;
1278 output_X1_format (f
, rtype
, ab
, reg
, t
, w1
)
1280 unw_record_type rtype
;
1290 if (rtype
== spill_sprel
)
1292 else if (rtype
!= spill_psprel
)
1293 as_bad ("Invalid record type for format X1");
1294 bytes
[1] = ((r
<< 7) | format_ab_reg (ab
, reg
));
1295 count
+= output_leb128 (bytes
+ 2, t
, 0);
1296 count
+= output_leb128 (bytes
+ count
, w1
, 0);
1297 (*f
) (count
, bytes
, NULL
);
1301 output_X2_format (f
, ab
, reg
, x
, y
, treg
, t
)
1310 bytes
[1] = (((x
& 1) << 7) | format_ab_reg (ab
, reg
));
1311 bytes
[2] = (((y
& 1) << 7) | (treg
& 0x7f));
1312 count
+= output_leb128 (bytes
+ 3, t
, 0);
1313 (*f
) (count
, bytes
, NULL
);
1317 output_X3_format (f
, rtype
, qp
, ab
, reg
, t
, w1
)
1319 unw_record_type rtype
;
1330 if (rtype
== spill_sprel_p
)
1332 else if (rtype
!= spill_psprel_p
)
1333 as_bad ("Invalid record type for format X3");
1334 bytes
[1] = ((r
<< 7) | (qp
& 0x3f));
1335 bytes
[2] = format_ab_reg (ab
, reg
);
1336 count
+= output_leb128 (bytes
+ 3, t
, 0);
1337 count
+= output_leb128 (bytes
+ count
, w1
, 0);
1338 (*f
) (count
, bytes
, NULL
);
1342 output_X4_format (f
, qp
, ab
, reg
, x
, y
, treg
, t
)
1352 bytes
[1] = (qp
& 0x3f);
1353 bytes
[2] = (((x
& 1) << 7) | format_ab_reg (ab
, reg
));
1354 bytes
[3] = (((y
& 1) << 7) | (treg
& 0x7f));
1355 count
+= output_leb128 (bytes
+ 4, t
, 0);
1356 (*f
) (count
, bytes
, NULL
);
1359 /* This function allocates a record list structure, and initializes fields. */
1360 static unw_rec_list
*
1361 alloc_record (unw_record_type t
)
1364 ptr
= xmalloc (sizeof (*ptr
));
1366 ptr
->slot_number
= SLOT_NUM_NOT_SET
;
1371 /* This function frees an entire list of record structures. */
1373 free_list_records (unw_rec_list
*first
)
1376 for (ptr
= first
; ptr
!= NULL
; )
1378 unw_rec_list
*tmp
= ptr
;
1380 if ((tmp
->r
.type
== prologue
|| tmp
->r
.type
== prologue_gr
)
1381 && tmp
->r
.record
.r
.mask
.i
)
1382 free (tmp
->r
.record
.r
.mask
.i
);
1389 static unw_rec_list
*
1392 unw_rec_list
*ptr
= alloc_record (prologue
);
1393 memset (&ptr
->r
.record
.r
.mask
, 0, sizeof (ptr
->r
.record
.r
.mask
));
1397 static unw_rec_list
*
1398 output_prologue_gr (saved_mask
, reg
)
1399 unsigned int saved_mask
;
1402 unw_rec_list
*ptr
= alloc_record (prologue_gr
);
1403 memset (&ptr
->r
.record
.r
.mask
, 0, sizeof (ptr
->r
.record
.r
.mask
));
1404 ptr
->r
.record
.r
.grmask
= saved_mask
;
1405 ptr
->r
.record
.r
.grsave
= reg
;
1409 static unw_rec_list
*
1412 unw_rec_list
*ptr
= alloc_record (body
);
1416 static unw_rec_list
*
1417 output_mem_stack_f (size
)
1420 unw_rec_list
*ptr
= alloc_record (mem_stack_f
);
1421 ptr
->r
.record
.p
.size
= size
;
1425 static unw_rec_list
*
1426 output_mem_stack_v ()
1428 unw_rec_list
*ptr
= alloc_record (mem_stack_v
);
1432 static unw_rec_list
*
1436 unw_rec_list
*ptr
= alloc_record (psp_gr
);
1437 ptr
->r
.record
.p
.gr
= gr
;
1441 static unw_rec_list
*
1442 output_psp_sprel (offset
)
1443 unsigned int offset
;
1445 unw_rec_list
*ptr
= alloc_record (psp_sprel
);
1446 ptr
->r
.record
.p
.spoff
= offset
/4;
1450 static unw_rec_list
*
1453 unw_rec_list
*ptr
= alloc_record (rp_when
);
1457 static unw_rec_list
*
1461 unw_rec_list
*ptr
= alloc_record (rp_gr
);
1462 ptr
->r
.record
.p
.gr
= gr
;
1466 static unw_rec_list
*
1470 unw_rec_list
*ptr
= alloc_record (rp_br
);
1471 ptr
->r
.record
.p
.br
= br
;
1475 static unw_rec_list
*
1476 output_rp_psprel (offset
)
1477 unsigned int offset
;
1479 unw_rec_list
*ptr
= alloc_record (rp_psprel
);
1480 ptr
->r
.record
.p
.pspoff
= offset
/4;
1484 static unw_rec_list
*
1485 output_rp_sprel (offset
)
1486 unsigned int offset
;
1488 unw_rec_list
*ptr
= alloc_record (rp_sprel
);
1489 ptr
->r
.record
.p
.spoff
= offset
/4;
1493 static unw_rec_list
*
1496 unw_rec_list
*ptr
= alloc_record (pfs_when
);
1500 static unw_rec_list
*
1504 unw_rec_list
*ptr
= alloc_record (pfs_gr
);
1505 ptr
->r
.record
.p
.gr
= gr
;
1509 static unw_rec_list
*
1510 output_pfs_psprel (offset
)
1511 unsigned int offset
;
1513 unw_rec_list
*ptr
= alloc_record (pfs_psprel
);
1514 ptr
->r
.record
.p
.pspoff
= offset
/4;
1518 static unw_rec_list
*
1519 output_pfs_sprel (offset
)
1520 unsigned int offset
;
1522 unw_rec_list
*ptr
= alloc_record (pfs_sprel
);
1523 ptr
->r
.record
.p
.spoff
= offset
/4;
1527 static unw_rec_list
*
1528 output_preds_when ()
1530 unw_rec_list
*ptr
= alloc_record (preds_when
);
1534 static unw_rec_list
*
1535 output_preds_gr (gr
)
1538 unw_rec_list
*ptr
= alloc_record (preds_gr
);
1539 ptr
->r
.record
.p
.gr
= gr
;
1543 static unw_rec_list
*
1544 output_preds_psprel (offset
)
1545 unsigned int offset
;
1547 unw_rec_list
*ptr
= alloc_record (preds_psprel
);
1548 ptr
->r
.record
.p
.pspoff
= offset
/4;
1552 static unw_rec_list
*
1553 output_preds_sprel (offset
)
1554 unsigned int offset
;
1556 unw_rec_list
*ptr
= alloc_record (preds_sprel
);
1557 ptr
->r
.record
.p
.spoff
= offset
/4;
1561 static unw_rec_list
*
1562 output_fr_mem (mask
)
1565 unw_rec_list
*ptr
= alloc_record (fr_mem
);
1566 ptr
->r
.record
.p
.rmask
= mask
;
1570 static unw_rec_list
*
1571 output_frgr_mem (gr_mask
, fr_mask
)
1572 unsigned int gr_mask
;
1573 unsigned int fr_mask
;
1575 unw_rec_list
*ptr
= alloc_record (frgr_mem
);
1576 ptr
->r
.record
.p
.grmask
= gr_mask
;
1577 ptr
->r
.record
.p
.frmask
= fr_mask
;
1581 static unw_rec_list
*
1582 output_gr_gr (mask
, reg
)
1586 unw_rec_list
*ptr
= alloc_record (gr_gr
);
1587 ptr
->r
.record
.p
.grmask
= mask
;
1588 ptr
->r
.record
.p
.gr
= reg
;
1592 static unw_rec_list
*
1593 output_gr_mem (mask
)
1596 unw_rec_list
*ptr
= alloc_record (gr_mem
);
1597 ptr
->r
.record
.p
.rmask
= mask
;
1601 static unw_rec_list
*
1602 output_br_mem (unsigned int mask
)
1604 unw_rec_list
*ptr
= alloc_record (br_mem
);
1605 ptr
->r
.record
.p
.brmask
= mask
;
1609 static unw_rec_list
*
1610 output_br_gr (save_mask
, reg
)
1611 unsigned int save_mask
;
1614 unw_rec_list
*ptr
= alloc_record (br_gr
);
1615 ptr
->r
.record
.p
.brmask
= save_mask
;
1616 ptr
->r
.record
.p
.gr
= reg
;
1620 static unw_rec_list
*
1621 output_spill_base (offset
)
1622 unsigned int offset
;
1624 unw_rec_list
*ptr
= alloc_record (spill_base
);
1625 ptr
->r
.record
.p
.pspoff
= offset
/4;
1629 static unw_rec_list
*
1632 unw_rec_list
*ptr
= alloc_record (unat_when
);
1636 static unw_rec_list
*
1640 unw_rec_list
*ptr
= alloc_record (unat_gr
);
1641 ptr
->r
.record
.p
.gr
= gr
;
1645 static unw_rec_list
*
1646 output_unat_psprel (offset
)
1647 unsigned int offset
;
1649 unw_rec_list
*ptr
= alloc_record (unat_psprel
);
1650 ptr
->r
.record
.p
.pspoff
= offset
/4;
1654 static unw_rec_list
*
1655 output_unat_sprel (offset
)
1656 unsigned int offset
;
1658 unw_rec_list
*ptr
= alloc_record (unat_sprel
);
1659 ptr
->r
.record
.p
.spoff
= offset
/4;
1663 static unw_rec_list
*
1666 unw_rec_list
*ptr
= alloc_record (lc_when
);
1670 static unw_rec_list
*
1674 unw_rec_list
*ptr
= alloc_record (lc_gr
);
1675 ptr
->r
.record
.p
.gr
= gr
;
1679 static unw_rec_list
*
1680 output_lc_psprel (offset
)
1681 unsigned int offset
;
1683 unw_rec_list
*ptr
= alloc_record (lc_psprel
);
1684 ptr
->r
.record
.p
.pspoff
= offset
/4;
1688 static unw_rec_list
*
1689 output_lc_sprel (offset
)
1690 unsigned int offset
;
1692 unw_rec_list
*ptr
= alloc_record (lc_sprel
);
1693 ptr
->r
.record
.p
.spoff
= offset
/4;
1697 static unw_rec_list
*
1700 unw_rec_list
*ptr
= alloc_record (fpsr_when
);
1704 static unw_rec_list
*
1708 unw_rec_list
*ptr
= alloc_record (fpsr_gr
);
1709 ptr
->r
.record
.p
.gr
= gr
;
1713 static unw_rec_list
*
1714 output_fpsr_psprel (offset
)
1715 unsigned int offset
;
1717 unw_rec_list
*ptr
= alloc_record (fpsr_psprel
);
1718 ptr
->r
.record
.p
.pspoff
= offset
/4;
1722 static unw_rec_list
*
1723 output_fpsr_sprel (offset
)
1724 unsigned int offset
;
1726 unw_rec_list
*ptr
= alloc_record (fpsr_sprel
);
1727 ptr
->r
.record
.p
.spoff
= offset
/4;
1731 static unw_rec_list
*
1732 output_priunat_when_gr ()
1734 unw_rec_list
*ptr
= alloc_record (priunat_when_gr
);
1738 static unw_rec_list
*
1739 output_priunat_when_mem ()
1741 unw_rec_list
*ptr
= alloc_record (priunat_when_mem
);
1745 static unw_rec_list
*
1746 output_priunat_gr (gr
)
1749 unw_rec_list
*ptr
= alloc_record (priunat_gr
);
1750 ptr
->r
.record
.p
.gr
= gr
;
1754 static unw_rec_list
*
1755 output_priunat_psprel (offset
)
1756 unsigned int offset
;
1758 unw_rec_list
*ptr
= alloc_record (priunat_psprel
);
1759 ptr
->r
.record
.p
.pspoff
= offset
/4;
1763 static unw_rec_list
*
1764 output_priunat_sprel (offset
)
1765 unsigned int offset
;
1767 unw_rec_list
*ptr
= alloc_record (priunat_sprel
);
1768 ptr
->r
.record
.p
.spoff
= offset
/4;
1772 static unw_rec_list
*
1775 unw_rec_list
*ptr
= alloc_record (bsp_when
);
1779 static unw_rec_list
*
1783 unw_rec_list
*ptr
= alloc_record (bsp_gr
);
1784 ptr
->r
.record
.p
.gr
= gr
;
1788 static unw_rec_list
*
1789 output_bsp_psprel (offset
)
1790 unsigned int offset
;
1792 unw_rec_list
*ptr
= alloc_record (bsp_psprel
);
1793 ptr
->r
.record
.p
.pspoff
= offset
/4;
1797 static unw_rec_list
*
1798 output_bsp_sprel (offset
)
1799 unsigned int offset
;
1801 unw_rec_list
*ptr
= alloc_record (bsp_sprel
);
1802 ptr
->r
.record
.p
.spoff
= offset
/4;
1806 static unw_rec_list
*
1807 output_bspstore_when ()
1809 unw_rec_list
*ptr
= alloc_record (bspstore_when
);
1813 static unw_rec_list
*
1814 output_bspstore_gr (gr
)
1817 unw_rec_list
*ptr
= alloc_record (bspstore_gr
);
1818 ptr
->r
.record
.p
.gr
= gr
;
1822 static unw_rec_list
*
1823 output_bspstore_psprel (offset
)
1824 unsigned int offset
;
1826 unw_rec_list
*ptr
= alloc_record (bspstore_psprel
);
1827 ptr
->r
.record
.p
.pspoff
= offset
/4;
1831 static unw_rec_list
*
1832 output_bspstore_sprel (offset
)
1833 unsigned int offset
;
1835 unw_rec_list
*ptr
= alloc_record (bspstore_sprel
);
1836 ptr
->r
.record
.p
.spoff
= offset
/4;
1840 static unw_rec_list
*
1843 unw_rec_list
*ptr
= alloc_record (rnat_when
);
1847 static unw_rec_list
*
1851 unw_rec_list
*ptr
= alloc_record (rnat_gr
);
1852 ptr
->r
.record
.p
.gr
= gr
;
1856 static unw_rec_list
*
1857 output_rnat_psprel (offset
)
1858 unsigned int offset
;
1860 unw_rec_list
*ptr
= alloc_record (rnat_psprel
);
1861 ptr
->r
.record
.p
.pspoff
= offset
/4;
1865 static unw_rec_list
*
1866 output_rnat_sprel (offset
)
1867 unsigned int offset
;
1869 unw_rec_list
*ptr
= alloc_record (rnat_sprel
);
1870 ptr
->r
.record
.p
.spoff
= offset
/4;
1874 static unw_rec_list
*
1875 output_unwabi (abi
, context
)
1877 unsigned long context
;
1879 unw_rec_list
*ptr
= alloc_record (unwabi
);
1880 ptr
->r
.record
.p
.abi
= abi
;
1881 ptr
->r
.record
.p
.context
= context
;
1885 static unw_rec_list
*
1886 output_epilogue (unsigned long ecount
)
1888 unw_rec_list
*ptr
= alloc_record (epilogue
);
1889 ptr
->r
.record
.b
.ecount
= ecount
;
1893 static unw_rec_list
*
1894 output_label_state (unsigned long label
)
1896 unw_rec_list
*ptr
= alloc_record (label_state
);
1897 ptr
->r
.record
.b
.label
= label
;
1901 static unw_rec_list
*
1902 output_copy_state (unsigned long label
)
1904 unw_rec_list
*ptr
= alloc_record (copy_state
);
1905 ptr
->r
.record
.b
.label
= label
;
1909 static unw_rec_list
*
1910 output_spill_psprel (ab
, reg
, offset
)
1913 unsigned int offset
;
1915 unw_rec_list
*ptr
= alloc_record (spill_psprel
);
1916 ptr
->r
.record
.x
.ab
= ab
;
1917 ptr
->r
.record
.x
.reg
= reg
;
1918 ptr
->r
.record
.x
.pspoff
= offset
/4;
1922 static unw_rec_list
*
1923 output_spill_sprel (ab
, reg
, offset
)
1926 unsigned int offset
;
1928 unw_rec_list
*ptr
= alloc_record (spill_sprel
);
1929 ptr
->r
.record
.x
.ab
= ab
;
1930 ptr
->r
.record
.x
.reg
= reg
;
1931 ptr
->r
.record
.x
.spoff
= offset
/4;
1935 static unw_rec_list
*
1936 output_spill_psprel_p (ab
, reg
, offset
, predicate
)
1939 unsigned int offset
;
1940 unsigned int predicate
;
1942 unw_rec_list
*ptr
= alloc_record (spill_psprel_p
);
1943 ptr
->r
.record
.x
.ab
= ab
;
1944 ptr
->r
.record
.x
.reg
= reg
;
1945 ptr
->r
.record
.x
.pspoff
= offset
/4;
1946 ptr
->r
.record
.x
.qp
= predicate
;
1950 static unw_rec_list
*
1951 output_spill_sprel_p (ab
, reg
, offset
, predicate
)
1954 unsigned int offset
;
1955 unsigned int predicate
;
1957 unw_rec_list
*ptr
= alloc_record (spill_sprel_p
);
1958 ptr
->r
.record
.x
.ab
= ab
;
1959 ptr
->r
.record
.x
.reg
= reg
;
1960 ptr
->r
.record
.x
.spoff
= offset
/4;
1961 ptr
->r
.record
.x
.qp
= predicate
;
1965 static unw_rec_list
*
1966 output_spill_reg (ab
, reg
, targ_reg
, xy
)
1969 unsigned int targ_reg
;
1972 unw_rec_list
*ptr
= alloc_record (spill_reg
);
1973 ptr
->r
.record
.x
.ab
= ab
;
1974 ptr
->r
.record
.x
.reg
= reg
;
1975 ptr
->r
.record
.x
.treg
= targ_reg
;
1976 ptr
->r
.record
.x
.xy
= xy
;
1980 static unw_rec_list
*
1981 output_spill_reg_p (ab
, reg
, targ_reg
, xy
, predicate
)
1984 unsigned int targ_reg
;
1986 unsigned int predicate
;
1988 unw_rec_list
*ptr
= alloc_record (spill_reg_p
);
1989 ptr
->r
.record
.x
.ab
= ab
;
1990 ptr
->r
.record
.x
.reg
= reg
;
1991 ptr
->r
.record
.x
.treg
= targ_reg
;
1992 ptr
->r
.record
.x
.xy
= xy
;
1993 ptr
->r
.record
.x
.qp
= predicate
;
1997 /* Given a unw_rec_list process the correct format with the
1998 specified function. */
2000 process_one_record (ptr
, f
)
2004 unsigned long fr_mask
, gr_mask
;
2006 switch (ptr
->r
.type
)
2012 /* these are taken care of by prologue/prologue_gr */
2017 if (ptr
->r
.type
== prologue_gr
)
2018 output_R2_format (f
, ptr
->r
.record
.r
.grmask
,
2019 ptr
->r
.record
.r
.grsave
, ptr
->r
.record
.r
.rlen
);
2021 output_R1_format (f
, ptr
->r
.type
, ptr
->r
.record
.r
.rlen
);
2023 /* output descriptor(s) for union of register spills (if any): */
2024 gr_mask
= ptr
->r
.record
.r
.mask
.gr_mem
;
2025 fr_mask
= ptr
->r
.record
.r
.mask
.fr_mem
;
2028 if ((fr_mask
& ~0xfUL
) == 0)
2029 output_P6_format (f
, fr_mem
, fr_mask
);
2032 output_P5_format (f
, gr_mask
, fr_mask
);
2037 output_P6_format (f
, gr_mem
, gr_mask
);
2038 if (ptr
->r
.record
.r
.mask
.br_mem
)
2039 output_P1_format (f
, ptr
->r
.record
.r
.mask
.br_mem
);
2041 /* output imask descriptor if necessary: */
2042 if (ptr
->r
.record
.r
.mask
.i
)
2043 output_P4_format (f
, ptr
->r
.record
.r
.mask
.i
,
2044 ptr
->r
.record
.r
.imask_size
);
2048 output_R1_format (f
, ptr
->r
.type
, ptr
->r
.record
.r
.rlen
);
2052 output_P7_format (f
, ptr
->r
.type
, ptr
->r
.record
.p
.t
,
2053 ptr
->r
.record
.p
.size
);
2066 output_P3_format (f
, ptr
->r
.type
, ptr
->r
.record
.p
.gr
);
2069 output_P3_format (f
, rp_br
, ptr
->r
.record
.p
.br
);
2072 output_P7_format (f
, psp_sprel
, ptr
->r
.record
.p
.spoff
, 0);
2080 output_P7_format (f
, ptr
->r
.type
, ptr
->r
.record
.p
.t
, 0);
2089 output_P7_format (f
, ptr
->r
.type
, ptr
->r
.record
.p
.pspoff
, 0);
2099 case bspstore_sprel
:
2101 output_P8_format (f
, ptr
->r
.type
, ptr
->r
.record
.p
.spoff
);
2104 output_P9_format (f
, ptr
->r
.record
.p
.grmask
, ptr
->r
.record
.p
.gr
);
2107 output_P2_format (f
, ptr
->r
.record
.p
.brmask
, ptr
->r
.record
.p
.gr
);
2110 as_bad ("spill_mask record unimplemented.");
2112 case priunat_when_gr
:
2113 case priunat_when_mem
:
2117 output_P8_format (f
, ptr
->r
.type
, ptr
->r
.record
.p
.t
);
2119 case priunat_psprel
:
2121 case bspstore_psprel
:
2123 output_P8_format (f
, ptr
->r
.type
, ptr
->r
.record
.p
.pspoff
);
2126 output_P10_format (f
, ptr
->r
.record
.p
.abi
, ptr
->r
.record
.p
.context
);
2129 output_B3_format (f
, ptr
->r
.record
.b
.ecount
, ptr
->r
.record
.b
.t
);
2133 output_B4_format (f
, ptr
->r
.type
, ptr
->r
.record
.b
.label
);
2136 output_X1_format (f
, ptr
->r
.type
, ptr
->r
.record
.x
.ab
,
2137 ptr
->r
.record
.x
.reg
, ptr
->r
.record
.x
.t
,
2138 ptr
->r
.record
.x
.pspoff
);
2141 output_X1_format (f
, ptr
->r
.type
, ptr
->r
.record
.x
.ab
,
2142 ptr
->r
.record
.x
.reg
, ptr
->r
.record
.x
.t
,
2143 ptr
->r
.record
.x
.spoff
);
2146 output_X2_format (f
, ptr
->r
.record
.x
.ab
, ptr
->r
.record
.x
.reg
,
2147 ptr
->r
.record
.x
.xy
>> 1, ptr
->r
.record
.x
.xy
,
2148 ptr
->r
.record
.x
.treg
, ptr
->r
.record
.x
.t
);
2150 case spill_psprel_p
:
2151 output_X3_format (f
, ptr
->r
.type
, ptr
->r
.record
.x
.qp
,
2152 ptr
->r
.record
.x
.ab
, ptr
->r
.record
.x
.reg
,
2153 ptr
->r
.record
.x
.t
, ptr
->r
.record
.x
.pspoff
);
2156 output_X3_format (f
, ptr
->r
.type
, ptr
->r
.record
.x
.qp
,
2157 ptr
->r
.record
.x
.ab
, ptr
->r
.record
.x
.reg
,
2158 ptr
->r
.record
.x
.t
, ptr
->r
.record
.x
.spoff
);
2161 output_X4_format (f
, ptr
->r
.record
.x
.qp
, ptr
->r
.record
.x
.ab
,
2162 ptr
->r
.record
.x
.reg
, ptr
->r
.record
.x
.xy
>> 1,
2163 ptr
->r
.record
.x
.xy
, ptr
->r
.record
.x
.treg
,
2167 as_bad ("record_type_not_valid");
2172 /* Given a unw_rec_list list, process all the records with
2173 the specified function. */
2175 process_unw_records (list
, f
)
2180 for (ptr
= list
; ptr
; ptr
= ptr
->next
)
2181 process_one_record (ptr
, f
);
2184 /* Determine the size of a record list in bytes. */
2186 calc_record_size (list
)
2190 process_unw_records (list
, count_output
);
2194 /* Update IMASK bitmask to reflect the fact that one or more registers
2195 of type TYPE are saved starting at instruction with index T. If N
2196 bits are set in REGMASK, it is assumed that instructions T through
2197 T+N-1 save these registers.
2201 1: instruction saves next fp reg
2202 2: instruction saves next general reg
2203 3: instruction saves next branch reg */
2205 set_imask (region
, regmask
, t
, type
)
2206 unw_rec_list
*region
;
2207 unsigned long regmask
;
2211 unsigned char *imask
;
2212 unsigned long imask_size
;
2216 imask
= region
->r
.record
.r
.mask
.i
;
2217 imask_size
= region
->r
.record
.r
.imask_size
;
2220 imask_size
= (region
->r
.record
.r
.rlen
*2 + 7)/8 + 1;
2221 imask
= xmalloc (imask_size
);
2222 memset (imask
, 0, imask_size
);
2224 region
->r
.record
.r
.imask_size
= imask_size
;
2225 region
->r
.record
.r
.mask
.i
= imask
;
2232 if (i
>= imask_size
)
2234 as_bad ("Ignoring attempt to spill beyond end of region");
2238 imask
[i
] |= (type
& 0x3) << pos
;
2240 regmask
&= (regmask
- 1);
2251 count_bits (unsigned long mask
)
2264 slot_index (unsigned long slot_addr
, unsigned long first_addr
)
2266 return (3*((slot_addr
>> 4) - (first_addr
>> 4))
2267 + ((slot_addr
& 0x3) - (first_addr
& 0x3)));
2270 /* Given a complete record list, process any records which have
2271 unresolved fields, (ie length counts for a prologue). After
2272 this has been run, all neccessary information should be available
2273 within each record to generate an image. */
2275 fixup_unw_records (list
)
2278 unw_rec_list
*ptr
, *region
= 0;
2279 unsigned long first_addr
= 0, rlen
= 0, t
;
2281 for (ptr
= list
; ptr
; ptr
= ptr
->next
)
2283 if (ptr
->slot_number
== SLOT_NUM_NOT_SET
)
2284 as_bad (" Insn slot not set in unwind record.");
2285 t
= slot_index (ptr
->slot_number
, first_addr
);
2286 switch (ptr
->r
.type
)
2293 int size
, dir_len
= 0;
2294 unsigned long last_addr
;
2296 first_addr
= ptr
->slot_number
;
2297 ptr
->slot_number
= 0;
2298 /* Find either the next body/prologue start, or the end of
2299 the list, and determine the size of the region. */
2300 last_addr
= unwind
.next_slot_number
;
2301 for (last
= ptr
->next
; last
!= NULL
; last
= last
->next
)
2302 if (last
->r
.type
== prologue
|| last
->r
.type
== prologue_gr
2303 || last
->r
.type
== body
)
2305 last_addr
= last
->slot_number
;
2308 else if (!last
->next
)
2310 /* In the absence of an explicit .body directive,
2311 the prologue ends after the last instruction
2312 covered by an unwind directive. */
2313 if (ptr
->r
.type
!= body
)
2315 last_addr
= last
->slot_number
;
2316 switch (last
->r
.type
)
2319 dir_len
= (count_bits (last
->r
.record
.p
.frmask
)
2320 + count_bits (last
->r
.record
.p
.grmask
));
2324 dir_len
+= count_bits (last
->r
.record
.p
.rmask
);
2328 dir_len
+= count_bits (last
->r
.record
.p
.brmask
);
2331 dir_len
+= count_bits (last
->r
.record
.p
.grmask
);
2340 size
= slot_index (last_addr
, first_addr
) + dir_len
;
2341 rlen
= ptr
->r
.record
.r
.rlen
= size
;
2346 ptr
->r
.record
.b
.t
= rlen
- 1 - t
;
2357 case priunat_when_gr
:
2358 case priunat_when_mem
:
2362 ptr
->r
.record
.p
.t
= t
;
2370 case spill_psprel_p
:
2371 ptr
->r
.record
.x
.t
= t
;
2377 as_bad ("frgr_mem record before region record!\n");
2380 region
->r
.record
.r
.mask
.fr_mem
|= ptr
->r
.record
.p
.frmask
;
2381 region
->r
.record
.r
.mask
.gr_mem
|= ptr
->r
.record
.p
.grmask
;
2382 set_imask (region
, ptr
->r
.record
.p
.frmask
, t
, 1);
2383 set_imask (region
, ptr
->r
.record
.p
.grmask
, t
, 2);
2388 as_bad ("fr_mem record before region record!\n");
2391 region
->r
.record
.r
.mask
.fr_mem
|= ptr
->r
.record
.p
.rmask
;
2392 set_imask (region
, ptr
->r
.record
.p
.rmask
, t
, 1);
2397 as_bad ("gr_mem record before region record!\n");
2400 region
->r
.record
.r
.mask
.gr_mem
|= ptr
->r
.record
.p
.rmask
;
2401 set_imask (region
, ptr
->r
.record
.p
.rmask
, t
, 2);
2406 as_bad ("br_mem record before region record!\n");
2409 region
->r
.record
.r
.mask
.br_mem
|= ptr
->r
.record
.p
.brmask
;
2410 set_imask (region
, ptr
->r
.record
.p
.brmask
, t
, 3);
2416 as_bad ("gr_gr record before region record!\n");
2419 set_imask (region
, ptr
->r
.record
.p
.grmask
, t
, 2);
2424 as_bad ("br_gr record before region record!\n");
2427 set_imask (region
, ptr
->r
.record
.p
.brmask
, t
, 3);
2436 /* Generate an unwind image from a record list. Returns the number of
2437 bytes in the resulting image. The memory image itselof is returned
2438 in the 'ptr' parameter. */
2440 output_unw_records (list
, ptr
)
2444 int size
, x
, extra
= 0;
2447 fixup_unw_records (list
);
2448 size
= calc_record_size (list
);
2450 /* pad to 8 byte boundry. */
2454 /* Add 8 for the header + 8 more bytes for the personality offset. */
2455 mem
= xmalloc (size
+ extra
+ 16);
2457 vbyte_mem_ptr
= mem
+ 8;
2458 /* Clear the padding area and personality. */
2459 memset (mem
+ 8 + size
, 0 , extra
+ 8);
2460 /* Initialize the header area. */
2461 md_number_to_chars (mem
, ( ((bfd_vma
) 1 << 48) /* version */
2462 | ((bfd_vma
) 3 << 32) /* U & E handler flags */
2463 | ((size
+ extra
) / 8)), /* length (dwords) */
2466 process_unw_records (list
, output_vbyte_mem
);
2469 return size
+ extra
+ 16;
2473 convert_expr_to_ab_reg (e
, ab
, regp
)
2480 if (e
->X_op
!= O_register
)
2483 reg
= e
->X_add_number
;
2484 if (reg
>= REG_GR
+ 4 && reg
<= REG_GR
+ 7)
2487 *regp
= reg
- REG_GR
;
2489 else if ((reg
>= REG_FR
+ 2 && reg
<= REG_FR
+ 5)
2490 || (reg
>= REG_FR
+ 16 && reg
<= REG_FR
+ 31))
2493 *regp
= reg
- REG_FR
;
2495 else if (reg
>= REG_BR
+ 1 && reg
<= REG_BR
+ 5)
2498 *regp
= reg
- REG_BR
;
2505 case REG_PR
: *regp
= 0; break;
2506 case REG_PSP
: *regp
= 1; break;
2507 case REG_PRIUNAT
: *regp
= 2; break;
2508 case REG_BR
+ 0: *regp
= 3; break;
2509 case REG_AR
+ AR_BSP
: *regp
= 4; break;
2510 case REG_AR
+ AR_BSPSTORE
: *regp
= 5; break;
2511 case REG_AR
+ AR_RNAT
: *regp
= 6; break;
2512 case REG_AR
+ AR_UNAT
: *regp
= 7; break;
2513 case REG_AR
+ AR_FPSR
: *regp
= 8; break;
2514 case REG_AR
+ AR_PFS
: *regp
= 9; break;
2515 case REG_AR
+ AR_LC
: *regp
= 10; break;
2525 convert_expr_to_xy_reg (e
, xy
, regp
)
2532 if (e
->X_op
!= O_register
)
2535 reg
= e
->X_add_number
;
2537 if (reg
>= REG_GR
&& reg
<= REG_GR
+ 127)
2540 *regp
= reg
- REG_GR
;
2542 else if (reg
>= REG_FR
&& reg
<= REG_FR
+ 127)
2545 *regp
= reg
- REG_FR
;
2547 else if (reg
>= REG_BR
&& reg
<= REG_BR
+ 7)
2550 *regp
= reg
- REG_BR
;
2564 radix
= *input_line_pointer
++;
2566 if (radix
!= 'C' && !is_end_of_line
[(unsigned char) radix
])
2568 as_bad ("Radix `%c' unsupported", *input_line_pointer
);
2569 ignore_rest_of_line ();
2574 /* .sbss, .bss etc. are macros that expand into ".section SECNAME". */
2576 dot_special_section (which
)
2579 set_section ((char *) special_section_name
[which
]);
2583 add_unwind_entry (ptr
)
2587 unwind
.tail
->next
= ptr
;
2592 /* The current entry can in fact be a chain of unwind entries. */
2593 if (unwind
.current_entry
== NULL
)
2594 unwind
.current_entry
= ptr
;
2605 if (e
.X_op
!= O_constant
)
2606 as_bad ("Operand to .fframe must be a constant");
2608 add_unwind_entry (output_mem_stack_f (e
.X_add_number
));
2619 reg
= e
.X_add_number
- REG_GR
;
2620 if (e
.X_op
== O_register
&& reg
< 128)
2622 add_unwind_entry (output_mem_stack_v ());
2623 add_unwind_entry (output_psp_gr (reg
));
2626 as_bad ("First operand to .vframe must be a general register");
2630 dot_vframesp (dummy
)
2636 if (e
.X_op
== O_constant
)
2638 add_unwind_entry (output_mem_stack_v ());
2639 add_unwind_entry (output_psp_sprel (e
.X_add_number
));
2642 as_bad ("First operand to .vframesp must be a general register");
2646 dot_vframepsp (dummy
)
2652 if (e
.X_op
== O_constant
)
2654 add_unwind_entry (output_mem_stack_v ());
2655 add_unwind_entry (output_psp_sprel (e
.X_add_number
));
2658 as_bad ("First operand to .vframepsp must be a general register");
2669 sep
= parse_operand (&e1
);
2671 as_bad ("No second operand to .save");
2672 sep
= parse_operand (&e2
);
2674 reg1
= e1
.X_add_number
;
2675 reg2
= e2
.X_add_number
- REG_GR
;
2677 /* Make sure its a valid ar.xxx reg, OR its br0, aka 'rp'. */
2678 if (e1
.X_op
== O_register
)
2680 if (e2
.X_op
== O_register
&& reg2
>=0 && reg2
< 128)
2684 case REG_AR
+ AR_BSP
:
2685 add_unwind_entry (output_bsp_when ());
2686 add_unwind_entry (output_bsp_gr (reg2
));
2688 case REG_AR
+ AR_BSPSTORE
:
2689 add_unwind_entry (output_bspstore_when ());
2690 add_unwind_entry (output_bspstore_gr (reg2
));
2692 case REG_AR
+ AR_RNAT
:
2693 add_unwind_entry (output_rnat_when ());
2694 add_unwind_entry (output_rnat_gr (reg2
));
2696 case REG_AR
+AR_UNAT
:
2697 add_unwind_entry (output_unat_when ());
2698 add_unwind_entry (output_unat_gr (reg2
));
2700 case REG_AR
+AR_FPSR
:
2701 add_unwind_entry (output_fpsr_when ());
2702 add_unwind_entry (output_fpsr_gr (reg2
));
2705 add_unwind_entry (output_pfs_when ());
2706 add_unwind_entry (output_pfs_gr (reg2
));
2709 add_unwind_entry (output_lc_when ());
2710 add_unwind_entry (output_lc_gr (reg2
));
2713 add_unwind_entry (output_rp_when ());
2714 add_unwind_entry (output_rp_gr (reg2
));
2717 add_unwind_entry (output_preds_when ());
2718 add_unwind_entry (output_preds_gr (reg2
));
2721 add_unwind_entry (output_priunat_when_gr ());
2722 add_unwind_entry (output_priunat_gr (reg2
));
2725 as_bad ("First operand not a valid register");
2729 as_bad (" Second operand not a valid register");
2732 as_bad ("First operand not a register");
2740 unsigned long ecount
= 0;
2743 sep
= parse_operand (&e1
);
2744 if (e1
.X_op
!= O_register
|| e1
.X_add_number
!= REG_GR
+ 12)
2746 as_bad ("First operand to .restore must be stack pointer (sp)");
2752 parse_operand (&e2
);
2753 if (e1
.X_op
!= O_constant
)
2755 as_bad ("Second operand to .restore must be constant");
2760 add_unwind_entry (output_epilogue (ecount
));
2764 dot_restorereg (dummy
)
2767 unsigned int ab
, reg
;
2772 if (!convert_expr_to_ab_reg (&e
, &ab
, ®
))
2774 as_bad ("First operand to .restorereg must be a preserved register");
2777 add_unwind_entry (output_spill_reg (ab
, reg
, 0, 0));
2781 dot_restorereg_p (dummy
)
2784 unsigned int qp
, ab
, reg
;
2788 sep
= parse_operand (&e1
);
2791 as_bad ("No second operand to .restorereg.p");
2795 parse_operand (&e2
);
2797 qp
= e1
.X_add_number
- REG_P
;
2798 if (e1
.X_op
!= O_register
|| qp
> 63)
2800 as_bad ("First operand to .restorereg.p must be a predicate");
2804 if (!convert_expr_to_ab_reg (&e2
, &ab
, ®
))
2806 as_bad ("Second operand to .restorereg.p must be a preserved register");
2809 add_unwind_entry (output_spill_reg_p (ab
, reg
, 0, 0, qp
));
2813 generate_unwind_image ()
2816 unsigned char *unw_rec
;
2818 /* Generate the unwind record. */
2819 size
= output_unw_records (unwind
.list
, &unw_rec
);
2821 as_bad ("Unwind record is not a multiple of 8 bytes.");
2823 /* If there are unwind records, switch sections, and output the info. */
2826 unsigned char *where
;
2828 set_section ((char *) special_section_name
[SPECIAL_SECTION_UNWIND_INFO
]);
2830 /* Set expression which points to start of unwind descriptor area. */
2831 unwind
.info
= expr_build_dot ();
2833 where
= (unsigned char *)frag_more (size
);
2835 /* Issue a label for this address, and keep track of it to put it
2836 in the unwind section. */
2838 /* Copy the information from the unwind record into this section. The
2839 data is already in the correct byte order. */
2840 memcpy (where
, unw_rec
, size
);
2841 /* Add the personality address to the image. */
2842 if (unwind
.personality_routine
!= 0)
2844 exp
.X_op
= O_symbol
;
2845 exp
.X_add_symbol
= unwind
.personality_routine
;
2846 exp
.X_add_number
= 0;
2847 fix_new_exp (frag_now
, frag_now_fix () - 8, 8,
2848 &exp
, 0, BFD_RELOC_IA64_LTOFF_FPTR64LSB
);
2849 unwind
.personality_routine
= 0;
2851 obj_elf_previous (0);
2854 free_list_records (unwind
.list
);
2855 unwind
.list
= unwind
.tail
= unwind
.current_entry
= NULL
;
2861 dot_handlerdata (dummy
)
2864 generate_unwind_image ();
2865 demand_empty_rest_of_line ();
2869 dot_unwentry (dummy
)
2872 demand_empty_rest_of_line ();
2883 reg
= e
.X_add_number
- REG_BR
;
2884 if (e
.X_op
== O_register
&& reg
< 8)
2885 add_unwind_entry (output_rp_br (reg
));
2887 as_bad ("First operand not a valid branch register");
2891 dot_savemem (psprel
)
2898 sep
= parse_operand (&e1
);
2900 as_bad ("No second operand to .save%ssp", psprel
? "p" : "");
2901 sep
= parse_operand (&e2
);
2903 reg1
= e1
.X_add_number
;
2904 val
= e2
.X_add_number
;
2906 /* Make sure its a valid ar.xxx reg, OR its br0, aka 'rp'. */
2907 if (e1
.X_op
== O_register
)
2909 if (e2
.X_op
== O_constant
)
2913 case REG_AR
+ AR_BSP
:
2914 add_unwind_entry (output_bsp_when ());
2915 add_unwind_entry ((psprel
2917 : output_bsp_sprel
) (val
));
2919 case REG_AR
+ AR_BSPSTORE
:
2920 add_unwind_entry (output_bspstore_when ());
2921 add_unwind_entry ((psprel
2922 ? output_bspstore_psprel
2923 : output_bspstore_sprel
) (val
));
2925 case REG_AR
+ AR_RNAT
:
2926 add_unwind_entry (output_rnat_when ());
2927 add_unwind_entry ((psprel
2928 ? output_rnat_psprel
2929 : output_rnat_sprel
) (val
));
2931 case REG_AR
+ AR_UNAT
:
2932 add_unwind_entry (output_unat_when ());
2933 add_unwind_entry ((psprel
2934 ? output_unat_psprel
2935 : output_unat_sprel
) (val
));
2937 case REG_AR
+ AR_FPSR
:
2938 add_unwind_entry (output_fpsr_when ());
2939 add_unwind_entry ((psprel
2940 ? output_fpsr_psprel
2941 : output_fpsr_sprel
) (val
));
2943 case REG_AR
+ AR_PFS
:
2944 add_unwind_entry (output_pfs_when ());
2945 add_unwind_entry ((psprel
2947 : output_pfs_sprel
) (val
));
2949 case REG_AR
+ AR_LC
:
2950 add_unwind_entry (output_lc_when ());
2951 add_unwind_entry ((psprel
2953 : output_lc_sprel
) (val
));
2956 add_unwind_entry (output_rp_when ());
2957 add_unwind_entry ((psprel
2959 : output_rp_sprel
) (val
));
2962 add_unwind_entry (output_preds_when ());
2963 add_unwind_entry ((psprel
2964 ? output_preds_psprel
2965 : output_preds_sprel
) (val
));
2968 add_unwind_entry (output_priunat_when_mem ());
2969 add_unwind_entry ((psprel
2970 ? output_priunat_psprel
2971 : output_priunat_sprel
) (val
));
2974 as_bad ("First operand not a valid register");
2978 as_bad (" Second operand not a valid constant");
2981 as_bad ("First operand not a register");
2990 sep
= parse_operand (&e1
);
2992 parse_operand (&e2
);
2994 if (e1
.X_op
!= O_constant
)
2995 as_bad ("First operand to .save.g must be a constant.");
2998 int grmask
= e1
.X_add_number
;
3000 add_unwind_entry (output_gr_mem (grmask
));
3003 int reg
= e2
.X_add_number
- REG_GR
;
3004 if (e2
.X_op
== O_register
&& reg
>=0 && reg
< 128)
3005 add_unwind_entry (output_gr_gr (grmask
, reg
));
3007 as_bad ("Second operand is an invalid register.");
3018 sep
= parse_operand (&e1
);
3020 if (e1
.X_op
!= O_constant
)
3021 as_bad ("Operand to .save.f must be a constant.");
3023 add_unwind_entry (output_fr_mem (e1
.X_add_number
));
3035 sep
= parse_operand (&e1
);
3036 if (e1
.X_op
!= O_constant
)
3038 as_bad ("First operand to .save.b must be a constant.");
3041 brmask
= e1
.X_add_number
;
3045 sep
= parse_operand (&e2
);
3046 reg
= e2
.X_add_number
- REG_GR
;
3047 if (e2
.X_op
!= O_register
|| reg
> 127)
3049 as_bad ("Second operand to .save.b must be a general register.");
3052 add_unwind_entry (output_br_gr (brmask
, e2
.X_add_number
));
3055 add_unwind_entry (output_br_mem (brmask
));
3057 if (!is_end_of_line
[sep
] && !is_it_end_of_statement ())
3058 ignore_rest_of_line ();
3067 sep
= parse_operand (&e1
);
3069 parse_operand (&e2
);
3071 if (e1
.X_op
!= O_constant
|| sep
!= ',' || e2
.X_op
!= O_constant
)
3072 as_bad ("Both operands of .save.gf must be constants.");
3075 int grmask
= e1
.X_add_number
;
3076 int frmask
= e2
.X_add_number
;
3077 add_unwind_entry (output_frgr_mem (grmask
, frmask
));
3088 sep
= parse_operand (&e
);
3089 if (!is_end_of_line
[sep
] && !is_it_end_of_statement ())
3090 ignore_rest_of_line ();
3092 if (e
.X_op
!= O_constant
)
3093 as_bad ("Operand to .spill must be a constant");
3095 add_unwind_entry (output_spill_base (e
.X_add_number
));
3099 dot_spillreg (dummy
)
3102 int sep
, ab
, xy
, reg
, treg
;
3105 sep
= parse_operand (&e1
);
3108 as_bad ("No second operand to .spillreg");
3112 parse_operand (&e2
);
3114 if (!convert_expr_to_ab_reg (&e1
, &ab
, ®
))
3116 as_bad ("First operand to .spillreg must be a preserved register");
3120 if (!convert_expr_to_xy_reg (&e2
, &xy
, &treg
))
3122 as_bad ("Second operand to .spillreg must be a register");
3126 add_unwind_entry (output_spill_reg (ab
, reg
, treg
, xy
));
3130 dot_spillmem (psprel
)
3136 sep
= parse_operand (&e1
);
3139 as_bad ("Second operand missing");
3143 parse_operand (&e2
);
3145 if (!convert_expr_to_ab_reg (&e1
, &ab
, ®
))
3147 as_bad ("First operand to .spill%s must be a preserved register",
3148 psprel
? "psp" : "sp");
3152 if (e2
.X_op
!= O_constant
)
3154 as_bad ("Second operand to .spill%s must be a constant",
3155 psprel
? "psp" : "sp");
3160 add_unwind_entry (output_spill_psprel (ab
, reg
, e2
.X_add_number
));
3162 add_unwind_entry (output_spill_sprel (ab
, reg
, e2
.X_add_number
));
3166 dot_spillreg_p (dummy
)
3169 int sep
, ab
, xy
, reg
, treg
;
3170 expressionS e1
, e2
, e3
;
3173 sep
= parse_operand (&e1
);
3176 as_bad ("No second and third operand to .spillreg.p");
3180 sep
= parse_operand (&e2
);
3183 as_bad ("No third operand to .spillreg.p");
3187 parse_operand (&e3
);
3189 qp
= e1
.X_add_number
- REG_P
;
3191 if (e1
.X_op
!= O_register
|| qp
> 63)
3193 as_bad ("First operand to .spillreg.p must be a predicate");
3197 if (!convert_expr_to_ab_reg (&e2
, &ab
, ®
))
3199 as_bad ("Second operand to .spillreg.p must be a preserved register");
3203 if (!convert_expr_to_xy_reg (&e3
, &xy
, &treg
))
3205 as_bad ("Third operand to .spillreg.p must be a register");
3209 add_unwind_entry (output_spill_reg_p (ab
, reg
, treg
, xy
, qp
));
3213 dot_spillmem_p (psprel
)
3216 expressionS e1
, e2
, e3
;
3220 sep
= parse_operand (&e1
);
3223 as_bad ("Second operand missing");
3227 parse_operand (&e2
);
3230 as_bad ("Second operand missing");
3234 parse_operand (&e3
);
3236 qp
= e1
.X_add_number
- REG_P
;
3237 if (e1
.X_op
!= O_register
|| qp
> 63)
3239 as_bad ("First operand to .spill%s_p must be a predicate",
3240 psprel
? "psp" : "sp");
3244 if (!convert_expr_to_ab_reg (&e2
, &ab
, ®
))
3246 as_bad ("Second operand to .spill%s_p must be a preserved register",
3247 psprel
? "psp" : "sp");
3251 if (e3
.X_op
!= O_constant
)
3253 as_bad ("Third operand to .spill%s_p must be a constant",
3254 psprel
? "psp" : "sp");
3259 add_unwind_entry (output_spill_psprel_p (qp
, ab
, reg
, e3
.X_add_number
));
3261 add_unwind_entry (output_spill_sprel_p (qp
, ab
, reg
, e3
.X_add_number
));
3265 dot_label_state (dummy
)
3271 if (e
.X_op
!= O_constant
)
3273 as_bad ("Operand to .label_state must be a constant");
3276 add_unwind_entry (output_label_state (e
.X_add_number
));
3280 dot_copy_state (dummy
)
3286 if (e
.X_op
!= O_constant
)
3288 as_bad ("Operand to .copy_state must be a constant");
3291 add_unwind_entry (output_copy_state (e
.X_add_number
));
3301 sep
= parse_operand (&e1
);
3304 as_bad ("Second operand to .unwabi missing");
3307 sep
= parse_operand (&e2
);
3308 if (!is_end_of_line
[sep
] && !is_it_end_of_statement ())
3309 ignore_rest_of_line ();
3311 if (e1
.X_op
!= O_constant
)
3313 as_bad ("First operand to .unwabi must be a constant");
3317 if (e2
.X_op
!= O_constant
)
3319 as_bad ("Second operand to .unwabi must be a constant");
3323 add_unwind_entry (output_unwabi (e1
.X_add_number
, e2
.X_add_number
));
3327 dot_personality (dummy
)
3332 name
= input_line_pointer
;
3333 c
= get_symbol_end ();
3334 p
= input_line_pointer
;
3335 unwind
.personality_routine
= symbol_find_or_make (name
);
3338 demand_empty_rest_of_line ();
3348 unwind
.proc_start
= expr_build_dot ();
3349 /* Parse names of main and alternate entry points and mark them as
3350 function symbols: */
3354 name
= input_line_pointer
;
3355 c
= get_symbol_end ();
3356 p
= input_line_pointer
;
3357 sym
= symbol_find_or_make (name
);
3358 if (unwind
.proc_start
== 0)
3360 unwind
.proc_start
= sym
;
3362 symbol_get_bfdsym (sym
)->flags
|= BSF_FUNCTION
;
3365 if (*input_line_pointer
!= ',')
3367 ++input_line_pointer
;
3369 demand_empty_rest_of_line ();
3372 unwind
.list
= unwind
.tail
= unwind
.current_entry
= NULL
;
3373 unwind
.personality_routine
= 0;
3380 unwind
.prologue
= 0;
3381 add_unwind_entry (output_body ());
3382 demand_empty_rest_of_line ();
3386 dot_prologue (dummy
)
3391 unwind
.prologue
= 1;
3392 if (!is_it_end_of_statement ())
3395 sep
= parse_operand (&e1
);
3397 as_bad ("No second operand to .prologue");
3398 sep
= parse_operand (&e2
);
3399 if (!is_end_of_line
[sep
] && !is_it_end_of_statement ())
3400 ignore_rest_of_line ();
3402 if (e1
.X_op
== O_constant
)
3404 if (e2
.X_op
== O_constant
)
3406 int mask
= e1
.X_add_number
;
3407 int reg
= e2
.X_add_number
;
3408 add_unwind_entry (output_prologue_gr (mask
, reg
));
3411 as_bad ("Second operand not a constant");
3414 as_bad ("First operand not a constant");
3417 add_unwind_entry (output_prologue ());
3428 subsegT saved_subseg
;
3430 saved_seg
= now_seg
;
3431 saved_subseg
= now_subseg
;
3434 demand_empty_rest_of_line ();
3436 insn_group_break (1, 0, 0);
3437 ia64_flush_insns ();
3439 /* If there was a .handlerdata, we haven't generated an image yet. */
3440 if (unwind
.info
== 0)
3442 generate_unwind_image ();
3445 subseg_set (md
.last_text_seg
, 0);
3446 unwind
.proc_end
= expr_build_dot ();
3448 set_section ((char *) special_section_name
[SPECIAL_SECTION_UNWIND
]);
3449 ptr
= frag_more (24);
3450 where
= frag_now_fix () - 24;
3452 /* Issue the values of a) Proc Begin, b) Proc End, c) Unwind Record. */
3453 e
.X_op
= O_pseudo_fixup
;
3454 e
.X_op_symbol
= pseudo_func
[FUNC_SEG_RELATIVE
].u
.sym
;
3456 e
.X_add_symbol
= unwind
.proc_start
;
3457 ia64_cons_fix_new (frag_now
, where
, 8, &e
);
3459 e
.X_op
= O_pseudo_fixup
;
3460 e
.X_op_symbol
= pseudo_func
[FUNC_SEG_RELATIVE
].u
.sym
;
3462 e
.X_add_symbol
= unwind
.proc_end
;
3463 ia64_cons_fix_new (frag_now
, where
+ 8, 8, &e
);
3465 if (unwind
.info
!= 0)
3467 e
.X_op
= O_pseudo_fixup
;
3468 e
.X_op_symbol
= pseudo_func
[FUNC_SEG_RELATIVE
].u
.sym
;
3470 e
.X_add_symbol
= unwind
.info
;
3471 ia64_cons_fix_new (frag_now
, where
+ 16, 8, &e
);
3474 md_number_to_chars (ptr
+ 16, 0, 8);
3476 subseg_set (saved_seg
, saved_subseg
);
3477 unwind
.proc_start
= unwind
.proc_end
= unwind
.info
= 0;
3481 dot_template (template)
3484 CURR_SLOT
.user_template
= template;
3491 int ins
, locs
, outs
, rots
;
3493 if (is_it_end_of_statement ())
3494 ins
= locs
= outs
= rots
= 0;
3497 ins
= get_absolute_expression ();
3498 if (*input_line_pointer
++ != ',')
3500 locs
= get_absolute_expression ();
3501 if (*input_line_pointer
++ != ',')
3503 outs
= get_absolute_expression ();
3504 if (*input_line_pointer
++ != ',')
3506 rots
= get_absolute_expression ();
3508 set_regstack (ins
, locs
, outs
, rots
);
3512 as_bad ("Comma expected");
3513 ignore_rest_of_line ();
3520 unsigned num_regs
, num_alloced
= 0;
3521 struct dynreg
**drpp
, *dr
;
3522 int ch
, base_reg
= 0;
3528 case DYNREG_GR
: base_reg
= REG_GR
+ 32; break;
3529 case DYNREG_FR
: base_reg
= REG_FR
+ 32; break;
3530 case DYNREG_PR
: base_reg
= REG_P
+ 16; break;
3534 /* first, remove existing names from hash table: */
3535 for (dr
= md
.dynreg
[type
]; dr
&& dr
->num_regs
; dr
= dr
->next
)
3537 hash_delete (md
.dynreg_hash
, dr
->name
);
3541 drpp
= &md
.dynreg
[type
];
3544 start
= input_line_pointer
;
3545 ch
= get_symbol_end ();
3546 *input_line_pointer
= ch
;
3547 len
= (input_line_pointer
- start
);
3550 if (*input_line_pointer
!= '[')
3552 as_bad ("Expected '['");
3555 ++input_line_pointer
; /* skip '[' */
3557 num_regs
= get_absolute_expression ();
3559 if (*input_line_pointer
++ != ']')
3561 as_bad ("Expected ']'");
3566 num_alloced
+= num_regs
;
3570 if (num_alloced
> md
.rot
.num_regs
)
3572 as_bad ("Used more than the declared %d rotating registers",
3578 if (num_alloced
> 96)
3580 as_bad ("Used more than the available 96 rotating registers");
3585 if (num_alloced
> 48)
3587 as_bad ("Used more than the available 48 rotating registers");
3596 name
= obstack_alloc (¬es
, len
+ 1);
3597 memcpy (name
, start
, len
);
3602 *drpp
= obstack_alloc (¬es
, sizeof (*dr
));
3603 memset (*drpp
, 0, sizeof (*dr
));
3608 dr
->num_regs
= num_regs
;
3609 dr
->base
= base_reg
;
3611 base_reg
+= num_regs
;
3613 if (hash_insert (md
.dynreg_hash
, name
, dr
))
3615 as_bad ("Attempt to redefine register set `%s'", name
);
3619 if (*input_line_pointer
!= ',')
3621 ++input_line_pointer
; /* skip comma */
3624 demand_empty_rest_of_line ();
3628 ignore_rest_of_line ();
3632 dot_byteorder (byteorder
)
3635 target_big_endian
= byteorder
;
3647 option
= input_line_pointer
;
3648 ch
= get_symbol_end ();
3649 if (strcmp (option
, "lsb") == 0)
3650 md
.flags
&= ~EF_IA_64_BE
;
3651 else if (strcmp (option
, "msb") == 0)
3652 md
.flags
|= EF_IA_64_BE
;
3653 else if (strcmp (option
, "abi32") == 0)
3654 md
.flags
&= ~EF_IA_64_ABI64
;
3655 else if (strcmp (option
, "abi64") == 0)
3656 md
.flags
|= EF_IA_64_ABI64
;
3658 as_bad ("Unknown psr option `%s'", option
);
3659 *input_line_pointer
= ch
;
3662 if (*input_line_pointer
!= ',')
3665 ++input_line_pointer
;
3668 demand_empty_rest_of_line ();
3675 as_bad (".alias not implemented yet");
3682 new_logical_line (0, get_absolute_expression ());
3683 demand_empty_rest_of_line ();
3687 parse_section_name ()
3693 if (*input_line_pointer
!= '"')
3695 as_bad ("Missing section name");
3696 ignore_rest_of_line ();
3699 name
= demand_copy_C_string (&len
);
3702 ignore_rest_of_line ();
3706 if (*input_line_pointer
!= ',')
3708 as_bad ("Comma expected after section name");
3709 ignore_rest_of_line ();
3712 ++input_line_pointer
; /* skip comma */
3720 char *name
= parse_section_name ();
3726 obj_elf_previous (0);
3729 /* Why doesn't float_cons() call md_cons_align() the way cons() does? */
3731 stmt_float_cons (kind
)
3738 case 'd': size
= 8; break;
3739 case 'x': size
= 10; break;
3746 ia64_do_align (size
);
3754 int saved_auto_align
= md
.auto_align
;
3758 md
.auto_align
= saved_auto_align
;
3762 dot_xfloat_cons (kind
)
3765 char *name
= parse_section_name ();
3770 stmt_float_cons (kind
);
3771 obj_elf_previous (0);
3775 dot_xstringer (zero
)
3778 char *name
= parse_section_name ();
3784 obj_elf_previous (0);
3791 int saved_auto_align
= md
.auto_align
;
3792 char *name
= parse_section_name ();
3799 md
.auto_align
= saved_auto_align
;
3800 obj_elf_previous (0);
3804 dot_xfloat_cons_ua (kind
)
3807 int saved_auto_align
= md
.auto_align
;
3808 char *name
= parse_section_name ();
3814 stmt_float_cons (kind
);
3815 md
.auto_align
= saved_auto_align
;
3816 obj_elf_previous (0);
3819 /* .reg.val <regname>,value */
3827 if (reg
.X_op
!= O_register
)
3829 as_bad (_("Register name expected"));
3830 ignore_rest_of_line ();
3832 else if (*input_line_pointer
++ != ',')
3834 as_bad (_("Comma expected"));
3835 ignore_rest_of_line ();
3839 valueT value
= get_absolute_expression ();
3840 int regno
= reg
.X_add_number
;
3841 if (regno
< REG_GR
|| regno
> REG_GR
+128)
3842 as_warn (_("Register value annotation ignored"));
3845 gr_values
[regno
-REG_GR
].known
= 1;
3846 gr_values
[regno
-REG_GR
].value
= value
;
3847 gr_values
[regno
-REG_GR
].path
= md
.path
;
3850 demand_empty_rest_of_line ();
3853 /* select dv checking mode
3858 A stop is inserted when changing modes
3864 if (md
.manual_bundling
)
3865 as_warn (_("Directive invalid within a bundle"));
3867 if (type
== 'E' || type
== 'A')
3868 md
.mode_explicitly_set
= 0;
3870 md
.mode_explicitly_set
= 1;
3877 if (md
.explicit_mode
)
3878 insn_group_break (1, 0, 0);
3879 md
.explicit_mode
= 0;
3883 if (!md
.explicit_mode
)
3884 insn_group_break (1, 0, 0);
3885 md
.explicit_mode
= 1;
3889 if (md
.explicit_mode
!= md
.default_explicit_mode
)
3890 insn_group_break (1, 0, 0);
3891 md
.explicit_mode
= md
.default_explicit_mode
;
3892 md
.mode_explicitly_set
= 0;
3903 for (regno
= 0;regno
< 64;regno
++)
3905 if (mask
& ((valueT
)1<<regno
))
3907 fprintf (stderr
, "%s p%d", comma
, regno
);
3914 .pred.rel.clear [p1 [,p2 [,...]]] (also .pred.rel "clear")
3915 .pred.rel.imply p1, p2 (also .pred.rel "imply")
3916 .pred.rel.mutex p1, p2 [,...] (also .pred.rel "mutex")
3917 .pred.safe_across_calls p1 [, p2 [,...]]
3925 int p1
= -1, p2
= -1;
3929 if (*input_line_pointer
!= '"')
3931 as_bad (_("Missing predicate relation type"));
3932 ignore_rest_of_line ();
3938 char *form
= demand_copy_C_string (&len
);
3939 if (strcmp (form
, "mutex") == 0)
3941 else if (strcmp (form
, "clear") == 0)
3943 else if (strcmp (form
, "imply") == 0)
3947 as_bad (_("Unrecognized predicate relation type"));
3948 ignore_rest_of_line ();
3952 if (*input_line_pointer
== ',')
3953 ++input_line_pointer
;
3963 if (toupper (*input_line_pointer
) != 'P'
3964 || (regno
= atoi (++input_line_pointer
)) < 0
3967 as_bad (_("Predicate register expected"));
3968 ignore_rest_of_line ();
3971 while (isdigit (*input_line_pointer
))
3972 ++input_line_pointer
;
3979 as_warn (_("Duplicate predicate register ignored"));
3980 mask
|= bit
; count
++;
3981 /* see if it's a range */
3982 if (*input_line_pointer
== '-')
3985 ++input_line_pointer
;
3987 if (toupper (*input_line_pointer
) != 'P'
3988 || (regno
= atoi (++input_line_pointer
)) < 0
3991 as_bad (_("Predicate register expected"));
3992 ignore_rest_of_line ();
3995 while (isdigit (*input_line_pointer
))
3996 ++input_line_pointer
;
4000 as_bad (_("Bad register range"));
4001 ignore_rest_of_line ();
4007 mask
|= bit
; count
++;
4011 if (*input_line_pointer
!= ',')
4013 ++input_line_pointer
;
4022 clear_qp_mutex (mask
);
4023 clear_qp_implies (mask
, (valueT
)0);
4026 if (count
!= 2 || p1
== -1 || p2
== -1)
4027 as_bad (_("Predicate source and target required"));
4028 else if (p1
== 0 || p2
== 0)
4029 as_bad (_("Use of p0 is not valid in this context"));
4031 add_qp_imply (p1
, p2
);
4036 as_bad (_("At least two PR arguments expected"));
4041 as_bad (_("Use of p0 is not valid in this context"));
4044 add_qp_mutex (mask
);
4047 /* note that we don't override any existing relations */
4050 as_bad (_("At least one PR argument expected"));
4055 fprintf (stderr
, "Safe across calls: ");
4056 print_prmask (mask
);
4057 fprintf (stderr
, "\n");
4059 qp_safe_across_calls
= mask
;
4062 demand_empty_rest_of_line ();
4065 /* .entry label [, label [, ...]]
4066 Hint to DV code that the given labels are to be considered entry points.
4067 Otherwise, only global labels are considered entry points.
4080 name
= input_line_pointer
;
4081 c
= get_symbol_end ();
4082 symbolP
= symbol_find_or_make (name
);
4084 err
= hash_insert (md
.entry_hash
, S_GET_NAME (symbolP
), (PTR
) symbolP
);
4086 as_fatal (_("Inserting \"%s\" into entry hint table failed: %s"),
4089 *input_line_pointer
= c
;
4091 c
= *input_line_pointer
;
4094 input_line_pointer
++;
4096 if (*input_line_pointer
== '\n')
4102 demand_empty_rest_of_line ();
4105 /* .mem.offset offset, base
4106 "base" is used to distinguish between offsets from a different base.
4109 dot_mem_offset (dummy
)
4112 md
.mem_offset
.hint
= 1;
4113 md
.mem_offset
.offset
= get_absolute_expression ();
4114 if (*input_line_pointer
!= ',')
4116 as_bad (_("Comma expected"));
4117 ignore_rest_of_line ();
4120 ++input_line_pointer
;
4121 md
.mem_offset
.base
= get_absolute_expression ();
4122 demand_empty_rest_of_line ();
4125 /* ia64-specific pseudo-ops: */
4126 const pseudo_typeS md_pseudo_table
[] =
4128 { "radix", dot_radix
, 0 },
4129 { "lcomm", s_lcomm_bytes
, 1 },
4130 { "bss", dot_special_section
, SPECIAL_SECTION_BSS
},
4131 { "sbss", dot_special_section
, SPECIAL_SECTION_SBSS
},
4132 { "sdata", dot_special_section
, SPECIAL_SECTION_SDATA
},
4133 { "rodata", dot_special_section
, SPECIAL_SECTION_RODATA
},
4134 { "comment", dot_special_section
, SPECIAL_SECTION_COMMENT
},
4135 { "ia_64.unwind", dot_special_section
, SPECIAL_SECTION_UNWIND
},
4136 { "ia_64.unwind_info", dot_special_section
, SPECIAL_SECTION_UNWIND_INFO
},
4137 { "proc", dot_proc
, 0 },
4138 { "body", dot_body
, 0 },
4139 { "prologue", dot_prologue
, 0 },
4140 { "endp", dot_endp
},
4141 { "file", dwarf2_directive_file
},
4142 { "loc", dwarf2_directive_loc
},
4144 { "fframe", dot_fframe
},
4145 { "vframe", dot_vframe
},
4146 { "vframesp", dot_vframesp
},
4147 { "vframepsp", dot_vframepsp
},
4148 { "save", dot_save
},
4149 { "restore", dot_restore
},
4150 { "restorereg", dot_restorereg
},
4151 { "restorereg.p", dot_restorereg_p
},
4152 { "handlerdata", dot_handlerdata
},
4153 { "unwentry", dot_unwentry
},
4154 { "altrp", dot_altrp
},
4155 { "savesp", dot_savemem
, 0 },
4156 { "savepsp", dot_savemem
, 1 },
4157 { "save.g", dot_saveg
},
4158 { "save.f", dot_savef
},
4159 { "save.b", dot_saveb
},
4160 { "save.gf", dot_savegf
},
4161 { "spill", dot_spill
},
4162 { "spillreg", dot_spillreg
},
4163 { "spillsp", dot_spillmem
, 0 },
4164 { "spillpsp", dot_spillmem
, 1 },
4165 { "spillreg.p", dot_spillreg_p
},
4166 { "spillsp.p", dot_spillmem_p
, 0 },
4167 { "spillpsp.p", dot_spillmem_p
, 1 },
4168 { "label_state", dot_label_state
},
4169 { "copy_state", dot_copy_state
},
4170 { "unwabi", dot_unwabi
},
4171 { "personality", dot_personality
},
4173 { "estate", dot_estate
},
4175 { "mii", dot_template
, 0x0 },
4176 { "mli", dot_template
, 0x2 }, /* old format, for compatibility */
4177 { "mlx", dot_template
, 0x2 },
4178 { "mmi", dot_template
, 0x4 },
4179 { "mfi", dot_template
, 0x6 },
4180 { "mmf", dot_template
, 0x7 },
4181 { "mib", dot_template
, 0x8 },
4182 { "mbb", dot_template
, 0x9 },
4183 { "bbb", dot_template
, 0xb },
4184 { "mmb", dot_template
, 0xc },
4185 { "mfb", dot_template
, 0xe },
4187 { "lb", dot_scope
, 0 },
4188 { "le", dot_scope
, 1 },
4190 { "align", s_align_bytes
, 0 },
4191 { "regstk", dot_regstk
, 0 },
4192 { "rotr", dot_rot
, DYNREG_GR
},
4193 { "rotf", dot_rot
, DYNREG_FR
},
4194 { "rotp", dot_rot
, DYNREG_PR
},
4195 { "lsb", dot_byteorder
, 0 },
4196 { "msb", dot_byteorder
, 1 },
4197 { "psr", dot_psr
, 0 },
4198 { "alias", dot_alias
, 0 },
4199 { "ln", dot_ln
, 0 }, /* source line info (for debugging) */
4201 { "xdata1", dot_xdata
, 1 },
4202 { "xdata2", dot_xdata
, 2 },
4203 { "xdata4", dot_xdata
, 4 },
4204 { "xdata8", dot_xdata
, 8 },
4205 { "xreal4", dot_xfloat_cons
, 'f' },
4206 { "xreal8", dot_xfloat_cons
, 'd' },
4207 { "xreal10", dot_xfloat_cons
, 'x' },
4208 { "xstring", dot_xstringer
, 0 },
4209 { "xstringz", dot_xstringer
, 1 },
4211 /* unaligned versions: */
4212 { "xdata2.ua", dot_xdata_ua
, 2 },
4213 { "xdata4.ua", dot_xdata_ua
, 4 },
4214 { "xdata8.ua", dot_xdata_ua
, 8 },
4215 { "xreal4.ua", dot_xfloat_cons_ua
, 'f' },
4216 { "xreal8.ua", dot_xfloat_cons_ua
, 'd' },
4217 { "xreal10.ua", dot_xfloat_cons_ua
, 'x' },
4219 /* annotations/DV checking support */
4220 { "entry", dot_entry
, 0 },
4221 { "mem.offset", dot_mem_offset
},
4222 { "pred.rel", dot_pred_rel
, 0 },
4223 { "pred.rel.clear", dot_pred_rel
, 'c' },
4224 { "pred.rel.imply", dot_pred_rel
, 'i' },
4225 { "pred.rel.mutex", dot_pred_rel
, 'm' },
4226 { "pred.safe_across_calls", dot_pred_rel
, 's' },
4227 { "reg.val", dot_reg_val
},
4228 { "auto", dot_dv_mode
, 'a' },
4229 { "explicit", dot_dv_mode
, 'e' },
4230 { "default", dot_dv_mode
, 'd' },
4235 static const struct pseudo_opcode
4238 void (*handler
) (int);
4243 /* these are more like pseudo-ops, but don't start with a dot */
4244 { "data1", cons
, 1 },
4245 { "data2", cons
, 2 },
4246 { "data4", cons
, 4 },
4247 { "data8", cons
, 8 },
4248 { "real4", stmt_float_cons
, 'f' },
4249 { "real8", stmt_float_cons
, 'd' },
4250 { "real10", stmt_float_cons
, 'x' },
4251 { "string", stringer
, 0 },
4252 { "stringz", stringer
, 1 },
4254 /* unaligned versions: */
4255 { "data2.ua", stmt_cons_ua
, 2 },
4256 { "data4.ua", stmt_cons_ua
, 4 },
4257 { "data8.ua", stmt_cons_ua
, 8 },
4258 { "real4.ua", float_cons
, 'f' },
4259 { "real8.ua", float_cons
, 'd' },
4260 { "real10.ua", float_cons
, 'x' },
4263 /* Declare a register by creating a symbol for it and entering it in
4264 the symbol table. */
4266 declare_register (name
, regnum
)
4273 sym
= symbol_new (name
, reg_section
, regnum
, &zero_address_frag
);
4275 err
= hash_insert (md
.reg_hash
, S_GET_NAME (sym
), (PTR
) sym
);
4277 as_fatal ("Inserting \"%s\" into register table failed: %s",
4284 declare_register_set (prefix
, num_regs
, base_regnum
)
4292 for (i
= 0; i
< num_regs
; ++i
)
4294 sprintf (name
, "%s%u", prefix
, i
);
4295 declare_register (name
, base_regnum
+ i
);
4300 operand_width (opnd
)
4301 enum ia64_opnd opnd
;
4303 const struct ia64_operand
*odesc
= &elf64_ia64_operands
[opnd
];
4304 unsigned int bits
= 0;
4308 for (i
= 0; i
< NELEMS (odesc
->field
) && odesc
->field
[i
].bits
; ++i
)
4309 bits
+= odesc
->field
[i
].bits
;
4315 operand_match (idesc
, index
, e
)
4316 const struct ia64_opcode
*idesc
;
4320 enum ia64_opnd opnd
= idesc
->operands
[index
];
4321 int bits
, relocatable
= 0;
4322 struct insn_fix
*fix
;
4329 case IA64_OPND_AR_CCV
:
4330 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_AR
+ 32)
4334 case IA64_OPND_AR_PFS
:
4335 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_AR
+ 64)
4340 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_GR
+ 0)
4345 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_IP
)
4350 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_PR
)
4354 case IA64_OPND_PR_ROT
:
4355 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_PR_ROT
)
4360 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_PSR
)
4364 case IA64_OPND_PSR_L
:
4365 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_PSR_L
)
4369 case IA64_OPND_PSR_UM
:
4370 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_PSR_UM
)
4375 if (e
->X_op
== O_constant
&& e
->X_add_number
== 1)
4380 if (e
->X_op
== O_constant
&& e
->X_add_number
== 8)
4385 if (e
->X_op
== O_constant
&& e
->X_add_number
== 16)
4389 /* register operands: */
4392 if (e
->X_op
== O_register
&& e
->X_add_number
>= REG_AR
4393 && e
->X_add_number
< REG_AR
+ 128)
4399 if (e
->X_op
== O_register
&& e
->X_add_number
>= REG_BR
4400 && e
->X_add_number
< REG_BR
+ 8)
4405 if (e
->X_op
== O_register
&& e
->X_add_number
>= REG_CR
4406 && e
->X_add_number
< REG_CR
+ 128)
4414 if (e
->X_op
== O_register
&& e
->X_add_number
>= REG_FR
4415 && e
->X_add_number
< REG_FR
+ 128)
4421 if (e
->X_op
== O_register
&& e
->X_add_number
>= REG_P
4422 && e
->X_add_number
< REG_P
+ 64)
4429 if (e
->X_op
== O_register
&& e
->X_add_number
>= REG_GR
4430 && e
->X_add_number
< REG_GR
+ 128)
4434 case IA64_OPND_R3_2
:
4435 if (e
->X_op
== O_register
&& e
->X_add_number
>= REG_GR
4436 && e
->X_add_number
< REG_GR
+ 4)
4440 /* indirect operands: */
4441 case IA64_OPND_CPUID_R3
:
4442 case IA64_OPND_DBR_R3
:
4443 case IA64_OPND_DTR_R3
:
4444 case IA64_OPND_ITR_R3
:
4445 case IA64_OPND_IBR_R3
:
4446 case IA64_OPND_MSR_R3
:
4447 case IA64_OPND_PKR_R3
:
4448 case IA64_OPND_PMC_R3
:
4449 case IA64_OPND_PMD_R3
:
4450 case IA64_OPND_RR_R3
:
4451 if (e
->X_op
== O_index
&& e
->X_op_symbol
4452 && (S_GET_VALUE (e
->X_op_symbol
) - IND_CPUID
4453 == opnd
- IA64_OPND_CPUID_R3
))
4458 if (e
->X_op
== O_index
&& !e
->X_op_symbol
)
4462 /* immediate operands: */
4463 case IA64_OPND_CNT2a
:
4464 case IA64_OPND_LEN4
:
4465 case IA64_OPND_LEN6
:
4466 bits
= operand_width (idesc
->operands
[index
]);
4467 if (e
->X_op
== O_constant
4468 && (bfd_vma
) (e
->X_add_number
- 1) < ((bfd_vma
) 1 << bits
))
4472 case IA64_OPND_CNT2b
:
4473 if (e
->X_op
== O_constant
4474 && (bfd_vma
) (e
->X_add_number
- 1) < 3)
4478 case IA64_OPND_CNT2c
:
4479 val
= e
->X_add_number
;
4480 if (e
->X_op
== O_constant
4481 && (val
== 0 || val
== 7 || val
== 15 || val
== 16))
4486 /* SOR must be an integer multiple of 8 */
4487 if (e
->X_add_number
& 0x7)
4491 if (e
->X_op
== O_constant
&&
4492 (bfd_vma
) e
->X_add_number
<= 96)
4496 case IA64_OPND_IMMU62
:
4497 if (e
->X_op
== O_constant
)
4499 if ((bfd_vma
) e
->X_add_number
< ((bfd_vma
) 1 << 62))
4504 /* FIXME -- need 62-bit relocation type */
4505 as_bad (_("62-bit relocation not yet implemented"));
4509 case IA64_OPND_IMMU64
:
4510 if (e
->X_op
== O_symbol
|| e
->X_op
== O_pseudo_fixup
4511 || e
->X_op
== O_subtract
)
4513 fix
= CURR_SLOT
.fixup
+ CURR_SLOT
.num_fixups
;
4514 fix
->code
= BFD_RELOC_IA64_IMM64
;
4515 if (e
->X_op
!= O_subtract
)
4517 fix
->code
= ia64_gen_real_reloc_type (e
->X_op_symbol
, fix
->code
);
4518 if (e
->X_op
== O_pseudo_fixup
)
4522 fix
->opnd
= idesc
->operands
[index
];
4525 ++CURR_SLOT
.num_fixups
;
4528 else if (e
->X_op
== O_constant
)
4532 case IA64_OPND_CCNT5
:
4533 case IA64_OPND_CNT5
:
4534 case IA64_OPND_CNT6
:
4535 case IA64_OPND_CPOS6a
:
4536 case IA64_OPND_CPOS6b
:
4537 case IA64_OPND_CPOS6c
:
4538 case IA64_OPND_IMMU2
:
4539 case IA64_OPND_IMMU7a
:
4540 case IA64_OPND_IMMU7b
:
4541 case IA64_OPND_IMMU21
:
4542 case IA64_OPND_IMMU24
:
4543 case IA64_OPND_MBTYPE4
:
4544 case IA64_OPND_MHTYPE8
:
4545 case IA64_OPND_POS6
:
4546 bits
= operand_width (idesc
->operands
[index
]);
4547 if (e
->X_op
== O_constant
4548 && (bfd_vma
) e
->X_add_number
< ((bfd_vma
) 1 << bits
))
4552 case IA64_OPND_IMMU9
:
4553 bits
= operand_width (idesc
->operands
[index
]);
4554 if (e
->X_op
== O_constant
4555 && (bfd_vma
) e
->X_add_number
< ((bfd_vma
) 1 << bits
))
4557 int lobits
= e
->X_add_number
& 0x3;
4558 if (((bfd_vma
) e
->X_add_number
& 0x3C) != 0 && lobits
== 0)
4559 e
->X_add_number
|= (bfd_vma
)0x3;
4564 case IA64_OPND_IMM44
:
4565 /* least 16 bits must be zero */
4566 if ((e
->X_add_number
& 0xffff) != 0)
4567 as_warn (_("lower 16 bits of mask ignored"));
4569 if (e
->X_op
== O_constant
4570 && ((e
->X_add_number
>= 0
4571 && e
->X_add_number
< ((bfd_vma
) 1 << 44))
4572 || (e
->X_add_number
< 0
4573 && -e
->X_add_number
<= ((bfd_vma
) 1 << 44))))
4576 if (e
->X_add_number
>= 0
4577 && (e
->X_add_number
& ((bfd_vma
) 1 << 43)) != 0)
4579 e
->X_add_number
|= ~(((bfd_vma
) 1 << 44) - 1);
4585 case IA64_OPND_IMM17
:
4586 /* bit 0 is a don't care (pr0 is hardwired to 1) */
4587 if (e
->X_op
== O_constant
4588 && ((e
->X_add_number
>= 0
4589 && e
->X_add_number
< ((bfd_vma
) 1 << 17))
4590 || (e
->X_add_number
< 0
4591 && -e
->X_add_number
<= ((bfd_vma
) 1 << 17))))
4594 if (e
->X_add_number
>= 0
4595 && (e
->X_add_number
& ((bfd_vma
) 1 << 16)) != 0)
4597 e
->X_add_number
|= ~(((bfd_vma
)1 << 17) - 1);
4603 case IA64_OPND_IMM14
:
4604 case IA64_OPND_IMM22
:
4606 case IA64_OPND_IMM1
:
4607 case IA64_OPND_IMM8
:
4608 case IA64_OPND_IMM8U4
:
4609 case IA64_OPND_IMM8M1
:
4610 case IA64_OPND_IMM8M1U4
:
4611 case IA64_OPND_IMM8M1U8
:
4612 case IA64_OPND_IMM9a
:
4613 case IA64_OPND_IMM9b
:
4614 bits
= operand_width (idesc
->operands
[index
]);
4615 if (relocatable
&& (e
->X_op
== O_symbol
4616 || e
->X_op
== O_subtract
4617 || e
->X_op
== O_pseudo_fixup
))
4619 fix
= CURR_SLOT
.fixup
+ CURR_SLOT
.num_fixups
;
4621 if (idesc
->operands
[index
] == IA64_OPND_IMM14
)
4622 fix
->code
= BFD_RELOC_IA64_IMM14
;
4624 fix
->code
= BFD_RELOC_IA64_IMM22
;
4626 if (e
->X_op
!= O_subtract
)
4628 fix
->code
= ia64_gen_real_reloc_type (e
->X_op_symbol
, fix
->code
);
4629 if (e
->X_op
== O_pseudo_fixup
)
4633 fix
->opnd
= idesc
->operands
[index
];
4636 ++CURR_SLOT
.num_fixups
;
4639 else if (e
->X_op
!= O_constant
4640 && ! (e
->X_op
== O_big
&& opnd
== IA64_OPND_IMM8M1U8
))
4643 if (opnd
== IA64_OPND_IMM8M1U4
)
4645 /* Zero is not valid for unsigned compares that take an adjusted
4646 constant immediate range. */
4647 if (e
->X_add_number
== 0)
4650 /* Sign-extend 32-bit unsigned numbers, so that the following range
4651 checks will work. */
4652 val
= e
->X_add_number
;
4653 if (((val
& (~(bfd_vma
)0 << 32)) == 0)
4654 && ((val
& ((bfd_vma
)1 << 31)) != 0))
4655 val
= ((val
<< 32) >> 32);
4657 /* Check for 0x100000000. This is valid because
4658 0x100000000-1 is the same as ((uint32_t) -1). */
4659 if (val
== ((bfd_signed_vma
) 1 << 32))
4664 else if (opnd
== IA64_OPND_IMM8M1U8
)
4666 /* Zero is not valid for unsigned compares that take an adjusted
4667 constant immediate range. */
4668 if (e
->X_add_number
== 0)
4671 /* Check for 0x10000000000000000. */
4672 if (e
->X_op
== O_big
)
4674 if (generic_bignum
[0] == 0
4675 && generic_bignum
[1] == 0
4676 && generic_bignum
[2] == 0
4677 && generic_bignum
[3] == 0
4678 && generic_bignum
[4] == 1)
4684 val
= e
->X_add_number
- 1;
4686 else if (opnd
== IA64_OPND_IMM8M1
)
4687 val
= e
->X_add_number
- 1;
4688 else if (opnd
== IA64_OPND_IMM8U4
)
4690 /* Sign-extend 32-bit unsigned numbers, so that the following range
4691 checks will work. */
4692 val
= e
->X_add_number
;
4693 if (((val
& (~(bfd_vma
)0 << 32)) == 0)
4694 && ((val
& ((bfd_vma
)1 << 31)) != 0))
4695 val
= ((val
<< 32) >> 32);
4698 val
= e
->X_add_number
;
4700 if ((val
>= 0 && val
< ((bfd_vma
) 1 << (bits
- 1)))
4701 || (val
< 0 && -val
<= ((bfd_vma
) 1 << (bits
- 1))))
4705 case IA64_OPND_INC3
:
4706 /* +/- 1, 4, 8, 16 */
4707 val
= e
->X_add_number
;
4710 if (e
->X_op
== O_constant
4711 && (val
== 1 || val
== 4 || val
== 8 || val
== 16))
4715 case IA64_OPND_TGT25
:
4716 case IA64_OPND_TGT25b
:
4717 case IA64_OPND_TGT25c
:
4718 case IA64_OPND_TGT64
:
4719 if (e
->X_op
== O_symbol
)
4721 fix
= CURR_SLOT
.fixup
+ CURR_SLOT
.num_fixups
;
4722 if (opnd
== IA64_OPND_TGT25
)
4723 fix
->code
= BFD_RELOC_IA64_PCREL21F
;
4724 else if (opnd
== IA64_OPND_TGT25b
)
4725 fix
->code
= BFD_RELOC_IA64_PCREL21M
;
4726 else if (opnd
== IA64_OPND_TGT25c
)
4727 fix
->code
= BFD_RELOC_IA64_PCREL21B
;
4728 else if (opnd
== IA64_OPND_TGT64
)
4729 fix
->code
= BFD_RELOC_IA64_PCREL60B
;
4733 fix
->code
= ia64_gen_real_reloc_type (e
->X_op_symbol
, fix
->code
);
4734 fix
->opnd
= idesc
->operands
[index
];
4737 ++CURR_SLOT
.num_fixups
;
4740 case IA64_OPND_TAG13
:
4741 case IA64_OPND_TAG13b
:
4748 fix
= CURR_SLOT
.fixup
+ CURR_SLOT
.num_fixups
;
4749 fix
->code
= ia64_gen_real_reloc_type (e
->X_op_symbol
, 0);
4750 fix
->opnd
= idesc
->operands
[index
];
4753 ++CURR_SLOT
.num_fixups
;
4773 memset (e
, 0, sizeof (*e
));
4776 if (*input_line_pointer
!= '}')
4778 sep
= *input_line_pointer
++;
4782 if (!md
.manual_bundling
)
4783 as_warn ("Found '}' when manual bundling is off");
4785 CURR_SLOT
.manual_bundling_off
= 1;
4786 md
.manual_bundling
= 0;
4792 /* Returns the next entry in the opcode table that matches the one in
4793 IDESC, and frees the entry in IDESC. If no matching entry is
4794 found, NULL is returned instead. */
4796 static struct ia64_opcode
*
4797 get_next_opcode (struct ia64_opcode
*idesc
)
4799 struct ia64_opcode
*next
= ia64_find_next_opcode (idesc
);
4800 ia64_free_opcode (idesc
);
4804 /* Parse the operands for the opcode and find the opcode variant that
4805 matches the specified operands, or NULL if no match is possible. */
4806 static struct ia64_opcode
*
4807 parse_operands (idesc
)
4808 struct ia64_opcode
*idesc
;
4810 int i
= 0, highest_unmatched_operand
, num_operands
= 0, num_outputs
= 0;
4812 enum ia64_opnd expected_operand
= IA64_OPND_NIL
;
4814 char *first_arg
= 0, *end
, *saved_input_pointer
;
4817 assert (strlen (idesc
->name
) <= 128);
4819 strcpy (mnemonic
, idesc
->name
);
4820 if (idesc
->operands
[2] == IA64_OPND_SOF
)
4822 /* To make the common idiom "alloc loc?=ar.pfs,0,1,0,0" work, we
4823 can't parse the first operand until we have parsed the
4824 remaining operands of the "alloc" instruction. */
4826 first_arg
= input_line_pointer
;
4827 end
= strchr (input_line_pointer
, '=');
4830 as_bad ("Expected separator `='");
4833 input_line_pointer
= end
+ 1;
4838 for (; i
< NELEMS (CURR_SLOT
.opnd
); ++i
)
4840 sep
= parse_operand (CURR_SLOT
.opnd
+ i
);
4841 if (CURR_SLOT
.opnd
[i
].X_op
== O_absent
)
4846 if (sep
!= '=' && sep
!= ',')
4851 if (num_outputs
> 0)
4852 as_bad ("Duplicate equal sign (=) in instruction");
4854 num_outputs
= i
+ 1;
4859 as_bad ("Illegal operand separator `%c'", sep
);
4863 if (idesc
->operands
[2] == IA64_OPND_SOF
)
4865 /* map alloc r1=ar.pfs,i,l,o,r to alloc r1=ar.pfs,(i+l+o),(i+l),r */
4866 know (strcmp (idesc
->name
, "alloc") == 0);
4867 if (num_operands
== 5 /* first_arg not included in this count! */
4868 && CURR_SLOT
.opnd
[2].X_op
== O_constant
4869 && CURR_SLOT
.opnd
[3].X_op
== O_constant
4870 && CURR_SLOT
.opnd
[4].X_op
== O_constant
4871 && CURR_SLOT
.opnd
[5].X_op
== O_constant
)
4873 sof
= set_regstack (CURR_SLOT
.opnd
[2].X_add_number
,
4874 CURR_SLOT
.opnd
[3].X_add_number
,
4875 CURR_SLOT
.opnd
[4].X_add_number
,
4876 CURR_SLOT
.opnd
[5].X_add_number
);
4878 /* now we can parse the first arg: */
4879 saved_input_pointer
= input_line_pointer
;
4880 input_line_pointer
= first_arg
;
4881 sep
= parse_operand (CURR_SLOT
.opnd
+ 0);
4883 --num_outputs
; /* force error */
4884 input_line_pointer
= saved_input_pointer
;
4886 CURR_SLOT
.opnd
[2].X_add_number
= sof
;
4887 CURR_SLOT
.opnd
[3].X_add_number
4888 = sof
- CURR_SLOT
.opnd
[4].X_add_number
;
4889 CURR_SLOT
.opnd
[4] = CURR_SLOT
.opnd
[5];
4893 highest_unmatched_operand
= 0;
4894 expected_operand
= idesc
->operands
[0];
4895 for (; idesc
; idesc
= get_next_opcode (idesc
))
4897 if (num_outputs
!= idesc
->num_outputs
)
4898 continue; /* mismatch in # of outputs */
4900 CURR_SLOT
.num_fixups
= 0;
4901 for (i
= 0; i
< num_operands
&& idesc
->operands
[i
]; ++i
)
4902 if (!operand_match (idesc
, i
, CURR_SLOT
.opnd
+ i
))
4905 if (i
!= num_operands
)
4907 if (i
> highest_unmatched_operand
)
4909 highest_unmatched_operand
= i
;
4910 expected_operand
= idesc
->operands
[i
];
4915 if (num_operands
< NELEMS (idesc
->operands
)
4916 && idesc
->operands
[num_operands
])
4917 continue; /* mismatch in number of arguments */
4923 if (expected_operand
)
4924 as_bad ("Operand %u of `%s' should be %s",
4925 highest_unmatched_operand
+ 1, mnemonic
,
4926 elf64_ia64_operands
[expected_operand
].desc
);
4928 as_bad ("Operand mismatch");
4935 build_insn (slot
, insnp
)
4939 const struct ia64_operand
*odesc
, *o2desc
;
4940 struct ia64_opcode
*idesc
= slot
->idesc
;
4941 bfd_signed_vma insn
, val
;
4945 insn
= idesc
->opcode
| slot
->qp_regno
;
4947 for (i
= 0; i
< NELEMS (idesc
->operands
) && idesc
->operands
[i
]; ++i
)
4949 if (slot
->opnd
[i
].X_op
== O_register
4950 || slot
->opnd
[i
].X_op
== O_constant
4951 || slot
->opnd
[i
].X_op
== O_index
)
4952 val
= slot
->opnd
[i
].X_add_number
;
4953 else if (slot
->opnd
[i
].X_op
== O_big
)
4955 /* This must be the value 0x10000000000000000. */
4956 assert (idesc
->operands
[i
] == IA64_OPND_IMM8M1U8
);
4962 switch (idesc
->operands
[i
])
4964 case IA64_OPND_IMMU64
:
4965 *insnp
++ = (val
>> 22) & 0x1ffffffffffLL
;
4966 insn
|= (((val
& 0x7f) << 13) | (((val
>> 7) & 0x1ff) << 27)
4967 | (((val
>> 16) & 0x1f) << 22) | (((val
>> 21) & 0x1) << 21)
4968 | (((val
>> 63) & 0x1) << 36));
4971 case IA64_OPND_IMMU62
:
4972 val
&= 0x3fffffffffffffffULL
;
4973 if (val
!= slot
->opnd
[i
].X_add_number
)
4974 as_warn (_("Value truncated to 62 bits"));
4975 *insnp
++ = (val
>> 21) & 0x1ffffffffffLL
;
4976 insn
|= (((val
& 0xfffff) << 6) | (((val
>> 20) & 0x1) << 36));
4979 case IA64_OPND_TGT64
:
4981 *insnp
++ = ((val
>> 20) & 0x7fffffffffLL
) << 2;
4982 insn
|= ((((val
>> 59) & 0x1) << 36)
4983 | (((val
>> 0) & 0xfffff) << 13));
5014 case IA64_OPND_R3_2
:
5015 case IA64_OPND_CPUID_R3
:
5016 case IA64_OPND_DBR_R3
:
5017 case IA64_OPND_DTR_R3
:
5018 case IA64_OPND_ITR_R3
:
5019 case IA64_OPND_IBR_R3
:
5021 case IA64_OPND_MSR_R3
:
5022 case IA64_OPND_PKR_R3
:
5023 case IA64_OPND_PMC_R3
:
5024 case IA64_OPND_PMD_R3
:
5025 case IA64_OPND_RR_R3
:
5033 odesc
= elf64_ia64_operands
+ idesc
->operands
[i
];
5034 err
= (*odesc
->insert
) (odesc
, val
, &insn
);
5036 as_bad_where (slot
->src_file
, slot
->src_line
,
5037 "Bad operand value: %s", err
);
5038 if (idesc
->flags
& IA64_OPCODE_PSEUDO
)
5040 if ((idesc
->flags
& IA64_OPCODE_F2_EQ_F3
)
5041 && odesc
== elf64_ia64_operands
+ IA64_OPND_F3
)
5043 o2desc
= elf64_ia64_operands
+ IA64_OPND_F2
;
5044 (*o2desc
->insert
) (o2desc
, val
, &insn
);
5046 if ((idesc
->flags
& IA64_OPCODE_LEN_EQ_64MCNT
)
5047 && (odesc
== elf64_ia64_operands
+ IA64_OPND_CPOS6a
5048 || odesc
== elf64_ia64_operands
+ IA64_OPND_POS6
))
5050 o2desc
= elf64_ia64_operands
+ IA64_OPND_LEN6
;
5051 (*o2desc
->insert
) (o2desc
, 64 - val
, &insn
);
5061 unsigned int manual_bundling_on
= 0, manual_bundling_off
= 0;
5062 unsigned int manual_bundling
= 0;
5063 enum ia64_unit required_unit
, insn_unit
= 0;
5064 enum ia64_insn_type type
[3], insn_type
;
5065 unsigned int template, orig_template
;
5066 bfd_vma insn
[3] = {-1, -1, -1};
5067 struct ia64_opcode
*idesc
;
5068 int end_of_insn_group
= 0, user_template
= -1;
5069 int n
, i
, j
, first
, curr
;
5070 unw_rec_list
*ptr
, *prev
;
5071 bfd_vma t0
= 0, t1
= 0;
5072 struct label_fix
*lfix
;
5073 struct insn_fix
*ifix
;
5078 first
= (md
.curr_slot
+ NUM_SLOTS
- md
.num_slots_in_use
) % NUM_SLOTS
;
5079 know (first
>= 0 & first
< NUM_SLOTS
);
5080 n
= MIN (3, md
.num_slots_in_use
);
5082 /* Determine template: user user_template if specified, best match
5085 if (md
.slot
[first
].user_template
>= 0)
5086 user_template
= template = md
.slot
[first
].user_template
;
5089 /* auto select appropriate template */
5090 memset (type
, 0, sizeof (type
));
5092 for (i
= 0; i
< n
; ++i
)
5094 type
[i
] = md
.slot
[curr
].idesc
->type
;
5095 curr
= (curr
+ 1) % NUM_SLOTS
;
5097 template = best_template
[type
[0]][type
[1]][type
[2]];
5100 /* initialize instructions with appropriate nops: */
5101 for (i
= 0; i
< 3; ++i
)
5102 insn
[i
] = nop
[ia64_templ_desc
[template].exec_unit
[i
]];
5106 /* now fill in slots with as many insns as possible: */
5108 idesc
= md
.slot
[curr
].idesc
;
5109 end_of_insn_group
= 0;
5110 for (i
= 0; i
< 3 && md
.num_slots_in_use
> 0; ++i
)
5112 /* Set the slot number for prologue/body records now as those
5113 refer to the current point, not the point after the
5114 instruction has been issued: */
5116 for (ptr
= md
.slot
[curr
].unwind_record
; ptr
; ptr
= ptr
->next
)
5118 if (ptr
->r
.type
== prologue
|| ptr
->r
.type
== prologue_gr
5119 || ptr
->r
.type
== body
)
5121 ptr
->slot_number
= (unsigned long) f
+ i
;
5123 prev
->next
= ptr
->next
;
5125 md
.slot
[curr
].unwind_record
= ptr
->next
;
5131 if (idesc
->flags
& IA64_OPCODE_SLOT2
)
5133 if (manual_bundling
&& i
!= 2)
5134 as_bad_where (md
.slot
[curr
].src_file
, md
.slot
[curr
].src_line
,
5135 "`%s' must be last in bundle", idesc
->name
);
5139 if (idesc
->flags
& IA64_OPCODE_LAST
)
5141 int required_slot
, required_template
;
5143 /* If we need a stop bit after an M slot, our only choice is
5144 template 5 (M;;MI). If we need a stop bit after a B
5145 slot, our only choice is to place it at the end of the
5146 bundle, because the only available templates are MIB,
5147 MBB, BBB, MMB, and MFB. We don't handle anything other
5148 than M and B slots because these are the only kind of
5149 instructions that can have the IA64_OPCODE_LAST bit set. */
5150 required_template
= template;
5151 switch (idesc
->type
)
5155 required_template
= 5;
5163 as_bad_where (md
.slot
[curr
].src_file
, md
.slot
[curr
].src_line
,
5164 "Internal error: don't know how to force %s to end"
5165 "of instruction group", idesc
->name
);
5169 if (manual_bundling
&& i
!= required_slot
)
5170 as_bad_where (md
.slot
[curr
].src_file
, md
.slot
[curr
].src_line
,
5171 "`%s' must be last in instruction group",
5173 if (required_slot
< i
)
5174 /* Can't fit this instruction. */
5178 if (required_template
!= template)
5180 /* If we switch the template, we need to reset the NOPs
5181 after slot i. The slot-types of the instructions ahead
5182 of i never change, so we don't need to worry about
5183 changing NOPs in front of this slot. */
5184 for (j
= i
; j
< 3; ++j
)
5185 insn
[j
] = nop
[ia64_templ_desc
[required_template
].exec_unit
[j
]];
5187 template = required_template
;
5189 if (curr
!= first
&& md
.slot
[curr
].label_fixups
)
5191 if (manual_bundling_on
)
5192 as_bad_where (md
.slot
[curr
].src_file
, md
.slot
[curr
].src_line
,
5193 "Label must be first in a bundle");
5194 /* This insn must go into the first slot of a bundle. */
5198 manual_bundling_on
= md
.slot
[curr
].manual_bundling_on
;
5199 manual_bundling_off
= md
.slot
[curr
].manual_bundling_off
;
5201 if (manual_bundling_on
)
5204 manual_bundling
= 1;
5206 break; /* need to start a new bundle */
5209 if (end_of_insn_group
&& md
.num_slots_in_use
>= 1)
5211 /* We need an instruction group boundary in the middle of a
5212 bundle. See if we can switch to an other template with
5213 an appropriate boundary. */
5215 orig_template
= template;
5216 if (i
== 1 && (user_template
== 4
5217 || (user_template
< 0
5218 && (ia64_templ_desc
[template].exec_unit
[0]
5222 end_of_insn_group
= 0;
5224 else if (i
== 2 && (user_template
== 0
5225 || (user_template
< 0
5226 && (ia64_templ_desc
[template].exec_unit
[1]
5228 /* This test makes sure we don't switch the template if
5229 the next instruction is one that needs to be first in
5230 an instruction group. Since all those instructions are
5231 in the M group, there is no way such an instruction can
5232 fit in this bundle even if we switch the template. The
5233 reason we have to check for this is that otherwise we
5234 may end up generating "MI;;I M.." which has the deadly
5235 effect that the second M instruction is no longer the
5236 first in the bundle! --davidm 99/12/16 */
5237 && (idesc
->flags
& IA64_OPCODE_FIRST
) == 0)
5240 end_of_insn_group
= 0;
5242 else if (curr
!= first
)
5243 /* can't fit this insn */
5246 if (template != orig_template
)
5247 /* if we switch the template, we need to reset the NOPs
5248 after slot i. The slot-types of the instructions ahead
5249 of i never change, so we don't need to worry about
5250 changing NOPs in front of this slot. */
5251 for (j
= i
; j
< 3; ++j
)
5252 insn
[j
] = nop
[ia64_templ_desc
[template].exec_unit
[j
]];
5254 required_unit
= ia64_templ_desc
[template].exec_unit
[i
];
5256 /* resolve dynamic opcodes such as "break" and "nop": */
5257 if (idesc
->type
== IA64_TYPE_DYN
)
5259 if ((strcmp (idesc
->name
, "nop") == 0)
5260 || (strcmp (idesc
->name
, "break") == 0))
5261 insn_unit
= required_unit
;
5262 else if (strcmp (idesc
->name
, "chk.s") == 0)
5264 insn_unit
= IA64_UNIT_M
;
5265 if (required_unit
== IA64_UNIT_I
)
5266 insn_unit
= IA64_UNIT_I
;
5269 as_fatal ("emit_one_bundle: unexpected dynamic op");
5271 sprintf (mnemonic
, "%s.%c", idesc
->name
, "?imbf??"[insn_unit
]);
5272 md
.slot
[curr
].idesc
= idesc
= ia64_find_opcode (mnemonic
);
5274 know (!idesc
->next
); /* no resolved dynamic ops have collisions */
5279 insn_type
= idesc
->type
;
5280 insn_unit
= IA64_UNIT_NIL
;
5284 if (required_unit
== IA64_UNIT_I
|| required_unit
== IA64_UNIT_M
)
5285 insn_unit
= required_unit
;
5287 case IA64_TYPE_X
: insn_unit
= IA64_UNIT_L
; break;
5288 case IA64_TYPE_I
: insn_unit
= IA64_UNIT_I
; break;
5289 case IA64_TYPE_M
: insn_unit
= IA64_UNIT_M
; break;
5290 case IA64_TYPE_B
: insn_unit
= IA64_UNIT_B
; break;
5291 case IA64_TYPE_F
: insn_unit
= IA64_UNIT_F
; break;
5296 if (insn_unit
!= required_unit
)
5298 if (required_unit
== IA64_UNIT_L
5299 && insn_unit
== IA64_UNIT_I
5300 && !(idesc
->flags
& IA64_OPCODE_X_IN_MLX
))
5302 /* we got ourselves an MLX template but the current
5303 instruction isn't an X-unit, or an I-unit instruction
5304 that can go into the X slot of an MLX template. Duh. */
5305 if (md
.num_slots_in_use
>= NUM_SLOTS
)
5307 as_bad_where (md
.slot
[curr
].src_file
,
5308 md
.slot
[curr
].src_line
,
5309 "`%s' can't go in X slot of "
5310 "MLX template", idesc
->name
);
5311 /* drop this insn so we don't livelock: */
5312 --md
.num_slots_in_use
;
5316 continue; /* try next slot */
5319 if (debug_type
== DEBUG_DWARF2
)
5323 addr
= frag_now
->fr_address
+ frag_now_fix () - 16 + 1*i
;
5324 dwarf2_gen_line_info (addr
, &md
.slot
[curr
].debug_line
);
5327 build_insn (md
.slot
+ curr
, insn
+ i
);
5329 /* Set slot counts for unwind records. */
5330 while (md
.slot
[curr
].unwind_record
)
5332 md
.slot
[curr
].unwind_record
->slot_number
= (unsigned long) f
+ i
;
5333 md
.slot
[curr
].unwind_record
= md
.slot
[curr
].unwind_record
->next
;
5335 unwind
.next_slot_number
= (unsigned long) f
+ i
+ ((i
== 2)?(0x10-2):1);
5336 if (required_unit
== IA64_UNIT_L
)
5339 /* skip one slot for long/X-unit instructions */
5342 --md
.num_slots_in_use
;
5344 /* now is a good time to fix up the labels for this insn: */
5345 for (lfix
= md
.slot
[curr
].label_fixups
; lfix
; lfix
= lfix
->next
)
5347 S_SET_VALUE (lfix
->sym
, frag_now_fix () - 16);
5348 symbol_set_frag (lfix
->sym
, frag_now
);
5351 for (j
= 0; j
< md
.slot
[curr
].num_fixups
; ++j
)
5353 ifix
= md
.slot
[curr
].fixup
+ j
;
5354 fix
= fix_new_exp (frag_now
, frag_now_fix () - 16 + i
, 4,
5355 &ifix
->expr
, ifix
->is_pcrel
, ifix
->code
);
5356 fix
->tc_fix_data
.opnd
= ifix
->opnd
;
5357 fix
->fx_plt
= (fix
->fx_r_type
== BFD_RELOC_IA64_PLTOFF22
);
5358 fix
->fx_file
= md
.slot
[curr
].src_file
;
5359 fix
->fx_line
= md
.slot
[curr
].src_line
;
5362 end_of_insn_group
= md
.slot
[curr
].end_of_insn_group
;
5365 ia64_free_opcode (md
.slot
[curr
].idesc
);
5366 memset (md
.slot
+ curr
, 0, sizeof (md
.slot
[curr
]));
5367 md
.slot
[curr
].user_template
= -1;
5369 if (manual_bundling_off
)
5371 manual_bundling
= 0;
5374 curr
= (curr
+ 1) % NUM_SLOTS
;
5375 idesc
= md
.slot
[curr
].idesc
;
5377 if (manual_bundling
)
5379 if (md
.num_slots_in_use
> 0)
5380 as_bad_where (md
.slot
[curr
].src_file
, md
.slot
[curr
].src_line
,
5381 "`%s' does not fit into %s template",
5382 idesc
->name
, ia64_templ_desc
[template].name
);
5384 as_bad_where (md
.slot
[curr
].src_file
, md
.slot
[curr
].src_line
,
5385 "Missing '}' at end of file");
5387 know (md
.num_slots_in_use
< NUM_SLOTS
);
5389 t0
= end_of_insn_group
| (template << 1) | (insn
[0] << 5) | (insn
[1] << 46);
5390 t1
= ((insn
[1] >> 18) & 0x7fffff) | (insn
[2] << 23);
5392 md_number_to_chars (f
+ 0, t0
, 8);
5393 md_number_to_chars (f
+ 8, t1
, 8);
5397 md_parse_option (c
, arg
)
5401 /* Switches from the Intel assembler. */
5405 if (strcmp (arg
, "ilp64") == 0
5406 || strcmp (arg
, "lp64") == 0
5407 || strcmp (arg
, "p64") == 0)
5409 md
.flags
|= EF_IA_64_ABI64
;
5411 else if (strcmp (arg
, "ilp32") == 0)
5413 md
.flags
&= ~EF_IA_64_ABI64
;
5415 else if (strcmp (arg
, "le") == 0)
5417 md
.flags
&= ~EF_IA_64_BE
;
5419 else if (strcmp (arg
, "be") == 0)
5421 md
.flags
|= EF_IA_64_BE
;
5428 if (strcmp (arg
, "so") == 0)
5430 /* Suppress signon message. */
5432 else if (strcmp (arg
, "pi") == 0)
5434 /* Reject privileged instructions. FIXME */
5436 else if (strcmp (arg
, "us") == 0)
5438 /* Allow union of signed and unsigned range. FIXME */
5440 else if (strcmp (arg
, "close_fcalls") == 0)
5442 /* Do not resolve global function calls. */
5449 /* temp[="prefix"] Insert temporary labels into the object file
5450 symbol table prefixed by "prefix".
5451 Default prefix is ":temp:".
5456 /* ??? Conflicts with gas' listing option. */
5457 /* indirect=<tgt> Assume unannotated indirect branches behavior
5458 according to <tgt> --
5459 exit: branch out from the current context (default)
5460 labels: all labels in context may be branch targets
5465 /* -X conflicts with an ignored option, use -x instead */
5467 if (!arg
|| strcmp (arg
, "explicit") == 0)
5469 /* set default mode to explicit */
5470 md
.default_explicit_mode
= 1;
5473 else if (strcmp (arg
, "auto") == 0)
5475 md
.default_explicit_mode
= 0;
5477 else if (strcmp (arg
, "debug") == 0)
5481 else if (strcmp (arg
, "debugx") == 0)
5483 md
.default_explicit_mode
= 1;
5488 as_bad (_("Unrecognized option '-x%s'"), arg
);
5493 /* nops Print nops statistics. */
5504 md_show_usage (stream
)
5509 -Milp32|-Milp64|-Mlp64|-Mp64 select data model (default -Mlp64)\n\
5510 -Mle | -Mbe select little- or big-endian byte order (default -Mle)\n\
5511 -x | -xexplicit turn on dependency violation checking (default)\n\
5512 -xauto automagically remove dependency violations\n\
5513 -xdebug debug dependency violation checker\n"),
5518 match (int templ
, int type
, int slot
)
5520 enum ia64_unit unit
;
5523 unit
= ia64_templ_desc
[templ
].exec_unit
[slot
];
5526 case IA64_TYPE_DYN
: result
= 1; break; /* for nop and break */
5528 result
= (unit
== IA64_UNIT_I
|| unit
== IA64_UNIT_M
);
5530 case IA64_TYPE_X
: result
= (unit
== IA64_UNIT_L
); break;
5531 case IA64_TYPE_I
: result
= (unit
== IA64_UNIT_I
); break;
5532 case IA64_TYPE_M
: result
= (unit
== IA64_UNIT_M
); break;
5533 case IA64_TYPE_B
: result
= (unit
== IA64_UNIT_B
); break;
5534 case IA64_TYPE_F
: result
= (unit
== IA64_UNIT_F
); break;
5535 default: result
= 0; break;
5540 /* This function is called once, at assembler startup time. It sets
5541 up all the tables, etc. that the MD part of the assembler will need
5542 that can be determined before arguments are parsed. */
5546 int i
, j
, k
, t
, total
, ar_base
, cr_base
, goodness
, best
, regnum
;
5551 md
.explicit_mode
= md
.default_explicit_mode
;
5553 bfd_set_section_alignment (stdoutput
, text_section
, 4);
5555 target_big_endian
= 0;
5556 pseudo_func
[FUNC_FPTR_RELATIVE
].u
.sym
=
5557 symbol_new (".<fptr>", undefined_section
, FUNC_FPTR_RELATIVE
,
5558 &zero_address_frag
);
5560 pseudo_func
[FUNC_GP_RELATIVE
].u
.sym
=
5561 symbol_new (".<gprel>", undefined_section
, FUNC_GP_RELATIVE
,
5562 &zero_address_frag
);
5564 pseudo_func
[FUNC_LT_RELATIVE
].u
.sym
=
5565 symbol_new (".<ltoff>", undefined_section
, FUNC_LT_RELATIVE
,
5566 &zero_address_frag
);
5568 pseudo_func
[FUNC_PC_RELATIVE
].u
.sym
=
5569 symbol_new (".<pcrel>", undefined_section
, FUNC_PC_RELATIVE
,
5570 &zero_address_frag
);
5572 pseudo_func
[FUNC_PLT_RELATIVE
].u
.sym
=
5573 symbol_new (".<pltoff>", undefined_section
, FUNC_PLT_RELATIVE
,
5574 &zero_address_frag
);
5576 pseudo_func
[FUNC_SEC_RELATIVE
].u
.sym
=
5577 symbol_new (".<secrel>", undefined_section
, FUNC_SEC_RELATIVE
,
5578 &zero_address_frag
);
5580 pseudo_func
[FUNC_SEG_RELATIVE
].u
.sym
=
5581 symbol_new (".<segrel>", undefined_section
, FUNC_SEG_RELATIVE
,
5582 &zero_address_frag
);
5584 pseudo_func
[FUNC_LTV_RELATIVE
].u
.sym
=
5585 symbol_new (".<ltv>", undefined_section
, FUNC_LTV_RELATIVE
,
5586 &zero_address_frag
);
5588 pseudo_func
[FUNC_LT_FPTR_RELATIVE
].u
.sym
=
5589 symbol_new (".<ltoff.fptr>", undefined_section
, FUNC_LT_FPTR_RELATIVE
,
5590 &zero_address_frag
);
5592 /* compute the table of best templates: */
5593 for (i
= 0; i
< IA64_NUM_TYPES
; ++i
)
5594 for (j
= 0; j
< IA64_NUM_TYPES
; ++j
)
5595 for (k
= 0; k
< IA64_NUM_TYPES
; ++k
)
5598 for (t
= 0; t
< NELEMS (ia64_templ_desc
); ++t
)
5601 if (match (t
, i
, 0))
5603 if (match (t
, j
, 1))
5605 if (match (t
, k
, 2))
5610 else if (match (t
, j
, 2))
5615 else if (match (t
, i
, 1))
5617 if (match (t
, j
, 2))
5622 else if (match (t
, i
, 2))
5625 if (goodness
> best
)
5628 best_template
[i
][j
][k
] = t
;
5633 for (i
= 0; i
< NUM_SLOTS
; ++i
)
5634 md
.slot
[i
].user_template
= -1;
5636 md
.pseudo_hash
= hash_new ();
5637 for (i
= 0; i
< NELEMS (pseudo_opcode
); ++i
)
5639 err
= hash_insert (md
.pseudo_hash
, pseudo_opcode
[i
].name
,
5640 (void *) (pseudo_opcode
+ i
));
5642 as_fatal ("ia64.md_begin: can't hash `%s': %s",
5643 pseudo_opcode
[i
].name
, err
);
5646 md
.reg_hash
= hash_new ();
5647 md
.dynreg_hash
= hash_new ();
5648 md
.const_hash
= hash_new ();
5649 md
.entry_hash
= hash_new ();
5651 /* general registers: */
5654 for (i
= 0; i
< total
; ++i
)
5656 sprintf (name
, "r%d", i
- REG_GR
);
5657 md
.regsym
[i
] = declare_register (name
, i
);
5660 /* floating point registers: */
5662 for (; i
< total
; ++i
)
5664 sprintf (name
, "f%d", i
- REG_FR
);
5665 md
.regsym
[i
] = declare_register (name
, i
);
5668 /* application registers: */
5671 for (; i
< total
; ++i
)
5673 sprintf (name
, "ar%d", i
- REG_AR
);
5674 md
.regsym
[i
] = declare_register (name
, i
);
5677 /* control registers: */
5680 for (; i
< total
; ++i
)
5682 sprintf (name
, "cr%d", i
- REG_CR
);
5683 md
.regsym
[i
] = declare_register (name
, i
);
5686 /* predicate registers: */
5688 for (; i
< total
; ++i
)
5690 sprintf (name
, "p%d", i
- REG_P
);
5691 md
.regsym
[i
] = declare_register (name
, i
);
5694 /* branch registers: */
5696 for (; i
< total
; ++i
)
5698 sprintf (name
, "b%d", i
- REG_BR
);
5699 md
.regsym
[i
] = declare_register (name
, i
);
5702 md
.regsym
[REG_IP
] = declare_register ("ip", REG_IP
);
5703 md
.regsym
[REG_CFM
] = declare_register ("cfm", REG_CFM
);
5704 md
.regsym
[REG_PR
] = declare_register ("pr", REG_PR
);
5705 md
.regsym
[REG_PR_ROT
] = declare_register ("pr.rot", REG_PR_ROT
);
5706 md
.regsym
[REG_PSR
] = declare_register ("psr", REG_PSR
);
5707 md
.regsym
[REG_PSR_L
] = declare_register ("psr.l", REG_PSR_L
);
5708 md
.regsym
[REG_PSR_UM
] = declare_register ("psr.um", REG_PSR_UM
);
5710 for (i
= 0; i
< NELEMS (indirect_reg
); ++i
)
5712 regnum
= indirect_reg
[i
].regnum
;
5713 md
.regsym
[regnum
] = declare_register (indirect_reg
[i
].name
, regnum
);
5716 /* define synonyms for application registers: */
5717 for (i
= REG_AR
; i
< REG_AR
+ NELEMS (ar
); ++i
)
5718 md
.regsym
[i
] = declare_register (ar
[i
- REG_AR
].name
,
5719 REG_AR
+ ar
[i
- REG_AR
].regnum
);
5721 /* define synonyms for control registers: */
5722 for (i
= REG_CR
; i
< REG_CR
+ NELEMS (cr
); ++i
)
5723 md
.regsym
[i
] = declare_register (cr
[i
- REG_CR
].name
,
5724 REG_CR
+ cr
[i
- REG_CR
].regnum
);
5726 declare_register ("gp", REG_GR
+ 1);
5727 declare_register ("sp", REG_GR
+ 12);
5728 declare_register ("rp", REG_BR
+ 0);
5730 /* pseudo-registers used to specify unwind info: */
5731 declare_register ("psp", REG_PSP
);
5733 declare_register_set ("ret", 4, REG_GR
+ 8);
5734 declare_register_set ("farg", 8, REG_FR
+ 8);
5735 declare_register_set ("fret", 8, REG_FR
+ 8);
5737 for (i
= 0; i
< NELEMS (const_bits
); ++i
)
5739 err
= hash_insert (md
.const_hash
, const_bits
[i
].name
,
5740 (PTR
) (const_bits
+ i
));
5742 as_fatal ("Inserting \"%s\" into constant hash table failed: %s",
5746 /* Default to 64-bit mode. */
5747 md
.flags
= EF_IA_64_ABI64
;
5749 md
.mem_offset
.hint
= 0;
5752 md
.entry_labels
= NULL
;
5756 ia64_end_of_source ()
5758 /* terminate insn group upon reaching end of file: */
5759 insn_group_break (1, 0, 0);
5761 /* emits slots we haven't written yet: */
5762 ia64_flush_insns ();
5764 bfd_set_private_flags (stdoutput
, md
.flags
);
5766 if (debug_type
== DEBUG_DWARF2
)
5769 md
.mem_offset
.hint
= 0;
5775 md
.qp
.X_op
= O_absent
;
5777 if (ignore_input ())
5780 if (input_line_pointer
[0] == ';' && input_line_pointer
[-1] == ';')
5782 if (md
.detect_dv
&& !md
.explicit_mode
)
5783 as_warn (_("Explicit stops are ignored in auto mode"));
5785 insn_group_break (1, 0, 0);
5790 ia64_unrecognized_line (ch
)
5796 expression (&md
.qp
);
5797 if (*input_line_pointer
++ != ')')
5799 as_bad ("Expected ')'");
5802 if (md
.qp
.X_op
!= O_register
)
5804 as_bad ("Qualifying predicate expected");
5807 if (md
.qp
.X_add_number
< REG_P
|| md
.qp
.X_add_number
>= REG_P
+ 64)
5809 as_bad ("Predicate register expected");
5815 if (md
.manual_bundling
)
5816 as_warn ("Found '{' when manual bundling is already turned on");
5818 CURR_SLOT
.manual_bundling_on
= 1;
5819 md
.manual_bundling
= 1;
5821 /* bundling is only acceptable in explicit mode
5822 or when in default automatic mode */
5823 if (md
.detect_dv
&& !md
.explicit_mode
)
5825 if (!md
.mode_explicitly_set
5826 && !md
.default_explicit_mode
)
5829 as_warn (_("Found '{' after explicit switch to automatic mode"));
5834 if (!md
.manual_bundling
)
5835 as_warn ("Found '}' when manual bundling is off");
5837 PREV_SLOT
.manual_bundling_off
= 1;
5838 md
.manual_bundling
= 0;
5840 /* switch back to automatic mode, if applicable */
5843 && !md
.mode_explicitly_set
5844 && !md
.default_explicit_mode
)
5847 /* Allow '{' to follow on the same line. We also allow ";;", but that
5848 happens automatically because ';' is an end of line marker. */
5850 if (input_line_pointer
[0] == '{')
5852 input_line_pointer
++;
5853 return ia64_unrecognized_line ('{');
5856 demand_empty_rest_of_line ();
5862 return 0; /* not a valid line */
5866 ia64_frob_label (sym
)
5869 struct label_fix
*fix
;
5871 if (bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
)
5873 md
.last_text_seg
= now_seg
;
5874 fix
= obstack_alloc (¬es
, sizeof (*fix
));
5876 fix
->next
= CURR_SLOT
.label_fixups
;
5877 CURR_SLOT
.label_fixups
= fix
;
5879 /* keep track of how many code entry points we've seen */
5880 if (md
.path
== md
.maxpaths
)
5883 md
.entry_labels
= (const char **)
5884 xrealloc ((void *)md
.entry_labels
, md
.maxpaths
* sizeof (char *));
5886 md
.entry_labels
[md
.path
++] = S_GET_NAME (sym
);
5891 ia64_flush_pending_output ()
5893 if (bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
)
5895 /* ??? This causes many unnecessary stop bits to be emitted.
5896 Unfortunately, it isn't clear if it is safe to remove this. */
5897 insn_group_break (1, 0, 0);
5898 ia64_flush_insns ();
5902 /* Do ia64-specific expression optimization. All that's done here is
5903 to transform index expressions that are either due to the indexing
5904 of rotating registers or due to the indexing of indirect register
5907 ia64_optimize_expr (l
, op
, r
)
5916 if (l
->X_op
== O_register
&& r
->X_op
== O_constant
)
5918 num_regs
= (l
->X_add_number
>> 16);
5919 if ((unsigned) r
->X_add_number
>= num_regs
)
5922 as_bad ("No current frame");
5924 as_bad ("Index out of range 0..%u", num_regs
- 1);
5925 r
->X_add_number
= 0;
5927 l
->X_add_number
= (l
->X_add_number
& 0xffff) + r
->X_add_number
;
5930 else if (l
->X_op
== O_register
&& r
->X_op
== O_register
)
5932 if (l
->X_add_number
< IND_CPUID
|| l
->X_add_number
> IND_RR
5933 || l
->X_add_number
== IND_MEM
)
5935 as_bad ("Indirect register set name expected");
5936 l
->X_add_number
= IND_CPUID
;
5939 l
->X_op_symbol
= md
.regsym
[l
->X_add_number
];
5940 l
->X_add_number
= r
->X_add_number
;
5948 ia64_parse_name (name
, e
)
5952 struct const_desc
*cdesc
;
5953 struct dynreg
*dr
= 0;
5954 unsigned int regnum
;
5958 /* first see if NAME is a known register name: */
5959 sym
= hash_find (md
.reg_hash
, name
);
5962 e
->X_op
= O_register
;
5963 e
->X_add_number
= S_GET_VALUE (sym
);
5967 cdesc
= hash_find (md
.const_hash
, name
);
5970 e
->X_op
= O_constant
;
5971 e
->X_add_number
= cdesc
->value
;
5975 /* check for inN, locN, or outN: */
5979 if (name
[1] == 'n' && isdigit (name
[2]))
5987 if (name
[1] == 'o' && name
[2] == 'c' && isdigit (name
[3]))
5995 if (name
[1] == 'u' && name
[2] == 't' && isdigit (name
[3]))
6008 /* the name is inN, locN, or outN; parse the register number: */
6009 regnum
= strtoul (name
, &end
, 10);
6010 if (end
> name
&& *end
== '\0')
6012 if ((unsigned) regnum
>= dr
->num_regs
)
6015 as_bad ("No current frame");
6017 as_bad ("Register number out of range 0..%u", dr
->num_regs
-1);
6020 e
->X_op
= O_register
;
6021 e
->X_add_number
= dr
->base
+ regnum
;
6026 if ((dr
= hash_find (md
.dynreg_hash
, name
)))
6028 /* We've got ourselves the name of a rotating register set.
6029 Store the base register number in the low 16 bits of
6030 X_add_number and the size of the register set in the top 16
6032 e
->X_op
= O_register
;
6033 e
->X_add_number
= dr
->base
| (dr
->num_regs
<< 16);
6039 /* Remove the '#' suffix that indicates a symbol as opposed to a register. */
6042 ia64_canonicalize_symbol_name (name
)
6045 size_t len
= strlen(name
);
6046 if (len
> 1 && name
[len
-1] == '#')
6052 is_conditional_branch (idesc
)
6053 struct ia64_opcode
*idesc
;
6055 return (strncmp (idesc
->name
, "br", 2) == 0
6056 && (strcmp (idesc
->name
, "br") == 0
6057 || strncmp (idesc
->name
, "br.cond", 7) == 0
6058 || strncmp (idesc
->name
, "br.call", 7) == 0
6059 || strncmp (idesc
->name
, "br.ret", 6) == 0
6060 || strcmp (idesc
->name
, "brl") == 0
6061 || strncmp (idesc
->name
, "brl.cond", 7) == 0
6062 || strncmp (idesc
->name
, "brl.call", 7) == 0
6063 || strncmp (idesc
->name
, "brl.ret", 6) == 0));
6066 /* Return whether the given opcode is a taken branch. If there's any doubt,
6069 is_taken_branch (idesc
)
6070 struct ia64_opcode
*idesc
;
6072 return ((is_conditional_branch (idesc
) && CURR_SLOT
.qp_regno
== 0)
6073 || strncmp (idesc
->name
, "br.ia", 5) == 0);
6076 /* Return whether the given opcode is an interruption or rfi. If there's any
6077 doubt, returns zero */
6079 is_interruption_or_rfi (idesc
)
6080 struct ia64_opcode
*idesc
;
6082 if (strcmp (idesc
->name
, "rfi") == 0)
6087 /* Returns the index of the given dependency in the opcode's list of chks, or
6088 -1 if there is no dependency. */
6090 depends_on (depind
, idesc
)
6092 struct ia64_opcode
*idesc
;
6095 const struct ia64_opcode_dependency
*dep
= idesc
->dependencies
;
6096 for (i
= 0;i
< dep
->nchks
; i
++)
6098 if (depind
== DEP(dep
->chks
[i
]))
6104 /* Determine a set of specific resources used for a particular resource
6105 class. Returns the number of specific resources identified For those
6106 cases which are not determinable statically, the resource returned is
6109 Meanings of value in 'NOTE':
6110 1) only read/write when the register number is explicitly encoded in the
6112 2) only read CFM when accessing a rotating GR, FR, or PR. mov pr only
6113 accesses CFM when qualifying predicate is in the rotating region.
6114 3) general register value is used to specify an indirect register; not
6115 determinable statically.
6116 4) only read the given resource when bits 7:0 of the indirect index
6117 register value does not match the register number of the resource; not
6118 determinable statically.
6119 5) all rules are implementation specific.
6120 6) only when both the index specified by the reader and the index specified
6121 by the writer have the same value in bits 63:61; not determinable
6123 7) only access the specified resource when the corresponding mask bit is
6125 8) PSR.dfh is only read when these insns reference FR32-127. PSR.dfl is
6126 only read when these insns reference FR2-31
6127 9) PSR.mfl is only written when these insns write FR2-31. PSR.mfh is only
6128 written when these insns write FR32-127
6129 10) The PSR.bn bit is only accessed when one of GR16-31 is specified in the
6131 11) The target predicates are written independently of PR[qp], but source
6132 registers are only read if PR[qp] is true. Since the state of PR[qp]
6133 cannot statically be determined, all source registers are marked used.
6134 12) This insn only reads the specified predicate register when that
6135 register is the PR[qp].
6136 13) This reference to ld-c only applies to teh GR whose value is loaded
6137 with data returned from memory, not the post-incremented address register.
6138 14) The RSE resource includes the implementation-specific RSE internal
6139 state resources. At least one (and possibly more) of these resources are
6140 read by each instruction listed in IC:rse-readers. At least one (and
6141 possibly more) of these resources are written by each insn listed in
6143 15+16) Represents reserved instructions, which the assembler does not
6146 Memory resources (i.e. locations in memory) are *not* marked or tracked by
6147 this code; there are no dependency violations based on memory access.
6151 #define MAX_SPECS 256
6156 specify_resource (dep
, idesc
, type
, specs
, note
, path
)
6157 const struct ia64_dependency
*dep
;
6158 struct ia64_opcode
*idesc
;
6159 int type
; /* is this a DV chk or a DV reg? */
6160 struct rsrc specs
[MAX_SPECS
]; /* returned specific resources */
6161 int note
; /* resource note for this insn's usage */
6162 int path
; /* which execution path to examine */
6169 if (dep
->mode
== IA64_DV_WAW
6170 || (dep
->mode
== IA64_DV_RAW
&& type
== DV_REG
)
6171 || (dep
->mode
== IA64_DV_WAR
&& type
== DV_CHK
))
6174 /* template for any resources we identify */
6175 tmpl
.dependency
= dep
;
6177 tmpl
.insn_srlz
= tmpl
.data_srlz
= 0;
6178 tmpl
.qp_regno
= CURR_SLOT
.qp_regno
;
6179 tmpl
.link_to_qp_branch
= 1;
6180 tmpl
.mem_offset
.hint
= 0;
6185 as_warn (_("Unhandled dependency %s for %s (%s), note %d"), \
6186 dep->name, idesc->name, (rsrc_write?"write":"read"), note)
6187 #define KNOWN(REG) (gr_values[REG].known && gr_values[REG].path >= path)
6189 /* we don't need to track these */
6190 if (dep
->semantics
== IA64_DVS_NONE
)
6193 switch (dep
->specifier
)
6198 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_AR3
)
6200 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_AR
;
6201 if (regno
>= 0 && regno
<= 7)
6203 specs
[count
] = tmpl
;
6204 specs
[count
++].index
= regno
;
6212 specs
[count
] = tmpl
;
6213 specs
[count
++].index
= i
;
6222 case IA64_RS_AR_UNAT
:
6223 /* This is a mov =AR or mov AR= instruction. */
6224 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_AR3
)
6226 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_AR
;
6227 if (regno
== AR_UNAT
)
6229 specs
[count
++] = tmpl
;
6234 /* This is a spill/fill, or other instruction that modifies the
6237 /* Unless we can determine the specific bits used, mark the whole
6238 thing; bits 8:3 of the memory address indicate the bit used in
6239 UNAT. The .mem.offset hint may be used to eliminate a small
6240 subset of conflicts. */
6241 specs
[count
] = tmpl
;
6242 if (md
.mem_offset
.hint
)
6245 fprintf (stderr
, " Using hint for spill/fill\n");
6246 /* the index isn't actually used, just set it to something
6247 approximating the bit index */
6248 specs
[count
].index
= (md
.mem_offset
.offset
>> 3) & 0x3F;
6249 specs
[count
].mem_offset
.hint
= 1;
6250 specs
[count
].mem_offset
.offset
= md
.mem_offset
.offset
;
6251 specs
[count
++].mem_offset
.base
= md
.mem_offset
.base
;
6255 specs
[count
++].specific
= 0;
6263 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_AR3
)
6265 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_AR
;
6266 if ((regno
>= 8 && regno
<= 15)
6267 || (regno
>= 20 && regno
<= 23)
6268 || (regno
>= 31 && regno
<= 39)
6269 || (regno
>= 41 && regno
<= 47)
6270 || (regno
>= 67 && regno
<= 111))
6272 specs
[count
] = tmpl
;
6273 specs
[count
++].index
= regno
;
6286 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_AR3
)
6288 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_AR
;
6289 if ((regno
>= 48 && regno
<= 63)
6290 || (regno
>= 112 && regno
<= 127))
6292 specs
[count
] = tmpl
;
6293 specs
[count
++].index
= regno
;
6299 for (i
=48;i
< 64;i
++)
6301 specs
[count
] = tmpl
;
6302 specs
[count
++].index
= i
;
6304 for (i
=112;i
< 128;i
++)
6306 specs
[count
] = tmpl
;
6307 specs
[count
++].index
= i
;
6325 for (i
=0;i
< idesc
->num_outputs
;i
++)
6326 if (idesc
->operands
[i
] == IA64_OPND_B1
6327 || idesc
->operands
[i
] == IA64_OPND_B2
)
6329 specs
[count
] = tmpl
;
6330 specs
[count
++].index
=
6331 CURR_SLOT
.opnd
[i
].X_add_number
- REG_BR
;
6336 for (i
= idesc
->num_outputs
;i
< NELEMS(idesc
->operands
);i
++)
6337 if (idesc
->operands
[i
] == IA64_OPND_B1
6338 || idesc
->operands
[i
] == IA64_OPND_B2
)
6340 specs
[count
] = tmpl
;
6341 specs
[count
++].index
=
6342 CURR_SLOT
.opnd
[i
].X_add_number
- REG_BR
;
6348 case IA64_RS_CPUID
: /* four or more registers */
6351 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_CPUID_R3
)
6353 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_GR
;
6354 if (regno
>= 0 && regno
< NELEMS(gr_values
)
6357 specs
[count
] = tmpl
;
6358 specs
[count
++].index
= gr_values
[regno
].value
& 0xFF;
6362 specs
[count
] = tmpl
;
6363 specs
[count
++].specific
= 0;
6373 case IA64_RS_DBR
: /* four or more registers */
6376 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_DBR_R3
)
6378 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_GR
;
6379 if (regno
>= 0 && regno
< NELEMS(gr_values
)
6382 specs
[count
] = tmpl
;
6383 specs
[count
++].index
= gr_values
[regno
].value
& 0xFF;
6387 specs
[count
] = tmpl
;
6388 specs
[count
++].specific
= 0;
6392 else if (note
== 0 && !rsrc_write
)
6394 specs
[count
] = tmpl
;
6395 specs
[count
++].specific
= 0;
6403 case IA64_RS_IBR
: /* four or more registers */
6406 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_IBR_R3
)
6408 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_GR
;
6409 if (regno
>= 0 && regno
< NELEMS(gr_values
)
6412 specs
[count
] = tmpl
;
6413 specs
[count
++].index
= gr_values
[regno
].value
& 0xFF;
6417 specs
[count
] = tmpl
;
6418 specs
[count
++].specific
= 0;
6431 /* These are implementation specific. Force all references to
6432 conflict with all other references. */
6433 specs
[count
] = tmpl
;
6434 specs
[count
++].specific
= 0;
6442 case IA64_RS_PKR
: /* 16 or more registers */
6443 if (note
== 3 || note
== 4)
6445 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_PKR_R3
)
6447 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_GR
;
6448 if (regno
>= 0 && regno
< NELEMS(gr_values
)
6453 specs
[count
] = tmpl
;
6454 specs
[count
++].index
= gr_values
[regno
].value
& 0xFF;
6456 else for (i
=0;i
< NELEMS(gr_values
);i
++)
6458 /* uses all registers *except* the one in R3 */
6459 if (i
!= (gr_values
[regno
].value
& 0xFF))
6461 specs
[count
] = tmpl
;
6462 specs
[count
++].index
= i
;
6468 specs
[count
] = tmpl
;
6469 specs
[count
++].specific
= 0;
6476 specs
[count
] = tmpl
;
6477 specs
[count
++].specific
= 0;
6481 case IA64_RS_PMC
: /* four or more registers */
6484 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_PMC_R3
6485 || (!rsrc_write
&& idesc
->operands
[1] == IA64_OPND_PMD_R3
))
6488 int index
= ((idesc
->operands
[1] == IA64_OPND_R3
&& !rsrc_write
)
6490 int regno
= CURR_SLOT
.opnd
[index
].X_add_number
- REG_GR
;
6491 if (regno
>= 0 && regno
< NELEMS(gr_values
)
6494 specs
[count
] = tmpl
;
6495 specs
[count
++].index
= gr_values
[regno
].value
& 0xFF;
6499 specs
[count
] = tmpl
;
6500 specs
[count
++].specific
= 0;
6510 case IA64_RS_PMD
: /* four or more registers */
6513 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_PMD_R3
)
6515 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_GR
;
6516 if (regno
>= 0 && regno
< NELEMS(gr_values
)
6519 specs
[count
] = tmpl
;
6520 specs
[count
++].index
= gr_values
[regno
].value
& 0xFF;
6524 specs
[count
] = tmpl
;
6525 specs
[count
++].specific
= 0;
6535 case IA64_RS_RR
: /* eight registers */
6538 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_RR_R3
)
6540 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_GR
;
6541 if (regno
>= 0 && regno
< NELEMS(gr_values
)
6544 specs
[count
] = tmpl
;
6545 specs
[count
++].index
= (gr_values
[regno
].value
>> 61) & 0x7;
6549 specs
[count
] = tmpl
;
6550 specs
[count
++].specific
= 0;
6554 else if (note
== 0 && !rsrc_write
)
6556 specs
[count
] = tmpl
;
6557 specs
[count
++].specific
= 0;
6565 case IA64_RS_CR_IRR
:
6568 /* handle mov-from-CR-IVR; it's a read that writes CR[IRR] */
6569 int regno
= CURR_SLOT
.opnd
[1].X_add_number
- REG_CR
;
6571 && idesc
->operands
[1] == IA64_OPND_CR3
6576 specs
[count
] = tmpl
;
6577 specs
[count
++].index
= CR_IRR0
+ i
;
6583 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_CR
;
6584 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_CR3
6586 && regno
<= CR_IRR3
)
6588 specs
[count
] = tmpl
;
6589 specs
[count
++].index
= regno
;
6598 case IA64_RS_CR_LRR
:
6605 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_CR
;
6606 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_CR3
6607 && (regno
== CR_LRR0
|| regno
== CR_LRR1
))
6609 specs
[count
] = tmpl
;
6610 specs
[count
++].index
= regno
;
6618 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_CR3
)
6620 specs
[count
] = tmpl
;
6621 specs
[count
++].index
=
6622 CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_CR
;
6637 else if (rsrc_write
)
6639 if (dep
->specifier
== IA64_RS_FRb
6640 && idesc
->operands
[0] == IA64_OPND_F1
)
6642 specs
[count
] = tmpl
;
6643 specs
[count
++].index
= CURR_SLOT
.opnd
[0].X_add_number
- REG_FR
;
6648 for (i
=idesc
->num_outputs
;i
< NELEMS(idesc
->operands
);i
++)
6650 if (idesc
->operands
[i
] == IA64_OPND_F2
6651 || idesc
->operands
[i
] == IA64_OPND_F3
6652 || idesc
->operands
[i
] == IA64_OPND_F4
)
6654 specs
[count
] = tmpl
;
6655 specs
[count
++].index
=
6656 CURR_SLOT
.opnd
[i
].X_add_number
- REG_FR
;
6665 /* This reference applies only to the GR whose value is loaded with
6666 data returned from memory */
6667 specs
[count
] = tmpl
;
6668 specs
[count
++].index
= CURR_SLOT
.opnd
[0].X_add_number
- REG_GR
;
6674 for (i
=0;i
< idesc
->num_outputs
;i
++)
6676 if (idesc
->operands
[i
] == IA64_OPND_R1
6677 || idesc
->operands
[i
] == IA64_OPND_R2
6678 || idesc
->operands
[i
] == IA64_OPND_R3
)
6680 specs
[count
] = tmpl
;
6681 specs
[count
++].index
=
6682 CURR_SLOT
.opnd
[i
].X_add_number
- REG_GR
;
6688 /* Look for anything that reads a GR */
6689 for (i
=0;i
< NELEMS(idesc
->operands
);i
++)
6691 if (idesc
->operands
[i
] == IA64_OPND_MR3
6692 || idesc
->operands
[i
] == IA64_OPND_CPUID_R3
6693 || idesc
->operands
[i
] == IA64_OPND_DBR_R3
6694 || idesc
->operands
[i
] == IA64_OPND_IBR_R3
6695 || idesc
->operands
[i
] == IA64_OPND_MSR_R3
6696 || idesc
->operands
[i
] == IA64_OPND_PKR_R3
6697 || idesc
->operands
[i
] == IA64_OPND_PMC_R3
6698 || idesc
->operands
[i
] == IA64_OPND_PMD_R3
6699 || idesc
->operands
[i
] == IA64_OPND_RR_R3
6700 || ((i
>= idesc
->num_outputs
)
6701 && (idesc
->operands
[i
] == IA64_OPND_R1
6702 || idesc
->operands
[i
] == IA64_OPND_R2
6703 || idesc
->operands
[i
] == IA64_OPND_R3
)))
6705 specs
[count
] = tmpl
;
6706 specs
[count
++].index
=
6707 CURR_SLOT
.opnd
[i
].X_add_number
- REG_GR
;
6721 if (idesc
->operands
[0] == IA64_OPND_PR_ROT
)
6723 for (i
=16;i
< 63;i
++)
6725 specs
[count
] = tmpl
;
6726 specs
[count
++].index
= i
;
6731 for (i
=1;i
< 63;i
++)
6733 specs
[count
] = tmpl
;
6734 specs
[count
++].index
= i
;
6741 /* mark only those registers indicated by the mask */
6743 && idesc
->operands
[0] == IA64_OPND_PR
)
6745 mask
= CURR_SLOT
.opnd
[2].X_add_number
;
6746 if (mask
& ((valueT
)1<<16))
6747 mask
|= ~(valueT
)0xffff;
6748 for (i
=1;i
< 63;i
++)
6750 if (mask
& ((valueT
)1<<i
))
6752 specs
[count
] = tmpl
;
6753 specs
[count
++].index
= i
;
6758 && idesc
->operands
[0] == IA64_OPND_PR_ROT
)
6760 for (i
=16;i
< 63;i
++)
6762 specs
[count
] = tmpl
;
6763 specs
[count
++].index
= i
;
6771 else if (note
== 11) /* note 11 implies note 1 as well */
6775 for (i
=0;i
< idesc
->num_outputs
;i
++)
6777 if (idesc
->operands
[i
] == IA64_OPND_P1
6778 || idesc
->operands
[i
] == IA64_OPND_P2
)
6780 int regno
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_P
;
6783 specs
[count
] = tmpl
;
6784 specs
[count
++].index
= regno
;
6794 else if (note
== 12)
6796 if (CURR_SLOT
.qp_regno
!= 0)
6798 specs
[count
] = tmpl
;
6799 specs
[count
++].index
= CURR_SLOT
.qp_regno
;
6806 int p1
= CURR_SLOT
.opnd
[0].X_add_number
- REG_P
;
6807 int p2
= CURR_SLOT
.opnd
[1].X_add_number
- REG_P
;
6808 if ((idesc
->operands
[0] == IA64_OPND_P1
6809 || idesc
->operands
[0] == IA64_OPND_P2
)
6810 && p1
!= 0 && p1
!= 63)
6812 specs
[count
] = tmpl
;
6813 specs
[count
++].index
= p1
;
6815 if ((idesc
->operands
[1] == IA64_OPND_P1
6816 || idesc
->operands
[1] == IA64_OPND_P2
)
6817 && p2
!= 0 && p2
!= 63)
6819 specs
[count
] = tmpl
;
6820 specs
[count
++].index
= p2
;
6825 if (CURR_SLOT
.qp_regno
!= 0)
6827 specs
[count
] = tmpl
;
6828 specs
[count
++].index
= CURR_SLOT
.qp_regno
;
6830 if (idesc
->operands
[1] == IA64_OPND_PR
)
6832 for (i
=1;i
< 63;i
++)
6834 specs
[count
] = tmpl
;
6835 specs
[count
++].index
= i
;
6847 /* Verify that the instruction is using the PSR bit indicated in
6851 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_PSR_UM
)
6853 if (dep
->regindex
< 6)
6855 specs
[count
++] = tmpl
;
6858 else if (idesc
->operands
[!rsrc_write
] == IA64_OPND_PSR
)
6860 if (dep
->regindex
< 32
6861 || dep
->regindex
== 35
6862 || dep
->regindex
== 36
6863 || (!rsrc_write
&& dep
->regindex
== PSR_CPL
))
6865 specs
[count
++] = tmpl
;
6868 else if (idesc
->operands
[!rsrc_write
] == IA64_OPND_PSR_L
)
6870 if (dep
->regindex
< 32
6871 || dep
->regindex
== 35
6872 || dep
->regindex
== 36
6873 || (rsrc_write
&& dep
->regindex
== PSR_CPL
))
6875 specs
[count
++] = tmpl
;
6880 /* Several PSR bits have very specific dependencies. */
6881 switch (dep
->regindex
)
6884 specs
[count
++] = tmpl
;
6889 specs
[count
++] = tmpl
;
6893 /* Only certain CR accesses use PSR.ic */
6894 if (idesc
->operands
[0] == IA64_OPND_CR3
6895 || idesc
->operands
[1] == IA64_OPND_CR3
)
6898 ((idesc
->operands
[0] == IA64_OPND_CR3
)
6901 CURR_SLOT
.opnd
[index
].X_add_number
- REG_CR
;
6916 specs
[count
++] = tmpl
;
6925 specs
[count
++] = tmpl
;
6929 /* Only some AR accesses use cpl */
6930 if (idesc
->operands
[0] == IA64_OPND_AR3
6931 || idesc
->operands
[1] == IA64_OPND_AR3
)
6934 ((idesc
->operands
[0] == IA64_OPND_AR3
)
6937 CURR_SLOT
.opnd
[index
].X_add_number
- REG_AR
;
6944 && regno
<= AR_K7
))))
6946 specs
[count
++] = tmpl
;
6951 specs
[count
++] = tmpl
;
6961 if (idesc
->operands
[0] == IA64_OPND_IMMU24
)
6963 mask
= CURR_SLOT
.opnd
[0].X_add_number
;
6969 if (mask
& ((valueT
)1<<dep
->regindex
))
6971 specs
[count
++] = tmpl
;
6976 int min
= dep
->regindex
== PSR_DFL
? 2 : 32;
6977 int max
= dep
->regindex
== PSR_DFL
? 31 : 127;
6978 /* dfh is read on FR32-127; dfl is read on FR2-31 */
6979 for (i
=0;i
< NELEMS(idesc
->operands
);i
++)
6981 if (idesc
->operands
[i
] == IA64_OPND_F1
6982 || idesc
->operands
[i
] == IA64_OPND_F2
6983 || idesc
->operands
[i
] == IA64_OPND_F3
6984 || idesc
->operands
[i
] == IA64_OPND_F4
)
6986 int reg
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_FR
;
6987 if (reg
>= min
&& reg
<= max
)
6989 specs
[count
++] = tmpl
;
6996 int min
= dep
->regindex
== PSR_MFL
? 2 : 32;
6997 int max
= dep
->regindex
== PSR_MFL
? 31 : 127;
6998 /* mfh is read on writes to FR32-127; mfl is read on writes to
7000 for (i
=0;i
< idesc
->num_outputs
;i
++)
7002 if (idesc
->operands
[i
] == IA64_OPND_F1
)
7004 int reg
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_FR
;
7005 if (reg
>= min
&& reg
<= max
)
7007 specs
[count
++] = tmpl
;
7012 else if (note
== 10)
7014 for (i
=0;i
< NELEMS(idesc
->operands
);i
++)
7016 if (idesc
->operands
[i
] == IA64_OPND_R1
7017 || idesc
->operands
[i
] == IA64_OPND_R2
7018 || idesc
->operands
[i
] == IA64_OPND_R3
)
7020 int regno
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_GR
;
7021 if (regno
>= 16 && regno
<= 31)
7023 specs
[count
++] = tmpl
;
7034 case IA64_RS_AR_FPSR
:
7035 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_AR3
)
7037 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_AR
;
7038 if (regno
== AR_FPSR
)
7040 specs
[count
++] = tmpl
;
7045 specs
[count
++] = tmpl
;
7050 /* Handle all AR[REG] resources */
7051 if (note
== 0 || note
== 1)
7053 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_AR
;
7054 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_AR3
7055 && regno
== dep
->regindex
)
7057 specs
[count
++] = tmpl
;
7059 /* other AR[REG] resources may be affected by AR accesses */
7060 else if (idesc
->operands
[0] == IA64_OPND_AR3
)
7063 regno
= CURR_SLOT
.opnd
[0].X_add_number
- REG_AR
;
7064 switch (dep
->regindex
)
7070 if (regno
== AR_BSPSTORE
)
7072 specs
[count
++] = tmpl
;
7076 (regno
== AR_BSPSTORE
7077 || regno
== AR_RNAT
))
7079 specs
[count
++] = tmpl
;
7084 else if (idesc
->operands
[1] == IA64_OPND_AR3
)
7087 regno
= CURR_SLOT
.opnd
[1].X_add_number
- REG_AR
;
7088 switch (dep
->regindex
)
7093 if (regno
== AR_BSPSTORE
|| regno
== AR_RNAT
)
7095 specs
[count
++] = tmpl
;
7102 specs
[count
++] = tmpl
;
7112 /* Handle all CR[REG] resources */
7113 if (note
== 0 || note
== 1)
7115 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_CR3
)
7117 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_CR
;
7118 if (regno
== dep
->regindex
)
7120 specs
[count
++] = tmpl
;
7122 else if (!rsrc_write
)
7124 /* Reads from CR[IVR] affect other resources. */
7125 if (regno
== CR_IVR
)
7127 if ((dep
->regindex
>= CR_IRR0
7128 && dep
->regindex
<= CR_IRR3
)
7129 || dep
->regindex
== CR_TPR
)
7131 specs
[count
++] = tmpl
;
7138 specs
[count
++] = tmpl
;
7147 case IA64_RS_INSERVICE
:
7148 /* look for write of EOI (67) or read of IVR (65) */
7149 if ((idesc
->operands
[0] == IA64_OPND_CR3
7150 && CURR_SLOT
.opnd
[0].X_add_number
- REG_CR
== CR_EOI
)
7151 || (idesc
->operands
[1] == IA64_OPND_CR3
7152 && CURR_SLOT
.opnd
[1].X_add_number
- REG_CR
== CR_IVR
))
7154 specs
[count
++] = tmpl
;
7161 specs
[count
++] = tmpl
;
7172 specs
[count
++] = tmpl
;
7176 /* Check if any of the registers accessed are in the rotating region.
7177 mov to/from pr accesses CFM only when qp_regno is in the rotating
7179 for (i
=0;i
< NELEMS(idesc
->operands
);i
++)
7181 if (idesc
->operands
[i
] == IA64_OPND_R1
7182 || idesc
->operands
[i
] == IA64_OPND_R2
7183 || idesc
->operands
[i
] == IA64_OPND_R3
)
7185 int num
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_GR
;
7186 /* Assumes that md.rot.num_regs is always valid */
7187 if (md
.rot
.num_regs
> 0
7189 && num
< 31 + md
.rot
.num_regs
)
7191 specs
[count
] = tmpl
;
7192 specs
[count
++].specific
= 0;
7195 else if (idesc
->operands
[i
] == IA64_OPND_F1
7196 || idesc
->operands
[i
] == IA64_OPND_F2
7197 || idesc
->operands
[i
] == IA64_OPND_F3
7198 || idesc
->operands
[i
] == IA64_OPND_F4
)
7200 int num
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_FR
;
7203 specs
[count
] = tmpl
;
7204 specs
[count
++].specific
= 0;
7207 else if (idesc
->operands
[i
] == IA64_OPND_P1
7208 || idesc
->operands
[i
] == IA64_OPND_P2
)
7210 int num
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_P
;
7213 specs
[count
] = tmpl
;
7214 specs
[count
++].specific
= 0;
7218 if (CURR_SLOT
.qp_regno
> 15)
7220 specs
[count
] = tmpl
;
7221 specs
[count
++].specific
= 0;
7229 specs
[count
++] = tmpl
;
7231 else if (note
== 11)
7233 if ((idesc
->operands
[0] == IA64_OPND_P1
7234 && CURR_SLOT
.opnd
[0].X_add_number
- REG_P
== 63)
7235 || (idesc
->operands
[1] == IA64_OPND_P2
7236 && CURR_SLOT
.opnd
[1].X_add_number
- REG_P
== 63))
7238 specs
[count
++] = tmpl
;
7241 else if (note
== 12)
7243 if (CURR_SLOT
.qp_regno
== 63)
7245 specs
[count
++] = tmpl
;
7251 if (idesc
->operands
[2] == IA64_OPND_IMM17
)
7252 mask
= CURR_SLOT
.opnd
[2].X_add_number
;
7253 if (mask
& ((valueT
)1<<63))
7255 specs
[count
++] = tmpl
;
7262 for (i
=0;i
< idesc
->num_outputs
;i
++)
7263 if ((idesc
->operands
[i
] == IA64_OPND_P1
7264 || idesc
->operands
[i
] == IA64_OPND_P2
)
7265 && CURR_SLOT
.opnd
[i
].X_add_number
- REG_P
== 63)
7267 specs
[count
++] = tmpl
;
7272 if (CURR_SLOT
.qp_regno
== 63)
7274 specs
[count
++] = tmpl
;
7285 /* FIXME we can identify some individual RSE written resources, but RSE
7286 read resources have not yet been completely identified, so for now
7287 treat RSE as a single resource */
7288 if (strncmp (idesc
->name
, "mov", 3) == 0)
7292 if (idesc
->operands
[0] == IA64_OPND_AR3
7293 && CURR_SLOT
.opnd
[0].X_add_number
- REG_AR
== AR_BSPSTORE
)
7295 specs
[count
] = tmpl
;
7296 specs
[count
++].index
= 0; /* IA64_RSE_BSPLOAD/RNATBITINDEX */
7301 if (idesc
->operands
[0] == IA64_OPND_AR3
)
7303 if (CURR_SLOT
.opnd
[0].X_add_number
- REG_AR
== AR_BSPSTORE
7304 || CURR_SLOT
.opnd
[0].X_add_number
- REG_AR
== AR_RNAT
)
7306 specs
[count
++] = tmpl
;
7309 else if (idesc
->operands
[1] == IA64_OPND_AR3
)
7311 if (CURR_SLOT
.opnd
[1].X_add_number
- REG_AR
== AR_BSP
7312 || CURR_SLOT
.opnd
[1].X_add_number
- REG_AR
== AR_BSPSTORE
7313 || CURR_SLOT
.opnd
[1].X_add_number
- REG_AR
== AR_RNAT
)
7315 specs
[count
++] = tmpl
;
7322 specs
[count
++] = tmpl
;
7327 /* FIXME -- do any of these need to be non-specific? */
7328 specs
[count
++] = tmpl
;
7332 as_bad (_("Unrecognized dependency specifier %d\n"), dep
->specifier
);
7339 /* Clear branch flags on marked resources. This breaks the link between the
7340 QP of the marking instruction and a subsequent branch on the same QP.
7343 clear_qp_branch_flag (mask
)
7347 for (i
= 0;i
< regdepslen
;i
++)
7349 valueT bit
= ((valueT
)1 << regdeps
[i
].qp_regno
);
7350 if ((bit
& mask
) != 0)
7352 regdeps
[i
].link_to_qp_branch
= 0;
7357 /* Remove any mutexes which contain any of the PRs indicated in the mask.
7359 Any changes to a PR clears the mutex relations which include that PR.
7362 clear_qp_mutex (mask
)
7368 while (i
< qp_mutexeslen
)
7370 if ((qp_mutexes
[i
].prmask
& mask
) != 0)
7374 fprintf (stderr
, " Clearing mutex relation");
7375 print_prmask (qp_mutexes
[i
].prmask
);
7376 fprintf (stderr
, "\n");
7378 qp_mutexes
[i
] = qp_mutexes
[--qp_mutexeslen
];
7385 /* Clear implies relations which contain PRs in the given masks.
7386 P1_MASK indicates the source of the implies relation, while P2_MASK
7387 indicates the implied PR.
7390 clear_qp_implies (p1_mask
, p2_mask
)
7397 while (i
< qp_implieslen
)
7399 if ((((valueT
)1 << qp_implies
[i
].p1
) & p1_mask
) != 0
7400 || (((valueT
)1 << qp_implies
[i
].p2
) & p2_mask
) != 0)
7403 fprintf (stderr
, "Clearing implied relation PR%d->PR%d\n",
7404 qp_implies
[i
].p1
, qp_implies
[i
].p2
);
7405 qp_implies
[i
] = qp_implies
[--qp_implieslen
];
7412 /* add the PRs specified to the list of implied relations */
7414 add_qp_imply (p1
, p2
)
7421 /* p0 is not meaningful here */
7422 if (p1
== 0 || p2
== 0)
7428 /* if it exists already, ignore it */
7429 for (i
=0;i
< qp_implieslen
;i
++)
7431 if (qp_implies
[i
].p1
== p1
7432 && qp_implies
[i
].p2
== p2
7433 && qp_implies
[i
].path
== md
.path
7434 && !qp_implies
[i
].p2_branched
)
7438 if (qp_implieslen
== qp_impliestotlen
)
7440 qp_impliestotlen
+= 20;
7441 qp_implies
= (struct qp_imply
*)
7442 xrealloc ((void *)qp_implies
,
7443 qp_impliestotlen
* sizeof (struct qp_imply
));
7446 fprintf (stderr
, " Registering PR%d implies PR%d\n", p1
, p2
);
7447 qp_implies
[qp_implieslen
].p1
= p1
;
7448 qp_implies
[qp_implieslen
].p2
= p2
;
7449 qp_implies
[qp_implieslen
].path
= md
.path
;
7450 qp_implies
[qp_implieslen
++].p2_branched
= 0;
7452 /* Add in the implied transitive relations; for everything that p2 implies,
7453 make p1 imply that, too; for everything that implies p1, make it imply p2
7455 for (i
=0;i
< qp_implieslen
;i
++)
7457 if (qp_implies
[i
].p1
== p2
)
7458 add_qp_imply (p1
, qp_implies
[i
].p2
);
7459 if (qp_implies
[i
].p2
== p1
)
7460 add_qp_imply (qp_implies
[i
].p1
, p2
);
7462 /* Add in mutex relations implied by this implies relation; for each mutex
7463 relation containing p2, duplicate it and replace p2 with p1. */
7464 bit
= (valueT
)1 << p1
;
7465 mask
= (valueT
)1 << p2
;
7466 for (i
=0;i
< qp_mutexeslen
;i
++)
7468 if (qp_mutexes
[i
].prmask
& mask
)
7469 add_qp_mutex ((qp_mutexes
[i
].prmask
& ~mask
) | bit
);
7474 /* Add the PRs specified in the mask to the mutex list; this means that only
7475 one of the PRs can be true at any time. PR0 should never be included in
7484 if (qp_mutexeslen
== qp_mutexestotlen
)
7486 qp_mutexestotlen
+= 20;
7487 qp_mutexes
= (struct qpmutex
*)
7488 xrealloc ((void *)qp_mutexes
,
7489 qp_mutexestotlen
* sizeof (struct qpmutex
));
7493 fprintf (stderr
, " Registering mutex on");
7494 print_prmask (mask
);
7495 fprintf (stderr
, "\n");
7497 qp_mutexes
[qp_mutexeslen
].path
= md
.path
;
7498 qp_mutexes
[qp_mutexeslen
++].prmask
= mask
;
7502 clear_register_values ()
7506 fprintf (stderr
, " Clearing register values\n");
7507 for (i
=1;i
< NELEMS(gr_values
);i
++)
7508 gr_values
[i
].known
= 0;
7511 /* Keep track of register values/changes which affect DV tracking.
7513 optimization note: should add a flag to classes of insns where otherwise we
7514 have to examine a group of strings to identify them.
7518 note_register_values (idesc
)
7519 struct ia64_opcode
*idesc
;
7521 valueT qp_changemask
= 0;
7524 /* invalidate values for registers being written to */
7525 for (i
=0;i
< idesc
->num_outputs
;i
++)
7527 if (idesc
->operands
[i
] == IA64_OPND_R1
7528 || idesc
->operands
[i
] == IA64_OPND_R2
7529 || idesc
->operands
[i
] == IA64_OPND_R3
)
7531 int regno
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_GR
;
7532 if (regno
> 0 && regno
< NELEMS(gr_values
))
7533 gr_values
[regno
].known
= 0;
7535 else if (idesc
->operands
[i
] == IA64_OPND_P1
7536 || idesc
->operands
[i
] == IA64_OPND_P2
)
7538 int regno
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_P
;
7539 qp_changemask
|= (valueT
)1 << regno
;
7541 else if (idesc
->operands
[i
] == IA64_OPND_PR
)
7543 if (idesc
->operands
[2] & (valueT
)0x10000)
7544 qp_changemask
= ~(valueT
)0x1FFFF | idesc
->operands
[2];
7546 qp_changemask
= idesc
->operands
[2];
7549 else if (idesc
->operands
[i
] == IA64_OPND_PR_ROT
)
7551 if (idesc
->operands
[1] & ((valueT
)1 << 43))
7552 qp_changemask
= ~(valueT
)0xFFFFFFFFFFF | idesc
->operands
[1];
7554 qp_changemask
= idesc
->operands
[1];
7555 qp_changemask
&= ~(valueT
)0xFFFF;
7560 /* Always clear qp branch flags on any PR change */
7561 /* FIXME there may be exceptions for certain compares */
7562 clear_qp_branch_flag (qp_changemask
);
7564 /* invalidate rotating registers on insns which affect RRBs in CFM */
7565 if (idesc
->flags
& IA64_OPCODE_MOD_RRBS
)
7567 qp_changemask
|= ~(valueT
)0xFFFF;
7568 if (strcmp (idesc
->name
, "clrrrb.pr") != 0)
7570 for (i
=32;i
< 32+md
.rot
.num_regs
;i
++)
7571 gr_values
[i
].known
= 0;
7573 clear_qp_mutex (qp_changemask
);
7574 clear_qp_implies (qp_changemask
, qp_changemask
);
7576 /* after a call, all register values are undefined, except those marked
7578 else if (strncmp (idesc
->name
, "br.call", 6) == 0
7579 || strncmp (idesc
->name
, "brl.call", 7) == 0)
7581 // FIXME keep GR values which are marked as "safe_across_calls"
7582 clear_register_values ();
7583 clear_qp_mutex (~qp_safe_across_calls
);
7584 clear_qp_implies (~qp_safe_across_calls
, ~qp_safe_across_calls
);
7585 clear_qp_branch_flag (~qp_safe_across_calls
);
7587 /* Look for mutex and implies relations */
7588 else if ((idesc
->operands
[0] == IA64_OPND_P1
7589 || idesc
->operands
[0] == IA64_OPND_P2
)
7590 && (idesc
->operands
[1] == IA64_OPND_P1
7591 || idesc
->operands
[1] == IA64_OPND_P2
))
7593 int p1
= CURR_SLOT
.opnd
[0].X_add_number
- REG_P
;
7594 int p2
= CURR_SLOT
.opnd
[1].X_add_number
- REG_P
;
7595 valueT p1mask
= (valueT
)1 << p1
;
7596 valueT p2mask
= (valueT
)1 << p2
;
7598 /* if one of the PRs is PR0, we can't really do anything */
7599 if (p1
== 0 || p2
== 0)
7602 fprintf (stderr
, " Ignoring PRs due to inclusion of p0\n");
7604 /* In general, clear mutexes and implies which include P1 or P2,
7605 with the following exceptions */
7606 else if (strstr (idesc
->name
, ".or.andcm") != NULL
)
7608 add_qp_mutex (p1mask
| p2mask
);
7609 clear_qp_implies (p2mask
, p1mask
);
7611 else if (strstr (idesc
->name
, ".and.orcm") != NULL
)
7613 add_qp_mutex (p1mask
| p2mask
);
7614 clear_qp_implies (p1mask
, p2mask
);
7616 else if (strstr (idesc
->name
, ".and") != NULL
)
7618 clear_qp_implies (0, p1mask
| p2mask
);
7620 else if (strstr (idesc
->name
, ".or") != NULL
)
7622 clear_qp_mutex (p1mask
| p2mask
);
7623 clear_qp_implies (p1mask
| p2mask
, 0);
7627 clear_qp_implies (p1mask
| p2mask
, p1mask
| p2mask
);
7628 if (strstr (idesc
->name
, ".unc") != NULL
)
7630 add_qp_mutex (p1mask
| p2mask
);
7631 if (CURR_SLOT
.qp_regno
!= 0)
7633 add_qp_imply (CURR_SLOT
.opnd
[0].X_add_number
- REG_P
,
7634 CURR_SLOT
.qp_regno
);
7635 add_qp_imply (CURR_SLOT
.opnd
[1].X_add_number
- REG_P
,
7636 CURR_SLOT
.qp_regno
);
7639 else if (CURR_SLOT
.qp_regno
== 0)
7641 add_qp_mutex (p1mask
| p2mask
);
7645 clear_qp_mutex (p1mask
| p2mask
);
7649 /* Look for mov imm insns into GRs */
7650 else if (idesc
->operands
[0] == IA64_OPND_R1
7651 && (idesc
->operands
[1] == IA64_OPND_IMM22
7652 || idesc
->operands
[1] == IA64_OPND_IMMU64
)
7653 && (strcmp(idesc
->name
, "mov") == 0
7654 || strcmp(idesc
->name
, "movl") == 0))
7656 int regno
= CURR_SLOT
.opnd
[0].X_add_number
- REG_GR
;
7657 if (regno
> 0 && regno
< NELEMS(gr_values
))
7659 gr_values
[regno
].known
= 1;
7660 gr_values
[regno
].value
= CURR_SLOT
.opnd
[1].X_add_number
;
7661 gr_values
[regno
].path
= md
.path
;
7663 fprintf (stderr
, " Know gr%d = 0x%llx\n",
7664 regno
, gr_values
[regno
].value
);
7669 clear_qp_mutex (qp_changemask
);
7670 clear_qp_implies (qp_changemask
, qp_changemask
);
7674 /* Return whether the given predicate registers are currently mutex */
7676 qp_mutex (p1
, p2
, path
)
7686 mask
= ((valueT
)1<<p1
) | (valueT
)1<<p2
;
7687 for (i
=0;i
< qp_mutexeslen
;i
++)
7689 if (qp_mutexes
[i
].path
>= path
7690 && (qp_mutexes
[i
].prmask
& mask
) == mask
)
7697 /* Return whether the given resource is in the given insn's list of chks
7698 Return 1 if the conflict is absolutely determined, 2 if it's a potential
7702 resources_match (rs
, idesc
, note
, qp_regno
, path
)
7704 struct ia64_opcode
*idesc
;
7709 struct rsrc specs
[MAX_SPECS
];
7712 /* If the marked resource's qp_regno and the given qp_regno are mutex,
7713 we don't need to check. One exception is note 11, which indicates that
7714 target predicates are written regardless of PR[qp]. */
7715 if (qp_mutex (rs
->qp_regno
, qp_regno
, path
)
7719 count
= specify_resource (rs
->dependency
, idesc
, DV_CHK
, specs
, note
, path
);
7722 /* UNAT checking is a bit more specific than other resources */
7723 if (rs
->dependency
->specifier
== IA64_RS_AR_UNAT
7724 && specs
[count
].mem_offset
.hint
7725 && rs
->mem_offset
.hint
)
7727 if (rs
->mem_offset
.base
== specs
[count
].mem_offset
.base
)
7729 if (((rs
->mem_offset
.offset
>> 3) & 0x3F) ==
7730 ((specs
[count
].mem_offset
.offset
>> 3) & 0x3F))
7737 /* If either resource is not specific, conservatively assume a conflict
7739 if (!specs
[count
].specific
|| !rs
->specific
)
7741 else if (specs
[count
].index
== rs
->index
)
7746 fprintf (stderr
, " No %s conflicts\n", rs
->dependency
->name
);
7752 /* Indicate an instruction group break; if INSERT_STOP is non-zero, then
7753 insert a stop to create the break. Update all resource dependencies
7754 appropriately. If QP_REGNO is non-zero, only apply the break to resources
7755 which use the same QP_REGNO and have the link_to_qp_branch flag set.
7756 If SAVE_CURRENT is non-zero, don't affect resources marked by the current
7761 insn_group_break (insert_stop
, qp_regno
, save_current
)
7768 if (insert_stop
&& md
.num_slots_in_use
> 0)
7769 PREV_SLOT
.end_of_insn_group
= 1;
7773 fprintf (stderr
, " Insn group break%s",
7774 (insert_stop
? " (w/stop)" : ""));
7776 fprintf (stderr
, " effective for QP=%d", qp_regno
);
7777 fprintf (stderr
, "\n");
7781 while (i
< regdepslen
)
7783 const struct ia64_dependency
*dep
= regdeps
[i
].dependency
;
7786 && regdeps
[i
].qp_regno
!= qp_regno
)
7793 && CURR_SLOT
.src_file
== regdeps
[i
].file
7794 && CURR_SLOT
.src_line
== regdeps
[i
].line
)
7800 /* clear dependencies which are automatically cleared by a stop, or
7801 those that have reached the appropriate state of insn serialization */
7802 if (dep
->semantics
== IA64_DVS_IMPLIED
7803 || dep
->semantics
== IA64_DVS_IMPLIEDF
7804 || regdeps
[i
].insn_srlz
== STATE_SRLZ
)
7806 print_dependency ("Removing", i
);
7807 regdeps
[i
] = regdeps
[--regdepslen
];
7811 if (dep
->semantics
== IA64_DVS_DATA
7812 || dep
->semantics
== IA64_DVS_INSTR
7813 || dep
->semantics
== IA64_DVS_SPECIFIC
)
7815 if (regdeps
[i
].insn_srlz
== STATE_NONE
)
7816 regdeps
[i
].insn_srlz
= STATE_STOP
;
7817 if (regdeps
[i
].data_srlz
== STATE_NONE
)
7818 regdeps
[i
].data_srlz
= STATE_STOP
;
7825 /* Add the given resource usage spec to the list of active dependencies */
7827 mark_resource (idesc
, dep
, spec
, depind
, path
)
7828 struct ia64_opcode
*idesc
;
7829 const struct ia64_dependency
*dep
;
7834 if (regdepslen
== regdepstotlen
)
7836 regdepstotlen
+= 20;
7837 regdeps
= (struct rsrc
*)
7838 xrealloc ((void *)regdeps
,
7839 regdepstotlen
* sizeof(struct rsrc
));
7842 regdeps
[regdepslen
] = *spec
;
7843 regdeps
[regdepslen
].depind
= depind
;
7844 regdeps
[regdepslen
].path
= path
;
7845 regdeps
[regdepslen
].file
= CURR_SLOT
.src_file
;
7846 regdeps
[regdepslen
].line
= CURR_SLOT
.src_line
;
7848 print_dependency ("Adding", regdepslen
);
7854 print_dependency (action
, depind
)
7860 fprintf (stderr
, " %s %s '%s'",
7861 action
, dv_mode
[(regdeps
[depind
].dependency
)->mode
],
7862 (regdeps
[depind
].dependency
)->name
);
7863 if (regdeps
[depind
].specific
&& regdeps
[depind
].index
!= 0)
7864 fprintf (stderr
, " (%d)", regdeps
[depind
].index
);
7865 if (regdeps
[depind
].mem_offset
.hint
)
7866 fprintf (stderr
, " 0x%llx+0x%llx",
7867 regdeps
[depind
].mem_offset
.base
,
7868 regdeps
[depind
].mem_offset
.offset
);
7869 fprintf (stderr
, "\n");
7874 instruction_serialization ()
7878 fprintf (stderr
, " Instruction serialization\n");
7879 for (i
=0;i
< regdepslen
;i
++)
7880 if (regdeps
[i
].insn_srlz
== STATE_STOP
)
7881 regdeps
[i
].insn_srlz
= STATE_SRLZ
;
7885 data_serialization ()
7889 fprintf (stderr
, " Data serialization\n");
7890 while (i
< regdepslen
)
7892 if (regdeps
[i
].data_srlz
== STATE_STOP
7893 /* Note: as of 991210, all "other" dependencies are cleared by a
7894 data serialization. This might change with new tables */
7895 || (regdeps
[i
].dependency
)->semantics
== IA64_DVS_OTHER
)
7897 print_dependency ("Removing", i
);
7898 regdeps
[i
] = regdeps
[--regdepslen
];
7905 /* Insert stops and serializations as needed to avoid DVs */
7907 remove_marked_resource (rs
)
7910 switch (rs
->dependency
->semantics
)
7912 case IA64_DVS_SPECIFIC
:
7914 fprintf (stderr
, "Implementation-specific, assume worst case...\n");
7915 /* ...fall through... */
7916 case IA64_DVS_INSTR
:
7918 fprintf (stderr
, "Inserting instr serialization\n");
7919 if (rs
->insn_srlz
< STATE_STOP
)
7920 insn_group_break (1, 0, 0);
7921 if (rs
->insn_srlz
< STATE_SRLZ
)
7923 int oldqp
= CURR_SLOT
.qp_regno
;
7924 struct ia64_opcode
*oldidesc
= CURR_SLOT
.idesc
;
7925 /* Manually jam a srlz.i insn into the stream */
7926 CURR_SLOT
.qp_regno
= 0;
7927 CURR_SLOT
.idesc
= ia64_find_opcode ("srlz.i");
7928 instruction_serialization ();
7929 md
.curr_slot
= (md
.curr_slot
+ 1) % NUM_SLOTS
;
7930 if (++md
.num_slots_in_use
>= NUM_SLOTS
)
7932 CURR_SLOT
.qp_regno
= oldqp
;
7933 CURR_SLOT
.idesc
= oldidesc
;
7935 insn_group_break (1, 0, 0);
7937 case IA64_DVS_OTHER
: /* as of rev2 (991220) of the DV tables, all
7938 "other" types of DV are eliminated
7939 by a data serialization */
7942 fprintf (stderr
, "Inserting data serialization\n");
7943 if (rs
->data_srlz
< STATE_STOP
)
7944 insn_group_break (1, 0, 0);
7946 int oldqp
= CURR_SLOT
.qp_regno
;
7947 struct ia64_opcode
*oldidesc
= CURR_SLOT
.idesc
;
7948 /* Manually jam a srlz.d insn into the stream */
7949 CURR_SLOT
.qp_regno
= 0;
7950 CURR_SLOT
.idesc
= ia64_find_opcode ("srlz.d");
7951 data_serialization ();
7952 md
.curr_slot
= (md
.curr_slot
+ 1) % NUM_SLOTS
;
7953 if (++md
.num_slots_in_use
>= NUM_SLOTS
)
7955 CURR_SLOT
.qp_regno
= oldqp
;
7956 CURR_SLOT
.idesc
= oldidesc
;
7959 case IA64_DVS_IMPLIED
:
7960 case IA64_DVS_IMPLIEDF
:
7962 fprintf (stderr
, "Inserting stop\n");
7963 insn_group_break (1, 0, 0);
7970 /* Check the resources used by the given opcode against the current dependency
7973 The check is run once for each execution path encountered. In this case,
7974 a unique execution path is the sequence of instructions following a code
7975 entry point, e.g. the following has three execution paths, one starting
7976 at L0, one at L1, and one at L2.
7984 check_dependencies (idesc
)
7985 struct ia64_opcode
*idesc
;
7987 const struct ia64_opcode_dependency
*opdeps
= idesc
->dependencies
;
7991 /* Note that the number of marked resources may change within the
7992 loop if in auto mode. */
7994 while (i
< regdepslen
)
7996 struct rsrc
*rs
= ®deps
[i
];
7997 const struct ia64_dependency
*dep
= rs
->dependency
;
8002 if (dep
->semantics
== IA64_DVS_NONE
8003 || (chkind
= depends_on (rs
->depind
, idesc
)) == -1)
8008 note
= NOTE(opdeps
->chks
[chkind
]);
8010 /* Check this resource against each execution path seen thus far */
8011 for (path
=0;path
<= md
.path
;path
++)
8015 /* If the dependency wasn't on the path being checked, ignore it */
8016 if (rs
->path
< path
)
8019 /* If the QP for this insn implies a QP which has branched, don't
8020 bother checking. Ed. NOTE: I don't think this check is terribly
8021 useful; what's the point of generating code which will only be
8022 reached if its QP is zero?
8023 This code was specifically inserted to handle the following code,
8024 based on notes from Intel's DV checking code, where p1 implies p2.
8031 if (CURR_SLOT
.qp_regno
!= 0)
8035 for (implies
=0;implies
< qp_implieslen
;implies
++)
8037 if (qp_implies
[implies
].path
>= path
8038 && qp_implies
[implies
].p1
== CURR_SLOT
.qp_regno
8039 && qp_implies
[implies
].p2_branched
)
8049 if ((matchtype
= resources_match (rs
, idesc
, note
,
8050 CURR_SLOT
.qp_regno
, path
)) != 0)
8053 char pathmsg
[256] = "";
8054 char indexmsg
[256] = "";
8055 int certain
= (matchtype
== 1 && CURR_SLOT
.qp_regno
== 0);
8058 sprintf (pathmsg
, " when entry is at label '%s'",
8059 md
.entry_labels
[path
-1]);
8060 if (rs
->specific
&& rs
->index
!= 0)
8061 sprintf (indexmsg
, ", specific resource number is %d",
8063 sprintf (msg
, "Use of '%s' %s %s dependency '%s' (%s)%s%s",
8065 (certain
? "violates" : "may violate"),
8066 dv_mode
[dep
->mode
], dep
->name
,
8067 dv_sem
[dep
->semantics
],
8070 if (md
.explicit_mode
)
8072 as_warn ("%s", msg
);
8074 as_warn (_("Only the first path encountering the conflict "
8076 as_warn_where (rs
->file
, rs
->line
,
8077 _("This is the location of the "
8078 "conflicting usage"));
8079 /* Don't bother checking other paths, to avoid duplicating
8086 fprintf(stderr
, "%s @ %s:%d\n", msg
, rs
->file
, rs
->line
);
8088 remove_marked_resource (rs
);
8090 /* since the set of dependencies has changed, start over */
8091 /* FIXME -- since we're removing dvs as we go, we
8092 probably don't really need to start over... */
8105 /* register new dependencies based on the given opcode */
8107 mark_resources (idesc
)
8108 struct ia64_opcode
*idesc
;
8111 const struct ia64_opcode_dependency
*opdeps
= idesc
->dependencies
;
8112 int add_only_qp_reads
= 0;
8114 /* A conditional branch only uses its resources if it is taken; if it is
8115 taken, we stop following that path. The other branch types effectively
8116 *always* write their resources. If it's not taken, register only QP
8118 if (is_conditional_branch (idesc
) || is_interruption_or_rfi (idesc
))
8120 add_only_qp_reads
= 1;
8124 fprintf (stderr
, "Registering '%s' resource usage\n", idesc
->name
);
8126 for (i
=0;i
< opdeps
->nregs
;i
++)
8128 const struct ia64_dependency
*dep
;
8129 struct rsrc specs
[MAX_SPECS
];
8134 dep
= ia64_find_dependency (opdeps
->regs
[i
]);
8135 note
= NOTE(opdeps
->regs
[i
]);
8137 if (add_only_qp_reads
8138 && !(dep
->mode
== IA64_DV_WAR
8139 && (dep
->specifier
== IA64_RS_PR
8140 || dep
->specifier
== IA64_RS_PR63
)))
8143 count
= specify_resource (dep
, idesc
, DV_REG
, specs
, note
, md
.path
);
8146 if (md
.debug_dv
&& !count
)
8147 fprintf (stderr
, " No %s %s usage found (path %d)\n",
8148 dv_mode
[dep
->mode
], dep
->name
, md
.path
);
8153 mark_resource (idesc
, dep
, &specs
[count
],
8154 DEP(opdeps
->regs
[i
]), md
.path
);
8157 /* The execution path may affect register values, which may in turn
8158 affect which indirect-access resources are accessed. */
8159 switch (dep
->specifier
)
8171 for (path
=0;path
< md
.path
;path
++)
8173 count
= specify_resource (dep
, idesc
, DV_REG
, specs
, note
, path
);
8175 mark_resource (idesc
, dep
, &specs
[count
],
8176 DEP(opdeps
->regs
[i
]), path
);
8183 /* remove dependencies when they no longer apply */
8185 update_dependencies (idesc
)
8186 struct ia64_opcode
*idesc
;
8190 if (strcmp (idesc
->name
, "srlz.i") == 0)
8192 instruction_serialization ();
8194 else if (strcmp (idesc
->name
, "srlz.d") == 0)
8196 data_serialization ();
8198 else if (is_interruption_or_rfi (idesc
)
8199 || is_taken_branch (idesc
))
8201 /* although technically the taken branch doesn't clear dependencies
8202 which require a srlz.[id], we don't follow the branch; the next
8203 instruction is assumed to start with a clean slate */
8205 clear_register_values ();
8206 clear_qp_mutex (~(valueT
)0);
8207 clear_qp_implies (~(valueT
)0, ~(valueT
)0);
8210 else if (is_conditional_branch (idesc
)
8211 && CURR_SLOT
.qp_regno
!= 0)
8213 int is_call
= strstr (idesc
->name
, ".call") != NULL
;
8215 for (i
=0;i
< qp_implieslen
;i
++)
8217 /* if the conditional branch's predicate is implied by the predicate
8218 in an existing dependency, remove that dependency */
8219 if (qp_implies
[i
].p2
== CURR_SLOT
.qp_regno
)
8222 /* note that this implied predicate takes a branch so that if
8223 a later insn generates a DV but its predicate implies this
8224 one, we can avoid the false DV warning */
8225 qp_implies
[i
].p2_branched
= 1;
8226 while (depind
< regdepslen
)
8228 if (regdeps
[depind
].qp_regno
== qp_implies
[i
].p1
)
8230 print_dependency ("Removing", depind
);
8231 regdeps
[depind
] = regdeps
[--regdepslen
];
8238 /* Any marked resources which have this same predicate should be
8239 cleared, provided that the QP hasn't been modified between the
8240 marking instruction and the branch.
8244 insn_group_break (0, CURR_SLOT
.qp_regno
, 1);
8249 while (i
< regdepslen
)
8251 if (regdeps
[i
].qp_regno
== CURR_SLOT
.qp_regno
8252 && regdeps
[i
].link_to_qp_branch
8253 && (regdeps
[i
].file
!= CURR_SLOT
.src_file
8254 || regdeps
[i
].line
!= CURR_SLOT
.src_line
))
8256 /* Treat like a taken branch */
8257 print_dependency ("Removing", i
);
8258 regdeps
[i
] = regdeps
[--regdepslen
];
8267 /* Examine the current instruction for dependency violations. */
8270 struct ia64_opcode
*idesc
;
8274 fprintf (stderr
, "Checking %s for violations (line %d, %d/%d)\n",
8275 idesc
->name
, CURR_SLOT
.src_line
,
8276 idesc
->dependencies
->nchks
,
8277 idesc
->dependencies
->nregs
);
8280 /* Look through the list of currently marked resources; if the current
8281 instruction has the dependency in its chks list which uses that resource,
8282 check against the specific resources used.
8284 check_dependencies (idesc
);
8287 Look up the instruction's regdeps (RAW writes, WAW writes, and WAR reads),
8288 then add them to the list of marked resources.
8290 mark_resources (idesc
);
8292 /* There are several types of dependency semantics, and each has its own
8293 requirements for being cleared
8295 Instruction serialization (insns separated by interruption, rfi, or
8296 writer + srlz.i + reader, all in separate groups) clears DVS_INSTR.
8298 Data serialization (instruction serialization, or writer + srlz.d +
8299 reader, where writer and srlz.d are in separate groups) clears
8300 DVS_DATA. (This also clears DVS_OTHER, but that is not guaranteed to
8301 always be the case).
8303 Instruction group break (groups separated by stop, taken branch,
8304 interruption or rfi) clears DVS_IMPLIED and DVS_IMPLIEDF.
8306 update_dependencies (idesc
);
8308 /* Sometimes, knowing a register value allows us to avoid giving a false DV
8309 warning. Keep track of as many as possible that are useful. */
8310 note_register_values (idesc
);
8312 /* We don't need or want this anymore. */
8313 md
.mem_offset
.hint
= 0;
8318 /* Translate one line of assembly. Pseudo ops and labels do not show
8324 char *saved_input_line_pointer
, *mnemonic
;
8325 const struct pseudo_opcode
*pdesc
;
8326 struct ia64_opcode
*idesc
;
8327 unsigned char qp_regno
;
8331 saved_input_line_pointer
= input_line_pointer
;
8332 input_line_pointer
= str
;
8334 /* extract the opcode (mnemonic): */
8336 mnemonic
= input_line_pointer
;
8337 ch
= get_symbol_end ();
8338 pdesc
= (struct pseudo_opcode
*) hash_find (md
.pseudo_hash
, mnemonic
);
8341 *input_line_pointer
= ch
;
8342 (*pdesc
->handler
) (pdesc
->arg
);
8346 /* find the instruction descriptor matching the arguments: */
8348 idesc
= ia64_find_opcode (mnemonic
);
8349 *input_line_pointer
= ch
;
8352 as_bad ("Unknown opcode `%s'", mnemonic
);
8356 idesc
= parse_operands (idesc
);
8360 /* Handle the dynamic ops we can handle now: */
8361 if (idesc
->type
== IA64_TYPE_DYN
)
8363 if (strcmp (idesc
->name
, "add") == 0)
8365 if (CURR_SLOT
.opnd
[2].X_op
== O_register
8366 && CURR_SLOT
.opnd
[2].X_add_number
< 4)
8370 idesc
= ia64_find_opcode (mnemonic
);
8372 know (!idesc
->next
);
8375 else if (strcmp (idesc
->name
, "mov") == 0)
8377 enum ia64_opnd opnd1
, opnd2
;
8380 opnd1
= idesc
->operands
[0];
8381 opnd2
= idesc
->operands
[1];
8382 if (opnd1
== IA64_OPND_AR3
)
8384 else if (opnd2
== IA64_OPND_AR3
)
8388 if (CURR_SLOT
.opnd
[rop
].X_op
== O_register
8389 && ar_is_in_integer_unit (CURR_SLOT
.opnd
[rop
].X_add_number
))
8393 idesc
= ia64_find_opcode (mnemonic
);
8394 while (idesc
!= NULL
8395 && (idesc
->operands
[0] != opnd1
8396 || idesc
->operands
[1] != opnd2
))
8397 idesc
= get_next_opcode (idesc
);
8402 if (md
.qp
.X_op
== O_register
)
8403 qp_regno
= md
.qp
.X_add_number
- REG_P
;
8405 flags
= idesc
->flags
;
8407 if ((flags
& IA64_OPCODE_FIRST
) != 0)
8408 insn_group_break (1, 0, 0);
8410 if ((flags
& IA64_OPCODE_NO_PRED
) != 0 && qp_regno
!= 0)
8412 as_bad ("`%s' cannot be predicated", idesc
->name
);
8416 /* build the instruction: */
8417 CURR_SLOT
.qp_regno
= qp_regno
;
8418 CURR_SLOT
.idesc
= idesc
;
8419 as_where (&CURR_SLOT
.src_file
, &CURR_SLOT
.src_line
);
8420 if (debug_type
== DEBUG_DWARF2
)
8421 dwarf2_where (&CURR_SLOT
.debug_line
);
8423 /* Add unwind entry, if there is one. */
8424 if (unwind
.current_entry
)
8426 CURR_SLOT
.unwind_record
= unwind
.current_entry
;
8427 unwind
.current_entry
= NULL
;
8430 /* check for dependency violations */
8434 md
.curr_slot
= (md
.curr_slot
+ 1) % NUM_SLOTS
;
8435 if (++md
.num_slots_in_use
>= NUM_SLOTS
)
8438 if ((flags
& IA64_OPCODE_LAST
) != 0)
8439 insn_group_break (1, 0, 0);
8441 md
.last_text_seg
= now_seg
;
8444 input_line_pointer
= saved_input_line_pointer
;
8447 /* Called when symbol NAME cannot be found in the symbol table.
8448 Should be used for dynamic valued symbols only. */
8450 md_undefined_symbol (name
)
8456 /* Called for any expression that can not be recognized. When the
8457 function is called, `input_line_pointer' will point to the start of
8463 enum pseudo_type pseudo_type
;
8468 switch (*input_line_pointer
)
8471 /* find what relocation pseudo-function we're dealing with: */
8473 ch
= *++input_line_pointer
;
8474 for (i
= 0; i
< NELEMS (pseudo_func
); ++i
)
8475 if (pseudo_func
[i
].name
&& pseudo_func
[i
].name
[0] == ch
)
8477 len
= strlen (pseudo_func
[i
].name
);
8478 if (strncmp (pseudo_func
[i
].name
+ 1,
8479 input_line_pointer
+ 1, len
- 1) == 0
8480 && !is_part_of_name (input_line_pointer
[len
]))
8482 input_line_pointer
+= len
;
8483 pseudo_type
= pseudo_func
[i
].type
;
8487 switch (pseudo_type
)
8489 case PSEUDO_FUNC_RELOC
:
8491 if (*input_line_pointer
!= '(')
8493 as_bad ("Expected '('");
8496 ++input_line_pointer
; /* skip '(' */
8498 if (*input_line_pointer
++ != ')')
8500 as_bad ("Missing ')'");
8503 if (e
->X_op
!= O_symbol
)
8505 if (e
->X_op
!= O_pseudo_fixup
)
8507 as_bad ("Not a symbolic expression");
8510 if (S_GET_VALUE (e
->X_op_symbol
) == FUNC_FPTR_RELATIVE
8511 && i
== FUNC_LT_RELATIVE
)
8512 i
= FUNC_LT_FPTR_RELATIVE
;
8515 as_bad ("Illegal combination of relocation functions");
8519 /* make sure gas doesn't get rid of local symbols that are used
8521 e
->X_op
= O_pseudo_fixup
;
8522 e
->X_op_symbol
= pseudo_func
[i
].u
.sym
;
8525 case PSEUDO_FUNC_CONST
:
8526 e
->X_op
= O_constant
;
8527 e
->X_add_number
= pseudo_func
[i
].u
.ival
;
8530 case PSEUDO_FUNC_REG
:
8531 e
->X_op
= O_register
;
8532 e
->X_add_number
= pseudo_func
[i
].u
.ival
;
8536 name
= input_line_pointer
- 1;
8538 as_bad ("Unknown pseudo function `%s'", name
);
8544 ++input_line_pointer
;
8546 if (*input_line_pointer
!= ']')
8548 as_bad ("Closing bracket misssing");
8553 if (e
->X_op
!= O_register
)
8554 as_bad ("Register expected as index");
8556 ++input_line_pointer
;
8567 ignore_rest_of_line ();
8570 /* Return 1 if it's OK to adjust a reloc by replacing the symbol with
8571 a section symbol plus some offset. For relocs involving @fptr(),
8572 directives we don't want such adjustments since we need to have the
8573 original symbol's name in the reloc. */
8575 ia64_fix_adjustable (fix
)
8578 /* Prevent all adjustments to global symbols */
8579 if (S_IS_EXTERN (fix
->fx_addsy
) || S_IS_WEAK (fix
->fx_addsy
))
8582 switch (fix
->fx_r_type
)
8584 case BFD_RELOC_IA64_FPTR64I
:
8585 case BFD_RELOC_IA64_FPTR32MSB
:
8586 case BFD_RELOC_IA64_FPTR32LSB
:
8587 case BFD_RELOC_IA64_FPTR64MSB
:
8588 case BFD_RELOC_IA64_FPTR64LSB
:
8589 case BFD_RELOC_IA64_LTOFF_FPTR22
:
8590 case BFD_RELOC_IA64_LTOFF_FPTR64I
:
8600 ia64_force_relocation (fix
)
8603 switch (fix
->fx_r_type
)
8605 case BFD_RELOC_IA64_FPTR64I
:
8606 case BFD_RELOC_IA64_FPTR32MSB
:
8607 case BFD_RELOC_IA64_FPTR32LSB
:
8608 case BFD_RELOC_IA64_FPTR64MSB
:
8609 case BFD_RELOC_IA64_FPTR64LSB
:
8611 case BFD_RELOC_IA64_LTOFF22
:
8612 case BFD_RELOC_IA64_LTOFF64I
:
8613 case BFD_RELOC_IA64_LTOFF_FPTR22
:
8614 case BFD_RELOC_IA64_LTOFF_FPTR64I
:
8615 case BFD_RELOC_IA64_PLTOFF22
:
8616 case BFD_RELOC_IA64_PLTOFF64I
:
8617 case BFD_RELOC_IA64_PLTOFF64MSB
:
8618 case BFD_RELOC_IA64_PLTOFF64LSB
:
8627 /* Decide from what point a pc-relative relocation is relative to,
8628 relative to the pc-relative fixup. Er, relatively speaking. */
8630 ia64_pcrel_from_section (fix
, sec
)
8634 unsigned long off
= fix
->fx_frag
->fr_address
+ fix
->fx_where
;
8636 if (bfd_get_section_flags (stdoutput
, sec
) & SEC_CODE
)
8642 /* This is called whenever some data item (not an instruction) needs a
8643 fixup. We pick the right reloc code depending on the byteorder
8644 currently in effect. */
8646 ia64_cons_fix_new (f
, where
, nbytes
, exp
)
8652 bfd_reloc_code_real_type code
;
8657 /* There are no reloc for 8 and 16 bit quantities, but we allow
8658 them here since they will work fine as long as the expression
8659 is fully defined at the end of the pass over the source file. */
8660 case 1: code
= BFD_RELOC_8
; break;
8661 case 2: code
= BFD_RELOC_16
; break;
8663 if (target_big_endian
)
8664 code
= BFD_RELOC_IA64_DIR32MSB
;
8666 code
= BFD_RELOC_IA64_DIR32LSB
;
8670 if (target_big_endian
)
8671 code
= BFD_RELOC_IA64_DIR64MSB
;
8673 code
= BFD_RELOC_IA64_DIR64LSB
;
8677 as_bad ("Unsupported fixup size %d", nbytes
);
8678 ignore_rest_of_line ();
8681 if (exp
->X_op
== O_pseudo_fixup
)
8684 exp
->X_op
= O_symbol
;
8685 code
= ia64_gen_real_reloc_type (exp
->X_op_symbol
, code
);
8687 fix
= fix_new_exp (f
, where
, nbytes
, exp
, 0, code
);
8688 /* We need to store the byte order in effect in case we're going
8689 to fix an 8 or 16 bit relocation (for which there no real
8690 relocs available). See md_apply_fix(). */
8691 fix
->tc_fix_data
.bigendian
= target_big_endian
;
8694 /* Return the actual relocation we wish to associate with the pseudo
8695 reloc described by SYM and R_TYPE. SYM should be one of the
8696 symbols in the pseudo_func array, or NULL. */
8698 static bfd_reloc_code_real_type
8699 ia64_gen_real_reloc_type (sym
, r_type
)
8701 bfd_reloc_code_real_type r_type
;
8703 bfd_reloc_code_real_type
new = 0;
8710 switch (S_GET_VALUE (sym
))
8712 case FUNC_FPTR_RELATIVE
:
8715 case BFD_RELOC_IA64_IMM64
: new = BFD_RELOC_IA64_FPTR64I
; break;
8716 case BFD_RELOC_IA64_DIR32MSB
: new = BFD_RELOC_IA64_FPTR32MSB
; break;
8717 case BFD_RELOC_IA64_DIR32LSB
: new = BFD_RELOC_IA64_FPTR32LSB
; break;
8718 case BFD_RELOC_IA64_DIR64MSB
: new = BFD_RELOC_IA64_FPTR64MSB
; break;
8719 case BFD_RELOC_IA64_DIR64LSB
: new = BFD_RELOC_IA64_FPTR64LSB
; break;
8724 case FUNC_GP_RELATIVE
:
8727 case BFD_RELOC_IA64_IMM22
: new = BFD_RELOC_IA64_GPREL22
; break;
8728 case BFD_RELOC_IA64_IMM64
: new = BFD_RELOC_IA64_GPREL64I
; break;
8729 case BFD_RELOC_IA64_DIR32MSB
: new = BFD_RELOC_IA64_GPREL32MSB
; break;
8730 case BFD_RELOC_IA64_DIR32LSB
: new = BFD_RELOC_IA64_GPREL32LSB
; break;
8731 case BFD_RELOC_IA64_DIR64MSB
: new = BFD_RELOC_IA64_GPREL64MSB
; break;
8732 case BFD_RELOC_IA64_DIR64LSB
: new = BFD_RELOC_IA64_GPREL64LSB
; break;
8737 case FUNC_LT_RELATIVE
:
8740 case BFD_RELOC_IA64_IMM22
: new = BFD_RELOC_IA64_LTOFF22
; break;
8741 case BFD_RELOC_IA64_IMM64
: new = BFD_RELOC_IA64_LTOFF64I
; break;
8746 case FUNC_PC_RELATIVE
:
8749 case BFD_RELOC_IA64_IMM22
: new = BFD_RELOC_IA64_PCREL22
; break;
8750 case BFD_RELOC_IA64_IMM64
: new = BFD_RELOC_IA64_PCREL64I
; break;
8751 case BFD_RELOC_IA64_DIR32MSB
: new = BFD_RELOC_IA64_PCREL32MSB
; break;
8752 case BFD_RELOC_IA64_DIR32LSB
: new = BFD_RELOC_IA64_PCREL32LSB
; break;
8753 case BFD_RELOC_IA64_DIR64MSB
: new = BFD_RELOC_IA64_PCREL64MSB
; break;
8754 case BFD_RELOC_IA64_DIR64LSB
: new = BFD_RELOC_IA64_PCREL64LSB
; break;
8759 case FUNC_PLT_RELATIVE
:
8762 case BFD_RELOC_IA64_IMM22
: new = BFD_RELOC_IA64_PLTOFF22
; break;
8763 case BFD_RELOC_IA64_IMM64
: new = BFD_RELOC_IA64_PLTOFF64I
; break;
8764 case BFD_RELOC_IA64_DIR64MSB
: new = BFD_RELOC_IA64_PLTOFF64MSB
;break;
8765 case BFD_RELOC_IA64_DIR64LSB
: new = BFD_RELOC_IA64_PLTOFF64LSB
;break;
8770 case FUNC_SEC_RELATIVE
:
8773 case BFD_RELOC_IA64_DIR32MSB
: new = BFD_RELOC_IA64_SECREL32MSB
;break;
8774 case BFD_RELOC_IA64_DIR32LSB
: new = BFD_RELOC_IA64_SECREL32LSB
;break;
8775 case BFD_RELOC_IA64_DIR64MSB
: new = BFD_RELOC_IA64_SECREL64MSB
;break;
8776 case BFD_RELOC_IA64_DIR64LSB
: new = BFD_RELOC_IA64_SECREL64LSB
;break;
8781 case FUNC_SEG_RELATIVE
:
8784 case BFD_RELOC_IA64_DIR32MSB
: new = BFD_RELOC_IA64_SEGREL32MSB
;break;
8785 case BFD_RELOC_IA64_DIR32LSB
: new = BFD_RELOC_IA64_SEGREL32LSB
;break;
8786 case BFD_RELOC_IA64_DIR64MSB
: new = BFD_RELOC_IA64_SEGREL64MSB
;break;
8787 case BFD_RELOC_IA64_DIR64LSB
: new = BFD_RELOC_IA64_SEGREL64LSB
;break;
8792 case FUNC_LTV_RELATIVE
:
8795 case BFD_RELOC_IA64_DIR32MSB
: new = BFD_RELOC_IA64_LTV32MSB
; break;
8796 case BFD_RELOC_IA64_DIR32LSB
: new = BFD_RELOC_IA64_LTV32LSB
; break;
8797 case BFD_RELOC_IA64_DIR64MSB
: new = BFD_RELOC_IA64_LTV64MSB
; break;
8798 case BFD_RELOC_IA64_DIR64LSB
: new = BFD_RELOC_IA64_LTV64LSB
; break;
8803 case FUNC_LT_FPTR_RELATIVE
:
8806 case BFD_RELOC_IA64_IMM22
:
8807 new = BFD_RELOC_IA64_LTOFF_FPTR22
; break;
8808 case BFD_RELOC_IA64_IMM64
:
8809 new = BFD_RELOC_IA64_LTOFF_FPTR64I
; break;
8817 /* Hmmmm. Should this ever occur? */
8824 /* Here is where generate the appropriate reloc for pseudo relocation
8827 ia64_validate_fix (fix
)
8830 switch (fix
->fx_r_type
)
8832 case BFD_RELOC_IA64_FPTR64I
:
8833 case BFD_RELOC_IA64_FPTR32MSB
:
8834 case BFD_RELOC_IA64_FPTR64LSB
:
8835 case BFD_RELOC_IA64_LTOFF_FPTR22
:
8836 case BFD_RELOC_IA64_LTOFF_FPTR64I
:
8837 if (fix
->fx_offset
!= 0)
8838 as_bad_where (fix
->fx_file
, fix
->fx_line
,
8839 "No addend allowed in @fptr() relocation");
8849 fix_insn (fix
, odesc
, value
)
8851 const struct ia64_operand
*odesc
;
8854 bfd_vma insn
[3], t0
, t1
, control_bits
;
8859 slot
= fix
->fx_where
& 0x3;
8860 fixpos
= fix
->fx_frag
->fr_literal
+ (fix
->fx_where
- slot
);
8862 /* Bundles are always in little-endian byte order */
8863 t0
= bfd_getl64 (fixpos
);
8864 t1
= bfd_getl64 (fixpos
+ 8);
8865 control_bits
= t0
& 0x1f;
8866 insn
[0] = (t0
>> 5) & 0x1ffffffffffLL
;
8867 insn
[1] = ((t0
>> 46) & 0x3ffff) | ((t1
& 0x7fffff) << 18);
8868 insn
[2] = (t1
>> 23) & 0x1ffffffffffLL
;
8871 if (odesc
- elf64_ia64_operands
== IA64_OPND_IMMU64
)
8873 insn
[1] = (value
>> 22) & 0x1ffffffffffLL
;
8874 insn
[2] |= (((value
& 0x7f) << 13)
8875 | (((value
>> 7) & 0x1ff) << 27)
8876 | (((value
>> 16) & 0x1f) << 22)
8877 | (((value
>> 21) & 0x1) << 21)
8878 | (((value
>> 63) & 0x1) << 36));
8880 else if (odesc
- elf64_ia64_operands
== IA64_OPND_IMMU62
)
8882 if (value
& ~0x3fffffffffffffffULL
)
8883 err
= "integer operand out of range";
8884 insn
[1] = (value
>> 21) & 0x1ffffffffffLL
;
8885 insn
[2] |= (((value
& 0xfffff) << 6) | (((value
>> 20) & 0x1) << 36));
8887 else if (odesc
- elf64_ia64_operands
== IA64_OPND_TGT64
)
8890 insn
[1] = ((value
>> 20) & 0x7fffffffffLL
) << 2;
8891 insn
[2] |= ((((value
>> 59) & 0x1) << 36)
8892 | (((value
>> 0) & 0xfffff) << 13));
8895 err
= (*odesc
->insert
) (odesc
, value
, insn
+ slot
);
8898 as_bad_where (fix
->fx_file
, fix
->fx_line
, err
);
8900 t0
= control_bits
| (insn
[0] << 5) | (insn
[1] << 46);
8901 t1
= ((insn
[1] >> 18) & 0x7fffff) | (insn
[2] << 23);
8902 md_number_to_chars (fixpos
+ 0, t0
, 8);
8903 md_number_to_chars (fixpos
+ 8, t1
, 8);
8906 /* Attempt to simplify or even eliminate a fixup. The return value is
8907 ignored; perhaps it was once meaningful, but now it is historical.
8908 To indicate that a fixup has been eliminated, set FIXP->FX_DONE.
8910 If fixp->fx_addsy is non-NULL, we'll have to generate a reloc entry
8913 md_apply_fix3 (fix
, valuep
, seg
)
8919 valueT value
= *valuep
;
8922 fixpos
= fix
->fx_frag
->fr_literal
+ fix
->fx_where
;
8926 switch (fix
->fx_r_type
)
8928 case BFD_RELOC_IA64_DIR32MSB
:
8929 fix
->fx_r_type
= BFD_RELOC_IA64_PCREL32MSB
;
8933 case BFD_RELOC_IA64_DIR32LSB
:
8934 fix
->fx_r_type
= BFD_RELOC_IA64_PCREL32LSB
;
8938 case BFD_RELOC_IA64_DIR64MSB
:
8939 fix
->fx_r_type
= BFD_RELOC_IA64_PCREL64MSB
;
8943 case BFD_RELOC_IA64_DIR64LSB
:
8944 fix
->fx_r_type
= BFD_RELOC_IA64_PCREL64LSB
;
8954 switch (fix
->fx_r_type
)
8957 as_bad_where (fix
->fx_file
, fix
->fx_line
,
8958 "%s must have a constant value",
8959 elf64_ia64_operands
[fix
->tc_fix_data
.opnd
].desc
);
8966 /* ??? This is a hack copied from tc-i386.c to make PCREL relocs
8967 work. There should be a better way to handle this. */
8969 fix
->fx_offset
+= fix
->fx_where
+ fix
->fx_frag
->fr_address
;
8971 else if (fix
->tc_fix_data
.opnd
== IA64_OPND_NIL
)
8973 if (fix
->tc_fix_data
.bigendian
)
8974 number_to_chars_bigendian (fixpos
, value
, fix
->fx_size
);
8976 number_to_chars_littleendian (fixpos
, value
, fix
->fx_size
);
8982 fix_insn (fix
, elf64_ia64_operands
+ fix
->tc_fix_data
.opnd
, value
);
8989 /* Generate the BFD reloc to be stuck in the object file from the
8990 fixup used internally in the assembler. */
8992 tc_gen_reloc (sec
, fixp
)
8998 reloc
= xmalloc (sizeof (*reloc
));
8999 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
9000 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
9001 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
9002 reloc
->addend
= fixp
->fx_offset
;
9003 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
9007 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
9008 "Cannot represent %s relocation in object file",
9009 bfd_get_reloc_code_name (fixp
->fx_r_type
));
9014 /* Turn a string in input_line_pointer into a floating point constant
9015 of type type, and store the appropriate bytes in *lit. The number
9016 of LITTLENUMS emitted is stored in *size. An error message is
9017 returned, or NULL on OK. */
9019 #define MAX_LITTLENUMS 5
9022 md_atof (type
, lit
, size
)
9027 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
9028 LITTLENUM_TYPE
*word
;
9058 return "Bad call to MD_ATOF()";
9060 t
= atof_ieee (input_line_pointer
, type
, words
);
9062 input_line_pointer
= t
;
9063 *size
= prec
* sizeof (LITTLENUM_TYPE
);
9065 for (word
= words
+ prec
- 1; prec
--;)
9067 md_number_to_chars (lit
, (long) (*word
--), sizeof (LITTLENUM_TYPE
));
9068 lit
+= sizeof (LITTLENUM_TYPE
);
9073 /* Round up a section's size to the appropriate boundary. */
9075 md_section_align (seg
, size
)
9079 int align
= bfd_get_section_alignment (stdoutput
, seg
);
9080 valueT mask
= ((valueT
)1 << align
) - 1;
9082 return (size
+ mask
) & ~mask
;
9085 /* Handle ia64 specific semantics of the align directive. */
9088 ia64_md_do_align (n
, fill
, len
, max
)
9094 /* Fill any pending bundle with nops. */
9095 if (bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
)
9096 ia64_flush_insns ();
9098 /* When we align code in a text section, emit a bundle of 3 nops instead of
9099 zero bytes. We can only do this if a multiple of 16 bytes was requested.
9100 N is log base 2 of the requested alignment. */
9102 && bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
9105 /* Use mfi bundle of nops with no stop bits. */
9106 static const unsigned char be_nop
[]
9107 = { 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
9108 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c};
9109 static const unsigned char le_nop
[]
9110 = { 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
9111 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00};
9113 /* Make sure we are on a 16-byte boundary, in case someone has been
9114 putting data into a text section. */
9115 frag_align (4, 0, 0);
9117 if (target_big_endian
)
9118 frag_align_pattern (n
, be_nop
, 16, max
);
9120 frag_align_pattern (n
, le_nop
, 16, max
);