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 { "natval", 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 } },
462 /* 41-bit nop opcodes (one per unit): */
463 static const bfd_vma nop
[IA64_NUM_UNITS
] =
465 0x0000000000LL
, /* NIL => break 0 */
466 0x0008000000LL
, /* I-unit nop */
467 0x0008000000LL
, /* M-unit nop */
468 0x4000000000LL
, /* B-unit nop */
469 0x0008000000LL
, /* F-unit nop */
470 0x0008000000LL
, /* L-"unit" nop */
471 0x0008000000LL
, /* X-unit nop */
474 /* Can't be `const' as it's passed to input routines (which have the
475 habit of setting temporary sentinels. */
476 static char special_section_name
[][20] =
478 {".bss"}, {".sbss"}, {".sdata"}, {".rodata"}, {".comment"},
479 {".IA_64.unwind"}, {".IA_64.unwind_info"}
482 /* The best template for a particular sequence of up to three
484 #define N IA64_NUM_TYPES
485 static unsigned char best_template
[N
][N
][N
];
488 /* Resource dependencies currently in effect */
490 int depind
; /* dependency index */
491 const struct ia64_dependency
*dependency
; /* actual dependency */
492 unsigned specific
:1, /* is this a specific bit/regno? */
493 link_to_qp_branch
:1; /* will a branch on the same QP clear it?*/
494 int index
; /* specific regno/bit within dependency */
495 int note
; /* optional qualifying note (0 if none) */
499 int insn_srlz
; /* current insn serialization state */
500 int data_srlz
; /* current data serialization state */
501 int qp_regno
; /* qualifying predicate for this usage */
502 char *file
; /* what file marked this dependency */
503 int line
; /* what line marked this dependency */
504 struct mem_offset mem_offset
; /* optional memory offset hint */
505 int path
; /* corresponding code entry index */
507 static int regdepslen
= 0;
508 static int regdepstotlen
= 0;
509 static const char *dv_mode
[] = { "RAW", "WAW", "WAR" };
510 static const char *dv_sem
[] = { "none", "implied", "impliedf",
511 "data", "instr", "specific", "other" };
513 /* Current state of PR mutexation */
514 static struct qpmutex
{
517 } *qp_mutexes
= NULL
; /* QP mutex bitmasks */
518 static int qp_mutexeslen
= 0;
519 static int qp_mutexestotlen
= 0;
520 static valueT qp_safe_across_calls
= 0;
522 /* Current state of PR implications */
523 static struct qp_imply
{
526 unsigned p2_branched
:1;
528 } *qp_implies
= NULL
;
529 static int qp_implieslen
= 0;
530 static int qp_impliestotlen
= 0;
532 /* Keep track of static GR values so that indirect register usage can
533 sometimes be tracked. */
538 } gr_values
[128] = {{ 1, 0 }};
540 /* These are the routines required to output the various types of
543 typedef struct unw_rec_list
{
545 unsigned long slot_number
;
546 struct unw_rec_list
*next
;
549 #define SLOT_NUM_NOT_SET -1
551 /* TRUE if processing unwind directives in a prologue region. */
552 static int unwind_prologue
= 0;
554 /* Maintain a list of unwind entries for the current function. */
555 static unw_rec_list
*unwind_list
= 0;
556 static unw_rec_list
*unwind_tail
= 0;
558 /* Any unwind entires that should be attached to the current
559 slot that an insn is being constructed for. */
560 static unw_rec_list
*current_unwind_entry
= 0;
562 /* These are used to create the unwind table entry for this function. */
563 static symbolS
*proc_start
= 0;
564 static symbolS
*proc_end
= 0;
565 static symbolS
*unwind_info
= 0;
566 static symbolS
*personality_routine
= 0;
568 typedef void (*vbyte_func
) PARAMS ((int, char *, char *));
570 /* Forward delarations: */
571 static int ar_is_in_integer_unit
PARAMS ((int regnum
));
572 static void set_section
PARAMS ((char *name
));
573 static unsigned int set_regstack
PARAMS ((unsigned int, unsigned int,
574 unsigned int, unsigned int));
575 static void dot_radix
PARAMS ((int));
576 static void dot_special_section
PARAMS ((int));
577 static void dot_proc
PARAMS ((int));
578 static void dot_fframe
PARAMS ((int));
579 static void dot_vframe
PARAMS ((int));
580 static void dot_save
PARAMS ((int));
581 static void dot_restore
PARAMS ((int));
582 static void dot_handlerdata
PARAMS ((int));
583 static void dot_unwentry
PARAMS ((int));
584 static void dot_altrp
PARAMS ((int));
585 static void dot_savesp
PARAMS ((int));
586 static void dot_savepsp
PARAMS ((int));
587 static void dot_saveg
PARAMS ((int));
588 static void dot_savef
PARAMS ((int));
589 static void dot_saveb
PARAMS ((int));
590 static void dot_savegf
PARAMS ((int));
591 static void dot_spill
PARAMS ((int));
592 static void dot_unwabi
PARAMS ((int));
593 static void dot_personality
PARAMS ((int));
594 static void dot_body
PARAMS ((int));
595 static void dot_prologue
PARAMS ((int));
596 static void dot_endp
PARAMS ((int));
597 static void dot_template
PARAMS ((int));
598 static void dot_regstk
PARAMS ((int));
599 static void dot_rot
PARAMS ((int));
600 static void dot_byteorder
PARAMS ((int));
601 static void dot_psr
PARAMS ((int));
602 static void dot_alias
PARAMS ((int));
603 static void dot_ln
PARAMS ((int));
604 static char *parse_section_name
PARAMS ((void));
605 static void dot_xdata
PARAMS ((int));
606 static void stmt_float_cons
PARAMS ((int));
607 static void stmt_cons_ua
PARAMS ((int));
608 static void dot_xfloat_cons
PARAMS ((int));
609 static void dot_xstringer
PARAMS ((int));
610 static void dot_xdata_ua
PARAMS ((int));
611 static void dot_xfloat_cons_ua
PARAMS ((int));
612 static void dot_pred_rel
PARAMS ((int));
613 static void dot_reg_val
PARAMS ((int));
614 static void dot_dv_mode
PARAMS ((int));
615 static void dot_entry
PARAMS ((int));
616 static void dot_mem_offset
PARAMS ((int));
617 static symbolS
* declare_register
PARAMS ((const char *name
, int regnum
));
618 static void declare_register_set
PARAMS ((const char *, int, int));
619 static unsigned int operand_width
PARAMS ((enum ia64_opnd
));
620 static int operand_match
PARAMS ((const struct ia64_opcode
*idesc
,
621 int index
, expressionS
*e
));
622 static int parse_operand
PARAMS ((expressionS
*e
));
623 static struct ia64_opcode
* parse_operands
PARAMS ((struct ia64_opcode
*));
624 static void build_insn
PARAMS ((struct slot
*, bfd_vma
*));
625 static void emit_one_bundle
PARAMS ((void));
626 static void fix_insn
PARAMS ((fixS
*, const struct ia64_operand
*, valueT
));
627 static bfd_reloc_code_real_type ia64_gen_real_reloc_type
PARAMS ((struct symbol
*sym
,
628 bfd_reloc_code_real_type r_type
));
629 static void insn_group_break
PARAMS ((int, int, int));
630 static void add_qp_mutex
PARAMS((valueT mask
));
631 static void add_qp_imply
PARAMS((int p1
, int p2
));
632 static void clear_qp_branch_flag
PARAMS((valueT mask
));
633 static void clear_qp_mutex
PARAMS((valueT mask
));
634 static void clear_qp_implies
PARAMS((valueT p1_mask
, valueT p2_mask
));
635 static void clear_register_values
PARAMS ((void));
636 static void print_dependency
PARAMS ((const char *action
, int depind
));
637 static int is_conditional_branch
PARAMS ((struct ia64_opcode
*));
638 static int is_interruption_or_rfi
PARAMS ((struct ia64_opcode
*));
639 static int check_dv
PARAMS((struct ia64_opcode
*idesc
));
640 static void check_dependencies
PARAMS((struct ia64_opcode
*));
641 static void mark_resources
PARAMS((struct ia64_opcode
*));
642 static void update_dependencies
PARAMS((struct ia64_opcode
*));
643 static void note_register_values
PARAMS((struct ia64_opcode
*));
644 static void output_R3_format
PARAMS ((vbyte_func
, unw_record_type
, unsigned long));
645 static void output_B3_format
PARAMS ((vbyte_func
, unsigned long, unsigned long));
646 static void output_B4_format
PARAMS ((vbyte_func
, unw_record_type
, unsigned long));
648 /* Determine if application register REGNUM resides in the integer
649 unit (as opposed to the memory unit). */
651 ar_is_in_integer_unit (reg
)
656 return (reg
== 64 /* pfs */
657 || reg
== 65 /* lc */
658 || reg
== 66 /* ec */
659 /* ??? ias accepts and puts these in the integer unit. */
660 || (reg
>= 112 && reg
<= 127));
663 /* Switch to section NAME and create section if necessary. It's
664 rather ugly that we have to manipulate input_line_pointer but I
665 don't see any other way to accomplish the same thing without
666 changing obj-elf.c (which may be the Right Thing, in the end). */
671 char *saved_input_line_pointer
;
673 saved_input_line_pointer
= input_line_pointer
;
674 input_line_pointer
= name
;
676 input_line_pointer
= saved_input_line_pointer
;
679 /* Map SHF_IA_64_SHORT to SEC_SMALL_DATA. */
682 ia64_elf_section_flags (flags
, attr
, type
)
686 if (attr
& SHF_IA_64_SHORT
)
687 flags
|= SEC_SMALL_DATA
;
692 set_regstack (ins
, locs
, outs
, rots
)
693 unsigned int ins
, locs
, outs
, rots
;
695 unsigned int sof
; /* size of frame */
697 sof
= ins
+ locs
+ outs
;
700 as_bad ("Size of frame exceeds maximum of 96 registers");
705 as_warn ("Size of rotating registers exceeds frame size");
708 md
.in
.base
= REG_GR
+ 32;
709 md
.loc
.base
= md
.in
.base
+ ins
;
710 md
.out
.base
= md
.loc
.base
+ locs
;
712 md
.in
.num_regs
= ins
;
713 md
.loc
.num_regs
= locs
;
714 md
.out
.num_regs
= outs
;
715 md
.rot
.num_regs
= rots
;
722 struct label_fix
*lfix
;
724 subsegT saved_subseg
;
726 if (!md
.last_text_seg
)
730 saved_subseg
= now_subseg
;
732 subseg_set (md
.last_text_seg
, 0);
734 while (md
.num_slots_in_use
> 0)
735 emit_one_bundle (); /* force out queued instructions */
737 /* In case there are labels following the last instruction, resolve
739 for (lfix
= CURR_SLOT
.label_fixups
; lfix
; lfix
= lfix
->next
)
741 S_SET_VALUE (lfix
->sym
, frag_now_fix ());
742 symbol_set_frag (lfix
->sym
, frag_now
);
744 CURR_SLOT
.label_fixups
= 0;
746 subseg_set (saved_seg
, saved_subseg
);
750 ia64_do_align (nbytes
)
753 char *saved_input_line_pointer
= input_line_pointer
;
755 input_line_pointer
= "";
756 s_align_bytes (nbytes
);
757 input_line_pointer
= saved_input_line_pointer
;
761 ia64_cons_align (nbytes
)
766 char *saved_input_line_pointer
= input_line_pointer
;
767 input_line_pointer
= "";
768 s_align_bytes (nbytes
);
769 input_line_pointer
= saved_input_line_pointer
;
773 /* Output COUNT bytes to a memory location. */
774 static unsigned char *vbyte_mem_ptr
= NULL
;
777 output_vbyte_mem (count
, ptr
, comment
)
783 if (vbyte_mem_ptr
== NULL
)
788 for (x
= 0; x
< count
; x
++)
789 *(vbyte_mem_ptr
++) = ptr
[x
];
792 /* Count the number of bytes required for records. */
793 static int vbyte_count
= 0;
795 count_output (count
, ptr
, comment
)
800 vbyte_count
+= count
;
804 output_R1_format (f
, rtype
, rlen
)
806 unw_record_type rtype
;
813 output_R3_format (f
, rtype
, rlen
);
816 if (rtype
== prologue
)
822 as_bad ("record type is not valid");
824 byte
= UNW_R1
| (r
<< 5) | (rlen
& 0x1f);
825 (*f
) (1, &byte
, NULL
);
829 output_R2_format (f
, mask
, grsave
, rlen
)
836 mask
= (mask
& 0x0f);
837 grsave
= (grsave
& 0x7f);
839 bytes
[0] = (UNW_R2
| (mask
>> 1));
840 bytes
[1] = (((mask
& 0x01) << 7) | grsave
);
841 count
+= output_leb128 (bytes
+ 2, rlen
, 0);
842 (*f
) (count
, bytes
, NULL
);
846 output_R3_format (f
, rtype
, rlen
)
848 unw_record_type rtype
;
855 output_R1_format (f
, rtype
, rlen
);
858 if (rtype
== prologue
)
864 as_bad ("record type is not valid");
865 bytes
[0] = (UNW_R3
| r
);
866 count
= output_leb128 (bytes
+ 1, rlen
, 0);
867 (*f
) (count
+ 1, bytes
, NULL
);
871 output_P1_format (f
, brmask
)
876 byte
= UNW_P1
| (brmask
& 0x1f);
877 (*f
) (1, &byte
, NULL
);
881 output_P2_format (f
, brmask
, gr
)
887 brmask
= (brmask
& 0x1f);
888 bytes
[0] = UNW_P2
| (brmask
>> 1);
889 bytes
[1] = (((brmask
& 1) << 7) | gr
);
890 (*f
) (2, bytes
, NULL
);
894 output_P3_format (f
, rtype
, reg
)
896 unw_record_type rtype
;
941 as_bad ("Invalid record type for P3 format.");
943 bytes
[0] = (UNW_P3
| (r
>> 1));
944 bytes
[1] = (((r
& 1) << 7) | reg
);
945 (*f
) (2, bytes
, NULL
);
950 output_P4_format (f
, count
, imask
)
956 bytes
= alloca (count
+ 1);
958 memcpy (bytes
+ 1, imask
, count
);
959 (*f
) (count
+ 1, bytes
, NULL
);
963 output_P5_format (f
, grmask
, frmask
)
966 unsigned long frmask
;
969 grmask
= (grmask
& 0x0f);
972 bytes
[1] = ((grmask
<< 4) | ((frmask
& 0x000f0000) >> 16));
973 bytes
[2] = ((frmask
& 0x0000ff00) >> 8);
974 bytes
[3] = (frmask
& 0x000000ff);
975 (*f
) (4, bytes
, NULL
);
979 output_P6_format (f
, rtype
, rmask
)
981 unw_record_type rtype
;
992 as_bad ("Invalid record type for format P6");
993 byte
= (UNW_P6
| (r
<< 4) | (rmask
& 0x0f));
994 (*f
) (1, &byte
, NULL
);
998 output_P7_format (f
, rtype
, w1
, w2
)
1000 unw_record_type rtype
;
1007 count
+= output_leb128 (bytes
+ 1, w1
, 0);
1012 count
+= output_leb128 (bytes
+ count
, w2
, 0);
1060 bytes
[0] = (UNW_P7
| r
);
1061 (*f
) (count
, bytes
, NULL
);
1065 output_P8_format (f
, rtype
, t
)
1067 unw_record_type rtype
;
1106 case bspstore_psprel
:
1109 case bspstore_sprel
:
1121 case priunat_when_gr
:
1124 case priunat_psprel
:
1130 case priunat_when_mem
:
1135 count
+= output_leb128 (bytes
+ 2, t
, 0);
1136 (*f
) (count
, bytes
, NULL
);
1140 output_P9_format (f
, grmask
, gr
)
1147 bytes
[1] = (grmask
& 0x0f);
1148 bytes
[2] = (gr
& 0x7f);
1149 (*f
) (3, bytes
, NULL
);
1153 output_P10_format (f
, abi
, context
)
1160 bytes
[1] = (abi
& 0xff);
1161 bytes
[2] = (context
& 0xff);
1162 (*f
) (3, bytes
, NULL
);
1166 output_B1_format (f
, rtype
, label
)
1168 unw_record_type rtype
;
1169 unsigned long label
;
1175 output_B4_format (f
, rtype
, label
);
1178 if (rtype
== label_state
)
1181 if (rtype
== copy_state
)
1184 as_bad ("Invalid record type for format B1");
1186 byte
= (UNW_B1
| (r
<< 5) | (label
& 0x1f));
1187 (*f
) (1, &byte
, NULL
);
1191 output_B2_format (f
, ecount
, t
)
1193 unsigned long ecount
;
1200 output_B3_format (f
, ecount
, t
);
1203 bytes
[0] = (UNW_B2
| (ecount
& 0x1f));
1204 count
+= output_leb128 (bytes
+ 1, t
, 0);
1205 (*f
) (count
, bytes
, NULL
);
1209 output_B3_format (f
, ecount
, t
)
1211 unsigned long ecount
;
1218 output_B2_format (f
, ecount
, t
);
1222 count
+= output_leb128 (bytes
+ 1, t
, 0);
1223 count
+= output_leb128 (bytes
+ count
, ecount
, 0);
1224 (*f
) (count
, bytes
, NULL
);
1228 output_B4_format (f
, rtype
, label
)
1230 unw_record_type rtype
;
1231 unsigned long label
;
1238 output_B1_format (f
, rtype
, label
);
1241 if (rtype
== label_state
)
1244 if (rtype
== copy_state
)
1247 as_bad ("Invalid record type for format B1");
1249 bytes
[0] = (UNW_B4
| (r
<< 3));
1250 count
+= output_leb128 (bytes
+ 1, label
, 0);
1251 (*f
) (count
, bytes
, NULL
);
1255 format_a_b_reg (a
, b
, reg
)
1263 ret
= (a
<< 6) | (a
<< 5) | reg
;
1268 output_X1_format (f
, rtype
, a
, b
, reg
, t
, w1
)
1270 unw_record_type rtype
;
1279 if (rtype
== spill_psprel
)
1282 if (rtype
= spill_sprel
)
1285 as_bad ("Invalid record type for format X1");
1286 bytes
[1] = ((r
<< 7) | format_a_b_reg (a
, b
, reg
));
1287 count
+= output_leb128 (bytes
+ 2, t
, 0);
1288 count
+= output_leb128 (bytes
+ count
, w1
, 0);
1289 (*f
) (count
, bytes
, NULL
);
1293 output_X2_format (f
, a
, b
, reg
, x
, y
, treg
, t
)
1303 bytes
[1] = (((x
& 1) << 7) | format_a_b_reg (a
, b
, reg
));
1304 bytes
[2] = (((y
& 1) << 7) | (treg
& 0x7f));
1305 count
+= output_leb128 (bytes
+ 3, t
, 0);
1306 (*f
) (count
, bytes
, NULL
);
1310 output_X3_format (f
, rtype
, qp
, a
, b
, reg
, t
, w1
)
1312 unw_record_type rtype
;
1322 if (rtype
== spill_psprel_p
)
1325 if (rtype
= spill_sprel_p
)
1328 as_bad ("Invalid record type for format X1");
1329 bytes
[1] = ((r
<< 7) | (qp
& 0x3f));
1330 bytes
[2] = format_a_b_reg (a
, b
, reg
);
1331 count
+= output_leb128 (bytes
+ 3, t
, 0);
1332 count
+= output_leb128 (bytes
+ count
, w1
, 0);
1333 (*f
) (count
, bytes
, NULL
);
1337 output_X4_format (f
, qp
, a
, b
, reg
, x
, y
, treg
, t
)
1348 bytes
[1] = (qp
& 0x3f);
1349 bytes
[2] = (((x
& 1) << 7) | format_a_b_reg (a
, b
, reg
));
1350 bytes
[3] = (((y
& 1) << 7) | (treg
& 0x7f));
1351 count
+= output_leb128 (bytes
+ 4, t
, 0);
1352 (*f
) (count
, bytes
, NULL
);
1355 /* This function allocates a record list structure, and initializes fields. */
1356 static unw_rec_list
*
1357 alloc_record (unw_record_type t
)
1360 ptr
= xmalloc (sizeof (*ptr
));
1362 ptr
->slot_number
= SLOT_NUM_NOT_SET
;
1367 /* This function frees a record list structure. */
1369 free_record (unw_rec_list
*ptr
)
1374 /* This function frees an entire list of record structures. */
1376 free_list_records (unw_rec_list
*first
)
1379 for (ptr
= first
; ptr
!= NULL
; )
1381 unw_rec_list
*tmp
= ptr
;
1387 static unw_rec_list
*
1390 unw_rec_list
*ptr
= alloc_record (prologue
);
1394 static unw_rec_list
*
1395 output_prologue_gr (saved_mask
, reg
)
1396 unsigned int saved_mask
;
1399 unw_rec_list
*ptr
= alloc_record (prologue_gr
);
1400 ptr
->r
.record
.r
.mask
= saved_mask
;
1401 ptr
->r
.record
.r
.grsave
= reg
;
1405 static unw_rec_list
*
1408 unw_rec_list
*ptr
= alloc_record (body
);
1412 static unw_rec_list
*
1413 output_mem_stack_f (size
)
1416 unw_rec_list
*ptr
= alloc_record (mem_stack_f
);
1417 ptr
->r
.record
.p
.size
= size
;
1421 static unw_rec_list
*
1422 output_mem_stack_v ()
1424 unw_rec_list
*ptr
= alloc_record (mem_stack_v
);
1428 static unw_rec_list
*
1432 unw_rec_list
*ptr
= alloc_record (psp_gr
);
1433 ptr
->r
.record
.p
.gr
= gr
;
1437 static unw_rec_list
*
1438 output_psp_sprel (offset
)
1439 unsigned int offset
;
1441 unw_rec_list
*ptr
= alloc_record (psp_sprel
);
1442 ptr
->r
.record
.p
.spoff
= offset
;
1446 static unw_rec_list
*
1449 unw_rec_list
*ptr
= alloc_record (rp_when
);
1453 static unw_rec_list
*
1457 unw_rec_list
*ptr
= alloc_record (rp_gr
);
1458 ptr
->r
.record
.p
.gr
= gr
;
1462 static unw_rec_list
*
1466 unw_rec_list
*ptr
= alloc_record (rp_br
);
1467 ptr
->r
.record
.p
.br
= br
;
1471 static unw_rec_list
*
1472 output_rp_psprel (offset
)
1473 unsigned int offset
;
1475 unw_rec_list
*ptr
= alloc_record (rp_psprel
);
1476 ptr
->r
.record
.p
.pspoff
= offset
;
1480 static unw_rec_list
*
1481 output_rp_sprel (offset
)
1482 unsigned int offset
;
1484 unw_rec_list
*ptr
= alloc_record (rp_sprel
);
1485 ptr
->r
.record
.p
.spoff
= offset
;
1489 static unw_rec_list
*
1492 unw_rec_list
*ptr
= alloc_record (pfs_when
);
1496 static unw_rec_list
*
1500 unw_rec_list
*ptr
= alloc_record (pfs_gr
);
1501 ptr
->r
.record
.p
.gr
= gr
;
1505 static unw_rec_list
*
1506 output_pfs_psprel (offset
)
1507 unsigned int offset
;
1509 unw_rec_list
*ptr
= alloc_record (pfs_psprel
);
1510 ptr
->r
.record
.p
.pspoff
= offset
;
1514 static unw_rec_list
*
1515 output_pfs_sprel (offset
)
1516 unsigned int offset
;
1518 unw_rec_list
*ptr
= alloc_record (pfs_sprel
);
1519 ptr
->r
.record
.p
.spoff
= offset
;
1523 static unw_rec_list
*
1524 output_preds_when ()
1526 unw_rec_list
*ptr
= alloc_record (preds_when
);
1530 static unw_rec_list
*
1531 output_preds_gr (gr
)
1534 unw_rec_list
*ptr
= alloc_record (preds_gr
);
1535 ptr
->r
.record
.p
.gr
= gr
;
1539 static unw_rec_list
*
1540 output_preds_psprel (offset
)
1541 unsigned int offset
;
1543 unw_rec_list
*ptr
= alloc_record (preds_psprel
);
1544 ptr
->r
.record
.p
.pspoff
= offset
;
1548 static unw_rec_list
*
1549 output_preds_sprel (offset
)
1550 unsigned int offset
;
1552 unw_rec_list
*ptr
= alloc_record (preds_sprel
);
1553 ptr
->r
.record
.p
.spoff
= offset
;
1557 static unw_rec_list
*
1558 output_fr_mem (mask
)
1561 unw_rec_list
*ptr
= alloc_record (fr_mem
);
1562 ptr
->r
.record
.p
.rmask
= mask
;
1566 static unw_rec_list
*
1567 output_frgr_mem (gr_mask
, fr_mask
)
1568 unsigned int gr_mask
;
1569 unsigned int fr_mask
;
1571 unw_rec_list
*ptr
= alloc_record (frgr_mem
);
1572 ptr
->r
.record
.p
.grmask
= gr_mask
;
1573 ptr
->r
.record
.p
.frmask
= fr_mask
;
1577 static unw_rec_list
*
1578 output_gr_gr (mask
, reg
)
1582 unw_rec_list
*ptr
= alloc_record (gr_gr
);
1583 ptr
->r
.record
.p
.grmask
= mask
;
1584 ptr
->r
.record
.p
.gr
= reg
;
1588 static unw_rec_list
*
1589 output_gr_mem (mask
)
1592 unw_rec_list
*ptr
= alloc_record (gr_mem
);
1593 ptr
->r
.record
.p
.rmask
= mask
;
1597 static unw_rec_list
*
1598 output_br_mem (unsigned int mask
)
1600 unw_rec_list
*ptr
= alloc_record (br_mem
);
1601 ptr
->r
.record
.p
.brmask
= mask
;
1605 static unw_rec_list
*
1606 output_br_gr (save_mask
, reg
)
1607 unsigned int save_mask
;
1610 unw_rec_list
*ptr
= alloc_record (br_gr
);
1611 ptr
->r
.record
.p
.brmask
= save_mask
;
1612 ptr
->r
.record
.p
.gr
= reg
;
1616 static unw_rec_list
*
1617 output_spill_base (offset
)
1618 unsigned int offset
;
1620 unw_rec_list
*ptr
= alloc_record (spill_base
);
1621 ptr
->r
.record
.p
.pspoff
= offset
;
1625 static unw_rec_list
*
1626 output_spill_mask ()
1628 /* TODO - how to implement this record.... I guess GAS could fill in the
1629 correct fields from the record list and construct one of these
1630 after the symbols have been resolved and we know how big the
1631 region is. This could be done in fixup_unw_records. */
1632 unw_rec_list
*ptr
= NULL
;
1636 static unw_rec_list
*
1639 unw_rec_list
*ptr
= alloc_record (unat_when
);
1643 static unw_rec_list
*
1647 unw_rec_list
*ptr
= alloc_record (unat_gr
);
1648 ptr
->r
.record
.p
.gr
= gr
;
1652 static unw_rec_list
*
1653 output_unat_psprel (offset
)
1654 unsigned int offset
;
1656 unw_rec_list
*ptr
= alloc_record (unat_psprel
);
1657 ptr
->r
.record
.p
.pspoff
= offset
;
1661 static unw_rec_list
*
1662 output_unat_sprel (offset
)
1663 unsigned int offset
;
1665 unw_rec_list
*ptr
= alloc_record (unat_sprel
);
1666 ptr
->r
.record
.p
.spoff
= offset
;
1670 static unw_rec_list
*
1673 unw_rec_list
*ptr
= alloc_record (lc_when
);
1677 static unw_rec_list
*
1681 unw_rec_list
*ptr
= alloc_record (lc_gr
);
1682 ptr
->r
.record
.p
.gr
= gr
;
1686 static unw_rec_list
*
1687 output_lc_psprel (offset
)
1688 unsigned int offset
;
1690 unw_rec_list
*ptr
= alloc_record (lc_psprel
);
1691 ptr
->r
.record
.p
.pspoff
= offset
;
1695 static unw_rec_list
*
1696 output_lc_sprel (offset
)
1697 unsigned int offset
;
1699 unw_rec_list
*ptr
= alloc_record (lc_sprel
);
1700 ptr
->r
.record
.p
.spoff
= offset
;
1704 static unw_rec_list
*
1707 unw_rec_list
*ptr
= alloc_record (fpsr_when
);
1711 static unw_rec_list
*
1715 unw_rec_list
*ptr
= alloc_record (fpsr_gr
);
1716 ptr
->r
.record
.p
.gr
= gr
;
1720 static unw_rec_list
*
1721 output_fpsr_psprel (offset
)
1722 unsigned int offset
;
1724 unw_rec_list
*ptr
= alloc_record (fpsr_psprel
);
1725 ptr
->r
.record
.p
.pspoff
= offset
;
1729 static unw_rec_list
*
1730 output_fpsr_sprel (offset
)
1731 unsigned int offset
;
1733 unw_rec_list
*ptr
= alloc_record (fpsr_sprel
);
1734 ptr
->r
.record
.p
.spoff
= offset
;
1738 static unw_rec_list
*
1739 output_priunat_when_gr ()
1741 unw_rec_list
*ptr
= alloc_record (priunat_when_gr
);
1745 static unw_rec_list
*
1746 output_priunat_when_mem ()
1748 unw_rec_list
*ptr
= alloc_record (priunat_when_mem
);
1752 static unw_rec_list
*
1753 output_priunat_gr (gr
)
1756 unw_rec_list
*ptr
= alloc_record (priunat_gr
);
1757 ptr
->r
.record
.p
.gr
= gr
;
1761 static unw_rec_list
*
1762 output_priunat_psprel (offset
)
1763 unsigned int offset
;
1765 unw_rec_list
*ptr
= alloc_record (priunat_psprel
);
1766 ptr
->r
.record
.p
.pspoff
= offset
;
1770 static unw_rec_list
*
1771 output_priunat_sprel (offset
)
1772 unsigned int offset
;
1774 unw_rec_list
*ptr
= alloc_record (priunat_sprel
);
1775 ptr
->r
.record
.p
.spoff
= offset
;
1779 static unw_rec_list
*
1782 unw_rec_list
*ptr
= alloc_record (bsp_when
);
1786 static unw_rec_list
*
1790 unw_rec_list
*ptr
= alloc_record (bsp_gr
);
1791 ptr
->r
.record
.p
.gr
= gr
;
1795 static unw_rec_list
*
1796 output_bsp_psprel (offset
)
1797 unsigned int offset
;
1799 unw_rec_list
*ptr
= alloc_record (bsp_psprel
);
1800 ptr
->r
.record
.p
.pspoff
= offset
;
1804 static unw_rec_list
*
1805 output_bsp_sprel (offset
)
1806 unsigned int offset
;
1808 unw_rec_list
*ptr
= alloc_record (bsp_sprel
);
1809 ptr
->r
.record
.p
.spoff
= offset
;
1813 static unw_rec_list
*
1814 output_bspstore_when ()
1816 unw_rec_list
*ptr
= alloc_record (bspstore_when
);
1820 static unw_rec_list
*
1821 output_bspstore_gr (gr
)
1824 unw_rec_list
*ptr
= alloc_record (bspstore_gr
);
1825 ptr
->r
.record
.p
.gr
= gr
;
1829 static unw_rec_list
*
1830 output_bspstore_psprel (offset
)
1831 unsigned int offset
;
1833 unw_rec_list
*ptr
= alloc_record (bspstore_psprel
);
1834 ptr
->r
.record
.p
.pspoff
= offset
;
1838 static unw_rec_list
*
1839 output_bspstore_sprel (offset
)
1840 unsigned int offset
;
1842 unw_rec_list
*ptr
= alloc_record (bspstore_sprel
);
1843 ptr
->r
.record
.p
.spoff
= offset
;
1847 static unw_rec_list
*
1850 unw_rec_list
*ptr
= alloc_record (rnat_when
);
1854 static unw_rec_list
*
1858 unw_rec_list
*ptr
= alloc_record (rnat_gr
);
1859 ptr
->r
.record
.p
.gr
= gr
;
1863 static unw_rec_list
*
1864 output_rnat_psprel (offset
)
1865 unsigned int offset
;
1867 unw_rec_list
*ptr
= alloc_record (rnat_psprel
);
1868 ptr
->r
.record
.p
.pspoff
= offset
;
1872 static unw_rec_list
*
1873 output_rnat_sprel (offset
)
1874 unsigned int offset
;
1876 unw_rec_list
*ptr
= alloc_record (rnat_sprel
);
1877 ptr
->r
.record
.p
.spoff
= offset
;
1881 static unw_rec_list
*
1884 unw_rec_list
*ptr
= NULL
;
1888 static unw_rec_list
*
1889 output_label_state ()
1891 unw_rec_list
*ptr
= NULL
;
1895 static unw_rec_list
*
1896 output_copy_state ()
1898 unw_rec_list
*ptr
= NULL
;
1902 static unw_rec_list
*
1903 output_spill_psprel (reg
, offset
)
1905 unsigned int offset
;
1907 unw_rec_list
*ptr
= alloc_record (spill_psprel
);
1908 ptr
->r
.record
.x
.reg
= reg
;
1909 ptr
->r
.record
.x
.pspoff
= offset
;
1913 static unw_rec_list
*
1914 output_spill_sprel (reg
, offset
)
1916 unsigned int offset
;
1918 unw_rec_list
*ptr
= alloc_record (spill_sprel
);
1919 ptr
->r
.record
.x
.reg
= reg
;
1920 ptr
->r
.record
.x
.spoff
= offset
;
1924 static unw_rec_list
*
1925 output_spill_psprel_p (reg
, offset
, predicate
)
1927 unsigned int offset
;
1928 unsigned int predicate
;
1930 unw_rec_list
*ptr
= alloc_record (spill_psprel_p
);
1931 ptr
->r
.record
.x
.reg
= reg
;
1932 ptr
->r
.record
.x
.pspoff
= offset
;
1933 ptr
->r
.record
.x
.qp
= predicate
;
1937 static unw_rec_list
*
1938 output_spill_sprel_p (reg
, offset
, predicate
)
1940 unsigned int offset
;
1941 unsigned int predicate
;
1943 unw_rec_list
*ptr
= alloc_record (spill_sprel_p
);
1944 ptr
->r
.record
.x
.reg
= reg
;
1945 ptr
->r
.record
.x
.spoff
= offset
;
1946 ptr
->r
.record
.x
.qp
= predicate
;
1950 static unw_rec_list
*
1951 output_spill_reg (reg
, targ_reg
, xy
)
1953 unsigned int targ_reg
;
1956 unw_rec_list
*ptr
= alloc_record (spill_reg
);
1957 ptr
->r
.record
.x
.reg
= reg
;
1958 ptr
->r
.record
.x
.treg
= targ_reg
;
1959 ptr
->r
.record
.x
.xy
= xy
;
1963 static unw_rec_list
*
1964 output_spill_reg_p (reg
, targ_reg
, xy
, predicate
)
1966 unsigned int targ_reg
;
1968 unsigned int predicate
;
1970 unw_rec_list
*ptr
= alloc_record (spill_reg_p
);
1971 ptr
->r
.record
.x
.reg
= reg
;
1972 ptr
->r
.record
.x
.treg
= targ_reg
;
1973 ptr
->r
.record
.x
.xy
= xy
;
1974 ptr
->r
.record
.x
.qp
= predicate
;
1978 /* Given a unw_rec_list process the correct format with the
1979 specified function. */
1981 process_one_record (ptr
, f
)
1985 switch (ptr
->r
.type
)
1989 output_R1_format (f
, ptr
->r
.type
, ptr
->r
.record
.r
.rlen
);
1992 output_R2_format (f
, ptr
->r
.record
.r
.mask
,
1993 ptr
->r
.record
.r
.grsave
, ptr
->r
.record
.r
.rlen
);
1997 output_P7_format (f
, ptr
->r
.type
, ptr
->r
.record
.p
.t
,
1998 ptr
->r
.record
.p
.size
);
2011 output_P3_format (f
, ptr
->r
.type
, ptr
->r
.record
.p
.gr
);
2014 output_P3_format (f
, rp_br
, ptr
->r
.record
.p
.br
);
2017 output_P7_format (f
, psp_sprel
, ptr
->r
.record
.p
.spoff
, 0);
2025 output_P7_format (f
, ptr
->r
.type
, ptr
->r
.record
.p
.t
, 0);
2034 output_P7_format (f
, ptr
->r
.type
, ptr
->r
.record
.p
.pspoff
, 0);
2044 case bspstore_sprel
:
2046 output_P8_format (f
, ptr
->r
.type
, ptr
->r
.record
.p
.spoff
);
2050 output_P6_format (f
, ptr
->r
.type
, ptr
->r
.record
.p
.rmask
);
2053 output_P5_format (f
, ptr
->r
.record
.p
.grmask
, ptr
->r
.record
.p
.frmask
);
2056 output_P9_format (f
, ptr
->r
.record
.p
.grmask
, ptr
->r
.record
.p
.gr
);
2059 output_P1_format (f
, ptr
->r
.record
.p
.brmask
);
2062 output_P2_format (f
, ptr
->r
.record
.p
.brmask
, ptr
->r
.record
.p
.gr
);
2065 as_bad ("spill_mask record unimplemented.");
2067 case priunat_when_gr
:
2068 case priunat_when_mem
:
2072 output_P8_format (f
, ptr
->r
.type
, ptr
->r
.record
.p
.t
);
2074 case priunat_psprel
:
2076 case bspstore_psprel
:
2078 output_P8_format (f
, ptr
->r
.type
, ptr
->r
.record
.p
.pspoff
);
2081 as_bad ("epilogue record unimplemented.");
2084 as_bad ("label_state record unimplemented.");
2087 as_bad ("copy_state record unimplemented.");
2092 case spill_psprel_p
:
2095 as_bad ("spill_* record unimplemented.");
2098 as_bad ("record_type_not_valid");
2103 /* Given a unw_rec_list list, process all the records with
2104 the specified function. */
2106 process_unw_records (list
, f
)
2111 for (ptr
= list
; ptr
; ptr
= ptr
->next
)
2112 process_one_record (ptr
, f
);
2115 /* Determine the size of a record list in bytes. */
2117 calc_record_size (list
)
2121 process_unw_records (list
, count_output
);
2125 /* Given a complete record list, process any records which have
2126 unresolved fields, (ie length counts for a prologue). After
2127 this has been run, all neccessary information should be available
2128 within each record to generate an image. */
2130 fixup_unw_records (list
)
2134 unsigned long first_addr
= 0;
2135 for (ptr
= list
; ptr
; ptr
= ptr
->next
)
2137 if (ptr
->slot_number
== SLOT_NUM_NOT_SET
)
2138 as_bad (" Insn slot not set in unwind record.");
2139 switch (ptr
->r
.type
)
2147 unsigned long last_addr
;
2148 first_addr
= ptr
->slot_number
;
2149 ptr
->slot_number
= 0;
2150 /* Find either the next body/prologue start, or the end of
2151 the list, and determine the size of the region. */
2152 for (last
= ptr
; last
->next
!= NULL
; last
= last
->next
)
2153 if (last
->next
->r
.type
== prologue
2154 || last
->next
->r
.type
== prologue_gr
2155 || last
->next
->r
.type
== body
)
2159 last_addr
= last
->slot_number
;
2160 size
= ((last_addr
- first_addr
) / 16) * 3 + last_addr
% 4;
2161 ptr
->r
.record
.r
.rlen
= size
;
2172 case priunat_when_gr
:
2173 case priunat_when_mem
:
2178 /* All the time fields. */
2179 int x
= ptr
->slot_number
- first_addr
;
2180 ptr
->r
.record
.p
.t
= (x
/ 16) * 3 + (ptr
->slot_number
% 4);
2183 /* TODO. We also need to combine all the register masks into a single
2184 record. (Ie, all the save.g save.gf, save.f and save.br's) */
2189 /* Generate an unwind image from a record list. Returns the number of
2190 bytes in the resulting image. The memory image itselof is returned
2191 in the 'ptr' parameter. */
2193 output_unw_records (list
, ptr
)
2197 int size
, x
, extra
= 0;
2200 fixup_unw_records (list
);
2201 size
= calc_record_size (list
);
2203 /* pad to 8 byte boundry. */
2207 /* Add 8 for the header + 8 more bytes for the personality offset. */
2208 mem
= xmalloc (size
+ extra
+ 16);
2210 vbyte_mem_ptr
= mem
+ 8;
2211 /* Clear the padding area and personality. */
2212 memset (mem
+ 8 + size
, 0 , extra
+ 8);
2213 /* Initialize the header area. */
2214 md_number_to_chars (mem
, 1, 2); /* version number. */
2215 md_number_to_chars (mem
+ 2, 0x03, 2); /* Set E and U handler bits. */
2217 /* Length in double words. */
2218 md_number_to_chars (mem
+ 4, (size
+ extra
) / 8, 4);
2220 process_unw_records (list
, output_vbyte_mem
);
2223 return size
+ extra
+ 16;
2233 radix
= *input_line_pointer
++;
2235 if (radix
!= 'C' && !is_end_of_line
[(unsigned char) radix
])
2237 as_bad ("Radix `%c' unsupported", *input_line_pointer
);
2238 ignore_rest_of_line ();
2243 /* .sbss, .bss etc. are macros that expand into ".section SECNAME". */
2245 dot_special_section (which
)
2248 set_section ((char *) special_section_name
[which
]);
2252 add_unwind_entry (ptr
)
2256 unwind_tail
->next
= ptr
;
2261 /* The current entry can in fact be a chain of unwind entries. */
2262 if (current_unwind_entry
== NULL
)
2263 current_unwind_entry
= ptr
;
2273 if (e
.X_op
!= O_constant
)
2274 as_bad ("Operand to .fframe must be a constant");
2277 add_unwind_entry (output_mem_stack_f (e
.X_add_number
));
2285 discard_rest_of_line ();
2296 sep
= parse_operand (&e1
);
2298 as_bad ("No second operand to .save");
2299 sep
= parse_operand (&e2
);
2301 reg1
= e1
.X_add_number
- REG_AR
;
2302 reg2
= e2
.X_add_number
- REG_GR
;
2304 /* Make sure its a valid ar.xxx reg, OR its br0, aka 'rp'. */
2305 if (e1
.X_op
== O_register
2306 && ((reg1
>=0 && reg1
< 128) || reg1
== REG_BR
- REG_AR
))
2308 if (e2
.X_op
== O_register
&& reg2
>=0 && reg2
< 128)
2312 case 17: /* ar.bsp */
2313 add_unwind_entry (output_bsp_when ());
2314 add_unwind_entry (output_bsp_gr (reg2
));
2316 case 18: /* ar.bspstore */
2317 add_unwind_entry (output_bspstore_when ());
2318 add_unwind_entry (output_bspstore_gr (reg2
));
2320 case 19: /* ar.rnat */
2321 add_unwind_entry (output_rnat_when ());
2322 add_unwind_entry (output_rnat_gr (reg2
));
2324 case 36: /* ar.unat */
2325 add_unwind_entry (output_unat_when ());
2326 add_unwind_entry (output_unat_gr (reg2
));
2328 case 40: /* ar.fpsr */
2329 add_unwind_entry (output_fpsr_when ());
2330 add_unwind_entry (output_fpsr_gr (reg2
));
2332 case 64: /* ar.pfs */
2333 add_unwind_entry (output_pfs_when ());
2334 add_unwind_entry (output_pfs_gr (reg2
));
2336 case 65: /* ar.lc */
2337 add_unwind_entry (output_lc_when ());
2338 add_unwind_entry (output_lc_gr (reg2
));
2340 case REG_BR
- REG_AR
: /* rp */
2341 add_unwind_entry (output_rp_when ());
2342 add_unwind_entry (output_rp_gr (reg2
));
2345 as_bad ("first operand is unknown application register");
2349 as_bad (" Second operand not a valid register");
2352 as_bad ("First operand not a valid register");
2359 discard_rest_of_line ();
2363 generate_unwind_image ()
2366 unsigned char *unw_rec
;
2369 /* Generate the unwind record. */
2370 size
= output_unw_records (unwind_list
, &unw_rec
);
2372 as_bad ("Unwind record is ont a multiple of 4 bytes.");
2374 /* If there are unwind records, switch sections, and output the info. */
2378 unsigned char *where
;
2379 unsigned char *personality
;
2382 set_section ((char *) special_section_name
[SPECIAL_SECTION_UNWIND_INFO
]);
2384 /* Set expression which points to start of unwind descriptor area. */
2385 unwind_info
= expr_build_dot ();
2387 where
= (unsigned char *)frag_more (size
);
2389 /* Issue a label for this address, and keep track of it to put it
2390 in the unwind section. */
2392 /* Copy the information from the unwind record into this section. The
2393 data is already in the correct byte order. */
2394 memcpy (where
, unw_rec
, size
);
2395 /* Add the personality address to the image. */
2396 if (personality_routine
!= 0)
2398 exp
.X_op
= O_symbol
;
2399 exp
.X_add_symbol
= personality_routine
;
2400 exp
.X_add_number
= 0;
2401 fix_new_exp (frag_now
, frag_now_fix () - 8, 8,
2402 &exp
, 0, BFD_RELOC_IA64_LTOFF_FPTR64LSB
);
2403 personality_routine
= 0;
2405 obj_elf_previous (0);
2408 free_list_records (unwind_list
);
2409 unwind_list
= unwind_tail
= current_unwind_entry
= NULL
;
2415 dot_handlerdata (dummy
)
2418 generate_unwind_image ();
2422 dot_unwentry (dummy
)
2425 discard_rest_of_line ();
2432 discard_rest_of_line ();
2443 sep
= parse_operand (&e1
);
2445 as_bad ("No second operand to .savesp");
2446 sep
= parse_operand (&e2
);
2448 reg1
= e1
.X_add_number
- REG_AR
;
2449 val
= e2
.X_add_number
;
2451 /* Make sure its a valid ar.xxx reg, OR its br0, aka 'rp'. */
2452 if (e1
.X_op
== O_register
2453 && ((reg1
>=0 && reg1
< 128) || reg1
== REG_BR
- REG_AR
|| reg1
== REG_PR
- REG_AR
))
2455 if (e2
.X_op
== O_constant
)
2459 case 17: /* ar.bsp */
2460 add_unwind_entry (output_bsp_when ());
2461 add_unwind_entry (output_bsp_sprel (val
));
2463 case 18: /* ar.bspstore */
2464 add_unwind_entry (output_bspstore_when ());
2465 add_unwind_entry (output_bspstore_sprel (val
));
2467 case 19: /* ar.rnat */
2468 add_unwind_entry (output_rnat_when ());
2469 add_unwind_entry (output_rnat_sprel (val
));
2471 case 36: /* ar.unat */
2472 add_unwind_entry (output_unat_when ());
2473 add_unwind_entry (output_unat_sprel (val
));
2475 case 40: /* ar.fpsr */
2476 add_unwind_entry (output_fpsr_when ());
2477 add_unwind_entry (output_fpsr_sprel (val
));
2479 case 64: /* ar.pfs */
2480 add_unwind_entry (output_pfs_when ());
2481 add_unwind_entry (output_pfs_sprel (val
));
2483 case 65: /* ar.lc */
2484 add_unwind_entry (output_lc_when ());
2485 add_unwind_entry (output_lc_sprel (val
));
2487 case REG_BR
- REG_AR
: /* rp */
2488 add_unwind_entry (output_rp_when ());
2489 add_unwind_entry (output_rp_sprel (val
));
2491 case REG_PR
- REG_AR
: /* Predicate registers. */
2492 add_unwind_entry (output_preds_when ());
2493 add_unwind_entry (output_preds_sprel (val
));
2496 as_bad ("first operand is unknown application register");
2500 as_bad (" Second operand not a valid constant");
2503 as_bad ("First operand not a valid register");
2510 discard_rest_of_line ();
2519 sep
= parse_operand (&e1
);
2521 parse_operand (&e2
);
2523 if (e1
.X_op
!= O_constant
)
2524 as_bad ("First operand to .save.g must be a constant.");
2527 int grmask
= e1
.X_add_number
;
2529 add_unwind_entry (output_gr_mem (grmask
));
2532 int reg
= e2
.X_add_number
- REG_GR
;
2533 if (e2
.X_op
== O_register
&& reg
>=0 && reg
< 128)
2534 add_unwind_entry (output_gr_gr (grmask
, reg
));
2536 as_bad ("Second operand is an invalid register.");
2547 sep
= parse_operand (&e1
);
2549 if (e1
.X_op
!= O_constant
)
2550 as_bad ("Operand to .save.f must be a constant.");
2553 int frmask
= e1
.X_add_number
;
2554 add_unwind_entry (output_fr_mem (e1
.X_add_number
));
2564 sep
= parse_operand (&e1
);
2566 if (e1
.X_op
!= O_constant
)
2567 as_bad ("Operand to .save.b must be a constant.");
2570 int brmask
= e1
.X_add_number
;
2571 add_unwind_entry (output_br_mem (brmask
));
2581 sep
= parse_operand (&e1
);
2583 parse_operand (&e2
);
2585 if (e1
.X_op
!= O_constant
|| sep
!= ',' || e2
.X_op
!= O_constant
)
2586 as_bad ("Both operands of .save.gf must be constants.");
2589 int grmask
= e1
.X_add_number
;
2590 int frmask
= e2
.X_add_number
;
2591 add_unwind_entry (output_frgr_mem (grmask
, frmask
));
2602 if (e
.X_op
!= O_constant
)
2603 as_bad ("Operand to .spill must be a constant");
2606 add_unwind_entry (output_spill_base (e
.X_add_number
));
2614 discard_rest_of_line ();
2618 dot_personality (dummy
)
2623 name
= input_line_pointer
;
2624 c
= get_symbol_end ();
2625 p
= input_line_pointer
;
2626 personality_routine
= symbol_find_or_make (name
);
2629 demand_empty_rest_of_line ();
2639 proc_start
= expr_build_dot ();
2640 /* Parse names of main and alternate entry points and mark them s
2641 function symbols: */
2645 name
= input_line_pointer
;
2646 c
= get_symbol_end ();
2647 p
= input_line_pointer
;
2648 sym
= symbol_find_or_make (name
);
2649 if (proc_start
== 0)
2653 symbol_get_bfdsym (sym
)->flags
|= BSF_FUNCTION
;
2656 if (*input_line_pointer
!= ',')
2658 ++input_line_pointer
;
2660 demand_empty_rest_of_line ();
2663 unwind_list
= unwind_tail
= current_unwind_entry
= NULL
;
2664 personality_routine
= 0;
2671 unwind_prologue
= 0;
2672 add_unwind_entry (output_body ());
2676 dot_prologue (dummy
)
2679 unwind_prologue
= 1;
2681 if (! is_end_of_line
[(unsigned char) *input_line_pointer
])
2685 sep
= parse_operand (&e1
);
2687 as_bad ("No second operand to .prologue");
2688 sep
= parse_operand (&e2
);
2690 if (e1
.X_op
== O_constant
)
2692 if (e2
.X_op
== O_constant
)
2694 int mask
= e1
.X_add_number
;
2695 int reg
= e2
.X_add_number
;
2696 add_unwind_entry (output_prologue_gr (mask
, reg
));
2699 as_bad ("Second operand not a constant");
2702 as_bad ("First operand not a constant");
2705 add_unwind_entry (output_prologue ());
2717 subsegT saved_subseg
;
2719 saved_seg
= now_seg
;
2720 saved_subseg
= now_subseg
;
2723 demand_empty_rest_of_line ();
2725 insn_group_break (1, 0, 0);
2726 ia64_flush_insns ();
2728 /* If there was a .handlerdata, we haven't generated an image yet. */
2729 if (unwind_info
== 0)
2731 generate_unwind_image ();
2734 subseg_set (md
.last_text_seg
, 0);
2735 proc_end
= expr_build_dot ();
2737 set_section ((char *) special_section_name
[SPECIAL_SECTION_UNWIND
]);
2738 ptr
= frag_more (24);
2739 where
= frag_now_fix () - 24;
2741 /* Issue the values of a) Proc Begin, b) Proc End, c) Unwind Record. */
2742 e
.X_op
= O_pseudo_fixup
;
2743 e
.X_op_symbol
= pseudo_func
[FUNC_SEG_RELATIVE
].u
.sym
;
2745 e
.X_add_symbol
= proc_start
;
2746 ia64_cons_fix_new (frag_now
, where
, 8, &e
);
2748 e
.X_op
= O_pseudo_fixup
;
2749 e
.X_op_symbol
= pseudo_func
[FUNC_SEG_RELATIVE
].u
.sym
;
2751 e
.X_add_symbol
= proc_end
;
2752 ia64_cons_fix_new (frag_now
, where
+ 8, 8, &e
);
2754 if (unwind_info
!= 0)
2756 e
.X_op
= O_pseudo_fixup
;
2757 e
.X_op_symbol
= pseudo_func
[FUNC_SEG_RELATIVE
].u
.sym
;
2759 e
.X_add_symbol
= unwind_info
;
2760 ia64_cons_fix_new (frag_now
, where
+ 16, 8, &e
);
2763 md_number_to_chars (ptr
+ 16, 0, 8);
2765 subseg_set (saved_seg
, saved_subseg
);
2766 proc_start
= proc_end
= unwind_info
= 0;
2770 dot_template (template)
2773 CURR_SLOT
.user_template
= template;
2780 int ins
, locs
, outs
, rots
;
2782 if (is_it_end_of_statement ())
2783 ins
= locs
= outs
= rots
= 0;
2786 ins
= get_absolute_expression ();
2787 if (*input_line_pointer
++ != ',')
2789 locs
= get_absolute_expression ();
2790 if (*input_line_pointer
++ != ',')
2792 outs
= get_absolute_expression ();
2793 if (*input_line_pointer
++ != ',')
2795 rots
= get_absolute_expression ();
2797 set_regstack (ins
, locs
, outs
, rots
);
2801 as_bad ("Comma expected");
2802 ignore_rest_of_line ();
2809 unsigned num_regs
, num_alloced
= 0;
2810 struct dynreg
**drpp
, *dr
;
2811 int ch
, base_reg
= 0;
2817 case DYNREG_GR
: base_reg
= REG_GR
+ 32; break;
2818 case DYNREG_FR
: base_reg
= REG_FR
+ 32; break;
2819 case DYNREG_PR
: base_reg
= REG_P
+ 16; break;
2823 /* first, remove existing names from hash table: */
2824 for (dr
= md
.dynreg
[type
]; dr
&& dr
->num_regs
; dr
= dr
->next
)
2826 hash_delete (md
.dynreg_hash
, dr
->name
);
2830 drpp
= &md
.dynreg
[type
];
2833 start
= input_line_pointer
;
2834 ch
= get_symbol_end ();
2835 *input_line_pointer
= ch
;
2836 len
= (input_line_pointer
- start
);
2839 if (*input_line_pointer
!= '[')
2841 as_bad ("Expected '['");
2844 ++input_line_pointer
; /* skip '[' */
2846 num_regs
= get_absolute_expression ();
2848 if (*input_line_pointer
++ != ']')
2850 as_bad ("Expected ']'");
2855 num_alloced
+= num_regs
;
2859 if (num_alloced
> md
.rot
.num_regs
)
2861 as_bad ("Used more than the declared %d rotating registers",
2867 if (num_alloced
> 96)
2869 as_bad ("Used more than the available 96 rotating registers");
2874 if (num_alloced
> 48)
2876 as_bad ("Used more than the available 48 rotating registers");
2885 name
= obstack_alloc (¬es
, len
+ 1);
2886 memcpy (name
, start
, len
);
2891 *drpp
= obstack_alloc (¬es
, sizeof (*dr
));
2892 memset (*drpp
, 0, sizeof (*dr
));
2897 dr
->num_regs
= num_regs
;
2898 dr
->base
= base_reg
;
2900 base_reg
+= num_regs
;
2902 if (hash_insert (md
.dynreg_hash
, name
, dr
))
2904 as_bad ("Attempt to redefine register set `%s'", name
);
2908 if (*input_line_pointer
!= ',')
2910 ++input_line_pointer
; /* skip comma */
2913 demand_empty_rest_of_line ();
2917 ignore_rest_of_line ();
2921 dot_byteorder (byteorder
)
2924 target_big_endian
= byteorder
;
2936 option
= input_line_pointer
;
2937 ch
= get_symbol_end ();
2938 if (strcmp (option
, "lsb") == 0)
2939 md
.flags
&= ~EF_IA_64_BE
;
2940 else if (strcmp (option
, "msb") == 0)
2941 md
.flags
|= EF_IA_64_BE
;
2942 else if (strcmp (option
, "abi32") == 0)
2943 md
.flags
&= ~EF_IA_64_ABI64
;
2944 else if (strcmp (option
, "abi64") == 0)
2945 md
.flags
|= EF_IA_64_ABI64
;
2947 as_bad ("Unknown psr option `%s'", option
);
2948 *input_line_pointer
= ch
;
2951 if (*input_line_pointer
!= ',')
2954 ++input_line_pointer
;
2957 demand_empty_rest_of_line ();
2964 as_bad (".alias not implemented yet");
2971 new_logical_line (0, get_absolute_expression ());
2972 demand_empty_rest_of_line ();
2976 parse_section_name ()
2982 if (*input_line_pointer
!= '"')
2984 as_bad ("Missing section name");
2985 ignore_rest_of_line ();
2988 name
= demand_copy_C_string (&len
);
2991 ignore_rest_of_line ();
2995 if (*input_line_pointer
!= ',')
2997 as_bad ("Comma expected after section name");
2998 ignore_rest_of_line ();
3001 ++input_line_pointer
; /* skip comma */
3009 char *name
= parse_section_name ();
3015 obj_elf_previous (0);
3018 /* Why doesn't float_cons() call md_cons_align() the way cons() does? */
3020 stmt_float_cons (kind
)
3027 case 'd': size
= 8; break;
3028 case 'x': size
= 10; break;
3035 ia64_do_align (size
);
3043 int saved_auto_align
= md
.auto_align
;
3047 md
.auto_align
= saved_auto_align
;
3051 dot_xfloat_cons (kind
)
3054 char *name
= parse_section_name ();
3059 stmt_float_cons (kind
);
3060 obj_elf_previous (0);
3064 dot_xstringer (zero
)
3067 char *name
= parse_section_name ();
3073 obj_elf_previous (0);
3080 int saved_auto_align
= md
.auto_align
;
3081 char *name
= parse_section_name ();
3088 md
.auto_align
= saved_auto_align
;
3089 obj_elf_previous (0);
3093 dot_xfloat_cons_ua (kind
)
3096 int saved_auto_align
= md
.auto_align
;
3097 char *name
= parse_section_name ();
3103 stmt_float_cons (kind
);
3104 md
.auto_align
= saved_auto_align
;
3105 obj_elf_previous (0);
3108 /* .reg.val <regname>,value */
3116 if (reg
.X_op
!= O_register
)
3118 as_bad (_("Register name expected"));
3119 ignore_rest_of_line ();
3121 else if (*input_line_pointer
++ != ',')
3123 as_bad (_("Comma expected"));
3124 ignore_rest_of_line ();
3128 valueT value
= get_absolute_expression ();
3129 int regno
= reg
.X_add_number
;
3130 if (regno
< REG_GR
|| regno
> REG_GR
+128)
3131 as_warn (_("Register value annotation ignored"));
3134 gr_values
[regno
-REG_GR
].known
= 1;
3135 gr_values
[regno
-REG_GR
].value
= value
;
3136 gr_values
[regno
-REG_GR
].path
= md
.path
;
3139 demand_empty_rest_of_line ();
3142 /* select dv checking mode
3147 A stop is inserted when changing modes
3153 if (md
.manual_bundling
)
3154 as_warn (_("Directive invalid within a bundle"));
3156 if (type
== 'E' || type
== 'A')
3157 md
.mode_explicitly_set
= 0;
3159 md
.mode_explicitly_set
= 1;
3166 if (md
.explicit_mode
)
3167 insn_group_break (1, 0, 0);
3168 md
.explicit_mode
= 0;
3172 if (!md
.explicit_mode
)
3173 insn_group_break (1, 0, 0);
3174 md
.explicit_mode
= 1;
3178 if (md
.explicit_mode
!= md
.default_explicit_mode
)
3179 insn_group_break (1, 0, 0);
3180 md
.explicit_mode
= md
.default_explicit_mode
;
3181 md
.mode_explicitly_set
= 0;
3192 for (regno
= 0;regno
< 64;regno
++)
3194 if (mask
& ((valueT
)1<<regno
))
3196 fprintf (stderr
, "%s p%d", comma
, regno
);
3203 .pred.rel.clear [p1 [,p2 [,...]]] (also .pred.rel "clear")
3204 .pred.rel.imply p1, p2 (also .pred.rel "imply")
3205 .pred.rel.mutex p1, p2 [,...] (also .pred.rel "mutex")
3206 .pred.safe_across_calls p1 [, p2 [,...]]
3214 int p1
= -1, p2
= -1;
3218 if (*input_line_pointer
!= '"')
3220 as_bad (_("Missing predicate relation type"));
3221 ignore_rest_of_line ();
3227 char *form
= demand_copy_C_string (&len
);
3228 if (strcmp (form
, "mutex") == 0)
3230 else if (strcmp (form
, "clear") == 0)
3232 else if (strcmp (form
, "imply") == 0)
3236 as_bad (_("Unrecognized predicate relation type"));
3237 ignore_rest_of_line ();
3241 if (*input_line_pointer
== ',')
3242 ++input_line_pointer
;
3252 if (toupper (*input_line_pointer
) != 'P'
3253 || (regno
= atoi (++input_line_pointer
)) < 0
3256 as_bad (_("Predicate register expected"));
3257 ignore_rest_of_line ();
3260 while (isdigit (*input_line_pointer
))
3261 ++input_line_pointer
;
3268 as_warn (_("Duplicate predicate register ignored"));
3269 mask
|= bit
; count
++;
3270 /* see if it's a range */
3271 if (*input_line_pointer
== '-')
3274 ++input_line_pointer
;
3276 if (toupper (*input_line_pointer
) != 'P'
3277 || (regno
= atoi (++input_line_pointer
)) < 0
3280 as_bad (_("Predicate register expected"));
3281 ignore_rest_of_line ();
3284 while (isdigit (*input_line_pointer
))
3285 ++input_line_pointer
;
3289 as_bad (_("Bad register range"));
3290 ignore_rest_of_line ();
3296 mask
|= bit
; count
++;
3300 if (*input_line_pointer
!= ',')
3302 ++input_line_pointer
;
3311 clear_qp_mutex (mask
);
3312 clear_qp_implies (mask
, (valueT
)0);
3315 if (count
!= 2 || p1
== -1 || p2
== -1)
3316 as_bad (_("Predicate source and target required"));
3317 else if (p1
== 0 || p2
== 0)
3318 as_bad (_("Use of p0 is not valid in this context"));
3320 add_qp_imply (p1
, p2
);
3325 as_bad (_("At least two PR arguments expected"));
3330 as_bad (_("Use of p0 is not valid in this context"));
3333 add_qp_mutex (mask
);
3336 /* note that we don't override any existing relations */
3339 as_bad (_("At least one PR argument expected"));
3344 fprintf (stderr
, "Safe across calls: ");
3345 print_prmask (mask
);
3346 fprintf (stderr
, "\n");
3348 qp_safe_across_calls
= mask
;
3351 demand_empty_rest_of_line ();
3354 /* .entry label [, label [, ...]]
3355 Hint to DV code that the given labels are to be considered entry points.
3356 Otherwise, only global labels are considered entry points.
3369 name
= input_line_pointer
;
3370 c
= get_symbol_end ();
3371 symbolP
= symbol_find_or_make (name
);
3373 err
= hash_insert (md
.entry_hash
, S_GET_NAME (symbolP
), (PTR
) symbolP
);
3375 as_fatal (_("Inserting \"%s\" into entry hint table failed: %s"),
3378 *input_line_pointer
= c
;
3380 c
= *input_line_pointer
;
3383 input_line_pointer
++;
3385 if (*input_line_pointer
== '\n')
3391 demand_empty_rest_of_line ();
3394 /* .mem.offset offset, base
3395 "base" is used to distinguish between offsets from a different base.
3398 dot_mem_offset (dummy
)
3401 md
.mem_offset
.hint
= 1;
3402 md
.mem_offset
.offset
= get_absolute_expression ();
3403 if (*input_line_pointer
!= ',')
3405 as_bad (_("Comma expected"));
3406 ignore_rest_of_line ();
3409 ++input_line_pointer
;
3410 md
.mem_offset
.base
= get_absolute_expression ();
3411 demand_empty_rest_of_line ();
3414 /* ia64-specific pseudo-ops: */
3415 const pseudo_typeS md_pseudo_table
[] =
3417 { "radix", dot_radix
, 0 },
3418 { "lcomm", s_lcomm_bytes
, 1 },
3419 { "bss", dot_special_section
, SPECIAL_SECTION_BSS
},
3420 { "sbss", dot_special_section
, SPECIAL_SECTION_SBSS
},
3421 { "sdata", dot_special_section
, SPECIAL_SECTION_SDATA
},
3422 { "rodata", dot_special_section
, SPECIAL_SECTION_RODATA
},
3423 { "comment", dot_special_section
, SPECIAL_SECTION_COMMENT
},
3424 { "ia_64.unwind", dot_special_section
, SPECIAL_SECTION_UNWIND
},
3425 { "ia_64.unwind_info", dot_special_section
, SPECIAL_SECTION_UNWIND_INFO
},
3426 { "proc", dot_proc
, 0 },
3427 { "body", dot_body
, 0 },
3428 { "prologue", dot_prologue
, 0 },
3429 { "endp", dot_endp
},
3430 { "file", dwarf2_directive_file
},
3431 { "loc", dwarf2_directive_loc
},
3433 { "fframe", dot_fframe
},
3434 { "vframe", dot_vframe
},
3435 { "save", dot_save
},
3436 { "restore", dot_restore
},
3437 { "handlerdata", dot_handlerdata
},
3438 { "unwentry", dot_unwentry
},
3439 { "alprp", dot_altrp
},
3440 { "savesp", dot_savesp
},
3441 { "savepsp", dot_savepsp
},
3442 { "save.g", dot_saveg
},
3443 { "save.f", dot_savef
},
3444 { "save.b", dot_saveb
},
3445 { "save.gf", dot_savegf
},
3446 { "spill", dot_spill
},
3447 { "unwabi", dot_unwabi
},
3448 { "personality", dot_personality
},
3450 { "estate", dot_estate
},
3452 { "mii", dot_template
, 0x0 },
3453 { "mli", dot_template
, 0x2 }, /* old format, for compatibility */
3454 { "mlx", dot_template
, 0x2 },
3455 { "mmi", dot_template
, 0x4 },
3456 { "mfi", dot_template
, 0x6 },
3457 { "mmf", dot_template
, 0x7 },
3458 { "mib", dot_template
, 0x8 },
3459 { "mbb", dot_template
, 0x9 },
3460 { "bbb", dot_template
, 0xb },
3461 { "mmb", dot_template
, 0xc },
3462 { "mfb", dot_template
, 0xe },
3464 { "lb", dot_scope
, 0 },
3465 { "le", dot_scope
, 1 },
3467 { "align", s_align_bytes
, 0 },
3468 { "regstk", dot_regstk
, 0 },
3469 { "rotr", dot_rot
, DYNREG_GR
},
3470 { "rotf", dot_rot
, DYNREG_FR
},
3471 { "rotp", dot_rot
, DYNREG_PR
},
3472 { "lsb", dot_byteorder
, 0 },
3473 { "msb", dot_byteorder
, 1 },
3474 { "psr", dot_psr
, 0 },
3475 { "alias", dot_alias
, 0 },
3476 { "ln", dot_ln
, 0 }, /* source line info (for debugging) */
3478 { "xdata1", dot_xdata
, 1 },
3479 { "xdata2", dot_xdata
, 2 },
3480 { "xdata4", dot_xdata
, 4 },
3481 { "xdata8", dot_xdata
, 8 },
3482 { "xreal4", dot_xfloat_cons
, 'f' },
3483 { "xreal8", dot_xfloat_cons
, 'd' },
3484 { "xreal10", dot_xfloat_cons
, 'x' },
3485 { "xstring", dot_xstringer
, 0 },
3486 { "xstringz", dot_xstringer
, 1 },
3488 /* unaligned versions: */
3489 { "xdata2.ua", dot_xdata_ua
, 2 },
3490 { "xdata4.ua", dot_xdata_ua
, 4 },
3491 { "xdata8.ua", dot_xdata_ua
, 8 },
3492 { "xreal4.ua", dot_xfloat_cons_ua
, 'f' },
3493 { "xreal8.ua", dot_xfloat_cons_ua
, 'd' },
3494 { "xreal10.ua", dot_xfloat_cons_ua
, 'x' },
3496 /* annotations/DV checking support */
3497 { "entry", dot_entry
, 0 },
3498 { "mem.offset", dot_mem_offset
},
3499 { "pred.rel", dot_pred_rel
, 0 },
3500 { "pred.rel.clear", dot_pred_rel
, 'c' },
3501 { "pred.rel.imply", dot_pred_rel
, 'i' },
3502 { "pred.rel.mutex", dot_pred_rel
, 'm' },
3503 { "pred.safe_across_calls", dot_pred_rel
, 's' },
3504 { "reg.val", dot_reg_val
},
3505 { "auto", dot_dv_mode
, 'a' },
3506 { "explicit", dot_dv_mode
, 'e' },
3507 { "default", dot_dv_mode
, 'd' },
3512 static const struct pseudo_opcode
3515 void (*handler
) (int);
3520 /* these are more like pseudo-ops, but don't start with a dot */
3521 { "data1", cons
, 1 },
3522 { "data2", cons
, 2 },
3523 { "data4", cons
, 4 },
3524 { "data8", cons
, 8 },
3525 { "real4", stmt_float_cons
, 'f' },
3526 { "real8", stmt_float_cons
, 'd' },
3527 { "real10", stmt_float_cons
, 'x' },
3528 { "string", stringer
, 0 },
3529 { "stringz", stringer
, 1 },
3531 /* unaligned versions: */
3532 { "data2.ua", stmt_cons_ua
, 2 },
3533 { "data4.ua", stmt_cons_ua
, 4 },
3534 { "data8.ua", stmt_cons_ua
, 8 },
3535 { "real4.ua", float_cons
, 'f' },
3536 { "real8.ua", float_cons
, 'd' },
3537 { "real10.ua", float_cons
, 'x' },
3540 /* Declare a register by creating a symbol for it and entering it in
3541 the symbol table. */
3543 declare_register (name
, regnum
)
3550 sym
= symbol_new (name
, reg_section
, regnum
, &zero_address_frag
);
3552 err
= hash_insert (md
.reg_hash
, S_GET_NAME (sym
), (PTR
) sym
);
3554 as_fatal ("Inserting \"%s\" into register table failed: %s",
3561 declare_register_set (prefix
, num_regs
, base_regnum
)
3569 for (i
= 0; i
< num_regs
; ++i
)
3571 sprintf (name
, "%s%u", prefix
, i
);
3572 declare_register (name
, base_regnum
+ i
);
3577 operand_width (opnd
)
3578 enum ia64_opnd opnd
;
3580 const struct ia64_operand
*odesc
= &elf64_ia64_operands
[opnd
];
3581 unsigned int bits
= 0;
3585 for (i
= 0; i
< NELEMS (odesc
->field
) && odesc
->field
[i
].bits
; ++i
)
3586 bits
+= odesc
->field
[i
].bits
;
3592 operand_match (idesc
, index
, e
)
3593 const struct ia64_opcode
*idesc
;
3597 enum ia64_opnd opnd
= idesc
->operands
[index
];
3598 int bits
, relocatable
= 0;
3599 struct insn_fix
*fix
;
3606 case IA64_OPND_AR_CCV
:
3607 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_AR
+ 32)
3611 case IA64_OPND_AR_PFS
:
3612 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_AR
+ 64)
3617 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_GR
+ 0)
3622 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_IP
)
3627 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_PR
)
3631 case IA64_OPND_PR_ROT
:
3632 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_PR_ROT
)
3637 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_PSR
)
3641 case IA64_OPND_PSR_L
:
3642 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_PSR_L
)
3646 case IA64_OPND_PSR_UM
:
3647 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_PSR_UM
)
3652 if (e
->X_op
== O_constant
&& e
->X_add_number
== 1)
3657 if (e
->X_op
== O_constant
&& e
->X_add_number
== 8)
3662 if (e
->X_op
== O_constant
&& e
->X_add_number
== 16)
3666 /* register operands: */
3669 if (e
->X_op
== O_register
&& e
->X_add_number
>= REG_AR
3670 && e
->X_add_number
< REG_AR
+ 128)
3676 if (e
->X_op
== O_register
&& e
->X_add_number
>= REG_BR
3677 && e
->X_add_number
< REG_BR
+ 8)
3682 if (e
->X_op
== O_register
&& e
->X_add_number
>= REG_CR
3683 && e
->X_add_number
< REG_CR
+ 128)
3691 if (e
->X_op
== O_register
&& e
->X_add_number
>= REG_FR
3692 && e
->X_add_number
< REG_FR
+ 128)
3698 if (e
->X_op
== O_register
&& e
->X_add_number
>= REG_P
3699 && e
->X_add_number
< REG_P
+ 64)
3706 if (e
->X_op
== O_register
&& e
->X_add_number
>= REG_GR
3707 && e
->X_add_number
< REG_GR
+ 128)
3711 case IA64_OPND_R3_2
:
3712 if (e
->X_op
== O_register
&& e
->X_add_number
>= REG_GR
3713 && e
->X_add_number
< REG_GR
+ 4)
3717 /* indirect operands: */
3718 case IA64_OPND_CPUID_R3
:
3719 case IA64_OPND_DBR_R3
:
3720 case IA64_OPND_DTR_R3
:
3721 case IA64_OPND_ITR_R3
:
3722 case IA64_OPND_IBR_R3
:
3723 case IA64_OPND_MSR_R3
:
3724 case IA64_OPND_PKR_R3
:
3725 case IA64_OPND_PMC_R3
:
3726 case IA64_OPND_PMD_R3
:
3727 case IA64_OPND_RR_R3
:
3728 if (e
->X_op
== O_index
&& e
->X_op_symbol
3729 && (S_GET_VALUE (e
->X_op_symbol
) - IND_CPUID
3730 == opnd
- IA64_OPND_CPUID_R3
))
3735 if (e
->X_op
== O_index
&& !e
->X_op_symbol
)
3739 /* immediate operands: */
3740 case IA64_OPND_CNT2a
:
3741 case IA64_OPND_LEN4
:
3742 case IA64_OPND_LEN6
:
3743 bits
= operand_width (idesc
->operands
[index
]);
3744 if (e
->X_op
== O_constant
3745 && (bfd_vma
) (e
->X_add_number
- 1) < ((bfd_vma
) 1 << bits
))
3749 case IA64_OPND_CNT2b
:
3750 if (e
->X_op
== O_constant
3751 && (bfd_vma
) (e
->X_add_number
- 1) < 3)
3755 case IA64_OPND_CNT2c
:
3756 val
= e
->X_add_number
;
3757 if (e
->X_op
== O_constant
3758 && (val
== 0 || val
== 7 || val
== 15 || val
== 16))
3763 /* SOR must be an integer multiple of 8 */
3764 if (e
->X_add_number
& 0x7)
3768 if (e
->X_op
== O_constant
&&
3769 (bfd_vma
) e
->X_add_number
<= 96)
3773 case IA64_OPND_IMMU62
:
3774 if (e
->X_op
== O_constant
)
3776 if ((bfd_vma
) e
->X_add_number
< ((bfd_vma
) 1 << 62))
3781 /* FIXME -- need 62-bit relocation type */
3782 as_bad (_("62-bit relocation not yet implemented"));
3786 case IA64_OPND_IMMU64
:
3787 if (e
->X_op
== O_symbol
|| e
->X_op
== O_pseudo_fixup
3788 || e
->X_op
== O_subtract
)
3790 fix
= CURR_SLOT
.fixup
+ CURR_SLOT
.num_fixups
;
3791 fix
->code
= BFD_RELOC_IA64_IMM64
;
3792 if (e
->X_op
!= O_subtract
)
3794 fix
->code
= ia64_gen_real_reloc_type (e
->X_op_symbol
, fix
->code
);
3795 if (e
->X_op
== O_pseudo_fixup
)
3799 fix
->opnd
= idesc
->operands
[index
];
3802 ++CURR_SLOT
.num_fixups
;
3805 else if (e
->X_op
== O_constant
)
3809 case IA64_OPND_CCNT5
:
3810 case IA64_OPND_CNT5
:
3811 case IA64_OPND_CNT6
:
3812 case IA64_OPND_CPOS6a
:
3813 case IA64_OPND_CPOS6b
:
3814 case IA64_OPND_CPOS6c
:
3815 case IA64_OPND_IMMU2
:
3816 case IA64_OPND_IMMU7a
:
3817 case IA64_OPND_IMMU7b
:
3818 case IA64_OPND_IMMU9
:
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_IMM44
:
3831 /* least 16 bits must be zero */
3832 if ((e
->X_add_number
& 0xffff) != 0)
3833 as_warn (_("lower 16 bits of mask ignored"));
3835 if (e
->X_op
== O_constant
3836 && ((e
->X_add_number
>= 0
3837 && e
->X_add_number
< ((bfd_vma
) 1 << 44))
3838 || (e
->X_add_number
< 0
3839 && -e
->X_add_number
<= ((bfd_vma
) 1 << 44))))
3842 if (e
->X_add_number
>= 0
3843 && (e
->X_add_number
& ((bfd_vma
) 1 << 43)) != 0)
3845 e
->X_add_number
|= ~(((bfd_vma
) 1 << 44) - 1);
3851 case IA64_OPND_IMM17
:
3852 /* bit 0 is a don't care (pr0 is hardwired to 1) */
3853 if (e
->X_op
== O_constant
3854 && ((e
->X_add_number
>= 0
3855 && e
->X_add_number
< ((bfd_vma
) 1 << 17))
3856 || (e
->X_add_number
< 0
3857 && -e
->X_add_number
<= ((bfd_vma
) 1 << 17))))
3860 if (e
->X_add_number
>= 0
3861 && (e
->X_add_number
& ((bfd_vma
) 1 << 16)) != 0)
3863 e
->X_add_number
|= ~(((bfd_vma
)1 << 17) - 1);
3869 case IA64_OPND_IMM14
:
3870 case IA64_OPND_IMM22
:
3872 case IA64_OPND_IMM1
:
3873 case IA64_OPND_IMM8
:
3874 case IA64_OPND_IMM8U4
:
3875 case IA64_OPND_IMM8M1
:
3876 case IA64_OPND_IMM8M1U4
:
3877 case IA64_OPND_IMM8M1U8
:
3878 case IA64_OPND_IMM9a
:
3879 case IA64_OPND_IMM9b
:
3880 bits
= operand_width (idesc
->operands
[index
]);
3881 if (relocatable
&& (e
->X_op
== O_symbol
3882 || e
->X_op
== O_subtract
3883 || e
->X_op
== O_pseudo_fixup
))
3885 fix
= CURR_SLOT
.fixup
+ CURR_SLOT
.num_fixups
;
3887 if (idesc
->operands
[index
] == IA64_OPND_IMM14
)
3888 fix
->code
= BFD_RELOC_IA64_IMM14
;
3890 fix
->code
= BFD_RELOC_IA64_IMM22
;
3892 if (e
->X_op
!= O_subtract
)
3894 fix
->code
= ia64_gen_real_reloc_type (e
->X_op_symbol
, fix
->code
);
3895 if (e
->X_op
== O_pseudo_fixup
)
3899 fix
->opnd
= idesc
->operands
[index
];
3902 ++CURR_SLOT
.num_fixups
;
3905 else if (e
->X_op
!= O_constant
3906 && ! (e
->X_op
== O_big
&& opnd
== IA64_OPND_IMM8M1U8
))
3909 if (opnd
== IA64_OPND_IMM8M1U4
)
3911 /* Zero is not valid for unsigned compares that take an adjusted
3912 constant immediate range. */
3913 if (e
->X_add_number
== 0)
3916 /* Sign-extend 32-bit unsigned numbers, so that the following range
3917 checks will work. */
3918 val
= e
->X_add_number
;
3919 if (((val
& (~(bfd_vma
)0 << 32)) == 0)
3920 && ((val
& ((bfd_vma
)1 << 31)) != 0))
3921 val
= ((val
<< 32) >> 32);
3923 /* Check for 0x100000000. This is valid because
3924 0x100000000-1 is the same as ((uint32_t) -1). */
3925 if (val
== ((bfd_signed_vma
) 1 << 32))
3930 else if (opnd
== IA64_OPND_IMM8M1U8
)
3932 /* Zero is not valid for unsigned compares that take an adjusted
3933 constant immediate range. */
3934 if (e
->X_add_number
== 0)
3937 /* Check for 0x10000000000000000. */
3938 if (e
->X_op
== O_big
)
3940 if (generic_bignum
[0] == 0
3941 && generic_bignum
[1] == 0
3942 && generic_bignum
[2] == 0
3943 && generic_bignum
[3] == 0
3944 && generic_bignum
[4] == 1)
3950 val
= e
->X_add_number
- 1;
3952 else if (opnd
== IA64_OPND_IMM8M1
)
3953 val
= e
->X_add_number
- 1;
3954 else if (opnd
== IA64_OPND_IMM8U4
)
3956 /* Sign-extend 32-bit unsigned numbers, so that the following range
3957 checks will work. */
3958 val
= e
->X_add_number
;
3959 if (((val
& (~(bfd_vma
)0 << 32)) == 0)
3960 && ((val
& ((bfd_vma
)1 << 31)) != 0))
3961 val
= ((val
<< 32) >> 32);
3964 val
= e
->X_add_number
;
3966 if ((val
>= 0 && val
< ((bfd_vma
) 1 << (bits
- 1)))
3967 || (val
< 0 && -val
<= ((bfd_vma
) 1 << (bits
- 1))))
3971 case IA64_OPND_INC3
:
3972 /* +/- 1, 4, 8, 16 */
3973 val
= e
->X_add_number
;
3976 if (e
->X_op
== O_constant
3977 && (val
== 1 || val
== 4 || val
== 8 || val
== 16))
3981 case IA64_OPND_TGT25
:
3982 case IA64_OPND_TGT25b
:
3983 case IA64_OPND_TGT25c
:
3984 case IA64_OPND_TGT64
:
3985 if (e
->X_op
== O_symbol
)
3987 fix
= CURR_SLOT
.fixup
+ CURR_SLOT
.num_fixups
;
3988 if (opnd
== IA64_OPND_TGT25
)
3989 fix
->code
= BFD_RELOC_IA64_PCREL21F
;
3990 else if (opnd
== IA64_OPND_TGT25b
)
3991 fix
->code
= BFD_RELOC_IA64_PCREL21M
;
3992 else if (opnd
== IA64_OPND_TGT25c
)
3993 fix
->code
= BFD_RELOC_IA64_PCREL21B
;
3995 /* FIXME -- use appropriate relocation type */
3996 as_bad (_("long branch targets not implemented"));
3997 fix
->code
= ia64_gen_real_reloc_type (e
->X_op_symbol
, fix
->code
);
3998 fix
->opnd
= idesc
->operands
[index
];
4001 ++CURR_SLOT
.num_fixups
;
4004 case IA64_OPND_TAG13
:
4005 case IA64_OPND_TAG13b
:
4012 fix
= CURR_SLOT
.fixup
+ CURR_SLOT
.num_fixups
;
4013 fix
->code
= ia64_gen_real_reloc_type (e
->X_op_symbol
, 0);
4014 fix
->opnd
= idesc
->operands
[index
];
4017 ++CURR_SLOT
.num_fixups
;
4037 memset (e
, 0, sizeof (*e
));
4040 if (*input_line_pointer
!= '}')
4042 sep
= *input_line_pointer
++;
4046 if (!md
.manual_bundling
)
4047 as_warn ("Found '}' when manual bundling is off");
4049 CURR_SLOT
.manual_bundling_off
= 1;
4050 md
.manual_bundling
= 0;
4056 /* Returns the next entry in the opcode table that matches the one in
4057 IDESC, and frees the entry in IDESC. If no matching entry is
4058 found, NULL is returned instead. */
4060 static struct ia64_opcode
*
4061 get_next_opcode (struct ia64_opcode
*idesc
)
4063 struct ia64_opcode
*next
= ia64_find_next_opcode (idesc
);
4064 ia64_free_opcode (idesc
);
4068 /* Parse the operands for the opcode and find the opcode variant that
4069 matches the specified operands, or NULL if no match is possible. */
4070 static struct ia64_opcode
*
4071 parse_operands (idesc
)
4072 struct ia64_opcode
*idesc
;
4074 int i
= 0, highest_unmatched_operand
, num_operands
= 0, num_outputs
= 0;
4076 enum ia64_opnd expected_operand
= IA64_OPND_NIL
;
4078 char *first_arg
= 0, *end
, *saved_input_pointer
;
4081 assert (strlen (idesc
->name
) <= 128);
4083 strcpy (mnemonic
, idesc
->name
);
4084 if (idesc
->operands
[2] == IA64_OPND_SOF
)
4086 /* To make the common idiom "alloc loc?=ar.pfs,0,1,0,0" work, we
4087 can't parse the first operand until we have parsed the
4088 remaining operands of the "alloc" instruction. */
4090 first_arg
= input_line_pointer
;
4091 end
= strchr (input_line_pointer
, '=');
4094 as_bad ("Expected separator `='");
4097 input_line_pointer
= end
+ 1;
4102 for (; i
< NELEMS (CURR_SLOT
.opnd
); ++i
)
4104 sep
= parse_operand (CURR_SLOT
.opnd
+ i
);
4105 if (CURR_SLOT
.opnd
[i
].X_op
== O_absent
)
4110 if (sep
!= '=' && sep
!= ',')
4115 if (num_outputs
> 0)
4116 as_bad ("Duplicate equal sign (=) in instruction");
4118 num_outputs
= i
+ 1;
4123 as_bad ("Illegal operand separator `%c'", sep
);
4127 if (idesc
->operands
[2] == IA64_OPND_SOF
)
4129 /* map alloc r1=ar.pfs,i,l,o,r to alloc r1=ar.pfs,(i+l+o),(i+l),r */
4130 know (strcmp (idesc
->name
, "alloc") == 0);
4131 if (num_operands
== 5 /* first_arg not included in this count! */
4132 && CURR_SLOT
.opnd
[2].X_op
== O_constant
4133 && CURR_SLOT
.opnd
[3].X_op
== O_constant
4134 && CURR_SLOT
.opnd
[4].X_op
== O_constant
4135 && CURR_SLOT
.opnd
[5].X_op
== O_constant
)
4137 sof
= set_regstack (CURR_SLOT
.opnd
[2].X_add_number
,
4138 CURR_SLOT
.opnd
[3].X_add_number
,
4139 CURR_SLOT
.opnd
[4].X_add_number
,
4140 CURR_SLOT
.opnd
[5].X_add_number
);
4142 /* now we can parse the first arg: */
4143 saved_input_pointer
= input_line_pointer
;
4144 input_line_pointer
= first_arg
;
4145 sep
= parse_operand (CURR_SLOT
.opnd
+ 0);
4147 --num_outputs
; /* force error */
4148 input_line_pointer
= saved_input_pointer
;
4150 CURR_SLOT
.opnd
[2].X_add_number
= sof
;
4151 CURR_SLOT
.opnd
[3].X_add_number
4152 = sof
- CURR_SLOT
.opnd
[4].X_add_number
;
4153 CURR_SLOT
.opnd
[4] = CURR_SLOT
.opnd
[5];
4157 highest_unmatched_operand
= 0;
4158 expected_operand
= idesc
->operands
[0];
4159 for (; idesc
; idesc
= get_next_opcode (idesc
))
4161 if (num_outputs
!= idesc
->num_outputs
)
4162 continue; /* mismatch in # of outputs */
4164 CURR_SLOT
.num_fixups
= 0;
4165 for (i
= 0; i
< num_operands
&& idesc
->operands
[i
]; ++i
)
4166 if (!operand_match (idesc
, i
, CURR_SLOT
.opnd
+ i
))
4169 if (i
!= num_operands
)
4171 if (i
> highest_unmatched_operand
)
4173 highest_unmatched_operand
= i
;
4174 expected_operand
= idesc
->operands
[i
];
4179 if (num_operands
< NELEMS (idesc
->operands
)
4180 && idesc
->operands
[num_operands
])
4181 continue; /* mismatch in number of arguments */
4187 if (expected_operand
)
4188 as_bad ("Operand %u of `%s' should be %s",
4189 highest_unmatched_operand
+ 1, mnemonic
,
4190 elf64_ia64_operands
[expected_operand
].desc
);
4192 as_bad ("Operand mismatch");
4199 build_insn (slot
, insnp
)
4203 const struct ia64_operand
*odesc
, *o2desc
;
4204 struct ia64_opcode
*idesc
= slot
->idesc
;
4205 bfd_signed_vma insn
, val
;
4209 insn
= idesc
->opcode
| slot
->qp_regno
;
4211 for (i
= 0; i
< NELEMS (idesc
->operands
) && idesc
->operands
[i
]; ++i
)
4213 if (idesc
->operands
[i
] == IA64_OPND_IMMU64
)
4215 val
= slot
->opnd
[i
].X_add_number
;
4216 *insnp
++ = (val
>> 22) & 0x1ffffffffffLL
;
4217 insn
|= (((val
& 0x7f) << 13) | (((val
>> 7) & 0x1ff) << 27)
4218 | (((val
>> 16) & 0x1f) << 22) | (((val
>> 21) & 0x1) << 21)
4219 | (((val
>> 63) & 0x1) << 36));
4221 else if (idesc
->operands
[i
] == IA64_OPND_IMMU62
)
4223 val
= slot
->opnd
[i
].X_add_number
& 0x3fffffffffffffffULL
;
4224 if (val
!= slot
->opnd
[i
].X_add_number
)
4225 as_warn (_("Value truncated to 62 bits"));
4226 *insnp
++ = (val
>> 21) & 0x1ffffffffffLL
;
4227 insn
|= (((val
& 0xfffff) << 6) | (((val
>> 20) & 0x1) << 36));
4229 else if (idesc
->operands
[i
] == IA64_OPND_TGT64
)
4231 // FIXME -- need to implement the target address encoding properly
4232 as_bad (_("long branch target encoding not implemented"));
4235 else if (slot
->opnd
[i
].X_op
== O_register
4236 || slot
->opnd
[i
].X_op
== O_constant
4237 || slot
->opnd
[i
].X_op
== O_index
4238 || slot
->opnd
[i
].X_op
== O_big
)
4240 if (slot
->opnd
[i
].X_op
== O_big
)
4242 /* This must be the value 0x10000000000000000. */
4243 assert (idesc
->operands
[i
] == IA64_OPND_IMM8M1U8
);
4247 val
= slot
->opnd
[i
].X_add_number
;
4249 switch (idesc
->operands
[i
])
4251 case IA64_OPND_AR3
: val
-= REG_AR
; break;
4252 case IA64_OPND_B1
: case IA64_OPND_B2
: val
-= REG_BR
; break;
4253 case IA64_OPND_CR3
: val
-= REG_CR
; break;
4254 case IA64_OPND_F1
: case IA64_OPND_F2
:
4255 case IA64_OPND_F3
: case IA64_OPND_F4
: val
-= REG_FR
; break;
4256 case IA64_OPND_P1
: case IA64_OPND_P2
: val
-= REG_P
; break;
4258 case IA64_OPND_R1
: case IA64_OPND_R2
:
4259 case IA64_OPND_R3
: case IA64_OPND_R3_2
:
4260 case IA64_OPND_CPUID_R3
: case IA64_OPND_DBR_R3
:
4261 case IA64_OPND_DTR_R3
: case IA64_OPND_ITR_R3
:
4262 case IA64_OPND_IBR_R3
: case IA64_OPND_MR3
:
4263 case IA64_OPND_MSR_R3
: case IA64_OPND_PKR_R3
:
4264 case IA64_OPND_PMC_R3
: case IA64_OPND_PMD_R3
:
4265 case IA64_OPND_RR_R3
:
4272 odesc
= elf64_ia64_operands
+ idesc
->operands
[i
];
4273 err
= (*odesc
->insert
) (odesc
, val
, &insn
);
4275 as_bad_where (slot
->src_file
, slot
->src_line
,
4276 "Bad operand value: %s", err
);
4277 if (idesc
->flags
& IA64_OPCODE_PSEUDO
)
4279 if ((idesc
->flags
& IA64_OPCODE_F2_EQ_F3
)
4280 && odesc
== elf64_ia64_operands
+ IA64_OPND_F3
)
4282 o2desc
= elf64_ia64_operands
+ IA64_OPND_F2
;
4283 (*o2desc
->insert
) (o2desc
, val
, &insn
);
4286 if ((idesc
->flags
& IA64_OPCODE_LEN_EQ_64MCNT
)
4287 && (odesc
== elf64_ia64_operands
+ IA64_OPND_CPOS6a
4288 || odesc
== elf64_ia64_operands
+ IA64_OPND_POS6
))
4290 o2desc
= elf64_ia64_operands
+ IA64_OPND_LEN6
;
4291 (*o2desc
->insert
) (o2desc
, 64 - val
, &insn
);
4302 unsigned int manual_bundling_on
= 0, manual_bundling_off
= 0;
4303 unsigned int manual_bundling
= 0;
4304 enum ia64_unit required_unit
, insn_unit
= 0;
4305 enum ia64_insn_type type
[3], insn_type
;
4306 unsigned int template, orig_template
;
4307 bfd_vma insn
[3] = {-1, -1, -1};
4308 struct ia64_opcode
*idesc
;
4309 int end_of_insn_group
= 0, user_template
= -1;
4310 int n
, i
, j
, first
, curr
;
4311 bfd_vma t0
= 0, t1
= 0;
4312 struct label_fix
*lfix
;
4313 struct insn_fix
*ifix
;
4318 first
= (md
.curr_slot
+ NUM_SLOTS
- md
.num_slots_in_use
) % NUM_SLOTS
;
4319 know (first
>= 0 & first
< NUM_SLOTS
);
4320 n
= MIN (3, md
.num_slots_in_use
);
4322 /* Determine template: user user_template if specified, best match
4325 if (md
.slot
[first
].user_template
>= 0)
4326 user_template
= template = md
.slot
[first
].user_template
;
4329 /* auto select appropriate template */
4330 memset (type
, 0, sizeof (type
));
4332 for (i
= 0; i
< n
; ++i
)
4334 type
[i
] = md
.slot
[curr
].idesc
->type
;
4335 curr
= (curr
+ 1) % NUM_SLOTS
;
4337 template = best_template
[type
[0]][type
[1]][type
[2]];
4340 /* initialize instructions with appropriate nops: */
4341 for (i
= 0; i
< 3; ++i
)
4342 insn
[i
] = nop
[ia64_templ_desc
[template].exec_unit
[i
]];
4346 /* now fill in slots with as many insns as possible: */
4348 idesc
= md
.slot
[curr
].idesc
;
4349 end_of_insn_group
= 0;
4350 for (i
= 0; i
< 3 && md
.num_slots_in_use
> 0; ++i
)
4352 if (idesc
->flags
& IA64_OPCODE_SLOT2
)
4354 if (manual_bundling
&& i
!= 2)
4355 as_bad_where (md
.slot
[curr
].src_file
, md
.slot
[curr
].src_line
,
4356 "`%s' must be last in bundle", idesc
->name
);
4360 if (idesc
->flags
& IA64_OPCODE_LAST
)
4362 int required_slot
, required_template
;
4364 /* If we need a stop bit after an M slot, our only choice is
4365 template 5 (M;;MI). If we need a stop bit after a B
4366 slot, our only choice is to place it at the end of the
4367 bundle, because the only available templates are MIB,
4368 MBB, BBB, MMB, and MFB. We don't handle anything other
4369 than M and B slots because these are the only kind of
4370 instructions that can have the IA64_OPCODE_LAST bit set. */
4371 required_template
= template;
4372 switch (idesc
->type
)
4376 required_template
= 5;
4384 as_bad_where (md
.slot
[curr
].src_file
, md
.slot
[curr
].src_line
,
4385 "Internal error: don't know how to force %s to end"
4386 "of instruction group", idesc
->name
);
4390 if (manual_bundling
&& i
!= required_slot
)
4391 as_bad_where (md
.slot
[curr
].src_file
, md
.slot
[curr
].src_line
,
4392 "`%s' must be last in instruction group",
4394 if (required_slot
< i
)
4395 /* Can't fit this instruction. */
4399 if (required_template
!= template)
4401 /* If we switch the template, we need to reset the NOPs
4402 after slot i. The slot-types of the instructions ahead
4403 of i never change, so we don't need to worry about
4404 changing NOPs in front of this slot. */
4405 for (j
= i
; j
< 3; ++j
)
4406 insn
[j
] = nop
[ia64_templ_desc
[required_template
].exec_unit
[j
]];
4408 template = required_template
;
4410 if (curr
!= first
&& md
.slot
[curr
].label_fixups
)
4412 if (manual_bundling_on
)
4413 as_bad_where (md
.slot
[curr
].src_file
, md
.slot
[curr
].src_line
,
4414 "Label must be first in a bundle");
4415 /* This insn must go into the first slot of a bundle. */
4419 manual_bundling_on
= md
.slot
[curr
].manual_bundling_on
;
4420 manual_bundling_off
= md
.slot
[curr
].manual_bundling_off
;
4422 if (manual_bundling_on
)
4425 manual_bundling
= 1;
4427 break; /* need to start a new bundle */
4430 if (end_of_insn_group
&& md
.num_slots_in_use
>= 1)
4432 /* We need an instruction group boundary in the middle of a
4433 bundle. See if we can switch to an other template with
4434 an appropriate boundary. */
4436 orig_template
= template;
4437 if (i
== 1 && (user_template
== 4
4438 || (user_template
< 0
4439 && (ia64_templ_desc
[template].exec_unit
[0]
4443 end_of_insn_group
= 0;
4445 else if (i
== 2 && (user_template
== 0
4446 || (user_template
< 0
4447 && (ia64_templ_desc
[template].exec_unit
[1]
4449 /* This test makes sure we don't switch the template if
4450 the next instruction is one that needs to be first in
4451 an instruction group. Since all those instructions are
4452 in the M group, there is no way such an instruction can
4453 fit in this bundle even if we switch the template. The
4454 reason we have to check for this is that otherwise we
4455 may end up generating "MI;;I M.." which has the deadly
4456 effect that the second M instruction is no longer the
4457 first in the bundle! --davidm 99/12/16 */
4458 && (idesc
->flags
& IA64_OPCODE_FIRST
) == 0)
4461 end_of_insn_group
= 0;
4463 else if (curr
!= first
)
4464 /* can't fit this insn */
4467 if (template != orig_template
)
4468 /* if we switch the template, we need to reset the NOPs
4469 after slot i. The slot-types of the instructions ahead
4470 of i never change, so we don't need to worry about
4471 changing NOPs in front of this slot. */
4472 for (j
= i
; j
< 3; ++j
)
4473 insn
[j
] = nop
[ia64_templ_desc
[template].exec_unit
[j
]];
4475 required_unit
= ia64_templ_desc
[template].exec_unit
[i
];
4477 /* resolve dynamic opcodes such as "break" and "nop": */
4478 if (idesc
->type
== IA64_TYPE_DYN
)
4480 if ((strcmp (idesc
->name
, "nop") == 0)
4481 || (strcmp (idesc
->name
, "break") == 0))
4482 insn_unit
= required_unit
;
4483 else if (strcmp (idesc
->name
, "chk.s") == 0)
4485 insn_unit
= IA64_UNIT_M
;
4486 if (required_unit
== IA64_UNIT_I
)
4487 insn_unit
= IA64_UNIT_I
;
4490 as_fatal ("emit_one_bundle: unexpected dynamic op");
4492 sprintf (mnemonic
, "%s.%c", idesc
->name
, "?imbf??"[insn_unit
]);
4493 md
.slot
[curr
].idesc
= idesc
= ia64_find_opcode (mnemonic
);
4495 know (!idesc
->next
); /* no resolved dynamic ops have collisions */
4500 insn_type
= idesc
->type
;
4501 insn_unit
= IA64_UNIT_NIL
;
4505 if (required_unit
== IA64_UNIT_I
|| required_unit
== IA64_UNIT_M
)
4506 insn_unit
= required_unit
;
4508 case IA64_TYPE_X
: insn_unit
= IA64_UNIT_L
; break;
4509 case IA64_TYPE_I
: insn_unit
= IA64_UNIT_I
; break;
4510 case IA64_TYPE_M
: insn_unit
= IA64_UNIT_M
; break;
4511 case IA64_TYPE_B
: insn_unit
= IA64_UNIT_B
; break;
4512 case IA64_TYPE_F
: insn_unit
= IA64_UNIT_F
; break;
4517 if (insn_unit
!= required_unit
)
4519 if (required_unit
== IA64_UNIT_L
4520 && insn_unit
== IA64_UNIT_I
4521 && !(idesc
->flags
& IA64_OPCODE_X_IN_MLX
))
4523 /* we got ourselves an MLX template but the current
4524 instruction isn't an X-unit, or an I-unit instruction
4525 that can go into the X slot of an MLX template. Duh. */
4526 if (md
.num_slots_in_use
>= NUM_SLOTS
)
4528 as_bad_where (md
.slot
[curr
].src_file
,
4529 md
.slot
[curr
].src_line
,
4530 "`%s' can't go in X slot of "
4531 "MLX template", idesc
->name
);
4532 /* drop this insn so we don't livelock: */
4533 --md
.num_slots_in_use
;
4537 continue; /* try next slot */
4540 if (debug_type
== DEBUG_DWARF2
)
4544 addr
= frag_now
->fr_address
+ frag_now_fix () - 16 + 1*i
;
4545 dwarf2_gen_line_info (addr
, &md
.slot
[curr
].debug_line
);
4548 build_insn (md
.slot
+ curr
, insn
+ i
);
4550 /* Set slot counts for unwind records. */
4551 while (md
.slot
[curr
].unwind_record
)
4553 md
.slot
[curr
].unwind_record
->slot_number
= (unsigned long) (f
+ i
);
4554 md
.slot
[curr
].unwind_record
= md
.slot
[curr
].unwind_record
->next
;
4556 if (required_unit
== IA64_UNIT_L
)
4559 /* skip one slot for long/X-unit instructions */
4562 --md
.num_slots_in_use
;
4564 /* now is a good time to fix up the labels for this insn: */
4565 for (lfix
= md
.slot
[curr
].label_fixups
; lfix
; lfix
= lfix
->next
)
4567 S_SET_VALUE (lfix
->sym
, frag_now_fix () - 16);
4568 symbol_set_frag (lfix
->sym
, frag_now
);
4571 for (j
= 0; j
< md
.slot
[curr
].num_fixups
; ++j
)
4573 ifix
= md
.slot
[curr
].fixup
+ j
;
4574 fix
= fix_new_exp (frag_now
, frag_now_fix () - 16 + i
, 4,
4575 &ifix
->expr
, ifix
->is_pcrel
, ifix
->code
);
4576 fix
->tc_fix_data
.opnd
= ifix
->opnd
;
4577 fix
->fx_plt
= (fix
->fx_r_type
== BFD_RELOC_IA64_PLTOFF22
);
4578 fix
->fx_file
= md
.slot
[curr
].src_file
;
4579 fix
->fx_line
= md
.slot
[curr
].src_line
;
4582 end_of_insn_group
= md
.slot
[curr
].end_of_insn_group
;
4585 ia64_free_opcode (md
.slot
[curr
].idesc
);
4586 memset (md
.slot
+ curr
, 0, sizeof (md
.slot
[curr
]));
4587 md
.slot
[curr
].user_template
= -1;
4589 if (manual_bundling_off
)
4591 manual_bundling
= 0;
4594 curr
= (curr
+ 1) % NUM_SLOTS
;
4595 idesc
= md
.slot
[curr
].idesc
;
4597 if (manual_bundling
)
4599 if (md
.num_slots_in_use
> 0)
4600 as_bad_where (md
.slot
[curr
].src_file
, md
.slot
[curr
].src_line
,
4601 "`%s' does not fit into %s template",
4602 idesc
->name
, ia64_templ_desc
[template].name
);
4604 as_bad_where (md
.slot
[curr
].src_file
, md
.slot
[curr
].src_line
,
4605 "Missing '}' at end of file");
4607 know (md
.num_slots_in_use
< NUM_SLOTS
);
4609 t0
= end_of_insn_group
| (template << 1) | (insn
[0] << 5) | (insn
[1] << 46);
4610 t1
= ((insn
[1] >> 18) & 0x7fffff) | (insn
[2] << 23);
4612 md_number_to_chars (f
+ 0, t0
, 8);
4613 md_number_to_chars (f
+ 8, t1
, 8);
4617 md_parse_option (c
, arg
)
4621 /* Switches from the Intel assembler. */
4625 if (strcmp (arg
, "ilp64") == 0
4626 || strcmp (arg
, "lp64") == 0
4627 || strcmp (arg
, "p64") == 0)
4629 md
.flags
|= EF_IA_64_ABI64
;
4631 else if (strcmp (arg
, "ilp32") == 0)
4633 md
.flags
&= ~EF_IA_64_ABI64
;
4635 else if (strcmp (arg
, "le") == 0)
4637 md
.flags
&= ~EF_IA_64_BE
;
4639 else if (strcmp (arg
, "be") == 0)
4641 md
.flags
|= EF_IA_64_BE
;
4648 if (strcmp (arg
, "so") == 0)
4650 /* Suppress signon message. */
4652 else if (strcmp (arg
, "pi") == 0)
4654 /* Reject privileged instructions. FIXME */
4656 else if (strcmp (arg
, "us") == 0)
4658 /* Allow union of signed and unsigned range. FIXME */
4660 else if (strcmp (arg
, "close_fcalls") == 0)
4662 /* Do not resolve global function calls. */
4669 /* temp[="prefix"] Insert temporary labels into the object file
4670 symbol table prefixed by "prefix".
4671 Default prefix is ":temp:".
4676 /* ??? Conflicts with gas' listing option. */
4677 /* indirect=<tgt> Assume unannotated indirect branches behavior
4678 according to <tgt> --
4679 exit: branch out from the current context (default)
4680 labels: all labels in context may be branch targets
4685 /* -X conflicts with an ignored option, use -x instead */
4687 if (!arg
|| strcmp (arg
, "explicit") == 0)
4689 /* set default mode to explicit */
4690 md
.default_explicit_mode
= 1;
4693 else if (strcmp (arg
, "auto") == 0)
4695 md
.default_explicit_mode
= 0;
4697 else if (strcmp (arg
, "debug") == 0)
4701 else if (strcmp (arg
, "debugx") == 0)
4703 md
.default_explicit_mode
= 1;
4708 as_bad (_("Unrecognized option '-x%s'"), arg
);
4713 /* nops Print nops statistics. */
4724 md_show_usage (stream
)
4729 -Milp32|-Milp64|-Mlp64|-Mp64 select data model (default -Mlp64)\n\
4730 -Mle | -Mbe select little- or big-endian byte order (default -Mle)\n\
4731 -x | -xexplicit turn on dependency violation checking (default)\n\
4732 -xauto automagically remove dependency violations\n\
4733 -xdebug debug dependency violation checker\n"),
4738 match (int templ
, int type
, int slot
)
4740 enum ia64_unit unit
;
4743 unit
= ia64_templ_desc
[templ
].exec_unit
[slot
];
4746 case IA64_TYPE_DYN
: result
= 1; break; /* for nop and break */
4748 result
= (unit
== IA64_UNIT_I
|| unit
== IA64_UNIT_M
);
4750 case IA64_TYPE_X
: result
= (unit
== IA64_UNIT_L
); break;
4751 case IA64_TYPE_I
: result
= (unit
== IA64_UNIT_I
); break;
4752 case IA64_TYPE_M
: result
= (unit
== IA64_UNIT_M
); break;
4753 case IA64_TYPE_B
: result
= (unit
== IA64_UNIT_B
); break;
4754 case IA64_TYPE_F
: result
= (unit
== IA64_UNIT_F
); break;
4755 default: result
= 0; break;
4760 /* This function is called once, at assembler startup time. It sets
4761 up all the tables, etc. that the MD part of the assembler will need
4762 that can be determined before arguments are parsed. */
4766 int i
, j
, k
, t
, total
, ar_base
, cr_base
, goodness
, best
, regnum
;
4771 md
.explicit_mode
= md
.default_explicit_mode
;
4773 bfd_set_section_alignment (stdoutput
, text_section
, 4);
4775 target_big_endian
= 0;
4776 pseudo_func
[FUNC_FPTR_RELATIVE
].u
.sym
=
4777 symbol_new (".<fptr>", undefined_section
, FUNC_FPTR_RELATIVE
,
4778 &zero_address_frag
);
4780 pseudo_func
[FUNC_GP_RELATIVE
].u
.sym
=
4781 symbol_new (".<gprel>", undefined_section
, FUNC_GP_RELATIVE
,
4782 &zero_address_frag
);
4784 pseudo_func
[FUNC_LT_RELATIVE
].u
.sym
=
4785 symbol_new (".<ltoff>", undefined_section
, FUNC_LT_RELATIVE
,
4786 &zero_address_frag
);
4788 pseudo_func
[FUNC_PLT_RELATIVE
].u
.sym
=
4789 symbol_new (".<pltoff>", undefined_section
, FUNC_PLT_RELATIVE
,
4790 &zero_address_frag
);
4792 pseudo_func
[FUNC_SEC_RELATIVE
].u
.sym
=
4793 symbol_new (".<secrel>", undefined_section
, FUNC_SEC_RELATIVE
,
4794 &zero_address_frag
);
4796 pseudo_func
[FUNC_SEG_RELATIVE
].u
.sym
=
4797 symbol_new (".<segrel>", undefined_section
, FUNC_SEG_RELATIVE
,
4798 &zero_address_frag
);
4800 pseudo_func
[FUNC_LTV_RELATIVE
].u
.sym
=
4801 symbol_new (".<ltv>", undefined_section
, FUNC_LTV_RELATIVE
,
4802 &zero_address_frag
);
4804 pseudo_func
[FUNC_LT_FPTR_RELATIVE
].u
.sym
=
4805 symbol_new (".<ltoff.fptr>", undefined_section
, FUNC_LT_FPTR_RELATIVE
,
4806 &zero_address_frag
);
4808 /* compute the table of best templates: */
4809 for (i
= 0; i
< IA64_NUM_TYPES
; ++i
)
4810 for (j
= 0; j
< IA64_NUM_TYPES
; ++j
)
4811 for (k
= 0; k
< IA64_NUM_TYPES
; ++k
)
4814 for (t
= 0; t
< NELEMS (ia64_templ_desc
); ++t
)
4817 if (match (t
, i
, 0))
4819 if (match (t
, j
, 1))
4821 if (match (t
, k
, 2))
4826 else if (match (t
, j
, 2))
4831 else if (match (t
, i
, 1))
4833 if (match (t
, j
, 2))
4838 else if (match (t
, i
, 2))
4841 if (goodness
> best
)
4844 best_template
[i
][j
][k
] = t
;
4849 for (i
= 0; i
< NUM_SLOTS
; ++i
)
4850 md
.slot
[i
].user_template
= -1;
4852 md
.pseudo_hash
= hash_new ();
4853 for (i
= 0; i
< NELEMS (pseudo_opcode
); ++i
)
4855 err
= hash_insert (md
.pseudo_hash
, pseudo_opcode
[i
].name
,
4856 (void *) (pseudo_opcode
+ i
));
4858 as_fatal ("ia64.md_begin: can't hash `%s': %s",
4859 pseudo_opcode
[i
].name
, err
);
4862 md
.reg_hash
= hash_new ();
4863 md
.dynreg_hash
= hash_new ();
4864 md
.const_hash
= hash_new ();
4865 md
.entry_hash
= hash_new ();
4867 /* general registers: */
4870 for (i
= 0; i
< total
; ++i
)
4872 sprintf (name
, "r%d", i
- REG_GR
);
4873 md
.regsym
[i
] = declare_register (name
, i
);
4876 /* floating point registers: */
4878 for (; i
< total
; ++i
)
4880 sprintf (name
, "f%d", i
- REG_FR
);
4881 md
.regsym
[i
] = declare_register (name
, i
);
4884 /* application registers: */
4887 for (; i
< total
; ++i
)
4889 sprintf (name
, "ar%d", i
- REG_AR
);
4890 md
.regsym
[i
] = declare_register (name
, i
);
4893 /* control registers: */
4896 for (; i
< total
; ++i
)
4898 sprintf (name
, "cr%d", i
- REG_CR
);
4899 md
.regsym
[i
] = declare_register (name
, i
);
4902 /* predicate registers: */
4904 for (; i
< total
; ++i
)
4906 sprintf (name
, "p%d", i
- REG_P
);
4907 md
.regsym
[i
] = declare_register (name
, i
);
4910 /* branch registers: */
4912 for (; i
< total
; ++i
)
4914 sprintf (name
, "b%d", i
- REG_BR
);
4915 md
.regsym
[i
] = declare_register (name
, i
);
4918 md
.regsym
[REG_IP
] = declare_register ("ip", REG_IP
);
4919 md
.regsym
[REG_CFM
] = declare_register ("cfm", REG_CFM
);
4920 md
.regsym
[REG_PR
] = declare_register ("pr", REG_PR
);
4921 md
.regsym
[REG_PR_ROT
] = declare_register ("pr.rot", REG_PR_ROT
);
4922 md
.regsym
[REG_PSR
] = declare_register ("psr", REG_PSR
);
4923 md
.regsym
[REG_PSR_L
] = declare_register ("psr.l", REG_PSR_L
);
4924 md
.regsym
[REG_PSR_UM
] = declare_register ("psr.um", REG_PSR_UM
);
4926 for (i
= 0; i
< NELEMS (indirect_reg
); ++i
)
4928 regnum
= indirect_reg
[i
].regnum
;
4929 md
.regsym
[regnum
] = declare_register (indirect_reg
[i
].name
, regnum
);
4932 /* define synonyms for application registers: */
4933 for (i
= REG_AR
; i
< REG_AR
+ NELEMS (ar
); ++i
)
4934 md
.regsym
[i
] = declare_register (ar
[i
- REG_AR
].name
,
4935 REG_AR
+ ar
[i
- REG_AR
].regnum
);
4937 /* define synonyms for control registers: */
4938 for (i
= REG_CR
; i
< REG_CR
+ NELEMS (cr
); ++i
)
4939 md
.regsym
[i
] = declare_register (cr
[i
- REG_CR
].name
,
4940 REG_CR
+ cr
[i
- REG_CR
].regnum
);
4942 declare_register ("gp", REG_GR
+ 1);
4943 declare_register ("sp", REG_GR
+ 12);
4944 declare_register ("rp", REG_BR
+ 0);
4946 declare_register_set ("ret", 4, REG_GR
+ 8);
4947 declare_register_set ("farg", 8, REG_FR
+ 8);
4948 declare_register_set ("fret", 8, REG_FR
+ 8);
4950 for (i
= 0; i
< NELEMS (const_bits
); ++i
)
4952 err
= hash_insert (md
.const_hash
, const_bits
[i
].name
,
4953 (PTR
) (const_bits
+ i
));
4955 as_fatal ("Inserting \"%s\" into constant hash table failed: %s",
4959 /* Default to 64-bit mode. */
4960 md
.flags
= EF_IA_64_ABI64
;
4962 md
.mem_offset
.hint
= 0;
4965 md
.entry_labels
= NULL
;
4969 ia64_end_of_source ()
4971 /* terminate insn group upon reaching end of file: */
4972 insn_group_break (1, 0, 0);
4974 /* emits slots we haven't written yet: */
4975 ia64_flush_insns ();
4977 bfd_set_private_flags (stdoutput
, md
.flags
);
4979 if (debug_type
== DEBUG_DWARF2
)
4982 md
.mem_offset
.hint
= 0;
4988 md
.qp
.X_op
= O_absent
;
4990 if (ignore_input ())
4993 if (input_line_pointer
[0] == ';' && input_line_pointer
[-1] == ';')
4995 if (md
.detect_dv
&& !md
.explicit_mode
)
4996 as_warn (_("Explicit stops are ignored in auto mode"));
4998 insn_group_break (1, 0, 0);
5003 ia64_unrecognized_line (ch
)
5009 expression (&md
.qp
);
5010 if (*input_line_pointer
++ != ')')
5012 as_bad ("Expected ')'");
5015 if (md
.qp
.X_op
!= O_register
)
5017 as_bad ("Qualifying predicate expected");
5020 if (md
.qp
.X_add_number
< REG_P
|| md
.qp
.X_add_number
>= REG_P
+ 64)
5022 as_bad ("Predicate register expected");
5028 if (md
.manual_bundling
)
5029 as_warn ("Found '{' when manual bundling is already turned on");
5031 CURR_SLOT
.manual_bundling_on
= 1;
5032 md
.manual_bundling
= 1;
5034 /* bundling is only acceptable in explicit mode
5035 or when in default automatic mode */
5036 if (md
.detect_dv
&& !md
.explicit_mode
)
5038 if (!md
.mode_explicitly_set
5039 && !md
.default_explicit_mode
)
5042 as_warn (_("Found '{' after explicit switch to automatic mode"));
5047 if (!md
.manual_bundling
)
5048 as_warn ("Found '}' when manual bundling is off");
5050 PREV_SLOT
.manual_bundling_off
= 1;
5051 md
.manual_bundling
= 0;
5053 /* switch back to automatic mode, if applicable */
5056 && !md
.mode_explicitly_set
5057 && !md
.default_explicit_mode
)
5060 /* Allow '{' to follow on the same line. We also allow ";;", but that
5061 happens automatically because ';' is an end of line marker. */
5063 if (input_line_pointer
[0] == '{')
5065 input_line_pointer
++;
5066 return ia64_unrecognized_line ('{');
5069 demand_empty_rest_of_line ();
5075 return 0; /* not a valid line */
5079 ia64_frob_label (sym
)
5082 struct label_fix
*fix
;
5084 if (bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
)
5086 md
.last_text_seg
= now_seg
;
5087 fix
= obstack_alloc (¬es
, sizeof (*fix
));
5089 fix
->next
= CURR_SLOT
.label_fixups
;
5090 CURR_SLOT
.label_fixups
= fix
;
5092 /* keep track of how many code entry points we've seen */
5093 if (md
.path
== md
.maxpaths
)
5096 md
.entry_labels
= (const char **)
5097 xrealloc ((void *)md
.entry_labels
, md
.maxpaths
* sizeof (char *));
5099 md
.entry_labels
[md
.path
++] = S_GET_NAME (sym
);
5104 ia64_flush_pending_output ()
5106 if (bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
)
5108 /* ??? This causes many unnecessary stop bits to be emitted.
5109 Unfortunately, it isn't clear if it is safe to remove this. */
5110 insn_group_break (1, 0, 0);
5111 ia64_flush_insns ();
5115 /* Do ia64-specific expression optimization. All that's done here is
5116 to transform index expressions that are either due to the indexing
5117 of rotating registers or due to the indexing of indirect register
5120 ia64_optimize_expr (l
, op
, r
)
5129 if (l
->X_op
== O_register
&& r
->X_op
== O_constant
)
5131 num_regs
= (l
->X_add_number
>> 16);
5132 if ((unsigned) r
->X_add_number
>= num_regs
)
5135 as_bad ("No current frame");
5137 as_bad ("Index out of range 0..%u", num_regs
- 1);
5138 r
->X_add_number
= 0;
5140 l
->X_add_number
= (l
->X_add_number
& 0xffff) + r
->X_add_number
;
5143 else if (l
->X_op
== O_register
&& r
->X_op
== O_register
)
5145 if (l
->X_add_number
< IND_CPUID
|| l
->X_add_number
> IND_RR
5146 || l
->X_add_number
== IND_MEM
)
5148 as_bad ("Indirect register set name expected");
5149 l
->X_add_number
= IND_CPUID
;
5152 l
->X_op_symbol
= md
.regsym
[l
->X_add_number
];
5153 l
->X_add_number
= r
->X_add_number
;
5161 ia64_parse_name (name
, e
)
5165 struct const_desc
*cdesc
;
5166 struct dynreg
*dr
= 0;
5167 unsigned int regnum
;
5171 /* first see if NAME is a known register name: */
5172 sym
= hash_find (md
.reg_hash
, name
);
5175 e
->X_op
= O_register
;
5176 e
->X_add_number
= S_GET_VALUE (sym
);
5180 cdesc
= hash_find (md
.const_hash
, name
);
5183 e
->X_op
= O_constant
;
5184 e
->X_add_number
= cdesc
->value
;
5188 /* check for inN, locN, or outN: */
5192 if (name
[1] == 'n' && isdigit (name
[2]))
5200 if (name
[1] == 'o' && name
[2] == 'c' && isdigit (name
[3]))
5208 if (name
[1] == 'u' && name
[2] == 't' && isdigit (name
[3]))
5221 /* the name is inN, locN, or outN; parse the register number: */
5222 regnum
= strtoul (name
, &end
, 10);
5223 if (end
> name
&& *end
== '\0')
5225 if ((unsigned) regnum
>= dr
->num_regs
)
5228 as_bad ("No current frame");
5230 as_bad ("Register number out of range 0..%u", dr
->num_regs
-1);
5233 e
->X_op
= O_register
;
5234 e
->X_add_number
= dr
->base
+ regnum
;
5239 if ((dr
= hash_find (md
.dynreg_hash
, name
)))
5241 /* We've got ourselves the name of a rotating register set.
5242 Store the base register number in the low 16 bits of
5243 X_add_number and the size of the register set in the top 16
5245 e
->X_op
= O_register
;
5246 e
->X_add_number
= dr
->base
| (dr
->num_regs
<< 16);
5252 /* Remove the '#' suffix that indicates a symbol as opposed to a register. */
5255 ia64_canonicalize_symbol_name (name
)
5258 size_t len
= strlen(name
);
5259 if (len
> 1 && name
[len
-1] == '#')
5265 is_conditional_branch (idesc
)
5266 struct ia64_opcode
*idesc
;
5268 return (strncmp (idesc
->name
, "br", 2) == 0
5269 && (strcmp (idesc
->name
, "br") == 0
5270 || strncmp (idesc
->name
, "br.cond", 7) == 0
5271 || strncmp (idesc
->name
, "br.call", 7) == 0
5272 || strncmp (idesc
->name
, "br.ret", 6) == 0
5273 || strcmp (idesc
->name
, "brl") == 0
5274 || strncmp (idesc
->name
, "brl.cond", 7) == 0
5275 || strncmp (idesc
->name
, "brl.call", 7) == 0
5276 || strncmp (idesc
->name
, "brl.ret", 6) == 0));
5279 /* Return whether the given opcode is a taken branch. If there's any doubt,
5282 is_taken_branch (idesc
)
5283 struct ia64_opcode
*idesc
;
5285 return ((is_conditional_branch (idesc
) && CURR_SLOT
.qp_regno
== 0)
5286 || strncmp (idesc
->name
, "br.ia", 5) == 0);
5289 /* Return whether the given opcode is an interruption or rfi. If there's any
5290 doubt, returns zero */
5292 is_interruption_or_rfi (idesc
)
5293 struct ia64_opcode
*idesc
;
5295 if (strcmp (idesc
->name
, "rfi") == 0)
5300 /* Returns the index of the given dependency in the opcode's list of chks, or
5301 -1 if there is no dependency. */
5303 depends_on (depind
, idesc
)
5305 struct ia64_opcode
*idesc
;
5308 const struct ia64_opcode_dependency
*dep
= idesc
->dependencies
;
5309 for (i
= 0;i
< dep
->nchks
; i
++)
5311 if (depind
== DEP(dep
->chks
[i
]))
5317 /* Determine a set of specific resources used for a particular resource
5318 class. Returns the number of specific resources identified For those
5319 cases which are not determinable statically, the resource returned is
5322 Meanings of value in 'NOTE':
5323 1) only read/write when the register number is explicitly encoded in the
5325 2) only read CFM when accessing a rotating GR, FR, or PR. mov pr only
5326 accesses CFM when qualifying predicate is in the rotating region.
5327 3) general register value is used to specify an indirect register; not
5328 determinable statically.
5329 4) only read the given resource when bits 7:0 of the indirect index
5330 register value does not match the register number of the resource; not
5331 determinable statically.
5332 5) all rules are implementation specific.
5333 6) only when both the index specified by the reader and the index specified
5334 by the writer have the same value in bits 63:61; not determinable
5336 7) only access the specified resource when the corresponding mask bit is
5338 8) PSR.dfh is only read when these insns reference FR32-127. PSR.dfl is
5339 only read when these insns reference FR2-31
5340 9) PSR.mfl is only written when these insns write FR2-31. PSR.mfh is only
5341 written when these insns write FR32-127
5342 10) The PSR.bn bit is only accessed when one of GR16-31 is specified in the
5344 11) The target predicates are written independently of PR[qp], but source
5345 registers are only read if PR[qp] is true. Since the state of PR[qp]
5346 cannot statically be determined, all source registers are marked used.
5347 12) This insn only reads the specified predicate register when that
5348 register is the PR[qp].
5349 13) This reference to ld-c only applies to teh GR whose value is loaded
5350 with data returned from memory, not the post-incremented address register.
5351 14) The RSE resource includes the implementation-specific RSE internal
5352 state resources. At least one (and possibly more) of these resources are
5353 read by each instruction listed in IC:rse-readers. At least one (and
5354 possibly more) of these resources are written by each insn listed in
5356 15+16) Represents reserved instructions, which the assembler does not
5359 Memory resources (i.e. locations in memory) are *not* marked or tracked by
5360 this code; there are no dependency violations based on memory access.
5364 #define MAX_SPECS 256
5369 specify_resource (dep
, idesc
, type
, specs
, note
, path
)
5370 const struct ia64_dependency
*dep
;
5371 struct ia64_opcode
*idesc
;
5372 int type
; /* is this a DV chk or a DV reg? */
5373 struct rsrc specs
[MAX_SPECS
]; /* returned specific resources */
5374 int note
; /* resource note for this insn's usage */
5375 int path
; /* which execution path to examine */
5382 if (dep
->mode
== IA64_DV_WAW
5383 || (dep
->mode
== IA64_DV_RAW
&& type
== DV_REG
)
5384 || (dep
->mode
== IA64_DV_WAR
&& type
== DV_CHK
))
5387 /* template for any resources we identify */
5388 tmpl
.dependency
= dep
;
5390 tmpl
.insn_srlz
= tmpl
.data_srlz
= 0;
5391 tmpl
.qp_regno
= CURR_SLOT
.qp_regno
;
5392 tmpl
.link_to_qp_branch
= 1;
5393 tmpl
.mem_offset
.hint
= 0;
5398 as_warn (_("Unhandled dependency %s for %s (%s), note %d"), \
5399 dep->name, idesc->name, (rsrc_write?"write":"read"), note)
5400 #define KNOWN(REG) (gr_values[REG].known && gr_values[REG].path >= path)
5402 /* we don't need to track these */
5403 if (dep
->semantics
== IA64_DVS_NONE
)
5406 switch (dep
->specifier
)
5411 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_AR3
)
5413 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_AR
;
5414 if (regno
>= 0 && regno
<= 7)
5416 specs
[count
] = tmpl
;
5417 specs
[count
++].index
= regno
;
5425 specs
[count
] = tmpl
;
5426 specs
[count
++].index
= i
;
5435 case IA64_RS_AR_UNAT
:
5436 /* This is a mov =AR or mov AR= instruction. */
5437 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_AR3
)
5439 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_AR
;
5440 if (regno
== AR_UNAT
)
5442 specs
[count
++] = tmpl
;
5447 /* This is a spill/fill, or other instruction that modifies the
5450 /* Unless we can determine the specific bits used, mark the whole
5451 thing; bits 8:3 of the memory address indicate the bit used in
5452 UNAT. The .mem.offset hint may be used to eliminate a small
5453 subset of conflicts. */
5454 specs
[count
] = tmpl
;
5455 if (md
.mem_offset
.hint
)
5458 fprintf (stderr
, " Using hint for spill/fill\n");
5459 /* the index isn't actually used, just set it to something
5460 approximating the bit index */
5461 specs
[count
].index
= (md
.mem_offset
.offset
>> 3) & 0x3F;
5462 specs
[count
].mem_offset
.hint
= 1;
5463 specs
[count
].mem_offset
.offset
= md
.mem_offset
.offset
;
5464 specs
[count
++].mem_offset
.base
= md
.mem_offset
.base
;
5468 specs
[count
++].specific
= 0;
5476 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_AR3
)
5478 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_AR
;
5479 if ((regno
>= 8 && regno
<= 15)
5480 || (regno
>= 20 && regno
<= 23)
5481 || (regno
>= 31 && regno
<= 39)
5482 || (regno
>= 41 && regno
<= 47)
5483 || (regno
>= 67 && regno
<= 111))
5485 specs
[count
] = tmpl
;
5486 specs
[count
++].index
= regno
;
5499 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_AR3
)
5501 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_AR
;
5502 if ((regno
>= 48 && regno
<= 63)
5503 || (regno
>= 112 && regno
<= 127))
5505 specs
[count
] = tmpl
;
5506 specs
[count
++].index
= regno
;
5512 for (i
=48;i
< 64;i
++)
5514 specs
[count
] = tmpl
;
5515 specs
[count
++].index
= i
;
5517 for (i
=112;i
< 128;i
++)
5519 specs
[count
] = tmpl
;
5520 specs
[count
++].index
= i
;
5538 for (i
=0;i
< idesc
->num_outputs
;i
++)
5539 if (idesc
->operands
[i
] == IA64_OPND_B1
5540 || idesc
->operands
[i
] == IA64_OPND_B2
)
5542 specs
[count
] = tmpl
;
5543 specs
[count
++].index
=
5544 CURR_SLOT
.opnd
[i
].X_add_number
- REG_BR
;
5549 for (i
= idesc
->num_outputs
;i
< NELEMS(idesc
->operands
);i
++)
5550 if (idesc
->operands
[i
] == IA64_OPND_B1
5551 || idesc
->operands
[i
] == IA64_OPND_B2
)
5553 specs
[count
] = tmpl
;
5554 specs
[count
++].index
=
5555 CURR_SLOT
.opnd
[i
].X_add_number
- REG_BR
;
5561 case IA64_RS_CPUID
: /* four or more registers */
5564 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_CPUID_R3
)
5566 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_GR
;
5567 if (regno
>= 0 && regno
< NELEMS(gr_values
)
5570 specs
[count
] = tmpl
;
5571 specs
[count
++].index
= gr_values
[regno
].value
& 0xFF;
5575 specs
[count
] = tmpl
;
5576 specs
[count
++].specific
= 0;
5586 case IA64_RS_DBR
: /* four or more registers */
5589 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_DBR_R3
)
5591 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_GR
;
5592 if (regno
>= 0 && regno
< NELEMS(gr_values
)
5595 specs
[count
] = tmpl
;
5596 specs
[count
++].index
= gr_values
[regno
].value
& 0xFF;
5600 specs
[count
] = tmpl
;
5601 specs
[count
++].specific
= 0;
5605 else if (note
== 0 && !rsrc_write
)
5607 specs
[count
] = tmpl
;
5608 specs
[count
++].specific
= 0;
5616 case IA64_RS_IBR
: /* four or more registers */
5619 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_IBR_R3
)
5621 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_GR
;
5622 if (regno
>= 0 && regno
< NELEMS(gr_values
)
5625 specs
[count
] = tmpl
;
5626 specs
[count
++].index
= gr_values
[regno
].value
& 0xFF;
5630 specs
[count
] = tmpl
;
5631 specs
[count
++].specific
= 0;
5644 /* These are implementation specific. Force all references to
5645 conflict with all other references. */
5646 specs
[count
] = tmpl
;
5647 specs
[count
++].specific
= 0;
5655 case IA64_RS_PKR
: /* 16 or more registers */
5656 if (note
== 3 || note
== 4)
5658 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_PKR_R3
)
5660 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_GR
;
5661 if (regno
>= 0 && regno
< NELEMS(gr_values
)
5666 specs
[count
] = tmpl
;
5667 specs
[count
++].index
= gr_values
[regno
].value
& 0xFF;
5669 else for (i
=0;i
< NELEMS(gr_values
);i
++)
5671 /* uses all registers *except* the one in R3 */
5672 if (i
!= (gr_values
[regno
].value
& 0xFF))
5674 specs
[count
] = tmpl
;
5675 specs
[count
++].index
= i
;
5681 specs
[count
] = tmpl
;
5682 specs
[count
++].specific
= 0;
5689 specs
[count
] = tmpl
;
5690 specs
[count
++].specific
= 0;
5694 case IA64_RS_PMC
: /* four or more registers */
5697 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_PMC_R3
5698 || (!rsrc_write
&& idesc
->operands
[1] == IA64_OPND_PMD_R3
))
5701 int index
= ((idesc
->operands
[1] == IA64_OPND_R3
&& !rsrc_write
)
5703 int regno
= CURR_SLOT
.opnd
[index
].X_add_number
- REG_GR
;
5704 if (regno
>= 0 && regno
< NELEMS(gr_values
)
5707 specs
[count
] = tmpl
;
5708 specs
[count
++].index
= gr_values
[regno
].value
& 0xFF;
5712 specs
[count
] = tmpl
;
5713 specs
[count
++].specific
= 0;
5723 case IA64_RS_PMD
: /* four or more registers */
5726 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_PMD_R3
)
5728 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_GR
;
5729 if (regno
>= 0 && regno
< NELEMS(gr_values
)
5732 specs
[count
] = tmpl
;
5733 specs
[count
++].index
= gr_values
[regno
].value
& 0xFF;
5737 specs
[count
] = tmpl
;
5738 specs
[count
++].specific
= 0;
5748 case IA64_RS_RR
: /* eight registers */
5751 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_RR_R3
)
5753 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_GR
;
5754 if (regno
>= 0 && regno
< NELEMS(gr_values
)
5757 specs
[count
] = tmpl
;
5758 specs
[count
++].index
= (gr_values
[regno
].value
>> 61) & 0x7;
5762 specs
[count
] = tmpl
;
5763 specs
[count
++].specific
= 0;
5767 else if (note
== 0 && !rsrc_write
)
5769 specs
[count
] = tmpl
;
5770 specs
[count
++].specific
= 0;
5778 case IA64_RS_CR_IRR
:
5781 /* handle mov-from-CR-IVR; it's a read that writes CR[IRR] */
5782 int regno
= CURR_SLOT
.opnd
[1].X_add_number
- REG_CR
;
5784 && idesc
->operands
[1] == IA64_OPND_CR3
5789 specs
[count
] = tmpl
;
5790 specs
[count
++].index
= CR_IRR0
+ i
;
5796 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_CR
;
5797 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_CR3
5799 && regno
<= CR_IRR3
)
5801 specs
[count
] = tmpl
;
5802 specs
[count
++].index
= regno
;
5811 case IA64_RS_CR_LRR
:
5818 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_CR
;
5819 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_CR3
5820 && (regno
== CR_LRR0
|| regno
== CR_LRR1
))
5822 specs
[count
] = tmpl
;
5823 specs
[count
++].index
= regno
;
5831 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_CR3
)
5833 specs
[count
] = tmpl
;
5834 specs
[count
++].index
=
5835 CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_CR
;
5850 else if (rsrc_write
)
5852 if (dep
->specifier
== IA64_RS_FRb
5853 && idesc
->operands
[0] == IA64_OPND_F1
)
5855 specs
[count
] = tmpl
;
5856 specs
[count
++].index
= CURR_SLOT
.opnd
[0].X_add_number
- REG_FR
;
5861 for (i
=idesc
->num_outputs
;i
< NELEMS(idesc
->operands
);i
++)
5863 if (idesc
->operands
[i
] == IA64_OPND_F2
5864 || idesc
->operands
[i
] == IA64_OPND_F3
5865 || idesc
->operands
[i
] == IA64_OPND_F4
)
5867 specs
[count
] = tmpl
;
5868 specs
[count
++].index
=
5869 CURR_SLOT
.opnd
[i
].X_add_number
- REG_FR
;
5878 /* This reference applies only to the GR whose value is loaded with
5879 data returned from memory */
5880 specs
[count
] = tmpl
;
5881 specs
[count
++].index
= CURR_SLOT
.opnd
[0].X_add_number
- REG_GR
;
5887 for (i
=0;i
< idesc
->num_outputs
;i
++)
5889 if (idesc
->operands
[i
] == IA64_OPND_R1
5890 || idesc
->operands
[i
] == IA64_OPND_R2
5891 || idesc
->operands
[i
] == IA64_OPND_R3
)
5893 specs
[count
] = tmpl
;
5894 specs
[count
++].index
=
5895 CURR_SLOT
.opnd
[i
].X_add_number
- REG_GR
;
5901 /* Look for anything that reads a GR */
5902 for (i
=0;i
< NELEMS(idesc
->operands
);i
++)
5904 if (idesc
->operands
[i
] == IA64_OPND_MR3
5905 || idesc
->operands
[i
] == IA64_OPND_CPUID_R3
5906 || idesc
->operands
[i
] == IA64_OPND_DBR_R3
5907 || idesc
->operands
[i
] == IA64_OPND_IBR_R3
5908 || idesc
->operands
[i
] == IA64_OPND_MSR_R3
5909 || idesc
->operands
[i
] == IA64_OPND_PKR_R3
5910 || idesc
->operands
[i
] == IA64_OPND_PMC_R3
5911 || idesc
->operands
[i
] == IA64_OPND_PMD_R3
5912 || idesc
->operands
[i
] == IA64_OPND_RR_R3
5913 || ((i
>= idesc
->num_outputs
)
5914 && (idesc
->operands
[i
] == IA64_OPND_R1
5915 || idesc
->operands
[i
] == IA64_OPND_R2
5916 || idesc
->operands
[i
] == IA64_OPND_R3
)))
5918 specs
[count
] = tmpl
;
5919 specs
[count
++].index
=
5920 CURR_SLOT
.opnd
[i
].X_add_number
- REG_GR
;
5934 if (idesc
->operands
[0] == IA64_OPND_PR_ROT
)
5936 for (i
=16;i
< 63;i
++)
5938 specs
[count
] = tmpl
;
5939 specs
[count
++].index
= i
;
5944 for (i
=1;i
< 63;i
++)
5946 specs
[count
] = tmpl
;
5947 specs
[count
++].index
= i
;
5954 /* mark only those registers indicated by the mask */
5956 && idesc
->operands
[0] == IA64_OPND_PR
)
5958 mask
= CURR_SLOT
.opnd
[2].X_add_number
;
5959 if (mask
& ((valueT
)1<<16))
5960 mask
|= ~(valueT
)0xffff;
5961 for (i
=1;i
< 63;i
++)
5963 if (mask
& ((valueT
)1<<i
))
5965 specs
[count
] = tmpl
;
5966 specs
[count
++].index
= i
;
5971 && idesc
->operands
[0] == IA64_OPND_PR_ROT
)
5973 for (i
=16;i
< 63;i
++)
5975 specs
[count
] = tmpl
;
5976 specs
[count
++].index
= i
;
5984 else if (note
== 11) /* note 11 implies note 1 as well */
5988 for (i
=0;i
< idesc
->num_outputs
;i
++)
5990 if (idesc
->operands
[i
] == IA64_OPND_P1
5991 || idesc
->operands
[i
] == IA64_OPND_P2
)
5993 int regno
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_P
;
5996 specs
[count
] = tmpl
;
5997 specs
[count
++].index
= regno
;
6007 else if (note
== 12)
6009 if (CURR_SLOT
.qp_regno
!= 0)
6011 specs
[count
] = tmpl
;
6012 specs
[count
++].index
= CURR_SLOT
.qp_regno
;
6019 int p1
= CURR_SLOT
.opnd
[0].X_add_number
- REG_P
;
6020 int p2
= CURR_SLOT
.opnd
[1].X_add_number
- REG_P
;
6021 if ((idesc
->operands
[0] == IA64_OPND_P1
6022 || idesc
->operands
[0] == IA64_OPND_P2
)
6023 && p1
!= 0 && p1
!= 63)
6025 specs
[count
] = tmpl
;
6026 specs
[count
++].index
= p1
;
6028 if ((idesc
->operands
[1] == IA64_OPND_P1
6029 || idesc
->operands
[1] == IA64_OPND_P2
)
6030 && p2
!= 0 && p2
!= 63)
6032 specs
[count
] = tmpl
;
6033 specs
[count
++].index
= p2
;
6038 if (CURR_SLOT
.qp_regno
!= 0)
6040 specs
[count
] = tmpl
;
6041 specs
[count
++].index
= CURR_SLOT
.qp_regno
;
6043 if (idesc
->operands
[1] == IA64_OPND_PR
)
6045 for (i
=1;i
< 63;i
++)
6047 specs
[count
] = tmpl
;
6048 specs
[count
++].index
= i
;
6060 /* Verify that the instruction is using the PSR bit indicated in
6064 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_PSR_UM
)
6066 if (dep
->regindex
< 6)
6068 specs
[count
++] = tmpl
;
6071 else if (idesc
->operands
[!rsrc_write
] == IA64_OPND_PSR
)
6073 if (dep
->regindex
< 32
6074 || dep
->regindex
== 35
6075 || dep
->regindex
== 36
6076 || (!rsrc_write
&& dep
->regindex
== PSR_CPL
))
6078 specs
[count
++] = tmpl
;
6081 else if (idesc
->operands
[!rsrc_write
] == IA64_OPND_PSR_L
)
6083 if (dep
->regindex
< 32
6084 || dep
->regindex
== 35
6085 || dep
->regindex
== 36
6086 || (rsrc_write
&& dep
->regindex
== PSR_CPL
))
6088 specs
[count
++] = tmpl
;
6093 /* Several PSR bits have very specific dependencies. */
6094 switch (dep
->regindex
)
6097 specs
[count
++] = tmpl
;
6102 specs
[count
++] = tmpl
;
6106 /* Only certain CR accesses use PSR.ic */
6107 if (idesc
->operands
[0] == IA64_OPND_CR3
6108 || idesc
->operands
[1] == IA64_OPND_CR3
)
6111 ((idesc
->operands
[0] == IA64_OPND_CR3
)
6114 CURR_SLOT
.opnd
[index
].X_add_number
- REG_CR
;
6129 specs
[count
++] = tmpl
;
6138 specs
[count
++] = tmpl
;
6142 /* Only some AR accesses use cpl */
6143 if (idesc
->operands
[0] == IA64_OPND_AR3
6144 || idesc
->operands
[1] == IA64_OPND_AR3
)
6147 ((idesc
->operands
[0] == IA64_OPND_AR3
)
6150 CURR_SLOT
.opnd
[index
].X_add_number
- REG_AR
;
6157 && regno
<= AR_K7
))))
6159 specs
[count
++] = tmpl
;
6164 specs
[count
++] = tmpl
;
6174 if (idesc
->operands
[0] == IA64_OPND_IMMU24
)
6176 mask
= CURR_SLOT
.opnd
[0].X_add_number
;
6182 if (mask
& ((valueT
)1<<dep
->regindex
))
6184 specs
[count
++] = tmpl
;
6189 int min
= dep
->regindex
== PSR_DFL
? 2 : 32;
6190 int max
= dep
->regindex
== PSR_DFL
? 31 : 127;
6191 /* dfh is read on FR32-127; dfl is read on FR2-31 */
6192 for (i
=0;i
< NELEMS(idesc
->operands
);i
++)
6194 if (idesc
->operands
[i
] == IA64_OPND_F1
6195 || idesc
->operands
[i
] == IA64_OPND_F2
6196 || idesc
->operands
[i
] == IA64_OPND_F3
6197 || idesc
->operands
[i
] == IA64_OPND_F4
)
6199 int reg
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_FR
;
6200 if (reg
>= min
&& reg
<= max
)
6202 specs
[count
++] = tmpl
;
6209 int min
= dep
->regindex
== PSR_MFL
? 2 : 32;
6210 int max
= dep
->regindex
== PSR_MFL
? 31 : 127;
6211 /* mfh is read on writes to FR32-127; mfl is read on writes to
6213 for (i
=0;i
< idesc
->num_outputs
;i
++)
6215 if (idesc
->operands
[i
] == IA64_OPND_F1
)
6217 int reg
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_FR
;
6218 if (reg
>= min
&& reg
<= max
)
6220 specs
[count
++] = tmpl
;
6225 else if (note
== 10)
6227 for (i
=0;i
< NELEMS(idesc
->operands
);i
++)
6229 if (idesc
->operands
[i
] == IA64_OPND_R1
6230 || idesc
->operands
[i
] == IA64_OPND_R2
6231 || idesc
->operands
[i
] == IA64_OPND_R3
)
6233 int regno
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_GR
;
6234 if (regno
>= 16 && regno
<= 31)
6236 specs
[count
++] = tmpl
;
6247 case IA64_RS_AR_FPSR
:
6248 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_AR3
)
6250 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_AR
;
6251 if (regno
== AR_FPSR
)
6253 specs
[count
++] = tmpl
;
6258 specs
[count
++] = tmpl
;
6263 /* Handle all AR[REG] resources */
6264 if (note
== 0 || note
== 1)
6266 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_AR
;
6267 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_AR3
6268 && regno
== dep
->regindex
)
6270 specs
[count
++] = tmpl
;
6272 /* other AR[REG] resources may be affected by AR accesses */
6273 else if (idesc
->operands
[0] == IA64_OPND_AR3
)
6276 regno
= CURR_SLOT
.opnd
[0].X_add_number
- REG_AR
;
6277 switch (dep
->regindex
)
6283 if (regno
== AR_BSPSTORE
)
6285 specs
[count
++] = tmpl
;
6289 (regno
== AR_BSPSTORE
6290 || regno
== AR_RNAT
))
6292 specs
[count
++] = tmpl
;
6297 else if (idesc
->operands
[1] == IA64_OPND_AR3
)
6300 regno
= CURR_SLOT
.opnd
[1].X_add_number
- REG_AR
;
6301 switch (dep
->regindex
)
6306 if (regno
== AR_BSPSTORE
|| regno
== AR_RNAT
)
6308 specs
[count
++] = tmpl
;
6315 specs
[count
++] = tmpl
;
6325 /* Handle all CR[REG] resources */
6326 if (note
== 0 || note
== 1)
6328 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_CR3
)
6330 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_CR
;
6331 if (regno
== dep
->regindex
)
6333 specs
[count
++] = tmpl
;
6335 else if (!rsrc_write
)
6337 /* Reads from CR[IVR] affect other resources. */
6338 if (regno
== CR_IVR
)
6340 if ((dep
->regindex
>= CR_IRR0
6341 && dep
->regindex
<= CR_IRR3
)
6342 || dep
->regindex
== CR_TPR
)
6344 specs
[count
++] = tmpl
;
6351 specs
[count
++] = tmpl
;
6360 case IA64_RS_INSERVICE
:
6361 /* look for write of EOI (67) or read of IVR (65) */
6362 if ((idesc
->operands
[0] == IA64_OPND_CR3
6363 && CURR_SLOT
.opnd
[0].X_add_number
- REG_CR
== CR_EOI
)
6364 || (idesc
->operands
[1] == IA64_OPND_CR3
6365 && CURR_SLOT
.opnd
[1].X_add_number
- REG_CR
== CR_IVR
))
6367 specs
[count
++] = tmpl
;
6374 specs
[count
++] = tmpl
;
6385 specs
[count
++] = tmpl
;
6389 /* Check if any of the registers accessed are in the rotating region.
6390 mov to/from pr accesses CFM only when qp_regno is in the rotating
6392 for (i
=0;i
< NELEMS(idesc
->operands
);i
++)
6394 if (idesc
->operands
[i
] == IA64_OPND_R1
6395 || idesc
->operands
[i
] == IA64_OPND_R2
6396 || idesc
->operands
[i
] == IA64_OPND_R3
)
6398 int num
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_GR
;
6399 /* Assumes that md.rot.num_regs is always valid */
6400 if (md
.rot
.num_regs
> 0
6402 && num
< 31 + md
.rot
.num_regs
)
6404 specs
[count
] = tmpl
;
6405 specs
[count
++].specific
= 0;
6408 else if (idesc
->operands
[i
] == IA64_OPND_F1
6409 || idesc
->operands
[i
] == IA64_OPND_F2
6410 || idesc
->operands
[i
] == IA64_OPND_F3
6411 || idesc
->operands
[i
] == IA64_OPND_F4
)
6413 int num
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_FR
;
6416 specs
[count
] = tmpl
;
6417 specs
[count
++].specific
= 0;
6420 else if (idesc
->operands
[i
] == IA64_OPND_P1
6421 || idesc
->operands
[i
] == IA64_OPND_P2
)
6423 int num
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_P
;
6426 specs
[count
] = tmpl
;
6427 specs
[count
++].specific
= 0;
6431 if (CURR_SLOT
.qp_regno
> 15)
6433 specs
[count
] = tmpl
;
6434 specs
[count
++].specific
= 0;
6442 specs
[count
++] = tmpl
;
6444 else if (note
== 11)
6446 if ((idesc
->operands
[0] == IA64_OPND_P1
6447 && CURR_SLOT
.opnd
[0].X_add_number
- REG_P
== 63)
6448 || (idesc
->operands
[1] == IA64_OPND_P2
6449 && CURR_SLOT
.opnd
[1].X_add_number
- REG_P
== 63))
6451 specs
[count
++] = tmpl
;
6454 else if (note
== 12)
6456 if (CURR_SLOT
.qp_regno
== 63)
6458 specs
[count
++] = tmpl
;
6464 if (idesc
->operands
[2] == IA64_OPND_IMM17
)
6465 mask
= CURR_SLOT
.opnd
[2].X_add_number
;
6466 if (mask
& ((valueT
)1<<63))
6468 specs
[count
++] = tmpl
;
6475 for (i
=0;i
< idesc
->num_outputs
;i
++)
6476 if ((idesc
->operands
[i
] == IA64_OPND_P1
6477 || idesc
->operands
[i
] == IA64_OPND_P2
)
6478 && CURR_SLOT
.opnd
[i
].X_add_number
- REG_P
== 63)
6480 specs
[count
++] = tmpl
;
6485 if (CURR_SLOT
.qp_regno
== 63)
6487 specs
[count
++] = tmpl
;
6498 /* FIXME we can identify some individual RSE written resources, but RSE
6499 read resources have not yet been completely identified, so for now
6500 treat RSE as a single resource */
6501 if (strncmp (idesc
->name
, "mov", 3) == 0)
6505 if (idesc
->operands
[0] == IA64_OPND_AR3
6506 && CURR_SLOT
.opnd
[0].X_add_number
- REG_AR
== AR_BSPSTORE
)
6508 specs
[count
] = tmpl
;
6509 specs
[count
++].index
= 0; /* IA64_RSE_BSPLOAD/RNATBITINDEX */
6514 if (idesc
->operands
[0] == IA64_OPND_AR3
)
6516 if (CURR_SLOT
.opnd
[0].X_add_number
- REG_AR
== AR_BSPSTORE
6517 || CURR_SLOT
.opnd
[0].X_add_number
- REG_AR
== AR_RNAT
)
6519 specs
[count
++] = tmpl
;
6522 else if (idesc
->operands
[1] == IA64_OPND_AR3
)
6524 if (CURR_SLOT
.opnd
[1].X_add_number
- REG_AR
== AR_BSP
6525 || CURR_SLOT
.opnd
[1].X_add_number
- REG_AR
== AR_BSPSTORE
6526 || CURR_SLOT
.opnd
[1].X_add_number
- REG_AR
== AR_RNAT
)
6528 specs
[count
++] = tmpl
;
6535 specs
[count
++] = tmpl
;
6540 /* FIXME -- do any of these need to be non-specific? */
6541 specs
[count
++] = tmpl
;
6545 as_bad (_("Unrecognized dependency specifier %d\n"), dep
->specifier
);
6552 /* Clear branch flags on marked resources. This breaks the link between the
6553 QP of the marking instruction and a subsequent branch on the same QP.
6556 clear_qp_branch_flag (mask
)
6560 for (i
= 0;i
< regdepslen
;i
++)
6562 valueT bit
= ((valueT
)1 << regdeps
[i
].qp_regno
);
6563 if ((bit
& mask
) != 0)
6565 regdeps
[i
].link_to_qp_branch
= 0;
6570 /* Remove any mutexes which contain any of the PRs indicated in the mask.
6572 Any changes to a PR clears the mutex relations which include that PR.
6575 clear_qp_mutex (mask
)
6581 while (i
< qp_mutexeslen
)
6583 if ((qp_mutexes
[i
].prmask
& mask
) != 0)
6587 fprintf (stderr
, " Clearing mutex relation");
6588 print_prmask (qp_mutexes
[i
].prmask
);
6589 fprintf (stderr
, "\n");
6591 qp_mutexes
[i
] = qp_mutexes
[--qp_mutexeslen
];
6598 /* Clear implies relations which contain PRs in the given masks.
6599 P1_MASK indicates the source of the implies relation, while P2_MASK
6600 indicates the implied PR.
6603 clear_qp_implies (p1_mask
, p2_mask
)
6610 while (i
< qp_implieslen
)
6612 if ((((valueT
)1 << qp_implies
[i
].p1
) & p1_mask
) != 0
6613 || (((valueT
)1 << qp_implies
[i
].p2
) & p2_mask
) != 0)
6616 fprintf (stderr
, "Clearing implied relation PR%d->PR%d\n",
6617 qp_implies
[i
].p1
, qp_implies
[i
].p2
);
6618 qp_implies
[i
] = qp_implies
[--qp_implieslen
];
6625 /* add the PRs specified to the list of implied relations */
6627 add_qp_imply (p1
, p2
)
6634 /* p0 is not meaningful here */
6635 if (p1
== 0 || p2
== 0)
6641 /* if it exists already, ignore it */
6642 for (i
=0;i
< qp_implieslen
;i
++)
6644 if (qp_implies
[i
].p1
== p1
6645 && qp_implies
[i
].p2
== p2
6646 && qp_implies
[i
].path
== md
.path
6647 && !qp_implies
[i
].p2_branched
)
6651 if (qp_implieslen
== qp_impliestotlen
)
6653 qp_impliestotlen
+= 20;
6654 qp_implies
= (struct qp_imply
*)
6655 xrealloc ((void *)qp_implies
,
6656 qp_impliestotlen
* sizeof (struct qp_imply
));
6659 fprintf (stderr
, " Registering PR%d implies PR%d\n", p1
, p2
);
6660 qp_implies
[qp_implieslen
].p1
= p1
;
6661 qp_implies
[qp_implieslen
].p2
= p2
;
6662 qp_implies
[qp_implieslen
].path
= md
.path
;
6663 qp_implies
[qp_implieslen
++].p2_branched
= 0;
6665 /* Add in the implied transitive relations; for everything that p2 implies,
6666 make p1 imply that, too; for everything that implies p1, make it imply p2
6668 for (i
=0;i
< qp_implieslen
;i
++)
6670 if (qp_implies
[i
].p1
== p2
)
6671 add_qp_imply (p1
, qp_implies
[i
].p2
);
6672 if (qp_implies
[i
].p2
== p1
)
6673 add_qp_imply (qp_implies
[i
].p1
, p2
);
6675 /* Add in mutex relations implied by this implies relation; for each mutex
6676 relation containing p2, duplicate it and replace p2 with p1. */
6677 bit
= (valueT
)1 << p1
;
6678 mask
= (valueT
)1 << p2
;
6679 for (i
=0;i
< qp_mutexeslen
;i
++)
6681 if (qp_mutexes
[i
].prmask
& mask
)
6682 add_qp_mutex ((qp_mutexes
[i
].prmask
& ~mask
) | bit
);
6687 /* Add the PRs specified in the mask to the mutex list; this means that only
6688 one of the PRs can be true at any time. PR0 should never be included in
6697 if (qp_mutexeslen
== qp_mutexestotlen
)
6699 qp_mutexestotlen
+= 20;
6700 qp_mutexes
= (struct qpmutex
*)
6701 xrealloc ((void *)qp_mutexes
,
6702 qp_mutexestotlen
* sizeof (struct qpmutex
));
6706 fprintf (stderr
, " Registering mutex on");
6707 print_prmask (mask
);
6708 fprintf (stderr
, "\n");
6710 qp_mutexes
[qp_mutexeslen
].path
= md
.path
;
6711 qp_mutexes
[qp_mutexeslen
++].prmask
= mask
;
6715 clear_register_values ()
6719 fprintf (stderr
, " Clearing register values\n");
6720 for (i
=1;i
< NELEMS(gr_values
);i
++)
6721 gr_values
[i
].known
= 0;
6724 /* Keep track of register values/changes which affect DV tracking.
6726 optimization note: should add a flag to classes of insns where otherwise we
6727 have to examine a group of strings to identify them.
6731 note_register_values (idesc
)
6732 struct ia64_opcode
*idesc
;
6734 valueT qp_changemask
= 0;
6737 /* invalidate values for registers being written to */
6738 for (i
=0;i
< idesc
->num_outputs
;i
++)
6740 if (idesc
->operands
[i
] == IA64_OPND_R1
6741 || idesc
->operands
[i
] == IA64_OPND_R2
6742 || idesc
->operands
[i
] == IA64_OPND_R3
)
6744 int regno
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_GR
;
6745 if (regno
> 0 && regno
< NELEMS(gr_values
))
6746 gr_values
[regno
].known
= 0;
6748 else if (idesc
->operands
[i
] == IA64_OPND_P1
6749 || idesc
->operands
[i
] == IA64_OPND_P2
)
6751 int regno
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_P
;
6752 qp_changemask
|= (valueT
)1 << regno
;
6754 else if (idesc
->operands
[i
] == IA64_OPND_PR
)
6756 if (idesc
->operands
[2] & (valueT
)0x10000)
6757 qp_changemask
= ~(valueT
)0x1FFFF | idesc
->operands
[2];
6759 qp_changemask
= idesc
->operands
[2];
6762 else if (idesc
->operands
[i
] == IA64_OPND_PR_ROT
)
6764 if (idesc
->operands
[1] & ((valueT
)1 << 43))
6765 qp_changemask
= ~(valueT
)0xFFFFFFFFFFF | idesc
->operands
[1];
6767 qp_changemask
= idesc
->operands
[1];
6768 qp_changemask
&= ~(valueT
)0xFFFF;
6773 /* Always clear qp branch flags on any PR change */
6774 /* FIXME there may be exceptions for certain compares */
6775 clear_qp_branch_flag (qp_changemask
);
6777 /* invalidate rotating registers on insns which affect RRBs in CFM */
6778 if (idesc
->flags
& IA64_OPCODE_MOD_RRBS
)
6780 qp_changemask
|= ~(valueT
)0xFFFF;
6781 if (strcmp (idesc
->name
, "clrrrb.pr") != 0)
6783 for (i
=32;i
< 32+md
.rot
.num_regs
;i
++)
6784 gr_values
[i
].known
= 0;
6786 clear_qp_mutex (qp_changemask
);
6787 clear_qp_implies (qp_changemask
, qp_changemask
);
6789 /* after a call, all register values are undefined, except those marked
6791 else if (strncmp (idesc
->name
, "br.call", 6) == 0
6792 || strncmp (idesc
->name
, "brl.call", 7) == 0)
6794 // FIXME keep GR values which are marked as "safe_across_calls"
6795 clear_register_values ();
6796 clear_qp_mutex (~qp_safe_across_calls
);
6797 clear_qp_implies (~qp_safe_across_calls
, ~qp_safe_across_calls
);
6798 clear_qp_branch_flag (~qp_safe_across_calls
);
6800 /* Look for mutex and implies relations */
6801 else if ((idesc
->operands
[0] == IA64_OPND_P1
6802 || idesc
->operands
[0] == IA64_OPND_P2
)
6803 && (idesc
->operands
[1] == IA64_OPND_P1
6804 || idesc
->operands
[1] == IA64_OPND_P2
))
6806 int p1
= CURR_SLOT
.opnd
[0].X_add_number
- REG_P
;
6807 int p2
= CURR_SLOT
.opnd
[1].X_add_number
- REG_P
;
6808 valueT p1mask
= (valueT
)1 << p1
;
6809 valueT p2mask
= (valueT
)1 << p2
;
6811 /* if one of the PRs is PR0, we can't really do anything */
6812 if (p1
== 0 || p2
== 0)
6815 fprintf (stderr
, " Ignoring PRs due to inclusion of p0\n");
6817 /* In general, clear mutexes and implies which include P1 or P2,
6818 with the following exceptions */
6819 else if (strstr (idesc
->name
, ".or.andcm") != NULL
)
6821 add_qp_mutex (p1mask
| p2mask
);
6822 clear_qp_implies (p2mask
, p1mask
);
6824 else if (strstr (idesc
->name
, ".and.orcm") != NULL
)
6826 add_qp_mutex (p1mask
| p2mask
);
6827 clear_qp_implies (p1mask
, p2mask
);
6829 else if (strstr (idesc
->name
, ".and") != NULL
)
6831 clear_qp_implies (0, p1mask
| p2mask
);
6833 else if (strstr (idesc
->name
, ".or") != NULL
)
6835 clear_qp_mutex (p1mask
| p2mask
);
6836 clear_qp_implies (p1mask
| p2mask
, 0);
6840 clear_qp_implies (p1mask
| p2mask
, p1mask
| p2mask
);
6841 if (strstr (idesc
->name
, ".unc") != NULL
)
6843 add_qp_mutex (p1mask
| p2mask
);
6844 if (CURR_SLOT
.qp_regno
!= 0)
6846 add_qp_imply (CURR_SLOT
.opnd
[0].X_add_number
- REG_P
,
6847 CURR_SLOT
.qp_regno
);
6848 add_qp_imply (CURR_SLOT
.opnd
[1].X_add_number
- REG_P
,
6849 CURR_SLOT
.qp_regno
);
6852 else if (CURR_SLOT
.qp_regno
== 0)
6854 add_qp_mutex (p1mask
| p2mask
);
6858 clear_qp_mutex (p1mask
| p2mask
);
6862 /* Look for mov imm insns into GRs */
6863 else if (idesc
->operands
[0] == IA64_OPND_R1
6864 && (idesc
->operands
[1] == IA64_OPND_IMM22
6865 || idesc
->operands
[1] == IA64_OPND_IMMU64
)
6866 && (strcmp(idesc
->name
, "mov") == 0
6867 || strcmp(idesc
->name
, "movl") == 0))
6869 int regno
= CURR_SLOT
.opnd
[0].X_add_number
- REG_GR
;
6870 if (regno
> 0 && regno
< NELEMS(gr_values
))
6872 gr_values
[regno
].known
= 1;
6873 gr_values
[regno
].value
= CURR_SLOT
.opnd
[1].X_add_number
;
6874 gr_values
[regno
].path
= md
.path
;
6876 fprintf (stderr
, " Know gr%d = 0x%llx\n",
6877 regno
, gr_values
[regno
].value
);
6882 clear_qp_mutex (qp_changemask
);
6883 clear_qp_implies (qp_changemask
, qp_changemask
);
6887 /* Return whether the given predicate registers are currently mutex */
6889 qp_mutex (p1
, p2
, path
)
6899 mask
= ((valueT
)1<<p1
) | (valueT
)1<<p2
;
6900 for (i
=0;i
< qp_mutexeslen
;i
++)
6902 if (qp_mutexes
[i
].path
>= path
6903 && (qp_mutexes
[i
].prmask
& mask
) == mask
)
6910 /* Return whether the given resource is in the given insn's list of chks
6911 Return 1 if the conflict is absolutely determined, 2 if it's a potential
6915 resources_match (rs
, idesc
, note
, qp_regno
, path
)
6917 struct ia64_opcode
*idesc
;
6922 struct rsrc specs
[MAX_SPECS
];
6925 /* If the marked resource's qp_regno and the given qp_regno are mutex,
6926 we don't need to check. One exception is note 11, which indicates that
6927 target predicates are written regardless of PR[qp]. */
6928 if (qp_mutex (rs
->qp_regno
, qp_regno
, path
)
6932 count
= specify_resource (rs
->dependency
, idesc
, DV_CHK
, specs
, note
, path
);
6935 /* UNAT checking is a bit more specific than other resources */
6936 if (rs
->dependency
->specifier
== IA64_RS_AR_UNAT
6937 && specs
[count
].mem_offset
.hint
6938 && rs
->mem_offset
.hint
)
6940 if (rs
->mem_offset
.base
== specs
[count
].mem_offset
.base
)
6942 if (((rs
->mem_offset
.offset
>> 3) & 0x3F) ==
6943 ((specs
[count
].mem_offset
.offset
>> 3) & 0x3F))
6950 /* If either resource is not specific, conservatively assume a conflict
6952 if (!specs
[count
].specific
|| !rs
->specific
)
6954 else if (specs
[count
].index
== rs
->index
)
6959 fprintf (stderr
, " No %s conflicts\n", rs
->dependency
->name
);
6965 /* Indicate an instruction group break; if INSERT_STOP is non-zero, then
6966 insert a stop to create the break. Update all resource dependencies
6967 appropriately. If QP_REGNO is non-zero, only apply the break to resources
6968 which use the same QP_REGNO and have the link_to_qp_branch flag set.
6969 If SAVE_CURRENT is non-zero, don't affect resources marked by the current
6974 insn_group_break (insert_stop
, qp_regno
, save_current
)
6981 if (insert_stop
&& md
.num_slots_in_use
> 0)
6982 PREV_SLOT
.end_of_insn_group
= 1;
6986 fprintf (stderr
, " Insn group break%s",
6987 (insert_stop
? " (w/stop)" : ""));
6989 fprintf (stderr
, " effective for QP=%d", qp_regno
);
6990 fprintf (stderr
, "\n");
6994 while (i
< regdepslen
)
6996 const struct ia64_dependency
*dep
= regdeps
[i
].dependency
;
6999 && regdeps
[i
].qp_regno
!= qp_regno
)
7006 && CURR_SLOT
.src_file
== regdeps
[i
].file
7007 && CURR_SLOT
.src_line
== regdeps
[i
].line
)
7013 /* clear dependencies which are automatically cleared by a stop, or
7014 those that have reached the appropriate state of insn serialization */
7015 if (dep
->semantics
== IA64_DVS_IMPLIED
7016 || dep
->semantics
== IA64_DVS_IMPLIEDF
7017 || regdeps
[i
].insn_srlz
== STATE_SRLZ
)
7019 print_dependency ("Removing", i
);
7020 regdeps
[i
] = regdeps
[--regdepslen
];
7024 if (dep
->semantics
== IA64_DVS_DATA
7025 || dep
->semantics
== IA64_DVS_INSTR
7026 || dep
->semantics
== IA64_DVS_SPECIFIC
)
7028 if (regdeps
[i
].insn_srlz
== STATE_NONE
)
7029 regdeps
[i
].insn_srlz
= STATE_STOP
;
7030 if (regdeps
[i
].data_srlz
== STATE_NONE
)
7031 regdeps
[i
].data_srlz
= STATE_STOP
;
7038 /* Add the given resource usage spec to the list of active dependencies */
7040 mark_resource (idesc
, dep
, spec
, depind
, path
)
7041 struct ia64_opcode
*idesc
;
7042 const struct ia64_dependency
*dep
;
7047 if (regdepslen
== regdepstotlen
)
7049 regdepstotlen
+= 20;
7050 regdeps
= (struct rsrc
*)
7051 xrealloc ((void *)regdeps
,
7052 regdepstotlen
* sizeof(struct rsrc
));
7055 regdeps
[regdepslen
] = *spec
;
7056 regdeps
[regdepslen
].depind
= depind
;
7057 regdeps
[regdepslen
].path
= path
;
7058 regdeps
[regdepslen
].file
= CURR_SLOT
.src_file
;
7059 regdeps
[regdepslen
].line
= CURR_SLOT
.src_line
;
7061 print_dependency ("Adding", regdepslen
);
7067 print_dependency (action
, depind
)
7073 fprintf (stderr
, " %s %s '%s'",
7074 action
, dv_mode
[(regdeps
[depind
].dependency
)->mode
],
7075 (regdeps
[depind
].dependency
)->name
);
7076 if (regdeps
[depind
].specific
&& regdeps
[depind
].index
!= 0)
7077 fprintf (stderr
, " (%d)", regdeps
[depind
].index
);
7078 if (regdeps
[depind
].mem_offset
.hint
)
7079 fprintf (stderr
, " 0x%llx+0x%llx",
7080 regdeps
[depind
].mem_offset
.base
,
7081 regdeps
[depind
].mem_offset
.offset
);
7082 fprintf (stderr
, "\n");
7087 instruction_serialization ()
7091 fprintf (stderr
, " Instruction serialization\n");
7092 for (i
=0;i
< regdepslen
;i
++)
7093 if (regdeps
[i
].insn_srlz
== STATE_STOP
)
7094 regdeps
[i
].insn_srlz
= STATE_SRLZ
;
7098 data_serialization ()
7102 fprintf (stderr
, " Data serialization\n");
7103 while (i
< regdepslen
)
7105 if (regdeps
[i
].data_srlz
== STATE_STOP
7106 /* Note: as of 991210, all "other" dependencies are cleared by a
7107 data serialization. This might change with new tables */
7108 || (regdeps
[i
].dependency
)->semantics
== IA64_DVS_OTHER
)
7110 print_dependency ("Removing", i
);
7111 regdeps
[i
] = regdeps
[--regdepslen
];
7118 /* Insert stops and serializations as needed to avoid DVs */
7120 remove_marked_resource (rs
)
7123 switch (rs
->dependency
->semantics
)
7125 case IA64_DVS_SPECIFIC
:
7127 fprintf (stderr
, "Implementation-specific, assume worst case...\n");
7128 /* ...fall through... */
7129 case IA64_DVS_INSTR
:
7131 fprintf (stderr
, "Inserting instr serialization\n");
7132 if (rs
->insn_srlz
< STATE_STOP
)
7133 insn_group_break (1, 0, 0);
7134 if (rs
->insn_srlz
< STATE_SRLZ
)
7136 int oldqp
= CURR_SLOT
.qp_regno
;
7137 struct ia64_opcode
*oldidesc
= CURR_SLOT
.idesc
;
7138 /* Manually jam a srlz.i insn into the stream */
7139 CURR_SLOT
.qp_regno
= 0;
7140 CURR_SLOT
.idesc
= ia64_find_opcode ("srlz.i");
7141 instruction_serialization ();
7142 md
.curr_slot
= (md
.curr_slot
+ 1) % NUM_SLOTS
;
7143 if (++md
.num_slots_in_use
>= NUM_SLOTS
)
7145 CURR_SLOT
.qp_regno
= oldqp
;
7146 CURR_SLOT
.idesc
= oldidesc
;
7148 insn_group_break (1, 0, 0);
7150 case IA64_DVS_OTHER
: /* as of rev2 (991220) of the DV tables, all
7151 "other" types of DV are eliminated
7152 by a data serialization */
7155 fprintf (stderr
, "Inserting data serialization\n");
7156 if (rs
->data_srlz
< STATE_STOP
)
7157 insn_group_break (1, 0, 0);
7159 int oldqp
= CURR_SLOT
.qp_regno
;
7160 struct ia64_opcode
*oldidesc
= CURR_SLOT
.idesc
;
7161 /* Manually jam a srlz.d insn into the stream */
7162 CURR_SLOT
.qp_regno
= 0;
7163 CURR_SLOT
.idesc
= ia64_find_opcode ("srlz.d");
7164 data_serialization ();
7165 md
.curr_slot
= (md
.curr_slot
+ 1) % NUM_SLOTS
;
7166 if (++md
.num_slots_in_use
>= NUM_SLOTS
)
7168 CURR_SLOT
.qp_regno
= oldqp
;
7169 CURR_SLOT
.idesc
= oldidesc
;
7172 case IA64_DVS_IMPLIED
:
7173 case IA64_DVS_IMPLIEDF
:
7175 fprintf (stderr
, "Inserting stop\n");
7176 insn_group_break (1, 0, 0);
7183 /* Check the resources used by the given opcode against the current dependency
7186 The check is run once for each execution path encountered. In this case,
7187 a unique execution path is the sequence of instructions following a code
7188 entry point, e.g. the following has three execution paths, one starting
7189 at L0, one at L1, and one at L2.
7197 check_dependencies (idesc
)
7198 struct ia64_opcode
*idesc
;
7200 const struct ia64_opcode_dependency
*opdeps
= idesc
->dependencies
;
7204 /* Note that the number of marked resources may change within the
7205 loop if in auto mode. */
7207 while (i
< regdepslen
)
7209 struct rsrc
*rs
= ®deps
[i
];
7210 const struct ia64_dependency
*dep
= rs
->dependency
;
7215 if (dep
->semantics
== IA64_DVS_NONE
7216 || (chkind
= depends_on (rs
->depind
, idesc
)) == -1)
7221 note
= NOTE(opdeps
->chks
[chkind
]);
7223 /* Check this resource against each execution path seen thus far */
7224 for (path
=0;path
<= md
.path
;path
++)
7228 /* If the dependency wasn't on the path being checked, ignore it */
7229 if (rs
->path
< path
)
7232 /* If the QP for this insn implies a QP which has branched, don't
7233 bother checking. Ed. NOTE: I don't think this check is terribly
7234 useful; what's the point of generating code which will only be
7235 reached if its QP is zero?
7236 This code was specifically inserted to handle the following code,
7237 based on notes from Intel's DV checking code, where p1 implies p2.
7244 if (CURR_SLOT
.qp_regno
!= 0)
7248 for (implies
=0;implies
< qp_implieslen
;implies
++)
7250 if (qp_implies
[implies
].path
>= path
7251 && qp_implies
[implies
].p1
== CURR_SLOT
.qp_regno
7252 && qp_implies
[implies
].p2_branched
)
7262 if ((matchtype
= resources_match (rs
, idesc
, note
,
7263 CURR_SLOT
.qp_regno
, path
)) != 0)
7266 char pathmsg
[256] = "";
7267 char indexmsg
[256] = "";
7268 int certain
= (matchtype
== 1 && CURR_SLOT
.qp_regno
== 0);
7271 sprintf (pathmsg
, " when entry is at label '%s'",
7272 md
.entry_labels
[path
-1]);
7273 if (rs
->specific
&& rs
->index
!= 0)
7274 sprintf (indexmsg
, ", specific resource number is %d",
7276 sprintf (msg
, "Use of '%s' %s %s dependency '%s' (%s)%s%s",
7278 (certain
? "violates" : "may violate"),
7279 dv_mode
[dep
->mode
], dep
->name
,
7280 dv_sem
[dep
->semantics
],
7283 if (md
.explicit_mode
)
7285 as_warn ("%s", msg
);
7287 as_warn (_("Only the first path encountering the conflict "
7289 as_warn_where (rs
->file
, rs
->line
,
7290 _("This is the location of the "
7291 "conflicting usage"));
7292 /* Don't bother checking other paths, to avoid duplicating
7299 fprintf(stderr
, "%s @ %s:%d\n", msg
, rs
->file
, rs
->line
);
7301 remove_marked_resource (rs
);
7303 /* since the set of dependencies has changed, start over */
7304 /* FIXME -- since we're removing dvs as we go, we
7305 probably don't really need to start over... */
7318 /* register new dependencies based on the given opcode */
7320 mark_resources (idesc
)
7321 struct ia64_opcode
*idesc
;
7324 const struct ia64_opcode_dependency
*opdeps
= idesc
->dependencies
;
7325 int add_only_qp_reads
= 0;
7327 /* A conditional branch only uses its resources if it is taken; if it is
7328 taken, we stop following that path. The other branch types effectively
7329 *always* write their resources. If it's not taken, register only QP
7331 if (is_conditional_branch (idesc
) || is_interruption_or_rfi (idesc
))
7333 add_only_qp_reads
= 1;
7337 fprintf (stderr
, "Registering '%s' resource usage\n", idesc
->name
);
7339 for (i
=0;i
< opdeps
->nregs
;i
++)
7341 const struct ia64_dependency
*dep
;
7342 struct rsrc specs
[MAX_SPECS
];
7347 dep
= ia64_find_dependency (opdeps
->regs
[i
]);
7348 note
= NOTE(opdeps
->regs
[i
]);
7350 if (add_only_qp_reads
7351 && !(dep
->mode
== IA64_DV_WAR
7352 && (dep
->specifier
== IA64_RS_PR
7353 || dep
->specifier
== IA64_RS_PR63
)))
7356 count
= specify_resource (dep
, idesc
, DV_REG
, specs
, note
, md
.path
);
7359 if (md
.debug_dv
&& !count
)
7360 fprintf (stderr
, " No %s %s usage found (path %d)\n",
7361 dv_mode
[dep
->mode
], dep
->name
, md
.path
);
7366 mark_resource (idesc
, dep
, &specs
[count
],
7367 DEP(opdeps
->regs
[i
]), md
.path
);
7370 /* The execution path may affect register values, which may in turn
7371 affect which indirect-access resources are accessed. */
7372 switch (dep
->specifier
)
7384 for (path
=0;path
< md
.path
;path
++)
7386 count
= specify_resource (dep
, idesc
, DV_REG
, specs
, note
, path
);
7388 mark_resource (idesc
, dep
, &specs
[count
],
7389 DEP(opdeps
->regs
[i
]), path
);
7396 /* remove dependencies when they no longer apply */
7398 update_dependencies (idesc
)
7399 struct ia64_opcode
*idesc
;
7403 if (strcmp (idesc
->name
, "srlz.i") == 0)
7405 instruction_serialization ();
7407 else if (strcmp (idesc
->name
, "srlz.d") == 0)
7409 data_serialization ();
7411 else if (is_interruption_or_rfi (idesc
)
7412 || is_taken_branch (idesc
))
7414 /* although technically the taken branch doesn't clear dependencies
7415 which require a srlz.[id], we don't follow the branch; the next
7416 instruction is assumed to start with a clean slate */
7418 clear_register_values ();
7419 clear_qp_mutex (~(valueT
)0);
7420 clear_qp_implies (~(valueT
)0, ~(valueT
)0);
7423 else if (is_conditional_branch (idesc
)
7424 && CURR_SLOT
.qp_regno
!= 0)
7426 int is_call
= strstr (idesc
->name
, ".call") != NULL
;
7428 for (i
=0;i
< qp_implieslen
;i
++)
7430 /* if the conditional branch's predicate is implied by the predicate
7431 in an existing dependency, remove that dependency */
7432 if (qp_implies
[i
].p2
== CURR_SLOT
.qp_regno
)
7435 /* note that this implied predicate takes a branch so that if
7436 a later insn generates a DV but its predicate implies this
7437 one, we can avoid the false DV warning */
7438 qp_implies
[i
].p2_branched
= 1;
7439 while (depind
< regdepslen
)
7441 if (regdeps
[depind
].qp_regno
== qp_implies
[i
].p1
)
7443 print_dependency ("Removing", depind
);
7444 regdeps
[depind
] = regdeps
[--regdepslen
];
7451 /* Any marked resources which have this same predicate should be
7452 cleared, provided that the QP hasn't been modified between the
7453 marking instruction and the branch.
7457 insn_group_break (0, CURR_SLOT
.qp_regno
, 1);
7462 while (i
< regdepslen
)
7464 if (regdeps
[i
].qp_regno
== CURR_SLOT
.qp_regno
7465 && regdeps
[i
].link_to_qp_branch
7466 && (regdeps
[i
].file
!= CURR_SLOT
.src_file
7467 || regdeps
[i
].line
!= CURR_SLOT
.src_line
))
7469 /* Treat like a taken branch */
7470 print_dependency ("Removing", i
);
7471 regdeps
[i
] = regdeps
[--regdepslen
];
7480 /* Examine the current instruction for dependency violations. */
7483 struct ia64_opcode
*idesc
;
7487 fprintf (stderr
, "Checking %s for violations (line %d, %d/%d)\n",
7488 idesc
->name
, CURR_SLOT
.src_line
,
7489 idesc
->dependencies
->nchks
,
7490 idesc
->dependencies
->nregs
);
7493 /* Look through the list of currently marked resources; if the current
7494 instruction has the dependency in its chks list which uses that resource,
7495 check against the specific resources used.
7497 check_dependencies (idesc
);
7500 Look up the instruction's regdeps (RAW writes, WAW writes, and WAR reads),
7501 then add them to the list of marked resources.
7503 mark_resources (idesc
);
7505 /* There are several types of dependency semantics, and each has its own
7506 requirements for being cleared
7508 Instruction serialization (insns separated by interruption, rfi, or
7509 writer + srlz.i + reader, all in separate groups) clears DVS_INSTR.
7511 Data serialization (instruction serialization, or writer + srlz.d +
7512 reader, where writer and srlz.d are in separate groups) clears
7513 DVS_DATA. (This also clears DVS_OTHER, but that is not guaranteed to
7514 always be the case).
7516 Instruction group break (groups separated by stop, taken branch,
7517 interruption or rfi) clears DVS_IMPLIED and DVS_IMPLIEDF.
7519 update_dependencies (idesc
);
7521 /* Sometimes, knowing a register value allows us to avoid giving a false DV
7522 warning. Keep track of as many as possible that are useful. */
7523 note_register_values (idesc
);
7525 /* We don't need or want this anymore. */
7526 md
.mem_offset
.hint
= 0;
7531 /* Translate one line of assembly. Pseudo ops and labels do not show
7537 char *saved_input_line_pointer
, *mnemonic
;
7538 const struct pseudo_opcode
*pdesc
;
7539 struct ia64_opcode
*idesc
;
7540 unsigned char qp_regno
;
7544 saved_input_line_pointer
= input_line_pointer
;
7545 input_line_pointer
= str
;
7547 /* extract the opcode (mnemonic): */
7549 mnemonic
= input_line_pointer
;
7550 ch
= get_symbol_end ();
7551 pdesc
= (struct pseudo_opcode
*) hash_find (md
.pseudo_hash
, mnemonic
);
7554 *input_line_pointer
= ch
;
7555 (*pdesc
->handler
) (pdesc
->arg
);
7559 /* find the instruction descriptor matching the arguments: */
7561 idesc
= ia64_find_opcode (mnemonic
);
7562 *input_line_pointer
= ch
;
7565 as_bad ("Unknown opcode `%s'", mnemonic
);
7569 idesc
= parse_operands (idesc
);
7573 /* Handle the dynamic ops we can handle now: */
7574 if (idesc
->type
== IA64_TYPE_DYN
)
7576 if (strcmp (idesc
->name
, "add") == 0)
7578 if (CURR_SLOT
.opnd
[2].X_op
== O_register
7579 && CURR_SLOT
.opnd
[2].X_add_number
< 4)
7583 idesc
= ia64_find_opcode (mnemonic
);
7585 know (!idesc
->next
);
7588 else if (strcmp (idesc
->name
, "mov") == 0)
7590 enum ia64_opnd opnd1
, opnd2
;
7593 opnd1
= idesc
->operands
[0];
7594 opnd2
= idesc
->operands
[1];
7595 if (opnd1
== IA64_OPND_AR3
)
7597 else if (opnd2
== IA64_OPND_AR3
)
7601 if (CURR_SLOT
.opnd
[rop
].X_op
== O_register
7602 && ar_is_in_integer_unit (CURR_SLOT
.opnd
[rop
].X_add_number
))
7606 idesc
= ia64_find_opcode (mnemonic
);
7607 while (idesc
!= NULL
7608 && (idesc
->operands
[0] != opnd1
7609 || idesc
->operands
[1] != opnd2
))
7610 idesc
= get_next_opcode (idesc
);
7615 if (md
.qp
.X_op
== O_register
)
7616 qp_regno
= md
.qp
.X_add_number
- REG_P
;
7618 flags
= idesc
->flags
;
7620 if ((flags
& IA64_OPCODE_FIRST
) != 0)
7621 insn_group_break (1, 0, 0);
7623 if ((flags
& IA64_OPCODE_NO_PRED
) != 0 && qp_regno
!= 0)
7625 as_bad ("`%s' cannot be predicated", idesc
->name
);
7629 /* build the instruction: */
7630 CURR_SLOT
.qp_regno
= qp_regno
;
7631 CURR_SLOT
.idesc
= idesc
;
7632 as_where (&CURR_SLOT
.src_file
, &CURR_SLOT
.src_line
);
7633 if (debug_type
== DEBUG_DWARF2
)
7634 dwarf2_where (&CURR_SLOT
.debug_line
);
7636 /* Add unwind entry, if there is one. */
7637 if (current_unwind_entry
)
7639 CURR_SLOT
.unwind_record
= current_unwind_entry
;
7640 current_unwind_entry
= NULL
;
7643 /* check for dependency violations */
7647 md
.curr_slot
= (md
.curr_slot
+ 1) % NUM_SLOTS
;
7648 if (++md
.num_slots_in_use
>= NUM_SLOTS
)
7651 if ((flags
& IA64_OPCODE_LAST
) != 0)
7652 insn_group_break (1, 0, 0);
7654 md
.last_text_seg
= now_seg
;
7657 input_line_pointer
= saved_input_line_pointer
;
7660 /* Called when symbol NAME cannot be found in the symbol table.
7661 Should be used for dynamic valued symbols only. */
7663 md_undefined_symbol (name
)
7669 /* Called for any expression that can not be recognized. When the
7670 function is called, `input_line_pointer' will point to the start of
7676 enum pseudo_type pseudo_type
;
7680 switch (*input_line_pointer
)
7683 /* find what relocation pseudo-function we're dealing with: */
7685 ch
= *++input_line_pointer
;
7686 for (i
= 0; i
< NELEMS (pseudo_func
); ++i
)
7687 if (pseudo_func
[i
].name
&& pseudo_func
[i
].name
[0] == ch
)
7689 len
= strlen (pseudo_func
[i
].name
);
7690 if (strncmp (pseudo_func
[i
].name
+ 1,
7691 input_line_pointer
+ 1, len
- 1) == 0
7692 && !is_part_of_name (input_line_pointer
[len
]))
7694 input_line_pointer
+= len
;
7695 pseudo_type
= pseudo_func
[i
].type
;
7699 switch (pseudo_type
)
7701 case PSEUDO_FUNC_RELOC
:
7703 if (*input_line_pointer
!= '(')
7705 as_bad ("Expected '('");
7708 ++input_line_pointer
; /* skip '(' */
7710 if (*input_line_pointer
++ != ')')
7712 as_bad ("Missing ')'");
7715 if (e
->X_op
!= O_symbol
)
7717 if (e
->X_op
!= O_pseudo_fixup
)
7719 as_bad ("Not a symbolic expression");
7722 if (S_GET_VALUE (e
->X_op_symbol
) == FUNC_FPTR_RELATIVE
7723 && i
== FUNC_LT_RELATIVE
)
7724 i
= FUNC_LT_FPTR_RELATIVE
;
7727 as_bad ("Illegal combination of relocation functions");
7731 /* make sure gas doesn't get rid of local symbols that are used
7733 e
->X_op
= O_pseudo_fixup
;
7734 e
->X_op_symbol
= pseudo_func
[i
].u
.sym
;
7737 case PSEUDO_FUNC_CONST
:
7738 e
->X_op
= O_constant
;
7739 e
->X_add_number
= pseudo_func
[i
].u
.ival
;
7743 as_bad ("Unknown pseudo function `%s'", input_line_pointer
- 1);
7749 ++input_line_pointer
;
7751 if (*input_line_pointer
!= ']')
7753 as_bad ("Closing bracket misssing");
7758 if (e
->X_op
!= O_register
)
7759 as_bad ("Register expected as index");
7761 ++input_line_pointer
;
7772 ignore_rest_of_line ();
7775 /* Return 1 if it's OK to adjust a reloc by replacing the symbol with
7776 a section symbol plus some offset. For relocs involving @fptr(),
7777 directives we don't want such adjustments since we need to have the
7778 original symbol's name in the reloc. */
7780 ia64_fix_adjustable (fix
)
7783 /* Prevent all adjustments to global symbols */
7784 if (S_IS_EXTERN (fix
->fx_addsy
) || S_IS_WEAK (fix
->fx_addsy
))
7787 switch (fix
->fx_r_type
)
7789 case BFD_RELOC_IA64_FPTR64I
:
7790 case BFD_RELOC_IA64_FPTR32MSB
:
7791 case BFD_RELOC_IA64_FPTR32LSB
:
7792 case BFD_RELOC_IA64_FPTR64MSB
:
7793 case BFD_RELOC_IA64_FPTR64LSB
:
7794 case BFD_RELOC_IA64_LTOFF_FPTR22
:
7795 case BFD_RELOC_IA64_LTOFF_FPTR64I
:
7805 ia64_force_relocation (fix
)
7808 switch (fix
->fx_r_type
)
7810 case BFD_RELOC_IA64_FPTR64I
:
7811 case BFD_RELOC_IA64_FPTR32MSB
:
7812 case BFD_RELOC_IA64_FPTR32LSB
:
7813 case BFD_RELOC_IA64_FPTR64MSB
:
7814 case BFD_RELOC_IA64_FPTR64LSB
:
7816 case BFD_RELOC_IA64_LTOFF22
:
7817 case BFD_RELOC_IA64_LTOFF64I
:
7818 case BFD_RELOC_IA64_LTOFF_FPTR22
:
7819 case BFD_RELOC_IA64_LTOFF_FPTR64I
:
7820 case BFD_RELOC_IA64_PLTOFF22
:
7821 case BFD_RELOC_IA64_PLTOFF64I
:
7822 case BFD_RELOC_IA64_PLTOFF64MSB
:
7823 case BFD_RELOC_IA64_PLTOFF64LSB
:
7832 /* Decide from what point a pc-relative relocation is relative to,
7833 relative to the pc-relative fixup. Er, relatively speaking. */
7835 ia64_pcrel_from_section (fix
, sec
)
7839 unsigned long off
= fix
->fx_frag
->fr_address
+ fix
->fx_where
;
7841 if (bfd_get_section_flags (stdoutput
, sec
) & SEC_CODE
)
7847 /* This is called whenever some data item (not an instruction) needs a
7848 fixup. We pick the right reloc code depending on the byteorder
7849 currently in effect. */
7851 ia64_cons_fix_new (f
, where
, nbytes
, exp
)
7857 bfd_reloc_code_real_type code
;
7862 /* There are no reloc for 8 and 16 bit quantities, but we allow
7863 them here since they will work fine as long as the expression
7864 is fully defined at the end of the pass over the source file. */
7865 case 1: code
= BFD_RELOC_8
; break;
7866 case 2: code
= BFD_RELOC_16
; break;
7868 if (target_big_endian
)
7869 code
= BFD_RELOC_IA64_DIR32MSB
;
7871 code
= BFD_RELOC_IA64_DIR32LSB
;
7875 if (target_big_endian
)
7876 code
= BFD_RELOC_IA64_DIR64MSB
;
7878 code
= BFD_RELOC_IA64_DIR64LSB
;
7882 as_bad ("Unsupported fixup size %d", nbytes
);
7883 ignore_rest_of_line ();
7886 if (exp
->X_op
== O_pseudo_fixup
)
7889 exp
->X_op
= O_symbol
;
7890 code
= ia64_gen_real_reloc_type (exp
->X_op_symbol
, code
);
7892 fix
= fix_new_exp (f
, where
, nbytes
, exp
, 0, code
);
7893 /* We need to store the byte order in effect in case we're going
7894 to fix an 8 or 16 bit relocation (for which there no real
7895 relocs available). See md_apply_fix(). */
7896 fix
->tc_fix_data
.bigendian
= target_big_endian
;
7899 /* Return the actual relocation we wish to associate with the pseudo
7900 reloc described by SYM and R_TYPE. SYM should be one of the
7901 symbols in the pseudo_func array, or NULL. */
7903 static bfd_reloc_code_real_type
7904 ia64_gen_real_reloc_type (sym
, r_type
)
7906 bfd_reloc_code_real_type r_type
;
7908 bfd_reloc_code_real_type
new = 0;
7915 switch (S_GET_VALUE (sym
))
7917 case FUNC_FPTR_RELATIVE
:
7920 case BFD_RELOC_IA64_IMM64
: new = BFD_RELOC_IA64_FPTR64I
; break;
7921 case BFD_RELOC_IA64_DIR32MSB
: new = BFD_RELOC_IA64_FPTR32MSB
; break;
7922 case BFD_RELOC_IA64_DIR32LSB
: new = BFD_RELOC_IA64_FPTR32LSB
; break;
7923 case BFD_RELOC_IA64_DIR64MSB
: new = BFD_RELOC_IA64_FPTR64MSB
; break;
7924 case BFD_RELOC_IA64_DIR64LSB
: new = BFD_RELOC_IA64_FPTR64LSB
; break;
7929 case FUNC_GP_RELATIVE
:
7932 case BFD_RELOC_IA64_IMM22
: new = BFD_RELOC_IA64_GPREL22
; break;
7933 case BFD_RELOC_IA64_IMM64
: new = BFD_RELOC_IA64_GPREL64I
; break;
7934 case BFD_RELOC_IA64_DIR32MSB
: new = BFD_RELOC_IA64_GPREL32MSB
; break;
7935 case BFD_RELOC_IA64_DIR32LSB
: new = BFD_RELOC_IA64_GPREL32LSB
; break;
7936 case BFD_RELOC_IA64_DIR64MSB
: new = BFD_RELOC_IA64_GPREL64MSB
; break;
7937 case BFD_RELOC_IA64_DIR64LSB
: new = BFD_RELOC_IA64_GPREL64LSB
; break;
7942 case FUNC_LT_RELATIVE
:
7945 case BFD_RELOC_IA64_IMM22
: new = BFD_RELOC_IA64_LTOFF22
; break;
7946 case BFD_RELOC_IA64_IMM64
: new = BFD_RELOC_IA64_LTOFF64I
; break;
7951 case FUNC_PLT_RELATIVE
:
7954 case BFD_RELOC_IA64_IMM22
: new = BFD_RELOC_IA64_PLTOFF22
; break;
7955 case BFD_RELOC_IA64_IMM64
: new = BFD_RELOC_IA64_PLTOFF64I
; break;
7956 case BFD_RELOC_IA64_DIR64MSB
: new = BFD_RELOC_IA64_PLTOFF64MSB
;break;
7957 case BFD_RELOC_IA64_DIR64LSB
: new = BFD_RELOC_IA64_PLTOFF64LSB
;break;
7962 case FUNC_SEC_RELATIVE
:
7965 case BFD_RELOC_IA64_DIR32MSB
: new = BFD_RELOC_IA64_SECREL32MSB
;break;
7966 case BFD_RELOC_IA64_DIR32LSB
: new = BFD_RELOC_IA64_SECREL32LSB
;break;
7967 case BFD_RELOC_IA64_DIR64MSB
: new = BFD_RELOC_IA64_SECREL64MSB
;break;
7968 case BFD_RELOC_IA64_DIR64LSB
: new = BFD_RELOC_IA64_SECREL64LSB
;break;
7973 case FUNC_SEG_RELATIVE
:
7976 case BFD_RELOC_IA64_DIR32MSB
: new = BFD_RELOC_IA64_SEGREL32MSB
;break;
7977 case BFD_RELOC_IA64_DIR32LSB
: new = BFD_RELOC_IA64_SEGREL32LSB
;break;
7978 case BFD_RELOC_IA64_DIR64MSB
: new = BFD_RELOC_IA64_SEGREL64MSB
;break;
7979 case BFD_RELOC_IA64_DIR64LSB
: new = BFD_RELOC_IA64_SEGREL64LSB
;break;
7984 case FUNC_LTV_RELATIVE
:
7987 case BFD_RELOC_IA64_DIR32MSB
: new = BFD_RELOC_IA64_LTV32MSB
; break;
7988 case BFD_RELOC_IA64_DIR32LSB
: new = BFD_RELOC_IA64_LTV32LSB
; break;
7989 case BFD_RELOC_IA64_DIR64MSB
: new = BFD_RELOC_IA64_LTV64MSB
; break;
7990 case BFD_RELOC_IA64_DIR64LSB
: new = BFD_RELOC_IA64_LTV64LSB
; break;
7995 case FUNC_LT_FPTR_RELATIVE
:
7998 case BFD_RELOC_IA64_IMM22
:
7999 new = BFD_RELOC_IA64_LTOFF_FPTR22
; break;
8000 case BFD_RELOC_IA64_IMM64
:
8001 new = BFD_RELOC_IA64_LTOFF_FPTR64I
; break;
8009 /* Hmmmm. Should this ever occur? */
8016 /* Here is where generate the appropriate reloc for pseudo relocation
8019 ia64_validate_fix (fix
)
8022 switch (fix
->fx_r_type
)
8024 case BFD_RELOC_IA64_FPTR64I
:
8025 case BFD_RELOC_IA64_FPTR32MSB
:
8026 case BFD_RELOC_IA64_FPTR64LSB
:
8027 case BFD_RELOC_IA64_LTOFF_FPTR22
:
8028 case BFD_RELOC_IA64_LTOFF_FPTR64I
:
8029 if (fix
->fx_offset
!= 0)
8030 as_bad_where (fix
->fx_file
, fix
->fx_line
,
8031 "No addend allowed in @fptr() relocation");
8041 fix_insn (fix
, odesc
, value
)
8043 const struct ia64_operand
*odesc
;
8046 bfd_vma insn
[3], t0
, t1
, control_bits
;
8051 slot
= fix
->fx_where
& 0x3;
8052 fixpos
= fix
->fx_frag
->fr_literal
+ (fix
->fx_where
- slot
);
8054 /* bundles are always in little-endian byte order */
8055 t0
= bfd_getl64 (fixpos
);
8056 t1
= bfd_getl64 (fixpos
+ 8);
8057 control_bits
= t0
& 0x1f;
8058 insn
[0] = (t0
>> 5) & 0x1ffffffffffLL
;
8059 insn
[1] = ((t0
>> 46) & 0x3ffff) | ((t1
& 0x7fffff) << 18);
8060 insn
[2] = (t1
>> 23) & 0x1ffffffffffLL
;
8062 err
= (*odesc
->insert
) (odesc
, value
, insn
+ slot
);
8065 as_bad_where (fix
->fx_file
, fix
->fx_line
, err
);
8069 t0
= control_bits
| (insn
[0] << 5) | (insn
[1] << 46);
8070 t1
= ((insn
[1] >> 18) & 0x7fffff) | (insn
[2] << 23);
8071 md_number_to_chars (fixpos
+ 0, t0
, 8);
8072 md_number_to_chars (fixpos
+ 8, t1
, 8);
8076 /* Attempt to simplify or even eliminate a fixup. The return value is
8077 ignored; perhaps it was once meaningful, but now it is historical.
8078 To indicate that a fixup has been eliminated, set FIXP->FX_DONE.
8080 If fixp->fx_addsy is non-NULL, we'll have to generate a reloc entry
8083 md_apply_fix3 (fix
, valuep
, seg
)
8089 valueT value
= *valuep
;
8092 fixpos
= fix
->fx_frag
->fr_literal
+ fix
->fx_where
;
8096 switch (fix
->fx_r_type
)
8098 case BFD_RELOC_IA64_DIR32MSB
:
8099 fix
->fx_r_type
= BFD_RELOC_IA64_PCREL32MSB
;
8103 case BFD_RELOC_IA64_DIR32LSB
:
8104 fix
->fx_r_type
= BFD_RELOC_IA64_PCREL32LSB
;
8108 case BFD_RELOC_IA64_DIR64MSB
:
8109 fix
->fx_r_type
= BFD_RELOC_IA64_PCREL64MSB
;
8113 case BFD_RELOC_IA64_DIR64LSB
:
8114 fix
->fx_r_type
= BFD_RELOC_IA64_PCREL64LSB
;
8124 switch (fix
->fx_r_type
)
8127 as_bad_where (fix
->fx_file
, fix
->fx_line
,
8128 "%s must have a constant value",
8129 elf64_ia64_operands
[fix
->tc_fix_data
.opnd
].desc
);
8136 /* ??? This is a hack copied from tc-i386.c to make PCREL relocs
8137 work. There should be a better way to handle this. */
8139 fix
->fx_offset
+= fix
->fx_where
+ fix
->fx_frag
->fr_address
;
8141 else if (fix
->tc_fix_data
.opnd
== IA64_OPND_NIL
)
8143 if (fix
->tc_fix_data
.bigendian
)
8144 number_to_chars_bigendian (fixpos
, value
, fix
->fx_size
);
8146 number_to_chars_littleendian (fixpos
, value
, fix
->fx_size
);
8152 fix_insn (fix
, elf64_ia64_operands
+ fix
->tc_fix_data
.opnd
, value
);
8159 /* Generate the BFD reloc to be stuck in the object file from the
8160 fixup used internally in the assembler. */
8162 tc_gen_reloc (sec
, fixp
)
8168 reloc
= xmalloc (sizeof (*reloc
));
8169 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
8170 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
8171 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
8172 reloc
->addend
= fixp
->fx_offset
;
8173 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
8177 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
8178 "Cannot represent %s relocation in object file",
8179 bfd_get_reloc_code_name (fixp
->fx_r_type
));
8184 /* Turn a string in input_line_pointer into a floating point constant
8185 of type type, and store the appropriate bytes in *lit. The number
8186 of LITTLENUMS emitted is stored in *size. An error message is
8187 returned, or NULL on OK. */
8189 #define MAX_LITTLENUMS 5
8192 md_atof (type
, lit
, size
)
8197 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
8198 LITTLENUM_TYPE
*word
;
8228 return "Bad call to MD_ATOF()";
8230 t
= atof_ieee (input_line_pointer
, type
, words
);
8232 input_line_pointer
= t
;
8233 *size
= prec
* sizeof (LITTLENUM_TYPE
);
8235 for (word
= words
+ prec
- 1; prec
--;)
8237 md_number_to_chars (lit
, (long) (*word
--), sizeof (LITTLENUM_TYPE
));
8238 lit
+= sizeof (LITTLENUM_TYPE
);
8243 /* Round up a section's size to the appropriate boundary. */
8245 md_section_align (seg
, size
)
8249 int align
= bfd_get_section_alignment (stdoutput
, seg
);
8250 valueT mask
= ((valueT
)1 << align
) - 1;
8252 return (size
+ mask
) & ~mask
;
8255 /* Handle ia64 specific semantics of the align directive. */
8258 ia64_md_do_align (n
, fill
, len
, max
)
8264 /* Fill any pending bundle with nops. */
8265 if (bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
)
8266 ia64_flush_insns ();
8268 /* When we align code in a text section, emit a bundle of 3 nops instead of
8269 zero bytes. We can only do this if a multiple of 16 bytes was requested.
8270 N is log base 2 of the requested alignment. */
8272 && bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
8275 /* Use mfi bundle of nops with no stop bits. */
8276 static const unsigned char be_nop
[]
8277 = { 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
8278 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c};
8279 static const unsigned char le_nop
[]
8280 = { 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
8281 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00};
8283 /* Make sure we are on a 16-byte boundary, in case someone has been
8284 putting data into a text section. */
8285 frag_align (4, 0, 0);
8287 if (target_big_endian
)
8288 frag_align_pattern (n
, be_nop
, 16, max
);
8290 frag_align_pattern (n
, le_nop
, 16, max
);