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"
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 **));
{"%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. */
/* 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;
/* 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
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 ();
}
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, -1024, 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
*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;
{
/* 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;
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),