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
>> 4, 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
, ( ((bfd_vma
) 1 << 48) /* version */
2217 | ((bfd_vma
) 3 << 32) /* U & E handler flags */
2218 | ((size
+ extra
) / 8)), /* length (dwords) */
2221 process_unw_records (list
, output_vbyte_mem
);
2224 return size
+ extra
+ 16;
2234 radix
= *input_line_pointer
++;
2236 if (radix
!= 'C' && !is_end_of_line
[(unsigned char) radix
])
2238 as_bad ("Radix `%c' unsupported", *input_line_pointer
);
2239 ignore_rest_of_line ();
2244 /* .sbss, .bss etc. are macros that expand into ".section SECNAME". */
2246 dot_special_section (which
)
2249 set_section ((char *) special_section_name
[which
]);
2253 add_unwind_entry (ptr
)
2257 unwind_tail
->next
= ptr
;
2262 /* The current entry can in fact be a chain of unwind entries. */
2263 if (current_unwind_entry
== NULL
)
2264 current_unwind_entry
= ptr
;
2274 if (e
.X_op
!= O_constant
)
2275 as_bad ("Operand to .fframe must be a constant");
2278 add_unwind_entry (output_mem_stack_f (e
.X_add_number
));
2286 discard_rest_of_line ();
2297 sep
= parse_operand (&e1
);
2299 as_bad ("No second operand to .save");
2300 sep
= parse_operand (&e2
);
2302 reg1
= e1
.X_add_number
- REG_AR
;
2303 reg2
= e2
.X_add_number
- REG_GR
;
2305 /* Make sure its a valid ar.xxx reg, OR its br0, aka 'rp'. */
2306 if (e1
.X_op
== O_register
2307 && ((reg1
>=0 && reg1
< 128) || reg1
== REG_BR
- REG_AR
))
2309 if (e2
.X_op
== O_register
&& reg2
>=0 && reg2
< 128)
2313 case 17: /* ar.bsp */
2314 add_unwind_entry (output_bsp_when ());
2315 add_unwind_entry (output_bsp_gr (reg2
));
2317 case 18: /* ar.bspstore */
2318 add_unwind_entry (output_bspstore_when ());
2319 add_unwind_entry (output_bspstore_gr (reg2
));
2321 case 19: /* ar.rnat */
2322 add_unwind_entry (output_rnat_when ());
2323 add_unwind_entry (output_rnat_gr (reg2
));
2325 case 36: /* ar.unat */
2326 add_unwind_entry (output_unat_when ());
2327 add_unwind_entry (output_unat_gr (reg2
));
2329 case 40: /* ar.fpsr */
2330 add_unwind_entry (output_fpsr_when ());
2331 add_unwind_entry (output_fpsr_gr (reg2
));
2333 case 64: /* ar.pfs */
2334 add_unwind_entry (output_pfs_when ());
2335 add_unwind_entry (output_pfs_gr (reg2
));
2337 case 65: /* ar.lc */
2338 add_unwind_entry (output_lc_when ());
2339 add_unwind_entry (output_lc_gr (reg2
));
2341 case REG_BR
- REG_AR
: /* rp */
2342 add_unwind_entry (output_rp_when ());
2343 add_unwind_entry (output_rp_gr (reg2
));
2346 as_bad ("first operand is unknown application register");
2350 as_bad (" Second operand not a valid register");
2353 as_bad ("First operand not a valid register");
2360 discard_rest_of_line ();
2364 generate_unwind_image ()
2367 unsigned char *unw_rec
;
2370 /* Generate the unwind record. */
2371 size
= output_unw_records (unwind_list
, &unw_rec
);
2373 as_bad ("Unwind record is ont a multiple of 4 bytes.");
2375 /* If there are unwind records, switch sections, and output the info. */
2379 unsigned char *where
;
2380 unsigned char *personality
;
2383 set_section ((char *) special_section_name
[SPECIAL_SECTION_UNWIND_INFO
]);
2385 /* Set expression which points to start of unwind descriptor area. */
2386 unwind_info
= expr_build_dot ();
2388 where
= (unsigned char *)frag_more (size
);
2390 /* Issue a label for this address, and keep track of it to put it
2391 in the unwind section. */
2393 /* Copy the information from the unwind record into this section. The
2394 data is already in the correct byte order. */
2395 memcpy (where
, unw_rec
, size
);
2396 /* Add the personality address to the image. */
2397 if (personality_routine
!= 0)
2399 exp
.X_op
= O_symbol
;
2400 exp
.X_add_symbol
= personality_routine
;
2401 exp
.X_add_number
= 0;
2402 fix_new_exp (frag_now
, frag_now_fix () - 8, 8,
2403 &exp
, 0, BFD_RELOC_IA64_LTOFF_FPTR64LSB
);
2404 personality_routine
= 0;
2406 obj_elf_previous (0);
2409 free_list_records (unwind_list
);
2410 unwind_list
= unwind_tail
= current_unwind_entry
= NULL
;
2416 dot_handlerdata (dummy
)
2419 generate_unwind_image ();
2423 dot_unwentry (dummy
)
2426 discard_rest_of_line ();
2433 discard_rest_of_line ();
2444 sep
= parse_operand (&e1
);
2446 as_bad ("No second operand to .savesp");
2447 sep
= parse_operand (&e2
);
2449 reg1
= e1
.X_add_number
- REG_AR
;
2450 val
= e2
.X_add_number
;
2452 /* Make sure its a valid ar.xxx reg, OR its br0, aka 'rp'. */
2453 if (e1
.X_op
== O_register
2454 && ((reg1
>=0 && reg1
< 128) || reg1
== REG_BR
- REG_AR
|| reg1
== REG_PR
- REG_AR
))
2456 if (e2
.X_op
== O_constant
)
2460 case 17: /* ar.bsp */
2461 add_unwind_entry (output_bsp_when ());
2462 add_unwind_entry (output_bsp_sprel (val
));
2464 case 18: /* ar.bspstore */
2465 add_unwind_entry (output_bspstore_when ());
2466 add_unwind_entry (output_bspstore_sprel (val
));
2468 case 19: /* ar.rnat */
2469 add_unwind_entry (output_rnat_when ());
2470 add_unwind_entry (output_rnat_sprel (val
));
2472 case 36: /* ar.unat */
2473 add_unwind_entry (output_unat_when ());
2474 add_unwind_entry (output_unat_sprel (val
));
2476 case 40: /* ar.fpsr */
2477 add_unwind_entry (output_fpsr_when ());
2478 add_unwind_entry (output_fpsr_sprel (val
));
2480 case 64: /* ar.pfs */
2481 add_unwind_entry (output_pfs_when ());
2482 add_unwind_entry (output_pfs_sprel (val
));
2484 case 65: /* ar.lc */
2485 add_unwind_entry (output_lc_when ());
2486 add_unwind_entry (output_lc_sprel (val
));
2488 case REG_BR
- REG_AR
: /* rp */
2489 add_unwind_entry (output_rp_when ());
2490 add_unwind_entry (output_rp_sprel (val
));
2492 case REG_PR
- REG_AR
: /* Predicate registers. */
2493 add_unwind_entry (output_preds_when ());
2494 add_unwind_entry (output_preds_sprel (val
));
2497 as_bad ("first operand is unknown application register");
2501 as_bad (" Second operand not a valid constant");
2504 as_bad ("First operand not a valid register");
2511 discard_rest_of_line ();
2520 sep
= parse_operand (&e1
);
2522 parse_operand (&e2
);
2524 if (e1
.X_op
!= O_constant
)
2525 as_bad ("First operand to .save.g must be a constant.");
2528 int grmask
= e1
.X_add_number
;
2530 add_unwind_entry (output_gr_mem (grmask
));
2533 int reg
= e2
.X_add_number
- REG_GR
;
2534 if (e2
.X_op
== O_register
&& reg
>=0 && reg
< 128)
2535 add_unwind_entry (output_gr_gr (grmask
, reg
));
2537 as_bad ("Second operand is an invalid register.");
2548 sep
= parse_operand (&e1
);
2550 if (e1
.X_op
!= O_constant
)
2551 as_bad ("Operand to .save.f must be a constant.");
2554 int frmask
= e1
.X_add_number
;
2555 add_unwind_entry (output_fr_mem (e1
.X_add_number
));
2565 sep
= parse_operand (&e1
);
2567 if (e1
.X_op
!= O_constant
)
2568 as_bad ("Operand to .save.b must be a constant.");
2571 int brmask
= e1
.X_add_number
;
2572 add_unwind_entry (output_br_mem (brmask
));
2582 sep
= parse_operand (&e1
);
2584 parse_operand (&e2
);
2586 if (e1
.X_op
!= O_constant
|| sep
!= ',' || e2
.X_op
!= O_constant
)
2587 as_bad ("Both operands of .save.gf must be constants.");
2590 int grmask
= e1
.X_add_number
;
2591 int frmask
= e2
.X_add_number
;
2592 add_unwind_entry (output_frgr_mem (grmask
, frmask
));
2603 if (e
.X_op
!= O_constant
)
2604 as_bad ("Operand to .spill must be a constant");
2607 add_unwind_entry (output_spill_base (e
.X_add_number
));
2615 discard_rest_of_line ();
2619 dot_personality (dummy
)
2624 name
= input_line_pointer
;
2625 c
= get_symbol_end ();
2626 p
= input_line_pointer
;
2627 personality_routine
= symbol_find_or_make (name
);
2630 demand_empty_rest_of_line ();
2640 proc_start
= expr_build_dot ();
2641 /* Parse names of main and alternate entry points and mark them s
2642 function symbols: */
2646 name
= input_line_pointer
;
2647 c
= get_symbol_end ();
2648 p
= input_line_pointer
;
2649 sym
= symbol_find_or_make (name
);
2650 if (proc_start
== 0)
2654 symbol_get_bfdsym (sym
)->flags
|= BSF_FUNCTION
;
2657 if (*input_line_pointer
!= ',')
2659 ++input_line_pointer
;
2661 demand_empty_rest_of_line ();
2664 unwind_list
= unwind_tail
= current_unwind_entry
= NULL
;
2665 personality_routine
= 0;
2672 unwind_prologue
= 0;
2673 add_unwind_entry (output_body ());
2677 dot_prologue (dummy
)
2680 unwind_prologue
= 1;
2682 if (! is_end_of_line
[(unsigned char) *input_line_pointer
])
2686 sep
= parse_operand (&e1
);
2688 as_bad ("No second operand to .prologue");
2689 sep
= parse_operand (&e2
);
2691 if (e1
.X_op
== O_constant
)
2693 if (e2
.X_op
== O_constant
)
2695 int mask
= e1
.X_add_number
;
2696 int reg
= e2
.X_add_number
;
2697 add_unwind_entry (output_prologue_gr (mask
, reg
));
2700 as_bad ("Second operand not a constant");
2703 as_bad ("First operand not a constant");
2706 add_unwind_entry (output_prologue ());
2718 subsegT saved_subseg
;
2720 saved_seg
= now_seg
;
2721 saved_subseg
= now_subseg
;
2724 demand_empty_rest_of_line ();
2726 insn_group_break (1, 0, 0);
2727 ia64_flush_insns ();
2729 /* If there was a .handlerdata, we haven't generated an image yet. */
2730 if (unwind_info
== 0)
2732 generate_unwind_image ();
2735 subseg_set (md
.last_text_seg
, 0);
2736 proc_end
= expr_build_dot ();
2738 set_section ((char *) special_section_name
[SPECIAL_SECTION_UNWIND
]);
2739 ptr
= frag_more (24);
2740 where
= frag_now_fix () - 24;
2742 /* Issue the values of a) Proc Begin, b) Proc End, c) Unwind Record. */
2743 e
.X_op
= O_pseudo_fixup
;
2744 e
.X_op_symbol
= pseudo_func
[FUNC_SEG_RELATIVE
].u
.sym
;
2746 e
.X_add_symbol
= proc_start
;
2747 ia64_cons_fix_new (frag_now
, where
, 8, &e
);
2749 e
.X_op
= O_pseudo_fixup
;
2750 e
.X_op_symbol
= pseudo_func
[FUNC_SEG_RELATIVE
].u
.sym
;
2752 e
.X_add_symbol
= proc_end
;
2753 ia64_cons_fix_new (frag_now
, where
+ 8, 8, &e
);
2755 if (unwind_info
!= 0)
2757 e
.X_op
= O_pseudo_fixup
;
2758 e
.X_op_symbol
= pseudo_func
[FUNC_SEG_RELATIVE
].u
.sym
;
2760 e
.X_add_symbol
= unwind_info
;
2761 ia64_cons_fix_new (frag_now
, where
+ 16, 8, &e
);
2764 md_number_to_chars (ptr
+ 16, 0, 8);
2766 subseg_set (saved_seg
, saved_subseg
);
2767 proc_start
= proc_end
= unwind_info
= 0;
2771 dot_template (template)
2774 CURR_SLOT
.user_template
= template;
2781 int ins
, locs
, outs
, rots
;
2783 if (is_it_end_of_statement ())
2784 ins
= locs
= outs
= rots
= 0;
2787 ins
= get_absolute_expression ();
2788 if (*input_line_pointer
++ != ',')
2790 locs
= get_absolute_expression ();
2791 if (*input_line_pointer
++ != ',')
2793 outs
= get_absolute_expression ();
2794 if (*input_line_pointer
++ != ',')
2796 rots
= get_absolute_expression ();
2798 set_regstack (ins
, locs
, outs
, rots
);
2802 as_bad ("Comma expected");
2803 ignore_rest_of_line ();
2810 unsigned num_regs
, num_alloced
= 0;
2811 struct dynreg
**drpp
, *dr
;
2812 int ch
, base_reg
= 0;
2818 case DYNREG_GR
: base_reg
= REG_GR
+ 32; break;
2819 case DYNREG_FR
: base_reg
= REG_FR
+ 32; break;
2820 case DYNREG_PR
: base_reg
= REG_P
+ 16; break;
2824 /* first, remove existing names from hash table: */
2825 for (dr
= md
.dynreg
[type
]; dr
&& dr
->num_regs
; dr
= dr
->next
)
2827 hash_delete (md
.dynreg_hash
, dr
->name
);
2831 drpp
= &md
.dynreg
[type
];
2834 start
= input_line_pointer
;
2835 ch
= get_symbol_end ();
2836 *input_line_pointer
= ch
;
2837 len
= (input_line_pointer
- start
);
2840 if (*input_line_pointer
!= '[')
2842 as_bad ("Expected '['");
2845 ++input_line_pointer
; /* skip '[' */
2847 num_regs
= get_absolute_expression ();
2849 if (*input_line_pointer
++ != ']')
2851 as_bad ("Expected ']'");
2856 num_alloced
+= num_regs
;
2860 if (num_alloced
> md
.rot
.num_regs
)
2862 as_bad ("Used more than the declared %d rotating registers",
2868 if (num_alloced
> 96)
2870 as_bad ("Used more than the available 96 rotating registers");
2875 if (num_alloced
> 48)
2877 as_bad ("Used more than the available 48 rotating registers");
2886 name
= obstack_alloc (¬es
, len
+ 1);
2887 memcpy (name
, start
, len
);
2892 *drpp
= obstack_alloc (¬es
, sizeof (*dr
));
2893 memset (*drpp
, 0, sizeof (*dr
));
2898 dr
->num_regs
= num_regs
;
2899 dr
->base
= base_reg
;
2901 base_reg
+= num_regs
;
2903 if (hash_insert (md
.dynreg_hash
, name
, dr
))
2905 as_bad ("Attempt to redefine register set `%s'", name
);
2909 if (*input_line_pointer
!= ',')
2911 ++input_line_pointer
; /* skip comma */
2914 demand_empty_rest_of_line ();
2918 ignore_rest_of_line ();
2922 dot_byteorder (byteorder
)
2925 target_big_endian
= byteorder
;
2937 option
= input_line_pointer
;
2938 ch
= get_symbol_end ();
2939 if (strcmp (option
, "lsb") == 0)
2940 md
.flags
&= ~EF_IA_64_BE
;
2941 else if (strcmp (option
, "msb") == 0)
2942 md
.flags
|= EF_IA_64_BE
;
2943 else if (strcmp (option
, "abi32") == 0)
2944 md
.flags
&= ~EF_IA_64_ABI64
;
2945 else if (strcmp (option
, "abi64") == 0)
2946 md
.flags
|= EF_IA_64_ABI64
;
2948 as_bad ("Unknown psr option `%s'", option
);
2949 *input_line_pointer
= ch
;
2952 if (*input_line_pointer
!= ',')
2955 ++input_line_pointer
;
2958 demand_empty_rest_of_line ();
2965 as_bad (".alias not implemented yet");
2972 new_logical_line (0, get_absolute_expression ());
2973 demand_empty_rest_of_line ();
2977 parse_section_name ()
2983 if (*input_line_pointer
!= '"')
2985 as_bad ("Missing section name");
2986 ignore_rest_of_line ();
2989 name
= demand_copy_C_string (&len
);
2992 ignore_rest_of_line ();
2996 if (*input_line_pointer
!= ',')
2998 as_bad ("Comma expected after section name");
2999 ignore_rest_of_line ();
3002 ++input_line_pointer
; /* skip comma */
3010 char *name
= parse_section_name ();
3016 obj_elf_previous (0);
3019 /* Why doesn't float_cons() call md_cons_align() the way cons() does? */
3021 stmt_float_cons (kind
)
3028 case 'd': size
= 8; break;
3029 case 'x': size
= 10; break;
3036 ia64_do_align (size
);
3044 int saved_auto_align
= md
.auto_align
;
3048 md
.auto_align
= saved_auto_align
;
3052 dot_xfloat_cons (kind
)
3055 char *name
= parse_section_name ();
3060 stmt_float_cons (kind
);
3061 obj_elf_previous (0);
3065 dot_xstringer (zero
)
3068 char *name
= parse_section_name ();
3074 obj_elf_previous (0);
3081 int saved_auto_align
= md
.auto_align
;
3082 char *name
= parse_section_name ();
3089 md
.auto_align
= saved_auto_align
;
3090 obj_elf_previous (0);
3094 dot_xfloat_cons_ua (kind
)
3097 int saved_auto_align
= md
.auto_align
;
3098 char *name
= parse_section_name ();
3104 stmt_float_cons (kind
);
3105 md
.auto_align
= saved_auto_align
;
3106 obj_elf_previous (0);
3109 /* .reg.val <regname>,value */
3117 if (reg
.X_op
!= O_register
)
3119 as_bad (_("Register name expected"));
3120 ignore_rest_of_line ();
3122 else if (*input_line_pointer
++ != ',')
3124 as_bad (_("Comma expected"));
3125 ignore_rest_of_line ();
3129 valueT value
= get_absolute_expression ();
3130 int regno
= reg
.X_add_number
;
3131 if (regno
< REG_GR
|| regno
> REG_GR
+128)
3132 as_warn (_("Register value annotation ignored"));
3135 gr_values
[regno
-REG_GR
].known
= 1;
3136 gr_values
[regno
-REG_GR
].value
= value
;
3137 gr_values
[regno
-REG_GR
].path
= md
.path
;
3140 demand_empty_rest_of_line ();
3143 /* select dv checking mode
3148 A stop is inserted when changing modes
3154 if (md
.manual_bundling
)
3155 as_warn (_("Directive invalid within a bundle"));
3157 if (type
== 'E' || type
== 'A')
3158 md
.mode_explicitly_set
= 0;
3160 md
.mode_explicitly_set
= 1;
3167 if (md
.explicit_mode
)
3168 insn_group_break (1, 0, 0);
3169 md
.explicit_mode
= 0;
3173 if (!md
.explicit_mode
)
3174 insn_group_break (1, 0, 0);
3175 md
.explicit_mode
= 1;
3179 if (md
.explicit_mode
!= md
.default_explicit_mode
)
3180 insn_group_break (1, 0, 0);
3181 md
.explicit_mode
= md
.default_explicit_mode
;
3182 md
.mode_explicitly_set
= 0;
3193 for (regno
= 0;regno
< 64;regno
++)
3195 if (mask
& ((valueT
)1<<regno
))
3197 fprintf (stderr
, "%s p%d", comma
, regno
);
3204 .pred.rel.clear [p1 [,p2 [,...]]] (also .pred.rel "clear")
3205 .pred.rel.imply p1, p2 (also .pred.rel "imply")
3206 .pred.rel.mutex p1, p2 [,...] (also .pred.rel "mutex")
3207 .pred.safe_across_calls p1 [, p2 [,...]]
3215 int p1
= -1, p2
= -1;
3219 if (*input_line_pointer
!= '"')
3221 as_bad (_("Missing predicate relation type"));
3222 ignore_rest_of_line ();
3228 char *form
= demand_copy_C_string (&len
);
3229 if (strcmp (form
, "mutex") == 0)
3231 else if (strcmp (form
, "clear") == 0)
3233 else if (strcmp (form
, "imply") == 0)
3237 as_bad (_("Unrecognized predicate relation type"));
3238 ignore_rest_of_line ();
3242 if (*input_line_pointer
== ',')
3243 ++input_line_pointer
;
3253 if (toupper (*input_line_pointer
) != 'P'
3254 || (regno
= atoi (++input_line_pointer
)) < 0
3257 as_bad (_("Predicate register expected"));
3258 ignore_rest_of_line ();
3261 while (isdigit (*input_line_pointer
))
3262 ++input_line_pointer
;
3269 as_warn (_("Duplicate predicate register ignored"));
3270 mask
|= bit
; count
++;
3271 /* see if it's a range */
3272 if (*input_line_pointer
== '-')
3275 ++input_line_pointer
;
3277 if (toupper (*input_line_pointer
) != 'P'
3278 || (regno
= atoi (++input_line_pointer
)) < 0
3281 as_bad (_("Predicate register expected"));
3282 ignore_rest_of_line ();
3285 while (isdigit (*input_line_pointer
))
3286 ++input_line_pointer
;
3290 as_bad (_("Bad register range"));
3291 ignore_rest_of_line ();
3297 mask
|= bit
; count
++;
3301 if (*input_line_pointer
!= ',')
3303 ++input_line_pointer
;
3312 clear_qp_mutex (mask
);
3313 clear_qp_implies (mask
, (valueT
)0);
3316 if (count
!= 2 || p1
== -1 || p2
== -1)
3317 as_bad (_("Predicate source and target required"));
3318 else if (p1
== 0 || p2
== 0)
3319 as_bad (_("Use of p0 is not valid in this context"));
3321 add_qp_imply (p1
, p2
);
3326 as_bad (_("At least two PR arguments expected"));
3331 as_bad (_("Use of p0 is not valid in this context"));
3334 add_qp_mutex (mask
);
3337 /* note that we don't override any existing relations */
3340 as_bad (_("At least one PR argument expected"));
3345 fprintf (stderr
, "Safe across calls: ");
3346 print_prmask (mask
);
3347 fprintf (stderr
, "\n");
3349 qp_safe_across_calls
= mask
;
3352 demand_empty_rest_of_line ();
3355 /* .entry label [, label [, ...]]
3356 Hint to DV code that the given labels are to be considered entry points.
3357 Otherwise, only global labels are considered entry points.
3370 name
= input_line_pointer
;
3371 c
= get_symbol_end ();
3372 symbolP
= symbol_find_or_make (name
);
3374 err
= hash_insert (md
.entry_hash
, S_GET_NAME (symbolP
), (PTR
) symbolP
);
3376 as_fatal (_("Inserting \"%s\" into entry hint table failed: %s"),
3379 *input_line_pointer
= c
;
3381 c
= *input_line_pointer
;
3384 input_line_pointer
++;
3386 if (*input_line_pointer
== '\n')
3392 demand_empty_rest_of_line ();
3395 /* .mem.offset offset, base
3396 "base" is used to distinguish between offsets from a different base.
3399 dot_mem_offset (dummy
)
3402 md
.mem_offset
.hint
= 1;
3403 md
.mem_offset
.offset
= get_absolute_expression ();
3404 if (*input_line_pointer
!= ',')
3406 as_bad (_("Comma expected"));
3407 ignore_rest_of_line ();
3410 ++input_line_pointer
;
3411 md
.mem_offset
.base
= get_absolute_expression ();
3412 demand_empty_rest_of_line ();
3415 /* ia64-specific pseudo-ops: */
3416 const pseudo_typeS md_pseudo_table
[] =
3418 { "radix", dot_radix
, 0 },
3419 { "lcomm", s_lcomm_bytes
, 1 },
3420 { "bss", dot_special_section
, SPECIAL_SECTION_BSS
},
3421 { "sbss", dot_special_section
, SPECIAL_SECTION_SBSS
},
3422 { "sdata", dot_special_section
, SPECIAL_SECTION_SDATA
},
3423 { "rodata", dot_special_section
, SPECIAL_SECTION_RODATA
},
3424 { "comment", dot_special_section
, SPECIAL_SECTION_COMMENT
},
3425 { "ia_64.unwind", dot_special_section
, SPECIAL_SECTION_UNWIND
},
3426 { "ia_64.unwind_info", dot_special_section
, SPECIAL_SECTION_UNWIND_INFO
},
3427 { "proc", dot_proc
, 0 },
3428 { "body", dot_body
, 0 },
3429 { "prologue", dot_prologue
, 0 },
3430 { "endp", dot_endp
},
3431 { "file", dwarf2_directive_file
},
3432 { "loc", dwarf2_directive_loc
},
3434 { "fframe", dot_fframe
},
3435 { "vframe", dot_vframe
},
3436 { "save", dot_save
},
3437 { "restore", dot_restore
},
3438 { "handlerdata", dot_handlerdata
},
3439 { "unwentry", dot_unwentry
},
3440 { "alprp", dot_altrp
},
3441 { "savesp", dot_savesp
},
3442 { "savepsp", dot_savepsp
},
3443 { "save.g", dot_saveg
},
3444 { "save.f", dot_savef
},
3445 { "save.b", dot_saveb
},
3446 { "save.gf", dot_savegf
},
3447 { "spill", dot_spill
},
3448 { "unwabi", dot_unwabi
},
3449 { "personality", dot_personality
},
3451 { "estate", dot_estate
},
3453 { "mii", dot_template
, 0x0 },
3454 { "mli", dot_template
, 0x2 }, /* old format, for compatibility */
3455 { "mlx", dot_template
, 0x2 },
3456 { "mmi", dot_template
, 0x4 },
3457 { "mfi", dot_template
, 0x6 },
3458 { "mmf", dot_template
, 0x7 },
3459 { "mib", dot_template
, 0x8 },
3460 { "mbb", dot_template
, 0x9 },
3461 { "bbb", dot_template
, 0xb },
3462 { "mmb", dot_template
, 0xc },
3463 { "mfb", dot_template
, 0xe },
3465 { "lb", dot_scope
, 0 },
3466 { "le", dot_scope
, 1 },
3468 { "align", s_align_bytes
, 0 },
3469 { "regstk", dot_regstk
, 0 },
3470 { "rotr", dot_rot
, DYNREG_GR
},
3471 { "rotf", dot_rot
, DYNREG_FR
},
3472 { "rotp", dot_rot
, DYNREG_PR
},
3473 { "lsb", dot_byteorder
, 0 },
3474 { "msb", dot_byteorder
, 1 },
3475 { "psr", dot_psr
, 0 },
3476 { "alias", dot_alias
, 0 },
3477 { "ln", dot_ln
, 0 }, /* source line info (for debugging) */
3479 { "xdata1", dot_xdata
, 1 },
3480 { "xdata2", dot_xdata
, 2 },
3481 { "xdata4", dot_xdata
, 4 },
3482 { "xdata8", dot_xdata
, 8 },
3483 { "xreal4", dot_xfloat_cons
, 'f' },
3484 { "xreal8", dot_xfloat_cons
, 'd' },
3485 { "xreal10", dot_xfloat_cons
, 'x' },
3486 { "xstring", dot_xstringer
, 0 },
3487 { "xstringz", dot_xstringer
, 1 },
3489 /* unaligned versions: */
3490 { "xdata2.ua", dot_xdata_ua
, 2 },
3491 { "xdata4.ua", dot_xdata_ua
, 4 },
3492 { "xdata8.ua", dot_xdata_ua
, 8 },
3493 { "xreal4.ua", dot_xfloat_cons_ua
, 'f' },
3494 { "xreal8.ua", dot_xfloat_cons_ua
, 'd' },
3495 { "xreal10.ua", dot_xfloat_cons_ua
, 'x' },
3497 /* annotations/DV checking support */
3498 { "entry", dot_entry
, 0 },
3499 { "mem.offset", dot_mem_offset
},
3500 { "pred.rel", dot_pred_rel
, 0 },
3501 { "pred.rel.clear", dot_pred_rel
, 'c' },
3502 { "pred.rel.imply", dot_pred_rel
, 'i' },
3503 { "pred.rel.mutex", dot_pred_rel
, 'm' },
3504 { "pred.safe_across_calls", dot_pred_rel
, 's' },
3505 { "reg.val", dot_reg_val
},
3506 { "auto", dot_dv_mode
, 'a' },
3507 { "explicit", dot_dv_mode
, 'e' },
3508 { "default", dot_dv_mode
, 'd' },
3513 static const struct pseudo_opcode
3516 void (*handler
) (int);
3521 /* these are more like pseudo-ops, but don't start with a dot */
3522 { "data1", cons
, 1 },
3523 { "data2", cons
, 2 },
3524 { "data4", cons
, 4 },
3525 { "data8", cons
, 8 },
3526 { "real4", stmt_float_cons
, 'f' },
3527 { "real8", stmt_float_cons
, 'd' },
3528 { "real10", stmt_float_cons
, 'x' },
3529 { "string", stringer
, 0 },
3530 { "stringz", stringer
, 1 },
3532 /* unaligned versions: */
3533 { "data2.ua", stmt_cons_ua
, 2 },
3534 { "data4.ua", stmt_cons_ua
, 4 },
3535 { "data8.ua", stmt_cons_ua
, 8 },
3536 { "real4.ua", float_cons
, 'f' },
3537 { "real8.ua", float_cons
, 'd' },
3538 { "real10.ua", float_cons
, 'x' },
3541 /* Declare a register by creating a symbol for it and entering it in
3542 the symbol table. */
3544 declare_register (name
, regnum
)
3551 sym
= symbol_new (name
, reg_section
, regnum
, &zero_address_frag
);
3553 err
= hash_insert (md
.reg_hash
, S_GET_NAME (sym
), (PTR
) sym
);
3555 as_fatal ("Inserting \"%s\" into register table failed: %s",
3562 declare_register_set (prefix
, num_regs
, base_regnum
)
3570 for (i
= 0; i
< num_regs
; ++i
)
3572 sprintf (name
, "%s%u", prefix
, i
);
3573 declare_register (name
, base_regnum
+ i
);
3578 operand_width (opnd
)
3579 enum ia64_opnd opnd
;
3581 const struct ia64_operand
*odesc
= &elf64_ia64_operands
[opnd
];
3582 unsigned int bits
= 0;
3586 for (i
= 0; i
< NELEMS (odesc
->field
) && odesc
->field
[i
].bits
; ++i
)
3587 bits
+= odesc
->field
[i
].bits
;
3593 operand_match (idesc
, index
, e
)
3594 const struct ia64_opcode
*idesc
;
3598 enum ia64_opnd opnd
= idesc
->operands
[index
];
3599 int bits
, relocatable
= 0;
3600 struct insn_fix
*fix
;
3607 case IA64_OPND_AR_CCV
:
3608 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_AR
+ 32)
3612 case IA64_OPND_AR_PFS
:
3613 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_AR
+ 64)
3618 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_GR
+ 0)
3623 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_IP
)
3628 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_PR
)
3632 case IA64_OPND_PR_ROT
:
3633 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_PR_ROT
)
3638 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_PSR
)
3642 case IA64_OPND_PSR_L
:
3643 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_PSR_L
)
3647 case IA64_OPND_PSR_UM
:
3648 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_PSR_UM
)
3653 if (e
->X_op
== O_constant
&& e
->X_add_number
== 1)
3658 if (e
->X_op
== O_constant
&& e
->X_add_number
== 8)
3663 if (e
->X_op
== O_constant
&& e
->X_add_number
== 16)
3667 /* register operands: */
3670 if (e
->X_op
== O_register
&& e
->X_add_number
>= REG_AR
3671 && e
->X_add_number
< REG_AR
+ 128)
3677 if (e
->X_op
== O_register
&& e
->X_add_number
>= REG_BR
3678 && e
->X_add_number
< REG_BR
+ 8)
3683 if (e
->X_op
== O_register
&& e
->X_add_number
>= REG_CR
3684 && e
->X_add_number
< REG_CR
+ 128)
3692 if (e
->X_op
== O_register
&& e
->X_add_number
>= REG_FR
3693 && e
->X_add_number
< REG_FR
+ 128)
3699 if (e
->X_op
== O_register
&& e
->X_add_number
>= REG_P
3700 && e
->X_add_number
< REG_P
+ 64)
3707 if (e
->X_op
== O_register
&& e
->X_add_number
>= REG_GR
3708 && e
->X_add_number
< REG_GR
+ 128)
3712 case IA64_OPND_R3_2
:
3713 if (e
->X_op
== O_register
&& e
->X_add_number
>= REG_GR
3714 && e
->X_add_number
< REG_GR
+ 4)
3718 /* indirect operands: */
3719 case IA64_OPND_CPUID_R3
:
3720 case IA64_OPND_DBR_R3
:
3721 case IA64_OPND_DTR_R3
:
3722 case IA64_OPND_ITR_R3
:
3723 case IA64_OPND_IBR_R3
:
3724 case IA64_OPND_MSR_R3
:
3725 case IA64_OPND_PKR_R3
:
3726 case IA64_OPND_PMC_R3
:
3727 case IA64_OPND_PMD_R3
:
3728 case IA64_OPND_RR_R3
:
3729 if (e
->X_op
== O_index
&& e
->X_op_symbol
3730 && (S_GET_VALUE (e
->X_op_symbol
) - IND_CPUID
3731 == opnd
- IA64_OPND_CPUID_R3
))
3736 if (e
->X_op
== O_index
&& !e
->X_op_symbol
)
3740 /* immediate operands: */
3741 case IA64_OPND_CNT2a
:
3742 case IA64_OPND_LEN4
:
3743 case IA64_OPND_LEN6
:
3744 bits
= operand_width (idesc
->operands
[index
]);
3745 if (e
->X_op
== O_constant
3746 && (bfd_vma
) (e
->X_add_number
- 1) < ((bfd_vma
) 1 << bits
))
3750 case IA64_OPND_CNT2b
:
3751 if (e
->X_op
== O_constant
3752 && (bfd_vma
) (e
->X_add_number
- 1) < 3)
3756 case IA64_OPND_CNT2c
:
3757 val
= e
->X_add_number
;
3758 if (e
->X_op
== O_constant
3759 && (val
== 0 || val
== 7 || val
== 15 || val
== 16))
3764 /* SOR must be an integer multiple of 8 */
3765 if (e
->X_add_number
& 0x7)
3769 if (e
->X_op
== O_constant
&&
3770 (bfd_vma
) e
->X_add_number
<= 96)
3774 case IA64_OPND_IMMU62
:
3775 if (e
->X_op
== O_constant
)
3777 if ((bfd_vma
) e
->X_add_number
< ((bfd_vma
) 1 << 62))
3782 /* FIXME -- need 62-bit relocation type */
3783 as_bad (_("62-bit relocation not yet implemented"));
3787 case IA64_OPND_IMMU64
:
3788 if (e
->X_op
== O_symbol
|| e
->X_op
== O_pseudo_fixup
3789 || e
->X_op
== O_subtract
)
3791 fix
= CURR_SLOT
.fixup
+ CURR_SLOT
.num_fixups
;
3792 fix
->code
= BFD_RELOC_IA64_IMM64
;
3793 if (e
->X_op
!= O_subtract
)
3795 fix
->code
= ia64_gen_real_reloc_type (e
->X_op_symbol
, fix
->code
);
3796 if (e
->X_op
== O_pseudo_fixup
)
3800 fix
->opnd
= idesc
->operands
[index
];
3803 ++CURR_SLOT
.num_fixups
;
3806 else if (e
->X_op
== O_constant
)
3810 case IA64_OPND_CCNT5
:
3811 case IA64_OPND_CNT5
:
3812 case IA64_OPND_CNT6
:
3813 case IA64_OPND_CPOS6a
:
3814 case IA64_OPND_CPOS6b
:
3815 case IA64_OPND_CPOS6c
:
3816 case IA64_OPND_IMMU2
:
3817 case IA64_OPND_IMMU7a
:
3818 case IA64_OPND_IMMU7b
:
3819 case IA64_OPND_IMMU21
:
3820 case IA64_OPND_IMMU24
:
3821 case IA64_OPND_MBTYPE4
:
3822 case IA64_OPND_MHTYPE8
:
3823 case IA64_OPND_POS6
:
3824 bits
= operand_width (idesc
->operands
[index
]);
3825 if (e
->X_op
== O_constant
3826 && (bfd_vma
) e
->X_add_number
< ((bfd_vma
) 1 << bits
))
3830 case IA64_OPND_IMMU9
:
3831 bits
= operand_width (idesc
->operands
[index
]);
3832 if (e
->X_op
== O_constant
3833 && (bfd_vma
) e
->X_add_number
< ((bfd_vma
) 1 << bits
))
3835 int lobits
= e
->X_add_number
& 0x3;
3836 if (((bfd_vma
) e
->X_add_number
& 0x3C) != 0 && lobits
== 0)
3837 e
->X_add_number
|= (bfd_vma
)0x3;
3842 case IA64_OPND_IMM44
:
3843 /* least 16 bits must be zero */
3844 if ((e
->X_add_number
& 0xffff) != 0)
3845 as_warn (_("lower 16 bits of mask ignored"));
3847 if (e
->X_op
== O_constant
3848 && ((e
->X_add_number
>= 0
3849 && e
->X_add_number
< ((bfd_vma
) 1 << 44))
3850 || (e
->X_add_number
< 0
3851 && -e
->X_add_number
<= ((bfd_vma
) 1 << 44))))
3854 if (e
->X_add_number
>= 0
3855 && (e
->X_add_number
& ((bfd_vma
) 1 << 43)) != 0)
3857 e
->X_add_number
|= ~(((bfd_vma
) 1 << 44) - 1);
3863 case IA64_OPND_IMM17
:
3864 /* bit 0 is a don't care (pr0 is hardwired to 1) */
3865 if (e
->X_op
== O_constant
3866 && ((e
->X_add_number
>= 0
3867 && e
->X_add_number
< ((bfd_vma
) 1 << 17))
3868 || (e
->X_add_number
< 0
3869 && -e
->X_add_number
<= ((bfd_vma
) 1 << 17))))
3872 if (e
->X_add_number
>= 0
3873 && (e
->X_add_number
& ((bfd_vma
) 1 << 16)) != 0)
3875 e
->X_add_number
|= ~(((bfd_vma
)1 << 17) - 1);
3881 case IA64_OPND_IMM14
:
3882 case IA64_OPND_IMM22
:
3884 case IA64_OPND_IMM1
:
3885 case IA64_OPND_IMM8
:
3886 case IA64_OPND_IMM8U4
:
3887 case IA64_OPND_IMM8M1
:
3888 case IA64_OPND_IMM8M1U4
:
3889 case IA64_OPND_IMM8M1U8
:
3890 case IA64_OPND_IMM9a
:
3891 case IA64_OPND_IMM9b
:
3892 bits
= operand_width (idesc
->operands
[index
]);
3893 if (relocatable
&& (e
->X_op
== O_symbol
3894 || e
->X_op
== O_subtract
3895 || e
->X_op
== O_pseudo_fixup
))
3897 fix
= CURR_SLOT
.fixup
+ CURR_SLOT
.num_fixups
;
3899 if (idesc
->operands
[index
] == IA64_OPND_IMM14
)
3900 fix
->code
= BFD_RELOC_IA64_IMM14
;
3902 fix
->code
= BFD_RELOC_IA64_IMM22
;
3904 if (e
->X_op
!= O_subtract
)
3906 fix
->code
= ia64_gen_real_reloc_type (e
->X_op_symbol
, fix
->code
);
3907 if (e
->X_op
== O_pseudo_fixup
)
3911 fix
->opnd
= idesc
->operands
[index
];
3914 ++CURR_SLOT
.num_fixups
;
3917 else if (e
->X_op
!= O_constant
3918 && ! (e
->X_op
== O_big
&& opnd
== IA64_OPND_IMM8M1U8
))
3921 if (opnd
== IA64_OPND_IMM8M1U4
)
3923 /* Zero is not valid for unsigned compares that take an adjusted
3924 constant immediate range. */
3925 if (e
->X_add_number
== 0)
3928 /* Sign-extend 32-bit unsigned numbers, so that the following range
3929 checks will work. */
3930 val
= e
->X_add_number
;
3931 if (((val
& (~(bfd_vma
)0 << 32)) == 0)
3932 && ((val
& ((bfd_vma
)1 << 31)) != 0))
3933 val
= ((val
<< 32) >> 32);
3935 /* Check for 0x100000000. This is valid because
3936 0x100000000-1 is the same as ((uint32_t) -1). */
3937 if (val
== ((bfd_signed_vma
) 1 << 32))
3942 else if (opnd
== IA64_OPND_IMM8M1U8
)
3944 /* Zero is not valid for unsigned compares that take an adjusted
3945 constant immediate range. */
3946 if (e
->X_add_number
== 0)
3949 /* Check for 0x10000000000000000. */
3950 if (e
->X_op
== O_big
)
3952 if (generic_bignum
[0] == 0
3953 && generic_bignum
[1] == 0
3954 && generic_bignum
[2] == 0
3955 && generic_bignum
[3] == 0
3956 && generic_bignum
[4] == 1)
3962 val
= e
->X_add_number
- 1;
3964 else if (opnd
== IA64_OPND_IMM8M1
)
3965 val
= e
->X_add_number
- 1;
3966 else if (opnd
== IA64_OPND_IMM8U4
)
3968 /* Sign-extend 32-bit unsigned numbers, so that the following range
3969 checks will work. */
3970 val
= e
->X_add_number
;
3971 if (((val
& (~(bfd_vma
)0 << 32)) == 0)
3972 && ((val
& ((bfd_vma
)1 << 31)) != 0))
3973 val
= ((val
<< 32) >> 32);
3976 val
= e
->X_add_number
;
3978 if ((val
>= 0 && val
< ((bfd_vma
) 1 << (bits
- 1)))
3979 || (val
< 0 && -val
<= ((bfd_vma
) 1 << (bits
- 1))))
3983 case IA64_OPND_INC3
:
3984 /* +/- 1, 4, 8, 16 */
3985 val
= e
->X_add_number
;
3988 if (e
->X_op
== O_constant
3989 && (val
== 1 || val
== 4 || val
== 8 || val
== 16))
3993 case IA64_OPND_TGT25
:
3994 case IA64_OPND_TGT25b
:
3995 case IA64_OPND_TGT25c
:
3996 case IA64_OPND_TGT64
:
3997 if (e
->X_op
== O_symbol
)
3999 fix
= CURR_SLOT
.fixup
+ CURR_SLOT
.num_fixups
;
4000 if (opnd
== IA64_OPND_TGT25
)
4001 fix
->code
= BFD_RELOC_IA64_PCREL21F
;
4002 else if (opnd
== IA64_OPND_TGT25b
)
4003 fix
->code
= BFD_RELOC_IA64_PCREL21M
;
4004 else if (opnd
== IA64_OPND_TGT25c
)
4005 fix
->code
= BFD_RELOC_IA64_PCREL21B
;
4007 /* FIXME -- use appropriate relocation type */
4008 as_bad (_("long branch targets not implemented"));
4009 fix
->code
= ia64_gen_real_reloc_type (e
->X_op_symbol
, fix
->code
);
4010 fix
->opnd
= idesc
->operands
[index
];
4013 ++CURR_SLOT
.num_fixups
;
4016 case IA64_OPND_TAG13
:
4017 case IA64_OPND_TAG13b
:
4024 fix
= CURR_SLOT
.fixup
+ CURR_SLOT
.num_fixups
;
4025 fix
->code
= ia64_gen_real_reloc_type (e
->X_op_symbol
, 0);
4026 fix
->opnd
= idesc
->operands
[index
];
4029 ++CURR_SLOT
.num_fixups
;
4049 memset (e
, 0, sizeof (*e
));
4052 if (*input_line_pointer
!= '}')
4054 sep
= *input_line_pointer
++;
4058 if (!md
.manual_bundling
)
4059 as_warn ("Found '}' when manual bundling is off");
4061 CURR_SLOT
.manual_bundling_off
= 1;
4062 md
.manual_bundling
= 0;
4068 /* Returns the next entry in the opcode table that matches the one in
4069 IDESC, and frees the entry in IDESC. If no matching entry is
4070 found, NULL is returned instead. */
4072 static struct ia64_opcode
*
4073 get_next_opcode (struct ia64_opcode
*idesc
)
4075 struct ia64_opcode
*next
= ia64_find_next_opcode (idesc
);
4076 ia64_free_opcode (idesc
);
4080 /* Parse the operands for the opcode and find the opcode variant that
4081 matches the specified operands, or NULL if no match is possible. */
4082 static struct ia64_opcode
*
4083 parse_operands (idesc
)
4084 struct ia64_opcode
*idesc
;
4086 int i
= 0, highest_unmatched_operand
, num_operands
= 0, num_outputs
= 0;
4088 enum ia64_opnd expected_operand
= IA64_OPND_NIL
;
4090 char *first_arg
= 0, *end
, *saved_input_pointer
;
4093 assert (strlen (idesc
->name
) <= 128);
4095 strcpy (mnemonic
, idesc
->name
);
4096 if (idesc
->operands
[2] == IA64_OPND_SOF
)
4098 /* To make the common idiom "alloc loc?=ar.pfs,0,1,0,0" work, we
4099 can't parse the first operand until we have parsed the
4100 remaining operands of the "alloc" instruction. */
4102 first_arg
= input_line_pointer
;
4103 end
= strchr (input_line_pointer
, '=');
4106 as_bad ("Expected separator `='");
4109 input_line_pointer
= end
+ 1;
4114 for (; i
< NELEMS (CURR_SLOT
.opnd
); ++i
)
4116 sep
= parse_operand (CURR_SLOT
.opnd
+ i
);
4117 if (CURR_SLOT
.opnd
[i
].X_op
== O_absent
)
4122 if (sep
!= '=' && sep
!= ',')
4127 if (num_outputs
> 0)
4128 as_bad ("Duplicate equal sign (=) in instruction");
4130 num_outputs
= i
+ 1;
4135 as_bad ("Illegal operand separator `%c'", sep
);
4139 if (idesc
->operands
[2] == IA64_OPND_SOF
)
4141 /* map alloc r1=ar.pfs,i,l,o,r to alloc r1=ar.pfs,(i+l+o),(i+l),r */
4142 know (strcmp (idesc
->name
, "alloc") == 0);
4143 if (num_operands
== 5 /* first_arg not included in this count! */
4144 && CURR_SLOT
.opnd
[2].X_op
== O_constant
4145 && CURR_SLOT
.opnd
[3].X_op
== O_constant
4146 && CURR_SLOT
.opnd
[4].X_op
== O_constant
4147 && CURR_SLOT
.opnd
[5].X_op
== O_constant
)
4149 sof
= set_regstack (CURR_SLOT
.opnd
[2].X_add_number
,
4150 CURR_SLOT
.opnd
[3].X_add_number
,
4151 CURR_SLOT
.opnd
[4].X_add_number
,
4152 CURR_SLOT
.opnd
[5].X_add_number
);
4154 /* now we can parse the first arg: */
4155 saved_input_pointer
= input_line_pointer
;
4156 input_line_pointer
= first_arg
;
4157 sep
= parse_operand (CURR_SLOT
.opnd
+ 0);
4159 --num_outputs
; /* force error */
4160 input_line_pointer
= saved_input_pointer
;
4162 CURR_SLOT
.opnd
[2].X_add_number
= sof
;
4163 CURR_SLOT
.opnd
[3].X_add_number
4164 = sof
- CURR_SLOT
.opnd
[4].X_add_number
;
4165 CURR_SLOT
.opnd
[4] = CURR_SLOT
.opnd
[5];
4169 highest_unmatched_operand
= 0;
4170 expected_operand
= idesc
->operands
[0];
4171 for (; idesc
; idesc
= get_next_opcode (idesc
))
4173 if (num_outputs
!= idesc
->num_outputs
)
4174 continue; /* mismatch in # of outputs */
4176 CURR_SLOT
.num_fixups
= 0;
4177 for (i
= 0; i
< num_operands
&& idesc
->operands
[i
]; ++i
)
4178 if (!operand_match (idesc
, i
, CURR_SLOT
.opnd
+ i
))
4181 if (i
!= num_operands
)
4183 if (i
> highest_unmatched_operand
)
4185 highest_unmatched_operand
= i
;
4186 expected_operand
= idesc
->operands
[i
];
4191 if (num_operands
< NELEMS (idesc
->operands
)
4192 && idesc
->operands
[num_operands
])
4193 continue; /* mismatch in number of arguments */
4199 if (expected_operand
)
4200 as_bad ("Operand %u of `%s' should be %s",
4201 highest_unmatched_operand
+ 1, mnemonic
,
4202 elf64_ia64_operands
[expected_operand
].desc
);
4204 as_bad ("Operand mismatch");
4211 build_insn (slot
, insnp
)
4215 const struct ia64_operand
*odesc
, *o2desc
;
4216 struct ia64_opcode
*idesc
= slot
->idesc
;
4217 bfd_signed_vma insn
, val
;
4221 insn
= idesc
->opcode
| slot
->qp_regno
;
4223 for (i
= 0; i
< NELEMS (idesc
->operands
) && idesc
->operands
[i
]; ++i
)
4225 if (idesc
->operands
[i
] == IA64_OPND_IMMU64
)
4227 val
= slot
->opnd
[i
].X_add_number
;
4228 *insnp
++ = (val
>> 22) & 0x1ffffffffffLL
;
4229 insn
|= (((val
& 0x7f) << 13) | (((val
>> 7) & 0x1ff) << 27)
4230 | (((val
>> 16) & 0x1f) << 22) | (((val
>> 21) & 0x1) << 21)
4231 | (((val
>> 63) & 0x1) << 36));
4233 else if (idesc
->operands
[i
] == IA64_OPND_IMMU62
)
4235 val
= slot
->opnd
[i
].X_add_number
& 0x3fffffffffffffffULL
;
4236 if (val
!= slot
->opnd
[i
].X_add_number
)
4237 as_warn (_("Value truncated to 62 bits"));
4238 *insnp
++ = (val
>> 21) & 0x1ffffffffffLL
;
4239 insn
|= (((val
& 0xfffff) << 6) | (((val
>> 20) & 0x1) << 36));
4241 else if (idesc
->operands
[i
] == IA64_OPND_TGT64
)
4243 // FIXME -- need to implement the target address encoding properly
4244 as_bad (_("long branch target encoding not implemented"));
4247 else if (slot
->opnd
[i
].X_op
== O_register
4248 || slot
->opnd
[i
].X_op
== O_constant
4249 || slot
->opnd
[i
].X_op
== O_index
4250 || slot
->opnd
[i
].X_op
== O_big
)
4252 if (slot
->opnd
[i
].X_op
== O_big
)
4254 /* This must be the value 0x10000000000000000. */
4255 assert (idesc
->operands
[i
] == IA64_OPND_IMM8M1U8
);
4259 val
= slot
->opnd
[i
].X_add_number
;
4261 switch (idesc
->operands
[i
])
4263 case IA64_OPND_AR3
: val
-= REG_AR
; break;
4264 case IA64_OPND_B1
: case IA64_OPND_B2
: val
-= REG_BR
; break;
4265 case IA64_OPND_CR3
: val
-= REG_CR
; break;
4266 case IA64_OPND_F1
: case IA64_OPND_F2
:
4267 case IA64_OPND_F3
: case IA64_OPND_F4
: val
-= REG_FR
; break;
4268 case IA64_OPND_P1
: case IA64_OPND_P2
: val
-= REG_P
; break;
4270 case IA64_OPND_R1
: case IA64_OPND_R2
:
4271 case IA64_OPND_R3
: case IA64_OPND_R3_2
:
4272 case IA64_OPND_CPUID_R3
: case IA64_OPND_DBR_R3
:
4273 case IA64_OPND_DTR_R3
: case IA64_OPND_ITR_R3
:
4274 case IA64_OPND_IBR_R3
: case IA64_OPND_MR3
:
4275 case IA64_OPND_MSR_R3
: case IA64_OPND_PKR_R3
:
4276 case IA64_OPND_PMC_R3
: case IA64_OPND_PMD_R3
:
4277 case IA64_OPND_RR_R3
:
4284 odesc
= elf64_ia64_operands
+ idesc
->operands
[i
];
4285 err
= (*odesc
->insert
) (odesc
, val
, &insn
);
4287 as_bad_where (slot
->src_file
, slot
->src_line
,
4288 "Bad operand value: %s", err
);
4289 if (idesc
->flags
& IA64_OPCODE_PSEUDO
)
4291 if ((idesc
->flags
& IA64_OPCODE_F2_EQ_F3
)
4292 && odesc
== elf64_ia64_operands
+ IA64_OPND_F3
)
4294 o2desc
= elf64_ia64_operands
+ IA64_OPND_F2
;
4295 (*o2desc
->insert
) (o2desc
, val
, &insn
);
4298 if ((idesc
->flags
& IA64_OPCODE_LEN_EQ_64MCNT
)
4299 && (odesc
== elf64_ia64_operands
+ IA64_OPND_CPOS6a
4300 || odesc
== elf64_ia64_operands
+ IA64_OPND_POS6
))
4302 o2desc
= elf64_ia64_operands
+ IA64_OPND_LEN6
;
4303 (*o2desc
->insert
) (o2desc
, 64 - val
, &insn
);
4314 unsigned int manual_bundling_on
= 0, manual_bundling_off
= 0;
4315 unsigned int manual_bundling
= 0;
4316 enum ia64_unit required_unit
, insn_unit
= 0;
4317 enum ia64_insn_type type
[3], insn_type
;
4318 unsigned int template, orig_template
;
4319 bfd_vma insn
[3] = {-1, -1, -1};
4320 struct ia64_opcode
*idesc
;
4321 int end_of_insn_group
= 0, user_template
= -1;
4322 int n
, i
, j
, first
, curr
;
4323 bfd_vma t0
= 0, t1
= 0;
4324 struct label_fix
*lfix
;
4325 struct insn_fix
*ifix
;
4330 first
= (md
.curr_slot
+ NUM_SLOTS
- md
.num_slots_in_use
) % NUM_SLOTS
;
4331 know (first
>= 0 & first
< NUM_SLOTS
);
4332 n
= MIN (3, md
.num_slots_in_use
);
4334 /* Determine template: user user_template if specified, best match
4337 if (md
.slot
[first
].user_template
>= 0)
4338 user_template
= template = md
.slot
[first
].user_template
;
4341 /* auto select appropriate template */
4342 memset (type
, 0, sizeof (type
));
4344 for (i
= 0; i
< n
; ++i
)
4346 type
[i
] = md
.slot
[curr
].idesc
->type
;
4347 curr
= (curr
+ 1) % NUM_SLOTS
;
4349 template = best_template
[type
[0]][type
[1]][type
[2]];
4352 /* initialize instructions with appropriate nops: */
4353 for (i
= 0; i
< 3; ++i
)
4354 insn
[i
] = nop
[ia64_templ_desc
[template].exec_unit
[i
]];
4358 /* now fill in slots with as many insns as possible: */
4360 idesc
= md
.slot
[curr
].idesc
;
4361 end_of_insn_group
= 0;
4362 for (i
= 0; i
< 3 && md
.num_slots_in_use
> 0; ++i
)
4364 if (idesc
->flags
& IA64_OPCODE_SLOT2
)
4366 if (manual_bundling
&& i
!= 2)
4367 as_bad_where (md
.slot
[curr
].src_file
, md
.slot
[curr
].src_line
,
4368 "`%s' must be last in bundle", idesc
->name
);
4372 if (idesc
->flags
& IA64_OPCODE_LAST
)
4374 int required_slot
, required_template
;
4376 /* If we need a stop bit after an M slot, our only choice is
4377 template 5 (M;;MI). If we need a stop bit after a B
4378 slot, our only choice is to place it at the end of the
4379 bundle, because the only available templates are MIB,
4380 MBB, BBB, MMB, and MFB. We don't handle anything other
4381 than M and B slots because these are the only kind of
4382 instructions that can have the IA64_OPCODE_LAST bit set. */
4383 required_template
= template;
4384 switch (idesc
->type
)
4388 required_template
= 5;
4396 as_bad_where (md
.slot
[curr
].src_file
, md
.slot
[curr
].src_line
,
4397 "Internal error: don't know how to force %s to end"
4398 "of instruction group", idesc
->name
);
4402 if (manual_bundling
&& i
!= required_slot
)
4403 as_bad_where (md
.slot
[curr
].src_file
, md
.slot
[curr
].src_line
,
4404 "`%s' must be last in instruction group",
4406 if (required_slot
< i
)
4407 /* Can't fit this instruction. */
4411 if (required_template
!= template)
4413 /* If we switch the template, we need to reset the NOPs
4414 after slot i. The slot-types of the instructions ahead
4415 of i never change, so we don't need to worry about
4416 changing NOPs in front of this slot. */
4417 for (j
= i
; j
< 3; ++j
)
4418 insn
[j
] = nop
[ia64_templ_desc
[required_template
].exec_unit
[j
]];
4420 template = required_template
;
4422 if (curr
!= first
&& md
.slot
[curr
].label_fixups
)
4424 if (manual_bundling_on
)
4425 as_bad_where (md
.slot
[curr
].src_file
, md
.slot
[curr
].src_line
,
4426 "Label must be first in a bundle");
4427 /* This insn must go into the first slot of a bundle. */
4431 manual_bundling_on
= md
.slot
[curr
].manual_bundling_on
;
4432 manual_bundling_off
= md
.slot
[curr
].manual_bundling_off
;
4434 if (manual_bundling_on
)
4437 manual_bundling
= 1;
4439 break; /* need to start a new bundle */
4442 if (end_of_insn_group
&& md
.num_slots_in_use
>= 1)
4444 /* We need an instruction group boundary in the middle of a
4445 bundle. See if we can switch to an other template with
4446 an appropriate boundary. */
4448 orig_template
= template;
4449 if (i
== 1 && (user_template
== 4
4450 || (user_template
< 0
4451 && (ia64_templ_desc
[template].exec_unit
[0]
4455 end_of_insn_group
= 0;
4457 else if (i
== 2 && (user_template
== 0
4458 || (user_template
< 0
4459 && (ia64_templ_desc
[template].exec_unit
[1]
4461 /* This test makes sure we don't switch the template if
4462 the next instruction is one that needs to be first in
4463 an instruction group. Since all those instructions are
4464 in the M group, there is no way such an instruction can
4465 fit in this bundle even if we switch the template. The
4466 reason we have to check for this is that otherwise we
4467 may end up generating "MI;;I M.." which has the deadly
4468 effect that the second M instruction is no longer the
4469 first in the bundle! --davidm 99/12/16 */
4470 && (idesc
->flags
& IA64_OPCODE_FIRST
) == 0)
4473 end_of_insn_group
= 0;
4475 else if (curr
!= first
)
4476 /* can't fit this insn */
4479 if (template != orig_template
)
4480 /* if we switch the template, we need to reset the NOPs
4481 after slot i. The slot-types of the instructions ahead
4482 of i never change, so we don't need to worry about
4483 changing NOPs in front of this slot. */
4484 for (j
= i
; j
< 3; ++j
)
4485 insn
[j
] = nop
[ia64_templ_desc
[template].exec_unit
[j
]];
4487 required_unit
= ia64_templ_desc
[template].exec_unit
[i
];
4489 /* resolve dynamic opcodes such as "break" and "nop": */
4490 if (idesc
->type
== IA64_TYPE_DYN
)
4492 if ((strcmp (idesc
->name
, "nop") == 0)
4493 || (strcmp (idesc
->name
, "break") == 0))
4494 insn_unit
= required_unit
;
4495 else if (strcmp (idesc
->name
, "chk.s") == 0)
4497 insn_unit
= IA64_UNIT_M
;
4498 if (required_unit
== IA64_UNIT_I
)
4499 insn_unit
= IA64_UNIT_I
;
4502 as_fatal ("emit_one_bundle: unexpected dynamic op");
4504 sprintf (mnemonic
, "%s.%c", idesc
->name
, "?imbf??"[insn_unit
]);
4505 md
.slot
[curr
].idesc
= idesc
= ia64_find_opcode (mnemonic
);
4507 know (!idesc
->next
); /* no resolved dynamic ops have collisions */
4512 insn_type
= idesc
->type
;
4513 insn_unit
= IA64_UNIT_NIL
;
4517 if (required_unit
== IA64_UNIT_I
|| required_unit
== IA64_UNIT_M
)
4518 insn_unit
= required_unit
;
4520 case IA64_TYPE_X
: insn_unit
= IA64_UNIT_L
; break;
4521 case IA64_TYPE_I
: insn_unit
= IA64_UNIT_I
; break;
4522 case IA64_TYPE_M
: insn_unit
= IA64_UNIT_M
; break;
4523 case IA64_TYPE_B
: insn_unit
= IA64_UNIT_B
; break;
4524 case IA64_TYPE_F
: insn_unit
= IA64_UNIT_F
; break;
4529 if (insn_unit
!= required_unit
)
4531 if (required_unit
== IA64_UNIT_L
4532 && insn_unit
== IA64_UNIT_I
4533 && !(idesc
->flags
& IA64_OPCODE_X_IN_MLX
))
4535 /* we got ourselves an MLX template but the current
4536 instruction isn't an X-unit, or an I-unit instruction
4537 that can go into the X slot of an MLX template. Duh. */
4538 if (md
.num_slots_in_use
>= NUM_SLOTS
)
4540 as_bad_where (md
.slot
[curr
].src_file
,
4541 md
.slot
[curr
].src_line
,
4542 "`%s' can't go in X slot of "
4543 "MLX template", idesc
->name
);
4544 /* drop this insn so we don't livelock: */
4545 --md
.num_slots_in_use
;
4549 continue; /* try next slot */
4552 if (debug_type
== DEBUG_DWARF2
)
4556 addr
= frag_now
->fr_address
+ frag_now_fix () - 16 + 1*i
;
4557 dwarf2_gen_line_info (addr
, &md
.slot
[curr
].debug_line
);
4560 build_insn (md
.slot
+ curr
, insn
+ i
);
4562 /* Set slot counts for unwind records. */
4563 while (md
.slot
[curr
].unwind_record
)
4565 md
.slot
[curr
].unwind_record
->slot_number
= (unsigned long) (f
+ i
);
4566 md
.slot
[curr
].unwind_record
= md
.slot
[curr
].unwind_record
->next
;
4568 if (required_unit
== IA64_UNIT_L
)
4571 /* skip one slot for long/X-unit instructions */
4574 --md
.num_slots_in_use
;
4576 /* now is a good time to fix up the labels for this insn: */
4577 for (lfix
= md
.slot
[curr
].label_fixups
; lfix
; lfix
= lfix
->next
)
4579 S_SET_VALUE (lfix
->sym
, frag_now_fix () - 16);
4580 symbol_set_frag (lfix
->sym
, frag_now
);
4583 for (j
= 0; j
< md
.slot
[curr
].num_fixups
; ++j
)
4585 ifix
= md
.slot
[curr
].fixup
+ j
;
4586 fix
= fix_new_exp (frag_now
, frag_now_fix () - 16 + i
, 4,
4587 &ifix
->expr
, ifix
->is_pcrel
, ifix
->code
);
4588 fix
->tc_fix_data
.opnd
= ifix
->opnd
;
4589 fix
->fx_plt
= (fix
->fx_r_type
== BFD_RELOC_IA64_PLTOFF22
);
4590 fix
->fx_file
= md
.slot
[curr
].src_file
;
4591 fix
->fx_line
= md
.slot
[curr
].src_line
;
4594 end_of_insn_group
= md
.slot
[curr
].end_of_insn_group
;
4597 ia64_free_opcode (md
.slot
[curr
].idesc
);
4598 memset (md
.slot
+ curr
, 0, sizeof (md
.slot
[curr
]));
4599 md
.slot
[curr
].user_template
= -1;
4601 if (manual_bundling_off
)
4603 manual_bundling
= 0;
4606 curr
= (curr
+ 1) % NUM_SLOTS
;
4607 idesc
= md
.slot
[curr
].idesc
;
4609 if (manual_bundling
)
4611 if (md
.num_slots_in_use
> 0)
4612 as_bad_where (md
.slot
[curr
].src_file
, md
.slot
[curr
].src_line
,
4613 "`%s' does not fit into %s template",
4614 idesc
->name
, ia64_templ_desc
[template].name
);
4616 as_bad_where (md
.slot
[curr
].src_file
, md
.slot
[curr
].src_line
,
4617 "Missing '}' at end of file");
4619 know (md
.num_slots_in_use
< NUM_SLOTS
);
4621 t0
= end_of_insn_group
| (template << 1) | (insn
[0] << 5) | (insn
[1] << 46);
4622 t1
= ((insn
[1] >> 18) & 0x7fffff) | (insn
[2] << 23);
4624 md_number_to_chars (f
+ 0, t0
, 8);
4625 md_number_to_chars (f
+ 8, t1
, 8);
4629 md_parse_option (c
, arg
)
4633 /* Switches from the Intel assembler. */
4637 if (strcmp (arg
, "ilp64") == 0
4638 || strcmp (arg
, "lp64") == 0
4639 || strcmp (arg
, "p64") == 0)
4641 md
.flags
|= EF_IA_64_ABI64
;
4643 else if (strcmp (arg
, "ilp32") == 0)
4645 md
.flags
&= ~EF_IA_64_ABI64
;
4647 else if (strcmp (arg
, "le") == 0)
4649 md
.flags
&= ~EF_IA_64_BE
;
4651 else if (strcmp (arg
, "be") == 0)
4653 md
.flags
|= EF_IA_64_BE
;
4660 if (strcmp (arg
, "so") == 0)
4662 /* Suppress signon message. */
4664 else if (strcmp (arg
, "pi") == 0)
4666 /* Reject privileged instructions. FIXME */
4668 else if (strcmp (arg
, "us") == 0)
4670 /* Allow union of signed and unsigned range. FIXME */
4672 else if (strcmp (arg
, "close_fcalls") == 0)
4674 /* Do not resolve global function calls. */
4681 /* temp[="prefix"] Insert temporary labels into the object file
4682 symbol table prefixed by "prefix".
4683 Default prefix is ":temp:".
4688 /* ??? Conflicts with gas' listing option. */
4689 /* indirect=<tgt> Assume unannotated indirect branches behavior
4690 according to <tgt> --
4691 exit: branch out from the current context (default)
4692 labels: all labels in context may be branch targets
4697 /* -X conflicts with an ignored option, use -x instead */
4699 if (!arg
|| strcmp (arg
, "explicit") == 0)
4701 /* set default mode to explicit */
4702 md
.default_explicit_mode
= 1;
4705 else if (strcmp (arg
, "auto") == 0)
4707 md
.default_explicit_mode
= 0;
4709 else if (strcmp (arg
, "debug") == 0)
4713 else if (strcmp (arg
, "debugx") == 0)
4715 md
.default_explicit_mode
= 1;
4720 as_bad (_("Unrecognized option '-x%s'"), arg
);
4725 /* nops Print nops statistics. */
4736 md_show_usage (stream
)
4741 -Milp32|-Milp64|-Mlp64|-Mp64 select data model (default -Mlp64)\n\
4742 -Mle | -Mbe select little- or big-endian byte order (default -Mle)\n\
4743 -x | -xexplicit turn on dependency violation checking (default)\n\
4744 -xauto automagically remove dependency violations\n\
4745 -xdebug debug dependency violation checker\n"),
4750 match (int templ
, int type
, int slot
)
4752 enum ia64_unit unit
;
4755 unit
= ia64_templ_desc
[templ
].exec_unit
[slot
];
4758 case IA64_TYPE_DYN
: result
= 1; break; /* for nop and break */
4760 result
= (unit
== IA64_UNIT_I
|| unit
== IA64_UNIT_M
);
4762 case IA64_TYPE_X
: result
= (unit
== IA64_UNIT_L
); break;
4763 case IA64_TYPE_I
: result
= (unit
== IA64_UNIT_I
); break;
4764 case IA64_TYPE_M
: result
= (unit
== IA64_UNIT_M
); break;
4765 case IA64_TYPE_B
: result
= (unit
== IA64_UNIT_B
); break;
4766 case IA64_TYPE_F
: result
= (unit
== IA64_UNIT_F
); break;
4767 default: result
= 0; break;
4772 /* This function is called once, at assembler startup time. It sets
4773 up all the tables, etc. that the MD part of the assembler will need
4774 that can be determined before arguments are parsed. */
4778 int i
, j
, k
, t
, total
, ar_base
, cr_base
, goodness
, best
, regnum
;
4783 md
.explicit_mode
= md
.default_explicit_mode
;
4785 bfd_set_section_alignment (stdoutput
, text_section
, 4);
4787 target_big_endian
= 0;
4788 pseudo_func
[FUNC_FPTR_RELATIVE
].u
.sym
=
4789 symbol_new (".<fptr>", undefined_section
, FUNC_FPTR_RELATIVE
,
4790 &zero_address_frag
);
4792 pseudo_func
[FUNC_GP_RELATIVE
].u
.sym
=
4793 symbol_new (".<gprel>", undefined_section
, FUNC_GP_RELATIVE
,
4794 &zero_address_frag
);
4796 pseudo_func
[FUNC_LT_RELATIVE
].u
.sym
=
4797 symbol_new (".<ltoff>", undefined_section
, FUNC_LT_RELATIVE
,
4798 &zero_address_frag
);
4800 pseudo_func
[FUNC_PLT_RELATIVE
].u
.sym
=
4801 symbol_new (".<pltoff>", undefined_section
, FUNC_PLT_RELATIVE
,
4802 &zero_address_frag
);
4804 pseudo_func
[FUNC_SEC_RELATIVE
].u
.sym
=
4805 symbol_new (".<secrel>", undefined_section
, FUNC_SEC_RELATIVE
,
4806 &zero_address_frag
);
4808 pseudo_func
[FUNC_SEG_RELATIVE
].u
.sym
=
4809 symbol_new (".<segrel>", undefined_section
, FUNC_SEG_RELATIVE
,
4810 &zero_address_frag
);
4812 pseudo_func
[FUNC_LTV_RELATIVE
].u
.sym
=
4813 symbol_new (".<ltv>", undefined_section
, FUNC_LTV_RELATIVE
,
4814 &zero_address_frag
);
4816 pseudo_func
[FUNC_LT_FPTR_RELATIVE
].u
.sym
=
4817 symbol_new (".<ltoff.fptr>", undefined_section
, FUNC_LT_FPTR_RELATIVE
,
4818 &zero_address_frag
);
4820 /* compute the table of best templates: */
4821 for (i
= 0; i
< IA64_NUM_TYPES
; ++i
)
4822 for (j
= 0; j
< IA64_NUM_TYPES
; ++j
)
4823 for (k
= 0; k
< IA64_NUM_TYPES
; ++k
)
4826 for (t
= 0; t
< NELEMS (ia64_templ_desc
); ++t
)
4829 if (match (t
, i
, 0))
4831 if (match (t
, j
, 1))
4833 if (match (t
, k
, 2))
4838 else if (match (t
, j
, 2))
4843 else if (match (t
, i
, 1))
4845 if (match (t
, j
, 2))
4850 else if (match (t
, i
, 2))
4853 if (goodness
> best
)
4856 best_template
[i
][j
][k
] = t
;
4861 for (i
= 0; i
< NUM_SLOTS
; ++i
)
4862 md
.slot
[i
].user_template
= -1;
4864 md
.pseudo_hash
= hash_new ();
4865 for (i
= 0; i
< NELEMS (pseudo_opcode
); ++i
)
4867 err
= hash_insert (md
.pseudo_hash
, pseudo_opcode
[i
].name
,
4868 (void *) (pseudo_opcode
+ i
));
4870 as_fatal ("ia64.md_begin: can't hash `%s': %s",
4871 pseudo_opcode
[i
].name
, err
);
4874 md
.reg_hash
= hash_new ();
4875 md
.dynreg_hash
= hash_new ();
4876 md
.const_hash
= hash_new ();
4877 md
.entry_hash
= hash_new ();
4879 /* general registers: */
4882 for (i
= 0; i
< total
; ++i
)
4884 sprintf (name
, "r%d", i
- REG_GR
);
4885 md
.regsym
[i
] = declare_register (name
, i
);
4888 /* floating point registers: */
4890 for (; i
< total
; ++i
)
4892 sprintf (name
, "f%d", i
- REG_FR
);
4893 md
.regsym
[i
] = declare_register (name
, i
);
4896 /* application registers: */
4899 for (; i
< total
; ++i
)
4901 sprintf (name
, "ar%d", i
- REG_AR
);
4902 md
.regsym
[i
] = declare_register (name
, i
);
4905 /* control registers: */
4908 for (; i
< total
; ++i
)
4910 sprintf (name
, "cr%d", i
- REG_CR
);
4911 md
.regsym
[i
] = declare_register (name
, i
);
4914 /* predicate registers: */
4916 for (; i
< total
; ++i
)
4918 sprintf (name
, "p%d", i
- REG_P
);
4919 md
.regsym
[i
] = declare_register (name
, i
);
4922 /* branch registers: */
4924 for (; i
< total
; ++i
)
4926 sprintf (name
, "b%d", i
- REG_BR
);
4927 md
.regsym
[i
] = declare_register (name
, i
);
4930 md
.regsym
[REG_IP
] = declare_register ("ip", REG_IP
);
4931 md
.regsym
[REG_CFM
] = declare_register ("cfm", REG_CFM
);
4932 md
.regsym
[REG_PR
] = declare_register ("pr", REG_PR
);
4933 md
.regsym
[REG_PR_ROT
] = declare_register ("pr.rot", REG_PR_ROT
);
4934 md
.regsym
[REG_PSR
] = declare_register ("psr", REG_PSR
);
4935 md
.regsym
[REG_PSR_L
] = declare_register ("psr.l", REG_PSR_L
);
4936 md
.regsym
[REG_PSR_UM
] = declare_register ("psr.um", REG_PSR_UM
);
4938 for (i
= 0; i
< NELEMS (indirect_reg
); ++i
)
4940 regnum
= indirect_reg
[i
].regnum
;
4941 md
.regsym
[regnum
] = declare_register (indirect_reg
[i
].name
, regnum
);
4944 /* define synonyms for application registers: */
4945 for (i
= REG_AR
; i
< REG_AR
+ NELEMS (ar
); ++i
)
4946 md
.regsym
[i
] = declare_register (ar
[i
- REG_AR
].name
,
4947 REG_AR
+ ar
[i
- REG_AR
].regnum
);
4949 /* define synonyms for control registers: */
4950 for (i
= REG_CR
; i
< REG_CR
+ NELEMS (cr
); ++i
)
4951 md
.regsym
[i
] = declare_register (cr
[i
- REG_CR
].name
,
4952 REG_CR
+ cr
[i
- REG_CR
].regnum
);
4954 declare_register ("gp", REG_GR
+ 1);
4955 declare_register ("sp", REG_GR
+ 12);
4956 declare_register ("rp", REG_BR
+ 0);
4958 declare_register_set ("ret", 4, REG_GR
+ 8);
4959 declare_register_set ("farg", 8, REG_FR
+ 8);
4960 declare_register_set ("fret", 8, REG_FR
+ 8);
4962 for (i
= 0; i
< NELEMS (const_bits
); ++i
)
4964 err
= hash_insert (md
.const_hash
, const_bits
[i
].name
,
4965 (PTR
) (const_bits
+ i
));
4967 as_fatal ("Inserting \"%s\" into constant hash table failed: %s",
4971 /* Default to 64-bit mode. */
4972 md
.flags
= EF_IA_64_ABI64
;
4974 md
.mem_offset
.hint
= 0;
4977 md
.entry_labels
= NULL
;
4981 ia64_end_of_source ()
4983 /* terminate insn group upon reaching end of file: */
4984 insn_group_break (1, 0, 0);
4986 /* emits slots we haven't written yet: */
4987 ia64_flush_insns ();
4989 bfd_set_private_flags (stdoutput
, md
.flags
);
4991 if (debug_type
== DEBUG_DWARF2
)
4994 md
.mem_offset
.hint
= 0;
5000 md
.qp
.X_op
= O_absent
;
5002 if (ignore_input ())
5005 if (input_line_pointer
[0] == ';' && input_line_pointer
[-1] == ';')
5007 if (md
.detect_dv
&& !md
.explicit_mode
)
5008 as_warn (_("Explicit stops are ignored in auto mode"));
5010 insn_group_break (1, 0, 0);
5015 ia64_unrecognized_line (ch
)
5021 expression (&md
.qp
);
5022 if (*input_line_pointer
++ != ')')
5024 as_bad ("Expected ')'");
5027 if (md
.qp
.X_op
!= O_register
)
5029 as_bad ("Qualifying predicate expected");
5032 if (md
.qp
.X_add_number
< REG_P
|| md
.qp
.X_add_number
>= REG_P
+ 64)
5034 as_bad ("Predicate register expected");
5040 if (md
.manual_bundling
)
5041 as_warn ("Found '{' when manual bundling is already turned on");
5043 CURR_SLOT
.manual_bundling_on
= 1;
5044 md
.manual_bundling
= 1;
5046 /* bundling is only acceptable in explicit mode
5047 or when in default automatic mode */
5048 if (md
.detect_dv
&& !md
.explicit_mode
)
5050 if (!md
.mode_explicitly_set
5051 && !md
.default_explicit_mode
)
5054 as_warn (_("Found '{' after explicit switch to automatic mode"));
5059 if (!md
.manual_bundling
)
5060 as_warn ("Found '}' when manual bundling is off");
5062 PREV_SLOT
.manual_bundling_off
= 1;
5063 md
.manual_bundling
= 0;
5065 /* switch back to automatic mode, if applicable */
5068 && !md
.mode_explicitly_set
5069 && !md
.default_explicit_mode
)
5072 /* Allow '{' to follow on the same line. We also allow ";;", but that
5073 happens automatically because ';' is an end of line marker. */
5075 if (input_line_pointer
[0] == '{')
5077 input_line_pointer
++;
5078 return ia64_unrecognized_line ('{');
5081 demand_empty_rest_of_line ();
5087 return 0; /* not a valid line */
5091 ia64_frob_label (sym
)
5094 struct label_fix
*fix
;
5096 if (bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
)
5098 md
.last_text_seg
= now_seg
;
5099 fix
= obstack_alloc (¬es
, sizeof (*fix
));
5101 fix
->next
= CURR_SLOT
.label_fixups
;
5102 CURR_SLOT
.label_fixups
= fix
;
5104 /* keep track of how many code entry points we've seen */
5105 if (md
.path
== md
.maxpaths
)
5108 md
.entry_labels
= (const char **)
5109 xrealloc ((void *)md
.entry_labels
, md
.maxpaths
* sizeof (char *));
5111 md
.entry_labels
[md
.path
++] = S_GET_NAME (sym
);
5116 ia64_flush_pending_output ()
5118 if (bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
)
5120 /* ??? This causes many unnecessary stop bits to be emitted.
5121 Unfortunately, it isn't clear if it is safe to remove this. */
5122 insn_group_break (1, 0, 0);
5123 ia64_flush_insns ();
5127 /* Do ia64-specific expression optimization. All that's done here is
5128 to transform index expressions that are either due to the indexing
5129 of rotating registers or due to the indexing of indirect register
5132 ia64_optimize_expr (l
, op
, r
)
5141 if (l
->X_op
== O_register
&& r
->X_op
== O_constant
)
5143 num_regs
= (l
->X_add_number
>> 16);
5144 if ((unsigned) r
->X_add_number
>= num_regs
)
5147 as_bad ("No current frame");
5149 as_bad ("Index out of range 0..%u", num_regs
- 1);
5150 r
->X_add_number
= 0;
5152 l
->X_add_number
= (l
->X_add_number
& 0xffff) + r
->X_add_number
;
5155 else if (l
->X_op
== O_register
&& r
->X_op
== O_register
)
5157 if (l
->X_add_number
< IND_CPUID
|| l
->X_add_number
> IND_RR
5158 || l
->X_add_number
== IND_MEM
)
5160 as_bad ("Indirect register set name expected");
5161 l
->X_add_number
= IND_CPUID
;
5164 l
->X_op_symbol
= md
.regsym
[l
->X_add_number
];
5165 l
->X_add_number
= r
->X_add_number
;
5173 ia64_parse_name (name
, e
)
5177 struct const_desc
*cdesc
;
5178 struct dynreg
*dr
= 0;
5179 unsigned int regnum
;
5183 /* first see if NAME is a known register name: */
5184 sym
= hash_find (md
.reg_hash
, name
);
5187 e
->X_op
= O_register
;
5188 e
->X_add_number
= S_GET_VALUE (sym
);
5192 cdesc
= hash_find (md
.const_hash
, name
);
5195 e
->X_op
= O_constant
;
5196 e
->X_add_number
= cdesc
->value
;
5200 /* check for inN, locN, or outN: */
5204 if (name
[1] == 'n' && isdigit (name
[2]))
5212 if (name
[1] == 'o' && name
[2] == 'c' && isdigit (name
[3]))
5220 if (name
[1] == 'u' && name
[2] == 't' && isdigit (name
[3]))
5233 /* the name is inN, locN, or outN; parse the register number: */
5234 regnum
= strtoul (name
, &end
, 10);
5235 if (end
> name
&& *end
== '\0')
5237 if ((unsigned) regnum
>= dr
->num_regs
)
5240 as_bad ("No current frame");
5242 as_bad ("Register number out of range 0..%u", dr
->num_regs
-1);
5245 e
->X_op
= O_register
;
5246 e
->X_add_number
= dr
->base
+ regnum
;
5251 if ((dr
= hash_find (md
.dynreg_hash
, name
)))
5253 /* We've got ourselves the name of a rotating register set.
5254 Store the base register number in the low 16 bits of
5255 X_add_number and the size of the register set in the top 16
5257 e
->X_op
= O_register
;
5258 e
->X_add_number
= dr
->base
| (dr
->num_regs
<< 16);
5264 /* Remove the '#' suffix that indicates a symbol as opposed to a register. */
5267 ia64_canonicalize_symbol_name (name
)
5270 size_t len
= strlen(name
);
5271 if (len
> 1 && name
[len
-1] == '#')
5277 is_conditional_branch (idesc
)
5278 struct ia64_opcode
*idesc
;
5280 return (strncmp (idesc
->name
, "br", 2) == 0
5281 && (strcmp (idesc
->name
, "br") == 0
5282 || strncmp (idesc
->name
, "br.cond", 7) == 0
5283 || strncmp (idesc
->name
, "br.call", 7) == 0
5284 || strncmp (idesc
->name
, "br.ret", 6) == 0
5285 || strcmp (idesc
->name
, "brl") == 0
5286 || strncmp (idesc
->name
, "brl.cond", 7) == 0
5287 || strncmp (idesc
->name
, "brl.call", 7) == 0
5288 || strncmp (idesc
->name
, "brl.ret", 6) == 0));
5291 /* Return whether the given opcode is a taken branch. If there's any doubt,
5294 is_taken_branch (idesc
)
5295 struct ia64_opcode
*idesc
;
5297 return ((is_conditional_branch (idesc
) && CURR_SLOT
.qp_regno
== 0)
5298 || strncmp (idesc
->name
, "br.ia", 5) == 0);
5301 /* Return whether the given opcode is an interruption or rfi. If there's any
5302 doubt, returns zero */
5304 is_interruption_or_rfi (idesc
)
5305 struct ia64_opcode
*idesc
;
5307 if (strcmp (idesc
->name
, "rfi") == 0)
5312 /* Returns the index of the given dependency in the opcode's list of chks, or
5313 -1 if there is no dependency. */
5315 depends_on (depind
, idesc
)
5317 struct ia64_opcode
*idesc
;
5320 const struct ia64_opcode_dependency
*dep
= idesc
->dependencies
;
5321 for (i
= 0;i
< dep
->nchks
; i
++)
5323 if (depind
== DEP(dep
->chks
[i
]))
5329 /* Determine a set of specific resources used for a particular resource
5330 class. Returns the number of specific resources identified For those
5331 cases which are not determinable statically, the resource returned is
5334 Meanings of value in 'NOTE':
5335 1) only read/write when the register number is explicitly encoded in the
5337 2) only read CFM when accessing a rotating GR, FR, or PR. mov pr only
5338 accesses CFM when qualifying predicate is in the rotating region.
5339 3) general register value is used to specify an indirect register; not
5340 determinable statically.
5341 4) only read the given resource when bits 7:0 of the indirect index
5342 register value does not match the register number of the resource; not
5343 determinable statically.
5344 5) all rules are implementation specific.
5345 6) only when both the index specified by the reader and the index specified
5346 by the writer have the same value in bits 63:61; not determinable
5348 7) only access the specified resource when the corresponding mask bit is
5350 8) PSR.dfh is only read when these insns reference FR32-127. PSR.dfl is
5351 only read when these insns reference FR2-31
5352 9) PSR.mfl is only written when these insns write FR2-31. PSR.mfh is only
5353 written when these insns write FR32-127
5354 10) The PSR.bn bit is only accessed when one of GR16-31 is specified in the
5356 11) The target predicates are written independently of PR[qp], but source
5357 registers are only read if PR[qp] is true. Since the state of PR[qp]
5358 cannot statically be determined, all source registers are marked used.
5359 12) This insn only reads the specified predicate register when that
5360 register is the PR[qp].
5361 13) This reference to ld-c only applies to teh GR whose value is loaded
5362 with data returned from memory, not the post-incremented address register.
5363 14) The RSE resource includes the implementation-specific RSE internal
5364 state resources. At least one (and possibly more) of these resources are
5365 read by each instruction listed in IC:rse-readers. At least one (and
5366 possibly more) of these resources are written by each insn listed in
5368 15+16) Represents reserved instructions, which the assembler does not
5371 Memory resources (i.e. locations in memory) are *not* marked or tracked by
5372 this code; there are no dependency violations based on memory access.
5376 #define MAX_SPECS 256
5381 specify_resource (dep
, idesc
, type
, specs
, note
, path
)
5382 const struct ia64_dependency
*dep
;
5383 struct ia64_opcode
*idesc
;
5384 int type
; /* is this a DV chk or a DV reg? */
5385 struct rsrc specs
[MAX_SPECS
]; /* returned specific resources */
5386 int note
; /* resource note for this insn's usage */
5387 int path
; /* which execution path to examine */
5394 if (dep
->mode
== IA64_DV_WAW
5395 || (dep
->mode
== IA64_DV_RAW
&& type
== DV_REG
)
5396 || (dep
->mode
== IA64_DV_WAR
&& type
== DV_CHK
))
5399 /* template for any resources we identify */
5400 tmpl
.dependency
= dep
;
5402 tmpl
.insn_srlz
= tmpl
.data_srlz
= 0;
5403 tmpl
.qp_regno
= CURR_SLOT
.qp_regno
;
5404 tmpl
.link_to_qp_branch
= 1;
5405 tmpl
.mem_offset
.hint
= 0;
5410 as_warn (_("Unhandled dependency %s for %s (%s), note %d"), \
5411 dep->name, idesc->name, (rsrc_write?"write":"read"), note)
5412 #define KNOWN(REG) (gr_values[REG].known && gr_values[REG].path >= path)
5414 /* we don't need to track these */
5415 if (dep
->semantics
== IA64_DVS_NONE
)
5418 switch (dep
->specifier
)
5423 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_AR3
)
5425 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_AR
;
5426 if (regno
>= 0 && regno
<= 7)
5428 specs
[count
] = tmpl
;
5429 specs
[count
++].index
= regno
;
5437 specs
[count
] = tmpl
;
5438 specs
[count
++].index
= i
;
5447 case IA64_RS_AR_UNAT
:
5448 /* This is a mov =AR or mov AR= instruction. */
5449 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_AR3
)
5451 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_AR
;
5452 if (regno
== AR_UNAT
)
5454 specs
[count
++] = tmpl
;
5459 /* This is a spill/fill, or other instruction that modifies the
5462 /* Unless we can determine the specific bits used, mark the whole
5463 thing; bits 8:3 of the memory address indicate the bit used in
5464 UNAT. The .mem.offset hint may be used to eliminate a small
5465 subset of conflicts. */
5466 specs
[count
] = tmpl
;
5467 if (md
.mem_offset
.hint
)
5470 fprintf (stderr
, " Using hint for spill/fill\n");
5471 /* the index isn't actually used, just set it to something
5472 approximating the bit index */
5473 specs
[count
].index
= (md
.mem_offset
.offset
>> 3) & 0x3F;
5474 specs
[count
].mem_offset
.hint
= 1;
5475 specs
[count
].mem_offset
.offset
= md
.mem_offset
.offset
;
5476 specs
[count
++].mem_offset
.base
= md
.mem_offset
.base
;
5480 specs
[count
++].specific
= 0;
5488 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_AR3
)
5490 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_AR
;
5491 if ((regno
>= 8 && regno
<= 15)
5492 || (regno
>= 20 && regno
<= 23)
5493 || (regno
>= 31 && regno
<= 39)
5494 || (regno
>= 41 && regno
<= 47)
5495 || (regno
>= 67 && regno
<= 111))
5497 specs
[count
] = tmpl
;
5498 specs
[count
++].index
= regno
;
5511 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_AR3
)
5513 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_AR
;
5514 if ((regno
>= 48 && regno
<= 63)
5515 || (regno
>= 112 && regno
<= 127))
5517 specs
[count
] = tmpl
;
5518 specs
[count
++].index
= regno
;
5524 for (i
=48;i
< 64;i
++)
5526 specs
[count
] = tmpl
;
5527 specs
[count
++].index
= i
;
5529 for (i
=112;i
< 128;i
++)
5531 specs
[count
] = tmpl
;
5532 specs
[count
++].index
= i
;
5550 for (i
=0;i
< idesc
->num_outputs
;i
++)
5551 if (idesc
->operands
[i
] == IA64_OPND_B1
5552 || idesc
->operands
[i
] == IA64_OPND_B2
)
5554 specs
[count
] = tmpl
;
5555 specs
[count
++].index
=
5556 CURR_SLOT
.opnd
[i
].X_add_number
- REG_BR
;
5561 for (i
= idesc
->num_outputs
;i
< NELEMS(idesc
->operands
);i
++)
5562 if (idesc
->operands
[i
] == IA64_OPND_B1
5563 || idesc
->operands
[i
] == IA64_OPND_B2
)
5565 specs
[count
] = tmpl
;
5566 specs
[count
++].index
=
5567 CURR_SLOT
.opnd
[i
].X_add_number
- REG_BR
;
5573 case IA64_RS_CPUID
: /* four or more registers */
5576 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_CPUID_R3
)
5578 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_GR
;
5579 if (regno
>= 0 && regno
< NELEMS(gr_values
)
5582 specs
[count
] = tmpl
;
5583 specs
[count
++].index
= gr_values
[regno
].value
& 0xFF;
5587 specs
[count
] = tmpl
;
5588 specs
[count
++].specific
= 0;
5598 case IA64_RS_DBR
: /* four or more registers */
5601 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_DBR_R3
)
5603 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_GR
;
5604 if (regno
>= 0 && regno
< NELEMS(gr_values
)
5607 specs
[count
] = tmpl
;
5608 specs
[count
++].index
= gr_values
[regno
].value
& 0xFF;
5612 specs
[count
] = tmpl
;
5613 specs
[count
++].specific
= 0;
5617 else if (note
== 0 && !rsrc_write
)
5619 specs
[count
] = tmpl
;
5620 specs
[count
++].specific
= 0;
5628 case IA64_RS_IBR
: /* four or more registers */
5631 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_IBR_R3
)
5633 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_GR
;
5634 if (regno
>= 0 && regno
< NELEMS(gr_values
)
5637 specs
[count
] = tmpl
;
5638 specs
[count
++].index
= gr_values
[regno
].value
& 0xFF;
5642 specs
[count
] = tmpl
;
5643 specs
[count
++].specific
= 0;
5656 /* These are implementation specific. Force all references to
5657 conflict with all other references. */
5658 specs
[count
] = tmpl
;
5659 specs
[count
++].specific
= 0;
5667 case IA64_RS_PKR
: /* 16 or more registers */
5668 if (note
== 3 || note
== 4)
5670 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_PKR_R3
)
5672 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_GR
;
5673 if (regno
>= 0 && regno
< NELEMS(gr_values
)
5678 specs
[count
] = tmpl
;
5679 specs
[count
++].index
= gr_values
[regno
].value
& 0xFF;
5681 else for (i
=0;i
< NELEMS(gr_values
);i
++)
5683 /* uses all registers *except* the one in R3 */
5684 if (i
!= (gr_values
[regno
].value
& 0xFF))
5686 specs
[count
] = tmpl
;
5687 specs
[count
++].index
= i
;
5693 specs
[count
] = tmpl
;
5694 specs
[count
++].specific
= 0;
5701 specs
[count
] = tmpl
;
5702 specs
[count
++].specific
= 0;
5706 case IA64_RS_PMC
: /* four or more registers */
5709 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_PMC_R3
5710 || (!rsrc_write
&& idesc
->operands
[1] == IA64_OPND_PMD_R3
))
5713 int index
= ((idesc
->operands
[1] == IA64_OPND_R3
&& !rsrc_write
)
5715 int regno
= CURR_SLOT
.opnd
[index
].X_add_number
- REG_GR
;
5716 if (regno
>= 0 && regno
< NELEMS(gr_values
)
5719 specs
[count
] = tmpl
;
5720 specs
[count
++].index
= gr_values
[regno
].value
& 0xFF;
5724 specs
[count
] = tmpl
;
5725 specs
[count
++].specific
= 0;
5735 case IA64_RS_PMD
: /* four or more registers */
5738 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_PMD_R3
)
5740 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_GR
;
5741 if (regno
>= 0 && regno
< NELEMS(gr_values
)
5744 specs
[count
] = tmpl
;
5745 specs
[count
++].index
= gr_values
[regno
].value
& 0xFF;
5749 specs
[count
] = tmpl
;
5750 specs
[count
++].specific
= 0;
5760 case IA64_RS_RR
: /* eight registers */
5763 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_RR_R3
)
5765 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_GR
;
5766 if (regno
>= 0 && regno
< NELEMS(gr_values
)
5769 specs
[count
] = tmpl
;
5770 specs
[count
++].index
= (gr_values
[regno
].value
>> 61) & 0x7;
5774 specs
[count
] = tmpl
;
5775 specs
[count
++].specific
= 0;
5779 else if (note
== 0 && !rsrc_write
)
5781 specs
[count
] = tmpl
;
5782 specs
[count
++].specific
= 0;
5790 case IA64_RS_CR_IRR
:
5793 /* handle mov-from-CR-IVR; it's a read that writes CR[IRR] */
5794 int regno
= CURR_SLOT
.opnd
[1].X_add_number
- REG_CR
;
5796 && idesc
->operands
[1] == IA64_OPND_CR3
5801 specs
[count
] = tmpl
;
5802 specs
[count
++].index
= CR_IRR0
+ i
;
5808 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_CR
;
5809 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_CR3
5811 && regno
<= CR_IRR3
)
5813 specs
[count
] = tmpl
;
5814 specs
[count
++].index
= regno
;
5823 case IA64_RS_CR_LRR
:
5830 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_CR
;
5831 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_CR3
5832 && (regno
== CR_LRR0
|| regno
== CR_LRR1
))
5834 specs
[count
] = tmpl
;
5835 specs
[count
++].index
= regno
;
5843 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_CR3
)
5845 specs
[count
] = tmpl
;
5846 specs
[count
++].index
=
5847 CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_CR
;
5862 else if (rsrc_write
)
5864 if (dep
->specifier
== IA64_RS_FRb
5865 && idesc
->operands
[0] == IA64_OPND_F1
)
5867 specs
[count
] = tmpl
;
5868 specs
[count
++].index
= CURR_SLOT
.opnd
[0].X_add_number
- REG_FR
;
5873 for (i
=idesc
->num_outputs
;i
< NELEMS(idesc
->operands
);i
++)
5875 if (idesc
->operands
[i
] == IA64_OPND_F2
5876 || idesc
->operands
[i
] == IA64_OPND_F3
5877 || idesc
->operands
[i
] == IA64_OPND_F4
)
5879 specs
[count
] = tmpl
;
5880 specs
[count
++].index
=
5881 CURR_SLOT
.opnd
[i
].X_add_number
- REG_FR
;
5890 /* This reference applies only to the GR whose value is loaded with
5891 data returned from memory */
5892 specs
[count
] = tmpl
;
5893 specs
[count
++].index
= CURR_SLOT
.opnd
[0].X_add_number
- REG_GR
;
5899 for (i
=0;i
< idesc
->num_outputs
;i
++)
5901 if (idesc
->operands
[i
] == IA64_OPND_R1
5902 || idesc
->operands
[i
] == IA64_OPND_R2
5903 || idesc
->operands
[i
] == IA64_OPND_R3
)
5905 specs
[count
] = tmpl
;
5906 specs
[count
++].index
=
5907 CURR_SLOT
.opnd
[i
].X_add_number
- REG_GR
;
5913 /* Look for anything that reads a GR */
5914 for (i
=0;i
< NELEMS(idesc
->operands
);i
++)
5916 if (idesc
->operands
[i
] == IA64_OPND_MR3
5917 || idesc
->operands
[i
] == IA64_OPND_CPUID_R3
5918 || idesc
->operands
[i
] == IA64_OPND_DBR_R3
5919 || idesc
->operands
[i
] == IA64_OPND_IBR_R3
5920 || idesc
->operands
[i
] == IA64_OPND_MSR_R3
5921 || idesc
->operands
[i
] == IA64_OPND_PKR_R3
5922 || idesc
->operands
[i
] == IA64_OPND_PMC_R3
5923 || idesc
->operands
[i
] == IA64_OPND_PMD_R3
5924 || idesc
->operands
[i
] == IA64_OPND_RR_R3
5925 || ((i
>= idesc
->num_outputs
)
5926 && (idesc
->operands
[i
] == IA64_OPND_R1
5927 || idesc
->operands
[i
] == IA64_OPND_R2
5928 || idesc
->operands
[i
] == IA64_OPND_R3
)))
5930 specs
[count
] = tmpl
;
5931 specs
[count
++].index
=
5932 CURR_SLOT
.opnd
[i
].X_add_number
- REG_GR
;
5946 if (idesc
->operands
[0] == IA64_OPND_PR_ROT
)
5948 for (i
=16;i
< 63;i
++)
5950 specs
[count
] = tmpl
;
5951 specs
[count
++].index
= i
;
5956 for (i
=1;i
< 63;i
++)
5958 specs
[count
] = tmpl
;
5959 specs
[count
++].index
= i
;
5966 /* mark only those registers indicated by the mask */
5968 && idesc
->operands
[0] == IA64_OPND_PR
)
5970 mask
= CURR_SLOT
.opnd
[2].X_add_number
;
5971 if (mask
& ((valueT
)1<<16))
5972 mask
|= ~(valueT
)0xffff;
5973 for (i
=1;i
< 63;i
++)
5975 if (mask
& ((valueT
)1<<i
))
5977 specs
[count
] = tmpl
;
5978 specs
[count
++].index
= i
;
5983 && idesc
->operands
[0] == IA64_OPND_PR_ROT
)
5985 for (i
=16;i
< 63;i
++)
5987 specs
[count
] = tmpl
;
5988 specs
[count
++].index
= i
;
5996 else if (note
== 11) /* note 11 implies note 1 as well */
6000 for (i
=0;i
< idesc
->num_outputs
;i
++)
6002 if (idesc
->operands
[i
] == IA64_OPND_P1
6003 || idesc
->operands
[i
] == IA64_OPND_P2
)
6005 int regno
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_P
;
6008 specs
[count
] = tmpl
;
6009 specs
[count
++].index
= regno
;
6019 else if (note
== 12)
6021 if (CURR_SLOT
.qp_regno
!= 0)
6023 specs
[count
] = tmpl
;
6024 specs
[count
++].index
= CURR_SLOT
.qp_regno
;
6031 int p1
= CURR_SLOT
.opnd
[0].X_add_number
- REG_P
;
6032 int p2
= CURR_SLOT
.opnd
[1].X_add_number
- REG_P
;
6033 if ((idesc
->operands
[0] == IA64_OPND_P1
6034 || idesc
->operands
[0] == IA64_OPND_P2
)
6035 && p1
!= 0 && p1
!= 63)
6037 specs
[count
] = tmpl
;
6038 specs
[count
++].index
= p1
;
6040 if ((idesc
->operands
[1] == IA64_OPND_P1
6041 || idesc
->operands
[1] == IA64_OPND_P2
)
6042 && p2
!= 0 && p2
!= 63)
6044 specs
[count
] = tmpl
;
6045 specs
[count
++].index
= p2
;
6050 if (CURR_SLOT
.qp_regno
!= 0)
6052 specs
[count
] = tmpl
;
6053 specs
[count
++].index
= CURR_SLOT
.qp_regno
;
6055 if (idesc
->operands
[1] == IA64_OPND_PR
)
6057 for (i
=1;i
< 63;i
++)
6059 specs
[count
] = tmpl
;
6060 specs
[count
++].index
= i
;
6072 /* Verify that the instruction is using the PSR bit indicated in
6076 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_PSR_UM
)
6078 if (dep
->regindex
< 6)
6080 specs
[count
++] = tmpl
;
6083 else if (idesc
->operands
[!rsrc_write
] == IA64_OPND_PSR
)
6085 if (dep
->regindex
< 32
6086 || dep
->regindex
== 35
6087 || dep
->regindex
== 36
6088 || (!rsrc_write
&& dep
->regindex
== PSR_CPL
))
6090 specs
[count
++] = tmpl
;
6093 else if (idesc
->operands
[!rsrc_write
] == IA64_OPND_PSR_L
)
6095 if (dep
->regindex
< 32
6096 || dep
->regindex
== 35
6097 || dep
->regindex
== 36
6098 || (rsrc_write
&& dep
->regindex
== PSR_CPL
))
6100 specs
[count
++] = tmpl
;
6105 /* Several PSR bits have very specific dependencies. */
6106 switch (dep
->regindex
)
6109 specs
[count
++] = tmpl
;
6114 specs
[count
++] = tmpl
;
6118 /* Only certain CR accesses use PSR.ic */
6119 if (idesc
->operands
[0] == IA64_OPND_CR3
6120 || idesc
->operands
[1] == IA64_OPND_CR3
)
6123 ((idesc
->operands
[0] == IA64_OPND_CR3
)
6126 CURR_SLOT
.opnd
[index
].X_add_number
- REG_CR
;
6141 specs
[count
++] = tmpl
;
6150 specs
[count
++] = tmpl
;
6154 /* Only some AR accesses use cpl */
6155 if (idesc
->operands
[0] == IA64_OPND_AR3
6156 || idesc
->operands
[1] == IA64_OPND_AR3
)
6159 ((idesc
->operands
[0] == IA64_OPND_AR3
)
6162 CURR_SLOT
.opnd
[index
].X_add_number
- REG_AR
;
6169 && regno
<= AR_K7
))))
6171 specs
[count
++] = tmpl
;
6176 specs
[count
++] = tmpl
;
6186 if (idesc
->operands
[0] == IA64_OPND_IMMU24
)
6188 mask
= CURR_SLOT
.opnd
[0].X_add_number
;
6194 if (mask
& ((valueT
)1<<dep
->regindex
))
6196 specs
[count
++] = tmpl
;
6201 int min
= dep
->regindex
== PSR_DFL
? 2 : 32;
6202 int max
= dep
->regindex
== PSR_DFL
? 31 : 127;
6203 /* dfh is read on FR32-127; dfl is read on FR2-31 */
6204 for (i
=0;i
< NELEMS(idesc
->operands
);i
++)
6206 if (idesc
->operands
[i
] == IA64_OPND_F1
6207 || idesc
->operands
[i
] == IA64_OPND_F2
6208 || idesc
->operands
[i
] == IA64_OPND_F3
6209 || idesc
->operands
[i
] == IA64_OPND_F4
)
6211 int reg
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_FR
;
6212 if (reg
>= min
&& reg
<= max
)
6214 specs
[count
++] = tmpl
;
6221 int min
= dep
->regindex
== PSR_MFL
? 2 : 32;
6222 int max
= dep
->regindex
== PSR_MFL
? 31 : 127;
6223 /* mfh is read on writes to FR32-127; mfl is read on writes to
6225 for (i
=0;i
< idesc
->num_outputs
;i
++)
6227 if (idesc
->operands
[i
] == IA64_OPND_F1
)
6229 int reg
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_FR
;
6230 if (reg
>= min
&& reg
<= max
)
6232 specs
[count
++] = tmpl
;
6237 else if (note
== 10)
6239 for (i
=0;i
< NELEMS(idesc
->operands
);i
++)
6241 if (idesc
->operands
[i
] == IA64_OPND_R1
6242 || idesc
->operands
[i
] == IA64_OPND_R2
6243 || idesc
->operands
[i
] == IA64_OPND_R3
)
6245 int regno
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_GR
;
6246 if (regno
>= 16 && regno
<= 31)
6248 specs
[count
++] = tmpl
;
6259 case IA64_RS_AR_FPSR
:
6260 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_AR3
)
6262 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_AR
;
6263 if (regno
== AR_FPSR
)
6265 specs
[count
++] = tmpl
;
6270 specs
[count
++] = tmpl
;
6275 /* Handle all AR[REG] resources */
6276 if (note
== 0 || note
== 1)
6278 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_AR
;
6279 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_AR3
6280 && regno
== dep
->regindex
)
6282 specs
[count
++] = tmpl
;
6284 /* other AR[REG] resources may be affected by AR accesses */
6285 else if (idesc
->operands
[0] == IA64_OPND_AR3
)
6288 regno
= CURR_SLOT
.opnd
[0].X_add_number
- REG_AR
;
6289 switch (dep
->regindex
)
6295 if (regno
== AR_BSPSTORE
)
6297 specs
[count
++] = tmpl
;
6301 (regno
== AR_BSPSTORE
6302 || regno
== AR_RNAT
))
6304 specs
[count
++] = tmpl
;
6309 else if (idesc
->operands
[1] == IA64_OPND_AR3
)
6312 regno
= CURR_SLOT
.opnd
[1].X_add_number
- REG_AR
;
6313 switch (dep
->regindex
)
6318 if (regno
== AR_BSPSTORE
|| regno
== AR_RNAT
)
6320 specs
[count
++] = tmpl
;
6327 specs
[count
++] = tmpl
;
6337 /* Handle all CR[REG] resources */
6338 if (note
== 0 || note
== 1)
6340 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_CR3
)
6342 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_CR
;
6343 if (regno
== dep
->regindex
)
6345 specs
[count
++] = tmpl
;
6347 else if (!rsrc_write
)
6349 /* Reads from CR[IVR] affect other resources. */
6350 if (regno
== CR_IVR
)
6352 if ((dep
->regindex
>= CR_IRR0
6353 && dep
->regindex
<= CR_IRR3
)
6354 || dep
->regindex
== CR_TPR
)
6356 specs
[count
++] = tmpl
;
6363 specs
[count
++] = tmpl
;
6372 case IA64_RS_INSERVICE
:
6373 /* look for write of EOI (67) or read of IVR (65) */
6374 if ((idesc
->operands
[0] == IA64_OPND_CR3
6375 && CURR_SLOT
.opnd
[0].X_add_number
- REG_CR
== CR_EOI
)
6376 || (idesc
->operands
[1] == IA64_OPND_CR3
6377 && CURR_SLOT
.opnd
[1].X_add_number
- REG_CR
== CR_IVR
))
6379 specs
[count
++] = tmpl
;
6386 specs
[count
++] = tmpl
;
6397 specs
[count
++] = tmpl
;
6401 /* Check if any of the registers accessed are in the rotating region.
6402 mov to/from pr accesses CFM only when qp_regno is in the rotating
6404 for (i
=0;i
< NELEMS(idesc
->operands
);i
++)
6406 if (idesc
->operands
[i
] == IA64_OPND_R1
6407 || idesc
->operands
[i
] == IA64_OPND_R2
6408 || idesc
->operands
[i
] == IA64_OPND_R3
)
6410 int num
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_GR
;
6411 /* Assumes that md.rot.num_regs is always valid */
6412 if (md
.rot
.num_regs
> 0
6414 && num
< 31 + md
.rot
.num_regs
)
6416 specs
[count
] = tmpl
;
6417 specs
[count
++].specific
= 0;
6420 else if (idesc
->operands
[i
] == IA64_OPND_F1
6421 || idesc
->operands
[i
] == IA64_OPND_F2
6422 || idesc
->operands
[i
] == IA64_OPND_F3
6423 || idesc
->operands
[i
] == IA64_OPND_F4
)
6425 int num
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_FR
;
6428 specs
[count
] = tmpl
;
6429 specs
[count
++].specific
= 0;
6432 else if (idesc
->operands
[i
] == IA64_OPND_P1
6433 || idesc
->operands
[i
] == IA64_OPND_P2
)
6435 int num
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_P
;
6438 specs
[count
] = tmpl
;
6439 specs
[count
++].specific
= 0;
6443 if (CURR_SLOT
.qp_regno
> 15)
6445 specs
[count
] = tmpl
;
6446 specs
[count
++].specific
= 0;
6454 specs
[count
++] = tmpl
;
6456 else if (note
== 11)
6458 if ((idesc
->operands
[0] == IA64_OPND_P1
6459 && CURR_SLOT
.opnd
[0].X_add_number
- REG_P
== 63)
6460 || (idesc
->operands
[1] == IA64_OPND_P2
6461 && CURR_SLOT
.opnd
[1].X_add_number
- REG_P
== 63))
6463 specs
[count
++] = tmpl
;
6466 else if (note
== 12)
6468 if (CURR_SLOT
.qp_regno
== 63)
6470 specs
[count
++] = tmpl
;
6476 if (idesc
->operands
[2] == IA64_OPND_IMM17
)
6477 mask
= CURR_SLOT
.opnd
[2].X_add_number
;
6478 if (mask
& ((valueT
)1<<63))
6480 specs
[count
++] = tmpl
;
6487 for (i
=0;i
< idesc
->num_outputs
;i
++)
6488 if ((idesc
->operands
[i
] == IA64_OPND_P1
6489 || idesc
->operands
[i
] == IA64_OPND_P2
)
6490 && CURR_SLOT
.opnd
[i
].X_add_number
- REG_P
== 63)
6492 specs
[count
++] = tmpl
;
6497 if (CURR_SLOT
.qp_regno
== 63)
6499 specs
[count
++] = tmpl
;
6510 /* FIXME we can identify some individual RSE written resources, but RSE
6511 read resources have not yet been completely identified, so for now
6512 treat RSE as a single resource */
6513 if (strncmp (idesc
->name
, "mov", 3) == 0)
6517 if (idesc
->operands
[0] == IA64_OPND_AR3
6518 && CURR_SLOT
.opnd
[0].X_add_number
- REG_AR
== AR_BSPSTORE
)
6520 specs
[count
] = tmpl
;
6521 specs
[count
++].index
= 0; /* IA64_RSE_BSPLOAD/RNATBITINDEX */
6526 if (idesc
->operands
[0] == IA64_OPND_AR3
)
6528 if (CURR_SLOT
.opnd
[0].X_add_number
- REG_AR
== AR_BSPSTORE
6529 || CURR_SLOT
.opnd
[0].X_add_number
- REG_AR
== AR_RNAT
)
6531 specs
[count
++] = tmpl
;
6534 else if (idesc
->operands
[1] == IA64_OPND_AR3
)
6536 if (CURR_SLOT
.opnd
[1].X_add_number
- REG_AR
== AR_BSP
6537 || CURR_SLOT
.opnd
[1].X_add_number
- REG_AR
== AR_BSPSTORE
6538 || CURR_SLOT
.opnd
[1].X_add_number
- REG_AR
== AR_RNAT
)
6540 specs
[count
++] = tmpl
;
6547 specs
[count
++] = tmpl
;
6552 /* FIXME -- do any of these need to be non-specific? */
6553 specs
[count
++] = tmpl
;
6557 as_bad (_("Unrecognized dependency specifier %d\n"), dep
->specifier
);
6564 /* Clear branch flags on marked resources. This breaks the link between the
6565 QP of the marking instruction and a subsequent branch on the same QP.
6568 clear_qp_branch_flag (mask
)
6572 for (i
= 0;i
< regdepslen
;i
++)
6574 valueT bit
= ((valueT
)1 << regdeps
[i
].qp_regno
);
6575 if ((bit
& mask
) != 0)
6577 regdeps
[i
].link_to_qp_branch
= 0;
6582 /* Remove any mutexes which contain any of the PRs indicated in the mask.
6584 Any changes to a PR clears the mutex relations which include that PR.
6587 clear_qp_mutex (mask
)
6593 while (i
< qp_mutexeslen
)
6595 if ((qp_mutexes
[i
].prmask
& mask
) != 0)
6599 fprintf (stderr
, " Clearing mutex relation");
6600 print_prmask (qp_mutexes
[i
].prmask
);
6601 fprintf (stderr
, "\n");
6603 qp_mutexes
[i
] = qp_mutexes
[--qp_mutexeslen
];
6610 /* Clear implies relations which contain PRs in the given masks.
6611 P1_MASK indicates the source of the implies relation, while P2_MASK
6612 indicates the implied PR.
6615 clear_qp_implies (p1_mask
, p2_mask
)
6622 while (i
< qp_implieslen
)
6624 if ((((valueT
)1 << qp_implies
[i
].p1
) & p1_mask
) != 0
6625 || (((valueT
)1 << qp_implies
[i
].p2
) & p2_mask
) != 0)
6628 fprintf (stderr
, "Clearing implied relation PR%d->PR%d\n",
6629 qp_implies
[i
].p1
, qp_implies
[i
].p2
);
6630 qp_implies
[i
] = qp_implies
[--qp_implieslen
];
6637 /* add the PRs specified to the list of implied relations */
6639 add_qp_imply (p1
, p2
)
6646 /* p0 is not meaningful here */
6647 if (p1
== 0 || p2
== 0)
6653 /* if it exists already, ignore it */
6654 for (i
=0;i
< qp_implieslen
;i
++)
6656 if (qp_implies
[i
].p1
== p1
6657 && qp_implies
[i
].p2
== p2
6658 && qp_implies
[i
].path
== md
.path
6659 && !qp_implies
[i
].p2_branched
)
6663 if (qp_implieslen
== qp_impliestotlen
)
6665 qp_impliestotlen
+= 20;
6666 qp_implies
= (struct qp_imply
*)
6667 xrealloc ((void *)qp_implies
,
6668 qp_impliestotlen
* sizeof (struct qp_imply
));
6671 fprintf (stderr
, " Registering PR%d implies PR%d\n", p1
, p2
);
6672 qp_implies
[qp_implieslen
].p1
= p1
;
6673 qp_implies
[qp_implieslen
].p2
= p2
;
6674 qp_implies
[qp_implieslen
].path
= md
.path
;
6675 qp_implies
[qp_implieslen
++].p2_branched
= 0;
6677 /* Add in the implied transitive relations; for everything that p2 implies,
6678 make p1 imply that, too; for everything that implies p1, make it imply p2
6680 for (i
=0;i
< qp_implieslen
;i
++)
6682 if (qp_implies
[i
].p1
== p2
)
6683 add_qp_imply (p1
, qp_implies
[i
].p2
);
6684 if (qp_implies
[i
].p2
== p1
)
6685 add_qp_imply (qp_implies
[i
].p1
, p2
);
6687 /* Add in mutex relations implied by this implies relation; for each mutex
6688 relation containing p2, duplicate it and replace p2 with p1. */
6689 bit
= (valueT
)1 << p1
;
6690 mask
= (valueT
)1 << p2
;
6691 for (i
=0;i
< qp_mutexeslen
;i
++)
6693 if (qp_mutexes
[i
].prmask
& mask
)
6694 add_qp_mutex ((qp_mutexes
[i
].prmask
& ~mask
) | bit
);
6699 /* Add the PRs specified in the mask to the mutex list; this means that only
6700 one of the PRs can be true at any time. PR0 should never be included in
6709 if (qp_mutexeslen
== qp_mutexestotlen
)
6711 qp_mutexestotlen
+= 20;
6712 qp_mutexes
= (struct qpmutex
*)
6713 xrealloc ((void *)qp_mutexes
,
6714 qp_mutexestotlen
* sizeof (struct qpmutex
));
6718 fprintf (stderr
, " Registering mutex on");
6719 print_prmask (mask
);
6720 fprintf (stderr
, "\n");
6722 qp_mutexes
[qp_mutexeslen
].path
= md
.path
;
6723 qp_mutexes
[qp_mutexeslen
++].prmask
= mask
;
6727 clear_register_values ()
6731 fprintf (stderr
, " Clearing register values\n");
6732 for (i
=1;i
< NELEMS(gr_values
);i
++)
6733 gr_values
[i
].known
= 0;
6736 /* Keep track of register values/changes which affect DV tracking.
6738 optimization note: should add a flag to classes of insns where otherwise we
6739 have to examine a group of strings to identify them.
6743 note_register_values (idesc
)
6744 struct ia64_opcode
*idesc
;
6746 valueT qp_changemask
= 0;
6749 /* invalidate values for registers being written to */
6750 for (i
=0;i
< idesc
->num_outputs
;i
++)
6752 if (idesc
->operands
[i
] == IA64_OPND_R1
6753 || idesc
->operands
[i
] == IA64_OPND_R2
6754 || idesc
->operands
[i
] == IA64_OPND_R3
)
6756 int regno
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_GR
;
6757 if (regno
> 0 && regno
< NELEMS(gr_values
))
6758 gr_values
[regno
].known
= 0;
6760 else if (idesc
->operands
[i
] == IA64_OPND_P1
6761 || idesc
->operands
[i
] == IA64_OPND_P2
)
6763 int regno
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_P
;
6764 qp_changemask
|= (valueT
)1 << regno
;
6766 else if (idesc
->operands
[i
] == IA64_OPND_PR
)
6768 if (idesc
->operands
[2] & (valueT
)0x10000)
6769 qp_changemask
= ~(valueT
)0x1FFFF | idesc
->operands
[2];
6771 qp_changemask
= idesc
->operands
[2];
6774 else if (idesc
->operands
[i
] == IA64_OPND_PR_ROT
)
6776 if (idesc
->operands
[1] & ((valueT
)1 << 43))
6777 qp_changemask
= ~(valueT
)0xFFFFFFFFFFF | idesc
->operands
[1];
6779 qp_changemask
= idesc
->operands
[1];
6780 qp_changemask
&= ~(valueT
)0xFFFF;
6785 /* Always clear qp branch flags on any PR change */
6786 /* FIXME there may be exceptions for certain compares */
6787 clear_qp_branch_flag (qp_changemask
);
6789 /* invalidate rotating registers on insns which affect RRBs in CFM */
6790 if (idesc
->flags
& IA64_OPCODE_MOD_RRBS
)
6792 qp_changemask
|= ~(valueT
)0xFFFF;
6793 if (strcmp (idesc
->name
, "clrrrb.pr") != 0)
6795 for (i
=32;i
< 32+md
.rot
.num_regs
;i
++)
6796 gr_values
[i
].known
= 0;
6798 clear_qp_mutex (qp_changemask
);
6799 clear_qp_implies (qp_changemask
, qp_changemask
);
6801 /* after a call, all register values are undefined, except those marked
6803 else if (strncmp (idesc
->name
, "br.call", 6) == 0
6804 || strncmp (idesc
->name
, "brl.call", 7) == 0)
6806 // FIXME keep GR values which are marked as "safe_across_calls"
6807 clear_register_values ();
6808 clear_qp_mutex (~qp_safe_across_calls
);
6809 clear_qp_implies (~qp_safe_across_calls
, ~qp_safe_across_calls
);
6810 clear_qp_branch_flag (~qp_safe_across_calls
);
6812 /* Look for mutex and implies relations */
6813 else if ((idesc
->operands
[0] == IA64_OPND_P1
6814 || idesc
->operands
[0] == IA64_OPND_P2
)
6815 && (idesc
->operands
[1] == IA64_OPND_P1
6816 || idesc
->operands
[1] == IA64_OPND_P2
))
6818 int p1
= CURR_SLOT
.opnd
[0].X_add_number
- REG_P
;
6819 int p2
= CURR_SLOT
.opnd
[1].X_add_number
- REG_P
;
6820 valueT p1mask
= (valueT
)1 << p1
;
6821 valueT p2mask
= (valueT
)1 << p2
;
6823 /* if one of the PRs is PR0, we can't really do anything */
6824 if (p1
== 0 || p2
== 0)
6827 fprintf (stderr
, " Ignoring PRs due to inclusion of p0\n");
6829 /* In general, clear mutexes and implies which include P1 or P2,
6830 with the following exceptions */
6831 else if (strstr (idesc
->name
, ".or.andcm") != NULL
)
6833 add_qp_mutex (p1mask
| p2mask
);
6834 clear_qp_implies (p2mask
, p1mask
);
6836 else if (strstr (idesc
->name
, ".and.orcm") != NULL
)
6838 add_qp_mutex (p1mask
| p2mask
);
6839 clear_qp_implies (p1mask
, p2mask
);
6841 else if (strstr (idesc
->name
, ".and") != NULL
)
6843 clear_qp_implies (0, p1mask
| p2mask
);
6845 else if (strstr (idesc
->name
, ".or") != NULL
)
6847 clear_qp_mutex (p1mask
| p2mask
);
6848 clear_qp_implies (p1mask
| p2mask
, 0);
6852 clear_qp_implies (p1mask
| p2mask
, p1mask
| p2mask
);
6853 if (strstr (idesc
->name
, ".unc") != NULL
)
6855 add_qp_mutex (p1mask
| p2mask
);
6856 if (CURR_SLOT
.qp_regno
!= 0)
6858 add_qp_imply (CURR_SLOT
.opnd
[0].X_add_number
- REG_P
,
6859 CURR_SLOT
.qp_regno
);
6860 add_qp_imply (CURR_SLOT
.opnd
[1].X_add_number
- REG_P
,
6861 CURR_SLOT
.qp_regno
);
6864 else if (CURR_SLOT
.qp_regno
== 0)
6866 add_qp_mutex (p1mask
| p2mask
);
6870 clear_qp_mutex (p1mask
| p2mask
);
6874 /* Look for mov imm insns into GRs */
6875 else if (idesc
->operands
[0] == IA64_OPND_R1
6876 && (idesc
->operands
[1] == IA64_OPND_IMM22
6877 || idesc
->operands
[1] == IA64_OPND_IMMU64
)
6878 && (strcmp(idesc
->name
, "mov") == 0
6879 || strcmp(idesc
->name
, "movl") == 0))
6881 int regno
= CURR_SLOT
.opnd
[0].X_add_number
- REG_GR
;
6882 if (regno
> 0 && regno
< NELEMS(gr_values
))
6884 gr_values
[regno
].known
= 1;
6885 gr_values
[regno
].value
= CURR_SLOT
.opnd
[1].X_add_number
;
6886 gr_values
[regno
].path
= md
.path
;
6888 fprintf (stderr
, " Know gr%d = 0x%llx\n",
6889 regno
, gr_values
[regno
].value
);
6894 clear_qp_mutex (qp_changemask
);
6895 clear_qp_implies (qp_changemask
, qp_changemask
);
6899 /* Return whether the given predicate registers are currently mutex */
6901 qp_mutex (p1
, p2
, path
)
6911 mask
= ((valueT
)1<<p1
) | (valueT
)1<<p2
;
6912 for (i
=0;i
< qp_mutexeslen
;i
++)
6914 if (qp_mutexes
[i
].path
>= path
6915 && (qp_mutexes
[i
].prmask
& mask
) == mask
)
6922 /* Return whether the given resource is in the given insn's list of chks
6923 Return 1 if the conflict is absolutely determined, 2 if it's a potential
6927 resources_match (rs
, idesc
, note
, qp_regno
, path
)
6929 struct ia64_opcode
*idesc
;
6934 struct rsrc specs
[MAX_SPECS
];
6937 /* If the marked resource's qp_regno and the given qp_regno are mutex,
6938 we don't need to check. One exception is note 11, which indicates that
6939 target predicates are written regardless of PR[qp]. */
6940 if (qp_mutex (rs
->qp_regno
, qp_regno
, path
)
6944 count
= specify_resource (rs
->dependency
, idesc
, DV_CHK
, specs
, note
, path
);
6947 /* UNAT checking is a bit more specific than other resources */
6948 if (rs
->dependency
->specifier
== IA64_RS_AR_UNAT
6949 && specs
[count
].mem_offset
.hint
6950 && rs
->mem_offset
.hint
)
6952 if (rs
->mem_offset
.base
== specs
[count
].mem_offset
.base
)
6954 if (((rs
->mem_offset
.offset
>> 3) & 0x3F) ==
6955 ((specs
[count
].mem_offset
.offset
>> 3) & 0x3F))
6962 /* If either resource is not specific, conservatively assume a conflict
6964 if (!specs
[count
].specific
|| !rs
->specific
)
6966 else if (specs
[count
].index
== rs
->index
)
6971 fprintf (stderr
, " No %s conflicts\n", rs
->dependency
->name
);
6977 /* Indicate an instruction group break; if INSERT_STOP is non-zero, then
6978 insert a stop to create the break. Update all resource dependencies
6979 appropriately. If QP_REGNO is non-zero, only apply the break to resources
6980 which use the same QP_REGNO and have the link_to_qp_branch flag set.
6981 If SAVE_CURRENT is non-zero, don't affect resources marked by the current
6986 insn_group_break (insert_stop
, qp_regno
, save_current
)
6993 if (insert_stop
&& md
.num_slots_in_use
> 0)
6994 PREV_SLOT
.end_of_insn_group
= 1;
6998 fprintf (stderr
, " Insn group break%s",
6999 (insert_stop
? " (w/stop)" : ""));
7001 fprintf (stderr
, " effective for QP=%d", qp_regno
);
7002 fprintf (stderr
, "\n");
7006 while (i
< regdepslen
)
7008 const struct ia64_dependency
*dep
= regdeps
[i
].dependency
;
7011 && regdeps
[i
].qp_regno
!= qp_regno
)
7018 && CURR_SLOT
.src_file
== regdeps
[i
].file
7019 && CURR_SLOT
.src_line
== regdeps
[i
].line
)
7025 /* clear dependencies which are automatically cleared by a stop, or
7026 those that have reached the appropriate state of insn serialization */
7027 if (dep
->semantics
== IA64_DVS_IMPLIED
7028 || dep
->semantics
== IA64_DVS_IMPLIEDF
7029 || regdeps
[i
].insn_srlz
== STATE_SRLZ
)
7031 print_dependency ("Removing", i
);
7032 regdeps
[i
] = regdeps
[--regdepslen
];
7036 if (dep
->semantics
== IA64_DVS_DATA
7037 || dep
->semantics
== IA64_DVS_INSTR
7038 || dep
->semantics
== IA64_DVS_SPECIFIC
)
7040 if (regdeps
[i
].insn_srlz
== STATE_NONE
)
7041 regdeps
[i
].insn_srlz
= STATE_STOP
;
7042 if (regdeps
[i
].data_srlz
== STATE_NONE
)
7043 regdeps
[i
].data_srlz
= STATE_STOP
;
7050 /* Add the given resource usage spec to the list of active dependencies */
7052 mark_resource (idesc
, dep
, spec
, depind
, path
)
7053 struct ia64_opcode
*idesc
;
7054 const struct ia64_dependency
*dep
;
7059 if (regdepslen
== regdepstotlen
)
7061 regdepstotlen
+= 20;
7062 regdeps
= (struct rsrc
*)
7063 xrealloc ((void *)regdeps
,
7064 regdepstotlen
* sizeof(struct rsrc
));
7067 regdeps
[regdepslen
] = *spec
;
7068 regdeps
[regdepslen
].depind
= depind
;
7069 regdeps
[regdepslen
].path
= path
;
7070 regdeps
[regdepslen
].file
= CURR_SLOT
.src_file
;
7071 regdeps
[regdepslen
].line
= CURR_SLOT
.src_line
;
7073 print_dependency ("Adding", regdepslen
);
7079 print_dependency (action
, depind
)
7085 fprintf (stderr
, " %s %s '%s'",
7086 action
, dv_mode
[(regdeps
[depind
].dependency
)->mode
],
7087 (regdeps
[depind
].dependency
)->name
);
7088 if (regdeps
[depind
].specific
&& regdeps
[depind
].index
!= 0)
7089 fprintf (stderr
, " (%d)", regdeps
[depind
].index
);
7090 if (regdeps
[depind
].mem_offset
.hint
)
7091 fprintf (stderr
, " 0x%llx+0x%llx",
7092 regdeps
[depind
].mem_offset
.base
,
7093 regdeps
[depind
].mem_offset
.offset
);
7094 fprintf (stderr
, "\n");
7099 instruction_serialization ()
7103 fprintf (stderr
, " Instruction serialization\n");
7104 for (i
=0;i
< regdepslen
;i
++)
7105 if (regdeps
[i
].insn_srlz
== STATE_STOP
)
7106 regdeps
[i
].insn_srlz
= STATE_SRLZ
;
7110 data_serialization ()
7114 fprintf (stderr
, " Data serialization\n");
7115 while (i
< regdepslen
)
7117 if (regdeps
[i
].data_srlz
== STATE_STOP
7118 /* Note: as of 991210, all "other" dependencies are cleared by a
7119 data serialization. This might change with new tables */
7120 || (regdeps
[i
].dependency
)->semantics
== IA64_DVS_OTHER
)
7122 print_dependency ("Removing", i
);
7123 regdeps
[i
] = regdeps
[--regdepslen
];
7130 /* Insert stops and serializations as needed to avoid DVs */
7132 remove_marked_resource (rs
)
7135 switch (rs
->dependency
->semantics
)
7137 case IA64_DVS_SPECIFIC
:
7139 fprintf (stderr
, "Implementation-specific, assume worst case...\n");
7140 /* ...fall through... */
7141 case IA64_DVS_INSTR
:
7143 fprintf (stderr
, "Inserting instr serialization\n");
7144 if (rs
->insn_srlz
< STATE_STOP
)
7145 insn_group_break (1, 0, 0);
7146 if (rs
->insn_srlz
< STATE_SRLZ
)
7148 int oldqp
= CURR_SLOT
.qp_regno
;
7149 struct ia64_opcode
*oldidesc
= CURR_SLOT
.idesc
;
7150 /* Manually jam a srlz.i insn into the stream */
7151 CURR_SLOT
.qp_regno
= 0;
7152 CURR_SLOT
.idesc
= ia64_find_opcode ("srlz.i");
7153 instruction_serialization ();
7154 md
.curr_slot
= (md
.curr_slot
+ 1) % NUM_SLOTS
;
7155 if (++md
.num_slots_in_use
>= NUM_SLOTS
)
7157 CURR_SLOT
.qp_regno
= oldqp
;
7158 CURR_SLOT
.idesc
= oldidesc
;
7160 insn_group_break (1, 0, 0);
7162 case IA64_DVS_OTHER
: /* as of rev2 (991220) of the DV tables, all
7163 "other" types of DV are eliminated
7164 by a data serialization */
7167 fprintf (stderr
, "Inserting data serialization\n");
7168 if (rs
->data_srlz
< STATE_STOP
)
7169 insn_group_break (1, 0, 0);
7171 int oldqp
= CURR_SLOT
.qp_regno
;
7172 struct ia64_opcode
*oldidesc
= CURR_SLOT
.idesc
;
7173 /* Manually jam a srlz.d insn into the stream */
7174 CURR_SLOT
.qp_regno
= 0;
7175 CURR_SLOT
.idesc
= ia64_find_opcode ("srlz.d");
7176 data_serialization ();
7177 md
.curr_slot
= (md
.curr_slot
+ 1) % NUM_SLOTS
;
7178 if (++md
.num_slots_in_use
>= NUM_SLOTS
)
7180 CURR_SLOT
.qp_regno
= oldqp
;
7181 CURR_SLOT
.idesc
= oldidesc
;
7184 case IA64_DVS_IMPLIED
:
7185 case IA64_DVS_IMPLIEDF
:
7187 fprintf (stderr
, "Inserting stop\n");
7188 insn_group_break (1, 0, 0);
7195 /* Check the resources used by the given opcode against the current dependency
7198 The check is run once for each execution path encountered. In this case,
7199 a unique execution path is the sequence of instructions following a code
7200 entry point, e.g. the following has three execution paths, one starting
7201 at L0, one at L1, and one at L2.
7209 check_dependencies (idesc
)
7210 struct ia64_opcode
*idesc
;
7212 const struct ia64_opcode_dependency
*opdeps
= idesc
->dependencies
;
7216 /* Note that the number of marked resources may change within the
7217 loop if in auto mode. */
7219 while (i
< regdepslen
)
7221 struct rsrc
*rs
= ®deps
[i
];
7222 const struct ia64_dependency
*dep
= rs
->dependency
;
7227 if (dep
->semantics
== IA64_DVS_NONE
7228 || (chkind
= depends_on (rs
->depind
, idesc
)) == -1)
7233 note
= NOTE(opdeps
->chks
[chkind
]);
7235 /* Check this resource against each execution path seen thus far */
7236 for (path
=0;path
<= md
.path
;path
++)
7240 /* If the dependency wasn't on the path being checked, ignore it */
7241 if (rs
->path
< path
)
7244 /* If the QP for this insn implies a QP which has branched, don't
7245 bother checking. Ed. NOTE: I don't think this check is terribly
7246 useful; what's the point of generating code which will only be
7247 reached if its QP is zero?
7248 This code was specifically inserted to handle the following code,
7249 based on notes from Intel's DV checking code, where p1 implies p2.
7256 if (CURR_SLOT
.qp_regno
!= 0)
7260 for (implies
=0;implies
< qp_implieslen
;implies
++)
7262 if (qp_implies
[implies
].path
>= path
7263 && qp_implies
[implies
].p1
== CURR_SLOT
.qp_regno
7264 && qp_implies
[implies
].p2_branched
)
7274 if ((matchtype
= resources_match (rs
, idesc
, note
,
7275 CURR_SLOT
.qp_regno
, path
)) != 0)
7278 char pathmsg
[256] = "";
7279 char indexmsg
[256] = "";
7280 int certain
= (matchtype
== 1 && CURR_SLOT
.qp_regno
== 0);
7283 sprintf (pathmsg
, " when entry is at label '%s'",
7284 md
.entry_labels
[path
-1]);
7285 if (rs
->specific
&& rs
->index
!= 0)
7286 sprintf (indexmsg
, ", specific resource number is %d",
7288 sprintf (msg
, "Use of '%s' %s %s dependency '%s' (%s)%s%s",
7290 (certain
? "violates" : "may violate"),
7291 dv_mode
[dep
->mode
], dep
->name
,
7292 dv_sem
[dep
->semantics
],
7295 if (md
.explicit_mode
)
7297 as_warn ("%s", msg
);
7299 as_warn (_("Only the first path encountering the conflict "
7301 as_warn_where (rs
->file
, rs
->line
,
7302 _("This is the location of the "
7303 "conflicting usage"));
7304 /* Don't bother checking other paths, to avoid duplicating
7311 fprintf(stderr
, "%s @ %s:%d\n", msg
, rs
->file
, rs
->line
);
7313 remove_marked_resource (rs
);
7315 /* since the set of dependencies has changed, start over */
7316 /* FIXME -- since we're removing dvs as we go, we
7317 probably don't really need to start over... */
7330 /* register new dependencies based on the given opcode */
7332 mark_resources (idesc
)
7333 struct ia64_opcode
*idesc
;
7336 const struct ia64_opcode_dependency
*opdeps
= idesc
->dependencies
;
7337 int add_only_qp_reads
= 0;
7339 /* A conditional branch only uses its resources if it is taken; if it is
7340 taken, we stop following that path. The other branch types effectively
7341 *always* write their resources. If it's not taken, register only QP
7343 if (is_conditional_branch (idesc
) || is_interruption_or_rfi (idesc
))
7345 add_only_qp_reads
= 1;
7349 fprintf (stderr
, "Registering '%s' resource usage\n", idesc
->name
);
7351 for (i
=0;i
< opdeps
->nregs
;i
++)
7353 const struct ia64_dependency
*dep
;
7354 struct rsrc specs
[MAX_SPECS
];
7359 dep
= ia64_find_dependency (opdeps
->regs
[i
]);
7360 note
= NOTE(opdeps
->regs
[i
]);
7362 if (add_only_qp_reads
7363 && !(dep
->mode
== IA64_DV_WAR
7364 && (dep
->specifier
== IA64_RS_PR
7365 || dep
->specifier
== IA64_RS_PR63
)))
7368 count
= specify_resource (dep
, idesc
, DV_REG
, specs
, note
, md
.path
);
7371 if (md
.debug_dv
&& !count
)
7372 fprintf (stderr
, " No %s %s usage found (path %d)\n",
7373 dv_mode
[dep
->mode
], dep
->name
, md
.path
);
7378 mark_resource (idesc
, dep
, &specs
[count
],
7379 DEP(opdeps
->regs
[i
]), md
.path
);
7382 /* The execution path may affect register values, which may in turn
7383 affect which indirect-access resources are accessed. */
7384 switch (dep
->specifier
)
7396 for (path
=0;path
< md
.path
;path
++)
7398 count
= specify_resource (dep
, idesc
, DV_REG
, specs
, note
, path
);
7400 mark_resource (idesc
, dep
, &specs
[count
],
7401 DEP(opdeps
->regs
[i
]), path
);
7408 /* remove dependencies when they no longer apply */
7410 update_dependencies (idesc
)
7411 struct ia64_opcode
*idesc
;
7415 if (strcmp (idesc
->name
, "srlz.i") == 0)
7417 instruction_serialization ();
7419 else if (strcmp (idesc
->name
, "srlz.d") == 0)
7421 data_serialization ();
7423 else if (is_interruption_or_rfi (idesc
)
7424 || is_taken_branch (idesc
))
7426 /* although technically the taken branch doesn't clear dependencies
7427 which require a srlz.[id], we don't follow the branch; the next
7428 instruction is assumed to start with a clean slate */
7430 clear_register_values ();
7431 clear_qp_mutex (~(valueT
)0);
7432 clear_qp_implies (~(valueT
)0, ~(valueT
)0);
7435 else if (is_conditional_branch (idesc
)
7436 && CURR_SLOT
.qp_regno
!= 0)
7438 int is_call
= strstr (idesc
->name
, ".call") != NULL
;
7440 for (i
=0;i
< qp_implieslen
;i
++)
7442 /* if the conditional branch's predicate is implied by the predicate
7443 in an existing dependency, remove that dependency */
7444 if (qp_implies
[i
].p2
== CURR_SLOT
.qp_regno
)
7447 /* note that this implied predicate takes a branch so that if
7448 a later insn generates a DV but its predicate implies this
7449 one, we can avoid the false DV warning */
7450 qp_implies
[i
].p2_branched
= 1;
7451 while (depind
< regdepslen
)
7453 if (regdeps
[depind
].qp_regno
== qp_implies
[i
].p1
)
7455 print_dependency ("Removing", depind
);
7456 regdeps
[depind
] = regdeps
[--regdepslen
];
7463 /* Any marked resources which have this same predicate should be
7464 cleared, provided that the QP hasn't been modified between the
7465 marking instruction and the branch.
7469 insn_group_break (0, CURR_SLOT
.qp_regno
, 1);
7474 while (i
< regdepslen
)
7476 if (regdeps
[i
].qp_regno
== CURR_SLOT
.qp_regno
7477 && regdeps
[i
].link_to_qp_branch
7478 && (regdeps
[i
].file
!= CURR_SLOT
.src_file
7479 || regdeps
[i
].line
!= CURR_SLOT
.src_line
))
7481 /* Treat like a taken branch */
7482 print_dependency ("Removing", i
);
7483 regdeps
[i
] = regdeps
[--regdepslen
];
7492 /* Examine the current instruction for dependency violations. */
7495 struct ia64_opcode
*idesc
;
7499 fprintf (stderr
, "Checking %s for violations (line %d, %d/%d)\n",
7500 idesc
->name
, CURR_SLOT
.src_line
,
7501 idesc
->dependencies
->nchks
,
7502 idesc
->dependencies
->nregs
);
7505 /* Look through the list of currently marked resources; if the current
7506 instruction has the dependency in its chks list which uses that resource,
7507 check against the specific resources used.
7509 check_dependencies (idesc
);
7512 Look up the instruction's regdeps (RAW writes, WAW writes, and WAR reads),
7513 then add them to the list of marked resources.
7515 mark_resources (idesc
);
7517 /* There are several types of dependency semantics, and each has its own
7518 requirements for being cleared
7520 Instruction serialization (insns separated by interruption, rfi, or
7521 writer + srlz.i + reader, all in separate groups) clears DVS_INSTR.
7523 Data serialization (instruction serialization, or writer + srlz.d +
7524 reader, where writer and srlz.d are in separate groups) clears
7525 DVS_DATA. (This also clears DVS_OTHER, but that is not guaranteed to
7526 always be the case).
7528 Instruction group break (groups separated by stop, taken branch,
7529 interruption or rfi) clears DVS_IMPLIED and DVS_IMPLIEDF.
7531 update_dependencies (idesc
);
7533 /* Sometimes, knowing a register value allows us to avoid giving a false DV
7534 warning. Keep track of as many as possible that are useful. */
7535 note_register_values (idesc
);
7537 /* We don't need or want this anymore. */
7538 md
.mem_offset
.hint
= 0;
7543 /* Translate one line of assembly. Pseudo ops and labels do not show
7549 char *saved_input_line_pointer
, *mnemonic
;
7550 const struct pseudo_opcode
*pdesc
;
7551 struct ia64_opcode
*idesc
;
7552 unsigned char qp_regno
;
7556 saved_input_line_pointer
= input_line_pointer
;
7557 input_line_pointer
= str
;
7559 /* extract the opcode (mnemonic): */
7561 mnemonic
= input_line_pointer
;
7562 ch
= get_symbol_end ();
7563 pdesc
= (struct pseudo_opcode
*) hash_find (md
.pseudo_hash
, mnemonic
);
7566 *input_line_pointer
= ch
;
7567 (*pdesc
->handler
) (pdesc
->arg
);
7571 /* find the instruction descriptor matching the arguments: */
7573 idesc
= ia64_find_opcode (mnemonic
);
7574 *input_line_pointer
= ch
;
7577 as_bad ("Unknown opcode `%s'", mnemonic
);
7581 idesc
= parse_operands (idesc
);
7585 /* Handle the dynamic ops we can handle now: */
7586 if (idesc
->type
== IA64_TYPE_DYN
)
7588 if (strcmp (idesc
->name
, "add") == 0)
7590 if (CURR_SLOT
.opnd
[2].X_op
== O_register
7591 && CURR_SLOT
.opnd
[2].X_add_number
< 4)
7595 idesc
= ia64_find_opcode (mnemonic
);
7597 know (!idesc
->next
);
7600 else if (strcmp (idesc
->name
, "mov") == 0)
7602 enum ia64_opnd opnd1
, opnd2
;
7605 opnd1
= idesc
->operands
[0];
7606 opnd2
= idesc
->operands
[1];
7607 if (opnd1
== IA64_OPND_AR3
)
7609 else if (opnd2
== IA64_OPND_AR3
)
7613 if (CURR_SLOT
.opnd
[rop
].X_op
== O_register
7614 && ar_is_in_integer_unit (CURR_SLOT
.opnd
[rop
].X_add_number
))
7618 idesc
= ia64_find_opcode (mnemonic
);
7619 while (idesc
!= NULL
7620 && (idesc
->operands
[0] != opnd1
7621 || idesc
->operands
[1] != opnd2
))
7622 idesc
= get_next_opcode (idesc
);
7627 if (md
.qp
.X_op
== O_register
)
7628 qp_regno
= md
.qp
.X_add_number
- REG_P
;
7630 flags
= idesc
->flags
;
7632 if ((flags
& IA64_OPCODE_FIRST
) != 0)
7633 insn_group_break (1, 0, 0);
7635 if ((flags
& IA64_OPCODE_NO_PRED
) != 0 && qp_regno
!= 0)
7637 as_bad ("`%s' cannot be predicated", idesc
->name
);
7641 /* build the instruction: */
7642 CURR_SLOT
.qp_regno
= qp_regno
;
7643 CURR_SLOT
.idesc
= idesc
;
7644 as_where (&CURR_SLOT
.src_file
, &CURR_SLOT
.src_line
);
7645 if (debug_type
== DEBUG_DWARF2
)
7646 dwarf2_where (&CURR_SLOT
.debug_line
);
7648 /* Add unwind entry, if there is one. */
7649 if (current_unwind_entry
)
7651 CURR_SLOT
.unwind_record
= current_unwind_entry
;
7652 current_unwind_entry
= NULL
;
7655 /* check for dependency violations */
7659 md
.curr_slot
= (md
.curr_slot
+ 1) % NUM_SLOTS
;
7660 if (++md
.num_slots_in_use
>= NUM_SLOTS
)
7663 if ((flags
& IA64_OPCODE_LAST
) != 0)
7664 insn_group_break (1, 0, 0);
7666 md
.last_text_seg
= now_seg
;
7669 input_line_pointer
= saved_input_line_pointer
;
7672 /* Called when symbol NAME cannot be found in the symbol table.
7673 Should be used for dynamic valued symbols only. */
7675 md_undefined_symbol (name
)
7681 /* Called for any expression that can not be recognized. When the
7682 function is called, `input_line_pointer' will point to the start of
7688 enum pseudo_type pseudo_type
;
7692 switch (*input_line_pointer
)
7695 /* find what relocation pseudo-function we're dealing with: */
7697 ch
= *++input_line_pointer
;
7698 for (i
= 0; i
< NELEMS (pseudo_func
); ++i
)
7699 if (pseudo_func
[i
].name
&& pseudo_func
[i
].name
[0] == ch
)
7701 len
= strlen (pseudo_func
[i
].name
);
7702 if (strncmp (pseudo_func
[i
].name
+ 1,
7703 input_line_pointer
+ 1, len
- 1) == 0
7704 && !is_part_of_name (input_line_pointer
[len
]))
7706 input_line_pointer
+= len
;
7707 pseudo_type
= pseudo_func
[i
].type
;
7711 switch (pseudo_type
)
7713 case PSEUDO_FUNC_RELOC
:
7715 if (*input_line_pointer
!= '(')
7717 as_bad ("Expected '('");
7720 ++input_line_pointer
; /* skip '(' */
7722 if (*input_line_pointer
++ != ')')
7724 as_bad ("Missing ')'");
7727 if (e
->X_op
!= O_symbol
)
7729 if (e
->X_op
!= O_pseudo_fixup
)
7731 as_bad ("Not a symbolic expression");
7734 if (S_GET_VALUE (e
->X_op_symbol
) == FUNC_FPTR_RELATIVE
7735 && i
== FUNC_LT_RELATIVE
)
7736 i
= FUNC_LT_FPTR_RELATIVE
;
7739 as_bad ("Illegal combination of relocation functions");
7743 /* make sure gas doesn't get rid of local symbols that are used
7745 e
->X_op
= O_pseudo_fixup
;
7746 e
->X_op_symbol
= pseudo_func
[i
].u
.sym
;
7749 case PSEUDO_FUNC_CONST
:
7750 e
->X_op
= O_constant
;
7751 e
->X_add_number
= pseudo_func
[i
].u
.ival
;
7755 as_bad ("Unknown pseudo function `%s'", input_line_pointer
- 1);
7761 ++input_line_pointer
;
7763 if (*input_line_pointer
!= ']')
7765 as_bad ("Closing bracket misssing");
7770 if (e
->X_op
!= O_register
)
7771 as_bad ("Register expected as index");
7773 ++input_line_pointer
;
7784 ignore_rest_of_line ();
7787 /* Return 1 if it's OK to adjust a reloc by replacing the symbol with
7788 a section symbol plus some offset. For relocs involving @fptr(),
7789 directives we don't want such adjustments since we need to have the
7790 original symbol's name in the reloc. */
7792 ia64_fix_adjustable (fix
)
7795 /* Prevent all adjustments to global symbols */
7796 if (S_IS_EXTERN (fix
->fx_addsy
) || S_IS_WEAK (fix
->fx_addsy
))
7799 switch (fix
->fx_r_type
)
7801 case BFD_RELOC_IA64_FPTR64I
:
7802 case BFD_RELOC_IA64_FPTR32MSB
:
7803 case BFD_RELOC_IA64_FPTR32LSB
:
7804 case BFD_RELOC_IA64_FPTR64MSB
:
7805 case BFD_RELOC_IA64_FPTR64LSB
:
7806 case BFD_RELOC_IA64_LTOFF_FPTR22
:
7807 case BFD_RELOC_IA64_LTOFF_FPTR64I
:
7817 ia64_force_relocation (fix
)
7820 switch (fix
->fx_r_type
)
7822 case BFD_RELOC_IA64_FPTR64I
:
7823 case BFD_RELOC_IA64_FPTR32MSB
:
7824 case BFD_RELOC_IA64_FPTR32LSB
:
7825 case BFD_RELOC_IA64_FPTR64MSB
:
7826 case BFD_RELOC_IA64_FPTR64LSB
:
7828 case BFD_RELOC_IA64_LTOFF22
:
7829 case BFD_RELOC_IA64_LTOFF64I
:
7830 case BFD_RELOC_IA64_LTOFF_FPTR22
:
7831 case BFD_RELOC_IA64_LTOFF_FPTR64I
:
7832 case BFD_RELOC_IA64_PLTOFF22
:
7833 case BFD_RELOC_IA64_PLTOFF64I
:
7834 case BFD_RELOC_IA64_PLTOFF64MSB
:
7835 case BFD_RELOC_IA64_PLTOFF64LSB
:
7844 /* Decide from what point a pc-relative relocation is relative to,
7845 relative to the pc-relative fixup. Er, relatively speaking. */
7847 ia64_pcrel_from_section (fix
, sec
)
7851 unsigned long off
= fix
->fx_frag
->fr_address
+ fix
->fx_where
;
7853 if (bfd_get_section_flags (stdoutput
, sec
) & SEC_CODE
)
7859 /* This is called whenever some data item (not an instruction) needs a
7860 fixup. We pick the right reloc code depending on the byteorder
7861 currently in effect. */
7863 ia64_cons_fix_new (f
, where
, nbytes
, exp
)
7869 bfd_reloc_code_real_type code
;
7874 /* There are no reloc for 8 and 16 bit quantities, but we allow
7875 them here since they will work fine as long as the expression
7876 is fully defined at the end of the pass over the source file. */
7877 case 1: code
= BFD_RELOC_8
; break;
7878 case 2: code
= BFD_RELOC_16
; break;
7880 if (target_big_endian
)
7881 code
= BFD_RELOC_IA64_DIR32MSB
;
7883 code
= BFD_RELOC_IA64_DIR32LSB
;
7887 if (target_big_endian
)
7888 code
= BFD_RELOC_IA64_DIR64MSB
;
7890 code
= BFD_RELOC_IA64_DIR64LSB
;
7894 as_bad ("Unsupported fixup size %d", nbytes
);
7895 ignore_rest_of_line ();
7898 if (exp
->X_op
== O_pseudo_fixup
)
7901 exp
->X_op
= O_symbol
;
7902 code
= ia64_gen_real_reloc_type (exp
->X_op_symbol
, code
);
7904 fix
= fix_new_exp (f
, where
, nbytes
, exp
, 0, code
);
7905 /* We need to store the byte order in effect in case we're going
7906 to fix an 8 or 16 bit relocation (for which there no real
7907 relocs available). See md_apply_fix(). */
7908 fix
->tc_fix_data
.bigendian
= target_big_endian
;
7911 /* Return the actual relocation we wish to associate with the pseudo
7912 reloc described by SYM and R_TYPE. SYM should be one of the
7913 symbols in the pseudo_func array, or NULL. */
7915 static bfd_reloc_code_real_type
7916 ia64_gen_real_reloc_type (sym
, r_type
)
7918 bfd_reloc_code_real_type r_type
;
7920 bfd_reloc_code_real_type
new = 0;
7927 switch (S_GET_VALUE (sym
))
7929 case FUNC_FPTR_RELATIVE
:
7932 case BFD_RELOC_IA64_IMM64
: new = BFD_RELOC_IA64_FPTR64I
; break;
7933 case BFD_RELOC_IA64_DIR32MSB
: new = BFD_RELOC_IA64_FPTR32MSB
; break;
7934 case BFD_RELOC_IA64_DIR32LSB
: new = BFD_RELOC_IA64_FPTR32LSB
; break;
7935 case BFD_RELOC_IA64_DIR64MSB
: new = BFD_RELOC_IA64_FPTR64MSB
; break;
7936 case BFD_RELOC_IA64_DIR64LSB
: new = BFD_RELOC_IA64_FPTR64LSB
; break;
7941 case FUNC_GP_RELATIVE
:
7944 case BFD_RELOC_IA64_IMM22
: new = BFD_RELOC_IA64_GPREL22
; break;
7945 case BFD_RELOC_IA64_IMM64
: new = BFD_RELOC_IA64_GPREL64I
; break;
7946 case BFD_RELOC_IA64_DIR32MSB
: new = BFD_RELOC_IA64_GPREL32MSB
; break;
7947 case BFD_RELOC_IA64_DIR32LSB
: new = BFD_RELOC_IA64_GPREL32LSB
; break;
7948 case BFD_RELOC_IA64_DIR64MSB
: new = BFD_RELOC_IA64_GPREL64MSB
; break;
7949 case BFD_RELOC_IA64_DIR64LSB
: new = BFD_RELOC_IA64_GPREL64LSB
; break;
7954 case FUNC_LT_RELATIVE
:
7957 case BFD_RELOC_IA64_IMM22
: new = BFD_RELOC_IA64_LTOFF22
; break;
7958 case BFD_RELOC_IA64_IMM64
: new = BFD_RELOC_IA64_LTOFF64I
; break;
7963 case FUNC_PLT_RELATIVE
:
7966 case BFD_RELOC_IA64_IMM22
: new = BFD_RELOC_IA64_PLTOFF22
; break;
7967 case BFD_RELOC_IA64_IMM64
: new = BFD_RELOC_IA64_PLTOFF64I
; break;
7968 case BFD_RELOC_IA64_DIR64MSB
: new = BFD_RELOC_IA64_PLTOFF64MSB
;break;
7969 case BFD_RELOC_IA64_DIR64LSB
: new = BFD_RELOC_IA64_PLTOFF64LSB
;break;
7974 case FUNC_SEC_RELATIVE
:
7977 case BFD_RELOC_IA64_DIR32MSB
: new = BFD_RELOC_IA64_SECREL32MSB
;break;
7978 case BFD_RELOC_IA64_DIR32LSB
: new = BFD_RELOC_IA64_SECREL32LSB
;break;
7979 case BFD_RELOC_IA64_DIR64MSB
: new = BFD_RELOC_IA64_SECREL64MSB
;break;
7980 case BFD_RELOC_IA64_DIR64LSB
: new = BFD_RELOC_IA64_SECREL64LSB
;break;
7985 case FUNC_SEG_RELATIVE
:
7988 case BFD_RELOC_IA64_DIR32MSB
: new = BFD_RELOC_IA64_SEGREL32MSB
;break;
7989 case BFD_RELOC_IA64_DIR32LSB
: new = BFD_RELOC_IA64_SEGREL32LSB
;break;
7990 case BFD_RELOC_IA64_DIR64MSB
: new = BFD_RELOC_IA64_SEGREL64MSB
;break;
7991 case BFD_RELOC_IA64_DIR64LSB
: new = BFD_RELOC_IA64_SEGREL64LSB
;break;
7996 case FUNC_LTV_RELATIVE
:
7999 case BFD_RELOC_IA64_DIR32MSB
: new = BFD_RELOC_IA64_LTV32MSB
; break;
8000 case BFD_RELOC_IA64_DIR32LSB
: new = BFD_RELOC_IA64_LTV32LSB
; break;
8001 case BFD_RELOC_IA64_DIR64MSB
: new = BFD_RELOC_IA64_LTV64MSB
; break;
8002 case BFD_RELOC_IA64_DIR64LSB
: new = BFD_RELOC_IA64_LTV64LSB
; break;
8007 case FUNC_LT_FPTR_RELATIVE
:
8010 case BFD_RELOC_IA64_IMM22
:
8011 new = BFD_RELOC_IA64_LTOFF_FPTR22
; break;
8012 case BFD_RELOC_IA64_IMM64
:
8013 new = BFD_RELOC_IA64_LTOFF_FPTR64I
; break;
8021 /* Hmmmm. Should this ever occur? */
8028 /* Here is where generate the appropriate reloc for pseudo relocation
8031 ia64_validate_fix (fix
)
8034 switch (fix
->fx_r_type
)
8036 case BFD_RELOC_IA64_FPTR64I
:
8037 case BFD_RELOC_IA64_FPTR32MSB
:
8038 case BFD_RELOC_IA64_FPTR64LSB
:
8039 case BFD_RELOC_IA64_LTOFF_FPTR22
:
8040 case BFD_RELOC_IA64_LTOFF_FPTR64I
:
8041 if (fix
->fx_offset
!= 0)
8042 as_bad_where (fix
->fx_file
, fix
->fx_line
,
8043 "No addend allowed in @fptr() relocation");
8053 fix_insn (fix
, odesc
, value
)
8055 const struct ia64_operand
*odesc
;
8058 bfd_vma insn
[3], t0
, t1
, control_bits
;
8063 slot
= fix
->fx_where
& 0x3;
8064 fixpos
= fix
->fx_frag
->fr_literal
+ (fix
->fx_where
- slot
);
8066 /* bundles are always in little-endian byte order */
8067 t0
= bfd_getl64 (fixpos
);
8068 t1
= bfd_getl64 (fixpos
+ 8);
8069 control_bits
= t0
& 0x1f;
8070 insn
[0] = (t0
>> 5) & 0x1ffffffffffLL
;
8071 insn
[1] = ((t0
>> 46) & 0x3ffff) | ((t1
& 0x7fffff) << 18);
8072 insn
[2] = (t1
>> 23) & 0x1ffffffffffLL
;
8074 err
= (*odesc
->insert
) (odesc
, value
, insn
+ slot
);
8077 as_bad_where (fix
->fx_file
, fix
->fx_line
, err
);
8081 t0
= control_bits
| (insn
[0] << 5) | (insn
[1] << 46);
8082 t1
= ((insn
[1] >> 18) & 0x7fffff) | (insn
[2] << 23);
8083 md_number_to_chars (fixpos
+ 0, t0
, 8);
8084 md_number_to_chars (fixpos
+ 8, t1
, 8);
8088 /* Attempt to simplify or even eliminate a fixup. The return value is
8089 ignored; perhaps it was once meaningful, but now it is historical.
8090 To indicate that a fixup has been eliminated, set FIXP->FX_DONE.
8092 If fixp->fx_addsy is non-NULL, we'll have to generate a reloc entry
8095 md_apply_fix3 (fix
, valuep
, seg
)
8101 valueT value
= *valuep
;
8104 fixpos
= fix
->fx_frag
->fr_literal
+ fix
->fx_where
;
8108 switch (fix
->fx_r_type
)
8110 case BFD_RELOC_IA64_DIR32MSB
:
8111 fix
->fx_r_type
= BFD_RELOC_IA64_PCREL32MSB
;
8115 case BFD_RELOC_IA64_DIR32LSB
:
8116 fix
->fx_r_type
= BFD_RELOC_IA64_PCREL32LSB
;
8120 case BFD_RELOC_IA64_DIR64MSB
:
8121 fix
->fx_r_type
= BFD_RELOC_IA64_PCREL64MSB
;
8125 case BFD_RELOC_IA64_DIR64LSB
:
8126 fix
->fx_r_type
= BFD_RELOC_IA64_PCREL64LSB
;
8136 switch (fix
->fx_r_type
)
8139 as_bad_where (fix
->fx_file
, fix
->fx_line
,
8140 "%s must have a constant value",
8141 elf64_ia64_operands
[fix
->tc_fix_data
.opnd
].desc
);
8148 /* ??? This is a hack copied from tc-i386.c to make PCREL relocs
8149 work. There should be a better way to handle this. */
8151 fix
->fx_offset
+= fix
->fx_where
+ fix
->fx_frag
->fr_address
;
8153 else if (fix
->tc_fix_data
.opnd
== IA64_OPND_NIL
)
8155 if (fix
->tc_fix_data
.bigendian
)
8156 number_to_chars_bigendian (fixpos
, value
, fix
->fx_size
);
8158 number_to_chars_littleendian (fixpos
, value
, fix
->fx_size
);
8164 fix_insn (fix
, elf64_ia64_operands
+ fix
->tc_fix_data
.opnd
, value
);
8171 /* Generate the BFD reloc to be stuck in the object file from the
8172 fixup used internally in the assembler. */
8174 tc_gen_reloc (sec
, fixp
)
8180 reloc
= xmalloc (sizeof (*reloc
));
8181 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
8182 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
8183 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
8184 reloc
->addend
= fixp
->fx_offset
;
8185 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
8189 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
8190 "Cannot represent %s relocation in object file",
8191 bfd_get_reloc_code_name (fixp
->fx_r_type
));
8196 /* Turn a string in input_line_pointer into a floating point constant
8197 of type type, and store the appropriate bytes in *lit. The number
8198 of LITTLENUMS emitted is stored in *size. An error message is
8199 returned, or NULL on OK. */
8201 #define MAX_LITTLENUMS 5
8204 md_atof (type
, lit
, size
)
8209 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
8210 LITTLENUM_TYPE
*word
;
8240 return "Bad call to MD_ATOF()";
8242 t
= atof_ieee (input_line_pointer
, type
, words
);
8244 input_line_pointer
= t
;
8245 *size
= prec
* sizeof (LITTLENUM_TYPE
);
8247 for (word
= words
+ prec
- 1; prec
--;)
8249 md_number_to_chars (lit
, (long) (*word
--), sizeof (LITTLENUM_TYPE
));
8250 lit
+= sizeof (LITTLENUM_TYPE
);
8255 /* Round up a section's size to the appropriate boundary. */
8257 md_section_align (seg
, size
)
8261 int align
= bfd_get_section_alignment (stdoutput
, seg
);
8262 valueT mask
= ((valueT
)1 << align
) - 1;
8264 return (size
+ mask
) & ~mask
;
8267 /* Handle ia64 specific semantics of the align directive. */
8270 ia64_md_do_align (n
, fill
, len
, max
)
8276 /* Fill any pending bundle with nops. */
8277 if (bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
)
8278 ia64_flush_insns ();
8280 /* When we align code in a text section, emit a bundle of 3 nops instead of
8281 zero bytes. We can only do this if a multiple of 16 bytes was requested.
8282 N is log base 2 of the requested alignment. */
8284 && bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
8287 /* Use mfi bundle of nops with no stop bits. */
8288 static const unsigned char be_nop
[]
8289 = { 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
8290 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c};
8291 static const unsigned char le_nop
[]
8292 = { 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
8293 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00};
8295 /* Make sure we are on a 16-byte boundary, in case someone has been
8296 putting data into a text section. */
8297 frag_align (4, 0, 0);
8299 if (target_big_endian
)
8300 frag_align_pattern (n
, be_nop
, 16, max
);
8302 frag_align_pattern (n
, le_nop
, 16, max
);