1 /* tc-ia64.c -- Assembler for the HP/Intel IA-64 architecture.
2 Copyright (C) 1998, 1999 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. */
37 - labels are wrong if automatic alignment is introduced
38 (e.g., checkout the second real10 definition in test-data.s)
40 <reg>.safe_across_calls and any other DV-related directives I don't
41 have documentation for.
42 verify mod-sched-brs reads/writes are checked/marked (and other
48 #include "dwarf2dbg.h"
51 #include "opcode/ia64.h"
55 #define NELEMS(a) ((int) (sizeof (a)/sizeof ((a)[0])))
56 #define MIN(a,b) ((a) < (b) ? (a) : (b))
59 #define PREV_SLOT md.slot[(md.curr_slot + NUM_SLOTS - 1) % NUM_SLOTS]
60 #define CURR_SLOT md.slot[md.curr_slot]
62 #define O_pseudo_fixup (O_max + 1)
66 SPECIAL_SECTION_BSS
= 0,
68 SPECIAL_SECTION_SDATA
,
69 SPECIAL_SECTION_RODATA
,
70 SPECIAL_SECTION_COMMENT
,
71 SPECIAL_SECTION_UNWIND
,
72 SPECIAL_SECTION_UNWIND_INFO
84 FUNC_LT_FPTR_RELATIVE
,
90 REG_FR
= (REG_GR
+ 128),
91 REG_AR
= (REG_FR
+ 128),
92 REG_CR
= (REG_AR
+ 128),
93 REG_P
= (REG_CR
+ 128),
94 REG_BR
= (REG_P
+ 64),
95 REG_IP
= (REG_BR
+ 8),
102 /* The following are pseudo-registers for use by gas only. */
119 DYNREG_GR
= 0, /* dynamic general purpose register */
120 DYNREG_FR
, /* dynamic floating point register */
121 DYNREG_PR
, /* dynamic predicate register */
125 /* On the ia64, we can't know the address of a text label until the
126 instructions are packed into a bundle. To handle this, we keep
127 track of the list of labels that appear in front of each
131 struct label_fix
*next
;
135 extern int target_big_endian
;
137 /* Characters which always start a comment. */
138 const char comment_chars
[] = "";
140 /* Characters which start a comment at the beginning of a line. */
141 const char line_comment_chars
[] = "#";
143 /* Characters which may be used to separate multiple commands on a
145 const char line_separator_chars
[] = ";";
147 /* Characters which are used to indicate an exponent in a floating
149 const char EXP_CHARS
[] = "eE";
151 /* Characters which mean that a number is a floating point constant,
153 const char FLT_CHARS
[] = "rRsSfFdDxXpP";
155 /* ia64-specific option processing: */
157 const char *md_shortopts
= "M:N:x::";
159 struct option md_longopts
[] =
161 { NULL
, no_argument
, NULL
, 0}
164 size_t md_longopts_size
= sizeof (md_longopts
);
168 struct hash_control
*pseudo_hash
; /* pseudo opcode hash table */
169 struct hash_control
*reg_hash
; /* register name hash table */
170 struct hash_control
*dynreg_hash
; /* dynamic register hash table */
171 struct hash_control
*const_hash
; /* constant hash table */
172 struct hash_control
*entry_hash
; /* code entry hint hash table */
174 symbolS
*regsym
[REG_NUM
];
176 /* If X_op is != O_absent, the registername for the instruction's
177 qualifying predicate. If NULL, p0 is assumed for instructions
178 that are predicatable. */
185 explicit_mode
: 1, /* which mode we're in */
186 default_explicit_mode
: 1, /* which mode is the default */
187 mode_explicitly_set
: 1, /* was the current mode explicitly set? */
190 /* Each bundle consists of up to three instructions. We keep
191 track of four most recent instructions so we can correctly set
192 the end_of_insn_group for the last instruction in a bundle. */
194 int num_slots_in_use
;
198 end_of_insn_group
: 1,
199 manual_bundling_on
: 1,
200 manual_bundling_off
: 1;
201 signed char user_template
; /* user-selected template, if any */
202 unsigned char qp_regno
; /* qualifying predicate */
203 /* This duplicates a good fraction of "struct fix" but we
204 can't use a "struct fix" instead since we can't call
205 fix_new_exp() until we know the address of the instruction. */
209 bfd_reloc_code_real_type code
;
210 enum ia64_opnd opnd
; /* type of operand in need of fix */
211 unsigned int is_pcrel
: 1; /* is operand pc-relative? */
212 expressionS expr
; /* the value to be inserted */
214 fixup
[2]; /* at most two fixups per insn */
215 struct ia64_opcode
*idesc
;
216 struct label_fix
*label_fixups
;
217 struct unw_rec_list
*unwind_record
; /* Unwind directive. */
220 unsigned int src_line
;
221 struct dwarf2_line_info debug_line
;
229 struct dynreg
*next
; /* next dynamic register */
231 unsigned short base
; /* the base register number */
232 unsigned short num_regs
; /* # of registers in this set */
234 *dynreg
[DYNREG_NUM_TYPES
], in
, loc
, out
, rot
;
236 flagword flags
; /* ELF-header flags */
239 unsigned hint
:1; /* is this hint currently valid? */
240 bfd_vma offset
; /* mem.offset offset */
241 bfd_vma base
; /* mem.offset base */
244 int path
; /* number of alt. entry points seen */
245 const char **entry_labels
; /* labels of all alternate paths in
246 the current DV-checking block. */
247 int maxpaths
; /* size currently allocated for
252 /* application registers: */
258 #define AR_BSPSTORE 18
271 {"ar.k0", 0}, {"ar.k1", 1}, {"ar.k2", 2}, {"ar.k3", 3},
272 {"ar.k4", 4}, {"ar.k5", 5}, {"ar.k6", 6}, {"ar.k7", 7},
273 {"ar.rsc", 16}, {"ar.bsp", 17},
274 {"ar.bspstore", 18}, {"ar.rnat", 19},
275 {"ar.fcr", 21}, {"ar.eflag", 24},
276 {"ar.csd", 25}, {"ar.ssd", 26},
277 {"ar.cflg", 27}, {"ar.fsr", 28},
278 {"ar.fir", 29}, {"ar.fdr", 30},
279 {"ar.ccv", 32}, {"ar.unat", 36},
280 {"ar.fpsr", 40}, {"ar.itc", 44},
281 {"ar.pfs", 64}, {"ar.lc", 65},
302 /* control registers: */
344 static const struct const_desc
351 /* PSR constant masks: */
354 {"psr.be", ((valueT
) 1) << 1},
355 {"psr.up", ((valueT
) 1) << 2},
356 {"psr.ac", ((valueT
) 1) << 3},
357 {"psr.mfl", ((valueT
) 1) << 4},
358 {"psr.mfh", ((valueT
) 1) << 5},
360 {"psr.ic", ((valueT
) 1) << 13},
361 {"psr.i", ((valueT
) 1) << 14},
362 {"psr.pk", ((valueT
) 1) << 15},
364 {"psr.dt", ((valueT
) 1) << 17},
365 {"psr.dfl", ((valueT
) 1) << 18},
366 {"psr.dfh", ((valueT
) 1) << 19},
367 {"psr.sp", ((valueT
) 1) << 20},
368 {"psr.pp", ((valueT
) 1) << 21},
369 {"psr.di", ((valueT
) 1) << 22},
370 {"psr.si", ((valueT
) 1) << 23},
371 {"psr.db", ((valueT
) 1) << 24},
372 {"psr.lp", ((valueT
) 1) << 25},
373 {"psr.tb", ((valueT
) 1) << 26},
374 {"psr.rt", ((valueT
) 1) << 27},
375 /* 28-31: reserved */
376 /* 32-33: cpl (current privilege level) */
377 {"psr.is", ((valueT
) 1) << 34},
378 {"psr.mc", ((valueT
) 1) << 35},
379 {"psr.it", ((valueT
) 1) << 36},
380 {"psr.id", ((valueT
) 1) << 37},
381 {"psr.da", ((valueT
) 1) << 38},
382 {"psr.dd", ((valueT
) 1) << 39},
383 {"psr.ss", ((valueT
) 1) << 40},
384 /* 41-42: ri (restart instruction) */
385 {"psr.ed", ((valueT
) 1) << 43},
386 {"psr.bn", ((valueT
) 1) << 44},
389 /* indirect register-sets/memory: */
398 { "CPUID", IND_CPUID
},
399 { "cpuid", IND_CPUID
},
411 /* Pseudo functions used to indicate relocation types (these functions
412 start with an at sign (@). */
433 /* reloc pseudo functions (these must come first!): */
434 { "fptr", PSEUDO_FUNC_RELOC
},
435 { "gprel", PSEUDO_FUNC_RELOC
},
436 { "ltoff", PSEUDO_FUNC_RELOC
},
437 { "pltoff", PSEUDO_FUNC_RELOC
},
438 { "secrel", PSEUDO_FUNC_RELOC
},
439 { "segrel", PSEUDO_FUNC_RELOC
},
440 { "ltv", PSEUDO_FUNC_RELOC
},
441 { 0, }, /* placeholder for FUNC_LT_FPTR_RELATIVE */
443 /* mbtype4 constants: */
444 { "alt", PSEUDO_FUNC_CONST
, { 0xa } },
445 { "brcst", PSEUDO_FUNC_CONST
, { 0x0 } },
446 { "mix", PSEUDO_FUNC_CONST
, { 0x8 } },
447 { "rev", PSEUDO_FUNC_CONST
, { 0xb } },
448 { "shuf", PSEUDO_FUNC_CONST
, { 0x9 } },
450 /* fclass constants: */
451 { "nat", PSEUDO_FUNC_CONST
, { 0x100 } },
452 { "qnan", PSEUDO_FUNC_CONST
, { 0x080 } },
453 { "snan", PSEUDO_FUNC_CONST
, { 0x040 } },
454 { "pos", PSEUDO_FUNC_CONST
, { 0x001 } },
455 { "neg", PSEUDO_FUNC_CONST
, { 0x002 } },
456 { "zero", PSEUDO_FUNC_CONST
, { 0x004 } },
457 { "unorm", PSEUDO_FUNC_CONST
, { 0x008 } },
458 { "norm", PSEUDO_FUNC_CONST
, { 0x010 } },
459 { "inf", PSEUDO_FUNC_CONST
, { 0x020 } },
461 { "natval", PSEUDO_FUNC_CONST
, { 0x100 } }, /* old usage */
464 /* 41-bit nop opcodes (one per unit): */
465 static const bfd_vma nop
[IA64_NUM_UNITS
] =
467 0x0000000000LL
, /* NIL => break 0 */
468 0x0008000000LL
, /* I-unit nop */
469 0x0008000000LL
, /* M-unit nop */
470 0x4000000000LL
, /* B-unit nop */
471 0x0008000000LL
, /* F-unit nop */
472 0x0008000000LL
, /* L-"unit" nop */
473 0x0008000000LL
, /* X-unit nop */
476 /* Can't be `const' as it's passed to input routines (which have the
477 habit of setting temporary sentinels. */
478 static char special_section_name
[][20] =
480 {".bss"}, {".sbss"}, {".sdata"}, {".rodata"}, {".comment"},
481 {".IA_64.unwind"}, {".IA_64.unwind_info"}
484 /* The best template for a particular sequence of up to three
486 #define N IA64_NUM_TYPES
487 static unsigned char best_template
[N
][N
][N
];
490 /* Resource dependencies currently in effect */
492 int depind
; /* dependency index */
493 const struct ia64_dependency
*dependency
; /* actual dependency */
494 unsigned specific
:1, /* is this a specific bit/regno? */
495 link_to_qp_branch
:1; /* will a branch on the same QP clear it?*/
496 int index
; /* specific regno/bit within dependency */
497 int note
; /* optional qualifying note (0 if none) */
501 int insn_srlz
; /* current insn serialization state */
502 int data_srlz
; /* current data serialization state */
503 int qp_regno
; /* qualifying predicate for this usage */
504 char *file
; /* what file marked this dependency */
505 int line
; /* what line marked this dependency */
506 struct mem_offset mem_offset
; /* optional memory offset hint */
507 int path
; /* corresponding code entry index */
509 static int regdepslen
= 0;
510 static int regdepstotlen
= 0;
511 static const char *dv_mode
[] = { "RAW", "WAW", "WAR" };
512 static const char *dv_sem
[] = { "none", "implied", "impliedf",
513 "data", "instr", "specific", "other" };
515 /* Current state of PR mutexation */
516 static struct qpmutex
{
519 } *qp_mutexes
= NULL
; /* QP mutex bitmasks */
520 static int qp_mutexeslen
= 0;
521 static int qp_mutexestotlen
= 0;
522 static valueT qp_safe_across_calls
= 0;
524 /* Current state of PR implications */
525 static struct qp_imply
{
528 unsigned p2_branched
:1;
530 } *qp_implies
= NULL
;
531 static int qp_implieslen
= 0;
532 static int qp_impliestotlen
= 0;
534 /* Keep track of static GR values so that indirect register usage can
535 sometimes be tracked. */
540 } gr_values
[128] = {{ 1, 0 }};
542 /* These are the routines required to output the various types of
545 typedef struct unw_rec_list
{
547 unsigned long slot_number
;
548 struct unw_rec_list
*next
;
551 #define SLOT_NUM_NOT_SET -1
553 /* TRUE if processing unwind directives in a prologue region. */
554 static int unwind_prologue
= 0;
556 /* Maintain a list of unwind entries for the current function. */
557 static unw_rec_list
*unwind_list
= 0;
558 static unw_rec_list
*unwind_tail
= 0;
560 /* Any unwind entires that should be attached to the current
561 slot that an insn is being constructed for. */
562 static unw_rec_list
*current_unwind_entry
= 0;
564 /* These are used to create the unwind table entry for this function. */
565 static symbolS
*proc_start
= 0;
566 static symbolS
*proc_end
= 0;
567 static symbolS
*unwind_info
= 0;
568 static symbolS
*personality_routine
= 0;
570 typedef void (*vbyte_func
) PARAMS ((int, char *, char *));
572 /* Forward delarations: */
573 static int ar_is_in_integer_unit
PARAMS ((int regnum
));
574 static void set_section
PARAMS ((char *name
));
575 static unsigned int set_regstack
PARAMS ((unsigned int, unsigned int,
576 unsigned int, unsigned int));
577 static void dot_radix
PARAMS ((int));
578 static void dot_special_section
PARAMS ((int));
579 static void dot_proc
PARAMS ((int));
580 static void dot_fframe
PARAMS ((int));
581 static void dot_vframe
PARAMS ((int));
582 static void dot_save
PARAMS ((int));
583 static void dot_restore
PARAMS ((int));
584 static void dot_handlerdata
PARAMS ((int));
585 static void dot_unwentry
PARAMS ((int));
586 static void dot_altrp
PARAMS ((int));
587 static void dot_savesp
PARAMS ((int));
588 static void dot_savepsp
PARAMS ((int));
589 static void dot_saveg
PARAMS ((int));
590 static void dot_savef
PARAMS ((int));
591 static void dot_saveb
PARAMS ((int));
592 static void dot_savegf
PARAMS ((int));
593 static void dot_spill
PARAMS ((int));
594 static void dot_unwabi
PARAMS ((int));
595 static void dot_personality
PARAMS ((int));
596 static void dot_body
PARAMS ((int));
597 static void dot_prologue
PARAMS ((int));
598 static void dot_endp
PARAMS ((int));
599 static void dot_template
PARAMS ((int));
600 static void dot_regstk
PARAMS ((int));
601 static void dot_rot
PARAMS ((int));
602 static void dot_byteorder
PARAMS ((int));
603 static void dot_psr
PARAMS ((int));
604 static void dot_alias
PARAMS ((int));
605 static void dot_ln
PARAMS ((int));
606 static char *parse_section_name
PARAMS ((void));
607 static void dot_xdata
PARAMS ((int));
608 static void stmt_float_cons
PARAMS ((int));
609 static void stmt_cons_ua
PARAMS ((int));
610 static void dot_xfloat_cons
PARAMS ((int));
611 static void dot_xstringer
PARAMS ((int));
612 static void dot_xdata_ua
PARAMS ((int));
613 static void dot_xfloat_cons_ua
PARAMS ((int));
614 static void dot_pred_rel
PARAMS ((int));
615 static void dot_reg_val
PARAMS ((int));
616 static void dot_dv_mode
PARAMS ((int));
617 static void dot_entry
PARAMS ((int));
618 static void dot_mem_offset
PARAMS ((int));
619 static symbolS
* declare_register
PARAMS ((const char *name
, int regnum
));
620 static void declare_register_set
PARAMS ((const char *, int, int));
621 static unsigned int operand_width
PARAMS ((enum ia64_opnd
));
622 static int operand_match
PARAMS ((const struct ia64_opcode
*idesc
,
623 int index
, expressionS
*e
));
624 static int parse_operand
PARAMS ((expressionS
*e
));
625 static struct ia64_opcode
* parse_operands
PARAMS ((struct ia64_opcode
*));
626 static void build_insn
PARAMS ((struct slot
*, bfd_vma
*));
627 static void emit_one_bundle
PARAMS ((void));
628 static void fix_insn
PARAMS ((fixS
*, const struct ia64_operand
*, valueT
));
629 static bfd_reloc_code_real_type ia64_gen_real_reloc_type
PARAMS ((struct symbol
*sym
,
630 bfd_reloc_code_real_type r_type
));
631 static void insn_group_break
PARAMS ((int, int, int));
632 static void add_qp_mutex
PARAMS((valueT mask
));
633 static void add_qp_imply
PARAMS((int p1
, int p2
));
634 static void clear_qp_branch_flag
PARAMS((valueT mask
));
635 static void clear_qp_mutex
PARAMS((valueT mask
));
636 static void clear_qp_implies
PARAMS((valueT p1_mask
, valueT p2_mask
));
637 static void clear_register_values
PARAMS ((void));
638 static void print_dependency
PARAMS ((const char *action
, int depind
));
639 static int is_conditional_branch
PARAMS ((struct ia64_opcode
*));
640 static int is_interruption_or_rfi
PARAMS ((struct ia64_opcode
*));
641 static int check_dv
PARAMS((struct ia64_opcode
*idesc
));
642 static void check_dependencies
PARAMS((struct ia64_opcode
*));
643 static void mark_resources
PARAMS((struct ia64_opcode
*));
644 static void update_dependencies
PARAMS((struct ia64_opcode
*));
645 static void note_register_values
PARAMS((struct ia64_opcode
*));
646 static void output_R3_format
PARAMS ((vbyte_func
, unw_record_type
, unsigned long));
647 static void output_B3_format
PARAMS ((vbyte_func
, unsigned long, unsigned long));
648 static void output_B4_format
PARAMS ((vbyte_func
, unw_record_type
, unsigned long));
650 /* Determine if application register REGNUM resides in the integer
651 unit (as opposed to the memory unit). */
653 ar_is_in_integer_unit (reg
)
658 return (reg
== 64 /* pfs */
659 || reg
== 65 /* lc */
660 || reg
== 66 /* ec */
661 /* ??? ias accepts and puts these in the integer unit. */
662 || (reg
>= 112 && reg
<= 127));
665 /* Switch to section NAME and create section if necessary. It's
666 rather ugly that we have to manipulate input_line_pointer but I
667 don't see any other way to accomplish the same thing without
668 changing obj-elf.c (which may be the Right Thing, in the end). */
673 char *saved_input_line_pointer
;
675 saved_input_line_pointer
= input_line_pointer
;
676 input_line_pointer
= name
;
678 input_line_pointer
= saved_input_line_pointer
;
681 /* Map SHF_IA_64_SHORT to SEC_SMALL_DATA. */
684 ia64_elf_section_flags (flags
, attr
, type
)
688 if (attr
& SHF_IA_64_SHORT
)
689 flags
|= SEC_SMALL_DATA
;
694 set_regstack (ins
, locs
, outs
, rots
)
695 unsigned int ins
, locs
, outs
, rots
;
697 unsigned int sof
; /* size of frame */
699 sof
= ins
+ locs
+ outs
;
702 as_bad ("Size of frame exceeds maximum of 96 registers");
707 as_warn ("Size of rotating registers exceeds frame size");
710 md
.in
.base
= REG_GR
+ 32;
711 md
.loc
.base
= md
.in
.base
+ ins
;
712 md
.out
.base
= md
.loc
.base
+ locs
;
714 md
.in
.num_regs
= ins
;
715 md
.loc
.num_regs
= locs
;
716 md
.out
.num_regs
= outs
;
717 md
.rot
.num_regs
= rots
;
724 struct label_fix
*lfix
;
726 subsegT saved_subseg
;
728 if (!md
.last_text_seg
)
732 saved_subseg
= now_subseg
;
734 subseg_set (md
.last_text_seg
, 0);
736 while (md
.num_slots_in_use
> 0)
737 emit_one_bundle (); /* force out queued instructions */
739 /* In case there are labels following the last instruction, resolve
741 for (lfix
= CURR_SLOT
.label_fixups
; lfix
; lfix
= lfix
->next
)
743 S_SET_VALUE (lfix
->sym
, frag_now_fix ());
744 symbol_set_frag (lfix
->sym
, frag_now
);
746 CURR_SLOT
.label_fixups
= 0;
748 subseg_set (saved_seg
, saved_subseg
);
752 ia64_do_align (nbytes
)
755 char *saved_input_line_pointer
= input_line_pointer
;
757 input_line_pointer
= "";
758 s_align_bytes (nbytes
);
759 input_line_pointer
= saved_input_line_pointer
;
763 ia64_cons_align (nbytes
)
768 char *saved_input_line_pointer
= input_line_pointer
;
769 input_line_pointer
= "";
770 s_align_bytes (nbytes
);
771 input_line_pointer
= saved_input_line_pointer
;
775 /* Output COUNT bytes to a memory location. */
776 static unsigned char *vbyte_mem_ptr
= NULL
;
779 output_vbyte_mem (count
, ptr
, comment
)
785 if (vbyte_mem_ptr
== NULL
)
790 for (x
= 0; x
< count
; x
++)
791 *(vbyte_mem_ptr
++) = ptr
[x
];
794 /* Count the number of bytes required for records. */
795 static int vbyte_count
= 0;
797 count_output (count
, ptr
, comment
)
802 vbyte_count
+= count
;
806 output_R1_format (f
, rtype
, rlen
)
808 unw_record_type rtype
;
815 output_R3_format (f
, rtype
, rlen
);
818 if (rtype
== prologue
)
824 as_bad ("record type is not valid");
826 byte
= UNW_R1
| (r
<< 5) | (rlen
& 0x1f);
827 (*f
) (1, &byte
, NULL
);
831 output_R2_format (f
, mask
, grsave
, rlen
)
838 mask
= (mask
& 0x0f);
839 grsave
= (grsave
& 0x7f);
841 bytes
[0] = (UNW_R2
| (mask
>> 1));
842 bytes
[1] = (((mask
& 0x01) << 7) | grsave
);
843 count
+= output_leb128 (bytes
+ 2, rlen
, 0);
844 (*f
) (count
, bytes
, NULL
);
848 output_R3_format (f
, rtype
, rlen
)
850 unw_record_type rtype
;
857 output_R1_format (f
, rtype
, rlen
);
860 if (rtype
== prologue
)
866 as_bad ("record type is not valid");
867 bytes
[0] = (UNW_R3
| r
);
868 count
= output_leb128 (bytes
+ 1, rlen
, 0);
869 (*f
) (count
+ 1, bytes
, NULL
);
873 output_P1_format (f
, brmask
)
878 byte
= UNW_P1
| (brmask
& 0x1f);
879 (*f
) (1, &byte
, NULL
);
883 output_P2_format (f
, brmask
, gr
)
889 brmask
= (brmask
& 0x1f);
890 bytes
[0] = UNW_P2
| (brmask
>> 1);
891 bytes
[1] = (((brmask
& 1) << 7) | gr
);
892 (*f
) (2, bytes
, NULL
);
896 output_P3_format (f
, rtype
, reg
)
898 unw_record_type rtype
;
943 as_bad ("Invalid record type for P3 format.");
945 bytes
[0] = (UNW_P3
| (r
>> 1));
946 bytes
[1] = (((r
& 1) << 7) | reg
);
947 (*f
) (2, bytes
, NULL
);
952 output_P4_format (f
, count
, imask
)
958 bytes
= alloca (count
+ 1);
960 memcpy (bytes
+ 1, imask
, count
);
961 (*f
) (count
+ 1, bytes
, NULL
);
965 output_P5_format (f
, grmask
, frmask
)
968 unsigned long frmask
;
971 grmask
= (grmask
& 0x0f);
974 bytes
[1] = ((grmask
<< 4) | ((frmask
& 0x000f0000) >> 16));
975 bytes
[2] = ((frmask
& 0x0000ff00) >> 8);
976 bytes
[3] = (frmask
& 0x000000ff);
977 (*f
) (4, bytes
, NULL
);
981 output_P6_format (f
, rtype
, rmask
)
983 unw_record_type rtype
;
994 as_bad ("Invalid record type for format P6");
995 byte
= (UNW_P6
| (r
<< 4) | (rmask
& 0x0f));
996 (*f
) (1, &byte
, NULL
);
1000 output_P7_format (f
, rtype
, w1
, w2
)
1002 unw_record_type rtype
;
1009 count
+= output_leb128 (bytes
+ 1, w1
, 0);
1014 count
+= output_leb128 (bytes
+ count
, w2
, 0);
1062 bytes
[0] = (UNW_P7
| r
);
1063 (*f
) (count
, bytes
, NULL
);
1067 output_P8_format (f
, rtype
, t
)
1069 unw_record_type rtype
;
1108 case bspstore_psprel
:
1111 case bspstore_sprel
:
1123 case priunat_when_gr
:
1126 case priunat_psprel
:
1132 case priunat_when_mem
:
1137 count
+= output_leb128 (bytes
+ 2, t
, 0);
1138 (*f
) (count
, bytes
, NULL
);
1142 output_P9_format (f
, grmask
, gr
)
1149 bytes
[1] = (grmask
& 0x0f);
1150 bytes
[2] = (gr
& 0x7f);
1151 (*f
) (3, bytes
, NULL
);
1155 output_P10_format (f
, abi
, context
)
1162 bytes
[1] = (abi
& 0xff);
1163 bytes
[2] = (context
& 0xff);
1164 (*f
) (3, bytes
, NULL
);
1168 output_B1_format (f
, rtype
, label
)
1170 unw_record_type rtype
;
1171 unsigned long label
;
1177 output_B4_format (f
, rtype
, label
);
1180 if (rtype
== label_state
)
1183 if (rtype
== copy_state
)
1186 as_bad ("Invalid record type for format B1");
1188 byte
= (UNW_B1
| (r
<< 5) | (label
& 0x1f));
1189 (*f
) (1, &byte
, NULL
);
1193 output_B2_format (f
, ecount
, t
)
1195 unsigned long ecount
;
1202 output_B3_format (f
, ecount
, t
);
1205 bytes
[0] = (UNW_B2
| (ecount
& 0x1f));
1206 count
+= output_leb128 (bytes
+ 1, t
, 0);
1207 (*f
) (count
, bytes
, NULL
);
1211 output_B3_format (f
, ecount
, t
)
1213 unsigned long ecount
;
1220 output_B2_format (f
, ecount
, t
);
1224 count
+= output_leb128 (bytes
+ 1, t
, 0);
1225 count
+= output_leb128 (bytes
+ count
, ecount
, 0);
1226 (*f
) (count
, bytes
, NULL
);
1230 output_B4_format (f
, rtype
, label
)
1232 unw_record_type rtype
;
1233 unsigned long label
;
1240 output_B1_format (f
, rtype
, label
);
1243 if (rtype
== label_state
)
1246 if (rtype
== copy_state
)
1249 as_bad ("Invalid record type for format B1");
1251 bytes
[0] = (UNW_B4
| (r
<< 3));
1252 count
+= output_leb128 (bytes
+ 1, label
, 0);
1253 (*f
) (count
, bytes
, NULL
);
1257 format_a_b_reg (a
, b
, reg
)
1265 ret
= (a
<< 6) | (a
<< 5) | reg
;
1270 output_X1_format (f
, rtype
, a
, b
, reg
, t
, w1
)
1272 unw_record_type rtype
;
1281 if (rtype
== spill_psprel
)
1284 if (rtype
= spill_sprel
)
1287 as_bad ("Invalid record type for format X1");
1288 bytes
[1] = ((r
<< 7) | format_a_b_reg (a
, b
, reg
));
1289 count
+= output_leb128 (bytes
+ 2, t
, 0);
1290 count
+= output_leb128 (bytes
+ count
, w1
, 0);
1291 (*f
) (count
, bytes
, NULL
);
1295 output_X2_format (f
, a
, b
, reg
, x
, y
, treg
, t
)
1305 bytes
[1] = (((x
& 1) << 7) | format_a_b_reg (a
, b
, reg
));
1306 bytes
[2] = (((y
& 1) << 7) | (treg
& 0x7f));
1307 count
+= output_leb128 (bytes
+ 3, t
, 0);
1308 (*f
) (count
, bytes
, NULL
);
1312 output_X3_format (f
, rtype
, qp
, a
, b
, reg
, t
, w1
)
1314 unw_record_type rtype
;
1324 if (rtype
== spill_psprel_p
)
1327 if (rtype
= spill_sprel_p
)
1330 as_bad ("Invalid record type for format X1");
1331 bytes
[1] = ((r
<< 7) | (qp
& 0x3f));
1332 bytes
[2] = format_a_b_reg (a
, b
, reg
);
1333 count
+= output_leb128 (bytes
+ 3, t
, 0);
1334 count
+= output_leb128 (bytes
+ count
, w1
, 0);
1335 (*f
) (count
, bytes
, NULL
);
1339 output_X4_format (f
, qp
, a
, b
, reg
, x
, y
, treg
, t
)
1350 bytes
[1] = (qp
& 0x3f);
1351 bytes
[2] = (((x
& 1) << 7) | format_a_b_reg (a
, b
, reg
));
1352 bytes
[3] = (((y
& 1) << 7) | (treg
& 0x7f));
1353 count
+= output_leb128 (bytes
+ 4, t
, 0);
1354 (*f
) (count
, bytes
, NULL
);
1357 /* This function allocates a record list structure, and initializes fields. */
1358 static unw_rec_list
*
1359 alloc_record (unw_record_type t
)
1362 ptr
= xmalloc (sizeof (*ptr
));
1364 ptr
->slot_number
= SLOT_NUM_NOT_SET
;
1369 /* This function frees a record list structure. */
1371 free_record (unw_rec_list
*ptr
)
1376 /* This function frees an entire list of record structures. */
1378 free_list_records (unw_rec_list
*first
)
1381 for (ptr
= first
; ptr
!= NULL
; )
1383 unw_rec_list
*tmp
= ptr
;
1389 static unw_rec_list
*
1392 unw_rec_list
*ptr
= alloc_record (prologue
);
1396 static unw_rec_list
*
1397 output_prologue_gr (saved_mask
, reg
)
1398 unsigned int saved_mask
;
1401 unw_rec_list
*ptr
= alloc_record (prologue_gr
);
1402 ptr
->r
.record
.r
.mask
= saved_mask
;
1403 ptr
->r
.record
.r
.grsave
= reg
;
1407 static unw_rec_list
*
1410 unw_rec_list
*ptr
= alloc_record (body
);
1414 static unw_rec_list
*
1415 output_mem_stack_f (size
)
1418 unw_rec_list
*ptr
= alloc_record (mem_stack_f
);
1419 ptr
->r
.record
.p
.size
= size
;
1423 static unw_rec_list
*
1424 output_mem_stack_v ()
1426 unw_rec_list
*ptr
= alloc_record (mem_stack_v
);
1430 static unw_rec_list
*
1434 unw_rec_list
*ptr
= alloc_record (psp_gr
);
1435 ptr
->r
.record
.p
.gr
= gr
;
1439 static unw_rec_list
*
1440 output_psp_sprel (offset
)
1441 unsigned int offset
;
1443 unw_rec_list
*ptr
= alloc_record (psp_sprel
);
1444 ptr
->r
.record
.p
.spoff
= offset
;
1448 static unw_rec_list
*
1451 unw_rec_list
*ptr
= alloc_record (rp_when
);
1455 static unw_rec_list
*
1459 unw_rec_list
*ptr
= alloc_record (rp_gr
);
1460 ptr
->r
.record
.p
.gr
= gr
;
1464 static unw_rec_list
*
1468 unw_rec_list
*ptr
= alloc_record (rp_br
);
1469 ptr
->r
.record
.p
.br
= br
;
1473 static unw_rec_list
*
1474 output_rp_psprel (offset
)
1475 unsigned int offset
;
1477 unw_rec_list
*ptr
= alloc_record (rp_psprel
);
1478 ptr
->r
.record
.p
.pspoff
= offset
;
1482 static unw_rec_list
*
1483 output_rp_sprel (offset
)
1484 unsigned int offset
;
1486 unw_rec_list
*ptr
= alloc_record (rp_sprel
);
1487 ptr
->r
.record
.p
.spoff
= offset
;
1491 static unw_rec_list
*
1494 unw_rec_list
*ptr
= alloc_record (pfs_when
);
1498 static unw_rec_list
*
1502 unw_rec_list
*ptr
= alloc_record (pfs_gr
);
1503 ptr
->r
.record
.p
.gr
= gr
;
1507 static unw_rec_list
*
1508 output_pfs_psprel (offset
)
1509 unsigned int offset
;
1511 unw_rec_list
*ptr
= alloc_record (pfs_psprel
);
1512 ptr
->r
.record
.p
.pspoff
= offset
;
1516 static unw_rec_list
*
1517 output_pfs_sprel (offset
)
1518 unsigned int offset
;
1520 unw_rec_list
*ptr
= alloc_record (pfs_sprel
);
1521 ptr
->r
.record
.p
.spoff
= offset
;
1525 static unw_rec_list
*
1526 output_preds_when ()
1528 unw_rec_list
*ptr
= alloc_record (preds_when
);
1532 static unw_rec_list
*
1533 output_preds_gr (gr
)
1536 unw_rec_list
*ptr
= alloc_record (preds_gr
);
1537 ptr
->r
.record
.p
.gr
= gr
;
1541 static unw_rec_list
*
1542 output_preds_psprel (offset
)
1543 unsigned int offset
;
1545 unw_rec_list
*ptr
= alloc_record (preds_psprel
);
1546 ptr
->r
.record
.p
.pspoff
= offset
;
1550 static unw_rec_list
*
1551 output_preds_sprel (offset
)
1552 unsigned int offset
;
1554 unw_rec_list
*ptr
= alloc_record (preds_sprel
);
1555 ptr
->r
.record
.p
.spoff
= offset
;
1559 static unw_rec_list
*
1560 output_fr_mem (mask
)
1563 unw_rec_list
*ptr
= alloc_record (fr_mem
);
1564 ptr
->r
.record
.p
.rmask
= mask
;
1568 static unw_rec_list
*
1569 output_frgr_mem (gr_mask
, fr_mask
)
1570 unsigned int gr_mask
;
1571 unsigned int fr_mask
;
1573 unw_rec_list
*ptr
= alloc_record (frgr_mem
);
1574 ptr
->r
.record
.p
.grmask
= gr_mask
;
1575 ptr
->r
.record
.p
.frmask
= fr_mask
;
1579 static unw_rec_list
*
1580 output_gr_gr (mask
, reg
)
1584 unw_rec_list
*ptr
= alloc_record (gr_gr
);
1585 ptr
->r
.record
.p
.grmask
= mask
;
1586 ptr
->r
.record
.p
.gr
= reg
;
1590 static unw_rec_list
*
1591 output_gr_mem (mask
)
1594 unw_rec_list
*ptr
= alloc_record (gr_mem
);
1595 ptr
->r
.record
.p
.rmask
= mask
;
1599 static unw_rec_list
*
1600 output_br_mem (unsigned int mask
)
1602 unw_rec_list
*ptr
= alloc_record (br_mem
);
1603 ptr
->r
.record
.p
.brmask
= mask
;
1607 static unw_rec_list
*
1608 output_br_gr (save_mask
, reg
)
1609 unsigned int save_mask
;
1612 unw_rec_list
*ptr
= alloc_record (br_gr
);
1613 ptr
->r
.record
.p
.brmask
= save_mask
;
1614 ptr
->r
.record
.p
.gr
= reg
;
1618 static unw_rec_list
*
1619 output_spill_base (offset
)
1620 unsigned int offset
;
1622 unw_rec_list
*ptr
= alloc_record (spill_base
);
1623 ptr
->r
.record
.p
.pspoff
= offset
;
1627 static unw_rec_list
*
1628 output_spill_mask ()
1630 /* TODO - how to implement this record.... I guess GAS could fill in the
1631 correct fields from the record list and construct one of these
1632 after the symbols have been resolved and we know how big the
1633 region is. This could be done in fixup_unw_records. */
1634 unw_rec_list
*ptr
= NULL
;
1638 static unw_rec_list
*
1641 unw_rec_list
*ptr
= alloc_record (unat_when
);
1645 static unw_rec_list
*
1649 unw_rec_list
*ptr
= alloc_record (unat_gr
);
1650 ptr
->r
.record
.p
.gr
= gr
;
1654 static unw_rec_list
*
1655 output_unat_psprel (offset
)
1656 unsigned int offset
;
1658 unw_rec_list
*ptr
= alloc_record (unat_psprel
);
1659 ptr
->r
.record
.p
.pspoff
= offset
;
1663 static unw_rec_list
*
1664 output_unat_sprel (offset
)
1665 unsigned int offset
;
1667 unw_rec_list
*ptr
= alloc_record (unat_sprel
);
1668 ptr
->r
.record
.p
.spoff
= offset
;
1672 static unw_rec_list
*
1675 unw_rec_list
*ptr
= alloc_record (lc_when
);
1679 static unw_rec_list
*
1683 unw_rec_list
*ptr
= alloc_record (lc_gr
);
1684 ptr
->r
.record
.p
.gr
= gr
;
1688 static unw_rec_list
*
1689 output_lc_psprel (offset
)
1690 unsigned int offset
;
1692 unw_rec_list
*ptr
= alloc_record (lc_psprel
);
1693 ptr
->r
.record
.p
.pspoff
= offset
;
1697 static unw_rec_list
*
1698 output_lc_sprel (offset
)
1699 unsigned int offset
;
1701 unw_rec_list
*ptr
= alloc_record (lc_sprel
);
1702 ptr
->r
.record
.p
.spoff
= offset
;
1706 static unw_rec_list
*
1709 unw_rec_list
*ptr
= alloc_record (fpsr_when
);
1713 static unw_rec_list
*
1717 unw_rec_list
*ptr
= alloc_record (fpsr_gr
);
1718 ptr
->r
.record
.p
.gr
= gr
;
1722 static unw_rec_list
*
1723 output_fpsr_psprel (offset
)
1724 unsigned int offset
;
1726 unw_rec_list
*ptr
= alloc_record (fpsr_psprel
);
1727 ptr
->r
.record
.p
.pspoff
= offset
;
1731 static unw_rec_list
*
1732 output_fpsr_sprel (offset
)
1733 unsigned int offset
;
1735 unw_rec_list
*ptr
= alloc_record (fpsr_sprel
);
1736 ptr
->r
.record
.p
.spoff
= offset
;
1740 static unw_rec_list
*
1741 output_priunat_when_gr ()
1743 unw_rec_list
*ptr
= alloc_record (priunat_when_gr
);
1747 static unw_rec_list
*
1748 output_priunat_when_mem ()
1750 unw_rec_list
*ptr
= alloc_record (priunat_when_mem
);
1754 static unw_rec_list
*
1755 output_priunat_gr (gr
)
1758 unw_rec_list
*ptr
= alloc_record (priunat_gr
);
1759 ptr
->r
.record
.p
.gr
= gr
;
1763 static unw_rec_list
*
1764 output_priunat_psprel (offset
)
1765 unsigned int offset
;
1767 unw_rec_list
*ptr
= alloc_record (priunat_psprel
);
1768 ptr
->r
.record
.p
.pspoff
= offset
;
1772 static unw_rec_list
*
1773 output_priunat_sprel (offset
)
1774 unsigned int offset
;
1776 unw_rec_list
*ptr
= alloc_record (priunat_sprel
);
1777 ptr
->r
.record
.p
.spoff
= offset
;
1781 static unw_rec_list
*
1784 unw_rec_list
*ptr
= alloc_record (bsp_when
);
1788 static unw_rec_list
*
1792 unw_rec_list
*ptr
= alloc_record (bsp_gr
);
1793 ptr
->r
.record
.p
.gr
= gr
;
1797 static unw_rec_list
*
1798 output_bsp_psprel (offset
)
1799 unsigned int offset
;
1801 unw_rec_list
*ptr
= alloc_record (bsp_psprel
);
1802 ptr
->r
.record
.p
.pspoff
= offset
;
1806 static unw_rec_list
*
1807 output_bsp_sprel (offset
)
1808 unsigned int offset
;
1810 unw_rec_list
*ptr
= alloc_record (bsp_sprel
);
1811 ptr
->r
.record
.p
.spoff
= offset
;
1815 static unw_rec_list
*
1816 output_bspstore_when ()
1818 unw_rec_list
*ptr
= alloc_record (bspstore_when
);
1822 static unw_rec_list
*
1823 output_bspstore_gr (gr
)
1826 unw_rec_list
*ptr
= alloc_record (bspstore_gr
);
1827 ptr
->r
.record
.p
.gr
= gr
;
1831 static unw_rec_list
*
1832 output_bspstore_psprel (offset
)
1833 unsigned int offset
;
1835 unw_rec_list
*ptr
= alloc_record (bspstore_psprel
);
1836 ptr
->r
.record
.p
.pspoff
= offset
;
1840 static unw_rec_list
*
1841 output_bspstore_sprel (offset
)
1842 unsigned int offset
;
1844 unw_rec_list
*ptr
= alloc_record (bspstore_sprel
);
1845 ptr
->r
.record
.p
.spoff
= offset
;
1849 static unw_rec_list
*
1852 unw_rec_list
*ptr
= alloc_record (rnat_when
);
1856 static unw_rec_list
*
1860 unw_rec_list
*ptr
= alloc_record (rnat_gr
);
1861 ptr
->r
.record
.p
.gr
= gr
;
1865 static unw_rec_list
*
1866 output_rnat_psprel (offset
)
1867 unsigned int offset
;
1869 unw_rec_list
*ptr
= alloc_record (rnat_psprel
);
1870 ptr
->r
.record
.p
.pspoff
= offset
;
1874 static unw_rec_list
*
1875 output_rnat_sprel (offset
)
1876 unsigned int offset
;
1878 unw_rec_list
*ptr
= alloc_record (rnat_sprel
);
1879 ptr
->r
.record
.p
.spoff
= offset
;
1883 static unw_rec_list
*
1886 unw_rec_list
*ptr
= NULL
;
1890 static unw_rec_list
*
1891 output_label_state ()
1893 unw_rec_list
*ptr
= NULL
;
1897 static unw_rec_list
*
1898 output_copy_state ()
1900 unw_rec_list
*ptr
= NULL
;
1904 static unw_rec_list
*
1905 output_spill_psprel (reg
, offset
)
1907 unsigned int offset
;
1909 unw_rec_list
*ptr
= alloc_record (spill_psprel
);
1910 ptr
->r
.record
.x
.reg
= reg
;
1911 ptr
->r
.record
.x
.pspoff
= offset
;
1915 static unw_rec_list
*
1916 output_spill_sprel (reg
, offset
)
1918 unsigned int offset
;
1920 unw_rec_list
*ptr
= alloc_record (spill_sprel
);
1921 ptr
->r
.record
.x
.reg
= reg
;
1922 ptr
->r
.record
.x
.spoff
= offset
;
1926 static unw_rec_list
*
1927 output_spill_psprel_p (reg
, offset
, predicate
)
1929 unsigned int offset
;
1930 unsigned int predicate
;
1932 unw_rec_list
*ptr
= alloc_record (spill_psprel_p
);
1933 ptr
->r
.record
.x
.reg
= reg
;
1934 ptr
->r
.record
.x
.pspoff
= offset
;
1935 ptr
->r
.record
.x
.qp
= predicate
;
1939 static unw_rec_list
*
1940 output_spill_sprel_p (reg
, offset
, predicate
)
1942 unsigned int offset
;
1943 unsigned int predicate
;
1945 unw_rec_list
*ptr
= alloc_record (spill_sprel_p
);
1946 ptr
->r
.record
.x
.reg
= reg
;
1947 ptr
->r
.record
.x
.spoff
= offset
;
1948 ptr
->r
.record
.x
.qp
= predicate
;
1952 static unw_rec_list
*
1953 output_spill_reg (reg
, targ_reg
, xy
)
1955 unsigned int targ_reg
;
1958 unw_rec_list
*ptr
= alloc_record (spill_reg
);
1959 ptr
->r
.record
.x
.reg
= reg
;
1960 ptr
->r
.record
.x
.treg
= targ_reg
;
1961 ptr
->r
.record
.x
.xy
= xy
;
1965 static unw_rec_list
*
1966 output_spill_reg_p (reg
, targ_reg
, xy
, predicate
)
1968 unsigned int targ_reg
;
1970 unsigned int predicate
;
1972 unw_rec_list
*ptr
= alloc_record (spill_reg_p
);
1973 ptr
->r
.record
.x
.reg
= reg
;
1974 ptr
->r
.record
.x
.treg
= targ_reg
;
1975 ptr
->r
.record
.x
.xy
= xy
;
1976 ptr
->r
.record
.x
.qp
= predicate
;
1980 /* Given a unw_rec_list process the correct format with the
1981 specified function. */
1983 process_one_record (ptr
, f
)
1987 switch (ptr
->r
.type
)
1991 output_R1_format (f
, ptr
->r
.type
, ptr
->r
.record
.r
.rlen
);
1994 output_R2_format (f
, ptr
->r
.record
.r
.mask
,
1995 ptr
->r
.record
.r
.grsave
, ptr
->r
.record
.r
.rlen
);
1999 output_P7_format (f
, ptr
->r
.type
, ptr
->r
.record
.p
.t
,
2000 ptr
->r
.record
.p
.size
);
2013 output_P3_format (f
, ptr
->r
.type
, ptr
->r
.record
.p
.gr
);
2016 output_P3_format (f
, rp_br
, ptr
->r
.record
.p
.br
);
2019 output_P7_format (f
, psp_sprel
, ptr
->r
.record
.p
.spoff
, 0);
2027 output_P7_format (f
, ptr
->r
.type
, ptr
->r
.record
.p
.t
, 0);
2036 output_P7_format (f
, ptr
->r
.type
, ptr
->r
.record
.p
.pspoff
, 0);
2046 case bspstore_sprel
:
2048 output_P8_format (f
, ptr
->r
.type
, ptr
->r
.record
.p
.spoff
);
2052 output_P6_format (f
, ptr
->r
.type
, ptr
->r
.record
.p
.rmask
);
2055 output_P5_format (f
, ptr
->r
.record
.p
.grmask
, ptr
->r
.record
.p
.frmask
);
2058 output_P9_format (f
, ptr
->r
.record
.p
.grmask
, ptr
->r
.record
.p
.gr
);
2061 output_P1_format (f
, ptr
->r
.record
.p
.brmask
);
2064 output_P2_format (f
, ptr
->r
.record
.p
.brmask
, ptr
->r
.record
.p
.gr
);
2067 as_bad ("spill_mask record unimplemented.");
2069 case priunat_when_gr
:
2070 case priunat_when_mem
:
2074 output_P8_format (f
, ptr
->r
.type
, ptr
->r
.record
.p
.t
);
2076 case priunat_psprel
:
2078 case bspstore_psprel
:
2080 output_P8_format (f
, ptr
->r
.type
, ptr
->r
.record
.p
.pspoff
);
2083 as_bad ("epilogue record unimplemented.");
2086 as_bad ("label_state record unimplemented.");
2089 as_bad ("copy_state record unimplemented.");
2094 case spill_psprel_p
:
2097 as_bad ("spill_* record unimplemented.");
2100 as_bad ("record_type_not_valid");
2105 /* Given a unw_rec_list list, process all the records with
2106 the specified function. */
2108 process_unw_records (list
, f
)
2113 for (ptr
= list
; ptr
; ptr
= ptr
->next
)
2114 process_one_record (ptr
, f
);
2117 /* Determine the size of a record list in bytes. */
2119 calc_record_size (list
)
2123 process_unw_records (list
, count_output
);
2127 /* Given a complete record list, process any records which have
2128 unresolved fields, (ie length counts for a prologue). After
2129 this has been run, all neccessary information should be available
2130 within each record to generate an image. */
2132 fixup_unw_records (list
)
2136 unsigned long first_addr
= 0;
2137 for (ptr
= list
; ptr
; ptr
= ptr
->next
)
2139 if (ptr
->slot_number
== SLOT_NUM_NOT_SET
)
2140 as_bad (" Insn slot not set in unwind record.");
2141 switch (ptr
->r
.type
)
2149 unsigned long last_addr
;
2150 first_addr
= ptr
->slot_number
;
2151 ptr
->slot_number
= 0;
2152 /* Find either the next body/prologue start, or the end of
2153 the list, and determine the size of the region. */
2154 for (last
= ptr
; last
->next
!= NULL
; last
= last
->next
)
2155 if (last
->next
->r
.type
== prologue
2156 || last
->next
->r
.type
== prologue_gr
2157 || last
->next
->r
.type
== body
)
2161 last_addr
= last
->slot_number
;
2162 size
= ((last_addr
- first_addr
) / 16) * 3 + last_addr
% 4;
2163 ptr
->r
.record
.r
.rlen
= size
;
2174 case priunat_when_gr
:
2175 case priunat_when_mem
:
2180 /* All the time fields. */
2181 int x
= ptr
->slot_number
- first_addr
;
2182 ptr
->r
.record
.p
.t
= (x
/ 16) * 3 + (ptr
->slot_number
% 4);
2185 /* TODO. We also need to combine all the register masks into a single
2186 record. (Ie, all the save.g save.gf, save.f and save.br's) */
2191 /* Generate an unwind image from a record list. Returns the number of
2192 bytes in the resulting image. The memory image itselof is returned
2193 in the 'ptr' parameter. */
2195 output_unw_records (list
, ptr
)
2199 int size
, x
, extra
= 0;
2202 fixup_unw_records (list
);
2203 size
= calc_record_size (list
);
2205 /* pad to 8 byte boundry. */
2209 /* Add 8 for the header + 8 more bytes for the personality offset. */
2210 mem
= xmalloc (size
+ extra
+ 16);
2212 vbyte_mem_ptr
= mem
+ 8;
2213 /* Clear the padding area and personality. */
2214 memset (mem
+ 8 + size
, 0 , extra
+ 8);
2215 /* Initialize the header area. */
2216 md_number_to_chars (mem
, 1, 2); /* version number. */
2217 md_number_to_chars (mem
+ 2, 0x03, 2); /* Set E and U handler bits. */
2219 /* Length in double words. */
2220 md_number_to_chars (mem
+ 4, (size
+ extra
) / 8, 4);
2222 process_unw_records (list
, output_vbyte_mem
);
2225 return size
+ extra
+ 16;
2235 radix
= *input_line_pointer
++;
2237 if (radix
!= 'C' && !is_end_of_line
[(unsigned char) radix
])
2239 as_bad ("Radix `%c' unsupported", *input_line_pointer
);
2240 ignore_rest_of_line ();
2245 /* .sbss, .bss etc. are macros that expand into ".section SECNAME". */
2247 dot_special_section (which
)
2250 set_section ((char *) special_section_name
[which
]);
2254 add_unwind_entry (ptr
)
2258 unwind_tail
->next
= ptr
;
2263 /* The current entry can in fact be a chain of unwind entries. */
2264 if (current_unwind_entry
== NULL
)
2265 current_unwind_entry
= ptr
;
2275 if (e
.X_op
!= O_constant
)
2276 as_bad ("Operand to .fframe must be a constant");
2279 add_unwind_entry (output_mem_stack_f (e
.X_add_number
));
2287 discard_rest_of_line ();
2298 sep
= parse_operand (&e1
);
2300 as_bad ("No second operand to .save");
2301 sep
= parse_operand (&e2
);
2303 reg1
= e1
.X_add_number
- REG_AR
;
2304 reg2
= e2
.X_add_number
- REG_GR
;
2306 /* Make sure its a valid ar.xxx reg, OR its br0, aka 'rp'. */
2307 if (e1
.X_op
== O_register
2308 && ((reg1
>=0 && reg1
< 128) || reg1
== REG_BR
- REG_AR
))
2310 if (e2
.X_op
== O_register
&& reg2
>=0 && reg2
< 128)
2314 case 17: /* ar.bsp */
2315 add_unwind_entry (output_bsp_when ());
2316 add_unwind_entry (output_bsp_gr (reg2
));
2318 case 18: /* ar.bspstore */
2319 add_unwind_entry (output_bspstore_when ());
2320 add_unwind_entry (output_bspstore_gr (reg2
));
2322 case 19: /* ar.rnat */
2323 add_unwind_entry (output_rnat_when ());
2324 add_unwind_entry (output_rnat_gr (reg2
));
2326 case 36: /* ar.unat */
2327 add_unwind_entry (output_unat_when ());
2328 add_unwind_entry (output_unat_gr (reg2
));
2330 case 40: /* ar.fpsr */
2331 add_unwind_entry (output_fpsr_when ());
2332 add_unwind_entry (output_fpsr_gr (reg2
));
2334 case 64: /* ar.pfs */
2335 add_unwind_entry (output_pfs_when ());
2336 add_unwind_entry (output_pfs_gr (reg2
));
2338 case 65: /* ar.lc */
2339 add_unwind_entry (output_lc_when ());
2340 add_unwind_entry (output_lc_gr (reg2
));
2342 case REG_BR
- REG_AR
: /* rp */
2343 add_unwind_entry (output_rp_when ());
2344 add_unwind_entry (output_rp_gr (reg2
));
2347 as_bad ("first operand is unknown application register");
2351 as_bad (" Second operand not a valid register");
2354 as_bad ("First operand not a valid register");
2361 discard_rest_of_line ();
2365 generate_unwind_image ()
2368 unsigned char *unw_rec
;
2371 /* Generate the unwind record. */
2372 size
= output_unw_records (unwind_list
, &unw_rec
);
2374 as_bad ("Unwind record is ont a multiple of 4 bytes.");
2376 /* If there are unwind records, switch sections, and output the info. */
2380 unsigned char *where
;
2381 unsigned char *personality
;
2384 set_section ((char *) special_section_name
[SPECIAL_SECTION_UNWIND_INFO
]);
2386 /* Set expression which points to start of unwind descriptor area. */
2387 unwind_info
= expr_build_dot ();
2389 where
= (unsigned char *)frag_more (size
);
2391 /* Issue a label for this address, and keep track of it to put it
2392 in the unwind section. */
2394 /* Copy the information from the unwind record into this section. The
2395 data is already in the correct byte order. */
2396 memcpy (where
, unw_rec
, size
);
2397 /* Add the personality address to the image. */
2398 if (personality_routine
!= 0)
2400 exp
.X_op
= O_symbol
;
2401 exp
.X_add_symbol
= personality_routine
;
2402 exp
.X_add_number
= 0;
2403 fix_new_exp (frag_now
, frag_now_fix () - 8, 8,
2404 &exp
, 0, BFD_RELOC_IA64_LTOFF_FPTR64LSB
);
2405 personality_routine
= 0;
2407 obj_elf_previous (0);
2410 free_list_records (unwind_list
);
2411 unwind_list
= unwind_tail
= current_unwind_entry
= NULL
;
2417 dot_handlerdata (dummy
)
2420 generate_unwind_image ();
2424 dot_unwentry (dummy
)
2427 discard_rest_of_line ();
2434 discard_rest_of_line ();
2445 sep
= parse_operand (&e1
);
2447 as_bad ("No second operand to .savesp");
2448 sep
= parse_operand (&e2
);
2450 reg1
= e1
.X_add_number
- REG_AR
;
2451 val
= e2
.X_add_number
;
2453 /* Make sure its a valid ar.xxx reg, OR its br0, aka 'rp'. */
2454 if (e1
.X_op
== O_register
2455 && ((reg1
>=0 && reg1
< 128) || reg1
== REG_BR
- REG_AR
|| reg1
== REG_PR
- REG_AR
))
2457 if (e2
.X_op
== O_constant
)
2461 case 17: /* ar.bsp */
2462 add_unwind_entry (output_bsp_when ());
2463 add_unwind_entry (output_bsp_sprel (val
));
2465 case 18: /* ar.bspstore */
2466 add_unwind_entry (output_bspstore_when ());
2467 add_unwind_entry (output_bspstore_sprel (val
));
2469 case 19: /* ar.rnat */
2470 add_unwind_entry (output_rnat_when ());
2471 add_unwind_entry (output_rnat_sprel (val
));
2473 case 36: /* ar.unat */
2474 add_unwind_entry (output_unat_when ());
2475 add_unwind_entry (output_unat_sprel (val
));
2477 case 40: /* ar.fpsr */
2478 add_unwind_entry (output_fpsr_when ());
2479 add_unwind_entry (output_fpsr_sprel (val
));
2481 case 64: /* ar.pfs */
2482 add_unwind_entry (output_pfs_when ());
2483 add_unwind_entry (output_pfs_sprel (val
));
2485 case 65: /* ar.lc */
2486 add_unwind_entry (output_lc_when ());
2487 add_unwind_entry (output_lc_sprel (val
));
2489 case REG_BR
- REG_AR
: /* rp */
2490 add_unwind_entry (output_rp_when ());
2491 add_unwind_entry (output_rp_sprel (val
));
2493 case REG_PR
- REG_AR
: /* Predicate registers. */
2494 add_unwind_entry (output_preds_when ());
2495 add_unwind_entry (output_preds_sprel (val
));
2498 as_bad ("first operand is unknown application register");
2502 as_bad (" Second operand not a valid constant");
2505 as_bad ("First operand not a valid register");
2512 discard_rest_of_line ();
2521 sep
= parse_operand (&e1
);
2523 parse_operand (&e2
);
2525 if (e1
.X_op
!= O_constant
)
2526 as_bad ("First operand to .save.g must be a constant.");
2529 int grmask
= e1
.X_add_number
;
2531 add_unwind_entry (output_gr_mem (grmask
));
2534 int reg
= e2
.X_add_number
- REG_GR
;
2535 if (e2
.X_op
== O_register
&& reg
>=0 && reg
< 128)
2536 add_unwind_entry (output_gr_gr (grmask
, reg
));
2538 as_bad ("Second operand is an invalid register.");
2549 sep
= parse_operand (&e1
);
2551 if (e1
.X_op
!= O_constant
)
2552 as_bad ("Operand to .save.f must be a constant.");
2555 int frmask
= e1
.X_add_number
;
2556 add_unwind_entry (output_fr_mem (e1
.X_add_number
));
2566 sep
= parse_operand (&e1
);
2568 if (e1
.X_op
!= O_constant
)
2569 as_bad ("Operand to .save.b must be a constant.");
2572 int brmask
= e1
.X_add_number
;
2573 add_unwind_entry (output_br_mem (brmask
));
2583 sep
= parse_operand (&e1
);
2585 parse_operand (&e2
);
2587 if (e1
.X_op
!= O_constant
|| sep
!= ',' || e2
.X_op
!= O_constant
)
2588 as_bad ("Both operands of .save.gf must be constants.");
2591 int grmask
= e1
.X_add_number
;
2592 int frmask
= e2
.X_add_number
;
2593 add_unwind_entry (output_frgr_mem (grmask
, frmask
));
2604 if (e
.X_op
!= O_constant
)
2605 as_bad ("Operand to .spill must be a constant");
2608 add_unwind_entry (output_spill_base (e
.X_add_number
));
2616 discard_rest_of_line ();
2620 dot_personality (dummy
)
2625 name
= input_line_pointer
;
2626 c
= get_symbol_end ();
2627 p
= input_line_pointer
;
2628 personality_routine
= symbol_find_or_make (name
);
2631 demand_empty_rest_of_line ();
2641 proc_start
= expr_build_dot ();
2642 /* Parse names of main and alternate entry points and mark them s
2643 function symbols: */
2647 name
= input_line_pointer
;
2648 c
= get_symbol_end ();
2649 p
= input_line_pointer
;
2650 sym
= symbol_find_or_make (name
);
2651 if (proc_start
== 0)
2655 symbol_get_bfdsym (sym
)->flags
|= BSF_FUNCTION
;
2658 if (*input_line_pointer
!= ',')
2660 ++input_line_pointer
;
2662 demand_empty_rest_of_line ();
2665 unwind_list
= unwind_tail
= current_unwind_entry
= NULL
;
2666 personality_routine
= 0;
2673 unwind_prologue
= 0;
2674 add_unwind_entry (output_body ());
2678 dot_prologue (dummy
)
2681 unwind_prologue
= 1;
2683 if (! is_end_of_line
[(unsigned char) *input_line_pointer
])
2687 sep
= parse_operand (&e1
);
2689 as_bad ("No second operand to .prologue");
2690 sep
= parse_operand (&e2
);
2692 if (e1
.X_op
== O_constant
)
2694 if (e2
.X_op
== O_constant
)
2696 int mask
= e1
.X_add_number
;
2697 int reg
= e2
.X_add_number
;
2698 add_unwind_entry (output_prologue_gr (mask
, reg
));
2701 as_bad ("Second operand not a constant");
2704 as_bad ("First operand not a constant");
2707 add_unwind_entry (output_prologue ());
2719 subsegT saved_subseg
;
2721 saved_seg
= now_seg
;
2722 saved_subseg
= now_subseg
;
2725 demand_empty_rest_of_line ();
2727 insn_group_break (1, 0, 0);
2728 ia64_flush_insns ();
2730 /* If there was a .handlerdata, we haven't generated an image yet. */
2731 if (unwind_info
== 0)
2733 generate_unwind_image ();
2736 subseg_set (md
.last_text_seg
, 0);
2737 proc_end
= expr_build_dot ();
2739 set_section ((char *) special_section_name
[SPECIAL_SECTION_UNWIND
]);
2740 ptr
= frag_more (24);
2741 where
= frag_now_fix () - 24;
2743 /* Issue the values of a) Proc Begin, b) Proc End, c) Unwind Record. */
2744 e
.X_op
= O_pseudo_fixup
;
2745 e
.X_op_symbol
= pseudo_func
[FUNC_SEG_RELATIVE
].u
.sym
;
2747 e
.X_add_symbol
= proc_start
;
2748 ia64_cons_fix_new (frag_now
, where
, 8, &e
);
2750 e
.X_op
= O_pseudo_fixup
;
2751 e
.X_op_symbol
= pseudo_func
[FUNC_SEG_RELATIVE
].u
.sym
;
2753 e
.X_add_symbol
= proc_end
;
2754 ia64_cons_fix_new (frag_now
, where
+ 8, 8, &e
);
2756 if (unwind_info
!= 0)
2758 e
.X_op
= O_pseudo_fixup
;
2759 e
.X_op_symbol
= pseudo_func
[FUNC_SEG_RELATIVE
].u
.sym
;
2761 e
.X_add_symbol
= unwind_info
;
2762 ia64_cons_fix_new (frag_now
, where
+ 16, 8, &e
);
2765 md_number_to_chars (ptr
+ 16, 0, 8);
2767 subseg_set (saved_seg
, saved_subseg
);
2768 proc_start
= proc_end
= unwind_info
= 0;
2772 dot_template (template)
2775 CURR_SLOT
.user_template
= template;
2782 int ins
, locs
, outs
, rots
;
2784 if (is_it_end_of_statement ())
2785 ins
= locs
= outs
= rots
= 0;
2788 ins
= get_absolute_expression ();
2789 if (*input_line_pointer
++ != ',')
2791 locs
= get_absolute_expression ();
2792 if (*input_line_pointer
++ != ',')
2794 outs
= get_absolute_expression ();
2795 if (*input_line_pointer
++ != ',')
2797 rots
= get_absolute_expression ();
2799 set_regstack (ins
, locs
, outs
, rots
);
2803 as_bad ("Comma expected");
2804 ignore_rest_of_line ();
2811 unsigned num_regs
, num_alloced
= 0;
2812 struct dynreg
**drpp
, *dr
;
2813 int ch
, base_reg
= 0;
2819 case DYNREG_GR
: base_reg
= REG_GR
+ 32; break;
2820 case DYNREG_FR
: base_reg
= REG_FR
+ 32; break;
2821 case DYNREG_PR
: base_reg
= REG_P
+ 16; break;
2825 /* first, remove existing names from hash table: */
2826 for (dr
= md
.dynreg
[type
]; dr
&& dr
->num_regs
; dr
= dr
->next
)
2828 hash_delete (md
.dynreg_hash
, dr
->name
);
2832 drpp
= &md
.dynreg
[type
];
2835 start
= input_line_pointer
;
2836 ch
= get_symbol_end ();
2837 *input_line_pointer
= ch
;
2838 len
= (input_line_pointer
- start
);
2841 if (*input_line_pointer
!= '[')
2843 as_bad ("Expected '['");
2846 ++input_line_pointer
; /* skip '[' */
2848 num_regs
= get_absolute_expression ();
2850 if (*input_line_pointer
++ != ']')
2852 as_bad ("Expected ']'");
2857 num_alloced
+= num_regs
;
2861 if (num_alloced
> md
.rot
.num_regs
)
2863 as_bad ("Used more than the declared %d rotating registers",
2869 if (num_alloced
> 96)
2871 as_bad ("Used more than the available 96 rotating registers");
2876 if (num_alloced
> 48)
2878 as_bad ("Used more than the available 48 rotating registers");
2887 name
= obstack_alloc (¬es
, len
+ 1);
2888 memcpy (name
, start
, len
);
2893 *drpp
= obstack_alloc (¬es
, sizeof (*dr
));
2894 memset (*drpp
, 0, sizeof (*dr
));
2899 dr
->num_regs
= num_regs
;
2900 dr
->base
= base_reg
;
2902 base_reg
+= num_regs
;
2904 if (hash_insert (md
.dynreg_hash
, name
, dr
))
2906 as_bad ("Attempt to redefine register set `%s'", name
);
2910 if (*input_line_pointer
!= ',')
2912 ++input_line_pointer
; /* skip comma */
2915 demand_empty_rest_of_line ();
2919 ignore_rest_of_line ();
2923 dot_byteorder (byteorder
)
2926 target_big_endian
= byteorder
;
2938 option
= input_line_pointer
;
2939 ch
= get_symbol_end ();
2940 if (strcmp (option
, "lsb") == 0)
2941 md
.flags
&= ~EF_IA_64_BE
;
2942 else if (strcmp (option
, "msb") == 0)
2943 md
.flags
|= EF_IA_64_BE
;
2944 else if (strcmp (option
, "abi32") == 0)
2945 md
.flags
&= ~EF_IA_64_ABI64
;
2946 else if (strcmp (option
, "abi64") == 0)
2947 md
.flags
|= EF_IA_64_ABI64
;
2949 as_bad ("Unknown psr option `%s'", option
);
2950 *input_line_pointer
= ch
;
2953 if (*input_line_pointer
!= ',')
2956 ++input_line_pointer
;
2959 demand_empty_rest_of_line ();
2966 as_bad (".alias not implemented yet");
2973 new_logical_line (0, get_absolute_expression ());
2974 demand_empty_rest_of_line ();
2978 parse_section_name ()
2984 if (*input_line_pointer
!= '"')
2986 as_bad ("Missing section name");
2987 ignore_rest_of_line ();
2990 name
= demand_copy_C_string (&len
);
2993 ignore_rest_of_line ();
2997 if (*input_line_pointer
!= ',')
2999 as_bad ("Comma expected after section name");
3000 ignore_rest_of_line ();
3003 ++input_line_pointer
; /* skip comma */
3011 char *name
= parse_section_name ();
3017 obj_elf_previous (0);
3020 /* Why doesn't float_cons() call md_cons_align() the way cons() does? */
3022 stmt_float_cons (kind
)
3029 case 'd': size
= 8; break;
3030 case 'x': size
= 10; break;
3037 ia64_do_align (size
);
3045 int saved_auto_align
= md
.auto_align
;
3049 md
.auto_align
= saved_auto_align
;
3053 dot_xfloat_cons (kind
)
3056 char *name
= parse_section_name ();
3061 stmt_float_cons (kind
);
3062 obj_elf_previous (0);
3066 dot_xstringer (zero
)
3069 char *name
= parse_section_name ();
3075 obj_elf_previous (0);
3082 int saved_auto_align
= md
.auto_align
;
3083 char *name
= parse_section_name ();
3090 md
.auto_align
= saved_auto_align
;
3091 obj_elf_previous (0);
3095 dot_xfloat_cons_ua (kind
)
3098 int saved_auto_align
= md
.auto_align
;
3099 char *name
= parse_section_name ();
3105 stmt_float_cons (kind
);
3106 md
.auto_align
= saved_auto_align
;
3107 obj_elf_previous (0);
3110 /* .reg.val <regname>,value */
3118 if (reg
.X_op
!= O_register
)
3120 as_bad (_("Register name expected"));
3121 ignore_rest_of_line ();
3123 else if (*input_line_pointer
++ != ',')
3125 as_bad (_("Comma expected"));
3126 ignore_rest_of_line ();
3130 valueT value
= get_absolute_expression ();
3131 int regno
= reg
.X_add_number
;
3132 if (regno
< REG_GR
|| regno
> REG_GR
+128)
3133 as_warn (_("Register value annotation ignored"));
3136 gr_values
[regno
-REG_GR
].known
= 1;
3137 gr_values
[regno
-REG_GR
].value
= value
;
3138 gr_values
[regno
-REG_GR
].path
= md
.path
;
3141 demand_empty_rest_of_line ();
3144 /* select dv checking mode
3149 A stop is inserted when changing modes
3155 if (md
.manual_bundling
)
3156 as_warn (_("Directive invalid within a bundle"));
3158 if (type
== 'E' || type
== 'A')
3159 md
.mode_explicitly_set
= 0;
3161 md
.mode_explicitly_set
= 1;
3168 if (md
.explicit_mode
)
3169 insn_group_break (1, 0, 0);
3170 md
.explicit_mode
= 0;
3174 if (!md
.explicit_mode
)
3175 insn_group_break (1, 0, 0);
3176 md
.explicit_mode
= 1;
3180 if (md
.explicit_mode
!= md
.default_explicit_mode
)
3181 insn_group_break (1, 0, 0);
3182 md
.explicit_mode
= md
.default_explicit_mode
;
3183 md
.mode_explicitly_set
= 0;
3194 for (regno
= 0;regno
< 64;regno
++)
3196 if (mask
& ((valueT
)1<<regno
))
3198 fprintf (stderr
, "%s p%d", comma
, regno
);
3205 .pred.rel.clear [p1 [,p2 [,...]]] (also .pred.rel "clear")
3206 .pred.rel.imply p1, p2 (also .pred.rel "imply")
3207 .pred.rel.mutex p1, p2 [,...] (also .pred.rel "mutex")
3208 .pred.safe_across_calls p1 [, p2 [,...]]
3216 int p1
= -1, p2
= -1;
3220 if (*input_line_pointer
!= '"')
3222 as_bad (_("Missing predicate relation type"));
3223 ignore_rest_of_line ();
3229 char *form
= demand_copy_C_string (&len
);
3230 if (strcmp (form
, "mutex") == 0)
3232 else if (strcmp (form
, "clear") == 0)
3234 else if (strcmp (form
, "imply") == 0)
3238 as_bad (_("Unrecognized predicate relation type"));
3239 ignore_rest_of_line ();
3243 if (*input_line_pointer
== ',')
3244 ++input_line_pointer
;
3254 if (toupper (*input_line_pointer
) != 'P'
3255 || (regno
= atoi (++input_line_pointer
)) < 0
3258 as_bad (_("Predicate register expected"));
3259 ignore_rest_of_line ();
3262 while (isdigit (*input_line_pointer
))
3263 ++input_line_pointer
;
3270 as_warn (_("Duplicate predicate register ignored"));
3271 mask
|= bit
; count
++;
3272 /* see if it's a range */
3273 if (*input_line_pointer
== '-')
3276 ++input_line_pointer
;
3278 if (toupper (*input_line_pointer
) != 'P'
3279 || (regno
= atoi (++input_line_pointer
)) < 0
3282 as_bad (_("Predicate register expected"));
3283 ignore_rest_of_line ();
3286 while (isdigit (*input_line_pointer
))
3287 ++input_line_pointer
;
3291 as_bad (_("Bad register range"));
3292 ignore_rest_of_line ();
3298 mask
|= bit
; count
++;
3302 if (*input_line_pointer
!= ',')
3304 ++input_line_pointer
;
3313 clear_qp_mutex (mask
);
3314 clear_qp_implies (mask
, (valueT
)0);
3317 if (count
!= 2 || p1
== -1 || p2
== -1)
3318 as_bad (_("Predicate source and target required"));
3319 else if (p1
== 0 || p2
== 0)
3320 as_bad (_("Use of p0 is not valid in this context"));
3322 add_qp_imply (p1
, p2
);
3327 as_bad (_("At least two PR arguments expected"));
3332 as_bad (_("Use of p0 is not valid in this context"));
3335 add_qp_mutex (mask
);
3338 /* note that we don't override any existing relations */
3341 as_bad (_("At least one PR argument expected"));
3346 fprintf (stderr
, "Safe across calls: ");
3347 print_prmask (mask
);
3348 fprintf (stderr
, "\n");
3350 qp_safe_across_calls
= mask
;
3353 demand_empty_rest_of_line ();
3356 /* .entry label [, label [, ...]]
3357 Hint to DV code that the given labels are to be considered entry points.
3358 Otherwise, only global labels are considered entry points.
3371 name
= input_line_pointer
;
3372 c
= get_symbol_end ();
3373 symbolP
= symbol_find_or_make (name
);
3375 err
= hash_insert (md
.entry_hash
, S_GET_NAME (symbolP
), (PTR
) symbolP
);
3377 as_fatal (_("Inserting \"%s\" into entry hint table failed: %s"),
3380 *input_line_pointer
= c
;
3382 c
= *input_line_pointer
;
3385 input_line_pointer
++;
3387 if (*input_line_pointer
== '\n')
3393 demand_empty_rest_of_line ();
3396 /* .mem.offset offset, base
3397 "base" is used to distinguish between offsets from a different base.
3400 dot_mem_offset (dummy
)
3403 md
.mem_offset
.hint
= 1;
3404 md
.mem_offset
.offset
= get_absolute_expression ();
3405 if (*input_line_pointer
!= ',')
3407 as_bad (_("Comma expected"));
3408 ignore_rest_of_line ();
3411 ++input_line_pointer
;
3412 md
.mem_offset
.base
= get_absolute_expression ();
3413 demand_empty_rest_of_line ();
3416 /* ia64-specific pseudo-ops: */
3417 const pseudo_typeS md_pseudo_table
[] =
3419 { "radix", dot_radix
, 0 },
3420 { "lcomm", s_lcomm_bytes
, 1 },
3421 { "bss", dot_special_section
, SPECIAL_SECTION_BSS
},
3422 { "sbss", dot_special_section
, SPECIAL_SECTION_SBSS
},
3423 { "sdata", dot_special_section
, SPECIAL_SECTION_SDATA
},
3424 { "rodata", dot_special_section
, SPECIAL_SECTION_RODATA
},
3425 { "comment", dot_special_section
, SPECIAL_SECTION_COMMENT
},
3426 { "ia_64.unwind", dot_special_section
, SPECIAL_SECTION_UNWIND
},
3427 { "ia_64.unwind_info", dot_special_section
, SPECIAL_SECTION_UNWIND_INFO
},
3428 { "proc", dot_proc
, 0 },
3429 { "body", dot_body
, 0 },
3430 { "prologue", dot_prologue
, 0 },
3431 { "endp", dot_endp
},
3432 { "file", dwarf2_directive_file
},
3433 { "loc", dwarf2_directive_loc
},
3435 { "fframe", dot_fframe
},
3436 { "vframe", dot_vframe
},
3437 { "save", dot_save
},
3438 { "restore", dot_restore
},
3439 { "handlerdata", dot_handlerdata
},
3440 { "unwentry", dot_unwentry
},
3441 { "alprp", dot_altrp
},
3442 { "savesp", dot_savesp
},
3443 { "savepsp", dot_savepsp
},
3444 { "save.g", dot_saveg
},
3445 { "save.f", dot_savef
},
3446 { "save.b", dot_saveb
},
3447 { "save.gf", dot_savegf
},
3448 { "spill", dot_spill
},
3449 { "unwabi", dot_unwabi
},
3450 { "personality", dot_personality
},
3452 { "estate", dot_estate
},
3454 { "mii", dot_template
, 0x0 },
3455 { "mli", dot_template
, 0x2 }, /* old format, for compatibility */
3456 { "mlx", dot_template
, 0x2 },
3457 { "mmi", dot_template
, 0x4 },
3458 { "mfi", dot_template
, 0x6 },
3459 { "mmf", dot_template
, 0x7 },
3460 { "mib", dot_template
, 0x8 },
3461 { "mbb", dot_template
, 0x9 },
3462 { "bbb", dot_template
, 0xb },
3463 { "mmb", dot_template
, 0xc },
3464 { "mfb", dot_template
, 0xe },
3466 { "lb", dot_scope
, 0 },
3467 { "le", dot_scope
, 1 },
3469 { "align", s_align_bytes
, 0 },
3470 { "regstk", dot_regstk
, 0 },
3471 { "rotr", dot_rot
, DYNREG_GR
},
3472 { "rotf", dot_rot
, DYNREG_FR
},
3473 { "rotp", dot_rot
, DYNREG_PR
},
3474 { "lsb", dot_byteorder
, 0 },
3475 { "msb", dot_byteorder
, 1 },
3476 { "psr", dot_psr
, 0 },
3477 { "alias", dot_alias
, 0 },
3478 { "ln", dot_ln
, 0 }, /* source line info (for debugging) */
3480 { "xdata1", dot_xdata
, 1 },
3481 { "xdata2", dot_xdata
, 2 },
3482 { "xdata4", dot_xdata
, 4 },
3483 { "xdata8", dot_xdata
, 8 },
3484 { "xreal4", dot_xfloat_cons
, 'f' },
3485 { "xreal8", dot_xfloat_cons
, 'd' },
3486 { "xreal10", dot_xfloat_cons
, 'x' },
3487 { "xstring", dot_xstringer
, 0 },
3488 { "xstringz", dot_xstringer
, 1 },
3490 /* unaligned versions: */
3491 { "xdata2.ua", dot_xdata_ua
, 2 },
3492 { "xdata4.ua", dot_xdata_ua
, 4 },
3493 { "xdata8.ua", dot_xdata_ua
, 8 },
3494 { "xreal4.ua", dot_xfloat_cons_ua
, 'f' },
3495 { "xreal8.ua", dot_xfloat_cons_ua
, 'd' },
3496 { "xreal10.ua", dot_xfloat_cons_ua
, 'x' },
3498 /* annotations/DV checking support */
3499 { "entry", dot_entry
, 0 },
3500 { "mem.offset", dot_mem_offset
},
3501 { "pred.rel", dot_pred_rel
, 0 },
3502 { "pred.rel.clear", dot_pred_rel
, 'c' },
3503 { "pred.rel.imply", dot_pred_rel
, 'i' },
3504 { "pred.rel.mutex", dot_pred_rel
, 'm' },
3505 { "pred.safe_across_calls", dot_pred_rel
, 's' },
3506 { "reg.val", dot_reg_val
},
3507 { "auto", dot_dv_mode
, 'a' },
3508 { "explicit", dot_dv_mode
, 'e' },
3509 { "default", dot_dv_mode
, 'd' },
3514 static const struct pseudo_opcode
3517 void (*handler
) (int);
3522 /* these are more like pseudo-ops, but don't start with a dot */
3523 { "data1", cons
, 1 },
3524 { "data2", cons
, 2 },
3525 { "data4", cons
, 4 },
3526 { "data8", cons
, 8 },
3527 { "real4", stmt_float_cons
, 'f' },
3528 { "real8", stmt_float_cons
, 'd' },
3529 { "real10", stmt_float_cons
, 'x' },
3530 { "string", stringer
, 0 },
3531 { "stringz", stringer
, 1 },
3533 /* unaligned versions: */
3534 { "data2.ua", stmt_cons_ua
, 2 },
3535 { "data4.ua", stmt_cons_ua
, 4 },
3536 { "data8.ua", stmt_cons_ua
, 8 },
3537 { "real4.ua", float_cons
, 'f' },
3538 { "real8.ua", float_cons
, 'd' },
3539 { "real10.ua", float_cons
, 'x' },
3542 /* Declare a register by creating a symbol for it and entering it in
3543 the symbol table. */
3545 declare_register (name
, regnum
)
3552 sym
= symbol_new (name
, reg_section
, regnum
, &zero_address_frag
);
3554 err
= hash_insert (md
.reg_hash
, S_GET_NAME (sym
), (PTR
) sym
);
3556 as_fatal ("Inserting \"%s\" into register table failed: %s",
3563 declare_register_set (prefix
, num_regs
, base_regnum
)
3571 for (i
= 0; i
< num_regs
; ++i
)
3573 sprintf (name
, "%s%u", prefix
, i
);
3574 declare_register (name
, base_regnum
+ i
);
3579 operand_width (opnd
)
3580 enum ia64_opnd opnd
;
3582 const struct ia64_operand
*odesc
= &elf64_ia64_operands
[opnd
];
3583 unsigned int bits
= 0;
3587 for (i
= 0; i
< NELEMS (odesc
->field
) && odesc
->field
[i
].bits
; ++i
)
3588 bits
+= odesc
->field
[i
].bits
;
3594 operand_match (idesc
, index
, e
)
3595 const struct ia64_opcode
*idesc
;
3599 enum ia64_opnd opnd
= idesc
->operands
[index
];
3600 int bits
, relocatable
= 0;
3601 struct insn_fix
*fix
;
3608 case IA64_OPND_AR_CCV
:
3609 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_AR
+ 32)
3613 case IA64_OPND_AR_PFS
:
3614 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_AR
+ 64)
3619 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_GR
+ 0)
3624 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_IP
)
3629 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_PR
)
3633 case IA64_OPND_PR_ROT
:
3634 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_PR_ROT
)
3639 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_PSR
)
3643 case IA64_OPND_PSR_L
:
3644 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_PSR_L
)
3648 case IA64_OPND_PSR_UM
:
3649 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_PSR_UM
)
3654 if (e
->X_op
== O_constant
&& e
->X_add_number
== 1)
3659 if (e
->X_op
== O_constant
&& e
->X_add_number
== 8)
3664 if (e
->X_op
== O_constant
&& e
->X_add_number
== 16)
3668 /* register operands: */
3671 if (e
->X_op
== O_register
&& e
->X_add_number
>= REG_AR
3672 && e
->X_add_number
< REG_AR
+ 128)
3678 if (e
->X_op
== O_register
&& e
->X_add_number
>= REG_BR
3679 && e
->X_add_number
< REG_BR
+ 8)
3684 if (e
->X_op
== O_register
&& e
->X_add_number
>= REG_CR
3685 && e
->X_add_number
< REG_CR
+ 128)
3693 if (e
->X_op
== O_register
&& e
->X_add_number
>= REG_FR
3694 && e
->X_add_number
< REG_FR
+ 128)
3700 if (e
->X_op
== O_register
&& e
->X_add_number
>= REG_P
3701 && e
->X_add_number
< REG_P
+ 64)
3708 if (e
->X_op
== O_register
&& e
->X_add_number
>= REG_GR
3709 && e
->X_add_number
< REG_GR
+ 128)
3713 case IA64_OPND_R3_2
:
3714 if (e
->X_op
== O_register
&& e
->X_add_number
>= REG_GR
3715 && e
->X_add_number
< REG_GR
+ 4)
3719 /* indirect operands: */
3720 case IA64_OPND_CPUID_R3
:
3721 case IA64_OPND_DBR_R3
:
3722 case IA64_OPND_DTR_R3
:
3723 case IA64_OPND_ITR_R3
:
3724 case IA64_OPND_IBR_R3
:
3725 case IA64_OPND_MSR_R3
:
3726 case IA64_OPND_PKR_R3
:
3727 case IA64_OPND_PMC_R3
:
3728 case IA64_OPND_PMD_R3
:
3729 case IA64_OPND_RR_R3
:
3730 if (e
->X_op
== O_index
&& e
->X_op_symbol
3731 && (S_GET_VALUE (e
->X_op_symbol
) - IND_CPUID
3732 == opnd
- IA64_OPND_CPUID_R3
))
3737 if (e
->X_op
== O_index
&& !e
->X_op_symbol
)
3741 /* immediate operands: */
3742 case IA64_OPND_CNT2a
:
3743 case IA64_OPND_LEN4
:
3744 case IA64_OPND_LEN6
:
3745 bits
= operand_width (idesc
->operands
[index
]);
3746 if (e
->X_op
== O_constant
3747 && (bfd_vma
) (e
->X_add_number
- 1) < ((bfd_vma
) 1 << bits
))
3751 case IA64_OPND_CNT2b
:
3752 if (e
->X_op
== O_constant
3753 && (bfd_vma
) (e
->X_add_number
- 1) < 3)
3757 case IA64_OPND_CNT2c
:
3758 val
= e
->X_add_number
;
3759 if (e
->X_op
== O_constant
3760 && (val
== 0 || val
== 7 || val
== 15 || val
== 16))
3765 /* SOR must be an integer multiple of 8 */
3766 if (e
->X_add_number
& 0x7)
3770 if (e
->X_op
== O_constant
&&
3771 (bfd_vma
) e
->X_add_number
<= 96)
3775 case IA64_OPND_IMMU62
:
3776 if (e
->X_op
== O_constant
)
3778 if ((bfd_vma
) e
->X_add_number
< ((bfd_vma
) 1 << 62))
3783 /* FIXME -- need 62-bit relocation type */
3784 as_bad (_("62-bit relocation not yet implemented"));
3788 case IA64_OPND_IMMU64
:
3789 if (e
->X_op
== O_symbol
|| e
->X_op
== O_pseudo_fixup
3790 || e
->X_op
== O_subtract
)
3792 fix
= CURR_SLOT
.fixup
+ CURR_SLOT
.num_fixups
;
3793 fix
->code
= BFD_RELOC_IA64_IMM64
;
3794 if (e
->X_op
!= O_subtract
)
3796 fix
->code
= ia64_gen_real_reloc_type (e
->X_op_symbol
, fix
->code
);
3797 if (e
->X_op
== O_pseudo_fixup
)
3801 fix
->opnd
= idesc
->operands
[index
];
3804 ++CURR_SLOT
.num_fixups
;
3807 else if (e
->X_op
== O_constant
)
3811 case IA64_OPND_CCNT5
:
3812 case IA64_OPND_CNT5
:
3813 case IA64_OPND_CNT6
:
3814 case IA64_OPND_CPOS6a
:
3815 case IA64_OPND_CPOS6b
:
3816 case IA64_OPND_CPOS6c
:
3817 case IA64_OPND_IMMU2
:
3818 case IA64_OPND_IMMU7a
:
3819 case IA64_OPND_IMMU7b
:
3820 case IA64_OPND_IMMU21
:
3821 case IA64_OPND_IMMU24
:
3822 case IA64_OPND_MBTYPE4
:
3823 case IA64_OPND_MHTYPE8
:
3824 case IA64_OPND_POS6
:
3825 bits
= operand_width (idesc
->operands
[index
]);
3826 if (e
->X_op
== O_constant
3827 && (bfd_vma
) e
->X_add_number
< ((bfd_vma
) 1 << bits
))
3831 case IA64_OPND_IMMU9
:
3832 bits
= operand_width (idesc
->operands
[index
]);
3833 if (e
->X_op
== O_constant
3834 && (bfd_vma
) e
->X_add_number
< ((bfd_vma
) 1 << bits
))
3836 int lobits
= e
->X_add_number
& 0x3;
3837 if (((bfd_vma
) e
->X_add_number
& 0x3C) != 0 && lobits
== 0)
3838 e
->X_add_number
|= (bfd_vma
)0x3;
3843 case IA64_OPND_IMM44
:
3844 /* least 16 bits must be zero */
3845 if ((e
->X_add_number
& 0xffff) != 0)
3846 as_warn (_("lower 16 bits of mask ignored"));
3848 if (e
->X_op
== O_constant
3849 && ((e
->X_add_number
>= 0
3850 && e
->X_add_number
< ((bfd_vma
) 1 << 44))
3851 || (e
->X_add_number
< 0
3852 && -e
->X_add_number
<= ((bfd_vma
) 1 << 44))))
3855 if (e
->X_add_number
>= 0
3856 && (e
->X_add_number
& ((bfd_vma
) 1 << 43)) != 0)
3858 e
->X_add_number
|= ~(((bfd_vma
) 1 << 44) - 1);
3864 case IA64_OPND_IMM17
:
3865 /* bit 0 is a don't care (pr0 is hardwired to 1) */
3866 if (e
->X_op
== O_constant
3867 && ((e
->X_add_number
>= 0
3868 && e
->X_add_number
< ((bfd_vma
) 1 << 17))
3869 || (e
->X_add_number
< 0
3870 && -e
->X_add_number
<= ((bfd_vma
) 1 << 17))))
3873 if (e
->X_add_number
>= 0
3874 && (e
->X_add_number
& ((bfd_vma
) 1 << 16)) != 0)
3876 e
->X_add_number
|= ~(((bfd_vma
)1 << 17) - 1);
3882 case IA64_OPND_IMM14
:
3883 case IA64_OPND_IMM22
:
3885 case IA64_OPND_IMM1
:
3886 case IA64_OPND_IMM8
:
3887 case IA64_OPND_IMM8U4
:
3888 case IA64_OPND_IMM8M1
:
3889 case IA64_OPND_IMM8M1U4
:
3890 case IA64_OPND_IMM8M1U8
:
3891 case IA64_OPND_IMM9a
:
3892 case IA64_OPND_IMM9b
:
3893 bits
= operand_width (idesc
->operands
[index
]);
3894 if (relocatable
&& (e
->X_op
== O_symbol
3895 || e
->X_op
== O_subtract
3896 || e
->X_op
== O_pseudo_fixup
))
3898 fix
= CURR_SLOT
.fixup
+ CURR_SLOT
.num_fixups
;
3900 if (idesc
->operands
[index
] == IA64_OPND_IMM14
)
3901 fix
->code
= BFD_RELOC_IA64_IMM14
;
3903 fix
->code
= BFD_RELOC_IA64_IMM22
;
3905 if (e
->X_op
!= O_subtract
)
3907 fix
->code
= ia64_gen_real_reloc_type (e
->X_op_symbol
, fix
->code
);
3908 if (e
->X_op
== O_pseudo_fixup
)
3912 fix
->opnd
= idesc
->operands
[index
];
3915 ++CURR_SLOT
.num_fixups
;
3918 else if (e
->X_op
!= O_constant
3919 && ! (e
->X_op
== O_big
&& opnd
== IA64_OPND_IMM8M1U8
))
3922 if (opnd
== IA64_OPND_IMM8M1U4
)
3924 /* Zero is not valid for unsigned compares that take an adjusted
3925 constant immediate range. */
3926 if (e
->X_add_number
== 0)
3929 /* Sign-extend 32-bit unsigned numbers, so that the following range
3930 checks will work. */
3931 val
= e
->X_add_number
;
3932 if (((val
& (~(bfd_vma
)0 << 32)) == 0)
3933 && ((val
& ((bfd_vma
)1 << 31)) != 0))
3934 val
= ((val
<< 32) >> 32);
3936 /* Check for 0x100000000. This is valid because
3937 0x100000000-1 is the same as ((uint32_t) -1). */
3938 if (val
== ((bfd_signed_vma
) 1 << 32))
3943 else if (opnd
== IA64_OPND_IMM8M1U8
)
3945 /* Zero is not valid for unsigned compares that take an adjusted
3946 constant immediate range. */
3947 if (e
->X_add_number
== 0)
3950 /* Check for 0x10000000000000000. */
3951 if (e
->X_op
== O_big
)
3953 if (generic_bignum
[0] == 0
3954 && generic_bignum
[1] == 0
3955 && generic_bignum
[2] == 0
3956 && generic_bignum
[3] == 0
3957 && generic_bignum
[4] == 1)
3963 val
= e
->X_add_number
- 1;
3965 else if (opnd
== IA64_OPND_IMM8M1
)
3966 val
= e
->X_add_number
- 1;
3967 else if (opnd
== IA64_OPND_IMM8U4
)
3969 /* Sign-extend 32-bit unsigned numbers, so that the following range
3970 checks will work. */
3971 val
= e
->X_add_number
;
3972 if (((val
& (~(bfd_vma
)0 << 32)) == 0)
3973 && ((val
& ((bfd_vma
)1 << 31)) != 0))
3974 val
= ((val
<< 32) >> 32);
3977 val
= e
->X_add_number
;
3979 if ((val
>= 0 && val
< ((bfd_vma
) 1 << (bits
- 1)))
3980 || (val
< 0 && -val
<= ((bfd_vma
) 1 << (bits
- 1))))
3984 case IA64_OPND_INC3
:
3985 /* +/- 1, 4, 8, 16 */
3986 val
= e
->X_add_number
;
3989 if (e
->X_op
== O_constant
3990 && (val
== 1 || val
== 4 || val
== 8 || val
== 16))
3994 case IA64_OPND_TGT25
:
3995 case IA64_OPND_TGT25b
:
3996 case IA64_OPND_TGT25c
:
3997 case IA64_OPND_TGT64
:
3998 if (e
->X_op
== O_symbol
)
4000 fix
= CURR_SLOT
.fixup
+ CURR_SLOT
.num_fixups
;
4001 if (opnd
== IA64_OPND_TGT25
)
4002 fix
->code
= BFD_RELOC_IA64_PCREL21F
;
4003 else if (opnd
== IA64_OPND_TGT25b
)
4004 fix
->code
= BFD_RELOC_IA64_PCREL21M
;
4005 else if (opnd
== IA64_OPND_TGT25c
)
4006 fix
->code
= BFD_RELOC_IA64_PCREL21B
;
4008 /* FIXME -- use appropriate relocation type */
4009 as_bad (_("long branch targets not implemented"));
4010 fix
->code
= ia64_gen_real_reloc_type (e
->X_op_symbol
, fix
->code
);
4011 fix
->opnd
= idesc
->operands
[index
];
4014 ++CURR_SLOT
.num_fixups
;
4017 case IA64_OPND_TAG13
:
4018 case IA64_OPND_TAG13b
:
4025 fix
= CURR_SLOT
.fixup
+ CURR_SLOT
.num_fixups
;
4026 fix
->code
= ia64_gen_real_reloc_type (e
->X_op_symbol
, 0);
4027 fix
->opnd
= idesc
->operands
[index
];
4030 ++CURR_SLOT
.num_fixups
;
4050 memset (e
, 0, sizeof (*e
));
4053 if (*input_line_pointer
!= '}')
4055 sep
= *input_line_pointer
++;
4059 if (!md
.manual_bundling
)
4060 as_warn ("Found '}' when manual bundling is off");
4062 CURR_SLOT
.manual_bundling_off
= 1;
4063 md
.manual_bundling
= 0;
4069 /* Returns the next entry in the opcode table that matches the one in
4070 IDESC, and frees the entry in IDESC. If no matching entry is
4071 found, NULL is returned instead. */
4073 static struct ia64_opcode
*
4074 get_next_opcode (struct ia64_opcode
*idesc
)
4076 struct ia64_opcode
*next
= ia64_find_next_opcode (idesc
);
4077 ia64_free_opcode (idesc
);
4081 /* Parse the operands for the opcode and find the opcode variant that
4082 matches the specified operands, or NULL if no match is possible. */
4083 static struct ia64_opcode
*
4084 parse_operands (idesc
)
4085 struct ia64_opcode
*idesc
;
4087 int i
= 0, highest_unmatched_operand
, num_operands
= 0, num_outputs
= 0;
4089 enum ia64_opnd expected_operand
= IA64_OPND_NIL
;
4091 char *first_arg
= 0, *end
, *saved_input_pointer
;
4094 assert (strlen (idesc
->name
) <= 128);
4096 strcpy (mnemonic
, idesc
->name
);
4097 if (idesc
->operands
[2] == IA64_OPND_SOF
)
4099 /* To make the common idiom "alloc loc?=ar.pfs,0,1,0,0" work, we
4100 can't parse the first operand until we have parsed the
4101 remaining operands of the "alloc" instruction. */
4103 first_arg
= input_line_pointer
;
4104 end
= strchr (input_line_pointer
, '=');
4107 as_bad ("Expected separator `='");
4110 input_line_pointer
= end
+ 1;
4115 for (; i
< NELEMS (CURR_SLOT
.opnd
); ++i
)
4117 sep
= parse_operand (CURR_SLOT
.opnd
+ i
);
4118 if (CURR_SLOT
.opnd
[i
].X_op
== O_absent
)
4123 if (sep
!= '=' && sep
!= ',')
4128 if (num_outputs
> 0)
4129 as_bad ("Duplicate equal sign (=) in instruction");
4131 num_outputs
= i
+ 1;
4136 as_bad ("Illegal operand separator `%c'", sep
);
4140 if (idesc
->operands
[2] == IA64_OPND_SOF
)
4142 /* map alloc r1=ar.pfs,i,l,o,r to alloc r1=ar.pfs,(i+l+o),(i+l),r */
4143 know (strcmp (idesc
->name
, "alloc") == 0);
4144 if (num_operands
== 5 /* first_arg not included in this count! */
4145 && CURR_SLOT
.opnd
[2].X_op
== O_constant
4146 && CURR_SLOT
.opnd
[3].X_op
== O_constant
4147 && CURR_SLOT
.opnd
[4].X_op
== O_constant
4148 && CURR_SLOT
.opnd
[5].X_op
== O_constant
)
4150 sof
= set_regstack (CURR_SLOT
.opnd
[2].X_add_number
,
4151 CURR_SLOT
.opnd
[3].X_add_number
,
4152 CURR_SLOT
.opnd
[4].X_add_number
,
4153 CURR_SLOT
.opnd
[5].X_add_number
);
4155 /* now we can parse the first arg: */
4156 saved_input_pointer
= input_line_pointer
;
4157 input_line_pointer
= first_arg
;
4158 sep
= parse_operand (CURR_SLOT
.opnd
+ 0);
4160 --num_outputs
; /* force error */
4161 input_line_pointer
= saved_input_pointer
;
4163 CURR_SLOT
.opnd
[2].X_add_number
= sof
;
4164 CURR_SLOT
.opnd
[3].X_add_number
4165 = sof
- CURR_SLOT
.opnd
[4].X_add_number
;
4166 CURR_SLOT
.opnd
[4] = CURR_SLOT
.opnd
[5];
4170 highest_unmatched_operand
= 0;
4171 expected_operand
= idesc
->operands
[0];
4172 for (; idesc
; idesc
= get_next_opcode (idesc
))
4174 if (num_outputs
!= idesc
->num_outputs
)
4175 continue; /* mismatch in # of outputs */
4177 CURR_SLOT
.num_fixups
= 0;
4178 for (i
= 0; i
< num_operands
&& idesc
->operands
[i
]; ++i
)
4179 if (!operand_match (idesc
, i
, CURR_SLOT
.opnd
+ i
))
4182 if (i
!= num_operands
)
4184 if (i
> highest_unmatched_operand
)
4186 highest_unmatched_operand
= i
;
4187 expected_operand
= idesc
->operands
[i
];
4192 if (num_operands
< NELEMS (idesc
->operands
)
4193 && idesc
->operands
[num_operands
])
4194 continue; /* mismatch in number of arguments */
4200 if (expected_operand
)
4201 as_bad ("Operand %u of `%s' should be %s",
4202 highest_unmatched_operand
+ 1, mnemonic
,
4203 elf64_ia64_operands
[expected_operand
].desc
);
4205 as_bad ("Operand mismatch");
4212 build_insn (slot
, insnp
)
4216 const struct ia64_operand
*odesc
, *o2desc
;
4217 struct ia64_opcode
*idesc
= slot
->idesc
;
4218 bfd_signed_vma insn
, val
;
4222 insn
= idesc
->opcode
| slot
->qp_regno
;
4224 for (i
= 0; i
< NELEMS (idesc
->operands
) && idesc
->operands
[i
]; ++i
)
4226 if (idesc
->operands
[i
] == IA64_OPND_IMMU64
)
4228 val
= slot
->opnd
[i
].X_add_number
;
4229 *insnp
++ = (val
>> 22) & 0x1ffffffffffLL
;
4230 insn
|= (((val
& 0x7f) << 13) | (((val
>> 7) & 0x1ff) << 27)
4231 | (((val
>> 16) & 0x1f) << 22) | (((val
>> 21) & 0x1) << 21)
4232 | (((val
>> 63) & 0x1) << 36));
4234 else if (idesc
->operands
[i
] == IA64_OPND_IMMU62
)
4236 val
= slot
->opnd
[i
].X_add_number
& 0x3fffffffffffffffULL
;
4237 if (val
!= slot
->opnd
[i
].X_add_number
)
4238 as_warn (_("Value truncated to 62 bits"));
4239 *insnp
++ = (val
>> 21) & 0x1ffffffffffLL
;
4240 insn
|= (((val
& 0xfffff) << 6) | (((val
>> 20) & 0x1) << 36));
4242 else if (idesc
->operands
[i
] == IA64_OPND_TGT64
)
4244 // FIXME -- need to implement the target address encoding properly
4245 as_bad (_("long branch target encoding not implemented"));
4248 else if (slot
->opnd
[i
].X_op
== O_register
4249 || slot
->opnd
[i
].X_op
== O_constant
4250 || slot
->opnd
[i
].X_op
== O_index
4251 || slot
->opnd
[i
].X_op
== O_big
)
4253 if (slot
->opnd
[i
].X_op
== O_big
)
4255 /* This must be the value 0x10000000000000000. */
4256 assert (idesc
->operands
[i
] == IA64_OPND_IMM8M1U8
);
4260 val
= slot
->opnd
[i
].X_add_number
;
4262 switch (idesc
->operands
[i
])
4264 case IA64_OPND_AR3
: val
-= REG_AR
; break;
4265 case IA64_OPND_B1
: case IA64_OPND_B2
: val
-= REG_BR
; break;
4266 case IA64_OPND_CR3
: val
-= REG_CR
; break;
4267 case IA64_OPND_F1
: case IA64_OPND_F2
:
4268 case IA64_OPND_F3
: case IA64_OPND_F4
: val
-= REG_FR
; break;
4269 case IA64_OPND_P1
: case IA64_OPND_P2
: val
-= REG_P
; break;
4271 case IA64_OPND_R1
: case IA64_OPND_R2
:
4272 case IA64_OPND_R3
: case IA64_OPND_R3_2
:
4273 case IA64_OPND_CPUID_R3
: case IA64_OPND_DBR_R3
:
4274 case IA64_OPND_DTR_R3
: case IA64_OPND_ITR_R3
:
4275 case IA64_OPND_IBR_R3
: case IA64_OPND_MR3
:
4276 case IA64_OPND_MSR_R3
: case IA64_OPND_PKR_R3
:
4277 case IA64_OPND_PMC_R3
: case IA64_OPND_PMD_R3
:
4278 case IA64_OPND_RR_R3
:
4285 odesc
= elf64_ia64_operands
+ idesc
->operands
[i
];
4286 err
= (*odesc
->insert
) (odesc
, val
, &insn
);
4288 as_bad_where (slot
->src_file
, slot
->src_line
,
4289 "Bad operand value: %s", err
);
4290 if (idesc
->flags
& IA64_OPCODE_PSEUDO
)
4292 if ((idesc
->flags
& IA64_OPCODE_F2_EQ_F3
)
4293 && odesc
== elf64_ia64_operands
+ IA64_OPND_F3
)
4295 o2desc
= elf64_ia64_operands
+ IA64_OPND_F2
;
4296 (*o2desc
->insert
) (o2desc
, val
, &insn
);
4299 if ((idesc
->flags
& IA64_OPCODE_LEN_EQ_64MCNT
)
4300 && (odesc
== elf64_ia64_operands
+ IA64_OPND_CPOS6a
4301 || odesc
== elf64_ia64_operands
+ IA64_OPND_POS6
))
4303 o2desc
= elf64_ia64_operands
+ IA64_OPND_LEN6
;
4304 (*o2desc
->insert
) (o2desc
, 64 - val
, &insn
);
4315 unsigned int manual_bundling_on
= 0, manual_bundling_off
= 0;
4316 unsigned int manual_bundling
= 0;
4317 enum ia64_unit required_unit
, insn_unit
= 0;
4318 enum ia64_insn_type type
[3], insn_type
;
4319 unsigned int template, orig_template
;
4320 bfd_vma insn
[3] = {-1, -1, -1};
4321 struct ia64_opcode
*idesc
;
4322 int end_of_insn_group
= 0, user_template
= -1;
4323 int n
, i
, j
, first
, curr
;
4324 bfd_vma t0
= 0, t1
= 0;
4325 struct label_fix
*lfix
;
4326 struct insn_fix
*ifix
;
4331 first
= (md
.curr_slot
+ NUM_SLOTS
- md
.num_slots_in_use
) % NUM_SLOTS
;
4332 know (first
>= 0 & first
< NUM_SLOTS
);
4333 n
= MIN (3, md
.num_slots_in_use
);
4335 /* Determine template: user user_template if specified, best match
4338 if (md
.slot
[first
].user_template
>= 0)
4339 user_template
= template = md
.slot
[first
].user_template
;
4342 /* auto select appropriate template */
4343 memset (type
, 0, sizeof (type
));
4345 for (i
= 0; i
< n
; ++i
)
4347 type
[i
] = md
.slot
[curr
].idesc
->type
;
4348 curr
= (curr
+ 1) % NUM_SLOTS
;
4350 template = best_template
[type
[0]][type
[1]][type
[2]];
4353 /* initialize instructions with appropriate nops: */
4354 for (i
= 0; i
< 3; ++i
)
4355 insn
[i
] = nop
[ia64_templ_desc
[template].exec_unit
[i
]];
4359 /* now fill in slots with as many insns as possible: */
4361 idesc
= md
.slot
[curr
].idesc
;
4362 end_of_insn_group
= 0;
4363 for (i
= 0; i
< 3 && md
.num_slots_in_use
> 0; ++i
)
4365 if (idesc
->flags
& IA64_OPCODE_SLOT2
)
4367 if (manual_bundling
&& i
!= 2)
4368 as_bad_where (md
.slot
[curr
].src_file
, md
.slot
[curr
].src_line
,
4369 "`%s' must be last in bundle", idesc
->name
);
4373 if (idesc
->flags
& IA64_OPCODE_LAST
)
4375 int required_slot
, required_template
;
4377 /* If we need a stop bit after an M slot, our only choice is
4378 template 5 (M;;MI). If we need a stop bit after a B
4379 slot, our only choice is to place it at the end of the
4380 bundle, because the only available templates are MIB,
4381 MBB, BBB, MMB, and MFB. We don't handle anything other
4382 than M and B slots because these are the only kind of
4383 instructions that can have the IA64_OPCODE_LAST bit set. */
4384 required_template
= template;
4385 switch (idesc
->type
)
4389 required_template
= 5;
4397 as_bad_where (md
.slot
[curr
].src_file
, md
.slot
[curr
].src_line
,
4398 "Internal error: don't know how to force %s to end"
4399 "of instruction group", idesc
->name
);
4403 if (manual_bundling
&& i
!= required_slot
)
4404 as_bad_where (md
.slot
[curr
].src_file
, md
.slot
[curr
].src_line
,
4405 "`%s' must be last in instruction group",
4407 if (required_slot
< i
)
4408 /* Can't fit this instruction. */
4412 if (required_template
!= template)
4414 /* If we switch the template, we need to reset the NOPs
4415 after slot i. The slot-types of the instructions ahead
4416 of i never change, so we don't need to worry about
4417 changing NOPs in front of this slot. */
4418 for (j
= i
; j
< 3; ++j
)
4419 insn
[j
] = nop
[ia64_templ_desc
[required_template
].exec_unit
[j
]];
4421 template = required_template
;
4423 if (curr
!= first
&& md
.slot
[curr
].label_fixups
)
4425 if (manual_bundling_on
)
4426 as_bad_where (md
.slot
[curr
].src_file
, md
.slot
[curr
].src_line
,
4427 "Label must be first in a bundle");
4428 /* This insn must go into the first slot of a bundle. */
4432 manual_bundling_on
= md
.slot
[curr
].manual_bundling_on
;
4433 manual_bundling_off
= md
.slot
[curr
].manual_bundling_off
;
4435 if (manual_bundling_on
)
4438 manual_bundling
= 1;
4440 break; /* need to start a new bundle */
4443 if (end_of_insn_group
&& md
.num_slots_in_use
>= 1)
4445 /* We need an instruction group boundary in the middle of a
4446 bundle. See if we can switch to an other template with
4447 an appropriate boundary. */
4449 orig_template
= template;
4450 if (i
== 1 && (user_template
== 4
4451 || (user_template
< 0
4452 && (ia64_templ_desc
[template].exec_unit
[0]
4456 end_of_insn_group
= 0;
4458 else if (i
== 2 && (user_template
== 0
4459 || (user_template
< 0
4460 && (ia64_templ_desc
[template].exec_unit
[1]
4462 /* This test makes sure we don't switch the template if
4463 the next instruction is one that needs to be first in
4464 an instruction group. Since all those instructions are
4465 in the M group, there is no way such an instruction can
4466 fit in this bundle even if we switch the template. The
4467 reason we have to check for this is that otherwise we
4468 may end up generating "MI;;I M.." which has the deadly
4469 effect that the second M instruction is no longer the
4470 first in the bundle! --davidm 99/12/16 */
4471 && (idesc
->flags
& IA64_OPCODE_FIRST
) == 0)
4474 end_of_insn_group
= 0;
4476 else if (curr
!= first
)
4477 /* can't fit this insn */
4480 if (template != orig_template
)
4481 /* if we switch the template, we need to reset the NOPs
4482 after slot i. The slot-types of the instructions ahead
4483 of i never change, so we don't need to worry about
4484 changing NOPs in front of this slot. */
4485 for (j
= i
; j
< 3; ++j
)
4486 insn
[j
] = nop
[ia64_templ_desc
[template].exec_unit
[j
]];
4488 required_unit
= ia64_templ_desc
[template].exec_unit
[i
];
4490 /* resolve dynamic opcodes such as "break" and "nop": */
4491 if (idesc
->type
== IA64_TYPE_DYN
)
4493 if ((strcmp (idesc
->name
, "nop") == 0)
4494 || (strcmp (idesc
->name
, "break") == 0))
4495 insn_unit
= required_unit
;
4496 else if (strcmp (idesc
->name
, "chk.s") == 0)
4498 insn_unit
= IA64_UNIT_M
;
4499 if (required_unit
== IA64_UNIT_I
)
4500 insn_unit
= IA64_UNIT_I
;
4503 as_fatal ("emit_one_bundle: unexpected dynamic op");
4505 sprintf (mnemonic
, "%s.%c", idesc
->name
, "?imbf??"[insn_unit
]);
4506 md
.slot
[curr
].idesc
= idesc
= ia64_find_opcode (mnemonic
);
4508 know (!idesc
->next
); /* no resolved dynamic ops have collisions */
4513 insn_type
= idesc
->type
;
4514 insn_unit
= IA64_UNIT_NIL
;
4518 if (required_unit
== IA64_UNIT_I
|| required_unit
== IA64_UNIT_M
)
4519 insn_unit
= required_unit
;
4521 case IA64_TYPE_X
: insn_unit
= IA64_UNIT_L
; break;
4522 case IA64_TYPE_I
: insn_unit
= IA64_UNIT_I
; break;
4523 case IA64_TYPE_M
: insn_unit
= IA64_UNIT_M
; break;
4524 case IA64_TYPE_B
: insn_unit
= IA64_UNIT_B
; break;
4525 case IA64_TYPE_F
: insn_unit
= IA64_UNIT_F
; break;
4530 if (insn_unit
!= required_unit
)
4532 if (required_unit
== IA64_UNIT_L
4533 && insn_unit
== IA64_UNIT_I
4534 && !(idesc
->flags
& IA64_OPCODE_X_IN_MLX
))
4536 /* we got ourselves an MLX template but the current
4537 instruction isn't an X-unit, or an I-unit instruction
4538 that can go into the X slot of an MLX template. Duh. */
4539 if (md
.num_slots_in_use
>= NUM_SLOTS
)
4541 as_bad_where (md
.slot
[curr
].src_file
,
4542 md
.slot
[curr
].src_line
,
4543 "`%s' can't go in X slot of "
4544 "MLX template", idesc
->name
);
4545 /* drop this insn so we don't livelock: */
4546 --md
.num_slots_in_use
;
4550 continue; /* try next slot */
4553 if (debug_type
== DEBUG_DWARF2
)
4557 addr
= frag_now
->fr_address
+ frag_now_fix () - 16 + 1*i
;
4558 dwarf2_gen_line_info (addr
, &md
.slot
[curr
].debug_line
);
4561 build_insn (md
.slot
+ curr
, insn
+ i
);
4563 /* Set slot counts for unwind records. */
4564 while (md
.slot
[curr
].unwind_record
)
4566 md
.slot
[curr
].unwind_record
->slot_number
= (unsigned long) (f
+ i
);
4567 md
.slot
[curr
].unwind_record
= md
.slot
[curr
].unwind_record
->next
;
4569 if (required_unit
== IA64_UNIT_L
)
4572 /* skip one slot for long/X-unit instructions */
4575 --md
.num_slots_in_use
;
4577 /* now is a good time to fix up the labels for this insn: */
4578 for (lfix
= md
.slot
[curr
].label_fixups
; lfix
; lfix
= lfix
->next
)
4580 S_SET_VALUE (lfix
->sym
, frag_now_fix () - 16);
4581 symbol_set_frag (lfix
->sym
, frag_now
);
4584 for (j
= 0; j
< md
.slot
[curr
].num_fixups
; ++j
)
4586 ifix
= md
.slot
[curr
].fixup
+ j
;
4587 fix
= fix_new_exp (frag_now
, frag_now_fix () - 16 + i
, 4,
4588 &ifix
->expr
, ifix
->is_pcrel
, ifix
->code
);
4589 fix
->tc_fix_data
.opnd
= ifix
->opnd
;
4590 fix
->fx_plt
= (fix
->fx_r_type
== BFD_RELOC_IA64_PLTOFF22
);
4591 fix
->fx_file
= md
.slot
[curr
].src_file
;
4592 fix
->fx_line
= md
.slot
[curr
].src_line
;
4595 end_of_insn_group
= md
.slot
[curr
].end_of_insn_group
;
4598 ia64_free_opcode (md
.slot
[curr
].idesc
);
4599 memset (md
.slot
+ curr
, 0, sizeof (md
.slot
[curr
]));
4600 md
.slot
[curr
].user_template
= -1;
4602 if (manual_bundling_off
)
4604 manual_bundling
= 0;
4607 curr
= (curr
+ 1) % NUM_SLOTS
;
4608 idesc
= md
.slot
[curr
].idesc
;
4610 if (manual_bundling
)
4612 if (md
.num_slots_in_use
> 0)
4613 as_bad_where (md
.slot
[curr
].src_file
, md
.slot
[curr
].src_line
,
4614 "`%s' does not fit into %s template",
4615 idesc
->name
, ia64_templ_desc
[template].name
);
4617 as_bad_where (md
.slot
[curr
].src_file
, md
.slot
[curr
].src_line
,
4618 "Missing '}' at end of file");
4620 know (md
.num_slots_in_use
< NUM_SLOTS
);
4622 t0
= end_of_insn_group
| (template << 1) | (insn
[0] << 5) | (insn
[1] << 46);
4623 t1
= ((insn
[1] >> 18) & 0x7fffff) | (insn
[2] << 23);
4625 md_number_to_chars (f
+ 0, t0
, 8);
4626 md_number_to_chars (f
+ 8, t1
, 8);
4630 md_parse_option (c
, arg
)
4634 /* Switches from the Intel assembler. */
4638 if (strcmp (arg
, "ilp64") == 0
4639 || strcmp (arg
, "lp64") == 0
4640 || strcmp (arg
, "p64") == 0)
4642 md
.flags
|= EF_IA_64_ABI64
;
4644 else if (strcmp (arg
, "ilp32") == 0)
4646 md
.flags
&= ~EF_IA_64_ABI64
;
4648 else if (strcmp (arg
, "le") == 0)
4650 md
.flags
&= ~EF_IA_64_BE
;
4652 else if (strcmp (arg
, "be") == 0)
4654 md
.flags
|= EF_IA_64_BE
;
4661 if (strcmp (arg
, "so") == 0)
4663 /* Suppress signon message. */
4665 else if (strcmp (arg
, "pi") == 0)
4667 /* Reject privileged instructions. FIXME */
4669 else if (strcmp (arg
, "us") == 0)
4671 /* Allow union of signed and unsigned range. FIXME */
4673 else if (strcmp (arg
, "close_fcalls") == 0)
4675 /* Do not resolve global function calls. */
4682 /* temp[="prefix"] Insert temporary labels into the object file
4683 symbol table prefixed by "prefix".
4684 Default prefix is ":temp:".
4689 /* ??? Conflicts with gas' listing option. */
4690 /* indirect=<tgt> Assume unannotated indirect branches behavior
4691 according to <tgt> --
4692 exit: branch out from the current context (default)
4693 labels: all labels in context may be branch targets
4698 /* -X conflicts with an ignored option, use -x instead */
4700 if (!arg
|| strcmp (arg
, "explicit") == 0)
4702 /* set default mode to explicit */
4703 md
.default_explicit_mode
= 1;
4706 else if (strcmp (arg
, "auto") == 0)
4708 md
.default_explicit_mode
= 0;
4710 else if (strcmp (arg
, "debug") == 0)
4714 else if (strcmp (arg
, "debugx") == 0)
4716 md
.default_explicit_mode
= 1;
4721 as_bad (_("Unrecognized option '-x%s'"), arg
);
4726 /* nops Print nops statistics. */
4737 md_show_usage (stream
)
4742 -Milp32|-Milp64|-Mlp64|-Mp64 select data model (default -Mlp64)\n\
4743 -Mle | -Mbe select little- or big-endian byte order (default -Mle)\n\
4744 -x | -xexplicit turn on dependency violation checking (default)\n\
4745 -xauto automagically remove dependency violations\n\
4746 -xdebug debug dependency violation checker\n"),
4751 match (int templ
, int type
, int slot
)
4753 enum ia64_unit unit
;
4756 unit
= ia64_templ_desc
[templ
].exec_unit
[slot
];
4759 case IA64_TYPE_DYN
: result
= 1; break; /* for nop and break */
4761 result
= (unit
== IA64_UNIT_I
|| unit
== IA64_UNIT_M
);
4763 case IA64_TYPE_X
: result
= (unit
== IA64_UNIT_L
); break;
4764 case IA64_TYPE_I
: result
= (unit
== IA64_UNIT_I
); break;
4765 case IA64_TYPE_M
: result
= (unit
== IA64_UNIT_M
); break;
4766 case IA64_TYPE_B
: result
= (unit
== IA64_UNIT_B
); break;
4767 case IA64_TYPE_F
: result
= (unit
== IA64_UNIT_F
); break;
4768 default: result
= 0; break;
4773 /* This function is called once, at assembler startup time. It sets
4774 up all the tables, etc. that the MD part of the assembler will need
4775 that can be determined before arguments are parsed. */
4779 int i
, j
, k
, t
, total
, ar_base
, cr_base
, goodness
, best
, regnum
;
4784 md
.explicit_mode
= md
.default_explicit_mode
;
4786 bfd_set_section_alignment (stdoutput
, text_section
, 4);
4788 target_big_endian
= 0;
4789 pseudo_func
[FUNC_FPTR_RELATIVE
].u
.sym
=
4790 symbol_new (".<fptr>", undefined_section
, FUNC_FPTR_RELATIVE
,
4791 &zero_address_frag
);
4793 pseudo_func
[FUNC_GP_RELATIVE
].u
.sym
=
4794 symbol_new (".<gprel>", undefined_section
, FUNC_GP_RELATIVE
,
4795 &zero_address_frag
);
4797 pseudo_func
[FUNC_LT_RELATIVE
].u
.sym
=
4798 symbol_new (".<ltoff>", undefined_section
, FUNC_LT_RELATIVE
,
4799 &zero_address_frag
);
4801 pseudo_func
[FUNC_PLT_RELATIVE
].u
.sym
=
4802 symbol_new (".<pltoff>", undefined_section
, FUNC_PLT_RELATIVE
,
4803 &zero_address_frag
);
4805 pseudo_func
[FUNC_SEC_RELATIVE
].u
.sym
=
4806 symbol_new (".<secrel>", undefined_section
, FUNC_SEC_RELATIVE
,
4807 &zero_address_frag
);
4809 pseudo_func
[FUNC_SEG_RELATIVE
].u
.sym
=
4810 symbol_new (".<segrel>", undefined_section
, FUNC_SEG_RELATIVE
,
4811 &zero_address_frag
);
4813 pseudo_func
[FUNC_LTV_RELATIVE
].u
.sym
=
4814 symbol_new (".<ltv>", undefined_section
, FUNC_LTV_RELATIVE
,
4815 &zero_address_frag
);
4817 pseudo_func
[FUNC_LT_FPTR_RELATIVE
].u
.sym
=
4818 symbol_new (".<ltoff.fptr>", undefined_section
, FUNC_LT_FPTR_RELATIVE
,
4819 &zero_address_frag
);
4821 /* compute the table of best templates: */
4822 for (i
= 0; i
< IA64_NUM_TYPES
; ++i
)
4823 for (j
= 0; j
< IA64_NUM_TYPES
; ++j
)
4824 for (k
= 0; k
< IA64_NUM_TYPES
; ++k
)
4827 for (t
= 0; t
< NELEMS (ia64_templ_desc
); ++t
)
4830 if (match (t
, i
, 0))
4832 if (match (t
, j
, 1))
4834 if (match (t
, k
, 2))
4839 else if (match (t
, j
, 2))
4844 else if (match (t
, i
, 1))
4846 if (match (t
, j
, 2))
4851 else if (match (t
, i
, 2))
4854 if (goodness
> best
)
4857 best_template
[i
][j
][k
] = t
;
4862 for (i
= 0; i
< NUM_SLOTS
; ++i
)
4863 md
.slot
[i
].user_template
= -1;
4865 md
.pseudo_hash
= hash_new ();
4866 for (i
= 0; i
< NELEMS (pseudo_opcode
); ++i
)
4868 err
= hash_insert (md
.pseudo_hash
, pseudo_opcode
[i
].name
,
4869 (void *) (pseudo_opcode
+ i
));
4871 as_fatal ("ia64.md_begin: can't hash `%s': %s",
4872 pseudo_opcode
[i
].name
, err
);
4875 md
.reg_hash
= hash_new ();
4876 md
.dynreg_hash
= hash_new ();
4877 md
.const_hash
= hash_new ();
4878 md
.entry_hash
= hash_new ();
4880 /* general registers: */
4883 for (i
= 0; i
< total
; ++i
)
4885 sprintf (name
, "r%d", i
- REG_GR
);
4886 md
.regsym
[i
] = declare_register (name
, i
);
4889 /* floating point registers: */
4891 for (; i
< total
; ++i
)
4893 sprintf (name
, "f%d", i
- REG_FR
);
4894 md
.regsym
[i
] = declare_register (name
, i
);
4897 /* application registers: */
4900 for (; i
< total
; ++i
)
4902 sprintf (name
, "ar%d", i
- REG_AR
);
4903 md
.regsym
[i
] = declare_register (name
, i
);
4906 /* control registers: */
4909 for (; i
< total
; ++i
)
4911 sprintf (name
, "cr%d", i
- REG_CR
);
4912 md
.regsym
[i
] = declare_register (name
, i
);
4915 /* predicate registers: */
4917 for (; i
< total
; ++i
)
4919 sprintf (name
, "p%d", i
- REG_P
);
4920 md
.regsym
[i
] = declare_register (name
, i
);
4923 /* branch registers: */
4925 for (; i
< total
; ++i
)
4927 sprintf (name
, "b%d", i
- REG_BR
);
4928 md
.regsym
[i
] = declare_register (name
, i
);
4931 md
.regsym
[REG_IP
] = declare_register ("ip", REG_IP
);
4932 md
.regsym
[REG_CFM
] = declare_register ("cfm", REG_CFM
);
4933 md
.regsym
[REG_PR
] = declare_register ("pr", REG_PR
);
4934 md
.regsym
[REG_PR_ROT
] = declare_register ("pr.rot", REG_PR_ROT
);
4935 md
.regsym
[REG_PSR
] = declare_register ("psr", REG_PSR
);
4936 md
.regsym
[REG_PSR_L
] = declare_register ("psr.l", REG_PSR_L
);
4937 md
.regsym
[REG_PSR_UM
] = declare_register ("psr.um", REG_PSR_UM
);
4939 for (i
= 0; i
< NELEMS (indirect_reg
); ++i
)
4941 regnum
= indirect_reg
[i
].regnum
;
4942 md
.regsym
[regnum
] = declare_register (indirect_reg
[i
].name
, regnum
);
4945 /* define synonyms for application registers: */
4946 for (i
= REG_AR
; i
< REG_AR
+ NELEMS (ar
); ++i
)
4947 md
.regsym
[i
] = declare_register (ar
[i
- REG_AR
].name
,
4948 REG_AR
+ ar
[i
- REG_AR
].regnum
);
4950 /* define synonyms for control registers: */
4951 for (i
= REG_CR
; i
< REG_CR
+ NELEMS (cr
); ++i
)
4952 md
.regsym
[i
] = declare_register (cr
[i
- REG_CR
].name
,
4953 REG_CR
+ cr
[i
- REG_CR
].regnum
);
4955 declare_register ("gp", REG_GR
+ 1);
4956 declare_register ("sp", REG_GR
+ 12);
4957 declare_register ("rp", REG_BR
+ 0);
4959 declare_register_set ("ret", 4, REG_GR
+ 8);
4960 declare_register_set ("farg", 8, REG_FR
+ 8);
4961 declare_register_set ("fret", 8, REG_FR
+ 8);
4963 for (i
= 0; i
< NELEMS (const_bits
); ++i
)
4965 err
= hash_insert (md
.const_hash
, const_bits
[i
].name
,
4966 (PTR
) (const_bits
+ i
));
4968 as_fatal ("Inserting \"%s\" into constant hash table failed: %s",
4972 /* Default to 64-bit mode. */
4973 md
.flags
= EF_IA_64_ABI64
;
4975 md
.mem_offset
.hint
= 0;
4978 md
.entry_labels
= NULL
;
4982 ia64_end_of_source ()
4984 /* terminate insn group upon reaching end of file: */
4985 insn_group_break (1, 0, 0);
4987 /* emits slots we haven't written yet: */
4988 ia64_flush_insns ();
4990 bfd_set_private_flags (stdoutput
, md
.flags
);
4992 if (debug_type
== DEBUG_DWARF2
)
4995 md
.mem_offset
.hint
= 0;
5001 md
.qp
.X_op
= O_absent
;
5003 if (ignore_input ())
5006 if (input_line_pointer
[0] == ';' && input_line_pointer
[-1] == ';')
5008 if (md
.detect_dv
&& !md
.explicit_mode
)
5009 as_warn (_("Explicit stops are ignored in auto mode"));
5011 insn_group_break (1, 0, 0);
5016 ia64_unrecognized_line (ch
)
5022 expression (&md
.qp
);
5023 if (*input_line_pointer
++ != ')')
5025 as_bad ("Expected ')'");
5028 if (md
.qp
.X_op
!= O_register
)
5030 as_bad ("Qualifying predicate expected");
5033 if (md
.qp
.X_add_number
< REG_P
|| md
.qp
.X_add_number
>= REG_P
+ 64)
5035 as_bad ("Predicate register expected");
5041 if (md
.manual_bundling
)
5042 as_warn ("Found '{' when manual bundling is already turned on");
5044 CURR_SLOT
.manual_bundling_on
= 1;
5045 md
.manual_bundling
= 1;
5047 /* bundling is only acceptable in explicit mode
5048 or when in default automatic mode */
5049 if (md
.detect_dv
&& !md
.explicit_mode
)
5051 if (!md
.mode_explicitly_set
5052 && !md
.default_explicit_mode
)
5055 as_warn (_("Found '{' after explicit switch to automatic mode"));
5060 if (!md
.manual_bundling
)
5061 as_warn ("Found '}' when manual bundling is off");
5063 PREV_SLOT
.manual_bundling_off
= 1;
5064 md
.manual_bundling
= 0;
5066 /* switch back to automatic mode, if applicable */
5069 && !md
.mode_explicitly_set
5070 && !md
.default_explicit_mode
)
5073 /* Allow '{' to follow on the same line. We also allow ";;", but that
5074 happens automatically because ';' is an end of line marker. */
5076 if (input_line_pointer
[0] == '{')
5078 input_line_pointer
++;
5079 return ia64_unrecognized_line ('{');
5082 demand_empty_rest_of_line ();
5088 return 0; /* not a valid line */
5092 ia64_frob_label (sym
)
5095 struct label_fix
*fix
;
5097 if (bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
)
5099 md
.last_text_seg
= now_seg
;
5100 fix
= obstack_alloc (¬es
, sizeof (*fix
));
5102 fix
->next
= CURR_SLOT
.label_fixups
;
5103 CURR_SLOT
.label_fixups
= fix
;
5105 /* keep track of how many code entry points we've seen */
5106 if (md
.path
== md
.maxpaths
)
5109 md
.entry_labels
= (const char **)
5110 xrealloc ((void *)md
.entry_labels
, md
.maxpaths
* sizeof (char *));
5112 md
.entry_labels
[md
.path
++] = S_GET_NAME (sym
);
5117 ia64_flush_pending_output ()
5119 if (bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
)
5121 /* ??? This causes many unnecessary stop bits to be emitted.
5122 Unfortunately, it isn't clear if it is safe to remove this. */
5123 insn_group_break (1, 0, 0);
5124 ia64_flush_insns ();
5128 /* Do ia64-specific expression optimization. All that's done here is
5129 to transform index expressions that are either due to the indexing
5130 of rotating registers or due to the indexing of indirect register
5133 ia64_optimize_expr (l
, op
, r
)
5142 if (l
->X_op
== O_register
&& r
->X_op
== O_constant
)
5144 num_regs
= (l
->X_add_number
>> 16);
5145 if ((unsigned) r
->X_add_number
>= num_regs
)
5148 as_bad ("No current frame");
5150 as_bad ("Index out of range 0..%u", num_regs
- 1);
5151 r
->X_add_number
= 0;
5153 l
->X_add_number
= (l
->X_add_number
& 0xffff) + r
->X_add_number
;
5156 else if (l
->X_op
== O_register
&& r
->X_op
== O_register
)
5158 if (l
->X_add_number
< IND_CPUID
|| l
->X_add_number
> IND_RR
5159 || l
->X_add_number
== IND_MEM
)
5161 as_bad ("Indirect register set name expected");
5162 l
->X_add_number
= IND_CPUID
;
5165 l
->X_op_symbol
= md
.regsym
[l
->X_add_number
];
5166 l
->X_add_number
= r
->X_add_number
;
5174 ia64_parse_name (name
, e
)
5178 struct const_desc
*cdesc
;
5179 struct dynreg
*dr
= 0;
5180 unsigned int regnum
;
5184 /* first see if NAME is a known register name: */
5185 sym
= hash_find (md
.reg_hash
, name
);
5188 e
->X_op
= O_register
;
5189 e
->X_add_number
= S_GET_VALUE (sym
);
5193 cdesc
= hash_find (md
.const_hash
, name
);
5196 e
->X_op
= O_constant
;
5197 e
->X_add_number
= cdesc
->value
;
5201 /* check for inN, locN, or outN: */
5205 if (name
[1] == 'n' && isdigit (name
[2]))
5213 if (name
[1] == 'o' && name
[2] == 'c' && isdigit (name
[3]))
5221 if (name
[1] == 'u' && name
[2] == 't' && isdigit (name
[3]))
5234 /* the name is inN, locN, or outN; parse the register number: */
5235 regnum
= strtoul (name
, &end
, 10);
5236 if (end
> name
&& *end
== '\0')
5238 if ((unsigned) regnum
>= dr
->num_regs
)
5241 as_bad ("No current frame");
5243 as_bad ("Register number out of range 0..%u", dr
->num_regs
-1);
5246 e
->X_op
= O_register
;
5247 e
->X_add_number
= dr
->base
+ regnum
;
5252 if ((dr
= hash_find (md
.dynreg_hash
, name
)))
5254 /* We've got ourselves the name of a rotating register set.
5255 Store the base register number in the low 16 bits of
5256 X_add_number and the size of the register set in the top 16
5258 e
->X_op
= O_register
;
5259 e
->X_add_number
= dr
->base
| (dr
->num_regs
<< 16);
5265 /* Remove the '#' suffix that indicates a symbol as opposed to a register. */
5268 ia64_canonicalize_symbol_name (name
)
5271 size_t len
= strlen(name
);
5272 if (len
> 1 && name
[len
-1] == '#')
5278 is_conditional_branch (idesc
)
5279 struct ia64_opcode
*idesc
;
5281 return (strncmp (idesc
->name
, "br", 2) == 0
5282 && (strcmp (idesc
->name
, "br") == 0
5283 || strncmp (idesc
->name
, "br.cond", 7) == 0
5284 || strncmp (idesc
->name
, "br.call", 7) == 0
5285 || strncmp (idesc
->name
, "br.ret", 6) == 0
5286 || strcmp (idesc
->name
, "brl") == 0
5287 || strncmp (idesc
->name
, "brl.cond", 7) == 0
5288 || strncmp (idesc
->name
, "brl.call", 7) == 0
5289 || strncmp (idesc
->name
, "brl.ret", 6) == 0));
5292 /* Return whether the given opcode is a taken branch. If there's any doubt,
5295 is_taken_branch (idesc
)
5296 struct ia64_opcode
*idesc
;
5298 return ((is_conditional_branch (idesc
) && CURR_SLOT
.qp_regno
== 0)
5299 || strncmp (idesc
->name
, "br.ia", 5) == 0);
5302 /* Return whether the given opcode is an interruption or rfi. If there's any
5303 doubt, returns zero */
5305 is_interruption_or_rfi (idesc
)
5306 struct ia64_opcode
*idesc
;
5308 if (strcmp (idesc
->name
, "rfi") == 0)
5313 /* Returns the index of the given dependency in the opcode's list of chks, or
5314 -1 if there is no dependency. */
5316 depends_on (depind
, idesc
)
5318 struct ia64_opcode
*idesc
;
5321 const struct ia64_opcode_dependency
*dep
= idesc
->dependencies
;
5322 for (i
= 0;i
< dep
->nchks
; i
++)
5324 if (depind
== DEP(dep
->chks
[i
]))
5330 /* Determine a set of specific resources used for a particular resource
5331 class. Returns the number of specific resources identified For those
5332 cases which are not determinable statically, the resource returned is
5335 Meanings of value in 'NOTE':
5336 1) only read/write when the register number is explicitly encoded in the
5338 2) only read CFM when accessing a rotating GR, FR, or PR. mov pr only
5339 accesses CFM when qualifying predicate is in the rotating region.
5340 3) general register value is used to specify an indirect register; not
5341 determinable statically.
5342 4) only read the given resource when bits 7:0 of the indirect index
5343 register value does not match the register number of the resource; not
5344 determinable statically.
5345 5) all rules are implementation specific.
5346 6) only when both the index specified by the reader and the index specified
5347 by the writer have the same value in bits 63:61; not determinable
5349 7) only access the specified resource when the corresponding mask bit is
5351 8) PSR.dfh is only read when these insns reference FR32-127. PSR.dfl is
5352 only read when these insns reference FR2-31
5353 9) PSR.mfl is only written when these insns write FR2-31. PSR.mfh is only
5354 written when these insns write FR32-127
5355 10) The PSR.bn bit is only accessed when one of GR16-31 is specified in the
5357 11) The target predicates are written independently of PR[qp], but source
5358 registers are only read if PR[qp] is true. Since the state of PR[qp]
5359 cannot statically be determined, all source registers are marked used.
5360 12) This insn only reads the specified predicate register when that
5361 register is the PR[qp].
5362 13) This reference to ld-c only applies to teh GR whose value is loaded
5363 with data returned from memory, not the post-incremented address register.
5364 14) The RSE resource includes the implementation-specific RSE internal
5365 state resources. At least one (and possibly more) of these resources are
5366 read by each instruction listed in IC:rse-readers. At least one (and
5367 possibly more) of these resources are written by each insn listed in
5369 15+16) Represents reserved instructions, which the assembler does not
5372 Memory resources (i.e. locations in memory) are *not* marked or tracked by
5373 this code; there are no dependency violations based on memory access.
5377 #define MAX_SPECS 256
5382 specify_resource (dep
, idesc
, type
, specs
, note
, path
)
5383 const struct ia64_dependency
*dep
;
5384 struct ia64_opcode
*idesc
;
5385 int type
; /* is this a DV chk or a DV reg? */
5386 struct rsrc specs
[MAX_SPECS
]; /* returned specific resources */
5387 int note
; /* resource note for this insn's usage */
5388 int path
; /* which execution path to examine */
5395 if (dep
->mode
== IA64_DV_WAW
5396 || (dep
->mode
== IA64_DV_RAW
&& type
== DV_REG
)
5397 || (dep
->mode
== IA64_DV_WAR
&& type
== DV_CHK
))
5400 /* template for any resources we identify */
5401 tmpl
.dependency
= dep
;
5403 tmpl
.insn_srlz
= tmpl
.data_srlz
= 0;
5404 tmpl
.qp_regno
= CURR_SLOT
.qp_regno
;
5405 tmpl
.link_to_qp_branch
= 1;
5406 tmpl
.mem_offset
.hint
= 0;
5411 as_warn (_("Unhandled dependency %s for %s (%s), note %d"), \
5412 dep->name, idesc->name, (rsrc_write?"write":"read"), note)
5413 #define KNOWN(REG) (gr_values[REG].known && gr_values[REG].path >= path)
5415 /* we don't need to track these */
5416 if (dep
->semantics
== IA64_DVS_NONE
)
5419 switch (dep
->specifier
)
5424 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_AR3
)
5426 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_AR
;
5427 if (regno
>= 0 && regno
<= 7)
5429 specs
[count
] = tmpl
;
5430 specs
[count
++].index
= regno
;
5438 specs
[count
] = tmpl
;
5439 specs
[count
++].index
= i
;
5448 case IA64_RS_AR_UNAT
:
5449 /* This is a mov =AR or mov AR= instruction. */
5450 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_AR3
)
5452 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_AR
;
5453 if (regno
== AR_UNAT
)
5455 specs
[count
++] = tmpl
;
5460 /* This is a spill/fill, or other instruction that modifies the
5463 /* Unless we can determine the specific bits used, mark the whole
5464 thing; bits 8:3 of the memory address indicate the bit used in
5465 UNAT. The .mem.offset hint may be used to eliminate a small
5466 subset of conflicts. */
5467 specs
[count
] = tmpl
;
5468 if (md
.mem_offset
.hint
)
5471 fprintf (stderr
, " Using hint for spill/fill\n");
5472 /* the index isn't actually used, just set it to something
5473 approximating the bit index */
5474 specs
[count
].index
= (md
.mem_offset
.offset
>> 3) & 0x3F;
5475 specs
[count
].mem_offset
.hint
= 1;
5476 specs
[count
].mem_offset
.offset
= md
.mem_offset
.offset
;
5477 specs
[count
++].mem_offset
.base
= md
.mem_offset
.base
;
5481 specs
[count
++].specific
= 0;
5489 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_AR3
)
5491 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_AR
;
5492 if ((regno
>= 8 && regno
<= 15)
5493 || (regno
>= 20 && regno
<= 23)
5494 || (regno
>= 31 && regno
<= 39)
5495 || (regno
>= 41 && regno
<= 47)
5496 || (regno
>= 67 && regno
<= 111))
5498 specs
[count
] = tmpl
;
5499 specs
[count
++].index
= regno
;
5512 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_AR3
)
5514 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_AR
;
5515 if ((regno
>= 48 && regno
<= 63)
5516 || (regno
>= 112 && regno
<= 127))
5518 specs
[count
] = tmpl
;
5519 specs
[count
++].index
= regno
;
5525 for (i
=48;i
< 64;i
++)
5527 specs
[count
] = tmpl
;
5528 specs
[count
++].index
= i
;
5530 for (i
=112;i
< 128;i
++)
5532 specs
[count
] = tmpl
;
5533 specs
[count
++].index
= i
;
5551 for (i
=0;i
< idesc
->num_outputs
;i
++)
5552 if (idesc
->operands
[i
] == IA64_OPND_B1
5553 || idesc
->operands
[i
] == IA64_OPND_B2
)
5555 specs
[count
] = tmpl
;
5556 specs
[count
++].index
=
5557 CURR_SLOT
.opnd
[i
].X_add_number
- REG_BR
;
5562 for (i
= idesc
->num_outputs
;i
< NELEMS(idesc
->operands
);i
++)
5563 if (idesc
->operands
[i
] == IA64_OPND_B1
5564 || idesc
->operands
[i
] == IA64_OPND_B2
)
5566 specs
[count
] = tmpl
;
5567 specs
[count
++].index
=
5568 CURR_SLOT
.opnd
[i
].X_add_number
- REG_BR
;
5574 case IA64_RS_CPUID
: /* four or more registers */
5577 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_CPUID_R3
)
5579 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_GR
;
5580 if (regno
>= 0 && regno
< NELEMS(gr_values
)
5583 specs
[count
] = tmpl
;
5584 specs
[count
++].index
= gr_values
[regno
].value
& 0xFF;
5588 specs
[count
] = tmpl
;
5589 specs
[count
++].specific
= 0;
5599 case IA64_RS_DBR
: /* four or more registers */
5602 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_DBR_R3
)
5604 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_GR
;
5605 if (regno
>= 0 && regno
< NELEMS(gr_values
)
5608 specs
[count
] = tmpl
;
5609 specs
[count
++].index
= gr_values
[regno
].value
& 0xFF;
5613 specs
[count
] = tmpl
;
5614 specs
[count
++].specific
= 0;
5618 else if (note
== 0 && !rsrc_write
)
5620 specs
[count
] = tmpl
;
5621 specs
[count
++].specific
= 0;
5629 case IA64_RS_IBR
: /* four or more registers */
5632 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_IBR_R3
)
5634 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_GR
;
5635 if (regno
>= 0 && regno
< NELEMS(gr_values
)
5638 specs
[count
] = tmpl
;
5639 specs
[count
++].index
= gr_values
[regno
].value
& 0xFF;
5643 specs
[count
] = tmpl
;
5644 specs
[count
++].specific
= 0;
5657 /* These are implementation specific. Force all references to
5658 conflict with all other references. */
5659 specs
[count
] = tmpl
;
5660 specs
[count
++].specific
= 0;
5668 case IA64_RS_PKR
: /* 16 or more registers */
5669 if (note
== 3 || note
== 4)
5671 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_PKR_R3
)
5673 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_GR
;
5674 if (regno
>= 0 && regno
< NELEMS(gr_values
)
5679 specs
[count
] = tmpl
;
5680 specs
[count
++].index
= gr_values
[regno
].value
& 0xFF;
5682 else for (i
=0;i
< NELEMS(gr_values
);i
++)
5684 /* uses all registers *except* the one in R3 */
5685 if (i
!= (gr_values
[regno
].value
& 0xFF))
5687 specs
[count
] = tmpl
;
5688 specs
[count
++].index
= i
;
5694 specs
[count
] = tmpl
;
5695 specs
[count
++].specific
= 0;
5702 specs
[count
] = tmpl
;
5703 specs
[count
++].specific
= 0;
5707 case IA64_RS_PMC
: /* four or more registers */
5710 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_PMC_R3
5711 || (!rsrc_write
&& idesc
->operands
[1] == IA64_OPND_PMD_R3
))
5714 int index
= ((idesc
->operands
[1] == IA64_OPND_R3
&& !rsrc_write
)
5716 int regno
= CURR_SLOT
.opnd
[index
].X_add_number
- REG_GR
;
5717 if (regno
>= 0 && regno
< NELEMS(gr_values
)
5720 specs
[count
] = tmpl
;
5721 specs
[count
++].index
= gr_values
[regno
].value
& 0xFF;
5725 specs
[count
] = tmpl
;
5726 specs
[count
++].specific
= 0;
5736 case IA64_RS_PMD
: /* four or more registers */
5739 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_PMD_R3
)
5741 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_GR
;
5742 if (regno
>= 0 && regno
< NELEMS(gr_values
)
5745 specs
[count
] = tmpl
;
5746 specs
[count
++].index
= gr_values
[regno
].value
& 0xFF;
5750 specs
[count
] = tmpl
;
5751 specs
[count
++].specific
= 0;
5761 case IA64_RS_RR
: /* eight registers */
5764 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_RR_R3
)
5766 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_GR
;
5767 if (regno
>= 0 && regno
< NELEMS(gr_values
)
5770 specs
[count
] = tmpl
;
5771 specs
[count
++].index
= (gr_values
[regno
].value
>> 61) & 0x7;
5775 specs
[count
] = tmpl
;
5776 specs
[count
++].specific
= 0;
5780 else if (note
== 0 && !rsrc_write
)
5782 specs
[count
] = tmpl
;
5783 specs
[count
++].specific
= 0;
5791 case IA64_RS_CR_IRR
:
5794 /* handle mov-from-CR-IVR; it's a read that writes CR[IRR] */
5795 int regno
= CURR_SLOT
.opnd
[1].X_add_number
- REG_CR
;
5797 && idesc
->operands
[1] == IA64_OPND_CR3
5802 specs
[count
] = tmpl
;
5803 specs
[count
++].index
= CR_IRR0
+ i
;
5809 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_CR
;
5810 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_CR3
5812 && regno
<= CR_IRR3
)
5814 specs
[count
] = tmpl
;
5815 specs
[count
++].index
= regno
;
5824 case IA64_RS_CR_LRR
:
5831 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_CR
;
5832 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_CR3
5833 && (regno
== CR_LRR0
|| regno
== CR_LRR1
))
5835 specs
[count
] = tmpl
;
5836 specs
[count
++].index
= regno
;
5844 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_CR3
)
5846 specs
[count
] = tmpl
;
5847 specs
[count
++].index
=
5848 CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_CR
;
5863 else if (rsrc_write
)
5865 if (dep
->specifier
== IA64_RS_FRb
5866 && idesc
->operands
[0] == IA64_OPND_F1
)
5868 specs
[count
] = tmpl
;
5869 specs
[count
++].index
= CURR_SLOT
.opnd
[0].X_add_number
- REG_FR
;
5874 for (i
=idesc
->num_outputs
;i
< NELEMS(idesc
->operands
);i
++)
5876 if (idesc
->operands
[i
] == IA64_OPND_F2
5877 || idesc
->operands
[i
] == IA64_OPND_F3
5878 || idesc
->operands
[i
] == IA64_OPND_F4
)
5880 specs
[count
] = tmpl
;
5881 specs
[count
++].index
=
5882 CURR_SLOT
.opnd
[i
].X_add_number
- REG_FR
;
5891 /* This reference applies only to the GR whose value is loaded with
5892 data returned from memory */
5893 specs
[count
] = tmpl
;
5894 specs
[count
++].index
= CURR_SLOT
.opnd
[0].X_add_number
- REG_GR
;
5900 for (i
=0;i
< idesc
->num_outputs
;i
++)
5902 if (idesc
->operands
[i
] == IA64_OPND_R1
5903 || idesc
->operands
[i
] == IA64_OPND_R2
5904 || idesc
->operands
[i
] == IA64_OPND_R3
)
5906 specs
[count
] = tmpl
;
5907 specs
[count
++].index
=
5908 CURR_SLOT
.opnd
[i
].X_add_number
- REG_GR
;
5914 /* Look for anything that reads a GR */
5915 for (i
=0;i
< NELEMS(idesc
->operands
);i
++)
5917 if (idesc
->operands
[i
] == IA64_OPND_MR3
5918 || idesc
->operands
[i
] == IA64_OPND_CPUID_R3
5919 || idesc
->operands
[i
] == IA64_OPND_DBR_R3
5920 || idesc
->operands
[i
] == IA64_OPND_IBR_R3
5921 || idesc
->operands
[i
] == IA64_OPND_MSR_R3
5922 || idesc
->operands
[i
] == IA64_OPND_PKR_R3
5923 || idesc
->operands
[i
] == IA64_OPND_PMC_R3
5924 || idesc
->operands
[i
] == IA64_OPND_PMD_R3
5925 || idesc
->operands
[i
] == IA64_OPND_RR_R3
5926 || ((i
>= idesc
->num_outputs
)
5927 && (idesc
->operands
[i
] == IA64_OPND_R1
5928 || idesc
->operands
[i
] == IA64_OPND_R2
5929 || idesc
->operands
[i
] == IA64_OPND_R3
)))
5931 specs
[count
] = tmpl
;
5932 specs
[count
++].index
=
5933 CURR_SLOT
.opnd
[i
].X_add_number
- REG_GR
;
5947 if (idesc
->operands
[0] == IA64_OPND_PR_ROT
)
5949 for (i
=16;i
< 63;i
++)
5951 specs
[count
] = tmpl
;
5952 specs
[count
++].index
= i
;
5957 for (i
=1;i
< 63;i
++)
5959 specs
[count
] = tmpl
;
5960 specs
[count
++].index
= i
;
5967 /* mark only those registers indicated by the mask */
5969 && idesc
->operands
[0] == IA64_OPND_PR
)
5971 mask
= CURR_SLOT
.opnd
[2].X_add_number
;
5972 if (mask
& ((valueT
)1<<16))
5973 mask
|= ~(valueT
)0xffff;
5974 for (i
=1;i
< 63;i
++)
5976 if (mask
& ((valueT
)1<<i
))
5978 specs
[count
] = tmpl
;
5979 specs
[count
++].index
= i
;
5984 && idesc
->operands
[0] == IA64_OPND_PR_ROT
)
5986 for (i
=16;i
< 63;i
++)
5988 specs
[count
] = tmpl
;
5989 specs
[count
++].index
= i
;
5997 else if (note
== 11) /* note 11 implies note 1 as well */
6001 for (i
=0;i
< idesc
->num_outputs
;i
++)
6003 if (idesc
->operands
[i
] == IA64_OPND_P1
6004 || idesc
->operands
[i
] == IA64_OPND_P2
)
6006 int regno
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_P
;
6009 specs
[count
] = tmpl
;
6010 specs
[count
++].index
= regno
;
6020 else if (note
== 12)
6022 if (CURR_SLOT
.qp_regno
!= 0)
6024 specs
[count
] = tmpl
;
6025 specs
[count
++].index
= CURR_SLOT
.qp_regno
;
6032 int p1
= CURR_SLOT
.opnd
[0].X_add_number
- REG_P
;
6033 int p2
= CURR_SLOT
.opnd
[1].X_add_number
- REG_P
;
6034 if ((idesc
->operands
[0] == IA64_OPND_P1
6035 || idesc
->operands
[0] == IA64_OPND_P2
)
6036 && p1
!= 0 && p1
!= 63)
6038 specs
[count
] = tmpl
;
6039 specs
[count
++].index
= p1
;
6041 if ((idesc
->operands
[1] == IA64_OPND_P1
6042 || idesc
->operands
[1] == IA64_OPND_P2
)
6043 && p2
!= 0 && p2
!= 63)
6045 specs
[count
] = tmpl
;
6046 specs
[count
++].index
= p2
;
6051 if (CURR_SLOT
.qp_regno
!= 0)
6053 specs
[count
] = tmpl
;
6054 specs
[count
++].index
= CURR_SLOT
.qp_regno
;
6056 if (idesc
->operands
[1] == IA64_OPND_PR
)
6058 for (i
=1;i
< 63;i
++)
6060 specs
[count
] = tmpl
;
6061 specs
[count
++].index
= i
;
6073 /* Verify that the instruction is using the PSR bit indicated in
6077 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_PSR_UM
)
6079 if (dep
->regindex
< 6)
6081 specs
[count
++] = tmpl
;
6084 else if (idesc
->operands
[!rsrc_write
] == IA64_OPND_PSR
)
6086 if (dep
->regindex
< 32
6087 || dep
->regindex
== 35
6088 || dep
->regindex
== 36
6089 || (!rsrc_write
&& dep
->regindex
== PSR_CPL
))
6091 specs
[count
++] = tmpl
;
6094 else if (idesc
->operands
[!rsrc_write
] == IA64_OPND_PSR_L
)
6096 if (dep
->regindex
< 32
6097 || dep
->regindex
== 35
6098 || dep
->regindex
== 36
6099 || (rsrc_write
&& dep
->regindex
== PSR_CPL
))
6101 specs
[count
++] = tmpl
;
6106 /* Several PSR bits have very specific dependencies. */
6107 switch (dep
->regindex
)
6110 specs
[count
++] = tmpl
;
6115 specs
[count
++] = tmpl
;
6119 /* Only certain CR accesses use PSR.ic */
6120 if (idesc
->operands
[0] == IA64_OPND_CR3
6121 || idesc
->operands
[1] == IA64_OPND_CR3
)
6124 ((idesc
->operands
[0] == IA64_OPND_CR3
)
6127 CURR_SLOT
.opnd
[index
].X_add_number
- REG_CR
;
6142 specs
[count
++] = tmpl
;
6151 specs
[count
++] = tmpl
;
6155 /* Only some AR accesses use cpl */
6156 if (idesc
->operands
[0] == IA64_OPND_AR3
6157 || idesc
->operands
[1] == IA64_OPND_AR3
)
6160 ((idesc
->operands
[0] == IA64_OPND_AR3
)
6163 CURR_SLOT
.opnd
[index
].X_add_number
- REG_AR
;
6170 && regno
<= AR_K7
))))
6172 specs
[count
++] = tmpl
;
6177 specs
[count
++] = tmpl
;
6187 if (idesc
->operands
[0] == IA64_OPND_IMMU24
)
6189 mask
= CURR_SLOT
.opnd
[0].X_add_number
;
6195 if (mask
& ((valueT
)1<<dep
->regindex
))
6197 specs
[count
++] = tmpl
;
6202 int min
= dep
->regindex
== PSR_DFL
? 2 : 32;
6203 int max
= dep
->regindex
== PSR_DFL
? 31 : 127;
6204 /* dfh is read on FR32-127; dfl is read on FR2-31 */
6205 for (i
=0;i
< NELEMS(idesc
->operands
);i
++)
6207 if (idesc
->operands
[i
] == IA64_OPND_F1
6208 || idesc
->operands
[i
] == IA64_OPND_F2
6209 || idesc
->operands
[i
] == IA64_OPND_F3
6210 || idesc
->operands
[i
] == IA64_OPND_F4
)
6212 int reg
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_FR
;
6213 if (reg
>= min
&& reg
<= max
)
6215 specs
[count
++] = tmpl
;
6222 int min
= dep
->regindex
== PSR_MFL
? 2 : 32;
6223 int max
= dep
->regindex
== PSR_MFL
? 31 : 127;
6224 /* mfh is read on writes to FR32-127; mfl is read on writes to
6226 for (i
=0;i
< idesc
->num_outputs
;i
++)
6228 if (idesc
->operands
[i
] == IA64_OPND_F1
)
6230 int reg
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_FR
;
6231 if (reg
>= min
&& reg
<= max
)
6233 specs
[count
++] = tmpl
;
6238 else if (note
== 10)
6240 for (i
=0;i
< NELEMS(idesc
->operands
);i
++)
6242 if (idesc
->operands
[i
] == IA64_OPND_R1
6243 || idesc
->operands
[i
] == IA64_OPND_R2
6244 || idesc
->operands
[i
] == IA64_OPND_R3
)
6246 int regno
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_GR
;
6247 if (regno
>= 16 && regno
<= 31)
6249 specs
[count
++] = tmpl
;
6260 case IA64_RS_AR_FPSR
:
6261 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_AR3
)
6263 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_AR
;
6264 if (regno
== AR_FPSR
)
6266 specs
[count
++] = tmpl
;
6271 specs
[count
++] = tmpl
;
6276 /* Handle all AR[REG] resources */
6277 if (note
== 0 || note
== 1)
6279 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_AR
;
6280 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_AR3
6281 && regno
== dep
->regindex
)
6283 specs
[count
++] = tmpl
;
6285 /* other AR[REG] resources may be affected by AR accesses */
6286 else if (idesc
->operands
[0] == IA64_OPND_AR3
)
6289 regno
= CURR_SLOT
.opnd
[0].X_add_number
- REG_AR
;
6290 switch (dep
->regindex
)
6296 if (regno
== AR_BSPSTORE
)
6298 specs
[count
++] = tmpl
;
6302 (regno
== AR_BSPSTORE
6303 || regno
== AR_RNAT
))
6305 specs
[count
++] = tmpl
;
6310 else if (idesc
->operands
[1] == IA64_OPND_AR3
)
6313 regno
= CURR_SLOT
.opnd
[1].X_add_number
- REG_AR
;
6314 switch (dep
->regindex
)
6319 if (regno
== AR_BSPSTORE
|| regno
== AR_RNAT
)
6321 specs
[count
++] = tmpl
;
6328 specs
[count
++] = tmpl
;
6338 /* Handle all CR[REG] resources */
6339 if (note
== 0 || note
== 1)
6341 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_CR3
)
6343 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_CR
;
6344 if (regno
== dep
->regindex
)
6346 specs
[count
++] = tmpl
;
6348 else if (!rsrc_write
)
6350 /* Reads from CR[IVR] affect other resources. */
6351 if (regno
== CR_IVR
)
6353 if ((dep
->regindex
>= CR_IRR0
6354 && dep
->regindex
<= CR_IRR3
)
6355 || dep
->regindex
== CR_TPR
)
6357 specs
[count
++] = tmpl
;
6364 specs
[count
++] = tmpl
;
6373 case IA64_RS_INSERVICE
:
6374 /* look for write of EOI (67) or read of IVR (65) */
6375 if ((idesc
->operands
[0] == IA64_OPND_CR3
6376 && CURR_SLOT
.opnd
[0].X_add_number
- REG_CR
== CR_EOI
)
6377 || (idesc
->operands
[1] == IA64_OPND_CR3
6378 && CURR_SLOT
.opnd
[1].X_add_number
- REG_CR
== CR_IVR
))
6380 specs
[count
++] = tmpl
;
6387 specs
[count
++] = tmpl
;
6398 specs
[count
++] = tmpl
;
6402 /* Check if any of the registers accessed are in the rotating region.
6403 mov to/from pr accesses CFM only when qp_regno is in the rotating
6405 for (i
=0;i
< NELEMS(idesc
->operands
);i
++)
6407 if (idesc
->operands
[i
] == IA64_OPND_R1
6408 || idesc
->operands
[i
] == IA64_OPND_R2
6409 || idesc
->operands
[i
] == IA64_OPND_R3
)
6411 int num
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_GR
;
6412 /* Assumes that md.rot.num_regs is always valid */
6413 if (md
.rot
.num_regs
> 0
6415 && num
< 31 + md
.rot
.num_regs
)
6417 specs
[count
] = tmpl
;
6418 specs
[count
++].specific
= 0;
6421 else if (idesc
->operands
[i
] == IA64_OPND_F1
6422 || idesc
->operands
[i
] == IA64_OPND_F2
6423 || idesc
->operands
[i
] == IA64_OPND_F3
6424 || idesc
->operands
[i
] == IA64_OPND_F4
)
6426 int num
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_FR
;
6429 specs
[count
] = tmpl
;
6430 specs
[count
++].specific
= 0;
6433 else if (idesc
->operands
[i
] == IA64_OPND_P1
6434 || idesc
->operands
[i
] == IA64_OPND_P2
)
6436 int num
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_P
;
6439 specs
[count
] = tmpl
;
6440 specs
[count
++].specific
= 0;
6444 if (CURR_SLOT
.qp_regno
> 15)
6446 specs
[count
] = tmpl
;
6447 specs
[count
++].specific
= 0;
6455 specs
[count
++] = tmpl
;
6457 else if (note
== 11)
6459 if ((idesc
->operands
[0] == IA64_OPND_P1
6460 && CURR_SLOT
.opnd
[0].X_add_number
- REG_P
== 63)
6461 || (idesc
->operands
[1] == IA64_OPND_P2
6462 && CURR_SLOT
.opnd
[1].X_add_number
- REG_P
== 63))
6464 specs
[count
++] = tmpl
;
6467 else if (note
== 12)
6469 if (CURR_SLOT
.qp_regno
== 63)
6471 specs
[count
++] = tmpl
;
6477 if (idesc
->operands
[2] == IA64_OPND_IMM17
)
6478 mask
= CURR_SLOT
.opnd
[2].X_add_number
;
6479 if (mask
& ((valueT
)1<<63))
6481 specs
[count
++] = tmpl
;
6488 for (i
=0;i
< idesc
->num_outputs
;i
++)
6489 if ((idesc
->operands
[i
] == IA64_OPND_P1
6490 || idesc
->operands
[i
] == IA64_OPND_P2
)
6491 && CURR_SLOT
.opnd
[i
].X_add_number
- REG_P
== 63)
6493 specs
[count
++] = tmpl
;
6498 if (CURR_SLOT
.qp_regno
== 63)
6500 specs
[count
++] = tmpl
;
6511 /* FIXME we can identify some individual RSE written resources, but RSE
6512 read resources have not yet been completely identified, so for now
6513 treat RSE as a single resource */
6514 if (strncmp (idesc
->name
, "mov", 3) == 0)
6518 if (idesc
->operands
[0] == IA64_OPND_AR3
6519 && CURR_SLOT
.opnd
[0].X_add_number
- REG_AR
== AR_BSPSTORE
)
6521 specs
[count
] = tmpl
;
6522 specs
[count
++].index
= 0; /* IA64_RSE_BSPLOAD/RNATBITINDEX */
6527 if (idesc
->operands
[0] == IA64_OPND_AR3
)
6529 if (CURR_SLOT
.opnd
[0].X_add_number
- REG_AR
== AR_BSPSTORE
6530 || CURR_SLOT
.opnd
[0].X_add_number
- REG_AR
== AR_RNAT
)
6532 specs
[count
++] = tmpl
;
6535 else if (idesc
->operands
[1] == IA64_OPND_AR3
)
6537 if (CURR_SLOT
.opnd
[1].X_add_number
- REG_AR
== AR_BSP
6538 || CURR_SLOT
.opnd
[1].X_add_number
- REG_AR
== AR_BSPSTORE
6539 || CURR_SLOT
.opnd
[1].X_add_number
- REG_AR
== AR_RNAT
)
6541 specs
[count
++] = tmpl
;
6548 specs
[count
++] = tmpl
;
6553 /* FIXME -- do any of these need to be non-specific? */
6554 specs
[count
++] = tmpl
;
6558 as_bad (_("Unrecognized dependency specifier %d\n"), dep
->specifier
);
6565 /* Clear branch flags on marked resources. This breaks the link between the
6566 QP of the marking instruction and a subsequent branch on the same QP.
6569 clear_qp_branch_flag (mask
)
6573 for (i
= 0;i
< regdepslen
;i
++)
6575 valueT bit
= ((valueT
)1 << regdeps
[i
].qp_regno
);
6576 if ((bit
& mask
) != 0)
6578 regdeps
[i
].link_to_qp_branch
= 0;
6583 /* Remove any mutexes which contain any of the PRs indicated in the mask.
6585 Any changes to a PR clears the mutex relations which include that PR.
6588 clear_qp_mutex (mask
)
6594 while (i
< qp_mutexeslen
)
6596 if ((qp_mutexes
[i
].prmask
& mask
) != 0)
6600 fprintf (stderr
, " Clearing mutex relation");
6601 print_prmask (qp_mutexes
[i
].prmask
);
6602 fprintf (stderr
, "\n");
6604 qp_mutexes
[i
] = qp_mutexes
[--qp_mutexeslen
];
6611 /* Clear implies relations which contain PRs in the given masks.
6612 P1_MASK indicates the source of the implies relation, while P2_MASK
6613 indicates the implied PR.
6616 clear_qp_implies (p1_mask
, p2_mask
)
6623 while (i
< qp_implieslen
)
6625 if ((((valueT
)1 << qp_implies
[i
].p1
) & p1_mask
) != 0
6626 || (((valueT
)1 << qp_implies
[i
].p2
) & p2_mask
) != 0)
6629 fprintf (stderr
, "Clearing implied relation PR%d->PR%d\n",
6630 qp_implies
[i
].p1
, qp_implies
[i
].p2
);
6631 qp_implies
[i
] = qp_implies
[--qp_implieslen
];
6638 /* add the PRs specified to the list of implied relations */
6640 add_qp_imply (p1
, p2
)
6647 /* p0 is not meaningful here */
6648 if (p1
== 0 || p2
== 0)
6654 /* if it exists already, ignore it */
6655 for (i
=0;i
< qp_implieslen
;i
++)
6657 if (qp_implies
[i
].p1
== p1
6658 && qp_implies
[i
].p2
== p2
6659 && qp_implies
[i
].path
== md
.path
6660 && !qp_implies
[i
].p2_branched
)
6664 if (qp_implieslen
== qp_impliestotlen
)
6666 qp_impliestotlen
+= 20;
6667 qp_implies
= (struct qp_imply
*)
6668 xrealloc ((void *)qp_implies
,
6669 qp_impliestotlen
* sizeof (struct qp_imply
));
6672 fprintf (stderr
, " Registering PR%d implies PR%d\n", p1
, p2
);
6673 qp_implies
[qp_implieslen
].p1
= p1
;
6674 qp_implies
[qp_implieslen
].p2
= p2
;
6675 qp_implies
[qp_implieslen
].path
= md
.path
;
6676 qp_implies
[qp_implieslen
++].p2_branched
= 0;
6678 /* Add in the implied transitive relations; for everything that p2 implies,
6679 make p1 imply that, too; for everything that implies p1, make it imply p2
6681 for (i
=0;i
< qp_implieslen
;i
++)
6683 if (qp_implies
[i
].p1
== p2
)
6684 add_qp_imply (p1
, qp_implies
[i
].p2
);
6685 if (qp_implies
[i
].p2
== p1
)
6686 add_qp_imply (qp_implies
[i
].p1
, p2
);
6688 /* Add in mutex relations implied by this implies relation; for each mutex
6689 relation containing p2, duplicate it and replace p2 with p1. */
6690 bit
= (valueT
)1 << p1
;
6691 mask
= (valueT
)1 << p2
;
6692 for (i
=0;i
< qp_mutexeslen
;i
++)
6694 if (qp_mutexes
[i
].prmask
& mask
)
6695 add_qp_mutex ((qp_mutexes
[i
].prmask
& ~mask
) | bit
);
6700 /* Add the PRs specified in the mask to the mutex list; this means that only
6701 one of the PRs can be true at any time. PR0 should never be included in
6710 if (qp_mutexeslen
== qp_mutexestotlen
)
6712 qp_mutexestotlen
+= 20;
6713 qp_mutexes
= (struct qpmutex
*)
6714 xrealloc ((void *)qp_mutexes
,
6715 qp_mutexestotlen
* sizeof (struct qpmutex
));
6719 fprintf (stderr
, " Registering mutex on");
6720 print_prmask (mask
);
6721 fprintf (stderr
, "\n");
6723 qp_mutexes
[qp_mutexeslen
].path
= md
.path
;
6724 qp_mutexes
[qp_mutexeslen
++].prmask
= mask
;
6728 clear_register_values ()
6732 fprintf (stderr
, " Clearing register values\n");
6733 for (i
=1;i
< NELEMS(gr_values
);i
++)
6734 gr_values
[i
].known
= 0;
6737 /* Keep track of register values/changes which affect DV tracking.
6739 optimization note: should add a flag to classes of insns where otherwise we
6740 have to examine a group of strings to identify them.
6744 note_register_values (idesc
)
6745 struct ia64_opcode
*idesc
;
6747 valueT qp_changemask
= 0;
6750 /* invalidate values for registers being written to */
6751 for (i
=0;i
< idesc
->num_outputs
;i
++)
6753 if (idesc
->operands
[i
] == IA64_OPND_R1
6754 || idesc
->operands
[i
] == IA64_OPND_R2
6755 || idesc
->operands
[i
] == IA64_OPND_R3
)
6757 int regno
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_GR
;
6758 if (regno
> 0 && regno
< NELEMS(gr_values
))
6759 gr_values
[regno
].known
= 0;
6761 else if (idesc
->operands
[i
] == IA64_OPND_P1
6762 || idesc
->operands
[i
] == IA64_OPND_P2
)
6764 int regno
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_P
;
6765 qp_changemask
|= (valueT
)1 << regno
;
6767 else if (idesc
->operands
[i
] == IA64_OPND_PR
)
6769 if (idesc
->operands
[2] & (valueT
)0x10000)
6770 qp_changemask
= ~(valueT
)0x1FFFF | idesc
->operands
[2];
6772 qp_changemask
= idesc
->operands
[2];
6775 else if (idesc
->operands
[i
] == IA64_OPND_PR_ROT
)
6777 if (idesc
->operands
[1] & ((valueT
)1 << 43))
6778 qp_changemask
= ~(valueT
)0xFFFFFFFFFFF | idesc
->operands
[1];
6780 qp_changemask
= idesc
->operands
[1];
6781 qp_changemask
&= ~(valueT
)0xFFFF;
6786 /* Always clear qp branch flags on any PR change */
6787 /* FIXME there may be exceptions for certain compares */
6788 clear_qp_branch_flag (qp_changemask
);
6790 /* invalidate rotating registers on insns which affect RRBs in CFM */
6791 if (idesc
->flags
& IA64_OPCODE_MOD_RRBS
)
6793 qp_changemask
|= ~(valueT
)0xFFFF;
6794 if (strcmp (idesc
->name
, "clrrrb.pr") != 0)
6796 for (i
=32;i
< 32+md
.rot
.num_regs
;i
++)
6797 gr_values
[i
].known
= 0;
6799 clear_qp_mutex (qp_changemask
);
6800 clear_qp_implies (qp_changemask
, qp_changemask
);
6802 /* after a call, all register values are undefined, except those marked
6804 else if (strncmp (idesc
->name
, "br.call", 6) == 0
6805 || strncmp (idesc
->name
, "brl.call", 7) == 0)
6807 // FIXME keep GR values which are marked as "safe_across_calls"
6808 clear_register_values ();
6809 clear_qp_mutex (~qp_safe_across_calls
);
6810 clear_qp_implies (~qp_safe_across_calls
, ~qp_safe_across_calls
);
6811 clear_qp_branch_flag (~qp_safe_across_calls
);
6813 /* Look for mutex and implies relations */
6814 else if ((idesc
->operands
[0] == IA64_OPND_P1
6815 || idesc
->operands
[0] == IA64_OPND_P2
)
6816 && (idesc
->operands
[1] == IA64_OPND_P1
6817 || idesc
->operands
[1] == IA64_OPND_P2
))
6819 int p1
= CURR_SLOT
.opnd
[0].X_add_number
- REG_P
;
6820 int p2
= CURR_SLOT
.opnd
[1].X_add_number
- REG_P
;
6821 valueT p1mask
= (valueT
)1 << p1
;
6822 valueT p2mask
= (valueT
)1 << p2
;
6824 /* if one of the PRs is PR0, we can't really do anything */
6825 if (p1
== 0 || p2
== 0)
6828 fprintf (stderr
, " Ignoring PRs due to inclusion of p0\n");
6830 /* In general, clear mutexes and implies which include P1 or P2,
6831 with the following exceptions */
6832 else if (strstr (idesc
->name
, ".or.andcm") != NULL
)
6834 add_qp_mutex (p1mask
| p2mask
);
6835 clear_qp_implies (p2mask
, p1mask
);
6837 else if (strstr (idesc
->name
, ".and.orcm") != NULL
)
6839 add_qp_mutex (p1mask
| p2mask
);
6840 clear_qp_implies (p1mask
, p2mask
);
6842 else if (strstr (idesc
->name
, ".and") != NULL
)
6844 clear_qp_implies (0, p1mask
| p2mask
);
6846 else if (strstr (idesc
->name
, ".or") != NULL
)
6848 clear_qp_mutex (p1mask
| p2mask
);
6849 clear_qp_implies (p1mask
| p2mask
, 0);
6853 clear_qp_implies (p1mask
| p2mask
, p1mask
| p2mask
);
6854 if (strstr (idesc
->name
, ".unc") != NULL
)
6856 add_qp_mutex (p1mask
| p2mask
);
6857 if (CURR_SLOT
.qp_regno
!= 0)
6859 add_qp_imply (CURR_SLOT
.opnd
[0].X_add_number
- REG_P
,
6860 CURR_SLOT
.qp_regno
);
6861 add_qp_imply (CURR_SLOT
.opnd
[1].X_add_number
- REG_P
,
6862 CURR_SLOT
.qp_regno
);
6865 else if (CURR_SLOT
.qp_regno
== 0)
6867 add_qp_mutex (p1mask
| p2mask
);
6871 clear_qp_mutex (p1mask
| p2mask
);
6875 /* Look for mov imm insns into GRs */
6876 else if (idesc
->operands
[0] == IA64_OPND_R1
6877 && (idesc
->operands
[1] == IA64_OPND_IMM22
6878 || idesc
->operands
[1] == IA64_OPND_IMMU64
)
6879 && (strcmp(idesc
->name
, "mov") == 0
6880 || strcmp(idesc
->name
, "movl") == 0))
6882 int regno
= CURR_SLOT
.opnd
[0].X_add_number
- REG_GR
;
6883 if (regno
> 0 && regno
< NELEMS(gr_values
))
6885 gr_values
[regno
].known
= 1;
6886 gr_values
[regno
].value
= CURR_SLOT
.opnd
[1].X_add_number
;
6887 gr_values
[regno
].path
= md
.path
;
6889 fprintf (stderr
, " Know gr%d = 0x%llx\n",
6890 regno
, gr_values
[regno
].value
);
6895 clear_qp_mutex (qp_changemask
);
6896 clear_qp_implies (qp_changemask
, qp_changemask
);
6900 /* Return whether the given predicate registers are currently mutex */
6902 qp_mutex (p1
, p2
, path
)
6912 mask
= ((valueT
)1<<p1
) | (valueT
)1<<p2
;
6913 for (i
=0;i
< qp_mutexeslen
;i
++)
6915 if (qp_mutexes
[i
].path
>= path
6916 && (qp_mutexes
[i
].prmask
& mask
) == mask
)
6923 /* Return whether the given resource is in the given insn's list of chks
6924 Return 1 if the conflict is absolutely determined, 2 if it's a potential
6928 resources_match (rs
, idesc
, note
, qp_regno
, path
)
6930 struct ia64_opcode
*idesc
;
6935 struct rsrc specs
[MAX_SPECS
];
6938 /* If the marked resource's qp_regno and the given qp_regno are mutex,
6939 we don't need to check. One exception is note 11, which indicates that
6940 target predicates are written regardless of PR[qp]. */
6941 if (qp_mutex (rs
->qp_regno
, qp_regno
, path
)
6945 count
= specify_resource (rs
->dependency
, idesc
, DV_CHK
, specs
, note
, path
);
6948 /* UNAT checking is a bit more specific than other resources */
6949 if (rs
->dependency
->specifier
== IA64_RS_AR_UNAT
6950 && specs
[count
].mem_offset
.hint
6951 && rs
->mem_offset
.hint
)
6953 if (rs
->mem_offset
.base
== specs
[count
].mem_offset
.base
)
6955 if (((rs
->mem_offset
.offset
>> 3) & 0x3F) ==
6956 ((specs
[count
].mem_offset
.offset
>> 3) & 0x3F))
6963 /* If either resource is not specific, conservatively assume a conflict
6965 if (!specs
[count
].specific
|| !rs
->specific
)
6967 else if (specs
[count
].index
== rs
->index
)
6972 fprintf (stderr
, " No %s conflicts\n", rs
->dependency
->name
);
6978 /* Indicate an instruction group break; if INSERT_STOP is non-zero, then
6979 insert a stop to create the break. Update all resource dependencies
6980 appropriately. If QP_REGNO is non-zero, only apply the break to resources
6981 which use the same QP_REGNO and have the link_to_qp_branch flag set.
6982 If SAVE_CURRENT is non-zero, don't affect resources marked by the current
6987 insn_group_break (insert_stop
, qp_regno
, save_current
)
6994 if (insert_stop
&& md
.num_slots_in_use
> 0)
6995 PREV_SLOT
.end_of_insn_group
= 1;
6999 fprintf (stderr
, " Insn group break%s",
7000 (insert_stop
? " (w/stop)" : ""));
7002 fprintf (stderr
, " effective for QP=%d", qp_regno
);
7003 fprintf (stderr
, "\n");
7007 while (i
< regdepslen
)
7009 const struct ia64_dependency
*dep
= regdeps
[i
].dependency
;
7012 && regdeps
[i
].qp_regno
!= qp_regno
)
7019 && CURR_SLOT
.src_file
== regdeps
[i
].file
7020 && CURR_SLOT
.src_line
== regdeps
[i
].line
)
7026 /* clear dependencies which are automatically cleared by a stop, or
7027 those that have reached the appropriate state of insn serialization */
7028 if (dep
->semantics
== IA64_DVS_IMPLIED
7029 || dep
->semantics
== IA64_DVS_IMPLIEDF
7030 || regdeps
[i
].insn_srlz
== STATE_SRLZ
)
7032 print_dependency ("Removing", i
);
7033 regdeps
[i
] = regdeps
[--regdepslen
];
7037 if (dep
->semantics
== IA64_DVS_DATA
7038 || dep
->semantics
== IA64_DVS_INSTR
7039 || dep
->semantics
== IA64_DVS_SPECIFIC
)
7041 if (regdeps
[i
].insn_srlz
== STATE_NONE
)
7042 regdeps
[i
].insn_srlz
= STATE_STOP
;
7043 if (regdeps
[i
].data_srlz
== STATE_NONE
)
7044 regdeps
[i
].data_srlz
= STATE_STOP
;
7051 /* Add the given resource usage spec to the list of active dependencies */
7053 mark_resource (idesc
, dep
, spec
, depind
, path
)
7054 struct ia64_opcode
*idesc
;
7055 const struct ia64_dependency
*dep
;
7060 if (regdepslen
== regdepstotlen
)
7062 regdepstotlen
+= 20;
7063 regdeps
= (struct rsrc
*)
7064 xrealloc ((void *)regdeps
,
7065 regdepstotlen
* sizeof(struct rsrc
));
7068 regdeps
[regdepslen
] = *spec
;
7069 regdeps
[regdepslen
].depind
= depind
;
7070 regdeps
[regdepslen
].path
= path
;
7071 regdeps
[regdepslen
].file
= CURR_SLOT
.src_file
;
7072 regdeps
[regdepslen
].line
= CURR_SLOT
.src_line
;
7074 print_dependency ("Adding", regdepslen
);
7080 print_dependency (action
, depind
)
7086 fprintf (stderr
, " %s %s '%s'",
7087 action
, dv_mode
[(regdeps
[depind
].dependency
)->mode
],
7088 (regdeps
[depind
].dependency
)->name
);
7089 if (regdeps
[depind
].specific
&& regdeps
[depind
].index
!= 0)
7090 fprintf (stderr
, " (%d)", regdeps
[depind
].index
);
7091 if (regdeps
[depind
].mem_offset
.hint
)
7092 fprintf (stderr
, " 0x%llx+0x%llx",
7093 regdeps
[depind
].mem_offset
.base
,
7094 regdeps
[depind
].mem_offset
.offset
);
7095 fprintf (stderr
, "\n");
7100 instruction_serialization ()
7104 fprintf (stderr
, " Instruction serialization\n");
7105 for (i
=0;i
< regdepslen
;i
++)
7106 if (regdeps
[i
].insn_srlz
== STATE_STOP
)
7107 regdeps
[i
].insn_srlz
= STATE_SRLZ
;
7111 data_serialization ()
7115 fprintf (stderr
, " Data serialization\n");
7116 while (i
< regdepslen
)
7118 if (regdeps
[i
].data_srlz
== STATE_STOP
7119 /* Note: as of 991210, all "other" dependencies are cleared by a
7120 data serialization. This might change with new tables */
7121 || (regdeps
[i
].dependency
)->semantics
== IA64_DVS_OTHER
)
7123 print_dependency ("Removing", i
);
7124 regdeps
[i
] = regdeps
[--regdepslen
];
7131 /* Insert stops and serializations as needed to avoid DVs */
7133 remove_marked_resource (rs
)
7136 switch (rs
->dependency
->semantics
)
7138 case IA64_DVS_SPECIFIC
:
7140 fprintf (stderr
, "Implementation-specific, assume worst case...\n");
7141 /* ...fall through... */
7142 case IA64_DVS_INSTR
:
7144 fprintf (stderr
, "Inserting instr serialization\n");
7145 if (rs
->insn_srlz
< STATE_STOP
)
7146 insn_group_break (1, 0, 0);
7147 if (rs
->insn_srlz
< STATE_SRLZ
)
7149 int oldqp
= CURR_SLOT
.qp_regno
;
7150 struct ia64_opcode
*oldidesc
= CURR_SLOT
.idesc
;
7151 /* Manually jam a srlz.i insn into the stream */
7152 CURR_SLOT
.qp_regno
= 0;
7153 CURR_SLOT
.idesc
= ia64_find_opcode ("srlz.i");
7154 instruction_serialization ();
7155 md
.curr_slot
= (md
.curr_slot
+ 1) % NUM_SLOTS
;
7156 if (++md
.num_slots_in_use
>= NUM_SLOTS
)
7158 CURR_SLOT
.qp_regno
= oldqp
;
7159 CURR_SLOT
.idesc
= oldidesc
;
7161 insn_group_break (1, 0, 0);
7163 case IA64_DVS_OTHER
: /* as of rev2 (991220) of the DV tables, all
7164 "other" types of DV are eliminated
7165 by a data serialization */
7168 fprintf (stderr
, "Inserting data serialization\n");
7169 if (rs
->data_srlz
< STATE_STOP
)
7170 insn_group_break (1, 0, 0);
7172 int oldqp
= CURR_SLOT
.qp_regno
;
7173 struct ia64_opcode
*oldidesc
= CURR_SLOT
.idesc
;
7174 /* Manually jam a srlz.d insn into the stream */
7175 CURR_SLOT
.qp_regno
= 0;
7176 CURR_SLOT
.idesc
= ia64_find_opcode ("srlz.d");
7177 data_serialization ();
7178 md
.curr_slot
= (md
.curr_slot
+ 1) % NUM_SLOTS
;
7179 if (++md
.num_slots_in_use
>= NUM_SLOTS
)
7181 CURR_SLOT
.qp_regno
= oldqp
;
7182 CURR_SLOT
.idesc
= oldidesc
;
7185 case IA64_DVS_IMPLIED
:
7186 case IA64_DVS_IMPLIEDF
:
7188 fprintf (stderr
, "Inserting stop\n");
7189 insn_group_break (1, 0, 0);
7196 /* Check the resources used by the given opcode against the current dependency
7199 The check is run once for each execution path encountered. In this case,
7200 a unique execution path is the sequence of instructions following a code
7201 entry point, e.g. the following has three execution paths, one starting
7202 at L0, one at L1, and one at L2.
7210 check_dependencies (idesc
)
7211 struct ia64_opcode
*idesc
;
7213 const struct ia64_opcode_dependency
*opdeps
= idesc
->dependencies
;
7217 /* Note that the number of marked resources may change within the
7218 loop if in auto mode. */
7220 while (i
< regdepslen
)
7222 struct rsrc
*rs
= ®deps
[i
];
7223 const struct ia64_dependency
*dep
= rs
->dependency
;
7228 if (dep
->semantics
== IA64_DVS_NONE
7229 || (chkind
= depends_on (rs
->depind
, idesc
)) == -1)
7234 note
= NOTE(opdeps
->chks
[chkind
]);
7236 /* Check this resource against each execution path seen thus far */
7237 for (path
=0;path
<= md
.path
;path
++)
7241 /* If the dependency wasn't on the path being checked, ignore it */
7242 if (rs
->path
< path
)
7245 /* If the QP for this insn implies a QP which has branched, don't
7246 bother checking. Ed. NOTE: I don't think this check is terribly
7247 useful; what's the point of generating code which will only be
7248 reached if its QP is zero?
7249 This code was specifically inserted to handle the following code,
7250 based on notes from Intel's DV checking code, where p1 implies p2.
7257 if (CURR_SLOT
.qp_regno
!= 0)
7261 for (implies
=0;implies
< qp_implieslen
;implies
++)
7263 if (qp_implies
[implies
].path
>= path
7264 && qp_implies
[implies
].p1
== CURR_SLOT
.qp_regno
7265 && qp_implies
[implies
].p2_branched
)
7275 if ((matchtype
= resources_match (rs
, idesc
, note
,
7276 CURR_SLOT
.qp_regno
, path
)) != 0)
7279 char pathmsg
[256] = "";
7280 char indexmsg
[256] = "";
7281 int certain
= (matchtype
== 1 && CURR_SLOT
.qp_regno
== 0);
7284 sprintf (pathmsg
, " when entry is at label '%s'",
7285 md
.entry_labels
[path
-1]);
7286 if (rs
->specific
&& rs
->index
!= 0)
7287 sprintf (indexmsg
, ", specific resource number is %d",
7289 sprintf (msg
, "Use of '%s' %s %s dependency '%s' (%s)%s%s",
7291 (certain
? "violates" : "may violate"),
7292 dv_mode
[dep
->mode
], dep
->name
,
7293 dv_sem
[dep
->semantics
],
7296 if (md
.explicit_mode
)
7298 as_warn ("%s", msg
);
7300 as_warn (_("Only the first path encountering the conflict "
7302 as_warn_where (rs
->file
, rs
->line
,
7303 _("This is the location of the "
7304 "conflicting usage"));
7305 /* Don't bother checking other paths, to avoid duplicating
7312 fprintf(stderr
, "%s @ %s:%d\n", msg
, rs
->file
, rs
->line
);
7314 remove_marked_resource (rs
);
7316 /* since the set of dependencies has changed, start over */
7317 /* FIXME -- since we're removing dvs as we go, we
7318 probably don't really need to start over... */
7331 /* register new dependencies based on the given opcode */
7333 mark_resources (idesc
)
7334 struct ia64_opcode
*idesc
;
7337 const struct ia64_opcode_dependency
*opdeps
= idesc
->dependencies
;
7338 int add_only_qp_reads
= 0;
7340 /* A conditional branch only uses its resources if it is taken; if it is
7341 taken, we stop following that path. The other branch types effectively
7342 *always* write their resources. If it's not taken, register only QP
7344 if (is_conditional_branch (idesc
) || is_interruption_or_rfi (idesc
))
7346 add_only_qp_reads
= 1;
7350 fprintf (stderr
, "Registering '%s' resource usage\n", idesc
->name
);
7352 for (i
=0;i
< opdeps
->nregs
;i
++)
7354 const struct ia64_dependency
*dep
;
7355 struct rsrc specs
[MAX_SPECS
];
7360 dep
= ia64_find_dependency (opdeps
->regs
[i
]);
7361 note
= NOTE(opdeps
->regs
[i
]);
7363 if (add_only_qp_reads
7364 && !(dep
->mode
== IA64_DV_WAR
7365 && (dep
->specifier
== IA64_RS_PR
7366 || dep
->specifier
== IA64_RS_PR63
)))
7369 count
= specify_resource (dep
, idesc
, DV_REG
, specs
, note
, md
.path
);
7372 if (md
.debug_dv
&& !count
)
7373 fprintf (stderr
, " No %s %s usage found (path %d)\n",
7374 dv_mode
[dep
->mode
], dep
->name
, md
.path
);
7379 mark_resource (idesc
, dep
, &specs
[count
],
7380 DEP(opdeps
->regs
[i
]), md
.path
);
7383 /* The execution path may affect register values, which may in turn
7384 affect which indirect-access resources are accessed. */
7385 switch (dep
->specifier
)
7397 for (path
=0;path
< md
.path
;path
++)
7399 count
= specify_resource (dep
, idesc
, DV_REG
, specs
, note
, path
);
7401 mark_resource (idesc
, dep
, &specs
[count
],
7402 DEP(opdeps
->regs
[i
]), path
);
7409 /* remove dependencies when they no longer apply */
7411 update_dependencies (idesc
)
7412 struct ia64_opcode
*idesc
;
7416 if (strcmp (idesc
->name
, "srlz.i") == 0)
7418 instruction_serialization ();
7420 else if (strcmp (idesc
->name
, "srlz.d") == 0)
7422 data_serialization ();
7424 else if (is_interruption_or_rfi (idesc
)
7425 || is_taken_branch (idesc
))
7427 /* although technically the taken branch doesn't clear dependencies
7428 which require a srlz.[id], we don't follow the branch; the next
7429 instruction is assumed to start with a clean slate */
7431 clear_register_values ();
7432 clear_qp_mutex (~(valueT
)0);
7433 clear_qp_implies (~(valueT
)0, ~(valueT
)0);
7436 else if (is_conditional_branch (idesc
)
7437 && CURR_SLOT
.qp_regno
!= 0)
7439 int is_call
= strstr (idesc
->name
, ".call") != NULL
;
7441 for (i
=0;i
< qp_implieslen
;i
++)
7443 /* if the conditional branch's predicate is implied by the predicate
7444 in an existing dependency, remove that dependency */
7445 if (qp_implies
[i
].p2
== CURR_SLOT
.qp_regno
)
7448 /* note that this implied predicate takes a branch so that if
7449 a later insn generates a DV but its predicate implies this
7450 one, we can avoid the false DV warning */
7451 qp_implies
[i
].p2_branched
= 1;
7452 while (depind
< regdepslen
)
7454 if (regdeps
[depind
].qp_regno
== qp_implies
[i
].p1
)
7456 print_dependency ("Removing", depind
);
7457 regdeps
[depind
] = regdeps
[--regdepslen
];
7464 /* Any marked resources which have this same predicate should be
7465 cleared, provided that the QP hasn't been modified between the
7466 marking instruction and the branch.
7470 insn_group_break (0, CURR_SLOT
.qp_regno
, 1);
7475 while (i
< regdepslen
)
7477 if (regdeps
[i
].qp_regno
== CURR_SLOT
.qp_regno
7478 && regdeps
[i
].link_to_qp_branch
7479 && (regdeps
[i
].file
!= CURR_SLOT
.src_file
7480 || regdeps
[i
].line
!= CURR_SLOT
.src_line
))
7482 /* Treat like a taken branch */
7483 print_dependency ("Removing", i
);
7484 regdeps
[i
] = regdeps
[--regdepslen
];
7493 /* Examine the current instruction for dependency violations. */
7496 struct ia64_opcode
*idesc
;
7500 fprintf (stderr
, "Checking %s for violations (line %d, %d/%d)\n",
7501 idesc
->name
, CURR_SLOT
.src_line
,
7502 idesc
->dependencies
->nchks
,
7503 idesc
->dependencies
->nregs
);
7506 /* Look through the list of currently marked resources; if the current
7507 instruction has the dependency in its chks list which uses that resource,
7508 check against the specific resources used.
7510 check_dependencies (idesc
);
7513 Look up the instruction's regdeps (RAW writes, WAW writes, and WAR reads),
7514 then add them to the list of marked resources.
7516 mark_resources (idesc
);
7518 /* There are several types of dependency semantics, and each has its own
7519 requirements for being cleared
7521 Instruction serialization (insns separated by interruption, rfi, or
7522 writer + srlz.i + reader, all in separate groups) clears DVS_INSTR.
7524 Data serialization (instruction serialization, or writer + srlz.d +
7525 reader, where writer and srlz.d are in separate groups) clears
7526 DVS_DATA. (This also clears DVS_OTHER, but that is not guaranteed to
7527 always be the case).
7529 Instruction group break (groups separated by stop, taken branch,
7530 interruption or rfi) clears DVS_IMPLIED and DVS_IMPLIEDF.
7532 update_dependencies (idesc
);
7534 /* Sometimes, knowing a register value allows us to avoid giving a false DV
7535 warning. Keep track of as many as possible that are useful. */
7536 note_register_values (idesc
);
7538 /* We don't need or want this anymore. */
7539 md
.mem_offset
.hint
= 0;
7544 /* Translate one line of assembly. Pseudo ops and labels do not show
7550 char *saved_input_line_pointer
, *mnemonic
;
7551 const struct pseudo_opcode
*pdesc
;
7552 struct ia64_opcode
*idesc
;
7553 unsigned char qp_regno
;
7557 saved_input_line_pointer
= input_line_pointer
;
7558 input_line_pointer
= str
;
7560 /* extract the opcode (mnemonic): */
7562 mnemonic
= input_line_pointer
;
7563 ch
= get_symbol_end ();
7564 pdesc
= (struct pseudo_opcode
*) hash_find (md
.pseudo_hash
, mnemonic
);
7567 *input_line_pointer
= ch
;
7568 (*pdesc
->handler
) (pdesc
->arg
);
7572 /* find the instruction descriptor matching the arguments: */
7574 idesc
= ia64_find_opcode (mnemonic
);
7575 *input_line_pointer
= ch
;
7578 as_bad ("Unknown opcode `%s'", mnemonic
);
7582 idesc
= parse_operands (idesc
);
7586 /* Handle the dynamic ops we can handle now: */
7587 if (idesc
->type
== IA64_TYPE_DYN
)
7589 if (strcmp (idesc
->name
, "add") == 0)
7591 if (CURR_SLOT
.opnd
[2].X_op
== O_register
7592 && CURR_SLOT
.opnd
[2].X_add_number
< 4)
7596 idesc
= ia64_find_opcode (mnemonic
);
7598 know (!idesc
->next
);
7601 else if (strcmp (idesc
->name
, "mov") == 0)
7603 enum ia64_opnd opnd1
, opnd2
;
7606 opnd1
= idesc
->operands
[0];
7607 opnd2
= idesc
->operands
[1];
7608 if (opnd1
== IA64_OPND_AR3
)
7610 else if (opnd2
== IA64_OPND_AR3
)
7614 if (CURR_SLOT
.opnd
[rop
].X_op
== O_register
7615 && ar_is_in_integer_unit (CURR_SLOT
.opnd
[rop
].X_add_number
))
7619 idesc
= ia64_find_opcode (mnemonic
);
7620 while (idesc
!= NULL
7621 && (idesc
->operands
[0] != opnd1
7622 || idesc
->operands
[1] != opnd2
))
7623 idesc
= get_next_opcode (idesc
);
7628 if (md
.qp
.X_op
== O_register
)
7629 qp_regno
= md
.qp
.X_add_number
- REG_P
;
7631 flags
= idesc
->flags
;
7633 if ((flags
& IA64_OPCODE_FIRST
) != 0)
7634 insn_group_break (1, 0, 0);
7636 if ((flags
& IA64_OPCODE_NO_PRED
) != 0 && qp_regno
!= 0)
7638 as_bad ("`%s' cannot be predicated", idesc
->name
);
7642 /* build the instruction: */
7643 CURR_SLOT
.qp_regno
= qp_regno
;
7644 CURR_SLOT
.idesc
= idesc
;
7645 as_where (&CURR_SLOT
.src_file
, &CURR_SLOT
.src_line
);
7646 if (debug_type
== DEBUG_DWARF2
)
7647 dwarf2_where (&CURR_SLOT
.debug_line
);
7649 /* Add unwind entry, if there is one. */
7650 if (current_unwind_entry
)
7652 CURR_SLOT
.unwind_record
= current_unwind_entry
;
7653 current_unwind_entry
= NULL
;
7656 /* check for dependency violations */
7660 md
.curr_slot
= (md
.curr_slot
+ 1) % NUM_SLOTS
;
7661 if (++md
.num_slots_in_use
>= NUM_SLOTS
)
7664 if ((flags
& IA64_OPCODE_LAST
) != 0)
7665 insn_group_break (1, 0, 0);
7667 md
.last_text_seg
= now_seg
;
7670 input_line_pointer
= saved_input_line_pointer
;
7673 /* Called when symbol NAME cannot be found in the symbol table.
7674 Should be used for dynamic valued symbols only. */
7676 md_undefined_symbol (name
)
7682 /* Called for any expression that can not be recognized. When the
7683 function is called, `input_line_pointer' will point to the start of
7689 enum pseudo_type pseudo_type
;
7693 switch (*input_line_pointer
)
7696 /* find what relocation pseudo-function we're dealing with: */
7698 ch
= *++input_line_pointer
;
7699 for (i
= 0; i
< NELEMS (pseudo_func
); ++i
)
7700 if (pseudo_func
[i
].name
&& pseudo_func
[i
].name
[0] == ch
)
7702 len
= strlen (pseudo_func
[i
].name
);
7703 if (strncmp (pseudo_func
[i
].name
+ 1,
7704 input_line_pointer
+ 1, len
- 1) == 0
7705 && !is_part_of_name (input_line_pointer
[len
]))
7707 input_line_pointer
+= len
;
7708 pseudo_type
= pseudo_func
[i
].type
;
7712 switch (pseudo_type
)
7714 case PSEUDO_FUNC_RELOC
:
7716 if (*input_line_pointer
!= '(')
7718 as_bad ("Expected '('");
7721 ++input_line_pointer
; /* skip '(' */
7723 if (*input_line_pointer
++ != ')')
7725 as_bad ("Missing ')'");
7728 if (e
->X_op
!= O_symbol
)
7730 if (e
->X_op
!= O_pseudo_fixup
)
7732 as_bad ("Not a symbolic expression");
7735 if (S_GET_VALUE (e
->X_op_symbol
) == FUNC_FPTR_RELATIVE
7736 && i
== FUNC_LT_RELATIVE
)
7737 i
= FUNC_LT_FPTR_RELATIVE
;
7740 as_bad ("Illegal combination of relocation functions");
7744 /* make sure gas doesn't get rid of local symbols that are used
7746 e
->X_op
= O_pseudo_fixup
;
7747 e
->X_op_symbol
= pseudo_func
[i
].u
.sym
;
7750 case PSEUDO_FUNC_CONST
:
7751 e
->X_op
= O_constant
;
7752 e
->X_add_number
= pseudo_func
[i
].u
.ival
;
7756 as_bad ("Unknown pseudo function `%s'", input_line_pointer
- 1);
7762 ++input_line_pointer
;
7764 if (*input_line_pointer
!= ']')
7766 as_bad ("Closing bracket misssing");
7771 if (e
->X_op
!= O_register
)
7772 as_bad ("Register expected as index");
7774 ++input_line_pointer
;
7785 ignore_rest_of_line ();
7788 /* Return 1 if it's OK to adjust a reloc by replacing the symbol with
7789 a section symbol plus some offset. For relocs involving @fptr(),
7790 directives we don't want such adjustments since we need to have the
7791 original symbol's name in the reloc. */
7793 ia64_fix_adjustable (fix
)
7796 /* Prevent all adjustments to global symbols */
7797 if (S_IS_EXTERN (fix
->fx_addsy
) || S_IS_WEAK (fix
->fx_addsy
))
7800 switch (fix
->fx_r_type
)
7802 case BFD_RELOC_IA64_FPTR64I
:
7803 case BFD_RELOC_IA64_FPTR32MSB
:
7804 case BFD_RELOC_IA64_FPTR32LSB
:
7805 case BFD_RELOC_IA64_FPTR64MSB
:
7806 case BFD_RELOC_IA64_FPTR64LSB
:
7807 case BFD_RELOC_IA64_LTOFF_FPTR22
:
7808 case BFD_RELOC_IA64_LTOFF_FPTR64I
:
7818 ia64_force_relocation (fix
)
7821 switch (fix
->fx_r_type
)
7823 case BFD_RELOC_IA64_FPTR64I
:
7824 case BFD_RELOC_IA64_FPTR32MSB
:
7825 case BFD_RELOC_IA64_FPTR32LSB
:
7826 case BFD_RELOC_IA64_FPTR64MSB
:
7827 case BFD_RELOC_IA64_FPTR64LSB
:
7829 case BFD_RELOC_IA64_LTOFF22
:
7830 case BFD_RELOC_IA64_LTOFF64I
:
7831 case BFD_RELOC_IA64_LTOFF_FPTR22
:
7832 case BFD_RELOC_IA64_LTOFF_FPTR64I
:
7833 case BFD_RELOC_IA64_PLTOFF22
:
7834 case BFD_RELOC_IA64_PLTOFF64I
:
7835 case BFD_RELOC_IA64_PLTOFF64MSB
:
7836 case BFD_RELOC_IA64_PLTOFF64LSB
:
7845 /* Decide from what point a pc-relative relocation is relative to,
7846 relative to the pc-relative fixup. Er, relatively speaking. */
7848 ia64_pcrel_from_section (fix
, sec
)
7852 unsigned long off
= fix
->fx_frag
->fr_address
+ fix
->fx_where
;
7854 if (bfd_get_section_flags (stdoutput
, sec
) & SEC_CODE
)
7860 /* This is called whenever some data item (not an instruction) needs a
7861 fixup. We pick the right reloc code depending on the byteorder
7862 currently in effect. */
7864 ia64_cons_fix_new (f
, where
, nbytes
, exp
)
7870 bfd_reloc_code_real_type code
;
7875 /* There are no reloc for 8 and 16 bit quantities, but we allow
7876 them here since they will work fine as long as the expression
7877 is fully defined at the end of the pass over the source file. */
7878 case 1: code
= BFD_RELOC_8
; break;
7879 case 2: code
= BFD_RELOC_16
; break;
7881 if (target_big_endian
)
7882 code
= BFD_RELOC_IA64_DIR32MSB
;
7884 code
= BFD_RELOC_IA64_DIR32LSB
;
7888 if (target_big_endian
)
7889 code
= BFD_RELOC_IA64_DIR64MSB
;
7891 code
= BFD_RELOC_IA64_DIR64LSB
;
7895 as_bad ("Unsupported fixup size %d", nbytes
);
7896 ignore_rest_of_line ();
7899 if (exp
->X_op
== O_pseudo_fixup
)
7902 exp
->X_op
= O_symbol
;
7903 code
= ia64_gen_real_reloc_type (exp
->X_op_symbol
, code
);
7905 fix
= fix_new_exp (f
, where
, nbytes
, exp
, 0, code
);
7906 /* We need to store the byte order in effect in case we're going
7907 to fix an 8 or 16 bit relocation (for which there no real
7908 relocs available). See md_apply_fix(). */
7909 fix
->tc_fix_data
.bigendian
= target_big_endian
;
7912 /* Return the actual relocation we wish to associate with the pseudo
7913 reloc described by SYM and R_TYPE. SYM should be one of the
7914 symbols in the pseudo_func array, or NULL. */
7916 static bfd_reloc_code_real_type
7917 ia64_gen_real_reloc_type (sym
, r_type
)
7919 bfd_reloc_code_real_type r_type
;
7921 bfd_reloc_code_real_type
new = 0;
7928 switch (S_GET_VALUE (sym
))
7930 case FUNC_FPTR_RELATIVE
:
7933 case BFD_RELOC_IA64_IMM64
: new = BFD_RELOC_IA64_FPTR64I
; break;
7934 case BFD_RELOC_IA64_DIR32MSB
: new = BFD_RELOC_IA64_FPTR32MSB
; break;
7935 case BFD_RELOC_IA64_DIR32LSB
: new = BFD_RELOC_IA64_FPTR32LSB
; break;
7936 case BFD_RELOC_IA64_DIR64MSB
: new = BFD_RELOC_IA64_FPTR64MSB
; break;
7937 case BFD_RELOC_IA64_DIR64LSB
: new = BFD_RELOC_IA64_FPTR64LSB
; break;
7942 case FUNC_GP_RELATIVE
:
7945 case BFD_RELOC_IA64_IMM22
: new = BFD_RELOC_IA64_GPREL22
; break;
7946 case BFD_RELOC_IA64_IMM64
: new = BFD_RELOC_IA64_GPREL64I
; break;
7947 case BFD_RELOC_IA64_DIR32MSB
: new = BFD_RELOC_IA64_GPREL32MSB
; break;
7948 case BFD_RELOC_IA64_DIR32LSB
: new = BFD_RELOC_IA64_GPREL32LSB
; break;
7949 case BFD_RELOC_IA64_DIR64MSB
: new = BFD_RELOC_IA64_GPREL64MSB
; break;
7950 case BFD_RELOC_IA64_DIR64LSB
: new = BFD_RELOC_IA64_GPREL64LSB
; break;
7955 case FUNC_LT_RELATIVE
:
7958 case BFD_RELOC_IA64_IMM22
: new = BFD_RELOC_IA64_LTOFF22
; break;
7959 case BFD_RELOC_IA64_IMM64
: new = BFD_RELOC_IA64_LTOFF64I
; break;
7964 case FUNC_PLT_RELATIVE
:
7967 case BFD_RELOC_IA64_IMM22
: new = BFD_RELOC_IA64_PLTOFF22
; break;
7968 case BFD_RELOC_IA64_IMM64
: new = BFD_RELOC_IA64_PLTOFF64I
; break;
7969 case BFD_RELOC_IA64_DIR64MSB
: new = BFD_RELOC_IA64_PLTOFF64MSB
;break;
7970 case BFD_RELOC_IA64_DIR64LSB
: new = BFD_RELOC_IA64_PLTOFF64LSB
;break;
7975 case FUNC_SEC_RELATIVE
:
7978 case BFD_RELOC_IA64_DIR32MSB
: new = BFD_RELOC_IA64_SECREL32MSB
;break;
7979 case BFD_RELOC_IA64_DIR32LSB
: new = BFD_RELOC_IA64_SECREL32LSB
;break;
7980 case BFD_RELOC_IA64_DIR64MSB
: new = BFD_RELOC_IA64_SECREL64MSB
;break;
7981 case BFD_RELOC_IA64_DIR64LSB
: new = BFD_RELOC_IA64_SECREL64LSB
;break;
7986 case FUNC_SEG_RELATIVE
:
7989 case BFD_RELOC_IA64_DIR32MSB
: new = BFD_RELOC_IA64_SEGREL32MSB
;break;
7990 case BFD_RELOC_IA64_DIR32LSB
: new = BFD_RELOC_IA64_SEGREL32LSB
;break;
7991 case BFD_RELOC_IA64_DIR64MSB
: new = BFD_RELOC_IA64_SEGREL64MSB
;break;
7992 case BFD_RELOC_IA64_DIR64LSB
: new = BFD_RELOC_IA64_SEGREL64LSB
;break;
7997 case FUNC_LTV_RELATIVE
:
8000 case BFD_RELOC_IA64_DIR32MSB
: new = BFD_RELOC_IA64_LTV32MSB
; break;
8001 case BFD_RELOC_IA64_DIR32LSB
: new = BFD_RELOC_IA64_LTV32LSB
; break;
8002 case BFD_RELOC_IA64_DIR64MSB
: new = BFD_RELOC_IA64_LTV64MSB
; break;
8003 case BFD_RELOC_IA64_DIR64LSB
: new = BFD_RELOC_IA64_LTV64LSB
; break;
8008 case FUNC_LT_FPTR_RELATIVE
:
8011 case BFD_RELOC_IA64_IMM22
:
8012 new = BFD_RELOC_IA64_LTOFF_FPTR22
; break;
8013 case BFD_RELOC_IA64_IMM64
:
8014 new = BFD_RELOC_IA64_LTOFF_FPTR64I
; break;
8022 /* Hmmmm. Should this ever occur? */
8029 /* Here is where generate the appropriate reloc for pseudo relocation
8032 ia64_validate_fix (fix
)
8035 switch (fix
->fx_r_type
)
8037 case BFD_RELOC_IA64_FPTR64I
:
8038 case BFD_RELOC_IA64_FPTR32MSB
:
8039 case BFD_RELOC_IA64_FPTR64LSB
:
8040 case BFD_RELOC_IA64_LTOFF_FPTR22
:
8041 case BFD_RELOC_IA64_LTOFF_FPTR64I
:
8042 if (fix
->fx_offset
!= 0)
8043 as_bad_where (fix
->fx_file
, fix
->fx_line
,
8044 "No addend allowed in @fptr() relocation");
8054 fix_insn (fix
, odesc
, value
)
8056 const struct ia64_operand
*odesc
;
8059 bfd_vma insn
[3], t0
, t1
, control_bits
;
8064 slot
= fix
->fx_where
& 0x3;
8065 fixpos
= fix
->fx_frag
->fr_literal
+ (fix
->fx_where
- slot
);
8067 /* bundles are always in little-endian byte order */
8068 t0
= bfd_getl64 (fixpos
);
8069 t1
= bfd_getl64 (fixpos
+ 8);
8070 control_bits
= t0
& 0x1f;
8071 insn
[0] = (t0
>> 5) & 0x1ffffffffffLL
;
8072 insn
[1] = ((t0
>> 46) & 0x3ffff) | ((t1
& 0x7fffff) << 18);
8073 insn
[2] = (t1
>> 23) & 0x1ffffffffffLL
;
8075 err
= (*odesc
->insert
) (odesc
, value
, insn
+ slot
);
8078 as_bad_where (fix
->fx_file
, fix
->fx_line
, err
);
8082 t0
= control_bits
| (insn
[0] << 5) | (insn
[1] << 46);
8083 t1
= ((insn
[1] >> 18) & 0x7fffff) | (insn
[2] << 23);
8084 md_number_to_chars (fixpos
+ 0, t0
, 8);
8085 md_number_to_chars (fixpos
+ 8, t1
, 8);
8089 /* Attempt to simplify or even eliminate a fixup. The return value is
8090 ignored; perhaps it was once meaningful, but now it is historical.
8091 To indicate that a fixup has been eliminated, set FIXP->FX_DONE.
8093 If fixp->fx_addsy is non-NULL, we'll have to generate a reloc entry
8096 md_apply_fix3 (fix
, valuep
, seg
)
8102 valueT value
= *valuep
;
8105 fixpos
= fix
->fx_frag
->fr_literal
+ fix
->fx_where
;
8109 switch (fix
->fx_r_type
)
8111 case BFD_RELOC_IA64_DIR32MSB
:
8112 fix
->fx_r_type
= BFD_RELOC_IA64_PCREL32MSB
;
8116 case BFD_RELOC_IA64_DIR32LSB
:
8117 fix
->fx_r_type
= BFD_RELOC_IA64_PCREL32LSB
;
8121 case BFD_RELOC_IA64_DIR64MSB
:
8122 fix
->fx_r_type
= BFD_RELOC_IA64_PCREL64MSB
;
8126 case BFD_RELOC_IA64_DIR64LSB
:
8127 fix
->fx_r_type
= BFD_RELOC_IA64_PCREL64LSB
;
8137 switch (fix
->fx_r_type
)
8140 as_bad_where (fix
->fx_file
, fix
->fx_line
,
8141 "%s must have a constant value",
8142 elf64_ia64_operands
[fix
->tc_fix_data
.opnd
].desc
);
8149 /* ??? This is a hack copied from tc-i386.c to make PCREL relocs
8150 work. There should be a better way to handle this. */
8152 fix
->fx_offset
+= fix
->fx_where
+ fix
->fx_frag
->fr_address
;
8154 else if (fix
->tc_fix_data
.opnd
== IA64_OPND_NIL
)
8156 if (fix
->tc_fix_data
.bigendian
)
8157 number_to_chars_bigendian (fixpos
, value
, fix
->fx_size
);
8159 number_to_chars_littleendian (fixpos
, value
, fix
->fx_size
);
8165 fix_insn (fix
, elf64_ia64_operands
+ fix
->tc_fix_data
.opnd
, value
);
8172 /* Generate the BFD reloc to be stuck in the object file from the
8173 fixup used internally in the assembler. */
8175 tc_gen_reloc (sec
, fixp
)
8181 reloc
= xmalloc (sizeof (*reloc
));
8182 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
8183 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
8184 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
8185 reloc
->addend
= fixp
->fx_offset
;
8186 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
8190 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
8191 "Cannot represent %s relocation in object file",
8192 bfd_get_reloc_code_name (fixp
->fx_r_type
));
8197 /* Turn a string in input_line_pointer into a floating point constant
8198 of type type, and store the appropriate bytes in *lit. The number
8199 of LITTLENUMS emitted is stored in *size. An error message is
8200 returned, or NULL on OK. */
8202 #define MAX_LITTLENUMS 5
8205 md_atof (type
, lit
, size
)
8210 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
8211 LITTLENUM_TYPE
*word
;
8241 return "Bad call to MD_ATOF()";
8243 t
= atof_ieee (input_line_pointer
, type
, words
);
8245 input_line_pointer
= t
;
8246 *size
= prec
* sizeof (LITTLENUM_TYPE
);
8248 for (word
= words
+ prec
- 1; prec
--;)
8250 md_number_to_chars (lit
, (long) (*word
--), sizeof (LITTLENUM_TYPE
));
8251 lit
+= sizeof (LITTLENUM_TYPE
);
8256 /* Round up a section's size to the appropriate boundary. */
8258 md_section_align (seg
, size
)
8262 int align
= bfd_get_section_alignment (stdoutput
, seg
);
8263 valueT mask
= ((valueT
)1 << align
) - 1;
8265 return (size
+ mask
) & ~mask
;
8268 /* Handle ia64 specific semantics of the align directive. */
8271 ia64_md_do_align (n
, fill
, len
, max
)
8277 /* Fill any pending bundle with nops. */
8278 if (bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
)
8279 ia64_flush_insns ();
8281 /* When we align code in a text section, emit a bundle of 3 nops instead of
8282 zero bytes. We can only do this if a multiple of 16 bytes was requested.
8283 N is log base 2 of the requested alignment. */
8285 && bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
8288 /* Use mfi bundle of nops with no stop bits. */
8289 static const unsigned char be_nop
[]
8290 = { 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
8291 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c};
8292 static const unsigned char le_nop
[]
8293 = { 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
8294 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00};
8296 /* Make sure we are on a 16-byte boundary, in case someone has been
8297 putting data into a text section. */
8298 frag_align (4, 0, 0);
8300 if (target_big_endian
)
8301 frag_align_pattern (n
, be_nop
, 16, max
);
8303 frag_align_pattern (n
, le_nop
, 16, max
);