/* tc-hppa.c -- Assemble for the PA
- Copyright (C) 1989, 93, 94, 95, 96, 97, 98, 99, 2000
+ Copyright 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
at the University of Utah. */
#include <stdio.h>
-#include <ctype.h>
#include "as.h"
+#include "safe-ctype.h"
#include "subsegs.h"
#include "bfd/libhppa.h"
#endif
#endif /* OBJ_SOM */
+#if TARGET_ARCH_SIZE == 64
+#define DEFAULT_LEVEL 25
+#else
+#define DEFAULT_LEVEL 10
+#endif
+
/* Various structures and types used internally in tc-hppa.c. */
/* Unwind table and descriptor. FIXME: Sync this with GDB version. */
unsigned int frame_size:27;
};
+/* We can't rely on compilers placing bitfields in any particular
+ place, so use these macros when dumping unwind descriptors to
+ object files. */
+#define UNWIND_LOW32(U) \
+ (((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))
+
+#define UNWIND_HIGH32(U) \
+ (((U)->hpe_interrupt_marker << 31) \
+ | ((U)->hpux_interrupt_marker << 30) \
+ | ((U)->frame_size << 0))
+
struct unwind_table
{
/* Starting and ending offsets of the region described by
static unsigned int pa_build_arg_reloc PARAMS ((char *));
static unsigned int pa_align_arg_reloc PARAMS ((unsigned int, unsigned int));
static int pa_parse_nullif PARAMS ((char **));
-static int pa_parse_nonneg_cmpsub_cmpltr PARAMS ((char **, int));
-static int pa_parse_neg_cmpsub_cmpltr PARAMS ((char **, int));
-static int pa_parse_neg_add_cmpltr PARAMS ((char **, int));
-static int pa_parse_nonneg_add_cmpltr PARAMS ((char **, int));
+static int pa_parse_nonneg_cmpsub_cmpltr PARAMS ((char **));
+static int pa_parse_neg_cmpsub_cmpltr PARAMS ((char **));
+static int pa_parse_neg_add_cmpltr PARAMS ((char **));
+static int pa_parse_nonneg_add_cmpltr PARAMS ((char **));
static int pa_parse_cmpb_64_cmpltr PARAMS ((char **));
static int pa_parse_cmpib_64_cmpltr PARAMS ((char **));
static int pa_parse_addb_64_cmpltr PARAMS ((char **));
offsetT, expressionS *, int,
bfd_reloc_code_real_type,
enum hppa_reloc_field_selector_type_alt,
- int, unsigned int, int *));
+ int, unsigned int, int));
static int is_end_of_statement PARAMS ((void));
static int reg_name_search PARAMS ((char *));
static int pa_chk_field_selector PARAMS ((char **));
{"%isr", 20},
{"%itmr", 16},
{"%iva", 14},
+#if TARGET_ARCH_SIZE == 64
+ {"%mrp", 2},
+#else
+ {"%mrp", 31},
+#endif
{"%pcoq", 18},
{"%pcsq", 17},
{"%pidr1", 8},
} \
}
+/* Variant of CHECK_FIELD for use in md_apply_fix and other places where
+ the current file and line number are not valid. */
+
+#define CHECK_FIELD_WHERE(FIELD, HIGH, LOW, FILENAME, LINE) \
+ { \
+ if ((FIELD) > (HIGH) || (FIELD) < (LOW)) \
+ { \
+ as_bad_where ((FILENAME), (LINE), \
+ _("Field out of range [%d..%d] (%d)."), (LOW), (HIGH), \
+ (int) (FIELD));\
+ break; \
+ } \
+ }
+
/* Simple alignment checking for FIELD againt ALIGN (a power of two).
IGNORE is used to suppress the error message. */
enum hppa_reloc_field_selector_type_alt r_field;
int r_format;
unsigned int arg_reloc;
- int* unwind_bits ATTRIBUTE_UNUSED;
+ int unwind_bits ATTRIBUTE_UNUSED;
{
fixS *new_fix;
hppa_fix->segment = now_seg;
#ifdef OBJ_SOM
if (r_type == R_ENTRY || r_type == R_EXIT)
- new_fix->fx_offset = *unwind_bits;
+ new_fix->fx_offset = unwind_bits;
#endif
/* foo-$global$ is used to access non-automatic storage. $global$
fix_new_hppa (frag, where, size,
(symbolS *) NULL, (offsetT) 0, exp, 0, rel_type,
- hppa_field_selector, size * 8, 0, NULL);
+ hppa_field_selector, size * 8, 0, 0);
/* Reset field selector to its default state. */
hppa_field_selector = 0;
call_info_root = NULL;
/* Set the default machine type. */
- if (!bfd_set_arch_mach (stdoutput, bfd_arch_hppa, 10))
+ 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.
information when the label appears after the proc/procend. */
if (within_entry_exit)
{
- char *where = frag_more (0);
+ 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,
- (int *)&last_call_info->ci_unwind.descriptor);
+ 0, R_HPPA_ENTRY, e_fsel, 0, 0, u);
}
#endif
}
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, NULL);
+ the_insn.format, the_insn.arg_reloc, 0);
#ifdef OBJ_ELF
- if (debug_type == DEBUG_DWARF2)
- dwarf2_generate_asm_lineno (4);
+ dwarf2_emit_insn (4);
#endif
}
/* Convert everything up to the first whitespace character into lower
case. */
for (s = str; *s != ' ' && *s != '\t' && *s != '\n' && *s != '\0'; s++)
- if (isupper (*s))
- *s = tolower (*s);
+ *s = TOLOWER (*s);
/* Skip to something interesting. */
- for (s = str; isupper (*s) || islower (*s) || (*s >= '0' && *s <= '3'); ++s)
+ for (s = str;
+ ISUPPER (*s) || ISLOWER (*s) || (*s >= '0' && *s <= '3');
+ ++s)
;
switch (*s)
as_fatal (_("Unknown opcode: `%s'"), str);
}
- save_s = str;
-
/* Look up the opcode in the has table. */
if ((insn = (struct pa_opcode *) hash_find (op_hash, str)) == NULL)
{
while (*s == ' ' || *s == '\t')
s = s + 1;
- if (!strncasecmp(s, "%sar", 4))
+ if (!strncasecmp (s, "%sar", 4))
{
s += 4;
continue;
}
- else if (!strncasecmp(s, "%cr11", 5))
+ else if (!strncasecmp (s, "%cr11", 5))
{
s += 5;
continue;
}
else if (*args == 'e')
{
- /* Gross! Hide these values in the immediate field
- of the instruction, then pull them out later. */
- opcode |= m << 8;
- opcode |= a << 9;
+ /* Stash the ma/mb flag temporarily in the
+ instruction. We will use (and remove it)
+ later when handling 'J', 'K', '<' & '>'. */
+ opcode |= a;
continue;
}
}
/* Handle load cache hint completer. */
case 'c':
cmpltr = 0;
- if (!strncmp(s, ",sl", 3))
+ if (!strncmp (s, ",sl", 3))
{
s += 3;
cmpltr = 2;
/* Handle store cache hint completer. */
case 'C':
cmpltr = 0;
- if (!strncmp(s, ",sl", 3))
+ if (!strncmp (s, ",sl", 3))
{
s += 3;
cmpltr = 2;
}
- else if (!strncmp(s, ",bc", 3))
+ else if (!strncmp (s, ",bc", 3))
{
s += 3;
cmpltr = 1;
/* Handle load and clear cache hint completer. */
case 'd':
cmpltr = 0;
- if (!strncmp(s, ",co", 3))
+ if (!strncmp (s, ",co", 3))
{
s += 3;
cmpltr = 1;
/* Handle load ordering completer. */
case 'o':
- if (strncmp(s, ",o", 2) != 0)
+ if (strncmp (s, ",o", 2) != 0)
break;
s += 2;
continue;
else if (*s == 'l')
lr = 0;
else
- as_bad(_("Invalid left/right combination completer"));
+ as_bad (_("Invalid left/right combination completer"));
s++;
INSERT_FIELD_AND_CONTINUE (opcode, lr, 13);
}
else
- as_bad(_("Invalid left/right combination completer"));
+ as_bad (_("Invalid left/right combination completer"));
break;
/* Handle saturation at 24:25. */
perm = 3;
break;
default:
- as_bad(_("Invalid permutation completer"));
+ as_bad (_("Invalid permutation completer"));
}
opcode |= perm << permloc[i];
}
continue;
}
else
- as_bad(_("Invalid permutation completer"));
+ as_bad (_("Invalid permutation completer"));
break;
default:
/* Handle non-negated add and branch condition. */
case 'd':
- cmpltr = pa_parse_nonneg_add_cmpltr (&s, 1);
+ cmpltr = pa_parse_nonneg_add_cmpltr (&s);
if (cmpltr < 0)
{
- as_bad (_("Invalid Add and Branch Condition: %c"), *s);
+ as_bad (_("Invalid Add and Branch Condition"));
cmpltr = 0;
}
INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 13);
cmpltr = pa_parse_addb_64_cmpltr (&s);
if (cmpltr < 0)
{
- as_bad (_("Invalid Add and Branch Condition: %c"), *s);
+ as_bad (_("Invalid Add and Branch Condition"));
cmpltr = 0;
}
else
condition. */
case '@':
save_s = s;
- cmpltr = pa_parse_nonneg_add_cmpltr (&s, 1);
+ cmpltr = pa_parse_nonneg_add_cmpltr (&s);
if (cmpltr < 0)
{
s = save_s;
- cmpltr = pa_parse_neg_add_cmpltr (&s, 1);
+ cmpltr = pa_parse_neg_add_cmpltr (&s);
if (cmpltr < 0)
{
as_bad (_("Invalid Compare/Subtract Condition"));
/* Handle a non-negated compare condition. */
case 't':
- cmpltr = pa_parse_nonneg_cmpsub_cmpltr (&s, 1);
+ cmpltr = pa_parse_nonneg_cmpsub_cmpltr (&s);
if (cmpltr < 0)
{
- as_bad (_("Invalid Compare/Subtract Condition: %c"), *s);
+ 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, 1);
+ cmpltr = pa_parse_nonneg_cmpsub_cmpltr (&s);
if (cmpltr < 0)
{
s = save_s;
- cmpltr = pa_parse_neg_cmpsub_cmpltr (&s, 1);
+ cmpltr = pa_parse_neg_cmpsub_cmpltr (&s);
if (cmpltr < 0)
{
- as_bad (_("Invalid Compare and Branch Condition."));
+ as_bad (_("Invalid Compare and Branch Condition"));
cmpltr = 0;
}
else
s = expr_end;
if (the_insn.exp.X_op == O_constant)
{
- int a, m;
+ int mb;
- /* XXX the completer stored away tibits of information
+ /* 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. */
- m = (opcode & (1 << 8)) != 0;
- a = (opcode & (1 << 9)) != 0;
- opcode &= ~ (3 << 8);
+ mb = opcode & 1;
+ opcode -= mb;
num = evaluate_absolute (&the_insn);
- if ((a == 1 && num >= 0) || (a == 0 && num < 0))
+ if (mb != (num < 0))
break;
CHECK_FIELD (num, 8191, -8192, 0);
num = low_sign_unext (num, 14);
INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
}
- else
- {
- break;
- }
+ break;
/* Handle a 14 bit immediate at 31. */
case 'K':
s = expr_end;
if (the_insn.exp.X_op == O_constant)
{
- int a, m;
+ int mb;
- /* XXX the completer stored away tibits 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. */
- m = (opcode & (1 << 8)) != 0;
- a = (opcode & (1 << 9)) != 0;
- opcode &= ~ (3 << 8);
+ mb = opcode & 1;
+ opcode -= mb;
num = evaluate_absolute (&the_insn);
- if ((a == 1 && num < 0) || (a == 0 && num > 0))
+ if (mb == (num < 0))
break;
if (num % 4)
break;
CHECK_FIELD (num, 8191, -8192, 0);
- if (num < 0)
- opcode |= 1;
- num &= 0x1fff;
- num >>= 2;
- INSERT_FIELD_AND_CONTINUE (opcode, num, 3);
+ num = low_sign_unext (num, 14);
+ INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
}
- else
+ 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)
{
- break;
+ 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 '#':
get_expression (s);
s = expr_end;
the_insn.pcrel = 1;
- if (!strcmp (S_GET_NAME (the_insn.exp.X_add_symbol), "L$0\001"))
+ if (!the_insn.exp.X_add_symbol
+ || !strcmp (S_GET_NAME (the_insn.exp.X_add_symbol),
+ "L$0\001"))
{
num = evaluate_absolute (&the_insn);
if (num % 4)
as_bad (_("Branch to unaligned address"));
break;
}
- CHECK_FIELD (num, 8199, -8184, 0);
-
- opcode |= re_assemble_12 ((num - 8) >> 2);
+ if (the_insn.exp.X_add_symbol)
+ num -= 8;
+ CHECK_FIELD (num, 8191, -8192, 0);
+ opcode |= re_assemble_12 (num >> 2);
continue;
}
else
as_bad (_("Branch to unaligned address"));
break;
}
- CHECK_FIELD (num, 262143, -262144, 0);
-
if (the_insn.exp.X_add_symbol)
num -= 8;
-
+ CHECK_FIELD (num, 262143, -262144, 0);
opcode |= re_assemble_17 (num >> 2);
continue;
}
as_bad (_("Branch to unaligned address"));
break;
}
- CHECK_FIELD (num, 8388607, -8388608, 0);
-
if (the_insn.exp.X_add_symbol)
num -= 8;
-
+ CHECK_FIELD (num, 8388607, -8388608, 0);
opcode |= re_assemble_22 (num >> 2);
}
else
as_bad (_("Branch to unaligned address"));
break;
}
- CHECK_FIELD (num, 262143, -262144, 0);
-
if (the_insn.exp.X_add_symbol)
num -= 8;
-
+ CHECK_FIELD (num, 262143, -262144, 0);
opcode |= re_assemble_17 (num >> 2);
continue;
}
if (strict && the_insn.exp.X_op != O_constant)
break;
s = expr_end;
- CHECK_FIELD (num, 671108864, 0, strict);
+ CHECK_FIELD (num, 67108863, 0, strict);
INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
/* Handle a 3 bit SFU identifier at 25. */
if (codes == NULL)
{
- as_bad (_("Cannot handle fixup at %s:%d"), fixp->fx_file, fixp->fx_line);
+ as_bad_where (fixp->fx_file, fixp->fx_line, _("Cannot handle fixup"));
abort ();
}
code = *codes[0];
- reloc->sym_ptr_ptr = (asymbol **) 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);
-
/* Now, do any processing that is dependent on the relocation type. */
switch (code)
{
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 = (asymbol **) 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 */
#endif
{NULL, no_argument, NULL, 0}
};
-size_t md_longopts_size = sizeof(md_longopts);
+size_t md_longopts_size = sizeof (md_longopts);
int
md_parse_option (c, arg)
hppa_fixP = (struct hppa_fix_struct *) fixP->tc_fix_data;
if (hppa_fixP == NULL)
{
- printf (_("no hppa_fixup entry for fixup type 0x%x at %s:%d"),
- fixP->fx_r_type, fixP->fx_file, fixP->fx_line);
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("no hppa_fixup entry for fixup type 0x%x"),
+ fixP->fx_r_type);
return 0;
}
switch (fmt)
{
case 10:
- CHECK_FIELD (new_val, 8191, -8192, 0);
+ 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 (new_val, 8191, -8192, 0);
+ CHECK_FIELD_WHERE (new_val, 8191, -8192,
+ fixP->fx_file, fixP->fx_line);
val = new_val;
insn = (insn & ~ 0x3ff9) | (((val & 0x1ffc) << 1)
break;
/* Handle all opcodes with the 'j' operand type. */
case 14:
- CHECK_FIELD (new_val, 8191, -8192, 0);
+ CHECK_FIELD_WHERE (new_val, 8191, -8192,
+ fixP->fx_file, fixP->fx_line);
val = new_val;
insn = ((insn & ~ 0x3fff) | low_sign_unext (val, 14));
/* Handle all opcodes with the 'k' operand type. */
case 21:
- CHECK_FIELD (new_val, 1048575, -1048576, 0);
+ CHECK_FIELD_WHERE (new_val, 1048575, -1048576,
+ fixP->fx_file, fixP->fx_line);
val = new_val;
insn = (insn & ~ 0x1fffff) | re_assemble_21 (val);
/* Handle all the opcodes with the 'i' operand type. */
case 11:
- CHECK_FIELD (new_val, 1023, -1023, 0);
+ CHECK_FIELD_WHERE (new_val, 1023, -1024,
+ fixP->fx_file, fixP->fx_line);
val = new_val;
insn = (insn & ~ 0x7ff) | low_sign_unext (val, 11);
/* Handle all the opcodes with the 'w' operand type. */
case 12:
- CHECK_FIELD (new_val - 8, 8191, -8192, 0);
+ 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);
range target, then we want to complain. */
if (fixP->fx_r_type == (int) R_HPPA_PCREL_CALL
&& (insn & 0xffe00000) == 0xe8000000)
- CHECK_FIELD (distance - 8, 262143, -262144, 0);
+ CHECK_FIELD_WHERE (distance - 8, 262143, -262144,
+ fixP->fx_file, fixP->fx_line);
- CHECK_FIELD (new_val - 8, 262143, -262144, 0);
+ 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);
range target, then we want to complain. */
if (fixP->fx_r_type == (int) R_HPPA_PCREL_CALL
&& (insn & 0xffe00000) == 0xe8000000)
- CHECK_FIELD (distance - 8, 8388607, -8388608, 0);
+ CHECK_FIELD_WHERE (distance - 8, 8388607, -8388608,
+ fixP->fx_file, fixP->fx_line);
- CHECK_FIELD (new_val - 8, 8388607, -8388608, 0);
+ 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;
default:
- as_bad (_("Unknown relocation encountered in md_apply_fix."));
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Unknown relocation encountered in md_apply_fix."));
return 0;
}
pa_number = -1;
have_prefix = 0;
num = 0;
- if (!strict && isdigit (*p))
+ if (!strict && ISDIGIT (*p))
{
/* Looks like a number. */
{
/* The number is specified in hex. */
p += 2;
- while (isdigit (*p) || ((*p >= 'a') && (*p <= 'f'))
+ while (ISDIGIT (*p) || ((*p >= 'a') && (*p <= 'f'))
|| ((*p >= 'A') && (*p <= 'F')))
{
- if (isdigit (*p))
+ if (ISDIGIT (*p))
num = num * 16 + *p - '0';
else if (*p >= 'a' && *p <= 'f')
num = num * 16 + *p - 'a' + 10;
else
{
/* The number is specified in decimal. */
- while (isdigit (*p))
+ while (ISDIGIT (*p))
{
num = num * 10 + *p - '0';
++p;
num = 2;
p++;
}
- else if (!isdigit (*p))
+ else if (!ISDIGIT (*p))
{
if (print_errors)
as_bad (_("Undefined register: '%s'."), name);
{
do
num = num * 10 + *p++ - '0';
- while (isdigit (*p));
+ while (ISDIGIT (*p));
}
}
else
return 0;
}
-#define REG_NAME_CNT (sizeof(pre_defined_registers) / sizeof(struct pd_reg))
+#define REG_NAME_CNT (sizeof (pre_defined_registers) / sizeof (struct pd_reg))
/* Given NAME, find the register number associated with that name, return
the integer value associated with the given name or -1 on failure. */
*str = *str + 1;
if ((*str)[1] == '\'' || (*str)[1] == '%')
- name[0] = tolower ((*str)[0]),
+ 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[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[0] = TOLOWER ((*str)[0]),
+ name[1] = TOLOWER ((*str)[1]),
+ name[2] = TOLOWER ((*str)[2]),
name[3] = 0;
else
return e_fsel;
}
/* Parse a non-negated compare/subtract completer returning the
- number (for encoding in instrutions) of the given completer.
-
- ISBRANCH specifies whether or not this is parsing a condition
- completer for a branch (vs a nullification completer for a
- computational instruction. */
+ number (for encoding in instrutions) of the given completer. */
static int
-pa_parse_nonneg_cmpsub_cmpltr (s, isbranch)
+pa_parse_nonneg_cmpsub_cmpltr (s)
char **s;
- int isbranch;
{
int cmpltr;
char *name = *s + 1;
}
/* If we have something like addb,n then there is no condition
completer. */
- else if (strcasecmp (name, "n") == 0 && isbranch)
+ else if (strcasecmp (name, "n") == 0)
{
cmpltr = 0;
nullify = 1;
}
/* Parse a negated compare/subtract completer returning the
- number (for encoding in instrutions) of the given completer.
-
- ISBRANCH specifies whether or not this is parsing a condition
- completer for a branch (vs a nullification completer for a
- computational instruction. */
+ number (for encoding in instrutions) of the given completer. */
static int
-pa_parse_neg_cmpsub_cmpltr (s, isbranch)
+pa_parse_neg_cmpsub_cmpltr (s)
char **s;
- int isbranch;
{
int cmpltr;
char *name = *s + 1;
}
/* If we have something like addb,n then there is no condition
completer. */
- else if (strcasecmp (name, "n") == 0 && isbranch)
+ else if (strcasecmp (name, "n") == 0)
{
cmpltr = 0;
nullify = 1;
}
/* Parse a non-negated addition completer returning the number
- (for encoding in instrutions) of the given completer.
-
- ISBRANCH specifies whether or not this is parsing a condition
- completer for a branch (vs a nullification completer for a
- computational instruction. */
+ (for encoding in instrutions) of the given completer. */
static int
-pa_parse_nonneg_add_cmpltr (s, isbranch)
+pa_parse_nonneg_add_cmpltr (s)
char **s;
- int isbranch;
{
int cmpltr;
char *name = *s + 1;
char c;
char *save_s = *s;
+ int nullify = 0;
cmpltr = 0;
if (**s == ',')
}
/* If we have something like addb,n then there is no condition
completer. */
- else if (strcasecmp (name, "n") == 0 && isbranch)
+ else if (strcasecmp (name, "n") == 0)
{
cmpltr = 0;
+ nullify = 1;
}
else
{
}
/* Reset pointers if this was really a ,n for a branch instruction. */
- if (cmpltr == 0 && *name == 'n' && isbranch)
+ if (nullify)
*s = save_s;
return cmpltr;
}
/* Parse a negated addition completer returning the number
- (for encoding in instrutions) of the given completer.
-
- ISBRANCH specifies whether or not this is parsing a condition
- completer for a branch (vs a nullification completer for a
- computational instruction). */
+ (for encoding in instrutions) of the given completer. */
static int
-pa_parse_neg_add_cmpltr (s, isbranch)
+pa_parse_neg_add_cmpltr (s)
char **s;
- int isbranch;
{
int cmpltr;
char *name = *s + 1;
char c;
char *save_s = *s;
+ int nullify = 0;
cmpltr = 0;
if (**s == ',')
}
/* If we have something like addb,n then there is no condition
completer. */
- else if (strcasecmp (name, "n") == 0 && isbranch)
+ else if (strcasecmp (name, "n") == 0)
{
cmpltr = 0;
+ nullify = 1;
}
else
{
}
/* Reset pointers if this was really a ,n for a branch instruction. */
- if (cmpltr == 0 && *name == 'n' && isbranch)
+ if (nullify)
*s = save_s;
return cmpltr;
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, NULL);
+ e_fsel, 0, 0, 0);
#endif
demand_empty_rest_of_line ();
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, NULL);
+ e_fsel, 0, 0, 0);
#endif
demand_empty_rest_of_line ();
pa_build_unwind_subspace (call_info)
struct call_info *call_info;
{
- char *unwind;
asection *seg, *save_seg;
subsegT save_subseg;
- unsigned int i;
+ unsigned int unwind;
int reloc;
- char c, *p;
+ char *p;
- if (now_seg != text_section)
+ if ((bfd_get_section_flags (stdoutput, now_seg)
+ & (SEC_ALLOC | SEC_LOAD | SEC_READONLY))
+ != (SEC_ALLOC | SEC_LOAD | SEC_READONLY))
return;
- if (bfd_get_arch_info (stdoutput)->bits_per_address == 32)
- reloc = R_PARISC_DIR32;
- else
- reloc = R_PARISC_SEGREL32;
-
+ reloc = R_PARISC_SEGREL32;
save_seg = now_seg;
save_subseg = now_subseg;
/* Get into the right seg/subseg. This may involve creating
/* Get some space to hold relocation information for the unwind
descriptor. */
- p = frag_more (4);
- md_number_to_chars (p, 0, 4);
+ p = frag_more (16);
/* Relocation info. for start offset of the function. */
+ md_number_to_chars (p, 0, 4);
fix_new_hppa (frag_now, p - frag_now->fr_literal, 4,
call_info->start_symbol, (offsetT) 0,
(expressionS *) NULL, 0, reloc,
- e_fsel, 32, 0, NULL);
-
- p = frag_more (4);
- md_number_to_chars (p, 0, 4);
+ e_fsel, 32, 0, 0);
/* Relocation info. for end offset of the function.
symbol into the symbol table. It (should) end up giving the same
value as call_info->start_symbol + function size once the linker is
finished with its work. */
-
- fix_new_hppa (frag_now, p - frag_now->fr_literal, 4,
+ md_number_to_chars (p + 4, 0, 4);
+ fix_new_hppa (frag_now, p + 4 - frag_now->fr_literal, 4,
call_info->end_symbol, (offsetT) 0,
(expressionS *) NULL, 0, reloc,
- e_fsel, 32, 0, NULL);
+ e_fsel, 32, 0, 0);
- /* Dump it. */
- unwind = (char *) &call_info->ci_unwind;
- for (i = 8; i < sizeof (struct unwind_table); i++)
- {
- c = *(unwind + i);
- {
- FRAG_APPEND_1_CHAR (c);
- }
- }
+ /* Dump the descriptor. */
+ unwind = UNWIND_LOW32 (&call_info->ci_unwind.descriptor);
+ md_number_to_chars (p + 8, unwind, 4);
+
+ unwind = UNWIND_HIGH32 (&call_info->ci_unwind.descriptor);
+ md_number_to_chars (p + 12, unwind, 4);
/* Return back to the original segment/subsegment. */
subseg_set (save_seg, save_subseg);
denote the entry and exit points. */
if (last_call_info->start_symbol != NULL)
{
- char *where = frag_more (0);
+ 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,
- (int *) &last_call_info->ci_unwind.descriptor);
+ 0, R_HPPA_ENTRY, e_fsel, 0, 0, u);
}
#endif
}
fix_new_hppa (frag_now, where - frag_now->fr_literal, 0,
NULL, (offsetT) 0,
NULL, 0, R_HPPA_EXIT, e_fsel, 0, 0,
- (int *) &last_call_info->ci_unwind.descriptor + 1);
+ UNWIND_HIGH32 (&last_call_info->ci_unwind.descriptor));
#endif
}
{
/* Sigh. To be compatable with the HP assembler and to help
poorly written assembly code, we assign a type based on
- the the current segment. Note only BSF_FUNCTION really
+ 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;
information when the label appears after the proc/procend. */
if (within_entry_exit)
{
- char *where = frag_more (0);
+ 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,
- (int *) &last_call_info->ci_unwind.descriptor);
+ 0, R_HPPA_ENTRY, e_fsel, 0, 0, u);
}
#endif
}
s++;
for (num_digit = 0, number = 0, dg = *s;
num_digit < 2
- && (isdigit (dg) || (dg >= 'a' && dg <= 'f')
+ && (ISDIGIT (dg) || (dg >= 'a' && dg <= 'f')
|| (dg >= 'A' && dg <= 'F'));
num_digit++)
{
- if (isdigit (dg))
+ if (ISDIGIT (dg))
number = number * 16 + dg - '0';
else if (dg >= 'a' && dg <= 'f')
number = number * 16 + dg - 'a' + 10;
return 1;
/* It is necessary to force PC-relative calls/jumps to have a relocation
- entry if they're going to need either a argument relocation or long
+ 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),
}
}
-void
-pa_end_of_source ()
-{
- if (debug_type == DEBUG_DWARF2)
- dwarf2_finish ();
-}
-
static void
pa_vtable_entry (ignore)
int ignore ATTRIBUTE_UNUSED;