Back to index

cell-binutils  2.17cvs20070401
Classes | Defines | Typedefs | Enumerations | Functions | Variables
tc-hppa.c File Reference
#include "as.h"
#include "safe-ctype.h"
#include "subsegs.h"
#include "dw2gencfi.h"
#include "bfd/libhppa.h"
#include "opcode/hppa.h"

Go to the source code of this file.

Classes

struct  unwind_desc
struct  unwind_table
struct  call_info
struct  pa_it
struct  call_desc
struct  label_symbol_struct
struct  hppa_fix_struct
struct  pd_reg
struct  fp_cond_map
struct  selector_entry

Defines

#define DEFAULT_LEVEL   10
#define UNWIND_LOW32(U)
#define UNWIND_HIGH32(U)
#define FP_REG_BASE   64
#define FP_REG_RSEL   128
#define IS_R_SELECT(S)   (*(S) == 'R' || *(S) == 'r')
#define IS_L_SELECT(S)   (*(S) == 'L' || *(S) == 'l')
#define INSERT_FIELD_AND_CONTINUE(OPCODE, FIELD, START)
#define CHECK_FIELD(FIELD, HIGH, LOW, IGNORE)
#define CHECK_FIELD_WHERE(FIELD, HIGH, LOW, FILENAME, LINE)
#define CHECK_ALIGN(FIELD, ALIGN, IGNORE)
#define is_DP_relative(exp)
#define is_PC_relative(exp)
#define is_tls_gdidx(exp)
#define is_tls_ldidx(exp)
#define is_tls_dtpoff(exp)
#define is_tls_ieoff(exp)
#define is_tls_leoff(exp)
#define is_complex(exp)   ((exp).X_op != O_constant && (exp).X_op != O_symbol)
#define MAX_LITTLENUMS   6
#define arg_reloc_stub_needed(CALLER, CALLEE)   0
#define REG_NAME_CNT   (sizeof (pre_defined_registers) / sizeof (struct pd_reg))

Typedefs

typedef struct label_symbol_struct label_symbol_struct

Enumerations

enum  fp_operand_format {
  SGL, DBL, ILLEGAL_FMT, QUAD,
  W, UW, DW, UDW,
  QW, UQW
}
enum  pa_symbol_type {
  SYMBOL_TYPE_UNKNOWN, SYMBOL_TYPE_ABSOLUTE, SYMBOL_TYPE_CODE, SYMBOL_TYPE_DATA,
  SYMBOL_TYPE_ENTRY, SYMBOL_TYPE_MILLICODE, SYMBOL_TYPE_PLABEL, SYMBOL_TYPE_PRI_PROG,
  SYMBOL_TYPE_SEC_PROG
}

Functions

static void pa_text (int)
static void pa_data (int)
static void pa_comm (int)
void pa_check_eof (void)
static label_symbol_structpa_get_label (void)
void pa_define_label (symbolS *symbol)
static void pa_undefine_label (void)
static void fix_new_hppa (fragS *frag, int where, int size, symbolS *add_symbol, offsetT offset, expressionS *exp, int pcrel, bfd_reloc_code_real_type r_type, enum hppa_reloc_field_selector_type_alt r_field, int r_format, unsigned int arg_reloc, int unwind_bits ATTRIBUTE_UNUSED)
void cons_fix_new_hppa (fragS *frag, int where, int size, expressionS *exp)
static void get_expression (char *str)
static int pa_parse_nullif (char **s)
char * md_atof (int type, char *litP, int *sizeP)
void md_number_to_chars (char *buf, valueT val, int n)
arelent ** tc_gen_reloc (asection *section, fixS *fixp)
void md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, asection *sec ATTRIBUTE_UNUSED, fragS *fragP)
valueT md_section_align (asection *segment, valueT size)
int md_estimate_size_before_relax (fragS *fragP, asection *segment ATTRIBUTE_UNUSED)
int md_parse_option (int c, char *arg ATTRIBUTE_UNUSED)
void md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
symbolS * md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
void md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
long md_pcrel_from (fixS *fixP)
static int is_end_of_statement (void)
static int reg_name_search (char *name)
static int pa_parse_number (char **s, int is_float)
static int need_pa11_opcode (void)
static int pa_parse_fp_cmp_cond (char **s)
static int pa_parse_ftest_gfx_completer (char **s)
static fp_operand_format pa_parse_fp_cnv_format (char **s)
static fp_operand_format pa_parse_fp_format (char **s)
static int pa_chk_field_selector (char **str)
void parse_cons_expression_hppa (expressionS *exp)
static int evaluate_absolute (struct pa_it *insn)
static int pa_get_absolute_expression (struct pa_it *insn, char **strp)
static unsigned int pa_build_arg_reloc (char *type_name)
static unsigned int pa_align_arg_reloc (unsigned int reg, unsigned int arg_reloc)
static int pa_parse_nonneg_cmpsub_cmpltr (char **s)
static int pa_parse_neg_cmpsub_cmpltr (char **s)
static int pa_parse_cmpb_64_cmpltr (char **s)
static int pa_parse_cmpib_64_cmpltr (char **s)
static int pa_parse_nonneg_add_cmpltr (char **s)
static int pa_parse_neg_add_cmpltr (char **s)
static int pa_parse_addb_64_cmpltr (char **s)
static void pa_ip (char *str)
void md_assemble (char *str)
static void pa_block (int z ATTRIBUTE_UNUSED)
static void pa_brtab (int begin ATTRIBUTE_UNUSED)
static void pa_try (int begin ATTRIBUTE_UNUSED)
static void pa_call_args (struct call_desc *call_desc)
static void pa_call (int unused ATTRIBUTE_UNUSED)
static bfd_boolean is_same_frag (fragS *frag1, fragS *frag2)
static void pa_callinfo (int unused ATTRIBUTE_UNUSED)
static void pa_text (int unused ATTRIBUTE_UNUSED)
static void pa_data (int unused ATTRIBUTE_UNUSED)
static void pa_comm (int unused ATTRIBUTE_UNUSED)
static void pa_end (int unused ATTRIBUTE_UNUSED)
static void pa_enter (int unused ATTRIBUTE_UNUSED)
static void pa_entry (int unused ATTRIBUTE_UNUSED)
int hppa_force_reg_syms_absolute (expressionS *resultP, operatorT op ATTRIBUTE_UNUSED, expressionS *rightP)
static void pa_equ (int reg)
static void process_exit (void)
static void pa_exit (int unused ATTRIBUTE_UNUSED)
static void pa_type_args (symbolS *symbolP, int is_export)
static void pa_export (int unused ATTRIBUTE_UNUSED)
static void pa_import (int unused ATTRIBUTE_UNUSED)
static void pa_label (int unused ATTRIBUTE_UNUSED)
static void pa_leave (int unused ATTRIBUTE_UNUSED)
static void pa_level (int unused ATTRIBUTE_UNUSED)
static void pa_origin (int unused ATTRIBUTE_UNUSED)
static void pa_param (int unused ATTRIBUTE_UNUSED)
static void pa_proc (int unused ATTRIBUTE_UNUSED)
static void pa_procend (int unused ATTRIBUTE_UNUSED)
static unsigned int pa_stringer_aux (char *s)
static void pa_stringer (int append_zero)
static void pa_version (int unused ATTRIBUTE_UNUSED)
static void pa_copyright (int unused ATTRIBUTE_UNUSED)
static void pa_cons (int nbytes)
static void pa_float_cons (int float_type)
static void pa_fill (int unused ATTRIBUTE_UNUSED)
static void pa_lcomm (int needs_align)
static void pa_lsym (int unused ATTRIBUTE_UNUSED)
void md_begin (void)
int hppa_fix_adjustable (fixS *fixp)
int hppa_force_relocation (struct fix *fixp)

Variables

static struct call_infocall_info_root
static struct call_infolast_call_info
static struct call_desc
static struct hash_controlop_hash = NULL
const char hppa_symbol_chars [] = "*?=<>"
const char line_comment_chars [] = "#"
const char comment_chars [] = ";"
const char line_separator_chars [] = "!"
const char EXP_CHARS [] = "eE"
const char FLT_CHARS [] = "rRsSfFdDxXpP"
static struct pa_it
static char * expr_end
static int callinfo_found
static int within_entry_exit
static int within_procedure
static label_symbol_structlabel_symbols_rootp = NULL
static int hppa_field_selector
static int strict
static int pa_number
static int print_errors = 1
static struct pd_reg []
static struct fp_cond_map []
static struct selector_entry []
const char * md_shortopts = ""
size_t md_longopts_size = sizeof (md_longopts)
static int fudge_reg_expressions
const pseudo_typeS md_pseudo_table []

Class Documentation

struct unwind_desc

Definition at line 119 of file tc-hppa.c.

Class Members
unsigned int args_stored:1
unsigned int call_fr:5
unsigned int call_gr:5
unsigned int cannot_unwind:1
unsigned int cleanup_defined:1
unsigned int entry_fr:4
unsigned int entry_gr:5
unsigned int extn_ptr_defined:1
unsigned int frame_size:27
unsigned int hpe_interrupt_marker:1
unsigned int hpux_interrupt_marker:1
unsigned int millicode:1
unsigned int millicode_save_rest:1
unsigned int region_desc:2
unsigned int reserved:3
unsigned int save_rp:1
unsigned int save_rp_in_frame:1
unsigned int save_sp:1
unsigned int save_sr:2
struct unwind_table

Definition at line 168 of file tc-hppa.c.

Class Members
unsigned int end_offset
unsigned int start_offset
struct call_info

Definition at line 187 of file tc-hppa.c.

Collaboration diagram for call_info:
Class Members
struct call_info * ci_next
symbolS * end_symbol
symbolS * start_symbol
struct pa_it

Definition at line 230 of file tc-hppa.c.

Collaboration diagram for pa_it:
Class Members
unsigned int arg_reloc
expressionS exp
long field_selector
int format
fp_operand_format fpof1
fp_operand_format fpof2
unsigned long opcode
int pcrel
reloc_type reloc
int trunc
struct call_desc

Definition at line 284 of file tc-hppa.c.

Class Members
unsigned int arg_count
unsigned int arg_reloc
struct label_symbol_struct

Definition at line 433 of file tc-hppa.c.

Collaboration diagram for label_symbol_struct:
Class Members
struct symbol * lss_label
struct label_symbol_struct * lss_next
struct hppa_fix_struct

Definition at line 447 of file tc-hppa.c.

struct pd_reg

Definition at line 467 of file tc-hppa.c.

Class Members
char * name
char * pname
int value
struct fp_cond_map

Definition at line 475 of file tc-hppa.c.

Class Members
int cond
char * string
struct selector_entry

Definition at line 483 of file tc-hppa.c.

Class Members
int field_selector
char * prefix

Define Documentation

#define arg_reloc_stub_needed (   CALLER,
  CALLEE 
)    0

Definition at line 1759 of file tc-hppa.c.

#define CHECK_ALIGN (   FIELD,
  ALIGN,
  IGNORE 
)
Value:
{ \
    if ((FIELD) & ((ALIGN) - 1)) \
      { \
       if (! IGNORE) \
          as_bad (_("Field not properly aligned [%d] (%d)."), (ALIGN), \
                (int) (FIELD));\
        break; \
      } \
  }

Definition at line 1038 of file tc-hppa.c.

#define CHECK_FIELD (   FIELD,
  HIGH,
  LOW,
  IGNORE 
)
Value:
{ \
    if ((FIELD) > (HIGH) || (FIELD) < (LOW)) \
      { \
       if (! IGNORE) \
          as_bad (_("Field out of range [%d..%d] (%d)."), (LOW), (HIGH), \
                (int) (FIELD));\
        break; \
      } \
  }

Definition at line 1010 of file tc-hppa.c.

#define CHECK_FIELD_WHERE (   FIELD,
  HIGH,
  LOW,
  FILENAME,
  LINE 
)
Value:
{ \
    if ((FIELD) > (HIGH) || (FIELD) < (LOW)) \
      { \
        as_bad_where ((FILENAME), (LINE), \
                    _("Field out of range [%d..%d] (%d)."), (LOW), (HIGH), \
                    (int) (FIELD));\
        break; \
      } \
  }

Definition at line 1024 of file tc-hppa.c.

#define DEFAULT_LEVEL   10

Definition at line 112 of file tc-hppa.c.

#define FP_REG_BASE   64

Definition at line 628 of file tc-hppa.c.

#define FP_REG_RSEL   128

Definition at line 629 of file tc-hppa.c.

#define INSERT_FIELD_AND_CONTINUE (   OPCODE,
  FIELD,
  START 
)
Value:
{ \
    ((OPCODE) |= (FIELD) << (START)); \
    continue; \
  }

Definition at line 1001 of file tc-hppa.c.

#define is_complex (   exp)    ((exp).X_op != O_constant && (exp).X_op != O_symbol)

Definition at line 1080 of file tc-hppa.c.

#define is_DP_relative (   exp)
Value:
((exp).X_op == O_subtract                 \
   && strcmp (S_GET_NAME ((exp).X_op_symbol), "$global$") == 0)

Definition at line 1049 of file tc-hppa.c.

#define IS_L_SELECT (   S)    (*(S) == 'L' || *(S) == 'l')

Definition at line 996 of file tc-hppa.c.

#define is_PC_relative (   exp)
Value:
((exp).X_op == O_subtract                 \
   && strcmp (S_GET_NAME ((exp).X_op_symbol), "$PIC_pcrel$0") == 0)

Definition at line 1053 of file tc-hppa.c.

#define IS_R_SELECT (   S)    (*(S) == 'R' || *(S) == 'r')

Definition at line 995 of file tc-hppa.c.

#define is_tls_dtpoff (   exp)
Value:
((exp).X_op == O_subtract                 \
   && strcmp (S_GET_NAME ((exp).X_op_symbol), "$tls_dtpoff$") == 0)

Definition at line 1065 of file tc-hppa.c.

#define is_tls_gdidx (   exp)
Value:
((exp).X_op == O_subtract                 \
   && strcmp (S_GET_NAME ((exp).X_op_symbol), "$tls_gdidx$") == 0)

Definition at line 1057 of file tc-hppa.c.

#define is_tls_ieoff (   exp)
Value:
((exp).X_op == O_subtract                 \
   && strcmp (S_GET_NAME ((exp).X_op_symbol), "$tls_ieoff$") == 0)

Definition at line 1069 of file tc-hppa.c.

#define is_tls_ldidx (   exp)
Value:
((exp).X_op == O_subtract                 \
   && strcmp (S_GET_NAME ((exp).X_op_symbol), "$tls_ldidx$") == 0)

Definition at line 1061 of file tc-hppa.c.

#define is_tls_leoff (   exp)
Value:
((exp).X_op == O_subtract                 \
   && strcmp (S_GET_NAME ((exp).X_op_symbol), "$tls_leoff$") == 0)

Definition at line 1073 of file tc-hppa.c.

#define MAX_LITTLENUMS   6

Definition at line 1342 of file tc-hppa.c.

#define REG_NAME_CNT   (sizeof (pre_defined_registers) / sizeof (struct pd_reg))

Definition at line 2032 of file tc-hppa.c.

#define UNWIND_HIGH32 (   U)
Value:
(((U)->hpe_interrupt_marker << 31) \
   | ((U)->hpux_interrupt_marker << 30)   \
   | ((U)->frame_size << 0))

Definition at line 163 of file tc-hppa.c.

#define UNWIND_LOW32 (   U)
Value:
(((U)->cannot_unwind << 31)        \
   | ((U)->millicode << 30)        \
   | ((U)->millicode_save_rest << 29)     \
   | ((U)->region_desc << 27)             \
   | ((U)->save_sr << 25)          \
   | ((U)->entry_fr << 21)         \
   | ((U)->entry_gr << 16)         \
   | ((U)->args_stored << 15)             \
   | ((U)->call_fr << 10)          \
   | ((U)->call_gr << 5)           \
   | ((U)->save_sp << 4)           \
   | ((U)->save_rp << 3)           \
   | ((U)->save_rp_in_frame << 2)  \
   | ((U)->extn_ptr_defined << 1)  \
   | ((U)->cleanup_defined << 0))

Definition at line 146 of file tc-hppa.c.


Typedef Documentation


Enumeration Type Documentation

Enumerator:
SGL 
DBL 
ILLEGAL_FMT 
QUAD 
W 
UW 
DW 
UDW 
QW 
UQW 

Definition at line 205 of file tc-hppa.c.

  {
    SGL, DBL, ILLEGAL_FMT, QUAD, W, UW, DW, UDW, QW, UQW
  }
Enumerator:
SYMBOL_TYPE_UNKNOWN 
SYMBOL_TYPE_ABSOLUTE 
SYMBOL_TYPE_CODE 
SYMBOL_TYPE_DATA 
SYMBOL_TYPE_ENTRY 
SYMBOL_TYPE_MILLICODE 
SYMBOL_TYPE_PLABEL 
SYMBOL_TYPE_PRI_PROG 
SYMBOL_TYPE_SEC_PROG 

Definition at line 214 of file tc-hppa.c.


Function Documentation

void cons_fix_new_hppa ( fragS *  frag,
int  where,
int  size,
expressionS exp 
)

Definition at line 1249 of file tc-hppa.c.

{
  unsigned int rel_type;

  /* Get a base relocation type.  */
  if (is_DP_relative (*exp))
    rel_type = R_HPPA_GOTOFF;
  else if (is_PC_relative (*exp))
    rel_type = R_HPPA_PCREL_CALL;
#ifdef OBJ_ELF
  else if (is_tls_gdidx (*exp))
    rel_type = R_PARISC_TLS_GD21L;
  else if (is_tls_ldidx (*exp))
    rel_type = R_PARISC_TLS_LDM21L;
  else if (is_tls_dtpoff (*exp))
    rel_type = R_PARISC_TLS_LDO21L;
  else if (is_tls_ieoff (*exp))
    rel_type = R_PARISC_TLS_IE21L;
  else if (is_tls_leoff (*exp))
    rel_type = R_PARISC_TLS_LE21L;
#endif
  else if (is_complex (*exp))
    rel_type = R_HPPA_COMPLEX;
  else
    rel_type = R_HPPA;

  if (hppa_field_selector != e_psel && hppa_field_selector != e_fsel)
    {
      as_warn (_("Invalid field selector.  Assuming F%%."));
      hppa_field_selector = e_fsel;
    }

  fix_new_hppa (frag, where, size,
              (symbolS *) NULL, (offsetT) 0, exp, 0, rel_type,
              hppa_field_selector, size * 8, 0, 0);

  /* Reset field selector to its default state.  */
  hppa_field_selector = 0;
}

Here is the call graph for this function:

static int evaluate_absolute ( struct pa_it insn) [static]

Definition at line 2549 of file tc-hppa.c.

