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
85 FUNC_LT_FPTR_RELATIVE
,
91 REG_FR
= (REG_GR
+ 128),
92 REG_AR
= (REG_FR
+ 128),
93 REG_CR
= (REG_AR
+ 128),
94 REG_P
= (REG_CR
+ 128),
95 REG_BR
= (REG_P
+ 64),
96 REG_IP
= (REG_BR
+ 8),
103 /* The following are pseudo-registers for use by gas only. */
120 DYNREG_GR
= 0, /* dynamic general purpose register */
121 DYNREG_FR
, /* dynamic floating point register */
122 DYNREG_PR
, /* dynamic predicate register */
126 /* On the ia64, we can't know the address of a text label until the
127 instructions are packed into a bundle. To handle this, we keep
128 track of the list of labels that appear in front of each
132 struct label_fix
*next
;
136 extern int target_big_endian
;
138 /* Characters which always start a comment. */
139 const char comment_chars
[] = "";
141 /* Characters which start a comment at the beginning of a line. */
142 const char line_comment_chars
[] = "#";
144 /* Characters which may be used to separate multiple commands on a
146 const char line_separator_chars
[] = ";";
148 /* Characters which are used to indicate an exponent in a floating
150 const char EXP_CHARS
[] = "eE";
152 /* Characters which mean that a number is a floating point constant,
154 const char FLT_CHARS
[] = "rRsSfFdDxXpP";
156 /* ia64-specific option processing: */
158 const char *md_shortopts
= "M:N:x::";
160 struct option md_longopts
[] =
162 { NULL
, no_argument
, NULL
, 0}
165 size_t md_longopts_size
= sizeof (md_longopts
);
169 struct hash_control
*pseudo_hash
; /* pseudo opcode hash table */
170 struct hash_control
*reg_hash
; /* register name hash table */
171 struct hash_control
*dynreg_hash
; /* dynamic register hash table */
172 struct hash_control
*const_hash
; /* constant hash table */
173 struct hash_control
*entry_hash
; /* code entry hint hash table */
175 symbolS
*regsym
[REG_NUM
];
177 /* If X_op is != O_absent, the registername for the instruction's
178 qualifying predicate. If NULL, p0 is assumed for instructions
179 that are predicatable. */
186 explicit_mode
: 1, /* which mode we're in */
187 default_explicit_mode
: 1, /* which mode is the default */
188 mode_explicitly_set
: 1, /* was the current mode explicitly set? */
191 /* Each bundle consists of up to three instructions. We keep
192 track of four most recent instructions so we can correctly set
193 the end_of_insn_group for the last instruction in a bundle. */
195 int num_slots_in_use
;
199 end_of_insn_group
: 1,
200 manual_bundling_on
: 1,
201 manual_bundling_off
: 1;
202 signed char user_template
; /* user-selected template, if any */
203 unsigned char qp_regno
; /* qualifying predicate */
204 /* This duplicates a good fraction of "struct fix" but we
205 can't use a "struct fix" instead since we can't call
206 fix_new_exp() until we know the address of the instruction. */
210 bfd_reloc_code_real_type code
;
211 enum ia64_opnd opnd
; /* type of operand in need of fix */
212 unsigned int is_pcrel
: 1; /* is operand pc-relative? */
213 expressionS expr
; /* the value to be inserted */
215 fixup
[2]; /* at most two fixups per insn */
216 struct ia64_opcode
*idesc
;
217 struct label_fix
*label_fixups
;
218 struct unw_rec_list
*unwind_record
; /* Unwind directive. */
221 unsigned int src_line
;
222 struct dwarf2_line_info debug_line
;
230 struct dynreg
*next
; /* next dynamic register */
232 unsigned short base
; /* the base register number */
233 unsigned short num_regs
; /* # of registers in this set */
235 *dynreg
[DYNREG_NUM_TYPES
], in
, loc
, out
, rot
;
237 flagword flags
; /* ELF-header flags */
240 unsigned hint
:1; /* is this hint currently valid? */
241 bfd_vma offset
; /* mem.offset offset */
242 bfd_vma base
; /* mem.offset base */
245 int path
; /* number of alt. entry points seen */
246 const char **entry_labels
; /* labels of all alternate paths in
247 the current DV-checking block. */
248 int maxpaths
; /* size currently allocated for
253 /* application registers: */
259 #define AR_BSPSTORE 18
272 {"ar.k0", 0}, {"ar.k1", 1}, {"ar.k2", 2}, {"ar.k3", 3},
273 {"ar.k4", 4}, {"ar.k5", 5}, {"ar.k6", 6}, {"ar.k7", 7},
274 {"ar.rsc", 16}, {"ar.bsp", 17},
275 {"ar.bspstore", 18}, {"ar.rnat", 19},
276 {"ar.fcr", 21}, {"ar.eflag", 24},
277 {"ar.csd", 25}, {"ar.ssd", 26},
278 {"ar.cflg", 27}, {"ar.fsr", 28},
279 {"ar.fir", 29}, {"ar.fdr", 30},
280 {"ar.ccv", 32}, {"ar.unat", 36},
281 {"ar.fpsr", 40}, {"ar.itc", 44},
282 {"ar.pfs", 64}, {"ar.lc", 65},
303 /* control registers: */
345 static const struct const_desc
352 /* PSR constant masks: */
355 {"psr.be", ((valueT
) 1) << 1},
356 {"psr.up", ((valueT
) 1) << 2},
357 {"psr.ac", ((valueT
) 1) << 3},
358 {"psr.mfl", ((valueT
) 1) << 4},
359 {"psr.mfh", ((valueT
) 1) << 5},
361 {"psr.ic", ((valueT
) 1) << 13},
362 {"psr.i", ((valueT
) 1) << 14},
363 {"psr.pk", ((valueT
) 1) << 15},
365 {"psr.dt", ((valueT
) 1) << 17},
366 {"psr.dfl", ((valueT
) 1) << 18},
367 {"psr.dfh", ((valueT
) 1) << 19},
368 {"psr.sp", ((valueT
) 1) << 20},
369 {"psr.pp", ((valueT
) 1) << 21},
370 {"psr.di", ((valueT
) 1) << 22},
371 {"psr.si", ((valueT
) 1) << 23},
372 {"psr.db", ((valueT
) 1) << 24},
373 {"psr.lp", ((valueT
) 1) << 25},
374 {"psr.tb", ((valueT
) 1) << 26},
375 {"psr.rt", ((valueT
) 1) << 27},
376 /* 28-31: reserved */
377 /* 32-33: cpl (current privilege level) */
378 {"psr.is", ((valueT
) 1) << 34},
379 {"psr.mc", ((valueT
) 1) << 35},
380 {"psr.it", ((valueT
) 1) << 36},
381 {"psr.id", ((valueT
) 1) << 37},
382 {"psr.da", ((valueT
) 1) << 38},
383 {"psr.dd", ((valueT
) 1) << 39},
384 {"psr.ss", ((valueT
) 1) << 40},
385 /* 41-42: ri (restart instruction) */
386 {"psr.ed", ((valueT
) 1) << 43},
387 {"psr.bn", ((valueT
) 1) << 44},
390 /* indirect register-sets/memory: */
399 { "CPUID", IND_CPUID
},
400 { "cpuid", IND_CPUID
},
412 /* Pseudo functions used to indicate relocation types (these functions
413 start with an at sign (@). */
434 /* reloc pseudo functions (these must come first!): */
435 { "fptr", PSEUDO_FUNC_RELOC
},
436 { "gprel", PSEUDO_FUNC_RELOC
},
437 { "ltoff", PSEUDO_FUNC_RELOC
},
438 { "pcrel", PSEUDO_FUNC_RELOC
},
439 { "pltoff", PSEUDO_FUNC_RELOC
},
440 { "secrel", PSEUDO_FUNC_RELOC
},
441 { "segrel", PSEUDO_FUNC_RELOC
},
442 { "ltv", PSEUDO_FUNC_RELOC
},
443 { 0, }, /* placeholder for FUNC_LT_FPTR_RELATIVE */
445 /* mbtype4 constants: */
446 { "alt", PSEUDO_FUNC_CONST
, { 0xa } },
447 { "brcst", PSEUDO_FUNC_CONST
, { 0x0 } },
448 { "mix", PSEUDO_FUNC_CONST
, { 0x8 } },
449 { "rev", PSEUDO_FUNC_CONST
, { 0xb } },
450 { "shuf", PSEUDO_FUNC_CONST
, { 0x9 } },
452 /* fclass constants: */
453 { "nat", PSEUDO_FUNC_CONST
, { 0x100 } },
454 { "qnan", PSEUDO_FUNC_CONST
, { 0x080 } },
455 { "snan", PSEUDO_FUNC_CONST
, { 0x040 } },
456 { "pos", PSEUDO_FUNC_CONST
, { 0x001 } },
457 { "neg", PSEUDO_FUNC_CONST
, { 0x002 } },
458 { "zero", PSEUDO_FUNC_CONST
, { 0x004 } },
459 { "unorm", PSEUDO_FUNC_CONST
, { 0x008 } },
460 { "norm", PSEUDO_FUNC_CONST
, { 0x010 } },
461 { "inf", PSEUDO_FUNC_CONST
, { 0x020 } },
463 { "natval", PSEUDO_FUNC_CONST
, { 0x100 } }, /* old usage */
466 /* 41-bit nop opcodes (one per unit): */
467 static const bfd_vma nop
[IA64_NUM_UNITS
] =
469 0x0000000000LL
, /* NIL => break 0 */
470 0x0008000000LL
, /* I-unit nop */
471 0x0008000000LL
, /* M-unit nop */
472 0x4000000000LL
, /* B-unit nop */
473 0x0008000000LL
, /* F-unit nop */
474 0x0008000000LL
, /* L-"unit" nop */
475 0x0008000000LL
, /* X-unit nop */
478 /* Can't be `const' as it's passed to input routines (which have the
479 habit of setting temporary sentinels. */
480 static char special_section_name
[][20] =
482 {".bss"}, {".sbss"}, {".sdata"}, {".rodata"}, {".comment"},
483 {".IA_64.unwind"}, {".IA_64.unwind_info"}
486 /* The best template for a particular sequence of up to three
488 #define N IA64_NUM_TYPES
489 static unsigned char best_template
[N
][N
][N
];
492 /* Resource dependencies currently in effect */
494 int depind
; /* dependency index */
495 const struct ia64_dependency
*dependency
; /* actual dependency */
496 unsigned specific
:1, /* is this a specific bit/regno? */
497 link_to_qp_branch
:1; /* will a branch on the same QP clear it?*/
498 int index
; /* specific regno/bit within dependency */
499 int note
; /* optional qualifying note (0 if none) */
503 int insn_srlz
; /* current insn serialization state */
504 int data_srlz
; /* current data serialization state */
505 int qp_regno
; /* qualifying predicate for this usage */
506 char *file
; /* what file marked this dependency */
507 int line
; /* what line marked this dependency */
508 struct mem_offset mem_offset
; /* optional memory offset hint */
509 int path
; /* corresponding code entry index */
511 static int regdepslen
= 0;
512 static int regdepstotlen
= 0;
513 static const char *dv_mode
[] = { "RAW", "WAW", "WAR" };
514 static const char *dv_sem
[] = { "none", "implied", "impliedf",
515 "data", "instr", "specific", "other" };
517 /* Current state of PR mutexation */
518 static struct qpmutex
{
521 } *qp_mutexes
= NULL
; /* QP mutex bitmasks */
522 static int qp_mutexeslen
= 0;
523 static int qp_mutexestotlen
= 0;
524 static valueT qp_safe_across_calls
= 0;
526 /* Current state of PR implications */
527 static struct qp_imply
{
530 unsigned p2_branched
:1;
532 } *qp_implies
= NULL
;
533 static int qp_implieslen
= 0;
534 static int qp_impliestotlen
= 0;
536 /* Keep track of static GR values so that indirect register usage can
537 sometimes be tracked. */
542 } gr_values
[128] = {{ 1, 0 }};
544 /* These are the routines required to output the various types of
547 typedef struct unw_rec_list
{
549 unsigned long slot_number
;
550 struct unw_rec_list
*next
;
553 #define SLOT_NUM_NOT_SET -1
555 /* TRUE if processing unwind directives in a prologue region. */
556 static int unwind_prologue
= 0;
558 /* Maintain a list of unwind entries for the current function. */
559 static unw_rec_list
*unwind_list
= 0;
560 static unw_rec_list
*unwind_tail
= 0;
562 /* Any unwind entires that should be attached to the current
563 slot that an insn is being constructed for. */
564 static unw_rec_list
*current_unwind_entry
= 0;
566 /* These are used to create the unwind table entry for this function. */
567 static symbolS
*proc_start
= 0;
568 static symbolS
*proc_end
= 0;
569 static symbolS
*unwind_info
= 0;
570 static symbolS
*personality_routine
= 0;
572 typedef void (*vbyte_func
) PARAMS ((int, char *, char *));
574 /* Forward delarations: */
575 static int ar_is_in_integer_unit
PARAMS ((int regnum
));
576 static void set_section
PARAMS ((char *name
));
577 static unsigned int set_regstack
PARAMS ((unsigned int, unsigned int,
578 unsigned int, unsigned int));
579 static void dot_radix
PARAMS ((int));
580 static void dot_special_section
PARAMS ((int));
581 static void dot_proc
PARAMS ((int));
582 static void dot_fframe
PARAMS ((int));
583 static void dot_vframe
PARAMS ((int));
584 static void dot_save
PARAMS ((int));
585 static void dot_restore
PARAMS ((int));
586 static void dot_handlerdata
PARAMS ((int));
587 static void dot_unwentry
PARAMS ((int));
588 static void dot_altrp
PARAMS ((int));
589 static void dot_savesp
PARAMS ((int));
590 static void dot_savepsp
PARAMS ((int));
591 static void dot_saveg
PARAMS ((int));
592 static void dot_savef
PARAMS ((int));
593 static void dot_saveb
PARAMS ((int));
594 static void dot_savegf
PARAMS ((int));
595 static void dot_spill
PARAMS ((int));
596 static void dot_unwabi
PARAMS ((int));
597 static void dot_personality
PARAMS ((int));
598 static void dot_body
PARAMS ((int));
599 static void dot_prologue
PARAMS ((int));
600 static void dot_endp
PARAMS ((int));
601 static void dot_template
PARAMS ((int));
602 static void dot_regstk
PARAMS ((int));
603 static void dot_rot
PARAMS ((int));
604 static void dot_byteorder
PARAMS ((int));
605 static void dot_psr
PARAMS ((int));
606 static void dot_alias
PARAMS ((int));
607 static void dot_ln
PARAMS ((int));
608 static char *parse_section_name
PARAMS ((void));
609 static void dot_xdata
PARAMS ((int));
610 static void stmt_float_cons
PARAMS ((int));
611 static void stmt_cons_ua
PARAMS ((int));
612 static void dot_xfloat_cons
PARAMS ((int));
613 static void dot_xstringer
PARAMS ((int));
614 static void dot_xdata_ua
PARAMS ((int));
615 static void dot_xfloat_cons_ua
PARAMS ((int));
616 static void dot_pred_rel
PARAMS ((int));
617 static void dot_reg_val
PARAMS ((int));
618 static void dot_dv_mode
PARAMS ((int));
619 static void dot_entry
PARAMS ((int));
620 static void dot_mem_offset
PARAMS ((int));
621 static symbolS
* declare_register
PARAMS ((const char *name
, int regnum
));
622 static void declare_register_set
PARAMS ((const char *, int, int));
623 static unsigned int operand_width
PARAMS ((enum ia64_opnd
));
624 static int operand_match
PARAMS ((const struct ia64_opcode
*idesc
,
625 int index
, expressionS
*e
));
626 static int parse_operand
PARAMS ((expressionS
*e
));
627 static struct ia64_opcode
* parse_operands
PARAMS ((struct ia64_opcode
*));
628 static void build_insn
PARAMS ((struct slot
*, bfd_vma
*));
629 static void emit_one_bundle
PARAMS ((void));
630 static void fix_insn
PARAMS ((fixS
*, const struct ia64_operand
*, valueT
));
631 static bfd_reloc_code_real_type ia64_gen_real_reloc_type
PARAMS ((struct symbol
*sym
,
632 bfd_reloc_code_real_type r_type
));
633 static void insn_group_break
PARAMS ((int, int, int));
634 static void add_qp_mutex
PARAMS((valueT mask
));
635 static void add_qp_imply
PARAMS((int p1
, int p2
));
636 static void clear_qp_branch_flag
PARAMS((valueT mask
));
637 static void clear_qp_mutex
PARAMS((valueT mask
));
638 static void clear_qp_implies
PARAMS((valueT p1_mask
, valueT p2_mask
));
639 static void clear_register_values
PARAMS ((void));
640 static void print_dependency
PARAMS ((const char *action
, int depind
));
641 static int is_conditional_branch
PARAMS ((struct ia64_opcode
*));
642 static int is_interruption_or_rfi
PARAMS ((struct ia64_opcode
*));
643 static int check_dv
PARAMS((struct ia64_opcode
*idesc
));
644 static void check_dependencies
PARAMS((struct ia64_opcode
*));
645 static void mark_resources
PARAMS((struct ia64_opcode
*));
646 static void update_dependencies
PARAMS((struct ia64_opcode
*));
647 static void note_register_values
PARAMS((struct ia64_opcode
*));
648 static void output_R3_format
PARAMS ((vbyte_func
, unw_record_type
, unsigned long));
649 static void output_B3_format
PARAMS ((vbyte_func
, unsigned long, unsigned long));
650 static void output_B4_format
PARAMS ((vbyte_func
, unw_record_type
, unsigned long));
652 /* Determine if application register REGNUM resides in the integer
653 unit (as opposed to the memory unit). */
655 ar_is_in_integer_unit (reg
)
660 return (reg
== 64 /* pfs */
661 || reg
== 65 /* lc */
662 || reg
== 66 /* ec */
663 /* ??? ias accepts and puts these in the integer unit. */
664 || (reg
>= 112 && reg
<= 127));
667 /* Switch to section NAME and create section if necessary. It's
668 rather ugly that we have to manipulate input_line_pointer but I
669 don't see any other way to accomplish the same thing without
670 changing obj-elf.c (which may be the Right Thing, in the end). */
675 char *saved_input_line_pointer
;
677 saved_input_line_pointer
= input_line_pointer
;
678 input_line_pointer
= name
;
680 input_line_pointer
= saved_input_line_pointer
;
683 /* Map SHF_IA_64_SHORT to SEC_SMALL_DATA. */
686 ia64_elf_section_flags (flags
, attr
, type
)
690 if (attr
& SHF_IA_64_SHORT
)
691 flags
|= SEC_SMALL_DATA
;
696 set_regstack (ins
, locs
, outs
, rots
)
697 unsigned int ins
, locs
, outs
, rots
;
699 unsigned int sof
; /* size of frame */
701 sof
= ins
+ locs
+ outs
;
704 as_bad ("Size of frame exceeds maximum of 96 registers");
709 as_warn ("Size of rotating registers exceeds frame size");
712 md
.in
.base
= REG_GR
+ 32;
713 md
.loc
.base
= md
.in
.base
+ ins
;
714 md
.out
.base
= md
.loc
.base
+ locs
;
716 md
.in
.num_regs
= ins
;
717 md
.loc
.num_regs
= locs
;
718 md
.out
.num_regs
= outs
;
719 md
.rot
.num_regs
= rots
;
726 struct label_fix
*lfix
;
728 subsegT saved_subseg
;
730 if (!md
.last_text_seg
)
734 saved_subseg
= now_subseg
;
736 subseg_set (md
.last_text_seg
, 0);
738 while (md
.num_slots_in_use
> 0)
739 emit_one_bundle (); /* force out queued instructions */
741 /* In case there are labels following the last instruction, resolve
743 for (lfix
= CURR_SLOT
.label_fixups
; lfix
; lfix
= lfix
->next
)
745 S_SET_VALUE (lfix
->sym
, frag_now_fix ());
746 symbol_set_frag (lfix
->sym
, frag_now
);
748 CURR_SLOT
.label_fixups
= 0;
750 subseg_set (saved_seg
, saved_subseg
);
754 ia64_do_align (nbytes
)
757 char *saved_input_line_pointer
= input_line_pointer
;
759 input_line_pointer
= "";
760 s_align_bytes (nbytes
);
761 input_line_pointer
= saved_input_line_pointer
;
765 ia64_cons_align (nbytes
)
770 char *saved_input_line_pointer
= input_line_pointer
;
771 input_line_pointer
= "";
772 s_align_bytes (nbytes
);
773 input_line_pointer
= saved_input_line_pointer
;
777 /* Output COUNT bytes to a memory location. */
778 static unsigned char *vbyte_mem_ptr
= NULL
;
781 output_vbyte_mem (count
, ptr
, comment
)
787 if (vbyte_mem_ptr
== NULL
)
792 for (x
= 0; x
< count
; x
++)
793 *(vbyte_mem_ptr
++) = ptr
[x
];
796 /* Count the number of bytes required for records. */
797 static int vbyte_count
= 0;
799 count_output (count
, ptr
, comment
)
804 vbyte_count
+= count
;
808 output_R1_format (f
, rtype
, rlen
)
810 unw_record_type rtype
;
817 output_R3_format (f
, rtype
, rlen
);
820 if (rtype
== prologue
)
826 as_bad ("record type is not valid");
828 byte
= UNW_R1
| (r
<< 5) | (rlen
& 0x1f);
829 (*f
) (1, &byte
, NULL
);
833 output_R2_format (f
, mask
, grsave
, rlen
)
840 mask
= (mask
& 0x0f);
841 grsave
= (grsave
& 0x7f);
843 bytes
[0] = (UNW_R2
| (mask
>> 1));
844 bytes
[1] = (((mask
& 0x01) << 7) | grsave
);
845 count
+= output_leb128 (bytes
+ 2, rlen
, 0);
846 (*f
) (count
, bytes
, NULL
);
850 output_R3_format (f
, rtype
, rlen
)
852 unw_record_type rtype
;
859 output_R1_format (f
, rtype
, rlen
);
862 if (rtype
== prologue
)
868 as_bad ("record type is not valid");
869 bytes
[0] = (UNW_R3
| r
);
870 count
= output_leb128 (bytes
+ 1, rlen
, 0);
871 (*f
) (count
+ 1, bytes
, NULL
);
875 output_P1_format (f
, brmask
)
880 byte
= UNW_P1
| (brmask
& 0x1f);
881 (*f
) (1, &byte
, NULL
);
885 output_P2_format (f
, brmask
, gr
)
891 brmask
= (brmask
& 0x1f);
892 bytes
[0] = UNW_P2
| (brmask
>> 1);
893 bytes
[1] = (((brmask
& 1) << 7) | gr
);
894 (*f
) (2, bytes
, NULL
);
898 output_P3_format (f
, rtype
, reg
)
900 unw_record_type rtype
;
945 as_bad ("Invalid record type for P3 format.");
947 bytes
[0] = (UNW_P3
| (r
>> 1));
948 bytes
[1] = (((r
& 1) << 7) | reg
);
949 (*f
) (2, bytes
, NULL
);
954 output_P4_format (f
, count
, imask
)
960 bytes
= alloca (count
+ 1);
962 memcpy (bytes
+ 1, imask
, count
);
963 (*f
) (count
+ 1, bytes
, NULL
);
967 output_P5_format (f
, grmask
, frmask
)
970 unsigned long frmask
;
973 grmask
= (grmask
& 0x0f);
976 bytes
[1] = ((grmask
<< 4) | ((frmask
& 0x000f0000) >> 16));
977 bytes
[2] = ((frmask
& 0x0000ff00) >> 8);
978 bytes
[3] = (frmask
& 0x000000ff);
979 (*f
) (4, bytes
, NULL
);
983 output_P6_format (f
, rtype
, rmask
)
985 unw_record_type rtype
;
996 as_bad ("Invalid record type for format P6");
997 byte
= (UNW_P6
| (r
<< 4) | (rmask
& 0x0f));
998 (*f
) (1, &byte
, NULL
);
1002 output_P7_format (f
, rtype
, w1
, w2
)
1004 unw_record_type rtype
;
1011 count
+= output_leb128 (bytes
+ 1, w1
, 0);
1016 count
+= output_leb128 (bytes
+ count
, w2
>> 4, 0);
1064 bytes
[0] = (UNW_P7
| r
);
1065 (*f
) (count
, bytes
, NULL
);
1069 output_P8_format (f
, rtype
, t
)
1071 unw_record_type rtype
;
1110 case bspstore_psprel
:
1113 case bspstore_sprel
:
1125 case priunat_when_gr
:
1128 case priunat_psprel
:
1134 case priunat_when_mem
:
1139 count
+= output_leb128 (bytes
+ 2, t
, 0);
1140 (*f
) (count
, bytes
, NULL
);
1144 output_P9_format (f
, grmask
, gr
)
1151 bytes
[1] = (grmask
& 0x0f);
1152 bytes
[2] = (gr
& 0x7f);
1153 (*f
) (3, bytes
, NULL
);
1157 output_P10_format (f
, abi
, context
)
1164 bytes
[1] = (abi
& 0xff);
1165 bytes
[2] = (context
& 0xff);
1166 (*f
) (3, bytes
, NULL
);
1170 output_B1_format (f
, rtype
, label
)
1172 unw_record_type rtype
;
1173 unsigned long label
;
1179 output_B4_format (f
, rtype
, label
);
1182 if (rtype
== label_state
)
1185 if (rtype
== copy_state
)
1188 as_bad ("Invalid record type for format B1");
1190 byte
= (UNW_B1
| (r
<< 5) | (label
& 0x1f));
1191 (*f
) (1, &byte
, NULL
);
1195 output_B2_format (f
, ecount
, t
)
1197 unsigned long ecount
;
1204 output_B3_format (f
, ecount
, t
);
1207 bytes
[0] = (UNW_B2
| (ecount
& 0x1f));
1208 count
+= output_leb128 (bytes
+ 1, t
, 0);
1209 (*f
) (count
, bytes
, NULL
);
1213 output_B3_format (f
, ecount
, t
)
1215 unsigned long ecount
;
1222 output_B2_format (f
, ecount
, t
);
1226 count
+= output_leb128 (bytes
+ 1, t
, 0);
1227 count
+= output_leb128 (bytes
+ count
, ecount
, 0);
1228 (*f
) (count
, bytes
, NULL
);
1232 output_B4_format (f
, rtype
, label
)
1234 unw_record_type rtype
;
1235 unsigned long label
;
1242 output_B1_format (f
, rtype
, label
);
1245 if (rtype
== label_state
)
1248 if (rtype
== copy_state
)
1251 as_bad ("Invalid record type for format B1");
1253 bytes
[0] = (UNW_B4
| (r
<< 3));
1254 count
+= output_leb128 (bytes
+ 1, label
, 0);
1255 (*f
) (count
, bytes
, NULL
);
1259 format_a_b_reg (a
, b
, reg
)
1267 ret
= (a
<< 6) | (a
<< 5) | reg
;
1272 output_X1_format (f
, rtype
, a
, b
, reg
, t
, w1
)
1274 unw_record_type rtype
;
1283 if (rtype
== spill_psprel
)
1286 if (rtype
= spill_sprel
)
1289 as_bad ("Invalid record type for format X1");
1290 bytes
[1] = ((r
<< 7) | format_a_b_reg (a
, b
, reg
));
1291 count
+= output_leb128 (bytes
+ 2, t
, 0);
1292 count
+= output_leb128 (bytes
+ count
, w1
, 0);
1293 (*f
) (count
, bytes
, NULL
);
1297 output_X2_format (f
, a
, b
, reg
, x
, y
, treg
, t
)
1307 bytes
[1] = (((x
& 1) << 7) | format_a_b_reg (a
, b
, reg
));
1308 bytes
[2] = (((y
& 1) << 7) | (treg
& 0x7f));
1309 count
+= output_leb128 (bytes
+ 3, t
, 0);
1310 (*f
) (count
, bytes
, NULL
);
1314 output_X3_format (f
, rtype
, qp
, a
, b
, reg
, t
, w1
)
1316 unw_record_type rtype
;
1326 if (rtype
== spill_psprel_p
)
1329 if (rtype
= spill_sprel_p
)
1332 as_bad ("Invalid record type for format X1");
1333 bytes
[1] = ((r
<< 7) | (qp
& 0x3f));
1334 bytes
[2] = format_a_b_reg (a
, b
, reg
);
1335 count
+= output_leb128 (bytes
+ 3, t
, 0);
1336 count
+= output_leb128 (bytes
+ count
, w1
, 0);
1337 (*f
) (count
, bytes
, NULL
);
1341 output_X4_format (f
, qp
, a
, b
, reg
, x
, y
, treg
, t
)
1352 bytes
[1] = (qp
& 0x3f);
1353 bytes
[2] = (((x
& 1) << 7) | format_a_b_reg (a
, b
, reg
));
1354 bytes
[3] = (((y
& 1) << 7) | (treg
& 0x7f));
1355 count
+= output_leb128 (bytes
+ 4, t
, 0);
1356 (*f
) (count
, bytes
, NULL
);
1359 /* This function allocates a record list structure, and initializes fields. */
1360 static unw_rec_list
*
1361 alloc_record (unw_record_type t
)
1364 ptr
= xmalloc (sizeof (*ptr
));
1366 ptr
->slot_number
= SLOT_NUM_NOT_SET
;
1371 /* This function frees a record list structure. */
1373 free_record (unw_rec_list
*ptr
)
1378 /* This function frees an entire list of record structures. */
1380 free_list_records (unw_rec_list
*first
)
1383 for (ptr
= first
; ptr
!= NULL
; )
1385 unw_rec_list
*tmp
= ptr
;
1391 static unw_rec_list
*
1394 unw_rec_list
*ptr
= alloc_record (prologue
);
1398 static unw_rec_list
*
1399 output_prologue_gr (saved_mask
, reg
)
1400 unsigned int saved_mask
;
1403 unw_rec_list
*ptr
= alloc_record (prologue_gr
);
1404 ptr
->r
.record
.r
.mask
= saved_mask
;
1405 ptr
->r
.record
.r
.grsave
= reg
;
1409 static unw_rec_list
*
1412 unw_rec_list
*ptr
= alloc_record (body
);
1416 static unw_rec_list
*
1417 output_mem_stack_f (size
)
1420 unw_rec_list
*ptr
= alloc_record (mem_stack_f
);
1421 ptr
->r
.record
.p
.size
= size
;
1425 static unw_rec_list
*
1426 output_mem_stack_v ()
1428 unw_rec_list
*ptr
= alloc_record (mem_stack_v
);
1432 static unw_rec_list
*
1436 unw_rec_list
*ptr
= alloc_record (psp_gr
);
1437 ptr
->r
.record
.p
.gr
= gr
;
1441 static unw_rec_list
*
1442 output_psp_sprel (offset
)
1443 unsigned int offset
;
1445 unw_rec_list
*ptr
= alloc_record (psp_sprel
);
1446 ptr
->r
.record
.p
.spoff
= offset
;
1450 static unw_rec_list
*
1453 unw_rec_list
*ptr
= alloc_record (rp_when
);
1457 static unw_rec_list
*
1461 unw_rec_list
*ptr
= alloc_record (rp_gr
);
1462 ptr
->r
.record
.p
.gr
= gr
;
1466 static unw_rec_list
*
1470 unw_rec_list
*ptr
= alloc_record (rp_br
);
1471 ptr
->r
.record
.p
.br
= br
;
1475 static unw_rec_list
*
1476 output_rp_psprel (offset
)
1477 unsigned int offset
;
1479 unw_rec_list
*ptr
= alloc_record (rp_psprel
);
1480 ptr
->r
.record
.p
.pspoff
= offset
;
1484 static unw_rec_list
*
1485 output_rp_sprel (offset
)
1486 unsigned int offset
;
1488 unw_rec_list
*ptr
= alloc_record (rp_sprel
);
1489 ptr
->r
.record
.p
.spoff
= offset
;
1493 static unw_rec_list
*
1496 unw_rec_list
*ptr
= alloc_record (pfs_when
);
1500 static unw_rec_list
*
1504 unw_rec_list
*ptr
= alloc_record (pfs_gr
);
1505 ptr
->r
.record
.p
.gr
= gr
;
1509 static unw_rec_list
*
1510 output_pfs_psprel (offset
)
1511 unsigned int offset
;
1513 unw_rec_list
*ptr
= alloc_record (pfs_psprel
);
1514 ptr
->r
.record
.p
.pspoff
= offset
;
1518 static unw_rec_list
*
1519 output_pfs_sprel (offset
)
1520 unsigned int offset
;
1522 unw_rec_list
*ptr
= alloc_record (pfs_sprel
);
1523 ptr
->r
.record
.p
.spoff
= offset
;
1527 static unw_rec_list
*
1528 output_preds_when ()
1530 unw_rec_list
*ptr
= alloc_record (preds_when
);
1534 static unw_rec_list
*
1535 output_preds_gr (gr
)
1538 unw_rec_list
*ptr
= alloc_record (preds_gr
);
1539 ptr
->r
.record
.p
.gr
= gr
;
1543 static unw_rec_list
*
1544 output_preds_psprel (offset
)
1545 unsigned int offset
;
1547 unw_rec_list
*ptr
= alloc_record (preds_psprel
);
1548 ptr
->r
.record
.p
.pspoff
= offset
;
1552 static unw_rec_list
*
1553 output_preds_sprel (offset
)
1554 unsigned int offset
;
1556 unw_rec_list
*ptr
= alloc_record (preds_sprel
);
1557 ptr
->r
.record
.p
.spoff
= offset
;
1561 static unw_rec_list
*
1562 output_fr_mem (mask
)
1565 unw_rec_list
*ptr
= alloc_record (fr_mem
);
1566 ptr
->r
.record
.p
.rmask
= mask
;
1570 static unw_rec_list
*
1571 output_frgr_mem (gr_mask
, fr_mask
)
1572 unsigned int gr_mask
;
1573 unsigned int fr_mask
;
1575 unw_rec_list
*ptr
= alloc_record (frgr_mem
);
1576 ptr
->r
.record
.p
.grmask
= gr_mask
;
1577 ptr
->r
.record
.p
.frmask
= fr_mask
;
1581 static unw_rec_list
*
1582 output_gr_gr (mask
, reg
)
1586 unw_rec_list
*ptr
= alloc_record (gr_gr
);
1587 ptr
->r
.record
.p
.grmask
= mask
;
1588 ptr
->r
.record
.p
.gr
= reg
;
1592 static unw_rec_list
*
1593 output_gr_mem (mask
)
1596 unw_rec_list
*ptr
= alloc_record (gr_mem
);
1597 ptr
->r
.record
.p
.rmask
= mask
;
1601 static unw_rec_list
*
1602 output_br_mem (unsigned int mask
)
1604 unw_rec_list
*ptr
= alloc_record (br_mem
);
1605 ptr
->r
.record
.p
.brmask
= mask
;
1609 static unw_rec_list
*
1610 output_br_gr (save_mask
, reg
)
1611 unsigned int save_mask
;
1614 unw_rec_list
*ptr
= alloc_record (br_gr
);
1615 ptr
->r
.record
.p
.brmask
= save_mask
;
1616 ptr
->r
.record
.p
.gr
= reg
;
1620 static unw_rec_list
*
1621 output_spill_base (offset
)
1622 unsigned int offset
;
1624 unw_rec_list
*ptr
= alloc_record (spill_base
);
1625 ptr
->r
.record
.p
.pspoff
= offset
;
1629 static unw_rec_list
*
1630 output_spill_mask ()
1632 /* TODO - how to implement this record.... I guess GAS could fill in the
1633 correct fields from the record list and construct one of these
1634 after the symbols have been resolved and we know how big the
1635 region is. This could be done in fixup_unw_records. */
1636 unw_rec_list
*ptr
= NULL
;
1640 static unw_rec_list
*
1643 unw_rec_list
*ptr
= alloc_record (unat_when
);
1647 static unw_rec_list
*
1651 unw_rec_list
*ptr
= alloc_record (unat_gr
);
1652 ptr
->r
.record
.p
.gr
= gr
;
1656 static unw_rec_list
*
1657 output_unat_psprel (offset
)
1658 unsigned int offset
;
1660 unw_rec_list
*ptr
= alloc_record (unat_psprel
);
1661 ptr
->r
.record
.p
.pspoff
= offset
;
1665 static unw_rec_list
*
1666 output_unat_sprel (offset
)
1667 unsigned int offset
;
1669 unw_rec_list
*ptr
= alloc_record (unat_sprel
);
1670 ptr
->r
.record
.p
.spoff
= offset
;
1674 static unw_rec_list
*
1677 unw_rec_list
*ptr
= alloc_record (lc_when
);
1681 static unw_rec_list
*
1685 unw_rec_list
*ptr
= alloc_record (lc_gr
);
1686 ptr
->r
.record
.p
.gr
= gr
;
1690 static unw_rec_list
*
1691 output_lc_psprel (offset
)
1692 unsigned int offset
;
1694 unw_rec_list
*ptr
= alloc_record (lc_psprel
);
1695 ptr
->r
.record
.p
.pspoff
= offset
;
1699 static unw_rec_list
*
1700 output_lc_sprel (offset
)
1701 unsigned int offset
;
1703 unw_rec_list
*ptr
= alloc_record (lc_sprel
);
1704 ptr
->r
.record
.p
.spoff
= offset
;
1708 static unw_rec_list
*
1711 unw_rec_list
*ptr
= alloc_record (fpsr_when
);
1715 static unw_rec_list
*
1719 unw_rec_list
*ptr
= alloc_record (fpsr_gr
);
1720 ptr
->r
.record
.p
.gr
= gr
;
1724 static unw_rec_list
*
1725 output_fpsr_psprel (offset
)
1726 unsigned int offset
;
1728 unw_rec_list
*ptr
= alloc_record (fpsr_psprel
);
1729 ptr
->r
.record
.p
.pspoff
= offset
;
1733 static unw_rec_list
*
1734 output_fpsr_sprel (offset
)
1735 unsigned int offset
;
1737 unw_rec_list
*ptr
= alloc_record (fpsr_sprel
);
1738 ptr
->r
.record
.p
.spoff
= offset
;
1742 static unw_rec_list
*
1743 output_priunat_when_gr ()
1745 unw_rec_list
*ptr
= alloc_record (priunat_when_gr
);
1749 static unw_rec_list
*
1750 output_priunat_when_mem ()
1752 unw_rec_list
*ptr
= alloc_record (priunat_when_mem
);
1756 static unw_rec_list
*
1757 output_priunat_gr (gr
)
1760 unw_rec_list
*ptr
= alloc_record (priunat_gr
);
1761 ptr
->r
.record
.p
.gr
= gr
;
1765 static unw_rec_list
*
1766 output_priunat_psprel (offset
)
1767 unsigned int offset
;
1769 unw_rec_list
*ptr
= alloc_record (priunat_psprel
);
1770 ptr
->r
.record
.p
.pspoff
= offset
;
1774 static unw_rec_list
*
1775 output_priunat_sprel (offset
)
1776 unsigned int offset
;
1778 unw_rec_list
*ptr
= alloc_record (priunat_sprel
);
1779 ptr
->r
.record
.p
.spoff
= offset
;
1783 static unw_rec_list
*
1786 unw_rec_list
*ptr
= alloc_record (bsp_when
);
1790 static unw_rec_list
*
1794 unw_rec_list
*ptr
= alloc_record (bsp_gr
);
1795 ptr
->r
.record
.p
.gr
= gr
;
1799 static unw_rec_list
*
1800 output_bsp_psprel (offset
)
1801 unsigned int offset
;
1803 unw_rec_list
*ptr
= alloc_record (bsp_psprel
);
1804 ptr
->r
.record
.p
.pspoff
= offset
;
1808 static unw_rec_list
*
1809 output_bsp_sprel (offset
)
1810 unsigned int offset
;
1812 unw_rec_list
*ptr
= alloc_record (bsp_sprel
);
1813 ptr
->r
.record
.p
.spoff
= offset
;
1817 static unw_rec_list
*
1818 output_bspstore_when ()
1820 unw_rec_list
*ptr
= alloc_record (bspstore_when
);
1824 static unw_rec_list
*
1825 output_bspstore_gr (gr
)
1828 unw_rec_list
*ptr
= alloc_record (bspstore_gr
);
1829 ptr
->r
.record
.p
.gr
= gr
;
1833 static unw_rec_list
*
1834 output_bspstore_psprel (offset
)
1835 unsigned int offset
;
1837 unw_rec_list
*ptr
= alloc_record (bspstore_psprel
);
1838 ptr
->r
.record
.p
.pspoff
= offset
;
1842 static unw_rec_list
*
1843 output_bspstore_sprel (offset
)
1844 unsigned int offset
;
1846 unw_rec_list
*ptr
= alloc_record (bspstore_sprel
);
1847 ptr
->r
.record
.p
.spoff
= offset
;
1851 static unw_rec_list
*
1854 unw_rec_list
*ptr
= alloc_record (rnat_when
);
1858 static unw_rec_list
*
1862 unw_rec_list
*ptr
= alloc_record (rnat_gr
);
1863 ptr
->r
.record
.p
.gr
= gr
;
1867 static unw_rec_list
*
1868 output_rnat_psprel (offset
)
1869 unsigned int offset
;
1871 unw_rec_list
*ptr
= alloc_record (rnat_psprel
);
1872 ptr
->r
.record
.p
.pspoff
= offset
;
1876 static unw_rec_list
*
1877 output_rnat_sprel (offset
)
1878 unsigned int offset
;
1880 unw_rec_list
*ptr
= alloc_record (rnat_sprel
);
1881 ptr
->r
.record
.p
.spoff
= offset
;
1885 static unw_rec_list
*
1888 unw_rec_list
*ptr
= NULL
;
1892 static unw_rec_list
*
1893 output_label_state ()
1895 unw_rec_list
*ptr
= NULL
;
1899 static unw_rec_list
*
1900 output_copy_state ()
1902 unw_rec_list
*ptr
= NULL
;
1906 static unw_rec_list
*
1907 output_spill_psprel (reg
, offset
)
1909 unsigned int offset
;
1911 unw_rec_list
*ptr
= alloc_record (spill_psprel
);
1912 ptr
->r
.record
.x
.reg
= reg
;
1913 ptr
->r
.record
.x
.pspoff
= offset
;
1917 static unw_rec_list
*
1918 output_spill_sprel (reg
, offset
)
1920 unsigned int offset
;
1922 unw_rec_list
*ptr
= alloc_record (spill_sprel
);
1923 ptr
->r
.record
.x
.reg
= reg
;
1924 ptr
->r
.record
.x
.spoff
= offset
;
1928 static unw_rec_list
*
1929 output_spill_psprel_p (reg
, offset
, predicate
)
1931 unsigned int offset
;
1932 unsigned int predicate
;
1934 unw_rec_list
*ptr
= alloc_record (spill_psprel_p
);
1935 ptr
->r
.record
.x
.reg
= reg
;
1936 ptr
->r
.record
.x
.pspoff
= offset
;
1937 ptr
->r
.record
.x
.qp
= predicate
;
1941 static unw_rec_list
*
1942 output_spill_sprel_p (reg
, offset
, predicate
)
1944 unsigned int offset
;
1945 unsigned int predicate
;
1947 unw_rec_list
*ptr
= alloc_record (spill_sprel_p
);
1948 ptr
->r
.record
.x
.reg
= reg
;
1949 ptr
->r
.record
.x
.spoff
= offset
;
1950 ptr
->r
.record
.x
.qp
= predicate
;
1954 static unw_rec_list
*
1955 output_spill_reg (reg
, targ_reg
, xy
)
1957 unsigned int targ_reg
;
1960 unw_rec_list
*ptr
= alloc_record (spill_reg
);
1961 ptr
->r
.record
.x
.reg
= reg
;
1962 ptr
->r
.record
.x
.treg
= targ_reg
;
1963 ptr
->r
.record
.x
.xy
= xy
;
1967 static unw_rec_list
*
1968 output_spill_reg_p (reg
, targ_reg
, xy
, predicate
)
1970 unsigned int targ_reg
;
1972 unsigned int predicate
;
1974 unw_rec_list
*ptr
= alloc_record (spill_reg_p
);
1975 ptr
->r
.record
.x
.reg
= reg
;
1976 ptr
->r
.record
.x
.treg
= targ_reg
;
1977 ptr
->r
.record
.x
.xy
= xy
;
1978 ptr
->r
.record
.x
.qp
= predicate
;
1982 /* Given a unw_rec_list process the correct format with the
1983 specified function. */
1985 process_one_record (ptr
, f
)
1989 switch (ptr
->r
.type
)
1993 output_R1_format (f
, ptr
->r
.type
, ptr
->r
.record
.r
.rlen
);
1996 output_R2_format (f
, ptr
->r
.record
.r
.mask
,
1997 ptr
->r
.record
.r
.grsave
, ptr
->r
.record
.r
.rlen
);
2001 output_P7_format (f
, ptr
->r
.type
, ptr
->r
.record
.p
.t
,
2002 ptr
->r
.record
.p
.size
);
2015 output_P3_format (f
, ptr
->r
.type
, ptr
->r
.record
.p
.gr
);
2018 output_P3_format (f
, rp_br
, ptr
->r
.record
.p
.br
);
2021 output_P7_format (f
, psp_sprel
, ptr
->r
.record
.p
.spoff
, 0);
2029 output_P7_format (f
, ptr
->r
.type
, ptr
->r
.record
.p
.t
, 0);
2038 output_P7_format (f
, ptr
->r
.type
, ptr
->r
.record
.p
.pspoff
, 0);
2048 case bspstore_sprel
:
2050 output_P8_format (f
, ptr
->r
.type
, ptr
->r
.record
.p
.spoff
);
2054 output_P6_format (f
, ptr
->r
.type
, ptr
->r
.record
.p
.rmask
);
2057 output_P5_format (f
, ptr
->r
.record
.p
.grmask
, ptr
->r
.record
.p
.frmask
);
2060 output_P9_format (f
, ptr
->r
.record
.p
.grmask
, ptr
->r
.record
.p
.gr
);
2063 output_P1_format (f
, ptr
->r
.record
.p
.brmask
);
2066 output_P2_format (f
, ptr
->r
.record
.p
.brmask
, ptr
->r
.record
.p
.gr
);
2069 as_bad ("spill_mask record unimplemented.");
2071 case priunat_when_gr
:
2072 case priunat_when_mem
:
2076 output_P8_format (f
, ptr
->r
.type
, ptr
->r
.record
.p
.t
);
2078 case priunat_psprel
:
2080 case bspstore_psprel
:
2082 output_P8_format (f
, ptr
->r
.type
, ptr
->r
.record
.p
.pspoff
);
2085 as_bad ("epilogue record unimplemented.");
2088 as_bad ("label_state record unimplemented.");
2091 as_bad ("copy_state record unimplemented.");
2096 case spill_psprel_p
:
2099 as_bad ("spill_* record unimplemented.");
2102 as_bad ("record_type_not_valid");
2107 /* Given a unw_rec_list list, process all the records with
2108 the specified function. */
2110 process_unw_records (list
, f
)
2115 for (ptr
= list
; ptr
; ptr
= ptr
->next
)
2116 process_one_record (ptr
, f
);
2119 /* Determine the size of a record list in bytes. */
2121 calc_record_size (list
)
2125 process_unw_records (list
, count_output
);
2129 /* Given a complete record list, process any records which have
2130 unresolved fields, (ie length counts for a prologue). After
2131 this has been run, all neccessary information should be available
2132 within each record to generate an image. */
2134 fixup_unw_records (list
)
2138 unsigned long first_addr
= 0;
2139 for (ptr
= list
; ptr
; ptr
= ptr
->next
)
2141 if (ptr
->slot_number
== SLOT_NUM_NOT_SET
)
2142 as_bad (" Insn slot not set in unwind record.");
2143 switch (ptr
->r
.type
)
2151 unsigned long last_addr
;
2152 first_addr
= ptr
->slot_number
;
2153 ptr
->slot_number
= 0;
2154 /* Find either the next body/prologue start, or the end of
2155 the list, and determine the size of the region. */
2156 for (last
= ptr
; last
->next
!= NULL
; last
= last
->next
)
2157 if (last
->next
->r
.type
== prologue
2158 || last
->next
->r
.type
== prologue_gr
2159 || last
->next
->r
.type
== body
)
2163 last_addr
= last
->slot_number
;
2164 size
= ((last_addr
- first_addr
) / 16) * 3 + last_addr
% 4;
2165 ptr
->r
.record
.r
.rlen
= size
;
2176 case priunat_when_gr
:
2177 case priunat_when_mem
:
2182 /* All the time fields. */
2183 int x
= ptr
->slot_number
- first_addr
;
2184 ptr
->r
.record
.p
.t
= (x
/ 16) * 3 + (ptr
->slot_number
% 4);
2187 /* TODO. We also need to combine all the register masks into a single
2188 record. (Ie, all the save.g save.gf, save.f and save.br's) */
2193 /* Generate an unwind image from a record list. Returns the number of
2194 bytes in the resulting image. The memory image itselof is returned
2195 in the 'ptr' parameter. */
2197 output_unw_records (list
, ptr
)
2201 int size
, x
, extra
= 0;
2204 fixup_unw_records (list
);
2205 size
= calc_record_size (list
);
2207 /* pad to 8 byte boundry. */
2211 /* Add 8 for the header + 8 more bytes for the personality offset. */
2212 mem
= xmalloc (size
+ extra
+ 16);
2214 vbyte_mem_ptr
= mem
+ 8;
2215 /* Clear the padding area and personality. */
2216 memset (mem
+ 8 + size
, 0 , extra
+ 8);
2217 /* Initialize the header area. */
2218 md_number_to_chars (mem
, ( ((bfd_vma
) 1 << 48) /* version */
2219 | ((bfd_vma
) 3 << 32) /* U & E handler flags */
2220 | ((size
+ extra
) / 8)), /* length (dwords) */
2223 process_unw_records (list
, output_vbyte_mem
);
2226 return size
+ extra
+ 16;
2236 radix
= *input_line_pointer
++;
2238 if (radix
!= 'C' && !is_end_of_line
[(unsigned char) radix
])
2240 as_bad ("Radix `%c' unsupported", *input_line_pointer
);
2241 ignore_rest_of_line ();
2246 /* .sbss, .bss etc. are macros that expand into ".section SECNAME". */
2248 dot_special_section (which
)
2251 set_section ((char *) special_section_name
[which
]);
2255 add_unwind_entry (ptr
)
2259 unwind_tail
->next
= ptr
;
2264 /* The current entry can in fact be a chain of unwind entries. */
2265 if (current_unwind_entry
== NULL
)
2266 current_unwind_entry
= ptr
;
2276 if (e
.X_op
!= O_constant
)
2277 as_bad ("Operand to .fframe must be a constant");
2280 add_unwind_entry (output_mem_stack_f (e
.X_add_number
));
2288 discard_rest_of_line ();
2299 sep
= parse_operand (&e1
);
2301 as_bad ("No second operand to .save");
2302 sep
= parse_operand (&e2
);
2304 reg1
= e1
.X_add_number
- REG_AR
;
2305 reg2
= e2
.X_add_number
- REG_GR
;
2307 /* Make sure its a valid ar.xxx reg, OR its br0, aka 'rp'. */
2308 if (e1
.X_op
== O_register
2309 && ((reg1
>=0 && reg1
< 128) || reg1
== REG_BR
- REG_AR
))
2311 if (e2
.X_op
== O_register
&& reg2
>=0 && reg2
< 128)
2315 case 17: /* ar.bsp */
2316 add_unwind_entry (output_bsp_when ());
2317 add_unwind_entry (output_bsp_gr (reg2
));
2319 case 18: /* ar.bspstore */
2320 add_unwind_entry (output_bspstore_when ());
2321 add_unwind_entry (output_bspstore_gr (reg2
));
2323 case 19: /* ar.rnat */
2324 add_unwind_entry (output_rnat_when ());
2325 add_unwind_entry (output_rnat_gr (reg2
));
2327 case 36: /* ar.unat */
2328 add_unwind_entry (output_unat_when ());
2329 add_unwind_entry (output_unat_gr (reg2
));
2331 case 40: /* ar.fpsr */
2332 add_unwind_entry (output_fpsr_when ());
2333 add_unwind_entry (output_fpsr_gr (reg2
));
2335 case 64: /* ar.pfs */
2336 add_unwind_entry (output_pfs_when ());
2337 add_unwind_entry (output_pfs_gr (reg2
));
2339 case 65: /* ar.lc */
2340 add_unwind_entry (output_lc_when ());
2341 add_unwind_entry (output_lc_gr (reg2
));
2343 case REG_BR
- REG_AR
: /* rp */
2344 add_unwind_entry (output_rp_when ());
2345 add_unwind_entry (output_rp_gr (reg2
));
2348 as_bad ("first operand is unknown application register");
2352 as_bad (" Second operand not a valid register");
2355 as_bad ("First operand not a valid register");
2362 discard_rest_of_line ();
2366 generate_unwind_image ()
2369 unsigned char *unw_rec
;
2372 /* Generate the unwind record. */
2373 size
= output_unw_records (unwind_list
, &unw_rec
);
2375 as_bad ("Unwind record is ont a multiple of 4 bytes.");
2377 /* If there are unwind records, switch sections, and output the info. */
2381 unsigned char *where
;
2382 unsigned char *personality
;
2385 set_section ((char *) special_section_name
[SPECIAL_SECTION_UNWIND_INFO
]);
2387 /* Set expression which points to start of unwind descriptor area. */
2388 unwind_info
= expr_build_dot ();
2390 where
= (unsigned char *)frag_more (size
);
2392 /* Issue a label for this address, and keep track of it to put it
2393 in the unwind section. */
2395 /* Copy the information from the unwind record into this section. The
2396 data is already in the correct byte order. */
2397 memcpy (where
, unw_rec
, size
);
2398 /* Add the personality address to the image. */
2399 if (personality_routine
!= 0)
2401 exp
.X_op
= O_symbol
;
2402 exp
.X_add_symbol
= personality_routine
;
2403 exp
.X_add_number
= 0;
2404 fix_new_exp (frag_now
, frag_now_fix () - 8, 8,
2405 &exp
, 0, BFD_RELOC_IA64_LTOFF_FPTR64LSB
);
2406 personality_routine
= 0;
2408 obj_elf_previous (0);
2411 free_list_records (unwind_list
);
2412 unwind_list
= unwind_tail
= current_unwind_entry
= NULL
;
2418 dot_handlerdata (dummy
)
2421 generate_unwind_image ();
2425 dot_unwentry (dummy
)
2428 discard_rest_of_line ();
2435 discard_rest_of_line ();
2446 sep
= parse_operand (&e1
);
2448 as_bad ("No second operand to .savesp");
2449 sep
= parse_operand (&e2
);
2451 reg1
= e1
.X_add_number
- REG_AR
;
2452 val
= e2
.X_add_number
;
2454 /* Make sure its a valid ar.xxx reg, OR its br0, aka 'rp'. */
2455 if (e1
.X_op
== O_register
2456 && ((reg1
>=0 && reg1
< 128) || reg1
== REG_BR
- REG_AR
|| reg1
== REG_PR
- REG_AR
))
2458 if (e2
.X_op
== O_constant
)
2462 case 17: /* ar.bsp */
2463 add_unwind_entry (output_bsp_when ());
2464 add_unwind_entry (output_bsp_sprel (val
));
2466 case 18: /* ar.bspstore */
2467 add_unwind_entry (output_bspstore_when ());
2468 add_unwind_entry (output_bspstore_sprel (val
));
2470 case 19: /* ar.rnat */
2471 add_unwind_entry (output_rnat_when ());
2472 add_unwind_entry (output_rnat_sprel (val
));
2474 case 36: /* ar.unat */
2475 add_unwind_entry (output_unat_when ());
2476 add_unwind_entry (output_unat_sprel (val
));
2478 case 40: /* ar.fpsr */
2479 add_unwind_entry (output_fpsr_when ());
2480 add_unwind_entry (output_fpsr_sprel (val
));
2482 case 64: /* ar.pfs */
2483 add_unwind_entry (output_pfs_when ());
2484 add_unwind_entry (output_pfs_sprel (val
));
2486 case 65: /* ar.lc */
2487 add_unwind_entry (output_lc_when ());
2488 add_unwind_entry (output_lc_sprel (val
));
2490 case REG_BR
- REG_AR
: /* rp */
2491 add_unwind_entry (output_rp_when ());
2492 add_unwind_entry (output_rp_sprel (val
));
2494 case REG_PR
- REG_AR
: /* Predicate registers. */
2495 add_unwind_entry (output_preds_when ());
2496 add_unwind_entry (output_preds_sprel (val
));
2499 as_bad ("first operand is unknown application register");
2503 as_bad (" Second operand not a valid constant");
2506 as_bad ("First operand not a valid register");
2513 discard_rest_of_line ();
2522 sep
= parse_operand (&e1
);
2524 parse_operand (&e2
);
2526 if (e1
.X_op
!= O_constant
)
2527 as_bad ("First operand to .save.g must be a constant.");
2530 int grmask
= e1
.X_add_number
;
2532 add_unwind_entry (output_gr_mem (grmask
));
2535 int reg
= e2
.X_add_number
- REG_GR
;
2536 if (e2
.X_op
== O_register
&& reg
>=0 && reg
< 128)
2537 add_unwind_entry (output_gr_gr (grmask
, reg
));
2539 as_bad ("Second operand is an invalid register.");
2550 sep
= parse_operand (&e1
);
2552 if (e1
.X_op
!= O_constant
)
2553 as_bad ("Operand to .save.f must be a constant.");
2556 int frmask
= e1
.X_add_number
;
2557 add_unwind_entry (output_fr_mem (e1
.X_add_number
));
2567 sep
= parse_operand (&e1
);
2569 if (e1
.X_op
!= O_constant
)
2570 as_bad ("Operand to .save.b must be a constant.");
2573 int brmask
= e1
.X_add_number
;
2574 add_unwind_entry (output_br_mem (brmask
));
2584 sep
= parse_operand (&e1
);
2586 parse_operand (&e2
);
2588 if (e1
.X_op
!= O_constant
|| sep
!= ',' || e2
.X_op
!= O_constant
)
2589 as_bad ("Both operands of .save.gf must be constants.");
2592 int grmask
= e1
.X_add_number
;
2593 int frmask
= e2
.X_add_number
;
2594 add_unwind_entry (output_frgr_mem (grmask
, frmask
));
2605 if (e
.X_op
!= O_constant
)
2606 as_bad ("Operand to .spill must be a constant");
2609 add_unwind_entry (output_spill_base (e
.X_add_number
));
2617 discard_rest_of_line ();
2621 dot_personality (dummy
)
2626 name
= input_line_pointer
;
2627 c
= get_symbol_end ();
2628 p
= input_line_pointer
;
2629 personality_routine
= symbol_find_or_make (name
);
2632 demand_empty_rest_of_line ();
2642 proc_start
= expr_build_dot ();
2643 /* Parse names of main and alternate entry points and mark them s
2644 function symbols: */
2648 name
= input_line_pointer
;
2649 c
= get_symbol_end ();
2650 p
= input_line_pointer
;
2651 sym
= symbol_find_or_make (name
);
2652 if (proc_start
== 0)
2656 symbol_get_bfdsym (sym
)->flags
|= BSF_FUNCTION
;
2659 if (*input_line_pointer
!= ',')
2661 ++input_line_pointer
;
2663 demand_empty_rest_of_line ();
2666 unwind_list
= unwind_tail
= current_unwind_entry
= NULL
;
2667 personality_routine
= 0;
2674 unwind_prologue
= 0;
2675 add_unwind_entry (output_body ());
2679 dot_prologue (dummy
)
2682 unwind_prologue
= 1;
2684 if (! is_end_of_line
[(unsigned char) *input_line_pointer
])
2688 sep
= parse_operand (&e1
);
2690 as_bad ("No second operand to .prologue");
2691 sep
= parse_operand (&e2
);
2693 if (e1
.X_op
== O_constant
)
2695 if (e2
.X_op
== O_constant
)
2697 int mask
= e1
.X_add_number
;
2698 int reg
= e2
.X_add_number
;
2699 add_unwind_entry (output_prologue_gr (mask
, reg
));
2702 as_bad ("Second operand not a constant");
2705 as_bad ("First operand not a constant");
2708 add_unwind_entry (output_prologue ());
2720 subsegT saved_subseg
;
2722 saved_seg
= now_seg
;
2723 saved_subseg
= now_subseg
;
2726 demand_empty_rest_of_line ();
2728 insn_group_break (1, 0, 0);
2729 ia64_flush_insns ();
2731 /* If there was a .handlerdata, we haven't generated an image yet. */
2732 if (unwind_info
== 0)
2734 generate_unwind_image ();
2737 subseg_set (md
.last_text_seg
, 0);
2738 proc_end
= expr_build_dot ();
2740 set_section ((char *) special_section_name
[SPECIAL_SECTION_UNWIND
]);
2741 ptr
= frag_more (24);
2742 where
= frag_now_fix () - 24;
2744 /* Issue the values of a) Proc Begin, b) Proc End, c) Unwind Record. */
2745 e
.X_op
= O_pseudo_fixup
;
2746 e
.X_op_symbol
= pseudo_func
[FUNC_SEG_RELATIVE
].u
.sym
;
2748 e
.X_add_symbol
= proc_start
;
2749 ia64_cons_fix_new (frag_now
, where
, 8, &e
);
2751 e
.X_op
= O_pseudo_fixup
;
2752 e
.X_op_symbol
= pseudo_func
[FUNC_SEG_RELATIVE
].u
.sym
;
2754 e
.X_add_symbol
= proc_end
;
2755 ia64_cons_fix_new (frag_now
, where
+ 8, 8, &e
);
2757 if (unwind_info
!= 0)
2759 e
.X_op
= O_pseudo_fixup
;
2760 e
.X_op_symbol
= pseudo_func
[FUNC_SEG_RELATIVE
].u
.sym
;
2762 e
.X_add_symbol
= unwind_info
;
2763 ia64_cons_fix_new (frag_now
, where
+ 16, 8, &e
);
2766 md_number_to_chars (ptr
+ 16, 0, 8);
2768 subseg_set (saved_seg
, saved_subseg
);
2769 proc_start
= proc_end
= unwind_info
= 0;
2773 dot_template (template)
2776 CURR_SLOT
.user_template
= template;
2783 int ins
, locs
, outs
, rots
;
2785 if (is_it_end_of_statement ())
2786 ins
= locs
= outs
= rots
= 0;
2789 ins
= get_absolute_expression ();
2790 if (*input_line_pointer
++ != ',')
2792 locs
= get_absolute_expression ();
2793 if (*input_line_pointer
++ != ',')
2795 outs
= get_absolute_expression ();
2796 if (*input_line_pointer
++ != ',')
2798 rots
= get_absolute_expression ();
2800 set_regstack (ins
, locs
, outs
, rots
);
2804 as_bad ("Comma expected");
2805 ignore_rest_of_line ();
2812 unsigned num_regs
, num_alloced
= 0;
2813 struct dynreg
**drpp
, *dr
;
2814 int ch
, base_reg
= 0;
2820 case DYNREG_GR
: base_reg
= REG_GR
+ 32; break;
2821 case DYNREG_FR
: base_reg
= REG_FR
+ 32; break;
2822 case DYNREG_PR
: base_reg
= REG_P
+ 16; break;
2826 /* first, remove existing names from hash table: */
2827 for (dr
= md
.dynreg
[type
]; dr
&& dr
->num_regs
; dr
= dr
->next
)
2829 hash_delete (md
.dynreg_hash
, dr
->name
);
2833 drpp
= &md
.dynreg
[type
];
2836 start
= input_line_pointer
;
2837 ch
= get_symbol_end ();
2838 *input_line_pointer
= ch
;
2839 len
= (input_line_pointer
- start
);
2842 if (*input_line_pointer
!= '[')
2844 as_bad ("Expected '['");
2847 ++input_line_pointer
; /* skip '[' */
2849 num_regs
= get_absolute_expression ();
2851 if (*input_line_pointer
++ != ']')
2853 as_bad ("Expected ']'");
2858 num_alloced
+= num_regs
;
2862 if (num_alloced
> md
.rot
.num_regs
)
2864 as_bad ("Used more than the declared %d rotating registers",
2870 if (num_alloced
> 96)
2872 as_bad ("Used more than the available 96 rotating registers");
2877 if (num_alloced
> 48)
2879 as_bad ("Used more than the available 48 rotating registers");
2888 name
= obstack_alloc (¬es
, len
+ 1);
2889 memcpy (name
, start
, len
);
2894 *drpp
= obstack_alloc (¬es
, sizeof (*dr
));
2895 memset (*drpp
, 0, sizeof (*dr
));
2900 dr
->num_regs
= num_regs
;
2901 dr
->base
= base_reg
;
2903 base_reg
+= num_regs
;
2905 if (hash_insert (md
.dynreg_hash
, name
, dr
))
2907 as_bad ("Attempt to redefine register set `%s'", name
);
2911 if (*input_line_pointer
!= ',')
2913 ++input_line_pointer
; /* skip comma */
2916 demand_empty_rest_of_line ();
2920 ignore_rest_of_line ();
2924 dot_byteorder (byteorder
)
2927 target_big_endian
= byteorder
;
2939 option
= input_line_pointer
;
2940 ch
= get_symbol_end ();
2941 if (strcmp (option
, "lsb") == 0)
2942 md
.flags
&= ~EF_IA_64_BE
;
2943 else if (strcmp (option
, "msb") == 0)
2944 md
.flags
|= EF_IA_64_BE
;
2945 else if (strcmp (option
, "abi32") == 0)
2946 md
.flags
&= ~EF_IA_64_ABI64
;
2947 else if (strcmp (option
, "abi64") == 0)
2948 md
.flags
|= EF_IA_64_ABI64
;
2950 as_bad ("Unknown psr option `%s'", option
);
2951 *input_line_pointer
= ch
;
2954 if (*input_line_pointer
!= ',')
2957 ++input_line_pointer
;
2960 demand_empty_rest_of_line ();
2967 as_bad (".alias not implemented yet");
2974 new_logical_line (0, get_absolute_expression ());
2975 demand_empty_rest_of_line ();
2979 parse_section_name ()
2985 if (*input_line_pointer
!= '"')
2987 as_bad ("Missing section name");
2988 ignore_rest_of_line ();
2991 name
= demand_copy_C_string (&len
);
2994 ignore_rest_of_line ();
2998 if (*input_line_pointer
!= ',')
3000 as_bad ("Comma expected after section name");
3001 ignore_rest_of_line ();
3004 ++input_line_pointer
; /* skip comma */
3012 char *name
= parse_section_name ();
3018 obj_elf_previous (0);
3021 /* Why doesn't float_cons() call md_cons_align() the way cons() does? */
3023 stmt_float_cons (kind
)
3030 case 'd': size
= 8; break;
3031 case 'x': size
= 10; break;
3038 ia64_do_align (size
);
3046 int saved_auto_align
= md
.auto_align
;
3050 md
.auto_align
= saved_auto_align
;
3054 dot_xfloat_cons (kind
)
3057 char *name
= parse_section_name ();
3062 stmt_float_cons (kind
);
3063 obj_elf_previous (0);
3067 dot_xstringer (zero
)
3070 char *name
= parse_section_name ();
3076 obj_elf_previous (0);
3083 int saved_auto_align
= md
.auto_align
;
3084 char *name
= parse_section_name ();
3091 md
.auto_align
= saved_auto_align
;
3092 obj_elf_previous (0);
3096 dot_xfloat_cons_ua (kind
)
3099 int saved_auto_align
= md
.auto_align
;
3100 char *name
= parse_section_name ();
3106 stmt_float_cons (kind
);
3107 md
.auto_align
= saved_auto_align
;
3108 obj_elf_previous (0);
3111 /* .reg.val <regname>,value */
3119 if (reg
.X_op
!= O_register
)
3121 as_bad (_("Register name expected"));
3122 ignore_rest_of_line ();
3124 else if (*input_line_pointer
++ != ',')
3126 as_bad (_("Comma expected"));
3127 ignore_rest_of_line ();
3131 valueT value
= get_absolute_expression ();
3132 int regno
= reg
.X_add_number
;
3133 if (regno
< REG_GR
|| regno
> REG_GR
+128)
3134 as_warn (_("Register value annotation ignored"));
3137 gr_values
[regno
-REG_GR
].known
= 1;
3138 gr_values
[regno
-REG_GR
].value
= value
;
3139 gr_values
[regno
-REG_GR
].path
= md
.path
;
3142 demand_empty_rest_of_line ();
3145 /* select dv checking mode
3150 A stop is inserted when changing modes
3156 if (md
.manual_bundling
)
3157 as_warn (_("Directive invalid within a bundle"));
3159 if (type
== 'E' || type
== 'A')
3160 md
.mode_explicitly_set
= 0;
3162 md
.mode_explicitly_set
= 1;
3169 if (md
.explicit_mode
)
3170 insn_group_break (1, 0, 0);
3171 md
.explicit_mode
= 0;
3175 if (!md
.explicit_mode
)
3176 insn_group_break (1, 0, 0);
3177 md
.explicit_mode
= 1;
3181 if (md
.explicit_mode
!= md
.default_explicit_mode
)
3182 insn_group_break (1, 0, 0);
3183 md
.explicit_mode
= md
.default_explicit_mode
;
3184 md
.mode_explicitly_set
= 0;
3195 for (regno
= 0;regno
< 64;regno
++)
3197 if (mask
& ((valueT
)1<<regno
))
3199 fprintf (stderr
, "%s p%d", comma
, regno
);
3206 .pred.rel.clear [p1 [,p2 [,...]]] (also .pred.rel "clear")
3207 .pred.rel.imply p1, p2 (also .pred.rel "imply")
3208 .pred.rel.mutex p1, p2 [,...] (also .pred.rel "mutex")
3209 .pred.safe_across_calls p1 [, p2 [,...]]
3217 int p1
= -1, p2
= -1;
3221 if (*input_line_pointer
!= '"')
3223 as_bad (_("Missing predicate relation type"));
3224 ignore_rest_of_line ();
3230 char *form
= demand_copy_C_string (&len
);
3231 if (strcmp (form
, "mutex") == 0)
3233 else if (strcmp (form
, "clear") == 0)
3235 else if (strcmp (form
, "imply") == 0)
3239 as_bad (_("Unrecognized predicate relation type"));
3240 ignore_rest_of_line ();
3244 if (*input_line_pointer
== ',')
3245 ++input_line_pointer
;
3255 if (toupper (*input_line_pointer
) != 'P'
3256 || (regno
= atoi (++input_line_pointer
)) < 0
3259 as_bad (_("Predicate register expected"));
3260 ignore_rest_of_line ();
3263 while (isdigit (*input_line_pointer
))
3264 ++input_line_pointer
;
3271 as_warn (_("Duplicate predicate register ignored"));
3272 mask
|= bit
; count
++;
3273 /* see if it's a range */
3274 if (*input_line_pointer
== '-')
3277 ++input_line_pointer
;
3279 if (toupper (*input_line_pointer
) != 'P'
3280 || (regno
= atoi (++input_line_pointer
)) < 0
3283 as_bad (_("Predicate register expected"));
3284 ignore_rest_of_line ();
3287 while (isdigit (*input_line_pointer
))
3288 ++input_line_pointer
;
3292 as_bad (_("Bad register range"));
3293 ignore_rest_of_line ();
3299 mask
|= bit
; count
++;
3303 if (*input_line_pointer
!= ',')
3305 ++input_line_pointer
;
3314 clear_qp_mutex (mask
);
3315 clear_qp_implies (mask
, (valueT
)0);
3318 if (count
!= 2 || p1
== -1 || p2
== -1)
3319 as_bad (_("Predicate source and target required"));
3320 else if (p1
== 0 || p2
== 0)
3321 as_bad (_("Use of p0 is not valid in this context"));
3323 add_qp_imply (p1
, p2
);
3328 as_bad (_("At least two PR arguments expected"));
3333 as_bad (_("Use of p0 is not valid in this context"));
3336 add_qp_mutex (mask
);
3339 /* note that we don't override any existing relations */
3342 as_bad (_("At least one PR argument expected"));
3347 fprintf (stderr
, "Safe across calls: ");
3348 print_prmask (mask
);
3349 fprintf (stderr
, "\n");
3351 qp_safe_across_calls
= mask
;
3354 demand_empty_rest_of_line ();
3357 /* .entry label [, label [, ...]]
3358 Hint to DV code that the given labels are to be considered entry points.
3359 Otherwise, only global labels are considered entry points.
3372 name
= input_line_pointer
;
3373 c
= get_symbol_end ();
3374 symbolP
= symbol_find_or_make (name
);
3376 err
= hash_insert (md
.entry_hash
, S_GET_NAME (symbolP
), (PTR
) symbolP
);
3378 as_fatal (_("Inserting \"%s\" into entry hint table failed: %s"),
3381 *input_line_pointer
= c
;
3383 c
= *input_line_pointer
;
3386 input_line_pointer
++;
3388 if (*input_line_pointer
== '\n')
3394 demand_empty_rest_of_line ();
3397 /* .mem.offset offset, base
3398 "base" is used to distinguish between offsets from a different base.
3401 dot_mem_offset (dummy
)
3404 md
.mem_offset
.hint
= 1;
3405 md
.mem_offset
.offset
= get_absolute_expression ();
3406 if (*input_line_pointer
!= ',')
3408 as_bad (_("Comma expected"));
3409 ignore_rest_of_line ();
3412 ++input_line_pointer
;
3413 md
.mem_offset
.base
= get_absolute_expression ();
3414 demand_empty_rest_of_line ();
3417 /* ia64-specific pseudo-ops: */
3418 const pseudo_typeS md_pseudo_table
[] =
3420 { "radix", dot_radix
, 0 },
3421 { "lcomm", s_lcomm_bytes
, 1 },
3422 { "bss", dot_special_section
, SPECIAL_SECTION_BSS
},
3423 { "sbss", dot_special_section
, SPECIAL_SECTION_SBSS
},
3424 { "sdata", dot_special_section
, SPECIAL_SECTION_SDATA
},
3425 { "rodata", dot_special_section
, SPECIAL_SECTION_RODATA
},
3426 { "comment", dot_special_section
, SPECIAL_SECTION_COMMENT
},
3427 { "ia_64.unwind", dot_special_section
, SPECIAL_SECTION_UNWIND
},
3428 { "ia_64.unwind_info", dot_special_section
, SPECIAL_SECTION_UNWIND_INFO
},
3429 { "proc", dot_proc
, 0 },
3430 { "body", dot_body
, 0 },
3431 { "prologue", dot_prologue
, 0 },
3432 { "endp", dot_endp
},
3433 { "file", dwarf2_directive_file
},
3434 { "loc", dwarf2_directive_loc
},
3436 { "fframe", dot_fframe
},
3437 { "vframe", dot_vframe
},
3438 { "save", dot_save
},
3439 { "restore", dot_restore
},
3440 { "handlerdata", dot_handlerdata
},
3441 { "unwentry", dot_unwentry
},
3442 { "alprp", dot_altrp
},
3443 { "savesp", dot_savesp
},
3444 { "savepsp", dot_savepsp
},
3445 { "save.g", dot_saveg
},
3446 { "save.f", dot_savef
},
3447 { "save.b", dot_saveb
},
3448 { "save.gf", dot_savegf
},
3449 { "spill", dot_spill
},
3450 { "unwabi", dot_unwabi
},
3451 { "personality", dot_personality
},
3453 { "estate", dot_estate
},
3455 { "mii", dot_template
, 0x0 },
3456 { "mli", dot_template
, 0x2 }, /* old format, for compatibility */
3457 { "mlx", dot_template
, 0x2 },
3458 { "mmi", dot_template
, 0x4 },
3459 { "mfi", dot_template
, 0x6 },
3460 { "mmf", dot_template
, 0x7 },
3461 { "mib", dot_template
, 0x8 },
3462 { "mbb", dot_template
, 0x9 },
3463 { "bbb", dot_template
, 0xb },
3464 { "mmb", dot_template
, 0xc },
3465 { "mfb", dot_template
, 0xe },
3467 { "lb", dot_scope
, 0 },
3468 { "le", dot_scope
, 1 },
3470 { "align", s_align_bytes
, 0 },
3471 { "regstk", dot_regstk
, 0 },
3472 { "rotr", dot_rot
, DYNREG_GR
},
3473 { "rotf", dot_rot
, DYNREG_FR
},
3474 { "rotp", dot_rot
, DYNREG_PR
},
3475 { "lsb", dot_byteorder
, 0 },
3476 { "msb", dot_byteorder
, 1 },
3477 { "psr", dot_psr
, 0 },
3478 { "alias", dot_alias
, 0 },
3479 { "ln", dot_ln
, 0 }, /* source line info (for debugging) */
3481 { "xdata1", dot_xdata
, 1 },
3482 { "xdata2", dot_xdata
, 2 },
3483 { "xdata4", dot_xdata
, 4 },
3484 { "xdata8", dot_xdata
, 8 },
3485 { "xreal4", dot_xfloat_cons
, 'f' },
3486 { "xreal8", dot_xfloat_cons
, 'd' },
3487 { "xreal10", dot_xfloat_cons
, 'x' },
3488 { "xstring", dot_xstringer
, 0 },
3489 { "xstringz", dot_xstringer
, 1 },
3491 /* unaligned versions: */
3492 { "xdata2.ua", dot_xdata_ua
, 2 },
3493 { "xdata4.ua", dot_xdata_ua
, 4 },
3494 { "xdata8.ua", dot_xdata_ua
, 8 },
3495 { "xreal4.ua", dot_xfloat_cons_ua
, 'f' },
3496 { "xreal8.ua", dot_xfloat_cons_ua
, 'd' },
3497 { "xreal10.ua", dot_xfloat_cons_ua
, 'x' },
3499 /* annotations/DV checking support */
3500 { "entry", dot_entry
, 0 },
3501 { "mem.offset", dot_mem_offset
},
3502 { "pred.rel", dot_pred_rel
, 0 },
3503 { "pred.rel.clear", dot_pred_rel
, 'c' },
3504 { "pred.rel.imply", dot_pred_rel
, 'i' },
3505 { "pred.rel.mutex", dot_pred_rel
, 'm' },
3506 { "pred.safe_across_calls", dot_pred_rel
, 's' },
3507 { "reg.val", dot_reg_val
},
3508 { "auto", dot_dv_mode
, 'a' },
3509 { "explicit", dot_dv_mode
, 'e' },
3510 { "default", dot_dv_mode
, 'd' },
3515 static const struct pseudo_opcode
3518 void (*handler
) (int);
3523 /* these are more like pseudo-ops, but don't start with a dot */
3524 { "data1", cons
, 1 },
3525 { "data2", cons
, 2 },
3526 { "data4", cons
, 4 },
3527 { "data8", cons
, 8 },
3528 { "real4", stmt_float_cons
, 'f' },
3529 { "real8", stmt_float_cons
, 'd' },
3530 { "real10", stmt_float_cons
, 'x' },
3531 { "string", stringer
, 0 },
3532 { "stringz", stringer
, 1 },
3534 /* unaligned versions: */
3535 { "data2.ua", stmt_cons_ua
, 2 },
3536 { "data4.ua", stmt_cons_ua
, 4 },
3537 { "data8.ua", stmt_cons_ua
, 8 },
3538 { "real4.ua", float_cons
, 'f' },
3539 { "real8.ua", float_cons
, 'd' },
3540 { "real10.ua", float_cons
, 'x' },
3543 /* Declare a register by creating a symbol for it and entering it in
3544 the symbol table. */
3546 declare_register (name
, regnum
)
3553 sym
= symbol_new (name
, reg_section
, regnum
, &zero_address_frag
);
3555 err
= hash_insert (md
.reg_hash
, S_GET_NAME (sym
), (PTR
) sym
);
3557 as_fatal ("Inserting \"%s\" into register table failed: %s",
3564 declare_register_set (prefix
, num_regs
, base_regnum
)
3572 for (i
= 0; i
< num_regs
; ++i
)
3574 sprintf (name
, "%s%u", prefix
, i
);
3575 declare_register (name
, base_regnum
+ i
);
3580 operand_width (opnd
)
3581 enum ia64_opnd opnd
;
3583 const struct ia64_operand
*odesc
= &elf64_ia64_operands
[opnd
];
3584 unsigned int bits
= 0;
3588 for (i
= 0; i
< NELEMS (odesc
->field
) && odesc
->field
[i
].bits
; ++i
)
3589 bits
+= odesc
->field
[i
].bits
;
3595 operand_match (idesc
, index
, e
)
3596 const struct ia64_opcode
*idesc
;
3600 enum ia64_opnd opnd
= idesc
->operands
[index
];
3601 int bits
, relocatable
= 0;
3602 struct insn_fix
*fix
;
3609 case IA64_OPND_AR_CCV
:
3610 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_AR
+ 32)
3614 case IA64_OPND_AR_PFS
:
3615 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_AR
+ 64)
3620 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_GR
+ 0)
3625 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_IP
)
3630 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_PR
)
3634 case IA64_OPND_PR_ROT
:
3635 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_PR_ROT
)
3640 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_PSR
)
3644 case IA64_OPND_PSR_L
:
3645 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_PSR_L
)
3649 case IA64_OPND_PSR_UM
:
3650 if (e
->X_op
== O_register
&& e
->X_add_number
== REG_PSR_UM
)
3655 if (e
->X_op
== O_constant
&& e
->X_add_number
== 1)
3660 if (e
->X_op
== O_constant
&& e
->X_add_number
== 8)
3665 if (e
->X_op
== O_constant
&& e
->X_add_number
== 16)
3669 /* register operands: */
3672 if (e
->X_op
== O_register
&& e
->X_add_number
>= REG_AR
3673 && e
->X_add_number
< REG_AR
+ 128)
3679 if (e
->X_op
== O_register
&& e
->X_add_number
>= REG_BR
3680 && e
->X_add_number
< REG_BR
+ 8)
3685 if (e
->X_op
== O_register
&& e
->X_add_number
>= REG_CR
3686 && e
->X_add_number
< REG_CR
+ 128)
3694 if (e
->X_op
== O_register
&& e
->X_add_number
>= REG_FR
3695 && e
->X_add_number
< REG_FR
+ 128)
3701 if (e
->X_op
== O_register
&& e
->X_add_number
>= REG_P
3702 && e
->X_add_number
< REG_P
+ 64)
3709 if (e
->X_op
== O_register
&& e
->X_add_number
>= REG_GR
3710 && e
->X_add_number
< REG_GR
+ 128)
3714 case IA64_OPND_R3_2
:
3715 if (e
->X_op
== O_register
&& e
->X_add_number
>= REG_GR
3716 && e
->X_add_number
< REG_GR
+ 4)
3720 /* indirect operands: */
3721 case IA64_OPND_CPUID_R3
:
3722 case IA64_OPND_DBR_R3
:
3723 case IA64_OPND_DTR_R3
:
3724 case IA64_OPND_ITR_R3
:
3725 case IA64_OPND_IBR_R3
:
3726 case IA64_OPND_MSR_R3
:
3727 case IA64_OPND_PKR_R3
:
3728 case IA64_OPND_PMC_R3
:
3729 case IA64_OPND_PMD_R3
:
3730 case IA64_OPND_RR_R3
:
3731 if (e
->X_op
== O_index
&& e
->X_op_symbol
3732 && (S_GET_VALUE (e
->X_op_symbol
) - IND_CPUID
3733 == opnd
- IA64_OPND_CPUID_R3
))
3738 if (e
->X_op
== O_index
&& !e
->X_op_symbol
)
3742 /* immediate operands: */
3743 case IA64_OPND_CNT2a
:
3744 case IA64_OPND_LEN4
:
3745 case IA64_OPND_LEN6
:
3746 bits
= operand_width (idesc
->operands
[index
]);
3747 if (e
->X_op
== O_constant
3748 && (bfd_vma
) (e
->X_add_number
- 1) < ((bfd_vma
) 1 << bits
))
3752 case IA64_OPND_CNT2b
:
3753 if (e
->X_op
== O_constant
3754 && (bfd_vma
) (e
->X_add_number
- 1) < 3)
3758 case IA64_OPND_CNT2c
:
3759 val
= e
->X_add_number
;
3760 if (e
->X_op
== O_constant
3761 && (val
== 0 || val
== 7 || val
== 15 || val
== 16))
3766 /* SOR must be an integer multiple of 8 */
3767 if (e
->X_add_number
& 0x7)
3771 if (e
->X_op
== O_constant
&&
3772 (bfd_vma
) e
->X_add_number
<= 96)
3776 case IA64_OPND_IMMU62
:
3777 if (e
->X_op
== O_constant
)
3779 if ((bfd_vma
) e
->X_add_number
< ((bfd_vma
) 1 << 62))
3784 /* FIXME -- need 62-bit relocation type */
3785 as_bad (_("62-bit relocation not yet implemented"));
3789 case IA64_OPND_IMMU64
:
3790 if (e
->X_op
== O_symbol
|| e
->X_op
== O_pseudo_fixup
3791 || e
->X_op
== O_subtract
)
3793 fix
= CURR_SLOT
.fixup
+ CURR_SLOT
.num_fixups
;
3794 fix
->code
= BFD_RELOC_IA64_IMM64
;
3795 if (e
->X_op
!= O_subtract
)
3797 fix
->code
= ia64_gen_real_reloc_type (e
->X_op_symbol
, fix
->code
);
3798 if (e
->X_op
== O_pseudo_fixup
)
3802 fix
->opnd
= idesc
->operands
[index
];
3805 ++CURR_SLOT
.num_fixups
;
3808 else if (e
->X_op
== O_constant
)
3812 case IA64_OPND_CCNT5
:
3813 case IA64_OPND_CNT5
:
3814 case IA64_OPND_CNT6
:
3815 case IA64_OPND_CPOS6a
:
3816 case IA64_OPND_CPOS6b
:
3817 case IA64_OPND_CPOS6c
:
3818 case IA64_OPND_IMMU2
:
3819 case IA64_OPND_IMMU7a
:
3820 case IA64_OPND_IMMU7b
:
3821 case IA64_OPND_IMMU21
:
3822 case IA64_OPND_IMMU24
:
3823 case IA64_OPND_MBTYPE4
:
3824 case IA64_OPND_MHTYPE8
:
3825 case IA64_OPND_POS6
:
3826 bits
= operand_width (idesc
->operands
[index
]);
3827 if (e
->X_op
== O_constant
3828 && (bfd_vma
) e
->X_add_number
< ((bfd_vma
) 1 << bits
))
3832 case IA64_OPND_IMMU9
:
3833 bits
= operand_width (idesc
->operands
[index
]);
3834 if (e
->X_op
== O_constant
3835 && (bfd_vma
) e
->X_add_number
< ((bfd_vma
) 1 << bits
))
3837 int lobits
= e
->X_add_number
& 0x3;
3838 if (((bfd_vma
) e
->X_add_number
& 0x3C) != 0 && lobits
== 0)
3839 e
->X_add_number
|= (bfd_vma
)0x3;
3844 case IA64_OPND_IMM44
:
3845 /* least 16 bits must be zero */
3846 if ((e
->X_add_number
& 0xffff) != 0)
3847 as_warn (_("lower 16 bits of mask ignored"));
3849 if (e
->X_op
== O_constant
3850 && ((e
->X_add_number
>= 0
3851 && e
->X_add_number
< ((bfd_vma
) 1 << 44))
3852 || (e
->X_add_number
< 0
3853 && -e
->X_add_number
<= ((bfd_vma
) 1 << 44))))
3856 if (e
->X_add_number
>= 0
3857 && (e
->X_add_number
& ((bfd_vma
) 1 << 43)) != 0)
3859 e
->X_add_number
|= ~(((bfd_vma
) 1 << 44) - 1);
3865 case IA64_OPND_IMM17
:
3866 /* bit 0 is a don't care (pr0 is hardwired to 1) */
3867 if (e
->X_op
== O_constant
3868 && ((e
->X_add_number
>= 0
3869 && e
->X_add_number
< ((bfd_vma
) 1 << 17))
3870 || (e
->X_add_number
< 0
3871 && -e
->X_add_number
<= ((bfd_vma
) 1 << 17))))
3874 if (e
->X_add_number
>= 0
3875 && (e
->X_add_number
& ((bfd_vma
) 1 << 16)) != 0)
3877 e
->X_add_number
|= ~(((bfd_vma
)1 << 17) - 1);
3883 case IA64_OPND_IMM14
:
3884 case IA64_OPND_IMM22
:
3886 case IA64_OPND_IMM1
:
3887 case IA64_OPND_IMM8
:
3888 case IA64_OPND_IMM8U4
:
3889 case IA64_OPND_IMM8M1
:
3890 case IA64_OPND_IMM8M1U4
:
3891 case IA64_OPND_IMM8M1U8
:
3892 case IA64_OPND_IMM9a
:
3893 case IA64_OPND_IMM9b
:
3894 bits
= operand_width (idesc
->operands
[index
]);
3895 if (relocatable
&& (e
->X_op
== O_symbol
3896 || e
->X_op
== O_subtract
3897 || e
->X_op
== O_pseudo_fixup
))
3899 fix
= CURR_SLOT
.fixup
+ CURR_SLOT
.num_fixups
;
3901 if (idesc
->operands
[index
] == IA64_OPND_IMM14
)
3902 fix
->code
= BFD_RELOC_IA64_IMM14
;
3904 fix
->code
= BFD_RELOC_IA64_IMM22
;
3906 if (e
->X_op
!= O_subtract
)
3908 fix
->code
= ia64_gen_real_reloc_type (e
->X_op_symbol
, fix
->code
);
3909 if (e
->X_op
== O_pseudo_fixup
)
3913 fix
->opnd
= idesc
->operands
[index
];
3916 ++CURR_SLOT
.num_fixups
;
3919 else if (e
->X_op
!= O_constant
3920 && ! (e
->X_op
== O_big
&& opnd
== IA64_OPND_IMM8M1U8
))
3923 if (opnd
== IA64_OPND_IMM8M1U4
)
3925 /* Zero is not valid for unsigned compares that take an adjusted
3926 constant immediate range. */
3927 if (e
->X_add_number
== 0)
3930 /* Sign-extend 32-bit unsigned numbers, so that the following range
3931 checks will work. */
3932 val
= e
->X_add_number
;
3933 if (((val
& (~(bfd_vma
)0 << 32)) == 0)
3934 && ((val
& ((bfd_vma
)1 << 31)) != 0))
3935 val
= ((val
<< 32) >> 32);
3937 /* Check for 0x100000000. This is valid because
3938 0x100000000-1 is the same as ((uint32_t) -1). */
3939 if (val
== ((bfd_signed_vma
) 1 << 32))
3944 else if (opnd
== IA64_OPND_IMM8M1U8
)
3946 /* Zero is not valid for unsigned compares that take an adjusted
3947 constant immediate range. */
3948 if (e
->X_add_number
== 0)
3951 /* Check for 0x10000000000000000. */
3952 if (e
->X_op
== O_big
)
3954 if (generic_bignum
[0] == 0
3955 && generic_bignum
[1] == 0
3956 && generic_bignum
[2] == 0
3957 && generic_bignum
[3] == 0
3958 && generic_bignum
[4] == 1)
3964 val
= e
->X_add_number
- 1;
3966 else if (opnd
== IA64_OPND_IMM8M1
)
3967 val
= e
->X_add_number
- 1;
3968 else if (opnd
== IA64_OPND_IMM8U4
)
3970 /* Sign-extend 32-bit unsigned numbers, so that the following range
3971 checks will work. */
3972 val
= e
->X_add_number
;
3973 if (((val
& (~(bfd_vma
)0 << 32)) == 0)
3974 && ((val
& ((bfd_vma
)1 << 31)) != 0))
3975 val
= ((val
<< 32) >> 32);
3978 val
= e
->X_add_number
;
3980 if ((val
>= 0 && val
< ((bfd_vma
) 1 << (bits
- 1)))
3981 || (val
< 0 && -val
<= ((bfd_vma
) 1 << (bits
- 1))))
3985 case IA64_OPND_INC3
:
3986 /* +/- 1, 4, 8, 16 */
3987 val
= e
->X_add_number
;
3990 if (e
->X_op
== O_constant
3991 && (val
== 1 || val
== 4 || val
== 8 || val
== 16))
3995 case IA64_OPND_TGT25
:
3996 case IA64_OPND_TGT25b
:
3997 case IA64_OPND_TGT25c
:
3998 case IA64_OPND_TGT64
:
3999 if (e
->X_op
== O_symbol
)
4001 fix
= CURR_SLOT
.fixup
+ CURR_SLOT
.num_fixups
;
4002 if (opnd
== IA64_OPND_TGT25
)
4003 fix
->code
= BFD_RELOC_IA64_PCREL21F
;
4004 else if (opnd
== IA64_OPND_TGT25b
)
4005 fix
->code
= BFD_RELOC_IA64_PCREL21M
;
4006 else if (opnd
== IA64_OPND_TGT25c
)
4007 fix
->code
= BFD_RELOC_IA64_PCREL21B
;
4008 else if (opnd
== IA64_OPND_TGT64
)
4009 fix
->code
= BFD_RELOC_IA64_PCREL60B
;
4013 fix
->code
= ia64_gen_real_reloc_type (e
->X_op_symbol
, fix
->code
);
4014 fix
->opnd
= idesc
->operands
[index
];
4017 ++CURR_SLOT
.num_fixups
;
4020 case IA64_OPND_TAG13
:
4021 case IA64_OPND_TAG13b
:
4028 fix
= CURR_SLOT
.fixup
+ CURR_SLOT
.num_fixups
;
4029 fix
->code
= ia64_gen_real_reloc_type (e
->X_op_symbol
, 0);
4030 fix
->opnd
= idesc
->operands
[index
];
4033 ++CURR_SLOT
.num_fixups
;
4053 memset (e
, 0, sizeof (*e
));
4056 if (*input_line_pointer
!= '}')
4058 sep
= *input_line_pointer
++;
4062 if (!md
.manual_bundling
)
4063 as_warn ("Found '}' when manual bundling is off");
4065 CURR_SLOT
.manual_bundling_off
= 1;
4066 md
.manual_bundling
= 0;
4072 /* Returns the next entry in the opcode table that matches the one in
4073 IDESC, and frees the entry in IDESC. If no matching entry is
4074 found, NULL is returned instead. */
4076 static struct ia64_opcode
*
4077 get_next_opcode (struct ia64_opcode
*idesc
)
4079 struct ia64_opcode
*next
= ia64_find_next_opcode (idesc
);
4080 ia64_free_opcode (idesc
);
4084 /* Parse the operands for the opcode and find the opcode variant that
4085 matches the specified operands, or NULL if no match is possible. */
4086 static struct ia64_opcode
*
4087 parse_operands (idesc
)
4088 struct ia64_opcode
*idesc
;
4090 int i
= 0, highest_unmatched_operand
, num_operands
= 0, num_outputs
= 0;
4092 enum ia64_opnd expected_operand
= IA64_OPND_NIL
;
4094 char *first_arg
= 0, *end
, *saved_input_pointer
;
4097 assert (strlen (idesc
->name
) <= 128);
4099 strcpy (mnemonic
, idesc
->name
);
4100 if (idesc
->operands
[2] == IA64_OPND_SOF
)
4102 /* To make the common idiom "alloc loc?=ar.pfs,0,1,0,0" work, we
4103 can't parse the first operand until we have parsed the
4104 remaining operands of the "alloc" instruction. */
4106 first_arg
= input_line_pointer
;
4107 end
= strchr (input_line_pointer
, '=');
4110 as_bad ("Expected separator `='");
4113 input_line_pointer
= end
+ 1;
4118 for (; i
< NELEMS (CURR_SLOT
.opnd
); ++i
)
4120 sep
= parse_operand (CURR_SLOT
.opnd
+ i
);
4121 if (CURR_SLOT
.opnd
[i
].X_op
== O_absent
)
4126 if (sep
!= '=' && sep
!= ',')
4131 if (num_outputs
> 0)
4132 as_bad ("Duplicate equal sign (=) in instruction");
4134 num_outputs
= i
+ 1;
4139 as_bad ("Illegal operand separator `%c'", sep
);
4143 if (idesc
->operands
[2] == IA64_OPND_SOF
)
4145 /* map alloc r1=ar.pfs,i,l,o,r to alloc r1=ar.pfs,(i+l+o),(i+l),r */
4146 know (strcmp (idesc
->name
, "alloc") == 0);
4147 if (num_operands
== 5 /* first_arg not included in this count! */
4148 && CURR_SLOT
.opnd
[2].X_op
== O_constant
4149 && CURR_SLOT
.opnd
[3].X_op
== O_constant
4150 && CURR_SLOT
.opnd
[4].X_op
== O_constant
4151 && CURR_SLOT
.opnd
[5].X_op
== O_constant
)
4153 sof
= set_regstack (CURR_SLOT
.opnd
[2].X_add_number
,
4154 CURR_SLOT
.opnd
[3].X_add_number
,
4155 CURR_SLOT
.opnd
[4].X_add_number
,
4156 CURR_SLOT
.opnd
[5].X_add_number
);
4158 /* now we can parse the first arg: */
4159 saved_input_pointer
= input_line_pointer
;
4160 input_line_pointer
= first_arg
;
4161 sep
= parse_operand (CURR_SLOT
.opnd
+ 0);
4163 --num_outputs
; /* force error */
4164 input_line_pointer
= saved_input_pointer
;
4166 CURR_SLOT
.opnd
[2].X_add_number
= sof
;
4167 CURR_SLOT
.opnd
[3].X_add_number
4168 = sof
- CURR_SLOT
.opnd
[4].X_add_number
;
4169 CURR_SLOT
.opnd
[4] = CURR_SLOT
.opnd
[5];
4173 highest_unmatched_operand
= 0;
4174 expected_operand
= idesc
->operands
[0];
4175 for (; idesc
; idesc
= get_next_opcode (idesc
))
4177 if (num_outputs
!= idesc
->num_outputs
)
4178 continue; /* mismatch in # of outputs */
4180 CURR_SLOT
.num_fixups
= 0;
4181 for (i
= 0; i
< num_operands
&& idesc
->operands
[i
]; ++i
)
4182 if (!operand_match (idesc
, i
, CURR_SLOT
.opnd
+ i
))
4185 if (i
!= num_operands
)
4187 if (i
> highest_unmatched_operand
)
4189 highest_unmatched_operand
= i
;
4190 expected_operand
= idesc
->operands
[i
];
4195 if (num_operands
< NELEMS (idesc
->operands
)
4196 && idesc
->operands
[num_operands
])
4197 continue; /* mismatch in number of arguments */
4203 if (expected_operand
)
4204 as_bad ("Operand %u of `%s' should be %s",
4205 highest_unmatched_operand
+ 1, mnemonic
,
4206 elf64_ia64_operands
[expected_operand
].desc
);
4208 as_bad ("Operand mismatch");
4215 build_insn (slot
, insnp
)
4219 const struct ia64_operand
*odesc
, *o2desc
;
4220 struct ia64_opcode
*idesc
= slot
->idesc
;
4221 bfd_signed_vma insn
, val
;
4225 insn
= idesc
->opcode
| slot
->qp_regno
;
4227 for (i
= 0; i
< NELEMS (idesc
->operands
) && idesc
->operands
[i
]; ++i
)
4229 if (slot
->opnd
[i
].X_op
== O_register
4230 || slot
->opnd
[i
].X_op
== O_constant
4231 || slot
->opnd
[i
].X_op
== O_index
)
4232 val
= slot
->opnd
[i
].X_add_number
;
4233 else if (slot
->opnd
[i
].X_op
== O_big
)
4235 /* This must be the value 0x10000000000000000. */
4236 assert (idesc
->operands
[i
] == IA64_OPND_IMM8M1U8
);
4242 switch (idesc
->operands
[i
])
4244 case IA64_OPND_IMMU64
:
4245 *insnp
++ = (val
>> 22) & 0x1ffffffffffLL
;
4246 insn
|= (((val
& 0x7f) << 13) | (((val
>> 7) & 0x1ff) << 27)
4247 | (((val
>> 16) & 0x1f) << 22) | (((val
>> 21) & 0x1) << 21)
4248 | (((val
>> 63) & 0x1) << 36));
4251 case IA64_OPND_IMMU62
:
4252 val
&= 0x3fffffffffffffffULL
;
4253 if (val
!= slot
->opnd
[i
].X_add_number
)
4254 as_warn (_("Value truncated to 62 bits"));
4255 *insnp
++ = (val
>> 21) & 0x1ffffffffffLL
;
4256 insn
|= (((val
& 0xfffff) << 6) | (((val
>> 20) & 0x1) << 36));
4259 case IA64_OPND_TGT64
:
4261 *insnp
++ = ((val
>> 20) & 0x7fffffffffLL
) << 2;
4262 insn
|= ((((val
>> 59) & 0x1) << 36)
4263 | (((val
>> 0) & 0xfffff) << 13));
4294 case IA64_OPND_R3_2
:
4295 case IA64_OPND_CPUID_R3
:
4296 case IA64_OPND_DBR_R3
:
4297 case IA64_OPND_DTR_R3
:
4298 case IA64_OPND_ITR_R3
:
4299 case IA64_OPND_IBR_R3
:
4301 case IA64_OPND_MSR_R3
:
4302 case IA64_OPND_PKR_R3
:
4303 case IA64_OPND_PMC_R3
:
4304 case IA64_OPND_PMD_R3
:
4305 case IA64_OPND_RR_R3
:
4313 odesc
= elf64_ia64_operands
+ idesc
->operands
[i
];
4314 err
= (*odesc
->insert
) (odesc
, val
, &insn
);
4316 as_bad_where (slot
->src_file
, slot
->src_line
,
4317 "Bad operand value: %s", err
);
4318 if (idesc
->flags
& IA64_OPCODE_PSEUDO
)
4320 if ((idesc
->flags
& IA64_OPCODE_F2_EQ_F3
)
4321 && odesc
== elf64_ia64_operands
+ IA64_OPND_F3
)
4323 o2desc
= elf64_ia64_operands
+ IA64_OPND_F2
;
4324 (*o2desc
->insert
) (o2desc
, val
, &insn
);
4326 if ((idesc
->flags
& IA64_OPCODE_LEN_EQ_64MCNT
)
4327 && (odesc
== elf64_ia64_operands
+ IA64_OPND_CPOS6a
4328 || odesc
== elf64_ia64_operands
+ IA64_OPND_POS6
))
4330 o2desc
= elf64_ia64_operands
+ IA64_OPND_LEN6
;
4331 (*o2desc
->insert
) (o2desc
, 64 - val
, &insn
);
4341 unsigned int manual_bundling_on
= 0, manual_bundling_off
= 0;
4342 unsigned int manual_bundling
= 0;
4343 enum ia64_unit required_unit
, insn_unit
= 0;
4344 enum ia64_insn_type type
[3], insn_type
;
4345 unsigned int template, orig_template
;
4346 bfd_vma insn
[3] = {-1, -1, -1};
4347 struct ia64_opcode
*idesc
;
4348 int end_of_insn_group
= 0, user_template
= -1;
4349 int n
, i
, j
, first
, curr
;
4350 bfd_vma t0
= 0, t1
= 0;
4351 struct label_fix
*lfix
;
4352 struct insn_fix
*ifix
;
4357 first
= (md
.curr_slot
+ NUM_SLOTS
- md
.num_slots_in_use
) % NUM_SLOTS
;
4358 know (first
>= 0 & first
< NUM_SLOTS
);
4359 n
= MIN (3, md
.num_slots_in_use
);
4361 /* Determine template: user user_template if specified, best match
4364 if (md
.slot
[first
].user_template
>= 0)
4365 user_template
= template = md
.slot
[first
].user_template
;
4368 /* auto select appropriate template */
4369 memset (type
, 0, sizeof (type
));
4371 for (i
= 0; i
< n
; ++i
)
4373 type
[i
] = md
.slot
[curr
].idesc
->type
;
4374 curr
= (curr
+ 1) % NUM_SLOTS
;
4376 template = best_template
[type
[0]][type
[1]][type
[2]];
4379 /* initialize instructions with appropriate nops: */
4380 for (i
= 0; i
< 3; ++i
)
4381 insn
[i
] = nop
[ia64_templ_desc
[template].exec_unit
[i
]];
4385 /* now fill in slots with as many insns as possible: */
4387 idesc
= md
.slot
[curr
].idesc
;
4388 end_of_insn_group
= 0;
4389 for (i
= 0; i
< 3 && md
.num_slots_in_use
> 0; ++i
)
4391 if (idesc
->flags
& IA64_OPCODE_SLOT2
)
4393 if (manual_bundling
&& i
!= 2)
4394 as_bad_where (md
.slot
[curr
].src_file
, md
.slot
[curr
].src_line
,
4395 "`%s' must be last in bundle", idesc
->name
);
4399 if (idesc
->flags
& IA64_OPCODE_LAST
)
4401 int required_slot
, required_template
;
4403 /* If we need a stop bit after an M slot, our only choice is
4404 template 5 (M;;MI). If we need a stop bit after a B
4405 slot, our only choice is to place it at the end of the
4406 bundle, because the only available templates are MIB,
4407 MBB, BBB, MMB, and MFB. We don't handle anything other
4408 than M and B slots because these are the only kind of
4409 instructions that can have the IA64_OPCODE_LAST bit set. */
4410 required_template
= template;
4411 switch (idesc
->type
)
4415 required_template
= 5;
4423 as_bad_where (md
.slot
[curr
].src_file
, md
.slot
[curr
].src_line
,
4424 "Internal error: don't know how to force %s to end"
4425 "of instruction group", idesc
->name
);
4429 if (manual_bundling
&& i
!= required_slot
)
4430 as_bad_where (md
.slot
[curr
].src_file
, md
.slot
[curr
].src_line
,
4431 "`%s' must be last in instruction group",
4433 if (required_slot
< i
)
4434 /* Can't fit this instruction. */
4438 if (required_template
!= template)
4440 /* If we switch the template, we need to reset the NOPs
4441 after slot i. The slot-types of the instructions ahead
4442 of i never change, so we don't need to worry about
4443 changing NOPs in front of this slot. */
4444 for (j
= i
; j
< 3; ++j
)
4445 insn
[j
] = nop
[ia64_templ_desc
[required_template
].exec_unit
[j
]];
4447 template = required_template
;
4449 if (curr
!= first
&& md
.slot
[curr
].label_fixups
)
4451 if (manual_bundling_on
)
4452 as_bad_where (md
.slot
[curr
].src_file
, md
.slot
[curr
].src_line
,
4453 "Label must be first in a bundle");
4454 /* This insn must go into the first slot of a bundle. */
4458 manual_bundling_on
= md
.slot
[curr
].manual_bundling_on
;
4459 manual_bundling_off
= md
.slot
[curr
].manual_bundling_off
;
4461 if (manual_bundling_on
)
4464 manual_bundling
= 1;
4466 break; /* need to start a new bundle */
4469 if (end_of_insn_group
&& md
.num_slots_in_use
>= 1)
4471 /* We need an instruction group boundary in the middle of a
4472 bundle. See if we can switch to an other template with
4473 an appropriate boundary. */
4475 orig_template
= template;
4476 if (i
== 1 && (user_template
== 4
4477 || (user_template
< 0
4478 && (ia64_templ_desc
[template].exec_unit
[0]
4482 end_of_insn_group
= 0;
4484 else if (i
== 2 && (user_template
== 0
4485 || (user_template
< 0
4486 && (ia64_templ_desc
[template].exec_unit
[1]
4488 /* This test makes sure we don't switch the template if
4489 the next instruction is one that needs to be first in
4490 an instruction group. Since all those instructions are
4491 in the M group, there is no way such an instruction can
4492 fit in this bundle even if we switch the template. The
4493 reason we have to check for this is that otherwise we
4494 may end up generating "MI;;I M.." which has the deadly
4495 effect that the second M instruction is no longer the
4496 first in the bundle! --davidm 99/12/16 */
4497 && (idesc
->flags
& IA64_OPCODE_FIRST
) == 0)
4500 end_of_insn_group
= 0;
4502 else if (curr
!= first
)
4503 /* can't fit this insn */
4506 if (template != orig_template
)
4507 /* if we switch the template, we need to reset the NOPs
4508 after slot i. The slot-types of the instructions ahead
4509 of i never change, so we don't need to worry about
4510 changing NOPs in front of this slot. */
4511 for (j
= i
; j
< 3; ++j
)
4512 insn
[j
] = nop
[ia64_templ_desc
[template].exec_unit
[j
]];
4514 required_unit
= ia64_templ_desc
[template].exec_unit
[i
];
4516 /* resolve dynamic opcodes such as "break" and "nop": */
4517 if (idesc
->type
== IA64_TYPE_DYN
)
4519 if ((strcmp (idesc
->name
, "nop") == 0)
4520 || (strcmp (idesc
->name
, "break") == 0))
4521 insn_unit
= required_unit
;
4522 else if (strcmp (idesc
->name
, "chk.s") == 0)
4524 insn_unit
= IA64_UNIT_M
;
4525 if (required_unit
== IA64_UNIT_I
)
4526 insn_unit
= IA64_UNIT_I
;
4529 as_fatal ("emit_one_bundle: unexpected dynamic op");
4531 sprintf (mnemonic
, "%s.%c", idesc
->name
, "?imbf??"[insn_unit
]);
4532 md
.slot
[curr
].idesc
= idesc
= ia64_find_opcode (mnemonic
);
4534 know (!idesc
->next
); /* no resolved dynamic ops have collisions */
4539 insn_type
= idesc
->type
;
4540 insn_unit
= IA64_UNIT_NIL
;
4544 if (required_unit
== IA64_UNIT_I
|| required_unit
== IA64_UNIT_M
)
4545 insn_unit
= required_unit
;
4547 case IA64_TYPE_X
: insn_unit
= IA64_UNIT_L
; break;
4548 case IA64_TYPE_I
: insn_unit
= IA64_UNIT_I
; break;
4549 case IA64_TYPE_M
: insn_unit
= IA64_UNIT_M
; break;
4550 case IA64_TYPE_B
: insn_unit
= IA64_UNIT_B
; break;
4551 case IA64_TYPE_F
: insn_unit
= IA64_UNIT_F
; break;
4556 if (insn_unit
!= required_unit
)
4558 if (required_unit
== IA64_UNIT_L
4559 && insn_unit
== IA64_UNIT_I
4560 && !(idesc
->flags
& IA64_OPCODE_X_IN_MLX
))
4562 /* we got ourselves an MLX template but the current
4563 instruction isn't an X-unit, or an I-unit instruction
4564 that can go into the X slot of an MLX template. Duh. */
4565 if (md
.num_slots_in_use
>= NUM_SLOTS
)
4567 as_bad_where (md
.slot
[curr
].src_file
,
4568 md
.slot
[curr
].src_line
,
4569 "`%s' can't go in X slot of "
4570 "MLX template", idesc
->name
);
4571 /* drop this insn so we don't livelock: */
4572 --md
.num_slots_in_use
;
4576 continue; /* try next slot */
4579 if (debug_type
== DEBUG_DWARF2
)
4583 addr
= frag_now
->fr_address
+ frag_now_fix () - 16 + 1*i
;
4584 dwarf2_gen_line_info (addr
, &md
.slot
[curr
].debug_line
);
4587 build_insn (md
.slot
+ curr
, insn
+ i
);
4589 /* Set slot counts for unwind records. */
4590 while (md
.slot
[curr
].unwind_record
)
4592 md
.slot
[curr
].unwind_record
->slot_number
= (unsigned long) (f
+ i
);
4593 md
.slot
[curr
].unwind_record
= md
.slot
[curr
].unwind_record
->next
;
4595 if (required_unit
== IA64_UNIT_L
)
4598 /* skip one slot for long/X-unit instructions */
4601 --md
.num_slots_in_use
;
4603 /* now is a good time to fix up the labels for this insn: */
4604 for (lfix
= md
.slot
[curr
].label_fixups
; lfix
; lfix
= lfix
->next
)
4606 S_SET_VALUE (lfix
->sym
, frag_now_fix () - 16);
4607 symbol_set_frag (lfix
->sym
, frag_now
);
4610 for (j
= 0; j
< md
.slot
[curr
].num_fixups
; ++j
)
4612 ifix
= md
.slot
[curr
].fixup
+ j
;
4613 fix
= fix_new_exp (frag_now
, frag_now_fix () - 16 + i
, 4,
4614 &ifix
->expr
, ifix
->is_pcrel
, ifix
->code
);
4615 fix
->tc_fix_data
.opnd
= ifix
->opnd
;
4616 fix
->fx_plt
= (fix
->fx_r_type
== BFD_RELOC_IA64_PLTOFF22
);
4617 fix
->fx_file
= md
.slot
[curr
].src_file
;
4618 fix
->fx_line
= md
.slot
[curr
].src_line
;
4621 end_of_insn_group
= md
.slot
[curr
].end_of_insn_group
;
4624 ia64_free_opcode (md
.slot
[curr
].idesc
);
4625 memset (md
.slot
+ curr
, 0, sizeof (md
.slot
[curr
]));
4626 md
.slot
[curr
].user_template
= -1;
4628 if (manual_bundling_off
)
4630 manual_bundling
= 0;
4633 curr
= (curr
+ 1) % NUM_SLOTS
;
4634 idesc
= md
.slot
[curr
].idesc
;
4636 if (manual_bundling
)
4638 if (md
.num_slots_in_use
> 0)
4639 as_bad_where (md
.slot
[curr
].src_file
, md
.slot
[curr
].src_line
,
4640 "`%s' does not fit into %s template",
4641 idesc
->name
, ia64_templ_desc
[template].name
);
4643 as_bad_where (md
.slot
[curr
].src_file
, md
.slot
[curr
].src_line
,
4644 "Missing '}' at end of file");
4646 know (md
.num_slots_in_use
< NUM_SLOTS
);
4648 t0
= end_of_insn_group
| (template << 1) | (insn
[0] << 5) | (insn
[1] << 46);
4649 t1
= ((insn
[1] >> 18) & 0x7fffff) | (insn
[2] << 23);
4651 md_number_to_chars (f
+ 0, t0
, 8);
4652 md_number_to_chars (f
+ 8, t1
, 8);
4656 md_parse_option (c
, arg
)
4660 /* Switches from the Intel assembler. */
4664 if (strcmp (arg
, "ilp64") == 0
4665 || strcmp (arg
, "lp64") == 0
4666 || strcmp (arg
, "p64") == 0)
4668 md
.flags
|= EF_IA_64_ABI64
;
4670 else if (strcmp (arg
, "ilp32") == 0)
4672 md
.flags
&= ~EF_IA_64_ABI64
;
4674 else if (strcmp (arg
, "le") == 0)
4676 md
.flags
&= ~EF_IA_64_BE
;
4678 else if (strcmp (arg
, "be") == 0)
4680 md
.flags
|= EF_IA_64_BE
;
4687 if (strcmp (arg
, "so") == 0)
4689 /* Suppress signon message. */
4691 else if (strcmp (arg
, "pi") == 0)
4693 /* Reject privileged instructions. FIXME */
4695 else if (strcmp (arg
, "us") == 0)
4697 /* Allow union of signed and unsigned range. FIXME */
4699 else if (strcmp (arg
, "close_fcalls") == 0)
4701 /* Do not resolve global function calls. */
4708 /* temp[="prefix"] Insert temporary labels into the object file
4709 symbol table prefixed by "prefix".
4710 Default prefix is ":temp:".
4715 /* ??? Conflicts with gas' listing option. */
4716 /* indirect=<tgt> Assume unannotated indirect branches behavior
4717 according to <tgt> --
4718 exit: branch out from the current context (default)
4719 labels: all labels in context may be branch targets
4724 /* -X conflicts with an ignored option, use -x instead */
4726 if (!arg
|| strcmp (arg
, "explicit") == 0)
4728 /* set default mode to explicit */
4729 md
.default_explicit_mode
= 1;
4732 else if (strcmp (arg
, "auto") == 0)
4734 md
.default_explicit_mode
= 0;
4736 else if (strcmp (arg
, "debug") == 0)
4740 else if (strcmp (arg
, "debugx") == 0)
4742 md
.default_explicit_mode
= 1;
4747 as_bad (_("Unrecognized option '-x%s'"), arg
);
4752 /* nops Print nops statistics. */
4763 md_show_usage (stream
)
4768 -Milp32|-Milp64|-Mlp64|-Mp64 select data model (default -Mlp64)\n\
4769 -Mle | -Mbe select little- or big-endian byte order (default -Mle)\n\
4770 -x | -xexplicit turn on dependency violation checking (default)\n\
4771 -xauto automagically remove dependency violations\n\
4772 -xdebug debug dependency violation checker\n"),
4777 match (int templ
, int type
, int slot
)
4779 enum ia64_unit unit
;
4782 unit
= ia64_templ_desc
[templ
].exec_unit
[slot
];
4785 case IA64_TYPE_DYN
: result
= 1; break; /* for nop and break */
4787 result
= (unit
== IA64_UNIT_I
|| unit
== IA64_UNIT_M
);
4789 case IA64_TYPE_X
: result
= (unit
== IA64_UNIT_L
); break;
4790 case IA64_TYPE_I
: result
= (unit
== IA64_UNIT_I
); break;
4791 case IA64_TYPE_M
: result
= (unit
== IA64_UNIT_M
); break;
4792 case IA64_TYPE_B
: result
= (unit
== IA64_UNIT_B
); break;
4793 case IA64_TYPE_F
: result
= (unit
== IA64_UNIT_F
); break;
4794 default: result
= 0; break;
4799 /* This function is called once, at assembler startup time. It sets
4800 up all the tables, etc. that the MD part of the assembler will need
4801 that can be determined before arguments are parsed. */
4805 int i
, j
, k
, t
, total
, ar_base
, cr_base
, goodness
, best
, regnum
;
4810 md
.explicit_mode
= md
.default_explicit_mode
;
4812 bfd_set_section_alignment (stdoutput
, text_section
, 4);
4814 target_big_endian
= 0;
4815 pseudo_func
[FUNC_FPTR_RELATIVE
].u
.sym
=
4816 symbol_new (".<fptr>", undefined_section
, FUNC_FPTR_RELATIVE
,
4817 &zero_address_frag
);
4819 pseudo_func
[FUNC_GP_RELATIVE
].u
.sym
=
4820 symbol_new (".<gprel>", undefined_section
, FUNC_GP_RELATIVE
,
4821 &zero_address_frag
);
4823 pseudo_func
[FUNC_LT_RELATIVE
].u
.sym
=
4824 symbol_new (".<ltoff>", undefined_section
, FUNC_LT_RELATIVE
,
4825 &zero_address_frag
);
4827 pseudo_func
[FUNC_PC_RELATIVE
].u
.sym
=
4828 symbol_new (".<pcrel>", undefined_section
, FUNC_PC_RELATIVE
,
4829 &zero_address_frag
);
4831 pseudo_func
[FUNC_PLT_RELATIVE
].u
.sym
=
4832 symbol_new (".<pltoff>", undefined_section
, FUNC_PLT_RELATIVE
,
4833 &zero_address_frag
);
4835 pseudo_func
[FUNC_SEC_RELATIVE
].u
.sym
=
4836 symbol_new (".<secrel>", undefined_section
, FUNC_SEC_RELATIVE
,
4837 &zero_address_frag
);
4839 pseudo_func
[FUNC_SEG_RELATIVE
].u
.sym
=
4840 symbol_new (".<segrel>", undefined_section
, FUNC_SEG_RELATIVE
,
4841 &zero_address_frag
);
4843 pseudo_func
[FUNC_LTV_RELATIVE
].u
.sym
=
4844 symbol_new (".<ltv>", undefined_section
, FUNC_LTV_RELATIVE
,
4845 &zero_address_frag
);
4847 pseudo_func
[FUNC_LT_FPTR_RELATIVE
].u
.sym
=
4848 symbol_new (".<ltoff.fptr>", undefined_section
, FUNC_LT_FPTR_RELATIVE
,
4849 &zero_address_frag
);
4851 /* compute the table of best templates: */
4852 for (i
= 0; i
< IA64_NUM_TYPES
; ++i
)
4853 for (j
= 0; j
< IA64_NUM_TYPES
; ++j
)
4854 for (k
= 0; k
< IA64_NUM_TYPES
; ++k
)
4857 for (t
= 0; t
< NELEMS (ia64_templ_desc
); ++t
)
4860 if (match (t
, i
, 0))
4862 if (match (t
, j
, 1))
4864 if (match (t
, k
, 2))
4869 else if (match (t
, j
, 2))
4874 else if (match (t
, i
, 1))
4876 if (match (t
, j
, 2))
4881 else if (match (t
, i
, 2))
4884 if (goodness
> best
)
4887 best_template
[i
][j
][k
] = t
;
4892 for (i
= 0; i
< NUM_SLOTS
; ++i
)
4893 md
.slot
[i
].user_template
= -1;
4895 md
.pseudo_hash
= hash_new ();
4896 for (i
= 0; i
< NELEMS (pseudo_opcode
); ++i
)
4898 err
= hash_insert (md
.pseudo_hash
, pseudo_opcode
[i
].name
,
4899 (void *) (pseudo_opcode
+ i
));
4901 as_fatal ("ia64.md_begin: can't hash `%s': %s",
4902 pseudo_opcode
[i
].name
, err
);
4905 md
.reg_hash
= hash_new ();
4906 md
.dynreg_hash
= hash_new ();
4907 md
.const_hash
= hash_new ();
4908 md
.entry_hash
= hash_new ();
4910 /* general registers: */
4913 for (i
= 0; i
< total
; ++i
)
4915 sprintf (name
, "r%d", i
- REG_GR
);
4916 md
.regsym
[i
] = declare_register (name
, i
);
4919 /* floating point registers: */
4921 for (; i
< total
; ++i
)
4923 sprintf (name
, "f%d", i
- REG_FR
);
4924 md
.regsym
[i
] = declare_register (name
, i
);
4927 /* application registers: */
4930 for (; i
< total
; ++i
)
4932 sprintf (name
, "ar%d", i
- REG_AR
);
4933 md
.regsym
[i
] = declare_register (name
, i
);
4936 /* control registers: */
4939 for (; i
< total
; ++i
)
4941 sprintf (name
, "cr%d", i
- REG_CR
);
4942 md
.regsym
[i
] = declare_register (name
, i
);
4945 /* predicate registers: */
4947 for (; i
< total
; ++i
)
4949 sprintf (name
, "p%d", i
- REG_P
);
4950 md
.regsym
[i
] = declare_register (name
, i
);
4953 /* branch registers: */
4955 for (; i
< total
; ++i
)
4957 sprintf (name
, "b%d", i
- REG_BR
);
4958 md
.regsym
[i
] = declare_register (name
, i
);
4961 md
.regsym
[REG_IP
] = declare_register ("ip", REG_IP
);
4962 md
.regsym
[REG_CFM
] = declare_register ("cfm", REG_CFM
);
4963 md
.regsym
[REG_PR
] = declare_register ("pr", REG_PR
);
4964 md
.regsym
[REG_PR_ROT
] = declare_register ("pr.rot", REG_PR_ROT
);
4965 md
.regsym
[REG_PSR
] = declare_register ("psr", REG_PSR
);
4966 md
.regsym
[REG_PSR_L
] = declare_register ("psr.l", REG_PSR_L
);
4967 md
.regsym
[REG_PSR_UM
] = declare_register ("psr.um", REG_PSR_UM
);
4969 for (i
= 0; i
< NELEMS (indirect_reg
); ++i
)
4971 regnum
= indirect_reg
[i
].regnum
;
4972 md
.regsym
[regnum
] = declare_register (indirect_reg
[i
].name
, regnum
);
4975 /* define synonyms for application registers: */
4976 for (i
= REG_AR
; i
< REG_AR
+ NELEMS (ar
); ++i
)
4977 md
.regsym
[i
] = declare_register (ar
[i
- REG_AR
].name
,
4978 REG_AR
+ ar
[i
- REG_AR
].regnum
);
4980 /* define synonyms for control registers: */
4981 for (i
= REG_CR
; i
< REG_CR
+ NELEMS (cr
); ++i
)
4982 md
.regsym
[i
] = declare_register (cr
[i
- REG_CR
].name
,
4983 REG_CR
+ cr
[i
- REG_CR
].regnum
);
4985 declare_register ("gp", REG_GR
+ 1);
4986 declare_register ("sp", REG_GR
+ 12);
4987 declare_register ("rp", REG_BR
+ 0);
4989 declare_register_set ("ret", 4, REG_GR
+ 8);
4990 declare_register_set ("farg", 8, REG_FR
+ 8);
4991 declare_register_set ("fret", 8, REG_FR
+ 8);
4993 for (i
= 0; i
< NELEMS (const_bits
); ++i
)
4995 err
= hash_insert (md
.const_hash
, const_bits
[i
].name
,
4996 (PTR
) (const_bits
+ i
));
4998 as_fatal ("Inserting \"%s\" into constant hash table failed: %s",
5002 /* Default to 64-bit mode. */
5003 md
.flags
= EF_IA_64_ABI64
;
5005 md
.mem_offset
.hint
= 0;
5008 md
.entry_labels
= NULL
;
5012 ia64_end_of_source ()
5014 /* terminate insn group upon reaching end of file: */
5015 insn_group_break (1, 0, 0);
5017 /* emits slots we haven't written yet: */
5018 ia64_flush_insns ();
5020 bfd_set_private_flags (stdoutput
, md
.flags
);
5022 if (debug_type
== DEBUG_DWARF2
)
5025 md
.mem_offset
.hint
= 0;
5031 md
.qp
.X_op
= O_absent
;
5033 if (ignore_input ())
5036 if (input_line_pointer
[0] == ';' && input_line_pointer
[-1] == ';')
5038 if (md
.detect_dv
&& !md
.explicit_mode
)
5039 as_warn (_("Explicit stops are ignored in auto mode"));
5041 insn_group_break (1, 0, 0);
5046 ia64_unrecognized_line (ch
)
5052 expression (&md
.qp
);
5053 if (*input_line_pointer
++ != ')')
5055 as_bad ("Expected ')'");
5058 if (md
.qp
.X_op
!= O_register
)
5060 as_bad ("Qualifying predicate expected");
5063 if (md
.qp
.X_add_number
< REG_P
|| md
.qp
.X_add_number
>= REG_P
+ 64)
5065 as_bad ("Predicate register expected");
5071 if (md
.manual_bundling
)
5072 as_warn ("Found '{' when manual bundling is already turned on");
5074 CURR_SLOT
.manual_bundling_on
= 1;
5075 md
.manual_bundling
= 1;
5077 /* bundling is only acceptable in explicit mode
5078 or when in default automatic mode */
5079 if (md
.detect_dv
&& !md
.explicit_mode
)
5081 if (!md
.mode_explicitly_set
5082 && !md
.default_explicit_mode
)
5085 as_warn (_("Found '{' after explicit switch to automatic mode"));
5090 if (!md
.manual_bundling
)
5091 as_warn ("Found '}' when manual bundling is off");
5093 PREV_SLOT
.manual_bundling_off
= 1;
5094 md
.manual_bundling
= 0;
5096 /* switch back to automatic mode, if applicable */
5099 && !md
.mode_explicitly_set
5100 && !md
.default_explicit_mode
)
5103 /* Allow '{' to follow on the same line. We also allow ";;", but that
5104 happens automatically because ';' is an end of line marker. */
5106 if (input_line_pointer
[0] == '{')
5108 input_line_pointer
++;
5109 return ia64_unrecognized_line ('{');
5112 demand_empty_rest_of_line ();
5118 return 0; /* not a valid line */
5122 ia64_frob_label (sym
)
5125 struct label_fix
*fix
;
5127 if (bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
)
5129 md
.last_text_seg
= now_seg
;
5130 fix
= obstack_alloc (¬es
, sizeof (*fix
));
5132 fix
->next
= CURR_SLOT
.label_fixups
;
5133 CURR_SLOT
.label_fixups
= fix
;
5135 /* keep track of how many code entry points we've seen */
5136 if (md
.path
== md
.maxpaths
)
5139 md
.entry_labels
= (const char **)
5140 xrealloc ((void *)md
.entry_labels
, md
.maxpaths
* sizeof (char *));
5142 md
.entry_labels
[md
.path
++] = S_GET_NAME (sym
);
5147 ia64_flush_pending_output ()
5149 if (bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
)
5151 /* ??? This causes many unnecessary stop bits to be emitted.
5152 Unfortunately, it isn't clear if it is safe to remove this. */
5153 insn_group_break (1, 0, 0);
5154 ia64_flush_insns ();
5158 /* Do ia64-specific expression optimization. All that's done here is
5159 to transform index expressions that are either due to the indexing
5160 of rotating registers or due to the indexing of indirect register
5163 ia64_optimize_expr (l
, op
, r
)
5172 if (l
->X_op
== O_register
&& r
->X_op
== O_constant
)
5174 num_regs
= (l
->X_add_number
>> 16);
5175 if ((unsigned) r
->X_add_number
>= num_regs
)
5178 as_bad ("No current frame");
5180 as_bad ("Index out of range 0..%u", num_regs
- 1);
5181 r
->X_add_number
= 0;
5183 l
->X_add_number
= (l
->X_add_number
& 0xffff) + r
->X_add_number
;
5186 else if (l
->X_op
== O_register
&& r
->X_op
== O_register
)
5188 if (l
->X_add_number
< IND_CPUID
|| l
->X_add_number
> IND_RR
5189 || l
->X_add_number
== IND_MEM
)
5191 as_bad ("Indirect register set name expected");
5192 l
->X_add_number
= IND_CPUID
;
5195 l
->X_op_symbol
= md
.regsym
[l
->X_add_number
];
5196 l
->X_add_number
= r
->X_add_number
;
5204 ia64_parse_name (name
, e
)
5208 struct const_desc
*cdesc
;
5209 struct dynreg
*dr
= 0;
5210 unsigned int regnum
;
5214 /* first see if NAME is a known register name: */
5215 sym
= hash_find (md
.reg_hash
, name
);
5218 e
->X_op
= O_register
;
5219 e
->X_add_number
= S_GET_VALUE (sym
);
5223 cdesc
= hash_find (md
.const_hash
, name
);
5226 e
->X_op
= O_constant
;
5227 e
->X_add_number
= cdesc
->value
;
5231 /* check for inN, locN, or outN: */
5235 if (name
[1] == 'n' && isdigit (name
[2]))
5243 if (name
[1] == 'o' && name
[2] == 'c' && isdigit (name
[3]))
5251 if (name
[1] == 'u' && name
[2] == 't' && isdigit (name
[3]))
5264 /* the name is inN, locN, or outN; parse the register number: */
5265 regnum
= strtoul (name
, &end
, 10);
5266 if (end
> name
&& *end
== '\0')
5268 if ((unsigned) regnum
>= dr
->num_regs
)
5271 as_bad ("No current frame");
5273 as_bad ("Register number out of range 0..%u", dr
->num_regs
-1);
5276 e
->X_op
= O_register
;
5277 e
->X_add_number
= dr
->base
+ regnum
;
5282 if ((dr
= hash_find (md
.dynreg_hash
, name
)))
5284 /* We've got ourselves the name of a rotating register set.
5285 Store the base register number in the low 16 bits of
5286 X_add_number and the size of the register set in the top 16
5288 e
->X_op
= O_register
;
5289 e
->X_add_number
= dr
->base
| (dr
->num_regs
<< 16);
5295 /* Remove the '#' suffix that indicates a symbol as opposed to a register. */
5298 ia64_canonicalize_symbol_name (name
)
5301 size_t len
= strlen(name
);
5302 if (len
> 1 && name
[len
-1] == '#')
5308 is_conditional_branch (idesc
)
5309 struct ia64_opcode
*idesc
;
5311 return (strncmp (idesc
->name
, "br", 2) == 0
5312 && (strcmp (idesc
->name
, "br") == 0
5313 || strncmp (idesc
->name
, "br.cond", 7) == 0
5314 || strncmp (idesc
->name
, "br.call", 7) == 0
5315 || strncmp (idesc
->name
, "br.ret", 6) == 0
5316 || strcmp (idesc
->name
, "brl") == 0
5317 || strncmp (idesc
->name
, "brl.cond", 7) == 0
5318 || strncmp (idesc
->name
, "brl.call", 7) == 0
5319 || strncmp (idesc
->name
, "brl.ret", 6) == 0));
5322 /* Return whether the given opcode is a taken branch. If there's any doubt,
5325 is_taken_branch (idesc
)
5326 struct ia64_opcode
*idesc
;
5328 return ((is_conditional_branch (idesc
) && CURR_SLOT
.qp_regno
== 0)
5329 || strncmp (idesc
->name
, "br.ia", 5) == 0);
5332 /* Return whether the given opcode is an interruption or rfi. If there's any
5333 doubt, returns zero */
5335 is_interruption_or_rfi (idesc
)
5336 struct ia64_opcode
*idesc
;
5338 if (strcmp (idesc
->name
, "rfi") == 0)
5343 /* Returns the index of the given dependency in the opcode's list of chks, or
5344 -1 if there is no dependency. */
5346 depends_on (depind
, idesc
)
5348 struct ia64_opcode
*idesc
;
5351 const struct ia64_opcode_dependency
*dep
= idesc
->dependencies
;
5352 for (i
= 0;i
< dep
->nchks
; i
++)
5354 if (depind
== DEP(dep
->chks
[i
]))
5360 /* Determine a set of specific resources used for a particular resource
5361 class. Returns the number of specific resources identified For those
5362 cases which are not determinable statically, the resource returned is
5365 Meanings of value in 'NOTE':
5366 1) only read/write when the register number is explicitly encoded in the
5368 2) only read CFM when accessing a rotating GR, FR, or PR. mov pr only
5369 accesses CFM when qualifying predicate is in the rotating region.
5370 3) general register value is used to specify an indirect register; not
5371 determinable statically.
5372 4) only read the given resource when bits 7:0 of the indirect index
5373 register value does not match the register number of the resource; not
5374 determinable statically.
5375 5) all rules are implementation specific.
5376 6) only when both the index specified by the reader and the index specified
5377 by the writer have the same value in bits 63:61; not determinable
5379 7) only access the specified resource when the corresponding mask bit is
5381 8) PSR.dfh is only read when these insns reference FR32-127. PSR.dfl is
5382 only read when these insns reference FR2-31
5383 9) PSR.mfl is only written when these insns write FR2-31. PSR.mfh is only
5384 written when these insns write FR32-127
5385 10) The PSR.bn bit is only accessed when one of GR16-31 is specified in the
5387 11) The target predicates are written independently of PR[qp], but source
5388 registers are only read if PR[qp] is true. Since the state of PR[qp]
5389 cannot statically be determined, all source registers are marked used.
5390 12) This insn only reads the specified predicate register when that
5391 register is the PR[qp].
5392 13) This reference to ld-c only applies to teh GR whose value is loaded
5393 with data returned from memory, not the post-incremented address register.
5394 14) The RSE resource includes the implementation-specific RSE internal
5395 state resources. At least one (and possibly more) of these resources are
5396 read by each instruction listed in IC:rse-readers. At least one (and
5397 possibly more) of these resources are written by each insn listed in
5399 15+16) Represents reserved instructions, which the assembler does not
5402 Memory resources (i.e. locations in memory) are *not* marked or tracked by
5403 this code; there are no dependency violations based on memory access.
5407 #define MAX_SPECS 256
5412 specify_resource (dep
, idesc
, type
, specs
, note
, path
)
5413 const struct ia64_dependency
*dep
;
5414 struct ia64_opcode
*idesc
;
5415 int type
; /* is this a DV chk or a DV reg? */
5416 struct rsrc specs
[MAX_SPECS
]; /* returned specific resources */
5417 int note
; /* resource note for this insn's usage */
5418 int path
; /* which execution path to examine */
5425 if (dep
->mode
== IA64_DV_WAW
5426 || (dep
->mode
== IA64_DV_RAW
&& type
== DV_REG
)
5427 || (dep
->mode
== IA64_DV_WAR
&& type
== DV_CHK
))
5430 /* template for any resources we identify */
5431 tmpl
.dependency
= dep
;
5433 tmpl
.insn_srlz
= tmpl
.data_srlz
= 0;
5434 tmpl
.qp_regno
= CURR_SLOT
.qp_regno
;
5435 tmpl
.link_to_qp_branch
= 1;
5436 tmpl
.mem_offset
.hint
= 0;
5441 as_warn (_("Unhandled dependency %s for %s (%s), note %d"), \
5442 dep->name, idesc->name, (rsrc_write?"write":"read"), note)
5443 #define KNOWN(REG) (gr_values[REG].known && gr_values[REG].path >= path)
5445 /* we don't need to track these */
5446 if (dep
->semantics
== IA64_DVS_NONE
)
5449 switch (dep
->specifier
)
5454 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_AR3
)
5456 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_AR
;
5457 if (regno
>= 0 && regno
<= 7)
5459 specs
[count
] = tmpl
;
5460 specs
[count
++].index
= regno
;
5468 specs
[count
] = tmpl
;
5469 specs
[count
++].index
= i
;
5478 case IA64_RS_AR_UNAT
:
5479 /* This is a mov =AR or mov AR= instruction. */
5480 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_AR3
)
5482 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_AR
;
5483 if (regno
== AR_UNAT
)
5485 specs
[count
++] = tmpl
;
5490 /* This is a spill/fill, or other instruction that modifies the
5493 /* Unless we can determine the specific bits used, mark the whole
5494 thing; bits 8:3 of the memory address indicate the bit used in
5495 UNAT. The .mem.offset hint may be used to eliminate a small
5496 subset of conflicts. */
5497 specs
[count
] = tmpl
;
5498 if (md
.mem_offset
.hint
)
5501 fprintf (stderr
, " Using hint for spill/fill\n");
5502 /* the index isn't actually used, just set it to something
5503 approximating the bit index */
5504 specs
[count
].index
= (md
.mem_offset
.offset
>> 3) & 0x3F;
5505 specs
[count
].mem_offset
.hint
= 1;
5506 specs
[count
].mem_offset
.offset
= md
.mem_offset
.offset
;
5507 specs
[count
++].mem_offset
.base
= md
.mem_offset
.base
;
5511 specs
[count
++].specific
= 0;
5519 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_AR3
)
5521 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_AR
;
5522 if ((regno
>= 8 && regno
<= 15)
5523 || (regno
>= 20 && regno
<= 23)
5524 || (regno
>= 31 && regno
<= 39)
5525 || (regno
>= 41 && regno
<= 47)
5526 || (regno
>= 67 && regno
<= 111))
5528 specs
[count
] = tmpl
;
5529 specs
[count
++].index
= regno
;
5542 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_AR3
)
5544 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_AR
;
5545 if ((regno
>= 48 && regno
<= 63)
5546 || (regno
>= 112 && regno
<= 127))
5548 specs
[count
] = tmpl
;
5549 specs
[count
++].index
= regno
;
5555 for (i
=48;i
< 64;i
++)
5557 specs
[count
] = tmpl
;
5558 specs
[count
++].index
= i
;
5560 for (i
=112;i
< 128;i
++)
5562 specs
[count
] = tmpl
;
5563 specs
[count
++].index
= i
;
5581 for (i
=0;i
< idesc
->num_outputs
;i
++)
5582 if (idesc
->operands
[i
] == IA64_OPND_B1
5583 || idesc
->operands
[i
] == IA64_OPND_B2
)
5585 specs
[count
] = tmpl
;
5586 specs
[count
++].index
=
5587 CURR_SLOT
.opnd
[i
].X_add_number
- REG_BR
;
5592 for (i
= idesc
->num_outputs
;i
< NELEMS(idesc
->operands
);i
++)
5593 if (idesc
->operands
[i
] == IA64_OPND_B1
5594 || idesc
->operands
[i
] == IA64_OPND_B2
)
5596 specs
[count
] = tmpl
;
5597 specs
[count
++].index
=
5598 CURR_SLOT
.opnd
[i
].X_add_number
- REG_BR
;
5604 case IA64_RS_CPUID
: /* four or more registers */
5607 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_CPUID_R3
)
5609 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_GR
;
5610 if (regno
>= 0 && regno
< NELEMS(gr_values
)
5613 specs
[count
] = tmpl
;
5614 specs
[count
++].index
= gr_values
[regno
].value
& 0xFF;
5618 specs
[count
] = tmpl
;
5619 specs
[count
++].specific
= 0;
5629 case IA64_RS_DBR
: /* four or more registers */
5632 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_DBR_R3
)
5634 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_GR
;
5635 if (regno
>= 0 && regno
< NELEMS(gr_values
)
5638 specs
[count
] = tmpl
;
5639 specs
[count
++].index
= gr_values
[regno
].value
& 0xFF;
5643 specs
[count
] = tmpl
;
5644 specs
[count
++].specific
= 0;
5648 else if (note
== 0 && !rsrc_write
)
5650 specs
[count
] = tmpl
;
5651 specs
[count
++].specific
= 0;
5659 case IA64_RS_IBR
: /* four or more registers */
5662 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_IBR_R3
)
5664 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_GR
;
5665 if (regno
>= 0 && regno
< NELEMS(gr_values
)
5668 specs
[count
] = tmpl
;
5669 specs
[count
++].index
= gr_values
[regno
].value
& 0xFF;
5673 specs
[count
] = tmpl
;
5674 specs
[count
++].specific
= 0;
5687 /* These are implementation specific. Force all references to
5688 conflict with all other references. */
5689 specs
[count
] = tmpl
;
5690 specs
[count
++].specific
= 0;
5698 case IA64_RS_PKR
: /* 16 or more registers */
5699 if (note
== 3 || note
== 4)
5701 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_PKR_R3
)
5703 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_GR
;
5704 if (regno
>= 0 && regno
< NELEMS(gr_values
)
5709 specs
[count
] = tmpl
;
5710 specs
[count
++].index
= gr_values
[regno
].value
& 0xFF;
5712 else for (i
=0;i
< NELEMS(gr_values
);i
++)
5714 /* uses all registers *except* the one in R3 */
5715 if (i
!= (gr_values
[regno
].value
& 0xFF))
5717 specs
[count
] = tmpl
;
5718 specs
[count
++].index
= i
;
5724 specs
[count
] = tmpl
;
5725 specs
[count
++].specific
= 0;
5732 specs
[count
] = tmpl
;
5733 specs
[count
++].specific
= 0;
5737 case IA64_RS_PMC
: /* four or more registers */
5740 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_PMC_R3
5741 || (!rsrc_write
&& idesc
->operands
[1] == IA64_OPND_PMD_R3
))
5744 int index
= ((idesc
->operands
[1] == IA64_OPND_R3
&& !rsrc_write
)
5746 int regno
= CURR_SLOT
.opnd
[index
].X_add_number
- REG_GR
;
5747 if (regno
>= 0 && regno
< NELEMS(gr_values
)
5750 specs
[count
] = tmpl
;
5751 specs
[count
++].index
= gr_values
[regno
].value
& 0xFF;
5755 specs
[count
] = tmpl
;
5756 specs
[count
++].specific
= 0;
5766 case IA64_RS_PMD
: /* four or more registers */
5769 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_PMD_R3
)
5771 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_GR
;
5772 if (regno
>= 0 && regno
< NELEMS(gr_values
)
5775 specs
[count
] = tmpl
;
5776 specs
[count
++].index
= gr_values
[regno
].value
& 0xFF;
5780 specs
[count
] = tmpl
;
5781 specs
[count
++].specific
= 0;
5791 case IA64_RS_RR
: /* eight registers */
5794 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_RR_R3
)
5796 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_GR
;
5797 if (regno
>= 0 && regno
< NELEMS(gr_values
)
5800 specs
[count
] = tmpl
;
5801 specs
[count
++].index
= (gr_values
[regno
].value
>> 61) & 0x7;
5805 specs
[count
] = tmpl
;
5806 specs
[count
++].specific
= 0;
5810 else if (note
== 0 && !rsrc_write
)
5812 specs
[count
] = tmpl
;
5813 specs
[count
++].specific
= 0;
5821 case IA64_RS_CR_IRR
:
5824 /* handle mov-from-CR-IVR; it's a read that writes CR[IRR] */
5825 int regno
= CURR_SLOT
.opnd
[1].X_add_number
- REG_CR
;
5827 && idesc
->operands
[1] == IA64_OPND_CR3
5832 specs
[count
] = tmpl
;
5833 specs
[count
++].index
= CR_IRR0
+ i
;
5839 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_CR
;
5840 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_CR3
5842 && regno
<= CR_IRR3
)
5844 specs
[count
] = tmpl
;
5845 specs
[count
++].index
= regno
;
5854 case IA64_RS_CR_LRR
:
5861 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_CR
;
5862 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_CR3
5863 && (regno
== CR_LRR0
|| regno
== CR_LRR1
))
5865 specs
[count
] = tmpl
;
5866 specs
[count
++].index
= regno
;
5874 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_CR3
)
5876 specs
[count
] = tmpl
;
5877 specs
[count
++].index
=
5878 CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_CR
;
5893 else if (rsrc_write
)
5895 if (dep
->specifier
== IA64_RS_FRb
5896 && idesc
->operands
[0] == IA64_OPND_F1
)
5898 specs
[count
] = tmpl
;
5899 specs
[count
++].index
= CURR_SLOT
.opnd
[0].X_add_number
- REG_FR
;
5904 for (i
=idesc
->num_outputs
;i
< NELEMS(idesc
->operands
);i
++)
5906 if (idesc
->operands
[i
] == IA64_OPND_F2
5907 || idesc
->operands
[i
] == IA64_OPND_F3
5908 || idesc
->operands
[i
] == IA64_OPND_F4
)
5910 specs
[count
] = tmpl
;
5911 specs
[count
++].index
=
5912 CURR_SLOT
.opnd
[i
].X_add_number
- REG_FR
;
5921 /* This reference applies only to the GR whose value is loaded with
5922 data returned from memory */
5923 specs
[count
] = tmpl
;
5924 specs
[count
++].index
= CURR_SLOT
.opnd
[0].X_add_number
- REG_GR
;
5930 for (i
=0;i
< idesc
->num_outputs
;i
++)
5932 if (idesc
->operands
[i
] == IA64_OPND_R1
5933 || idesc
->operands
[i
] == IA64_OPND_R2
5934 || idesc
->operands
[i
] == IA64_OPND_R3
)
5936 specs
[count
] = tmpl
;
5937 specs
[count
++].index
=
5938 CURR_SLOT
.opnd
[i
].X_add_number
- REG_GR
;
5944 /* Look for anything that reads a GR */
5945 for (i
=0;i
< NELEMS(idesc
->operands
);i
++)
5947 if (idesc
->operands
[i
] == IA64_OPND_MR3
5948 || idesc
->operands
[i
] == IA64_OPND_CPUID_R3
5949 || idesc
->operands
[i
] == IA64_OPND_DBR_R3
5950 || idesc
->operands
[i
] == IA64_OPND_IBR_R3
5951 || idesc
->operands
[i
] == IA64_OPND_MSR_R3
5952 || idesc
->operands
[i
] == IA64_OPND_PKR_R3
5953 || idesc
->operands
[i
] == IA64_OPND_PMC_R3
5954 || idesc
->operands
[i
] == IA64_OPND_PMD_R3
5955 || idesc
->operands
[i
] == IA64_OPND_RR_R3
5956 || ((i
>= idesc
->num_outputs
)
5957 && (idesc
->operands
[i
] == IA64_OPND_R1
5958 || idesc
->operands
[i
] == IA64_OPND_R2
5959 || idesc
->operands
[i
] == IA64_OPND_R3
)))
5961 specs
[count
] = tmpl
;
5962 specs
[count
++].index
=
5963 CURR_SLOT
.opnd
[i
].X_add_number
- REG_GR
;
5977 if (idesc
->operands
[0] == IA64_OPND_PR_ROT
)
5979 for (i
=16;i
< 63;i
++)
5981 specs
[count
] = tmpl
;
5982 specs
[count
++].index
= i
;
5987 for (i
=1;i
< 63;i
++)
5989 specs
[count
] = tmpl
;
5990 specs
[count
++].index
= i
;
5997 /* mark only those registers indicated by the mask */
5999 && idesc
->operands
[0] == IA64_OPND_PR
)
6001 mask
= CURR_SLOT
.opnd
[2].X_add_number
;
6002 if (mask
& ((valueT
)1<<16))
6003 mask
|= ~(valueT
)0xffff;
6004 for (i
=1;i
< 63;i
++)
6006 if (mask
& ((valueT
)1<<i
))
6008 specs
[count
] = tmpl
;
6009 specs
[count
++].index
= i
;
6014 && idesc
->operands
[0] == IA64_OPND_PR_ROT
)
6016 for (i
=16;i
< 63;i
++)
6018 specs
[count
] = tmpl
;
6019 specs
[count
++].index
= i
;
6027 else if (note
== 11) /* note 11 implies note 1 as well */
6031 for (i
=0;i
< idesc
->num_outputs
;i
++)
6033 if (idesc
->operands
[i
] == IA64_OPND_P1
6034 || idesc
->operands
[i
] == IA64_OPND_P2
)
6036 int regno
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_P
;
6039 specs
[count
] = tmpl
;
6040 specs
[count
++].index
= regno
;
6050 else if (note
== 12)
6052 if (CURR_SLOT
.qp_regno
!= 0)
6054 specs
[count
] = tmpl
;
6055 specs
[count
++].index
= CURR_SLOT
.qp_regno
;
6062 int p1
= CURR_SLOT
.opnd
[0].X_add_number
- REG_P
;
6063 int p2
= CURR_SLOT
.opnd
[1].X_add_number
- REG_P
;
6064 if ((idesc
->operands
[0] == IA64_OPND_P1
6065 || idesc
->operands
[0] == IA64_OPND_P2
)
6066 && p1
!= 0 && p1
!= 63)
6068 specs
[count
] = tmpl
;
6069 specs
[count
++].index
= p1
;
6071 if ((idesc
->operands
[1] == IA64_OPND_P1
6072 || idesc
->operands
[1] == IA64_OPND_P2
)
6073 && p2
!= 0 && p2
!= 63)
6075 specs
[count
] = tmpl
;
6076 specs
[count
++].index
= p2
;
6081 if (CURR_SLOT
.qp_regno
!= 0)
6083 specs
[count
] = tmpl
;
6084 specs
[count
++].index
= CURR_SLOT
.qp_regno
;
6086 if (idesc
->operands
[1] == IA64_OPND_PR
)
6088 for (i
=1;i
< 63;i
++)
6090 specs
[count
] = tmpl
;
6091 specs
[count
++].index
= i
;
6103 /* Verify that the instruction is using the PSR bit indicated in
6107 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_PSR_UM
)
6109 if (dep
->regindex
< 6)
6111 specs
[count
++] = tmpl
;
6114 else if (idesc
->operands
[!rsrc_write
] == IA64_OPND_PSR
)
6116 if (dep
->regindex
< 32
6117 || dep
->regindex
== 35
6118 || dep
->regindex
== 36
6119 || (!rsrc_write
&& dep
->regindex
== PSR_CPL
))
6121 specs
[count
++] = tmpl
;
6124 else if (idesc
->operands
[!rsrc_write
] == IA64_OPND_PSR_L
)
6126 if (dep
->regindex
< 32
6127 || dep
->regindex
== 35
6128 || dep
->regindex
== 36
6129 || (rsrc_write
&& dep
->regindex
== PSR_CPL
))
6131 specs
[count
++] = tmpl
;
6136 /* Several PSR bits have very specific dependencies. */
6137 switch (dep
->regindex
)
6140 specs
[count
++] = tmpl
;
6145 specs
[count
++] = tmpl
;
6149 /* Only certain CR accesses use PSR.ic */
6150 if (idesc
->operands
[0] == IA64_OPND_CR3
6151 || idesc
->operands
[1] == IA64_OPND_CR3
)
6154 ((idesc
->operands
[0] == IA64_OPND_CR3
)
6157 CURR_SLOT
.opnd
[index
].X_add_number
- REG_CR
;
6172 specs
[count
++] = tmpl
;
6181 specs
[count
++] = tmpl
;
6185 /* Only some AR accesses use cpl */
6186 if (idesc
->operands
[0] == IA64_OPND_AR3
6187 || idesc
->operands
[1] == IA64_OPND_AR3
)
6190 ((idesc
->operands
[0] == IA64_OPND_AR3
)
6193 CURR_SLOT
.opnd
[index
].X_add_number
- REG_AR
;
6200 && regno
<= AR_K7
))))
6202 specs
[count
++] = tmpl
;
6207 specs
[count
++] = tmpl
;
6217 if (idesc
->operands
[0] == IA64_OPND_IMMU24
)
6219 mask
= CURR_SLOT
.opnd
[0].X_add_number
;
6225 if (mask
& ((valueT
)1<<dep
->regindex
))
6227 specs
[count
++] = tmpl
;
6232 int min
= dep
->regindex
== PSR_DFL
? 2 : 32;
6233 int max
= dep
->regindex
== PSR_DFL
? 31 : 127;
6234 /* dfh is read on FR32-127; dfl is read on FR2-31 */
6235 for (i
=0;i
< NELEMS(idesc
->operands
);i
++)
6237 if (idesc
->operands
[i
] == IA64_OPND_F1
6238 || idesc
->operands
[i
] == IA64_OPND_F2
6239 || idesc
->operands
[i
] == IA64_OPND_F3
6240 || idesc
->operands
[i
] == IA64_OPND_F4
)
6242 int reg
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_FR
;
6243 if (reg
>= min
&& reg
<= max
)
6245 specs
[count
++] = tmpl
;
6252 int min
= dep
->regindex
== PSR_MFL
? 2 : 32;
6253 int max
= dep
->regindex
== PSR_MFL
? 31 : 127;
6254 /* mfh is read on writes to FR32-127; mfl is read on writes to
6256 for (i
=0;i
< idesc
->num_outputs
;i
++)
6258 if (idesc
->operands
[i
] == IA64_OPND_F1
)
6260 int reg
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_FR
;
6261 if (reg
>= min
&& reg
<= max
)
6263 specs
[count
++] = tmpl
;
6268 else if (note
== 10)
6270 for (i
=0;i
< NELEMS(idesc
->operands
);i
++)
6272 if (idesc
->operands
[i
] == IA64_OPND_R1
6273 || idesc
->operands
[i
] == IA64_OPND_R2
6274 || idesc
->operands
[i
] == IA64_OPND_R3
)
6276 int regno
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_GR
;
6277 if (regno
>= 16 && regno
<= 31)
6279 specs
[count
++] = tmpl
;
6290 case IA64_RS_AR_FPSR
:
6291 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_AR3
)
6293 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_AR
;
6294 if (regno
== AR_FPSR
)
6296 specs
[count
++] = tmpl
;
6301 specs
[count
++] = tmpl
;
6306 /* Handle all AR[REG] resources */
6307 if (note
== 0 || note
== 1)
6309 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_AR
;
6310 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_AR3
6311 && regno
== dep
->regindex
)
6313 specs
[count
++] = tmpl
;
6315 /* other AR[REG] resources may be affected by AR accesses */
6316 else if (idesc
->operands
[0] == IA64_OPND_AR3
)
6319 regno
= CURR_SLOT
.opnd
[0].X_add_number
- REG_AR
;
6320 switch (dep
->regindex
)
6326 if (regno
== AR_BSPSTORE
)
6328 specs
[count
++] = tmpl
;
6332 (regno
== AR_BSPSTORE
6333 || regno
== AR_RNAT
))
6335 specs
[count
++] = tmpl
;
6340 else if (idesc
->operands
[1] == IA64_OPND_AR3
)
6343 regno
= CURR_SLOT
.opnd
[1].X_add_number
- REG_AR
;
6344 switch (dep
->regindex
)
6349 if (regno
== AR_BSPSTORE
|| regno
== AR_RNAT
)
6351 specs
[count
++] = tmpl
;
6358 specs
[count
++] = tmpl
;
6368 /* Handle all CR[REG] resources */
6369 if (note
== 0 || note
== 1)
6371 if (idesc
->operands
[!rsrc_write
] == IA64_OPND_CR3
)
6373 int regno
= CURR_SLOT
.opnd
[!rsrc_write
].X_add_number
- REG_CR
;
6374 if (regno
== dep
->regindex
)
6376 specs
[count
++] = tmpl
;
6378 else if (!rsrc_write
)
6380 /* Reads from CR[IVR] affect other resources. */
6381 if (regno
== CR_IVR
)
6383 if ((dep
->regindex
>= CR_IRR0
6384 && dep
->regindex
<= CR_IRR3
)
6385 || dep
->regindex
== CR_TPR
)
6387 specs
[count
++] = tmpl
;
6394 specs
[count
++] = tmpl
;
6403 case IA64_RS_INSERVICE
:
6404 /* look for write of EOI (67) or read of IVR (65) */
6405 if ((idesc
->operands
[0] == IA64_OPND_CR3
6406 && CURR_SLOT
.opnd
[0].X_add_number
- REG_CR
== CR_EOI
)
6407 || (idesc
->operands
[1] == IA64_OPND_CR3
6408 && CURR_SLOT
.opnd
[1].X_add_number
- REG_CR
== CR_IVR
))
6410 specs
[count
++] = tmpl
;
6417 specs
[count
++] = tmpl
;
6428 specs
[count
++] = tmpl
;
6432 /* Check if any of the registers accessed are in the rotating region.
6433 mov to/from pr accesses CFM only when qp_regno is in the rotating
6435 for (i
=0;i
< NELEMS(idesc
->operands
);i
++)
6437 if (idesc
->operands
[i
] == IA64_OPND_R1
6438 || idesc
->operands
[i
] == IA64_OPND_R2
6439 || idesc
->operands
[i
] == IA64_OPND_R3
)
6441 int num
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_GR
;
6442 /* Assumes that md.rot.num_regs is always valid */
6443 if (md
.rot
.num_regs
> 0
6445 && num
< 31 + md
.rot
.num_regs
)
6447 specs
[count
] = tmpl
;
6448 specs
[count
++].specific
= 0;
6451 else if (idesc
->operands
[i
] == IA64_OPND_F1
6452 || idesc
->operands
[i
] == IA64_OPND_F2
6453 || idesc
->operands
[i
] == IA64_OPND_F3
6454 || idesc
->operands
[i
] == IA64_OPND_F4
)
6456 int num
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_FR
;
6459 specs
[count
] = tmpl
;
6460 specs
[count
++].specific
= 0;
6463 else if (idesc
->operands
[i
] == IA64_OPND_P1
6464 || idesc
->operands
[i
] == IA64_OPND_P2
)
6466 int num
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_P
;
6469 specs
[count
] = tmpl
;
6470 specs
[count
++].specific
= 0;
6474 if (CURR_SLOT
.qp_regno
> 15)
6476 specs
[count
] = tmpl
;
6477 specs
[count
++].specific
= 0;
6485 specs
[count
++] = tmpl
;
6487 else if (note
== 11)
6489 if ((idesc
->operands
[0] == IA64_OPND_P1
6490 && CURR_SLOT
.opnd
[0].X_add_number
- REG_P
== 63)
6491 || (idesc
->operands
[1] == IA64_OPND_P2
6492 && CURR_SLOT
.opnd
[1].X_add_number
- REG_P
== 63))
6494 specs
[count
++] = tmpl
;
6497 else if (note
== 12)
6499 if (CURR_SLOT
.qp_regno
== 63)
6501 specs
[count
++] = tmpl
;
6507 if (idesc
->operands
[2] == IA64_OPND_IMM17
)
6508 mask
= CURR_SLOT
.opnd
[2].X_add_number
;
6509 if (mask
& ((valueT
)1<<63))
6511 specs
[count
++] = tmpl
;
6518 for (i
=0;i
< idesc
->num_outputs
;i
++)
6519 if ((idesc
->operands
[i
] == IA64_OPND_P1
6520 || idesc
->operands
[i
] == IA64_OPND_P2
)
6521 && CURR_SLOT
.opnd
[i
].X_add_number
- REG_P
== 63)
6523 specs
[count
++] = tmpl
;
6528 if (CURR_SLOT
.qp_regno
== 63)
6530 specs
[count
++] = tmpl
;
6541 /* FIXME we can identify some individual RSE written resources, but RSE
6542 read resources have not yet been completely identified, so for now
6543 treat RSE as a single resource */
6544 if (strncmp (idesc
->name
, "mov", 3) == 0)
6548 if (idesc
->operands
[0] == IA64_OPND_AR3
6549 && CURR_SLOT
.opnd
[0].X_add_number
- REG_AR
== AR_BSPSTORE
)
6551 specs
[count
] = tmpl
;
6552 specs
[count
++].index
= 0; /* IA64_RSE_BSPLOAD/RNATBITINDEX */
6557 if (idesc
->operands
[0] == IA64_OPND_AR3
)
6559 if (CURR_SLOT
.opnd
[0].X_add_number
- REG_AR
== AR_BSPSTORE
6560 || CURR_SLOT
.opnd
[0].X_add_number
- REG_AR
== AR_RNAT
)
6562 specs
[count
++] = tmpl
;
6565 else if (idesc
->operands
[1] == IA64_OPND_AR3
)
6567 if (CURR_SLOT
.opnd
[1].X_add_number
- REG_AR
== AR_BSP
6568 || CURR_SLOT
.opnd
[1].X_add_number
- REG_AR
== AR_BSPSTORE
6569 || CURR_SLOT
.opnd
[1].X_add_number
- REG_AR
== AR_RNAT
)
6571 specs
[count
++] = tmpl
;
6578 specs
[count
++] = tmpl
;
6583 /* FIXME -- do any of these need to be non-specific? */
6584 specs
[count
++] = tmpl
;
6588 as_bad (_("Unrecognized dependency specifier %d\n"), dep
->specifier
);
6595 /* Clear branch flags on marked resources. This breaks the link between the
6596 QP of the marking instruction and a subsequent branch on the same QP.
6599 clear_qp_branch_flag (mask
)
6603 for (i
= 0;i
< regdepslen
;i
++)
6605 valueT bit
= ((valueT
)1 << regdeps
[i
].qp_regno
);
6606 if ((bit
& mask
) != 0)
6608 regdeps
[i
].link_to_qp_branch
= 0;
6613 /* Remove any mutexes which contain any of the PRs indicated in the mask.
6615 Any changes to a PR clears the mutex relations which include that PR.
6618 clear_qp_mutex (mask
)
6624 while (i
< qp_mutexeslen
)
6626 if ((qp_mutexes
[i
].prmask
& mask
) != 0)
6630 fprintf (stderr
, " Clearing mutex relation");
6631 print_prmask (qp_mutexes
[i
].prmask
);
6632 fprintf (stderr
, "\n");
6634 qp_mutexes
[i
] = qp_mutexes
[--qp_mutexeslen
];
6641 /* Clear implies relations which contain PRs in the given masks.
6642 P1_MASK indicates the source of the implies relation, while P2_MASK
6643 indicates the implied PR.
6646 clear_qp_implies (p1_mask
, p2_mask
)
6653 while (i
< qp_implieslen
)
6655 if ((((valueT
)1 << qp_implies
[i
].p1
) & p1_mask
) != 0
6656 || (((valueT
)1 << qp_implies
[i
].p2
) & p2_mask
) != 0)
6659 fprintf (stderr
, "Clearing implied relation PR%d->PR%d\n",
6660 qp_implies
[i
].p1
, qp_implies
[i
].p2
);
6661 qp_implies
[i
] = qp_implies
[--qp_implieslen
];
6668 /* add the PRs specified to the list of implied relations */
6670 add_qp_imply (p1
, p2
)
6677 /* p0 is not meaningful here */
6678 if (p1
== 0 || p2
== 0)
6684 /* if it exists already, ignore it */
6685 for (i
=0;i
< qp_implieslen
;i
++)
6687 if (qp_implies
[i
].p1
== p1
6688 && qp_implies
[i
].p2
== p2
6689 && qp_implies
[i
].path
== md
.path
6690 && !qp_implies
[i
].p2_branched
)
6694 if (qp_implieslen
== qp_impliestotlen
)
6696 qp_impliestotlen
+= 20;
6697 qp_implies
= (struct qp_imply
*)
6698 xrealloc ((void *)qp_implies
,
6699 qp_impliestotlen
* sizeof (struct qp_imply
));
6702 fprintf (stderr
, " Registering PR%d implies PR%d\n", p1
, p2
);
6703 qp_implies
[qp_implieslen
].p1
= p1
;
6704 qp_implies
[qp_implieslen
].p2
= p2
;
6705 qp_implies
[qp_implieslen
].path
= md
.path
;
6706 qp_implies
[qp_implieslen
++].p2_branched
= 0;
6708 /* Add in the implied transitive relations; for everything that p2 implies,
6709 make p1 imply that, too; for everything that implies p1, make it imply p2
6711 for (i
=0;i
< qp_implieslen
;i
++)
6713 if (qp_implies
[i
].p1
== p2
)
6714 add_qp_imply (p1
, qp_implies
[i
].p2
);
6715 if (qp_implies
[i
].p2
== p1
)
6716 add_qp_imply (qp_implies
[i
].p1
, p2
);
6718 /* Add in mutex relations implied by this implies relation; for each mutex
6719 relation containing p2, duplicate it and replace p2 with p1. */
6720 bit
= (valueT
)1 << p1
;
6721 mask
= (valueT
)1 << p2
;
6722 for (i
=0;i
< qp_mutexeslen
;i
++)
6724 if (qp_mutexes
[i
].prmask
& mask
)
6725 add_qp_mutex ((qp_mutexes
[i
].prmask
& ~mask
) | bit
);
6730 /* Add the PRs specified in the mask to the mutex list; this means that only
6731 one of the PRs can be true at any time. PR0 should never be included in
6740 if (qp_mutexeslen
== qp_mutexestotlen
)
6742 qp_mutexestotlen
+= 20;
6743 qp_mutexes
= (struct qpmutex
*)
6744 xrealloc ((void *)qp_mutexes
,
6745 qp_mutexestotlen
* sizeof (struct qpmutex
));
6749 fprintf (stderr
, " Registering mutex on");
6750 print_prmask (mask
);
6751 fprintf (stderr
, "\n");
6753 qp_mutexes
[qp_mutexeslen
].path
= md
.path
;
6754 qp_mutexes
[qp_mutexeslen
++].prmask
= mask
;
6758 clear_register_values ()
6762 fprintf (stderr
, " Clearing register values\n");
6763 for (i
=1;i
< NELEMS(gr_values
);i
++)
6764 gr_values
[i
].known
= 0;
6767 /* Keep track of register values/changes which affect DV tracking.
6769 optimization note: should add a flag to classes of insns where otherwise we
6770 have to examine a group of strings to identify them.
6774 note_register_values (idesc
)
6775 struct ia64_opcode
*idesc
;
6777 valueT qp_changemask
= 0;
6780 /* invalidate values for registers being written to */
6781 for (i
=0;i
< idesc
->num_outputs
;i
++)
6783 if (idesc
->operands
[i
] == IA64_OPND_R1
6784 || idesc
->operands
[i
] == IA64_OPND_R2
6785 || idesc
->operands
[i
] == IA64_OPND_R3
)
6787 int regno
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_GR
;
6788 if (regno
> 0 && regno
< NELEMS(gr_values
))
6789 gr_values
[regno
].known
= 0;
6791 else if (idesc
->operands
[i
] == IA64_OPND_P1
6792 || idesc
->operands
[i
] == IA64_OPND_P2
)
6794 int regno
= CURR_SLOT
.opnd
[i
].X_add_number
- REG_P
;
6795 qp_changemask
|= (valueT
)1 << regno
;
6797 else if (idesc
->operands
[i
] == IA64_OPND_PR
)
6799 if (idesc
->operands
[2] & (valueT
)0x10000)
6800 qp_changemask
= ~(valueT
)0x1FFFF | idesc
->operands
[2];
6802 qp_changemask
= idesc
->operands
[2];
6805 else if (idesc
->operands
[i
] == IA64_OPND_PR_ROT
)
6807 if (idesc
->operands
[1] & ((valueT
)1 << 43))
6808 qp_changemask
= ~(valueT
)0xFFFFFFFFFFF | idesc
->operands
[1];
6810 qp_changemask
= idesc
->operands
[1];
6811 qp_changemask
&= ~(valueT
)0xFFFF;
6816 /* Always clear qp branch flags on any PR change */
6817 /* FIXME there may be exceptions for certain compares */
6818 clear_qp_branch_flag (qp_changemask
);
6820 /* invalidate rotating registers on insns which affect RRBs in CFM */
6821 if (idesc
->flags
& IA64_OPCODE_MOD_RRBS
)
6823 qp_changemask
|= ~(valueT
)0xFFFF;
6824 if (strcmp (idesc
->name
, "clrrrb.pr") != 0)
6826 for (i
=32;i
< 32+md
.rot
.num_regs
;i
++)
6827 gr_values
[i
].known
= 0;
6829 clear_qp_mutex (qp_changemask
);
6830 clear_qp_implies (qp_changemask
, qp_changemask
);
6832 /* after a call, all register values are undefined, except those marked
6834 else if (strncmp (idesc
->name
, "br.call", 6) == 0
6835 || strncmp (idesc
->name
, "brl.call", 7) == 0)
6837 // FIXME keep GR values which are marked as "safe_across_calls"
6838 clear_register_values ();
6839 clear_qp_mutex (~qp_safe_across_calls
);
6840 clear_qp_implies (~qp_safe_across_calls
, ~qp_safe_across_calls
);
6841 clear_qp_branch_flag (~qp_safe_across_calls
);
6843 /* Look for mutex and implies relations */
6844 else if ((idesc
->operands
[0] == IA64_OPND_P1
6845 || idesc
->operands
[0] == IA64_OPND_P2
)
6846 && (idesc
->operands
[1] == IA64_OPND_P1
6847 || idesc
->operands
[1] == IA64_OPND_P2
))
6849 int p1
= CURR_SLOT
.opnd
[0].X_add_number
- REG_P
;
6850 int p2
= CURR_SLOT
.opnd
[1].X_add_number
- REG_P
;
6851 valueT p1mask
= (valueT
)1 << p1
;
6852 valueT p2mask
= (valueT
)1 << p2
;
6854 /* if one of the PRs is PR0, we can't really do anything */
6855 if (p1
== 0 || p2
== 0)
6858 fprintf (stderr
, " Ignoring PRs due to inclusion of p0\n");
6860 /* In general, clear mutexes and implies which include P1 or P2,
6861 with the following exceptions */
6862 else if (strstr (idesc
->name
, ".or.andcm") != NULL
)
6864 add_qp_mutex (p1mask
| p2mask
);
6865 clear_qp_implies (p2mask
, p1mask
);
6867 else if (strstr (idesc
->name
, ".and.orcm") != NULL
)
6869 add_qp_mutex (p1mask
| p2mask
);
6870 clear_qp_implies (p1mask
, p2mask
);
6872 else if (strstr (idesc
->name
, ".and") != NULL
)
6874 clear_qp_implies (0, p1mask
| p2mask
);
6876 else if (strstr (idesc
->name
, ".or") != NULL
)
6878 clear_qp_mutex (p1mask
| p2mask
);
6879 clear_qp_implies (p1mask
| p2mask
, 0);
6883 clear_qp_implies (p1mask
| p2mask
, p1mask
| p2mask
);
6884 if (strstr (idesc
->name
, ".unc") != NULL
)
6886 add_qp_mutex (p1mask
| p2mask
);
6887 if (CURR_SLOT
.qp_regno
!= 0)
6889 add_qp_imply (CURR_SLOT
.opnd
[0].X_add_number
- REG_P
,
6890 CURR_SLOT
.qp_regno
);
6891 add_qp_imply (CURR_SLOT
.opnd
[1].X_add_number
- REG_P
,
6892 CURR_SLOT
.qp_regno
);
6895 else if (CURR_SLOT
.qp_regno
== 0)
6897 add_qp_mutex (p1mask
| p2mask
);
6901 clear_qp_mutex (p1mask
| p2mask
);
6905 /* Look for mov imm insns into GRs */
6906 else if (idesc
->operands
[0] == IA64_OPND_R1
6907 && (idesc
->operands
[1] == IA64_OPND_IMM22
6908 || idesc
->operands
[1] == IA64_OPND_IMMU64
)
6909 && (strcmp(idesc
->name
, "mov") == 0
6910 || strcmp(idesc
->name
, "movl") == 0))
6912 int regno
= CURR_SLOT
.opnd
[0].X_add_number
- REG_GR
;
6913 if (regno
> 0 && regno
< NELEMS(gr_values
))
6915 gr_values
[regno
].known
= 1;
6916 gr_values
[regno
].value
= CURR_SLOT
.opnd
[1].X_add_number
;
6917 gr_values
[regno
].path
= md
.path
;
6919 fprintf (stderr
, " Know gr%d = 0x%llx\n",
6920 regno
, gr_values
[regno
].value
);
6925 clear_qp_mutex (qp_changemask
);
6926 clear_qp_implies (qp_changemask
, qp_changemask
);
6930 /* Return whether the given predicate registers are currently mutex */
6932 qp_mutex (p1
, p2
, path
)
6942 mask
= ((valueT
)1<<p1
) | (valueT
)1<<p2
;
6943 for (i
=0;i
< qp_mutexeslen
;i
++)
6945 if (qp_mutexes
[i
].path
>= path
6946 && (qp_mutexes
[i
].prmask
& mask
) == mask
)
6953 /* Return whether the given resource is in the given insn's list of chks
6954 Return 1 if the conflict is absolutely determined, 2 if it's a potential
6958 resources_match (rs
, idesc
, note
, qp_regno
, path
)
6960 struct ia64_opcode
*idesc
;
6965 struct rsrc specs
[MAX_SPECS
];
6968 /* If the marked resource's qp_regno and the given qp_regno are mutex,
6969 we don't need to check. One exception is note 11, which indicates that
6970 target predicates are written regardless of PR[qp]. */
6971 if (qp_mutex (rs
->qp_regno
, qp_regno
, path
)
6975 count
= specify_resource (rs
->dependency
, idesc
, DV_CHK
, specs
, note
, path
);
6978 /* UNAT checking is a bit more specific than other resources */
6979 if (rs
->dependency
->specifier
== IA64_RS_AR_UNAT
6980 && specs
[count
].mem_offset
.hint
6981 && rs
->mem_offset
.hint
)
6983 if (rs
->mem_offset
.base
== specs
[count
].mem_offset
.base
)
6985 if (((rs
->mem_offset
.offset
>> 3) & 0x3F) ==
6986 ((specs
[count
].mem_offset
.offset
>> 3) & 0x3F))
6993 /* If either resource is not specific, conservatively assume a conflict
6995 if (!specs
[count
].specific
|| !rs
->specific
)
6997 else if (specs
[count
].index
== rs
->index
)
7002 fprintf (stderr
, " No %s conflicts\n", rs
->dependency
->name
);
7008 /* Indicate an instruction group break; if INSERT_STOP is non-zero, then
7009 insert a stop to create the break. Update all resource dependencies
7010 appropriately. If QP_REGNO is non-zero, only apply the break to resources
7011 which use the same QP_REGNO and have the link_to_qp_branch flag set.
7012 If SAVE_CURRENT is non-zero, don't affect resources marked by the current
7017 insn_group_break (insert_stop
, qp_regno
, save_current
)
7024 if (insert_stop
&& md
.num_slots_in_use
> 0)
7025 PREV_SLOT
.end_of_insn_group
= 1;
7029 fprintf (stderr
, " Insn group break%s",
7030 (insert_stop
? " (w/stop)" : ""));
7032 fprintf (stderr
, " effective for QP=%d", qp_regno
);
7033 fprintf (stderr
, "\n");
7037 while (i
< regdepslen
)
7039 const struct ia64_dependency
*dep
= regdeps
[i
].dependency
;
7042 && regdeps
[i
].qp_regno
!= qp_regno
)
7049 && CURR_SLOT
.src_file
== regdeps
[i
].file
7050 && CURR_SLOT
.src_line
== regdeps
[i
].line
)
7056 /* clear dependencies which are automatically cleared by a stop, or
7057 those that have reached the appropriate state of insn serialization */
7058 if (dep
->semantics
== IA64_DVS_IMPLIED
7059 || dep
->semantics
== IA64_DVS_IMPLIEDF
7060 || regdeps
[i
].insn_srlz
== STATE_SRLZ
)
7062 print_dependency ("Removing", i
);
7063 regdeps
[i
] = regdeps
[--regdepslen
];
7067 if (dep
->semantics
== IA64_DVS_DATA
7068 || dep
->semantics
== IA64_DVS_INSTR
7069 || dep
->semantics
== IA64_DVS_SPECIFIC
)
7071 if (regdeps
[i
].insn_srlz
== STATE_NONE
)
7072 regdeps
[i
].insn_srlz
= STATE_STOP
;
7073 if (regdeps
[i
].data_srlz
== STATE_NONE
)
7074 regdeps
[i
].data_srlz
= STATE_STOP
;
7081 /* Add the given resource usage spec to the list of active dependencies */
7083 mark_resource (idesc
, dep
, spec
, depind
, path
)
7084 struct ia64_opcode
*idesc
;
7085 const struct ia64_dependency
*dep
;
7090 if (regdepslen
== regdepstotlen
)
7092 regdepstotlen
+= 20;
7093 regdeps
= (struct rsrc
*)
7094 xrealloc ((void *)regdeps
,
7095 regdepstotlen
* sizeof(struct rsrc
));
7098 regdeps
[regdepslen
] = *spec
;
7099 regdeps
[regdepslen
].depind
= depind
;
7100 regdeps
[regdepslen
].path
= path
;
7101 regdeps
[regdepslen
].file
= CURR_SLOT
.src_file
;
7102 regdeps
[regdepslen
].line
= CURR_SLOT
.src_line
;
7104 print_dependency ("Adding", regdepslen
);
7110 print_dependency (action
, depind
)
7116 fprintf (stderr
, " %s %s '%s'",
7117 action
, dv_mode
[(regdeps
[depind
].dependency
)->mode
],
7118 (regdeps
[depind
].dependency
)->name
);
7119 if (regdeps
[depind
].specific
&& regdeps
[depind
].index
!= 0)
7120 fprintf (stderr
, " (%d)", regdeps
[depind
].index
);
7121 if (regdeps
[depind
].mem_offset
.hint
)
7122 fprintf (stderr
, " 0x%llx+0x%llx",
7123 regdeps
[depind
].mem_offset
.base
,
7124 regdeps
[depind
].mem_offset
.offset
);
7125 fprintf (stderr
, "\n");
7130 instruction_serialization ()
7134 fprintf (stderr
, " Instruction serialization\n");
7135 for (i
=0;i
< regdepslen
;i
++)
7136 if (regdeps
[i
].insn_srlz
== STATE_STOP
)
7137 regdeps
[i
].insn_srlz
= STATE_SRLZ
;
7141 data_serialization ()
7145 fprintf (stderr
, " Data serialization\n");
7146 while (i
< regdepslen
)
7148 if (regdeps
[i
].data_srlz
== STATE_STOP
7149 /* Note: as of 991210, all "other" dependencies are cleared by a
7150 data serialization. This might change with new tables */
7151 || (regdeps
[i
].dependency
)->semantics
== IA64_DVS_OTHER
)
7153 print_dependency ("Removing", i
);
7154 regdeps
[i
] = regdeps
[--regdepslen
];
7161 /* Insert stops and serializations as needed to avoid DVs */
7163 remove_marked_resource (rs
)
7166 switch (rs
->dependency
->semantics
)
7168 case IA64_DVS_SPECIFIC
:
7170 fprintf (stderr
, "Implementation-specific, assume worst case...\n");
7171 /* ...fall through... */
7172 case IA64_DVS_INSTR
:
7174 fprintf (stderr
, "Inserting instr serialization\n");
7175 if (rs
->insn_srlz
< STATE_STOP
)
7176 insn_group_break (1, 0, 0);
7177 if (rs
->insn_srlz
< STATE_SRLZ
)
7179 int oldqp
= CURR_SLOT
.qp_regno
;
7180 struct ia64_opcode
*oldidesc
= CURR_SLOT
.idesc
;
7181 /* Manually jam a srlz.i insn into the stream */
7182 CURR_SLOT
.qp_regno
= 0;
7183 CURR_SLOT
.idesc
= ia64_find_opcode ("srlz.i");
7184 instruction_serialization ();
7185 md
.curr_slot
= (md
.curr_slot
+ 1) % NUM_SLOTS
;
7186 if (++md
.num_slots_in_use
>= NUM_SLOTS
)
7188 CURR_SLOT
.qp_regno
= oldqp
;
7189 CURR_SLOT
.idesc
= oldidesc
;
7191 insn_group_break (1, 0, 0);
7193 case IA64_DVS_OTHER
: /* as of rev2 (991220) of the DV tables, all
7194 "other" types of DV are eliminated
7195 by a data serialization */
7198 fprintf (stderr
, "Inserting data serialization\n");
7199 if (rs
->data_srlz
< STATE_STOP
)
7200 insn_group_break (1, 0, 0);
7202 int oldqp
= CURR_SLOT
.qp_regno
;
7203 struct ia64_opcode
*oldidesc
= CURR_SLOT
.idesc
;
7204 /* Manually jam a srlz.d insn into the stream */
7205 CURR_SLOT
.qp_regno
= 0;
7206 CURR_SLOT
.idesc
= ia64_find_opcode ("srlz.d");
7207 data_serialization ();
7208 md
.curr_slot
= (md
.curr_slot
+ 1) % NUM_SLOTS
;
7209 if (++md
.num_slots_in_use
>= NUM_SLOTS
)
7211 CURR_SLOT
.qp_regno
= oldqp
;
7212 CURR_SLOT
.idesc
= oldidesc
;
7215 case IA64_DVS_IMPLIED
:
7216 case IA64_DVS_IMPLIEDF
:
7218 fprintf (stderr
, "Inserting stop\n");
7219 insn_group_break (1, 0, 0);
7226 /* Check the resources used by the given opcode against the current dependency
7229 The check is run once for each execution path encountered. In this case,
7230 a unique execution path is the sequence of instructions following a code
7231 entry point, e.g. the following has three execution paths, one starting
7232 at L0, one at L1, and one at L2.
7240 check_dependencies (idesc
)
7241 struct ia64_opcode
*idesc
;
7243 const struct ia64_opcode_dependency
*opdeps
= idesc
->dependencies
;
7247 /* Note that the number of marked resources may change within the
7248 loop if in auto mode. */
7250 while (i
< regdepslen
)
7252 struct rsrc
*rs
= ®deps
[i
];
7253 const struct ia64_dependency
*dep
= rs
->dependency
;
7258 if (dep
->semantics
== IA64_DVS_NONE
7259 || (chkind
= depends_on (rs
->depind
, idesc
)) == -1)
7264 note
= NOTE(opdeps
->chks
[chkind
]);
7266 /* Check this resource against each execution path seen thus far */
7267 for (path
=0;path
<= md
.path
;path
++)
7271 /* If the dependency wasn't on the path being checked, ignore it */
7272 if (rs
->path
< path
)
7275 /* If the QP for this insn implies a QP which has branched, don't
7276 bother checking. Ed. NOTE: I don't think this check is terribly
7277 useful; what's the point of generating code which will only be
7278 reached if its QP is zero?
7279 This code was specifically inserted to handle the following code,
7280 based on notes from Intel's DV checking code, where p1 implies p2.
7287 if (CURR_SLOT
.qp_regno
!= 0)
7291 for (implies
=0;implies
< qp_implieslen
;implies
++)
7293 if (qp_implies
[implies
].path
>= path
7294 && qp_implies
[implies
].p1
== CURR_SLOT
.qp_regno
7295 && qp_implies
[implies
].p2_branched
)
7305 if ((matchtype
= resources_match (rs
, idesc
, note
,
7306 CURR_SLOT
.qp_regno
, path
)) != 0)
7309 char pathmsg
[256] = "";
7310 char indexmsg
[256] = "";
7311 int certain
= (matchtype
== 1 && CURR_SLOT
.qp_regno
== 0);
7314 sprintf (pathmsg
, " when entry is at label '%s'",
7315 md
.entry_labels
[path
-1]);
7316 if (rs
->specific
&& rs
->index
!= 0)
7317 sprintf (indexmsg
, ", specific resource number is %d",
7319 sprintf (msg
, "Use of '%s' %s %s dependency '%s' (%s)%s%s",
7321 (certain
? "violates" : "may violate"),
7322 dv_mode
[dep
->mode
], dep
->name
,
7323 dv_sem
[dep
->semantics
],
7326 if (md
.explicit_mode
)
7328 as_warn ("%s", msg
);
7330 as_warn (_("Only the first path encountering the conflict "
7332 as_warn_where (rs
->file
, rs
->line
,
7333 _("This is the location of the "
7334 "conflicting usage"));
7335 /* Don't bother checking other paths, to avoid duplicating
7342 fprintf(stderr
, "%s @ %s:%d\n", msg
, rs
->file
, rs
->line
);
7344 remove_marked_resource (rs
);
7346 /* since the set of dependencies has changed, start over */
7347 /* FIXME -- since we're removing dvs as we go, we
7348 probably don't really need to start over... */
7361 /* register new dependencies based on the given opcode */
7363 mark_resources (idesc
)
7364 struct ia64_opcode
*idesc
;
7367 const struct ia64_opcode_dependency
*opdeps
= idesc
->dependencies
;
7368 int add_only_qp_reads
= 0;
7370 /* A conditional branch only uses its resources if it is taken; if it is
7371 taken, we stop following that path. The other branch types effectively
7372 *always* write their resources. If it's not taken, register only QP
7374 if (is_conditional_branch (idesc
) || is_interruption_or_rfi (idesc
))
7376 add_only_qp_reads
= 1;
7380 fprintf (stderr
, "Registering '%s' resource usage\n", idesc
->name
);
7382 for (i
=0;i
< opdeps
->nregs
;i
++)
7384 const struct ia64_dependency
*dep
;
7385 struct rsrc specs
[MAX_SPECS
];
7390 dep
= ia64_find_dependency (opdeps
->regs
[i
]);
7391 note
= NOTE(opdeps
->regs
[i
]);
7393 if (add_only_qp_reads
7394 && !(dep
->mode
== IA64_DV_WAR
7395 && (dep
->specifier
== IA64_RS_PR
7396 || dep
->specifier
== IA64_RS_PR63
)))
7399 count
= specify_resource (dep
, idesc
, DV_REG
, specs
, note
, md
.path
);
7402 if (md
.debug_dv
&& !count
)
7403 fprintf (stderr
, " No %s %s usage found (path %d)\n",
7404 dv_mode
[dep
->mode
], dep
->name
, md
.path
);
7409 mark_resource (idesc
, dep
, &specs
[count
],
7410 DEP(opdeps
->regs
[i
]), md
.path
);
7413 /* The execution path may affect register values, which may in turn
7414 affect which indirect-access resources are accessed. */
7415 switch (dep
->specifier
)
7427 for (path
=0;path
< md
.path
;path
++)
7429 count
= specify_resource (dep
, idesc
, DV_REG
, specs
, note
, path
);
7431 mark_resource (idesc
, dep
, &specs
[count
],
7432 DEP(opdeps
->regs
[i
]), path
);
7439 /* remove dependencies when they no longer apply */
7441 update_dependencies (idesc
)
7442 struct ia64_opcode
*idesc
;
7446 if (strcmp (idesc
->name
, "srlz.i") == 0)
7448 instruction_serialization ();
7450 else if (strcmp (idesc
->name
, "srlz.d") == 0)
7452 data_serialization ();
7454 else if (is_interruption_or_rfi (idesc
)
7455 || is_taken_branch (idesc
))
7457 /* although technically the taken branch doesn't clear dependencies
7458 which require a srlz.[id], we don't follow the branch; the next
7459 instruction is assumed to start with a clean slate */
7461 clear_register_values ();
7462 clear_qp_mutex (~(valueT
)0);
7463 clear_qp_implies (~(valueT
)0, ~(valueT
)0);
7466 else if (is_conditional_branch (idesc
)
7467 && CURR_SLOT
.qp_regno
!= 0)
7469 int is_call
= strstr (idesc
->name
, ".call") != NULL
;
7471 for (i
=0;i
< qp_implieslen
;i
++)
7473 /* if the conditional branch's predicate is implied by the predicate
7474 in an existing dependency, remove that dependency */
7475 if (qp_implies
[i
].p2
== CURR_SLOT
.qp_regno
)
7478 /* note that this implied predicate takes a branch so that if
7479 a later insn generates a DV but its predicate implies this
7480 one, we can avoid the false DV warning */
7481 qp_implies
[i
].p2_branched
= 1;
7482 while (depind
< regdepslen
)
7484 if (regdeps
[depind
].qp_regno
== qp_implies
[i
].p1
)
7486 print_dependency ("Removing", depind
);
7487 regdeps
[depind
] = regdeps
[--regdepslen
];
7494 /* Any marked resources which have this same predicate should be
7495 cleared, provided that the QP hasn't been modified between the
7496 marking instruction and the branch.
7500 insn_group_break (0, CURR_SLOT
.qp_regno
, 1);
7505 while (i
< regdepslen
)
7507 if (regdeps
[i
].qp_regno
== CURR_SLOT
.qp_regno
7508 && regdeps
[i
].link_to_qp_branch
7509 && (regdeps
[i
].file
!= CURR_SLOT
.src_file
7510 || regdeps
[i
].line
!= CURR_SLOT
.src_line
))
7512 /* Treat like a taken branch */
7513 print_dependency ("Removing", i
);
7514 regdeps
[i
] = regdeps
[--regdepslen
];
7523 /* Examine the current instruction for dependency violations. */
7526 struct ia64_opcode
*idesc
;
7530 fprintf (stderr
, "Checking %s for violations (line %d, %d/%d)\n",
7531 idesc
->name
, CURR_SLOT
.src_line
,
7532 idesc
->dependencies
->nchks
,
7533 idesc
->dependencies
->nregs
);
7536 /* Look through the list of currently marked resources; if the current
7537 instruction has the dependency in its chks list which uses that resource,
7538 check against the specific resources used.
7540 check_dependencies (idesc
);
7543 Look up the instruction's regdeps (RAW writes, WAW writes, and WAR reads),
7544 then add them to the list of marked resources.
7546 mark_resources (idesc
);
7548 /* There are several types of dependency semantics, and each has its own
7549 requirements for being cleared
7551 Instruction serialization (insns separated by interruption, rfi, or
7552 writer + srlz.i + reader, all in separate groups) clears DVS_INSTR.
7554 Data serialization (instruction serialization, or writer + srlz.d +
7555 reader, where writer and srlz.d are in separate groups) clears
7556 DVS_DATA. (This also clears DVS_OTHER, but that is not guaranteed to
7557 always be the case).
7559 Instruction group break (groups separated by stop, taken branch,
7560 interruption or rfi) clears DVS_IMPLIED and DVS_IMPLIEDF.
7562 update_dependencies (idesc
);
7564 /* Sometimes, knowing a register value allows us to avoid giving a false DV
7565 warning. Keep track of as many as possible that are useful. */
7566 note_register_values (idesc
);
7568 /* We don't need or want this anymore. */
7569 md
.mem_offset
.hint
= 0;
7574 /* Translate one line of assembly. Pseudo ops and labels do not show
7580 char *saved_input_line_pointer
, *mnemonic
;
7581 const struct pseudo_opcode
*pdesc
;
7582 struct ia64_opcode
*idesc
;
7583 unsigned char qp_regno
;
7587 saved_input_line_pointer
= input_line_pointer
;
7588 input_line_pointer
= str
;
7590 /* extract the opcode (mnemonic): */
7592 mnemonic
= input_line_pointer
;
7593 ch
= get_symbol_end ();
7594 pdesc
= (struct pseudo_opcode
*) hash_find (md
.pseudo_hash
, mnemonic
);
7597 *input_line_pointer
= ch
;
7598 (*pdesc
->handler
) (pdesc
->arg
);
7602 /* find the instruction descriptor matching the arguments: */
7604 idesc
= ia64_find_opcode (mnemonic
);
7605 *input_line_pointer
= ch
;
7608 as_bad ("Unknown opcode `%s'", mnemonic
);
7612 idesc
= parse_operands (idesc
);
7616 /* Handle the dynamic ops we can handle now: */
7617 if (idesc
->type
== IA64_TYPE_DYN
)
7619 if (strcmp (idesc
->name
, "add") == 0)
7621 if (CURR_SLOT
.opnd
[2].X_op
== O_register
7622 && CURR_SLOT
.opnd
[2].X_add_number
< 4)
7626 idesc
= ia64_find_opcode (mnemonic
);
7628 know (!idesc
->next
);
7631 else if (strcmp (idesc
->name
, "mov") == 0)
7633 enum ia64_opnd opnd1
, opnd2
;
7636 opnd1
= idesc
->operands
[0];
7637 opnd2
= idesc
->operands
[1];
7638 if (opnd1
== IA64_OPND_AR3
)
7640 else if (opnd2
== IA64_OPND_AR3
)
7644 if (CURR_SLOT
.opnd
[rop
].X_op
== O_register
7645 && ar_is_in_integer_unit (CURR_SLOT
.opnd
[rop
].X_add_number
))
7649 idesc
= ia64_find_opcode (mnemonic
);
7650 while (idesc
!= NULL
7651 && (idesc
->operands
[0] != opnd1
7652 || idesc
->operands
[1] != opnd2
))
7653 idesc
= get_next_opcode (idesc
);
7658 if (md
.qp
.X_op
== O_register
)
7659 qp_regno
= md
.qp
.X_add_number
- REG_P
;
7661 flags
= idesc
->flags
;
7663 if ((flags
& IA64_OPCODE_FIRST
) != 0)
7664 insn_group_break (1, 0, 0);
7666 if ((flags
& IA64_OPCODE_NO_PRED
) != 0 && qp_regno
!= 0)
7668 as_bad ("`%s' cannot be predicated", idesc
->name
);
7672 /* build the instruction: */
7673 CURR_SLOT
.qp_regno
= qp_regno
;
7674 CURR_SLOT
.idesc
= idesc
;
7675 as_where (&CURR_SLOT
.src_file
, &CURR_SLOT
.src_line
);
7676 if (debug_type
== DEBUG_DWARF2
)
7677 dwarf2_where (&CURR_SLOT
.debug_line
);
7679 /* Add unwind entry, if there is one. */
7680 if (current_unwind_entry
)
7682 CURR_SLOT
.unwind_record
= current_unwind_entry
;
7683 current_unwind_entry
= NULL
;
7686 /* check for dependency violations */
7690 md
.curr_slot
= (md
.curr_slot
+ 1) % NUM_SLOTS
;
7691 if (++md
.num_slots_in_use
>= NUM_SLOTS
)
7694 if ((flags
& IA64_OPCODE_LAST
) != 0)
7695 insn_group_break (1, 0, 0);
7697 md
.last_text_seg
= now_seg
;
7700 input_line_pointer
= saved_input_line_pointer
;
7703 /* Called when symbol NAME cannot be found in the symbol table.
7704 Should be used for dynamic valued symbols only. */
7706 md_undefined_symbol (name
)
7712 /* Called for any expression that can not be recognized. When the
7713 function is called, `input_line_pointer' will point to the start of
7719 enum pseudo_type pseudo_type
;
7723 switch (*input_line_pointer
)
7726 /* find what relocation pseudo-function we're dealing with: */
7728 ch
= *++input_line_pointer
;
7729 for (i
= 0; i
< NELEMS (pseudo_func
); ++i
)
7730 if (pseudo_func
[i
].name
&& pseudo_func
[i
].name
[0] == ch
)
7732 len
= strlen (pseudo_func
[i
].name
);
7733 if (strncmp (pseudo_func
[i
].name
+ 1,
7734 input_line_pointer
+ 1, len
- 1) == 0
7735 && !is_part_of_name (input_line_pointer
[len
]))
7737 input_line_pointer
+= len
;
7738 pseudo_type
= pseudo_func
[i
].type
;
7742 switch (pseudo_type
)
7744 case PSEUDO_FUNC_RELOC
:
7746 if (*input_line_pointer
!= '(')
7748 as_bad ("Expected '('");
7751 ++input_line_pointer
; /* skip '(' */
7753 if (*input_line_pointer
++ != ')')
7755 as_bad ("Missing ')'");
7758 if (e
->X_op
!= O_symbol
)
7760 if (e
->X_op
!= O_pseudo_fixup
)
7762 as_bad ("Not a symbolic expression");
7765 if (S_GET_VALUE (e
->X_op_symbol
) == FUNC_FPTR_RELATIVE
7766 && i
== FUNC_LT_RELATIVE
)
7767 i
= FUNC_LT_FPTR_RELATIVE
;
7770 as_bad ("Illegal combination of relocation functions");
7774 /* make sure gas doesn't get rid of local symbols that are used
7776 e
->X_op
= O_pseudo_fixup
;
7777 e
->X_op_symbol
= pseudo_func
[i
].u
.sym
;
7780 case PSEUDO_FUNC_CONST
:
7781 e
->X_op
= O_constant
;
7782 e
->X_add_number
= pseudo_func
[i
].u
.ival
;
7786 as_bad ("Unknown pseudo function `%s'", input_line_pointer
- 1);
7792 ++input_line_pointer
;
7794 if (*input_line_pointer
!= ']')
7796 as_bad ("Closing bracket misssing");
7801 if (e
->X_op
!= O_register
)
7802 as_bad ("Register expected as index");
7804 ++input_line_pointer
;
7815 ignore_rest_of_line ();
7818 /* Return 1 if it's OK to adjust a reloc by replacing the symbol with
7819 a section symbol plus some offset. For relocs involving @fptr(),
7820 directives we don't want such adjustments since we need to have the
7821 original symbol's name in the reloc. */
7823 ia64_fix_adjustable (fix
)
7826 /* Prevent all adjustments to global symbols */
7827 if (S_IS_EXTERN (fix
->fx_addsy
) || S_IS_WEAK (fix
->fx_addsy
))
7830 switch (fix
->fx_r_type
)
7832 case BFD_RELOC_IA64_FPTR64I
:
7833 case BFD_RELOC_IA64_FPTR32MSB
:
7834 case BFD_RELOC_IA64_FPTR32LSB
:
7835 case BFD_RELOC_IA64_FPTR64MSB
:
7836 case BFD_RELOC_IA64_FPTR64LSB
:
7837 case BFD_RELOC_IA64_LTOFF_FPTR22
:
7838 case BFD_RELOC_IA64_LTOFF_FPTR64I
:
7848 ia64_force_relocation (fix
)
7851 switch (fix
->fx_r_type
)
7853 case BFD_RELOC_IA64_FPTR64I
:
7854 case BFD_RELOC_IA64_FPTR32MSB
:
7855 case BFD_RELOC_IA64_FPTR32LSB
:
7856 case BFD_RELOC_IA64_FPTR64MSB
:
7857 case BFD_RELOC_IA64_FPTR64LSB
:
7859 case BFD_RELOC_IA64_LTOFF22
:
7860 case BFD_RELOC_IA64_LTOFF64I
:
7861 case BFD_RELOC_IA64_LTOFF_FPTR22
:
7862 case BFD_RELOC_IA64_LTOFF_FPTR64I
:
7863 case BFD_RELOC_IA64_PLTOFF22
:
7864 case BFD_RELOC_IA64_PLTOFF64I
:
7865 case BFD_RELOC_IA64_PLTOFF64MSB
:
7866 case BFD_RELOC_IA64_PLTOFF64LSB
:
7875 /* Decide from what point a pc-relative relocation is relative to,
7876 relative to the pc-relative fixup. Er, relatively speaking. */
7878 ia64_pcrel_from_section (fix
, sec
)
7882 unsigned long off
= fix
->fx_frag
->fr_address
+ fix
->fx_where
;
7884 if (bfd_get_section_flags (stdoutput
, sec
) & SEC_CODE
)
7890 /* This is called whenever some data item (not an instruction) needs a
7891 fixup. We pick the right reloc code depending on the byteorder
7892 currently in effect. */
7894 ia64_cons_fix_new (f
, where
, nbytes
, exp
)
7900 bfd_reloc_code_real_type code
;
7905 /* There are no reloc for 8 and 16 bit quantities, but we allow
7906 them here since they will work fine as long as the expression
7907 is fully defined at the end of the pass over the source file. */
7908 case 1: code
= BFD_RELOC_8
; break;
7909 case 2: code
= BFD_RELOC_16
; break;
7911 if (target_big_endian
)
7912 code
= BFD_RELOC_IA64_DIR32MSB
;
7914 code
= BFD_RELOC_IA64_DIR32LSB
;
7918 if (target_big_endian
)
7919 code
= BFD_RELOC_IA64_DIR64MSB
;
7921 code
= BFD_RELOC_IA64_DIR64LSB
;
7925 as_bad ("Unsupported fixup size %d", nbytes
);
7926 ignore_rest_of_line ();
7929 if (exp
->X_op
== O_pseudo_fixup
)
7932 exp
->X_op
= O_symbol
;
7933 code
= ia64_gen_real_reloc_type (exp
->X_op_symbol
, code
);
7935 fix
= fix_new_exp (f
, where
, nbytes
, exp
, 0, code
);
7936 /* We need to store the byte order in effect in case we're going
7937 to fix an 8 or 16 bit relocation (for which there no real
7938 relocs available). See md_apply_fix(). */
7939 fix
->tc_fix_data
.bigendian
= target_big_endian
;
7942 /* Return the actual relocation we wish to associate with the pseudo
7943 reloc described by SYM and R_TYPE. SYM should be one of the
7944 symbols in the pseudo_func array, or NULL. */
7946 static bfd_reloc_code_real_type
7947 ia64_gen_real_reloc_type (sym
, r_type
)
7949 bfd_reloc_code_real_type r_type
;
7951 bfd_reloc_code_real_type
new = 0;
7958 switch (S_GET_VALUE (sym
))
7960 case FUNC_FPTR_RELATIVE
:
7963 case BFD_RELOC_IA64_IMM64
: new = BFD_RELOC_IA64_FPTR64I
; break;
7964 case BFD_RELOC_IA64_DIR32MSB
: new = BFD_RELOC_IA64_FPTR32MSB
; break;
7965 case BFD_RELOC_IA64_DIR32LSB
: new = BFD_RELOC_IA64_FPTR32LSB
; break;
7966 case BFD_RELOC_IA64_DIR64MSB
: new = BFD_RELOC_IA64_FPTR64MSB
; break;
7967 case BFD_RELOC_IA64_DIR64LSB
: new = BFD_RELOC_IA64_FPTR64LSB
; break;
7972 case FUNC_GP_RELATIVE
:
7975 case BFD_RELOC_IA64_IMM22
: new = BFD_RELOC_IA64_GPREL22
; break;
7976 case BFD_RELOC_IA64_IMM64
: new = BFD_RELOC_IA64_GPREL64I
; break;
7977 case BFD_RELOC_IA64_DIR32MSB
: new = BFD_RELOC_IA64_GPREL32MSB
; break;
7978 case BFD_RELOC_IA64_DIR32LSB
: new = BFD_RELOC_IA64_GPREL32LSB
; break;
7979 case BFD_RELOC_IA64_DIR64MSB
: new = BFD_RELOC_IA64_GPREL64MSB
; break;
7980 case BFD_RELOC_IA64_DIR64LSB
: new = BFD_RELOC_IA64_GPREL64LSB
; break;
7985 case FUNC_LT_RELATIVE
:
7988 case BFD_RELOC_IA64_IMM22
: new = BFD_RELOC_IA64_LTOFF22
; break;
7989 case BFD_RELOC_IA64_IMM64
: new = BFD_RELOC_IA64_LTOFF64I
; break;
7994 case FUNC_PC_RELATIVE
:
7997 case BFD_RELOC_IA64_IMM22
: new = BFD_RELOC_IA64_PCREL22
; break;
7998 case BFD_RELOC_IA64_IMM64
: new = BFD_RELOC_IA64_PCREL64I
; break;
7999 case BFD_RELOC_IA64_DIR32MSB
: new = BFD_RELOC_IA64_PCREL32MSB
; break;
8000 case BFD_RELOC_IA64_DIR32LSB
: new = BFD_RELOC_IA64_PCREL32LSB
; break;
8001 case BFD_RELOC_IA64_DIR64MSB
: new = BFD_RELOC_IA64_PCREL64MSB
; break;
8002 case BFD_RELOC_IA64_DIR64LSB
: new = BFD_RELOC_IA64_PCREL64LSB
; break;
8007 case FUNC_PLT_RELATIVE
:
8010 case BFD_RELOC_IA64_IMM22
: new = BFD_RELOC_IA64_PLTOFF22
; break;
8011 case BFD_RELOC_IA64_IMM64
: new = BFD_RELOC_IA64_PLTOFF64I
; break;
8012 case BFD_RELOC_IA64_DIR64MSB
: new = BFD_RELOC_IA64_PLTOFF64MSB
;break;
8013 case BFD_RELOC_IA64_DIR64LSB
: new = BFD_RELOC_IA64_PLTOFF64LSB
;break;
8018 case FUNC_SEC_RELATIVE
:
8021 case BFD_RELOC_IA64_DIR32MSB
: new = BFD_RELOC_IA64_SECREL32MSB
;break;
8022 case BFD_RELOC_IA64_DIR32LSB
: new = BFD_RELOC_IA64_SECREL32LSB
;break;
8023 case BFD_RELOC_IA64_DIR64MSB
: new = BFD_RELOC_IA64_SECREL64MSB
;break;
8024 case BFD_RELOC_IA64_DIR64LSB
: new = BFD_RELOC_IA64_SECREL64LSB
;break;
8029 case FUNC_SEG_RELATIVE
:
8032 case BFD_RELOC_IA64_DIR32MSB
: new = BFD_RELOC_IA64_SEGREL32MSB
;break;
8033 case BFD_RELOC_IA64_DIR32LSB
: new = BFD_RELOC_IA64_SEGREL32LSB
;break;
8034 case BFD_RELOC_IA64_DIR64MSB
: new = BFD_RELOC_IA64_SEGREL64MSB
;break;
8035 case BFD_RELOC_IA64_DIR64LSB
: new = BFD_RELOC_IA64_SEGREL64LSB
;break;
8040 case FUNC_LTV_RELATIVE
:
8043 case BFD_RELOC_IA64_DIR32MSB
: new = BFD_RELOC_IA64_LTV32MSB
; break;
8044 case BFD_RELOC_IA64_DIR32LSB
: new = BFD_RELOC_IA64_LTV32LSB
; break;
8045 case BFD_RELOC_IA64_DIR64MSB
: new = BFD_RELOC_IA64_LTV64MSB
; break;
8046 case BFD_RELOC_IA64_DIR64LSB
: new = BFD_RELOC_IA64_LTV64LSB
; break;
8051 case FUNC_LT_FPTR_RELATIVE
:
8054 case BFD_RELOC_IA64_IMM22
:
8055 new = BFD_RELOC_IA64_LTOFF_FPTR22
; break;
8056 case BFD_RELOC_IA64_IMM64
:
8057 new = BFD_RELOC_IA64_LTOFF_FPTR64I
; break;
8065 /* Hmmmm. Should this ever occur? */
8072 /* Here is where generate the appropriate reloc for pseudo relocation
8075 ia64_validate_fix (fix
)
8078 switch (fix
->fx_r_type
)
8080 case BFD_RELOC_IA64_FPTR64I
:
8081 case BFD_RELOC_IA64_FPTR32MSB
:
8082 case BFD_RELOC_IA64_FPTR64LSB
:
8083 case BFD_RELOC_IA64_LTOFF_FPTR22
:
8084 case BFD_RELOC_IA64_LTOFF_FPTR64I
:
8085 if (fix
->fx_offset
!= 0)
8086 as_bad_where (fix
->fx_file
, fix
->fx_line
,
8087 "No addend allowed in @fptr() relocation");
8097 fix_insn (fix
, odesc
, value
)
8099 const struct ia64_operand
*odesc
;
8102 bfd_vma insn
[3], t0
, t1
, control_bits
;
8107 slot
= fix
->fx_where
& 0x3;
8108 fixpos
= fix
->fx_frag
->fr_literal
+ (fix
->fx_where
- slot
);
8110 /* Bundles are always in little-endian byte order */
8111 t0
= bfd_getl64 (fixpos
);
8112 t1
= bfd_getl64 (fixpos
+ 8);
8113 control_bits
= t0
& 0x1f;
8114 insn
[0] = (t0
>> 5) & 0x1ffffffffffLL
;
8115 insn
[1] = ((t0
>> 46) & 0x3ffff) | ((t1
& 0x7fffff) << 18);
8116 insn
[2] = (t1
>> 23) & 0x1ffffffffffLL
;
8119 if (odesc
- elf64_ia64_operands
== IA64_OPND_IMMU64
)
8121 insn
[1] = (value
>> 22) & 0x1ffffffffffLL
;
8122 insn
[2] |= (((value
& 0x7f) << 13)
8123 | (((value
>> 7) & 0x1ff) << 27)
8124 | (((value
>> 16) & 0x1f) << 22)
8125 | (((value
>> 21) & 0x1) << 21)
8126 | (((value
>> 63) & 0x1) << 36));
8128 else if (odesc
- elf64_ia64_operands
== IA64_OPND_IMMU62
)
8130 if (value
& ~0x3fffffffffffffffULL
)
8131 err
= "integer operand out of range";
8132 insn
[1] = (value
>> 21) & 0x1ffffffffffLL
;
8133 insn
[2] |= (((value
& 0xfffff) << 6) | (((value
>> 20) & 0x1) << 36));
8135 else if (odesc
- elf64_ia64_operands
== IA64_OPND_TGT64
)
8138 insn
[1] = ((value
>> 20) & 0x7fffffffffLL
) << 2;
8139 insn
[2] |= ((((value
>> 59) & 0x1) << 36)
8140 | (((value
>> 0) & 0xfffff) << 13));
8143 err
= (*odesc
->insert
) (odesc
, value
, insn
+ slot
);
8146 as_bad_where (fix
->fx_file
, fix
->fx_line
, err
);
8148 t0
= control_bits
| (insn
[0] << 5) | (insn
[1] << 46);
8149 t1
= ((insn
[1] >> 18) & 0x7fffff) | (insn
[2] << 23);
8150 md_number_to_chars (fixpos
+ 0, t0
, 8);
8151 md_number_to_chars (fixpos
+ 8, t1
, 8);
8154 /* Attempt to simplify or even eliminate a fixup. The return value is
8155 ignored; perhaps it was once meaningful, but now it is historical.
8156 To indicate that a fixup has been eliminated, set FIXP->FX_DONE.
8158 If fixp->fx_addsy is non-NULL, we'll have to generate a reloc entry
8161 md_apply_fix3 (fix
, valuep
, seg
)
8167 valueT value
= *valuep
;
8170 fixpos
= fix
->fx_frag
->fr_literal
+ fix
->fx_where
;
8174 switch (fix
->fx_r_type
)
8176 case BFD_RELOC_IA64_DIR32MSB
:
8177 fix
->fx_r_type
= BFD_RELOC_IA64_PCREL32MSB
;
8181 case BFD_RELOC_IA64_DIR32LSB
:
8182 fix
->fx_r_type
= BFD_RELOC_IA64_PCREL32LSB
;
8186 case BFD_RELOC_IA64_DIR64MSB
:
8187 fix
->fx_r_type
= BFD_RELOC_IA64_PCREL64MSB
;
8191 case BFD_RELOC_IA64_DIR64LSB
:
8192 fix
->fx_r_type
= BFD_RELOC_IA64_PCREL64LSB
;
8202 switch (fix
->fx_r_type
)
8205 as_bad_where (fix
->fx_file
, fix
->fx_line
,
8206 "%s must have a constant value",
8207 elf64_ia64_operands
[fix
->tc_fix_data
.opnd
].desc
);
8214 /* ??? This is a hack copied from tc-i386.c to make PCREL relocs
8215 work. There should be a better way to handle this. */
8217 fix
->fx_offset
+= fix
->fx_where
+ fix
->fx_frag
->fr_address
;
8219 else if (fix
->tc_fix_data
.opnd
== IA64_OPND_NIL
)
8221 if (fix
->tc_fix_data
.bigendian
)
8222 number_to_chars_bigendian (fixpos
, value
, fix
->fx_size
);
8224 number_to_chars_littleendian (fixpos
, value
, fix
->fx_size
);
8230 fix_insn (fix
, elf64_ia64_operands
+ fix
->tc_fix_data
.opnd
, value
);
8237 /* Generate the BFD reloc to be stuck in the object file from the
8238 fixup used internally in the assembler. */
8240 tc_gen_reloc (sec
, fixp
)
8246 reloc
= xmalloc (sizeof (*reloc
));
8247 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
8248 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
8249 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
8250 reloc
->addend
= fixp
->fx_offset
;
8251 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
8255 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
8256 "Cannot represent %s relocation in object file",
8257 bfd_get_reloc_code_name (fixp
->fx_r_type
));
8262 /* Turn a string in input_line_pointer into a floating point constant
8263 of type type, and store the appropriate bytes in *lit. The number
8264 of LITTLENUMS emitted is stored in *size. An error message is
8265 returned, or NULL on OK. */
8267 #define MAX_LITTLENUMS 5
8270 md_atof (type
, lit
, size
)
8275 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
8276 LITTLENUM_TYPE
*word
;
8306 return "Bad call to MD_ATOF()";
8308 t
= atof_ieee (input_line_pointer
, type
, words
);
8310 input_line_pointer
= t
;
8311 *size
= prec
* sizeof (LITTLENUM_TYPE
);
8313 for (word
= words
+ prec
- 1; prec
--;)
8315 md_number_to_chars (lit
, (long) (*word
--), sizeof (LITTLENUM_TYPE
));
8316 lit
+= sizeof (LITTLENUM_TYPE
);
8321 /* Round up a section's size to the appropriate boundary. */
8323 md_section_align (seg
, size
)
8327 int align
= bfd_get_section_alignment (stdoutput
, seg
);
8328 valueT mask
= ((valueT
)1 << align
) - 1;
8330 return (size
+ mask
) & ~mask
;
8333 /* Handle ia64 specific semantics of the align directive. */
8336 ia64_md_do_align (n
, fill
, len
, max
)
8342 /* Fill any pending bundle with nops. */
8343 if (bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
)
8344 ia64_flush_insns ();
8346 /* When we align code in a text section, emit a bundle of 3 nops instead of
8347 zero bytes. We can only do this if a multiple of 16 bytes was requested.
8348 N is log base 2 of the requested alignment. */
8350 && bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
8353 /* Use mfi bundle of nops with no stop bits. */
8354 static const unsigned char be_nop
[]
8355 = { 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
8356 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c};
8357 static const unsigned char le_nop
[]
8358 = { 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
8359 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00};
8361 /* Make sure we are on a 16-byte boundary, in case someone has been
8362 putting data into a text section. */
8363 frag_align (4, 0, 0);
8365 if (target_big_endian
)
8366 frag_align_pattern (n
, be_nop
, 16, max
);
8368 frag_align_pattern (n
, le_nop
, 16, max
);