+++ /dev/null
-/* BFD support for the Morpho Technologies MS1 processor.
- Copyright (C) 2001, 2002, 2005 Free Software Foundation, Inc.
-
- This file is part of BFD, the Binary File Descriptor library.
-
- This program 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 of the License, or
- (at your option) any later version.
-
- This program 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 this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-#include "bfd.h"
-#include "sysdep.h"
-#include "libbfd.h"
-
-const bfd_arch_info_type arch_info_struct[] =
-{
-{
- 32, /* Bits per word - not really true. */
- 32, /* Bits per address. */
- 8, /* Bits per byte. */
- bfd_arch_ms1, /* Architecture. */
- bfd_mach_mrisc2, /* Machine. */
- "ms1", /* Architecture name. */
- "ms1-003", /* Printable name. */
- 1, /* Section align power. */
- FALSE, /* The default ? */
- bfd_default_compatible, /* Architecture comparison fn. */
- bfd_default_scan, /* String to architecture convert fn. */
- &arch_info_struct[1] /* Next in list. */
-},
-{
- 32, /* Bits per word - not really true. */
- 32, /* Bits per address. */
- 8, /* Bits per byte. */
- bfd_arch_ms1, /* Architecture. */
- bfd_mach_ms2, /* Machine. */
- "ms1", /* Architecture name. */
- "ms2", /* Printable name. */
- 1, /* Section align power. */
- FALSE, /* The default ? */
- bfd_default_compatible, /* Architecture comparison fn. */
- bfd_default_scan, /* String to architecture convert fn. */
- NULL /* Next in list. */
-},
-};
-
-const bfd_arch_info_type bfd_ms1_arch =
-{
- 32, /* Bits per word - not really true. */
- 32, /* Bits per address. */
- 8, /* Bits per byte. */
- bfd_arch_ms1, /* Architecture. */
- bfd_mach_ms1, /* Machine. */
- "ms1", /* Architecture name. */
- "ms1", /* Printable name. */
- 1, /* Section align power. */
- TRUE, /* The default ? */
- bfd_default_compatible, /* Architecture comparison fn. */
- bfd_default_scan, /* String to architecture convert fn. */
- &arch_info_struct[0] /* Next in list. */
-};
-
--- /dev/null
+/* BFD support for the Morpho Technologies MS1 processor.
+ Copyright (C) 2001, 2002, 2005 Free Software Foundation, Inc.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program 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 of the License, or
+ (at your option) any later version.
+
+ This program 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 this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type arch_info_struct[] =
+{
+{
+ 32, /* Bits per word - not really true. */
+ 32, /* Bits per address. */
+ 8, /* Bits per byte. */
+ bfd_arch_ms1, /* Architecture. */
+ bfd_mach_mrisc2, /* Machine. */
+ "ms1", /* Architecture name. */
+ "ms1-003", /* Printable name. */
+ 1, /* Section align power. */
+ FALSE, /* The default ? */
+ bfd_default_compatible, /* Architecture comparison fn. */
+ bfd_default_scan, /* String to architecture convert fn. */
+ &arch_info_struct[1] /* Next in list. */
+},
+{
+ 32, /* Bits per word - not really true. */
+ 32, /* Bits per address. */
+ 8, /* Bits per byte. */
+ bfd_arch_ms1, /* Architecture. */
+ bfd_mach_ms2, /* Machine. */
+ "ms1", /* Architecture name. */
+ "ms2", /* Printable name. */
+ 1, /* Section align power. */
+ FALSE, /* The default ? */
+ bfd_default_compatible, /* Architecture comparison fn. */
+ bfd_default_scan, /* String to architecture convert fn. */
+ NULL /* Next in list. */
+},
+};
+
+const bfd_arch_info_type bfd_ms1_arch =
+{
+ 32, /* Bits per word - not really true. */
+ 32, /* Bits per address. */
+ 8, /* Bits per byte. */
+ bfd_arch_ms1, /* Architecture. */
+ bfd_mach_ms1, /* Machine. */
+ "ms1", /* Architecture name. */
+ "ms1", /* Printable name. */
+ 1, /* Section align power. */
+ TRUE, /* The default ? */
+ bfd_default_compatible, /* Architecture comparison fn. */
+ bfd_default_scan, /* String to architecture convert fn. */
+ &arch_info_struct[0] /* Next in list. */
+};
+
+++ /dev/null
-/* Morpho Technologies MS1 specific support for 32-bit ELF
- Copyright 2001, 2002, 2003, 2004, 2005
- Free Software Foundation, Inc.
-
- This file is part of BFD, the Binary File Descriptor library.
-
- This program 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 of the License, or
- (at your option) any later version.
-
- This program 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 this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-#include "bfd.h"
-#include "sysdep.h"
-#include "libbfd.h"
-#include "elf-bfd.h"
-#include "elf/ms1.h"
-
-/* Prototypes. */
-static reloc_howto_type * ms1_reloc_type_lookup
- (bfd *, bfd_reloc_code_real_type);
-
-static void ms1_info_to_howto_rela
- (bfd *, arelent *, Elf_Internal_Rela *);
-
-static bfd_reloc_status_type ms1_elf_relocate_hi16
- (bfd *, Elf_Internal_Rela *, bfd_byte *, bfd_vma);
-
-static bfd_reloc_status_type ms1_final_link_relocate
- (reloc_howto_type *, bfd *, asection *, bfd_byte *,
- Elf_Internal_Rela *, bfd_vma);
-
-static bfd_boolean ms1_elf_relocate_section
- (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
- Elf_Internal_Rela *, Elf_Internal_Sym *, asection **);
-
-/* Relocation tables. */
-static reloc_howto_type ms1_elf_howto_table [] =
-{
- /* This reloc does nothing. */
- HOWTO (R_MS1_NONE, /* type */
- 0, /* rightshift */
- 2, /* size (0 = byte, 1 = short, 2 = long) */
- 32, /* bitsize */
- FALSE, /* pc_relative */
- 0, /* bitpos */
- complain_overflow_dont, /* complain_on_overflow */
- bfd_elf_generic_reloc, /* special_function */
- "R_MS1_NONE", /* name */
- FALSE, /* partial_inplace */
- 0 , /* src_mask */
- 0, /* dst_mask */
- FALSE), /* pcrel_offset */
-
- /* A 16 bit absolute relocation. */
- HOWTO (R_MS1_16, /* type */
- 0, /* rightshift */
- 2, /* size (0 = byte, 1 = short, 2 = long) */
- 16, /* bitsize */
- FALSE, /* pc_relative */
- 0, /* bitpos */
- complain_overflow_dont, /* complain_on_overflow */
- bfd_elf_generic_reloc, /* special_function */
- "R_MS1_16", /* name */
- FALSE, /* partial_inplace */
- 0 , /* src_mask */
- 0xffff, /* dst_mask */
- FALSE), /* pcrel_offset */
-
- /* A 32 bit absolute relocation. */
- HOWTO (R_MS1_32, /* type */
- 0, /* rightshift */
- 2, /* size (0 = byte, 1 = short, 2 = long) */
- 32, /* bitsize */
- FALSE, /* pc_relative */
- 0, /* bitpos */
- complain_overflow_dont, /* complain_on_overflow */
- bfd_elf_generic_reloc, /* special_function */
- "R_MS1_32", /* name */
- FALSE, /* partial_inplace */
- 0 , /* src_mask */
- 0xffffffff, /* dst_mask */
- FALSE), /* pcrel_offset */
-
- /* A 32 bit pc-relative relocation. */
- HOWTO (R_MS1_32_PCREL, /* type */
- 0, /* rightshift */
- 2, /* size (0 = byte, 1 = short, 2 = long) */
- 32, /* bitsize */
- TRUE, /* pc_relative */
- 0, /* bitpos */
- complain_overflow_dont, /* complain_on_overflow */
- bfd_elf_generic_reloc, /* special_function */
- "R_MS1_32_PCREL", /* name */
- FALSE, /* partial_inplace */
- 0 , /* src_mask */
- 0xffffffff, /* dst_mask */
- TRUE), /* pcrel_offset */
-
- /* A 16 bit pc-relative relocation. */
- HOWTO (R_MS1_PC16, /* type */
- 0, /* rightshift */
- 2, /* size (0 = byte, 1 = short, 2 = long) */
- 16, /* bitsize */
- TRUE, /* pc_relative */
- 0, /* bitpos */
- complain_overflow_signed, /* complain_on_overflow */
- bfd_elf_generic_reloc, /* special_function */
- "R_MS1_PC16", /* name */
- FALSE, /* partial_inplace */
- 0, /* src_mask */
- 0xffff, /* dst_mask */
- TRUE), /* pcrel_offset */
-
- /* high 16 bits of symbol value. */
- HOWTO (R_MS1_HI16, /* type */
- 0, /* rightshift */
- 2, /* size (0 = byte, 1 = short, 2 = long) */
- 16, /* bitsize */
- FALSE, /* pc_relative */
- 0, /* bitpos */
- complain_overflow_dont, /* complain_on_overflow */
- bfd_elf_generic_reloc, /* special_function */
- "R_MS1_HI16", /* name */
- FALSE, /* partial_inplace */
- 0xffff0000, /* src_mask */
- 0xffff0000, /* dst_mask */
- FALSE), /* pcrel_offset */
-
- /* Low 16 bits of symbol value. */
- HOWTO (R_MS1_LO16, /* type */
- 0, /* rightshift */
- 2, /* size (0 = byte, 1 = short, 2 = long) */
- 16, /* bitsize */
- FALSE, /* pc_relative */
- 0, /* bitpos */
- complain_overflow_dont, /* complain_on_overflow */
- bfd_elf_generic_reloc, /* special_function */
- "R_MS1_LO16", /* name */
- FALSE, /* partial_inplace */
- 0xffff, /* src_mask */
- 0xffff, /* dst_mask */
- FALSE), /* pcrel_offset */
-};
-
-/* Map BFD reloc types to MS1 ELF reloc types. */
-
-static reloc_howto_type *
-ms1_reloc_type_lookup
- (bfd * abfd ATTRIBUTE_UNUSED,
- bfd_reloc_code_real_type code)
-{
- /* Note that the ms1_elf_howto_table is indxed by the R_
- constants. Thus, the order that the howto records appear in the
- table *must* match the order of the relocation types defined in
- include/elf/ms1.h. */
-
- switch (code)
- {
- case BFD_RELOC_NONE:
- return &ms1_elf_howto_table[ (int) R_MS1_NONE];
- case BFD_RELOC_16:
- return &ms1_elf_howto_table[ (int) R_MS1_16];
- case BFD_RELOC_32:
- return &ms1_elf_howto_table[ (int) R_MS1_32];
- case BFD_RELOC_32_PCREL:
- return &ms1_elf_howto_table[ (int) R_MS1_32_PCREL];
- case BFD_RELOC_16_PCREL:
- return &ms1_elf_howto_table[ (int) R_MS1_PC16];
- case BFD_RELOC_HI16:
- return &ms1_elf_howto_table[ (int) R_MS1_HI16];
- case BFD_RELOC_LO16:
- return &ms1_elf_howto_table[ (int) R_MS1_LO16];
-
- default:
- /* Pacify gcc -Wall. */
- return NULL;
- }
- return NULL;
-}
-
-bfd_reloc_status_type
-ms1_elf_relocate_hi16
- (bfd * input_bfd,
- Elf_Internal_Rela * relhi,
- bfd_byte * contents,
- bfd_vma value)
-{
- bfd_vma insn;
-
- insn = bfd_get_32 (input_bfd, contents + relhi->r_offset);
-
- value += relhi->r_addend;
- value >>= 16;
- insn = ((insn & ~0xFFFF) | value);
-
- bfd_put_32 (input_bfd, insn, contents + relhi->r_offset);
- return bfd_reloc_ok;
-}
-\f
-/* XXX: The following code is the result of a cut&paste. This unfortunate
- practice is very widespread in the various target back-end files. */
-
-/* Set the howto pointer for a MS1 ELF reloc. */
-
-static void
-ms1_info_to_howto_rela
- (bfd * abfd ATTRIBUTE_UNUSED,
- arelent * cache_ptr,
- Elf_Internal_Rela * dst)
-{
- unsigned int r_type;
-
- r_type = ELF32_R_TYPE (dst->r_info);
- cache_ptr->howto = & ms1_elf_howto_table [r_type];
-}
-
-/* Perform a single relocation. By default we use the standard BFD
- routines. */
-
-static bfd_reloc_status_type
-ms1_final_link_relocate
- (reloc_howto_type * howto,
- bfd * input_bfd,
- asection * input_section,
- bfd_byte * contents,
- Elf_Internal_Rela * rel,
- bfd_vma relocation)
-{
- return _bfd_final_link_relocate (howto, input_bfd, input_section,
- contents, rel->r_offset,
- relocation, rel->r_addend);
-}
-
-/* Relocate a MS1 ELF section.
- There is some attempt to make this function usable for many architectures,
- both USE_REL and USE_RELA ['twould be nice if such a critter existed],
- if only to serve as a learning tool.
-
- The RELOCATE_SECTION function is called by the new ELF backend linker
- to handle the relocations for a section.
-
- The relocs are always passed as Rela structures; if the section
- actually uses Rel structures, the r_addend field will always be
- zero.
-
- This function is responsible for adjusting the section contents as
- necessary, and (if using Rela relocs and generating a relocatable
- output file) adjusting the reloc addend as necessary.
-
- This function does not have to worry about setting the reloc
- address or the reloc symbol index.
-
- LOCAL_SYMS is a pointer to the swapped in local symbols.
-
- LOCAL_SECTIONS is an array giving the section in the input file
- corresponding to the st_shndx field of each local symbol.
-
- The global hash table entry for the global symbols can be found
- via elf_sym_hashes (input_bfd).
-
- When generating relocatable output, this function must handle
- STB_LOCAL/STT_SECTION symbols specially. The output symbol is
- going to be the section symbol corresponding to the output
- section, which means that the addend must be adjusted
- accordingly. */
-
-static bfd_boolean
-ms1_elf_relocate_section
- (bfd * output_bfd ATTRIBUTE_UNUSED,
- struct bfd_link_info * info,
- bfd * input_bfd,
- asection * input_section,
- bfd_byte * contents,
- Elf_Internal_Rela * relocs,
- Elf_Internal_Sym * local_syms,
- asection ** local_sections)
-{
- Elf_Internal_Shdr * symtab_hdr;
- struct elf_link_hash_entry ** sym_hashes;
- Elf_Internal_Rela * rel;
- Elf_Internal_Rela * relend;
-
- symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
- sym_hashes = elf_sym_hashes (input_bfd);
- relend = relocs + input_section->reloc_count;
-
- for (rel = relocs; rel < relend; rel ++)
- {
- reloc_howto_type * howto;
- unsigned long r_symndx;
- Elf_Internal_Sym * sym;
- asection * sec;
- struct elf_link_hash_entry * h;
- bfd_vma relocation;
- bfd_reloc_status_type r;
- const char * name = NULL;
- int r_type;
-
- r_type = ELF32_R_TYPE (rel->r_info);
-
- r_symndx = ELF32_R_SYM (rel->r_info);
-
- /* This is a final link. */
- howto = ms1_elf_howto_table + ELF32_R_TYPE (rel->r_info);
- h = NULL;
- sym = NULL;
- sec = NULL;
-
- if (r_symndx < symtab_hdr->sh_info)
- {
- sym = local_syms + r_symndx;
- sec = local_sections [r_symndx];
- relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
-
- name = bfd_elf_string_from_elf_section
- (input_bfd, symtab_hdr->sh_link, sym->st_name);
- name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
- }
- else
- {
- bfd_boolean unresolved_reloc;
- bfd_boolean warned;
-
- RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
- r_symndx, symtab_hdr, sym_hashes,
- h, sec, relocation,
- unresolved_reloc, warned);
-
- name = h->root.root.string;
- }
-
-
- /* Finally, the sole MS1-specific part. */
- switch (r_type)
- {
- case R_MS1_HI16:
- r = ms1_elf_relocate_hi16 (input_bfd, rel, contents, relocation);
- break;
- default:
- r = ms1_final_link_relocate (howto, input_bfd, input_section,
- contents, rel, relocation);
- break;
- }
-
-
- if (r != bfd_reloc_ok)
- {
- const char * msg = (const char *) NULL;
-
- switch (r)
- {
- case bfd_reloc_overflow:
- r = info->callbacks->reloc_overflow
- (info, (h ? &h->root : NULL), name, howto->name, (bfd_vma) 0,
- input_bfd, input_section, rel->r_offset);
- break;
-
- case bfd_reloc_undefined:
- r = info->callbacks->undefined_symbol
- (info, name, input_bfd, input_section, rel->r_offset, TRUE);
- break;
-
- case bfd_reloc_outofrange:
- msg = _("internal error: out of range error");
- break;
-
- case bfd_reloc_dangerous:
- msg = _("internal error: dangerous relocation");
- break;
-
- default:
- msg = _("internal error: unknown error");
- break;
- }
-
- if (msg)
- r = info->callbacks->warning
- (info, msg, name, input_bfd, input_section, rel->r_offset);
-
- if (! r)
- return FALSE;
- }
- }
-
- return TRUE;
-}
-
-/* Return the section that should be marked against GC for a given
- relocation. */
-
-static asection *
-ms1_elf_gc_mark_hook
- (asection * sec,
- struct bfd_link_info * info ATTRIBUTE_UNUSED,
- Elf_Internal_Rela * rel ATTRIBUTE_UNUSED,
- struct elf_link_hash_entry * h,
- Elf_Internal_Sym * sym)
-{
- if (h != NULL)
- {
- switch (h->root.type)
- {
- case bfd_link_hash_defined:
- case bfd_link_hash_defweak:
- return h->root.u.def.section;
-
- case bfd_link_hash_common:
- return h->root.u.c.p->section;
-
- default:
- break;
- }
- }
- else
- {
- if (!(elf_bad_symtab (sec->owner)
- && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
- && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
- && sym->st_shndx != SHN_COMMON))
- return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
- }
-
- return NULL;
-}
-
-/* Update the got entry reference counts for the section being
- removed. */
-
-static bfd_boolean
-ms1_elf_gc_sweep_hook
- (bfd * abfd ATTRIBUTE_UNUSED,
- struct bfd_link_info * info ATTRIBUTE_UNUSED,
- asection * sec ATTRIBUTE_UNUSED,
- const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED)
-{
- return TRUE;
-}
-
-/* Look through the relocs for a section during the first phase.
- Since we don't do .gots or .plts, we just need to consider the
- virtual table relocs for gc. */
-
-static bfd_boolean
-ms1_elf_check_relocs
- (bfd * abfd,
- struct bfd_link_info * info,
- asection * sec,
- const Elf_Internal_Rela * relocs)
-{
- Elf_Internal_Shdr * symtab_hdr;
- struct elf_link_hash_entry ** sym_hashes;
- struct elf_link_hash_entry ** sym_hashes_end;
- const Elf_Internal_Rela * rel;
- const Elf_Internal_Rela * rel_end;
-
- if (info->relocatable)
- return TRUE;
-
- symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
- sym_hashes = elf_sym_hashes (abfd);
- sym_hashes_end = sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
- if (!elf_bad_symtab (abfd))
- sym_hashes_end -= symtab_hdr->sh_info;
-
- rel_end = relocs + sec->reloc_count;
- for (rel = relocs; rel < rel_end; rel++)
- {
- struct elf_link_hash_entry *h;
- unsigned long r_symndx;
-
- r_symndx = ELF32_R_SYM (rel->r_info);
- if (r_symndx < symtab_hdr->sh_info)
- h = NULL;
- else
- {
- h = sym_hashes[r_symndx - symtab_hdr->sh_info];
- while (h->root.type == bfd_link_hash_indirect
- || h->root.type == bfd_link_hash_warning)
- h = (struct elf_link_hash_entry *) h->root.u.i.link;
- }
- }
-
- return TRUE;
-}
-
-/* Return the MACH for an e_flags value. */
-
-static int
-elf32_ms1_machine (bfd *abfd)
-{
- switch (elf_elfheader (abfd)->e_flags & EF_MS1_CPU_MASK)
- {
- case EF_MS1_CPU_MRISC: return bfd_mach_ms1;
- case EF_MS1_CPU_MRISC2: return bfd_mach_mrisc2;
- case EF_MS1_CPU_MS2: return bfd_mach_ms2;
- }
-
- return bfd_mach_ms1;
-}
-
-static bfd_boolean
-ms1_elf_object_p (bfd * abfd)
-{
- bfd_default_set_arch_mach (abfd, bfd_arch_ms1, elf32_ms1_machine (abfd));
-
- return TRUE;
-}
-
-/* Function to set the ELF flag bits. */
-
-static bfd_boolean
-ms1_elf_set_private_flags (bfd * abfd,
- flagword flags)
-{
- elf_elfheader (abfd)->e_flags = flags;
- elf_flags_init (abfd) = TRUE;
- return TRUE;
-}
-
-static bfd_boolean
-ms1_elf_copy_private_bfd_data (bfd * ibfd, bfd * obfd)
-{
- if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
- || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
- return TRUE;
-
- BFD_ASSERT (!elf_flags_init (obfd)
- || elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags);
-
- elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
- elf_flags_init (obfd) = TRUE;
- return TRUE;
-}
-
-/* Merge backend specific data from an object file to the output
- object file when linking. */
-
-static bfd_boolean
-ms1_elf_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
-{
- flagword old_flags, new_flags;
- bfd_boolean error = FALSE;
-
- /* Check if we have the same endianess. */
- if (_bfd_generic_verify_endian_match (ibfd, obfd) == FALSE)
- return FALSE;
-
- /* If they're not both ms1, then merging is meaningless, so just
- don't do it. */
- if (strcmp (ibfd->arch_info->arch_name, "ms1") != 0)
- return TRUE;
- if (strcmp (obfd->arch_info->arch_name, "ms1") != 0)
- return TRUE;
-
- new_flags = elf_elfheader (ibfd)->e_flags;
- old_flags = elf_elfheader (obfd)->e_flags;
-
-#ifdef DEBUG
- _bfd_error_handler ("%B: old_flags = 0x%.8lx, new_flags = 0x%.8lx, init = %s",
- ibfd, old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no");
-#endif
-
- if (!elf_flags_init (obfd))
- {
- old_flags = new_flags;
- elf_flags_init (obfd) = TRUE;
- }
- else if ((new_flags & EF_MS1_CPU_MASK) != (old_flags & EF_MS1_CPU_MASK))
- {
- /* CPU has changed. This is invalid, because MRISC, MRISC2 and
- MS2 are not subsets of each other. */
- error = 1;
-
- /* FIXME:However, until the compiler is multilibbed, preventing
- mixing breaks the build. So we allow merging and use the
- greater CPU value. This is of course unsafe. */
- error = 0;
- if ((new_flags & EF_MS1_CPU_MASK) > (old_flags & EF_MS1_CPU_MASK))
- old_flags = ((old_flags & ~EF_MS1_CPU_MASK)
- | (new_flags & EF_MS1_CPU_MASK));
- }
- if (!error)
- {
- obfd->arch_info = ibfd->arch_info;
- elf_elfheader (obfd)->e_flags = old_flags;
- }
-
- return !error;
-}
-
-static bfd_boolean
-ms1_elf_print_private_bfd_data (bfd * abfd, void * ptr)
-{
- FILE * file = (FILE *) ptr;
- flagword flags;
-
- BFD_ASSERT (abfd != NULL && ptr != NULL);
-
- /* Print normal ELF private data. */
- _bfd_elf_print_private_bfd_data (abfd, ptr);
-
- flags = elf_elfheader (abfd)->e_flags;
- fprintf (file, _("private flags = 0x%lx:"), (long)flags);
-
- switch (flags & EF_MS1_CPU_MASK)
- {
- default:
- case EF_MS1_CPU_MRISC: fprintf (file, " ms1-16-002"); break;
- case EF_MS1_CPU_MRISC2: fprintf (file, " ms1-16-003"); break;
- case EF_MS1_CPU_MS2: fprintf (file, " ms2"); break;
- }
-
- fputc ('\n', file);
-
- return TRUE;
-}
-
-\f
-#define TARGET_BIG_SYM bfd_elf32_ms1_vec
-#define TARGET_BIG_NAME "elf32-ms1"
-
-#define ELF_ARCH bfd_arch_ms1
-#define ELF_MACHINE_CODE EM_MS1
-#define ELF_MAXPAGESIZE 1 /* No pages on the MS1. */
-
-#define elf_info_to_howto_rel NULL
-#define elf_info_to_howto ms1_info_to_howto_rela
-
-#define elf_backend_relocate_section ms1_elf_relocate_section
-
-#define bfd_elf32_bfd_reloc_type_lookup ms1_reloc_type_lookup
-
-#define elf_backend_gc_mark_hook ms1_elf_gc_mark_hook
-#define elf_backend_gc_sweep_hook ms1_elf_gc_sweep_hook
-#define elf_backend_check_relocs ms1_elf_check_relocs
-#define elf_backend_object_p ms1_elf_object_p
-#define elf_backend_rela_normal 1
-
-#define elf_backend_can_gc_sections 1
-
-#define bfd_elf32_bfd_set_private_flags ms1_elf_set_private_flags
-#define bfd_elf32_bfd_copy_private_bfd_data ms1_elf_copy_private_bfd_data
-#define bfd_elf32_bfd_merge_private_bfd_data ms1_elf_merge_private_bfd_data
-#define bfd_elf32_bfd_print_private_bfd_data ms1_elf_print_private_bfd_data
-
-#include "elf32-target.h"
--- /dev/null
+/* Morpho Technologies MS1 specific support for 32-bit ELF
+ Copyright 2001, 2002, 2003, 2004, 2005
+ Free Software Foundation, Inc.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program 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 of the License, or
+ (at your option) any later version.
+
+ This program 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 this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/ms1.h"
+
+/* Prototypes. */
+static reloc_howto_type * ms1_reloc_type_lookup
+ (bfd *, bfd_reloc_code_real_type);
+
+static void ms1_info_to_howto_rela
+ (bfd *, arelent *, Elf_Internal_Rela *);
+
+static bfd_reloc_status_type ms1_elf_relocate_hi16
+ (bfd *, Elf_Internal_Rela *, bfd_byte *, bfd_vma);
+
+static bfd_reloc_status_type ms1_final_link_relocate
+ (reloc_howto_type *, bfd *, asection *, bfd_byte *,
+ Elf_Internal_Rela *, bfd_vma);
+
+static bfd_boolean ms1_elf_relocate_section
+ (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
+ Elf_Internal_Rela *, Elf_Internal_Sym *, asection **);
+
+/* Relocation tables. */
+static reloc_howto_type ms1_elf_howto_table [] =
+{
+ /* This reloc does nothing. */
+ HOWTO (R_MS1_NONE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MS1_NONE", /* name */
+ FALSE, /* partial_inplace */
+ 0 , /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 16 bit absolute relocation. */
+ HOWTO (R_MS1_16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MS1_16", /* name */
+ FALSE, /* partial_inplace */
+ 0 , /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 32 bit absolute relocation. */
+ HOWTO (R_MS1_32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MS1_32", /* name */
+ FALSE, /* partial_inplace */
+ 0 , /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 32 bit pc-relative relocation. */
+ HOWTO (R_MS1_32_PCREL, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MS1_32_PCREL", /* name */
+ FALSE, /* partial_inplace */
+ 0 , /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A 16 bit pc-relative relocation. */
+ HOWTO (R_MS1_PC16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MS1_PC16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* high 16 bits of symbol value. */
+ HOWTO (R_MS1_HI16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MS1_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff0000, /* src_mask */
+ 0xffff0000, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Low 16 bits of symbol value. */
+ HOWTO (R_MS1_LO16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MS1_LO16", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+};
+
+/* Map BFD reloc types to MS1 ELF reloc types. */
+
+static reloc_howto_type *
+ms1_reloc_type_lookup
+ (bfd * abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ /* Note that the ms1_elf_howto_table is indxed by the R_
+ constants. Thus, the order that the howto records appear in the
+ table *must* match the order of the relocation types defined in
+ include/elf/ms1.h. */
+
+ switch (code)
+ {
+ case BFD_RELOC_NONE:
+ return &ms1_elf_howto_table[ (int) R_MS1_NONE];
+ case BFD_RELOC_16:
+ return &ms1_elf_howto_table[ (int) R_MS1_16];
+ case BFD_RELOC_32:
+ return &ms1_elf_howto_table[ (int) R_MS1_32];
+ case BFD_RELOC_32_PCREL:
+ return &ms1_elf_howto_table[ (int) R_MS1_32_PCREL];
+ case BFD_RELOC_16_PCREL:
+ return &ms1_elf_howto_table[ (int) R_MS1_PC16];
+ case BFD_RELOC_HI16:
+ return &ms1_elf_howto_table[ (int) R_MS1_HI16];
+ case BFD_RELOC_LO16:
+ return &ms1_elf_howto_table[ (int) R_MS1_LO16];
+
+ default:
+ /* Pacify gcc -Wall. */
+ return NULL;
+ }
+ return NULL;
+}
+
+bfd_reloc_status_type
+ms1_elf_relocate_hi16
+ (bfd * input_bfd,
+ Elf_Internal_Rela * relhi,
+ bfd_byte * contents,
+ bfd_vma value)
+{
+ bfd_vma insn;
+
+ insn = bfd_get_32 (input_bfd, contents + relhi->r_offset);
+
+ value += relhi->r_addend;
+ value >>= 16;
+ insn = ((insn & ~0xFFFF) | value);
+
+ bfd_put_32 (input_bfd, insn, contents + relhi->r_offset);
+ return bfd_reloc_ok;
+}
+\f
+/* XXX: The following code is the result of a cut&paste. This unfortunate
+ practice is very widespread in the various target back-end files. */
+
+/* Set the howto pointer for a MS1 ELF reloc. */
+
+static void
+ms1_info_to_howto_rela
+ (bfd * abfd ATTRIBUTE_UNUSED,
+ arelent * cache_ptr,
+ Elf_Internal_Rela * dst)
+{
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (dst->r_info);
+ cache_ptr->howto = & ms1_elf_howto_table [r_type];
+}
+
+/* Perform a single relocation. By default we use the standard BFD
+ routines. */
+
+static bfd_reloc_status_type
+ms1_final_link_relocate
+ (reloc_howto_type * howto,
+ bfd * input_bfd,
+ asection * input_section,
+ bfd_byte * contents,
+ Elf_Internal_Rela * rel,
+ bfd_vma relocation)
+{
+ return _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend);
+}
+
+/* Relocate a MS1 ELF section.
+ There is some attempt to make this function usable for many architectures,
+ both USE_REL and USE_RELA ['twould be nice if such a critter existed],
+ if only to serve as a learning tool.
+
+ The RELOCATE_SECTION function is called by the new ELF backend linker
+ to handle the relocations for a section.
+
+ The relocs are always passed as Rela structures; if the section
+ actually uses Rel structures, the r_addend field will always be
+ zero.
+
+ This function is responsible for adjusting the section contents as
+ necessary, and (if using Rela relocs and generating a relocatable
+ output file) adjusting the reloc addend as necessary.
+
+ This function does not have to worry about setting the reloc
+ address or the reloc symbol index.
+
+ LOCAL_SYMS is a pointer to the swapped in local symbols.
+
+ LOCAL_SECTIONS is an array giving the section in the input file
+ corresponding to the st_shndx field of each local symbol.
+
+ The global hash table entry for the global symbols can be found
+ via elf_sym_hashes (input_bfd).
+
+ When generating relocatable output, this function must handle
+ STB_LOCAL/STT_SECTION symbols specially. The output symbol is
+ going to be the section symbol corresponding to the output
+ section, which means that the addend must be adjusted
+ accordingly. */
+
+static bfd_boolean
+ms1_elf_relocate_section
+ (bfd * output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info * info,
+ bfd * input_bfd,
+ asection * input_section,
+ bfd_byte * contents,
+ Elf_Internal_Rela * relocs,
+ Elf_Internal_Sym * local_syms,
+ asection ** local_sections)
+{
+ Elf_Internal_Shdr * symtab_hdr;
+ struct elf_link_hash_entry ** sym_hashes;
+ Elf_Internal_Rela * rel;
+ Elf_Internal_Rela * relend;
+
+ symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (input_bfd);
+ relend = relocs + input_section->reloc_count;
+
+ for (rel = relocs; rel < relend; rel ++)
+ {
+ reloc_howto_type * howto;
+ unsigned long r_symndx;
+ Elf_Internal_Sym * sym;
+ asection * sec;
+ struct elf_link_hash_entry * h;
+ bfd_vma relocation;
+ bfd_reloc_status_type r;
+ const char * name = NULL;
+ int r_type;
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+
+ /* This is a final link. */
+ howto = ms1_elf_howto_table + ELF32_R_TYPE (rel->r_info);
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections [r_symndx];
+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+
+ name = bfd_elf_string_from_elf_section
+ (input_bfd, symtab_hdr->sh_link, sym->st_name);
+ name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
+ }
+ else
+ {
+ bfd_boolean unresolved_reloc;
+ bfd_boolean warned;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned);
+
+ name = h->root.root.string;
+ }
+
+
+ /* Finally, the sole MS1-specific part. */
+ switch (r_type)
+ {
+ case R_MS1_HI16:
+ r = ms1_elf_relocate_hi16 (input_bfd, rel, contents, relocation);
+ break;
+ default:
+ r = ms1_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel, relocation);
+ break;
+ }
+
+
+ if (r != bfd_reloc_ok)
+ {
+ const char * msg = (const char *) NULL;
+
+ switch (r)
+ {
+ case bfd_reloc_overflow:
+ r = info->callbacks->reloc_overflow
+ (info, (h ? &h->root : NULL), name, howto->name, (bfd_vma) 0,
+ input_bfd, input_section, rel->r_offset);
+ break;
+
+ case bfd_reloc_undefined:
+ r = info->callbacks->undefined_symbol
+ (info, name, input_bfd, input_section, rel->r_offset, TRUE);
+ break;
+
+ case bfd_reloc_outofrange:
+ msg = _("internal error: out of range error");
+ break;
+
+ case bfd_reloc_dangerous:
+ msg = _("internal error: dangerous relocation");
+ break;
+
+ default:
+ msg = _("internal error: unknown error");
+ break;
+ }
+
+ if (msg)
+ r = info->callbacks->warning
+ (info, msg, name, input_bfd, input_section, rel->r_offset);
+
+ if (! r)
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Return the section that should be marked against GC for a given
+ relocation. */
+
+static asection *
+ms1_elf_gc_mark_hook
+ (asection * sec,
+ struct bfd_link_info * info ATTRIBUTE_UNUSED,
+ Elf_Internal_Rela * rel ATTRIBUTE_UNUSED,
+ struct elf_link_hash_entry * h,
+ Elf_Internal_Sym * sym)
+{
+ if (h != NULL)
+ {
+ switch (h->root.type)
+ {
+ case bfd_link_hash_defined:
+ case bfd_link_hash_defweak:
+ return h->root.u.def.section;
+
+ case bfd_link_hash_common:
+ return h->root.u.c.p->section;
+
+ default:
+ break;
+ }
+ }
+ else
+ {
+ if (!(elf_bad_symtab (sec->owner)
+ && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
+ && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
+ && sym->st_shndx != SHN_COMMON))
+ return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
+ }
+
+ return NULL;
+}
+
+/* Update the got entry reference counts for the section being
+ removed. */
+
+static bfd_boolean
+ms1_elf_gc_sweep_hook
+ (bfd * abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info * info ATTRIBUTE_UNUSED,
+ asection * sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED)
+{
+ return TRUE;
+}
+
+/* Look through the relocs for a section during the first phase.
+ Since we don't do .gots or .plts, we just need to consider the
+ virtual table relocs for gc. */
+
+static bfd_boolean
+ms1_elf_check_relocs
+ (bfd * abfd,
+ struct bfd_link_info * info,
+ asection * sec,
+ const Elf_Internal_Rela * relocs)
+{
+ Elf_Internal_Shdr * symtab_hdr;
+ struct elf_link_hash_entry ** sym_hashes;
+ struct elf_link_hash_entry ** sym_hashes_end;
+ const Elf_Internal_Rela * rel;
+ const Elf_Internal_Rela * rel_end;
+
+ if (info->relocatable)
+ return TRUE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+ sym_hashes_end = sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
+ if (!elf_bad_symtab (abfd))
+ sym_hashes_end -= symtab_hdr->sh_info;
+
+ rel_end = relocs + sec->reloc_count;
+ for (rel = relocs; rel < rel_end; rel++)
+ {
+ struct elf_link_hash_entry *h;
+ unsigned long r_symndx;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ if (r_symndx < symtab_hdr->sh_info)
+ h = NULL;
+ else
+ {
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ while (h->root.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Return the MACH for an e_flags value. */
+
+static int
+elf32_ms1_machine (bfd *abfd)
+{
+ switch (elf_elfheader (abfd)->e_flags & EF_MS1_CPU_MASK)
+ {
+ case EF_MS1_CPU_MRISC: return bfd_mach_ms1;
+ case EF_MS1_CPU_MRISC2: return bfd_mach_mrisc2;
+ case EF_MS1_CPU_MS2: return bfd_mach_ms2;
+ }
+
+ return bfd_mach_ms1;
+}
+
+static bfd_boolean
+ms1_elf_object_p (bfd * abfd)
+{
+ bfd_default_set_arch_mach (abfd, bfd_arch_ms1, elf32_ms1_machine (abfd));
+
+ return TRUE;
+}
+
+/* Function to set the ELF flag bits. */
+
+static bfd_boolean
+ms1_elf_set_private_flags (bfd * abfd,
+ flagword flags)
+{
+ elf_elfheader (abfd)->e_flags = flags;
+ elf_flags_init (abfd) = TRUE;
+ return TRUE;
+}
+
+static bfd_boolean
+ms1_elf_copy_private_bfd_data (bfd * ibfd, bfd * obfd)
+{
+ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+ || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+ return TRUE;
+
+ BFD_ASSERT (!elf_flags_init (obfd)
+ || elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags);
+
+ elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
+ elf_flags_init (obfd) = TRUE;
+ return TRUE;
+}
+
+/* Merge backend specific data from an object file to the output
+ object file when linking. */
+
+static bfd_boolean
+ms1_elf_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
+{
+ flagword old_flags, new_flags;
+ bfd_boolean error = FALSE;
+
+ /* Check if we have the same endianess. */
+ if (_bfd_generic_verify_endian_match (ibfd, obfd) == FALSE)
+ return FALSE;
+
+ /* If they're not both ms1, then merging is meaningless, so just
+ don't do it. */
+ if (strcmp (ibfd->arch_info->arch_name, "ms1") != 0)
+ return TRUE;
+ if (strcmp (obfd->arch_info->arch_name, "ms1") != 0)
+ return TRUE;
+
+ new_flags = elf_elfheader (ibfd)->e_flags;
+ old_flags = elf_elfheader (obfd)->e_flags;
+
+#ifdef DEBUG
+ _bfd_error_handler ("%B: old_flags = 0x%.8lx, new_flags = 0x%.8lx, init = %s",
+ ibfd, old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no");
+#endif
+
+ if (!elf_flags_init (obfd))
+ {
+ old_flags = new_flags;
+ elf_flags_init (obfd) = TRUE;
+ }
+ else if ((new_flags & EF_MS1_CPU_MASK) != (old_flags & EF_MS1_CPU_MASK))
+ {
+ /* CPU has changed. This is invalid, because MRISC, MRISC2 and
+ MS2 are not subsets of each other. */
+ error = 1;
+
+ /* FIXME:However, until the compiler is multilibbed, preventing
+ mixing breaks the build. So we allow merging and use the
+ greater CPU value. This is of course unsafe. */
+ error = 0;
+ if ((new_flags & EF_MS1_CPU_MASK) > (old_flags & EF_MS1_CPU_MASK))
+ old_flags = ((old_flags & ~EF_MS1_CPU_MASK)
+ | (new_flags & EF_MS1_CPU_MASK));
+ }
+ if (!error)
+ {
+ obfd->arch_info = ibfd->arch_info;
+ elf_elfheader (obfd)->e_flags = old_flags;
+ }
+
+ return !error;
+}
+
+static bfd_boolean
+ms1_elf_print_private_bfd_data (bfd * abfd, void * ptr)
+{
+ FILE * file = (FILE *) ptr;
+ flagword flags;
+
+ BFD_ASSERT (abfd != NULL && ptr != NULL);
+
+ /* Print normal ELF private data. */
+ _bfd_elf_print_private_bfd_data (abfd, ptr);
+
+ flags = elf_elfheader (abfd)->e_flags;
+ fprintf (file, _("private flags = 0x%lx:"), (long)flags);
+
+ switch (flags & EF_MS1_CPU_MASK)
+ {
+ default:
+ case EF_MS1_CPU_MRISC: fprintf (file, " ms1-16-002"); break;
+ case EF_MS1_CPU_MRISC2: fprintf (file, " ms1-16-003"); break;
+ case EF_MS1_CPU_MS2: fprintf (file, " ms2"); break;
+ }
+
+ fputc ('\n', file);
+
+ return TRUE;
+}
+
+\f
+#define TARGET_BIG_SYM bfd_elf32_ms1_vec
+#define TARGET_BIG_NAME "elf32-ms1"
+
+#define ELF_ARCH bfd_arch_ms1
+#define ELF_MACHINE_CODE EM_MS1
+#define ELF_MAXPAGESIZE 1 /* No pages on the MS1. */
+
+#define elf_info_to_howto_rel NULL
+#define elf_info_to_howto ms1_info_to_howto_rela
+
+#define elf_backend_relocate_section ms1_elf_relocate_section
+
+#define bfd_elf32_bfd_reloc_type_lookup ms1_reloc_type_lookup
+
+#define elf_backend_gc_mark_hook ms1_elf_gc_mark_hook
+#define elf_backend_gc_sweep_hook ms1_elf_gc_sweep_hook
+#define elf_backend_check_relocs ms1_elf_check_relocs
+#define elf_backend_object_p ms1_elf_object_p
+#define elf_backend_rela_normal 1
+
+#define elf_backend_can_gc_sections 1
+
+#define bfd_elf32_bfd_set_private_flags ms1_elf_set_private_flags
+#define bfd_elf32_bfd_copy_private_bfd_data ms1_elf_copy_private_bfd_data
+#define bfd_elf32_bfd_merge_private_bfd_data ms1_elf_merge_private_bfd_data
+#define bfd_elf32_bfd_print_private_bfd_data ms1_elf_print_private_bfd_data
+
+#include "elf32-target.h"
+++ /dev/null
-; Morpho Technologies mRISC CPU description. -*- Scheme -*-
-; Copyright 2001 Free Software Foundation, Inc.
-;
-; Contributed by Red Hat Inc; developed under contract from
-; Morpho Technologies.
-;
-; This file is part of the GNU Binutils.
-;
-; This program 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 of the License, or
-; (at your option) any later version.
-;
-; This program 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 this program; if not, write to the Free Software
-; Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
-
-(include "simplify.inc")
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Define The Architecture, Attributes, ISA, CPU, Machine, And Model. ;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-; define-arch must appear first
-(define-arch
- (name ms1) ; name of cpu family
- (comment "Morpho Technologies mRISC family")
- (default-alignment aligned)
- (insn-lsb0? #t)
- (machs ms1 ms1-003 ms2)
- (isas ms1)
-)
-
-; Instruction set parameters.
-
-(define-isa
- (name ms1)
- (comment "Morpho Technologies mrisc ISA")
- (default-insn-word-bitsize 32)
- (default-insn-bitsize 32)
- (base-insn-bitsize 32)
- (parallel-insns 2)
-)
-\f
-; Cpu family definitions.
-
-
-(define-cpu
- ; cpu names must be distinct from the architecture name and machine names.
- (name ms1bf)
- (comment "Morpho Technologies mRISC family")
- (endian big)
- (word-bitsize 32)
-)
-
-(define-cpu
- ; cpu names must be distinct from the architecture name and machine names.
- (name ms1-003bf)
- (comment "Morpho Technologies mRISC family")
- (endian big)
- (word-bitsize 32)
-)
-
-(define-cpu
- ; cpu names must be distinct from the architecture name and machine names.
- (name ms2bf)
- (comment "Morpho Technologies mRISC family")
- (endian big)
- (word-bitsize 32)
-)
-
-(define-mach
- (name ms1)
- (comment "Morpho Technologies mrisc")
- (cpu ms1bf)
- (isas ms1)
-)
-
-(define-mach
- (name ms1-003)
- (comment "Morpho Technologies mrisc")
- (cpu ms1-003bf)
- (isas ms1)
-)
-
-(define-mach
- (name ms2)
- (comment "Morpho Technologies ms2")
- (cpu ms2bf)
- (isas ms1)
-)
-
-\f
-; Model descriptions.
-; Can probably take the u-exec out. We'll see.
-(define-model
- (name ms1)
- (comment "Morpho Technologies mrisc")
- (mach ms1)
- (unit u-exec "Execution Unit" ()
- 1 1 ; issue done
- () ; state
- () ; inputs
- () ; outputs
- () ; profile action (default)
- )
-)
-
-(define-model
- (name ms1-003)
- (comment "Morpho Technologies mrisc")
- (mach ms1-003)
- (unit u-exec "Execution Unit" ()
- 1 1 ; issue done
- () ; state
- () ; inputs
- () ; outputs
- () ; profile action (default)
- )
-)
-
-(define-model
- (name ms2)
- (comment "Morpho Technologies ms2")
- (mach ms2)
- (unit u-exec "Execution Unit" ()
- 1 1 ; issue done
- () ; state
- () ; inputs
- () ; outputs
- () ; profile action (default)
- )
-)
-
-; FIXME: It might simplify things to separate the execute process from the
-; one that updates the PC.
-\f
-
-;;;;;;;;;;;;;;;;;;;;;;;;
-;; Instruction Fields ;;
-;;;;;;;;;;;;;;;;;;;;;;;;
-
-; Attributes:
-; PCREL-ADDR: pc relative value (for reloc and disassembly purposes)
-; ABS-ADDR: absolute address (for reloc and disassembly purposes?)
-; RESERVED: bits are not used to decode insn, must be all 0
-; RELOC: there is a relocation associated with this field (experiment)
-;
-; f-msys: Identify a a morphosys insns. 1 if msys, 0 if not.
-; f-opc: 6 bit opcode for non-morphosys instructions.
-; f-msopc: 6 bit opcode for morphosys instructions.
-; f-imm: flag to indicate use of an immediate operand. 1 if yes, 0 if no.
-; f-sr1: source resgister 1. (also used for MSYS insns)
-; f-sr2: source register 2. (also used for MSYS insns)
-; f-dr: destination register when located in bits 19:16.
-; f-drrr: destination register when located in bits 15:12. (also for MSYS insns)
-; f-imm16: 16 bit immediate value when not an offset.
-; f-imm16a: 16 bit immediate value when it's a pc-rel offset.
-; f-uu4a: unused 4 bit field.
-; f-uu4b: second unsed 4 bit field.
-; f-uu1: unused 1 bit field
-; f-uu12: unused 12 bit field.
-; f-uu16: unused 16 bit field.
-; f-uu24: unused 24 bit field.
-
-(dnf f-msys "morphosys insn flag" () 31 1)
-(dnf f-opc "opcode field" () 30 6)
-(dnf f-imm "immedate flag" () 24 1)
-(dnf f-uu24 "unused 24 bits" () 23 24)
-(dnf f-sr1 "sr1 register field" (ABS-ADDR) 23 4)
-(dnf f-sr2 "sr2 register field" (ABS-ADDR) 19 4)
-(dnf f-dr "dr register field" (ABS-ADDR) 19 4)
-(dnf f-drrr "drrr register field" (ABS-ADDR) 15 4)
-(dnf f-imm16u "unsigned 16 bit immediate" () 15 16)
-(df f-imm16s "signed 16 bit immediate" () 15 16 INT ((value pc) (add HI value 0)) ((value pc) (add HI value 0)))
-(dnf f-imm16a "pc-rel offset" (PCREL-ADDR) 15 16)
-(dnf f-uu4a "unused 4 bit field" () 19 4)
-(dnf f-uu4b "unused 4 bit field" () 23 4)
-(dnf f-uu12 "unused 12 bit field" () 11 12)
-(dnf f-uu8 "unused 8 bit field" () 15 8)
-(dnf f-uu16 "unused 16 bit field" () 15 16)
-(dnf f-uu1 "unused 1 bit field" () 7 1)
-
-; The following ifields are used exclusively for the MorphoSys instructions.
-; In a few cases, a bit field is used for something in addition to what its
-; name suggests. For the most part, the names are meaningful though.
-
-(dnf f-msopc "opcode field" () 30 5)
-(dnf f-uu-26-25 "unused 26 bits" () 25 26)
-(dnf f-mask "mask" () 25 16)
-(dnf f-bankaddr "bank address" () 25 13)
-(dnf f-rda "rda" () 25 1)
-(dnf f-uu-2-25 "unused bits 25 & 24" () 25 2)
-(dnf f-rbbc "Omega network configuration" () 25 2)
-(dnf f-perm "perm" () 25 2)
-(dnf f-mode "mode" () 25 2)
-(dnf f-uu-1-24 "testing" () 24 1)
-(dnf f-wr "wr" () 24 1)
-(dnf f-fbincr "fb incr" () 23 4)
-(dnf f-uu-2-23 "unused bits 23 and 22" () 23 2)
-(dnf f-xmode "xmode" () 23 1)
-(dnf f-a23 "a23" () 23 1)
-(dnf f-mask1 "mask1" () 22 3)
-(dnf f-cr "cr" () 22 3)
-(dnf f-type "type" () 21 2)
-(dnf f-incamt "increment amount" () 19 8)
-(dnf f-cbs "cbs" () 19 2)
-(dnf f-uu-1-19 "unused bit 19" () 19 1)
-(dnf f-ball "b_all" () 19 1)
-(dnf f-colnum "column number" () 18 3)
-(dnf f-brc "b_r_c" () 18 3)
-(dnf f-incr "incr" () 17 6)
-(dnf f-fbdisp "frame buffer displacement" () 15 6)
-(dnf f-uu-4-15 "unused bits 15,14,13,12" () 15 4)
-(dnf f-length "length" () 15 3)
-(dnf f-uu-1-15 "unused bit 15" () 15 1)
-(dnf f-rc "row/column context" () 15 1)
-(dnf f-rcnum "starting cell of cntxt mem." () 14 3)
-(dnf f-rownum "row number" () 14 3)
-(dnf f-cbx "cbx" () 14 3)
-(dnf f-id "id" () 14 1)
-(dnf f-size "size" () 13 14)
-(dnf f-rownum1 "row number" () 12 3)
-(dnf f-uu-3-11 "unused 3 bits (11-9)" () 11 3)
-(dnf f-rc1 "row/column context" () 11 1)
-(dnf f-ccb "ccb" () 11 1)
-(dnf f-cbrb "data-bus orientation" () 10 1)
-(dnf f-cdb "cdb" () 10 1)
-(dnf f-rownum2 "row number" () 9 3)
-(dnf f-cell "cell" () 9 3)
-(dnf f-uu-3-9 "unused 3 bits (9-7)" () 9 3)
-(dnf f-contnum "context number" () 8 9)
-(dnf f-uu-1-6 "unused bit 6" () 6 1)
-(dnf f-dup "dup" () 6 1)
-(dnf f-rc2 "rc2" () 6 1)
-(dnf f-ctxdisp "context displacement" () 5 6)
-
-; additional fields in ms2
-(dnf f-imm16l "loop count" () 23 16)
-(df f-loopo "loop offset" () 7 8 UINT
- ((value pc) (srl SI value 2))
- ((value pc) (add SI (sll value 2) 8))
- )
-(dnf f-cb1sel "cb1 select" () 25 3)
-(dnf f-cb2sel "cb2 select" () 22 3)
-(dnf f-cb1incr "cb1 increment" (SIGNED) 19 6)
-(dnf f-cb2incr "cb2 increment" (SIGNED) 13 6)
-(dnf f-rc3 "row/colum context" () 7 1)
-
-; The following is just for a test
-(dnf f-msysfrsr2 "sr2 for msys" () 19 4)
-(dnf f-brc2 "b_r_c2" () 14 3)
-(dnf f-ball2 "b_all2" () 15 1)
-
-\f
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Enumerations Of Instruction Fields ;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-; insn-msys: bit 31. 1 for Morphosys Insns, 0 if not.
-(define-normal-insn-enum insn-msys "msys enums" () MSYS_ f-msys
- (NO YES)
-)
-
-; insn-opc: bits 30 through 25 . Non-MorphoSys Instructions
-; Note - the documentation is wrong for the encoding of the DBNZ
-; instruction. It is actually 011110. See Issue 67699.
-(define-normal-insn-enum insn-opc "opc enums" () OPC_ f-opc
- (ADD ADDU SUB SUBU MUL - - -
- AND OR XOR NAND NOR XNOR LDUI -
- LSL LSR ASR - - - - -
- BRLT BRLE BREQ JMP JAL BRNEQ DBNZ LOOP
- LDW STW - - - - - -
- - - - - - - - -
- EI DI SI RETI BREAK IFLUSH - -
- )
-)
-
-; insn-msopc: bits 30 through 26 . MorphoSys Instructions
-(define-normal-insn-enum insn-msopc "msopc enums" () MSOPC_ f-msopc
- (LDCTXT LDFB STFB FBCB MFBCB FBCCI FBRCI FBCRI
- FBRRI MFBCCI MFBRCI MFBCRI MFBRRI FBCBDR RCFBCB MRCFBCB
- CBCAST DUPCBCAST WFBI WFB RCRISC FBCBINC RCXMODE INTLVR
- WFBINC MWFBINC WFBINCR MWFBINCR FBCBINCS MFBCBINCS FBCBINCRS MFBCBINCRS
- - - - - - - - -
- )
-)
-
-; insn-imm: bit 24. Immediate operand indicator.
-(define-normal-insn-enum insn-imm "imm enums" () IMM_ f-imm
- ; This bit specifies whether and immediate operand will be present.
- ; It's 1 if there is, 0 if there is not.
- (NO YES)
-)
-;;;;;;;;;;;;;;;;
-;; Attributes ;;
-;;;;;;;;;;;;;;;;
-
-; Might not need this. Keep if for the sim just in case.
-;(define-attr
-; (for insn)
-; (type boolean)
-; (name EXT-SKIP-INSN)
-; (comment "instruction is a PAGE, LOADL or LOADH instruction")
-;)
-
-(define-attr
- (for insn)
- (type boolean)
- (name LOAD-DELAY)
- (comment "insn has a load delay")
-)
-
-(define-attr
- (for insn)
- (type boolean)
- (name MEMORY-ACCESS)
- (comment "insn performs a memory access")
-)
-
-(define-attr
- (for insn)
- (type boolean)
- (name AL-INSN)
- (comment "insn is an arithmetic or logic insn.")
-)
-
-(define-attr
- (for insn)
- (type boolean)
- (name IO-INSN)
- (comment "insn performs an I/O operation")
-)
-
-(define-attr
- (for insn)
- (type boolean)
- (name BR-INSN)
- (comment "insn performs an I/O operation")
-)
-
-(define-attr
- (for insn)
- (type boolean)
- (name JAL-HAZARD)
- (comment "insn has jal-like hazard")
-)
-
-(define-pmacro (define-reg-use-attr regfield)
- (define-attr
- (for insn)
- (type boolean)
- (name (.sym "USES-" (.upcase regfield)))
- (comment ("insn accesses register operand " regfield))))
-
-(define-reg-use-attr "frdr")
-(define-reg-use-attr "frdrrr")
-(define-reg-use-attr "frsr1")
-(define-reg-use-attr "frsr2")
-
-
-; Might not need this. Keep it for the sim just in case.
-(define-attr
- (for insn)
- (type boolean)
- (name SKIPA)
- (comment "instruction is a SKIP instruction")
-)
-
-
-;;;;;;;;;;;;;;;;;;;;;
-;; Hardware Pieces ;;
-;;;;;;;;;;;;;;;;;;;;;
-
-;(define-pmacro (build-reg-name n) (.splice (.str "$" n) n))
-
-; These are the 16 registers that the chip has. In later versions
-; where there will be more registers, this will need to be expanded.
-; Note that there are two entries for the registers with two names.
-(define-hardware
- (name h-spr)
- (comment "special-purpose registers")
- (type register SI (16))
- (indices keyword "" (("R0" 0) ("R1" 1) ("R2" 2) ("R3" 3) ("R4" 4) ("R5" 5)
- ("R6" 6) ("R7" 7) ("R8" 8) ("R9" 9) ("R10" 10) ("R11" 11) ("R12" 12) ("fp" 12)
- ("R13" 13) ("sp" 13) ("R14" 14) ("ra" 14) ("R15" 15) ("ira" 15)))
-; (get (index) (and (raw-reg h-spr) #xffffffff))
-; (set (index value) (set (raw-reg h-spr) (and value #xffffffff)))
-)
-
-; This is the program counter.
-(dnh h-pc "program counter" (PC PROFILE) (pc) () () ())
-
-(define-keyword
- (name msys-syms)
- (print-name h-nil)
- (prefix "")
- (values (DUP 1) (XX 0))
-)
-
-;;;;;;;;;;;;;;
-;; Operands ;;
-;;;;;;;;;;;;;;
-
-(define-operand (name frsr1) (comment "register") (attrs)
- (type h-spr) (index f-sr1) )
-(define-operand (name frsr2) (comment "register") (attrs)
- (type h-spr) (index f-sr2) )
-(define-operand (name frdr) (comment "register") (attrs)
- (type h-spr) (index f-dr) )
-(define-operand (name frdrrr) (comment "register") (attrs)
- (type h-spr) (index f-drrr) )
-(define-operand (name imm16) (comment "immediate value - sign extd") (attrs)
- (type h-sint) (index f-imm16s) (handlers (parse "imm16") (print "dollarhex")))
-(define-operand (name imm16z) (comment "immediate value - zero extd") (attrs)
- (type h-uint) (index f-imm16u) (handlers (parse "imm16") (print "dollarhex")))
-(define-operand (name imm16o) (comment "immediate value") (attrs PCREL-ADDR)
- (type h-uint) (index f-imm16s) (handlers (parse "imm16") (print "pcrel")))
-
-; Operands for MorphoSys Instructions
-
-(define-operand (name rc) (comment "rc") (attrs)
- (type h-uint) (index f-rc) (handlers (parse "rc") (print "dollarhex")))
-
-(define-operand (name rcnum) (comment "rcnum") (attrs)
- (type h-uint) (index f-rcnum) (handlers (print "dollarhex")))
-
-(define-operand (name contnum) (comment "context number") (attrs)
- (type h-uint) (index f-contnum) (handlers (print "dollarhex")))
-
-(define-operand (name rbbc) (comment "omega network configuration") (attrs)
- (type h-uint) (index f-rbbc) (handlers (parse "rbbc") (print "dollarhex")))
-
-(define-operand (name colnum) (comment "column number") (attrs)
- (type h-uint) (index f-colnum) (handlers (print "dollarhex")))
-
-(define-operand (name rownum) (comment "row number") (attrs)
- (type h-uint) (index f-rownum) (handlers (print "dollarhex")))
-
-(define-operand (name rownum1) (comment "row number") (attrs)
- (type h-uint) (index f-rownum1) (handlers (print "dollarhex")))
-
-(define-operand (name rownum2) (comment "row number") (attrs)
- (type h-uint) (index f-rownum2) (handlers (print "dollarhex")))
-
-(define-operand (name rc1) (comment "rc1") (attrs)
- (type h-uint) (index f-rc1) (handlers (parse "rc") (print "dollarhex")))
-
-(define-operand (name rc2) (comment "rc2") (attrs)
- (type h-uint) (index f-rc2) (handlers (parse "rc") (print "dollarhex")))
-
-(define-operand (name cbrb) (comment "data-bus orientation") (attrs)
- (type h-uint) (index f-cbrb) (handlers (parse "cbrb") (print "dollarhex")))
-
-(define-operand (name cell) (comment "cell") (attrs)
- (type h-uint) (index f-cell) (handlers (print "dollarhex")))
-
-(define-operand (name dup) (comment "dup") (attrs)
- (type h-uint) (index f-dup) (handlers (parse "dup") (print "dollarhex")))
-
-(define-operand (name ctxdisp) (comment "context displacement") (attrs)
- (type h-uint) (index f-ctxdisp) (handlers (print "dollarhex")))
-
-(define-operand (name fbdisp) (comment "frame buffer displacement") (attrs)
- (type h-uint) (index f-fbdisp) (handlers (print "dollarhex")))
-
-(define-operand (name type) (comment "type") (attrs)
- (type h-uint) (index f-type) (handlers (parse "type") (print "dollarhex")))
-
-(define-operand (name mask) (comment "mask") (attrs)
- (type h-uint) (index f-mask) (handlers (print "dollarhex")))
-
-(define-operand (name bankaddr) (comment "bank address") (attrs)
- (type h-uint) (index f-bankaddr) (handlers (print "dollarhex")))
-
-(define-operand (name incamt) (comment "increment amount") (attrs)
- (type h-uint) (index f-incamt) (handlers (print "dollarhex")))
-
-(define-operand (name xmode) (comment "xmode") (attrs)
- (type h-uint) (index f-xmode) (handlers (parse "xmode") (print "dollarhex")))
-
-(define-operand (name mask1) (comment "mask1") (attrs)
- (type h-uint) (index f-mask1) (handlers (print "dollarhex")))
-
-(define-operand (name ball) (comment "b_all") (attrs)
- (type h-uint) (index f-ball) (handlers (parse "ball") (print "dollarhex")))
-
-(define-operand (name brc) (comment "b_r_c") (attrs)
- (type h-uint) (index f-brc) (handlers (print "dollarhex")))
-
-(define-operand (name rda) (comment "rd") (attrs)
- (type h-uint) (index f-rda) (handlers (print "dollarhex")))
-
-(define-operand (name wr) (comment "wr") (attrs)
- (type h-uint) (index f-wr) (handlers (print "dollarhex")))
-
-(define-operand (name ball2) (comment "b_all2") (attrs)
- (type h-uint) (index f-ball2) (handlers (parse "ball") (print "dollarhex")))
-
-(define-operand (name brc2) (comment "b_r_c2") (attrs)
- (type h-uint) (index f-brc2) (handlers (print "dollarhex")))
-(define-operand (name perm) (comment "perm") (attrs)
- (type h-uint) (index f-perm) (handlers (print "dollarhex")))
-(define-operand (name a23) (comment "a23") (attrs)
- (type h-uint) (index f-a23) (handlers (print "dollarhex")))
-(define-operand (name cr) (comment "c-r") (attrs)
- (type h-uint) (index f-cr) (handlers (print "dollarhex")))
-(define-operand (name cbs) (comment "cbs") (attrs)
- (type h-uint) (index f-cbs) (handlers (print "dollarhex")))
-(define-operand (name incr) (comment "incr") (attrs)
- (type h-uint) (index f-incr) (handlers (print "dollarhex")))
-(define-operand (name length) (comment "length") (attrs)
- (type h-uint) (index f-length) (handlers (print "dollarhex")))
-(define-operand (name cbx) (comment "cbx") (attrs)
- (type h-uint) (index f-cbx) (handlers (print "dollarhex")))
-(define-operand (name ccb) (comment "ccb") (attrs)
- (type h-uint) (index f-ccb) (handlers (print "dollarhex")))
-(define-operand (name cdb) (comment "cdb") (attrs)
- (type h-uint) (index f-cdb) (handlers (print "dollarhex")))
-
-; For the INTLVR insn
-(define-operand (name mode) (comment "mode") (attrs)
- (type h-uint) (index f-mode) (handlers (print "dollarhex")))
-(define-operand (name id) (comment "i/d") (attrs)
- (type h-uint) (index f-id) (handlers (print "dollarhex")))
-(define-operand (name size) (comment "size") (attrs)
- (type h-uint) (index f-size) (handlers (print "dollarhex")))
-
-(define-operand (name fbincr) (comment "fb incr") (attrs)
- (type h-uint) (index f-fbincr) (handlers (print "dollarhex")))
-
-; For the ms2 insns
-(define-operand (name loopsize) (comment "immediate value")
- (attrs (MACH ms2) PCREL-ADDR)
- (type h-uint) (index f-loopo) (handlers (parse "loopsize") (print "pcrel")))
-(define-operand (name imm16l) (comment "immediate value")
- (attrs (MACH ms2))
- (type h-uint) (index f-imm16l) (handlers (print "dollarhex")))
-(define-operand (name rc3) (comment "rc3") (attrs (MACH ms2))
- (type h-uint) (index f-rc3) (handlers (parse "rc") (print "dollarhex")))
-(define-operand (name cb1sel) (comment "cb1sel") (attrs (MACH ms2))
- (type h-uint) (index f-cb1sel) (handlers (print "dollarhex")))
-(define-operand (name cb2sel) (comment "cb2sel") (attrs (MACH ms2))
- (type h-uint) (index f-cb2sel) (handlers (print "dollarhex")))
-(define-operand (name cb1incr) (comment "cb1incr") (attrs (MACH ms2))
- (type h-sint) (index f-cb1incr) (handlers (print "dollarhex")))
-(define-operand (name cb2incr) (comment "cb2incr") (attrs (MACH ms2))
- (type h-sint) (index f-cb2incr) (handlers (print "dollarhex")))
-
-; Probaby won't need most of these.
-(define-pmacro r0 (reg h-spr #x0))
-(define-pmacro r1 (reg h-spr #x01))
-(define-pmacro r2 (reg h-spr #x02))
-(define-pmacro r3 (reg h-spr #x03))
-(define-pmacro r4 (reg h-spr #x04))
-(define-pmacro r5 (reg h-spr #x05))
-(define-pmacro r6 (reg h-spr #x06))
-(define-pmacro r7 (reg h-spr #x07))
-(define-pmacro r8 (reg h-spr #x08))
-(define-pmacro r9 (reg h-spr #x09))
-(define-pmacro r10 (reg h-spr #xA))
-(define-pmacro r11 (reg h-spr #xB))
-(define-pmacro r12 (reg h-spr #xC))
-(define-pmacro fp (reg h-spr #xC))
-(define-pmacro r13 (reg h-spr #xD))
-(define-pmacro sp (reg h-spr #xD))
-(define-pmacro r14 (reg h-spr #xE))
-(define-pmacro ra (reg h-spr #xE))
-(define-pmacro r15 (reg h-spr #xF))
-(define-pmacro ira (reg h-spr #xF))
-
-; delayed set
-(define-pmacro (dset dest src) (set (delay 1 dest) src))
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Instructions As Defined In the MorphoRisc ISA Document ;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-; Arithmetic Instructions
-
-(dni add "ADD DstReg, SrcReg1, SrcReg2"
- (AL-INSN USES-FRDRRR USES-FRSR1 USES-FRSR2)
- "add $frdrrr,$frsr1,$frsr2"
- (+ MSYS_NO OPC_ADD IMM_NO frsr1 frsr2 frdrrr (f-uu12 0))
- (set frdrrr (add SI frsr1 frsr2))
- ()
-)
-
-(dni addu "ADDU DstReg, SrcReg1, SrcReg2"
- (AL-INSN USES-FRDRRR USES-FRSR1 USES-FRSR2)
- "addu $frdrrr,$frsr1,$frsr2"
- (+ MSYS_NO OPC_ADDU IMM_NO frsr1 frsr2 frdrrr (f-uu12 0))
- (set frdrrr (add USI frsr1 frsr2))
- ()
-)
-
-(dni addi "ADDI DstReg, SrcReg1 UnsImm"
- (AL-INSN USES-FRDR USES-FRSR1)
- "addi $frdr,$frsr1,#$imm16"
- (+ MSYS_NO OPC_ADD IMM_YES frsr1 frdr imm16)
- (sequence((HI tmp))
- (set HI tmp (and imm16 #xffff))
- (set frdr (add SI frsr1 (ext SI tmp)))
- )
- ()
-)
-
-(dni addui "ADDUI DstReg, SrcReg1, UnsImm"
- (AL-INSN USES-FRDR USES-FRSR1)
- "addui $frdr,$frsr1,#$imm16z"
- (+ MSYS_NO OPC_ADDU IMM_YES frsr1 frdr imm16z)
- (set frdr (add USI frsr1 (ext USI imm16z)))
- ()
-)
-
-(dni sub "SUB DstReg, SrcReg1, SrcReg2"
- (AL-INSN USES-FRDRRR USES-FRSR1 USES-FRSR2)
- "sub $frdrrr,$frsr1,$frsr2"
- (+ MSYS_NO OPC_SUB IMM_NO frsr1 frsr2 frdrrr (f-uu12 0))
- (set frdrrr (sub SI frsr1 frsr2))
- ()
-)
-
-(dni subu "SUBU DstReg, SrcReg1, SrcReg2"
- (AL-INSN USES-FRDRRR USES-FRSR1 USES-FRSR2)
- "subu $frdrrr,$frsr1,$frsr2"
- (+ MSYS_NO OPC_SUBU IMM_NO frsr1 frsr2 frdrrr (f-uu12 0))
- (set frdrrr (sub USI frsr1 frsr2))
- ()
-)
-
-(dni subi "SUBI DstReg, SrcReg1, UnsImm"
- (AL-INSN USES-FRDR USES-FRSR1)
- "subi $frdr,$frsr1,#$imm16"
- (+ MSYS_NO OPC_SUB IMM_YES frsr1 frdr imm16)
- (sequence((HI tmp))
- (set HI tmp (and imm16 #xffff))
- (set frdr (sub SI frsr1 (ext SI tmp)))
- )
- ;(set frdr (sub SI frsr1 (ext SI imm16)))
- ()
-)
-
-(dni subui "SUBUI DstReg, SrcReg1, UnsImm"
- (AL-INSN USES-FRDR USES-FRSR1)
- "subui $frdr,$frsr1,#$imm16z"
- (+ MSYS_NO OPC_SUBU IMM_YES frsr1 frdr imm16z)
- (set frdr (sub USI frsr1 (ext USI imm16z)))
- ()
-)
-
-(dni mul "MUL DstReg, SrcReg1, SrcReg2"
- ((MACH ms1-003,ms2) AL-INSN USES-FRDRRR USES-FRSR1 USES-FRSR2)
- "mul $frdrrr,$frsr1,$frsr2"
- (+ MSYS_NO OPC_MUL IMM_NO frsr1 frsr2 frdrrr (f-uu12 0))
- (sequence((HI op1) (HI op2))
- (set op1 (and frsr1 #xffff))
- (if (or (lt op1 (const -32768)) (gt op1 (const 32767)))
- (error "operand out of range")
- )
- (set op2 (and frsr2 #xffff))
- (if (or (lt op2 (const -32768)) (gt op2 (const 32767)))
- (error "operand out of range")
- )
- (set frdrrr (mul SI (ext SI op1) (ext SI op2)))
- )
- ()
-)
-
-(dni muli "MULI DstReg, SrcReg1, UnsImm"
- ((MACH ms1-003,ms2) AL-INSN USES-FRDR USES-FRSR1)
- "muli $frdr,$frsr1,#$imm16"
- (+ MSYS_NO OPC_MUL IMM_YES frsr1 frdr imm16)
- (sequence((HI op1) (HI op2))
- (set op1 (and frsr1 #xffff))
- (if (or (lt op1 (const -32768)) (gt op1 (const 32767)))
- (error "operand out of range")
- )
- (set op2 (and imm16 #xffff))
- (if (eq op1 (const 0))
- (error "op1 is 0")
- )
- (if (eq op2 (const 0))
- (error "op2 is 0")
- )
- (set frdr (mul SI (ext SI op1) (ext SI op2)))
- )
- ()
-)
-
-; Logical Instructions
-
-(dni and "AND DstReg, SrcReg1, SrcReg2"
- (AL-INSN USES-FRDRRR USES-FRSR1 USES-FRSR2)
- "and $frdrrr,$frsr1,$frsr2"
- (+ MSYS_NO OPC_AND IMM_NO frsr1 frsr2 frdrrr (f-uu12 0))
- (set frdrrr (and frsr1 frsr2))
- ()
-)
-
-(dni andi "ANDI DstReg, SrcReg1, UnsImm"
- (AL-INSN USES-FRDR USES-FRSR1)
- "andi $frdr,$frsr1,#$imm16z"
- (+ MSYS_NO OPC_AND IMM_YES frsr1 frdr imm16z)
- (set frdr (and frsr1 (ext USI imm16z)))
- ()
-)
-
-(dni or "OR DstReg, SrcReg1, SrcReg2"
- (AL-INSN USES-FRDRRR USES-FRSR1 USES-FRSR2)
- "or $frdrrr,$frsr1,$frsr2"
- (+ MSYS_NO OPC_OR IMM_NO frsr1 frsr2 frdrrr (f-uu12 0))
- (set frdrrr (or frsr1 frsr2))
- ()
-)
-
-(dni nop "nop"
- ()
- "nop"
- (+ MSYS_NO OPC_OR IMM_NO (f-uu24 0))
- (nop)
- ()
-)
-
-(dni ori "ORI DstReg, SrcReg1, UnsImm"
- (AL-INSN USES-FRDR USES-FRSR1)
- "ori $frdr,$frsr1,#$imm16z"
- (+ MSYS_NO OPC_OR IMM_YES frsr1 frdr imm16z)
- (set frdr (or frsr1 (ext USI imm16z)))
- ()
-)
-
-(dni xor "XOR DstReg, SrcReg1, SrcReg2"
- (AL-INSN USES-FRDRRR USES-FRSR1 USES-FRSR2)
- "xor $frdrrr,$frsr1,$frsr2"
- (+ MSYS_NO OPC_XOR IMM_NO frsr1 frsr2 frdrrr (f-uu12 0))
- (set frdrrr (xor frsr1 frsr2))
- ()
-)
-
-(dni xori "XORI DstReg, SrcReg1, UnsImm"
- (AL-INSN USES-FRDR USES-FRSR1)
- "xori $frdr,$frsr1,#$imm16z"
- (+ MSYS_NO OPC_XOR IMM_YES frsr1 frdr imm16z)
- (set frdr (xor frsr1 (ext USI imm16z)))
- ()
-)
-
-(dni nand "NAND DstReg, SrcReg1, SrcReg2"
- (AL-INSN USES-FRDRRR USES-FRSR1 USES-FRSR2)
- "nand $frdrrr,$frsr1,$frsr2"
- (+ MSYS_NO OPC_NAND IMM_NO frsr1 frsr2 frdrrr (f-uu12 0))
- (set frdrrr (inv (and frsr1 frsr2)))
- ()
-)
-
-(dni nandi "NANDI DstReg, SrcReg1, UnsImm"
- (AL-INSN USES-FRDR USES-FRSR1)
- "nandi $frdr,$frsr1,#$imm16z"
- (+ MSYS_NO OPC_NAND IMM_YES frsr1 frdr imm16z)
- (set frdr (inv (and frsr1 (ext USI imm16z))))
- ()
-)
-
-(dni nor "NOR DstReg, SrcReg1, SrcReg2"
- (AL-INSN USES-FRDRRR USES-FRSR1 USES-FRSR2)
- "nor $frdrrr,$frsr1,$frsr2"
- (+ MSYS_NO OPC_NOR IMM_NO frsr1 frsr2 frdrrr (f-uu12 0))
- (set frdrrr (inv (or frsr1 frsr2)))
- ()
-)
-
-(dni nori "NORI DstReg, SrcReg1, UnsImm"
- (AL-INSN USES-FRDR USES-FRSR1)
- "nori $frdr,$frsr1,#$imm16z"
- (+ MSYS_NO OPC_NOR IMM_YES frsr1 frdr imm16z)
- (set frdr (inv (or frsr1 (ext USI imm16z))))
- ()
-)
-
-(dni xnor "XNOR DstReg, SrcReg1, SrcReg2"
- (AL-INSN USES-FRDRRR USES-FRSR1 USES-FRSR2)
- "xnor $frdrrr,$frsr1,$frsr2"
- (+ MSYS_NO OPC_XNOR IMM_NO frsr1 frsr2 frdrrr (f-uu12 0))
- (set frdrrr (inv (xor frsr1 frsr2)))
- ()
-)
-
-(dni xnori "XNORI DstReg, SrcReg1, UnsImm"
- (AL-INSN USES-FRDR USES-FRSR1)
- "xnori $frdr,$frsr1,#$imm16z"
- (+ MSYS_NO OPC_XNOR IMM_YES frsr1 frdr imm16z)
- (set frdr (inv (xor frsr1 (ext USI imm16z))))
- ()
-)
-
-(dni ldui "LDUI DstReg, UnsImm"
- (AL-INSN USES-FRDR)
- "ldui $frdr,#$imm16z"
- (+ MSYS_NO OPC_LDUI IMM_YES (f-uu4b 0) frdr imm16z)
- (set frdr (and (sll imm16z 16) #xffff0000))
- ()
-)
-
-; Shift Instructions
-
-(dni lsl "LSL DstReg, SrcReg1, SrcReg2"
- (USES-FRDRRR USES-FRSR1 USES-FRSR2)
- "lsl $frdrrr,$frsr1,$frsr2"
- (+ MSYS_NO OPC_LSL IMM_NO frsr1 frsr2 frdrrr (f-uu12 0))
- (set frdrrr (sll frsr1 frsr2))
- ()
-)
-
-(dni lsli "LSLI DstReg, SrcReg1, UnsImm"
- (USES-FRDR USES-FRSR1)
- "lsli $frdr,$frsr1,#$imm16"
- (+ MSYS_NO OPC_LSL IMM_YES frsr1 frdr imm16)
- (set frdr (sll frsr1 imm16))
- ()
-)
-
-(dni lsr "LSR DstReg, SrcReg1, SrcReg2"
- (USES-FRDRRR USES-FRSR1 USES-FRSR2)
- "lsr $frdrrr,$frsr1,$frsr2"
- (+ MSYS_NO OPC_LSR IMM_NO frsr1 frsr2 frdrrr (f-uu12 0))
- (set frdrrr (srl frsr1 frsr2))
- ()
-)
-
-(dni lsri "LSRI DstReg, SrcReg1, UnsImm"
- (USES-FRDR USES-FRSR1)
- "lsri $frdr,$frsr1,#$imm16"
- (+ MSYS_NO OPC_LSR IMM_YES frsr1 frdr imm16)
- (set frdr (srl frsr1 imm16))
- ()
-)
-
-(dni asr "ASR DstReg, SrcReg1, SrcReg2"
- (USES-FRDRRR USES-FRSR1 USES-FRSR2)
- "asr $frdrrr,$frsr1,$frsr2"
- (+ MSYS_NO OPC_ASR IMM_NO frsr1 frsr2 frdrrr (f-uu12 0))
- (set frdrrr (sra frsr1 frsr2))
- ()
-)
-
-(dni asri "ASRI DstReg, SrcReg1, UnsImm"
- (USES-FRDR USES-FRSR1)
- "asri $frdr,$frsr1,#$imm16"
- (+ MSYS_NO OPC_ASR IMM_YES frsr1 frdr imm16)
- (set frdr (sra frsr1 imm16))
- ()
-)
-
-; Control Transfer Instructions
-
-(dni brlt "BRLT SrcReg1, SrcReg2, label"
- (BR-INSN DELAY-SLOT USES-FRDRRR USES-FRSR1 USES-FRSR2)
- "brlt $frsr1,$frsr2,$imm16o"
- (+ MSYS_NO OPC_BRLT IMM_YES frsr1 frsr2 imm16o)
- (sequence()
- (if (lt USI frsr1 frsr2)
- (dset pc (add pc (ext SI imm16o))))
- )
- ()
-)
-
-(dni brle "BRLE SrcReg1, SrcReg2, label"
- (BR-INSN DELAY-SLOT USES-FRSR1 USES-FRSR2)
- "brle $frsr1,$frsr2,$imm16o"
- (+ MSYS_NO OPC_BRLE IMM_YES frsr1 frsr2 imm16o)
- (sequence()
- (if (le USI frsr1 frsr2)
- (dset pc (add pc (ext SI imm16o))))
- )
- ()
-)
-
-(dni breq "BREQ SrcReg1, SrcReg2, label"
- (BR-INSN DELAY-SLOT USES-FRSR1 USES-FRSR2)
- "breq $frsr1,$frsr2,$imm16o"
- (+ MSYS_NO OPC_BREQ IMM_YES frsr1 frsr2 imm16o)
- (sequence()
- (if (eq USI frsr1 frsr2)
- (dset pc (add pc (ext SI imm16o))))
- )
- ()
-)
-
-(dni brne "BRNE SrcReg1, SrcReg2, label"
- (BR-INSN DELAY-SLOT USES-FRSR1 USES-FRSR2)
- "brne $frsr1,$frsr2,$imm16o"
- (+ MSYS_NO OPC_BRNEQ IMM_YES frsr1 frsr2 imm16o)
- (sequence()
- (if (not (eq USI frsr1 frsr2))
- (dset pc (add pc (ext SI imm16o))))
- )
- ()
-)
-
-(dni jmp "JMP, label"
- (DELAY-SLOT BR-INSN)
- "jmp $imm16o"
- (+ MSYS_NO OPC_JMP IMM_YES (f-uu4b 0) (f-uu4a 0) imm16o)
- (dset pc (add pc (ext SI imm16o)))
- ()
-)
-
-(dni jal "JAL DstReg, SrcReg1"
- (BR-INSN DELAY-SLOT BR-INSN USES-FRDR USES-FRSR1 JAL-HAZARD)
- "jal $frdrrr,$frsr1"
- (+ MSYS_NO OPC_JAL IMM_NO frsr1 (f-uu4a 0) frdrrr (f-uu12 0))
- (sequence()
- (if (eq frsr1 #x0)
- (c-call VOID "do_syscall" pc)
- (sequence() ; else part. Do non-syscall stuff here.
- (dset frdrrr (add pc #x8))
- (dset pc frsr1)
- )
- )
- )
- ()
-)
-
-(dni dbnz "DBNZ SrcReg1, label"
- ((MACH ms1-003,ms2) BR-INSN DELAY-SLOT USES-FRSR1)
- "dbnz $frsr1,$imm16o"
- (+ MSYS_NO OPC_DBNZ IMM_YES frsr1 (f-uu4a 0) imm16o)
- (sequence()
- (if (not (eq USI frsr1 0))
- (dset pc (add pc (ext SI imm16o))))
- )
- ()
-)
-
-; Interrupt Control Instructions
-
-(dni ei "EI - Enable Interrupt Processing"
- ()
- "ei"
- (+ MSYS_NO OPC_EI IMM_NO (f-uu4b 0) (f-uu4a 0) (f-uu16 0))
- (c-call VOID "enable_interrupts")
- ()
-)
-
-(dni di "DI - Disable Interrupt Processing"
- ()
- "di"
- (+ MSYS_NO OPC_DI IMM_NO (f-uu4b 0) (f-uu4a 0) (f-uu16 0))
- (c-call VOID "disable_interrupts")
- ()
-)
-
-(dni si "SI - Send software Interrupt"
- (DELAY-SLOT BR-INSN USES-FRDR)
- "si $frdrrr"
- (+ MSYS_NO OPC_SI IMM_NO (f-uu4b 0) (f-uu4a 0) frdrrr (f-uu12 0))
- ;(sequence()
- ; (dset frdr (add pc #x4))
- ; (c-call VOID "do_syscall1" pc)
- ; ; (dset pc frsr1) Do this later when we have the address.
- ;)
- (sequence()
- (set frdrrr (add pc #x4))
- (c-call VOID "do_syscall" pc)
- ; (set pc frsr1) Do this later when we have the address.
- )
- ()
-)
-
-(dni reti "RETI SrcReg1"
- (DELAY-SLOT BR-INSN USES-FRSR1 JAL-HAZARD)
- "reti $frsr1"
- (+ MSYS_NO OPC_RETI IMM_NO frsr1 (f-uu4a 0) (f-uu16 0))
- (sequence()
- (c-call VOID "enable_interrupts")
- (dset pc frsr1)
- )
- ()
-)
-
-; Memory Access Instructions
-
-(dni ldw "LDW DstReg, SrcReg1, Imm"
- (LOAD-DELAY MEMORY-ACCESS USES-FRDR USES-FRSR1)
- "ldw $frdr,$frsr1,#$imm16"
- (+ MSYS_NO OPC_LDW IMM_YES frsr1 frdr imm16)
- (sequence((USI ea) (HI tmp))
- (set HI tmp (and imm16 #xffff))
- (set ea (and (add SI frsr1 (ext SI tmp)) #xfffffffc))
- (set frdr (mem SI ea))
- )
- ()
-)
-
-(dni stw "STW SrcReg2, SrcReg1, Imm"
- (MEMORY-ACCESS USES-FRSR1 USES-FRSR2)
- "stw $frsr2,$frsr1,#$imm16"
- (+ MSYS_NO OPC_STW IMM_YES frsr1 frsr2 imm16)
- (sequence((USI ea) (HI tmp))
- (set HI tmp (and imm16 #xffff))
- (set ea (and (add SI frsr1 (ext SI tmp)) #xfffffffc))
- (set (mem SI ea) frsr2)
- )
- ()
-)
-
-; Break Instruction
-
-(dni break "BREAK"
- ()
- "break"
- (+ MSYS_NO OPC_BREAK (f-imm 0) (f-uu24 0))
- (c-call VOID "do_break" pc)
- ()
-)
-
-; Cache Flush Instruction
-
-(dni iflush "IFLUSH"
- ((MACH ms1-003,ms2))
- "iflush"
- (+ MSYS_NO OPC_IFLUSH (f-imm 0) (f-uu24 0))
- (nop)
- ()
-)
-
-; MorphoSys Instructions
-
-(dni ldctxt "LDCTXT SRC1, SRC2, r/c, r/c#, context#"
- ((MACH ms1))
- "ldctxt $frsr1,$frsr2,#$rc,#$rcnum,#$contnum"
- (+ MSYS_YES MSOPC_LDCTXT (f-uu-2-25 0) frsr1 frsr2 rc rcnum (f-uu-3-11 0)
- contnum )
- (nop)
- ()
-)
-
-(dni ldfb "LDFB SRC1, byte#"
- ((MACH ms1))
- "ldfb $frsr1,$frsr2,#$imm16z"
- (+ MSYS_YES MSOPC_LDFB (f-uu-2-25 0) frsr1 frsr2 imm16z)
- (nop)
- ()
-)
-
-(dni stfb "STFB SRC1, SRC2, byte "
- ((MACH ms1))
- "stfb $frsr1,$frsr2,#$imm16z"
- (+ MSYS_YES MSOPC_STFB (f-uu-2-25 0) frsr1 frsr2 imm16z)
- (nop)
- ()
-)
-
-(dni fbcb "FBCB SRC1, RT/BR1/BR2/CS, B_all, B_r_c, r/c, CB/RB, cell, dup, ctx_disp"
- ((MACH ms1,ms1-003))
- "fbcb $frsr1,#$rbbc,#$ball,#$brc,#$rc1,#$cbrb,#$cell,#$dup,#$ctxdisp"
- (+ MSYS_YES MSOPC_FBCB rbbc frsr1 ball brc (f-uu-4-15 0) rc cbrb cell dup ctxdisp)
- (nop)
- ()
-)
-
-(dni mfbcb "MFBCB SRC1, RT/BR1/BR2/CS, SRC2, r/c, CB/RB, cell, dup, ctx_disp"
- ()
- "mfbcb $frsr1,#$rbbc,$frsr2,#$rc1,#$cbrb,#$cell,#$dup,#$ctxdisp"
- (+ MSYS_YES MSOPC_MFBCB rbbc frsr1 frsr2 (f-uu-4-15 0) rc1 cbrb cell dup ctxdisp)
- (nop)
- ()
-)
-
-(dni fbcci "FBCCI SRC1, RT/BR1/BR2/CS, B_all, B_r_c, FB_disp, cell, dup, ctx_disp"
- ()
- "fbcci $frsr1,#$rbbc,#$ball,#$brc,#$fbdisp,#$cell,#$dup,#$ctxdisp"
- (+ MSYS_YES MSOPC_FBCCI rbbc frsr1 ball brc fbdisp cell dup ctxdisp)
- (nop)
- ()
-)
-
-(dni fbrci "FBRCI SRC1, RT/BR1/BR2/CS, B_all, B_r_c, FB_disp, cell, dup, ctx_disp"
- ()
- "fbrci $frsr1,#$rbbc,#$ball,#$brc,#$fbdisp,#$cell,#$dup,#$ctxdisp"
- (+ MSYS_YES MSOPC_FBRCI rbbc frsr1 ball brc fbdisp cell dup ctxdisp)
- (nop)
- ()
-)
-
-(dni fbcri "FBCRI SRC1, RT/BR1/BR2/CS, B_all, B_r_c, FB_disp, cell, dup, ctx_disp"
- ()
- "fbcri $frsr1,#$rbbc,#$ball,#$brc,#$fbdisp,#$cell,#$dup,#$ctxdisp"
- (+ MSYS_YES MSOPC_FBCRI rbbc frsr1 ball brc fbdisp cell dup ctxdisp)
- (nop)
- ()
-)
-
-(dni fbrri "FBRRI SRC1, RT/BR1/BR2/CS, B_all, B_r_c, FB_disp, cell, dup, ctx_disp"
- ()
- "fbrri $frsr1,#$rbbc,#$ball,#$brc,#$fbdisp,#$cell,#$dup,#$ctxdisp"
- (+ MSYS_YES MSOPC_FBRRI rbbc frsr1 ball brc fbdisp cell dup ctxdisp)
- (nop)
- ()
-)
-
-(dni mfbcci "MFBCCI SRC1, RT/BR1/BR2/CS, SRC2, FB_disp, cell, dup, ctx_disp"
- ()
- "mfbcci $frsr1,#$rbbc,$frsr2,#$fbdisp,#$cell,#$dup,#$ctxdisp"
- (+ MSYS_YES MSOPC_MFBCCI rbbc frsr1 frsr2 fbdisp cell dup ctxdisp)
- (nop)
- ()
-)
-
-(dni mfbrci "MFBRCI SRC1, RT/BR1/BR2/CS, SRC2, FB_disp, cell, dup, ctx_disp"
- ()
- "mfbrci $frsr1,#$rbbc,$frsr2,#$fbdisp,#$cell,#$dup,#$ctxdisp"
- (+ MSYS_YES MSOPC_MFBRCI rbbc frsr1 frsr2 fbdisp cell dup ctxdisp)
- (nop)
- ()
-)
-
-(dni mfbcri "MFBCRI SRC1, RT/BR1/BR2/CS, SRC2, FB_disp, cell, dup, ctx_disp"
- ()
- "mfbcri $frsr1,#$rbbc,$frsr2,#$fbdisp,#$cell,#$dup,#$ctxdisp"
- (+ MSYS_YES MSOPC_MFBCRI rbbc frsr1 frsr2 fbdisp cell dup ctxdisp)
- (nop)
- ()
-)
-
-(dni mfbrri "MFBRRI SRC1, RT/BR1/BR2/CS, SRC2, FB_disp, cell, dup, ctx_disp"
- ()
- "mfbrri $frsr1,#$rbbc,$frsr2,#$fbdisp,#$cell,#$dup,#$ctxdisp"
- (+ MSYS_YES MSOPC_MFBRRI rbbc frsr1 frsr2 fbdisp cell dup ctxdisp)
- (nop)
- ()
-)
-
-(dni fbcbdr "FBCBDR SRC1, RT/BR1/BR2/CS, SRC2, B_all, B_r_c, r/c, CB/RB, cell, dup, ctx_disp"
- ()
- "fbcbdr $frsr1,#$rbbc,$frsr2,#$ball2,#$brc2,#$rc1,#$cbrb,#$cell,#$dup,#$ctxdisp"
- (+ MSYS_YES MSOPC_FBCBDR rbbc frsr1 frsr2 ball2 brc2 rc1 cbrb cell dup ctxdisp)
- (nop)
- ()
-)
-
-(dni rcfbcb "RCFBCB RT/BR1/BR2/CS, type, B_all, B_r_c, row#, r/c, CB/RB, cell, dup, ctx_disp"
- ()
- "rcfbcb #$rbbc,#$type,#$ball,#$brc,#$rownum,#$rc1,#$cbrb,#$cell,#$dup,#$ctxdisp"
- (+ MSYS_YES MSOPC_RCFBCB rbbc (f-uu-2-23 0) type ball brc (f-uu-1-15 0) rownum rc1 cbrb cell dup ctxdisp)
- (nop)
- ()
-)
-
-(dni mrcfbcb "MRCFBCB SRC2, RT/BR1/BR2/CS, type, row#, r/c, CB/RB, cell, dup, ctx_disp"
- ()
- "mrcfbcb $frsr2,#$rbbc,#$type,#$rownum,#$rc1,#$cbrb,#$cell,#$dup,#$ctxdisp"
- (+ MSYS_YES MSOPC_MRCFBCB rbbc (f-uu-2-23 0) type frsr2 (f-uu-1-15 0) rownum rc1 cbrb cell dup ctxdisp)
- (nop)
- ()
-)
-
-(dni cbcast "CBCAST mask, r/c, ctx_disp "
- ()
- "cbcast #$mask,#$rc2,#$ctxdisp"
- (+ MSYS_YES MSOPC_CBCAST mask (f-uu-3-9 0) rc2 ctxdisp)
- (nop)
- ()
-)
-
-(dni dupcbcast "DUPCBCAST mask, cell, r/c, ctx_disp "
- ()
- "dupcbcast #$mask,#$cell,#$rc2,#$ctxdisp"
- (+ MSYS_YES MSOPC_DUPCBCAST mask cell rc2 ctxdisp)
- (nop)
- ()
-)
-
-(dni wfbi "WFBI Bank_address, row#, cell, dup, ctx_disp "
- ()
- "wfbi #$bankaddr,#$rownum1,#$cell,#$dup,#$ctxdisp"
- (+ MSYS_YES MSOPC_WFBI bankaddr rownum1 cell dup ctxdisp)
- (nop)
- ()
-)
-
-;(dni wfb "WFB SRC1, SRC2, FB_disp, row#, ctx_disp"
-; ()
-; "wfb $frsr1,$frsr2,#$fbdisp,#$rownum,#$ctxdisp"
-; (+ MSYS_YES MSOPC_WFB (f-uu-2-25 0) frsr1 frsr2 fbdisp rownum (f-uu-1-6 0) ctxdisp)
-; (nop)
-; ()
-;)
-
-(dni wfb "WFB, DRC1,SRC2,FB_disp,row#,ctx_disp"
- ()
- "wfb $frsr1,$frsr2,#$fbdisp,#$rownum2,#$ctxdisp"
- (+ MSYS_YES MSOPC_WFB (f-uu-2-25 0) frsr1 frsr2 fbdisp rownum2 (f-uu-1-6 0) ctxdisp)
- (nop)
- ()
-)
-
-
-(dni rcrisc "RCRISC DEST, RT/BR1/BR2/CS, SRC1, column#, r/c, CB/RB, cell, dup, ctx_disp"
- ()
- "rcrisc $frdrrr,#$rbbc,$frsr1,#$colnum,#$rc1,#$cbrb,#$cell,#$dup,#$ctxdisp"
- (+ MSYS_YES MSOPC_RCRISC rbbc frsr1 (f-uu-1-19 0) colnum frdrrr rc1 cbrb cell dup ctxdisp)
- (nop)
- ()
-)
-
-(dni fbcbinc "FBCBINC SRC1, RT/BR1/BR2/CS, Incr_amount, r/c, CB/RB, cell, dup, ctx_disp "
- ()
- "fbcbinc $frsr1,#$rbbc,#$incamt,#$rc1,#$cbrb,#$cell,#$dup,#$ctxdisp"
- (+ MSYS_YES MSOPC_FBCBINC rbbc frsr1 incamt rc1 cbrb cell dup ctxdisp)
- (nop)
- ()
-)
-
-(dni rcxmode "RCXMODE SRC2, rd, wr, xmode, mask, FB_disp, row#, r/c, ctx_disp"
- ()
- "rcxmode $frsr2,#$rda,#$wr,#$xmode,#$mask1,#$fbdisp,#$rownum2,#$rc2,#$ctxdisp"
- (+ MSYS_YES MSOPC_RCXMODE rda wr xmode mask1 frsr2 fbdisp rownum2 rc2 ctxdisp)
- (nop)
- ()
-)
-
-(dni interleaver "INTLVR ireg, mode, ireg, i/d, size"
- ()
- "intlvr $frsr1,#$mode,$frsr2,#$id,#$size"
- (+ MSYS_YES MSOPC_INTLVR mode frsr1 frsr2 (f-uu-1-15 0) id size)
- (nop)
- ()
-)
-
-;; Issue 66262: The documenatation gives the wrong order for
-;; the arguments to the WFBINC instruction.
-(dni wfbinc "WFBINC type, ccb/rcb, incr, all, c/r, length, rca_row, word, dup, ctxt_disp"
- ((MACH ms1-003,ms2))
- "wfbinc #$rda,#$wr,#$fbincr,#$ball,#$colnum,#$length,#$rownum1,#$rownum2,#$dup,#$ctxdisp"
- (+ MSYS_YES MSOPC_WFBINC rda wr fbincr ball colnum length rownum1 rownum2 dup ctxdisp)
- (nop)
- ()
-)
-
-(dni mwfbinc "MWFBINC mreg, type, ccb/rcb, incr, length, rca_row, word, dup, ctxt_disp"
- ((MACH ms1-003,ms2))
- "mwfbinc $frsr2,#$rda,#$wr,#$fbincr,#$length,#$rownum1,#$rownum2,#$dup,#$ctxdisp"
- (+ MSYS_YES MSOPC_MWFBINC rda wr fbincr frsr2 length rownum1 rownum2 dup ctxdisp)
- (nop)
- ()
-)
-
-(dni wfbincr "WFBINCR ireg, type, ccb/rcb, all, c/r, length, rca_row, word, dup, ctxt_disp"
- ((MACH ms1-003,ms2))
- "wfbincr $frsr1,#$rda,#$wr,#$ball,#$colnum,#$length,#$rownum1,#$rownum2,#$dup,#$ctxdisp"
- (+ MSYS_YES MSOPC_WFBINCR rda wr frsr1 ball colnum length rownum1 rownum2 dup ctxdisp)
- (nop)
- ()
-)
-
-(dni mwfbincr "MWFBINCR ireg, mreg, type, ccb/rcb, length, rca_row, word, dup, ctxt_disp"
- ((MACH ms1-003,ms2))
- "mwfbincr $frsr1,$frsr2,#$rda,#$wr,#$length,#$rownum1,#$rownum2,#$dup,#$ctxdisp"
- (+ MSYS_YES MSOPC_MWFBINCR rda wr frsr1 frsr2 length rownum1 rownum2 dup ctxdisp)
- (nop)
- ()
-)
-
-(dni fbcbincs "FBCBINCS perm, all, c/r, cbs, incr, ccb/rcb, cdb/rdb, word, dup, ctxt_disp"
- ((MACH ms1-003,ms2))
- "fbcbincs #$perm,#$a23,#$cr,#$cbs,#$incr,#$ccb,#$cdb,#$rownum2,#$dup,#$ctxdisp"
- (+ MSYS_YES MSOPC_FBCBINCS perm a23 cr cbs incr ccb cdb rownum2 dup ctxdisp)
- (nop)
- ()
-)
-
-(dni mfbcbincs "MFBCBINCS ireg, perm, cbs, incr, ccb/rcb, cdb/rdb, word, dup, ctxt_disp"
- ((MACH ms1-003,ms2))
- "mfbcbincs $frsr1,#$perm,#$cbs,#$incr,#$ccb,#$cdb,#$rownum2,#$dup,#$ctxdisp"
- (+ MSYS_YES MSOPC_MFBCBINCS perm frsr1 cbs incr ccb cdb rownum2 dup ctxdisp)
- (nop)
- ()
-)
-
-(dni fbcbincrs "FBCBINCRS ireg, perm, all, c/r, cbs, ccb/rcb, cdb/rdb, word, dup, ctxt_disp"
- ((MACH ms1-003,ms2))
- "fbcbincrs $frsr1,#$perm,#$ball,#$colnum,#$cbx,#$ccb,#$cdb,#$rownum2,#$dup,#$ctxdisp"
- (+ MSYS_YES MSOPC_FBCBINCRS perm frsr1 ball colnum (f-uu-1-15 0) cbx ccb cdb rownum2 dup ctxdisp)
- (nop)
- ()
-)
-
-(dni mfbcbincrs "MFBCBINCRS ireg, mreg, perm, cbs, ccb/rcb, cdb/rdb, word, dup, ctxt_disp"
- ((MACH ms1-003,ms2))
- "mfbcbincrs $frsr1,$frsr2,#$perm,#$cbx,#$ccb,#$cdb,#$rownum2,#$dup,#$ctxdisp"
- (+ MSYS_YES MSOPC_MFBCBINCRS perm frsr1 frsr2 (f-uu-1-15 0) cbx ccb cdb rownum2 dup ctxdisp)
- (nop)
- ()
-)
-
-; MS2 instructions
-(dni loop "LOOP SrcReg1, label"
- ((MACH ms2) DELAY-SLOT USES-FRSR1)
- "loop $frsr1,$loopsize"
- (+ MSYS_NO OPC_LOOP IMM_NO frsr1 (f-uu4a 0) (f-uu8 0) loopsize)
- (nop) ;; to be filled in
- ()
-)
-
-(dni loopi "LOOPI niter, label"
- ((MACH ms2) DELAY-SLOT)
- "loopi #$imm16l,$loopsize"
- (+ MSYS_NO OPC_LOOP IMM_YES imm16l loopsize)
- (nop) ;; to be filled in
- ()
-)
-
-(dni dfbc "dfbc cb1sel,cb2sel,cb1inc,cb2inc,dr/c,cr/c,ctxdisp"
- ((MACH ms2))
- "dfbc #$cb1sel,#$cb2sel,#$cb1incr,#$cb2incr,#$rc3,#$rc2,#$ctxdisp"
- (+ MSYS_YES MSOPC_LDCTXT cb1sel cb2sel cb1incr cb2incr rc3 rc2 ctxdisp)
- (nop)
- ()
-)
-
-(dni dwfb "dwfb cb1sel,cb2sel,cb1inc,cb2inc,cr/c,ctxdisp"
- ((MACH ms2))
- "dwfb #$cb1sel,#$cb2sel,#$cb1incr,#$cb2incr,#$rc2,#$ctxdisp"
- (+ MSYS_YES MSOPC_LDFB cb1sel cb2sel cb1incr cb2incr (f-uu1 0) rc2 ctxdisp)
- (nop)
- ()
-)
-
-(dni fbwfb "fbwfb cb1sel,cb2sel,cb1inc,cb2inc,r0/1,cr/c,ctxdisp"
- ((MACH ms2))
- "fbwfb #$cb1sel,#$cb2sel,#$cb1incr,#$cb2incr,#$rc3,#$rc2,#$ctxdisp"
- (+ MSYS_YES MSOPC_STFB cb1sel cb2sel cb1incr cb2incr rc3 rc2 ctxdisp)
- (nop)
- ()
-)
-
-(dni dfbr "dfbr cb1sel,cb2sel,reg,W/O1,W/O2,mode,cr/c,ctxdisp"
- ((MACH ms2) USES-FRSR2)
- "dfbr #$cb1sel,#$cb2sel,$frsr2,#$length,#$rownum1,#$rownum2,#$rc2,#$ctxdisp"
- (+ MSYS_YES MSOPC_FBCB cb1sel cb2sel frsr2 length rownum1 rownum2 rc2 ctxdisp)
- (nop)
- ()
-)
+++ /dev/null
-/* Morpho Technologies mRISC opcode support, for GNU Binutils. -*- C -*-
- Copyright 2001 Free Software Foundation, Inc.
-
- Contributed by Red Hat Inc; developed under contract from
- Morpho Technologies.
-
- This file is part of the GNU Binutils.
-
- This program 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 of the License, or
- (at your option) any later version.
-
- This program 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 this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
-
-*/
-
-/*
- Each section is delimited with start and end markers.
-
- <arch>-opc.h additions use: "-- opc.h"
- <arch>-opc.c additions use: "-- opc.c"
- <arch>-asm.c additions use: "-- asm.c"
- <arch>-dis.c additions use: "-- dis.c"
- <arch>-ibd.h additions use: "-- ibd.h"
-*/
-\f
-/* -- opc.h */
-
-/* Check applicability of instructions against machines. */
-#define CGEN_VALIDATE_INSN_SUPPORTED
-
-/* Allows reason codes to be output when assembler errors occur. */
-#define CGEN_VERBOSE_ASSEMBLER_ERRORS
-
-/* Override disassembly hashing - there are variable bits in the top
- byte of these instructions. */
-#define CGEN_DIS_HASH_SIZE 8
-#define CGEN_DIS_HASH(buf, value) (((* (unsigned char *) (buf)) >> 5) % CGEN_DIS_HASH_SIZE)
-
-#define CGEN_ASM_HASH_SIZE 127
-#define CGEN_ASM_HASH(insn) ms1_asm_hash (insn)
-
-extern unsigned int ms1_asm_hash (const char *);
-
-extern int ms1_cgen_insn_supported (CGEN_CPU_DESC, const CGEN_INSN *);
-
-\f
-/* -- opc.c */
-#include "safe-ctype.h"
-
-/* Special check to ensure that instruction exists for given machine. */
-
-int
-ms1_cgen_insn_supported (CGEN_CPU_DESC cd,
- const CGEN_INSN *insn)
-{
- int machs = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_MACH);
-
- /* No mach attribute? Assume it's supported for all machs. */
- if (machs == 0)
- return 1;
-
- return ((machs & cd->machs) != 0);
-}
-
-/* A better hash function for instruction mnemonics. */
-
-unsigned int
-ms1_asm_hash (const char* insn)
-{
- unsigned int hash;
- const char* m = insn;
-
- for (hash = 0; *m && ! ISSPACE (*m); m++)
- hash = (hash * 23) ^ (0x1F & TOLOWER (*m));
-
- /* printf ("%s %d\n", insn, (hash % CGEN_ASM_HASH_SIZE)); */
-
- return hash % CGEN_ASM_HASH_SIZE;
-}
-
-\f
-/* -- asm.c */
-/* Range checking for signed numbers. Returns 0 if acceptable
- and 1 if the value is out of bounds for a signed quantity. */
-
-static int
-signed_out_of_bounds (long val)
-{
- if ((val < -32768) || (val > 32767))
- return 1;
- return 0;
-}
-
-static const char *
-parse_loopsize (CGEN_CPU_DESC cd,
- const char **strp,
- int opindex,
- void *arg)
-{
- signed long * valuep = (signed long *) arg;
- const char *errmsg;
- bfd_reloc_code_real_type code = BFD_RELOC_NONE;
- enum cgen_parse_operand_result result_type;
- bfd_vma value;
-
- /* Is it a control transfer instructions? */
- if (opindex == (CGEN_OPERAND_TYPE) MS1_OPERAND_LOOPSIZE)
- {
- code = BFD_RELOC_MS1_PCINSN8;
- errmsg = cgen_parse_address (cd, strp, opindex, code,
- & result_type, & value);
- *valuep = value;
- return errmsg;
- }
-
- abort ();
-}
-
-static const char *
-parse_imm16 (CGEN_CPU_DESC cd,
- const char **strp,
- int opindex,
- void *arg)
-{
- signed long * valuep = (signed long *) arg;
- const char *errmsg;
- enum cgen_parse_operand_result result_type;
- bfd_reloc_code_real_type code = BFD_RELOC_NONE;
- bfd_vma value;
-
- /* Is it a control transfer instructions? */
- if (opindex == (CGEN_OPERAND_TYPE) MS1_OPERAND_IMM16O)
- {
- code = BFD_RELOC_16_PCREL;
- errmsg = cgen_parse_address (cd, strp, opindex, code,
- & result_type, & value);
- if (errmsg == NULL)
- {
- if (signed_out_of_bounds (value))
- errmsg = _("Operand out of range. Must be between -32768 and 32767.");
- }
- *valuep = value;
- return errmsg;
- }
-
- /* If it's not a control transfer instruction, then
- we have to check for %OP relocating operators. */
- if (opindex == (CGEN_OPERAND_TYPE) MS1_OPERAND_IMM16L)
- ;
- else if (strncmp (*strp, "%hi16", 5) == 0)
- {
- *strp += 5;
- code = BFD_RELOC_HI16;
- }
- else if (strncmp (*strp, "%lo16", 5) == 0)
- {
- *strp += 5;
- code = BFD_RELOC_LO16;
- }
-
- /* If we found a %OP relocating operator, then parse it as an address.
- If not, we need to parse it as an integer, either signed or unsigned
- depending on which operand type we have. */
- if (code != BFD_RELOC_NONE)
- {
- /* %OP relocating operator found. */
- errmsg = cgen_parse_address (cd, strp, opindex, code,
- & result_type, & value);
- if (errmsg == NULL)
- {
- switch (result_type)
- {
- case (CGEN_PARSE_OPERAND_RESULT_NUMBER):
- if (code == BFD_RELOC_HI16)
- value = (value >> 16) & 0xFFFF;
- else if (code == BFD_RELOC_LO16)
- value = value & 0xFFFF;
- else
- errmsg = _("Biiiig Trouble in parse_imm16!");
- break;
-
- case (CGEN_PARSE_OPERAND_RESULT_QUEUED):
- /* No special processing for this case. */
- break;
-
- default:
- errmsg = _("%operator operand is not a symbol");
- break;
- }
- }
- *valuep = value;
- }
- else
- {
- /* Parse hex values like 0xffff as unsigned, and sign extend
- them manually. */
- int parse_signed = (opindex == (CGEN_OPERAND_TYPE)MS1_OPERAND_IMM16);
-
- if ((*strp)[0] == '0'
- && ((*strp)[1] == 'x' || (*strp)[1] == 'X'))
- parse_signed = 0;
-
- /* No relocating operator. Parse as an number. */
- if (parse_signed)
- {
- /* Parse as as signed integer. */
-
- errmsg = cgen_parse_signed_integer (cd, strp, opindex, valuep);
-
- if (errmsg == NULL)
- {
-#if 0
- /* Manual range checking is needed for the signed case. */
- if (*valuep & 0x8000)
- value = 0xffff0000 | *valuep;
- else
- value = *valuep;
-
- if (signed_out_of_bounds (value))
- errmsg = _("Operand out of range. Must be between -32768 and 32767.");
- /* Truncate to 16 bits. This is necessary
- because cgen will have sign extended *valuep. */
- *valuep &= 0xFFFF;
-#endif
- }
- }
- else
- {
- /* MS1_OPERAND_IMM16Z. Parse as an unsigned integer. */
- errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, (unsigned long *) valuep);
-
- if (opindex == (CGEN_OPERAND_TYPE) MS1_OPERAND_IMM16
- && *valuep >= 0x8000
- && *valuep <= 0xffff)
- *valuep -= 0x10000;
- }
- }
-
- return errmsg;
-}
-
-
-static const char *
-parse_dup (CGEN_CPU_DESC cd,
- const char **strp,
- int opindex,
- unsigned long *valuep)
-{
- const char *errmsg = NULL;
-
- if (strncmp (*strp, "dup", 3) == 0 || strncmp (*strp, "DUP", 3) == 0)
- {
- *strp += 3;
- *valuep = 1;
- }
- else if (strncmp (*strp, "xx", 2) == 0 || strncmp (*strp, "XX", 2) == 0)
- {
- *strp += 2;
- *valuep = 0;
- }
- else
- errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
-
- return errmsg;
-}
-
-
-static const char *
-parse_ball (CGEN_CPU_DESC cd,
- const char **strp,
- int opindex,
- unsigned long *valuep)
-{
- const char *errmsg = NULL;
-
- if (strncmp (*strp, "all", 3) == 0 || strncmp (*strp, "ALL", 3) == 0)
- {
- *strp += 3;
- *valuep = 1;
- }
- else if (strncmp (*strp, "one", 3) == 0 || strncmp (*strp, "ONE", 3) == 0)
- {
- *strp += 3;
- *valuep = 0;
- }
- else
- errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
-
- return errmsg;
-}
-
-static const char *
-parse_xmode (CGEN_CPU_DESC cd,
- const char **strp,
- int opindex,
- unsigned long *valuep)
-{
- const char *errmsg = NULL;
-
- if (strncmp (*strp, "pm", 2) == 0 || strncmp (*strp, "PM", 2) == 0)
- {
- *strp += 2;
- *valuep = 1;
- }
- else if (strncmp (*strp, "xm", 2) == 0 || strncmp (*strp, "XM", 2) == 0)
- {
- *strp += 2;
- *valuep = 0;
- }
- else
- errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
-
- return errmsg;
-}
-
-static const char *
-parse_rc (CGEN_CPU_DESC cd,
- const char **strp,
- int opindex,
- unsigned long *valuep)
-{
- const char *errmsg = NULL;
-
- if (strncmp (*strp, "r", 1) == 0 || strncmp (*strp, "R", 1) == 0)
- {
- *strp += 1;
- *valuep = 1;
- }
- else if (strncmp (*strp, "c", 1) == 0 || strncmp (*strp, "C", 1) == 0)
- {
- *strp += 1;
- *valuep = 0;
- }
- else
- errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
-
- return errmsg;
-}
-
-static const char *
-parse_cbrb (CGEN_CPU_DESC cd,
- const char **strp,
- int opindex,
- unsigned long *valuep)
-{
- const char *errmsg = NULL;
-
- if (strncmp (*strp, "rb", 2) == 0 || strncmp (*strp, "RB", 2) == 0)
- {
- *strp += 2;
- *valuep = 1;
- }
- else if (strncmp (*strp, "cb", 2) == 0 || strncmp (*strp, "CB", 2) == 0)
- {
- *strp += 2;
- *valuep = 0;
- }
- else
- errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
-
- return errmsg;
-}
-
-static const char *
-parse_rbbc (CGEN_CPU_DESC cd,
- const char **strp,
- int opindex,
- unsigned long *valuep)
-{
- const char *errmsg = NULL;
-
- if (strncmp (*strp, "rt", 2) == 0 || strncmp (*strp, "RT", 2) == 0)
- {
- *strp += 2;
- *valuep = 0;
- }
- else if (strncmp (*strp, "br1", 3) == 0 || strncmp (*strp, "BR1", 3) == 0)
- {
- *strp += 3;
- *valuep = 1;
- }
- else if (strncmp (*strp, "br2", 3) == 0 || strncmp (*strp, "BR2", 3) == 0)
- {
- *strp += 3;
- *valuep = 2;
- }
- else if (strncmp (*strp, "cs", 2) == 0 || strncmp (*strp, "CS", 2) == 0)
- {
- *strp += 2;
- *valuep = 3;
- }
- else
- errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
-
- return errmsg;
-}
-
-static const char *
-parse_type (CGEN_CPU_DESC cd,
- const char **strp,
- int opindex,
- unsigned long *valuep)
-{
- const char *errmsg = NULL;
-
- if (strncmp (*strp, "odd", 3) == 0 || strncmp (*strp, "ODD", 3) == 0)
- {
- *strp += 3;
- *valuep = 0;
- }
- else if (strncmp (*strp, "even", 4) == 0 || strncmp (*strp, "EVEN", 4) == 0)
- {
- *strp += 4;
- *valuep = 1;
- }
- else if (strncmp (*strp, "oe", 2) == 0 || strncmp (*strp, "OE", 2) == 0)
- {
- *strp += 2;
- *valuep = 2;
- }
- else
- errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
-
- if ((errmsg == NULL) && (*valuep == 3))
- errmsg = _("invalid operand. type may have values 0,1,2 only.");
-
- return errmsg;
-}
-
-/* -- dis.c */
-static void print_dollarhex (CGEN_CPU_DESC, PTR, long, unsigned, bfd_vma, int);
-static void print_pcrel (CGEN_CPU_DESC, PTR, long, unsigned, bfd_vma, int);
-
-static void
-print_dollarhex (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
- void * dis_info,
- long value,
- unsigned int attrs ATTRIBUTE_UNUSED,
- bfd_vma pc ATTRIBUTE_UNUSED,
- int length ATTRIBUTE_UNUSED)
-{
- disassemble_info *info = (disassemble_info *) dis_info;
-
- info->fprintf_func (info->stream, "$%lx", value);
-
- if (0)
- print_normal (cd, dis_info, value, attrs, pc, length);
-}
-
-static void
-print_pcrel (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
- void * dis_info,
- long value,
- unsigned int attrs ATTRIBUTE_UNUSED,
- bfd_vma pc ATTRIBUTE_UNUSED,
- int length ATTRIBUTE_UNUSED)
-{
- print_address (cd, dis_info, value + pc, attrs, pc, length);
-}
-
-/* -- */
-
-
-
-
-
--- /dev/null
+; Morpho Technologies mRISC CPU description. -*- Scheme -*-
+; Copyright 2001 Free Software Foundation, Inc.
+;
+; Contributed by Red Hat Inc; developed under contract from
+; Morpho Technologies.
+;
+; This file is part of the GNU Binutils.
+;
+; This program 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 of the License, or
+; (at your option) any later version.
+;
+; This program 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 this program; if not, write to the Free Software
+; Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+
+(include "simplify.inc")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Define The Architecture, Attributes, ISA, CPU, Machine, And Model. ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+; define-arch must appear first
+(define-arch
+ (name ms1) ; name of cpu family
+ (comment "Morpho Technologies mRISC family")
+ (default-alignment aligned)
+ (insn-lsb0? #t)
+ (machs ms1 ms1-003 ms2)
+ (isas ms1)
+)
+
+; Instruction set parameters.
+
+(define-isa
+ (name ms1)
+ (comment "Morpho Technologies mrisc ISA")
+ (default-insn-word-bitsize 32)
+ (default-insn-bitsize 32)
+ (base-insn-bitsize 32)
+ (parallel-insns 2)
+)
+\f
+; Cpu family definitions.
+
+
+(define-cpu
+ ; cpu names must be distinct from the architecture name and machine names.
+ (name ms1bf)
+ (comment "Morpho Technologies mRISC family")
+ (endian big)
+ (word-bitsize 32)
+)
+
+(define-cpu
+ ; cpu names must be distinct from the architecture name and machine names.
+ (name ms1-003bf)
+ (comment "Morpho Technologies mRISC family")
+ (endian big)
+ (word-bitsize 32)
+)
+
+(define-cpu
+ ; cpu names must be distinct from the architecture name and machine names.
+ (name ms2bf)
+ (comment "Morpho Technologies mRISC family")
+ (endian big)
+ (word-bitsize 32)
+)
+
+(define-mach
+ (name ms1)
+ (comment "Morpho Technologies mrisc")
+ (cpu ms1bf)
+ (isas ms1)
+)
+
+(define-mach
+ (name ms1-003)
+ (comment "Morpho Technologies mrisc")
+ (cpu ms1-003bf)
+ (isas ms1)
+)
+
+(define-mach
+ (name ms2)
+ (comment "Morpho Technologies ms2")
+ (cpu ms2bf)
+ (isas ms1)
+)
+
+\f
+; Model descriptions.
+; Can probably take the u-exec out. We'll see.
+(define-model
+ (name ms1)
+ (comment "Morpho Technologies mrisc")
+ (mach ms1)
+ (unit u-exec "Execution Unit" ()
+ 1 1 ; issue done
+ () ; state
+ () ; inputs
+ () ; outputs
+ () ; profile action (default)
+ )
+)
+
+(define-model
+ (name ms1-003)
+ (comment "Morpho Technologies mrisc")
+ (mach ms1-003)
+ (unit u-exec "Execution Unit" ()
+ 1 1 ; issue done
+ () ; state
+ () ; inputs
+ () ; outputs
+ () ; profile action (default)
+ )
+)
+
+(define-model
+ (name ms2)
+ (comment "Morpho Technologies ms2")
+ (mach ms2)
+ (unit u-exec "Execution Unit" ()
+ 1 1 ; issue done
+ () ; state
+ () ; inputs
+ () ; outputs
+ () ; profile action (default)
+ )
+)
+
+; FIXME: It might simplify things to separate the execute process from the
+; one that updates the PC.
+\f
+
+;;;;;;;;;;;;;;;;;;;;;;;;
+;; Instruction Fields ;;
+;;;;;;;;;;;;;;;;;;;;;;;;
+
+; Attributes:
+; PCREL-ADDR: pc relative value (for reloc and disassembly purposes)
+; ABS-ADDR: absolute address (for reloc and disassembly purposes?)
+; RESERVED: bits are not used to decode insn, must be all 0
+; RELOC: there is a relocation associated with this field (experiment)
+;
+; f-msys: Identify a a morphosys insns. 1 if msys, 0 if not.
+; f-opc: 6 bit opcode for non-morphosys instructions.
+; f-msopc: 6 bit opcode for morphosys instructions.
+; f-imm: flag to indicate use of an immediate operand. 1 if yes, 0 if no.
+; f-sr1: source resgister 1. (also used for MSYS insns)
+; f-sr2: source register 2. (also used for MSYS insns)
+; f-dr: destination register when located in bits 19:16.
+; f-drrr: destination register when located in bits 15:12. (also for MSYS insns)
+; f-imm16: 16 bit immediate value when not an offset.
+; f-imm16a: 16 bit immediate value when it's a pc-rel offset.
+; f-uu4a: unused 4 bit field.
+; f-uu4b: second unsed 4 bit field.
+; f-uu1: unused 1 bit field
+; f-uu12: unused 12 bit field.
+; f-uu16: unused 16 bit field.
+; f-uu24: unused 24 bit field.
+
+(dnf f-msys "morphosys insn flag" () 31 1)
+(dnf f-opc "opcode field" () 30 6)
+(dnf f-imm "immedate flag" () 24 1)
+(dnf f-uu24 "unused 24 bits" () 23 24)
+(dnf f-sr1 "sr1 register field" (ABS-ADDR) 23 4)
+(dnf f-sr2 "sr2 register field" (ABS-ADDR) 19 4)
+(dnf f-dr "dr register field" (ABS-ADDR) 19 4)
+(dnf f-drrr "drrr register field" (ABS-ADDR) 15 4)
+(dnf f-imm16u "unsigned 16 bit immediate" () 15 16)
+(df f-imm16s "signed 16 bit immediate" () 15 16 INT ((value pc) (add HI value 0)) ((value pc) (add HI value 0)))
+(dnf f-imm16a "pc-rel offset" (PCREL-ADDR) 15 16)
+(dnf f-uu4a "unused 4 bit field" () 19 4)
+(dnf f-uu4b "unused 4 bit field" () 23 4)
+(dnf f-uu12 "unused 12 bit field" () 11 12)
+(dnf f-uu8 "unused 8 bit field" () 15 8)
+(dnf f-uu16 "unused 16 bit field" () 15 16)
+(dnf f-uu1 "unused 1 bit field" () 7 1)
+
+; The following ifields are used exclusively for the MorphoSys instructions.
+; In a few cases, a bit field is used for something in addition to what its
+; name suggests. For the most part, the names are meaningful though.
+
+(dnf f-msopc "opcode field" () 30 5)
+(dnf f-uu-26-25 "unused 26 bits" () 25 26)
+(dnf f-mask "mask" () 25 16)
+(dnf f-bankaddr "bank address" () 25 13)
+(dnf f-rda "rda" () 25 1)
+(dnf f-uu-2-25 "unused bits 25 & 24" () 25 2)
+(dnf f-rbbc "Omega network configuration" () 25 2)
+(dnf f-perm "perm" () 25 2)
+(dnf f-mode "mode" () 25 2)
+(dnf f-uu-1-24 "testing" () 24 1)
+(dnf f-wr "wr" () 24 1)
+(dnf f-fbincr "fb incr" () 23 4)
+(dnf f-uu-2-23 "unused bits 23 and 22" () 23 2)
+(dnf f-xmode "xmode" () 23 1)
+(dnf f-a23 "a23" () 23 1)
+(dnf f-mask1 "mask1" () 22 3)
+(dnf f-cr "cr" () 22 3)
+(dnf f-type "type" () 21 2)
+(dnf f-incamt "increment amount" () 19 8)
+(dnf f-cbs "cbs" () 19 2)
+(dnf f-uu-1-19 "unused bit 19" () 19 1)
+(dnf f-ball "b_all" () 19 1)
+(dnf f-colnum "column number" () 18 3)
+(dnf f-brc "b_r_c" () 18 3)
+(dnf f-incr "incr" () 17 6)
+(dnf f-fbdisp "frame buffer displacement" () 15 6)
+(dnf f-uu-4-15 "unused bits 15,14,13,12" () 15 4)
+(dnf f-length "length" () 15 3)
+(dnf f-uu-1-15 "unused bit 15" () 15 1)
+(dnf f-rc "row/column context" () 15 1)
+(dnf f-rcnum "starting cell of cntxt mem." () 14 3)
+(dnf f-rownum "row number" () 14 3)
+(dnf f-cbx "cbx" () 14 3)
+(dnf f-id "id" () 14 1)
+(dnf f-size "size" () 13 14)
+(dnf f-rownum1 "row number" () 12 3)
+(dnf f-uu-3-11 "unused 3 bits (11-9)" () 11 3)
+(dnf f-rc1 "row/column context" () 11 1)
+(dnf f-ccb "ccb" () 11 1)
+(dnf f-cbrb "data-bus orientation" () 10 1)
+(dnf f-cdb "cdb" () 10 1)
+(dnf f-rownum2 "row number" () 9 3)
+(dnf f-cell "cell" () 9 3)
+(dnf f-uu-3-9 "unused 3 bits (9-7)" () 9 3)
+(dnf f-contnum "context number" () 8 9)
+(dnf f-uu-1-6 "unused bit 6" () 6 1)
+(dnf f-dup "dup" () 6 1)
+(dnf f-rc2 "rc2" () 6 1)
+(dnf f-ctxdisp "context displacement" () 5 6)
+
+; additional fields in ms2
+(dnf f-imm16l "loop count" () 23 16)
+(df f-loopo "loop offset" () 7 8 UINT
+ ((value pc) (srl SI value 2))
+ ((value pc) (add SI (sll value 2) 8))
+ )
+(dnf f-cb1sel "cb1 select" () 25 3)
+(dnf f-cb2sel "cb2 select" () 22 3)
+(dnf f-cb1incr "cb1 increment" (SIGNED) 19 6)
+(dnf f-cb2incr "cb2 increment" (SIGNED) 13 6)
+(dnf f-rc3 "row/colum context" () 7 1)
+
+; The following is just for a test
+(dnf f-msysfrsr2 "sr2 for msys" () 19 4)
+(dnf f-brc2 "b_r_c2" () 14 3)
+(dnf f-ball2 "b_all2" () 15 1)
+
+\f
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Enumerations Of Instruction Fields ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+; insn-msys: bit 31. 1 for Morphosys Insns, 0 if not.
+(define-normal-insn-enum insn-msys "msys enums" () MSYS_ f-msys
+ (NO YES)
+)
+
+; insn-opc: bits 30 through 25 . Non-MorphoSys Instructions
+; Note - the documentation is wrong for the encoding of the DBNZ
+; instruction. It is actually 011110. See Issue 67699.
+(define-normal-insn-enum insn-opc "opc enums" () OPC_ f-opc
+ (ADD ADDU SUB SUBU MUL - - -
+ AND OR XOR NAND NOR XNOR LDUI -
+ LSL LSR ASR - - - - -
+ BRLT BRLE BREQ JMP JAL BRNEQ DBNZ LOOP
+ LDW STW - - - - - -
+ - - - - - - - -
+ EI DI SI RETI BREAK IFLUSH - -
+ )
+)
+
+; insn-msopc: bits 30 through 26 . MorphoSys Instructions
+(define-normal-insn-enum insn-msopc "msopc enums" () MSOPC_ f-msopc
+ (LDCTXT LDFB STFB FBCB MFBCB FBCCI FBRCI FBCRI
+ FBRRI MFBCCI MFBRCI MFBCRI MFBRRI FBCBDR RCFBCB MRCFBCB
+ CBCAST DUPCBCAST WFBI WFB RCRISC FBCBINC RCXMODE INTLVR
+ WFBINC MWFBINC WFBINCR MWFBINCR FBCBINCS MFBCBINCS FBCBINCRS MFBCBINCRS
+ - - - - - - - -
+ )
+)
+
+; insn-imm: bit 24. Immediate operand indicator.
+(define-normal-insn-enum insn-imm "imm enums" () IMM_ f-imm
+ ; This bit specifies whether and immediate operand will be present.
+ ; It's 1 if there is, 0 if there is not.
+ (NO YES)
+)
+;;;;;;;;;;;;;;;;
+;; Attributes ;;
+;;;;;;;;;;;;;;;;
+
+; Might not need this. Keep if for the sim just in case.
+;(define-attr
+; (for insn)
+; (type boolean)
+; (name EXT-SKIP-INSN)
+; (comment "instruction is a PAGE, LOADL or LOADH instruction")
+;)
+
+(define-attr
+ (for insn)
+ (type boolean)
+ (name LOAD-DELAY)
+ (comment "insn has a load delay")
+)
+
+(define-attr
+ (for insn)
+ (type boolean)
+ (name MEMORY-ACCESS)
+ (comment "insn performs a memory access")
+)
+
+(define-attr
+ (for insn)
+ (type boolean)
+ (name AL-INSN)
+ (comment "insn is an arithmetic or logic insn.")
+)
+
+(define-attr
+ (for insn)
+ (type boolean)
+ (name IO-INSN)
+ (comment "insn performs an I/O operation")
+)
+
+(define-attr
+ (for insn)
+ (type boolean)
+ (name BR-INSN)
+ (comment "insn performs an I/O operation")
+)
+
+(define-attr
+ (for insn)
+ (type boolean)
+ (name JAL-HAZARD)
+ (comment "insn has jal-like hazard")
+)
+
+(define-pmacro (define-reg-use-attr regfield)
+ (define-attr
+ (for insn)
+ (type boolean)
+ (name (.sym "USES-" (.upcase regfield)))
+ (comment ("insn accesses register operand " regfield))))
+
+(define-reg-use-attr "frdr")
+(define-reg-use-attr "frdrrr")
+(define-reg-use-attr "frsr1")
+(define-reg-use-attr "frsr2")
+
+
+; Might not need this. Keep it for the sim just in case.
+(define-attr
+ (for insn)
+ (type boolean)
+ (name SKIPA)
+ (comment "instruction is a SKIP instruction")
+)
+
+
+;;;;;;;;;;;;;;;;;;;;;
+;; Hardware Pieces ;;
+;;;;;;;;;;;;;;;;;;;;;
+
+;(define-pmacro (build-reg-name n) (.splice (.str "$" n) n))
+
+; These are the 16 registers that the chip has. In later versions
+; where there will be more registers, this will need to be expanded.
+; Note that there are two entries for the registers with two names.
+(define-hardware
+ (name h-spr)
+ (comment "special-purpose registers")
+ (type register SI (16))
+ (indices keyword "" (("R0" 0) ("R1" 1) ("R2" 2) ("R3" 3) ("R4" 4) ("R5" 5)
+ ("R6" 6) ("R7" 7) ("R8" 8) ("R9" 9) ("R10" 10) ("R11" 11) ("R12" 12) ("fp" 12)
+ ("R13" 13) ("sp" 13) ("R14" 14) ("ra" 14) ("R15" 15) ("ira" 15)))
+; (get (index) (and (raw-reg h-spr) #xffffffff))
+; (set (index value) (set (raw-reg h-spr) (and value #xffffffff)))
+)
+
+; This is the program counter.
+(dnh h-pc "program counter" (PC PROFILE) (pc) () () ())
+
+(define-keyword
+ (name msys-syms)
+ (print-name h-nil)
+ (prefix "")
+ (values (DUP 1) (XX 0))
+)
+
+;;;;;;;;;;;;;;
+;; Operands ;;
+;;;;;;;;;;;;;;
+
+(define-operand (name frsr1) (comment "register") (attrs)
+ (type h-spr) (index f-sr1) )
+(define-operand (name frsr2) (comment "register") (attrs)
+ (type h-spr) (index f-sr2) )
+(define-operand (name frdr) (comment "register") (attrs)
+ (type h-spr) (index f-dr) )
+(define-operand (name frdrrr) (comment "register") (attrs)
+ (type h-spr) (index f-drrr) )
+(define-operand (name imm16) (comment "immediate value - sign extd") (attrs)
+ (type h-sint) (index f-imm16s) (handlers (parse "imm16") (print "dollarhex")))
+(define-operand (name imm16z) (comment "immediate value - zero extd") (attrs)
+ (type h-uint) (index f-imm16u) (handlers (parse "imm16") (print "dollarhex")))
+(define-operand (name imm16o) (comment "immediate value") (attrs PCREL-ADDR)
+ (type h-uint) (index f-imm16s) (handlers (parse "imm16") (print "pcrel")))
+
+; Operands for MorphoSys Instructions
+
+(define-operand (name rc) (comment "rc") (attrs)
+ (type h-uint) (index f-rc) (handlers (parse "rc") (print "dollarhex")))
+
+(define-operand (name rcnum) (comment "rcnum") (attrs)
+ (type h-uint) (index f-rcnum) (handlers (print "dollarhex")))
+
+(define-operand (name contnum) (comment "context number") (attrs)
+ (type h-uint) (index f-contnum) (handlers (print "dollarhex")))
+
+(define-operand (name rbbc) (comment "omega network configuration") (attrs)
+ (type h-uint) (index f-rbbc) (handlers (parse "rbbc") (print "dollarhex")))
+
+(define-operand (name colnum) (comment "column number") (attrs)
+ (type h-uint) (index f-colnum) (handlers (print "dollarhex")))
+
+(define-operand (name rownum) (comment "row number") (attrs)
+ (type h-uint) (index f-rownum) (handlers (print "dollarhex")))
+
+(define-operand (name rownum1) (comment "row number") (attrs)
+ (type h-uint) (index f-rownum1) (handlers (print "dollarhex")))
+
+(define-operand (name rownum2) (comment "row number") (attrs)
+ (type h-uint) (index f-rownum2) (handlers (print "dollarhex")))
+
+(define-operand (name rc1) (comment "rc1") (attrs)
+ (type h-uint) (index f-rc1) (handlers (parse "rc") (print "dollarhex")))
+
+(define-operand (name rc2) (comment "rc2") (attrs)
+ (type h-uint) (index f-rc2) (handlers (parse "rc") (print "dollarhex")))
+
+(define-operand (name cbrb) (comment "data-bus orientation") (attrs)
+ (type h-uint) (index f-cbrb) (handlers (parse "cbrb") (print "dollarhex")))
+
+(define-operand (name cell) (comment "cell") (attrs)
+ (type h-uint) (index f-cell) (handlers (print "dollarhex")))
+
+(define-operand (name dup) (comment "dup") (attrs)
+ (type h-uint) (index f-dup) (handlers (parse "dup") (print "dollarhex")))
+
+(define-operand (name ctxdisp) (comment "context displacement") (attrs)
+ (type h-uint) (index f-ctxdisp) (handlers (print "dollarhex")))
+
+(define-operand (name fbdisp) (comment "frame buffer displacement") (attrs)
+ (type h-uint) (index f-fbdisp) (handlers (print "dollarhex")))
+
+(define-operand (name type) (comment "type") (attrs)
+ (type h-uint) (index f-type) (handlers (parse "type") (print "dollarhex")))
+
+(define-operand (name mask) (comment "mask") (attrs)
+ (type h-uint) (index f-mask) (handlers (print "dollarhex")))
+
+(define-operand (name bankaddr) (comment "bank address") (attrs)
+ (type h-uint) (index f-bankaddr) (handlers (print "dollarhex")))
+
+(define-operand (name incamt) (comment "increment amount") (attrs)
+ (type h-uint) (index f-incamt) (handlers (print "dollarhex")))
+
+(define-operand (name xmode) (comment "xmode") (attrs)
+ (type h-uint) (index f-xmode) (handlers (parse "xmode") (print "dollarhex")))
+
+(define-operand (name mask1) (comment "mask1") (attrs)
+ (type h-uint) (index f-mask1) (handlers (print "dollarhex")))
+
+(define-operand (name ball) (comment "b_all") (attrs)
+ (type h-uint) (index f-ball) (handlers (parse "ball") (print "dollarhex")))
+
+(define-operand (name brc) (comment "b_r_c") (attrs)
+ (type h-uint) (index f-brc) (handlers (print "dollarhex")))
+
+(define-operand (name rda) (comment "rd") (attrs)
+ (type h-uint) (index f-rda) (handlers (print "dollarhex")))
+
+(define-operand (name wr) (comment "wr") (attrs)
+ (type h-uint) (index f-wr) (handlers (print "dollarhex")))
+
+(define-operand (name ball2) (comment "b_all2") (attrs)
+ (type h-uint) (index f-ball2) (handlers (parse "ball") (print "dollarhex")))
+
+(define-operand (name brc2) (comment "b_r_c2") (attrs)
+ (type h-uint) (index f-brc2) (handlers (print "dollarhex")))
+(define-operand (name perm) (comment "perm") (attrs)
+ (type h-uint) (index f-perm) (handlers (print "dollarhex")))
+(define-operand (name a23) (comment "a23") (attrs)
+ (type h-uint) (index f-a23) (handlers (print "dollarhex")))
+(define-operand (name cr) (comment "c-r") (attrs)
+ (type h-uint) (index f-cr) (handlers (print "dollarhex")))
+(define-operand (name cbs) (comment "cbs") (attrs)
+ (type h-uint) (index f-cbs) (handlers (print "dollarhex")))
+(define-operand (name incr) (comment "incr") (attrs)
+ (type h-uint) (index f-incr) (handlers (print "dollarhex")))
+(define-operand (name length) (comment "length") (attrs)
+ (type h-uint) (index f-length) (handlers (print "dollarhex")))
+(define-operand (name cbx) (comment "cbx") (attrs)
+ (type h-uint) (index f-cbx) (handlers (print "dollarhex")))
+(define-operand (name ccb) (comment "ccb") (attrs)
+ (type h-uint) (index f-ccb) (handlers (print "dollarhex")))
+(define-operand (name cdb) (comment "cdb") (attrs)
+ (type h-uint) (index f-cdb) (handlers (print "dollarhex")))
+
+; For the INTLVR insn
+(define-operand (name mode) (comment "mode") (attrs)
+ (type h-uint) (index f-mode) (handlers (print "dollarhex")))
+(define-operand (name id) (comment "i/d") (attrs)
+ (type h-uint) (index f-id) (handlers (print "dollarhex")))
+(define-operand (name size) (comment "size") (attrs)
+ (type h-uint) (index f-size) (handlers (print "dollarhex")))
+
+(define-operand (name fbincr) (comment "fb incr") (attrs)
+ (type h-uint) (index f-fbincr) (handlers (print "dollarhex")))
+
+; For the ms2 insns
+(define-operand (name loopsize) (comment "immediate value")
+ (attrs (MACH ms2) PCREL-ADDR)
+ (type h-uint) (index f-loopo) (handlers (parse "loopsize") (print "pcrel")))
+(define-operand (name imm16l) (comment "immediate value")
+ (attrs (MACH ms2))
+ (type h-uint) (index f-imm16l) (handlers (print "dollarhex")))
+(define-operand (name rc3) (comment "rc3") (attrs (MACH ms2))
+ (type h-uint) (index f-rc3) (handlers (parse "rc") (print "dollarhex")))
+(define-operand (name cb1sel) (comment "cb1sel") (attrs (MACH ms2))
+ (type h-uint) (index f-cb1sel) (handlers (print "dollarhex")))
+(define-operand (name cb2sel) (comment "cb2sel") (attrs (MACH ms2))
+ (type h-uint) (index f-cb2sel) (handlers (print "dollarhex")))
+(define-operand (name cb1incr) (comment "cb1incr") (attrs (MACH ms2))
+ (type h-sint) (index f-cb1incr) (handlers (print "dollarhex")))
+(define-operand (name cb2incr) (comment "cb2incr") (attrs (MACH ms2))
+ (type h-sint) (index f-cb2incr) (handlers (print "dollarhex")))
+
+; Probaby won't need most of these.
+(define-pmacro r0 (reg h-spr #x0))
+(define-pmacro r1 (reg h-spr #x01))
+(define-pmacro r2 (reg h-spr #x02))
+(define-pmacro r3 (reg h-spr #x03))
+(define-pmacro r4 (reg h-spr #x04))
+(define-pmacro r5 (reg h-spr #x05))
+(define-pmacro r6 (reg h-spr #x06))
+(define-pmacro r7 (reg h-spr #x07))
+(define-pmacro r8 (reg h-spr #x08))
+(define-pmacro r9 (reg h-spr #x09))
+(define-pmacro r10 (reg h-spr #xA))
+(define-pmacro r11 (reg h-spr #xB))
+(define-pmacro r12 (reg h-spr #xC))
+(define-pmacro fp (reg h-spr #xC))
+(define-pmacro r13 (reg h-spr #xD))
+(define-pmacro sp (reg h-spr #xD))
+(define-pmacro r14 (reg h-spr #xE))
+(define-pmacro ra (reg h-spr #xE))
+(define-pmacro r15 (reg h-spr #xF))
+(define-pmacro ira (reg h-spr #xF))
+
+; delayed set
+(define-pmacro (dset dest src) (set (delay 1 dest) src))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Instructions As Defined In the MorphoRisc ISA Document ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+; Arithmetic Instructions
+
+(dni add "ADD DstReg, SrcReg1, SrcReg2"
+ (AL-INSN USES-FRDRRR USES-FRSR1 USES-FRSR2)
+ "add $frdrrr,$frsr1,$frsr2"
+ (+ MSYS_NO OPC_ADD IMM_NO frsr1 frsr2 frdrrr (f-uu12 0))
+ (set frdrrr (add SI frsr1 frsr2))
+ ()
+)
+
+(dni addu "ADDU DstReg, SrcReg1, SrcReg2"
+ (AL-INSN USES-FRDRRR USES-FRSR1 USES-FRSR2)
+ "addu $frdrrr,$frsr1,$frsr2"
+ (+ MSYS_NO OPC_ADDU IMM_NO frsr1 frsr2 frdrrr (f-uu12 0))
+ (set frdrrr (add USI frsr1 frsr2))
+ ()
+)
+
+(dni addi "ADDI DstReg, SrcReg1 UnsImm"
+ (AL-INSN USES-FRDR USES-FRSR1)
+ "addi $frdr,$frsr1,#$imm16"
+ (+ MSYS_NO OPC_ADD IMM_YES frsr1 frdr imm16)
+ (sequence((HI tmp))
+ (set HI tmp (and imm16 #xffff))
+ (set frdr (add SI frsr1 (ext SI tmp)))
+ )
+ ()
+)
+
+(dni addui "ADDUI DstReg, SrcReg1, UnsImm"
+ (AL-INSN USES-FRDR USES-FRSR1)
+ "addui $frdr,$frsr1,#$imm16z"
+ (+ MSYS_NO OPC_ADDU IMM_YES frsr1 frdr imm16z)
+ (set frdr (add USI frsr1 (ext USI imm16z)))
+ ()
+)
+
+(dni sub "SUB DstReg, SrcReg1, SrcReg2"
+ (AL-INSN USES-FRDRRR USES-FRSR1 USES-FRSR2)
+ "sub $frdrrr,$frsr1,$frsr2"
+ (+ MSYS_NO OPC_SUB IMM_NO frsr1 frsr2 frdrrr (f-uu12 0))
+ (set frdrrr (sub SI frsr1 frsr2))
+ ()
+)
+
+(dni subu "SUBU DstReg, SrcReg1, SrcReg2"
+ (AL-INSN USES-FRDRRR USES-FRSR1 USES-FRSR2)
+ "subu $frdrrr,$frsr1,$frsr2"
+ (+ MSYS_NO OPC_SUBU IMM_NO frsr1 frsr2 frdrrr (f-uu12 0))
+ (set frdrrr (sub USI frsr1 frsr2))
+ ()
+)
+
+(dni subi "SUBI DstReg, SrcReg1, UnsImm"
+ (AL-INSN USES-FRDR USES-FRSR1)
+ "subi $frdr,$frsr1,#$imm16"
+ (+ MSYS_NO OPC_SUB IMM_YES frsr1 frdr imm16)
+ (sequence((HI tmp))
+ (set HI tmp (and imm16 #xffff))
+ (set frdr (sub SI frsr1 (ext SI tmp)))
+ )
+ ;(set frdr (sub SI frsr1 (ext SI imm16)))
+ ()
+)
+
+(dni subui "SUBUI DstReg, SrcReg1, UnsImm"
+ (AL-INSN USES-FRDR USES-FRSR1)
+ "subui $frdr,$frsr1,#$imm16z"
+ (+ MSYS_NO OPC_SUBU IMM_YES frsr1 frdr imm16z)
+ (set frdr (sub USI frsr1 (ext USI imm16z)))
+ ()
+)
+
+(dni mul "MUL DstReg, SrcReg1, SrcReg2"
+ ((MACH ms1-003,ms2) AL-INSN USES-FRDRRR USES-FRSR1 USES-FRSR2)
+ "mul $frdrrr,$frsr1,$frsr2"
+ (+ MSYS_NO OPC_MUL IMM_NO frsr1 frsr2 frdrrr (f-uu12 0))
+ (sequence((HI op1) (HI op2))
+ (set op1 (and frsr1 #xffff))
+ (if (or (lt op1 (const -32768)) (gt op1 (const 32767)))
+ (error "operand out of range")
+ )
+ (set op2 (and frsr2 #xffff))
+ (if (or (lt op2 (const -32768)) (gt op2 (const 32767)))
+ (error "operand out of range")
+ )
+ (set frdrrr (mul SI (ext SI op1) (ext SI op2)))
+ )
+ ()
+)
+
+(dni muli "MULI DstReg, SrcReg1, UnsImm"
+ ((MACH ms1-003,ms2) AL-INSN USES-FRDR USES-FRSR1)
+ "muli $frdr,$frsr1,#$imm16"
+ (+ MSYS_NO OPC_MUL IMM_YES frsr1 frdr imm16)
+ (sequence((HI op1) (HI op2))
+ (set op1 (and frsr1 #xffff))
+ (if (or (lt op1 (const -32768)) (gt op1 (const 32767)))
+ (error "operand out of range")
+ )
+ (set op2 (and imm16 #xffff))
+ (if (eq op1 (const 0))
+ (error "op1 is 0")
+ )
+ (if (eq op2 (const 0))
+ (error "op2 is 0")
+ )
+ (set frdr (mul SI (ext SI op1) (ext SI op2)))
+ )
+ ()
+)
+
+; Logical Instructions
+
+(dni and "AND DstReg, SrcReg1, SrcReg2"
+ (AL-INSN USES-FRDRRR USES-FRSR1 USES-FRSR2)
+ "and $frdrrr,$frsr1,$frsr2"
+ (+ MSYS_NO OPC_AND IMM_NO frsr1 frsr2 frdrrr (f-uu12 0))
+ (set frdrrr (and frsr1 frsr2))
+ ()
+)
+
+(dni andi "ANDI DstReg, SrcReg1, UnsImm"
+ (AL-INSN USES-FRDR USES-FRSR1)
+ "andi $frdr,$frsr1,#$imm16z"
+ (+ MSYS_NO OPC_AND IMM_YES frsr1 frdr imm16z)
+ (set frdr (and frsr1 (ext USI imm16z)))
+ ()
+)
+
+(dni or "OR DstReg, SrcReg1, SrcReg2"
+ (AL-INSN USES-FRDRRR USES-FRSR1 USES-FRSR2)
+ "or $frdrrr,$frsr1,$frsr2"
+ (+ MSYS_NO OPC_OR IMM_NO frsr1 frsr2 frdrrr (f-uu12 0))
+ (set frdrrr (or frsr1 frsr2))
+ ()
+)
+
+(dni nop "nop"
+ ()
+ "nop"
+ (+ MSYS_NO OPC_OR IMM_NO (f-uu24 0))
+ (nop)
+ ()
+)
+
+(dni ori "ORI DstReg, SrcReg1, UnsImm"
+ (AL-INSN USES-FRDR USES-FRSR1)
+ "ori $frdr,$frsr1,#$imm16z"
+ (+ MSYS_NO OPC_OR IMM_YES frsr1 frdr imm16z)
+ (set frdr (or frsr1 (ext USI imm16z)))
+ ()
+)
+
+(dni xor "XOR DstReg, SrcReg1, SrcReg2"
+ (AL-INSN USES-FRDRRR USES-FRSR1 USES-FRSR2)
+ "xor $frdrrr,$frsr1,$frsr2"
+ (+ MSYS_NO OPC_XOR IMM_NO frsr1 frsr2 frdrrr (f-uu12 0))
+ (set frdrrr (xor frsr1 frsr2))
+ ()
+)
+
+(dni xori "XORI DstReg, SrcReg1, UnsImm"
+ (AL-INSN USES-FRDR USES-FRSR1)
+ "xori $frdr,$frsr1,#$imm16z"
+ (+ MSYS_NO OPC_XOR IMM_YES frsr1 frdr imm16z)
+ (set frdr (xor frsr1 (ext USI imm16z)))
+ ()
+)
+
+(dni nand "NAND DstReg, SrcReg1, SrcReg2"
+ (AL-INSN USES-FRDRRR USES-FRSR1 USES-FRSR2)
+ "nand $frdrrr,$frsr1,$frsr2"
+ (+ MSYS_NO OPC_NAND IMM_NO frsr1 frsr2 frdrrr (f-uu12 0))
+ (set frdrrr (inv (and frsr1 frsr2)))
+ ()
+)
+
+(dni nandi "NANDI DstReg, SrcReg1, UnsImm"
+ (AL-INSN USES-FRDR USES-FRSR1)
+ "nandi $frdr,$frsr1,#$imm16z"
+ (+ MSYS_NO OPC_NAND IMM_YES frsr1 frdr imm16z)
+ (set frdr (inv (and frsr1 (ext USI imm16z))))
+ ()
+)
+
+(dni nor "NOR DstReg, SrcReg1, SrcReg2"
+ (AL-INSN USES-FRDRRR USES-FRSR1 USES-FRSR2)
+ "nor $frdrrr,$frsr1,$frsr2"
+ (+ MSYS_NO OPC_NOR IMM_NO frsr1 frsr2 frdrrr (f-uu12 0))
+ (set frdrrr (inv (or frsr1 frsr2)))
+ ()
+)
+
+(dni nori "NORI DstReg, SrcReg1, UnsImm"
+ (AL-INSN USES-FRDR USES-FRSR1)
+ "nori $frdr,$frsr1,#$imm16z"
+ (+ MSYS_NO OPC_NOR IMM_YES frsr1 frdr imm16z)
+ (set frdr (inv (or frsr1 (ext USI imm16z))))
+ ()
+)
+
+(dni xnor "XNOR DstReg, SrcReg1, SrcReg2"
+ (AL-INSN USES-FRDRRR USES-FRSR1 USES-FRSR2)
+ "xnor $frdrrr,$frsr1,$frsr2"
+ (+ MSYS_NO OPC_XNOR IMM_NO frsr1 frsr2 frdrrr (f-uu12 0))
+ (set frdrrr (inv (xor frsr1 frsr2)))
+ ()
+)
+
+(dni xnori "XNORI DstReg, SrcReg1, UnsImm"
+ (AL-INSN USES-FRDR USES-FRSR1)
+ "xnori $frdr,$frsr1,#$imm16z"
+ (+ MSYS_NO OPC_XNOR IMM_YES frsr1 frdr imm16z)
+ (set frdr (inv (xor frsr1 (ext USI imm16z))))
+ ()
+)
+
+(dni ldui "LDUI DstReg, UnsImm"
+ (AL-INSN USES-FRDR)
+ "ldui $frdr,#$imm16z"
+ (+ MSYS_NO OPC_LDUI IMM_YES (f-uu4b 0) frdr imm16z)
+ (set frdr (and (sll imm16z 16) #xffff0000))
+ ()
+)
+
+; Shift Instructions
+
+(dni lsl "LSL DstReg, SrcReg1, SrcReg2"
+ (USES-FRDRRR USES-FRSR1 USES-FRSR2)
+ "lsl $frdrrr,$frsr1,$frsr2"
+ (+ MSYS_NO OPC_LSL IMM_NO frsr1 frsr2 frdrrr (f-uu12 0))
+ (set frdrrr (sll frsr1 frsr2))
+ ()
+)
+
+(dni lsli "LSLI DstReg, SrcReg1, UnsImm"
+ (USES-FRDR USES-FRSR1)
+ "lsli $frdr,$frsr1,#$imm16"
+ (+ MSYS_NO OPC_LSL IMM_YES frsr1 frdr imm16)
+ (set frdr (sll frsr1 imm16))
+ ()
+)
+
+(dni lsr "LSR DstReg, SrcReg1, SrcReg2"
+ (USES-FRDRRR USES-FRSR1 USES-FRSR2)
+ "lsr $frdrrr,$frsr1,$frsr2"
+ (+ MSYS_NO OPC_LSR IMM_NO frsr1 frsr2 frdrrr (f-uu12 0))
+ (set frdrrr (srl frsr1 frsr2))
+ ()
+)
+
+(dni lsri "LSRI DstReg, SrcReg1, UnsImm"
+ (USES-FRDR USES-FRSR1)
+ "lsri $frdr,$frsr1,#$imm16"
+ (+ MSYS_NO OPC_LSR IMM_YES frsr1 frdr imm16)
+ (set frdr (srl frsr1 imm16))
+ ()
+)
+
+(dni asr "ASR DstReg, SrcReg1, SrcReg2"
+ (USES-FRDRRR USES-FRSR1 USES-FRSR2)
+ "asr $frdrrr,$frsr1,$frsr2"
+ (+ MSYS_NO OPC_ASR IMM_NO frsr1 frsr2 frdrrr (f-uu12 0))
+ (set frdrrr (sra frsr1 frsr2))
+ ()
+)
+
+(dni asri "ASRI DstReg, SrcReg1, UnsImm"
+ (USES-FRDR USES-FRSR1)
+ "asri $frdr,$frsr1,#$imm16"
+ (+ MSYS_NO OPC_ASR IMM_YES frsr1 frdr imm16)
+ (set frdr (sra frsr1 imm16))
+ ()
+)
+
+; Control Transfer Instructions
+
+(dni brlt "BRLT SrcReg1, SrcReg2, label"
+ (BR-INSN DELAY-SLOT USES-FRDRRR USES-FRSR1 USES-FRSR2)
+ "brlt $frsr1,$frsr2,$imm16o"
+ (+ MSYS_NO OPC_BRLT IMM_YES frsr1 frsr2 imm16o)
+ (sequence()
+ (if (lt USI frsr1 frsr2)
+ (dset pc (add pc (ext SI imm16o))))
+ )
+ ()
+)
+
+(dni brle "BRLE SrcReg1, SrcReg2, label"
+ (BR-INSN DELAY-SLOT USES-FRSR1 USES-FRSR2)
+ "brle $frsr1,$frsr2,$imm16o"
+ (+ MSYS_NO OPC_BRLE IMM_YES frsr1 frsr2 imm16o)
+ (sequence()
+ (if (le USI frsr1 frsr2)
+ (dset pc (add pc (ext SI imm16o))))
+ )
+ ()
+)
+
+(dni breq "BREQ SrcReg1, SrcReg2, label"
+ (BR-INSN DELAY-SLOT USES-FRSR1 USES-FRSR2)
+ "breq $frsr1,$frsr2,$imm16o"
+ (+ MSYS_NO OPC_BREQ IMM_YES frsr1 frsr2 imm16o)
+ (sequence()
+ (if (eq USI frsr1 frsr2)
+ (dset pc (add pc (ext SI imm16o))))
+ )
+ ()
+)
+
+(dni brne "BRNE SrcReg1, SrcReg2, label"
+ (BR-INSN DELAY-SLOT USES-FRSR1 USES-FRSR2)
+ "brne $frsr1,$frsr2,$imm16o"
+ (+ MSYS_NO OPC_BRNEQ IMM_YES frsr1 frsr2 imm16o)
+ (sequence()
+ (if (not (eq USI frsr1 frsr2))
+ (dset pc (add pc (ext SI imm16o))))
+ )
+ ()
+)
+
+(dni jmp "JMP, label"
+ (DELAY-SLOT BR-INSN)
+ "jmp $imm16o"
+ (+ MSYS_NO OPC_JMP IMM_YES (f-uu4b 0) (f-uu4a 0) imm16o)
+ (dset pc (add pc (ext SI imm16o)))
+ ()
+)
+
+(dni jal "JAL DstReg, SrcReg1"
+ (BR-INSN DELAY-SLOT BR-INSN USES-FRDR USES-FRSR1 JAL-HAZARD)
+ "jal $frdrrr,$frsr1"
+ (+ MSYS_NO OPC_JAL IMM_NO frsr1 (f-uu4a 0) frdrrr (f-uu12 0))
+ (sequence()
+ (if (eq frsr1 #x0)
+ (c-call VOID "do_syscall" pc)
+ (sequence() ; else part. Do non-syscall stuff here.
+ (dset frdrrr (add pc #x8))
+ (dset pc frsr1)
+ )
+ )
+ )
+ ()
+)
+
+(dni dbnz "DBNZ SrcReg1, label"
+ ((MACH ms1-003,ms2) BR-INSN DELAY-SLOT USES-FRSR1)
+ "dbnz $frsr1,$imm16o"
+ (+ MSYS_NO OPC_DBNZ IMM_YES frsr1 (f-uu4a 0) imm16o)
+ (sequence()
+ (if (not (eq USI frsr1 0))
+ (dset pc (add pc (ext SI imm16o))))
+ )
+ ()
+)
+
+; Interrupt Control Instructions
+
+(dni ei "EI - Enable Interrupt Processing"
+ ()
+ "ei"
+ (+ MSYS_NO OPC_EI IMM_NO (f-uu4b 0) (f-uu4a 0) (f-uu16 0))
+ (c-call VOID "enable_interrupts")
+ ()
+)
+
+(dni di "DI - Disable Interrupt Processing"
+ ()
+ "di"
+ (+ MSYS_NO OPC_DI IMM_NO (f-uu4b 0) (f-uu4a 0) (f-uu16 0))
+ (c-call VOID "disable_interrupts")
+ ()
+)
+
+(dni si "SI - Send software Interrupt"
+ (DELAY-SLOT BR-INSN USES-FRDR)
+ "si $frdrrr"
+ (+ MSYS_NO OPC_SI IMM_NO (f-uu4b 0) (f-uu4a 0) frdrrr (f-uu12 0))
+ ;(sequence()
+ ; (dset frdr (add pc #x4))
+ ; (c-call VOID "do_syscall1" pc)
+ ; ; (dset pc frsr1) Do this later when we have the address.
+ ;)
+ (sequence()
+ (set frdrrr (add pc #x4))
+ (c-call VOID "do_syscall" pc)
+ ; (set pc frsr1) Do this later when we have the address.
+ )
+ ()
+)
+
+(dni reti "RETI SrcReg1"
+ (DELAY-SLOT BR-INSN USES-FRSR1 JAL-HAZARD)
+ "reti $frsr1"
+ (+ MSYS_NO OPC_RETI IMM_NO frsr1 (f-uu4a 0) (f-uu16 0))
+ (sequence()
+ (c-call VOID "enable_interrupts")
+ (dset pc frsr1)
+ )
+ ()
+)
+
+; Memory Access Instructions
+
+(dni ldw "LDW DstReg, SrcReg1, Imm"
+ (LOAD-DELAY MEMORY-ACCESS USES-FRDR USES-FRSR1)
+ "ldw $frdr,$frsr1,#$imm16"
+ (+ MSYS_NO OPC_LDW IMM_YES frsr1 frdr imm16)
+ (sequence((USI ea) (HI tmp))
+ (set HI tmp (and imm16 #xffff))
+ (set ea (and (add SI frsr1 (ext SI tmp)) #xfffffffc))
+ (set frdr (mem SI ea))
+ )
+ ()
+)
+
+(dni stw "STW SrcReg2, SrcReg1, Imm"
+ (MEMORY-ACCESS USES-FRSR1 USES-FRSR2)
+ "stw $frsr2,$frsr1,#$imm16"
+ (+ MSYS_NO OPC_STW IMM_YES frsr1 frsr2 imm16)
+ (sequence((USI ea) (HI tmp))
+ (set HI tmp (and imm16 #xffff))
+ (set ea (and (add SI frsr1 (ext SI tmp)) #xfffffffc))
+ (set (mem SI ea) frsr2)
+ )
+ ()
+)
+
+; Break Instruction
+
+(dni break "BREAK"
+ ()
+ "break"
+ (+ MSYS_NO OPC_BREAK (f-imm 0) (f-uu24 0))
+ (c-call VOID "do_break" pc)
+ ()
+)
+
+; Cache Flush Instruction
+
+(dni iflush "IFLUSH"
+ ((MACH ms1-003,ms2))
+ "iflush"
+ (+ MSYS_NO OPC_IFLUSH (f-imm 0) (f-uu24 0))
+ (nop)
+ ()
+)
+
+; MorphoSys Instructions
+
+(dni ldctxt "LDCTXT SRC1, SRC2, r/c, r/c#, context#"
+ ((MACH ms1))
+ "ldctxt $frsr1,$frsr2,#$rc,#$rcnum,#$contnum"
+ (+ MSYS_YES MSOPC_LDCTXT (f-uu-2-25 0) frsr1 frsr2 rc rcnum (f-uu-3-11 0)
+ contnum )
+ (nop)
+ ()
+)
+
+(dni ldfb "LDFB SRC1, byte#"
+ ((MACH ms1))
+ "ldfb $frsr1,$frsr2,#$imm16z"
+ (+ MSYS_YES MSOPC_LDFB (f-uu-2-25 0) frsr1 frsr2 imm16z)
+ (nop)
+ ()
+)
+
+(dni stfb "STFB SRC1, SRC2, byte "
+ ((MACH ms1))
+ "stfb $frsr1,$frsr2,#$imm16z"
+ (+ MSYS_YES MSOPC_STFB (f-uu-2-25 0) frsr1 frsr2 imm16z)
+ (nop)
+ ()
+)
+
+(dni fbcb "FBCB SRC1, RT/BR1/BR2/CS, B_all, B_r_c, r/c, CB/RB, cell, dup, ctx_disp"
+ ((MACH ms1,ms1-003))
+ "fbcb $frsr1,#$rbbc,#$ball,#$brc,#$rc1,#$cbrb,#$cell,#$dup,#$ctxdisp"
+ (+ MSYS_YES MSOPC_FBCB rbbc frsr1 ball brc (f-uu-4-15 0) rc cbrb cell dup ctxdisp)
+ (nop)
+ ()
+)
+
+(dni mfbcb "MFBCB SRC1, RT/BR1/BR2/CS, SRC2, r/c, CB/RB, cell, dup, ctx_disp"
+ ()
+ "mfbcb $frsr1,#$rbbc,$frsr2,#$rc1,#$cbrb,#$cell,#$dup,#$ctxdisp"
+ (+ MSYS_YES MSOPC_MFBCB rbbc frsr1 frsr2 (f-uu-4-15 0) rc1 cbrb cell dup ctxdisp)
+ (nop)
+ ()
+)
+
+(dni fbcci "FBCCI SRC1, RT/BR1/BR2/CS, B_all, B_r_c, FB_disp, cell, dup, ctx_disp"
+ ()
+ "fbcci $frsr1,#$rbbc,#$ball,#$brc,#$fbdisp,#$cell,#$dup,#$ctxdisp"
+ (+ MSYS_YES MSOPC_FBCCI rbbc frsr1 ball brc fbdisp cell dup ctxdisp)
+ (nop)
+ ()
+)
+
+(dni fbrci "FBRCI SRC1, RT/BR1/BR2/CS, B_all, B_r_c, FB_disp, cell, dup, ctx_disp"
+ ()
+ "fbrci $frsr1,#$rbbc,#$ball,#$brc,#$fbdisp,#$cell,#$dup,#$ctxdisp"
+ (+ MSYS_YES MSOPC_FBRCI rbbc frsr1 ball brc fbdisp cell dup ctxdisp)
+ (nop)
+ ()
+)
+
+(dni fbcri "FBCRI SRC1, RT/BR1/BR2/CS, B_all, B_r_c, FB_disp, cell, dup, ctx_disp"
+ ()
+ "fbcri $frsr1,#$rbbc,#$ball,#$brc,#$fbdisp,#$cell,#$dup,#$ctxdisp"
+ (+ MSYS_YES MSOPC_FBCRI rbbc frsr1 ball brc fbdisp cell dup ctxdisp)
+ (nop)
+ ()
+)
+
+(dni fbrri "FBRRI SRC1, RT/BR1/BR2/CS, B_all, B_r_c, FB_disp, cell, dup, ctx_disp"
+ ()
+ "fbrri $frsr1,#$rbbc,#$ball,#$brc,#$fbdisp,#$cell,#$dup,#$ctxdisp"
+ (+ MSYS_YES MSOPC_FBRRI rbbc frsr1 ball brc fbdisp cell dup ctxdisp)
+ (nop)
+ ()
+)
+
+(dni mfbcci "MFBCCI SRC1, RT/BR1/BR2/CS, SRC2, FB_disp, cell, dup, ctx_disp"
+ ()
+ "mfbcci $frsr1,#$rbbc,$frsr2,#$fbdisp,#$cell,#$dup,#$ctxdisp"
+ (+ MSYS_YES MSOPC_MFBCCI rbbc frsr1 frsr2 fbdisp cell dup ctxdisp)
+ (nop)
+ ()
+)
+
+(dni mfbrci "MFBRCI SRC1, RT/BR1/BR2/CS, SRC2, FB_disp, cell, dup, ctx_disp"
+ ()
+ "mfbrci $frsr1,#$rbbc,$frsr2,#$fbdisp,#$cell,#$dup,#$ctxdisp"
+ (+ MSYS_YES MSOPC_MFBRCI rbbc frsr1 frsr2 fbdisp cell dup ctxdisp)
+ (nop)
+ ()
+)
+
+(dni mfbcri "MFBCRI SRC1, RT/BR1/BR2/CS, SRC2, FB_disp, cell, dup, ctx_disp"
+ ()
+ "mfbcri $frsr1,#$rbbc,$frsr2,#$fbdisp,#$cell,#$dup,#$ctxdisp"
+ (+ MSYS_YES MSOPC_MFBCRI rbbc frsr1 frsr2 fbdisp cell dup ctxdisp)
+ (nop)
+ ()
+)
+
+(dni mfbrri "MFBRRI SRC1, RT/BR1/BR2/CS, SRC2, FB_disp, cell, dup, ctx_disp"
+ ()
+ "mfbrri $frsr1,#$rbbc,$frsr2,#$fbdisp,#$cell,#$dup,#$ctxdisp"
+ (+ MSYS_YES MSOPC_MFBRRI rbbc frsr1 frsr2 fbdisp cell dup ctxdisp)
+ (nop)
+ ()
+)
+
+(dni fbcbdr "FBCBDR SRC1, RT/BR1/BR2/CS, SRC2, B_all, B_r_c, r/c, CB/RB, cell, dup, ctx_disp"
+ ()
+ "fbcbdr $frsr1,#$rbbc,$frsr2,#$ball2,#$brc2,#$rc1,#$cbrb,#$cell,#$dup,#$ctxdisp"
+ (+ MSYS_YES MSOPC_FBCBDR rbbc frsr1 frsr2 ball2 brc2 rc1 cbrb cell dup ctxdisp)
+ (nop)
+ ()
+)
+
+(dni rcfbcb "RCFBCB RT/BR1/BR2/CS, type, B_all, B_r_c, row#, r/c, CB/RB, cell, dup, ctx_disp"
+ ()
+ "rcfbcb #$rbbc,#$type,#$ball,#$brc,#$rownum,#$rc1,#$cbrb,#$cell,#$dup,#$ctxdisp"
+ (+ MSYS_YES MSOPC_RCFBCB rbbc (f-uu-2-23 0) type ball brc (f-uu-1-15 0) rownum rc1 cbrb cell dup ctxdisp)
+ (nop)
+ ()
+)
+
+(dni mrcfbcb "MRCFBCB SRC2, RT/BR1/BR2/CS, type, row#, r/c, CB/RB, cell, dup, ctx_disp"
+ ()
+ "mrcfbcb $frsr2,#$rbbc,#$type,#$rownum,#$rc1,#$cbrb,#$cell,#$dup,#$ctxdisp"
+ (+ MSYS_YES MSOPC_MRCFBCB rbbc (f-uu-2-23 0) type frsr2 (f-uu-1-15 0) rownum rc1 cbrb cell dup ctxdisp)
+ (nop)
+ ()
+)
+
+(dni cbcast "CBCAST mask, r/c, ctx_disp "
+ ()
+ "cbcast #$mask,#$rc2,#$ctxdisp"
+ (+ MSYS_YES MSOPC_CBCAST mask (f-uu-3-9 0) rc2 ctxdisp)
+ (nop)
+ ()
+)
+
+(dni dupcbcast "DUPCBCAST mask, cell, r/c, ctx_disp "
+ ()
+ "dupcbcast #$mask,#$cell,#$rc2,#$ctxdisp"
+ (+ MSYS_YES MSOPC_DUPCBCAST mask cell rc2 ctxdisp)
+ (nop)
+ ()
+)
+
+(dni wfbi "WFBI Bank_address, row#, cell, dup, ctx_disp "
+ ()
+ "wfbi #$bankaddr,#$rownum1,#$cell,#$dup,#$ctxdisp"
+ (+ MSYS_YES MSOPC_WFBI bankaddr rownum1 cell dup ctxdisp)
+ (nop)
+ ()
+)
+
+;(dni wfb "WFB SRC1, SRC2, FB_disp, row#, ctx_disp"
+; ()
+; "wfb $frsr1,$frsr2,#$fbdisp,#$rownum,#$ctxdisp"
+; (+ MSYS_YES MSOPC_WFB (f-uu-2-25 0) frsr1 frsr2 fbdisp rownum (f-uu-1-6 0) ctxdisp)
+; (nop)
+; ()
+;)
+
+(dni wfb "WFB, DRC1,SRC2,FB_disp,row#,ctx_disp"
+ ()
+ "wfb $frsr1,$frsr2,#$fbdisp,#$rownum2,#$ctxdisp"
+ (+ MSYS_YES MSOPC_WFB (f-uu-2-25 0) frsr1 frsr2 fbdisp rownum2 (f-uu-1-6 0) ctxdisp)
+ (nop)
+ ()
+)
+
+
+(dni rcrisc "RCRISC DEST, RT/BR1/BR2/CS, SRC1, column#, r/c, CB/RB, cell, dup, ctx_disp"
+ ()
+ "rcrisc $frdrrr,#$rbbc,$frsr1,#$colnum,#$rc1,#$cbrb,#$cell,#$dup,#$ctxdisp"
+ (+ MSYS_YES MSOPC_RCRISC rbbc frsr1 (f-uu-1-19 0) colnum frdrrr rc1 cbrb cell dup ctxdisp)
+ (nop)
+ ()
+)
+
+(dni fbcbinc "FBCBINC SRC1, RT/BR1/BR2/CS, Incr_amount, r/c, CB/RB, cell, dup, ctx_disp "
+ ()
+ "fbcbinc $frsr1,#$rbbc,#$incamt,#$rc1,#$cbrb,#$cell,#$dup,#$ctxdisp"
+ (+ MSYS_YES MSOPC_FBCBINC rbbc frsr1 incamt rc1 cbrb cell dup ctxdisp)
+ (nop)
+ ()
+)
+
+(dni rcxmode "RCXMODE SRC2, rd, wr, xmode, mask, FB_disp, row#, r/c, ctx_disp"
+ ()
+ "rcxmode $frsr2,#$rda,#$wr,#$xmode,#$mask1,#$fbdisp,#$rownum2,#$rc2,#$ctxdisp"
+ (+ MSYS_YES MSOPC_RCXMODE rda wr xmode mask1 frsr2 fbdisp rownum2 rc2 ctxdisp)
+ (nop)
+ ()
+)
+
+(dni interleaver "INTLVR ireg, mode, ireg, i/d, size"
+ ()
+ "intlvr $frsr1,#$mode,$frsr2,#$id,#$size"
+ (+ MSYS_YES MSOPC_INTLVR mode frsr1 frsr2 (f-uu-1-15 0) id size)
+ (nop)
+ ()
+)
+
+;; Issue 66262: The documenatation gives the wrong order for
+;; the arguments to the WFBINC instruction.
+(dni wfbinc "WFBINC type, ccb/rcb, incr, all, c/r, length, rca_row, word, dup, ctxt_disp"
+ ((MACH ms1-003,ms2))
+ "wfbinc #$rda,#$wr,#$fbincr,#$ball,#$colnum,#$length,#$rownum1,#$rownum2,#$dup,#$ctxdisp"
+ (+ MSYS_YES MSOPC_WFBINC rda wr fbincr ball colnum length rownum1 rownum2 dup ctxdisp)
+ (nop)
+ ()
+)
+
+(dni mwfbinc "MWFBINC mreg, type, ccb/rcb, incr, length, rca_row, word, dup, ctxt_disp"
+ ((MACH ms1-003,ms2))
+ "mwfbinc $frsr2,#$rda,#$wr,#$fbincr,#$length,#$rownum1,#$rownum2,#$dup,#$ctxdisp"
+ (+ MSYS_YES MSOPC_MWFBINC rda wr fbincr frsr2 length rownum1 rownum2 dup ctxdisp)
+ (nop)
+ ()
+)
+
+(dni wfbincr "WFBINCR ireg, type, ccb/rcb, all, c/r, length, rca_row, word, dup, ctxt_disp"
+ ((MACH ms1-003,ms2))
+ "wfbincr $frsr1,#$rda,#$wr,#$ball,#$colnum,#$length,#$rownum1,#$rownum2,#$dup,#$ctxdisp"
+ (+ MSYS_YES MSOPC_WFBINCR rda wr frsr1 ball colnum length rownum1 rownum2 dup ctxdisp)
+ (nop)
+ ()
+)
+
+(dni mwfbincr "MWFBINCR ireg, mreg, type, ccb/rcb, length, rca_row, word, dup, ctxt_disp"
+ ((MACH ms1-003,ms2))
+ "mwfbincr $frsr1,$frsr2,#$rda,#$wr,#$length,#$rownum1,#$rownum2,#$dup,#$ctxdisp"
+ (+ MSYS_YES MSOPC_MWFBINCR rda wr frsr1 frsr2 length rownum1 rownum2 dup ctxdisp)
+ (nop)
+ ()
+)
+
+(dni fbcbincs "FBCBINCS perm, all, c/r, cbs, incr, ccb/rcb, cdb/rdb, word, dup, ctxt_disp"
+ ((MACH ms1-003,ms2))
+ "fbcbincs #$perm,#$a23,#$cr,#$cbs,#$incr,#$ccb,#$cdb,#$rownum2,#$dup,#$ctxdisp"
+ (+ MSYS_YES MSOPC_FBCBINCS perm a23 cr cbs incr ccb cdb rownum2 dup ctxdisp)
+ (nop)
+ ()
+)
+
+(dni mfbcbincs "MFBCBINCS ireg, perm, cbs, incr, ccb/rcb, cdb/rdb, word, dup, ctxt_disp"
+ ((MACH ms1-003,ms2))
+ "mfbcbincs $frsr1,#$perm,#$cbs,#$incr,#$ccb,#$cdb,#$rownum2,#$dup,#$ctxdisp"
+ (+ MSYS_YES MSOPC_MFBCBINCS perm frsr1 cbs incr ccb cdb rownum2 dup ctxdisp)
+ (nop)
+ ()
+)
+
+(dni fbcbincrs "FBCBINCRS ireg, perm, all, c/r, cbs, ccb/rcb, cdb/rdb, word, dup, ctxt_disp"
+ ((MACH ms1-003,ms2))
+ "fbcbincrs $frsr1,#$perm,#$ball,#$colnum,#$cbx,#$ccb,#$cdb,#$rownum2,#$dup,#$ctxdisp"
+ (+ MSYS_YES MSOPC_FBCBINCRS perm frsr1 ball colnum (f-uu-1-15 0) cbx ccb cdb rownum2 dup ctxdisp)
+ (nop)
+ ()
+)
+
+(dni mfbcbincrs "MFBCBINCRS ireg, mreg, perm, cbs, ccb/rcb, cdb/rdb, word, dup, ctxt_disp"
+ ((MACH ms1-003,ms2))
+ "mfbcbincrs $frsr1,$frsr2,#$perm,#$cbx,#$ccb,#$cdb,#$rownum2,#$dup,#$ctxdisp"
+ (+ MSYS_YES MSOPC_MFBCBINCRS perm frsr1 frsr2 (f-uu-1-15 0) cbx ccb cdb rownum2 dup ctxdisp)
+ (nop)
+ ()
+)
+
+; MS2 instructions
+(dni loop "LOOP SrcReg1, label"
+ ((MACH ms2) DELAY-SLOT USES-FRSR1)
+ "loop $frsr1,$loopsize"
+ (+ MSYS_NO OPC_LOOP IMM_NO frsr1 (f-uu4a 0) (f-uu8 0) loopsize)
+ (nop) ;; to be filled in
+ ()
+)
+
+(dni loopi "LOOPI niter, label"
+ ((MACH ms2) DELAY-SLOT)
+ "loopi #$imm16l,$loopsize"
+ (+ MSYS_NO OPC_LOOP IMM_YES imm16l loopsize)
+ (nop) ;; to be filled in
+ ()
+)
+
+(dni dfbc "dfbc cb1sel,cb2sel,cb1inc,cb2inc,dr/c,cr/c,ctxdisp"
+ ((MACH ms2))
+ "dfbc #$cb1sel,#$cb2sel,#$cb1incr,#$cb2incr,#$rc3,#$rc2,#$ctxdisp"
+ (+ MSYS_YES MSOPC_LDCTXT cb1sel cb2sel cb1incr cb2incr rc3 rc2 ctxdisp)
+ (nop)
+ ()
+)
+
+(dni dwfb "dwfb cb1sel,cb2sel,cb1inc,cb2inc,cr/c,ctxdisp"
+ ((MACH ms2))
+ "dwfb #$cb1sel,#$cb2sel,#$cb1incr,#$cb2incr,#$rc2,#$ctxdisp"
+ (+ MSYS_YES MSOPC_LDFB cb1sel cb2sel cb1incr cb2incr (f-uu1 0) rc2 ctxdisp)
+ (nop)
+ ()
+)
+
+(dni fbwfb "fbwfb cb1sel,cb2sel,cb1inc,cb2inc,r0/1,cr/c,ctxdisp"
+ ((MACH ms2))
+ "fbwfb #$cb1sel,#$cb2sel,#$cb1incr,#$cb2incr,#$rc3,#$rc2,#$ctxdisp"
+ (+ MSYS_YES MSOPC_STFB cb1sel cb2sel cb1incr cb2incr rc3 rc2 ctxdisp)
+ (nop)
+ ()
+)
+
+(dni dfbr "dfbr cb1sel,cb2sel,reg,W/O1,W/O2,mode,cr/c,ctxdisp"
+ ((MACH ms2) USES-FRSR2)
+ "dfbr #$cb1sel,#$cb2sel,$frsr2,#$length,#$rownum1,#$rownum2,#$rc2,#$ctxdisp"
+ (+ MSYS_YES MSOPC_FBCB cb1sel cb2sel frsr2 length rownum1 rownum2 rc2 ctxdisp)
+ (nop)
+ ()
+)
--- /dev/null
+/* Morpho Technologies mRISC opcode support, for GNU Binutils. -*- C -*-
+ Copyright 2001 Free Software Foundation, Inc.
+
+ Contributed by Red Hat Inc; developed under contract from
+ Morpho Technologies.
+
+ This file is part of the GNU Binutils.
+
+ This program 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 of the License, or
+ (at your option) any later version.
+
+ This program 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 this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+/*
+ Each section is delimited with start and end markers.
+
+ <arch>-opc.h additions use: "-- opc.h"
+ <arch>-opc.c additions use: "-- opc.c"
+ <arch>-asm.c additions use: "-- asm.c"
+ <arch>-dis.c additions use: "-- dis.c"
+ <arch>-ibd.h additions use: "-- ibd.h"
+*/
+\f
+/* -- opc.h */
+
+/* Check applicability of instructions against machines. */
+#define CGEN_VALIDATE_INSN_SUPPORTED
+
+/* Allows reason codes to be output when assembler errors occur. */
+#define CGEN_VERBOSE_ASSEMBLER_ERRORS
+
+/* Override disassembly hashing - there are variable bits in the top
+ byte of these instructions. */
+#define CGEN_DIS_HASH_SIZE 8
+#define CGEN_DIS_HASH(buf, value) (((* (unsigned char *) (buf)) >> 5) % CGEN_DIS_HASH_SIZE)
+
+#define CGEN_ASM_HASH_SIZE 127
+#define CGEN_ASM_HASH(insn) ms1_asm_hash (insn)
+
+extern unsigned int ms1_asm_hash (const char *);
+
+extern int ms1_cgen_insn_supported (CGEN_CPU_DESC, const CGEN_INSN *);
+
+\f
+/* -- opc.c */
+#include "safe-ctype.h"
+
+/* Special check to ensure that instruction exists for given machine. */
+
+int
+ms1_cgen_insn_supported (CGEN_CPU_DESC cd,
+ const CGEN_INSN *insn)
+{
+ int machs = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_MACH);
+
+ /* No mach attribute? Assume it's supported for all machs. */
+ if (machs == 0)
+ return 1;
+
+ return ((machs & cd->machs) != 0);
+}
+
+/* A better hash function for instruction mnemonics. */
+
+unsigned int
+ms1_asm_hash (const char* insn)
+{
+ unsigned int hash;
+ const char* m = insn;
+
+ for (hash = 0; *m && ! ISSPACE (*m); m++)
+ hash = (hash * 23) ^ (0x1F & TOLOWER (*m));
+
+ /* printf ("%s %d\n", insn, (hash % CGEN_ASM_HASH_SIZE)); */
+
+ return hash % CGEN_ASM_HASH_SIZE;
+}
+
+\f
+/* -- asm.c */
+/* Range checking for signed numbers. Returns 0 if acceptable
+ and 1 if the value is out of bounds for a signed quantity. */
+
+static int
+signed_out_of_bounds (long val)
+{
+ if ((val < -32768) || (val > 32767))
+ return 1;
+ return 0;
+}
+
+static const char *
+parse_loopsize (CGEN_CPU_DESC cd,
+ const char **strp,
+ int opindex,
+ void *arg)
+{
+ signed long * valuep = (signed long *) arg;
+ const char *errmsg;
+ bfd_reloc_code_real_type code = BFD_RELOC_NONE;
+ enum cgen_parse_operand_result result_type;
+ bfd_vma value;
+
+ /* Is it a control transfer instructions? */
+ if (opindex == (CGEN_OPERAND_TYPE) MS1_OPERAND_LOOPSIZE)
+ {
+ code = BFD_RELOC_MS1_PCINSN8;
+ errmsg = cgen_parse_address (cd, strp, opindex, code,
+ & result_type, & value);
+ *valuep = value;
+ return errmsg;
+ }
+
+ abort ();
+}
+
+static const char *
+parse_imm16 (CGEN_CPU_DESC cd,
+ const char **strp,
+ int opindex,
+ void *arg)
+{
+ signed long * valuep = (signed long *) arg;
+ const char *errmsg;
+ enum cgen_parse_operand_result result_type;
+ bfd_reloc_code_real_type code = BFD_RELOC_NONE;
+ bfd_vma value;
+
+ /* Is it a control transfer instructions? */
+ if (opindex == (CGEN_OPERAND_TYPE) MS1_OPERAND_IMM16O)
+ {
+ code = BFD_RELOC_16_PCREL;
+ errmsg = cgen_parse_address (cd, strp, opindex, code,
+ & result_type, & value);
+ if (errmsg == NULL)
+ {
+ if (signed_out_of_bounds (value))
+ errmsg = _("Operand out of range. Must be between -32768 and 32767.");
+ }
+ *valuep = value;
+ return errmsg;
+ }
+
+ /* If it's not a control transfer instruction, then
+ we have to check for %OP relocating operators. */
+ if (opindex == (CGEN_OPERAND_TYPE) MS1_OPERAND_IMM16L)
+ ;
+ else if (strncmp (*strp, "%hi16", 5) == 0)
+ {
+ *strp += 5;
+ code = BFD_RELOC_HI16;
+ }
+ else if (strncmp (*strp, "%lo16", 5) == 0)
+ {
+ *strp += 5;
+ code = BFD_RELOC_LO16;
+ }
+
+ /* If we found a %OP relocating operator, then parse it as an address.
+ If not, we need to parse it as an integer, either signed or unsigned
+ depending on which operand type we have. */
+ if (code != BFD_RELOC_NONE)
+ {
+ /* %OP relocating operator found. */
+ errmsg = cgen_parse_address (cd, strp, opindex, code,
+ & result_type, & value);
+ if (errmsg == NULL)
+ {
+ switch (result_type)
+ {
+ case (CGEN_PARSE_OPERAND_RESULT_NUMBER):
+ if (code == BFD_RELOC_HI16)
+ value = (value >> 16) & 0xFFFF;
+ else if (code == BFD_RELOC_LO16)
+ value = value & 0xFFFF;
+ else
+ errmsg = _("Biiiig Trouble in parse_imm16!");
+ break;
+
+ case (CGEN_PARSE_OPERAND_RESULT_QUEUED):
+ /* No special processing for this case. */
+ break;
+
+ default:
+ errmsg = _("%operator operand is not a symbol");
+ break;
+ }
+ }
+ *valuep = value;
+ }
+ else
+ {
+ /* Parse hex values like 0xffff as unsigned, and sign extend
+ them manually. */
+ int parse_signed = (opindex == (CGEN_OPERAND_TYPE)MS1_OPERAND_IMM16);
+
+ if ((*strp)[0] == '0'
+ && ((*strp)[1] == 'x' || (*strp)[1] == 'X'))
+ parse_signed = 0;
+
+ /* No relocating operator. Parse as an number. */
+ if (parse_signed)
+ {
+ /* Parse as as signed integer. */
+
+ errmsg = cgen_parse_signed_integer (cd, strp, opindex, valuep);
+
+ if (errmsg == NULL)
+ {
+#if 0
+ /* Manual range checking is needed for the signed case. */
+ if (*valuep & 0x8000)
+ value = 0xffff0000 | *valuep;
+ else
+ value = *valuep;
+
+ if (signed_out_of_bounds (value))
+ errmsg = _("Operand out of range. Must be between -32768 and 32767.");
+ /* Truncate to 16 bits. This is necessary
+ because cgen will have sign extended *valuep. */
+ *valuep &= 0xFFFF;
+#endif
+ }
+ }
+ else
+ {
+ /* MS1_OPERAND_IMM16Z. Parse as an unsigned integer. */
+ errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, (unsigned long *) valuep);
+
+ if (opindex == (CGEN_OPERAND_TYPE) MS1_OPERAND_IMM16
+ && *valuep >= 0x8000
+ && *valuep <= 0xffff)
+ *valuep -= 0x10000;
+ }
+ }
+
+ return errmsg;
+}
+
+
+static const char *
+parse_dup (CGEN_CPU_DESC cd,
+ const char **strp,
+ int opindex,
+ unsigned long *valuep)
+{
+ const char *errmsg = NULL;
+
+ if (strncmp (*strp, "dup", 3) == 0 || strncmp (*strp, "DUP", 3) == 0)
+ {
+ *strp += 3;
+ *valuep = 1;
+ }
+ else if (strncmp (*strp, "xx", 2) == 0 || strncmp (*strp, "XX", 2) == 0)
+ {
+ *strp += 2;
+ *valuep = 0;
+ }
+ else
+ errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
+
+ return errmsg;
+}
+
+
+static const char *
+parse_ball (CGEN_CPU_DESC cd,
+ const char **strp,
+ int opindex,
+ unsigned long *valuep)
+{
+ const char *errmsg = NULL;
+
+ if (strncmp (*strp, "all", 3) == 0 || strncmp (*strp, "ALL", 3) == 0)
+ {
+ *strp += 3;
+ *valuep = 1;
+ }
+ else if (strncmp (*strp, "one", 3) == 0 || strncmp (*strp, "ONE", 3) == 0)
+ {
+ *strp += 3;
+ *valuep = 0;
+ }
+ else
+ errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
+
+ return errmsg;
+}
+
+static const char *
+parse_xmode (CGEN_CPU_DESC cd,
+ const char **strp,
+ int opindex,
+ unsigned long *valuep)
+{
+ const char *errmsg = NULL;
+
+ if (strncmp (*strp, "pm", 2) == 0 || strncmp (*strp, "PM", 2) == 0)
+ {
+ *strp += 2;
+ *valuep = 1;
+ }
+ else if (strncmp (*strp, "xm", 2) == 0 || strncmp (*strp, "XM", 2) == 0)
+ {
+ *strp += 2;
+ *valuep = 0;
+ }
+ else
+ errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
+
+ return errmsg;
+}
+
+static const char *
+parse_rc (CGEN_CPU_DESC cd,
+ const char **strp,
+ int opindex,
+ unsigned long *valuep)
+{
+ const char *errmsg = NULL;
+
+ if (strncmp (*strp, "r", 1) == 0 || strncmp (*strp, "R", 1) == 0)
+ {
+ *strp += 1;
+ *valuep = 1;
+ }
+ else if (strncmp (*strp, "c", 1) == 0 || strncmp (*strp, "C", 1) == 0)
+ {
+ *strp += 1;
+ *valuep = 0;
+ }
+ else
+ errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
+
+ return errmsg;
+}
+
+static const char *
+parse_cbrb (CGEN_CPU_DESC cd,
+ const char **strp,
+ int opindex,
+ unsigned long *valuep)
+{
+ const char *errmsg = NULL;
+
+ if (strncmp (*strp, "rb", 2) == 0 || strncmp (*strp, "RB", 2) == 0)
+ {
+ *strp += 2;
+ *valuep = 1;
+ }
+ else if (strncmp (*strp, "cb", 2) == 0 || strncmp (*strp, "CB", 2) == 0)
+ {
+ *strp += 2;
+ *valuep = 0;
+ }
+ else
+ errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
+
+ return errmsg;
+}
+
+static const char *
+parse_rbbc (CGEN_CPU_DESC cd,
+ const char **strp,
+ int opindex,
+ unsigned long *valuep)
+{
+ const char *errmsg = NULL;
+
+ if (strncmp (*strp, "rt", 2) == 0 || strncmp (*strp, "RT", 2) == 0)
+ {
+ *strp += 2;
+ *valuep = 0;
+ }
+ else if (strncmp (*strp, "br1", 3) == 0 || strncmp (*strp, "BR1", 3) == 0)
+ {
+ *strp += 3;
+ *valuep = 1;
+ }
+ else if (strncmp (*strp, "br2", 3) == 0 || strncmp (*strp, "BR2", 3) == 0)
+ {
+ *strp += 3;
+ *valuep = 2;
+ }
+ else if (strncmp (*strp, "cs", 2) == 0 || strncmp (*strp, "CS", 2) == 0)
+ {
+ *strp += 2;
+ *valuep = 3;
+ }
+ else
+ errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
+
+ return errmsg;
+}
+
+static const char *
+parse_type (CGEN_CPU_DESC cd,
+ const char **strp,
+ int opindex,
+ unsigned long *valuep)
+{
+ const char *errmsg = NULL;
+
+ if (strncmp (*strp, "odd", 3) == 0 || strncmp (*strp, "ODD", 3) == 0)
+ {
+ *strp += 3;
+ *valuep = 0;
+ }
+ else if (strncmp (*strp, "even", 4) == 0 || strncmp (*strp, "EVEN", 4) == 0)
+ {
+ *strp += 4;
+ *valuep = 1;
+ }
+ else if (strncmp (*strp, "oe", 2) == 0 || strncmp (*strp, "OE", 2) == 0)
+ {
+ *strp += 2;
+ *valuep = 2;
+ }
+ else
+ errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
+
+ if ((errmsg == NULL) && (*valuep == 3))
+ errmsg = _("invalid operand. type may have values 0,1,2 only.");
+
+ return errmsg;
+}
+
+/* -- dis.c */
+static void print_dollarhex (CGEN_CPU_DESC, PTR, long, unsigned, bfd_vma, int);
+static void print_pcrel (CGEN_CPU_DESC, PTR, long, unsigned, bfd_vma, int);
+
+static void
+print_dollarhex (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
+ void * dis_info,
+ long value,
+ unsigned int attrs ATTRIBUTE_UNUSED,
+ bfd_vma pc ATTRIBUTE_UNUSED,
+ int length ATTRIBUTE_UNUSED)
+{
+ disassemble_info *info = (disassemble_info *) dis_info;
+
+ info->fprintf_func (info->stream, "$%lx", value);
+
+ if (0)
+ print_normal (cd, dis_info, value, attrs, pc, length);
+}
+
+static void
+print_pcrel (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
+ void * dis_info,
+ long value,
+ unsigned int attrs ATTRIBUTE_UNUSED,
+ bfd_vma pc ATTRIBUTE_UNUSED,
+ int length ATTRIBUTE_UNUSED)
+{
+ print_address (cd, dis_info, value + pc, attrs, pc, length);
+}
+
+/* -- */
+
+
+
+
+
+++ /dev/null
-/* tc-ms1.c -- Assembler for the Morpho Technologies ms-I.
- Copyright (C) 2005 Free Software Foundation.
-
- 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, 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
-
-#include <stdio.h>
-#include "as.h"
-#include "dwarf2dbg.h"
-#include "subsegs.h"
-#include "symcat.h"
-#include "opcodes/ms1-desc.h"
-#include "opcodes/ms1-opc.h"
-#include "cgen.h"
-#include "elf/common.h"
-#include "elf/ms1.h"
-#include "libbfd.h"
-
-/* Structure to hold all of the different components
- describing an individual instruction. */
-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];
-}
-ms1_insn;
-
-
-const char comment_chars[] = ";";
-const char line_comment_chars[] = "#";
-const char line_separator_chars[] = "";
-const char EXP_CHARS[] = "eE";
-const char FLT_CHARS[] = "dD";
-
-/* The target specific pseudo-ops which we support. */
-const pseudo_typeS md_pseudo_table[] =
-{
- { "word", cons, 4 },
- { NULL, NULL, 0 }
-};
-
-\f
-
-static int no_scheduling_restrictions = 0;
-
-struct option md_longopts[] =
-{
-#define OPTION_NO_SCHED_REST (OPTION_MD_BASE)
- { "nosched", no_argument, NULL, OPTION_NO_SCHED_REST },
-#define OPTION_MARCH (OPTION_MD_BASE + 1)
- { "march", required_argument, NULL, OPTION_MARCH},
- { NULL, no_argument, NULL, 0 },
-};
-size_t md_longopts_size = sizeof (md_longopts);
-
-const char * md_shortopts = "";
-
-/* Mach selected from command line. */
-static int ms1_mach = bfd_mach_ms1;
-static unsigned ms1_mach_bitmask = 1 << MACH_MS1;
-
-/* Flags to set in the elf header */
-static flagword ms1_flags = EF_MS1_CPU_MRISC;
-
-/* The architecture to use. */
-enum ms1_architectures
- {
- ms1_64_001,
- ms1_16_002,
- ms1_16_003,
- ms2
- };
-
-/* MS1 architecture we are using for this output file. */
-static enum ms1_architectures ms1_arch = ms1_64_001;
-
-int
-md_parse_option (int c ATTRIBUTE_UNUSED, char * arg)
-{
- switch (c)
- {
- case OPTION_MARCH:
- if (strcasecmp (arg, "MS1-64-001") == 0)
- {
- ms1_flags = (ms1_flags & ~EF_MS1_CPU_MASK) | EF_MS1_CPU_MRISC;
- ms1_mach = bfd_mach_ms1;
- ms1_mach_bitmask = 1 << MACH_MS1;
- ms1_arch = ms1_64_001;
- }
- else if (strcasecmp (arg, "MS1-16-002") == 0)
- {
- ms1_flags = (ms1_flags & ~EF_MS1_CPU_MASK) | EF_MS1_CPU_MRISC;
- ms1_mach = bfd_mach_ms1;
- ms1_mach_bitmask = 1 << MACH_MS1;
- ms1_arch = ms1_16_002;
- }
- else if (strcasecmp (arg, "MS1-16-003") == 0)
- {
- ms1_flags = (ms1_flags & ~EF_MS1_CPU_MASK) | EF_MS1_CPU_MRISC2;
- ms1_mach = bfd_mach_mrisc2;
- ms1_mach_bitmask = 1 << MACH_MS1_003;
- ms1_arch = ms1_16_003;
- }
- else if (strcasecmp (arg, "MS2") == 0)
- {
- ms1_flags = (ms1_flags & ~EF_MS1_CPU_MASK) | EF_MS1_CPU_MS2;
- ms1_mach = bfd_mach_mrisc2;
- ms1_mach_bitmask = 1 << MACH_MS2;
- ms1_arch = ms2;
- }
- case OPTION_NO_SCHED_REST:
- no_scheduling_restrictions = 1;
- break;
- default:
- return 0;
- }
-
- return 1;
-}
-
-
-void
-md_show_usage (FILE * stream)
-{
- fprintf (stream, _("MS1 specific command line options:\n"));
- fprintf (stream, _(" -march=ms1-64-001 allow ms1-64-001 instructions (default) \n"));
- fprintf (stream, _(" -march=ms1-16-002 allow ms1-16-002 instructions \n"));
- fprintf (stream, _(" -march=ms1-16-003 allow ms1-16-003 instructions \n"));
- fprintf (stream, _(" -march=ms2 allow ms2 instructions \n"));
- fprintf (stream, _(" -nosched disable scheduling restrictions \n"));
-}
-
-\f
-void
-md_begin (void)
-{
- /* Initialize the `cgen' interface. */
-
- /* Set the machine number and endian. */
- gas_cgen_cpu_desc = ms1_cgen_cpu_open (CGEN_CPU_OPEN_MACHS, ms1_mach_bitmask,
- CGEN_CPU_OPEN_ENDIAN,
- CGEN_ENDIAN_BIG,
- CGEN_CPU_OPEN_END);
- ms1_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);
-
- /* Set the ELF flags if desired. */
- if (ms1_flags)
- bfd_set_private_flags (stdoutput, ms1_flags);
-
- /* Set the machine type. */
- bfd_default_set_arch_mach (stdoutput, bfd_arch_ms1, ms1_mach);
-}
-
-void
-md_assemble (char * str)
-{
- static long delayed_load_register = 0;
- static long prev_delayed_load_register = 0;
- static int last_insn_had_delay_slot = 0;
- static int last_insn_in_noncond_delay_slot = 0;
- static int last_insn_has_load_delay = 0;
- static int last_insn_was_memory_access = 0;
- static int last_insn_was_io_insn = 0;
- static int last_insn_was_arithmetic_or_logic = 0;
- static int last_insn_was_branch_insn = 0;
- static int last_insn_was_conditional_branch_insn = 0;
-
- ms1_insn insn;
- char * errmsg;
-
- /* Initialize GAS's cgen interface for a new instruction. */
- gas_cgen_init_parse ();
-
- insn.insn = ms1_cgen_assemble_insn
- (gas_cgen_cpu_desc, str, & insn.fields, insn.buffer, & errmsg);
-
- if (!insn.insn)
- {
- as_bad ("%s", errmsg);
- return;
- }
-
- /* Doesn't really matter what we pass for RELAX_P here. */
- gas_cgen_finish_insn (insn.insn, insn.buffer,
- CGEN_FIELDS_BITSIZE (& insn.fields), 1, NULL);
-
-
- /* Handle Scheduling Restrictions. */
- if (!no_scheduling_restrictions)
- {
- /* Detect consecutive Memory Accesses. */
- if (last_insn_was_memory_access
- && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_MEMORY_ACCESS)
- && ms1_mach == ms1_64_001)
- as_warn (_("instruction %s may not follow another memory access instruction."),
- CGEN_INSN_NAME (insn.insn));
-
- /* Detect consecutive I/O Instructions. */
- else if (last_insn_was_io_insn
- && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_IO_INSN))
- as_warn (_("instruction %s may not follow another I/O instruction."),
- CGEN_INSN_NAME (insn.insn));
-
- /* Detect consecutive branch instructions. */
- else if (last_insn_was_branch_insn
- && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_BR_INSN))
- as_warn (_("%s may not occupy the delay slot of another branch insn."),
- CGEN_INSN_NAME (insn.insn));
-
- /* Detect data dependencies on delayed loads: memory and input insns. */
- if (last_insn_has_load_delay && delayed_load_register)
- {
- if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR1)
- && insn.fields.f_sr1 == delayed_load_register)
- as_warn (_("operand references R%ld of previous load."),
- insn.fields.f_sr1);
-
- if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR2)
- && insn.fields.f_sr2 == delayed_load_register)
- as_warn (_("operand references R%ld of previous load."),
- insn.fields.f_sr2);
- }
-
- /* Detect JAL/RETI hazard */
- if (ms1_mach == ms2
- && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_JAL_HAZARD))
- {
- if ((CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR1)
- && insn.fields.f_sr1 == delayed_load_register)
- || (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR2)
- && insn.fields.f_sr2 == delayed_load_register))
- as_warn (_("operand references R%ld of previous instrutcion."),
- delayed_load_register);
- else if ((CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR1)
- && insn.fields.f_sr1 == prev_delayed_load_register)
- || (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR2)
- && insn.fields.f_sr2 == prev_delayed_load_register))
- as_warn (_("operand references R%ld of instructcion before previous."),
- prev_delayed_load_register);
- }
-
- /* Detect data dependency between conditional branch instruction
- and an immediately preceding arithmetic or logical instruction. */
- if (last_insn_was_arithmetic_or_logic
- && !last_insn_in_noncond_delay_slot
- && (delayed_load_register != 0)
- && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_BR_INSN)
- && ms1_arch == ms1_64_001)
- {
- if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR1)
- && insn.fields.f_sr1 == delayed_load_register)
- as_warn (_("conditional branch or jal insn's operand references R%ld of previous arithmetic or logic insn."),
- insn.fields.f_sr1);
-
- if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR2)
- && insn.fields.f_sr2 == delayed_load_register)
- as_warn (_("conditional branch or jal insn's operand references R%ld of previous arithmetic or logic insn."),
- insn.fields.f_sr2);
- }
- }
-
- /* Keep track of details of this insn for processing next insn. */
- last_insn_in_noncond_delay_slot = last_insn_was_branch_insn
- && !last_insn_was_conditional_branch_insn;
-
- last_insn_had_delay_slot =
- CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_DELAY_SLOT);
-
- last_insn_has_load_delay =
- CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_LOAD_DELAY);
-
- last_insn_was_memory_access =
- CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_MEMORY_ACCESS);
-
- last_insn_was_io_insn =
- CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_IO_INSN);
-
- last_insn_was_arithmetic_or_logic =
- CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_AL_INSN);
-
- last_insn_was_branch_insn =
- CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_BR_INSN);
-
- last_insn_was_conditional_branch_insn =
- CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_BR_INSN)
- && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR2);
-
- prev_delayed_load_register = delayed_load_register;
-
- if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRDR))
- delayed_load_register = insn.fields.f_dr;
- else if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRDRRR))
- delayed_load_register = insn.fields.f_drrr;
- else /* Insns has no destination register. */
- delayed_load_register = 0;
-
- /* Generate dwarf2 line numbers. */
- dwarf2_emit_insn (4);
-}
-
-valueT
-md_section_align (segT segment, valueT size)
-{
- int align = bfd_get_section_alignment (stdoutput, segment);
-
- return ((size + (1 << align) - 1) & (-1 << align));
-}
-
-symbolS *
-md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
-{
- return NULL;
-}
-\f
-int
-md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
- segT segment ATTRIBUTE_UNUSED)
-{
- as_fatal (_("md_estimate_size_before_relax\n"));
- return 1;
-}
-
-/* *fragP has been relaxed to its final size, and now needs to have
- the bytes inside it modified to conform to the new size.
-
- Called after relaxation is finished.
- fragP->fr_type == rs_machine_dependent.
- fragP->fr_subtype is the subtype of what the address relaxed to. */
-
-void
-md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
- segT sec ATTRIBUTE_UNUSED,
- fragS * fragP ATTRIBUTE_UNUSED)
-{
-}
-
-\f
-/* Functions concerning relocs. */
-
-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;
-
- /* Return the address of the opcode - cgen adjusts for opcode size
- itself, to be consistent with the disassembler, which must do
- so. */
- return fixP->fx_where + fixP->fx_frag->fr_address;
-}
-
-
-/* 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)
-{
- bfd_reloc_code_real_type result;
-
- result = BFD_RELOC_NONE;
-
- switch (operand->type)
- {
- case MS1_OPERAND_IMM16O:
- result = BFD_RELOC_16_PCREL;
- fixP->fx_pcrel = 1;
- /* fixP->fx_no_overflow = 1; */
- break;
- case MS1_OPERAND_IMM16:
- case MS1_OPERAND_IMM16Z:
- /* These may have been processed at parse time. */
- if (fixP->fx_cgen.opinfo != 0)
- result = fixP->fx_cgen.opinfo;
- fixP->fx_no_overflow = 1;
- break;
- case MS1_OPERAND_LOOPSIZE:
- result = BFD_RELOC_MS1_PCINSN8;
- fixP->fx_pcrel = 1;
- /* Adjust for the delay slot, which is not part of the loop */
- fixP->fx_offset -= 8;
- break;
- default:
- result = BFD_RELOC_NONE;
- break;
- }
-
- return result;
-}
-
-/* Write a value out to the object file, using the appropriate endianness. */
-
-void
-md_number_to_chars (char * buf, valueT val, int n)
-{
- number_to_chars_bigendian (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. */
-
-/* Equal to MAX_PRECISION in atof-ieee.c. */
-#define MAX_LITTLENUMS 6
-
-char *
-md_atof (type, litP, sizeP)
- char type;
- char * litP;
- int * sizeP;
-{
- int prec;
- LITTLENUM_TYPE words [MAX_LITTLENUMS];
- LITTLENUM_TYPE * wordP;
- char * t;
-
- switch (type)
- {
- case 'f':
- case 'F':
- case 's':
- case 'S':
- prec = 2;
- break;
-
- case 'd':
- case 'D':
- case 'r':
- case 'R':
- prec = 4;
- break;
-
- /* FIXME: Some targets allow other format chars for bigger sizes here. */
-
- 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);
-
- /* This loops outputs the LITTLENUMs in REVERSE order;
- in accord with the ms1 endianness. */
- for (wordP = words; prec--;)
- {
- md_number_to_chars (litP, (valueT) (*wordP++), sizeof (LITTLENUM_TYPE));
- litP += sizeof (LITTLENUM_TYPE);
- }
-
- return 0;
-}
-
-/* See whether we need to force a relocation into the output file. */
-
-int
-ms1_force_relocation (fixS * fixp ATTRIBUTE_UNUSED)
-{
- return 0;
-}
-
-void
-ms1_apply_fix (fixS *fixP, valueT *valueP, segT seg)
-{
- if ((fixP->fx_pcrel != 0) && (fixP->fx_r_type == BFD_RELOC_32))
- fixP->fx_r_type = BFD_RELOC_32_PCREL;
-
- gas_cgen_md_apply_fix (fixP, valueP, seg);
-}
-
-bfd_boolean
-ms1_fix_adjustable (fixS * fixP)
-{
- bfd_reloc_code_real_type reloc_type;
-
- if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
- {
- const CGEN_INSN *insn = NULL;
- int opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
- const CGEN_OPERAND *operand;
-
- operand = cgen_operand_lookup_by_num(gas_cgen_cpu_desc, opindex);
- reloc_type = md_cgen_lookup_reloc (insn, operand, fixP);
- }
- else
- reloc_type = fixP->fx_r_type;
-
- if (fixP->fx_addsy == NULL)
- return TRUE;
-
- /* Prevent all adjustments to global symbols. */
- if (S_IS_EXTERNAL (fixP->fx_addsy))
- return FALSE;
-
- if (S_IS_WEAK (fixP->fx_addsy))
- return FALSE;
-
- return 1;
-}
+++ /dev/null
-/* tc-ms1.h -- Header file for tc-ms1.c.
- Copyright (C) 2005 Free Software Foundation, Inc.
-
- 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, 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
-
-#define TC_MS1
-
-#define LISTING_HEADER "MS1 GAS "
-
-/* The target BFD architecture. */
-#define TARGET_ARCH bfd_arch_ms1
-
-#define TARGET_FORMAT "elf32-ms1"
-
-#define TARGET_BYTES_BIG_ENDIAN 1
-
-/* Permit temporary numeric labels. */
-#define LOCAL_LABELS_FB 1
-
-/* .-foo gets turned into PC relative relocs. */
-#define DIFF_EXPR_OK
-
-/* We don't need to handle .word strangely. */
-#define WORKING_DOT_WORD
-
-/* All ms1 instructions are multiples of 32 bits. */
-#define DWARF2_LINE_MIN_INSN_LENGTH 4
-
-#define LITERAL_PREFIXDOLLAR_HEX
-#define LITERAL_PREFIXPERCENT_BIN
-
-#define md_apply_fix ms1_apply_fix
-extern void ms1_apply_fix (struct fix *, valueT *, segT);
-
-/* Call md_pcrel_from_section(), not md_pcrel_from(). */
-#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section (FIXP, SEC)
-extern long md_pcrel_from_section (struct fix *, segT);
-
-#define obj_fix_adjustable(fixP) iq2000_fix_adjustable (fixP)
-extern bfd_boolean ms1_fix_adjustable (struct fix *);
-
-/* Values passed to md_apply_fix don't include the symbol value. */
-#define MD_APPLY_SYM_VALUE(FIX) 0
-
-#define tc_gen_reloc gas_cgen_tc_gen_reloc
-
-#define md_operand(x) gas_cgen_md_operand (x)
-extern void gas_cgen_md_operand (expressionS *);
-
-#define TC_FORCE_RELOCATION(fixp) ms1_force_relocation (fixp)
-extern int ms1_force_relocation (struct fix *);
-
-#define tc_fix_adjustable(fixP) ms1_fix_adjustable (fixP)
-extern bfd_boolean ms1_fix_adjustable (struct fix *);
-
--- /dev/null
+/* tc-ms1.c -- Assembler for the Morpho Technologies ms-I.
+ Copyright (C) 2005 Free Software Foundation.
+
+ 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, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include "as.h"
+#include "dwarf2dbg.h"
+#include "subsegs.h"
+#include "symcat.h"
+#include "opcodes/ms1-desc.h"
+#include "opcodes/ms1-opc.h"
+#include "cgen.h"
+#include "elf/common.h"
+#include "elf/ms1.h"
+#include "libbfd.h"
+
+/* Structure to hold all of the different components
+ describing an individual instruction. */
+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];
+}
+ms1_insn;
+
+
+const char comment_chars[] = ";";
+const char line_comment_chars[] = "#";
+const char line_separator_chars[] = "";
+const char EXP_CHARS[] = "eE";
+const char FLT_CHARS[] = "dD";
+
+/* The target specific pseudo-ops which we support. */
+const pseudo_typeS md_pseudo_table[] =
+{
+ { "word", cons, 4 },
+ { NULL, NULL, 0 }
+};
+
+\f
+
+static int no_scheduling_restrictions = 0;
+
+struct option md_longopts[] =
+{
+#define OPTION_NO_SCHED_REST (OPTION_MD_BASE)
+ { "nosched", no_argument, NULL, OPTION_NO_SCHED_REST },
+#define OPTION_MARCH (OPTION_MD_BASE + 1)
+ { "march", required_argument, NULL, OPTION_MARCH},
+ { NULL, no_argument, NULL, 0 },
+};
+size_t md_longopts_size = sizeof (md_longopts);
+
+const char * md_shortopts = "";
+
+/* Mach selected from command line. */
+static int ms1_mach = bfd_mach_ms1;
+static unsigned ms1_mach_bitmask = 1 << MACH_MS1;
+
+/* Flags to set in the elf header */
+static flagword ms1_flags = EF_MS1_CPU_MRISC;
+
+/* The architecture to use. */
+enum ms1_architectures
+ {
+ ms1_64_001,
+ ms1_16_002,
+ ms1_16_003,
+ ms2
+ };
+
+/* MS1 architecture we are using for this output file. */
+static enum ms1_architectures ms1_arch = ms1_64_001;
+
+int
+md_parse_option (int c ATTRIBUTE_UNUSED, char * arg)
+{
+ switch (c)
+ {
+ case OPTION_MARCH:
+ if (strcasecmp (arg, "MS1-64-001") == 0)
+ {
+ ms1_flags = (ms1_flags & ~EF_MS1_CPU_MASK) | EF_MS1_CPU_MRISC;
+ ms1_mach = bfd_mach_ms1;
+ ms1_mach_bitmask = 1 << MACH_MS1;
+ ms1_arch = ms1_64_001;
+ }
+ else if (strcasecmp (arg, "MS1-16-002") == 0)
+ {
+ ms1_flags = (ms1_flags & ~EF_MS1_CPU_MASK) | EF_MS1_CPU_MRISC;
+ ms1_mach = bfd_mach_ms1;
+ ms1_mach_bitmask = 1 << MACH_MS1;
+ ms1_arch = ms1_16_002;
+ }
+ else if (strcasecmp (arg, "MS1-16-003") == 0)
+ {
+ ms1_flags = (ms1_flags & ~EF_MS1_CPU_MASK) | EF_MS1_CPU_MRISC2;
+ ms1_mach = bfd_mach_mrisc2;
+ ms1_mach_bitmask = 1 << MACH_MS1_003;
+ ms1_arch = ms1_16_003;
+ }
+ else if (strcasecmp (arg, "MS2") == 0)
+ {
+ ms1_flags = (ms1_flags & ~EF_MS1_CPU_MASK) | EF_MS1_CPU_MS2;
+ ms1_mach = bfd_mach_mrisc2;
+ ms1_mach_bitmask = 1 << MACH_MS2;
+ ms1_arch = ms2;
+ }
+ case OPTION_NO_SCHED_REST:
+ no_scheduling_restrictions = 1;
+ break;
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+
+void
+md_show_usage (FILE * stream)
+{
+ fprintf (stream, _("MS1 specific command line options:\n"));
+ fprintf (stream, _(" -march=ms1-64-001 allow ms1-64-001 instructions (default) \n"));
+ fprintf (stream, _(" -march=ms1-16-002 allow ms1-16-002 instructions \n"));
+ fprintf (stream, _(" -march=ms1-16-003 allow ms1-16-003 instructions \n"));
+ fprintf (stream, _(" -march=ms2 allow ms2 instructions \n"));
+ fprintf (stream, _(" -nosched disable scheduling restrictions \n"));
+}
+
+\f
+void
+md_begin (void)
+{
+ /* Initialize the `cgen' interface. */
+
+ /* Set the machine number and endian. */
+ gas_cgen_cpu_desc = ms1_cgen_cpu_open (CGEN_CPU_OPEN_MACHS, ms1_mach_bitmask,
+ CGEN_CPU_OPEN_ENDIAN,
+ CGEN_ENDIAN_BIG,
+ CGEN_CPU_OPEN_END);
+ ms1_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);
+
+ /* Set the ELF flags if desired. */
+ if (ms1_flags)
+ bfd_set_private_flags (stdoutput, ms1_flags);
+
+ /* Set the machine type. */
+ bfd_default_set_arch_mach (stdoutput, bfd_arch_ms1, ms1_mach);
+}
+
+void
+md_assemble (char * str)
+{
+ static long delayed_load_register = 0;
+ static long prev_delayed_load_register = 0;
+ static int last_insn_had_delay_slot = 0;
+ static int last_insn_in_noncond_delay_slot = 0;
+ static int last_insn_has_load_delay = 0;
+ static int last_insn_was_memory_access = 0;
+ static int last_insn_was_io_insn = 0;
+ static int last_insn_was_arithmetic_or_logic = 0;
+ static int last_insn_was_branch_insn = 0;
+ static int last_insn_was_conditional_branch_insn = 0;
+
+ ms1_insn insn;
+ char * errmsg;
+
+ /* Initialize GAS's cgen interface for a new instruction. */
+ gas_cgen_init_parse ();
+
+ insn.insn = ms1_cgen_assemble_insn
+ (gas_cgen_cpu_desc, str, & insn.fields, insn.buffer, & errmsg);
+
+ if (!insn.insn)
+ {
+ as_bad ("%s", errmsg);
+ return;
+ }
+
+ /* Doesn't really matter what we pass for RELAX_P here. */
+ gas_cgen_finish_insn (insn.insn, insn.buffer,
+ CGEN_FIELDS_BITSIZE (& insn.fields), 1, NULL);
+
+
+ /* Handle Scheduling Restrictions. */
+ if (!no_scheduling_restrictions)
+ {
+ /* Detect consecutive Memory Accesses. */
+ if (last_insn_was_memory_access
+ && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_MEMORY_ACCESS)
+ && ms1_mach == ms1_64_001)
+ as_warn (_("instruction %s may not follow another memory access instruction."),
+ CGEN_INSN_NAME (insn.insn));
+
+ /* Detect consecutive I/O Instructions. */
+ else if (last_insn_was_io_insn
+ && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_IO_INSN))
+ as_warn (_("instruction %s may not follow another I/O instruction."),
+ CGEN_INSN_NAME (insn.insn));
+
+ /* Detect consecutive branch instructions. */
+ else if (last_insn_was_branch_insn
+ && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_BR_INSN))
+ as_warn (_("%s may not occupy the delay slot of another branch insn."),
+ CGEN_INSN_NAME (insn.insn));
+
+ /* Detect data dependencies on delayed loads: memory and input insns. */
+ if (last_insn_has_load_delay && delayed_load_register)
+ {
+ if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR1)
+ && insn.fields.f_sr1 == delayed_load_register)
+ as_warn (_("operand references R%ld of previous load."),
+ insn.fields.f_sr1);
+
+ if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR2)
+ && insn.fields.f_sr2 == delayed_load_register)
+ as_warn (_("operand references R%ld of previous load."),
+ insn.fields.f_sr2);
+ }
+
+ /* Detect JAL/RETI hazard */
+ if (ms1_mach == ms2
+ && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_JAL_HAZARD))
+ {
+ if ((CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR1)
+ && insn.fields.f_sr1 == delayed_load_register)
+ || (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR2)
+ && insn.fields.f_sr2 == delayed_load_register))
+ as_warn (_("operand references R%ld of previous instrutcion."),
+ delayed_load_register);
+ else if ((CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR1)
+ && insn.fields.f_sr1 == prev_delayed_load_register)
+ || (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR2)
+ && insn.fields.f_sr2 == prev_delayed_load_register))
+ as_warn (_("operand references R%ld of instructcion before previous."),
+ prev_delayed_load_register);
+ }
+
+ /* Detect data dependency between conditional branch instruction
+ and an immediately preceding arithmetic or logical instruction. */
+ if (last_insn_was_arithmetic_or_logic
+ && !last_insn_in_noncond_delay_slot
+ && (delayed_load_register != 0)
+ && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_BR_INSN)
+ && ms1_arch == ms1_64_001)
+ {
+ if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR1)
+ && insn.fields.f_sr1 == delayed_load_register)
+ as_warn (_("conditional branch or jal insn's operand references R%ld of previous arithmetic or logic insn."),
+ insn.fields.f_sr1);
+
+ if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR2)
+ && insn.fields.f_sr2 == delayed_load_register)
+ as_warn (_("conditional branch or jal insn's operand references R%ld of previous arithmetic or logic insn."),
+ insn.fields.f_sr2);
+ }
+ }
+
+ /* Keep track of details of this insn for processing next insn. */
+ last_insn_in_noncond_delay_slot = last_insn_was_branch_insn
+ && !last_insn_was_conditional_branch_insn;
+
+ last_insn_had_delay_slot =
+ CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_DELAY_SLOT);
+
+ last_insn_has_load_delay =
+ CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_LOAD_DELAY);
+
+ last_insn_was_memory_access =
+ CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_MEMORY_ACCESS);
+
+ last_insn_was_io_insn =
+ CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_IO_INSN);
+
+ last_insn_was_arithmetic_or_logic =
+ CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_AL_INSN);
+
+ last_insn_was_branch_insn =
+ CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_BR_INSN);
+
+ last_insn_was_conditional_branch_insn =
+ CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_BR_INSN)
+ && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR2);
+
+ prev_delayed_load_register = delayed_load_register;
+
+ if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRDR))
+ delayed_load_register = insn.fields.f_dr;
+ else if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRDRRR))
+ delayed_load_register = insn.fields.f_drrr;
+ else /* Insns has no destination register. */
+ delayed_load_register = 0;
+
+ /* Generate dwarf2 line numbers. */
+ dwarf2_emit_insn (4);
+}
+
+valueT
+md_section_align (segT segment, valueT size)
+{
+ int align = bfd_get_section_alignment (stdoutput, segment);
+
+ return ((size + (1 << align) - 1) & (-1 << align));
+}
+
+symbolS *
+md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
+{
+ return NULL;
+}
+\f
+int
+md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
+ segT segment ATTRIBUTE_UNUSED)
+{
+ as_fatal (_("md_estimate_size_before_relax\n"));
+ return 1;
+}
+
+/* *fragP has been relaxed to its final size, and now needs to have
+ the bytes inside it modified to conform to the new size.
+
+ Called after relaxation is finished.
+ fragP->fr_type == rs_machine_dependent.
+ fragP->fr_subtype is the subtype of what the address relaxed to. */
+
+void
+md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
+ segT sec ATTRIBUTE_UNUSED,
+ fragS * fragP ATTRIBUTE_UNUSED)
+{
+}
+
+\f
+/* Functions concerning relocs. */
+
+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;
+
+ /* Return the address of the opcode - cgen adjusts for opcode size
+ itself, to be consistent with the disassembler, which must do
+ so. */
+ return fixP->fx_where + fixP->fx_frag->fr_address;
+}
+
+
+/* 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)
+{
+ bfd_reloc_code_real_type result;
+
+ result = BFD_RELOC_NONE;
+
+ switch (operand->type)
+ {
+ case MS1_OPERAND_IMM16O:
+ result = BFD_RELOC_16_PCREL;
+ fixP->fx_pcrel = 1;
+ /* fixP->fx_no_overflow = 1; */
+ break;
+ case MS1_OPERAND_IMM16:
+ case MS1_OPERAND_IMM16Z:
+ /* These may have been processed at parse time. */
+ if (fixP->fx_cgen.opinfo != 0)
+ result = fixP->fx_cgen.opinfo;
+ fixP->fx_no_overflow = 1;
+ break;
+ case MS1_OPERAND_LOOPSIZE:
+ result = BFD_RELOC_MS1_PCINSN8;
+ fixP->fx_pcrel = 1;
+ /* Adjust for the delay slot, which is not part of the loop */
+ fixP->fx_offset -= 8;
+ break;
+ default:
+ result = BFD_RELOC_NONE;
+ break;
+ }
+
+ return result;
+}
+
+/* Write a value out to the object file, using the appropriate endianness. */
+
+void
+md_number_to_chars (char * buf, valueT val, int n)
+{
+ number_to_chars_bigendian (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. */
+
+/* Equal to MAX_PRECISION in atof-ieee.c. */
+#define MAX_LITTLENUMS 6
+
+char *
+md_atof (type, litP, sizeP)
+ char type;
+ char * litP;
+ int * sizeP;
+{
+ int prec;
+ LITTLENUM_TYPE words [MAX_LITTLENUMS];
+ LITTLENUM_TYPE * wordP;
+ char * t;
+
+ switch (type)
+ {
+ case 'f':
+ case 'F':
+ case 's':
+ case 'S':
+ prec = 2;
+ break;
+
+ case 'd':
+ case 'D':
+ case 'r':
+ case 'R':
+ prec = 4;
+ break;
+
+ /* FIXME: Some targets allow other format chars for bigger sizes here. */
+
+ 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);
+
+ /* This loops outputs the LITTLENUMs in REVERSE order;
+ in accord with the ms1 endianness. */
+ for (wordP = words; prec--;)
+ {
+ md_number_to_chars (litP, (valueT) (*wordP++), sizeof (LITTLENUM_TYPE));
+ litP += sizeof (LITTLENUM_TYPE);
+ }
+
+ return 0;
+}
+
+/* See whether we need to force a relocation into the output file. */
+
+int
+ms1_force_relocation (fixS * fixp ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+void
+ms1_apply_fix (fixS *fixP, valueT *valueP, segT seg)
+{
+ if ((fixP->fx_pcrel != 0) && (fixP->fx_r_type == BFD_RELOC_32))
+ fixP->fx_r_type = BFD_RELOC_32_PCREL;
+
+ gas_cgen_md_apply_fix (fixP, valueP, seg);
+}
+
+bfd_boolean
+ms1_fix_adjustable (fixS * fixP)
+{
+ bfd_reloc_code_real_type reloc_type;
+
+ if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
+ {
+ const CGEN_INSN *insn = NULL;
+ int opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
+ const CGEN_OPERAND *operand;
+
+ operand = cgen_operand_lookup_by_num(gas_cgen_cpu_desc, opindex);
+ reloc_type = md_cgen_lookup_reloc (insn, operand, fixP);
+ }
+ else
+ reloc_type = fixP->fx_r_type;
+
+ if (fixP->fx_addsy == NULL)
+ return TRUE;
+
+ /* Prevent all adjustments to global symbols. */
+ if (S_IS_EXTERNAL (fixP->fx_addsy))
+ return FALSE;
+
+ if (S_IS_WEAK (fixP->fx_addsy))
+ return FALSE;
+
+ return 1;
+}
--- /dev/null
+/* tc-ms1.h -- Header file for tc-ms1.c.
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+ 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, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#define TC_MS1
+
+#define LISTING_HEADER "MS1 GAS "
+
+/* The target BFD architecture. */
+#define TARGET_ARCH bfd_arch_ms1
+
+#define TARGET_FORMAT "elf32-ms1"
+
+#define TARGET_BYTES_BIG_ENDIAN 1
+
+/* Permit temporary numeric labels. */
+#define LOCAL_LABELS_FB 1
+
+/* .-foo gets turned into PC relative relocs. */
+#define DIFF_EXPR_OK
+
+/* We don't need to handle .word strangely. */
+#define WORKING_DOT_WORD
+
+/* All ms1 instructions are multiples of 32 bits. */
+#define DWARF2_LINE_MIN_INSN_LENGTH 4
+
+#define LITERAL_PREFIXDOLLAR_HEX
+#define LITERAL_PREFIXPERCENT_BIN
+
+#define md_apply_fix ms1_apply_fix
+extern void ms1_apply_fix (struct fix *, valueT *, segT);
+
+/* Call md_pcrel_from_section(), not md_pcrel_from(). */
+#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section (FIXP, SEC)
+extern long md_pcrel_from_section (struct fix *, segT);
+
+#define obj_fix_adjustable(fixP) iq2000_fix_adjustable (fixP)
+extern bfd_boolean ms1_fix_adjustable (struct fix *);
+
+/* Values passed to md_apply_fix don't include the symbol value. */
+#define MD_APPLY_SYM_VALUE(FIX) 0
+
+#define tc_gen_reloc gas_cgen_tc_gen_reloc
+
+#define md_operand(x) gas_cgen_md_operand (x)
+extern void gas_cgen_md_operand (expressionS *);
+
+#define TC_FORCE_RELOCATION(fixp) ms1_force_relocation (fixp)
+extern int ms1_force_relocation (struct fix *);
+
+#define tc_fix_adjustable(fixP) ms1_fix_adjustable (fixP)
+extern bfd_boolean ms1_fix_adjustable (struct fix *);
+
+++ /dev/null
-@c Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
-@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 MS1-Dependent
-@chapter MS1 Dependent Features
-@end ifset
-
-@ifclear GENERIC
-@node Machine Dependencies
-@chapter MS1 Dependent Features
-@end ifclear
-
-@cindex MS1 support
-@menu
-* MS1 Options:: Options
-@end menu
-
-@node MS1 Options
-@section Options
-@cindex MS1 options (none)
-@cindex options for MS1 (none)
-
-@table @code
-
-@cindex @code{-march=} command line option, MS1
-@item -march=@var{processor}
-This option specifies the target processor. The assembler will issue an
-error message if an attempt is made to assemble an instruction which
-will not execute on the target processor. The following processor names are
-recognized:
-@code{ms1-64-001},
-@code{ms1-16-002},
-@code{ms1-16-003},
-and @code{ms2}.
-
-@cindex @code{-nosched} command line option, MS1
-@item -nosched
-This option disables scheduling restriction checking.
-
-@end table
--- /dev/null
+@c Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+@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 MS1-Dependent
+@chapter MS1 Dependent Features
+@end ifset
+
+@ifclear GENERIC
+@node Machine Dependencies
+@chapter MS1 Dependent Features
+@end ifclear
+
+@cindex MS1 support
+@menu
+* MS1 Options:: Options
+@end menu
+
+@node MS1 Options
+@section Options
+@cindex MS1 options (none)
+@cindex options for MS1 (none)
+
+@table @code
+
+@cindex @code{-march=} command line option, MS1
+@item -march=@var{processor}
+This option specifies the target processor. The assembler will issue an
+error message if an attempt is made to assemble an instruction which
+will not execute on the target processor. The following processor names are
+recognized:
+@code{ms1-64-001},
+@code{ms1-16-002},
+@code{ms1-16-003},
+and @code{ms2}.
+
+@cindex @code{-nosched} command line option, MS1
+@item -nosched
+This option disables scheduling restriction checking.
+
+@end table
+++ /dev/null
-#as: -nosched
-#objdump: -dr
-#name: allinsn
-
-.*: +file format .*
-
-Disassembly of section .text:
-
-00000000 <add>:
- 0: 00 00 00 00 add R0,R0,R0
-
-00000004 <addu>:
- 4: 02 00 00 00 addu R0,R0,R0
-
-00000008 <addi>:
- 8: 01 00 00 00 addi R0,R0,#\$0
-
-0000000c <addui>:
- c: 03 00 00 00 addui R0,R0,#\$0
-
-00000010 <sub>:
- 10: 04 00 00 00 sub R0,R0,R0
-
-00000014 <subu>:
- 14: 06 00 00 00 subu R0,R0,R0
-
-00000018 <subi>:
- 18: 05 00 00 00 subi R0,R0,#\$0
-
-0000001c <subui>:
- 1c: 07 00 00 00 subui R0,R0,#\$0
-
-00000020 <and>:
- 20: 10 00 00 00 and R0,R0,R0
-
-00000024 <andi>:
- 24: 11 00 00 00 andi R0,R0,#\$0
-
-00000028 <or>:
- 28: 12 01 00 00 or R0,R0,R1
-
-0000002c <ori>:
- 2c: 13 00 00 00 ori R0,R0,#\$0
-
-00000030 <xor>:
- 30: 14 00 00 00 xor R0,R0,R0
-
-00000034 <xori>:
- 34: 15 00 00 00 xori R0,R0,#\$0
-
-00000038 <nand>:
- 38: 16 00 00 00 nand R0,R0,R0
-
-0000003c <nandi>:
- 3c: 17 00 00 00 nandi R0,R0,#\$0
-
-00000040 <nor>:
- 40: 18 00 00 00 nor R0,R0,R0
-
-00000044 <nori>:
- 44: 19 00 00 00 nori R0,R0,#\$0
-
-00000048 <xnor>:
- 48: 1a 00 00 00 xnor R0,R0,R0
-
-0000004c <xnori>:
- 4c: 1b 00 00 00 xnori R0,R0,#\$0
-
-00000050 <ldui>:
- 50: 1d 00 00 00 ldui R0,#\$0
-
-00000054 <lsl>:
- 54: 20 00 00 00 lsl R0,R0,R0
-
-00000058 <lsli>:
- 58: 21 00 00 00 lsli R0,R0,#\$0
-
-0000005c <lsr>:
- 5c: 22 00 00 00 lsr R0,R0,R0
-
-00000060 <lsri>:
- 60: 23 00 00 00 lsri R0,R0,#\$0
-
-00000064 <asr>:
- 64: 24 00 00 00 asr R0,R0,R0
-
-00000068 <asri>:
- 68: 25 00 00 00 asri R0,R0,#\$0
-
-0000006c <brlt>:
- 6c: 31 00 00 00 brlt R0,R0,6c <brlt>
-
-00000070 <brle>:
- 70: 33 00 00 00 brle R0,R0,70 <brle>
-
-00000074 <breq>:
- 74: 35 00 00 00 breq R0,R0,74 <breq>
-
-00000078 <jmp>:
- 78: 37 00 00 00 jmp 78 <jmp>
-
-0000007c <jal>:
- 7c: 38 00 00 00 jal R0,R0
-
-00000080 <ei>:
- 80: 60 00 00 00 ei
-
-00000084 <di>:
- 84: 62 00 00 00 di
-
-00000088 <reti>:
- 88: 66 00 00 00 reti R0
-
-0000008c <ldw>:
- 8c: 41 00 00 00 ldw R0,R0,#\$0
-
-00000090 <stw>:
- 90: 43 00 00 00 stw R0,R0,#\$0
-
-00000094 <si>:
- 94: 64 00 00 00 si R0
-
-00000098 <brne>:
- 98: 3b 00 00 00 brne R0,R0,98 <brne>
-
-0000009c <break>:
- 9c: 68 00 00 00 break
-
-000000a0 <nop>:
- a0: 12 00 00 00 nop
+++ /dev/null
- .data
-foodata: .word 42
- .text
-footext:
- .text
- .global add
-add:
- add R0,R0,R0
- .text
- .global addu
-addu:
- addu R0,R0,R0
- .text
- .global addi
-addi:
- addi R0,R0,#0
- .text
- .global addui
-addui:
- addui R0,R0,#0
- .text
- .global sub
-sub:
- sub R0,R0,R0
- .text
- .global subu
-subu:
- subu R0,R0,R0
- .text
- .global subi
-subi:
- subi R0,R0,#0
- .text
- .global subui
-subui:
- subui R0,R0,#0
- .text
- .global and
-and:
- and R0,R0,R0
- .text
- .global andi
-andi:
- andi R0,R0,#0
- .text
- .global or
-or:
- or R0,R0,R1
- .text
- .global ori
-ori:
- ori R0,R0,#0
- .text
- .global xor
-xor:
- xor R0,R0,R0
- .text
- .global xori
-xori:
- xori R0,R0,#0
- .text
- .global nand
-nand:
- nand R0,R0,R0
- .text
- .global nandi
-nandi:
- nandi R0,R0,#0
- .text
- .global nor
-nor:
- nor R0,R0,R0
- .text
- .global nori
-nori:
- nori R0,R0,#0
- .text
- .global xnor
-xnor:
- xnor R0,R0,R0
- .text
- .global xnori
-xnori:
- xnori R0,R0,#0
- .text
- .global ldui
-ldui:
- ldui R0,#0
- .text
- .global lsl
-lsl:
- lsl R0,R0,R0
- .text
- .global lsli
-lsli:
- lsli R0,R0,#0
- .text
- .global lsr
-lsr:
- lsr R0,R0,R0
- .text
- .global lsri
-lsri:
- lsri R0,R0,#0
- .text
- .global asr
-asr:
- asr R0,R0,R0
- .text
- .global asri
-asri:
- asri R0,R0,#0
- .text
- .global brlt
-brlt:
- brlt R0,R0,0
- .text
- .global brle
-brle:
- brle R0,R0,0
- .text
- .global breq
-breq:
- breq R0,R0,0
- .text
- .global jmp
-jmp:
- jmp 0
- .text
- .global jal
-jal:
- jal R0,R0
- .text
- .global ei
-ei:
- ei
- .text
- .global di
-di:
- di
- .text
- .global reti
-reti:
- reti R0
- .text
- .global ldw
-ldw:
- ldw R0,R0,#0
- .text
- .global stw
-stw:
- stw R0,R0,#0
- .text
- .global si
-si:
- si R0
- .global brne
-brne:
- brne R0,R0,0
- .global break
-break:
- break
- .text
- .global nop
-nop:
- nop
+++ /dev/null
-; Bogus instruction mnemonic should generate an error.
-
-addcrap R1,R2,R3
+++ /dev/null
-; Extra operand should generate and error message.
-
-add R1,R2,R3,R4
+++ /dev/null
-; Offset greater than #32767 should cause an error since the offset is
-; a signed quantity.
-
-brlt R1,R2,$32768
+++ /dev/null
-; Offset less than #-32786 should cause an error since the offset is
-; a signed quantity. Also tests expression parsing.
-
-label1: add R1,R2,R3
-label2: add R4,R5,R6
- brlt R7,R8, ((label1-label2)-32765) ; evaluates to -32769
+++ /dev/null
-; Good operands in the wrong order should generate an error.
-
-addui R1, #32 R2
+++ /dev/null
-; Bad register name should generate an error.
-
-add R16,R10,R9
+++ /dev/null
-; Offset greater than #32767 should cause an error.
-
-addi R1,R2,#32768
+++ /dev/null
-; Immediate lower than #-32769 should cause an error.
-
-addi R1,R2,#-32769
+++ /dev/null
-; Good mnemonic with wrong operands should generate an error.
-
-add R1,R2,#0
+++ /dev/null
-; Good mnemonic with too few operands should generate an error.
-
-add R1,R2
+++ /dev/null
-; Offset greater than #$FFFF should cause an error.
-
-andi R1,R2,#$10000
+++ /dev/null
-; Offset less than #0 should cause an error.
-
-andi R1,R2,#-1
+++ /dev/null
-# Test for error messages when a bad register name, an out of range operand, or
-# invalid syntax is used. Adapted from Ben Elliston's load-hazard testcase.
-
-# Run GAS and check that it emits the desired error for the test case.
-# Arguments:
-# file -- name of the test case to assemble.
-# testname -- a string describing the test.
-# warnpattern -- a regular expression, suitable for use by the Tcl
-# regexp command, to decide if the warning string was emitted by
-# the assembler to stderr.
-
-proc mrisc1_error_test { file testname {warnpattern ""} } {
- global comp_output
-
- gas_run $file "" ">/dev/null"
- verbose "output was $comp_output" 2
-
- if {$warnpattern == ""} {
- if {$comp_output == ""} { pass $testname } else { fail $testname }
- return
- }
-
- if {[regexp "Error: $warnpattern" $comp_output]} {
- pass $testname
- } else {
- fail $testname
- }
-}
-
-if [istarget ms1-*-*] {
- foreach file [glob -nocomplain -- $srcdir/$subdir/bad*.s] {
- set file [file tail $file]
- switch -- $file {
- "badreg.s" {
- set warnpattern "unrecognized keyword/register name *"
- }
- "badorder.s" {
- set warnpattern "unrecognized form of instruction*"
- }
- "badsyntax.s" {
- set warnpattern "unrecognized keyword/register name *"
- }
- "badsyntax1.s" {
- set warnpattern "unrecognized form of instruction*"
- }
- "badoffsethigh.s" {
- set warnpattern "Operand out of range. Must be between -32768 and 32767.*"
- }
- "badoffsetlow.s" {
- set warnpattern "Operand out of range. Must be between -32768 and 32767.*"
- }
- "badunsignedimmhigh.s" {
- set warnpattern "operand out of range (65536 not between 0 and 65535)*"
- }
- "badunsignedimmlow.s" {
- set warnpattern "operand out of range (65536 not between 0 and 65535)*"
- }
- "badsignedimmhigh.s" {
- set warnpattern "operand out of range.*"
- }
- "badsignedimmlow.s" {
- set warnpattern "operand out of range.*"
- }
- "badinsn.s" {
- set warnpattern "unrecognized instruction *"
- }
- "badinsn1.s" {
- set warnpattern "junk at end of line *"
- }
- default {
- error "no expected result specified for $file"
- return
-
- }
- }
- mrisc1_error_test $file "assembler emits error for $file" $warnpattern
- }
-
-}
+++ /dev/null
-; load/store tests
-
- .data
-
-ldw_data:
- .word 0xbabeface
-
- .text
-
-ld_text:
- ld r4, r3
- ld r3, #8
- ld r5, #ld_text
- ldh r6, #ldh_text
- ldh r4, #4000
- ldh r5, #0x8000
- ldh r5, #-5
- ldh r5, #-0x8000
- ldh r0, #0xffff
-ldh_text:
- ldw r9, #30233000
- ldw r3, #ldw_data
- ldb r3, @[r9+r2]
- ldb @[r9+r3], r5 ; store
- ldb r3, @[r8+6]
- ldb @[r8+7], r3 ; store
- ldw r9, @[r14+23]
- ldw @[r14+10], r9 ; store
+++ /dev/null
-#as:
-#objdump: -dr
-#name: misc
-
-.*: +file format .*
-
-Disassembly of section .text:
-
-00000000 <.text>:
- 0: 00 12 00 00 add R0,R1,R2
- 4: 00 12 00 00 add R0,R1,R2
- 8: 00 23 10 00 add R1,R2,R3
- c: 00 33 10 00 add R1,R3,R3
- 10: 00 56 40 00 add R4,R5,R6
- 14: 00 89 70 00 add R7,R8,R9
- 18: 00 bc a0 00 add R10,R11,R12
- 1c: 00 ef d0 00 add R13,R14,R15
- 20: 03 dc 00 01 addui R12,R13,#\$1
- 24: 03 fe 00 01 addui R14,R15,#\$1
- 28: 03 10 00 00 addui R0,R1,#\$0
- 2c: 03 10 ff ff addui R0,R1,#\$ffff
+++ /dev/null
-; Check that register names, both upper and lower case work and that
-; the spacing between the operands doesn't matter.
-
-add R0,R1,R2
-add r0,r1,r2
-add R1,R2,r3
-add R1, R3, r3
-add R4,R5,R6
-add R7,R8,R9
-add R10,R11,R12
-add R13,R14,R15
-addui fp,sp,#1
-addui ra,ira,#1
-
-; Check that the range of legal operand values is accepted.
-
-addui R0,R1,#0
-addui R0,R1,#$FFFF
-
-
-
+++ /dev/null
-#as: -march=ms1-16-003
-#objdump: -dr
-#name: ms1-16-003
-
-.*: +file format .*
-
-Disassembly of section .text:
-
-00000000 <iflush>:
- 0: 6a 00 00 00 iflush
-00000004 <mul>:
- 4: 08 00 00 00 mul R0,R0,R0
-00000008 <muli>:
- 8: 09 00 00 00 muli R0,R0,#\$0
-0000000c <dbnz_>:
- c: 3d 00 00 00 dbnz R0,c <dbnz_>
-[ ]*c: R_MS1_PC16 dbnz
-00000010 <fbcbincs>:
- 10: f0 00 00 00 fbcbincs #\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
-00000014 <mfbcbincs>:
- 14: f4 00 00 00 mfbcbincs R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
-00000018 <fbcbincrs>:
- 18: f8 00 00 00 fbcbincrs R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
-0000001c <mfbcbincrs>:
- 1c: fc 00 00 00 mfbcbincrs R0,R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
-00000020 <wfbinc>:
- 20: e0 00 00 00 wfbinc #\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
-00000024 <mwfbinc>:
- 24: e4 00 00 00 mwfbinc R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
-00000028 <wfbincr>:
- 28: e8 00 00 00 wfbincr R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
-0000002c <mwfbincr>:
- 2c: ec 00 00 00 mwfbincr R0,R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
+++ /dev/null
- .text
- .global iflush
-iflush:
- iflush
-
- .global mul
-mul:
- mul R0, R0, R0
-
- .global muli
-muli:
- muli R0, R0, #0
-
- .global dbnz
-dbnz_:
- dbnz r0, dbnz
-
- .global fbcbincs
-fbcbincs:
- fbcbincs #0, #0, #0, #0, #0, #0, #0, #0, #0, #0
-
- .global mfbcbincs
-mfbcbincs:
- mfbcbincs r0, #0, #0, #0, #0, #0, #0, #0, #0
-
-
- .global fbcbincrs
-fbcbincrs:
- fbcbincrs r0, #0, #0, #0, #0, #0, #0, #0, #0, #0
-
- .global mfbcbincrs
-mfbcbincrs:
- mfbcbincrs r0, r0, #0, #0, #0, #0, #0, #0, #0
-
-
- .global wfbinc
-wfbinc:
-# Documentation error.
-# wfbinc #0, r0, #0, #0, #0, #0, #0, #0, #0, #0
- wfbinc #0, #0, #0, #0, #0, #0, #0, #0, #0, #0
-
- .global mwfbinc
-mwfbinc:
-# Documentation error.
-# mwfbinc r0, #0, #0, r0, #0, #0, #0, #0, #0
- mwfbinc r0, #0, #0, #0, #0, #0, #0, #0, #0
-
- .global wfbincr
-wfbincr:
- wfbincr r0, #0, #0, #0, #0, #0, #0, #0, #0, #0
-
- .global mwfbincr
-mwfbincr:
- mwfbincr r0, r0, #0, #0, #0, #0, #0, #0, #0
+++ /dev/null
-# MRISC1 assembler testsuite.
-
-if [istarget ms1*-*-*] {
- #
- run_dump_test "allinsn"
- run_dump_test "misc"
- run_dump_test "msys"
- run_dump_test "ms1-16-003"
- run_dump_test "ms2"
- #
-}
+++ /dev/null
-#as: -march=ms2
-#objdump: -dr
-#name: ms2
-
-.*: +file format .*
-
-Disassembly of section .text:
-
-00000000 <code>:
- 0: 3e 10 00 05 loop R1,1c <label>
- 4: 3f 00 10 04 loopi #\$10,1c <label>
- 8: 83 ff ff ff dfbc #\$7,#\$7,#\$ffffffff,#\$ffffffff,#\$1,#\$1,#\$3f
- c: 87 ff ff 7f dwfb #\$7,#\$7,#\$ffffffff,#\$ffffffff,#\$1,#\$3f
- 10: 8b ff ff ff fbwfb #\$7,#\$7,#\$ffffffff,#\$ffffffff,#\$1,#\$1,#\$3f
- 14: 8f f0 ff ff dfbr #\$7,#\$7,R0,#\$7,#\$7,#\$7,#\$1,#\$3f
- 18: 12 00 00 00 nop
-0000001c <label>:
- 1c: f0 00 00 00 fbcbincs #\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
+++ /dev/null
-
-code:
- loop R1, label
- loopi #16,label
- dfbc #7,#7,#-1,#-1,#1,#1,#63
- dwfb #7,#7,#-1,#-1,#1,#63
- fbwfb #7,#7,#-1,#-1,#1,#1,#63
- dfbr #7,#7,R0,#7,#7,#7,#1,#63
- nop
-label:
- fbcbincs #0,#0,#0,#0,#0,#0,#0,#0,#0,#0
+++ /dev/null
-#as: -nosched
-#objdump: -dr
-#name: msys
-
-.*: +file format .*
-
-Disassembly of section .text:
-
-00000000 <.text>:
- 0: 80 00 00 00 ldctxt R0,R0,#\$0,#\$0,#\$0
- 4: 84 00 00 00 ldfb R0,R0,#\$0
- 8: 88 00 00 00 stfb R0,R0,#\$0
- c: 8c 00 00 00 fbcb R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
- 10: 90 00 00 00 mfbcb R0,#\$0,R0,#\$0,#\$0,#\$0,#\$0,#\$0
- 14: 94 00 00 00 fbcci R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
- 18: 98 00 00 00 fbrci R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
- 1c: 9c 00 00 00 fbcri R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
- 20: a0 00 00 00 fbrri R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
- 24: a4 00 00 00 mfbcci R0,#\$0,R0,#\$0,#\$0,#\$0,#\$0
- 28: a8 00 00 00 mfbrci R0,#\$0,R0,#\$0,#\$0,#\$0,#\$0
- 2c: ac 00 00 00 mfbcri R0,#\$0,R0,#\$0,#\$0,#\$0,#\$0
- 30: b0 00 00 00 mfbrri R0,#\$0,R0,#\$0,#\$0,#\$0,#\$0
- 34: b4 00 00 00 fbcbdr R0,#\$0,R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
- 38: b8 00 00 00 rcfbcb #\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
- 3c: bc 00 00 00 mrcfbcb R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
- 40: c0 00 00 00 cbcast #\$0,#\$0,#\$0
- 44: c4 00 00 00 dupcbcast #\$0,#\$0,#\$0,#\$0
- 48: c8 00 00 00 wfbi #\$0,#\$0,#\$0,#\$0,#\$0
- 4c: cc 00 00 00 wfb R0,R0,#\$0,#\$0,#\$0
- 50: d0 00 00 00 rcrisc R0,#\$0,R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
- 54: d4 00 00 00 fbcbinc R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
- 58: d8 00 00 00 rcxmode R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
- 5c: 64 00 e0 00 si R14
- 60: b4 00 00 40 fbcbdr R0,#\$0,R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$1,#\$0
- 64: b4 00 00 00 fbcbdr R0,#\$0,R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
- 68: b4 00 00 40 fbcbdr R0,#\$0,R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$1,#\$0
- 6c: b4 00 00 00 fbcbdr R0,#\$0,R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
- 70: 64 00 e0 00 si R14
- 74: b8 08 00 00 rcfbcb #\$0,#\$0,#\$1,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
- 78: b8 00 00 00 rcfbcb #\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
- 7c: b8 08 00 00 rcfbcb #\$0,#\$0,#\$1,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
- 80: b8 00 00 00 rcfbcb #\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
- 84: 64 00 e0 00 si R14
- 88: bc 20 00 00 mrcfbcb R0,#\$0,#\$2,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
- 8c: bc 10 00 00 mrcfbcb R0,#\$0,#\$1,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
- 90: bc 00 00 00 mrcfbcb R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
- 94: bc 20 00 00 mrcfbcb R0,#\$0,#\$2,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
- 98: bc 10 00 00 mrcfbcb R0,#\$0,#\$1,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
- 9c: bc 00 00 00 mrcfbcb R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
- a0: 64 00 e0 00 si R14
- a4: d8 80 00 00 rcxmode R0,#\$0,#\$0,#\$1,#\$0,#\$0,#\$0,#\$0,#\$0
- a8: d8 00 00 00 rcxmode R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
- ac: d8 80 00 00 rcxmode R0,#\$0,#\$0,#\$1,#\$0,#\$0,#\$0,#\$0,#\$0
- b0: d8 00 00 00 rcxmode R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
- b4: 64 00 e0 00 si R14
- b8: 80 00 80 00 ldctxt R0,R0,#\$1,#\$0,#\$0
- bc: 80 00 00 00 ldctxt R0,R0,#\$0,#\$0,#\$0
- c0: 80 00 80 00 ldctxt R0,R0,#\$1,#\$0,#\$0
- c4: 80 00 00 00 ldctxt R0,R0,#\$0,#\$0,#\$0
- c8: 8c 00 08 00 fbcb R0,#\$0,#\$0,#\$0,#\$1,#\$0,#\$0,#\$0,#\$0
- cc: 8c 00 00 00 fbcb R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
- d0: c0 00 00 40 cbcast #\$0,#\$1,#\$0
- d4: c0 00 00 00 cbcast #\$0,#\$0,#\$0
- d8: 64 00 e0 00 si R14
- dc: 8c 00 04 00 fbcb R0,#\$0,#\$0,#\$0,#\$0,#\$1,#\$0,#\$0,#\$0
- e0: 8c 00 00 00 fbcb R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
- e4: 8c 00 04 00 fbcb R0,#\$0,#\$0,#\$0,#\$0,#\$1,#\$0,#\$0,#\$0
- e8: 8c 00 00 00 fbcb R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
- ec: 64 00 e0 00 si R14
- f0: 8f 00 00 00 fbcb R0,#\$3,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
- f4: 8e 00 00 00 fbcb R0,#\$2,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
- f8: 8d 00 00 00 fbcb R0,#\$1,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
- fc: 8c 00 00 00 fbcb R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
- 100: 8f 00 00 00 fbcb R0,#\$3,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
- 104: 8e 00 00 00 fbcb R0,#\$2,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
- 108: 8d 00 00 00 fbcb R0,#\$1,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
- 10c: 8c 00 00 00 fbcb R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
- 110: dc 00 00 00 intlvr R0,#\$0,R0,#\$0,#\$0
+++ /dev/null
-;; This file is a set of tests for the MorphoySys instructions.
-
-; Make sure that each mnemonic gives the proper opcode. Use R0 and #0
-; for all operands so that everything but the opcode will be 0 in the
-; assembled instructions.
-
- ldctxt R0,R0,#0,#0,#0
- ldfb R0,R0,#0
- stfb R0, R0, #0
- fbcb R0,#0,#0,#0,#0,#0,#0,#0,#0
- mfbcb R0,#0,R0,#0,#0,#0,#0,#0
- fbcci R0,#0,#0,#0,#0,#0,#0,#0
- fbrci R0,#0,#0,#0,#0,#0,#0,#0
- fbcri R0,#0,#0,#0,#0,#0,#0,#0
- fbrri R0,#0,#0,#0,#0,#0,#0,#0
- mfbcci R0,#0,R0,#0,#0,#0,#0
- mfbrci R0,#0,R0,#0,#0,#0,#0
- mfbcri R0,#0,R0,#0,#0,#0,#0
- mfbrri R0,#0,R0,#0,#0,#0,#0
- fbcbdr R0,#0,R0,#0,#0,#0,#0,#0,#0,#0
- rcfbcb #0,#0,#0,#0,#0,#0,#0,#0,#0,#0
- mrcfbcb R0,#0,#0,#0,#0,#0,#0,#0,#0
- cbcast #0,#0,#0
- dupcbcast #0,#0,#0,#0
- wfbi #0,#0,#0,#0,#0
- wfb R0,R0,#0,#0,#0
- rcrisc R0,#0,R0,#0,#0,#0,#0,#0,#0
- fbcbinc R0, #0, #0, #0, #0, #0, #0, #0
- rcxmode R0, #0, #0, #0, #0, #0, #0, #0, #0
-
-; Check to make sure that the parse routines that allow predifined
-; symbols (uppaer and lower case) to be used for some of the operands.
-
-; dup operand: dup, xx
- si R14
- fbcbdr R0,#0,R0,#0,#0,#0,#0,#0,#dup,#0 ; dup = 1
- fbcbdr R0,#0,R0,#0,#0,#0,#0,#0,#xx,#0 ; xx = 0
- fbcbdr R0,#0,R0,#0,#0,#0,#0,#0,#DUP,#0
- fbcbdr R0,#0,R0,#0,#0,#0,#0,#0,#XX,#0
-
-; ball operand: all, one
- si R14
- rcfbcb #0,#0,#all,#0,#0,#0,#0,#0,#0,#0 ; all = 1
- rcfbcb #0,#0,#one,#0,#0,#0,#0,#0,#0,#0 ; one = 0
- rcfbcb #0,#0,#ALL,#0,#0,#0,#0,#0,#0,#0
- rcfbcb #0,#0,#ONE,#0,#0,#0,#0,#0,#0,#0
-
-; type operand: odd, even, oe
- si R14
- mrcfbcb R0,#0,#oe,#0,#0,#0,#0,#0,#0 ; oe = 2
- mrcfbcb R0,#0,#even,#0,#0,#0,#0,#0,#0 ; even = 1
- mrcfbcb R0,#0,#odd,#0,#0,#0,#0,#0,#0 ; odd = 0
- mrcfbcb R0,#0,#OE,#0,#0,#0,#0,#0,#0
- mrcfbcb R0,#0,#EVEN,#0,#0,#0,#0,#0,#0
- mrcfbcb R0,#0,#ODD,#0,#0,#0,#0,#0,#0
-
-; xmode operand: pm, xm
- si R14
- rcxmode R0, #0, #0, #pm, #0, #0, #0, #0, #0 ; pm = 1
- rcxmode R0, #0, #0, #xm, #0, #0, #0, #0, #0 ; xm = 0
- rcxmode R0, #0, #0, #PM, #0, #0, #0, #0, #0
- rcxmode R0, #0, #0, #XM, #0, #0, #0, #0, #0
-
-; rc, rc1, rc2 operands: r,c
- si R14
- ldctxt R0,R0,#r,#0,#0 ; rc operand. r = 1
- ldctxt R0,R0,#c,#0,#0 ; rc operand. c = 0
- ldctxt R0,R0,#R,#0,#0
- ldctxt R0,R0,#C,#0,#0
-
- fbcb R0,#0,#0,#0,#r,#0,#0,#0,#0 ; rc1 operand. r = 1
- fbcb R0,#0,#0,#0,#c,#0,#0,#0,#0 ; rc1 operand. c = 0
-
- cbcast #0,#r,#0 ; rc2 operand. r = 1
- cbcast #0,#c,#0 ; rc2 opearnd. c = 0
-
-; cbrb operand: cb, rb
- si R14
- fbcb R0,#0,#0,#0,#0,#rb,#0,#0,#0 ; rb = 1
- fbcb R0,#0,#0,#0,#0,#cb,#0,#0,#0 ; cb = 0
- fbcb R0,#0,#0,#0,#0,#RB,#0,#0,#0
- fbcb R0,#0,#0,#0,#0,#CB,#0,#0,#0
-
-; rbbc operand: rt, br1, br2, cs
- si R14
- fbcb R0,#cs,#0,#0,#0,#0,#0,#0,#0 ; cs = 3
- fbcb R0,#br2,#0,#0,#0,#0,#0,#0,#0 ; br2 = 2
- fbcb R0,#br1,#0,#0,#0,#0,#0,#0,#0 ; br1 = 1
- fbcb R0,#rt,#0,#0,#0,#cb,#0,#0,#0 ; rt = 0
- fbcb R0,#CS,#0,#0,#0,#0,#0,#0,#0
- fbcb R0,#BR2,#0,#0,#0,#0,#0,#0,#0
- fbcb R0,#BR1,#0,#0,#0,#0,#0,#0,#0
- fbcb R0,#RT,#0,#0,#0,#cb,#0,#0,#0
-
- intlvr R0, #0, R0, #0, #0
+++ /dev/null
-
-relocs.x: file format elf32-(mrisc1|ms1)
-
-Contents of section .text:
- 2000 00131000 3700dffc 12000000 3700fff8 ....7.......7...
- 2010 03210000 03212215 03210001 03210000 .!...!"..!...!..
- 2020 0321ffff 0321eeee 03210005 03210006 .!...!...!...!..
- 2030 00675000 .gP.
-Contents of section .data:
- 2134 0f000000 00000000 00000000 00000000 ................
- 2144 00000000 00000000 00000000 00000000 ................
- 2154 00000000 00000000 00000000 00000000 ................
- 2164 00000000 00000000 00000000 00000000 ................
- 2174 00000000 00000000 00000000 00000000 ................
- 2184 00000000 00000000 00000000 00000000 ................
- 2194 00000000 00000000 00000000 00000000 ................
- 21a4 00000000 00000000 00000000 00000000 ................
- 21b4 00000000 00000000 00000000 00000000 ................
- 21c4 00000000 00000000 00000000 00000000 ................
- 21d4 00000000 00000000 00000000 00000000 ................
- 21e4 00000000 00000000 00000000 00000000 ................
- 21f4 00000000 00000000 00000000 00000000 ................
- 2204 00000000 00000000 00000000 00000000 ................
- 2214 00020000 00000000 00000000 00000000 ................
- 2224 00000000 00000000 00000000 00000000 ................
- 2234 00000000 00000000 00000000 00000000 ................
- 2244 00000000 00000000 00000000 00000000 ................
- 2254 00000000 00000000 00000000 00000000 ................
- 2264 00000000 00000000 00000000 00000000 ................
- 2274 00000000 00000000 00000000 00000000 ................
- 2284 00000000 00000000 00000000 00000000 ................
- 2294 00000000 00000000 00000000 00000000 ................
- 22a4 00000000 00000000 00000000 00000000 ................
- 22b4 00000000 00000000 00000000 00000000 ................
- 22c4 00000000 00000000 00000000 00000000 ................
- 22d4 00000000 00000000 00000000 00000000 ................
- 22e4 00000000 00000000 00000000 00000000 ................
- 22f4 00000000 00000000 00000000 00000000 ................
- 2304 00000000 00000000 00000000 00000000 ................
- 2314 000003 ...
-Contents of section .stack:
- 7ffff0 deaddead ....
-Disassembly of section .text:
-
-00002000 <_start>:
- 2000: 00 13 10 00 add R1,R1,R3
-
-00002004 <local>:
- 2004: 37 00 df fc jmp 0 <_start-0x2000>
-
-00002008 <none>:
- 2008: 12 00 00 00 nop
- 200c: 37 00 ff f8 jmp 2004 <local>
- 2010: 03 21 00 00 addui R1,R2,#\$0
- 2014: 03 21 22 15 addui R1,R2,#\$2215
- 2018: 03 21 00 01 addui R1,R2,#\$1
- 201c: 03 21 00 00 addui R1,R2,#\$0
- 2020: 03 21 ff ff addui R1,R2,#\$ffff
- 2024: 03 21 ee ee addui R1,R2,#\$eeee
-
-00002028 <dummy1>:
- 2028: 03 21 00 05 addui R1,R2,#\$5
-
-0000202c <dummy2>:
- 202c: 03 21 00 06 addui R1,R2,#\$6
-
-00002030 <i2>:
- 2030: 00 67 50 00 add R5,R6,R7
+++ /dev/null
-# Relocation test.
-# This test is special because it exercises the linker's
-
-proc ld_test { objects ldflags dest test } {
- set ld_output [target_link $objects $dest $ldflags]
- if [string match "" $ld_output] then { pass $test } else { fail $test }
-}
-
-
-proc objdump_test { exec flags dest test } {
- set objcopy [find_binutils_prog objdump]
- verbose -log "$objcopy $flags $exec > $dest"
- catch "exec $objcopy $flags $exec > $dest" objdump_output
- if [string match "" $objdump_output] then { pass $test } else { fail $test }
-}
-
-proc regexp_test { file1 file2 test } {
- if [regexp_diff $file1 $file2] then { fail $test } else { pass $test }
-}
-
-
-global srcdir subdir
-if [istarget ms1-*] {
- gas_test "relocs1.s" {-o relocs1.o} {} {assembling relocs1}
-
- # gas_test "relocs2.s" {-o relocs2.o} {} {assembling relocs2}
- # ld_test {relocs1.o relocs2.o} {} {relocs.x} {linking relocs.x}
- # objdump_test {relocs.x} {-ds} {relocs.dump} {disassembling relocs.x}
- # regexp_test {relocs.dump} "$srcdir/$subdir/relocs.d" {matching disassembly}
-
- gas_test "relocs2.s" {-o relocs2.o} {} {assembling relocs2}
- ld_test {relocs1.o relocs2.o} {} {relocs.x} {linking relocs.x}
- objdump_test {relocs.x} {-ds} {relocs.dump} {disassembling relocs.x}
- regexp_test {relocs.dump} "$srcdir/$subdir/relocs.d" {matching disassembly}
-}
+++ /dev/null
-;; This test is meant to exercise every unusual reloc supported
-;; by the mrisc port. (Ok, so there's only one so far. :P)
-
- .text
-text:
- .global _start
-_start:
- add R1,R1,R3
-
-; Make sure local fixups work.
-local:
- jmp (dummy2-dummy1)
-
-; Test the PC16 reloc.
-none:
- or R0,R0,R0 ;nop to conform to scheduling restrictions
- jmp local
-
-; Test the %hi16 and %lo16 relocs
-addui R1,R2,#%hi16(d2)
-addui R1,R2,#%lo16(d2)
-addui R1,R2,#%hi16(65536)
-addui R1,R2,#%lo16(65536)
-addui R1,R2,#%hi16($FFFFEEEE)
-addui R1,R2,#%lo16($FFFFEEEE)
-
-dummy1: addui R1, R2, #5
-dummy2: addui R1, R2, #6
-
- .data
-d1: .byte $f
+++ /dev/null
- .text
- ;; Put code near the top of the address space
-text:
- .global i2
-i2:
-
- add R5, R6, R7
-
- .data
- ;; Note that the .org that follows is more or less equivalent
- ;; to a .space, since the amount specified will be treated like
- ;; padding to be added between the .data section in relocs1.s
- ;; and this one.
- ;; Note also that the two test variables (d2 & d3) are intentionally
- ;; roughly $100 apart, so that the FR9 relocation processing in
- ;; bfd/elf32-ip2k.c (ip2k_final_link_relocate) is tested a little more.
- .org $e0
- .global d2
-d2: .byte 2
- .space $100
- .global d3
-d3: .byte 3
--- /dev/null
+#as: -nosched
+#objdump: -dr
+#name: allinsn
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+00000000 <add>:
+ 0: 00 00 00 00 add R0,R0,R0
+
+00000004 <addu>:
+ 4: 02 00 00 00 addu R0,R0,R0
+
+00000008 <addi>:
+ 8: 01 00 00 00 addi R0,R0,#\$0
+
+0000000c <addui>:
+ c: 03 00 00 00 addui R0,R0,#\$0
+
+00000010 <sub>:
+ 10: 04 00 00 00 sub R0,R0,R0
+
+00000014 <subu>:
+ 14: 06 00 00 00 subu R0,R0,R0
+
+00000018 <subi>:
+ 18: 05 00 00 00 subi R0,R0,#\$0
+
+0000001c <subui>:
+ 1c: 07 00 00 00 subui R0,R0,#\$0
+
+00000020 <and>:
+ 20: 10 00 00 00 and R0,R0,R0
+
+00000024 <andi>:
+ 24: 11 00 00 00 andi R0,R0,#\$0
+
+00000028 <or>:
+ 28: 12 01 00 00 or R0,R0,R1
+
+0000002c <ori>:
+ 2c: 13 00 00 00 ori R0,R0,#\$0
+
+00000030 <xor>:
+ 30: 14 00 00 00 xor R0,R0,R0
+
+00000034 <xori>:
+ 34: 15 00 00 00 xori R0,R0,#\$0
+
+00000038 <nand>:
+ 38: 16 00 00 00 nand R0,R0,R0
+
+0000003c <nandi>:
+ 3c: 17 00 00 00 nandi R0,R0,#\$0
+
+00000040 <nor>:
+ 40: 18 00 00 00 nor R0,R0,R0
+
+00000044 <nori>:
+ 44: 19 00 00 00 nori R0,R0,#\$0
+
+00000048 <xnor>:
+ 48: 1a 00 00 00 xnor R0,R0,R0
+
+0000004c <xnori>:
+ 4c: 1b 00 00 00 xnori R0,R0,#\$0
+
+00000050 <ldui>:
+ 50: 1d 00 00 00 ldui R0,#\$0
+
+00000054 <lsl>:
+ 54: 20 00 00 00 lsl R0,R0,R0
+
+00000058 <lsli>:
+ 58: 21 00 00 00 lsli R0,R0,#\$0
+
+0000005c <lsr>:
+ 5c: 22 00 00 00 lsr R0,R0,R0
+
+00000060 <lsri>:
+ 60: 23 00 00 00 lsri R0,R0,#\$0
+
+00000064 <asr>:
+ 64: 24 00 00 00 asr R0,R0,R0
+
+00000068 <asri>:
+ 68: 25 00 00 00 asri R0,R0,#\$0
+
+0000006c <brlt>:
+ 6c: 31 00 00 00 brlt R0,R0,6c <brlt>
+
+00000070 <brle>:
+ 70: 33 00 00 00 brle R0,R0,70 <brle>
+
+00000074 <breq>:
+ 74: 35 00 00 00 breq R0,R0,74 <breq>
+
+00000078 <jmp>:
+ 78: 37 00 00 00 jmp 78 <jmp>
+
+0000007c <jal>:
+ 7c: 38 00 00 00 jal R0,R0
+
+00000080 <ei>:
+ 80: 60 00 00 00 ei
+
+00000084 <di>:
+ 84: 62 00 00 00 di
+
+00000088 <reti>:
+ 88: 66 00 00 00 reti R0
+
+0000008c <ldw>:
+ 8c: 41 00 00 00 ldw R0,R0,#\$0
+
+00000090 <stw>:
+ 90: 43 00 00 00 stw R0,R0,#\$0
+
+00000094 <si>:
+ 94: 64 00 00 00 si R0
+
+00000098 <brne>:
+ 98: 3b 00 00 00 brne R0,R0,98 <brne>
+
+0000009c <break>:
+ 9c: 68 00 00 00 break
+
+000000a0 <nop>:
+ a0: 12 00 00 00 nop
--- /dev/null
+ .data
+foodata: .word 42
+ .text
+footext:
+ .text
+ .global add
+add:
+ add R0,R0,R0
+ .text
+ .global addu
+addu:
+ addu R0,R0,R0
+ .text
+ .global addi
+addi:
+ addi R0,R0,#0
+ .text
+ .global addui
+addui:
+ addui R0,R0,#0
+ .text
+ .global sub
+sub:
+ sub R0,R0,R0
+ .text
+ .global subu
+subu:
+ subu R0,R0,R0
+ .text
+ .global subi
+subi:
+ subi R0,R0,#0
+ .text
+ .global subui
+subui:
+ subui R0,R0,#0
+ .text
+ .global and
+and:
+ and R0,R0,R0
+ .text
+ .global andi
+andi:
+ andi R0,R0,#0
+ .text
+ .global or
+or:
+ or R0,R0,R1
+ .text
+ .global ori
+ori:
+ ori R0,R0,#0
+ .text
+ .global xor
+xor:
+ xor R0,R0,R0
+ .text
+ .global xori
+xori:
+ xori R0,R0,#0
+ .text
+ .global nand
+nand:
+ nand R0,R0,R0
+ .text
+ .global nandi
+nandi:
+ nandi R0,R0,#0
+ .text
+ .global nor
+nor:
+ nor R0,R0,R0
+ .text
+ .global nori
+nori:
+ nori R0,R0,#0
+ .text
+ .global xnor
+xnor:
+ xnor R0,R0,R0
+ .text
+ .global xnori
+xnori:
+ xnori R0,R0,#0
+ .text
+ .global ldui
+ldui:
+ ldui R0,#0
+ .text
+ .global lsl
+lsl:
+ lsl R0,R0,R0
+ .text
+ .global lsli
+lsli:
+ lsli R0,R0,#0
+ .text
+ .global lsr
+lsr:
+ lsr R0,R0,R0
+ .text
+ .global lsri
+lsri:
+ lsri R0,R0,#0
+ .text
+ .global asr
+asr:
+ asr R0,R0,R0
+ .text
+ .global asri
+asri:
+ asri R0,R0,#0
+ .text
+ .global brlt
+brlt:
+ brlt R0,R0,0
+ .text
+ .global brle
+brle:
+ brle R0,R0,0
+ .text
+ .global breq
+breq:
+ breq R0,R0,0
+ .text
+ .global jmp
+jmp:
+ jmp 0
+ .text
+ .global jal
+jal:
+ jal R0,R0
+ .text
+ .global ei
+ei:
+ ei
+ .text
+ .global di
+di:
+ di
+ .text
+ .global reti
+reti:
+ reti R0
+ .text
+ .global ldw
+ldw:
+ ldw R0,R0,#0
+ .text
+ .global stw
+stw:
+ stw R0,R0,#0
+ .text
+ .global si
+si:
+ si R0
+ .global brne
+brne:
+ brne R0,R0,0
+ .global break
+break:
+ break
+ .text
+ .global nop
+nop:
+ nop
--- /dev/null
+; Bogus instruction mnemonic should generate an error.
+
+addcrap R1,R2,R3
--- /dev/null
+; Extra operand should generate and error message.
+
+add R1,R2,R3,R4
--- /dev/null
+; Offset greater than #32767 should cause an error since the offset is
+; a signed quantity.
+
+brlt R1,R2,$32768
--- /dev/null
+; Offset less than #-32786 should cause an error since the offset is
+; a signed quantity. Also tests expression parsing.
+
+label1: add R1,R2,R3
+label2: add R4,R5,R6
+ brlt R7,R8, ((label1-label2)-32765) ; evaluates to -32769
--- /dev/null
+; Good operands in the wrong order should generate an error.
+
+addui R1, #32 R2
--- /dev/null
+; Bad register name should generate an error.
+
+add R16,R10,R9
--- /dev/null
+; Offset greater than #32767 should cause an error.
+
+addi R1,R2,#32768
--- /dev/null
+; Immediate lower than #-32769 should cause an error.
+
+addi R1,R2,#-32769
--- /dev/null
+; Good mnemonic with wrong operands should generate an error.
+
+add R1,R2,#0
--- /dev/null
+; Good mnemonic with too few operands should generate an error.
+
+add R1,R2
--- /dev/null
+; Offset greater than #$FFFF should cause an error.
+
+andi R1,R2,#$10000
--- /dev/null
+; Offset less than #0 should cause an error.
+
+andi R1,R2,#-1
--- /dev/null
+# Test for error messages when a bad register name, an out of range operand, or
+# invalid syntax is used. Adapted from Ben Elliston's load-hazard testcase.
+
+# Run GAS and check that it emits the desired error for the test case.
+# Arguments:
+# file -- name of the test case to assemble.
+# testname -- a string describing the test.
+# warnpattern -- a regular expression, suitable for use by the Tcl
+# regexp command, to decide if the warning string was emitted by
+# the assembler to stderr.
+
+proc mrisc1_error_test { file testname {warnpattern ""} } {
+ global comp_output
+
+ gas_run $file "" ">/dev/null"
+ verbose "output was $comp_output" 2
+
+ if {$warnpattern == ""} {
+ if {$comp_output == ""} { pass $testname } else { fail $testname }
+ return
+ }
+
+ if {[regexp "Error: $warnpattern" $comp_output]} {
+ pass $testname
+ } else {
+ fail $testname
+ }
+}
+
+if [istarget ms1-*-*] {
+ foreach file [glob -nocomplain -- $srcdir/$subdir/bad*.s] {
+ set file [file tail $file]
+ switch -- $file {
+ "badreg.s" {
+ set warnpattern "unrecognized keyword/register name *"
+ }
+ "badorder.s" {
+ set warnpattern "unrecognized form of instruction*"
+ }
+ "badsyntax.s" {
+ set warnpattern "unrecognized keyword/register name *"
+ }
+ "badsyntax1.s" {
+ set warnpattern "unrecognized form of instruction*"
+ }
+ "badoffsethigh.s" {
+ set warnpattern "Operand out of range. Must be between -32768 and 32767.*"
+ }
+ "badoffsetlow.s" {
+ set warnpattern "Operand out of range. Must be between -32768 and 32767.*"
+ }
+ "badunsignedimmhigh.s" {
+ set warnpattern "operand out of range (65536 not between 0 and 65535)*"
+ }
+ "badunsignedimmlow.s" {
+ set warnpattern "operand out of range (65536 not between 0 and 65535)*"
+ }
+ "badsignedimmhigh.s" {
+ set warnpattern "operand out of range.*"
+ }
+ "badsignedimmlow.s" {
+ set warnpattern "operand out of range.*"
+ }
+ "badinsn.s" {
+ set warnpattern "unrecognized instruction *"
+ }
+ "badinsn1.s" {
+ set warnpattern "junk at end of line *"
+ }
+ default {
+ error "no expected result specified for $file"
+ return
+
+ }
+ }
+ mrisc1_error_test $file "assembler emits error for $file" $warnpattern
+ }
+
+}
--- /dev/null
+; load/store tests
+
+ .data
+
+ldw_data:
+ .word 0xbabeface
+
+ .text
+
+ld_text:
+ ld r4, r3
+ ld r3, #8
+ ld r5, #ld_text
+ ldh r6, #ldh_text
+ ldh r4, #4000
+ ldh r5, #0x8000
+ ldh r5, #-5
+ ldh r5, #-0x8000
+ ldh r0, #0xffff
+ldh_text:
+ ldw r9, #30233000
+ ldw r3, #ldw_data
+ ldb r3, @[r9+r2]
+ ldb @[r9+r3], r5 ; store
+ ldb r3, @[r8+6]
+ ldb @[r8+7], r3 ; store
+ ldw r9, @[r14+23]
+ ldw @[r14+10], r9 ; store
--- /dev/null
+#as:
+#objdump: -dr
+#name: misc
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+00000000 <.text>:
+ 0: 00 12 00 00 add R0,R1,R2
+ 4: 00 12 00 00 add R0,R1,R2
+ 8: 00 23 10 00 add R1,R2,R3
+ c: 00 33 10 00 add R1,R3,R3
+ 10: 00 56 40 00 add R4,R5,R6
+ 14: 00 89 70 00 add R7,R8,R9
+ 18: 00 bc a0 00 add R10,R11,R12
+ 1c: 00 ef d0 00 add R13,R14,R15
+ 20: 03 dc 00 01 addui R12,R13,#\$1
+ 24: 03 fe 00 01 addui R14,R15,#\$1
+ 28: 03 10 00 00 addui R0,R1,#\$0
+ 2c: 03 10 ff ff addui R0,R1,#\$ffff
--- /dev/null
+; Check that register names, both upper and lower case work and that
+; the spacing between the operands doesn't matter.
+
+add R0,R1,R2
+add r0,r1,r2
+add R1,R2,r3
+add R1, R3, r3
+add R4,R5,R6
+add R7,R8,R9
+add R10,R11,R12
+add R13,R14,R15
+addui fp,sp,#1
+addui ra,ira,#1
+
+; Check that the range of legal operand values is accepted.
+
+addui R0,R1,#0
+addui R0,R1,#$FFFF
+
+
+
--- /dev/null
+#as: -march=ms1-16-003
+#objdump: -dr
+#name: ms1-16-003
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+00000000 <iflush>:
+ 0: 6a 00 00 00 iflush
+00000004 <mul>:
+ 4: 08 00 00 00 mul R0,R0,R0
+00000008 <muli>:
+ 8: 09 00 00 00 muli R0,R0,#\$0
+0000000c <dbnz_>:
+ c: 3d 00 00 00 dbnz R0,c <dbnz_>
+[ ]*c: R_MS1_PC16 dbnz
+00000010 <fbcbincs>:
+ 10: f0 00 00 00 fbcbincs #\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
+00000014 <mfbcbincs>:
+ 14: f4 00 00 00 mfbcbincs R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
+00000018 <fbcbincrs>:
+ 18: f8 00 00 00 fbcbincrs R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
+0000001c <mfbcbincrs>:
+ 1c: fc 00 00 00 mfbcbincrs R0,R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
+00000020 <wfbinc>:
+ 20: e0 00 00 00 wfbinc #\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
+00000024 <mwfbinc>:
+ 24: e4 00 00 00 mwfbinc R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
+00000028 <wfbincr>:
+ 28: e8 00 00 00 wfbincr R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
+0000002c <mwfbincr>:
+ 2c: ec 00 00 00 mwfbincr R0,R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
--- /dev/null
+ .text
+ .global iflush
+iflush:
+ iflush
+
+ .global mul
+mul:
+ mul R0, R0, R0
+
+ .global muli
+muli:
+ muli R0, R0, #0
+
+ .global dbnz
+dbnz_:
+ dbnz r0, dbnz
+
+ .global fbcbincs
+fbcbincs:
+ fbcbincs #0, #0, #0, #0, #0, #0, #0, #0, #0, #0
+
+ .global mfbcbincs
+mfbcbincs:
+ mfbcbincs r0, #0, #0, #0, #0, #0, #0, #0, #0
+
+
+ .global fbcbincrs
+fbcbincrs:
+ fbcbincrs r0, #0, #0, #0, #0, #0, #0, #0, #0, #0
+
+ .global mfbcbincrs
+mfbcbincrs:
+ mfbcbincrs r0, r0, #0, #0, #0, #0, #0, #0, #0
+
+
+ .global wfbinc
+wfbinc:
+# Documentation error.
+# wfbinc #0, r0, #0, #0, #0, #0, #0, #0, #0, #0
+ wfbinc #0, #0, #0, #0, #0, #0, #0, #0, #0, #0
+
+ .global mwfbinc
+mwfbinc:
+# Documentation error.
+# mwfbinc r0, #0, #0, r0, #0, #0, #0, #0, #0
+ mwfbinc r0, #0, #0, #0, #0, #0, #0, #0, #0
+
+ .global wfbincr
+wfbincr:
+ wfbincr r0, #0, #0, #0, #0, #0, #0, #0, #0, #0
+
+ .global mwfbincr
+mwfbincr:
+ mwfbincr r0, r0, #0, #0, #0, #0, #0, #0, #0
--- /dev/null
+#as: -march=ms2
+#objdump: -dr
+#name: ms2
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+00000000 <code>:
+ 0: 3e 10 00 05 loop R1,1c <label>
+ 4: 3f 00 10 04 loopi #\$10,1c <label>
+ 8: 83 ff ff ff dfbc #\$7,#\$7,#\$ffffffff,#\$ffffffff,#\$1,#\$1,#\$3f
+ c: 87 ff ff 7f dwfb #\$7,#\$7,#\$ffffffff,#\$ffffffff,#\$1,#\$3f
+ 10: 8b ff ff ff fbwfb #\$7,#\$7,#\$ffffffff,#\$ffffffff,#\$1,#\$1,#\$3f
+ 14: 8f f0 ff ff dfbr #\$7,#\$7,R0,#\$7,#\$7,#\$7,#\$1,#\$3f
+ 18: 12 00 00 00 nop
+0000001c <label>:
+ 1c: f0 00 00 00 fbcbincs #\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
--- /dev/null
+
+code:
+ loop R1, label
+ loopi #16,label
+ dfbc #7,#7,#-1,#-1,#1,#1,#63
+ dwfb #7,#7,#-1,#-1,#1,#63
+ fbwfb #7,#7,#-1,#-1,#1,#1,#63
+ dfbr #7,#7,R0,#7,#7,#7,#1,#63
+ nop
+label:
+ fbcbincs #0,#0,#0,#0,#0,#0,#0,#0,#0,#0
--- /dev/null
+#as: -nosched
+#objdump: -dr
+#name: msys
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+00000000 <.text>:
+ 0: 80 00 00 00 ldctxt R0,R0,#\$0,#\$0,#\$0
+ 4: 84 00 00 00 ldfb R0,R0,#\$0
+ 8: 88 00 00 00 stfb R0,R0,#\$0
+ c: 8c 00 00 00 fbcb R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
+ 10: 90 00 00 00 mfbcb R0,#\$0,R0,#\$0,#\$0,#\$0,#\$0,#\$0
+ 14: 94 00 00 00 fbcci R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
+ 18: 98 00 00 00 fbrci R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
+ 1c: 9c 00 00 00 fbcri R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
+ 20: a0 00 00 00 fbrri R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
+ 24: a4 00 00 00 mfbcci R0,#\$0,R0,#\$0,#\$0,#\$0,#\$0
+ 28: a8 00 00 00 mfbrci R0,#\$0,R0,#\$0,#\$0,#\$0,#\$0
+ 2c: ac 00 00 00 mfbcri R0,#\$0,R0,#\$0,#\$0,#\$0,#\$0
+ 30: b0 00 00 00 mfbrri R0,#\$0,R0,#\$0,#\$0,#\$0,#\$0
+ 34: b4 00 00 00 fbcbdr R0,#\$0,R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
+ 38: b8 00 00 00 rcfbcb #\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
+ 3c: bc 00 00 00 mrcfbcb R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
+ 40: c0 00 00 00 cbcast #\$0,#\$0,#\$0
+ 44: c4 00 00 00 dupcbcast #\$0,#\$0,#\$0,#\$0
+ 48: c8 00 00 00 wfbi #\$0,#\$0,#\$0,#\$0,#\$0
+ 4c: cc 00 00 00 wfb R0,R0,#\$0,#\$0,#\$0
+ 50: d0 00 00 00 rcrisc R0,#\$0,R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
+ 54: d4 00 00 00 fbcbinc R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
+ 58: d8 00 00 00 rcxmode R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
+ 5c: 64 00 e0 00 si R14
+ 60: b4 00 00 40 fbcbdr R0,#\$0,R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$1,#\$0
+ 64: b4 00 00 00 fbcbdr R0,#\$0,R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
+ 68: b4 00 00 40 fbcbdr R0,#\$0,R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$1,#\$0
+ 6c: b4 00 00 00 fbcbdr R0,#\$0,R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
+ 70: 64 00 e0 00 si R14
+ 74: b8 08 00 00 rcfbcb #\$0,#\$0,#\$1,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
+ 78: b8 00 00 00 rcfbcb #\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
+ 7c: b8 08 00 00 rcfbcb #\$0,#\$0,#\$1,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
+ 80: b8 00 00 00 rcfbcb #\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
+ 84: 64 00 e0 00 si R14
+ 88: bc 20 00 00 mrcfbcb R0,#\$0,#\$2,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
+ 8c: bc 10 00 00 mrcfbcb R0,#\$0,#\$1,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
+ 90: bc 00 00 00 mrcfbcb R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
+ 94: bc 20 00 00 mrcfbcb R0,#\$0,#\$2,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
+ 98: bc 10 00 00 mrcfbcb R0,#\$0,#\$1,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
+ 9c: bc 00 00 00 mrcfbcb R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
+ a0: 64 00 e0 00 si R14
+ a4: d8 80 00 00 rcxmode R0,#\$0,#\$0,#\$1,#\$0,#\$0,#\$0,#\$0,#\$0
+ a8: d8 00 00 00 rcxmode R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
+ ac: d8 80 00 00 rcxmode R0,#\$0,#\$0,#\$1,#\$0,#\$0,#\$0,#\$0,#\$0
+ b0: d8 00 00 00 rcxmode R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
+ b4: 64 00 e0 00 si R14
+ b8: 80 00 80 00 ldctxt R0,R0,#\$1,#\$0,#\$0
+ bc: 80 00 00 00 ldctxt R0,R0,#\$0,#\$0,#\$0
+ c0: 80 00 80 00 ldctxt R0,R0,#\$1,#\$0,#\$0
+ c4: 80 00 00 00 ldctxt R0,R0,#\$0,#\$0,#\$0
+ c8: 8c 00 08 00 fbcb R0,#\$0,#\$0,#\$0,#\$1,#\$0,#\$0,#\$0,#\$0
+ cc: 8c 00 00 00 fbcb R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
+ d0: c0 00 00 40 cbcast #\$0,#\$1,#\$0
+ d4: c0 00 00 00 cbcast #\$0,#\$0,#\$0
+ d8: 64 00 e0 00 si R14
+ dc: 8c 00 04 00 fbcb R0,#\$0,#\$0,#\$0,#\$0,#\$1,#\$0,#\$0,#\$0
+ e0: 8c 00 00 00 fbcb R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
+ e4: 8c 00 04 00 fbcb R0,#\$0,#\$0,#\$0,#\$0,#\$1,#\$0,#\$0,#\$0
+ e8: 8c 00 00 00 fbcb R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
+ ec: 64 00 e0 00 si R14
+ f0: 8f 00 00 00 fbcb R0,#\$3,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
+ f4: 8e 00 00 00 fbcb R0,#\$2,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
+ f8: 8d 00 00 00 fbcb R0,#\$1,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
+ fc: 8c 00 00 00 fbcb R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
+ 100: 8f 00 00 00 fbcb R0,#\$3,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
+ 104: 8e 00 00 00 fbcb R0,#\$2,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
+ 108: 8d 00 00 00 fbcb R0,#\$1,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
+ 10c: 8c 00 00 00 fbcb R0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0,#\$0
+ 110: dc 00 00 00 intlvr R0,#\$0,R0,#\$0,#\$0
--- /dev/null
+;; This file is a set of tests for the MorphoySys instructions.
+
+; Make sure that each mnemonic gives the proper opcode. Use R0 and #0
+; for all operands so that everything but the opcode will be 0 in the
+; assembled instructions.
+
+ ldctxt R0,R0,#0,#0,#0
+ ldfb R0,R0,#0
+ stfb R0, R0, #0
+ fbcb R0,#0,#0,#0,#0,#0,#0,#0,#0
+ mfbcb R0,#0,R0,#0,#0,#0,#0,#0
+ fbcci R0,#0,#0,#0,#0,#0,#0,#0
+ fbrci R0,#0,#0,#0,#0,#0,#0,#0
+ fbcri R0,#0,#0,#0,#0,#0,#0,#0
+ fbrri R0,#0,#0,#0,#0,#0,#0,#0
+ mfbcci R0,#0,R0,#0,#0,#0,#0
+ mfbrci R0,#0,R0,#0,#0,#0,#0
+ mfbcri R0,#0,R0,#0,#0,#0,#0
+ mfbrri R0,#0,R0,#0,#0,#0,#0
+ fbcbdr R0,#0,R0,#0,#0,#0,#0,#0,#0,#0
+ rcfbcb #0,#0,#0,#0,#0,#0,#0,#0,#0,#0
+ mrcfbcb R0,#0,#0,#0,#0,#0,#0,#0,#0
+ cbcast #0,#0,#0
+ dupcbcast #0,#0,#0,#0
+ wfbi #0,#0,#0,#0,#0
+ wfb R0,R0,#0,#0,#0
+ rcrisc R0,#0,R0,#0,#0,#0,#0,#0,#0
+ fbcbinc R0, #0, #0, #0, #0, #0, #0, #0
+ rcxmode R0, #0, #0, #0, #0, #0, #0, #0, #0
+
+; Check to make sure that the parse routines that allow predifined
+; symbols (uppaer and lower case) to be used for some of the operands.
+
+; dup operand: dup, xx
+ si R14
+ fbcbdr R0,#0,R0,#0,#0,#0,#0,#0,#dup,#0 ; dup = 1
+ fbcbdr R0,#0,R0,#0,#0,#0,#0,#0,#xx,#0 ; xx = 0
+ fbcbdr R0,#0,R0,#0,#0,#0,#0,#0,#DUP,#0
+ fbcbdr R0,#0,R0,#0,#0,#0,#0,#0,#XX,#0
+
+; ball operand: all, one
+ si R14
+ rcfbcb #0,#0,#all,#0,#0,#0,#0,#0,#0,#0 ; all = 1
+ rcfbcb #0,#0,#one,#0,#0,#0,#0,#0,#0,#0 ; one = 0
+ rcfbcb #0,#0,#ALL,#0,#0,#0,#0,#0,#0,#0
+ rcfbcb #0,#0,#ONE,#0,#0,#0,#0,#0,#0,#0
+
+; type operand: odd, even, oe
+ si R14
+ mrcfbcb R0,#0,#oe,#0,#0,#0,#0,#0,#0 ; oe = 2
+ mrcfbcb R0,#0,#even,#0,#0,#0,#0,#0,#0 ; even = 1
+ mrcfbcb R0,#0,#odd,#0,#0,#0,#0,#0,#0 ; odd = 0
+ mrcfbcb R0,#0,#OE,#0,#0,#0,#0,#0,#0
+ mrcfbcb R0,#0,#EVEN,#0,#0,#0,#0,#0,#0
+ mrcfbcb R0,#0,#ODD,#0,#0,#0,#0,#0,#0
+
+; xmode operand: pm, xm
+ si R14
+ rcxmode R0, #0, #0, #pm, #0, #0, #0, #0, #0 ; pm = 1
+ rcxmode R0, #0, #0, #xm, #0, #0, #0, #0, #0 ; xm = 0
+ rcxmode R0, #0, #0, #PM, #0, #0, #0, #0, #0
+ rcxmode R0, #0, #0, #XM, #0, #0, #0, #0, #0
+
+; rc, rc1, rc2 operands: r,c
+ si R14
+ ldctxt R0,R0,#r,#0,#0 ; rc operand. r = 1
+ ldctxt R0,R0,#c,#0,#0 ; rc operand. c = 0
+ ldctxt R0,R0,#R,#0,#0
+ ldctxt R0,R0,#C,#0,#0
+
+ fbcb R0,#0,#0,#0,#r,#0,#0,#0,#0 ; rc1 operand. r = 1
+ fbcb R0,#0,#0,#0,#c,#0,#0,#0,#0 ; rc1 operand. c = 0
+
+ cbcast #0,#r,#0 ; rc2 operand. r = 1
+ cbcast #0,#c,#0 ; rc2 opearnd. c = 0
+
+; cbrb operand: cb, rb
+ si R14
+ fbcb R0,#0,#0,#0,#0,#rb,#0,#0,#0 ; rb = 1
+ fbcb R0,#0,#0,#0,#0,#cb,#0,#0,#0 ; cb = 0
+ fbcb R0,#0,#0,#0,#0,#RB,#0,#0,#0
+ fbcb R0,#0,#0,#0,#0,#CB,#0,#0,#0
+
+; rbbc operand: rt, br1, br2, cs
+ si R14
+ fbcb R0,#cs,#0,#0,#0,#0,#0,#0,#0 ; cs = 3
+ fbcb R0,#br2,#0,#0,#0,#0,#0,#0,#0 ; br2 = 2
+ fbcb R0,#br1,#0,#0,#0,#0,#0,#0,#0 ; br1 = 1
+ fbcb R0,#rt,#0,#0,#0,#cb,#0,#0,#0 ; rt = 0
+ fbcb R0,#CS,#0,#0,#0,#0,#0,#0,#0
+ fbcb R0,#BR2,#0,#0,#0,#0,#0,#0,#0
+ fbcb R0,#BR1,#0,#0,#0,#0,#0,#0,#0
+ fbcb R0,#RT,#0,#0,#0,#cb,#0,#0,#0
+
+ intlvr R0, #0, R0, #0, #0
--- /dev/null
+# MRISC1 assembler testsuite.
+
+if [istarget ms1*-*-*] {
+ #
+ run_dump_test "allinsn"
+ run_dump_test "misc"
+ run_dump_test "msys"
+ run_dump_test "ms1-16-003"
+ run_dump_test "ms2"
+ #
+}
--- /dev/null
+
+relocs.x: file format elf32-(mrisc1|ms1)
+
+Contents of section .text:
+ 2000 00131000 3700dffc 12000000 3700fff8 ....7.......7...
+ 2010 03210000 03212215 03210001 03210000 .!...!"..!...!..
+ 2020 0321ffff 0321eeee 03210005 03210006 .!...!...!...!..
+ 2030 00675000 .gP.
+Contents of section .data:
+ 2134 0f000000 00000000 00000000 00000000 ................
+ 2144 00000000 00000000 00000000 00000000 ................
+ 2154 00000000 00000000 00000000 00000000 ................
+ 2164 00000000 00000000 00000000 00000000 ................
+ 2174 00000000 00000000 00000000 00000000 ................
+ 2184 00000000 00000000 00000000 00000000 ................
+ 2194 00000000 00000000 00000000 00000000 ................
+ 21a4 00000000 00000000 00000000 00000000 ................
+ 21b4 00000000 00000000 00000000 00000000 ................
+ 21c4 00000000 00000000 00000000 00000000 ................
+ 21d4 00000000 00000000 00000000 00000000 ................
+ 21e4 00000000 00000000 00000000 00000000 ................
+ 21f4 00000000 00000000 00000000 00000000 ................
+ 2204 00000000 00000000 00000000 00000000 ................
+ 2214 00020000 00000000 00000000 00000000 ................
+ 2224 00000000 00000000 00000000 00000000 ................
+ 2234 00000000 00000000 00000000 00000000 ................
+ 2244 00000000 00000000 00000000 00000000 ................
+ 2254 00000000 00000000 00000000 00000000 ................
+ 2264 00000000 00000000 00000000 00000000 ................
+ 2274 00000000 00000000 00000000 00000000 ................
+ 2284 00000000 00000000 00000000 00000000 ................
+ 2294 00000000 00000000 00000000 00000000 ................
+ 22a4 00000000 00000000 00000000 00000000 ................
+ 22b4 00000000 00000000 00000000 00000000 ................
+ 22c4 00000000 00000000 00000000 00000000 ................
+ 22d4 00000000 00000000 00000000 00000000 ................
+ 22e4 00000000 00000000 00000000 00000000 ................
+ 22f4 00000000 00000000 00000000 00000000 ................
+ 2304 00000000 00000000 00000000 00000000 ................
+ 2314 000003 ...
+Contents of section .stack:
+ 7ffff0 deaddead ....
+Disassembly of section .text:
+
+00002000 <_start>:
+ 2000: 00 13 10 00 add R1,R1,R3
+
+00002004 <local>:
+ 2004: 37 00 df fc jmp 0 <_start-0x2000>
+
+00002008 <none>:
+ 2008: 12 00 00 00 nop
+ 200c: 37 00 ff f8 jmp 2004 <local>
+ 2010: 03 21 00 00 addui R1,R2,#\$0
+ 2014: 03 21 22 15 addui R1,R2,#\$2215
+ 2018: 03 21 00 01 addui R1,R2,#\$1
+ 201c: 03 21 00 00 addui R1,R2,#\$0
+ 2020: 03 21 ff ff addui R1,R2,#\$ffff
+ 2024: 03 21 ee ee addui R1,R2,#\$eeee
+
+00002028 <dummy1>:
+ 2028: 03 21 00 05 addui R1,R2,#\$5
+
+0000202c <dummy2>:
+ 202c: 03 21 00 06 addui R1,R2,#\$6
+
+00002030 <i2>:
+ 2030: 00 67 50 00 add R5,R6,R7
--- /dev/null
+# Relocation test.
+# This test is special because it exercises the linker's
+
+proc ld_test { objects ldflags dest test } {
+ set ld_output [target_link $objects $dest $ldflags]
+ if [string match "" $ld_output] then { pass $test } else { fail $test }
+}
+
+
+proc objdump_test { exec flags dest test } {
+ set objcopy [find_binutils_prog objdump]
+ verbose -log "$objcopy $flags $exec > $dest"
+ catch "exec $objcopy $flags $exec > $dest" objdump_output
+ if [string match "" $objdump_output] then { pass $test } else { fail $test }
+}
+
+proc regexp_test { file1 file2 test } {
+ if [regexp_diff $file1 $file2] then { fail $test } else { pass $test }
+}
+
+
+global srcdir subdir
+if [istarget ms1-*] {
+ gas_test "relocs1.s" {-o relocs1.o} {} {assembling relocs1}
+
+ # gas_test "relocs2.s" {-o relocs2.o} {} {assembling relocs2}
+ # ld_test {relocs1.o relocs2.o} {} {relocs.x} {linking relocs.x}
+ # objdump_test {relocs.x} {-ds} {relocs.dump} {disassembling relocs.x}
+ # regexp_test {relocs.dump} "$srcdir/$subdir/relocs.d" {matching disassembly}
+
+ gas_test "relocs2.s" {-o relocs2.o} {} {assembling relocs2}
+ ld_test {relocs1.o relocs2.o} {} {relocs.x} {linking relocs.x}
+ objdump_test {relocs.x} {-ds} {relocs.dump} {disassembling relocs.x}
+ regexp_test {relocs.dump} "$srcdir/$subdir/relocs.d" {matching disassembly}
+}
--- /dev/null
+;; This test is meant to exercise every unusual reloc supported
+;; by the mrisc port. (Ok, so there's only one so far. :P)
+
+ .text
+text:
+ .global _start
+_start:
+ add R1,R1,R3
+
+; Make sure local fixups work.
+local:
+ jmp (dummy2-dummy1)
+
+; Test the PC16 reloc.
+none:
+ or R0,R0,R0 ;nop to conform to scheduling restrictions
+ jmp local
+
+; Test the %hi16 and %lo16 relocs
+addui R1,R2,#%hi16(d2)
+addui R1,R2,#%lo16(d2)
+addui R1,R2,#%hi16(65536)
+addui R1,R2,#%lo16(65536)
+addui R1,R2,#%hi16($FFFFEEEE)
+addui R1,R2,#%lo16($FFFFEEEE)
+
+dummy1: addui R1, R2, #5
+dummy2: addui R1, R2, #6
+
+ .data
+d1: .byte $f
--- /dev/null
+ .text
+ ;; Put code near the top of the address space
+text:
+ .global i2
+i2:
+
+ add R5, R6, R7
+
+ .data
+ ;; Note that the .org that follows is more or less equivalent
+ ;; to a .space, since the amount specified will be treated like
+ ;; padding to be added between the .data section in relocs1.s
+ ;; and this one.
+ ;; Note also that the two test variables (d2 & d3) are intentionally
+ ;; roughly $100 apart, so that the FR9 relocation processing in
+ ;; bfd/elf32-ip2k.c (ip2k_final_link_relocate) is tested a little more.
+ .org $e0
+ .global d2
+d2: .byte 2
+ .space $100
+ .global d3
+d3: .byte 3
+++ /dev/null
-# Target: Morpho Technologies ms1 processor
-TDEPFILES= ms1-tdep.o
--- /dev/null
+# Target: Morpho Technologies ms1 processor
+TDEPFILES= ms1-tdep.o
+++ /dev/null
-/* Target-dependent code for Morpho ms1 processor, for GDB.
-
- Copyright 2005 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program 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 of the License, or
- (at your option) any later version.
-
- This program 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 this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
-
-/* Contributed by Michael Snyder, msnyder@redhat.com. */
-
-#include "defs.h"
-#include "frame.h"
-#include "frame-unwind.h"
-#include "frame-base.h"
-#include "symtab.h"
-#include "dis-asm.h"
-#include "arch-utils.h"
-#include "gdbtypes.h"
-#include "gdb_string.h"
-#include "regcache.h"
-#include "reggroups.h"
-#include "gdbcore.h"
-#include "trad-frame.h"
-#include "inferior.h"
-#include "dwarf2-frame.h"
-#include "infcall.h"
-#include "gdb_assert.h"
-
-enum ms1_arch_constants
-{
- MS1_MAX_STRUCT_SIZE = 16
-};
-
-enum ms1_gdb_regnums
-{
- MS1_R0_REGNUM, /* 32 bit regs. */
- MS1_R1_REGNUM,
- MS1_1ST_ARGREG = MS1_R1_REGNUM,
- MS1_R2_REGNUM,
- MS1_R3_REGNUM,
- MS1_R4_REGNUM,
- MS1_LAST_ARGREG = MS1_R4_REGNUM,
- MS1_R5_REGNUM,
- MS1_R6_REGNUM,
- MS1_R7_REGNUM,
- MS1_R8_REGNUM,
- MS1_R9_REGNUM,
- MS1_R10_REGNUM,
- MS1_R11_REGNUM,
- MS1_R12_REGNUM,
- MS1_FP_REGNUM = MS1_R12_REGNUM,
- MS1_R13_REGNUM,
- MS1_SP_REGNUM = MS1_R13_REGNUM,
- MS1_R14_REGNUM,
- MS1_RA_REGNUM = MS1_R14_REGNUM,
- MS1_R15_REGNUM,
- MS1_IRA_REGNUM = MS1_R15_REGNUM,
- MS1_PC_REGNUM,
-
- /* Interrupt Enable pseudo-register, exported by SID. */
- MS1_INT_ENABLE_REGNUM,
- /* End of CPU regs. */
-
- MS1_NUM_CPU_REGS,
-
- /* Co-processor registers. */
- MS1_COPRO_REGNUM = MS1_NUM_CPU_REGS, /* 16 bit regs. */
- MS1_CPR0_REGNUM,
- MS1_CPR1_REGNUM,
- MS1_CPR2_REGNUM,
- MS1_CPR3_REGNUM,
- MS1_CPR4_REGNUM,
- MS1_CPR5_REGNUM,
- MS1_CPR6_REGNUM,
- MS1_CPR7_REGNUM,
- MS1_CPR8_REGNUM,
- MS1_CPR9_REGNUM,
- MS1_CPR10_REGNUM,
- MS1_CPR11_REGNUM,
- MS1_CPR12_REGNUM,
- MS1_CPR13_REGNUM,
- MS1_CPR14_REGNUM,
- MS1_CPR15_REGNUM,
- MS1_BYPA_REGNUM, /* 32 bit regs. */
- MS1_BYPB_REGNUM,
- MS1_BYPC_REGNUM,
- MS1_FLAG_REGNUM,
- MS1_CONTEXT_REGNUM, /* 38 bits (treat as array of
- six bytes). */
- MS1_MAC_REGNUM, /* 32 bits. */
- MS1_Z1_REGNUM, /* 16 bits. */
- MS1_Z2_REGNUM, /* 16 bits. */
- MS1_ICHANNEL_REGNUM, /* 32 bits. */
- MS1_ISCRAMB_REGNUM, /* 32 bits. */
- MS1_QSCRAMB_REGNUM, /* 32 bits. */
- MS1_OUT_REGNUM, /* 16 bits. */
- MS1_EXMAC_REGNUM, /* 32 bits (8 used). */
- MS1_QCHANNEL_REGNUM, /* 32 bits. */
-
- /* Number of real registers. */
- MS1_NUM_REGS,
-
- /* Pseudo-registers. */
- MS1_COPRO_PSEUDOREG_REGNUM = MS1_NUM_REGS,
- MS1_MAC_PSEUDOREG_REGNUM,
-
- /* Two pseudo-regs ('coprocessor' and 'mac'). */
- MS1_NUM_PSEUDO_REGS = 2
-};
-
-/* Return name of register number specified by REGNUM. */
-
-static const char *
-ms1_register_name (int regnum)
-{
- static const char *const register_names[] = {
- /* CPU regs. */
- "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
- "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
- "pc", "IE",
- /* Co-processor regs. */
- "", /* copro register. */
- "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",
- "cr8", "cr9", "cr10", "cr11", "cr12", "cr13", "cr14", "cr15",
- "bypa", "bypb", "bypc", "flag", "context", "" /* mac. */ , "z1", "z2",
- "Ichannel", "Iscramb", "Qscramb", "out", "" /* ex-mac. */ , "Qchannel",
- /* Pseudo-registers. */
- "coprocessor", "MAC"
- };
-
- gdb_assert (regnum >= 0 && regnum < ARRAY_SIZE (register_names));
- return register_names[regnum];
-}
-
-/* Given ARCH and a register number specified by REGNUM, return the
- type of that register. */
-
-static struct type *
-ms1_register_type (struct gdbarch *arch, int regnum)
-{
- static struct type *void_func_ptr = NULL;
- static struct type *void_ptr = NULL;
- static struct type *copro_type;
-
- if (regnum >= 0 && regnum < MS1_NUM_REGS + MS1_NUM_PSEUDO_REGS)
- {
- if (void_func_ptr == NULL)
- {
- struct type *temp;
-
- void_ptr = lookup_pointer_type (builtin_type_void);
- void_func_ptr =
- lookup_pointer_type (lookup_function_type (builtin_type_void));
- temp = create_range_type (NULL, builtin_type_unsigned_int, 0, 1);
- copro_type = create_array_type (NULL, builtin_type_int16, temp);
- }
- switch (regnum)
- {
- case MS1_PC_REGNUM:
- case MS1_RA_REGNUM:
- case MS1_IRA_REGNUM:
- return void_func_ptr;
- case MS1_SP_REGNUM:
- case MS1_FP_REGNUM:
- return void_ptr;
- case MS1_INT_ENABLE_REGNUM:
- case MS1_ICHANNEL_REGNUM:
- case MS1_QCHANNEL_REGNUM:
- case MS1_ISCRAMB_REGNUM:
- case MS1_QSCRAMB_REGNUM:
- return builtin_type_int32;
- case MS1_EXMAC_REGNUM:
- case MS1_MAC_REGNUM:
- return builtin_type_uint32;
- case MS1_BYPA_REGNUM:
- case MS1_BYPB_REGNUM:
- case MS1_BYPC_REGNUM:
- case MS1_Z1_REGNUM:
- case MS1_Z2_REGNUM:
- case MS1_OUT_REGNUM:
- return builtin_type_int16;
- case MS1_CONTEXT_REGNUM:
- return builtin_type_long_long;
- case MS1_COPRO_REGNUM:
- case MS1_COPRO_PSEUDOREG_REGNUM:
- return copro_type;
- case MS1_MAC_PSEUDOREG_REGNUM:
- if (gdbarch_bfd_arch_info (arch)->mach == bfd_mach_mrisc2
- || gdbarch_bfd_arch_info (arch)->mach == bfd_mach_ms2)
- return builtin_type_uint64;
- else
- return builtin_type_uint32;
- case MS1_FLAG_REGNUM:
- return builtin_type_unsigned_char;
- default:
- if (regnum >= MS1_R0_REGNUM && regnum <= MS1_R15_REGNUM)
- return builtin_type_int32;
- else if (regnum >= MS1_CPR0_REGNUM && regnum <= MS1_CPR15_REGNUM)
- return builtin_type_int16;
- }
- }
- internal_error (__FILE__, __LINE__,
- _("ms1_register_type: illegal register number %d"), regnum);
-}
-
-/* Return true if register REGNUM is a member of the register group
- specified by GROUP. */
-
-static int
-ms1_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
- struct reggroup *group)
-{
- /* Groups of registers that can be displayed via "info reg". */
- if (group == all_reggroup)
- return (regnum >= 0
- && regnum < MS1_NUM_REGS + MS1_NUM_PSEUDO_REGS
- && ms1_register_name (regnum)[0] != '\0');
-
- if (group == general_reggroup)
- return (regnum >= MS1_R0_REGNUM && regnum <= MS1_R15_REGNUM);
-
- if (group == float_reggroup)
- return 0; /* No float regs. */
-
- if (group == vector_reggroup)
- return 0; /* No vector regs. */
-
- /* For any that are not handled above. */
- return default_register_reggroup_p (gdbarch, regnum, group);
-}
-
-/* Return the return value convention used for a given type TYPE.
- Optionally, fetch or set the return value via READBUF or
- WRITEBUF respectively using REGCACHE for the register
- values. */
-
-static enum return_value_convention
-ms1_return_value (struct gdbarch *gdbarch, struct type *type,
- struct regcache *regcache, gdb_byte *readbuf,
- const gdb_byte *writebuf)
-{
- if (TYPE_LENGTH (type) > 4)
- {
- /* Return values > 4 bytes are returned in memory,
- pointed to by R11. */
- if (readbuf)
- {
- ULONGEST addr;
-
- regcache_cooked_read_unsigned (regcache, MS1_R11_REGNUM, &addr);
- read_memory (addr, readbuf, TYPE_LENGTH (type));
- }
-
- if (writebuf)
- {
- ULONGEST addr;
-
- regcache_cooked_read_unsigned (regcache, MS1_R11_REGNUM, &addr);
- write_memory (addr, writebuf, TYPE_LENGTH (type));
- }
-
- return RETURN_VALUE_ABI_RETURNS_ADDRESS;
- }
- else
- {
- if (readbuf)
- {
- ULONGEST temp;
-
- /* Return values of <= 4 bytes are returned in R11. */
- regcache_cooked_read_unsigned (regcache, MS1_R11_REGNUM, &temp);
- store_unsigned_integer (readbuf, TYPE_LENGTH (type), temp);
- }
-
- if (writebuf)
- {
- if (TYPE_LENGTH (type) < 4)
- {
- gdb_byte buf[4];
- /* Add leading zeros to the value. */
- memset (buf, 0, sizeof (buf));
- memcpy (buf + sizeof (buf) - TYPE_LENGTH (type),
- writebuf, TYPE_LENGTH (type));
- regcache_cooked_write (regcache, MS1_R11_REGNUM, buf);
- }
- else /* (TYPE_LENGTH (type) == 4 */
- regcache_cooked_write (regcache, MS1_R11_REGNUM, writebuf);
- }
-
- return RETURN_VALUE_REGISTER_CONVENTION;
- }
-}
-
-/* If the input address, PC, is in a function prologue, return the
- address of the end of the prologue, otherwise return the input
- address.
-
- Note: PC is likely to be the function start, since this function
- is mainly used for advancing a breakpoint to the first line, or
- stepping to the first line when we have stepped into a function
- call. */
-
-static CORE_ADDR
-ms1_skip_prologue (CORE_ADDR pc)
-{
- CORE_ADDR func_addr = 0, func_end = 0;
- char *func_name;
- unsigned long instr;
-
- if (find_pc_partial_function (pc, &func_name, &func_addr, &func_end))
- {
- struct symtab_and_line sal;
- struct symbol *sym;
-
- /* Found a function. */
- sym = lookup_symbol (func_name, NULL, VAR_DOMAIN, NULL, NULL);
- if (sym && SYMBOL_LANGUAGE (sym) != language_asm)
- {
- /* Don't use this trick for assembly source files. */
- sal = find_pc_line (func_addr, 0);
-
- if (sal.end && sal.end < func_end)
- {
- /* Found a line number, use it as end of prologue. */
- return sal.end;
- }
- }
- }
-
- /* No function symbol, or no line symbol. Use prologue scanning method. */
- for (;; pc += 4)
- {
- instr = read_memory_unsigned_integer (pc, 4);
- if (instr == 0x12000000) /* nop */
- continue;
- if (instr == 0x12ddc000) /* copy sp into fp */
- continue;
- instr >>= 16;
- if (instr == 0x05dd) /* subi sp, sp, imm */
- continue;
- if (instr >= 0x43c0 && instr <= 0x43df) /* push */
- continue;
- /* Not an obvious prologue instruction. */
- break;
- }
-
- return pc;
-}
-
-/* The breakpoint instruction must be the same size as the smallest
- instruction in the instruction set.
-
- The BP for ms1 is defined as 0x68000000 (BREAK).
- The BP for ms2 is defined as 0x69000000 (illegal) */
-
-static const gdb_byte *
-ms1_breakpoint_from_pc (CORE_ADDR *bp_addr, int *bp_size)
-{
- static gdb_byte ms1_breakpoint[] = { 0x68, 0, 0, 0 };
- static gdb_byte ms2_breakpoint[] = { 0x69, 0, 0, 0 };
-
- *bp_size = 4;
- if (gdbarch_bfd_arch_info (current_gdbarch)->mach == bfd_mach_ms2)
- return ms2_breakpoint;
-
- return ms1_breakpoint;
-}
-
-/* Fetch the pseudo registers:
-
- There are two pseudo-registers:
- 1) The 'coprocessor' pseudo-register (which mirrors the
- "real" coprocessor register sent by the target), and
- 2) The 'MAC' pseudo-register (which represents the union
- of the original 32 bit target MAC register and the new
- 8-bit extended-MAC register). */
-
-static void
-ms1_pseudo_register_read (struct gdbarch *gdbarch,
- struct regcache *regcache, int regno, gdb_byte *buf)
-{
- switch (regno)
- {
- case MS1_COPRO_REGNUM:
- case MS1_COPRO_PSEUDOREG_REGNUM:
- regcache_raw_read (regcache, MS1_COPRO_REGNUM, buf);
- break;
- case MS1_MAC_REGNUM:
- case MS1_MAC_PSEUDOREG_REGNUM:
- if (gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_mrisc2
- || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_ms2)
- {
- ULONGEST oldmac = 0, ext_mac = 0;
- ULONGEST newmac;
-
- regcache_cooked_read_unsigned (regcache, MS1_MAC_REGNUM, &oldmac);
- regcache_cooked_read_unsigned (regcache, MS1_EXMAC_REGNUM, &ext_mac);
- newmac =
- (oldmac & 0xffffffff) | ((long long) (ext_mac & 0xff) << 32);
- store_signed_integer (buf, 8, newmac);
- }
- else
- regcache_raw_read (regcache, MS1_MAC_REGNUM, buf);
- break;
- default:
- internal_error (__FILE__, __LINE__,
- _("ms1_pseudo_register_read: bad reg # (%d)"), regno);
- break;
- }
-}
-
-/* Write the pseudo registers:
-
- Ms1 pseudo-registers are stored directly to the target. The
- 'coprocessor' register is special, because when it is modified, all
- the other coprocessor regs must be flushed from the reg cache. */
-
-static void
-ms1_pseudo_register_write (struct gdbarch *gdbarch,
- struct regcache *regcache,
- int regno, const gdb_byte *buf)
-{
- int i;
-
- switch (regno)
- {
- case MS1_COPRO_REGNUM:
- case MS1_COPRO_PSEUDOREG_REGNUM:
- regcache_raw_write (regcache, MS1_COPRO_REGNUM, buf);
- for (i = MS1_NUM_CPU_REGS; i < MS1_NUM_REGS; i++)
- set_register_cached (i, 0);
- break;
- case MS1_MAC_REGNUM:
- case MS1_MAC_PSEUDOREG_REGNUM:
- if (gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_mrisc2
- || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_ms2)
- {
- /* The 8-byte MAC pseudo-register must be broken down into two
- 32-byte registers. */
- unsigned int oldmac, ext_mac;
- ULONGEST newmac;
-
- newmac = extract_unsigned_integer (buf, 8);
- oldmac = newmac & 0xffffffff;
- ext_mac = (newmac >> 32) & 0xff;
- regcache_cooked_write_unsigned (regcache, MS1_MAC_REGNUM, oldmac);
- regcache_cooked_write_unsigned (regcache, MS1_EXMAC_REGNUM, ext_mac);
- }
- else
- regcache_raw_write (regcache, MS1_MAC_REGNUM, buf);
- break;
- default:
- internal_error (__FILE__, __LINE__,
- _("ms1_pseudo_register_write: bad reg # (%d)"), regno);
- break;
- }
-}
-
-static CORE_ADDR
-ms1_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
-{
- /* Register size is 4 bytes. */
- return align_down (sp, 4);
-}
-
-/* Implements the "info registers" command. When ``all'' is non-zero,
- the coprocessor registers will be printed in addition to the rest
- of the registers. */
-
-static void
-ms1_registers_info (struct gdbarch *gdbarch,
- struct ui_file *file,
- struct frame_info *frame, int regnum, int all)
-{
- if (regnum == -1)
- {
- int lim;
-
- lim = all ? MS1_NUM_REGS : MS1_NUM_CPU_REGS;
-
- for (regnum = 0; regnum < lim; regnum++)
- {
- /* Don't display the Qchannel register since it will be displayed
- along with Ichannel. (See below.) */
- if (regnum == MS1_QCHANNEL_REGNUM)
- continue;
-
- ms1_registers_info (gdbarch, file, frame, regnum, all);
-
- /* Display the Qchannel register immediately after Ichannel. */
- if (regnum == MS1_ICHANNEL_REGNUM)
- ms1_registers_info (gdbarch, file, frame, MS1_QCHANNEL_REGNUM, all);
- }
- }
- else
- {
- if (regnum == MS1_EXMAC_REGNUM)
- return;
- else if (regnum == MS1_CONTEXT_REGNUM)
- {
- /* Special output handling for 38-bit context register. */
- unsigned char *buff;
- unsigned int *bytes, i, regsize;
-
- regsize = register_size (gdbarch, regnum);
-
- buff = alloca (regsize);
- bytes = alloca (regsize * sizeof (*bytes));
-
- frame_register_read (frame, regnum, buff);
-
- fputs_filtered (REGISTER_NAME (regnum), file);
- print_spaces_filtered (15 - strlen (REGISTER_NAME (regnum)), file);
- fputs_filtered ("0x", file);
-
- for (i = 0; i < regsize; i++)
- fprintf_filtered (file, "%02x", (unsigned int)
- extract_unsigned_integer (buff + i, 1));
- fputs_filtered ("\t", file);
- print_longest (file, 'd', 0,
- extract_unsigned_integer (buff, regsize));
- fputs_filtered ("\n", file);
- }
- else if (regnum == MS1_COPRO_REGNUM
- || regnum == MS1_COPRO_PSEUDOREG_REGNUM)
- {
- /* Special output handling for the 'coprocessor' register. */
- gdb_byte *buf;
-
- buf = alloca (register_size (gdbarch, MS1_COPRO_REGNUM));
- frame_register_read (frame, MS1_COPRO_REGNUM, buf);
- /* And print. */
- regnum = MS1_COPRO_PSEUDOREG_REGNUM;
- fputs_filtered (REGISTER_NAME (regnum), file);
- print_spaces_filtered (15 - strlen (REGISTER_NAME (regnum)), file);
- val_print (register_type (gdbarch, regnum), buf,
- 0, 0, file, 0, 1, 0, Val_no_prettyprint);
- fputs_filtered ("\n", file);
- }
- else if (regnum == MS1_MAC_REGNUM || regnum == MS1_MAC_PSEUDOREG_REGNUM)
- {
- ULONGEST oldmac, ext_mac, newmac;
- gdb_byte buf[3 * sizeof (LONGEST)];
-
- /* Get the two "real" mac registers. */
- frame_register_read (frame, MS1_MAC_REGNUM, buf);
- oldmac = extract_unsigned_integer
- (buf, register_size (gdbarch, MS1_MAC_REGNUM));
- if (gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_mrisc2
- || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_ms2)
- {
- frame_register_read (frame, MS1_EXMAC_REGNUM, buf);
- ext_mac = extract_unsigned_integer
- (buf, register_size (gdbarch, MS1_EXMAC_REGNUM));
- }
- else
- ext_mac = 0;
-
- /* Add them together. */
- newmac = (oldmac & 0xffffffff) + ((ext_mac & 0xff) << 32);
-
- /* And print. */
- regnum = MS1_MAC_PSEUDOREG_REGNUM;
- fputs_filtered (REGISTER_NAME (regnum), file);
- print_spaces_filtered (15 - strlen (REGISTER_NAME (regnum)), file);
- fputs_filtered ("0x", file);
- print_longest (file, 'x', 0, newmac);
- fputs_filtered ("\t", file);
- print_longest (file, 'u', 0, newmac);
- fputs_filtered ("\n", file);
- }
- else
- default_print_registers_info (gdbarch, file, frame, regnum, all);
- }
-}
-
-/* Set up the callee's arguments for an inferior function call. The
- arguments are pushed on the stack or are placed in registers as
- appropriate. It also sets up the return address (which points to
- the call dummy breakpoint).
-
- Returns the updated (and aligned) stack pointer. */
-
-static CORE_ADDR
-ms1_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
- struct regcache *regcache, CORE_ADDR bp_addr,
- int nargs, struct value **args, CORE_ADDR sp,
- int struct_return, CORE_ADDR struct_addr)
-{
-#define wordsize 4
- gdb_byte buf[MS1_MAX_STRUCT_SIZE];
- int argreg = MS1_1ST_ARGREG;
- int split_param_len = 0;
- int stack_dest = sp;
- int slacklen;
- int typelen;
- int i, j;
-
- /* First handle however many args we can fit into MS1_1ST_ARGREG thru
- MS1_LAST_ARGREG. */
- for (i = 0; i < nargs && argreg <= MS1_LAST_ARGREG; i++)
- {
- const gdb_byte *val;
- typelen = TYPE_LENGTH (value_type (args[i]));
- switch (typelen)
- {
- case 1:
- case 2:
- case 3:
- case 4:
- regcache_cooked_write_unsigned (regcache, argreg++,
- extract_unsigned_integer
- (value_contents (args[i]),
- wordsize));
- break;
- case 8:
- case 12:
- case 16:
- val = value_contents (args[i]);
- while (typelen > 0)
- {
- if (argreg <= MS1_LAST_ARGREG)
- {
- /* This word of the argument is passed in a register. */
- regcache_cooked_write_unsigned (regcache, argreg++,
- extract_unsigned_integer
- (val, wordsize));
- typelen -= wordsize;
- val += wordsize;
- }
- else
- {
- /* Remainder of this arg must be passed on the stack
- (deferred to do later). */
- split_param_len = typelen;
- memcpy (buf, val, typelen);
- break; /* No more args can be handled in regs. */
- }
- }
- break;
- default:
- /* By reverse engineering of gcc output, args bigger than
- 16 bytes go on the stack, and their address is passed
- in the argreg. */
- stack_dest -= typelen;
- write_memory (stack_dest, value_contents (args[i]), typelen);
- regcache_cooked_write_unsigned (regcache, argreg++, stack_dest);
- break;
- }
- }
-
- /* Next, the rest of the arguments go onto the stack, in reverse order. */
- for (j = nargs - 1; j >= i; j--)
- {
- gdb_byte *val;
-
- /* Right-justify the value in an aligned-length buffer. */
- typelen = TYPE_LENGTH (value_type (args[j]));
- slacklen = (wordsize - (typelen % wordsize)) % wordsize;
- val = alloca (typelen + slacklen);
- memcpy (val, value_contents (args[j]), typelen);
- memset (val + typelen, 0, slacklen);
- /* Now write this data to the stack. */
- stack_dest -= typelen + slacklen;
- write_memory (stack_dest, val, typelen + slacklen);
- }
-
- /* Finally, if a param needs to be split between registers and stack,
- write the second half to the stack now. */
- if (split_param_len != 0)
- {
- stack_dest -= split_param_len;
- write_memory (stack_dest, buf, split_param_len);
- }
-
- /* Set up return address (provided to us as bp_addr). */
- regcache_cooked_write_unsigned (regcache, MS1_RA_REGNUM, bp_addr);
-
- /* Store struct return address, if given. */
- if (struct_return && struct_addr != 0)
- regcache_cooked_write_unsigned (regcache, MS1_R11_REGNUM, struct_addr);
-
- /* Set aside 16 bytes for the callee to save regs 1-4. */
- stack_dest -= 16;
-
- /* Update the stack pointer. */
- regcache_cooked_write_unsigned (regcache, MS1_SP_REGNUM, stack_dest);
-
- /* And that should do it. Return the new stack pointer. */
- return stack_dest;
-}
-
-
-/* The 'unwind_cache' data structure. */
-
-struct ms1_unwind_cache
-{
- /* The previous frame's inner most stack address.
- Used as this frame ID's stack_addr. */
- CORE_ADDR prev_sp;
- CORE_ADDR frame_base;
- int framesize;
- int frameless_p;
-
- /* Table indicating the location of each and every register. */
- struct trad_frame_saved_reg *saved_regs;
-};
-
-/* Initialize an unwind_cache. Build up the saved_regs table etc. for
- the frame. */
-
-static struct ms1_unwind_cache *
-ms1_frame_unwind_cache (struct frame_info *next_frame,
- void **this_prologue_cache)
-{
- struct gdbarch *gdbarch;
- struct ms1_unwind_cache *info;
- CORE_ADDR next_addr, start_addr, end_addr, prologue_end_addr;
- unsigned long instr, upper_half, delayed_store = 0;
- int regnum, offset;
- ULONGEST sp, fp;
-
- if ((*this_prologue_cache))
- return (*this_prologue_cache);
-
- gdbarch = get_frame_arch (next_frame);
- info = FRAME_OBSTACK_ZALLOC (struct ms1_unwind_cache);
- (*this_prologue_cache) = info;
-
- info->prev_sp = 0;
- info->framesize = 0;
- info->frame_base = 0;
- info->frameless_p = 1;
- info->saved_regs = trad_frame_alloc_saved_regs (next_frame);
-
- /* Grab the frame-relative values of SP and FP, needed below.
- The frame_saved_register function will find them on the
- stack or in the registers as appropriate. */
- frame_unwind_unsigned_register (next_frame, MS1_SP_REGNUM, &sp);
- frame_unwind_unsigned_register (next_frame, MS1_FP_REGNUM, &fp);
-
- start_addr = frame_func_unwind (next_frame);
-
- /* Return early if GDB couldn't find the function. */
- if (start_addr == 0)
- return info;
-
- end_addr = frame_pc_unwind (next_frame);
- prologue_end_addr = skip_prologue_using_sal (start_addr);
- if (end_addr == 0)
- for (next_addr = start_addr; next_addr < end_addr; next_addr += 4)
- {
- instr = get_frame_memory_unsigned (next_frame, next_addr, 4);
- if (delayed_store) /* previous instr was a push */
- {
- upper_half = delayed_store >> 16;
- regnum = upper_half & 0xf;
- offset = delayed_store & 0xffff;
- switch (upper_half & 0xfff0)
- {
- case 0x43c0: /* push using frame pointer */
- info->saved_regs[regnum].addr = offset;
- break;
- case 0x43d0: /* push using stack pointer */
- info->saved_regs[regnum].addr = offset;
- break;
- default: /* lint */
- break;
- }
- delayed_store = 0;
- }
-
- switch (instr)
- {
- case 0x12000000: /* NO-OP */
- continue;
- case 0x12ddc000: /* copy sp into fp */
- info->frameless_p = 0; /* Record that the frame pointer is in use. */
- continue;
- default:
- upper_half = instr >> 16;
- if (upper_half == 0x05dd || /* subi sp, sp, imm */
- upper_half == 0x07dd) /* subui sp, sp, imm */
- {
- /* Record the frame size. */
- info->framesize = instr & 0xffff;
- continue;
- }
- if ((upper_half & 0xfff0) == 0x43c0 || /* frame push */
- (upper_half & 0xfff0) == 0x43d0) /* stack push */
- {
- /* Save this instruction, but don't record the
- pushed register as 'saved' until we see the
- next instruction. That's because of deferred stores
- on this target -- GDB won't be able to read the register
- from the stack until one instruction later. */
- delayed_store = instr;
- continue;
- }
- /* Not a prologue instruction. Is this the end of the prologue?
- This is the most difficult decision; when to stop scanning.
-
- If we have no line symbol, then the best thing we can do
- is to stop scanning when we encounter an instruction that
- is not likely to be a part of the prologue.
-
- But if we do have a line symbol, then we should
- keep scanning until we reach it (or we reach end_addr). */
-
- if (prologue_end_addr && (prologue_end_addr > (next_addr + 4)))
- continue; /* Keep scanning, recording saved_regs etc. */
- else
- break; /* Quit scanning: breakpoint can be set here. */
- }
- }
-
- /* Special handling for the "saved" address of the SP:
- The SP is of course never saved on the stack at all, so
- by convention what we put here is simply the previous
- _value_ of the SP (as opposed to an address where the
- previous value would have been pushed). This will also
- give us the frame base address. */
-
- if (info->frameless_p)
- {
- info->frame_base = sp + info->framesize;
- info->prev_sp = sp + info->framesize;
- }
- else
- {
- info->frame_base = fp + info->framesize;
- info->prev_sp = fp + info->framesize;
- }
- /* Save prev_sp in saved_regs as a value, not as an address. */
- trad_frame_set_value (info->saved_regs, MS1_SP_REGNUM, info->prev_sp);
-
- /* Now convert frame offsets to actual addresses (not offsets). */
- for (regnum = 0; regnum < MS1_NUM_REGS; regnum++)
- if (trad_frame_addr_p (info->saved_regs, regnum))
- info->saved_regs[regnum].addr += info->frame_base - info->framesize;
-
- /* The call instruction moves the caller's PC in the callee's RA reg.
- Since this is an unwind, do the reverse. Copy the location of RA
- into PC (the address / regnum) so that a request for PC will be
- converted into a request for the RA. */
- info->saved_regs[MS1_PC_REGNUM] = info->saved_regs[MS1_RA_REGNUM];
-
- return info;
-}
-
-static CORE_ADDR
-ms1_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
-{
- ULONGEST pc;
-
- frame_unwind_unsigned_register (next_frame, MS1_PC_REGNUM, &pc);
- return pc;
-}
-
-static CORE_ADDR
-ms1_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
-{
- ULONGEST sp;
-
- frame_unwind_unsigned_register (next_frame, MS1_SP_REGNUM, &sp);
- return sp;
-}
-
-/* Assuming NEXT_FRAME->prev is a dummy, return the frame ID of that
- dummy frame. The frame ID's base needs to match the TOS value
- saved by save_dummy_frame_tos(), and the PC match the dummy frame's
- breakpoint. */
-
-static struct frame_id
-ms1_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
-{
- return frame_id_build (ms1_unwind_sp (gdbarch, next_frame),
- frame_pc_unwind (next_frame));
-}
-
-/* Given a GDB frame, determine the address of the calling function's
- frame. This will be used to create a new GDB frame struct. */
-
-static void
-ms1_frame_this_id (struct frame_info *next_frame,
- void **this_prologue_cache, struct frame_id *this_id)
-{
- struct ms1_unwind_cache *info =
- ms1_frame_unwind_cache (next_frame, this_prologue_cache);
-
- if (!(info == NULL || info->prev_sp == 0))
- {
- (*this_id) = frame_id_build (info->prev_sp,
- frame_func_unwind (next_frame));
- }
- return;
-}
-
-static void
-ms1_frame_prev_register (struct frame_info *next_frame,
- void **this_prologue_cache,
- int regnum, int *optimizedp,
- enum lval_type *lvalp, CORE_ADDR *addrp,
- int *realnump, gdb_byte *bufferp)
-{
- struct ms1_unwind_cache *info =
- ms1_frame_unwind_cache (next_frame, this_prologue_cache);
-
- trad_frame_get_prev_register (next_frame, info->saved_regs, regnum,
- optimizedp, lvalp, addrp, realnump, bufferp);
-}
-
-static CORE_ADDR
-ms1_frame_base_address (struct frame_info *next_frame,
- void **this_prologue_cache)
-{
- struct ms1_unwind_cache *info =
- ms1_frame_unwind_cache (next_frame, this_prologue_cache);
-
- return info->frame_base;
-}
-
-/* This is a shared interface: the 'frame_unwind' object is what's
- returned by the 'sniffer' function, and in turn specifies how to
- get a frame's ID and prev_regs.
-
- This exports the 'prev_register' and 'this_id' methods. */
-
-static const struct frame_unwind ms1_frame_unwind = {
- NORMAL_FRAME,
- ms1_frame_this_id,
- ms1_frame_prev_register
-};
-
-/* The sniffer is a registered function that identifies our family of
- frame unwind functions (this_id and prev_register). */
-
-static const struct frame_unwind *
-ms1_frame_sniffer (struct frame_info *next_frame)
-{
- return &ms1_frame_unwind;
-}
-
-/* Another shared interface: the 'frame_base' object specifies how to
- unwind a frame and secure the base addresses for frame objects
- (locals, args). */
-
-static struct frame_base ms1_frame_base = {
- &ms1_frame_unwind,
- ms1_frame_base_address,
- ms1_frame_base_address,
- ms1_frame_base_address
-};
-
-static struct gdbarch *
-ms1_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
-{
- struct gdbarch *gdbarch;
-
- /* Find a candidate among the list of pre-declared architectures. */
- arches = gdbarch_list_lookup_by_info (arches, &info);
- if (arches != NULL)
- return arches->gdbarch;
-
- /* None found, create a new architecture from the information
- provided. */
- gdbarch = gdbarch_alloc (&info, NULL);
-
- switch (info.byte_order)
- {
- case BFD_ENDIAN_BIG:
- set_gdbarch_float_format (gdbarch, &floatformat_ieee_single_big);
- set_gdbarch_double_format (gdbarch, &floatformat_ieee_double_big);
- set_gdbarch_long_double_format (gdbarch, &floatformat_ieee_double_big);
- break;
- case BFD_ENDIAN_LITTLE:
- set_gdbarch_float_format (gdbarch, &floatformat_ieee_single_little);
- set_gdbarch_double_format (gdbarch, &floatformat_ieee_double_little);
- set_gdbarch_long_double_format (gdbarch,
- &floatformat_ieee_double_little);
- break;
- default:
- internal_error (__FILE__, __LINE__,
- _("ms1_gdbarch_init: bad byte order for float format"));
- }
-
- set_gdbarch_register_name (gdbarch, ms1_register_name);
- set_gdbarch_num_regs (gdbarch, MS1_NUM_REGS);
- set_gdbarch_num_pseudo_regs (gdbarch, MS1_NUM_PSEUDO_REGS);
- set_gdbarch_pc_regnum (gdbarch, MS1_PC_REGNUM);
- set_gdbarch_sp_regnum (gdbarch, MS1_SP_REGNUM);
- set_gdbarch_pseudo_register_read (gdbarch, ms1_pseudo_register_read);
- set_gdbarch_pseudo_register_write (gdbarch, ms1_pseudo_register_write);
- set_gdbarch_skip_prologue (gdbarch, ms1_skip_prologue);
- set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
- set_gdbarch_breakpoint_from_pc (gdbarch, ms1_breakpoint_from_pc);
- set_gdbarch_decr_pc_after_break (gdbarch, 0);
- set_gdbarch_frame_args_skip (gdbarch, 0);
- set_gdbarch_print_insn (gdbarch, print_insn_ms1);
- set_gdbarch_register_type (gdbarch, ms1_register_type);
- set_gdbarch_register_reggroup_p (gdbarch, ms1_register_reggroup_p);
-
- set_gdbarch_return_value (gdbarch, ms1_return_value);
- set_gdbarch_sp_regnum (gdbarch, MS1_SP_REGNUM);
-
- set_gdbarch_frame_align (gdbarch, ms1_frame_align);
-
- set_gdbarch_print_registers_info (gdbarch, ms1_registers_info);
-
- set_gdbarch_push_dummy_call (gdbarch, ms1_push_dummy_call);
-
- /* Target builtin data types. */
- set_gdbarch_short_bit (gdbarch, 16);
- set_gdbarch_int_bit (gdbarch, 32);
- set_gdbarch_long_bit (gdbarch, 32);
- set_gdbarch_long_long_bit (gdbarch, 64);
- set_gdbarch_float_bit (gdbarch, 32);
- set_gdbarch_double_bit (gdbarch, 64);
- set_gdbarch_long_double_bit (gdbarch, 64);
- set_gdbarch_ptr_bit (gdbarch, 32);
-
- /* Register the DWARF 2 sniffer first, and then the traditional prologue
- based sniffer. */
- frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);
- frame_unwind_append_sniffer (gdbarch, ms1_frame_sniffer);
- frame_base_set_default (gdbarch, &ms1_frame_base);
-
- /* Register the 'unwind_pc' method. */
- set_gdbarch_unwind_pc (gdbarch, ms1_unwind_pc);
- set_gdbarch_unwind_sp (gdbarch, ms1_unwind_sp);
-
- /* Methods for saving / extracting a dummy frame's ID.
- The ID's stack address must match the SP value returned by
- PUSH_DUMMY_CALL, and saved by generic_save_dummy_frame_tos. */
- set_gdbarch_unwind_dummy_id (gdbarch, ms1_unwind_dummy_id);
-
- return gdbarch;
-}
-
-void
-_initialize_ms1_tdep (void)
-{
- register_gdbarch_init (bfd_arch_ms1, ms1_gdbarch_init);
-}
--- /dev/null
+/* Target-dependent code for Morpho ms1 processor, for GDB.
+
+ Copyright 2005 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program 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 of the License, or
+ (at your option) any later version.
+
+ This program 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 this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* Contributed by Michael Snyder, msnyder@redhat.com. */
+
+#include "defs.h"
+#include "frame.h"
+#include "frame-unwind.h"
+#include "frame-base.h"
+#include "symtab.h"
+#include "dis-asm.h"
+#include "arch-utils.h"
+#include "gdbtypes.h"
+#include "gdb_string.h"
+#include "regcache.h"
+#include "reggroups.h"
+#include "gdbcore.h"
+#include "trad-frame.h"
+#include "inferior.h"
+#include "dwarf2-frame.h"
+#include "infcall.h"
+#include "gdb_assert.h"
+
+enum ms1_arch_constants
+{
+ MS1_MAX_STRUCT_SIZE = 16
+};
+
+enum ms1_gdb_regnums
+{
+ MS1_R0_REGNUM, /* 32 bit regs. */
+ MS1_R1_REGNUM,
+ MS1_1ST_ARGREG = MS1_R1_REGNUM,
+ MS1_R2_REGNUM,
+ MS1_R3_REGNUM,
+ MS1_R4_REGNUM,
+ MS1_LAST_ARGREG = MS1_R4_REGNUM,
+ MS1_R5_REGNUM,
+ MS1_R6_REGNUM,
+ MS1_R7_REGNUM,
+ MS1_R8_REGNUM,
+ MS1_R9_REGNUM,
+ MS1_R10_REGNUM,
+ MS1_R11_REGNUM,
+ MS1_R12_REGNUM,
+ MS1_FP_REGNUM = MS1_R12_REGNUM,
+ MS1_R13_REGNUM,
+ MS1_SP_REGNUM = MS1_R13_REGNUM,
+ MS1_R14_REGNUM,
+ MS1_RA_REGNUM = MS1_R14_REGNUM,
+ MS1_R15_REGNUM,
+ MS1_IRA_REGNUM = MS1_R15_REGNUM,
+ MS1_PC_REGNUM,
+
+ /* Interrupt Enable pseudo-register, exported by SID. */
+ MS1_INT_ENABLE_REGNUM,
+ /* End of CPU regs. */
+
+ MS1_NUM_CPU_REGS,
+
+ /* Co-processor registers. */
+ MS1_COPRO_REGNUM = MS1_NUM_CPU_REGS, /* 16 bit regs. */
+ MS1_CPR0_REGNUM,
+ MS1_CPR1_REGNUM,
+ MS1_CPR2_REGNUM,
+ MS1_CPR3_REGNUM,
+ MS1_CPR4_REGNUM,
+ MS1_CPR5_REGNUM,
+ MS1_CPR6_REGNUM,
+ MS1_CPR7_REGNUM,
+ MS1_CPR8_REGNUM,
+ MS1_CPR9_REGNUM,
+ MS1_CPR10_REGNUM,
+ MS1_CPR11_REGNUM,
+ MS1_CPR12_REGNUM,
+ MS1_CPR13_REGNUM,
+ MS1_CPR14_REGNUM,
+ MS1_CPR15_REGNUM,
+ MS1_BYPA_REGNUM, /* 32 bit regs. */
+ MS1_BYPB_REGNUM,
+ MS1_BYPC_REGNUM,
+ MS1_FLAG_REGNUM,
+ MS1_CONTEXT_REGNUM, /* 38 bits (treat as array of
+ six bytes). */
+ MS1_MAC_REGNUM, /* 32 bits. */
+ MS1_Z1_REGNUM, /* 16 bits. */
+ MS1_Z2_REGNUM, /* 16 bits. */
+ MS1_ICHANNEL_REGNUM, /* 32 bits. */
+ MS1_ISCRAMB_REGNUM, /* 32 bits. */
+ MS1_QSCRAMB_REGNUM, /* 32 bits. */
+ MS1_OUT_REGNUM, /* 16 bits. */
+ MS1_EXMAC_REGNUM, /* 32 bits (8 used). */
+ MS1_QCHANNEL_REGNUM, /* 32 bits. */
+
+ /* Number of real registers. */
+ MS1_NUM_REGS,
+
+ /* Pseudo-registers. */
+ MS1_COPRO_PSEUDOREG_REGNUM = MS1_NUM_REGS,
+ MS1_MAC_PSEUDOREG_REGNUM,
+
+ /* Two pseudo-regs ('coprocessor' and 'mac'). */
+ MS1_NUM_PSEUDO_REGS = 2
+};
+
+/* Return name of register number specified by REGNUM. */
+
+static const char *
+ms1_register_name (int regnum)
+{
+ static const char *const register_names[] = {
+ /* CPU regs. */
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ "pc", "IE",
+ /* Co-processor regs. */
+ "", /* copro register. */
+ "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",
+ "cr8", "cr9", "cr10", "cr11", "cr12", "cr13", "cr14", "cr15",
+ "bypa", "bypb", "bypc", "flag", "context", "" /* mac. */ , "z1", "z2",
+ "Ichannel", "Iscramb", "Qscramb", "out", "" /* ex-mac. */ , "Qchannel",
+ /* Pseudo-registers. */
+ "coprocessor", "MAC"
+ };
+
+ gdb_assert (regnum >= 0 && regnum < ARRAY_SIZE (register_names));
+ return register_names[regnum];
+}
+
+/* Given ARCH and a register number specified by REGNUM, return the
+ type of that register. */
+
+static struct type *
+ms1_register_type (struct gdbarch *arch, int regnum)
+{
+ static struct type *void_func_ptr = NULL;
+ static struct type *void_ptr = NULL;
+ static struct type *copro_type;
+
+ if (regnum >= 0 && regnum < MS1_NUM_REGS + MS1_NUM_PSEUDO_REGS)
+ {
+ if (void_func_ptr == NULL)
+ {
+ struct type *temp;
+
+ void_ptr = lookup_pointer_type (builtin_type_void);
+ void_func_ptr =
+ lookup_pointer_type (lookup_function_type (builtin_type_void));
+ temp = create_range_type (NULL, builtin_type_unsigned_int, 0, 1);
+ copro_type = create_array_type (NULL, builtin_type_int16, temp);
+ }
+ switch (regnum)
+ {
+ case MS1_PC_REGNUM:
+ case MS1_RA_REGNUM:
+ case MS1_IRA_REGNUM:
+ return void_func_ptr;
+ case MS1_SP_REGNUM:
+ case MS1_FP_REGNUM:
+ return void_ptr;
+ case MS1_INT_ENABLE_REGNUM:
+ case MS1_ICHANNEL_REGNUM:
+ case MS1_QCHANNEL_REGNUM:
+ case MS1_ISCRAMB_REGNUM:
+ case MS1_QSCRAMB_REGNUM:
+ return builtin_type_int32;
+ case MS1_EXMAC_REGNUM:
+ case MS1_MAC_REGNUM:
+ return builtin_type_uint32;
+ case MS1_BYPA_REGNUM:
+ case MS1_BYPB_REGNUM:
+ case MS1_BYPC_REGNUM:
+ case MS1_Z1_REGNUM:
+ case MS1_Z2_REGNUM:
+ case MS1_OUT_REGNUM:
+ return builtin_type_int16;
+ case MS1_CONTEXT_REGNUM:
+ return builtin_type_long_long;
+ case MS1_COPRO_REGNUM:
+ case MS1_COPRO_PSEUDOREG_REGNUM:
+ return copro_type;
+ case MS1_MAC_PSEUDOREG_REGNUM:
+ if (gdbarch_bfd_arch_info (arch)->mach == bfd_mach_mrisc2
+ || gdbarch_bfd_arch_info (arch)->mach == bfd_mach_ms2)
+ return builtin_type_uint64;
+ else
+ return builtin_type_uint32;
+ case MS1_FLAG_REGNUM:
+ return builtin_type_unsigned_char;
+ default:
+ if (regnum >= MS1_R0_REGNUM && regnum <= MS1_R15_REGNUM)
+ return builtin_type_int32;
+ else if (regnum >= MS1_CPR0_REGNUM && regnum <= MS1_CPR15_REGNUM)
+ return builtin_type_int16;
+ }
+ }
+ internal_error (__FILE__, __LINE__,
+ _("ms1_register_type: illegal register number %d"), regnum);
+}
+
+/* Return true if register REGNUM is a member of the register group
+ specified by GROUP. */
+
+static int
+ms1_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
+ struct reggroup *group)
+{
+ /* Groups of registers that can be displayed via "info reg". */
+ if (group == all_reggroup)
+ return (regnum >= 0
+ && regnum < MS1_NUM_REGS + MS1_NUM_PSEUDO_REGS
+ && ms1_register_name (regnum)[0] != '\0');
+
+ if (group == general_reggroup)
+ return (regnum >= MS1_R0_REGNUM && regnum <= MS1_R15_REGNUM);
+
+ if (group == float_reggroup)
+ return 0; /* No float regs. */
+
+ if (group == vector_reggroup)
+ return 0; /* No vector regs. */
+
+ /* For any that are not handled above. */
+ return default_register_reggroup_p (gdbarch, regnum, group);
+}
+
+/* Return the return value convention used for a given type TYPE.
+ Optionally, fetch or set the return value via READBUF or
+ WRITEBUF respectively using REGCACHE for the register
+ values. */
+
+static enum return_value_convention
+ms1_return_value (struct gdbarch *gdbarch, struct type *type,
+ struct regcache *regcache, gdb_byte *readbuf,
+ const gdb_byte *writebuf)
+{
+ if (TYPE_LENGTH (type) > 4)
+ {
+ /* Return values > 4 bytes are returned in memory,
+ pointed to by R11. */
+ if (readbuf)
+ {
+ ULONGEST addr;
+
+ regcache_cooked_read_unsigned (regcache, MS1_R11_REGNUM, &addr);
+ read_memory (addr, readbuf, TYPE_LENGTH (type));
+ }
+
+ if (writebuf)
+ {
+ ULONGEST addr;
+
+ regcache_cooked_read_unsigned (regcache, MS1_R11_REGNUM, &addr);
+ write_memory (addr, writebuf, TYPE_LENGTH (type));
+ }
+
+ return RETURN_VALUE_ABI_RETURNS_ADDRESS;
+ }
+ else
+ {
+ if (readbuf)
+ {
+ ULONGEST temp;
+
+ /* Return values of <= 4 bytes are returned in R11. */
+ regcache_cooked_read_unsigned (regcache, MS1_R11_REGNUM, &temp);
+ store_unsigned_integer (readbuf, TYPE_LENGTH (type), temp);
+ }
+
+ if (writebuf)
+ {
+ if (TYPE_LENGTH (type) < 4)
+ {
+ gdb_byte buf[4];
+ /* Add leading zeros to the value. */
+ memset (buf, 0, sizeof (buf));
+ memcpy (buf + sizeof (buf) - TYPE_LENGTH (type),
+ writebuf, TYPE_LENGTH (type));
+ regcache_cooked_write (regcache, MS1_R11_REGNUM, buf);
+ }
+ else /* (TYPE_LENGTH (type) == 4 */
+ regcache_cooked_write (regcache, MS1_R11_REGNUM, writebuf);
+ }
+
+ return RETURN_VALUE_REGISTER_CONVENTION;
+ }
+}
+
+/* If the input address, PC, is in a function prologue, return the
+ address of the end of the prologue, otherwise return the input
+ address.
+
+ Note: PC is likely to be the function start, since this function
+ is mainly used for advancing a breakpoint to the first line, or
+ stepping to the first line when we have stepped into a function
+ call. */
+
+static CORE_ADDR
+ms1_skip_prologue (CORE_ADDR pc)
+{
+ CORE_ADDR func_addr = 0, func_end = 0;
+ char *func_name;
+ unsigned long instr;
+
+ if (find_pc_partial_function (pc, &func_name, &func_addr, &func_end))
+ {
+ struct symtab_and_line sal;
+ struct symbol *sym;
+
+ /* Found a function. */
+ sym = lookup_symbol (func_name, NULL, VAR_DOMAIN, NULL, NULL);
+ if (sym && SYMBOL_LANGUAGE (sym) != language_asm)
+ {
+ /* Don't use this trick for assembly source files. */
+ sal = find_pc_line (func_addr, 0);
+
+ if (sal.end && sal.end < func_end)
+ {
+ /* Found a line number, use it as end of prologue. */
+ return sal.end;
+ }
+ }
+ }
+
+ /* No function symbol, or no line symbol. Use prologue scanning method. */
+ for (;; pc += 4)
+ {
+ instr = read_memory_unsigned_integer (pc, 4);
+ if (instr == 0x12000000) /* nop */
+ continue;
+ if (instr == 0x12ddc000) /* copy sp into fp */
+ continue;
+ instr >>= 16;
+ if (instr == 0x05dd) /* subi sp, sp, imm */
+ continue;
+ if (instr >= 0x43c0 && instr <= 0x43df) /* push */
+ continue;
+ /* Not an obvious prologue instruction. */
+ break;
+ }
+
+ return pc;
+}
+
+/* The breakpoint instruction must be the same size as the smallest
+ instruction in the instruction set.
+
+ The BP for ms1 is defined as 0x68000000 (BREAK).
+ The BP for ms2 is defined as 0x69000000 (illegal) */
+
+static const gdb_byte *
+ms1_breakpoint_from_pc (CORE_ADDR *bp_addr, int *bp_size)
+{
+ static gdb_byte ms1_breakpoint[] = { 0x68, 0, 0, 0 };
+ static gdb_byte ms2_breakpoint[] = { 0x69, 0, 0, 0 };
+
+ *bp_size = 4;
+ if (gdbarch_bfd_arch_info (current_gdbarch)->mach == bfd_mach_ms2)
+ return ms2_breakpoint;
+
+ return ms1_breakpoint;
+}
+
+/* Fetch the pseudo registers:
+
+ There are two pseudo-registers:
+ 1) The 'coprocessor' pseudo-register (which mirrors the
+ "real" coprocessor register sent by the target), and
+ 2) The 'MAC' pseudo-register (which represents the union
+ of the original 32 bit target MAC register and the new
+ 8-bit extended-MAC register). */
+
+static void
+ms1_pseudo_register_read (struct gdbarch *gdbarch,
+ struct regcache *regcache, int regno, gdb_byte *buf)
+{
+ switch (regno)
+ {
+ case MS1_COPRO_REGNUM:
+ case MS1_COPRO_PSEUDOREG_REGNUM:
+ regcache_raw_read (regcache, MS1_COPRO_REGNUM, buf);
+ break;
+ case MS1_MAC_REGNUM:
+ case MS1_MAC_PSEUDOREG_REGNUM:
+ if (gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_mrisc2
+ || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_ms2)
+ {
+ ULONGEST oldmac = 0, ext_mac = 0;
+ ULONGEST newmac;
+
+ regcache_cooked_read_unsigned (regcache, MS1_MAC_REGNUM, &oldmac);
+ regcache_cooked_read_unsigned (regcache, MS1_EXMAC_REGNUM, &ext_mac);
+ newmac =
+ (oldmac & 0xffffffff) | ((long long) (ext_mac & 0xff) << 32);
+ store_signed_integer (buf, 8, newmac);
+ }
+ else
+ regcache_raw_read (regcache, MS1_MAC_REGNUM, buf);
+ break;
+ default:
+ internal_error (__FILE__, __LINE__,
+ _("ms1_pseudo_register_read: bad reg # (%d)"), regno);
+ break;
+ }
+}
+
+/* Write the pseudo registers:
+
+ Ms1 pseudo-registers are stored directly to the target. The
+ 'coprocessor' register is special, because when it is modified, all
+ the other coprocessor regs must be flushed from the reg cache. */
+
+static void
+ms1_pseudo_register_write (struct gdbarch *gdbarch,
+ struct regcache *regcache,
+ int regno, const gdb_byte *buf)
+{
+ int i;
+
+ switch (regno)
+ {
+ case MS1_COPRO_REGNUM:
+ case MS1_COPRO_PSEUDOREG_REGNUM:
+ regcache_raw_write (regcache, MS1_COPRO_REGNUM, buf);
+ for (i = MS1_NUM_CPU_REGS; i < MS1_NUM_REGS; i++)
+ set_register_cached (i, 0);
+ break;
+ case MS1_MAC_REGNUM:
+ case MS1_MAC_PSEUDOREG_REGNUM:
+ if (gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_mrisc2
+ || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_ms2)
+ {
+ /* The 8-byte MAC pseudo-register must be broken down into two
+ 32-byte registers. */
+ unsigned int oldmac, ext_mac;
+ ULONGEST newmac;
+
+ newmac = extract_unsigned_integer (buf, 8);
+ oldmac = newmac & 0xffffffff;
+ ext_mac = (newmac >> 32) & 0xff;
+ regcache_cooked_write_unsigned (regcache, MS1_MAC_REGNUM, oldmac);
+ regcache_cooked_write_unsigned (regcache, MS1_EXMAC_REGNUM, ext_mac);
+ }
+ else
+ regcache_raw_write (regcache, MS1_MAC_REGNUM, buf);
+ break;
+ default:
+ internal_error (__FILE__, __LINE__,
+ _("ms1_pseudo_register_write: bad reg # (%d)"), regno);
+ break;
+ }
+}
+
+static CORE_ADDR
+ms1_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
+{
+ /* Register size is 4 bytes. */
+ return align_down (sp, 4);
+}
+
+/* Implements the "info registers" command. When ``all'' is non-zero,
+ the coprocessor registers will be printed in addition to the rest
+ of the registers. */
+
+static void
+ms1_registers_info (struct gdbarch *gdbarch,
+ struct ui_file *file,
+ struct frame_info *frame, int regnum, int all)
+{
+ if (regnum == -1)
+ {
+ int lim;
+
+ lim = all ? MS1_NUM_REGS : MS1_NUM_CPU_REGS;
+
+ for (regnum = 0; regnum < lim; regnum++)
+ {
+ /* Don't display the Qchannel register since it will be displayed
+ along with Ichannel. (See below.) */
+ if (regnum == MS1_QCHANNEL_REGNUM)
+ continue;
+
+ ms1_registers_info (gdbarch, file, frame, regnum, all);
+
+ /* Display the Qchannel register immediately after Ichannel. */
+ if (regnum == MS1_ICHANNEL_REGNUM)
+ ms1_registers_info (gdbarch, file, frame, MS1_QCHANNEL_REGNUM, all);
+ }
+ }
+ else
+ {
+ if (regnum == MS1_EXMAC_REGNUM)
+ return;
+ else if (regnum == MS1_CONTEXT_REGNUM)
+ {
+ /* Special output handling for 38-bit context register. */
+ unsigned char *buff;
+ unsigned int *bytes, i, regsize;
+
+ regsize = register_size (gdbarch, regnum);
+
+ buff = alloca (regsize);
+ bytes = alloca (regsize * sizeof (*bytes));
+
+ frame_register_read (frame, regnum, buff);
+
+ fputs_filtered (REGISTER_NAME (regnum), file);
+ print_spaces_filtered (15 - strlen (REGISTER_NAME (regnum)), file);
+ fputs_filtered ("0x", file);
+
+ for (i = 0; i < regsize; i++)
+ fprintf_filtered (file, "%02x", (unsigned int)
+ extract_unsigned_integer (buff + i, 1));
+ fputs_filtered ("\t", file);
+ print_longest (file, 'd', 0,
+ extract_unsigned_integer (buff, regsize));
+ fputs_filtered ("\n", file);
+ }
+ else if (regnum == MS1_COPRO_REGNUM
+ || regnum == MS1_COPRO_PSEUDOREG_REGNUM)
+ {
+ /* Special output handling for the 'coprocessor' register. */
+ gdb_byte *buf;
+
+ buf = alloca (register_size (gdbarch, MS1_COPRO_REGNUM));
+ frame_register_read (frame, MS1_COPRO_REGNUM, buf);
+ /* And print. */
+ regnum = MS1_COPRO_PSEUDOREG_REGNUM;
+ fputs_filtered (REGISTER_NAME (regnum), file);
+ print_spaces_filtered (15 - strlen (REGISTER_NAME (regnum)), file);
+ val_print (register_type (gdbarch, regnum), buf,
+ 0, 0, file, 0, 1, 0, Val_no_prettyprint);
+ fputs_filtered ("\n", file);
+ }
+ else if (regnum == MS1_MAC_REGNUM || regnum == MS1_MAC_PSEUDOREG_REGNUM)
+ {
+ ULONGEST oldmac, ext_mac, newmac;
+ gdb_byte buf[3 * sizeof (LONGEST)];
+
+ /* Get the two "real" mac registers. */
+ frame_register_read (frame, MS1_MAC_REGNUM, buf);
+ oldmac = extract_unsigned_integer
+ (buf, register_size (gdbarch, MS1_MAC_REGNUM));
+ if (gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_mrisc2
+ || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_ms2)
+ {
+ frame_register_read (frame, MS1_EXMAC_REGNUM, buf);
+ ext_mac = extract_unsigned_integer
+ (buf, register_size (gdbarch, MS1_EXMAC_REGNUM));
+ }
+ else
+ ext_mac = 0;
+
+ /* Add them together. */
+ newmac = (oldmac & 0xffffffff) + ((ext_mac & 0xff) << 32);
+
+ /* And print. */
+ regnum = MS1_MAC_PSEUDOREG_REGNUM;
+ fputs_filtered (REGISTER_NAME (regnum), file);
+ print_spaces_filtered (15 - strlen (REGISTER_NAME (regnum)), file);
+ fputs_filtered ("0x", file);
+ print_longest (file, 'x', 0, newmac);
+ fputs_filtered ("\t", file);
+ print_longest (file, 'u', 0, newmac);
+ fputs_filtered ("\n", file);
+ }
+ else
+ default_print_registers_info (gdbarch, file, frame, regnum, all);
+ }
+}
+
+/* Set up the callee's arguments for an inferior function call. The
+ arguments are pushed on the stack or are placed in registers as
+ appropriate. It also sets up the return address (which points to
+ the call dummy breakpoint).
+
+ Returns the updated (and aligned) stack pointer. */
+
+static CORE_ADDR
+ms1_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
+ struct regcache *regcache, CORE_ADDR bp_addr,
+ int nargs, struct value **args, CORE_ADDR sp,
+ int struct_return, CORE_ADDR struct_addr)
+{
+#define wordsize 4
+ gdb_byte buf[MS1_MAX_STRUCT_SIZE];
+ int argreg = MS1_1ST_ARGREG;
+ int split_param_len = 0;
+ int stack_dest = sp;
+ int slacklen;
+ int typelen;
+ int i, j;
+
+ /* First handle however many args we can fit into MS1_1ST_ARGREG thru
+ MS1_LAST_ARGREG. */
+ for (i = 0; i < nargs && argreg <= MS1_LAST_ARGREG; i++)
+ {
+ const gdb_byte *val;
+ typelen = TYPE_LENGTH (value_type (args[i]));
+ switch (typelen)
+ {
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ regcache_cooked_write_unsigned (regcache, argreg++,
+ extract_unsigned_integer
+ (value_contents (args[i]),
+ wordsize));
+ break;
+ case 8:
+ case 12:
+ case 16:
+ val = value_contents (args[i]);
+ while (typelen > 0)
+ {
+ if (argreg <= MS1_LAST_ARGREG)
+ {
+ /* This word of the argument is passed in a register. */
+ regcache_cooked_write_unsigned (regcache, argreg++,
+ extract_unsigned_integer
+ (val, wordsize));
+ typelen -= wordsize;
+ val += wordsize;
+ }
+ else
+ {
+ /* Remainder of this arg must be passed on the stack
+ (deferred to do later). */
+ split_param_len = typelen;
+ memcpy (buf, val, typelen);
+ break; /* No more args can be handled in regs. */
+ }
+ }
+ break;
+ default:
+ /* By reverse engineering of gcc output, args bigger than
+ 16 bytes go on the stack, and their address is passed
+ in the argreg. */
+ stack_dest -= typelen;
+ write_memory (stack_dest, value_contents (args[i]), typelen);
+ regcache_cooked_write_unsigned (regcache, argreg++, stack_dest);
+ break;
+ }
+ }
+
+ /* Next, the rest of the arguments go onto the stack, in reverse order. */
+ for (j = nargs - 1; j >= i; j--)
+ {
+ gdb_byte *val;
+
+ /* Right-justify the value in an aligned-length buffer. */
+ typelen = TYPE_LENGTH (value_type (args[j]));
+ slacklen = (wordsize - (typelen % wordsize)) % wordsize;
+ val = alloca (typelen + slacklen);
+ memcpy (val, value_contents (args[j]), typelen);
+ memset (val + typelen, 0, slacklen);
+ /* Now write this data to the stack. */
+ stack_dest -= typelen + slacklen;
+ write_memory (stack_dest, val, typelen + slacklen);
+ }
+
+ /* Finally, if a param needs to be split between registers and stack,
+ write the second half to the stack now. */
+ if (split_param_len != 0)
+ {
+ stack_dest -= split_param_len;
+ write_memory (stack_dest, buf, split_param_len);
+ }
+
+ /* Set up return address (provided to us as bp_addr). */
+ regcache_cooked_write_unsigned (regcache, MS1_RA_REGNUM, bp_addr);
+
+ /* Store struct return address, if given. */
+ if (struct_return && struct_addr != 0)
+ regcache_cooked_write_unsigned (regcache, MS1_R11_REGNUM, struct_addr);
+
+ /* Set aside 16 bytes for the callee to save regs 1-4. */
+ stack_dest -= 16;
+
+ /* Update the stack pointer. */
+ regcache_cooked_write_unsigned (regcache, MS1_SP_REGNUM, stack_dest);
+
+ /* And that should do it. Return the new stack pointer. */
+ return stack_dest;
+}
+
+
+/* The 'unwind_cache' data structure. */
+
+struct ms1_unwind_cache
+{
+ /* The previous frame's inner most stack address.
+ Used as this frame ID's stack_addr. */
+ CORE_ADDR prev_sp;
+ CORE_ADDR frame_base;
+ int framesize;
+ int frameless_p;
+
+ /* Table indicating the location of each and every register. */
+ struct trad_frame_saved_reg *saved_regs;
+};
+
+/* Initialize an unwind_cache. Build up the saved_regs table etc. for
+ the frame. */
+
+static struct ms1_unwind_cache *
+ms1_frame_unwind_cache (struct frame_info *next_frame,
+ void **this_prologue_cache)
+{
+ struct gdbarch *gdbarch;
+ struct ms1_unwind_cache *info;
+ CORE_ADDR next_addr, start_addr, end_addr, prologue_end_addr;
+ unsigned long instr, upper_half, delayed_store = 0;
+ int regnum, offset;
+ ULONGEST sp, fp;
+
+ if ((*this_prologue_cache))
+ return (*this_prologue_cache);
+
+ gdbarch = get_frame_arch (next_frame);
+ info = FRAME_OBSTACK_ZALLOC (struct ms1_unwind_cache);
+ (*this_prologue_cache) = info;
+
+ info->prev_sp = 0;
+ info->framesize = 0;
+ info->frame_base = 0;
+ info->frameless_p = 1;
+ info->saved_regs = trad_frame_alloc_saved_regs (next_frame);
+
+ /* Grab the frame-relative values of SP and FP, needed below.
+ The frame_saved_register function will find them on the
+ stack or in the registers as appropriate. */
+ frame_unwind_unsigned_register (next_frame, MS1_SP_REGNUM, &sp);
+ frame_unwind_unsigned_register (next_frame, MS1_FP_REGNUM, &fp);
+
+ start_addr = frame_func_unwind (next_frame);
+
+ /* Return early if GDB couldn't find the function. */
+ if (start_addr == 0)
+ return info;
+
+ end_addr = frame_pc_unwind (next_frame);
+ prologue_end_addr = skip_prologue_using_sal (start_addr);
+ if (end_addr == 0)
+ for (next_addr = start_addr; next_addr < end_addr; next_addr += 4)
+ {
+ instr = get_frame_memory_unsigned (next_frame, next_addr, 4);
+ if (delayed_store) /* previous instr was a push */
+ {
+ upper_half = delayed_store >> 16;
+ regnum = upper_half & 0xf;
+ offset = delayed_store & 0xffff;
+ switch (upper_half & 0xfff0)
+ {
+ case 0x43c0: /* push using frame pointer */
+ info->saved_regs[regnum].addr = offset;
+ break;
+ case 0x43d0: /* push using stack pointer */
+ info->saved_regs[regnum].addr = offset;
+ break;
+ default: /* lint */
+ break;
+ }
+ delayed_store = 0;
+ }
+
+ switch (instr)
+ {
+ case 0x12000000: /* NO-OP */
+ continue;
+ case 0x12ddc000: /* copy sp into fp */
+ info->frameless_p = 0; /* Record that the frame pointer is in use. */
+ continue;
+ default:
+ upper_half = instr >> 16;
+ if (upper_half == 0x05dd || /* subi sp, sp, imm */
+ upper_half == 0x07dd) /* subui sp, sp, imm */
+ {
+ /* Record the frame size. */
+ info->framesize = instr & 0xffff;
+ continue;
+ }
+ if ((upper_half & 0xfff0) == 0x43c0 || /* frame push */
+ (upper_half & 0xfff0) == 0x43d0) /* stack push */
+ {
+ /* Save this instruction, but don't record the
+ pushed register as 'saved' until we see the
+ next instruction. That's because of deferred stores
+ on this target -- GDB won't be able to read the register
+ from the stack until one instruction later. */
+ delayed_store = instr;
+ continue;
+ }
+ /* Not a prologue instruction. Is this the end of the prologue?
+ This is the most difficult decision; when to stop scanning.
+
+ If we have no line symbol, then the best thing we can do
+ is to stop scanning when we encounter an instruction that
+ is not likely to be a part of the prologue.
+
+ But if we do have a line symbol, then we should
+ keep scanning until we reach it (or we reach end_addr). */
+
+ if (prologue_end_addr && (prologue_end_addr > (next_addr + 4)))
+ continue; /* Keep scanning, recording saved_regs etc. */
+ else
+ break; /* Quit scanning: breakpoint can be set here. */
+ }
+ }
+
+ /* Special handling for the "saved" address of the SP:
+ The SP is of course never saved on the stack at all, so
+ by convention what we put here is simply the previous
+ _value_ of the SP (as opposed to an address where the
+ previous value would have been pushed). This will also
+ give us the frame base address. */
+
+ if (info->frameless_p)
+ {
+ info->frame_base = sp + info->framesize;
+ info->prev_sp = sp + info->framesize;
+ }
+ else
+ {
+ info->frame_base = fp + info->framesize;
+ info->prev_sp = fp + info->framesize;
+ }
+ /* Save prev_sp in saved_regs as a value, not as an address. */
+ trad_frame_set_value (info->saved_regs, MS1_SP_REGNUM, info->prev_sp);
+
+ /* Now convert frame offsets to actual addresses (not offsets). */
+ for (regnum = 0; regnum < MS1_NUM_REGS; regnum++)
+ if (trad_frame_addr_p (info->saved_regs, regnum))
+ info->saved_regs[regnum].addr += info->frame_base - info->framesize;
+
+ /* The call instruction moves the caller's PC in the callee's RA reg.
+ Since this is an unwind, do the reverse. Copy the location of RA
+ into PC (the address / regnum) so that a request for PC will be
+ converted into a request for the RA. */
+ info->saved_regs[MS1_PC_REGNUM] = info->saved_regs[MS1_RA_REGNUM];
+
+ return info;
+}
+
+static CORE_ADDR
+ms1_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
+{
+ ULONGEST pc;
+
+ frame_unwind_unsigned_register (next_frame, MS1_PC_REGNUM, &pc);
+ return pc;
+}
+
+static CORE_ADDR
+ms1_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
+{
+ ULONGEST sp;
+
+ frame_unwind_unsigned_register (next_frame, MS1_SP_REGNUM, &sp);
+ return sp;
+}
+
+/* Assuming NEXT_FRAME->prev is a dummy, return the frame ID of that
+ dummy frame. The frame ID's base needs to match the TOS value
+ saved by save_dummy_frame_tos(), and the PC match the dummy frame's
+ breakpoint. */
+
+static struct frame_id
+ms1_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
+{
+ return frame_id_build (ms1_unwind_sp (gdbarch, next_frame),
+ frame_pc_unwind (next_frame));
+}
+
+/* Given a GDB frame, determine the address of the calling function's
+ frame. This will be used to create a new GDB frame struct. */
+
+static void
+ms1_frame_this_id (struct frame_info *next_frame,
+ void **this_prologue_cache, struct frame_id *this_id)
+{
+ struct ms1_unwind_cache *info =
+ ms1_frame_unwind_cache (next_frame, this_prologue_cache);
+
+ if (!(info == NULL || info->prev_sp == 0))
+ {
+ (*this_id) = frame_id_build (info->prev_sp,
+ frame_func_unwind (next_frame));
+ }
+ return;
+}
+
+static void
+ms1_frame_prev_register (struct frame_info *next_frame,
+ void **this_prologue_cache,
+ int regnum, int *optimizedp,
+ enum lval_type *lvalp, CORE_ADDR *addrp,
+ int *realnump, gdb_byte *bufferp)
+{
+ struct ms1_unwind_cache *info =
+ ms1_frame_unwind_cache (next_frame, this_prologue_cache);
+
+ trad_frame_get_prev_register (next_frame, info->saved_regs, regnum,
+ optimizedp, lvalp, addrp, realnump, bufferp);
+}
+
+static CORE_ADDR
+ms1_frame_base_address (struct frame_info *next_frame,
+ void **this_prologue_cache)
+{
+ struct ms1_unwind_cache *info =
+ ms1_frame_unwind_cache (next_frame, this_prologue_cache);
+
+ return info->frame_base;
+}
+
+/* This is a shared interface: the 'frame_unwind' object is what's
+ returned by the 'sniffer' function, and in turn specifies how to
+ get a frame's ID and prev_regs.
+
+ This exports the 'prev_register' and 'this_id' methods. */
+
+static const struct frame_unwind ms1_frame_unwind = {
+ NORMAL_FRAME,
+ ms1_frame_this_id,
+ ms1_frame_prev_register
+};
+
+/* The sniffer is a registered function that identifies our family of
+ frame unwind functions (this_id and prev_register). */
+
+static const struct frame_unwind *
+ms1_frame_sniffer (struct frame_info *next_frame)
+{
+ return &ms1_frame_unwind;
+}
+
+/* Another shared interface: the 'frame_base' object specifies how to
+ unwind a frame and secure the base addresses for frame objects
+ (locals, args). */
+
+static struct frame_base ms1_frame_base = {
+ &ms1_frame_unwind,
+ ms1_frame_base_address,
+ ms1_frame_base_address,
+ ms1_frame_base_address
+};
+
+static struct gdbarch *
+ms1_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
+{
+ struct gdbarch *gdbarch;
+
+ /* Find a candidate among the list of pre-declared architectures. */
+ arches = gdbarch_list_lookup_by_info (arches, &info);
+ if (arches != NULL)
+ return arches->gdbarch;
+
+ /* None found, create a new architecture from the information
+ provided. */
+ gdbarch = gdbarch_alloc (&info, NULL);
+
+ switch (info.byte_order)
+ {
+ case BFD_ENDIAN_BIG:
+ set_gdbarch_float_format (gdbarch, &floatformat_ieee_single_big);
+ set_gdbarch_double_format (gdbarch, &floatformat_ieee_double_big);
+ set_gdbarch_long_double_format (gdbarch, &floatformat_ieee_double_big);
+ break;
+ case BFD_ENDIAN_LITTLE:
+ set_gdbarch_float_format (gdbarch, &floatformat_ieee_single_little);
+ set_gdbarch_double_format (gdbarch, &floatformat_ieee_double_little);
+ set_gdbarch_long_double_format (gdbarch,
+ &floatformat_ieee_double_little);
+ break;
+ default:
+ internal_error (__FILE__, __LINE__,
+ _("ms1_gdbarch_init: bad byte order for float format"));
+ }
+
+ set_gdbarch_register_name (gdbarch, ms1_register_name);
+ set_gdbarch_num_regs (gdbarch, MS1_NUM_REGS);
+ set_gdbarch_num_pseudo_regs (gdbarch, MS1_NUM_PSEUDO_REGS);
+ set_gdbarch_pc_regnum (gdbarch, MS1_PC_REGNUM);
+ set_gdbarch_sp_regnum (gdbarch, MS1_SP_REGNUM);
+ set_gdbarch_pseudo_register_read (gdbarch, ms1_pseudo_register_read);
+ set_gdbarch_pseudo_register_write (gdbarch, ms1_pseudo_register_write);
+ set_gdbarch_skip_prologue (gdbarch, ms1_skip_prologue);
+ set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
+ set_gdbarch_breakpoint_from_pc (gdbarch, ms1_breakpoint_from_pc);
+ set_gdbarch_decr_pc_after_break (gdbarch, 0);
+ set_gdbarch_frame_args_skip (gdbarch, 0);
+ set_gdbarch_print_insn (gdbarch, print_insn_ms1);
+ set_gdbarch_register_type (gdbarch, ms1_register_type);
+ set_gdbarch_register_reggroup_p (gdbarch, ms1_register_reggroup_p);
+
+ set_gdbarch_return_value (gdbarch, ms1_return_value);
+ set_gdbarch_sp_regnum (gdbarch, MS1_SP_REGNUM);
+
+ set_gdbarch_frame_align (gdbarch, ms1_frame_align);
+
+ set_gdbarch_print_registers_info (gdbarch, ms1_registers_info);
+
+ set_gdbarch_push_dummy_call (gdbarch, ms1_push_dummy_call);
+
+ /* Target builtin data types. */
+ set_gdbarch_short_bit (gdbarch, 16);
+ set_gdbarch_int_bit (gdbarch, 32);
+ set_gdbarch_long_bit (gdbarch, 32);
+ set_gdbarch_long_long_bit (gdbarch, 64);
+ set_gdbarch_float_bit (gdbarch, 32);
+ set_gdbarch_double_bit (gdbarch, 64);
+ set_gdbarch_long_double_bit (gdbarch, 64);
+ set_gdbarch_ptr_bit (gdbarch, 32);
+
+ /* Register the DWARF 2 sniffer first, and then the traditional prologue
+ based sniffer. */
+ frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);
+ frame_unwind_append_sniffer (gdbarch, ms1_frame_sniffer);
+ frame_base_set_default (gdbarch, &ms1_frame_base);
+
+ /* Register the 'unwind_pc' method. */
+ set_gdbarch_unwind_pc (gdbarch, ms1_unwind_pc);
+ set_gdbarch_unwind_sp (gdbarch, ms1_unwind_sp);
+
+ /* Methods for saving / extracting a dummy frame's ID.
+ The ID's stack address must match the SP value returned by
+ PUSH_DUMMY_CALL, and saved by generic_save_dummy_frame_tos. */
+ set_gdbarch_unwind_dummy_id (gdbarch, ms1_unwind_dummy_id);
+
+ return gdbarch;
+}
+
+void
+_initialize_ms1_tdep (void)
+{
+ register_gdbarch_init (bfd_arch_ms1, ms1_gdbarch_init);
+}
+++ /dev/null
-/* MS1 ELF support for BFD.
- Copyright (C) 2000, 2005 Free Software Foundation, Inc.
-
-This file is part of BFD, the Binary File Descriptor library.
-
-This program 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 of the License, or
-(at your option) any later version.
-
-This program 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 this program; if not, write to the Free Software Foundation, Inc.,
-59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-#ifndef _ELF_MS1_H
-#define _ELF_MS1_H
-
-#include "elf/reloc-macros.h"
-
-/* Relocations. */
-START_RELOC_NUMBERS (elf_ms1_reloc_type)
- RELOC_NUMBER (R_MS1_NONE, 0)
- RELOC_NUMBER (R_MS1_16, 1)
- RELOC_NUMBER (R_MS1_32, 2)
- RELOC_NUMBER (R_MS1_32_PCREL, 3)
- RELOC_NUMBER (R_MS1_PC16, 4)
- RELOC_NUMBER (R_MS1_HI16, 5)
- RELOC_NUMBER (R_MS1_LO16, 6)
-END_RELOC_NUMBERS(R_MS1_max)
-
-#define EF_MS1_CPU_MRISC 0x00000001 /* default */
-#define EF_MS1_CPU_MRISC2 0x00000002 /* MRISC2 */
-#define EF_MS1_CPU_MS2 0x00000003 /* MS2 */
-#define EF_MS1_CPU_MASK 0x00000003 /* specific cpu bits */
-#define EF_MS1_ALL_FLAGS (EF_MS1_CPU_MASK)
-
-/* The location of the memory mapped hardware stack. */
-#define MS1_STACK_VALUE 0x0f000000
-#define MS1_STACK_SIZE 0x20
-
-#endif /* _ELF_MS1_H */
--- /dev/null
+/* MS1 ELF support for BFD.
+ Copyright (C) 2000, 2005 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+This program 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 of the License, or
+(at your option) any later version.
+
+This program 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 this program; if not, write to the Free Software Foundation, Inc.,
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef _ELF_MS1_H
+#define _ELF_MS1_H
+
+#include "elf/reloc-macros.h"
+
+/* Relocations. */
+START_RELOC_NUMBERS (elf_ms1_reloc_type)
+ RELOC_NUMBER (R_MS1_NONE, 0)
+ RELOC_NUMBER (R_MS1_16, 1)
+ RELOC_NUMBER (R_MS1_32, 2)
+ RELOC_NUMBER (R_MS1_32_PCREL, 3)
+ RELOC_NUMBER (R_MS1_PC16, 4)
+ RELOC_NUMBER (R_MS1_HI16, 5)
+ RELOC_NUMBER (R_MS1_LO16, 6)
+END_RELOC_NUMBERS(R_MS1_max)
+
+#define EF_MS1_CPU_MRISC 0x00000001 /* default */
+#define EF_MS1_CPU_MRISC2 0x00000002 /* MRISC2 */
+#define EF_MS1_CPU_MS2 0x00000003 /* MS2 */
+#define EF_MS1_CPU_MASK 0x00000003 /* specific cpu bits */
+#define EF_MS1_ALL_FLAGS (EF_MS1_CPU_MASK)
+
+/* The location of the memory mapped hardware stack. */
+#define MS1_STACK_VALUE 0x0f000000
+#define MS1_STACK_SIZE 0x20
+
+#endif /* _ELF_MS1_H */
+++ /dev/null
-MACHINE=
-SCRIPT_NAME=elf
-OUTPUT_FORMAT="elf32-ms1"
-# See also `include/elf/ms1.h'
-TEXT_START_ADDR=0x2000
-ARCH=ms1
-ENTRY=_start
-EMBEDDED=yes
-ELFSIZE=32
-MAXPAGESIZE=256
-# This is like setting STACK_ADDR to 0x0073FFFF0, except that the setting can
-# be overridden, e.g. --defsym _stack=0x0f00, and that we put an extra
-# sentinal value at the bottom.
-# N.B. We can't use PROVIDE to set the default value in a symbol because
-# the address is needed to place the .stack section, which in turn is needed
-# to hold the sentinel value(s).
-test -z "$CREATE_SHLIB" && OTHER_SECTIONS=" .stack ${RELOCATING-0}${RELOCATING+(DEFINED(__stack) ? __stack : 0x007FFFF0)} :
- {
- ${RELOCATING+__stack = .;}
- *(.stack)
- LONG(0xdeaddead)
- }"
-# We do not need .stack for shared library.
-test -n "$CREATE_SHLIB" && OTHER_SECTIONS=""
--- /dev/null
+MACHINE=
+SCRIPT_NAME=elf
+OUTPUT_FORMAT="elf32-ms1"
+# See also `include/elf/ms1.h'
+TEXT_START_ADDR=0x2000
+ARCH=ms1
+ENTRY=_start
+EMBEDDED=yes
+ELFSIZE=32
+MAXPAGESIZE=256
+# This is like setting STACK_ADDR to 0x0073FFFF0, except that the setting can
+# be overridden, e.g. --defsym _stack=0x0f00, and that we put an extra
+# sentinal value at the bottom.
+# N.B. We can't use PROVIDE to set the default value in a symbol because
+# the address is needed to place the .stack section, which in turn is needed
+# to hold the sentinel value(s).
+test -z "$CREATE_SHLIB" && OTHER_SECTIONS=" .stack ${RELOCATING-0}${RELOCATING+(DEFINED(__stack) ? __stack : 0x007FFFF0)} :
+ {
+ ${RELOCATING+__stack = .;}
+ *(.stack)
+ LONG(0xdeaddead)
+ }"
+# We do not need .stack for shared library.
+test -n "$CREATE_SHLIB" && OTHER_SECTIONS=""