aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gas/ChangeLog18
-rw-r--r--gas/config/tc-hppa.c481
2 files changed, 429 insertions, 70 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index fc1e189..164c893 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,21 @@
+Sun Oct 10 01:47:23 1999 Jerry Quinn <jerry.quinn.adv91@alum.dartmouth.org>
+
+ * config/tc-hppa.c (pa_ip): Add new codes 'cc', 'cd', 'cC', 'co',
+ '@'. Change autoincrement completers to fall through to cache control
+ completers.
+
+ * config/tc-hppa.c (pa_ip): Remove unused args. Add code to '?W'
+ arg.
+ (pa_parse_addb_64_cmpltr): New function.
+
+ * config/tc-hppa.c (pa_ip): Change error message.
+ (pa_ip,pa_parse_cmpb_64_cmpltr,pa_parse_cmpib_64_cmpltr) Fix '?N' and
+ '?Q' args to allow falling through.
+
+ * configtc-hppa.c (pa_ip): Implement conditional codes "?N", "?Q".
+ Remove unused conditional codes.
+ (pa_parse_cmpb_64_cmpltr,pa_parse_cmpib_64_cmpltr): New.
+
Thu Oct 7 00:23:53 MDT 1999 Diego Novillo <dnovillo@cygnus.com>
* config/tc-d30v.c (CHAR_BIT): Define.
diff --git a/gas/config/tc-hppa.c b/gas/config/tc-hppa.c
index 6846802..2f3f2d9 100644
--- a/gas/config/tc-hppa.c
+++ b/gas/config/tc-hppa.c
@@ -495,6 +495,9 @@ 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_cmpb_64_cmpltr PARAMS ((char **));
+static int pa_parse_cmpib_64_cmpltr PARAMS ((char **));
+static int pa_parse_addb_64_cmpltr PARAMS ((char **));
static void pa_block PARAMS ((int));
static void pa_brtab PARAMS ((int));
static void pa_try PARAMS ((int));
@@ -1393,7 +1396,7 @@ md_begin ()
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);
+ (void) symbol_get_bfdsym (dummy_symbol);
#endif
}
@@ -1767,11 +1770,15 @@ pa_ip (str)
}
else if (strncasecmp (s, "m", 1) == 0)
m = 1;
- else if (strncasecmp (s, "s", 1) == 0)
+ else if ((strncasecmp (s, "s ", 2) == 0)
+ || (strncasecmp (s, "s,", 2) == 0))
uu = 1;
/* When in strict mode this is a match failure. */
else if (strict)
- break;
+ {
+ s--;
+ break;
+ }
else
as_bad (_("Invalid Indexed Load Completer."));
s++;
@@ -1787,33 +1794,40 @@ pa_ip (str)
case 'm':
case 'q':
case 'J':
- case 'c':
+ case 'e':
{
int a = 0;
int m = 0;
if (*s == ',')
{
+ int found = 0;
s++;
if (strncasecmp (s, "ma", 2) == 0)
{
a = 0;
m = 1;
+ found = 1;
}
else if (strncasecmp (s, "mb", 2) == 0)
{
a = 1;
m = 1;
+ found = 1;
}
- /* When in strict mode this is a match failure. */
- else if (strict)
- break;
+
+ /* When in strict mode, pass through for cache op. */
+ if (!found && strict)
+ s--;
else
- as_bad (_("Invalid Short Load/Store Completer."));
- s += 2;
+ {
+ if (!found)
+ 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 'cc'. */
- else if (*args == 'c')
+ consider this a positive match for 'ce'. */
+ else if (*args == 'e')
break;
/* 'J', 'm' and 'q' are the same, except for where they
@@ -1833,7 +1847,7 @@ pa_ip (str)
/* M bit is explicit in the major opcode. */
INSERT_FIELD_AND_CONTINUE (opcode, a, 2);
}
- else if (*args == 'c')
+ else if (*args == 'e')
{
/* Gross! Hide these values in the immediate field
of the instruction, then pull them out later. */
@@ -1854,13 +1868,17 @@ pa_ip (str)
s++;
if (strncasecmp (s, "m", 1) == 0)
m = 1;
- else if (strncasecmp (s, "b", 1) == 0)
+ else if ((strncasecmp (s, "b ", 2) == 0)
+ || (strncasecmp (s, "b,", 2) == 0))
a = 0;
else if (strncasecmp (s, "e", 1) == 0)
a = 1;
/* When in strict mode this is a match failure. */
else if (strict)
- break;
+ {
+ s--;
+ break;
+ }
else
as_bad (_("Invalid Store Bytes Short Completer"));
s++;
@@ -1872,6 +1890,48 @@ pa_ip (str)
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)
@@ -1924,7 +1984,7 @@ pa_ip (str)
INSERT_FIELD_AND_CONTINUE (opcode, flag, 6);
/* Handle MFCTL wide completer. */
- case 'W':
+ case 'W':
if (strncasecmp (s, ",w", 2) != 0)
break;
s += 2;
@@ -1988,7 +2048,7 @@ pa_ip (str)
flag = 3;
s += 4;
}
-
+
INSERT_FIELD_AND_CONTINUE (opcode, flag, 10);
/* Handle 64 bit carry for ADD. */
@@ -2310,24 +2370,27 @@ pa_ip (str)
cmpltr = pa_parse_nonneg_add_cmpltr (&s, 1);
if (cmpltr < 0)
{
- as_bad (_("Invalid Compare/Subtract Condition: %c"), *s);
+ as_bad (_("Invalid Add and Branch Condition: %c"), *s);
cmpltr = 0;
}
INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 13);
- /* Handle negated add and branch condition. */
- case 'D':
- abort ();
-
- /* Handle wide-mode non-negated add and branch condition. */
- case 'w':
- abort ();
-
- /* Handle wide-mode negated add and branch condition. */
+ /* Handle 64 bit wide-mode add and branch condition. */
case 'W':
- abort();
+ cmpltr = pa_parse_addb_64_cmpltr (&s);
+ if (cmpltr < 0)
+ {
+ as_bad (_("Invalid Add and Branch Condition: %c"), *s);
+ 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
+ /* Handle a negated or non-negated add and branch
condition. */
case '@':
save_s = s;
@@ -2393,16 +2456,16 @@ pa_ip (str)
/* 64 bit conditions. */
if (*args == 'S')
- {
+ {
if (*s == '*')
s++;
else
break;
- }
+ }
else if (*s == '*')
break;
name = s;
-
+
name = s;
while (*s != ',' && *s != ' ' && *s != '\t')
s += 1;
@@ -2481,24 +2544,7 @@ pa_ip (str)
}
INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 13);
- /* Handle a negated compare condition. */
- case 'T':
- abort ();
-
- /* Handle a 64 bit non-negated compare condition. */
- case 'r':
- abort ();
-
- /* Handle a 64 bit negated compare condition. */
- case 'R':
- abort ();
-
- /* Handle a 64 bit cmpib condition. */
- case 'Q':
- abort ();
-
- /* Handle a negated or non-negated compare/subtract
- condition. */
+ /* Handle a 32 bit compare and branch condition. */
case 'n':
save_s = s;
cmpltr = pa_parse_nonneg_cmpsub_cmpltr (&s, 1);
@@ -2508,7 +2554,7 @@ pa_ip (str)
cmpltr = pa_parse_neg_cmpsub_cmpltr (&s, 1);
if (cmpltr < 0)
{
- as_bad (_("Invalid Compare/Subtract Condition."));
+ as_bad (_("Invalid Compare and Branch Condition."));
cmpltr = 0;
}
else
@@ -2517,7 +2563,30 @@ pa_ip (str)
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. */
@@ -2540,14 +2609,14 @@ pa_ip (str)
else if (*s == '*')
break;
name = s;
-
+
name = s;
while (*s != ',' && *s != ' ' && *s != '\t')
s += 1;
c = *s;
*s = 0x00;
-
-
+
+
if (strcmp (name, "=") == 0)
cmpltr = 1;
else if (strcmp (name, "<") == 0)
@@ -2609,7 +2678,7 @@ pa_ip (str)
else if (*s == '*')
break;
name = s;
-
+
name = s;
while (*s != ',' && *s != ' ' && *s != '\t')
s += 1;
@@ -2652,7 +2721,7 @@ pa_ip (str)
if (*s == ',')
{
s++;
-
+
/* 64 bit conditions. */
if (*args == 'U')
{
@@ -2663,7 +2732,7 @@ pa_ip (str)
}
else if (*s == '*')
break;
-
+
if (strncasecmp (s, "sbz", 3) == 0)
{
cmpltr = 2;
@@ -3149,6 +3218,13 @@ pa_ip (str)
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);
@@ -3250,7 +3326,7 @@ pa_ip (str)
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);
@@ -3373,7 +3449,7 @@ pa_ip (str)
flag = QUAD;
opcode |= flag << 13;
if (the_insn.fpof1 == SGL
- || the_insn.fpof1 == DBL
+ || the_insn.fpof1 == DBL
|| the_insn.fpof1 == QUAD)
{
if (the_insn.fpof2 == SGL
@@ -3392,7 +3468,7 @@ pa_ip (str)
abort ();
}
else if (the_insn.fpof1 == W
- || the_insn.fpof1 == DW
+ || the_insn.fpof1 == DW
|| the_insn.fpof1 == QW)
{
if (the_insn.fpof2 == SGL
@@ -3403,7 +3479,7 @@ pa_ip (str)
abort ();
}
else if (the_insn.fpof1 == UW
- || the_insn.fpof1 == UDW
+ || the_insn.fpof1 == UDW
|| the_insn.fpof1 == UQW)
{
if (the_insn.fpof2 == SGL
@@ -3603,7 +3679,7 @@ pa_ip (str)
case 'j':
{
struct pa_11_fp_reg_struct result;
-
+
/* This should be more strict. Small steps. */
if (strict && *s != '%')
break;
@@ -3626,7 +3702,7 @@ pa_ip (str)
case 'k':
{
struct pa_11_fp_reg_struct result;
-
+
/* This should be more strict. Small steps. */
if (strict && *s != '%')
break;
@@ -3649,7 +3725,7 @@ pa_ip (str)
case 'l':
{
struct pa_11_fp_reg_struct result;
-
+
/* This should be more strict. Small steps. */
if (strict && *s != '%')
break;
@@ -3672,7 +3748,7 @@ pa_ip (str)
case 'm':
{
struct pa_11_fp_reg_struct result;
-
+
/* This should be more strict. Small steps. */
if (strict && *s != '%')
break;
@@ -4189,10 +4265,10 @@ md_apply_fix (fixP, valp)
&& 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);
#undef arg_reloc_stub_needed
-
+
switch (fmt)
{
/* Handle all opcodes with the 'j' operand type. */
@@ -5259,6 +5335,169 @@ pa_parse_neg_cmpsub_cmpltr (s, isbranch)
}
+/* Parse a 64 bit compare and branch completer returning the number (for
+ encoding in instrutions) of the given completer.
+
+ Nonnegated comparisons are returned as 0-7, negated comparisons are
+ returned as 8-15. */
+
+static int
+pa_parse_cmpb_64_cmpltr (s)
+ char **s;
+{
+ int cmpltr;
+ char *name = *s + 1;
+ char c;
+ char *save_s = *s;
+
+ 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;
+}
+
+/* Parse a 64 bit compare immediate and branch completer returning the number
+ (for encoding in instrutions) of the given completer. */
+
+static int
+pa_parse_cmpib_64_cmpltr (s)
+ char **s;
+{
+ int cmpltr;
+ char *name = *s + 1;
+ char c;
+ char *save_s = *s;
+
+ 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;
+}
+
/* Parse a non-negated addition completer returning the number
(for encoding in instrutions) of the given completer.
@@ -5409,6 +5648,108 @@ pa_parse_neg_add_cmpltr (s, isbranch)
return cmpltr;
}
+/* Parse a 64 bit wide mode add and branch completer returning the number (for
+ encoding in instrutions) of the given completer. */
+
+static int
+pa_parse_addb_64_cmpltr (s)
+ char **s;
+{
+ 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;
+}
+
#ifdef OBJ_SOM
/* Handle an alignment directive. Special so that we can update the
alignment of the subspace if necessary. */
@@ -5621,7 +5962,7 @@ pa_build_unwind_subspace (call_info)
reloc = R_PARISC_DIR32;
else
reloc = R_PARISC_SEGREL32;
-
+
/* Get into the right seg/subseg. This may involve creating
the seg the first time through. Make sure to have the
old seg/subseg so that we can reset things when we are done. */
@@ -7836,7 +8177,7 @@ pa_text (unused)
selectors).
Reject reductions involving symbols with external scope; such
- reductions make life a living hell for object file editors.
+ reductions make life a living hell for object file editors.
FIXME. Also reject R_HPPA relocations which are 32bits wide in
the code space. The SOM BFD backend doesn't know how to pull the
@@ -7856,7 +8197,7 @@ hppa_fix_adjustable (fixp)
return 0;
/* Reject reductions of symbols in sym1-sym2 expressions when
- the fixup will occur in a CODE subspace.
+ 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