/* tc-hppa.c -- Assemble for the PA
Copyright 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
- 2002, 2003 Free Software Foundation, Inc.
+ 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
You should have received a copy of the GNU General Public License
along with GAS; see the file COPYING. If not, write to the Free
- Software Foundation, 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
+ Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
/* HP PA-RISC support was contributed by the Center for Software Science
at the University of Utah. */
/* Holds the last field selector. */
static int hppa_field_selector;
-/* Nonzero when strict syntax checking is enabled. Zero otherwise.
+/* Nonzero when strict matching is enabled. Zero otherwise.
- Each opcode in the table has a flag which indicates whether or not
- strict syntax checking should be enabled for that instruction. */
-static int strict = 0;
+ Each opcode in the table has a flag which indicates whether or
+ not strict matching should be enabled for that instruction.
+
+ Mainly, strict causes errors to be ignored when a match failure
+ occurs. However, it also affects the parsing of register fields
+ by pa_parse_number. */
+static int strict;
/* pa_parse_number returns values in `pa_number'. Mostly
pa_parse_number is used to return a register number, with floating
%r26 - %r23 have %arg0 - %arg3 as synonyms
%r28 - %r29 have %ret0 - %ret1 as synonyms
+ %fr4 - %fr7 have %farg0 - %farg3 as synonyms
%r30 has %sp as a synonym
%r27 has %dp as a synonym
%r2 has %rp as a synonym
{"%dp", 27},
{"%eiem", 15},
{"%eirr", 23},
- {"%farg0", 5},
- {"%farg1", 6},
- {"%farg2", 7},
- {"%farg3", 8},
+ {"%farg0", 4 + FP_REG_BASE},
+ {"%farg1", 5 + FP_REG_BASE},
+ {"%farg2", 6 + FP_REG_BASE},
+ {"%farg3", 7 + FP_REG_BASE},
{"%fr0", 0 + FP_REG_BASE},
{"%fr0l", 0 + FP_REG_BASE},
{"%fr0r", 0 + FP_REG_BASE + FP_REG_RSEL},
} \
}
-/* Variant of CHECK_FIELD for use in md_apply_fix3 and other places where
+/* 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) \
label_symbols_rootp = label_chain;
}
+
+#ifdef OBJ_ELF
+ dwarf2_emit_label (symbol);
+#endif
}
/* Removes a label definition for the current space.
the_insn.reloc = R_HPPA_NONE;
- /* If this instruction is specific to a particular architecture,
- then set a new architecture. */
- /* But do not automatically promote to pa2.0. The automatic promotion
- crud is for compatibility with HP's old assemblers only. */
- if (insn->arch < 20
+ if (insn->arch >= pa20
&& bfd_get_mach (stdoutput) < insn->arch)
- {
- if (!bfd_set_arch_mach (stdoutput, bfd_arch_hppa, insn->arch))
- as_warn (_("could not update architecture and machine"));
- }
- else if (bfd_get_mach (stdoutput) < insn->arch)
- {
- match = FALSE;
- goto failed;
- }
+ goto failed;
/* Build the opcode, checking as we go to make
sure that the operands match. */
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)
{
+ /* This is a match failure. */
s--;
break;
}
int m = 0;
if (*s == ',')
{
- int found = 0;
s++;
if (strncasecmp (s, "ma", 2) == 0)
{
a = 0;
m = 1;
- found = 1;
+ s += 2;
}
else if (strncasecmp (s, "mb", 2) == 0)
{
a = 1;
m = 1;
- found = 1;
+ s += 2;
}
-
- /* When in strict mode, pass through for cache op. */
- if (!found && strict)
+ else if (strict)
+ /* This is a match failure. */
s--;
else
{
- if (!found)
- as_bad (_("Invalid Short Load/Store Completer."));
+ as_bad (_("Invalid Short Load/Store Completer."));
s += 2;
}
}
a = 0;
else if (strncasecmp (s, "e", 1) == 0)
a = 1;
- /* When in strict mode this is a match failure. */
+ /* In strict mode, this is a match failure. */
else if (strict)
{
s--;
/* 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;
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)
/* Apply a fixup to an instruction. */
void
-md_apply_fix3 (fixP, valP, seg)
+md_apply_fix (fixP, valP, seg)
fixS *fixP;
valueT *valP;
segT seg ATTRIBUTE_UNUSED;
pa_block (z)
int z ATTRIBUTE_UNUSED;
{
- char *p;
- long int temp_fill;
unsigned int temp_size;
- unsigned int i;
#ifdef OBJ_SOM
/* We must have a valid space and subspace. */
temp_size = get_absolute_expression ();
- /* Always fill with zeros, that's what the HP assembler does. */
- temp_fill = 0;
-
- p = frag_var (rs_fill, (int) temp_size, (int) temp_size,
- (relax_substateT) 0, (symbolS *) 0, (offsetT) 1, NULL);
- memset (p, 0, temp_size);
-
- /* Convert 2 bytes at a time. */
-
- for (i = 0; i < temp_size; i += 2)
+ if (temp_size > 0x3FFFFFFF)
{
- md_number_to_chars (p + i,
- (valueT) temp_fill,
- (int) ((temp_size - i) > 2 ? 2 : (temp_size - i)));
+ 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 ();