aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2003-12-03 17:38:48 +0000
committerNick Clifton <nickc@redhat.com>2003-12-03 17:38:48 +0000
commit8884595866edbe6697a1268f5605b7ffe91efb0a (patch)
tree1710b68cb96d5cba8449135a5113d5c9a6a8c62f /gas
parentf8fc3443814cb6f315680a7fb34ff4effc86442e (diff)
downloadgdb-8884595866edbe6697a1268f5605b7ffe91efb0a.zip
gdb-8884595866edbe6697a1268f5605b7ffe91efb0a.tar.gz
gdb-8884595866edbe6697a1268f5605b7ffe91efb0a.tar.bz2
Add support for the M32R2 processor.
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog9
-rw-r--r--gas/config/tc-m32r.c305
-rw-r--r--gas/config/tc-m32r.h23
-rw-r--r--gas/doc/c-m32r.texi143
-rw-r--r--gas/testsuite/ChangeLog6
-rw-r--r--gas/testsuite/gas/m32r/m32r2.d92
-rw-r--r--gas/testsuite/gas/m32r/m32r2.exp5
-rw-r--r--gas/testsuite/gas/m32r/m32r2.s126
8 files changed, 669 insertions, 40 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 634166f..f3d2fb8 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,12 @@
+2003-12-03 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
+
+ * config/tc-m32r.h : Add support for new machine m32r2.
+ * config/tc-m32r.c : Likewise.
+ Add new command line switches and directives to allow endian-ness
+ to be selected and some warnings to be turned into errors.
+ (line_separator_chars) : Use '!'.
+ * doc/c-m32r.texi: Document new switches and directives.
+
2003-12-03 Dave Airlie <airlied@linux.ie>
* configure.in: Likewise.
diff --git a/gas/config/tc-m32r.c b/gas/config/tc-m32r.c
index dc640c4..58f9054 100644
--- a/gas/config/tc-m32r.c
+++ b/gas/config/tc-m32r.c
@@ -27,6 +27,7 @@
#include "opcodes/m32r-desc.h"
#include "opcodes/m32r-opc.h"
#include "cgen.h"
+#include "elf/m32r.h"
/* Linked list of symbols that are debugging symbols to be defined as the
beginning of the current instruction. */
@@ -93,21 +94,41 @@ static const char *m32r_cpu_desc;
shouldn't assume or require it to). */
static int warn_unmatched_high = 0;
-/* Non-zero if -m32rx has been specified, in which case support for the
- extended M32RX instruction set should be enabled. */
-static int enable_m32rx = 0;
+/* 1 if -m32rx has been specified, in which case support for
+ the extended M32RX instruction set should be enabled.
+ 2 if -m32r2 has been specified, in which case support for
+ the extended M32R2 instruction set should be enabled. */
+static int enable_m32rx = 0; /* Default to M32R. */
/* Non-zero if -m32rx -hidden has been specified, in which case support for
the special M32RX instruction set should be enabled. */
static int enable_special = 0;
+/* Non-zero if -bitinst has been specified, in which case support
+ for extended M32R bit-field instruction set should be enabled. */
+static int enable_special_m32r = 0;
+
+/* Non-zero if -float has been specified, in which case support for
+ extended M32R floating point instruction set should be enabled. */
+static int enable_special_float = 0;
+
/* Non-zero if the programmer should be warned when an explicit parallel
instruction might have constraint violations. */
static int warn_explicit_parallel_conflicts = 1;
+/* Non-zero if the programmer should receive an error message when an
+ explicit parallel instruction might have constraint violations. */
+static int error_explicit_parallel_conflicts = 1;
+
/* Non-zero if insns can be made parallel. */
+static int use_parallel = 1;
+
+/* Non-zero if optimizations should be performed. */
static int optimize;
+/* m32r er_flags. */
+static int m32r_flags = 0;
+
/* Stuff for .scomm symbols. */
static segT sbss_section;
static asection scom_section;
@@ -115,7 +136,7 @@ static asymbol scom_symbol;
const char comment_chars[] = ";";
const char line_comment_chars[] = "#";
-const char line_separator_chars[] = "";
+const char line_separator_chars[] = "!";
const char EXP_CHARS[] = "eE";
const char FLT_CHARS[] = "dD";
@@ -146,17 +167,28 @@ struct m32r_hi_fixup
static struct m32r_hi_fixup *m32r_hi_fixup_list;
-static void allow_m32rx PARAMS ((int));
+struct {
+ enum bfd_architecture bfd_mach;
+ int mach_flags;
+} mach_table[] =
+{
+ { bfd_mach_m32r, (1<<MACH_M32R) },
+ { bfd_mach_m32rx, (1<<MACH_M32RX) },
+ { bfd_mach_m32r2, (1<<MACH_M32R2) }
+};
+
+static void allow_m32rx (int);
static void
-allow_m32rx (on)
- int on;
+allow_m32rx (int on)
{
enable_m32rx = on;
if (stdoutput != NULL)
- bfd_set_arch_mach (stdoutput, TARGET_ARCH,
- enable_m32rx ? bfd_mach_m32rx : bfd_mach_m32r);
+ bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach_table[on].bfd_mach);
+
+ if (gas_cgen_cpu_desc != NULL)
+ gas_cgen_cpu_desc->machs = mach_table[on].mach_flags;
}
#define M32R_SHORTOPTS "O"
@@ -165,20 +197,42 @@ const char *md_shortopts = M32R_SHORTOPTS;
struct option md_longopts[] =
{
-#define OPTION_M32R (OPTION_MD_BASE)
-#define OPTION_M32RX (OPTION_M32R + 1)
-#define OPTION_WARN_PARALLEL (OPTION_M32RX + 1)
-#define OPTION_NO_WARN_PARALLEL (OPTION_WARN_PARALLEL + 1)
-#define OPTION_SPECIAL (OPTION_NO_WARN_PARALLEL + 1)
-#define OPTION_WARN_UNMATCHED (OPTION_SPECIAL + 1)
+#define OPTION_M32R (OPTION_MD_BASE)
+#define OPTION_M32RX (OPTION_M32R + 1)
+#define OPTION_M32R2 (OPTION_M32RX + 1)
+#define OPTION_BIG (OPTION_M32R2 + 1)
+#define OPTION_LITTLE (OPTION_BIG + 1)
+#define OPTION_PARALLEL (OPTION_LITTLE + 1)
+#define OPTION_NO_PARALLEL (OPTION_PARALLEL + 1)
+#define OPTION_WARN_PARALLEL (OPTION_NO_PARALLEL + 1)
+#define OPTION_NO_WARN_PARALLEL (OPTION_WARN_PARALLEL + 1)
+#define OPTION_ERROR_PARALLEL (OPTION_NO_WARN_PARALLEL + 1)
+#define OPTION_NO_ERROR_PARALLEL (OPTION_ERROR_PARALLEL + 1)
+#define OPTION_SPECIAL (OPTION_NO_ERROR_PARALLEL + 1)
+#define OPTION_SPECIAL_M32R (OPTION_SPECIAL + 1)
+#define OPTION_SPECIAL_FLOAT (OPTION_SPECIAL_M32R + 1)
+#define OPTION_WARN_UNMATCHED (OPTION_SPECIAL_FLOAT + 1)
#define OPTION_NO_WARN_UNMATCHED (OPTION_WARN_UNMATCHED + 1)
{"m32r", no_argument, NULL, OPTION_M32R},
{"m32rx", no_argument, NULL, OPTION_M32RX},
+ {"m32r2", no_argument, NULL, OPTION_M32R2},
+ {"big", no_argument, NULL, OPTION_BIG},
+ {"little", no_argument, NULL, OPTION_LITTLE},
+ {"EB", no_argument, NULL, OPTION_BIG},
+ {"EL", no_argument, NULL, OPTION_LITTLE},
+ {"parallel", no_argument, NULL, OPTION_PARALLEL},
+ {"no-parallel", no_argument, NULL, OPTION_NO_PARALLEL},
{"warn-explicit-parallel-conflicts", no_argument, NULL, OPTION_WARN_PARALLEL},
{"Wp", no_argument, NULL, OPTION_WARN_PARALLEL},
{"no-warn-explicit-parallel-conflicts", no_argument, NULL, OPTION_NO_WARN_PARALLEL},
{"Wnp", no_argument, NULL, OPTION_NO_WARN_PARALLEL},
+ {"error-explicit-parallel-conflicts", no_argument, NULL, OPTION_ERROR_PARALLEL},
+ {"Ep", no_argument, NULL, OPTION_ERROR_PARALLEL},
+ {"no-error-explicit-parallel-conflicts", no_argument, NULL, OPTION_NO_ERROR_PARALLEL},
+ {"Enp", no_argument, NULL, OPTION_NO_ERROR_PARALLEL},
{"hidden", no_argument, NULL, OPTION_SPECIAL},
+ {"bitinst", no_argument, NULL, OPTION_SPECIAL_M32R},
+ {"float", no_argument, NULL, OPTION_SPECIAL_FLOAT},
/* Sigh. I guess all warnings must now have both variants. */
{"warn-unmatched-high", no_argument, NULL, OPTION_WARN_UNMATCHED},
{"Wuh", no_argument, NULL, OPTION_WARN_UNMATCHED},
@@ -197,6 +251,29 @@ struct option md_longopts[] =
size_t md_longopts_size = sizeof (md_longopts);
+static void little (int);
+static int parallel (void);
+
+static void
+little (int on)
+{
+ target_big_endian = ! on;
+}
+
+/* Use parallel execution. */
+
+static int
+parallel (void)
+{
+ if (! enable_m32rx)
+ return 0;
+
+ if (use_parallel == 1)
+ return 1;
+
+ return 0;
+}
+
int
md_parse_option (c, arg)
int c;
@@ -206,6 +283,7 @@ md_parse_option (c, arg)
{
case 'O':
optimize = 1;
+ use_parallel = 1;
break;
case OPTION_M32R:
@@ -216,12 +294,46 @@ md_parse_option (c, arg)
allow_m32rx (1);
break;
+ case OPTION_M32R2:
+ allow_m32rx (2);
+ enable_special = 1;
+ enable_special_m32r = 1;
+ break;
+
+ case OPTION_BIG:
+ target_big_endian = 1;
+ break;
+
+ case OPTION_LITTLE:
+ target_big_endian = 0;
+ break;
+
+ case OPTION_PARALLEL:
+ use_parallel = 1;
+ break;
+
+ case OPTION_NO_PARALLEL:
+ use_parallel = 0;
+ break;
+
case OPTION_WARN_PARALLEL:
warn_explicit_parallel_conflicts = 1;
+ error_explicit_parallel_conflicts = 0;
break;
case OPTION_NO_WARN_PARALLEL:
warn_explicit_parallel_conflicts = 0;
+ error_explicit_parallel_conflicts = 0;
+ break;
+
+ case OPTION_ERROR_PARALLEL:
+ warn_explicit_parallel_conflicts = 1;
+ error_explicit_parallel_conflicts = 1;
+ break;
+
+ case OPTION_NO_ERROR_PARALLEL:
+ error_explicit_parallel_conflicts = 0;
+ warn_explicit_parallel_conflicts = 0;
break;
case OPTION_SPECIAL:
@@ -235,6 +347,14 @@ md_parse_option (c, arg)
}
break;
+ case OPTION_SPECIAL_M32R:
+ enable_special_m32r = 1;
+ break;
+
+ case OPTION_SPECIAL_FLOAT:
+ enable_special_float = 1;
+ break;
+
case OPTION_WARN_UNMATCHED:
warn_unmatched_high = 1;
break;
@@ -271,7 +391,17 @@ md_show_usage (stream)
fprintf (stream, _("\
-m32rx support the extended m32rx instruction set\n"));
fprintf (stream, _("\
- -O try to combine instructions in parallel\n"));
+ -m32r2 support the extended m32r2 instruction set\n"));
+ fprintf (stream, _("\
+ -EL,-little produce little endian code and data\n"));
+ fprintf (stream, _("\
+ -EB,-big produce big endian code and data\n"));
+ fprintf (stream, _("\
+ -parallel try to combine instructions in parallel\n"));
+ fprintf (stream, _("\
+ -no-parallel disable -parallel\n"));
+ fprintf (stream, _("\
+ -O try to optimize code. Implies -parallel\n"));
fprintf (stream, _("\
-warn-explicit-parallel-conflicts warn when parallel instructions\n"));
@@ -285,6 +415,18 @@ md_show_usage (stream)
-Wp synonym for -warn-explicit-parallel-conflicts\n"));
fprintf (stream, _("\
-Wnp synonym for -no-warn-explicit-parallel-conflicts\n"));
+ fprintf (stream, _("\
+ -error-explicit-parallel-conflicts error when parallel instructions\n"));
+ fprintf (stream, _("\
+ violate contraints\n"));
+ fprintf (stream, _("\
+ -no-error-explicit-parallel-conflicts do not error when parallel\n"));
+ fprintf (stream, _("\
+ instructions violate contraints\n"));
+ fprintf (stream, _("\
+ -Ep synonym for -error-explicit-parallel-conflicts\n"));
+ fprintf (stream, _("\
+ -Enp synonym for -no-error-explicit-parallel-conflicts\n"));
fprintf (stream, _("\
-warn-unmatched-high warn when an (s)high reloc has no matching low reloc\n"));
@@ -319,14 +461,16 @@ const pseudo_typeS md_pseudo_table[] =
{ "fillinsn", fill_insn, 0 },
{ "scomm", m32r_scomm, 0 },
{ "debugsym", debug_sym, 0 },
- /* Not documented as so far there is no need for them.... */
{ "m32r", allow_m32rx, 0 },
{ "m32rx", allow_m32rx, 1 },
+ { "m32r2", allow_m32rx, 2 },
+ { "little", little, 1 },
+ { "big", little, 0 },
{ NULL, NULL, 0 }
};
/* FIXME: Should be machine generated. */
-#define NOP_INSN 0x7000
+#define NOP_INSN 0x7000
#define PAR_NOP_INSN 0xf000 /* Can only be used in 2nd slot. */
/* This is called from HANDLE_ALIGN in write.c. Fill in the contents
@@ -459,6 +603,16 @@ expand_debug_syms (syms, align)
input_line_pointer = save_input_line;
}
+void
+m32r_flush_pending_output()
+{
+ if (debug_sym_link)
+ {
+ expand_debug_syms (debug_sym_link, 1);
+ debug_sym_link = (sym_linkS *) 0;
+ }
+}
+
/* Cover function to fill_insn called after a label and at end of assembly.
The result is always 1: we're called in a conditional to see if the
current line is a label. */
@@ -488,6 +642,24 @@ m32r_fill_insn (done)
return 1;
}
+/* The default target format to use. */
+
+const char *
+m32r_target_format ()
+{
+#ifdef TE_LINUX
+ if (target_big_endian)
+ return "elf32-m32r-linux";
+ else
+ return "elf32-m32rle-linux";
+#else
+ if (target_big_endian)
+ return "elf32-m32r";
+ else
+ return "elf32-m32rle";
+#endif
+}
+
void
md_begin ()
{
@@ -500,7 +672,8 @@ md_begin ()
/* Set the machine number and endian. */
gas_cgen_cpu_desc = m32r_cgen_cpu_open (CGEN_CPU_OPEN_MACHS, 0,
CGEN_CPU_OPEN_ENDIAN,
- CGEN_ENDIAN_BIG,
+ (target_big_endian ?
+ CGEN_ENDIAN_BIG : CGEN_ENDIAN_LITTLE),
CGEN_CPU_OPEN_END);
m32r_cgen_init_asm (gas_cgen_cpu_desc);
@@ -711,7 +884,8 @@ can_make_parallel (a, b)
go away if the instructions are swapped, and we want to make
sure that any other errors are detected before this happens. */
if (a_pipe == PIPE_S
- || b_pipe == PIPE_O)
+ || b_pipe == PIPE_O
+ || (b_pipe == PIPE_O_OS && (enable_m32rx != 2)))
return _("Instructions share the same execution pipeline");
return NULL;
@@ -791,8 +965,26 @@ assemble_two_insns (str, str2, parallel_p)
as_bad (_("not a 16 bit instruction '%s'"), str);
return;
}
+#ifdef E_M32R2_ARCH
+ else if ((enable_m32rx == 1)
+ /* FIXME: Need standard macro to perform this test. */
+ && ((CGEN_INSN_ATTR_VALUE (first.insn, CGEN_INSN_MACH)
+ & (1 << MACH_M32R2))
+ && !((CGEN_INSN_ATTR_VALUE (first.insn, CGEN_INSN_MACH)
+ & (1 << MACH_M32RX)))))
+ {
+ /* xgettext:c-format */
+ as_bad (_("instruction '%s' is for the M32R2 only"), str);
+ return;
+ }
+ else if ((! enable_special
+ && CGEN_INSN_ATTR_VALUE (first.insn, CGEN_INSN_SPECIAL))
+ || (! enable_special_m32r
+ && CGEN_INSN_ATTR_VALUE (first.insn, CGEN_INSN_SPECIAL_M32R)))
+#else
else if (! enable_special
&& CGEN_INSN_ATTR_VALUE (first.insn, CGEN_INSN_SPECIAL))
+#endif
{
/* xgettext:c-format */
as_bad (_("unknown instruction '%s'"), str);
@@ -887,8 +1079,26 @@ assemble_two_insns (str, str2, parallel_p)
as_bad (_("not a 16 bit instruction '%s'"), str);
return;
}
+#ifdef E_M32R2_ARCH
+ else if ((enable_m32rx == 1)
+ /* FIXME: Need standard macro to perform this test. */
+ && ((CGEN_INSN_ATTR_VALUE (first.insn, CGEN_INSN_MACH)
+ & (1 << MACH_M32R2))
+ && !((CGEN_INSN_ATTR_VALUE (first.insn, CGEN_INSN_MACH)
+ & (1 << MACH_M32RX)))))
+ {
+ /* xgettext:c-format */
+ as_bad (_("instruction '%s' is for the M32R2 only"), str);
+ return;
+ }
+ else if ((! enable_special
+ && CGEN_INSN_ATTR_VALUE (second.insn, CGEN_INSN_SPECIAL))
+ || (! enable_special_m32r
+ && CGEN_INSN_ATTR_VALUE (second.insn, CGEN_INSN_SPECIAL_M32R)))
+#else
else if (! enable_special
&& CGEN_INSN_ATTR_VALUE (second.insn, CGEN_INSN_SPECIAL))
+#endif
{
/* xgettext:c-format */
as_bad (_("unknown instruction '%s'"), str);
@@ -944,13 +1154,17 @@ assemble_two_insns (str, str2, parallel_p)
if (parallel_p && warn_explicit_parallel_conflicts)
{
+ void (* func)(const char *, ...);
+
+ func = error_explicit_parallel_conflicts ? as_bad : as_warn;
+
if (first_writes_to_seconds_operands (&first, &second, FALSE))
/* xgettext:c-format */
- as_warn (_("%s: output of 1st instruction is the same as an input to 2nd instruction - is this intentional ?"), str2);
+ func (_("%s: output of 1st instruction is the same as an input to 2nd instruction - is this intentional ?"), str2);
if (first_writes_to_seconds_operands (&second, &first, FALSE))
/* xgettext:c-format */
- as_warn (_("%s: output of 2nd instruction is the same as an input to 1st instruction - is this intentional ?"), str2);
+ func (_("%s: output of 2nd instruction is the same as an input to 1st instruction - is this intentional ?"), str2);
}
if (!parallel_p
@@ -1001,6 +1215,16 @@ assemble_two_insns (str, str2, parallel_p)
return;
}
+ if (CGEN_INSN_ATTR_VALUE (first.insn, CGEN_INSN_SPECIAL)
+ || CGEN_INSN_ATTR_VALUE (second.insn, CGEN_INSN_SPECIAL))
+ m32r_flags |= E_M32R_HAS_HIDDEN_INST;
+ if (CGEN_INSN_ATTR_VALUE (first.insn, CGEN_INSN_SPECIAL_M32R)
+ || CGEN_INSN_ATTR_VALUE (second.insn, CGEN_INSN_SPECIAL_M32R))
+ m32r_flags |= E_M32R_HAS_BIT_INST;
+ if (CGEN_INSN_ATTR_VALUE (first.insn, CGEN_INSN_SPECIAL_FLOAT)
+ || CGEN_INSN_ATTR_VALUE (second.insn, CGEN_INSN_SPECIAL_FLOAT))
+ m32r_flags |= E_M32R_HAS_FLOAT_INST;
+
/* Set these so m32r_fill_insn can use them. */
prev_seg = now_seg;
prev_subseg = now_subseg;
@@ -1021,6 +1245,7 @@ md_assemble (str)
if ((str2 = strstr (str, "||")) != NULL)
{
assemble_two_insns (str, str2, 1);
+ m32r_flags |= E_M32R_HAS_PARALLEL;
return;
}
@@ -1043,8 +1268,26 @@ md_assemble (str)
return;
}
+#ifdef E_M32R2_ARCH
+ if ((enable_m32rx == 1)
+ /* FIXME: Need standard macro to perform this test. */
+ && ((CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_MACH)
+ & (1 << MACH_M32R2))
+ && !((CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_MACH)
+ & (1 << MACH_M32RX)))))
+ {
+ /* xgettext:c-format */
+ as_bad (_("instruction '%s' is for the M32R2 only"), str);
+ return;
+ }
+ else if ((! enable_special
+ && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_SPECIAL))
+ || (! enable_special_m32r
+ && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_SPECIAL_M32R)))
+#else
if (! enable_special
&& CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_SPECIAL))
+#endif
{
/* xgettext:c-format */
as_bad (_("unknown instruction '%s'"), str);
@@ -1058,6 +1301,13 @@ md_assemble (str)
return;
}
+ if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_SPECIAL))
+ m32r_flags |= E_M32R_HAS_HIDDEN_INST;
+ if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_SPECIAL_M32R))
+ m32r_flags |= E_M32R_HAS_BIT_INST;
+ if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_SPECIAL_FLOAT))
+ m32r_flags |= E_M32R_HAS_FLOAT_INST;
+
if (CGEN_INSN_BITSIZE (insn.insn) == 32)
{
/* 32 bit insns must live on 32 bit boundaries. */
@@ -1122,8 +1372,7 @@ md_assemble (str)
Otherwise call can_make_parallel() with both orderings of the
instructions to see if they can be combined. */
if (! on_32bit_boundary_p
- && enable_m32rx
- && optimize
+ && parallel ()
&& CGEN_INSN_ATTR_VALUE (insn.orig_insn, CGEN_INSN_RELAXABLE) == 0
&& ! writes_to_pc (&prev_insn)
&& ! first_writes_to_seconds_operands (&prev_insn, &insn, FALSE))
@@ -1949,3 +2198,11 @@ m32r_fix_adjustable (fixP)
return 1;
}
+
+void
+m32r_elf_final_processing ()
+{
+ if (use_parallel)
+ m32r_flags |= E_M32R_HAS_PARALLEL;
+ elf_elfheader (stdoutput)->e_flags |= m32r_flags;
+}
diff --git a/gas/config/tc-m32r.h b/gas/config/tc-m32r.h
index f54c980..1a8e655 100644
--- a/gas/config/tc-m32r.h
+++ b/gas/config/tc-m32r.h
@@ -1,5 +1,5 @@
/* tc-m32r.h -- Header file for tc-m32r.c.
- Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -22,20 +22,27 @@
#define TC_M32R
#ifndef BFD_ASSEMBLER
-/* leading space so will compile with cc */
+/* Leading space so will compile with cc. */
#error M32R support requires BFD_ASSEMBLER
#endif
-#define LISTING_HEADER "M32R GAS "
+#define LISTING_HEADER \
+ (target_big_endian ? "M32R GAS" : "M32R GAS Little Endian")
/* The target BFD architecture. */
#define TARGET_ARCH bfd_arch_m32r
-#define TARGET_FORMAT "elf32-m32r"
+/* The endianness of the target format may change based on command
+ line arguments. */
+#define TARGET_FORMAT m32r_target_format()
+extern const char *m32r_target_format PARAMS ((void));
+/* Default to big endian. */
+#ifndef TARGET_BYTES_BIG_ENDIAN
#define TARGET_BYTES_BIG_ENDIAN 1
+#endif
-/* call md_pcrel_from_section, not md_pcrel_from */
+/* Call md_pcrel_from_section, not md_pcrel_from. */
long md_pcrel_from_section PARAMS ((struct fix *, segT));
#define MD_PCREL_FROM_SECTION(FIX, SEC) md_pcrel_from_section(FIX, SEC)
@@ -101,3 +108,9 @@ int m32r_fill_insn PARAMS ((int));
#define md_cleanup m32r_elf_section_change_hook
#define md_elf_section_change_hook m32r_elf_section_change_hook
extern void m32r_elf_section_change_hook PARAMS ((void));
+
+#define md_flush_pending_output() m32r_flush_pending_output ()
+extern void m32r_flush_pending_output PARAMS ((void));
+
+#define elf_tc_final_processing m32r_elf_final_processing
+extern void m32r_elf_final_processing PARAMS ((void));
diff --git a/gas/doc/c-m32r.texi b/gas/doc/c-m32r.texi
index a1c414c..1324cd7 100644
--- a/gas/doc/c-m32r.texi
+++ b/gas/doc/c-m32r.texi
@@ -29,6 +29,7 @@ The Renease M32R version of @code{@value{AS}} has a few machine
dependent options:
@table @code
+
@item -m32rx
@cindex @samp{-m32rx} option, M32RX
@cindex architecture options, M32RX
@@ -40,6 +41,13 @@ to the M32RX microprocessor, which adds some more instructions to the
basic M32R instruction set, and some additional parameters to some of
the original instructions.
+@item -m32r2
+@cindex @samp{-m32rx} option, M32R2
+@cindex architecture options, M32R2
+@cindex M32R architecture options
+This option changes the target processor to the the M32R2
+microprocessor.
+
@item -m32r
@cindex @samp{-m32r} option, M32R
@cindex architecture options, M32R
@@ -48,6 +56,42 @@ This option can be used to restore the assembler's default behaviour of
assembling for the M32R microprocessor. This can be useful if the
default has been changed by a previous command line option.
+@item -little
+@cindex @code{-little} option, M32R
+This option tells the assembler to produce little-endian code and
+data. The default is dependent upon how the toolchain was
+configured.
+
+@item -EL
+@cindex @code{-EL} option, M32R
+This is a synonum for @emph{-little}.
+
+@item -big
+@cindex @code{-big} option, M32R
+This option tells the assembler to produce big-endian code and
+data.
+
+@item -EB
+@cindex @code{-EB} option, M32R
+This is a synonum for @emph{-big}.
+
+@item -parallel
+@cindex @code{-parallel} option, M32RX
+This option tells the assembler to attempts to combine two sequential
+instructions into a single, parallel instruction, where it is legal to
+do so.
+
+@item -no-parallel
+@cindex @code{-no-parallel} option, M32RX
+This option disables a previously enabled @emph{-parallel} option.
+
+@item -O
+@cindex @code{-O} option, M32RX
+This option tells the assembler to attempt to optimize the
+instructions that it produces. This includes filling delay slots and
+converting sequential instructions into parallel ones. This option
+implies @emph{-parallel}.
+
@item -warn-explicit-parallel-conflicts
@cindex @samp{-warn-explicit-parallel-conflicts} option, M32RX
Instructs @code{@value{AS}} to produce warning messages when
@@ -75,6 +119,48 @@ questionable parallel instructions are encountered.
This is a shorter synonym for the @emph{-no-warn-explicit-parallel-conflicts}
option.
+@item -error-explicit-parallel-conflicts
+@cindex @samp{-error-explicit-parallel-conflicts} option, M32RX
+This option performs the same thing as the
+@emph{-warn-explicit-parallel-conflicts} expcept that instead of
+warning messages being produced, error messages will be produced. If
+any error messages are generated then GAS will not produce an output
+file.
+
+@item -no-error-explicit-parallel-conflicts
+@cindex @samp{-no-error-explicit-parallel-conflicts} option, M32RX
+This option disables a previously enabled
+@emph{-error-explicit-parallel-conflicts} option.
+
+@item -Ep
+@cindex @samp{-Ep} option, M32RX
+This is a shorter synonym for the @emph{-error-explicit-parallel-conflicts}
+option.
+
+@item -Enp
+@cindex @samp{-Enp} option, M32RX
+This is a shorter synonym for the @emph{-no-error-explicit-parallel-conflicts}
+option.
+
+@item -warn-unmatched-high
+@cindex @samp{-warn-unmatched-high} option, M32R
+This option tells the assembler to produce a warning message if a
+@code{.high} pseudo op is encountered without a mathcing @code{.low}
+pseudo op. The presence of such an unmatches pseudo op usually
+indicates a programming error.
+
+@item -no-warn-unmatched-high
+@cindex @samp{-no-warn-unmatched-high} option, M32R
+Disables a previously enabled @emph{-warn-unmatched-high} option.
+
+@item -Wuh
+@cindex @samp{-Wuh} option, M32RX
+This is a shorter synonym for the @emph{-warn-unmatched-high} option.
+
+@item -Wnuh
+@cindex @samp{-Wnuh} option, M32RX
+This is a shorter synonym for the @emph{-no-warn-unmatched-high} option.
+
@end table
@node M32R-Directives
@@ -86,9 +172,10 @@ The Renease M32R version of @code{@value{AS}} has a few architecture
specific directives:
@table @code
-@cindex @code{.low} directive, M32R
-@item .low @var{expression}
-The @code{.low} directive computes the value of its expression and
+
+@cindex @code{low} directive, M32R
+@item low @var{expression}
+The @code{low} directive computes the value of its expression and
places the lower 16-bits of the result into the immediate-field of the
instruction. For example:
@@ -97,9 +184,9 @@ instruction. For example:
add3, r0, r0, #low(fred) ; compute r0 = r0 + low 16-bits of address of fred
@end smallexample
-@item .high @var{expression}
-@cindex @code{.high} directive, M32R
-The @code{.high} directive computes the value of its expression and
+@item high @var{expression}
+@cindex @code{high} directive, M32R
+The @code{high} directive computes the value of its expression and
places the upper 16-bits of the result into the immediate-field of the
instruction. For example:
@@ -108,15 +195,15 @@ instruction. For example:
seth, r0, #high(fred) ; compute r0 = upper 16-bits of address of fred
@end smallexample
-@item .shigh @var{expression}
-@cindex @code{.shigh} directive, M32R
-The @code{.shigh} directive is very similar to the @code{.high}
+@item shigh @var{expression}
+@cindex @code{shigh} directive, M32R
+The @code{shigh} directive is very similar to the @code{high}
directive. It also computes the value of its expression and places
the upper 16-bits of the result into the immediate-field of the
-instruction. The difference is that @code{.shigh} also checks to see
+instruction. The difference is that @code{shigh} also checks to see
if the lower 16-bits could be interpreted as a signed number, and if
so it assumes that a borrow will occur from the upper-16 bits. To
-compensate for this the @code{.shigh} directive pre-biases the upper
+compensate for this the @code{shigh} directive pre-biases the upper
16 bit value by adding one to it. For example:
For example:
@@ -156,6 +243,40 @@ source code the lower 16-bits of the value are going set, so it cannot
check to make sure that an @code{or3} instruction is being used rather
than an @code{add3} instruction. It is up to the programmer to make
sure that correct directives are used.
+
+@cindex @code{.m32r} directive, M32R
+@item .m32r
+The directive performs a similar thing as the @emph{-m32r} command
+line option. It tells the assembler to only accept M32R instructions
+from now on. An instructions from later M32R architectures are
+refused.
+
+@cindex @code{.m32rx} directive, M32RX
+@item .m32rx
+The directive performs a similar thing as the @emph{-m32rx} command
+line option. It tells the assembler to start accepting the extra
+instructions in the M32RX ISA as well as the ordinary M32R ISA.
+
+@cindex @code{.m32r2} directive, M32R2
+@item .m32r2
+The directive performs a similar thing as the @emph{-m32r2} command
+line option. It tells the assembler to start accepting the extra
+instructions in the M32R2 ISA as well as the ordinary M32R ISA.
+
+@cindex @code{.little} directive, M32RX
+@item .little
+The directive performs a similar thing as the @emph{-little} command
+line option. It tells the assembler to start producing little-endian
+code and data. This option should be used with care as producing
+mixed-endian binary files is frought with danger.
+
+@cindex @code{.big} directive, M32RX
+@item .big
+The directive performs a similar thing as the @emph{-big} command
+line option. It tells the assembler to start producing big-endian
+code and data. This option should be used with care as producing
+mixed-endian binary files is frought with danger.
+
@end table
@node M32R-Warnings
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index d3de7c4..80243a4 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2003-12-02 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
+
+ * gas/m32r/m32r2.exp: New file for m32r2.
+ * gas/m32r/m32r2.s: Likewise.
+ * gas/m32r/m32r2.d: Likewise.
+
2003-12-03 Nick Clifton <nickc@redhat.com>
* gas/vax/vax.exp (do_quad): Treat a vax-*-linux-gnu target as an
diff --git a/gas/testsuite/gas/m32r/m32r2.d b/gas/testsuite/gas/m32r/m32r2.d
new file mode 100644
index 0000000..a17ed0f
--- /dev/null
+++ b/gas/testsuite/gas/m32r/m32r2.d
@@ -0,0 +1,92 @@
+#as: -m32r2
+#objdump: -dr
+#name: m32r2
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+0000 <setpsw>:
+ 0: 71 c1 71 ff setpsw #0xc1 -> setpsw #0xff
+
+0+0004 <clrpsw>:
+ 4: 72 c1 72 ff clrpsw #0xc1 -> clrpsw #0xff
+
+0+0008 <bset>:
+ 8: a0 61 00 04 bset #0x0,@\(4,r1\)
+ c: a1 61 00 04 bset #0x1,@\(4,r1\)
+ 10: a7 61 00 04 bset #0x7,@\(4,r1\)
+
+0+0014 <bclr>:
+ 14: a0 71 00 04 bclr #0x0,@\(4,r1\)
+ 18: a1 71 00 04 bclr #0x1,@\(4,r1\)
+ 1c: a7 71 00 04 bclr #0x7,@\(4,r1\)
+
+0+0020 <btst>:
+ 20: 00 fd 01 fd btst #0x0,fp -> btst #0x1,fp
+ 24: 07 fd f0 00 btst #0x7,fp \|\| nop
+ 28: 01 fd 90 82 btst #0x1,fp \|\| mv r0,r2
+ 2c: 01 fd 90 82 btst #0x1,fp \|\| mv r0,r2
+
+0+0030 <divuh>:
+ 30: 9d 1d 00 10 divuh fp,fp
+
+0+0034 <divb>:
+ 34: 9d 0d 00 18 divb fp,fp
+
+0+0038 <divub>:
+ 38: 9d 1d 00 18 divub fp,fp
+
+0+003c <remh>:
+ 3c: 9d 2d 00 10 remh fp,fp
+
+0+0040 <remuh>:
+ 40: 9d 3d 00 10 remuh fp,fp
+
+0+0044 <remb>:
+ 44: 9d 2d 00 18 remb fp,fp
+
+0+0048 <remub>:
+ 48: 9d 3d 00 18 remub fp,fp
+
+0+004c <sll>:
+ 4c: 10 41 92 43 sll r0,r1 \|\| sll r2,r3
+ 50: 12 43 90 61 sll r2,r3 \|\| mul r0,r1
+ 54: 10 41 92 63 sll r0,r1 \|\| mul r2,r3
+ 58: 60 01 92 43 ldi r0,#1 \|\| sll r2,r3
+ 5c: 10 41 e2 01 sll r0,r1 \|\| ldi r2,#1
+
+0+0060 <slli>:
+ 60: 50 41 d2 5f slli r0,#0x1 \|\| slli r2,#0x1f
+ 64: 52 5f 90 61 slli r2,#0x1f \|\| mul r0,r1
+ 68: 50 41 92 63 slli r0,#0x1 \|\| mul r2,r3
+ 6c: 60 01 d2 5f ldi r0,#1 \|\| slli r2,#0x1f
+ 70: 50 41 e2 01 slli r0,#0x1 \|\| ldi r2,#1
+
+0+0074 <sra>:
+ 74: 10 21 92 23 sra r0,r1 \|\| sra r2,r3
+ 78: 12 23 90 61 sra r2,r3 \|\| mul r0,r1
+ 7c: 10 21 92 63 sra r0,r1 \|\| mul r2,r3
+ 80: 60 01 92 23 ldi r0,#1 \|\| sra r2,r3
+ 84: 10 21 e2 01 sra r0,r1 \|\| ldi r2,#1
+
+0+0088 <srai>:
+ 88: 50 21 d2 3f srai r0,#0x1 \|\| srai r2,#0x1f
+ 8c: 52 3f 90 61 srai r2,#0x1f \|\| mul r0,r1
+ 90: 50 21 92 63 srai r0,#0x1 \|\| mul r2,r3
+ 94: 60 01 d2 3f ldi r0,#1 \|\| srai r2,#0x1f
+ 98: 50 21 e2 01 srai r0,#0x1 \|\| ldi r2,#1
+
+0+009c <srl>:
+ 9c: 10 01 92 03 srl r0,r1 \|\| srl r2,r3
+ a0: 12 03 90 61 srl r2,r3 \|\| mul r0,r1
+ a4: 10 01 92 63 srl r0,r1 \|\| mul r2,r3
+ a8: 60 01 92 03 ldi r0,#1 \|\| srl r2,r3
+ ac: 10 01 e2 01 srl r0,r1 \|\| ldi r2,#1
+
+0+00b0 <srli>:
+ b0: 50 01 d2 1f srli r0,#0x1 \|\| srli r2,#0x1f
+ b4: 52 1f 90 61 srli r2,#0x1f \|\| mul r0,r1
+ b8: 50 01 92 63 srli r0,#0x1 \|\| mul r2,r3
+ bc: 60 01 d2 1f ldi r0,#1 \|\| srli r2,#0x1f
+ c0: 50 01 e2 01 srli r0,#0x1 \|\| ldi r2,#1
diff --git a/gas/testsuite/gas/m32r/m32r2.exp b/gas/testsuite/gas/m32r/m32r2.exp
new file mode 100644
index 0000000..03a160a
--- /dev/null
+++ b/gas/testsuite/gas/m32r/m32r2.exp
@@ -0,0 +1,5 @@
+# M32R2 assembler testsuite.
+
+if [istarget m32r*-*-*] {
+ run_dump_test "m32r2"
+}
diff --git a/gas/testsuite/gas/m32r/m32r2.s b/gas/testsuite/gas/m32r/m32r2.s
new file mode 100644
index 0000000..4f753c0
--- /dev/null
+++ b/gas/testsuite/gas/m32r/m32r2.s
@@ -0,0 +1,126 @@
+# Test new instructions
+
+ .text
+ .global setpsw
+setpsw:
+ setpsw 0xc1
+ setpsw 0xff
+
+ .text
+ .global clrpsw
+clrpsw:
+ clrpsw 0xc1
+ clrpsw 0xff
+
+ .text
+ .global bset
+bset:
+ bset #0,@(4,r1)
+ bset #1,@(4,r1)
+ bset #7,@(4,r1)
+
+ .text
+ .global bclr
+bclr:
+ bclr #0,@(4,r1)
+ bclr #1,@(4,r1)
+ bclr #7,@(4,r1)
+
+ .text
+ .global btst
+btst:
+ btst #0,fp
+ btst #1,fp
+ btst #7,fp
+ btst #1,fp || mv r0,r2
+ mv r0,r2 || btst #1,fp
+
+ .text
+ .global divuh
+divuh:
+ divuh fp,fp
+
+ .text
+ .global divb
+divb:
+ divb fp,fp
+
+ .text
+ .global divub
+divub:
+ divub fp,fp
+
+ .text
+ .global remh
+remh:
+ remh fp,fp
+
+ .text
+ .global remuh
+remuh:
+ remuh fp,fp
+
+ .text
+ .global remb
+remb:
+ remb fp,fp
+
+ .text
+ .global remub
+remub:
+ remub fp,fp
+
+ .text
+ .global sll
+sll:
+ sll r0,r1 || sll r2,r3
+ mul r0,r1 || sll r2,r3
+ sll r0,r1 || mul r2,r3
+ ldi r0,#1 || sll r2,r3
+ sll r0,r1 || ldi r2,#1
+
+ .text
+ .global slli
+slli:
+ slli r0,#1 || slli r2,#31
+ mul r0,r1 || slli r2,#31
+ slli r0,#1 || mul r2,r3
+ ldi r0,#1 || slli r2,#31
+ slli r0,#1 || ldi r2,#1
+
+ .text
+ .global sra
+sra:
+ sra r0,r1 || sra r2,r3
+ mul r0,r1 || sra r2,r3
+ sra r0,r1 || mul r2,r3
+ ldi r0,#1 || sra r2,r3
+ sra r0,r1 || ldi r2,#1
+
+ .text
+ .global srai
+srai:
+ srai r0,#1 || srai r2,#31
+ mul r0,r1 || srai r2,#31
+ srai r0,#1 || mul r2,r3
+ ldi r0,#1 || srai r2,#31
+ srai r0,#1 || ldi r2,#1
+
+ .text
+ .global sra
+srl:
+ srl r0,r1 || srl r2,r3
+ mul r0,r1 || srl r2,r3
+ srl r0,r1 || mul r2,r3
+ ldi r0,#1 || srl r2,r3
+ srl r0,r1 || ldi r2,#1
+
+ .text
+ .global srai
+srli:
+ srli r0,#1 || srli r2,#31
+ mul r0,r1 || srli r2,#31
+ srli r0,#1 || mul r2,r3
+ ldi r0,#1 || srli r2,#31
+ srli r0,#1 || ldi r2,#1
+