{
  offsetT value;
  expressionS exp;
  int field_selector = insn->field_selector;

  exp = insn->exp;
  value = exp.X_add_number;

  return hppa_field_adjust (0, value, field_selector);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void fix_new_hppa ( fragS *  frag,
int  where,
int  size,
symbolS *  add_symbol,
offsetT  offset,
expressionS exp,
int  pcrel,
bfd_reloc_code_real_type  r_type,
enum hppa_reloc_field_selector_type_alt  r_field,
int  r_format,
unsigned int  arg_reloc,
int unwind_bits  ATTRIBUTE_UNUSED 
) [static]

Definition at line 1200 of file tc-hppa.c.

{
  fixS *new_fix;
  struct hppa_fix_struct *hppa_fix = obstack_alloc (&notes, sizeof (struct hppa_fix_struct));

  if (exp != NULL)
    new_fix = fix_new_exp (frag, where, size, exp, pcrel, r_type);
  else
    new_fix = fix_new (frag, where, size, add_symbol, offset, pcrel, r_type);
  new_fix->tc_fix_data = (void *) hppa_fix;
  hppa_fix->fx_r_type = r_type;
  hppa_fix->fx_r_field = r_field;
  hppa_fix->fx_r_format = r_format;
  hppa_fix->fx_arg_reloc = arg_reloc;
  hppa_fix->segment = now_seg;
#ifdef OBJ_SOM
  if (r_type == R_ENTRY || r_type == R_EXIT)
    new_fix->fx_offset = unwind_bits;
#endif

  /* foo-$global$ is used to access non-automatic storage.  $global$
     is really just a marker and has served its purpose, so eliminate
     it now so as not to confuse write.c.  Ditto for $PIC_pcrel$0.  */
  if (new_fix->fx_subsy
      && (strcmp (S_GET_NAME (new_fix->fx_subsy), "$global$") == 0
         || strcmp (S_GET_NAME (new_fix->fx_subsy), "$PIC_pcrel$0") == 0
         || strcmp (S_GET_NAME (new_fix->fx_subsy), "$tls_gdidx$") == 0
         || strcmp (S_GET_NAME (new_fix->fx_subsy), "$tls_ldidx$") == 0
         || strcmp (S_GET_NAME (new_fix->fx_subsy), "$tls_dtpoff$") == 0
         || strcmp (S_GET_NAME (new_fix->fx_subsy), "$tls_ieoff$") == 0
         || strcmp (S_GET_NAME (new_fix->fx_subsy), "$tls_leoff$") == 0))
    new_fix->fx_subsy = NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void get_expression ( char *  str) [static]

Definition at line 1292 of file tc-hppa.c.

{
  char *save_in;
  asection *seg;

  save_in = input_line_pointer;
  input_line_pointer = str;
  seg = expression (&the_insn.exp);
  if (!(seg == absolute_section
       || seg == undefined_section
       || SEG_NORMAL (seg)))
    {
      as_warn (_("Bad segment in expression."));
      expr_end = input_line_pointer;
      input_line_pointer = save_in;
      return;
    }
  expr_end = input_line_pointer;
  input_line_pointer = save_in;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int hppa_fix_adjustable ( fixS *  fixp)

Definition at line 8344 of file tc-hppa.c.

{
#ifdef OBJ_ELF
  reloc_type code;
#endif
  struct hppa_fix_struct *hppa_fix;

  hppa_fix = (struct hppa_fix_struct *) fixp->tc_fix_data;

#ifdef OBJ_ELF
  /* LR/RR selectors are implicitly used for a number of different relocation
     types.  We must ensure that none of these types are adjusted (see below)
     even if they occur with a different selector.  */
  code = elf_hppa_reloc_final_type (stdoutput, fixp->fx_r_type,
                                hppa_fix->fx_r_format,
                                hppa_fix->fx_r_field);

  switch (code)
    {
    /* Relocation types which use e_lrsel.  */
    case R_PARISC_DIR21L:
    case R_PARISC_DLTREL21L:
    case R_PARISC_DPREL21L:
    case R_PARISC_PLTOFF21L:

    /* Relocation types which use e_rrsel.  */
    case R_PARISC_DIR14R:
    case R_PARISC_DIR14DR:
    case R_PARISC_DIR14WR:
    case R_PARISC_DIR17R:
    case R_PARISC_DLTREL14R:
    case R_PARISC_DLTREL14DR:
    case R_PARISC_DLTREL14WR:
    case R_PARISC_DPREL14R:
    case R_PARISC_DPREL14DR:
    case R_PARISC_DPREL14WR:
    case R_PARISC_PLTOFF14R:
    case R_PARISC_PLTOFF14DR:
    case R_PARISC_PLTOFF14WR:

    /* Other types that we reject for reduction.  */
    case R_PARISC_GNU_VTENTRY:
    case R_PARISC_GNU_VTINHERIT:
      return 0;
    default:
      break;
    }
#endif

  /* Reject reductions of symbols in sym1-sym2 expressions when
     the fixup will occur in a CODE subspace.

     XXX FIXME: Long term we probably want to reject all of these;
     for example reducing in the debug section would lose if we ever
     supported using the optimizing hp linker.  */
  if (fixp->fx_addsy
      && fixp->fx_subsy
      && (hppa_fix->segment->flags & SEC_CODE))
    return 0;

  /* We can't adjust any relocs that use LR% and RR% field selectors.

     If a symbol is reduced to a section symbol, the assembler will
     adjust the addend unless the symbol happens to reside right at
     the start of the section.  Additionally, the linker has no choice
     but to manipulate the addends when coalescing input sections for
     "ld -r".  Since an LR% field selector is defined to round the
     addend, we can't change the addend without risking that a LR% and
     it's corresponding (possible multiple) RR% field will no longer
     sum to the right value.

     eg. Suppose we have
     .        ldil   LR%foo+0,%r21
     .        ldw    RR%foo+0(%r21),%r26
     .        ldw    RR%foo+4(%r21),%r25

     If foo is at address 4092 (decimal) in section `sect', then after
     reducing to the section symbol we get
     .               LR%sect+4092 == (L%sect)+0
     .               RR%sect+4092 == (R%sect)+4092
     .               RR%sect+4096 == (R%sect)-4096
     and the last address loses because rounding the addend to 8k
     multiples takes us up to 8192 with an offset of -4096.

     In cases where the LR% expression is identical to the RR% one we
     will never have a problem, but is so happens that gcc rounds
     addends involved in LR% field selectors to work around a HP
     linker bug.  ie. We often have addresses like the last case
     above where the LR% expression is offset from the RR% one.  */

  if (hppa_fix->fx_r_field == e_lrsel
      || hppa_fix->fx_r_field == e_rrsel
      || hppa_fix->fx_r_field == e_nlrsel)
    return 0;

  /* Reject reductions of symbols in DLT relative relocs,
     relocations with plabels.  */
  if (hppa_fix->fx_r_field == e_tsel
      || hppa_fix->fx_r_field == e_ltsel
      || hppa_fix->fx_r_field == e_rtsel
      || hppa_fix->fx_r_field == e_psel
      || hppa_fix->fx_r_field == e_rpsel
      || hppa_fix->fx_r_field == e_lpsel)
    return 0;

  /* Reject absolute calls (jumps).  */
  if (hppa_fix->fx_r_type == R_HPPA_ABS_CALL)
    return 0;

  /* Reject reductions of function symbols.  */
  if (fixp->fx_addsy != 0 && S_IS_FUNCTION (fixp->fx_addsy))
    return 0;

  return 1;
}

Here is the call graph for this function:

int hppa_force_reg_syms_absolute ( expressionS resultP,
operatorT op  ATTRIBUTE_UNUSED,
expressionS rightP 
)

Definition at line 6343 of file tc-hppa.c.

{
  if (fudge_reg_expressions
      && rightP->X_op == O_register
      && resultP->X_op == O_register)
    {
      rightP->X_op = O_constant;
      resultP->X_op = O_constant;
    }
  return 0;  /* Continue normal expr handling.  */
}

Definition at line 8465 of file tc-hppa.c.

{
  struct hppa_fix_struct *hppa_fixp;

  hppa_fixp = (struct hppa_fix_struct *) fixp->tc_fix_data;
#ifdef OBJ_SOM
  if (fixp->fx_r_type == (int) R_HPPA_ENTRY
      || fixp->fx_r_type == (int) R_HPPA_EXIT
      || fixp->fx_r_type == (int) R_HPPA_BEGIN_BRTAB
      || fixp->fx_r_type == (int) R_HPPA_END_BRTAB
      || fixp->fx_r_type == (int) R_HPPA_BEGIN_TRY
      || fixp->fx_r_type == (int) R_HPPA_END_TRY
      || (fixp->fx_addsy != NULL && fixp->fx_subsy != NULL
         && (hppa_fixp->segment->flags & SEC_CODE) != 0))
    return 1;
#endif
#ifdef OBJ_ELF
  if (fixp->fx_r_type == (int) R_PARISC_GNU_VTINHERIT
      || fixp->fx_r_type == (int) R_PARISC_GNU_VTENTRY)
    return 1;
#endif

  assert (fixp->fx_addsy != NULL);

  /* Ensure we emit a relocation for global symbols so that dynamic
     linking works.  */
  if (S_FORCE_RELOC (fixp->fx_addsy, 1))
    return 1;

  /* It is necessary to force PC-relative calls/jumps to have a relocation
     entry if they're going to need either an argument relocation or long
     call stub.  */
  if (fixp->fx_pcrel
      && arg_reloc_stub_needed (symbol_arg_reloc_info (fixp->fx_addsy),
                            hppa_fixp->fx_arg_reloc))
    return 1;

  /* Now check to see if we're going to need a long-branch stub.  */
  if (fixp->fx_r_type == (int) R_HPPA_PCREL_CALL)
    {
      long pc = md_pcrel_from (fixp);
      valueT distance, min_stub_distance;

      distance = fixp->fx_offset + S_GET_VALUE (fixp->fx_addsy) - pc - 8;

      /* Distance to the closest possible stub.  This will detect most
        but not all circumstances where a stub will not work.  */
      min_stub_distance = pc + 16;
#ifdef OBJ_SOM
      if (last_call_info != NULL)
       min_stub_distance -= S_GET_VALUE (last_call_info->start_symbol);
#endif

      if ((distance + 8388608 >= 16777216
          && min_stub_distance <= 8388608)
         || (hppa_fixp->fx_r_format == 17
             && distance + 262144 >= 524288
             && min_stub_distance <= 262144)
         || (hppa_fixp->fx_r_format == 12
             && distance + 8192 >= 16384
             && min_stub_distance <= 8192)
         )
       return 1;
    }

  if (fixp->fx_r_type == (int) R_HPPA_ABS_CALL)
    return 1;

  /* No need (yet) to force another relocations to be emitted.  */
  return 0;
}

Here is the call graph for this function:

static int is_end_of_statement ( void  ) [static]

Definition at line 2025 of file tc-hppa.c.

{
  return ((*input_line_pointer == '\n')
         || (*input_line_pointer == ';')
         || (*input_line_pointer == '!'));
}

Here is the caller graph for this function:

static bfd_boolean is_same_frag ( fragS *  frag1,
fragS *  frag2 
) [static]

Definition at line 5955 of file tc-hppa.c.

{

  if (frag1 == NULL)
    return FALSE;
  else if (frag2 == NULL)
    return FALSE;
  else if (frag1 == frag2)
    return TRUE;
  else if (frag2->fr_type == rs_fill && frag2->fr_fix == 0)
    return (is_same_frag (frag1, frag2->fr_next));
  else
    return FALSE;
}
void md_apply_fix ( fixS *  fixP,
valueT valP,
segT seg  ATTRIBUTE_UNUSED 
)

Definition at line 1765 of file tc-hppa.c.

{
  char *fixpos;
  struct hppa_fix_struct *hppa_fixP;
  offsetT new_val;
  int insn, val, fmt;

  /* SOM uses R_HPPA_ENTRY and R_HPPA_EXIT relocations which can
     never be "applied" (they are just markers).  Likewise for
     R_HPPA_BEGIN_BRTAB and R_HPPA_END_BRTAB.  */
#ifdef OBJ_SOM
  if (fixP->fx_r_type == R_HPPA_ENTRY
      || fixP->fx_r_type == R_HPPA_EXIT
      || fixP->fx_r_type == R_HPPA_BEGIN_BRTAB
      || fixP->fx_r_type == R_HPPA_END_BRTAB
      || fixP->fx_r_type == R_HPPA_BEGIN_TRY)
    return;

  /* Disgusting.  We must set fx_offset ourselves -- R_HPPA_END_TRY
     fixups are considered not adjustable, which in turn causes
     adjust_reloc_syms to not set fx_offset.  Ugh.  */
  if (fixP->fx_r_type == R_HPPA_END_TRY)
    {
      fixP->fx_offset = * valP;
      return;
    }
#endif
#ifdef OBJ_ELF
  if (fixP->fx_r_type == (int) R_PARISC_GNU_VTENTRY
      || fixP->fx_r_type == (int) R_PARISC_GNU_VTINHERIT)
    return;
#endif

  if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
    fixP->fx_done = 1;

  /* There should be a HPPA specific fixup associated with the GAS fixup.  */
  hppa_fixP = (struct hppa_fix_struct *) fixP->tc_fix_data;
  if (hppa_fixP == NULL)
    {
      as_bad_where (fixP->fx_file, fixP->fx_line,
                  _("no hppa_fixup entry for fixup type 0x%x"),
                  fixP->fx_r_type);
      return;
    }

  fixpos = fixP->fx_frag->fr_literal + fixP->fx_where;

  if (fixP->fx_size != 4 || hppa_fixP->fx_r_format == 32)
    {
      /* Handle constant output. */
      number_to_chars_bigendian (fixpos, *valP, fixP->fx_size);
      return;
    }

  insn = bfd_get_32 (stdoutput, fixpos);
  fmt = bfd_hppa_insn2fmt (stdoutput, insn);

  /* If there is a symbol associated with this fixup, then it's something
     which will need a SOM relocation (except for some PC-relative relocs).
     In such cases we should treat the "val" or "addend" as zero since it
     will be added in as needed from fx_offset in tc_gen_reloc.  */
  if ((fixP->fx_addsy != NULL
       || fixP->fx_r_type == (int) R_HPPA_NONE)
#ifdef OBJ_SOM
      && fmt != 32
#endif
      )
    new_val = ((fmt == 12 || fmt == 17 || fmt == 22) ? 8 : 0);
#ifdef OBJ_SOM
  /* These field selectors imply that we do not want an addend.  */
  else if (hppa_fixP->fx_r_field == e_psel
          || hppa_fixP->fx_r_field == e_rpsel
          || hppa_fixP->fx_r_field == e_lpsel
          || hppa_fixP->fx_r_field == e_tsel
          || hppa_fixP->fx_r_field == e_rtsel
          || hppa_fixP->fx_r_field == e_ltsel)
    new_val = ((fmt == 12 || fmt == 17 || fmt == 22) ? 8 : 0);
#endif
  else
    new_val = hppa_field_adjust (* valP, 0, hppa_fixP->fx_r_field);

  /* Handle pc-relative exceptions from above.  */
  if ((fmt == 12 || fmt == 17 || fmt == 22)
      && fixP->fx_addsy
      && fixP->fx_pcrel
      && !arg_reloc_stub_needed (symbol_arg_reloc_info (fixP->fx_addsy),
                             hppa_fixP->fx_arg_reloc)
#ifdef OBJ_ELF
      && (* valP - 8 + 8192 < 16384
         || (fmt == 17 && * valP - 8 + 262144 < 524288)
         || (fmt == 22 && * valP - 8 + 8388608 < 16777216))
#endif
#ifdef OBJ_SOM
      && (* valP - 8 + 262144 < 524288
         || (fmt == 22 && * valP - 8 + 8388608 < 16777216))
#endif
      && !S_IS_EXTERNAL (fixP->fx_addsy)
      && !S_IS_WEAK (fixP->fx_addsy)
      && S_GET_SEGMENT (fixP->fx_addsy) == hppa_fixP->segment
      && !(fixP->fx_subsy
          && S_GET_SEGMENT (fixP->fx_subsy) != hppa_fixP->segment))
    {
      new_val = hppa_field_adjust (* valP, 0, hppa_fixP->fx_r_field);
    }

  switch (fmt)
    {
    case 10:
      CHECK_FIELD_WHERE (new_val, 8191, -8192,
                      fixP->fx_file, fixP->fx_line);
      val = new_val;

      insn = (insn & ~ 0x3ff1) | (((val & 0x1ff8) << 1)
                              | ((val & 0x2000) >> 13));
      break;
    case -11:
      CHECK_FIELD_WHERE (new_val, 8191, -8192,
                      fixP->fx_file, fixP->fx_line);
      val = new_val;

      insn = (insn & ~ 0x3ff9) | (((val & 0x1ffc) << 1)
                              | ((val & 0x2000) >> 13));
      break;
      /* Handle all opcodes with the 'j' operand type.  */
    case 14:
      CHECK_FIELD_WHERE (new_val, 8191, -8192,
                      fixP->fx_file, fixP->fx_line);
      val = new_val;

      insn = ((insn & ~ 0x3fff) | low_sign_unext (val, 14));
      break;

      /* Handle all opcodes with the 'k' operand type.  */
    case 21:
      CHECK_FIELD_WHERE (new_val, 1048575, -1048576,
                      fixP->fx_file, fixP->fx_line);
      val = new_val;

      insn = (insn & ~ 0x1fffff) | re_assemble_21 (val);
      break;

      /* Handle all the opcodes with the 'i' operand type.  */
    case 11:
      CHECK_FIELD_WHERE (new_val, 1023, -1024,
                      fixP->fx_file, fixP->fx_line);
      val = new_val;

      insn = (insn & ~ 0x7ff) | low_sign_unext (val, 11);
      break;

      /* Handle all the opcodes with the 'w' operand type.  */
    case 12:
      CHECK_FIELD_WHERE (new_val - 8, 8191, -8192,
                      fixP->fx_file, fixP->fx_line);
      val = new_val - 8;

      insn = (insn & ~ 0x1ffd) | re_assemble_12 (val >> 2);
      break;

      /* Handle some of the opcodes with the 'W' operand type.  */
    case 17:
      {
       offsetT distance = * valP;

       /* If this is an absolute branch (ie no link) with an out of
          range target, then we want to complain.  */
       if (fixP->fx_r_type == (int) R_HPPA_PCREL_CALL
           && (insn & 0xffe00000) == 0xe8000000)
         CHECK_FIELD_WHERE (distance - 8, 262143, -262144,
                          fixP->fx_file, fixP->fx_line);

       CHECK_FIELD_WHERE (new_val - 8, 262143, -262144,
                        fixP->fx_file, fixP->fx_line);
       val = new_val - 8;

       insn = (insn & ~ 0x1f1ffd) | re_assemble_17 (val >> 2);
       break;
      }

    case 22:
      {
       offsetT distance = * valP;

       /* If this is an absolute branch (ie no link) with an out of
          range target, then we want to complain.  */
       if (fixP->fx_r_type == (int) R_HPPA_PCREL_CALL
           && (insn & 0xffe00000) == 0xe8000000)
         CHECK_FIELD_WHERE (distance - 8, 8388607, -8388608,
                          fixP->fx_file, fixP->fx_line);

       CHECK_FIELD_WHERE (new_val - 8, 8388607, -8388608,
                        fixP->fx_file, fixP->fx_line);
       val = new_val - 8;

       insn = (insn & ~ 0x3ff1ffd) | re_assemble_22 (val >> 2);
       break;
      }

    case -10:
      val = new_val;
      insn = (insn & ~ 0xfff1) | re_assemble_16 (val & -8);
      break;

    case -16:
      val = new_val;
      insn = (insn & ~ 0xfff9) | re_assemble_16 (val & -4);
      break;

    case 16:
      val = new_val;
      insn = (insn & ~ 0xffff) | re_assemble_16 (val);
      break;

    case 32:
      insn = new_val;
      break;

    default:
      as_bad_where (fixP->fx_file, fixP->fx_line,
                  _("Unknown relocation encountered in md_apply_fix."));
      return;
    }

#ifdef OBJ_ELF
  switch (fixP->fx_r_type)
    {
      case R_PARISC_TLS_GD21L:
      case R_PARISC_TLS_GD14R:
      case R_PARISC_TLS_LDM21L:
      case R_PARISC_TLS_LDM14R:
      case R_PARISC_TLS_LE21L:
      case R_PARISC_TLS_LE14R:
      case R_PARISC_TLS_IE21L:
      case R_PARISC_TLS_IE14R:
        if (fixP->fx_addsy)
         S_SET_THREAD_LOCAL (fixP->fx_addsy);
       break;
      default:
       break;
    }
#endif

  /* Insert the relocation.  */
  bfd_put_32 (stdoutput, insn, fixpos);
}

Here is the call graph for this function:

void md_assemble ( char *  str)

Definition at line 5727 of file tc-hppa.c.

{
  char *to;

  /* The had better be something to assemble.  */
  assert (str);

  /* If we are within a procedure definition, make sure we've
     defined a label for the procedure; handle case where the
     label was defined after the .PROC directive.

     Note there's not need to diddle with the segment or fragment
     for the label symbol in this case.  We have already switched
     into the new $CODE$ subspace at this point.  */
  if (within_procedure && last_call_info->start_symbol == NULL)
    {
      label_symbol_struct *label_symbol = pa_get_label ();

      if (label_symbol)
       {
         if (label_symbol->lss_label)
           {
             last_call_info->start_symbol = label_symbol->lss_label;
             symbol_get_bfdsym (label_symbol->lss_label)->flags
              |= BSF_FUNCTION;
#ifdef OBJ_SOM
             /* Also handle allocation of a fixup to hold the unwind
               information when the label appears after the proc/procend.  */
             if (within_entry_exit)
              {
                char *where;
                unsigned int u;

                where = frag_more (0);
                u = UNWIND_LOW32 (&last_call_info->ci_unwind.descriptor);
                fix_new_hppa (frag_now, where - frag_now->fr_literal, 0,
                            NULL, (offsetT) 0, NULL,
                            0, R_HPPA_ENTRY, e_fsel, 0, 0, u);
              }
#endif
           }
         else
           as_bad (_("Missing function name for .PROC (corrupted label chain)"));
       }
      else
       as_bad (_("Missing function name for .PROC"));
    }

  /* Assemble the instruction.  Results are saved into "the_insn".  */
  pa_ip (str);

  /* Get somewhere to put the assembled instruction.  */
  to = frag_more (4);

  /* Output the opcode.  */
  md_number_to_chars (to, the_insn.opcode, 4);

  /* If necessary output more stuff.  */
  if (the_insn.reloc != R_HPPA_NONE)
    fix_new_hppa (frag_now, (to - frag_now->fr_literal), 4, NULL,
                (offsetT) 0, &the_insn.exp, the_insn.pcrel,
                the_insn.reloc, the_insn.field_selector,
                the_insn.format, the_insn.arg_reloc, 0);

#ifdef OBJ_ELF
  dwarf2_emit_insn (4);
#endif
}

Here is the call graph for this function:

char* md_atof ( int type  ,
char *  litP,
int sizeP 
)

Definition at line 1345 of file tc-hppa.c.

{
  int prec;
  LITTLENUM_TYPE words[MAX_LITTLENUMS];
  LITTLENUM_TYPE *wordP;
  char *t;

  switch (type)
    {

    case 'f':
    case 'F':
    case 's':
    case 'S':
      prec = 2;
      break;

    case 'd':
    case 'D':
    case 'r':
    case 'R':
      prec = 4;
      break;

    case 'x':
    case 'X':
      prec = 6;
      break;

    case 'p':
    case 'P':
      prec = 6;
      break;

    default:
      *sizeP = 0;
      return _("Bad call to MD_ATOF()");
    }
  t = atof_ieee (input_line_pointer, type, words);
  if (t)
    input_line_pointer = t;
  *sizeP = prec * sizeof (LITTLENUM_TYPE);
  for (wordP = words; prec--;)
    {
      md_number_to_chars (litP, (valueT) (*wordP++), sizeof (LITTLENUM_TYPE));
      litP += sizeof (LITTLENUM_TYPE);
    }
  return NULL;
}

Here is the call graph for this function:

void md_begin ( void  )

Definition at line 8253 of file tc-hppa.c.

{
  const char *retval = NULL;
  int lose = 0;
  unsigned int i = 0;

  last_call_info = NULL;
  call_info_root = NULL;

  /* Set the default machine type.  */
  if (!bfd_set_arch_mach (stdoutput, bfd_arch_hppa, DEFAULT_LEVEL))
    as_warn (_("could not set architecture and machine"));

  /* Folding of text and data segments fails miserably on the PA.
     Warn user and disable "-R" option.  */
  if (flag_readonly_data_in_text)
    {
      as_warn (_("-R option not supported on this target."));
      flag_readonly_data_in_text = 0;
    }

#ifdef OBJ_SOM
  pa_spaces_begin ();
#endif

  op_hash = hash_new ();

  while (i < NUMOPCODES)
    {
      const char *name = pa_opcodes[i].name;

      retval = hash_insert (op_hash, name, (struct pa_opcode *) &pa_opcodes[i]);
      if (retval != NULL && *retval != '\0')
       {
         as_fatal (_("Internal error: can't hash `%s': %s\n"), name, retval);
         lose = 1;
       }

      do
       {
         if ((pa_opcodes[i].match & pa_opcodes[i].mask)
             != pa_opcodes[i].match)
           {
             fprintf (stderr, _("internal error: losing opcode: `%s' \"%s\"\n"),
                     pa_opcodes[i].name, pa_opcodes[i].args);
             lose = 1;
           }
         ++i;
       }
      while (i < NUMOPCODES && !strcmp (pa_opcodes[i].name, name));
    }

  if (lose)
    as_fatal (_("Broken assembler.  No assembly attempted."));

#ifdef OBJ_SOM
  /* SOM will change text_section.  To make sure we never put
     anything into the old one switch to the new one now.  */
  subseg_set (text_section, 0);
#endif

#ifdef OBJ_SOM
  dummy_symbol = symbol_find_or_make ("L$dummy");
  S_SET_SEGMENT (dummy_symbol, text_section);
  /* Force the symbol to be converted to a real symbol.  */
  (void) symbol_get_bfdsym (dummy_symbol);
#endif
}

Here is the call graph for this function:

void md_convert_frag ( bfd *abfd  ATTRIBUTE_UNUSED,
asection *sec  ATTRIBUTE_UNUSED,
fragS *  fragP 
)

Definition at line 1631 of file tc-hppa.c.

{
  unsigned int address;

  if (fragP->fr_type == rs_machine_dependent)
    {
      switch ((int) fragP->fr_subtype)
       {
       case 0:
         fragP->fr_type = rs_fill;
         know (fragP->fr_var == 1);
         know (fragP->fr_next);
         address = fragP->fr_address + fragP->fr_fix;
         if (address % fragP->fr_offset)
           {
             fragP->fr_offset =
              fragP->fr_next->fr_address
              - fragP->fr_address
              - fragP->fr_fix;
           }
         else
           fragP->fr_offset = 0;
         break;
       }
    }
}
int md_estimate_size_before_relax ( fragS *  fragP,
asection *segment  ATTRIBUTE_UNUSED 
)

Definition at line 1674 of file tc-hppa.c.

{
  int size;

  size = 0;

  while ((fragP->fr_fix + size) % fragP->fr_offset)
    size++;

  return size;
}
void md_number_to_chars ( char *  buf,
valueT  val,
int  n 
)

Definition at line 1398 of file tc-hppa.c.

Here is the call graph for this function:

int md_parse_option ( int c  ,
char *arg  ATTRIBUTE_UNUSED 
)

Definition at line 1710 of file tc-hppa.c.

{
  switch (c)
    {
    default:
      return 0;

#ifdef OBJ_ELF
    case 'V':
      print_version_id ();
      break;
#endif
#ifdef WARN_COMMENTS
    case 'c':
      warn_comment = 1;
      break;
#endif
    }

  return 1;
}

Here is the call graph for this function:

long md_pcrel_from ( fixS *  fixP)

Definition at line 2016 of file tc-hppa.c.

{
  return fixP->fx_where + fixP->fx_frag->fr_address;
}
valueT md_section_align ( asection * segment  ,
valueT  size 
)

Definition at line 1663 of file tc-hppa.c.

{
  int align = bfd_get_section_alignment (stdoutput, segment);
  int align2 = (1 << align) - 1;

  return (size + align2) & ~align2;
}

Here is the call graph for this function:

void md_show_usage ( FILE *stream  ATTRIBUTE_UNUSED)

Definition at line 1733 of file tc-hppa.c.

{
#ifdef OBJ_ELF
  fprintf (stream, _("\
  -Q                      ignored\n"));
#endif
#ifdef WARN_COMMENTS
  fprintf (stream, _("\
  -c                      print a warning if a comment is found\n"));
#endif
}

Here is the call graph for this function:

symbolS* md_undefined_symbol ( char *name  ATTRIBUTE_UNUSED)

Definition at line 1748 of file tc-hppa.c.

{
  return NULL;
}
static int need_pa11_opcode ( void  ) [static]

Definition at line 2268 of file tc-hppa.c.

{
  if ((pa_number & FP_REG_RSEL) != 0
      && !(the_insn.fpof1 == DBL && the_insn.fpof2 == DBL))
    {
      /* If this instruction is specific to a particular architecture,
        then set a new architecture.  */
      if (bfd_get_mach (stdoutput) < pa11)
       {
         if (!bfd_set_arch_mach (stdoutput, bfd_arch_hppa, pa11))
           as_warn (_("could not update architecture and machine"));
       }
      return TRUE;
    }
  else
    return FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static unsigned int pa_align_arg_reloc ( unsigned int  reg,
unsigned int  arg_reloc 
) [static]

Definition at line 2644 of file tc-hppa.c.

{
  unsigned int new_reloc;

  new_reloc = arg_reloc;
  switch (reg)
    {
    case 0:
      new_reloc <<= 8;
      break;
    case 1:
      new_reloc <<= 6;
      break;
    case 2:
      new_reloc <<= 4;
      break;
    case 3:
      new_reloc <<= 2;
      break;
    default:
      as_bad (_("Invalid argument description: %d"), reg);
    }

  return new_reloc;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void pa_block ( int ATTRIBUTE_UNUSED) [static]

Definition at line 5818 of file tc-hppa.c.

{
  unsigned int temp_size;

#ifdef OBJ_SOM
  /* We must have a valid space and subspace.  */
  pa_check_current_space_and_subspace ();
#endif

  temp_size = get_absolute_expression ();

  if (temp_size > 0x3FFFFFFF)
    {
      as_bad (_("Argument to .BLOCK/.BLOCKZ must be between 0 and 0x3fffffff"));
      temp_size = 0;
    }
  else
    {
      /* Always fill with zeros, that's what the HP assembler does.  */
      char *p = frag_var (rs_fill, 1, 1, 0, NULL, temp_size, NULL);
      *p = 0;
    }

  pa_undefine_label ();
  demand_empty_rest_of_line ();
}

Here is the call graph for this function:

static void pa_brtab ( int begin  ATTRIBUTE_UNUSED) [static]

Definition at line 5848 of file tc-hppa.c.

{

#ifdef OBJ_SOM
  /* The BRTAB relocations are only available in SOM (to denote
     the beginning and end of branch tables).  */
  char *where = frag_more (0);

  fix_new_hppa (frag_now, where - frag_now->fr_literal, 0,
              NULL, (offsetT) 0, NULL,
              0, begin ? R_HPPA_BEGIN_BRTAB : R_HPPA_END_BRTAB,
              e_fsel, 0, 0, 0);
#endif

  demand_empty_rest_of_line ();
}

Here is the call graph for this function:

static unsigned int pa_build_arg_reloc ( char *  type_name) [static]

Definition at line 2623 of file tc-hppa.c.

{

  if (strncasecmp (type_name, "no", 2) == 0)
    return 0;
  if (strncasecmp (type_name, "gr", 2) == 0)
    return 1;
  else if (strncasecmp (type_name, "fr", 2) == 0)
    return 2;
  else if (strncasecmp (type_name, "fu", 2) == 0)
    return 3;
  else
    as_bad (_("Invalid argument location: %s\n"), type_name);

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void pa_call ( int unused  ATTRIBUTE_UNUSED) [static]

Definition at line 5941 of file tc-hppa.c.

{
#ifdef OBJ_SOM
  /* We must have a valid space and subspace.  */
  pa_check_current_space_and_subspace ();
#endif

  pa_call_args (&last_call_desc);
  demand_empty_rest_of_line ();
}

Here is the call graph for this function:

static void pa_call_args ( struct call_desc call_desc) [static]

Definition at line 5893 of file tc-hppa.c.

{
  char *name, c, *p;
  unsigned int temp, arg_reloc;

  while (!is_end_of_statement ())
    {
      name = input_line_pointer;
      c = get_symbol_end ();
      /* Process a source argument.  */
      if ((strncasecmp (name, "argw", 4) == 0))
       {
         temp = atoi (name + 4);
         p = input_line_pointer;
         *p = c;
         input_line_pointer++;
         name = input_line_pointer;
         c = get_symbol_end ();
         arg_reloc = pa_build_arg_reloc (name);
         call_desc->arg_reloc |= pa_align_arg_reloc (temp, arg_reloc);
       }
      /* Process a return value.  */
      else if ((strncasecmp (name, "rtnval", 6) == 0))
       {
         p = input_line_pointer;
         *p = c;
         input_line_pointer++;
         name = input_line_pointer;
         c = get_symbol_end ();
         arg_reloc = pa_build_arg_reloc (name);
         call_desc->arg_reloc |= (arg_reloc & 0x3);
       }
      else
       {
         as_bad (_("Invalid .CALL argument: %s"), name);
       }
      p = input_line_pointer;
      *p = c;
      if (!is_end_of_statement ())
       input_line_pointer++;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void pa_callinfo ( int unused  ATTRIBUTE_UNUSED) [static]

Definition at line 6049 of file tc-hppa.c.

{
  char *name, c, *p;
  int temp;

#ifdef OBJ_SOM
  /* We must have a valid space and subspace.  */
  pa_check_current_space_and_subspace ();
#endif

  /* .CALLINFO must appear within a procedure definition.  */
  if (!within_procedure)
    as_bad (_(".callinfo is not within a procedure definition"));

  /* Mark the fact that we found the .CALLINFO for the
     current procedure.  */
  callinfo_found = TRUE;

  /* Iterate over the .CALLINFO arguments.  */
  while (!is_end_of_statement ())
    {
      name = input_line_pointer;
      c = get_symbol_end ();
      /* Frame size specification.  */
      if ((strncasecmp (name, "frame", 5) == 0))
       {
         p = input_line_pointer;
         *p = c;
         input_line_pointer++;
         temp = get_absolute_expression ();
         if ((temp & 0x3) != 0)
           {
             as_bad (_("FRAME parameter must be a multiple of 8: %d\n"), temp);
             temp = 0;
           }

         /* callinfo is in bytes and unwind_desc is in 8 byte units.  */
         last_call_info->ci_unwind.descriptor.frame_size = temp / 8;

       }
      /* Entry register (GR, GR and SR) specifications.  */
      else if ((strncasecmp (name, "entry_gr", 8) == 0))
       {
         p = input_line_pointer;
         *p = c;
         input_line_pointer++;
         temp = get_absolute_expression ();
         /* The HP assembler accepts 19 as the high bound for ENTRY_GR
            even though %r19 is caller saved.  I think this is a bug in
            the HP assembler, and we are not going to emulate it.  */
         if (temp < 3 || temp > 18)
           as_bad (_("Value for ENTRY_GR must be in the range 3..18\n"));
         last_call_info->ci_unwind.descriptor.entry_gr = temp - 2;
       }
      else if ((strncasecmp (name, "entry_fr", 8) == 0))
       {
         p = input_line_pointer;
         *p = c;
         input_line_pointer++;
         temp = get_absolute_expression ();
         /* Similarly the HP assembler takes 31 as the high bound even
            though %fr21 is the last callee saved floating point register.  */
         if (temp < 12 || temp > 21)
           as_bad (_("Value for ENTRY_FR must be in the range 12..21\n"));
         last_call_info->ci_unwind.descriptor.entry_fr = temp - 11;
       }
      else if ((strncasecmp (name, "entry_sr", 8) == 0))
       {
         p = input_line_pointer;
         *p = c;
         input_line_pointer++;
         temp = get_absolute_expression ();
         if (temp != 3)
           as_bad (_("Value for ENTRY_SR must be 3\n"));
       }
      /* Note whether or not this function performs any calls.  */
      else if ((strncasecmp (name, "calls", 5) == 0) ||
              (strncasecmp (name, "caller", 6) == 0))
       {
         p = input_line_pointer;
         *p = c;
       }
      else if ((strncasecmp (name, "no_calls", 8) == 0))
       {
         p = input_line_pointer;
         *p = c;
       }
      /* Should RP be saved into the stack.  */
      else if ((strncasecmp (name, "save_rp", 7) == 0))
       {
         p = input_line_pointer;
         *p = c;
         last_call_info->ci_unwind.descriptor.save_rp = 1;
       }
      /* Likewise for SP.  */
      else if ((strncasecmp (name, "save_sp", 7) == 0))
       {
         p = input_line_pointer;
         *p = c;
         last_call_info->ci_unwind.descriptor.save_sp = 1;
       }
      /* Is this an unwindable procedure.  If so mark it so
         in the unwind descriptor.  */
      else if ((strncasecmp (name, "no_unwind", 9) == 0))
       {
         p = input_line_pointer;
         *p = c;
         last_call_info->ci_unwind.descriptor.cannot_unwind = 1;
       }
      /* Is this an interrupt routine.  If so mark it in the
         unwind descriptor.  */
      else if ((strncasecmp (name, "hpux_int", 7) == 0))
       {
         p = input_line_pointer;
         *p = c;
         last_call_info->ci_unwind.descriptor.hpux_interrupt_marker = 1;
       }
      /* Is this a millicode routine.  "millicode" isn't in my
        assembler manual, but my copy is old.  The HP assembler
        accepts it, and there's a place in the unwind descriptor
        to drop the information, so we'll accept it too.  */
      else if ((strncasecmp (name, "millicode", 9) == 0))
       {
         p = input_line_pointer;
         *p = c;
         last_call_info->ci_unwind.descriptor.millicode = 1;
       }
      else
       {
         as_bad (_("Invalid .CALLINFO argument: %s"), name);
         *input_line_pointer = c;
       }
      if (!is_end_of_statement ())
       input_line_pointer++;
    }

  demand_empty_rest_of_line ();
}

Here is the call graph for this function:

void pa_check_eof ( void  )

Definition at line 1089 of file tc-hppa.c.

{
  if (within_entry_exit)
    as_fatal (_("Missing .exit\n"));

  if (within_procedure)
    as_fatal (_("Missing .procend\n"));
}

Here is the call graph for this function:

static int pa_chk_field_selector ( char **  str) [static]

Definition at line 2484 of file tc-hppa.c.

{
  int middle, low, high;
  int cmp;
  char name[4];

  /* Read past any whitespace.  */
  /* FIXME: should we read past newlines and formfeeds??? */
  while (**str == ' ' || **str == '\t' || **str == '\n' || **str == '\f')
    *str = *str + 1;

  if ((*str)[1] == '\'' || (*str)[1] == '%')
    name[0] = TOLOWER ((*str)[0]),
    name[1] = 0;
  else if ((*str)[2] == '\'' || (*str)[2] == '%')
    name[0] = TOLOWER ((*str)[0]),
    name[1] = TOLOWER ((*str)[1]),
    name[2] = 0;
  else if ((*str)[3] == '\'' || (*str)[3] == '%')
    name[0] = TOLOWER ((*str)[0]),
    name[1] = TOLOWER ((*str)[1]),
    name[2] = TOLOWER ((*str)[2]),
    name[3] = 0;
  else
    return e_fsel;

  low = 0;
  high = sizeof (selector_table) / sizeof (struct selector_entry) - 1;

  do
    {
      middle = (low + high) / 2;
      cmp = strcmp (name, selector_table[middle].prefix);
      if (cmp < 0)
       high = middle - 1;
      else if (cmp > 0)
       low = middle + 1;
      else
       {
         *str += strlen (name) + 1;
#ifndef OBJ_SOM
         if (selector_table[middle].field_selector == e_nsel)
           return e_fsel;
#endif
         return selector_table[middle].field_selector;
       }
    }
  while (low <= high);

  return e_fsel;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void pa_comm ( int  ) [static]
static void pa_comm ( int unused  ATTRIBUTE_UNUSED) [static]

Definition at line 6240 of file tc-hppa.c.

{
  unsigned int size;
  symbolS *symbol;
  label_symbol_struct *label_symbol = pa_get_label ();

  if (label_symbol)
    symbol = label_symbol->lss_label;
  else
    symbol = NULL;

  SKIP_WHITESPACE ();
  size = get_absolute_expression ();

  if (symbol)
    {
      symbol_get_bfdsym (symbol)->flags |= BSF_OBJECT;
      S_SET_VALUE (symbol, size);
      S_SET_SEGMENT (symbol, bfd_com_section_ptr);
      S_SET_EXTERNAL (symbol);

      /* colon() has already set the frag to the current location in the
         current subspace; we need to reset the fragment to the zero address
         fragment.  We also need to reset the segment pointer.  */
      symbol_set_frag (symbol, &zero_address_frag);
    }
  demand_empty_rest_of_line ();
}

Here is the call graph for this function:

static void pa_cons ( int  nbytes) [static]

Definition at line 8192 of file tc-hppa.c.

{
  cons (nbytes);
  pa_undefine_label ();
}

Here is the call graph for this function:

static void pa_copyright ( int unused  ATTRIBUTE_UNUSED) [static]

Definition at line 8182 of file tc-hppa.c.

{
  obj_copyright (0);
  pa_undefine_label ();
}

Here is the call graph for this function:

static void pa_data ( int  ) [static]
static void pa_data ( int unused  ATTRIBUTE_UNUSED) [static]

Definition at line 6208 of file tc-hppa.c.

{
#ifdef OBJ_SOM
  current_space = is_defined_space ("$PRIVATE$");
  current_subspace
    = pa_subsegment_to_subspace (current_space->sd_seg, 0);
#endif
  s_data (0);
  pa_undefine_label ();
}

Here is the call graph for this function:

void pa_define_label ( symbolS *  symbol)

Definition at line 1127 of file tc-hppa.c.

{
  label_symbol_struct *label_chain = pa_get_label ();

  if (label_chain)
    label_chain->lss_label = symbol;
  else
    {
      /* Create a new label entry and add it to the head of the chain.  */
      label_chain = xmalloc (sizeof (label_symbol_struct));
      label_chain->lss_label = symbol;
#ifdef OBJ_SOM
      label_chain->lss_space = current_space;
#endif
#ifdef OBJ_ELF
      label_chain->lss_segment = now_seg;
#endif
      label_chain->lss_next = NULL;

      if (label_symbols_rootp)
       label_chain->lss_next = label_symbols_rootp;

      label_symbols_rootp = label_chain;
    }

#ifdef OBJ_ELF
  dwarf2_emit_label (symbol);
#endif
}

Here is the call graph for this function:

static void pa_end ( int unused  ATTRIBUTE_UNUSED) [static]

Definition at line 6273 of file tc-hppa.c.

Here is the call graph for this function:

static void pa_enter ( int unused  ATTRIBUTE_UNUSED) [static]

Definition at line 6281 of file tc-hppa.c.

{
#ifdef OBJ_SOM
  /* We must have a valid space and subspace.  */
  pa_check_current_space_and_subspace ();
#endif

  as_bad (_("The .ENTER pseudo-op is not supported"));
  demand_empty_rest_of_line ();
}

Here is the call graph for this function:

static void pa_entry ( int unused  ATTRIBUTE_UNUSED) [static]

Definition at line 6296 of file tc-hppa.c.

{
#ifdef OBJ_SOM
  /* We must have a valid space and subspace.  */
  pa_check_current_space_and_subspace ();
#endif

  if (!within_procedure)
    as_bad (_("Misplaced .entry. Ignored."));
  else
    {
      if (!callinfo_found)
       as_bad (_("Missing .callinfo."));
    }
  demand_empty_rest_of_line ();
  within_entry_exit = TRUE;

#ifdef OBJ_SOM
  /* SOM defers building of unwind descriptors until the link phase.
     The assembler is responsible for creating an R_ENTRY relocation
     to mark the beginning of a region and hold the unwind bits, and
     for creating an R_EXIT relocation to mark the end of the region.

     FIXME.  ELF should be using the same conventions!  The problem
     is an unwind requires too much relocation space.  Hmmm.  Maybe
     if we split the unwind bits up between the relocations which
     denote the entry and exit points.  */
  if (last_call_info->start_symbol != NULL)
    {
      char *where;
      unsigned int u;

      where = frag_more (0);
      u = UNWIND_LOW32 (&last_call_info->ci_unwind.descriptor);
      fix_new_hppa (frag_now, where - frag_now->fr_literal, 0,
                  NULL, (offsetT) 0, NULL,
                  0, R_HPPA_ENTRY, e_fsel, 0, 0, u);
    }
#endif
}

Here is the call graph for this function:

static void pa_equ ( int  reg) [static]

Definition at line 6360 of file tc-hppa.c.

{
  label_symbol_struct *label_symbol = pa_get_label ();
  symbolS *symbol;

  if (label_symbol)
    {
      symbol = label_symbol->lss_label;
      if (reg)
       {
         strict = 1;
         if (!pa_parse_number (&input_line_pointer, 0))
           as_bad (_(".REG expression must be a register"));
         S_SET_VALUE (symbol, pa_number);
         S_SET_SEGMENT (symbol, reg_section);
       }
      else
       {
         expressionS exp;
         segT seg;

         fudge_reg_expressions = 1;
         seg = expression (&exp);
         fudge_reg_expressions = 0;
         if (exp.X_op != O_constant
             && exp.X_op != O_register)
           {
             if (exp.X_op != O_absent)
              as_bad (_("bad or irreducible absolute expression; zero assumed"));
             exp.X_add_number = 0;
             seg = absolute_section;
           }
         S_SET_VALUE (symbol, (unsigned int) exp.X_add_number);
         S_SET_SEGMENT (symbol, seg);
       }
    }
  else
    {
      if (reg)
       as_bad (_(".REG must use a label"));
      else
       as_bad (_(".EQU must use a label"));
    }

  pa_undefine_label ();
  demand_empty_rest_of_line ();
}

Here is the call graph for this function:

static void pa_exit ( int unused  ATTRIBUTE_UNUSED) [static]

Definition at line 6508 of file tc-hppa.c.

{
#ifdef OBJ_SOM
  /* We must have a valid space and subspace.  */
  pa_check_current_space_and_subspace ();
#endif

  if (!within_procedure)
    as_bad (_(".EXIT must appear within a procedure"));
  else
    {
      if (!callinfo_found)
       as_bad (_("Missing .callinfo"));
      else
       {
         if (!within_entry_exit)
           as_bad (_("No .ENTRY for this .EXIT"));
         else
           {
             within_entry_exit = FALSE;
             process_exit ();
           }
       }
    }
  demand_empty_rest_of_line ();
}

Here is the call graph for this function:

static void pa_export ( int unused  ATTRIBUTE_UNUSED) [static]

Definition at line 6695 of file tc-hppa.c.

{
  char *name, c, *p;
  symbolS *symbol;

  name = input_line_pointer;
  c = get_symbol_end ();
  /* Make sure the given symbol exists.  */
  if ((symbol = symbol_find_or_make (name)) == NULL)
    {
      as_bad (_("Cannot define export symbol: %s\n"), name);
      p = input_line_pointer;
      *p = c;
      input_line_pointer++;
    }
  else
    {
      /* OK.  Set the external bits and process argument relocations.
         For the HP, weak and global are not mutually exclusive.
         S_SET_EXTERNAL will not set BSF_GLOBAL if WEAK is set.
         Call S_SET_EXTERNAL to get the other processing.  Manually
         set BSF_GLOBAL when we get back.  */
      S_SET_EXTERNAL (symbol);
      symbol_get_bfdsym (symbol)->flags |= BSF_GLOBAL;
      p = input_line_pointer;
      *p = c;
      if (!is_end_of_statement ())
       {
         input_line_pointer++;
         pa_type_args (symbol, 1);
       }
    }

  demand_empty_rest_of_line ();
}

Here is the call graph for this function:

static void pa_fill ( int unused  ATTRIBUTE_UNUSED) [static]

Definition at line 8210 of file tc-hppa.c.

{
#ifdef OBJ_SOM
  /* We must have a valid space and subspace.  */
  pa_check_current_space_and_subspace ();
#endif

  s_fill (0);
  pa_undefine_label ();
}

Here is the call graph for this function:

static void pa_float_cons ( int  float_type) [static]

Definition at line 8201 of file tc-hppa.c.

{
  float_cons (float_type);
  pa_undefine_label ();
}

Here is the call graph for this function:

static int pa_get_absolute_expression ( struct pa_it insn,
char **  strp 
) [static]

Definition at line 2564 of file tc-hppa.c.

{
  char *save_in;

  insn->field_selector = pa_chk_field_selector (strp);
  save_in = input_line_pointer;
  input_line_pointer = *strp;
  expression (&insn->exp);
  /* This is not perfect, but is a huge improvement over doing nothing.

     The PA assembly syntax is ambiguous in a variety of ways.  Consider
     this string "4 %r5"  Is that the number 4 followed by the register
     r5, or is that 4 MOD r5?

     If we get a modulo expression when looking for an absolute, we try
     again cutting off the input string at the first whitespace character.  */
  if (insn->exp.X_op == O_modulus)
    {
      char *s, c;
      int retval;

      input_line_pointer = *strp;
      s = *strp;
      while (*s != ',' && *s != ' ' && *s != '\t')
       s++;

      c = *s;
      *s = 0;

      retval = pa_get_absolute_expression (insn, strp);

      input_line_pointer = save_in;
      *s = c;
      return evaluate_absolute (insn);
    }
  /* When in strict mode we have a non-match, fix up the pointers
     and return to our caller.  */
  if (insn->exp.X_op != O_constant && strict)
    {
      expr_end = input_line_pointer;
      input_line_pointer = save_in;
      return 0;
    }
  if (insn->exp.X_op != O_constant)
    {
      as_bad (_("Bad segment (should be absolute)."));
      expr_end = input_line_pointer;
      input_line_pointer = save_in;
      return 0;
    }
  expr_end = input_line_pointer;
  input_line_pointer = save_in;
  return evaluate_absolute (insn);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static label_symbol_struct* pa_get_label ( void  ) [static]

Definition at line 1102 of file tc-hppa.c.

{
  label_symbol_struct *label_chain;

  for (label_chain = label_symbols_rootp;
       label_chain;
       label_chain = label_chain->lss_next)
    {
#ifdef OBJ_SOM
    if (current_space == label_chain->lss_space && label_chain->lss_label)
      return label_chain;
#endif
#ifdef OBJ_ELF
    if (now_seg == label_chain->lss_segment && label_chain->lss_label)
      return label_chain;
#endif
    }

  return NULL;
}

Here is the caller graph for this function:

static void pa_import ( int unused  ATTRIBUTE_UNUSED) [static]

Definition at line 6736 of file tc-hppa.c.

{
  char *name, c, *p;
  symbolS *symbol;

  name = input_line_pointer;
  c = get_symbol_end ();

  symbol = symbol_find (name);
  /* Ugh.  We might be importing a symbol defined earlier in the file,
     in which case all the code below will really screw things up
     (set the wrong segment, symbol flags & type, etc).  */
  if (symbol == NULL || !S_IS_DEFINED (symbol))
    {
      symbol = symbol_find_or_make (name);
      p = input_line_pointer;
      *p = c;

      if (!is_end_of_statement ())
       {
         input_line_pointer++;
         pa_type_args (symbol, 0);
       }
      else
       {
         /* Sigh.  To be compatible with the HP assembler and to help
            poorly written assembly code, we assign a type based on
            the current segment.  Note only BSF_FUNCTION really
            matters, we do not need to set the full SYMBOL_TYPE_* info.  */
         if (now_seg == text_section)
           symbol_get_bfdsym (symbol)->flags |= BSF_FUNCTION;

         /* If the section is undefined, then the symbol is undefined
            Since this is an import, leave the section undefined.  */
         S_SET_SEGMENT (symbol, bfd_und_section_ptr);
       }
    }
  else
    {
      /* The symbol was already defined.  Just eat everything up to
        the end of the current statement.  */
      while (!is_end_of_statement ())
       input_line_pointer++;
    }

  demand_empty_rest_of_line ();
}

Here is the call graph for this function:

static void pa_ip ( char *  str) [static]

Definition at line 3218 of file tc-hppa.c.

{
  char *error_message = "";
  char *s, c, *argstart, *name, *save_s;
  const char *args;
  int match = FALSE;
  int comma = 0;
  int cmpltr, nullif, flag, cond, num;
  unsigned long opcode;
  struct pa_opcode *insn;

#ifdef OBJ_SOM
  /* We must have a valid space and subspace.  */
  pa_check_current_space_and_subspace ();
#endif

  /* Convert everything up to the first whitespace character into lower
     case.  */
  for (s = str; *s != ' ' && *s != '\t' && *s != '\n' && *s != '\0'; s++)
    *s = TOLOWER (*s);

  /* Skip to something interesting.  */
  for (s = str;
       ISUPPER (*s) || ISLOWER (*s) || (*s >= '0' && *s <= '3');
       ++s)
    ;

  switch (*s)
    {

    case '\0':
      break;

    case ',':
      comma = 1;

      /*FALLTHROUGH */

    case ' ':
      *s++ = '\0';
      break;

    default:
      as_bad (_("Unknown opcode: `%s'"), str);
      return;
    }

  /* Look up the opcode in the has table.  */
  if ((insn = (struct pa_opcode *) hash_find (op_hash, str)) == NULL)
    {
      as_bad ("Unknown opcode: `%s'", str);
      return;
    }

  if (comma)
    *--s = ',';

  /* Mark the location where arguments for the instruction start, then
     start processing them.  */
  argstart = s;
  for (;;)
    {
      /* Do some initialization.  */
      opcode = insn->match;
      strict = (insn->flags & FLAG_STRICT);
      memset (&the_insn, 0, sizeof (the_insn));

      the_insn.reloc = R_HPPA_NONE;

      if (insn->arch >= pa20
         && bfd_get_mach (stdoutput) < insn->arch)
       goto failed;

      /* Build the opcode, checking as we go to make
         sure that the operands match.  */
      for (args = insn->args;; ++args)
       {
         /* Absorb white space in instruction.  */
         while (*s == ' ' || *s == '\t')
           s++;

         switch (*args)
           {
           /* End of arguments.  */
           case '\0':
             if (*s == '\0')
              match = TRUE;
             break;

           case '+':
             if (*s == '+')
              {
                ++s;
                continue;
              }
             if (*s == '-')
              continue;
             break;

           /* These must match exactly.  */
           case '(':
           case ')':
           case ',':
           case ' ':
             if (*s++ == *args)
              continue;
             break;

           /* Handle a 5 bit register or control register field at 10.  */
           case 'b':
           case '^':
             if (!pa_parse_number (&s, 0))
              break;
             num = pa_number;
             CHECK_FIELD (num, 31, 0, 0);
             INSERT_FIELD_AND_CONTINUE (opcode, num, 21);

           /* Handle %sar or %cr11.  No bits get set, we just verify that it
              is there.  */
           case '!':
             /* Skip whitespace before register.  */
             while (*s == ' ' || *s == '\t')
              s = s + 1;

             if (!strncasecmp (s, "%sar", 4))
               {
                s += 4;
                continue;
              }
             else if (!strncasecmp (s, "%cr11", 5))
               {
                s += 5;
                continue;
              }
             break;

           /* Handle a 5 bit register field at 15.  */
           case 'x':
             if (!pa_parse_number (&s, 0))
              break;
             num = pa_number;
             CHECK_FIELD (num, 31, 0, 0);
             INSERT_FIELD_AND_CONTINUE (opcode, num, 16);

           /* Handle a 5 bit register field at 31.  */
           case 't':
             if (!pa_parse_number (&s, 0))
              break;
             num = pa_number;
             CHECK_FIELD (num, 31, 0, 0);
             INSERT_FIELD_AND_CONTINUE (opcode, num, 0);

           /* Handle a 5 bit register field at 10 and 15.  */
           case 'a':
             if (!pa_parse_number (&s, 0))
              break;
             num = pa_number;
             CHECK_FIELD (num, 31, 0, 0);
             opcode |= num << 16;
             INSERT_FIELD_AND_CONTINUE (opcode, num, 21);

           /* Handle a 5 bit field length at 31.  */
           case 'T':
             num = pa_get_absolute_expression (&the_insn, &s);
             if (strict && the_insn.exp.X_op != O_constant)
              break;
             s = expr_end;
             CHECK_FIELD (num, 32, 1, 0);
             INSERT_FIELD_AND_CONTINUE (opcode, 32 - num, 0);

           /* Handle a 5 bit immediate at 15.  */
           case '5':
             num = pa_get_absolute_expression (&the_insn, &s);
             if (strict && the_insn.exp.X_op != O_constant)
              break;
             s = expr_end;
             /* When in strict mode, we want to just reject this
               match instead of giving an out of range error.  */
             CHECK_FIELD (num, 15, -16, strict);
             num = low_sign_unext (num, 5);
             INSERT_FIELD_AND_CONTINUE (opcode, num, 16);

           /* Handle a 5 bit immediate at 31.  */
           case 'V':
             num = pa_get_absolute_expression (&the_insn, &s);
             if (strict && the_insn.exp.X_op != O_constant)
              break;
             s = expr_end;
             /* When in strict mode, we want to just reject this
               match instead of giving an out of range error.  */
             CHECK_FIELD (num, 15, -16, strict);
             num = low_sign_unext (num, 5);
             INSERT_FIELD_AND_CONTINUE (opcode, num, 0);

           /* Handle an unsigned 5 bit immediate at 31.  */
           case 'r':
             num = pa_get_absolute_expression (&the_insn, &s);
             if (strict && the_insn.exp.X_op != O_constant)
              break;
             s = expr_end;
             CHECK_FIELD (num, 31, 0, strict);
             INSERT_FIELD_AND_CONTINUE (opcode, num, 0);

           /* Handle an unsigned 5 bit immediate at 15.  */
           case 'R':
             num = pa_get_absolute_expression (&the_insn, &s);
             if (strict && the_insn.exp.X_op != O_constant)
              break;
             s = expr_end;
             CHECK_FIELD (num, 31, 0, strict);
             INSERT_FIELD_AND_CONTINUE (opcode, num, 16);

           /* Handle an unsigned 10 bit immediate at 15.  */
           case 'U':
             num = pa_get_absolute_expression (&the_insn, &s);
             if (strict && the_insn.exp.X_op != O_constant)
              break;
             s = expr_end;
             CHECK_FIELD (num, 1023, 0, strict);
             INSERT_FIELD_AND_CONTINUE (opcode, num, 16);

           /* Handle a 2 bit space identifier at 17.  */
           case 's':
             if (!pa_parse_number (&s, 0))
              break;
             num = pa_number;
             CHECK_FIELD (num, 3, 0, 1);
             INSERT_FIELD_AND_CONTINUE (opcode, num, 14);

           /* Handle a 3 bit space identifier at 18.  */
           case 'S':
             if (!pa_parse_number (&s, 0))
              break;
             num = pa_number;
             CHECK_FIELD (num, 7, 0, 1);
             opcode |= re_assemble_3 (num);
             continue;

           /* Handle all completers.  */
           case 'c':
             switch (*++args)
              {

              /* Handle a completer for an indexing load or store.  */
              case 'X':
              case 'x':
                {
                  int uu = 0;
                  int m = 0;
                  int i = 0;
                  while (*s == ',' && i < 2)
                    {
                     s++;
                     if (strncasecmp (s, "sm", 2) == 0)
                       {
                         uu = 1;
                         m = 1;
                         s++;
                         i++;
                       }
                     else if (strncasecmp (s, "m", 1) == 0)
                       m = 1;
                     else if ((strncasecmp (s, "s ", 2) == 0)
                             || (strncasecmp (s, "s,", 2) == 0))
                       uu = 1;
                     else if (strict)
                       {
                         /* This is a match failure.  */
                         s--;
                         break;
                       }
                     else
                       as_bad (_("Invalid Indexed Load Completer."));
                     s++;
                     i++;
                    }
                  if (i > 2)
                    as_bad (_("Invalid Indexed Load Completer Syntax."));
                  opcode |= m << 5;
                  INSERT_FIELD_AND_CONTINUE (opcode, uu, 13);
                }

              /* Handle a short load/store completer.  */
              case 'M':
              case 'm':
              case 'q':
              case 'J':
              case 'e':
                {
                  int a = 0;
                  int m = 0;
                  if (*s == ',')
                    {
                     s++;
                     if (strncasecmp (s, "ma", 2) == 0)
                       {
                         a = 0;
                         m = 1;
                         s += 2;
                       }
                     else if (strncasecmp (s, "mb", 2) == 0)
                       {
                         a = 1;
                         m = 1;
                         s += 2;
                       }
                     else if (strict)
                       /* This is a match failure.  */
                       s--;
                     else
                       {
                         as_bad (_("Invalid Short Load/Store Completer."));
                         s += 2;
                       }
                    }
                  /* If we did not get a ma/mb completer, then we do not
                     consider this a positive match for 'ce'.  */
                  else if (*args == 'e')
                    break;

                 /* 'J', 'm', 'M' and 'q' are the same, except for where they
                     encode the before/after field.  */
                 if (*args == 'm' || *args == 'M')
                    {
                     opcode |= m << 5;
                     INSERT_FIELD_AND_CONTINUE (opcode, a, 13);
                    }
                  else if (*args == 'q')
                    {
                     opcode |= m << 3;
                     INSERT_FIELD_AND_CONTINUE (opcode, a, 2);
                    }
                  else if (*args == 'J')
                    {
                      /* M bit is explicit in the major opcode.  */
                     INSERT_FIELD_AND_CONTINUE (opcode, a, 2);
                    }
                  else if (*args == 'e')
                    {
                     /* Stash the ma/mb flag temporarily in the
                        instruction.  We will use (and remove it)
                        later when handling 'J', 'K', '<' & '>'.  */
                     opcode |= a;
                     continue;
                    }
                }

              /* Handle a stbys completer.  */
              case 'A':
              case 's':
                {
                  int a = 0;
                  int m = 0;
                  int i = 0;
                  while (*s == ',' && i < 2)
                    {
                     s++;
                     if (strncasecmp (s, "m", 1) == 0)
                       m = 1;
                     else if ((strncasecmp (s, "b ", 2) == 0)
                             || (strncasecmp (s, "b,", 2) == 0))
                       a = 0;
                     else if (strncasecmp (s, "e", 1) == 0)
                       a = 1;
                     /* In strict mode, this is a match failure.  */
                     else if (strict)
                       {
                         s--;
                         break;
                       }
                     else
                       as_bad (_("Invalid Store Bytes Short Completer"));
                     s++;
                     i++;
                    }
                  if (i > 2)
                    as_bad (_("Invalid Store Bytes Short Completer"));
                  opcode |= m << 5;
                  INSERT_FIELD_AND_CONTINUE (opcode, a, 13);
                }

              /* Handle load cache hint completer.  */
              case 'c':
                cmpltr = 0;
                if (!strncmp (s, ",sl", 3))
                  {
                    s += 3;
                    cmpltr = 2;
                  }
                INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 10);

              /* Handle store cache hint completer.  */
              case 'C':
                cmpltr = 0;
                if (!strncmp (s, ",sl", 3))
                  {
                    s += 3;
                    cmpltr = 2;
                  }
                else if (!strncmp (s, ",bc", 3))
                  {
                    s += 3;
                    cmpltr = 1;
                  }
                INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 10);

              /* Handle load and clear cache hint completer.  */
              case 'd':
                cmpltr = 0;
                if (!strncmp (s, ",co", 3))
                  {
                    s += 3;
                    cmpltr = 1;
                  }
                INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 10);

              /* Handle load ordering completer.  */
              case 'o':
                if (strncmp (s, ",o", 2) != 0)
                  break;
                s += 2;
                continue;

              /* Handle a branch gate completer.  */
              case 'g':
                if (strncasecmp (s, ",gate", 5) != 0)
                  break;
                s += 5;
                continue;

              /* Handle a branch link and push completer.  */
              case 'p':
                if (strncasecmp (s, ",l,push", 7) != 0)
                  break;
                s += 7;
                continue;

              /* Handle a branch link completer.  */
              case 'l':
                if (strncasecmp (s, ",l", 2) != 0)
                  break;
                s += 2;
                continue;

              /* Handle a branch pop completer.  */
              case 'P':
                if (strncasecmp (s, ",pop", 4) != 0)
                  break;
                s += 4;
                continue;

              /* Handle a local processor completer.  */
              case 'L':
                if (strncasecmp (s, ",l", 2) != 0)
                  break;
                s += 2;
                continue;

              /* Handle a PROBE read/write completer.  */
              case 'w':
                flag = 0;
                if (!strncasecmp (s, ",w", 2))
                  {
                    flag = 1;
                    s += 2;
                  }
                else if (!strncasecmp (s, ",r", 2))
                  {
                    flag = 0;
                    s += 2;
                  }

                INSERT_FIELD_AND_CONTINUE (opcode, flag, 6);

              /* Handle MFCTL wide completer.  */
              case 'W':
                if (strncasecmp (s, ",w", 2) != 0)
                  break;
                s += 2;
                continue;

              /* Handle an RFI restore completer.  */
              case 'r':
                flag = 0;
                if (!strncasecmp (s, ",r", 2))
                  {
                    flag = 5;
                    s += 2;
                  }

                INSERT_FIELD_AND_CONTINUE (opcode, flag, 5);

              /* Handle a system control completer.  */
              case 'Z':
                if (*s == ',' && (*(s + 1) == 'm' || *(s + 1) == 'M'))
                  {
                    flag = 1;
                    s += 2;
                  }
                else
                  flag = 0;

                INSERT_FIELD_AND_CONTINUE (opcode, flag, 5);

              /* Handle intermediate/final completer for DCOR.  */
              case 'i':
                flag = 0;
                if (!strncasecmp (s, ",i", 2))
                  {
                    flag = 1;
                    s += 2;
                  }

                INSERT_FIELD_AND_CONTINUE (opcode, flag, 6);

              /* Handle zero/sign extension completer.  */
              case 'z':
                flag = 1;
                if (!strncasecmp (s, ",z", 2))
                  {
                    flag = 0;
                    s += 2;
                  }

                INSERT_FIELD_AND_CONTINUE (opcode, flag, 10);

              /* Handle add completer.  */
              case 'a':
                flag = 1;
                if (!strncasecmp (s, ",l", 2))
                  {
                    flag = 2;
                    s += 2;
                  }
                else if (!strncasecmp (s, ",tsv", 4))
                  {
                    flag = 3;
                    s += 4;
                  }

                INSERT_FIELD_AND_CONTINUE (opcode, flag, 10);

              /* Handle 64 bit carry for ADD.  */
              case 'Y':
                flag = 0;
                if (!strncasecmp (s, ",dc,tsv", 7) ||
                    !strncasecmp (s, ",tsv,dc", 7))
                  {
                    flag = 1;
                    s += 7;
                  }
                else if (!strncasecmp (s, ",dc", 3))
                  {
                    flag = 0;
                    s += 3;
                  }
                else
                  break;

                INSERT_FIELD_AND_CONTINUE (opcode, flag, 11);

              /* Handle 32 bit carry for ADD.  */
              case 'y':
                flag = 0;
                if (!strncasecmp (s, ",c,tsv", 6) ||
                    !strncasecmp (s, ",tsv,c", 6))
                  {
                    flag = 1;
                    s += 6;
                  }
                else if (!strncasecmp (s, ",c", 2))
                  {
                    flag = 0;
                    s += 2;
                  }
                else
                  break;

                INSERT_FIELD_AND_CONTINUE (opcode, flag, 11);

              /* Handle trap on signed overflow.  */
              case 'v':
                flag = 0;
                if (!strncasecmp (s, ",tsv", 4))
                  {
                    flag = 1;
                    s += 4;
                  }

                INSERT_FIELD_AND_CONTINUE (opcode, flag, 11);

              /* Handle trap on condition and overflow.  */
              case 't':
                flag = 0;
                if (!strncasecmp (s, ",tc,tsv", 7) ||
                    !strncasecmp (s, ",tsv,tc", 7))
                  {
                    flag = 1;
                    s += 7;
                  }
                else if (!strncasecmp (s, ",tc", 3))
                  {
                    flag = 0;
                    s += 3;
                  }
                else
                  break;

                INSERT_FIELD_AND_CONTINUE (opcode, flag, 11);

              /* Handle 64 bit borrow for SUB.  */
              case 'B':
                flag = 0;
                if (!strncasecmp (s, ",db,tsv", 7) ||
                    !strncasecmp (s, ",tsv,db", 7))
                  {
                    flag = 1;
                    s += 7;
                  }
                else if (!strncasecmp (s, ",db", 3))
                  {
                    flag = 0;
                    s += 3;
                  }
                else
                  break;

                INSERT_FIELD_AND_CONTINUE (opcode, flag, 11);

              /* Handle 32 bit borrow for SUB.  */
              case 'b':
                flag = 0;
                if (!strncasecmp (s, ",b,tsv", 6) ||
                    !strncasecmp (s, ",tsv,b", 6))
                  {
                    flag = 1;
                    s += 6;
                  }
                else if (!strncasecmp (s, ",b", 2))
                  {
                    flag = 0;
                    s += 2;
                  }
                else
                  break;

                INSERT_FIELD_AND_CONTINUE (opcode, flag, 11);

              /* Handle trap condition completer for UADDCM.  */
              case 'T':
                flag = 0;
                if (!strncasecmp (s, ",tc", 3))
                  {
                    flag = 1;
                    s += 3;
                  }

                INSERT_FIELD_AND_CONTINUE (opcode, flag, 6);

              /* Handle signed/unsigned at 21.  */
              case 'S':
                {
                  int sign = 1;
                  if (strncasecmp (s, ",s", 2) == 0)
                    {
                     sign = 1;
                     s += 2;
                    }
                  else if (strncasecmp (s, ",u", 2) == 0)
                    {
                     sign = 0;
                     s += 2;
                    }

                  INSERT_FIELD_AND_CONTINUE (opcode, sign, 10);
                }

              /* Handle left/right combination at 17:18.  */
              case 'h':
                if (*s++ == ',')
                  {
                    int lr = 0;
                    if (*s == 'r')
                     lr = 2;
                    else if (*s == 'l')
                     lr = 0;
                    else
                     as_bad (_("Invalid left/right combination completer"));

                    s++;
                    INSERT_FIELD_AND_CONTINUE (opcode, lr, 13);
                  }
                else
                  as_bad (_("Invalid left/right combination completer"));
                break;

              /* Handle saturation at 24:25.  */
              case 'H':
                {
                  int sat = 3;
                  if (strncasecmp (s, ",ss", 3) == 0)
                    {
                     sat = 1;
                     s += 3;
                    }
                  else if (strncasecmp (s, ",us", 3) == 0)
                    {
                     sat = 0;
                     s += 3;
                    }

                  INSERT_FIELD_AND_CONTINUE (opcode, sat, 6);
                }

              /* Handle permutation completer.  */
              case '*':
                if (*s++ == ',')
                  {
                    int permloc[4];
                    int perm = 0;
                    int i = 0;
                    permloc[0] = 13;
                    permloc[1] = 10;
                    permloc[2] = 8;
                    permloc[3] = 6;
                    for (; i < 4; i++)
                      {
                       switch (*s++)
                         {
                         case '0':
                           perm = 0;
                           break;
                         case '1':
                           perm = 1;
                           break;
                         case '2':
                           perm = 2;
                           break;
                         case '3':
                           perm = 3;
                           break;
                         default:
                           as_bad (_("Invalid permutation completer"));
                         }
                       opcode |= perm << permloc[i];
                     }
                    continue;
                  }
                else
                  as_bad (_("Invalid permutation completer"));
                break;

              default:
                abort ();
              }
             break;

           /* Handle all conditions.  */
           case '?':
             {
              args++;
              switch (*args)
                {
                /* Handle FP compare conditions.  */
                case 'f':
                  cond = pa_parse_fp_cmp_cond (&s);
                  INSERT_FIELD_AND_CONTINUE (opcode, cond, 0);

                /* Handle an add condition.  */
                case 'A':
                case 'a':
                  cmpltr = 0;
                  flag = 0;
                  if (*s == ',')
                    {
                     s++;

                     /* 64 bit conditions.  */
                     if (*args == 'A')
                       {
                         if (*s == '*')
                           s++;
                         else
                           break;
                       }
                     else if (*s == '*')
                       break;

                     name = s;
                     while (*s != ',' && *s != ' ' && *s != '\t')
                       s += 1;
                     c = *s;
                     *s = 0x00;
                     if (strcmp (name, "=") == 0)
                       cmpltr = 1;
                     else if (strcmp (name, "<") == 0)
                       cmpltr = 2;
                     else if (strcmp (name, "<=") == 0)
                       cmpltr = 3;
                     else if (strcasecmp (name, "nuv") == 0)
                       cmpltr = 4;
                     else if (strcasecmp (name, "znv") == 0)
                       cmpltr = 5;
                     else if (strcasecmp (name, "sv") == 0)
                       cmpltr = 6;
                     else if (strcasecmp (name, "od") == 0)
                       cmpltr = 7;
                     else if (strcasecmp (name, "tr") == 0)
                       {
                         cmpltr = 0;
                         flag = 1;
                       }
                     else if (strcmp (name, "<>") == 0)
                       {
                         cmpltr = 1;
                         flag = 1;
                       }
                     else if (strcmp (name, ">=") == 0)
                       {
                         cmpltr = 2;
                         flag = 1;
                       }
                     else if (strcmp (name, ">") == 0)
                       {
                         cmpltr = 3;
                         flag = 1;
                       }
                     else if (strcasecmp (name, "uv") == 0)
                       {
                         cmpltr = 4;
                         flag = 1;
                       }
                     else if (strcasecmp (name, "vnz") == 0)
                       {
                         cmpltr = 5;
                         flag = 1;
                       }
                     else if (strcasecmp (name, "nsv") == 0)
                       {
                         cmpltr = 6;
                         flag = 1;
                       }
                     else if (strcasecmp (name, "ev") == 0)
                       {
                         cmpltr = 7;
                         flag = 1;
                       }
                     /* ",*" is a valid condition.  */
                     else if (*args == 'a' || *name)
                       as_bad (_("Invalid Add Condition: %s"), name);
                     *s = c;
                    }
                  opcode |= cmpltr << 13;
                  INSERT_FIELD_AND_CONTINUE (opcode, flag, 12);

                /* Handle non-negated add and branch condition.  */
                case 'd':
                  cmpltr = pa_parse_nonneg_add_cmpltr (&s);
                  if (cmpltr < 0)
                    {
                     as_bad (_("Invalid Add and Branch Condition"));
                     cmpltr = 0;
                    }
                  INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 13);

                /* Handle 64 bit wide-mode add and branch condition.  */
                case 'W':
                  cmpltr = pa_parse_addb_64_cmpltr (&s);
                  if (cmpltr < 0)
                    {
                     as_bad (_("Invalid Add and Branch Condition"));
                     cmpltr = 0;
                    }
                  else
                    {
                     /* Negated condition requires an opcode change.  */
                     opcode |= (cmpltr & 8) << 24;
                    }
                  INSERT_FIELD_AND_CONTINUE (opcode, cmpltr & 7, 13);

                /* Handle a negated or non-negated add and branch
                   condition.  */
                case '@':
                  save_s = s;
                  cmpltr = pa_parse_nonneg_add_cmpltr (&s);
                  if (cmpltr < 0)
                    {
                     s = save_s;
                     cmpltr = pa_parse_neg_add_cmpltr (&s);
                     if (cmpltr < 0)
                       {
                         as_bad (_("Invalid Compare/Subtract Condition"));
                         cmpltr = 0;
                       }
                     else
                       {
                         /* Negated condition requires an opcode change.  */
                         opcode |= 1 << 27;
                       }
                    }
                  INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 13);

                /* Handle branch on bit conditions.  */
                case 'B':
                case 'b':
                  cmpltr = 0;
                  if (*s == ',')
                    {
                     s++;

                     if (*args == 'B')
                       {
                         if (*s == '*')
                           s++;
                         else
                           break;
                       }
                     else if (*s == '*')
                       break;

                     if (strncmp (s, "<", 1) == 0)
                       {
                         cmpltr = 0;
                         s++;
                       }
                     else if (strncmp (s, ">=", 2) == 0)
                       {
                         cmpltr = 1;
                         s += 2;
                       }
                     else
                       as_bad (_("Invalid Bit Branch Condition: %c"), *s);
                    }
                  INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 15);

                /* Handle a compare/subtract condition.  */
                case 'S':
                case 's':
                  cmpltr = 0;
                  flag = 0;
                  if (*s == ',')
                    {
                     s++;

                     /* 64 bit conditions.  */
                     if (*args == 'S')
                       {
                         if (*s == '*')
                           s++;
                         else
                           break;
                       }
                     else if (*s == '*')
                       break;

                     name = s;
                     while (*s != ',' && *s != ' ' && *s != '\t')
                       s += 1;
                     c = *s;
                     *s = 0x00;
                     if (strcmp (name, "=") == 0)
                       cmpltr = 1;
                     else if (strcmp (name, "<") == 0)
                       cmpltr = 2;
                     else if (strcmp (name, "<=") == 0)
                       cmpltr = 3;
                     else if (strcasecmp (name, "<<") == 0)
                       cmpltr = 4;
                     else if (strcasecmp (name, "<<=") == 0)
                       cmpltr = 5;
                     else if (strcasecmp (name, "sv") == 0)
                       cmpltr = 6;
                     else if (strcasecmp (name, "od") == 0)
                       cmpltr = 7;
                     else if (strcasecmp (name, "tr") == 0)
                       {
                         cmpltr = 0;
                         flag = 1;
                       }
                     else if (strcmp (name, "<>") == 0)
                       {
                         cmpltr = 1;
                         flag = 1;
                       }
                     else if (strcmp (name, ">=") == 0)
                       {
                         cmpltr = 2;
                         flag = 1;
                       }
                     else if (strcmp (name, ">") == 0)
                       {
                         cmpltr = 3;
                         flag = 1;
                       }
                     else if (strcasecmp (name, ">>=") == 0)
                       {
                         cmpltr = 4;
                         flag = 1;
                       }
                     else if (strcasecmp (name, ">>") == 0)
                       {
                         cmpltr = 5;
                         flag = 1;
                       }
                     else if (strcasecmp (name, "nsv") == 0)
                       {
                         cmpltr = 6;
                         flag = 1;
                       }
                     else if (strcasecmp (name, "ev") == 0)
                       {
                         cmpltr = 7;
                         flag = 1;
                       }
                     /* ",*" is a valid condition.  */
                     else if (*args != 'S' || *name)
                       as_bad (_("Invalid Compare/Subtract Condition: %s"),
                              name);
                     *s = c;
                    }
                  opcode |= cmpltr << 13;
                  INSERT_FIELD_AND_CONTINUE (opcode, flag, 12);

                /* Handle a non-negated compare condition.  */
                case 't':
                  cmpltr = pa_parse_nonneg_cmpsub_cmpltr (&s);
                  if (cmpltr < 0)
                    {
                     as_bad (_("Invalid Compare/Subtract Condition"));
                     cmpltr = 0;
                    }
                  INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 13);

                /* Handle a 32 bit compare and branch condition.  */
                case 'n':
                  save_s = s;
                  cmpltr = pa_parse_nonneg_cmpsub_cmpltr (&s);
                  if (cmpltr < 0)
                    {
                     s = save_s;
                     cmpltr = pa_parse_neg_cmpsub_cmpltr (&s);
                     if (cmpltr < 0)
                       {
                         as_bad (_("Invalid Compare and Branch Condition"));
                         cmpltr = 0;
                       }
                     else
                       {
                         /* Negated condition requires an opcode change.  */
                         opcode |= 1 << 27;
                       }
                    }

                  INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 13);

                /* Handle a 64 bit compare and branch condition.  */
                case 'N':
                  cmpltr = pa_parse_cmpb_64_cmpltr (&s);
                  if (cmpltr >= 0)
                    {
                     /* Negated condition requires an opcode change.  */
                     opcode |= (cmpltr & 8) << 26;
                    }
                  else
                    /* Not a 64 bit cond.  Give 32 bit a chance.  */
                    break;

                  INSERT_FIELD_AND_CONTINUE (opcode, cmpltr & 7, 13);

                /* Handle a 64 bit cmpib condition.  */
                case 'Q':
                  cmpltr = pa_parse_cmpib_64_cmpltr (&s);
                  if (cmpltr < 0)
                    /* Not a 64 bit cond.  Give 32 bit a chance.  */
                    break;

                  INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 13);

                  /* Handle a logical instruction condition.  */
                case 'L':
                case 'l':
                  cmpltr = 0;
                  flag = 0;
                  if (*s == ',')
                    {
                     s++;

                     /* 64 bit conditions.  */
                     if (*args == 'L')
                       {
                         if (*s == '*')
                           s++;
                         else
                           break;
                       }
                     else if (*s == '*')
                       break;

                     name = s;
                     while (*s != ',' && *s != ' ' && *s != '\t')
                       s += 1;
                     c = *s;
                     *s = 0x00;

                     if (strcmp (name, "=") == 0)
                       cmpltr = 1;
                     else if (strcmp (name, "<") == 0)
                       cmpltr = 2;
                     else if (strcmp (name, "<=") == 0)
                       cmpltr = 3;
                     else if (strcasecmp (name, "od") == 0)
                       cmpltr = 7;
                     else if (strcasecmp (name, "tr") == 0)
                       {
                         cmpltr = 0;
                         flag = 1;
                       }
                     else if (strcmp (name, "<>") == 0)
                       {
                         cmpltr = 1;
                         flag = 1;
                       }
                     else if (strcmp (name, ">=") == 0)
                       {
                         cmpltr = 2;
                         flag = 1;
                       }
                     else if (strcmp (name, ">") == 0)
                       {
                         cmpltr = 3;
                         flag = 1;
                       }
                     else if (strcasecmp (name, "ev") == 0)
                       {
                         cmpltr = 7;
                         flag = 1;
                       }
                     /* ",*" is a valid condition.  */
                     else if (*args != 'L' || *name)
                       as_bad (_("Invalid Logical Instruction Condition."));
                     *s = c;
                    }
                  opcode |= cmpltr << 13;
                  INSERT_FIELD_AND_CONTINUE (opcode, flag, 12);

                /* Handle a shift/extract/deposit condition.  */
                case 'X':
                case 'x':
                case 'y':
                  cmpltr = 0;
                  if (*s == ',')
                    {
                     save_s = s++;

                     /* 64 bit conditions.  */
                     if (*args == 'X')
                       {
                         if (*s == '*')
                           s++;
                         else
                           break;
                       }
                     else if (*s == '*')
                       break;

                     name = s;
                     while (*s != ',' && *s != ' ' && *s != '\t')
                       s += 1;
                     c = *s;
                     *s = 0x00;
                     if (strcmp (name, "=") == 0)
                       cmpltr = 1;
                     else if (strcmp (name, "<") == 0)
                       cmpltr = 2;
                     else if (strcasecmp (name, "od") == 0)
                       cmpltr = 3;
                     else if (strcasecmp (name, "tr") == 0)
                       cmpltr = 4;
                     else if (strcmp (name, "<>") == 0)
                       cmpltr = 5;
                     else if (strcmp (name, ">=") == 0)
                       cmpltr = 6;
                     else if (strcasecmp (name, "ev") == 0)
                       cmpltr = 7;
                     /* Handle movb,n.  Put things back the way they were.
                        This includes moving s back to where it started.  */
                     else if (strcasecmp (name, "n") == 0 && *args == 'y')
                       {
                         *s = c;
                         s = save_s;
                         continue;
                       }
                     /* ",*" is a valid condition.  */
                     else if (*args != 'X' || *name)
                       as_bad (_("Invalid Shift/Extract/Deposit Condition."));
                     *s = c;
                    }
                  INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 13);

                /* Handle a unit instruction condition.  */
                case 'U':
                case 'u':
                  cmpltr = 0;
                  flag = 0;
                  if (*s == ',')
                    {
                     s++;

                     /* 64 bit conditions.  */
                     if (*args == 'U')
                       {
                         if (*s == '*')
                           s++;
                         else
                           break;
                       }
                     else if (*s == '*')
                       break;

                     if (strncasecmp (s, "sbz", 3) == 0)
                       {
                         cmpltr = 2;
                         s += 3;
                       }
                     else if (strncasecmp (s, "shz", 3) == 0)
                       {
                         cmpltr = 3;
                         s += 3;
                       }
                     else if (strncasecmp (s, "sdc", 3) == 0)
                       {
                         cmpltr = 4;
                         s += 3;
                       }
                     else if (strncasecmp (s, "sbc", 3) == 0)
                       {
                         cmpltr = 6;
                         s += 3;
                       }
                     else if (strncasecmp (s, "shc", 3) == 0)
                       {
                         cmpltr = 7;
                         s += 3;
                       }
                     else if (strncasecmp (s, "tr", 2) == 0)
                       {
                         cmpltr = 0;
                         flag = 1;
                         s += 2;
                       }
                     else if (strncasecmp (s, "nbz", 3) == 0)
                       {
                         cmpltr = 2;
                         flag = 1;
                         s += 3;
                       }
                     else if (strncasecmp (s, "nhz", 3) == 0)
                       {
                         cmpltr = 3;
                         flag = 1;
                         s += 3;
                       }
                     else if (strncasecmp (s, "ndc", 3) == 0)
                       {
                         cmpltr = 4;
                         flag = 1;
                         s += 3;
                       }
                     else if (strncasecmp (s, "nbc", 3) == 0)
                       {
                         cmpltr = 6;
                         flag = 1;
                         s += 3;
                       }
                     else if (strncasecmp (s, "nhc", 3) == 0)
                       {
                         cmpltr = 7;
                         flag = 1;
                         s += 3;
                       }
                     else if (strncasecmp (s, "swz", 3) == 0)
                       {
                         cmpltr = 1;
                         flag = 0;
                         s += 3;
                       }
                     else if (strncasecmp (s, "swc", 3) == 0)
                       {
                         cmpltr = 5;
                         flag = 0;
                         s += 3;
                       }
                     else if (strncasecmp (s, "nwz", 3) == 0)
                       {
                         cmpltr = 1;
                         flag = 1;
                         s += 3;
                       }
                     else if (strncasecmp (s, "nwc", 3) == 0)
                       {
                         cmpltr = 5;
                         flag = 1;
                         s += 3;
                       }
                     /* ",*" is a valid condition.  */
                     else if (*args != 'U' || (*s != ' ' && *s != '\t'))
                       as_bad (_("Invalid Unit Instruction Condition."));
                    }
                  opcode |= cmpltr << 13;
                  INSERT_FIELD_AND_CONTINUE (opcode, flag, 12);

                default:
                  abort ();
                }
              break;
             }

           /* Handle a nullification completer for branch instructions.  */
           case 'n':
             nullif = pa_parse_nullif (&s);
             INSERT_FIELD_AND_CONTINUE (opcode, nullif, 1);

           /* Handle a nullification completer for copr and spop insns.  */
           case 'N':
             nullif = pa_parse_nullif (&s);
             INSERT_FIELD_AND_CONTINUE (opcode, nullif, 5);

           /* Handle ,%r2 completer for new syntax branches.  */
           case 'L':
             if (*s == ',' && strncasecmp (s + 1, "%r2", 3) == 0)
              s += 4;
             else if (*s == ',' && strncasecmp (s + 1, "%rp", 3) == 0)
              s += 4;
             else
              break;
             continue;

           /* Handle 3 bit entry into the fp compare array.   Valid values
              are 0..6 inclusive.  */
           case 'h':
             get_expression (s);
             s = expr_end;
             if (the_insn.exp.X_op == O_constant)
              {
                num = evaluate_absolute (&the_insn);
                CHECK_FIELD (num, 6, 0, 0);
                num++;
                INSERT_FIELD_AND_CONTINUE (opcode, num, 13);
              }
             else
              break;

           /* Handle 3 bit entry into the fp compare array.   Valid values
              are 0..6 inclusive.  */
           case 'm':
             get_expression (s);
             if (the_insn.exp.X_op == O_constant)
              {
                s = expr_end;
                num = evaluate_absolute (&the_insn);
                CHECK_FIELD (num, 6, 0, 0);
                num = (num + 1) ^ 1;
                INSERT_FIELD_AND_CONTINUE (opcode, num, 13);
              }
             else
              break;

           /* Handle graphics test completers for ftest */
           case '=':
             {
              num = pa_parse_ftest_gfx_completer (&s);
              INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
             }

           /* Handle a 11 bit immediate at 31.  */
           case 'i':
             the_insn.field_selector = pa_chk_field_selector (&s);
             get_expression (s);
             s = expr_end;
             if (the_insn.exp.X_op == O_constant)
              {
                num = evaluate_absolute (&the_insn);
                CHECK_FIELD (num, 1023, -1024, 0);
                num = low_sign_unext (num, 11);
                INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
              }
             else
              {
                if (is_DP_relative (the_insn.exp))
                  the_insn.reloc = R_HPPA_GOTOFF;
                else if (is_PC_relative (the_insn.exp))
                  the_insn.reloc = R_HPPA_PCREL_CALL;
#ifdef OBJ_ELF
                else if (is_tls_gdidx (the_insn.exp))
                  the_insn.reloc = R_PARISC_TLS_GD21L;
                else if (is_tls_ldidx (the_insn.exp))
                  the_insn.reloc = R_PARISC_TLS_LDM21L;
                else if (is_tls_dtpoff (the_insn.exp))
                  the_insn.reloc = R_PARISC_TLS_LDO21L;
                else if (is_tls_ieoff (the_insn.exp))
                  the_insn.reloc = R_PARISC_TLS_IE21L;
                else if (is_tls_leoff (the_insn.exp))
                  the_insn.reloc = R_PARISC_TLS_LE21L;
#endif
                else
                  the_insn.reloc = R_HPPA;
                the_insn.format = 11;
                continue;
              }

           /* Handle a 14 bit immediate at 31.  */
           case 'J':
             the_insn.field_selector = pa_chk_field_selector (&s);
             get_expression (s);
             s = expr_end;
             if (the_insn.exp.X_op == O_constant)
              {
                int mb;

                /* XXX the completer stored away tidbits of information
                   for us to extract.  We need a cleaner way to do this.
                   Now that we have lots of letters again, it would be
                   good to rethink this.  */
                mb = opcode & 1;
                opcode -= mb;
                num = evaluate_absolute (&the_insn);
                if (mb != (num < 0))
                  break;
                CHECK_FIELD (num, 8191, -8192, 0);
                num = low_sign_unext (num, 14);
                INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
              }
             break;

           /* Handle a 14 bit immediate at 31.  */
           case 'K':
             the_insn.field_selector = pa_chk_field_selector (&s);
             get_expression (s);
             s = expr_end;
             if (the_insn.exp.X_op == O_constant)
              {
                int mb;

                mb = opcode & 1;
                opcode -= mb;
                num = evaluate_absolute (&the_insn);
                if (mb == (num < 0))
                  break;
                if (num % 4)
                  break;
                CHECK_FIELD (num, 8191, -8192, 0);
                num = low_sign_unext (num, 14);
                INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
              }
             break;

           /* Handle a 16 bit immediate at 31.  */
           case '<':
             the_insn.field_selector = pa_chk_field_selector (&s);
             get_expression (s);
             s = expr_end;
             if (the_insn.exp.X_op == O_constant)
              {
                int mb;

                mb = opcode & 1;
                opcode -= mb;
                num = evaluate_absolute (&the_insn);
                if (mb != (num < 0))
                  break;
                CHECK_FIELD (num, 32767, -32768, 0);
                num = re_assemble_16 (num);
                INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
              }
             break;

           /* Handle a 16 bit immediate at 31.  */
           case '>':
             the_insn.field_selector = pa_chk_field_selector (&s);
             get_expression (s);
             s = expr_end;
             if (the_insn.exp.X_op == O_constant)
              {
                int mb;

                mb = opcode & 1;
                opcode -= mb;
                num = evaluate_absolute (&the_insn);
                if (mb == (num < 0))
                  break;
                if (num % 4)
                  break;
                CHECK_FIELD (num, 32767, -32768, 0);
                num = re_assemble_16 (num);
                INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
              }
             break;

           /* Handle 14 bit immediate, shifted left three times.  */
           case '#':
             if (bfd_get_mach (stdoutput) != pa20)
              break;
             the_insn.field_selector = pa_chk_field_selector (&s);
             get_expression (s);
             s = expr_end;
             if (the_insn.exp.X_op == O_constant)
              {
                num = evaluate_absolute (&the_insn);
                if (num & 0x7)
                  break;
                CHECK_FIELD (num, 8191, -8192, 0);
                if (num < 0)
                  opcode |= 1;
                num &= 0x1fff;
                num >>= 3;
                INSERT_FIELD_AND_CONTINUE (opcode, num, 4);
              }
             else
              {
                if (is_DP_relative (the_insn.exp))
                  the_insn.reloc = R_HPPA_GOTOFF;
                else if (is_PC_relative (the_insn.exp))
                  the_insn.reloc = R_HPPA_PCREL_CALL;
#ifdef OBJ_ELF
                else if (is_tls_gdidx (the_insn.exp))
                  the_insn.reloc = R_PARISC_TLS_GD21L;
                else if (is_tls_ldidx (the_insn.exp))
                  the_insn.reloc = R_PARISC_TLS_LDM21L;
                else if (is_tls_dtpoff (the_insn.exp))
                  the_insn.reloc = R_PARISC_TLS_LDO21L;
                else if (is_tls_ieoff (the_insn.exp))
                  the_insn.reloc = R_PARISC_TLS_IE21L;
                else if (is_tls_leoff (the_insn.exp))
                  the_insn.reloc = R_PARISC_TLS_LE21L;
#endif
                else
                  the_insn.reloc = R_HPPA;
                the_insn.format = 14;
                continue;
              }
             break;

           /* Handle 14 bit immediate, shifted left twice.  */
           case 'd':
             the_insn.field_selector = pa_chk_field_selector (&s);
             get_expression (s);
             s = expr_end;
             if (the_insn.exp.X_op == O_constant)
              {
                num = evaluate_absolute (&the_insn);
                if (num & 0x3)
                  break;
                CHECK_FIELD (num, 8191, -8192, 0);
                if (num < 0)
                  opcode |= 1;
                num &= 0x1fff;
                num >>= 2;
                INSERT_FIELD_AND_CONTINUE (opcode, num, 3);
              }
             else
              {
                if (is_DP_relative (the_insn.exp))
                  the_insn.reloc = R_HPPA_GOTOFF;
                else if (is_PC_relative (the_insn.exp))
                  the_insn.reloc = R_HPPA_PCREL_CALL;
#ifdef OBJ_ELF
                else if (is_tls_gdidx (the_insn.exp))
                  the_insn.reloc = R_PARISC_TLS_GD21L;
                else if (is_tls_ldidx (the_insn.exp))
                  the_insn.reloc = R_PARISC_TLS_LDM21L;
                else if (is_tls_dtpoff (the_insn.exp))
                  the_insn.reloc = R_PARISC_TLS_LDO21L;
                else if (is_tls_ieoff (the_insn.exp))
                  the_insn.reloc = R_PARISC_TLS_IE21L;
                else if (is_tls_leoff (the_insn.exp))
                  the_insn.reloc = R_PARISC_TLS_LE21L;
#endif
                else
                  the_insn.reloc = R_HPPA;
                the_insn.format = 14;
                continue;
              }

           /* Handle a 14 bit immediate at 31.  */
           case 'j':
             the_insn.field_selector = pa_chk_field_selector (&s);
             get_expression (s);
             s = expr_end;
             if (the_insn.exp.X_op == O_constant)
              {
                num = evaluate_absolute (&the_insn);
                CHECK_FIELD (num, 8191, -8192, 0);
                num = low_sign_unext (num, 14);
                INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
              }
             else
              {
                if (is_DP_relative (the_insn.exp))
                  the_insn.reloc = R_HPPA_GOTOFF;
                else if (is_PC_relative (the_insn.exp))
                  the_insn.reloc = R_HPPA_PCREL_CALL;
#ifdef OBJ_ELF
                else if (is_tls_gdidx (the_insn.exp))
                  the_insn.reloc = R_PARISC_TLS_GD21L;
                else if (is_tls_ldidx (the_insn.exp))
                  the_insn.reloc = R_PARISC_TLS_LDM21L;
                else if (is_tls_dtpoff (the_insn.exp))
                  the_insn.reloc = R_PARISC_TLS_LDO21L;
                else if (is_tls_ieoff (the_insn.exp))
                  the_insn.reloc = R_PARISC_TLS_IE21L;
                else if (is_tls_leoff (the_insn.exp))
                  the_insn.reloc = R_PARISC_TLS_LE21L;
#endif
                else
                  the_insn.reloc = R_HPPA;
                the_insn.format = 14;
                continue;
              }

           /* Handle a 21 bit immediate at 31.  */
           case 'k':
             the_insn.field_selector = pa_chk_field_selector (&s);
             get_expression (s);
             s = expr_end;
             if (the_insn.exp.X_op == O_constant)
              {
                num = evaluate_absolute (&the_insn);
                CHECK_FIELD (num >> 11, 1048575, -1048576, 0);
                opcode |= re_assemble_21 (num);
                continue;
              }
             else
              {
                if (is_DP_relative (the_insn.exp))
                  the_insn.reloc = R_HPPA_GOTOFF;
                else if (is_PC_relative (the_insn.exp))
                  the_insn.reloc = R_HPPA_PCREL_CALL;
#ifdef OBJ_ELF
                else if (is_tls_gdidx (the_insn.exp))
                  the_insn.reloc = R_PARISC_TLS_GD21L;
                else if (is_tls_ldidx (the_insn.exp))
                  the_insn.reloc = R_PARISC_TLS_LDM21L;
                else if (is_tls_dtpoff (the_insn.exp))
                  the_insn.reloc = R_PARISC_TLS_LDO21L;
                else if (is_tls_ieoff (the_insn.exp))
                  the_insn.reloc = R_PARISC_TLS_IE21L;
                else if (is_tls_leoff (the_insn.exp))
                  the_insn.reloc = R_PARISC_TLS_LE21L;
#endif
                else
                  the_insn.reloc = R_HPPA;
                the_insn.format = 21;
                continue;
              }

           /* Handle a 16 bit immediate at 31 (PA 2.0 wide mode only).  */
           case 'l':
             the_insn.field_selector = pa_chk_field_selector (&s);
             get_expression (s);
             s = expr_end;
             if (the_insn.exp.X_op == O_constant)
              {
                num = evaluate_absolute (&the_insn);
                CHECK_FIELD (num, 32767, -32768, 0);
                opcode |= re_assemble_16 (num);
                continue;
              }
             else
              {
                /* ??? Is this valid for wide mode?  */
                if (is_DP_relative (the_insn.exp))
                  the_insn.reloc = R_HPPA_GOTOFF;
                else if (is_PC_relative (the_insn.exp))
                  the_insn.reloc = R_HPPA_PCREL_CALL;
#ifdef OBJ_ELF
                else if (is_tls_gdidx (the_insn.exp))
                  the_insn.reloc = R_PARISC_TLS_GD21L;
                else if (is_tls_ldidx (the_insn.exp))
                  the_insn.reloc = R_PARISC_TLS_LDM21L;
                else if (is_tls_dtpoff (the_insn.exp))
                  the_insn.reloc = R_PARISC_TLS_LDO21L;
                else if (is_tls_ieoff (the_insn.exp))
                  the_insn.reloc = R_PARISC_TLS_IE21L;
                else if (is_tls_leoff (the_insn.exp))
                  the_insn.reloc = R_PARISC_TLS_LE21L;
#endif
                else
                  the_insn.reloc = R_HPPA;
                the_insn.format = 14;
                continue;
              }

           /* Handle a word-aligned 16-bit imm. at 31 (PA2.0 wide).  */
           case 'y':
             the_insn.field_selector = pa_chk_field_selector (&s);
             get_expression (s);
             s = expr_end;
             if (the_insn.exp.X_op == O_constant)
              {
                num = evaluate_absolute (&the_insn);
                CHECK_FIELD (num, 32767, -32768, 0);
                CHECK_ALIGN (num, 4, 0);
                opcode |= re_assemble_16 (num);
                continue;
              }
             else
              {
                /* ??? Is this valid for wide mode?  */
                if (is_DP_relative (the_insn.exp))
                  the_insn.reloc = R_HPPA_GOTOFF;
                else if (is_PC_relative (the_insn.exp))
                  the_insn.reloc = R_HPPA_PCREL_CALL;
#ifdef OBJ_ELF
                else if (is_tls_gdidx (the_insn.exp))
                  the_insn.reloc = R_PARISC_TLS_GD21L;
                else if (is_tls_ldidx (the_insn.exp))
                  the_insn.reloc = R_PARISC_TLS_LDM21L;
                else if (is_tls_dtpoff (the_insn.exp))
                  the_insn.reloc = R_PARISC_TLS_LDO21L;
                else if (is_tls_ieoff (the_insn.exp))
                  the_insn.reloc = R_PARISC_TLS_IE21L;
                else if (is_tls_leoff (the_insn.exp))
                  the_insn.reloc = R_PARISC_TLS_LE21L;
#endif
                else
                  the_insn.reloc = R_HPPA;
                the_insn.format = 14;
                continue;
              }

           /* Handle a dword-aligned 16-bit imm. at 31 (PA2.0 wide).  */
           case '&':
             the_insn.field_selector = pa_chk_field_selector (&s);
             get_expression (s);
             s = expr_end;
             if (the_insn.exp.X_op == O_constant)
              {
                num = evaluate_absolute (&the_insn);
                CHECK_FIELD (num, 32767, -32768, 0);
                CHECK_ALIGN (num, 8, 0);
                opcode |= re_assemble_16 (num);
                continue;
              }
             else
              {
                /* ??? Is this valid for wide mode?  */
                if (is_DP_relative (the_insn.exp))
                  the_insn.reloc = R_HPPA_GOTOFF;
                else if (is_PC_relative (the_insn.exp))
                  the_insn.reloc = R_HPPA_PCREL_CALL;
#ifdef OBJ_ELF
                else if (is_tls_gdidx (the_insn.exp))
                  the_insn.reloc = R_PARISC_TLS_GD21L;
                else if (is_tls_ldidx (the_insn.exp))
                  the_insn.reloc = R_PARISC_TLS_LDM21L;
                else if (is_tls_dtpoff (the_insn.exp))
                  the_insn.reloc = R_PARISC_TLS_LDO21L;
                else if (is_tls_ieoff (the_insn.exp))
                  the_insn.reloc = R_PARISC_TLS_IE21L;
                else if (is_tls_leoff (the_insn.exp))
                  the_insn.reloc = R_PARISC_TLS_LE21L;
#endif
                else
                  the_insn.reloc = R_HPPA;
                the_insn.format = 14;
                continue;
              }

           /* Handle a 12 bit branch displacement.  */
           case 'w':
             the_insn.field_selector = pa_chk_field_selector (&s);
             get_expression (s);
             s = expr_end;
             the_insn.pcrel = 1;
             if (!the_insn.exp.X_add_symbol
                || !strcmp (S_GET_NAME (the_insn.exp.X_add_symbol),
                           FAKE_LABEL_NAME))
              {
                num = evaluate_absolute (&the_insn);
                if (num % 4)
                  {
                    as_bad (_("Branch to unaligned address"));
                    break;
                  }
                if (the_insn.exp.X_add_symbol)
                  num -= 8;
                CHECK_FIELD (num, 8191, -8192, 0);
                opcode |= re_assemble_12 (num >> 2);
                continue;
              }
             else
              {
                the_insn.reloc = R_HPPA_PCREL_CALL;
                the_insn.format = 12;
                the_insn.arg_reloc = last_call_desc.arg_reloc;
                memset (&last_call_desc, 0, sizeof (struct call_desc));
                s = expr_end;
                continue;
              }

           /* Handle a 17 bit branch displacement.  */
           case 'W':
             the_insn.field_selector = pa_chk_field_selector (&s);
             get_expression (s);
             s = expr_end;
             the_insn.pcrel = 1;
             if (!the_insn.exp.X_add_symbol
                || !strcmp (S_GET_NAME (the_insn.exp.X_add_symbol),
                           FAKE_LABEL_NAME))
              {
                num = evaluate_absolute (&the_insn);
                if (num % 4)
                  {
                    as_bad (_("Branch to unaligned address"));
                    break;
                  }
                if (the_insn.exp.X_add_symbol)
                  num -= 8;
                CHECK_FIELD (num, 262143, -262144, 0);
                opcode |= re_assemble_17 (num >> 2);
                continue;
              }
             else
              {
                the_insn.reloc = R_HPPA_PCREL_CALL;
                the_insn.format = 17;
                the_insn.arg_reloc = last_call_desc.arg_reloc;
                memset (&last_call_desc, 0, sizeof (struct call_desc));
                continue;
              }

           /* Handle a 22 bit branch displacement.  */
           case 'X':
             the_insn.field_selector = pa_chk_field_selector (&s);
             get_expression (s);
             s = expr_end;
             the_insn.pcrel = 1;
             if (!the_insn.exp.X_add_symbol
                || !strcmp (S_GET_NAME (the_insn.exp.X_add_symbol),
                           FAKE_LABEL_NAME))
              {
                num = evaluate_absolute (&the_insn);
                if (num % 4)
                  {
                    as_bad (_("Branch to unaligned address"));
                    break;
                  }
                if (the_insn.exp.X_add_symbol)
                  num -= 8;
                CHECK_FIELD (num, 8388607, -8388608, 0);
                opcode |= re_assemble_22 (num >> 2);
              }
             else
              {
                the_insn.reloc = R_HPPA_PCREL_CALL;
                the_insn.format = 22;
                the_insn.arg_reloc = last_call_desc.arg_reloc;
                memset (&last_call_desc, 0, sizeof (struct call_desc));
                continue;
              }

           /* Handle an absolute 17 bit branch target.  */
           case 'z':
             the_insn.field_selector = pa_chk_field_selector (&s);
             get_expression (s);
             s = expr_end;
             the_insn.pcrel = 0;
             if (!the_insn.exp.X_add_symbol
                || !strcmp (S_GET_NAME (the_insn.exp.X_add_symbol),
                           FAKE_LABEL_NAME))
              {
                num = evaluate_absolute (&the_insn);
                if (num % 4)
                  {
                    as_bad (_("Branch to unaligned address"));
                    break;
                  }
                if (the_insn.exp.X_add_symbol)
                  num -= 8;
                CHECK_FIELD (num, 262143, -262144, 0);
                opcode |= re_assemble_17 (num >> 2);
                continue;
              }
             else
              {
                the_insn.reloc = R_HPPA_ABS_CALL;
                the_insn.format = 17;
                the_insn.arg_reloc = last_call_desc.arg_reloc;
                memset (&last_call_desc, 0, sizeof (struct call_desc));
                continue;
              }

           /* Handle '%r1' implicit operand of addil instruction.  */
           case 'Z':
             if (*s == ',' && *(s + 1) == '%' && *(s + 3) == '1'
                && (*(s + 2) == 'r' || *(s + 2) == 'R'))
              {
                s += 4;
                continue;
              }
             else
               break;

           /* Handle '%sr0,%r31' implicit operand of be,l instruction.  */
           case 'Y':
             if (strncasecmp (s, "%sr0,%r31", 9) != 0)
              break;
             s += 9;
             continue;

           /* Handle immediate value of 0 for ordered load/store instructions.  */
           case '@':
             if (*s != '0')
              break;
             s++;
             continue;

           /* Handle a 2 bit shift count at 25.  */
           case '.':
             num = pa_get_absolute_expression (&the_insn, &s);
             if (strict && the_insn.exp.X_op != O_constant)
              break;
             s = expr_end;
             CHECK_FIELD (num, 3, 1, strict);
             INSERT_FIELD_AND_CONTINUE (opcode, num, 6);

           /* Handle a 4 bit shift count at 25.  */
           case '*':
             num = pa_get_absolute_expression (&the_insn, &s);
             if (strict && the_insn.exp.X_op != O_constant)
              break;
             s = expr_end;
             CHECK_FIELD (num, 15, 0, strict);
             INSERT_FIELD_AND_CONTINUE (opcode, num, 6);

           /* Handle a 5 bit shift count at 26.  */
           case 'p':
             num = pa_get_absolute_expression (&the_insn, &s);
             if (strict && the_insn.exp.X_op != O_constant)
              break;
             s = expr_end;
             CHECK_FIELD (num, 31, 0, strict);
             INSERT_FIELD_AND_CONTINUE (opcode, 31 - num, 5);

           /* Handle a 6 bit shift count at 20,22:26.  */
           case '~':
             num = pa_get_absolute_expression (&the_insn, &s);
             if (strict && the_insn.exp.X_op != O_constant)
              break;
             s = expr_end;
             CHECK_FIELD (num, 63, 0, strict);
             num = 63 - num;
             opcode |= (num & 0x20) << 6;
             INSERT_FIELD_AND_CONTINUE (opcode, num & 0x1f, 5);

           /* Handle a 6 bit field length at 23,27:31.  */
           case '%':
             flag = 0;
             num = pa_get_absolute_expression (&the_insn, &s);
             if (strict && the_insn.exp.X_op != O_constant)
              break;
             s = expr_end;
             CHECK_FIELD (num, 64, 1, strict);
             num--;
             opcode |= (num & 0x20) << 3;
             num = 31 - (num & 0x1f);
             INSERT_FIELD_AND_CONTINUE (opcode, num, 0);

           /* Handle a 6 bit field length at 19,27:31.  */
           case '|':
             num = pa_get_absolute_expression (&the_insn, &s);
             if (strict && the_insn.exp.X_op != O_constant)
              break;
             s = expr_end;
             CHECK_FIELD (num, 64, 1, strict);
             num--;
             opcode |= (num & 0x20) << 7;
             num = 31 - (num & 0x1f);
             INSERT_FIELD_AND_CONTINUE (opcode, num, 0);

           /* Handle a 5 bit bit position at 26.  */
           case 'P':
             num = pa_get_absolute_expression (&the_insn, &s);
             if (strict && the_insn.exp.X_op != O_constant)
              break;
             s = expr_end;
             CHECK_FIELD (num, 31, 0, strict);
             INSERT_FIELD_AND_CONTINUE (opcode, num, 5);

           /* Handle a 6 bit bit position at 20,22:26.  */
           case 'q':
             num = pa_get_absolute_expression (&the_insn, &s);
             if (strict && the_insn.exp.X_op != O_constant)
              break;
             s = expr_end;
             CHECK_FIELD (num, 63, 0, strict);
             opcode |= (num & 0x20) << 6;
             INSERT_FIELD_AND_CONTINUE (opcode, num & 0x1f, 5);

           /* Handle a 5 bit immediate at 10 with 'd' as the complement
              of the high bit of the immediate.  */
           case 'B':
             num = pa_get_absolute_expression (&the_insn, &s);
             if (strict && the_insn.exp.X_op != O_constant)
              break;
             s = expr_end;
             CHECK_FIELD (num, 63, 0, strict);
             if (num & 0x20)
              ;
             else
              opcode |= (1 << 13);
             INSERT_FIELD_AND_CONTINUE (opcode, num & 0x1f, 21);

           /* Handle a 5 bit immediate at 10.  */
           case 'Q':
             num = pa_get_absolute_expression (&the_insn, &s);
             if (strict && the_insn.exp.X_op != O_constant)
              break;
             s = expr_end;
             CHECK_FIELD (num, 31, 0, strict);
             INSERT_FIELD_AND_CONTINUE (opcode, num, 21);

           /* Handle a 9 bit immediate at 28.  */
           case '$':
             num = pa_get_absolute_expression (&the_insn, &s);
             if (strict && the_insn.exp.X_op != O_constant)
              break;
             s = expr_end;
             CHECK_FIELD (num, 511, 1, strict);
             INSERT_FIELD_AND_CONTINUE (opcode, num, 3);

           /* Handle a 13 bit immediate at 18.  */
           case 'A':
             num = pa_get_absolute_expression (&the_insn, &s);
             if (strict && the_insn.exp.X_op != O_constant)
              break;
             s = expr_end;
             CHECK_FIELD (num, 8191, 0, strict);
             INSERT_FIELD_AND_CONTINUE (opcode, num, 13);

           /* Handle a 26 bit immediate at 31.  */
           case 'D':
             num = pa_get_absolute_expression (&the_insn, &s);
             if (strict && the_insn.exp.X_op != O_constant)
              break;
             s = expr_end;
             CHECK_FIELD (num, 67108863, 0, strict);
             INSERT_FIELD_AND_CONTINUE (opcode, num, 0);

           /* Handle a 3 bit SFU identifier at 25.  */
           case 'v':
             if (*s++ != ',')
              as_bad (_("Invalid SFU identifier"));
             num = pa_get_absolute_expression (&the_insn, &s);
             if (strict && the_insn.exp.X_op != O_constant)
              break;
             s = expr_end;
             CHECK_FIELD (num, 7, 0, strict);
             INSERT_FIELD_AND_CONTINUE (opcode, num, 6);

           /* Handle a 20 bit SOP field for spop0.  */
           case 'O':
             num = pa_get_absolute_expression (&the_insn, &s);
             if (strict && the_insn.exp.X_op != O_constant)
              break;
             s = expr_end;
             CHECK_FIELD (num, 1048575, 0, strict);
             num = (num & 0x1f) | ((num & 0x000fffe0) << 6);
             INSERT_FIELD_AND_CONTINUE (opcode, num, 0);

           /* Handle a 15bit SOP field for spop1.  */
           case 'o':
             num = pa_get_absolute_expression (&the_insn, &s);
             if (strict && the_insn.exp.X_op != O_constant)
              break;
             s = expr_end;
             CHECK_FIELD (num, 32767, 0, strict);
             INSERT_FIELD_AND_CONTINUE (opcode, num, 11);

           /* Handle a 10bit SOP field for spop3.  */
           case '0':
             num = pa_get_absolute_expression (&the_insn, &s);
             if (strict && the_insn.exp.X_op != O_constant)
              break;
             s = expr_end;
             CHECK_FIELD (num, 1023, 0, strict);
             num = (num & 0x1f) | ((num & 0x000003e0) << 6);
             INSERT_FIELD_AND_CONTINUE (opcode, num, 0);

           /* Handle a 15 bit SOP field for spop2.  */
           case '1':
             num = pa_get_absolute_expression (&the_insn, &s);
             if (strict && the_insn.exp.X_op != O_constant)
              break;
             s = expr_end;
             CHECK_FIELD (num, 32767, 0, strict);
             num = (num & 0x1f) | ((num & 0x00007fe0) << 6);
             INSERT_FIELD_AND_CONTINUE (opcode, num, 0);

           /* Handle a 3-bit co-processor ID field.  */
           case 'u':
             if (*s++ != ',')
              as_bad (_("Invalid COPR identifier"));
             num = pa_get_absolute_expression (&the_insn, &s);
             if (strict && the_insn.exp.X_op != O_constant)
              break;
             s = expr_end;
             CHECK_FIELD (num, 7, 0, strict);
             INSERT_FIELD_AND_CONTINUE (opcode, num, 6);

           /* Handle a 22bit SOP field for copr.  */
           case '2':
             num = pa_get_absolute_expression (&the_insn, &s);
             if (strict && the_insn.exp.X_op != O_constant)
              break;
             s = expr_end;
             CHECK_FIELD (num, 4194303, 0, strict);
             num = (num & 0x1f) | ((num & 0x003fffe0) << 4);
             INSERT_FIELD_AND_CONTINUE (opcode, num, 0);

           /* Handle a source FP operand format completer.  */
           case '{':
             if (*s == ',' && *(s+1) == 't')
              {
                the_insn.trunc = 1;
                s += 2;
              }
             else
              the_insn.trunc = 0;
             flag = pa_parse_fp_cnv_format (&s);
             the_insn.fpof1 = flag;
             if (flag == W || flag == UW)
              flag = SGL;
             if (flag == DW || flag == UDW)
              flag = DBL;
             if (flag == QW || flag == UQW)
              flag = QUAD;
             INSERT_FIELD_AND_CONTINUE (opcode, flag, 11);

           /* Handle a destination FP operand format completer.  */
           case '_':
             /* pa_parse_format needs the ',' prefix.  */
             s--;
             flag = pa_parse_fp_cnv_format (&s);
             the_insn.fpof2 = flag;
             if (flag == W || flag == UW)
              flag = SGL;
             if (flag == DW || flag == UDW)
              flag = DBL;
             if (flag == QW || flag == UQW)
              flag = QUAD;
             opcode |= flag << 13;
             if (the_insn.fpof1 == SGL
                || the_insn.fpof1 == DBL
                || the_insn.fpof1 == QUAD)
              {
                if (the_insn.fpof2 == SGL
                    || the_insn.fpof2 == DBL
                    || the_insn.fpof2 == QUAD)
                  flag = 0;
                else if (the_insn.fpof2 == W
                    || the_insn.fpof2 == DW
                    || the_insn.fpof2 == QW)
                  flag = 2;
                else if (the_insn.fpof2 == UW
                    || the_insn.fpof2 == UDW
                    || the_insn.fpof2 == UQW)
                  flag = 6;
                else
                  abort ();
              }
             else if (the_insn.fpof1 == W
                     || the_insn.fpof1 == DW
                     || the_insn.fpof1 == QW)
              {
                if (the_insn.fpof2 == SGL
                    || the_insn.fpof2 == DBL
                    || the_insn.fpof2 == QUAD)
                  flag = 1;
                else
                  abort ();
              }
             else if (the_insn.fpof1 == UW
                     || the_insn.fpof1 == UDW
                     || the_insn.fpof1 == UQW)
              {
                if (the_insn.fpof2 == SGL
                    || the_insn.fpof2 == DBL
                    || the_insn.fpof2 == QUAD)
                  flag = 5;
                else
                  abort ();
              }
             flag |= the_insn.trunc;
             INSERT_FIELD_AND_CONTINUE (opcode, flag, 15);

           /* Handle a source FP operand format completer.  */
           case 'F':
             flag = pa_parse_fp_format (&s);
             the_insn.fpof1 = flag;
             INSERT_FIELD_AND_CONTINUE (opcode, flag, 11);

           /* Handle a destination FP operand format completer.  */
           case 'G':
             /* pa_parse_format needs the ',' prefix.  */
             s--;
             flag = pa_parse_fp_format (&s);
             the_insn.fpof2 = flag;
             INSERT_FIELD_AND_CONTINUE (opcode, flag, 13);

           /* Handle a source FP operand format completer at 20.  */
           case 'I':
             flag = pa_parse_fp_format (&s);
             the_insn.fpof1 = flag;
             INSERT_FIELD_AND_CONTINUE (opcode, flag, 11);

           /* Handle a floating point operand format at 26.
              Only allows single and double precision.  */
           case 'H':
             flag = pa_parse_fp_format (&s);
             switch (flag)
              {
              case SGL:
                opcode |= 0x20;
              case DBL:
                the_insn.fpof1 = flag;
                continue;

              case QUAD:
              case ILLEGAL_FMT:
              default:
                as_bad (_("Invalid Floating Point Operand Format."));
              }
             break;

           /* Handle all floating point registers.  */
           case 'f':
             switch (*++args)
               {
              /* Float target register.  */
              case 't':
                if (!pa_parse_number (&s, 3))
                  break;
                num = (pa_number & ~FP_REG_RSEL) - FP_REG_BASE;
                CHECK_FIELD (num, 31, 0, 0);
                INSERT_FIELD_AND_CONTINUE (opcode, num, 0);

              /* Float target register with L/R selection.  */
              case 'T':
                {
                  if (!pa_parse_number (&s, 1))
                    break;
                  num = (pa_number & ~FP_REG_RSEL) - FP_REG_BASE;
                  CHECK_FIELD (num, 31, 0, 0);
                  opcode |= num;

                  /* 0x30 opcodes are FP arithmetic operation opcodes
                     and need to be turned into 0x38 opcodes.  This
                     is not necessary for loads/stores.  */
                  if (need_pa11_opcode ()
                     && ((opcode & 0xfc000000) == 0x30000000))
                    opcode |= 1 << 27;

                  opcode |= (pa_number & FP_REG_RSEL ? 1 << 6 : 0);
                  continue;
                }

              /* Float operand 1.  */
              case 'a':
                {
                  if (!pa_parse_number (&s, 1))
                    break;
                  num = (pa_number & ~FP_REG_RSEL) - FP_REG_BASE;
                  CHECK_FIELD (num, 31, 0, 0);
                  opcode |= num << 21;
                  if (need_pa11_opcode ())
                    {
                     opcode |= (pa_number & FP_REG_RSEL ? 1 << 7 : 0);
                     opcode |= 1 << 27;
                    }
                  continue;
                }

              /* Float operand 1 with L/R selection.  */
              case 'X':
              case 'A':
                {
                  if (!pa_parse_number (&s, 1))
                    break;
                  num = (pa_number & ~FP_REG_RSEL) - FP_REG_BASE;
                  CHECK_FIELD (num, 31, 0, 0);
                  opcode |= num << 21;
                  opcode |= (pa_number & FP_REG_RSEL ? 1 << 7 : 0);
                  continue;
                }

              /* Float operand 2.  */
              case 'b':
                {
                  if (!pa_parse_number (&s, 1))
                    break;
                  num = (pa_number & ~FP_REG_RSEL) - FP_REG_BASE;
                  CHECK_FIELD (num, 31, 0, 0);
                  opcode |= num << 16;
                  if (need_pa11_opcode ())
                    {
                     opcode |= (pa_number & FP_REG_RSEL ? 1 << 12 : 0);
                     opcode |= 1 << 27;
                    }
                  continue;
                }

              /* Float operand 2 with L/R selection.  */
              case 'B':
                {
                  if (!pa_parse_number (&s, 1))
                    break;
                  num = (pa_number & ~FP_REG_RSEL) - FP_REG_BASE;
                  CHECK_FIELD (num, 31, 0, 0);
                  opcode |= num << 16;
                  opcode |= (pa_number & FP_REG_RSEL ? 1 << 12 : 0);
                  continue;
                }

              /* Float operand 3 for fmpyfadd, fmpynfadd.  */
              case 'C':
                {
                  if (!pa_parse_number (&s, 1))
                    break;
                  num = (pa_number & ~FP_REG_RSEL) - FP_REG_BASE;
                  CHECK_FIELD (num, 31, 0, 0);
                  opcode |= (num & 0x1c) << 11;
                  opcode |= (num & 0x03) << 9;
                  opcode |= (pa_number & FP_REG_RSEL ? 1 << 8 : 0);
                  continue;
                }

              /* Float mult operand 1 for fmpyadd, fmpysub */
              case 'i':
                {
                  if (!pa_parse_number (&s, 1))
                    break;
                  num = (pa_number & ~FP_REG_RSEL) - FP_REG_BASE;
                  CHECK_FIELD (num, 31, 0, 0);
                  if (the_insn.fpof1 == SGL)
                    {
                     if (num < 16)
                       {
                         as_bad  (_("Invalid register for single precision fmpyadd or fmpysub"));
                         break;
                       }
                     num &= 0xF;
                     num |= (pa_number & FP_REG_RSEL ? 1 << 4 : 0);
                    }
                  INSERT_FIELD_AND_CONTINUE (opcode, num, 21);
                }

              /* Float mult operand 2 for fmpyadd, fmpysub */
              case 'j':
                {
                  if (!pa_parse_number (&s, 1))
                    break;
                  num = (pa_number & ~FP_REG_RSEL) - FP_REG_BASE;
                  CHECK_FIELD (num, 31, 0, 0);
                  if (the_insn.fpof1 == SGL)
                    {
                      if (num < 16)
                        {
                         as_bad  (_("Invalid register for single precision fmpyadd or fmpysub"));
                         break;
                        }
                      num &= 0xF;
                      num |= (pa_number & FP_REG_RSEL ? 1 << 4 : 0);
                    }
                  INSERT_FIELD_AND_CONTINUE (opcode, num, 16);
                }

              /* Float mult target for fmpyadd, fmpysub */
              case 'k':
                {
                  if (!pa_parse_number (&s, 1))
                    break;
                  num = (pa_number & ~FP_REG_RSEL) - FP_REG_BASE;
                  CHECK_FIELD (num, 31, 0, 0);
                  if (the_insn.fpof1 == SGL)
                    {
                      if (num < 16)
                        {
                         as_bad  (_("Invalid register for single precision fmpyadd or fmpysub"));
                         break;
                        }
                      num &= 0xF;
                      num |= (pa_number & FP_REG_RSEL ? 1 << 4 : 0);
                    }
                  INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
                }

              /* Float add operand 1 for fmpyadd, fmpysub */
              case 'l':
                {
                  if (!pa_parse_number (&s, 1))
                    break;
                  num = (pa_number & ~FP_REG_RSEL) - FP_REG_BASE;
                  CHECK_FIELD (num, 31, 0, 0);
                  if (the_insn.fpof1 == SGL)
                    {
                      if (num < 16)
                        {
                         as_bad  (_("Invalid register for single precision fmpyadd or fmpysub"));
                         break;
                        }
                      num &= 0xF;
                      num |= (pa_number & FP_REG_RSEL ? 1 << 4 : 0);
                    }
                  INSERT_FIELD_AND_CONTINUE (opcode, num, 6);
                }

              /* Float add target for fmpyadd, fmpysub */
              case 'm':
                {
                  if (!pa_parse_number (&s, 1))
                    break;
                  num = (pa_number & ~FP_REG_RSEL) - FP_REG_BASE;
                  CHECK_FIELD (num, 31, 0, 0);
                  if (the_insn.fpof1 == SGL)
                    {
                      if (num < 16)
                        {
                         as_bad  (_("Invalid register for single precision fmpyadd or fmpysub"));
                         break;
                        }
                      num &= 0xF;
                      num |= (pa_number & FP_REG_RSEL ? 1 << 4 : 0);
                    }
                  INSERT_FIELD_AND_CONTINUE (opcode, num, 11);
                }

              /* Handle L/R register halves like 'x'.  */
              case 'E':
              case 'e':
                {
                  if (!pa_parse_number (&s, 1))
                    break;
                  num = (pa_number & ~FP_REG_RSEL) - FP_REG_BASE;
                  CHECK_FIELD (num, 31, 0, 0);
                  opcode |= num << 16;
                  if (need_pa11_opcode ())
                    {
                     opcode |= (pa_number & FP_REG_RSEL ? 1 << 1 : 0);
                    }
                  continue;
                }

              /* Float target register (PA 2.0 wide).  */
              case 'x':
                if (!pa_parse_number (&s, 3))
                  break;
                num = (pa_number & ~FP_REG_RSEL) - FP_REG_BASE;
                CHECK_FIELD (num, 31, 0, 0);
                INSERT_FIELD_AND_CONTINUE (opcode, num, 16);

              default:
                abort ();
              }
             break;

           default:
             abort ();
           }
         break;
       }

      /* If this instruction is specific to a particular architecture,
        then set a new architecture.  This automatic promotion crud is
        for compatibility with HP's old assemblers only.  */
      if (match == TRUE
         && bfd_get_mach (stdoutput) < insn->arch
         && !bfd_set_arch_mach (stdoutput, bfd_arch_hppa, insn->arch))
       {
         as_warn (_("could not update architecture and machine"));
         match = FALSE;
       }

 failed:
      /* Check if the args matched.  */
      if (!match)
       {
         if (&insn[1] - pa_opcodes < (int) NUMOPCODES
             && !strcmp (insn->name, insn[1].name))
           {
             ++insn;
             s = argstart;
             continue;
           }
         else
           {
             as_bad (_("Invalid operands %s"), error_message);
             return;
           }
       }
      break;
    }

  the_insn.opcode = opcode;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void pa_label ( int unused  ATTRIBUTE_UNUSED) [static]

Definition at line 6787 of file tc-hppa.c.

{
  char *name, c, *p;

  name = input_line_pointer;
  c = get_symbol_end ();

  if (strlen (name) > 0)
    {
      colon (name);
      p = input_line_pointer;
      *p = c;
    }
  else
    {
      as_warn (_("Missing label name on .LABEL"));
    }

  if (!is_end_of_statement ())
    {
      as_warn (_("extra .LABEL arguments ignored."));
      ignore_rest_of_line ();
    }
  demand_empty_rest_of_line ();
}

Here is the call graph for this function:

static void pa_lcomm ( int  needs_align) [static]

Definition at line 8224 of file tc-hppa.c.

{
#ifdef OBJ_SOM
  /* We must have a valid space and subspace.  */
  pa_check_current_space_and_subspace ();
#endif

  s_lcomm (needs_align);
  pa_undefine_label ();
}

Here is the call graph for this function:

static void pa_leave ( int unused  ATTRIBUTE_UNUSED) [static]

Definition at line 6816 of file tc-hppa.c.

{
#ifdef OBJ_SOM
  /* We must have a valid space and subspace.  */
  pa_check_current_space_and_subspace ();
#endif

  as_bad (_("The .LEAVE pseudo-op is not supported"));
  demand_empty_rest_of_line ();
}

Here is the call graph for this function:

static void pa_level ( int unused  ATTRIBUTE_UNUSED) [static]

Definition at line 6830 of file tc-hppa.c.

{
  char *level;

  level = input_line_pointer;
  if (strncmp (level, "1.0", 3) == 0)
    {
      input_line_pointer += 3;
      if (!bfd_set_arch_mach (stdoutput, bfd_arch_hppa, 10))
       as_warn (_("could not set architecture and machine"));
    }
  else if (strncmp (level, "1.1", 3) == 0)
    {
      input_line_pointer += 3;
      if (!bfd_set_arch_mach (stdoutput, bfd_arch_hppa, 11))
       as_warn (_("could not set architecture and machine"));
    }
  else if (strncmp (level, "2.0w", 4) == 0)
    {
      input_line_pointer += 4;
      if (!bfd_set_arch_mach (stdoutput, bfd_arch_hppa, 25))
       as_warn (_("could not set architecture and machine"));
    }
  else if (strncmp (level, "2.0", 3) == 0)
    {
      input_line_pointer += 3;
      if (!bfd_set_arch_mach (stdoutput, bfd_arch_hppa, 20))
       as_warn (_("could not set architecture and machine"));
    }
  else
    {
      as_bad (_("Unrecognized .LEVEL argument\n"));
      ignore_rest_of_line ();
    }
  demand_empty_rest_of_line ();
}

Here is the call graph for this function:

static void pa_lsym ( int unused  ATTRIBUTE_UNUSED) [static]

Definition at line 8238 of file tc-hppa.c.

{
#ifdef OBJ_SOM
  /* We must have a valid space and subspace.  */
  pa_check_current_space_and_subspace ();
#endif

  s_lsym (0);
  pa_undefine_label ();
}

Here is the call graph for this function:

static void pa_origin ( int unused  ATTRIBUTE_UNUSED) [static]

Definition at line 6870 of file tc-hppa.c.

{
#ifdef OBJ_SOM
  /* We must have a valid space and subspace.  */
  pa_check_current_space_and_subspace ();
#endif

  s_org (0);
  pa_undefine_label ();
}

Here is the call graph for this function:

static void pa_param ( int unused  ATTRIBUTE_UNUSED) [static]

Definition at line 6885 of file tc-hppa.c.

{
  char *name, c, *p;
  symbolS *symbol;

  name = input_line_pointer;
  c = get_symbol_end ();

  if ((symbol = symbol_find_or_make (name)) == NULL)
    {
      as_bad (_("Cannot define static symbol: %s\n"), name);
      p = input_line_pointer;
      *p = c;
      input_line_pointer++;
    }
  else
    {
      S_CLEAR_EXTERNAL (symbol);
      p = input_line_pointer;
      *p = c;
      if (!is_end_of_statement ())
       {
         input_line_pointer++;
         pa_type_args (symbol, 0);
       }
    }

  demand_empty_rest_of_line ();
}

Here is the call graph for this function:

static int pa_parse_addb_64_cmpltr ( char **  s) [static]

Definition at line 3117 of file tc-hppa.c.

{
  int cmpltr;
  char *name = *s + 1;
  char c;
  char *save_s = *s;
  int nullify = 0;

  cmpltr = 0;
  if (**s == ',')
    {
      *s += 1;
      while (**s != ',' && **s != ' ' && **s != '\t')
       *s += 1;
      c = **s;
      **s = 0x00;
      if (strcmp (name, "=") == 0)
       {
         cmpltr = 1;
       }
      else if (strcmp (name, "<") == 0)
       {
         cmpltr = 2;
       }
      else if (strcmp (name, "<=") == 0)
       {
         cmpltr = 3;
       }
      else if (strcasecmp (name, "nuv") == 0)
       {
         cmpltr = 4;
       }
      else if (strcasecmp (name, "*=") == 0)
       {
         cmpltr = 5;
       }
      else if (strcasecmp (name, "*<") == 0)
       {
         cmpltr = 6;
       }
      else if (strcasecmp (name, "*<=") == 0)
       {
         cmpltr = 7;
       }
      else if (strcmp (name, "tr") == 0)
       {
         cmpltr = 8;
       }
      else if (strcmp (name, "<>") == 0)
       {
         cmpltr = 9;
       }
      else if (strcmp (name, ">=") == 0)
       {
         cmpltr = 10;
       }
      else if (strcmp (name, ">") == 0)
       {
         cmpltr = 11;
       }
      else if (strcasecmp (name, "uv") == 0)
       {
         cmpltr = 12;
       }
      else if (strcasecmp (name, "*<>") == 0)
       {
         cmpltr = 13;
       }
      else if (strcasecmp (name, "*>=") == 0)
       {
         cmpltr = 14;
       }
      else if (strcasecmp (name, "*>") == 0)
       {
         cmpltr = 15;
       }
      /* If we have something like addb,n then there is no condition
         completer.  */
      else if (strcasecmp (name, "n") == 0)
       {
         cmpltr = 0;
         nullify = 1;
       }
      else
       {
         cmpltr = -1;
       }
      **s = c;
    }

  /* Reset pointers if this was really a ,n for a branch instruction.  */
  if (nullify)
    *s = save_s;

  return cmpltr;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int pa_parse_cmpb_64_cmpltr ( char **  s) [static]

Definition at line 2821 of file tc-hppa.c.

{
  int cmpltr;
  char *name = *s + 1;
  char c;

  cmpltr = -1;
  if (**s == ',')
    {
      *s += 1;
      while (**s != ',' && **s != ' ' && **s != '\t')
       *s += 1;
      c = **s;
      **s = 0x00;

      if (strcmp (name, "*") == 0)
       {
         cmpltr = 0;
       }
      else if (strcmp (name, "*=") == 0)
       {
         cmpltr = 1;
       }
      else if (strcmp (name, "*<") == 0)
       {
         cmpltr = 2;
       }
      else if (strcmp (name, "*<=") == 0)
       {
         cmpltr = 3;
       }
      else if (strcmp (name, "*<<") == 0)
       {
         cmpltr = 4;
       }
      else if (strcmp (name, "*<<=") == 0)
       {
         cmpltr = 5;
       }
      else if (strcasecmp (name, "*sv") == 0)
       {
         cmpltr = 6;
       }
      else if (strcasecmp (name, "*od") == 0)
       {
         cmpltr = 7;
       }
      else if (strcasecmp (name, "*tr") == 0)
       {
         cmpltr = 8;
       }
      else if (strcmp (name, "*<>") == 0)
       {
         cmpltr = 9;
       }
      else if (strcmp (name, "*>=") == 0)
       {
         cmpltr = 10;
       }
      else if (strcmp (name, "*>") == 0)
       {
         cmpltr = 11;
       }
      else if (strcmp (name, "*>>=") == 0)
       {
         cmpltr = 12;
       }
      else if (strcmp (name, "*>>") == 0)
       {
         cmpltr = 13;
       }
      else if (strcasecmp (name, "*nsv") == 0)
       {
         cmpltr = 14;
       }
      else if (strcasecmp (name, "*ev") == 0)
       {
         cmpltr = 15;
       }
      else
       {
         cmpltr = -1;
       }
      **s = c;
    }

  return cmpltr;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int pa_parse_cmpib_64_cmpltr ( char **  s) [static]

Definition at line 2914 of file tc-hppa.c.

{
  int cmpltr;
  char *name = *s + 1;
  char c;

  cmpltr = -1;
  if (**s == ',')
    {
      *s += 1;
      while (**s != ',' && **s != ' ' && **s != '\t')
       *s += 1;
      c = **s;
      **s = 0x00;

      if (strcmp (name, "*<<") == 0)
       {
         cmpltr = 0;
       }
      else if (strcmp (name, "*=") == 0)
       {
         cmpltr = 1;
       }
      else if (strcmp (name, "*<") == 0)
       {
         cmpltr = 2;
       }
      else if (strcmp (name, "*<=") == 0)
       {
         cmpltr = 3;
       }
      else if (strcmp (name, "*>>=") == 0)
       {
         cmpltr = 4;
       }
      else if (strcmp (name, "*<>") == 0)
       {
         cmpltr = 5;
       }
      else if (strcasecmp (name, "*>=") == 0)
       {
         cmpltr = 6;
       }
      else if (strcasecmp (name, "*>") == 0)
       {
         cmpltr = 7;
       }
      else
       {
         cmpltr = -1;
       }
      **s = c;
    }

  return cmpltr;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int pa_parse_fp_cmp_cond ( char **  s) [static]

Definition at line 2290 of file tc-hppa.c.

{
  int cond, i;

  cond = 0;

  for (i = 0; i < 32; i++)
    {
      if (strncasecmp (*s, fp_cond_map[i].string,
                     strlen (fp_cond_map[i].string)) == 0)
       {
         cond = fp_cond_map[i].cond;
         *s += strlen (fp_cond_map[i].string);
         /* If not a complete match, back up the input string and
            report an error.  */
         if (**s != ' ' && **s != '\t')
           {
             *s -= strlen (fp_cond_map[i].string);
             break;
           }
         while (**s == ' ' || **s == '\t')
           *s = *s + 1;
         return cond;
       }
    }

  as_bad (_("Invalid FP Compare Condition: %s"), *s);

  /* Advance over the bogus completer.  */
  while (**s != ',' && **s != ' ' && **s != '\t')
    *s += 1;

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static fp_operand_format pa_parse_fp_cnv_format ( char **  s) [static]

Definition at line 2381 of file tc-hppa.c.

{
  int format;

  format = SGL;
  if (**s == ',')
    {
      *s += 1;
      if (strncasecmp (*s, "sgl", 3) == 0)
       {
         format = SGL;
         *s += 4;
       }
      else if (strncasecmp (*s, "dbl", 3) == 0)
       {
         format = DBL;
         *s += 4;
       }
      else if (strncasecmp (*s, "quad", 4) == 0)
       {
         format = QUAD;
         *s += 5;
       }
      else if (strncasecmp (*s, "w", 1) == 0)
       {
         format = W;
         *s += 2;
       }
      else if (strncasecmp (*s, "uw", 2) == 0)
       {
         format = UW;
         *s += 3;
       }
      else if (strncasecmp (*s, "dw", 2) == 0)
       {
         format = DW;
         *s += 3;
       }
      else if (strncasecmp (*s, "udw", 3) == 0)
       {
         format = UDW;
         *s += 4;
       }
      else if (strncasecmp (*s, "qw", 2) == 0)
       {
         format = QW;
         *s += 3;
       }
      else if (strncasecmp (*s, "uqw", 3) == 0)
       {
         format = UQW;
         *s += 4;
       }
      else
       {
         format = ILLEGAL_FMT;
         as_bad (_("Invalid FP Operand Format: %3s"), *s);
       }
    }

  return format;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static fp_operand_format pa_parse_fp_format ( char **  s) [static]

Definition at line 2448 of file tc-hppa.c.

{
  int format;

  format = SGL;
  if (**s == ',')
    {
      *s += 1;
      if (strncasecmp (*s, "sgl", 3) == 0)
       {
         format = SGL;
         *s += 4;
       }
      else if (strncasecmp (*s, "dbl", 3) == 0)
       {
         format = DBL;
         *s += 4;
       }
      else if (strncasecmp (*s, "quad", 4) == 0)
       {
         format = QUAD;
         *s += 5;
       }
      else
       {
         format = ILLEGAL_FMT;
         as_bad (_("Invalid FP Operand Format: %3s"), *s);
       }
    }

  return format;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int pa_parse_ftest_gfx_completer ( char **  s) [static]

Definition at line 2328 of file tc-hppa.c.

{
  int value;

  value = 0;
  if (strncasecmp (*s, "acc8", 4) == 0)
    {
      value = 5;
      *s += 4;
    }
  else if (strncasecmp (*s, "acc6", 4) == 0)
    {
      value = 9;
      *s += 4;
    }
  else if (strncasecmp (*s, "acc4", 4) == 0)
    {
      value = 13;
      *s += 4;
    }
  else if (strncasecmp (*s, "acc2", 4) == 0)
    {
      value = 17;
      *s += 4;
    }
  else if (strncasecmp (*s, "acc", 3) == 0)
    {
      value = 1;
      *s += 3;
    }
  else if (strncasecmp (*s, "rej8", 4) == 0)
    {
      value = 6;
      *s += 4;
    }
  else if (strncasecmp (*s, "rej", 3) == 0)
    {
      value = 2;
      *s += 3;
    }
  else
    {
      value = 0;
      as_bad (_("Invalid FTEST completer: %s"), *s);
    }

  return value;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int pa_parse_neg_add_cmpltr ( char **  s) [static]

Definition at line 3044 of file tc-hppa.c.

{
  int cmpltr;
  char *name = *s + 1;
  char c;
  char *save_s = *s;
  int nullify = 0;

  cmpltr = 0;
  if (**s == ',')
    {
      *s += 1;
      while (**s != ',' && **s != ' ' && **s != '\t')
       *s += 1;
      c = **s;
      **s = 0x00;
      if (strcasecmp (name, "tr") == 0)
       {
         cmpltr = 0;
       }
      else if (strcmp (name, "<>") == 0)
       {
         cmpltr = 1;
       }
      else if (strcmp (name, ">=") == 0)
       {
         cmpltr = 2;
       }
      else if (strcmp (name, ">") == 0)
       {
         cmpltr = 3;
       }
      else if (strcasecmp (name, "uv") == 0)
       {
         cmpltr = 4;
       }
      else if (strcasecmp (name, "vnz") == 0)
       {
         cmpltr = 5;
       }
      else if (strcasecmp (name, "nsv") == 0)
       {
         cmpltr = 6;
       }
      else if (strcasecmp (name, "ev") == 0)
       {
         cmpltr = 7;
       }
      /* If we have something like addb,n then there is no condition
         completer.  */
      else if (strcasecmp (name, "n") == 0)
       {
         cmpltr = 0;
         nullify = 1;
       }
      else
       {
         cmpltr = -1;
       }
      **s = c;
    }

  /* Reset pointers if this was really a ,n for a branch instruction.  */
  if (nullify)
    *s = save_s;

  return cmpltr;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int pa_parse_neg_cmpsub_cmpltr ( char **  s) [static]

Definition at line 2744 of file tc-hppa.c.

{
  int cmpltr;
  char *name = *s + 1;
  char c;
  char *save_s = *s;
  int nullify = 0;

  cmpltr = 0;
  if (**s == ',')
    {
      *s += 1;
      while (**s != ',' && **s != ' ' && **s != '\t')
       *s += 1;
      c = **s;
      **s = 0x00;

      if (strcasecmp (name, "tr") == 0)
       {
         cmpltr = 0;
       }
      else if (strcmp (name, "<>") == 0)
       {
         cmpltr = 1;
       }
      else if (strcmp (name, ">=") == 0)
       {
         cmpltr = 2;
       }
      else if (strcmp (name, ">") == 0)
       {
         cmpltr = 3;
       }
      else if (strcmp (name, ">>=") == 0)
       {
         cmpltr = 4;
       }
      else if (strcmp (name, ">>") == 0)
       {
         cmpltr = 5;
       }
      else if (strcasecmp (name, "nsv") == 0)
       {
         cmpltr = 6;
       }
      else if (strcasecmp (name, "ev") == 0)
       {
         cmpltr = 7;
       }
      /* If we have something like addb,n then there is no condition
         completer.  */
      else if (strcasecmp (name, "n") == 0)
       {
         cmpltr = 0;
         nullify = 1;
       }
      else
       {
         cmpltr = -1;
       }
      **s = c;
    }

  /* Reset pointers if this was really a ,n for a branch instruction.  */
  if (nullify)
    *s = save_s;

  return cmpltr;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int pa_parse_nonneg_add_cmpltr ( char **  s) [static]

Definition at line 2975 of file tc-hppa.c.

{
  int cmpltr;
  char *name = *s + 1;
  char c;
  char *save_s = *s;
  int nullify = 0;

  cmpltr = 0;
  if (**s == ',')
    {
      *s += 1;
      while (**s != ',' && **s != ' ' && **s != '\t')
       *s += 1;
      c = **s;
      **s = 0x00;
      if (strcmp (name, "=") == 0)
       {
         cmpltr = 1;
       }
      else if (strcmp (name, "<") == 0)
       {
         cmpltr = 2;
       }
      else if (strcmp (name, "<=") == 0)
       {
         cmpltr = 3;
       }
      else if (strcasecmp (name, "nuv") == 0)
       {
         cmpltr = 4;
       }
      else if (strcasecmp (name, "znv") == 0)
       {
         cmpltr = 5;
       }
      else if (strcasecmp (name, "sv") == 0)
       {
         cmpltr = 6;
       }
      else if (strcasecmp (name, "od") == 0)
       {
         cmpltr = 7;
       }
      /* If we have something like addb,n then there is no condition
         completer.  */
      else if (strcasecmp (name, "n") == 0)
       {
         cmpltr = 0;
         nullify = 1;
       }
      else
       {
         cmpltr = -1;
       }
      **s = c;
    }

  /* Reset pointers if this was really a ,n for a branch instruction.  */
  if (nullify)
    *s = save_s;

  return cmpltr;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int pa_parse_nonneg_cmpsub_cmpltr ( char **  s) [static]

Definition at line 2674 of file tc-hppa.c.

{
  int cmpltr;
  char *name = *s + 1;
  char c;
  char *save_s = *s;
  int nullify = 0;

  cmpltr = 0;
  if (**s == ',')
    {
      *s += 1;
      while (**s != ',' && **s != ' ' && **s != '\t')
       *s += 1;
      c = **s;
      **s = 0x00;

      if (strcmp (name, "=") == 0)
       {
         cmpltr = 1;
       }
      else if (strcmp (name, "<") == 0)
       {
         cmpltr = 2;
       }
      else if (strcmp (name, "<=") == 0)
       {
         cmpltr = 3;
       }
      else if (strcmp (name, "<<") == 0)
       {
         cmpltr = 4;
       }
      else if (strcmp (name, "<<=") == 0)
       {
         cmpltr = 5;
       }
      else if (strcasecmp (name, "sv") == 0)
       {
         cmpltr = 6;
       }
      else if (strcasecmp (name, "od") == 0)
       {
         cmpltr = 7;
       }
      /* If we have something like addb,n then there is no condition
         completer.  */
      else if (strcasecmp (name, "n") == 0)
       {
         cmpltr = 0;
         nullify = 1;
       }
      else
       {
         cmpltr = -1;
       }
      **s = c;
    }

  /* Reset pointers if this was really a ,n for a branch instruction.  */
  if (nullify)
    *s = save_s;

  return cmpltr;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int pa_parse_nullif ( char **  s) [static]

Definition at line 1317 of file tc-hppa.c.

{
  int nullif;

  nullif = 0;
  if (**s == ',')
    {
      *s = *s + 1;
      if (strncasecmp (*s, "n", 1) == 0)
       nullif = 1;
      else
       {
         as_bad (_("Invalid Nullification: (%c)"), **s);
         nullif = 0;
       }
      *s = *s + 1;
    }

  return nullif;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int pa_parse_number ( char **  s,
int  is_float 
) [static]

Definition at line 2078 of file tc-hppa.c.

{
  int num;
  char *name;
  char c;
  symbolS *sym;
  int status;
  char *p = *s;
  bfd_boolean have_prefix;

  /* Skip whitespace before the number.  */
  while (*p == ' ' || *p == '\t')
    p = p + 1;

  pa_number = -1;
  have_prefix = 0;
  num = 0;
  if (!strict && ISDIGIT (*p))
    {
      /* Looks like a number.  */

      if (*p == '0' && (*(p + 1) == 'x' || *(p + 1) == 'X'))
       {
         /* The number is specified in hex.  */
         p += 2;
         while (ISDIGIT (*p) || ((*p >= 'a') && (*p <= 'f'))
               || ((*p >= 'A') && (*p <= 'F')))
           {
             if (ISDIGIT (*p))
              num = num * 16 + *p - '0';
             else if (*p >= 'a' && *p <= 'f')
              num = num * 16 + *p - 'a' + 10;
             else
              num = num * 16 + *p - 'A' + 10;
             ++p;
           }
       }
      else
       {
         /* The number is specified in decimal.  */
         while (ISDIGIT (*p))
           {
             num = num * 10 + *p - '0';
             ++p;
           }
       }

      pa_number = num;

      /* Check for a `l' or `r' suffix.  */
      if (is_float)
       {
         pa_number += FP_REG_BASE;
         if (! (is_float & 2))
           {
             if (IS_R_SELECT (p))
              {
                pa_number += FP_REG_RSEL;
                ++p;
              }
             else if (IS_L_SELECT (p))
              {
                ++p;
              }
           }
       }
    }
  else if (*p == '%')
    {
      /* The number might be a predefined register.  */
      have_prefix = 1;
      name = p;
      p++;
      c = *p;
      /* Tege hack: Special case for general registers as the general
         code makes a binary search with case translation, and is VERY
         slow.  */
      if (c == 'r')
       {
         p++;
         if (*p == 'e' && *(p + 1) == 't'
             && (*(p + 2) == '0' || *(p + 2) == '1'))
           {
             p += 2;
             num = *p - '0' + 28;
             p++;
           }
         else if (*p == 'p')
           {
             num = 2;
             p++;
           }
         else if (!ISDIGIT (*p))
           {
             if (print_errors)
              as_bad (_("Undefined register: '%s'."), name);
             num = -1;
           }
         else
           {
             do
              num = num * 10 + *p++ - '0';
             while (ISDIGIT (*p));
           }
       }
      else
       {
         /* Do a normal register search.  */
         while (is_part_of_name (c))
           {
             p = p + 1;
             c = *p;
           }
         *p = 0;
         status = reg_name_search (name);
         if (status >= 0)
           num = status;
         else
           {
             if (print_errors)
              as_bad (_("Undefined register: '%s'."), name);
             num = -1;
           }
         *p = c;
       }

      pa_number = num;
    }
  else
    {
      /* And finally, it could be a symbol in the absolute section which
         is effectively a constant, or a register alias symbol.  */
      name = p;
      c = *p;
      while (is_part_of_name (c))
       {
         p = p + 1;
         c = *p;
       }
      *p = 0;
      if ((sym = symbol_find (name)) != NULL)
       {
         if (S_GET_SEGMENT (sym) == reg_section)
           {
             num = S_GET_VALUE (sym);
             /* Well, we don't really have one, but we do have a
               register, so...  */
             have_prefix = TRUE;
           }
         else if (S_GET_SEGMENT (sym) == &bfd_abs_section)
           num = S_GET_VALUE (sym);
         else if (!strict)
           {
             if (print_errors)
              as_bad (_("Non-absolute symbol: '%s'."), name);
             num = -1;
           }
       }
      else if (!strict)
       {
         /* There is where we'd come for an undefined symbol
            or for an empty string.  For an empty string we
            will return zero.  That's a concession made for
            compatibility with the braindamaged HP assemblers.  */
         if (*name == 0)
           num = 0;
         else
           {
             if (print_errors)
              as_bad (_("Undefined absolute constant: '%s'."), name);
             num = -1;
           }
       }
      *p = c;

      pa_number = num;
    }

  if (!strict || have_prefix)
    {
      *s = p;
      return 1;
    }
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void pa_proc ( int unused  ATTRIBUTE_UNUSED) [static]

Definition at line 6919 of file tc-hppa.c.

{
  struct call_info *call_info;

#ifdef OBJ_SOM
  /* We must have a valid space and subspace.  */
  pa_check_current_space_and_subspace ();
#endif

  if (within_procedure)
    as_fatal (_("Nested procedures"));

  /* Reset global variables for new procedure.  */
  callinfo_found = FALSE;
  within_procedure = TRUE;

  /* Create another call_info structure.  */
  call_info = xmalloc (sizeof (struct call_info));

  if (!call_info)
    as_fatal (_("Cannot allocate unwind descriptor\n"));

  memset (call_info, 0, sizeof (struct call_info));

  call_info->ci_next = NULL;

  if (call_info_root == NULL)
    {
      call_info_root = call_info;
      last_call_info = call_info;
    }
  else
    {
      last_call_info->ci_next = call_info;
      last_call_info = call_info;
    }

  /* set up defaults on call_info structure */

  call_info->ci_unwind.descriptor.cannot_unwind = 0;
  call_info->ci_unwind.descriptor.region_desc = 1;
  call_info->ci_unwind.descriptor.hpux_interrupt_marker = 0;

  /* If we got a .PROC pseudo-op, we know that the function is defined
     locally.  Make sure it gets into the symbol table.  */
  {
    label_symbol_struct *label_symbol = pa_get_label ();

    if (label_symbol)
      {
       if (label_symbol->lss_label)
         {
           last_call_info->start_symbol = label_symbol->lss_label;
           symbol_get_bfdsym (label_symbol->lss_label)->flags |= BSF_FUNCTION;
         }
       else
         as_bad (_("Missing function name for .PROC (corrupted label chain)"));
      }
    else
      last_call_info->start_symbol = NULL;
  }

  demand_empty_rest_of_line ();
}

Here is the call graph for this function:

static void pa_procend ( int unused  ATTRIBUTE_UNUSED) [static]

Definition at line 6988 of file tc-hppa.c.

{
#ifdef OBJ_SOM
  /* We must have a valid space and subspace.  */
  pa_check_current_space_and_subspace ();
#endif

  /* If we are within a procedure definition, make sure we've
     defined a label for the procedure; handle case where the
     label was defined after the .PROC directive.

     Note there's not need to diddle with the segment or fragment
     for the label symbol in this case.  We have already switched
     into the new $CODE$ subspace at this point.  */
  if (within_procedure && last_call_info->start_symbol == NULL)
    {
      label_symbol_struct *label_symbol = pa_get_label ();

      if (label_symbol)
       {
         if (label_symbol->lss_label)
           {
             last_call_info->start_symbol = label_symbol->lss_label;
             symbol_get_bfdsym (label_symbol->lss_label)->flags
              |= BSF_FUNCTION;
#ifdef OBJ_SOM
             /* Also handle allocation of a fixup to hold the unwind
               information when the label appears after the proc/procend.  */
             if (within_entry_exit)
              {
                char *where;
                unsigned int u;

                where = frag_more (0);
                u = UNWIND_LOW32 (&last_call_info->ci_unwind.descriptor);
                fix_new_hppa (frag_now, where - frag_now->fr_literal, 0,
                            NULL, (offsetT) 0, NULL,
                            0, R_HPPA_ENTRY, e_fsel, 0, 0, u);
              }
#endif
           }
         else
           as_bad (_("Missing function name for .PROC (corrupted label chain)"));
       }
      else
       as_bad (_("Missing function name for .PROC"));
    }

  if (!within_procedure)
    as_bad (_("misplaced .procend"));

  if (!callinfo_found)
    as_bad (_("Missing .callinfo for this procedure"));

  if (within_entry_exit)
    as_bad (_("Missing .EXIT for a .ENTRY"));

#ifdef OBJ_ELF
  /* ELF needs to mark the end of each function so that it can compute
     the size of the function (apparently its needed in the symbol table).  */
  hppa_elf_mark_end_of_function ();
#endif

  within_procedure = FALSE;
  demand_empty_rest_of_line ();
  pa_undefine_label ();
}

Here is the call graph for this function:

static void pa_stringer ( int  append_zero) [static]

Definition at line 8079 of file tc-hppa.c.

{
  char *s, num_buf[4];
  unsigned int c;
  int i;

  /* Preprocess the string to handle PA-specific escape sequences.
     For example, \xDD where DD is a hexadecimal number should be
     changed to \OOO where OOO is an octal number.  */

#ifdef OBJ_SOM
  /* We must have a valid space and subspace.  */
  pa_check_current_space_and_subspace ();
#endif

  /* Skip the opening quote.  */
  s = input_line_pointer + 1;

  while (is_a_char (c = pa_stringer_aux (s++)))
    {
      if (c == '\\')
       {
         c = *s;
         switch (c)
           {
             /* Handle \x<num>.  */
           case 'x':
             {
              unsigned int number;
              int num_digit;
              char dg;
              char *s_start = s;

              /* Get past the 'x'.  */
              s++;
              for (num_digit = 0, number = 0, dg = *s;
                   num_digit < 2
                   && (ISDIGIT (dg) || (dg >= 'a' && dg <= 'f')
                      || (dg >= 'A' && dg <= 'F'));
                   num_digit++)
                {
                  if (ISDIGIT (dg))
                    number = number * 16 + dg - '0';
                  else if (dg >= 'a' && dg <= 'f')
                    number = number * 16 + dg - 'a' + 10;
                  else
                    number = number * 16 + dg - 'A' + 10;

                  s++;
                  dg = *s;
                }
              if (num_digit > 0)
                {
                  switch (num_digit)
                    {
                    case 1:
                     sprintf (num_buf, "%02o", number);
                     break;
                    case 2:
                     sprintf (num_buf, "%03o", number);
                     break;
                    }
                  for (i = 0; i <= num_digit; i++)
                    s_start[i] = num_buf[i];
                }
              break;
             }
           /* This might be a "\"", skip over the escaped char.  */
           default:
             s++;
             break;
           }
       }
    }
  stringer (append_zero);
  pa_undefine_label ();
}

Here is the call graph for this function:

static unsigned int pa_stringer_aux ( char *  s) [static]

Definition at line 8061 of file tc-hppa.c.

{
  unsigned int c = *s & CHAR_MASK;

  switch (c)
    {
    case '\"':
      c = NOT_A_CHAR;
      break;
    default:
      break;
    }
  return c;
}

Here is the caller graph for this function:

static void pa_text ( int  ) [static]
static void pa_text ( int unused  ATTRIBUTE_UNUSED) [static]

Definition at line 6193 of file tc-hppa.c.

{
#ifdef OBJ_SOM
  current_space = is_defined_space ("$TEXT$");
  current_subspace
    = pa_subsegment_to_subspace (current_space->sd_seg, 0);
#endif

  s_text (0);
  pa_undefine_label ();
}

Here is the call graph for this function:

static void pa_try ( int begin  ATTRIBUTE_UNUSED) [static]

Definition at line 5868 of file tc-hppa.c.

{
#ifdef OBJ_SOM
  expressionS exp;
  char *where = frag_more (0);

  if (! begin)
    expression (&exp);

  /* The TRY relocations are only available in SOM (to denote
     the beginning and end of exception handling regions).  */

  fix_new_hppa (frag_now, where - frag_now->fr_literal, 0,
              NULL, (offsetT) 0, begin ? NULL : &exp,
              0, begin ? R_HPPA_BEGIN_TRY : R_HPPA_END_TRY,
              e_fsel, 0, 0, 0);
#endif

  demand_empty_rest_of_line ();
}

Here is the call graph for this function:

static void pa_type_args ( symbolS *  symbolP,
int  is_export 
) [static]

Definition at line 6538 of file tc-hppa.c.

{
  char *name, c, *p;
  unsigned int temp, arg_reloc;
  pa_symbol_type type = SYMBOL_TYPE_UNKNOWN;
  asymbol *bfdsym = symbol_get_bfdsym (symbolP);

  if (strncasecmp (input_line_pointer, "absolute", 8) == 0)
    {
      input_line_pointer += 8;
      bfdsym->flags &= ~BSF_FUNCTION;
      S_SET_SEGMENT (symbolP, bfd_abs_section_ptr);
      type = SYMBOL_TYPE_ABSOLUTE;
    }
  else if (strncasecmp (input_line_pointer, "code", 4) == 0)
    {
      input_line_pointer += 4;
      /* IMPORTing/EXPORTing CODE types for functions is meaningless for SOM,
         instead one should be IMPORTing/EXPORTing ENTRY types.

         Complain if one tries to EXPORT a CODE type since that's never
         done.  Both GCC and HP C still try to IMPORT CODE types, so
         silently fix them to be ENTRY types.  */
      if (S_IS_FUNCTION (symbolP))
       {
         if (is_export)
           as_tsktsk (_("Using ENTRY rather than CODE in export directive for %s"),
                     S_GET_NAME (symbolP));

         bfdsym->flags |= BSF_FUNCTION;
         type = SYMBOL_TYPE_ENTRY;
       }
      else
       {
         bfdsym->flags &= ~BSF_FUNCTION;
         type = SYMBOL_TYPE_CODE;
       }
    }
  else if (strncasecmp (input_line_pointer, "data", 4) == 0)
    {
      input_line_pointer += 4;
      bfdsym->flags &= ~BSF_FUNCTION;
      bfdsym->flags |= BSF_OBJECT;
      type = SYMBOL_TYPE_DATA;
    }
  else if ((strncasecmp (input_line_pointer, "entry", 5) == 0))
    {
      input_line_pointer += 5;
      bfdsym->flags |= BSF_FUNCTION;
      type = SYMBOL_TYPE_ENTRY;
    }
  else if (strncasecmp (input_line_pointer, "millicode", 9) == 0)
    {
      input_line_pointer += 9;
      bfdsym->flags |= BSF_FUNCTION;
#ifdef OBJ_ELF
      {
       elf_symbol_type *elfsym = (elf_symbol_type *) bfdsym;
       elfsym->internal_elf_sym.st_info =
         ELF_ST_INFO (ELF_ST_BIND (elfsym->internal_elf_sym.st_info),
                     STT_PARISC_MILLI);
      }
#endif
      type = SYMBOL_TYPE_MILLICODE;
    }
  else if (strncasecmp (input_line_pointer, "plabel", 6) == 0)
    {
      input_line_pointer += 6;
      bfdsym->flags &= ~BSF_FUNCTION;
      type = SYMBOL_TYPE_PLABEL;
    }
  else if (strncasecmp (input_line_pointer, "pri_prog", 8) == 0)
    {
      input_line_pointer += 8;
      bfdsym->flags |= BSF_FUNCTION;
      type = SYMBOL_TYPE_PRI_PROG;
    }
  else if (strncasecmp (input_line_pointer, "sec_prog", 8) == 0)
    {
      input_line_pointer += 8;
      bfdsym->flags |= BSF_FUNCTION;
      type = SYMBOL_TYPE_SEC_PROG;
    }

  /* SOM requires much more information about symbol types
     than BFD understands.  This is how we get this information
     to the SOM BFD backend.  */
#ifdef obj_set_symbol_type
  obj_set_symbol_type (bfdsym, (int) type);
#endif

  /* Now that the type of the exported symbol has been handled,
     handle any argument relocation information.  */
  while (!is_end_of_statement ())
    {
      if (*input_line_pointer == ',')
       input_line_pointer++;
      name = input_line_pointer;
      c = get_symbol_end ();
      /* Argument sources.  */
      if ((strncasecmp (name, "argw", 4) == 0))
       {
         p = input_line_pointer;
         *p = c;
         input_line_pointer++;
         temp = atoi (name + 4);
         name = input_line_pointer;
         c = get_symbol_end ();
         arg_reloc = pa_align_arg_reloc (temp, pa_build_arg_reloc (name));
#if defined (OBJ_SOM) || defined (ELF_ARG_RELOC)
         symbol_arg_reloc_info (symbolP) |= arg_reloc;
#endif
         *input_line_pointer = c;
       }
      /* The return value.  */
      else if ((strncasecmp (name, "rtnval", 6)) == 0)
       {
         p = input_line_pointer;
         *p = c;
         input_line_pointer++;
         name = input_line_pointer;
         c = get_symbol_end ();
         arg_reloc = pa_build_arg_reloc (name);
#if defined (OBJ_SOM) || defined (ELF_ARG_RELOC)
         symbol_arg_reloc_info (symbolP) |= arg_reloc;
#endif
         *input_line_pointer = c;
       }
      /* Privilege level.  */
      else if ((strncasecmp (name, "priv_lev", 8)) == 0)
       {
         p = input_line_pointer;
         *p = c;
         input_line_pointer++;
         temp = atoi (input_line_pointer);
#ifdef OBJ_SOM
         ((obj_symbol_type *) bfdsym)->tc_data.ap.hppa_priv_level = temp;
#endif
         c = get_symbol_end ();
         *input_line_pointer = c;
       }
      else
       {
         as_bad (_("Undefined .EXPORT/.IMPORT argument (ignored): %s"), name);
         p = input_line_pointer;
         *p = c;
       }
      if (!is_end_of_statement ())
       input_line_pointer++;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void pa_undefine_label ( void  ) [static]

Definition at line 1161 of file tc-hppa.c.

{
  label_symbol_struct *label_chain;
  label_symbol_struct *prev_label_chain = NULL;

  for (label_chain = label_symbols_rootp;
       label_chain;
       label_chain = label_chain->lss_next)
    {
      if (1
#ifdef OBJ_SOM
         && current_space == label_chain->lss_space && label_chain->lss_label
#endif
#ifdef OBJ_ELF
         && now_seg == label_chain->lss_segment && label_chain->lss_label
#endif
         )
       {
         /* Remove the label from the chain and free its memory.  */
         if (prev_label_chain)
           prev_label_chain->lss_next = label_chain->lss_next;
         else
           label_symbols_rootp = label_chain->lss_next;

         free (label_chain);
         break;
       }
      prev_label_chain = label_chain;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void pa_version ( int unused  ATTRIBUTE_UNUSED) [static]

Definition at line 8160 of file tc-hppa.c.

{
  obj_version (0);
  pa_undefine_label ();
}

Here is the call graph for this function:

Definition at line 2540 of file tc-hppa.c.

Here is the call graph for this function:

static void process_exit ( void  ) [static]

Definition at line 6476 of file tc-hppa.c.

{
  char *where;

  where = frag_more (0);

#ifdef OBJ_ELF
  /* Mark the end of the function, stuff away the location of the frag
     for the end of the function, and finally call pa_build_unwind_subspace
     to add an entry in the unwind table.  */
  hppa_elf_mark_end_of_function ();
  pa_build_unwind_subspace (last_call_info);
#else
  /* SOM defers building of unwind descriptors until the link phase.
     The assembler is responsible for creating an R_ENTRY relocation
     to mark the beginning of a region and hold the unwind bits, and
     for creating an R_EXIT relocation to mark the end of the region.

     FIXME.  ELF should be using the same conventions!  The problem
     is an unwind requires too much relocation space.  Hmmm.  Maybe
     if we split the unwind bits up between the relocations which
     denote the entry and exit points.  */
  fix_new_hppa (frag_now, where - frag_now->fr_literal, 0,
              NULL, (offsetT) 0,
              NULL, 0, R_HPPA_EXIT, e_fsel, 0, 0,
              UNWIND_HIGH32 (&last_call_info->ci_unwind.descriptor));
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int reg_name_search ( char *  name) [static]

Definition at line 2038 of file tc-hppa.c.

{
  int middle, low, high;
  int cmp;

  low = 0;
  high = REG_NAME_CNT - 1;

  do
    {
      middle = (low + high) / 2;
      cmp = strcasecmp (name, pre_defined_registers[middle].name);
      if (cmp < 0)
       high = middle - 1;
      else if (cmp > 0)
       low = middle + 1;
      else
       return pre_defined_registers[middle].value;
    }
  while (low <= high);

  return -1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

arelent** tc_gen_reloc ( asection section,
fixS *  fixp 
)

Definition at line 1407 of file tc-hppa.c.

{
  arelent *reloc;
  struct hppa_fix_struct *hppa_fixp;
  static arelent *no_relocs = NULL;
  arelent **relocs;
  reloc_type **codes;
  reloc_type code;
  int n_relocs;
  int i;

  hppa_fixp = (struct hppa_fix_struct *) fixp->tc_fix_data;
  if (fixp->fx_addsy == 0)
    return &no_relocs;

  assert (hppa_fixp != 0);
  assert (section != 0);

  reloc = xmalloc (sizeof (arelent));

  reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
  *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
  codes = hppa_gen_reloc_type (stdoutput,
                            fixp->fx_r_type,
                            hppa_fixp->fx_r_format,
                            hppa_fixp->fx_r_field,
                            fixp->fx_subsy != NULL,
                            symbol_get_bfdsym (fixp->fx_addsy));

  if (codes == NULL)
    {
      as_bad_where (fixp->fx_file, fixp->fx_line, _("Cannot handle fixup"));
      abort ();
    }

  for (n_relocs = 0; codes[n_relocs]; n_relocs++)
    ;

  relocs = xmalloc (sizeof (arelent *) * n_relocs + 1);
  reloc = xmalloc (sizeof (arelent) * n_relocs);
  for (i = 0; i < n_relocs; i++)
    relocs[i] = &reloc[i];

  relocs[n_relocs] = NULL;

#ifdef OBJ_ELF
  switch (fixp->fx_r_type)
    {
    default:
      assert (n_relocs == 1);

      code = *codes[0];

      /* Now, do any processing that is dependent on the relocation type.  */
      switch (code)
       {
       case R_PARISC_DLTREL21L:
       case R_PARISC_DLTREL14R:
       case R_PARISC_DLTREL14F:
       case R_PARISC_PLABEL32:
       case R_PARISC_PLABEL21L:
       case R_PARISC_PLABEL14R:
         /* For plabel relocations, the addend of the
            relocation should be either 0 (no static link) or 2
            (static link required).  This adjustment is done in
            bfd/elf32-hppa.c:elf32_hppa_relocate_section.

            We also slam a zero addend into the DLT relative relocs;
            it doesn't make a lot of sense to use any addend since
            it gets you a different (eg unknown) DLT entry.  */
         reloc->addend = 0;
         break;

#ifdef ELF_ARG_RELOC
       case R_PARISC_PCREL17R:
       case R_PARISC_PCREL17F:
       case R_PARISC_PCREL17C:
       case R_PARISC_DIR17R:
       case R_PARISC_DIR17F:
       case R_PARISC_PCREL21L:
       case R_PARISC_DIR21L:
         reloc->addend = HPPA_R_ADDEND (hppa_fixp->fx_arg_reloc,
                                    fixp->fx_offset);
         break;
#endif

       case R_PARISC_DIR32:
         /* Facilitate hand-crafted unwind info.  */
         if (strcmp (section->name, UNWIND_SECTION_NAME) == 0)
           code = R_PARISC_SEGREL32;
         /* Fall thru */

       default:
         reloc->addend = fixp->fx_offset;
         break;
       }

      reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
      *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
      reloc->howto = bfd_reloc_type_lookup (stdoutput,
                                       (bfd_reloc_code_real_type) code);
      reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;

      assert (reloc->howto && (unsigned int) code == reloc->howto->type);
      break;
    }
#else /* OBJ_SOM */

  /* Walk over reach relocation returned by the BFD backend.  */
  for (i = 0; i < n_relocs; i++)
    {
      code = *codes[i];

      relocs[i]->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
      *relocs[i]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
      relocs[i]->howto =
       bfd_reloc_type_lookup (stdoutput,
                            (bfd_reloc_code_real_type) code);
      relocs[i]->address = fixp->fx_frag->fr_address + fixp->fx_where;

      switch (code)
       {
       case R_COMP2:
         /* The only time we ever use a R_COMP2 fixup is for the difference
            of two symbols.  With that in mind we fill in all four
            relocs now and break out of the loop.  */
         assert (i == 1);
         relocs[0]->sym_ptr_ptr
           = (asymbol **) bfd_abs_section_ptr->symbol_ptr_ptr;
         relocs[0]->howto
           = bfd_reloc_type_lookup (stdoutput,
                                 (bfd_reloc_code_real_type) *codes[0]);
         relocs[0]->address = fixp->fx_frag->fr_address + fixp->fx_where;
         relocs[0]->addend = 0;
         relocs[1]->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
         *relocs[1]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
         relocs[1]->howto
           = bfd_reloc_type_lookup (stdoutput,
                                 (bfd_reloc_code_real_type) *codes[1]);
         relocs[1]->address = fixp->fx_frag->fr_address + fixp->fx_where;
         relocs[1]->addend = 0;
         relocs[2]->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
         *relocs[2]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy);
         relocs[2]->howto
           = bfd_reloc_type_lookup (stdoutput,
                                 (bfd_reloc_code_real_type) *codes[2]);
         relocs[2]->address = fixp->fx_frag->fr_address + fixp->fx_where;
         relocs[2]->addend = 0;
         relocs[3]->sym_ptr_ptr
           = (asymbol **) bfd_abs_section_ptr->symbol_ptr_ptr;
         relocs[3]->howto
           = bfd_reloc_type_lookup (stdoutput,
                                 (bfd_reloc_code_real_type) *codes[3]);
         relocs[3]->address = fixp->fx_frag->fr_address + fixp->fx_where;
         relocs[3]->addend = 0;
         relocs[4]->sym_ptr_ptr
           = (asymbol **) bfd_abs_section_ptr->symbol_ptr_ptr;
         relocs[4]->howto
           = bfd_reloc_type_lookup (stdoutput,
                                 (bfd_reloc_code_real_type) *codes[4]);
         relocs[4]->address = fixp->fx_frag->fr_address + fixp->fx_where;
         relocs[4]->addend = 0;
         goto done;
       case R_PCREL_CALL:
       case R_ABS_CALL:
         relocs[i]->addend = HPPA_R_ADDEND (hppa_fixp->fx_arg_reloc, 0);
         break;

       case R_DLT_REL:
       case R_DATA_PLABEL:
       case R_CODE_PLABEL:
         /* For plabel relocations, the addend of the
            relocation should be either 0 (no static link) or 2
            (static link required).

            FIXME: We always assume no static link!

            We also slam a zero addend into the DLT relative relocs;
            it doesn't make a lot of sense to use any addend since
            it gets you a different (eg unknown) DLT entry.  */
         relocs[i]->addend = 0;
         break;

       case R_N_MODE:
       case R_S_MODE:
       case R_D_MODE:
       case R_R_MODE:
       case R_FSEL:
       case R_LSEL:
       case R_RSEL:
       case R_BEGIN_BRTAB:
       case R_END_BRTAB:
       case R_BEGIN_TRY:
       case R_N0SEL:
       case R_N1SEL:
         /* There is no symbol or addend associated with these fixups.  */
         relocs[i]->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
         *relocs[i]->sym_ptr_ptr = symbol_get_bfdsym (dummy_symbol);
         relocs[i]->addend = 0;
         break;

       case R_END_TRY:
       case R_ENTRY:
       case R_EXIT:
         /* There is no symbol associated with these fixups.  */
         relocs[i]->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
         *relocs[i]->sym_ptr_ptr = symbol_get_bfdsym (dummy_symbol);
         relocs[i]->addend = fixp->fx_offset;
         break;

       default:
         relocs[i]->addend = fixp->fx_offset;
       }
    }

 done:
#endif

  return relocs;
}

Variable Documentation

struct call_desc [static]

Definition at line 551 of file tc-hppa.c.

Definition at line 543 of file tc-hppa.c.

int callinfo_found [static]

Definition at line 598 of file tc-hppa.c.

const char comment_chars[] = ";"

Definition at line 574 of file tc-hppa.c.

const char EXP_CHARS[] = "eE"

Definition at line 580 of file tc-hppa.c.

char* expr_end [static]

Definition at line 595 of file tc-hppa.c.

const char FLT_CHARS[] = "rRsSfFdDxXpP"

Definition at line 588 of file tc-hppa.c.

struct fp_cond_map[] [static]

Definition at line 888 of file tc-hppa.c.

Definition at line 6340 of file tc-hppa.c.

Definition at line 611 of file tc-hppa.c.

const char hppa_symbol_chars[] = "*?=<>"

Definition at line 559 of file tc-hppa.c.

Definition at line 608 of file tc-hppa.c.

Definition at line 548 of file tc-hppa.c.

const char line_comment_chars[] = "#"

Definition at line 570 of file tc-hppa.c.

Definition at line 577 of file tc-hppa.c.

size_t md_longopts_size = sizeof (md_longopts)

Definition at line 1707 of file tc-hppa.c.

const pseudo_typeS md_pseudo_table[]

Definition at line 8608 of file tc-hppa.c.

const char* md_shortopts = ""

Definition at line 1696 of file tc-hppa.c.

Definition at line 554 of file tc-hppa.c.

struct pa_it [static]

Definition at line 590 of file tc-hppa.c.

int pa_number [static]

Definition at line 630 of file tc-hppa.c.

struct pd_reg[] [static]

Definition at line 667 of file tc-hppa.c.

int print_errors = 1 [static]

Definition at line 638 of file tc-hppa.c.

struct selector_entry[] [static]
Initial value:
{
  {"f", e_fsel},
  {"l", e_lsel},
  {"ld", e_ldsel},
  {"lp", e_lpsel},
  {"lr", e_lrsel},
  {"ls", e_lssel},
  {"lt", e_ltsel},
  {"ltp", e_ltpsel},
  {"n", e_nsel},
  {"nl", e_nlsel},
  {"nlr", e_nlrsel},
  {"p", e_psel},
  {"r", e_rsel},
  {"rd", e_rdsel},
  {"rp", e_rpsel},
  {"rr", e_rrsel},
  {"rs", e_rssel},
  {"rt", e_rtsel},
  {"rtp", e_rtpsel},
  {"t", e_tsel},
}

Definition at line 924 of file tc-hppa.c.

int strict [static]

Definition at line 621 of file tc-hppa.c.

Definition at line 601 of file tc-hppa.c.

Definition at line 604 of file tc-hppa.c.