aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2008-12-23 19:10:25 +0000
committerNick Clifton <nickc@redhat.com>2008-12-23 19:10:25 +0000
commit84e94c9023c5d75f0ab10f9aa572003f9612b6ab (patch)
tree3751b6d7a3a336004ab82846b822b41c65e95699 /gas
parent0cd530490f8751125412c6c061640752724537ed (diff)
downloadgdb-84e94c9023c5d75f0ab10f9aa572003f9612b6ab.zip
gdb-84e94c9023c5d75f0ab10f9aa572003f9612b6ab.tar.gz
gdb-84e94c9023c5d75f0ab10f9aa572003f9612b6ab.tar.bz2
Add LM32 port.
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog16
-rw-r--r--gas/Makefile.am18
-rw-r--r--gas/Makefile.in21
-rw-r--r--gas/NEWS2
-rw-r--r--gas/config/tc-lm32.c419
-rw-r--r--gas/config/tc-lm32.h50
-rwxr-xr-xgas/configure2
-rw-r--r--gas/configure.in2
-rw-r--r--gas/configure.tgt3
-rw-r--r--gas/doc/Makefile.am1
-rw-r--r--gas/doc/Makefile.in1
-rw-r--r--gas/doc/all.texi1
-rw-r--r--gas/doc/as.texinfo9
-rw-r--r--gas/doc/c-lm32.texi215
-rw-r--r--gas/testsuite/ChangeLog9
15 files changed, 767 insertions, 2 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 7029e6a..e9fa298 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,19 @@
+2008-12-23 Jon Beniston <jon@beniston.com>
+
+ * NEWS: Record that support for LM32 has been added.
+ * Makefile.am: Add LM32 object files and dependencies.
+ * Makefile.in: Regenerate.
+ * configure.in: Indicate LM32 uses cgen.
+ * configure: Regenerate.
+ * configure.tgt: Add LM32 target.
+ * config/tc-lm32.c: New file.
+ * config/tc-lm32.h: New file.
+ * doc/Makefile.am: Add c-lm32.texi to CPU_DOCS.
+ * doc/Makefile.in: Regenerate.
+ * doc/all.texi: Add LM32 as CPU of interest.
+ * doc/as.texinfo: Add LM32 dependent features link.
+ * doc/c-lm32.texi: New file.
+
2008-12-23 H.J. Lu <hongjiu.lu@intel.com>
* config/tc-i386.c (match_template): Changed to return
diff --git a/gas/Makefile.am b/gas/Makefile.am
index 260c211..5502356 100644
--- a/gas/Makefile.am
+++ b/gas/Makefile.am
@@ -64,6 +64,7 @@ CPU_TYPES = \
i960 \
ia64 \
ip2k \
+ lm32 \
m32c \
m32r \
m68hc11 \
@@ -259,6 +260,7 @@ TARGET_CPU_CFILES = \
config/tc-i960.c \
config/tc-ip2k.c \
config/tc-iq2000.c \
+ config/tc-lm32.c \
config/tc-m32c.c \
config/tc-m32r.c \
config/tc-m68hc11.c \
@@ -319,6 +321,7 @@ TARGET_CPU_HFILES = \
config/tc-i960.h \
config/tc-ip2k.h \
config/tc-iq2000.h \
+ config/tc-lm32.h \
config/tc-m32c.h \
config/tc-m32r.h \
config/tc-m68hc11.h \
@@ -1195,6 +1198,13 @@ DEPTC_ip2k_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
$(INCDIR)/opcode/cgen-bitset.h $(srcdir)/../opcodes/ip2k-opc.h \
cgen.h $(INCDIR)/elf/ip2k.h $(INCDIR)/elf/reloc-macros.h \
$(BFDDIR)/libbfd.h $(INCDIR)/hashtab.h
+DEPTC_lm32_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-lm32.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ $(srcdir)/../opcodes/lm32-desc.h $(INCDIR)/opcode/cgen.h \
+ $(srcdir)/../opcodes/lm32-opc.h cgen.h $(INCDIR)/elf/lm32.h \
+ $(INCDIR)/elf/reloc-macros.h
DEPTC_m32c_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
$(INCDIR)/elf/common.h $(INCDIR)/elf/external.h $(INCDIR)/elf/internal.h \
$(INCDIR)/bfdlink.h $(srcdir)/config/tc-m32c.h dwarf2dbg.h \
@@ -1610,6 +1620,11 @@ DEPOBJ_ip2k_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
$(INCDIR)/bfdlink.h $(srcdir)/config/tc-ip2k.h dwarf2dbg.h \
$(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
struc-symbol.h $(INCDIR)/aout/aout64.h
+DEPOBJ_lm32_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-lm32.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
DEPOBJ_m32c_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
$(INCDIR)/elf/common.h $(INCDIR)/elf/external.h $(INCDIR)/elf/internal.h \
$(INCDIR)/bfdlink.h $(srcdir)/config/tc-m32c.h dwarf2dbg.h \
@@ -1953,6 +1968,9 @@ DEP_ip2k_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
$(INCDIR)/bfdlink.h $(srcdir)/config/tc-ip2k.h dwarf2dbg.h \
$(srcdir)/config/obj-coff.h $(INCDIR)/coff/internal.h \
$(BFDDIR)/libcoff.h
+DEP_lm32_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-lm32.h
DEP_m32c_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
$(INCDIR)/elf/common.h $(INCDIR)/elf/external.h $(INCDIR)/elf/internal.h \
$(INCDIR)/bfdlink.h $(srcdir)/config/tc-m32c.h dwarf2dbg.h \
diff --git a/gas/Makefile.in b/gas/Makefile.in
index c0f932a..3dca93d 100644
--- a/gas/Makefile.in
+++ b/gas/Makefile.in
@@ -326,6 +326,7 @@ CPU_TYPES = \
i960 \
ia64 \
ip2k \
+ lm32 \
m32c \
m32r \
m68hc11 \
@@ -519,6 +520,7 @@ TARGET_CPU_CFILES = \
config/tc-i960.c \
config/tc-ip2k.c \
config/tc-iq2000.c \
+ config/tc-lm32.c \
config/tc-m32c.c \
config/tc-m32r.c \
config/tc-m68hc11.c \
@@ -579,6 +581,7 @@ TARGET_CPU_HFILES = \
config/tc-i960.h \
config/tc-ip2k.h \
config/tc-iq2000.h \
+ config/tc-lm32.h \
config/tc-m32c.h \
config/tc-m32r.h \
config/tc-m68hc11.h \
@@ -998,6 +1001,14 @@ DEPTC_ip2k_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
cgen.h $(INCDIR)/elf/ip2k.h $(INCDIR)/elf/reloc-macros.h \
$(BFDDIR)/libbfd.h $(INCDIR)/hashtab.h
+DEPTC_lm32_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-lm32.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ $(srcdir)/../opcodes/lm32-desc.h $(INCDIR)/opcode/cgen.h \
+ $(srcdir)/../opcodes/lm32-opc.h cgen.h $(INCDIR)/elf/lm32.h \
+ $(INCDIR)/elf/reloc-macros.h
+
DEPTC_m32c_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
$(INCDIR)/elf/common.h $(INCDIR)/elf/external.h $(INCDIR)/elf/internal.h \
$(INCDIR)/bfdlink.h $(srcdir)/config/tc-m32c.h dwarf2dbg.h \
@@ -1493,6 +1504,12 @@ DEPOBJ_ip2k_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
$(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
struc-symbol.h $(INCDIR)/aout/aout64.h
+DEPOBJ_lm32_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-lm32.h \
+ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+
DEPOBJ_m32c_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
$(INCDIR)/elf/common.h $(INCDIR)/elf/external.h $(INCDIR)/elf/internal.h \
$(INCDIR)/bfdlink.h $(srcdir)/config/tc-m32c.h dwarf2dbg.h \
@@ -1916,6 +1933,10 @@ DEP_ip2k_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
$(srcdir)/config/obj-coff.h $(INCDIR)/coff/internal.h \
$(BFDDIR)/libcoff.h
+DEP_lm32_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-lm32.h
+
DEP_m32c_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
$(INCDIR)/elf/common.h $(INCDIR)/elf/external.h $(INCDIR)/elf/internal.h \
$(INCDIR)/bfdlink.h $(srcdir)/config/tc-m32c.h dwarf2dbg.h \
diff --git a/gas/NEWS b/gas/NEWS
index 16324d6..e3fed78 100644
--- a/gas/NEWS
+++ b/gas/NEWS
@@ -1,5 +1,7 @@
-*- text -*-
+* Add support for Lattice Mico32 (lm32) architecture.
+
Changes in 2.19:
* New pseudo op .cfi_val_encoded_addr, to record constant addresses in unwind
diff --git a/gas/config/tc-lm32.c b/gas/config/tc-lm32.c
new file mode 100644
index 0000000..5d02c3a
--- /dev/null
+++ b/gas/config/tc-lm32.c
@@ -0,0 +1,419 @@
+/* tc-lm32.c - Lattice Mico32 assembler.
+ Copyright 2008 Free Software Foundation, Inc.
+ Contributed by Jon Beniston <jon@beniston.com>
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ 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, 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "as.h"
+#include "safe-ctype.h"
+#include "subsegs.h"
+#include "bfd.h"
+#include "safe-ctype.h"
+#include "opcodes/lm32-desc.h"
+#include "opcodes/lm32-opc.h"
+#include "cgen.h"
+#include "elf/lm32.h"
+
+typedef struct
+{
+ const CGEN_INSN *insn;
+ const CGEN_INSN *orig_insn;
+ CGEN_FIELDS fields;
+#if CGEN_INT_INSN_P
+ CGEN_INSN_INT buffer [1];
+#define INSN_VALUE(buf) (*(buf))
+#else
+ unsigned char buffer[CGEN_MAX_INSN_SIZE];
+#define INSN_VALUE(buf) (buf)
+#endif
+ char *addr;
+ fragS *frag;
+ int num_fixups;
+ fixS *fixups[GAS_CGEN_MAX_FIXUPS];
+ int indices[MAX_OPERAND_INSTANCES];
+} lm32_insn;
+
+/* Configuration options */
+
+#define LM_CFG_MULTIPLIY_ENABLED 0x0001
+#define LM_CFG_DIVIDE_ENABLED 0x0002
+#define LM_CFG_BARREL_SHIFT_ENABLED 0x0004
+#define LM_CFG_SIGN_EXTEND_ENABLED 0x0008
+#define LM_CFG_USER_ENABLED 0x0010
+#define LM_CFG_ICACHE_ENABLED 0x0020
+#define LM_CFG_DCACHE_ENABLED 0x0040
+#define LM_CFG_BREAK_ENABLED 0x0080
+
+static unsigned config = 0U;
+
+/* Target specific assembler tokens / delimiters. */
+
+const char comment_chars[] = "#";
+const char line_comment_chars[] = "#";
+const char line_separator_chars[] = ";";
+const char EXP_CHARS[] = "eE";
+const char FLT_CHARS[] = "dD";
+
+/* Target specific assembly directives. */
+
+const pseudo_typeS md_pseudo_table[] =
+{
+ { "align", s_align_bytes, 0 },
+ { "byte", cons, 1 },
+ { "hword", cons, 2 },
+ { "word", cons, 4 },
+ { "dword", cons, 8 },
+ {(char *)0 , (void(*)(int))0, 0}
+};
+
+/* Target specific command line options. */
+
+const char * md_shortopts = "";
+
+struct option md_longopts[] =
+{
+#define OPTION_MULTIPLY_ENABLED (OPTION_MD_BASE + 1)
+ { "mmultiply-enabled", no_argument, NULL, OPTION_MULTIPLY_ENABLED },
+#define OPTION_DIVIDE_ENABLED (OPTION_MD_BASE + 2)
+ { "mdivide-enabled", no_argument, NULL, OPTION_DIVIDE_ENABLED },
+#define OPTION_BARREL_SHIFT_ENABLED (OPTION_MD_BASE + 3)
+ { "mbarrel-shift-enabled", no_argument, NULL, OPTION_BARREL_SHIFT_ENABLED },
+#define OPTION_SIGN_EXTEND_ENABLED (OPTION_MD_BASE + 4)
+ { "msign-extend-enabled", no_argument, NULL, OPTION_SIGN_EXTEND_ENABLED },
+#define OPTION_USER_ENABLED (OPTION_MD_BASE + 5)
+ { "muser-enabled", no_argument, NULL, OPTION_USER_ENABLED },
+#define OPTION_ICACHE_ENABLED (OPTION_MD_BASE + 6)
+ { "micache-enabled", no_argument, NULL, OPTION_ICACHE_ENABLED },
+#define OPTION_DCACHE_ENABLED (OPTION_MD_BASE + 7)
+ { "mdcache-enabled", no_argument, NULL, OPTION_DCACHE_ENABLED },
+#define OPTION_BREAK_ENABLED (OPTION_MD_BASE + 8)
+ { "mbreak-enabled", no_argument, NULL, OPTION_BREAK_ENABLED },
+#define OPTION_ALL_ENABLED (OPTION_MD_BASE + 9)
+ { "mall-enabled", no_argument, NULL, OPTION_ALL_ENABLED },
+};
+
+size_t md_longopts_size = sizeof (md_longopts);
+
+/* Display architecture specific options. */
+
+void
+md_show_usage (FILE * fp)
+{
+ fprintf (fp, "LM32 specific options:\n"
+ " -mmultiply-enabled enable multiply instructions\n"
+ " -mdivide-enabled enable divide and modulus instructions\n"
+ " -mbarrel-shift-enabled enable multi-bit shift instructions\n"
+ " -msign-extend-enabled enable sign-extension instructions\n"
+ " -muser-enabled enable user-defined instructions\n"
+ " -micache-enabled enable instruction cache instructions\n"
+ " -mdcache-enabled enable data cache instructions\n"
+ " -mbreak-enabled enable the break instruction\n"
+ " -mall-enabled enable all optional instructions\n"
+ );
+}
+
+/* Parse command line options. */
+
+int
+md_parse_option (int c, char * arg ATTRIBUTE_UNUSED)
+{
+ switch (c)
+ {
+ case OPTION_MULTIPLY_ENABLED:
+ config |= LM_CFG_MULTIPLIY_ENABLED;
+ break;
+ case OPTION_DIVIDE_ENABLED:
+ config |= LM_CFG_DIVIDE_ENABLED;
+ break;
+ case OPTION_BARREL_SHIFT_ENABLED:
+ config |= LM_CFG_BARREL_SHIFT_ENABLED;
+ break;
+ case OPTION_SIGN_EXTEND_ENABLED:
+ config |= LM_CFG_SIGN_EXTEND_ENABLED;
+ break;
+ case OPTION_USER_ENABLED:
+ config |= LM_CFG_USER_ENABLED;
+ break;
+ case OPTION_ICACHE_ENABLED:
+ config |= LM_CFG_ICACHE_ENABLED;
+ break;
+ case OPTION_DCACHE_ENABLED:
+ config |= LM_CFG_DCACHE_ENABLED;
+ break;
+ case OPTION_BREAK_ENABLED:
+ config |= LM_CFG_BREAK_ENABLED;
+ break;
+ case OPTION_ALL_ENABLED:
+ config |= LM_CFG_MULTIPLIY_ENABLED;
+ config |= LM_CFG_DIVIDE_ENABLED;
+ config |= LM_CFG_BARREL_SHIFT_ENABLED;
+ config |= LM_CFG_SIGN_EXTEND_ENABLED;
+ config |= LM_CFG_USER_ENABLED;
+ config |= LM_CFG_ICACHE_ENABLED;
+ config |= LM_CFG_DCACHE_ENABLED;
+ config |= LM_CFG_BREAK_ENABLED;
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+/* Do any architecture specific initialisation. */
+
+void
+md_begin (void)
+{
+ /* Initialize the `cgen' interface. */
+
+ /* Set the machine number and endian. */
+ gas_cgen_cpu_desc = lm32_cgen_cpu_open (CGEN_CPU_OPEN_MACHS, 0,
+ CGEN_CPU_OPEN_ENDIAN,
+ CGEN_ENDIAN_BIG,
+ CGEN_CPU_OPEN_END);
+ lm32_cgen_init_asm (gas_cgen_cpu_desc);
+
+ /* This is a callback from cgen to gas to parse operands. */
+ cgen_set_parse_operand_fn (gas_cgen_cpu_desc, gas_cgen_parse_operand);
+}
+
+/* Turn an integer of n bytes (in val) into a stream of bytes appropriate
+ for use in the a.out file, and stores them in the array pointed to by buf. */
+
+void
+md_number_to_chars (char * buf, valueT val, int n)
+{
+ if (target_big_endian)
+ number_to_chars_bigendian (buf, val, n);
+ else
+ number_to_chars_littleendian (buf, val, n);
+}
+
+/* Turn a string in input_line_pointer into a floating point constant
+ of type TYPE, and store the appropriate bytes in *LITP. The number
+ of LITTLENUMS emitted is stored in *SIZEP. An error message is
+ returned, or NULL on OK. */
+
+char *
+md_atof (int type, char *litP, int *sizeP)
+{
+ int i;
+ int prec;
+ LITTLENUM_TYPE words[4];
+
+ char *t;
+
+ switch (type)
+ {
+ case 'f':
+ prec = 2;
+ break;
+ case 'd':
+ prec = 4;
+ break;
+ default:
+ *sizeP = 0;
+ return _("bad call to md_atof");
+ }
+
+ t = atof_ieee (input_line_pointer, type, words);
+ if (t)
+ input_line_pointer = t;
+
+ *sizeP = prec * sizeof (LITTLENUM_TYPE);
+
+ if (target_big_endian)
+ {
+ for (i = 0; i < prec; i++)
+ {
+ md_number_to_chars (litP, (valueT) words[i],
+ sizeof (LITTLENUM_TYPE));
+ litP += sizeof (LITTLENUM_TYPE);
+ }
+ }
+ else
+ {
+ for (i = prec - 1; i >= 0; i--)
+ {
+ md_number_to_chars (litP, (valueT) words[i],
+ sizeof (LITTLENUM_TYPE));
+ litP += sizeof (LITTLENUM_TYPE);
+ }
+ }
+
+ return NULL;
+}
+
+/* Called for each undefined symbol. */
+
+symbolS *
+md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+/* Round up a section size to the appropriate boundary. */
+
+valueT
+md_section_align (asection *seg, valueT addr)
+{
+ int align = bfd_get_section_alignment (stdoutput, seg);
+ return ((addr + (1 << align) - 1) & (-1 << align));
+}
+
+/* This function assembles the instructions. It emits the frags/bytes to the
+ sections and creates the relocation entries. */
+
+void
+md_assemble (char * str)
+{
+ lm32_insn insn;
+ char * errmsg;
+
+ /* Initialize GAS's cgen interface for a new instruction. */
+ gas_cgen_init_parse ();
+
+ insn.insn = lm32_cgen_assemble_insn
+ (gas_cgen_cpu_desc, str, &insn.fields, insn.buffer, &errmsg);
+
+ if (!insn.insn)
+ {
+ as_bad ("%s", errmsg);
+ return;
+ }
+
+ gas_cgen_finish_insn (insn.insn, insn.buffer,
+ CGEN_FIELDS_BITSIZE (&insn.fields), 1, NULL);
+}
+
+/* Return the bfd reloc type for OPERAND of INSN at fixup FIXP.
+ Returns BFD_RELOC_NONE if no reloc type can be found.
+ *FIXP may be modified if desired. */
+
+bfd_reloc_code_real_type
+md_cgen_lookup_reloc (const CGEN_INSN *insn ATTRIBUTE_UNUSED,
+ const CGEN_OPERAND *operand,
+ fixS *fixP ATTRIBUTE_UNUSED)
+{
+ switch (operand->type)
+ {
+ case LM32_OPERAND_GOT16:
+ return BFD_RELOC_LM32_16_GOT;
+ case LM32_OPERAND_GOTOFFHI16:
+ return BFD_RELOC_LM32_GOTOFF_HI16;
+ case LM32_OPERAND_GOTOFFLO16:
+ return BFD_RELOC_LM32_GOTOFF_LO16;
+ case LM32_OPERAND_GP16:
+ return BFD_RELOC_GPREL16;
+ case LM32_OPERAND_LO16:
+ return BFD_RELOC_LO16;
+ case LM32_OPERAND_HI16:
+ return BFD_RELOC_HI16;
+ case LM32_OPERAND_BRANCH:
+ return BFD_RELOC_LM32_BRANCH;
+ case LM32_OPERAND_CALL:
+ return BFD_RELOC_LM32_CALL;
+ default:
+ break;
+ }
+ return BFD_RELOC_NONE;
+}
+
+/* Return the position from which the PC relative adjustment for a PC relative
+ fixup should be made. */
+
+long
+md_pcrel_from (fixS *fixP)
+{
+ /* Shouldn't get called. */
+ abort ();
+ /* Return address of current instruction. */
+ return fixP->fx_where + fixP->fx_frag->fr_address;
+}
+
+/* The location from which a PC relative jump should be calculated,
+ given a PC relative reloc. */
+
+long
+md_pcrel_from_section (fixS * fixP, segT sec)
+{
+ if ((fixP->fx_addsy != (symbolS *) NULL)
+ && (! S_IS_DEFINED (fixP->fx_addsy)
+ || (S_GET_SEGMENT (fixP->fx_addsy) != sec)))
+ {
+ /* The symbol is undefined (or is defined but not in this section).
+ Let the linker figure it out. */
+ return 0;
+ }
+
+ /*fprintf(stderr, "%s extern %d local %d\n", S_GET_NAME (fixP->fx_addsy), S_IS_EXTERN (fixP->fx_addsy), S_IS_LOCAL (fixP->fx_addsy));*/
+ /* FIXME: Weak problem? */
+ if ((fixP->fx_addsy != (symbolS *) NULL)
+ && S_IS_EXTERNAL (fixP->fx_addsy))
+ {
+ /* If the symbol is external, let the linker handle it. */
+ return 0;
+ }
+
+ return fixP->fx_where + fixP->fx_frag->fr_address;
+}
+
+/* Return true if we can partially resolve a relocation now. */
+
+bfd_boolean
+lm32_fix_adjustable (fixS * fixP)
+{
+ /* We need the symbol name for the VTABLE entries */
+ if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Relaxation isn't required/supported on this target. */
+
+int
+md_estimate_size_before_relax (fragS *fragp ATTRIBUTE_UNUSED,
+ asection *seg ATTRIBUTE_UNUSED)
+{
+ abort ();
+ return 0;
+}
+
+void
+md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec ATTRIBUTE_UNUSED,
+ fragS *fragP ATTRIBUTE_UNUSED)
+{
+ abort ();
+}
+
+void
+md_apply_fix (fixS * fixP, valueT * valP, segT seg)
+{
+ /* Fix for weak symbols. Why do we have fx_addsy for weak symbols? */
+ if (fixP->fx_addsy != NULL && S_IS_WEAK (fixP->fx_addsy))
+ *valP = 0;
+
+ gas_cgen_md_apply_fix (fixP, valP, seg);
+ return;
+}
diff --git a/gas/config/tc-lm32.h b/gas/config/tc-lm32.h
new file mode 100644
index 0000000..dbba939
--- /dev/null
+++ b/gas/config/tc-lm32.h
@@ -0,0 +1,50 @@
+/* tc-lm32.h -- Header file for tc-lm32.c
+ Copyright 2008 Free Software Foundation, Inc.
+ Contributed by Jon Beniston <jon@beniston.com>
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ 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, 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#ifndef TC_LM32_H
+#define TC_LM32_H
+
+#define TARGET_FORMAT "elf32-lm32"
+#define TARGET_ARCH bfd_arch_lm32
+#define TARGET_MACH bfd_mach_lm32
+
+#define TARGET_BYTES_BIG_ENDIAN 1
+
+/* Permit temporary numeric labels. */
+#define LOCAL_LABELS_FB 1
+
+#define WORKING_DOT_WORD
+
+/* Values passed to md_apply_fix3 don't include the symbol value. */
+#define MD_APPLY_SYM_VALUE(FIX) 0
+
+#define md_operand(X)
+#define tc_gen_reloc gas_cgen_tc_gen_reloc
+
+/* Call md_pcrel_from_section(), not md_pcrel_from(). */
+extern long md_pcrel_from_section (struct fix *, segT);
+#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section (FIXP, SEC)
+
+extern bfd_boolean lm32_fix_adjustable (struct fix *);
+#define tc_fix_adjustable(FIX) lm32_fix_adjustable (FIX)
+
+#endif /* TC_LM32_H */
+
diff --git a/gas/configure b/gas/configure
index fca53d7..88085df 100755
--- a/gas/configure
+++ b/gas/configure
@@ -12246,7 +12246,7 @@ _ACEOF
fi
;;
- fr30 | ip2k | iq2000 | m32r | openrisc)
+ fr30 | ip2k | iq2000 | lm32 | m32r | openrisc)
using_cgen=yes
;;
diff --git a/gas/configure.in b/gas/configure.in
index 2b10296..e892ad9 100644
--- a/gas/configure.in
+++ b/gas/configure.in
@@ -308,7 +308,7 @@ changequote([,])dnl
fi
;;
- fr30 | ip2k | iq2000 | m32r | openrisc)
+ fr30 | ip2k | iq2000 | lm32 | m32r | openrisc)
using_cgen=yes
;;
diff --git a/gas/configure.tgt b/gas/configure.tgt
index 1b206d3..0272b4e 100644
--- a/gas/configure.tgt
+++ b/gas/configure.tgt
@@ -44,6 +44,7 @@ case ${cpu} in
ia64) cpu_type=ia64 ;;
ip2k) cpu_type=ip2k endian=big ;;
iq2000) cpu_type=iq2000 endian=big ;;
+ lm32) cpu_type=lm32 ;;
m32c) cpu_type=m32c endian=big ;;
m32r) cpu_type=m32r endian=big ;;
m32rle) cpu_type=m32r endian=little ;;
@@ -246,6 +247,8 @@ case ${generic_target} in
m32c-*-elf | m32c-*-rtems*) fmt=elf ;;
+ lm32-*-*) fmt=elf ;;
+
m32r-*-elf* | m32r-*-rtems*) fmt=elf ;;
m32r-*-linux*) fmt=elf em=linux;;
diff --git a/gas/doc/Makefile.am b/gas/doc/Makefile.am
index 621c03f..5dc43b6 100644
--- a/gas/doc/Makefile.am
+++ b/gas/doc/Makefile.am
@@ -44,6 +44,7 @@ CPU_DOCS = \
c-i860.texi \
c-i960.texi \
c-ip2k.texi \
+ c-lm32.texi \
c-m32c.texi \
c-m32r.texi \
c-m68hc11.texi \
diff --git a/gas/doc/Makefile.in b/gas/doc/Makefile.in
index 3122f7c..0f9333d 100644
--- a/gas/doc/Makefile.in
+++ b/gas/doc/Makefile.in
@@ -264,6 +264,7 @@ CPU_DOCS = \
c-i860.texi \
c-i960.texi \
c-ip2k.texi \
+ c-lm32.texi \
c-m32c.texi \
c-m32r.texi \
c-m68hc11.texi \
diff --git a/gas/doc/all.texi b/gas/doc/all.texi
index b4778bf..911b4ee 100644
--- a/gas/doc/all.texi
+++ b/gas/doc/all.texi
@@ -43,6 +43,7 @@
@set I960
@set IA64
@set IP2K
+@set LM32
@set M32C
@set M32R
@set xc16x
diff --git a/gas/doc/as.texinfo b/gas/doc/as.texinfo
index d8748dd..3e85968 100644
--- a/gas/doc/as.texinfo
+++ b/gas/doc/as.texinfo
@@ -6679,6 +6679,9 @@ subject, see the hardware manufacturer's manual.
@ifset IP2K
* IP2K-Dependent:: IP2K Dependent Features
@end ifset
+@ifset LM32
+* LM32-Dependent:: LM32 Dependent Features
+@end ifset
@ifset M32C
* M32C-Dependent:: M32C Dependent Features
@end ifset
@@ -6833,6 +6836,10 @@ family.
@include c-ip2k.texi
@end ifset
+@ifset LM32
+@include c-lm32.texi
+@end ifset
+
@ifset M32C
@include c-m32c.texi
@end ifset
@@ -7212,6 +7219,8 @@ Inc.@: added support for Xtensa processors.
Several engineers at Cygnus Support have also provided many small bug fixes and
configuration enhancements.
+Jon Beniston added support for the Lattice Mico32 architecture.
+
Many others have contributed large or small bugfixes and enhancements. If
you have contributed significant work and are not mentioned on this list, and
want to be, let us know. Some of the history has been lost; we are not
diff --git a/gas/doc/c-lm32.texi b/gas/doc/c-lm32.texi
new file mode 100644
index 0000000..146442f
--- /dev/null
+++ b/gas/doc/c-lm32.texi
@@ -0,0 +1,215 @@
+@c Copyright 2008
+@c Free Software Foundation, Inc.
+@c This is part of the GAS manual.
+@c For copying conditions, see the file as.texinfo.
+
+@ifset GENERIC
+@page
+@node LM32-Dependent
+@chapter LM32 Dependent Features
+@end ifset
+
+@ifclear GENERIC
+@node Machine Dependencies
+@chapter LM£" Dependent Features
+@end ifclear
+
+@cindex LM32 support
+@menu
+* LM32 Options:: Options
+* LM32 Syntax:: Syntax
+* LM32 Opcodes:: Opcodes
+@end menu
+
+@node LM32 Options
+@section Options
+@cindex LM32 options (none)
+@cindex options for LM32 (none)
+
+@table @code
+
+@cindex @code{-mmultiply-enabled} command line option, LM32
+@item -mmultiply-enabled
+Enable multiply instructions.
+
+@cindex @code{-mdivide-enabled} command line option, LM32
+@item -mdivide-enabled
+Enable divide instructions.
+
+@cindex @code{-mbarrel-shift-enabled} command line option, LM32
+@item -mbarrel-shift-enabled
+Enable barrel-shift instructions.
+
+@cindex @code{-msign-extend-enabled} command line option, LM32
+@item -msign-extend-enabled
+Enable sign extend instructions.
+
+@cindex @code{-muser-enabled} command line option, LM32
+@item -muser-enabled
+Enable user defined instructions.
+
+@cindex @code{-micache-enabled} command line option, LM32
+@item -micache-enabled
+Enable instruction cache related CSRs.
+
+@cindex @code{-mdcache-enabled} command line option, LM32
+@item -mdcache-enabled
+Enable data cache related CSRs.
+
+@cindex @code{-mbreak-enabled} command line option, LM32
+@item -mbreak-enabled
+Enable break instructions.
+
+@cindex @code{-mall-enabled} command line option, LM32
+@item -mall-enabled
+Enable all instructions and CSRs.
+
+@end table
+
+
+@node LM32 Syntax
+@section Syntax
+@menu
+* LM32-Regs:: Register Names
+* LM32-Modifiers:: Relocatable Expression Modifiers
+@end menu
+
+@node LM32-Regs
+@subsection Register Names
+
+@cindex LM32 register names
+@cindex register names, LM32
+
+LM32 has 32 x 32-bit general purpose registers @samp{r0},
+@samp{r1}, ... @samp{r31}.
+
+The following aliases are defined: @samp{gp} - @samp{r26},
+@samp{fp} - @samp{r27}, @samp{sp} - @samp{r28},
+@samp{ra} - @samp{r29}, @samp{ea} - @samp{r30},
+@samp{ba} - @samp{r31}.
+
+LM32 has the following Control and Status Registers (CSRs).
+
+@table @code
+@item IE
+Interrupt enable.
+@item IM
+Interrupt mask.
+@item IP
+Interrupt pending.
+@item ICC
+Instruction cache control.
+@item DCC
+Data cache control.
+@item CC
+Cycle counter.
+@item CFG
+Configuration.
+@item EBA
+Exception base address.
+@item DC
+Debug control.
+@item DEBA
+Debug exception base address.
+@item JTX
+JTAG transmit.
+@item JRX
+JTAG receive.
+@item BP0
+Breakpoint 0.
+@item BP1
+Breakpoint 1.
+@item BP2
+Breakpoint 2.
+@item BP3
+Breakpoint 3.
+@item WP0
+Watchpoint 0.
+@item WP1
+Watchpoint 1.
+@item WP2
+Watchpoint 2.
+@item WP3
+Watchpoint 3.
+@end table
+
+@node LM32-Modifiers
+@subsection Relocatable Expression Modifiers
+
+@cindex LM32 modifiers
+@cindex syntax, LM32
+
+The assembler supports several modifiers when using relocatable addresses
+in LM32 instruction operands. The general syntax is the following:
+
+@smallexample
+modifier(relocatable-expression)
+@end smallexample
+
+@table @code
+@cindex symbol modifiers
+
+@item lo
+
+This modifier allows you to use bits 0 through 15 of
+an address expression as 16 bit relocatable expression.
+
+@item hi
+
+This modifier allows you to use bits 16 through 23 of an address expression
+as 16 bit relocatable expression.
+
+For example
+
+@smallexample
+ori r4, r4, lo(sym+10)
+orhi r4, r4, hi(sym+10)
+@end smallexample
+
+@item gp
+
+This modified creates a 16-bit relocatable expression that is
+the offset of the symbol from the global pointer.
+
+@smallexample
+mva r4, gp(sym)
+@end smallexample
+
+@item got
+
+This modifier places a symbol in the GOT and creates a 16-bit
+relocatable expression that is the offset into the GOT of this
+symbol.
+
+@smallexample
+lw r4, (gp+got(sym))
+@end smallexample
+
+@item gotofflo16
+
+This modifier allows you to use the bits 0 through 15 of an
+address which is an offset from the GOT.
+
+@item gotoffhi16
+
+This modifier allows you to use the bits 16 through 31 of an
+address which is an offset from the GOT.
+
+@smallexample
+orhi r4, r4, gotoffhi16(lsym)
+addi r4, r4, gotofflo16(lsym)
+@end smallexample
+
+@end table
+
+@node LM32 Opcodes
+@section Opcodes
+
+@cindex LM32 opcode summary
+@cindex opcode summary, LM32
+@cindex mnemonics, LM32
+@cindex instruction summary, LM32
+For detailed information on the LM32 machine instruction set, see
+@url{http://www.latticesemi.com/products/intellectualproperty/ipcores/mico32/}.
+
+@code{@value{AS}} implements all the standard LM32 opcodes.
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index 25e94a5..3e0b594 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -1,3 +1,12 @@
+2008-12-23 Jon Beniston <jon@beniston.com>
+
+ * gas/lm32: New directory.
+ * gas/lm32/all.exp: New file.
+ * gas/lm32/csr.d: New file.
+ * gas/lm32/csr.s: New file.
+ * gas/lm32/insn.d: New file.
+ * gas/lm32/insn.s: New file.
+
2008-12-23 H.J. Lu <hongjiu.lu@intel.com>
* gas/i386/i386.exp: Run x86-64-avx-swap and x86-64-avx-swap-intel.