--- /dev/null
+/* BFD support for the CRX processor.
+ Copyright 2004 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 bfd_crx_arch =
+ {
+ 16, /* 16 bits in a word. */
+ 32, /* 32 bits in an address. */
+ 8, /* 8 bits in a byte. */
+ bfd_arch_crx, /* enum bfd_architecture arch. */
+ bfd_mach_crx,
+ "crx", /* Arch name. */
+ "crx", /* Printable name. */
+ 1, /* Unsigned int section alignment power. */
+ TRUE, /* The one and only. */
+ bfd_default_compatible,
+ bfd_default_scan ,
+ 0,
+ };
--- /dev/null
+/* BFD back-end for National Semiconductor's CRX ELF
+ Copyright 2004 Free Software Foundation, Inc.
+ Written by Tomer Levi, NSC, Israel.
+
+ 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 "bfdlink.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/crx.h"
+
+static reloc_howto_type *elf_crx_reloc_type_lookup
+ (bfd *, bfd_reloc_code_real_type);
+static void elf_crx_info_to_howto
+ (bfd *, arelent *, Elf_Internal_Rela *);
+static bfd_boolean elf32_crx_relax_delete_bytes
+ (bfd *, asection *, bfd_vma, int);
+static bfd_reloc_status_type crx_elf_final_link_relocate
+ (reloc_howto_type *, bfd *, bfd *, asection *,
+ bfd_byte *, bfd_vma, bfd_vma, bfd_vma,
+ struct bfd_link_info *, asection *, int);
+static bfd_boolean elf32_crx_relocate_section
+ (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
+ Elf_Internal_Rela *, Elf_Internal_Sym *, asection **);
+static asection * elf32_crx_gc_mark_hook
+ (asection *, struct bfd_link_info *, Elf_Internal_Rela *,
+ struct elf_link_hash_entry *, Elf_Internal_Sym *);
+static bfd_boolean elf32_crx_gc_sweep_hook
+ (bfd *, struct bfd_link_info *, asection *,
+ const Elf_Internal_Rela *);
+static bfd_boolean elf32_crx_relax_section
+ (bfd *, asection *, struct bfd_link_info *, bfd_boolean *);
+static bfd_byte * elf32_crx_get_relocated_section_contents
+ (bfd *, struct bfd_link_info *, struct bfd_link_order *,
+ bfd_byte *, bfd_boolean, asymbol **);
+
+/* crx_reloc_map array maps BFD relocation enum into a CRGAS relocation type. */
+
+struct crx_reloc_map
+{
+ bfd_reloc_code_real_type bfd_reloc_enum; /* BFD relocation enum. */
+ unsigned short crx_reloc_type; /* CRX relocation type. */
+};
+
+static const struct crx_reloc_map crx_reloc_map[R_CRX_MAX] =
+{
+ {BFD_RELOC_NONE, R_CRX_NONE},
+ {BFD_RELOC_CRX_REL4, R_CRX_REL4},
+ {BFD_RELOC_CRX_REL8, R_CRX_REL8},
+ {BFD_RELOC_CRX_REL8_CMP, R_CRX_REL8_CMP},
+ {BFD_RELOC_CRX_REL16, R_CRX_REL16},
+ {BFD_RELOC_CRX_REL24, R_CRX_REL24},
+ {BFD_RELOC_CRX_REL32, R_CRX_REL32},
+ {BFD_RELOC_CRX_REGREL12, R_CRX_REGREL12},
+ {BFD_RELOC_CRX_REGREL22, R_CRX_REGREL22},
+ {BFD_RELOC_CRX_REGREL28, R_CRX_REGREL28},
+ {BFD_RELOC_CRX_REGREL32, R_CRX_REGREL32},
+ {BFD_RELOC_CRX_ABS16, R_CRX_ABS16},
+ {BFD_RELOC_CRX_ABS32, R_CRX_ABS32},
+ {BFD_RELOC_CRX_NUM8, R_CRX_NUM8},
+ {BFD_RELOC_CRX_NUM16, R_CRX_NUM16},
+ {BFD_RELOC_CRX_NUM32, R_CRX_NUM32},
+ {BFD_RELOC_CRX_IMM16, R_CRX_IMM16},
+ {BFD_RELOC_CRX_IMM32, R_CRX_IMM32},
+ {BFD_RELOC_CRX_SWITCH8, R_CRX_SWITCH8},
+ {BFD_RELOC_CRX_SWITCH16, R_CRX_SWITCH16},
+ {BFD_RELOC_CRX_SWITCH32, R_CRX_SWITCH32}
+};
+
+static reloc_howto_type crx_elf_howto_table[] =
+{
+ HOWTO (R_CRX_NONE, /* type */
+ 0, /* rightshift */
+ 2, /* size */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CRX_NONE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CRX_REL4, /* type */
+ 1, /* rightshift */
+ 0, /* size */
+ 4, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CRX_REL4", /* name */
+ FALSE, /* partial_inplace */
+ 0xf, /* src_mask */
+ 0xf, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CRX_REL8, /* type */
+ 1, /* rightshift */
+ 0, /* size */
+ 8, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CRX_REL8", /* name */
+ FALSE, /* partial_inplace */
+ 0xff, /* src_mask */
+ 0xff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CRX_REL8_CMP, /* type */
+ 1, /* rightshift */
+ 0, /* size */
+ 8, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CRX_REL8_CMP", /* name */
+ FALSE, /* partial_inplace */
+ 0xff, /* src_mask */
+ 0xff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CRX_REL16, /* type */
+ 1, /* rightshift */
+ 1, /* size */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CRX_REL16", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CRX_REL24, /* type */
+ 1, /* rightshift */
+ 2, /* size */
+ 24, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CRX_REL24", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffff, /* src_mask */
+ 0xffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CRX_REL32, /* type */
+ 1, /* rightshift */
+ 2, /* size */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CRX_REL32", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CRX_REGREL12, /* type */
+ 0, /* rightshift */
+ 1, /* size */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CRX_REGREL12", /* name */
+ FALSE, /* partial_inplace */
+ 0xfff, /* src_mask */
+ 0xfff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CRX_REGREL22, /* type */
+ 0, /* rightshift */
+ 2, /* size */
+ 22, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CRX_REGREL22", /* name */
+ FALSE, /* partial_inplace */
+ 0x3fffff, /* src_mask */
+ 0x3fffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CRX_REGREL28, /* type */
+ 0, /* rightshift */
+ 2, /* size */
+ 28, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CRX_REGREL28", /* name */
+ FALSE, /* partial_inplace */
+ 0xfffffff, /* src_mask */
+ 0xfffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CRX_REGREL32, /* type */
+ 0, /* rightshift */
+ 2, /* size */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CRX_REGREL32", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CRX_ABS16, /* type */
+ 0, /* rightshift */
+ 1, /* size */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CRX_ABS16", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CRX_ABS32, /* type */
+ 0, /* rightshift */
+ 2, /* size */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CRX_ABS32", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CRX_NUM8, /* type */
+ 0, /* rightshift */
+ 0, /* size */
+ 8, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CRX_NUM8", /* name */
+ FALSE, /* partial_inplace */
+ 0xff, /* src_mask */
+ 0xff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CRX_NUM16, /* type */
+ 0, /* rightshift */
+ 1, /* size */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CRX_NUM16", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CRX_NUM32, /* type */
+ 0, /* rightshift */
+ 2, /* size */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CRX_NUM32", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CRX_IMM16, /* type */
+ 0, /* rightshift */
+ 1, /* size */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CRX_IMM16", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CRX_IMM32, /* type */
+ 0, /* rightshift */
+ 2, /* size */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CRX_IMM32", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* An 8 bit switch table entry. This is generated for an expression
+ such as ``.byte L1 - L2''. The offset holds the difference
+ between the reloc address and L2. */
+ HOWTO (R_CRX_SWITCH8, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CRX_SWITCH8", /* name */
+ FALSE, /* partial_inplace */
+ 0xff, /* src_mask */
+ 0xff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A 16 bit switch table entry. This is generated for an expression
+ such as ``.word L1 - L2''. The offset holds the difference
+ between the reloc address and L2. */
+ HOWTO (R_CRX_SWITCH16, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CRX_SWITCH16", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A 32 bit switch table entry. This is generated for an expression
+ such as ``.long L1 - L2''. The offset holds the difference
+ between the reloc address and L2. */
+ HOWTO (R_CRX_SWITCH32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CRX_SWITCH32", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE) /* pcrel_offset */
+};
+
+/* Retrieve a howto ptr using a BFD reloc_code. */
+
+static reloc_howto_type *
+elf_crx_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ unsigned int i;
+
+ for (i = 0; i < R_CRX_MAX; i++)
+ if (code == crx_reloc_map[i].bfd_reloc_enum)
+ return &crx_elf_howto_table[crx_reloc_map[i].crx_reloc_type];
+
+ printf ("This relocation Type is not supported -0x%x\n", code);
+ return 0;
+}
+
+/* Retrieve a howto ptr using an internal relocation entry. */
+
+static void
+elf_crx_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
+ Elf_Internal_Rela *dst)
+{
+ unsigned int r_type = ELF32_R_TYPE (dst->r_info);
+ BFD_ASSERT (r_type < (unsigned int) R_CRX_MAX);
+ cache_ptr->howto = &crx_elf_howto_table[r_type];
+}
+
+/* Perform a relocation as part of a final link. */
+
+static bfd_reloc_status_type
+crx_elf_final_link_relocate (reloc_howto_type *howto, bfd *input_bfd,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ asection *input_section, bfd_byte *contents,
+ bfd_vma offset, bfd_vma Rvalue, bfd_vma addend,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ asection *sec ATTRIBUTE_UNUSED,
+ int is_local ATTRIBUTE_UNUSED)
+{
+ unsigned short r_type = howto->type;
+ bfd_byte *hit_data = contents + offset;
+ bfd_vma reloc_bits, check;
+
+ switch (r_type)
+ {
+ case R_CRX_IMM16:
+ case R_CRX_IMM32:
+ case R_CRX_ABS16:
+ case R_CRX_ABS32:
+ case R_CRX_REL8_CMP:
+ case R_CRX_REL16:
+ case R_CRX_REL24:
+ case R_CRX_REL32:
+ case R_CRX_REGREL12:
+ case R_CRX_REGREL22:
+ case R_CRX_REGREL28:
+ case R_CRX_REGREL32:
+ /* 'hit_data' is relative to the start of the instruction, not the
+ relocation offset. Advance it to account for the exact offset. */
+ hit_data += 2;
+ break;
+
+ case R_CRX_REL4:
+ /* This relocation type is used only in 'Branch if Equal to 0'
+ instructions and requires special handling. */
+ Rvalue -= 1;
+ break;
+
+ case R_CRX_NONE:
+ return bfd_reloc_ok;
+ break;
+
+ case R_CRX_SWITCH8:
+ case R_CRX_SWITCH16:
+ case R_CRX_SWITCH32:
+ /* We only care about the addend, where the difference between
+ expressions is kept. */
+ Rvalue = 0;
+
+ default:
+ break;
+ }
+
+ if (howto->pc_relative)
+ {
+ /* Subtract the address of the section containing the location. */
+ Rvalue -= (input_section->output_section->vma
+ + input_section->output_offset);
+ /* Subtract the position of the location within the section. */
+ Rvalue -= offset;
+ }
+
+ /* Add in supplied addend. */
+ Rvalue += addend;
+
+ /* Complain if the bitfield overflows, whether it is considered
+ as signed or unsigned. */
+ check = Rvalue >> howto->rightshift;
+
+ /* Assumes two's complement. This expression avoids
+ overflow if howto->bitsize is the number of bits in
+ bfd_vma. */
+ reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
+
+ if (((bfd_vma) check & ~reloc_bits) != 0
+ && (((bfd_vma) check & ~reloc_bits)
+ != (-(bfd_vma) 1 & ~reloc_bits)))
+ {
+ /* The above right shift is incorrect for a signed
+ value. See if turning on the upper bits fixes the
+ overflow. */
+ if (howto->rightshift && (bfd_signed_vma) Rvalue < 0)
+ {
+ check |= ((bfd_vma) - 1
+ & ~((bfd_vma) - 1
+ >> howto->rightshift));
+ if (((bfd_vma) check & ~reloc_bits)
+ != (-(bfd_vma) 1 & ~reloc_bits))
+ return bfd_reloc_overflow;
+ }
+ else
+ return bfd_reloc_overflow;
+ }
+
+ /* Drop unwanted bits from the value we are relocating to. */
+ Rvalue >>= (bfd_vma) howto->rightshift;
+
+ /* Apply dst_mask to select only relocatable part of the insn. */
+ Rvalue &= howto->dst_mask;
+
+ switch (howto->size)
+ {
+ case 0:
+ if (r_type == R_CRX_REL4)
+ {
+ Rvalue <<= 4;
+ Rvalue |= (bfd_get_8 (input_bfd, hit_data) & 0x0f);
+ }
+
+ bfd_put_8 (input_bfd, (unsigned char) Rvalue, hit_data);
+ break;
+
+ case 1:
+ if (r_type == R_CRX_REGREL12)
+ Rvalue |= (bfd_get_16 (input_bfd, hit_data) & 0xf000);
+
+ bfd_put_16 (input_bfd, Rvalue, hit_data);
+ break;
+
+ case 2:
+ if (r_type == R_CRX_REL24
+ || r_type == R_CRX_REGREL22
+ || r_type == R_CRX_REGREL28)
+ Rvalue |= (((bfd_get_16 (input_bfd, hit_data) << 16) |
+ bfd_get_16 (input_bfd, hit_data + 2)) & ~howto->dst_mask);
+
+ if (r_type == R_CRX_NUM32 || r_type == R_CRX_SWITCH32)
+ /* Relocation on DATA is purely little-endian, that is, for a
+ multi-byte datum, the lowest address in memory contains the
+ little end of the datum, that is, the least significant byte.
+ Therefore we use BFD's byte Putting functions. */
+ bfd_put_32 (input_bfd, Rvalue, hit_data);
+ else
+ /* Relocation on INSTRUCTIONS is different : Instructions are
+ word-addressable, that is, each word itself is arranged according
+ to little-endian convention, whereas the words are arranged with
+ respect to one another in BIG ENDIAN fashion.
+ When there is an immediate value that spans a word boundary, it is
+ split in a big-endian way with respect to the words. */
+ {
+ bfd_put_16 (input_bfd, (Rvalue >> 16) & 0xffff, hit_data);
+ bfd_put_16 (input_bfd, Rvalue & 0xffff, hit_data + 2);
+ }
+ break;
+
+ default:
+ return bfd_reloc_notsupported;
+ }
+
+ return bfd_reloc_ok;
+}
+
+/* Delete some bytes from a section while relaxing. */
+
+static bfd_boolean
+elf32_crx_relax_delete_bytes (bfd *abfd, asection *sec,
+ bfd_vma addr, int count)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ unsigned int sec_shndx;
+ bfd_byte *contents;
+ Elf_Internal_Rela *irel, *irelend;
+ Elf_Internal_Rela *irelalign;
+ bfd_vma toaddr;
+ Elf_Internal_Sym *isym;
+ Elf_Internal_Sym *isymend;
+ struct elf_link_hash_entry **sym_hashes;
+ struct elf_link_hash_entry **end_hashes;
+ unsigned int symcount;
+
+ sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
+
+ contents = elf_section_data (sec)->this_hdr.contents;
+
+ /* The deletion must stop at the next ALIGN reloc for an aligment
+ power larger than the number of bytes we are deleting. */
+
+ irelalign = NULL;
+ toaddr = sec->size;
+
+ irel = elf_section_data (sec)->relocs;
+ irelend = irel + sec->reloc_count;
+
+ /* Actually delete the bytes. */
+ memmove (contents + addr, contents + addr + count,
+ (size_t) (toaddr - addr - count));
+ sec->size -= count;
+
+ /* Adjust all the relocs. */
+ for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
+ {
+ /* Get the new reloc address. */
+ if ((irel->r_offset > addr
+ && irel->r_offset < toaddr))
+ irel->r_offset -= count;
+ }
+
+ /* Adjust the local symbols defined in this section. */
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ isym = (Elf_Internal_Sym *) symtab_hdr->contents;
+ for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
+ {
+ if (isym->st_shndx == sec_shndx
+ && isym->st_value > addr
+ && isym->st_value < toaddr)
+ {
+ /* Adjust the addend of SWITCH relocations in this section,
+ which reference this local symbol. */
+ for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
+ {
+ unsigned long r_symndx;
+ Elf_Internal_Sym *rsym;
+ bfd_vma addsym, subsym;
+
+ /* Skip if not a SWITCH relocation. */
+ if (ELF32_R_TYPE (irel->r_info) != (int) R_CRX_SWITCH8
+ && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_SWITCH16
+ && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_SWITCH32)
+ continue;
+
+ r_symndx = ELF32_R_SYM (irel->r_info);
+ rsym = (Elf_Internal_Sym *) symtab_hdr->contents + r_symndx;
+
+ /* Skip if not the local adjusted symbol. */
+ if (rsym != isym)
+ continue;
+
+ addsym = isym->st_value;
+ subsym = addsym - irel->r_addend;
+
+ /* Fix the addend only when -->> (addsym > addr >= subsym). */
+ if (subsym <= addr)
+ irel->r_addend -= count;
+ else
+ continue;
+ }
+
+ isym->st_value -= count;
+ }
+ }
+
+ /* Now adjust the global symbols defined in this section. */
+ symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
+ - symtab_hdr->sh_info);
+ sym_hashes = elf_sym_hashes (abfd);
+ end_hashes = sym_hashes + symcount;
+
+ for (; sym_hashes < end_hashes; sym_hashes++)
+ {
+ struct elf_link_hash_entry *sym_hash = *sym_hashes;
+
+ if ((sym_hash->root.type == bfd_link_hash_defined
+ || sym_hash->root.type == bfd_link_hash_defweak)
+ && sym_hash->root.u.def.section == sec
+ && sym_hash->root.u.def.value > addr
+ && sym_hash->root.u.def.value < toaddr)
+ sym_hash->root.u.def.value -= count;
+ }
+
+ return TRUE;
+}
+
+/* This is a version of bfd_generic_get_relocated_section_contents
+ which uses elf32_crx_relocate_section. */
+
+static bfd_byte *
+elf32_crx_get_relocated_section_contents (bfd *output_bfd,
+ struct bfd_link_info *link_info,
+ struct bfd_link_order *link_order,
+ bfd_byte *data,
+ bfd_boolean relocatable,
+ asymbol **symbols)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ asection *input_section = link_order->u.indirect.section;
+ bfd *input_bfd = input_section->owner;
+ asection **sections = NULL;
+ Elf_Internal_Rela *internal_relocs = NULL;
+ Elf_Internal_Sym *isymbuf = NULL;
+
+ /* We only need to handle the case of relaxing, or of having a
+ particular set of section contents, specially. */
+ if (relocatable
+ || elf_section_data (input_section)->this_hdr.contents == NULL)
+ return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
+ link_order, data,
+ relocatable,
+ symbols);
+
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+
+ memcpy (data, elf_section_data (input_section)->this_hdr.contents,
+ (size_t) input_section->size);
+
+ if ((input_section->flags & SEC_RELOC) != 0
+ && input_section->reloc_count > 0)
+ {
+ Elf_Internal_Sym *isym;
+ Elf_Internal_Sym *isymend;
+ asection **secpp;
+ bfd_size_type amt;
+
+ internal_relocs = (_bfd_elf_link_read_relocs
+ (input_bfd, input_section, (PTR) NULL,
+ (Elf_Internal_Rela *) NULL, FALSE));
+ if (internal_relocs == NULL)
+ goto error_return;
+
+ if (symtab_hdr->sh_info != 0)
+ {
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ goto error_return;
+ }
+
+ amt = symtab_hdr->sh_info;
+ amt *= sizeof (asection *);
+ sections = bfd_malloc (amt);
+ if (sections == NULL && amt != 0)
+ goto error_return;
+
+ isymend = isymbuf + symtab_hdr->sh_info;
+ for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp)
+ {
+ asection *isec;
+
+ if (isym->st_shndx == SHN_UNDEF)
+ isec = bfd_und_section_ptr;
+ else if (isym->st_shndx == SHN_ABS)
+ isec = bfd_abs_section_ptr;
+ else if (isym->st_shndx == SHN_COMMON)
+ isec = bfd_com_section_ptr;
+ else
+ isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
+
+ *secpp = isec;
+ }
+
+ if (! elf32_crx_relocate_section (output_bfd, link_info, input_bfd,
+ input_section, data, internal_relocs,
+ isymbuf, sections))
+ goto error_return;
+
+ if (sections != NULL)
+ free (sections);
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ free (isymbuf);
+ if (elf_section_data (input_section)->relocs != internal_relocs)
+ free (internal_relocs);
+ }
+
+ return data;
+
+ error_return:
+ if (sections != NULL)
+ free (sections);
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ free (isymbuf);
+ if (internal_relocs != NULL
+ && elf_section_data (input_section)->relocs != internal_relocs)
+ free (internal_relocs);
+ return NULL;
+}
+
+/* Relocate a CRX ELF section. */
+
+static bfd_boolean
+elf32_crx_relocate_section (bfd *output_bfd, 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, *relend;
+
+ if (info->relocatable)
+ return TRUE;
+
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (input_bfd);
+
+ rel = relocs;
+ relend = relocs + input_section->reloc_count;
+ for (; rel < relend; rel++)
+ {
+ int r_type;
+ 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;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ r_type = ELF32_R_TYPE (rel->r_info);
+ howto = crx_elf_howto_table + (r_type);
+
+ 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);
+ }
+ else
+ {
+ bfd_boolean unresolved_reloc, warned;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned);
+ }
+
+ r = crx_elf_final_link_relocate (howto, input_bfd, output_bfd,
+ input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend,
+ info, sec, h == NULL);
+
+ if (r != bfd_reloc_ok)
+ {
+ const char *name;
+ const char *msg = (const char *) 0;
+
+ if (h != NULL)
+ name = h->root.root.string;
+ else
+ {
+ name = (bfd_elf_string_from_elf_section
+ (input_bfd, symtab_hdr->sh_link, sym->st_name));
+ if (name == NULL || *name == '\0')
+ name = bfd_section_name (input_bfd, sec);
+ }
+
+ switch (r)
+ {
+ case bfd_reloc_overflow:
+ if (!((*info->callbacks->reloc_overflow)
+ (info, name, howto->name, (bfd_vma) 0,
+ input_bfd, input_section, rel->r_offset)))
+ return FALSE;
+ break;
+
+ case bfd_reloc_undefined:
+ if (!((*info->callbacks->undefined_symbol)
+ (info, name, input_bfd, input_section,
+ rel->r_offset, TRUE)))
+ return FALSE;
+ break;
+
+ case bfd_reloc_outofrange:
+ msg = _("internal error: out of range error");
+ goto common_error;
+
+ case bfd_reloc_notsupported:
+ msg = _("internal error: unsupported relocation error");
+ goto common_error;
+
+ case bfd_reloc_dangerous:
+ msg = _("internal error: dangerous error");
+ goto common_error;
+
+ default:
+ msg = _("internal error: unknown error");
+ /* Fall through. */
+
+ common_error:
+ if (!((*info->callbacks->warning)
+ (info, msg, name, input_bfd, input_section,
+ rel->r_offset)))
+ return FALSE;
+ break;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+/* This function handles relaxing for the CRX.
+
+ There's quite a few relaxing opportunites available on the CRX:
+
+ * bal/bcond:32 -> bal/bcond:16 2 bytes
+ * bcond:16 -> bcond:8 2 bytes
+ * cmpbcond:24 -> cmpbcond:8 2 bytes
+ * arithmetic imm32 -> arithmetic imm16 2 bytes
+
+ Symbol- and reloc-reading infrastructure copied from elf-m10200.c. */
+
+static bfd_boolean
+elf32_crx_relax_section (bfd *abfd, asection *sec,
+ struct bfd_link_info *link_info, bfd_boolean *again)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Rela *internal_relocs;
+ Elf_Internal_Rela *irel, *irelend;
+ bfd_byte *contents = NULL;
+ Elf_Internal_Sym *isymbuf = NULL;
+
+ /* Assume nothing changes. */
+ *again = FALSE;
+
+ /* We don't have to do anything for a relocatable link, if
+ this section does not have relocs, or if this is not a
+ code section. */
+ if (link_info->relocatable
+ || (sec->flags & SEC_RELOC) == 0
+ || sec->reloc_count == 0
+ || (sec->flags & SEC_CODE) == 0)
+ return TRUE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+
+ /* Get a copy of the native relocations. */
+ internal_relocs = (_bfd_elf_link_read_relocs
+ (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
+ link_info->keep_memory));
+ if (internal_relocs == NULL)
+ goto error_return;
+
+ /* Walk through them looking for relaxing opportunities. */
+ irelend = internal_relocs + sec->reloc_count;
+ for (irel = internal_relocs; irel < irelend; irel++)
+ {
+ bfd_vma symval;
+
+ /* If this isn't something that can be relaxed, then ignore
+ this reloc. */
+ if (ELF32_R_TYPE (irel->r_info) != (int) R_CRX_REL32
+ && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_REL16
+ && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_REL24
+ && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_IMM32)
+ continue;
+
+ /* Get the section contents if we haven't done so already. */
+ if (contents == NULL)
+ {
+ /* Get cached copy if it exists. */
+ if (elf_section_data (sec)->this_hdr.contents != NULL)
+ contents = elf_section_data (sec)->this_hdr.contents;
+ /* Go get them off disk. */
+ else if (!bfd_malloc_and_get_section (abfd, sec, &contents))
+ goto error_return;
+ }
+
+ /* Read this BFD's local symbols if we haven't done so already. */
+ if (isymbuf == NULL && symtab_hdr->sh_info != 0)
+ {
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ goto error_return;
+ }
+
+ /* Get the value of the symbol referred to by the reloc. */
+ if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
+ {
+ /* A local symbol. */
+ Elf_Internal_Sym *isym;
+ asection *sym_sec;
+
+ isym = isymbuf + ELF32_R_SYM (irel->r_info);
+ if (isym->st_shndx == SHN_UNDEF)
+ sym_sec = bfd_und_section_ptr;
+ else if (isym->st_shndx == SHN_ABS)
+ sym_sec = bfd_abs_section_ptr;
+ else if (isym->st_shndx == SHN_COMMON)
+ sym_sec = bfd_com_section_ptr;
+ else
+ sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
+ symval = (isym->st_value
+ + sym_sec->output_section->vma
+ + sym_sec->output_offset);
+ }
+ else
+ {
+ unsigned long indx;
+ struct elf_link_hash_entry *h;
+
+ /* An external symbol. */
+ indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
+ h = elf_sym_hashes (abfd)[indx];
+ BFD_ASSERT (h != NULL);
+
+ if (h->root.type != bfd_link_hash_defined
+ && h->root.type != bfd_link_hash_defweak)
+ /* This appears to be a reference to an undefined
+ symbol. Just ignore it--it will be caught by the
+ regular reloc processing. */
+ continue;
+
+ symval = (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset);
+ }
+
+ /* For simplicity of coding, we are going to modify the section
+ contents, the section relocs, and the BFD symbol table. We
+ must tell the rest of the code not to free up this
+ information. It would be possible to instead create a table
+ of changes which have to be made, as is done in coff-mips.c;
+ that would be more work, but would require less memory when
+ the linker is run. */
+
+ /* Try to turn a 32bit pc-relative branch/call into
+ a 16bit pc-relative branch/call. */
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_CRX_REL32)
+ {
+ bfd_vma value = symval;
+
+ /* Deal with pc-relative gunk. */
+ value -= (sec->output_section->vma + sec->output_offset);
+ value -= irel->r_offset;
+ value += irel->r_addend;
+
+ /* See if the value will fit in 16 bits, note the high value is
+ 0xfffe + 2 as the target will be two bytes closer if we are
+ able to relax. */
+ if ((long) value < 0x10000 && (long) value > -0x10002)
+ {
+ unsigned short code;
+
+ /* Get the opcode. */
+ code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
+
+ /* Verify it's a 'bal'/'bcond' and fix the opcode. */
+ if ((code & 0xfff0) == 0x3170)
+ bfd_put_8 (abfd, 0x30, contents + irel->r_offset + 1);
+ else if ((code & 0xf0ff) == 0x707f)
+ bfd_put_8 (abfd, 0x7e, contents + irel->r_offset);
+ else
+ continue;
+
+ /* Note that we've changed the relocs, section contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ /* Fix the relocation's type. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_CRX_REL16);
+
+ /* Delete two bytes of data. */
+ if (!elf32_crx_relax_delete_bytes (abfd, sec,
+ irel->r_offset + 2, 2))
+ goto error_return;
+
+ /* That will change things, so, we should relax again.
+ Note that this is not required, and it may be slow. */
+ *again = TRUE;
+ }
+ }
+
+ /* Try to turn a 16bit pc-relative branch into an
+ 8bit pc-relative branch. */
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_CRX_REL16)
+ {
+ bfd_vma value = symval;
+
+ /* Deal with pc-relative gunk. */
+ value -= (sec->output_section->vma + sec->output_offset);
+ value -= irel->r_offset;
+ value += irel->r_addend;
+
+ /* See if the value will fit in 8 bits, note the high value is
+ 0xfc + 2 as the target will be two bytes closer if we are
+ able to relax. */
+ if ((long) value < 0xfe && (long) value > -0x100)
+ {
+ unsigned short code;
+
+ /* Get the opcode. */
+ code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
+
+ /* Verify it's a 'bcond' opcode. */
+ if ((code & 0xf0ff) != 0x707e)
+ continue;
+
+ /* Note that we've changed the relocs, section contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ /* Fix the relocation's type. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_CRX_REL8);
+
+ /* Delete two bytes of data. */
+ if (!elf32_crx_relax_delete_bytes (abfd, sec,
+ irel->r_offset + 2, 2))
+ goto error_return;
+
+ /* That will change things, so, we should relax again.
+ Note that this is not required, and it may be slow. */
+ *again = TRUE;
+ }
+ }
+
+ /* Try to turn a 24bit pc-relative cmp&branch into
+ an 8bit pc-relative cmp&branch. */
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_CRX_REL24)
+ {
+ bfd_vma value = symval;
+
+ /* Deal with pc-relative gunk. */
+ value -= (sec->output_section->vma + sec->output_offset);
+ value -= irel->r_offset;
+ value += irel->r_addend;
+
+ /* See if the value will fit in 8 bits, note the high value is
+ 0x7e + 2 as the target will be two bytes closer if we are
+ able to relax. */
+ if ((long) value < 0x100 && (long) value > -0x100)
+ {
+ unsigned short code;
+
+ /* Get the opcode. */
+ code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
+
+ /* Verify it's a 'cmp&branch' opcode. */
+ if ((code & 0xfff0) != 0x3180 && (code & 0xfff0) != 0x3190
+ && (code & 0xfff0) != 0x31a0 && (code & 0xfff0) != 0x31c0
+ && (code & 0xfff0) != 0x31d0 && (code & 0xfff0) != 0x31e0)
+ continue;
+
+ /* Note that we've changed the relocs, section contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ /* Fix the opcode. */
+ bfd_put_8 (abfd, 0x30, contents + irel->r_offset + 1);
+
+ /* Fix the relocation's type. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_CRX_REL8_CMP);
+
+ /* Delete two bytes of data. */
+ if (!elf32_crx_relax_delete_bytes (abfd, sec,
+ irel->r_offset + 4, 2))
+ goto error_return;
+
+ /* That will change things, so, we should relax again.
+ Note that this is not required, and it may be slow. */
+ *again = TRUE;
+ }
+ }
+
+ /* Try to turn a 32bit immediate address into
+ a 16bit immediate address. */
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_CRX_IMM32)
+ {
+ bfd_vma value = symval;
+
+ /* See if the value will fit in 16 bits. */
+ if ((long) value < 0x7fff && (long) value > -0x8000)
+ {
+ unsigned short code;
+
+ /* Get the opcode. */
+ code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
+
+ /* Verify it's a 'arithmetic double'. */
+ if ((code & 0xf0f0) != 0x20f0)
+ continue;
+
+ /* Note that we've changed the relocs, section contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ /* Fix the opcode. */
+ bfd_put_8 (abfd, (code & 0xff) - 0x10, contents + irel->r_offset);
+
+ /* Fix the relocation's type. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_CRX_IMM16);
+
+ /* Delete two bytes of data. */
+ if (!elf32_crx_relax_delete_bytes (abfd, sec,
+ irel->r_offset + 2, 2))
+ goto error_return;
+
+ /* That will change things, so, we should relax again.
+ Note that this is not required, and it may be slow. */
+ *again = TRUE;
+ }
+ }
+ }
+
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ {
+ if (! link_info->keep_memory)
+ free (isymbuf);
+ else
+ {
+ /* Cache the symbols for elf_link_input_bfd. */
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+ }
+ }
+
+ if (contents != NULL
+ && elf_section_data (sec)->this_hdr.contents != contents)
+ {
+ if (! link_info->keep_memory)
+ free (contents);
+ else
+ {
+ /* Cache the section contents for elf_link_input_bfd. */
+ elf_section_data (sec)->this_hdr.contents = contents;
+ }
+ }
+
+ if (internal_relocs != NULL
+ && elf_section_data (sec)->relocs != internal_relocs)
+ free (internal_relocs);
+
+ return TRUE;
+
+ error_return:
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ free (isymbuf);
+ if (contents != NULL
+ && elf_section_data (sec)->this_hdr.contents != contents)
+ free (contents);
+ if (internal_relocs != NULL
+ && elf_section_data (sec)->relocs != internal_relocs)
+ free (internal_relocs);
+
+ return FALSE;
+}
+
+static asection *
+elf32_crx_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)
+ return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
+
+ 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:
+ return NULL;
+ }
+}
+
+/* Update the got entry reference counts for the section being removed. */
+
+static bfd_boolean
+elf32_crx_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)
+{
+ /* We don't support garbage collection of GOT and PLT relocs yet. */
+ return TRUE;
+}
+
+/* Definitions for setting CRX target vector. */
+#define TARGET_LITTLE_SYM bfd_elf32_crx_vec
+#define TARGET_LITTLE_NAME "elf32-crx"
+#define ELF_ARCH bfd_arch_crx
+#define ELF_MACHINE_CODE EM_CRX
+#define ELF_MAXPAGESIZE 0x1
+#define elf_symbol_leading_char '_'
+
+#define bfd_elf32_bfd_reloc_type_lookup elf_crx_reloc_type_lookup
+#define elf_info_to_howto elf_crx_info_to_howto
+#define elf_info_to_howto_rel 0
+#define elf_backend_relocate_section elf32_crx_relocate_section
+#define bfd_elf32_bfd_relax_section elf32_crx_relax_section
+#define bfd_elf32_bfd_get_relocated_section_contents \
+ elf32_crx_get_relocated_section_contents
+#define elf_backend_gc_mark_hook elf32_crx_gc_mark_hook
+#define elf_backend_gc_sweep_hook elf32_crx_gc_sweep_hook
+#define elf_backend_can_gc_sections 1
+#define elf_backend_rela_normal 1
+
+#include "elf32-target.h"
--- /dev/null
+/* Renesas / SuperH specific support for Symbian 32-bit ELF files
+ Copyright 2004
+ Free Software Foundation, Inc.
+ Contributed by Red Hat
+
+ 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. */
+
+/* Stop elf32-sh.c from defining any target vectors. */
+#define SH_TARGET_ALREADY_DEFINED
+#define sh_find_elf_flags sh_symbian_find_elf_flags
+#define sh_elf_get_flags_from_mach sh_symbian_elf_get_flags_from_mach
+#include "elf32-sh.c"
+
+
+//#define DEBUG 1
+#define DEBUG 0
+
+#define DIRECTIVE_HEADER "#<SYMEDIT>#\n"
+#define DIRECTIVE_IMPORT "IMPORT "
+#define DIRECTIVE_EXPORT "EXPORT "
+#define DIRECTIVE_AS "AS "
+
+/* Macro to advance 's' until either it reaches 'e' or the
+ character pointed to by 's' is equal to 'c'. If 'e' is
+ reached and DEBUG is enabled then the error message 'm'
+ is displayed. */
+#define SKIP_UNTIL(s,e,c,m) \
+ do \
+ { \
+ while (s < e && *s != c) \
+ ++ s; \
+ if (s >= e) \
+ { \
+ if (DEBUG) \
+ fprintf (stderr, "Corrupt directive: %s\n", m); \
+ result = FALSE; \
+ } \
+ } \
+ while (0); \
+ if (!result) \
+ break;
+
+/* Like SKIP_UNTIL except there are two terminator characters
+ c1 and c2. */
+#define SKIP_UNTIL2(s,e,c1,c2,m) \
+ do \
+ { \
+ while (s < e && *s != c1 && *s != c2) \
+ ++ s; \
+ if (s >= e) \
+ { \
+ if (DEBUG) \
+ fprintf (stderr, "Corrupt directive: %s\n", m); \
+ result = FALSE; \
+ } \
+ } \
+ while (0); \
+ if (!result) \
+ break;
+
+/* Macro to advance 's' until either it reaches 'e' or the
+ character pointed to by 's' is not equal to 'c'. If 'e'
+ is reached and DEBUG is enabled then the error message
+ 'm' is displayed. */
+#define SKIP_WHILE(s,e,c,m) \
+ do \
+ { \
+ while (s < e && *s == c) \
+ ++ s; \
+ if (s >= e) \
+ { \
+ if (DEBUG) \
+ fprintf (stderr, "Corrupt directive: %s\n", m); \
+ result = FALSE; \
+ } \
+ } \
+ while (0); \
+ if (!result) \
+ break;
+
+
+typedef struct symbol_rename
+{
+ struct symbol_rename * next;
+ bfd_byte * current_name;
+ bfd_byte * new_name;
+ struct elf_link_hash_entry * current_hash;
+ unsigned long new_symndx;
+}
+symbol_rename;
+
+static symbol_rename * rename_list = NULL;
+
+/* Accumulate a list of symbols to be renamed. */
+
+static bfd_boolean
+sh_symbian_import_as (struct bfd_link_info *info, bfd * abfd,
+ bfd_byte * current_name, bfd_byte * new_name)
+{
+ struct elf_link_hash_entry * new_hash;
+ symbol_rename * node;
+
+ if (DEBUG)
+ fprintf (stderr, "IMPORT '%s' AS '%s'\n", current_name, new_name);
+
+ for (node = rename_list; node; node = node->next)
+ if (strcmp (node->current_name, current_name) == 0)
+ {
+ if (strcmp (node->new_name, new_name) == 0)
+ /* Already added to rename list. */
+ return TRUE;
+
+ bfd_set_error (bfd_error_invalid_operation);
+ _bfd_error_handler (_("%B: IMPORT AS directive for %s conceals previous IMPORT AS"),
+ abfd, current_name);
+ return FALSE;
+ }
+
+ if ((node = bfd_malloc (sizeof * node)) == NULL)
+ {
+ if (DEBUG)
+ fprintf (stderr, "IMPORT AS: No mem for new rename node\n");
+ return FALSE;
+ }
+
+ if ((node->current_name = bfd_malloc (strlen (current_name) + 1)) == NULL)
+ {
+ if (DEBUG)
+ fprintf (stderr, "IMPORT AS: No mem for current name field in rename node\n");
+ free (node);
+ return FALSE;
+ }
+ else
+ strcpy (node->current_name, current_name);
+
+ if ((node->new_name = bfd_malloc (strlen (new_name) + 1)) == NULL)
+ {
+ if (DEBUG)
+ fprintf (stderr, "IMPORT AS: No mem for new name field in rename node\n");
+ free (node->current_name);
+ free (node);
+ return FALSE;
+ }
+ else
+ strcpy (node->new_name, new_name);
+
+ node->next = rename_list;
+ node->current_hash = NULL;
+ node->new_symndx = 0;
+ rename_list = node;
+
+ new_hash = elf_link_hash_lookup (elf_hash_table (info), node->new_name, TRUE, FALSE, TRUE);
+ bfd_elf_link_record_dynamic_symbol (info, new_hash);
+ if (new_hash->root.type == bfd_link_hash_new)
+ new_hash->root.type = bfd_link_hash_undefined;
+
+ return TRUE;
+}
+
+
+static bfd_boolean
+sh_symbian_import (bfd * abfd ATTRIBUTE_UNUSED, bfd_byte * name)
+{
+ if (DEBUG)
+ fprintf (stderr, "IMPORT '%s'\n", name);
+
+ /* XXX: Generate an import somehow ? */
+
+ return TRUE;
+}
+
+static bfd_boolean
+sh_symbian_export (bfd * abfd ATTRIBUTE_UNUSED, bfd_byte * name)
+{
+ if (DEBUG)
+ fprintf (stderr, "EXPORT '%s'\n", name);
+
+ /* XXX: Generate an export somehow ? */
+
+ return TRUE;
+}
+
+/* Process any magic embedded commands in the .directive. section.
+ Returns TRUE upon sucecss, but if it fails it sets bfd_error and
+ returns FALSE. */
+
+static bfd_boolean
+sh_symbian_process_embedded_commands (struct bfd_link_info *info, bfd * abfd,
+ asection * sec, bfd_byte * contents)
+{
+ bfd_byte *s;
+ bfd_byte *e;
+ bfd_boolean result = TRUE;
+ bfd_size_type sz = sec->rawsize ? sec->rawsize : sec->size;
+
+ for (s = contents, e = s + sz; s < e;)
+ {
+ bfd_byte * directive = s;
+
+ switch (*s)
+ {
+ /* I want to use "case DIRECTIVE_HEADER [0]:" here but gcc won't let me :-( */
+ case '#':
+ if (strcmp (s, DIRECTIVE_HEADER))
+ result = FALSE;
+ else
+ /* Just ignore the header.
+ XXX: Strictly speaking we ought to check that the header
+ is present and that it is the first thing in the file. */
+ s += strlen (DIRECTIVE_HEADER) + 1;
+ break;
+
+ case 'I':
+ if (strncmp (s, DIRECTIVE_IMPORT, strlen (DIRECTIVE_IMPORT)))
+ result = FALSE;
+ else
+ {
+ bfd_byte * new_name;
+ bfd_byte * new_name_end;
+ bfd_byte name_end_char;
+
+ /* Skip the IMPORT directive. */
+ s += strlen (DIRECTIVE_IMPORT);
+
+ new_name = s;
+ /* Find the end of the new name. */
+ while (s < e && *s != ' ' && *s != '\n')
+ ++ s;
+ if (s >= e)
+ {
+ /* We have reached the end of the .directive section
+ without encountering a string terminator. This is
+ allowed for IMPORT directives. */
+ new_name_end = e - 1;
+ name_end_char = * new_name_end;
+ * new_name_end = 0;
+ result = sh_symbian_import (abfd, new_name);
+ * new_name_end = name_end_char;
+ break;
+ }
+
+ /* Remember where the name ends. */
+ new_name_end = s;
+ /* Skip any whitespace before the 'AS'. */
+ SKIP_WHILE (s, e, ' ', "IMPORT: Name just followed by spaces");
+ /* Terminate the new name. (Do this after skiping...) */
+ name_end_char = * new_name_end;
+ * new_name_end = 0;
+
+ /* Check to see if 'AS '... is present. If se we have an IMPORT AS
+ directive, otherwise we have an IMPORT directive. */
+ if (strncmp (s, DIRECTIVE_AS, strlen (DIRECTIVE_AS)))
+ {
+ /* Skip the new-line at the end of the name. */
+ if (DEBUG && name_end_char != '\n')
+ fprintf (stderr, "IMPORT: No newline at end of directive\n");
+ else
+ s ++;
+
+ result = sh_symbian_import (abfd, new_name);
+
+ /* Skip past the NUL character. */
+ if (* s ++ != 0)
+ {
+ if (DEBUG)
+ fprintf (stderr, "IMPORT: No NUL at end of directive\n");
+ }
+ }
+ else
+ {
+ bfd_byte * current_name;
+ bfd_byte * current_name_end;
+ bfd_byte current_name_end_char;
+
+ /* Skip the 'AS '. */
+ s += strlen (DIRECTIVE_AS);
+ /* Skip any white space after the 'AS '. */
+ SKIP_WHILE (s, e, ' ', "IMPORT AS: Nothing after AS");
+ current_name = s;
+ /* Find the end of the current name. */
+ SKIP_UNTIL2 (s, e, ' ', '\n', "IMPORT AS: No newline at the end of the current name");
+ /* Skip (backwards) over spaces at the end of the current name. */
+ current_name_end = s;
+ current_name_end_char = * current_name_end;
+
+ SKIP_WHILE (s, e, ' ', "IMPORT AS: Current name just followed by spaces");
+ /* Skip past the newline character. */
+ if (* s ++ != '\n')
+ if (DEBUG)
+ fprintf (stderr, "IMPORT AS: No newline at end of directive\n");
+
+ /* Terminate the current name after having performed the skips. */
+ * current_name_end = 0;
+
+ result = sh_symbian_import_as (info, abfd, current_name, new_name);
+
+ /* The next character should be a NUL. */
+ if (* s != 0)
+ {
+ if (DEBUG)
+ fprintf (stderr, "IMPORT AS: Junk at end of directive\n");
+ result = FALSE;
+ }
+ s ++;
+
+ * current_name_end = current_name_end_char;
+ }
+
+ /* Restore the characters we overwrote, since
+ the .directive section will be emitted. */
+ * new_name_end = name_end_char;
+ }
+ break;
+
+ case 'E':
+ if (strncmp (s, DIRECTIVE_EXPORT, strlen (DIRECTIVE_EXPORT)))
+ result = FALSE;
+ else
+ {
+ bfd_byte * name;
+ bfd_byte * name_end;
+ bfd_byte name_end_char;
+
+ /* Skip the directive. */
+ s += strlen (DIRECTIVE_EXPORT);
+ name = s;
+ /* Find the end of the name to be exported. */
+ SKIP_UNTIL (s, e, '\n', "EXPORT: no newline at end of directive");
+ /* Skip (backwards) over spaces at end of exported name. */
+ for (name_end = s; name_end[-1] == ' '; name_end --)
+ ;
+ /* name_end now points at the first character after the
+ end of the exported name, so we can termiante it */
+ name_end_char = * name_end;
+ * name_end = 0;
+ /* Skip passed the newline character. */
+ s ++;
+
+ result = sh_symbian_export (abfd, name);
+
+ /* The next character should be a NUL. */
+ if (* s != 0)
+ {
+ if (DEBUG)
+ fprintf (stderr, "EXPORT: Junk at end of directive\n");
+ result = FALSE;
+ }
+ s++;
+
+ /* Restore the character we deleted. */
+ * name_end = name_end_char;
+ }
+ break;
+
+ default:
+ result = FALSE;
+ break;
+ }
+
+ if (! result)
+ {
+ if (DEBUG)
+ fprintf (stderr, "offset into .directive section: %d\n", directive - contents);
+
+ bfd_set_error (bfd_error_invalid_operation);
+ _bfd_error_handler (_("%B: Unrecognised .directive command: %s"),
+ abfd, directive);
+ break;
+ }
+ }
+
+ return result;
+}
+
+
+/* Scan a bfd for a .directive section, and if found process it.
+ Returns TRUE upon success, FALSE otherwise. */
+bfd_boolean bfd_elf32_sh_symbian_process_directives (struct bfd_link_info *info, bfd * abfd);
+
+bfd_boolean
+bfd_elf32_sh_symbian_process_directives (struct bfd_link_info *info, bfd * abfd)
+{
+ bfd_boolean result = FALSE;
+ bfd_byte * contents;
+ asection * sec = bfd_get_section_by_name (abfd, ".directive");
+ bfd_size_type sz;
+
+ if (!sec)
+ return TRUE;
+
+ sz = sec->rawsize ? sec->rawsize : sec->size;
+ contents = bfd_malloc (sz);
+
+ if (!contents)
+ bfd_set_error (bfd_error_no_memory);
+ else
+ {
+ if (bfd_get_section_contents (abfd, sec, contents, 0, sz))
+ result = sh_symbian_process_embedded_commands (info, abfd, sec, contents);
+ free (contents);
+ }
+
+ return result;
+}
+
+/* Intercept the normal sh_relocate_section() function
+ and magle the relocs to allow for symbol renaming. */
+
+static bfd_boolean
+sh_symbian_relocate_section (bfd * output_bfd,
+ 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)
+{
+ /* When performing a final link we implement the IMPORT AS directives. */
+ if (!info->relocatable)
+ {
+ Elf_Internal_Rela * rel;
+ Elf_Internal_Rela * relend;
+ Elf_Internal_Shdr * symtab_hdr;
+ struct elf_link_hash_entry ** sym_hashes;
+ struct elf_link_hash_entry ** sym_hashes_end;
+ struct elf_link_hash_table * hash_table;
+ symbol_rename * ptr;
+ bfd_size_type num_global_syms;
+ unsigned long num_local_syms;
+
+ BFD_ASSERT (! elf_bad_symtab (input_bfd));
+
+ symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
+ hash_table = elf_hash_table (info);
+ num_local_syms = symtab_hdr->sh_info;
+ num_global_syms = symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
+ num_global_syms -= num_local_syms;
+ sym_hashes = elf_sym_hashes (input_bfd);
+ sym_hashes_end = sym_hashes + num_global_syms;
+
+ /* First scan the rename table, caching the hash entry and the new index. */
+ for (ptr = rename_list; ptr; ptr = ptr->next)
+ {
+ struct elf_link_hash_entry * new_hash;
+ struct elf_link_hash_entry ** h;
+
+ ptr->current_hash = elf_link_hash_lookup (hash_table, ptr->current_name, FALSE, FALSE, TRUE);
+
+ if (ptr->current_hash == NULL)
+ {
+ if (DEBUG)
+ fprintf (stderr, "IMPORT AS: current symbol '%s' does not exist\n", ptr->current_name);
+ continue;
+ }
+
+ new_hash = elf_link_hash_lookup (hash_table, ptr->new_name, FALSE, FALSE, TRUE);
+
+ /* If we could not find the symbol then it is a new, undefined symbol.
+ Symbian want this behaviour - ie they want to be able to rename the
+ reference in a reloc from one undefined symbol to another, new and
+ undefined symbol. So we create that symbol here. */
+ if (new_hash == NULL)
+ {
+ asection * psec = bfd_und_section_ptr;
+ Elf_Internal_Sym new_sym;
+ bfd_vma new_value = 0;
+ bfd_boolean skip;
+ bfd_boolean override;
+ bfd_boolean type_change_ok;
+ bfd_boolean size_change_ok;
+
+ new_sym.st_value = 0;
+ new_sym.st_size = 0;
+ new_sym.st_name = -1;
+ new_sym.st_info = ELF_ST_INFO (STB_GLOBAL, STT_FUNC);
+ new_sym.st_other = ELF_ST_VISIBILITY (STV_DEFAULT);
+ new_sym.st_shndx = SHN_UNDEF;
+
+ if (! _bfd_elf_merge_symbol (input_bfd, info, ptr->new_name, & new_sym, & psec,
+ & new_value, & new_hash, & skip, & override, & type_change_ok,
+ & size_change_ok))
+ {
+ _bfd_error_handler (_("%B: Failed to add renamed symbol %s"),
+ input_bfd, ptr->new_name);
+ continue;
+ }
+ /* XXX - should we check psec, skip, override etc ? */
+
+ new_hash->root.type = bfd_link_hash_undefined;
+
+ /* Allow the symbol to become local if necessary. */
+ if (new_hash->dynindx == -1)
+ new_hash->def_regular = 1;
+
+ if (DEBUG)
+ fprintf (stderr, "Created new symbol %s\n", ptr->new_name);
+ }
+
+ /* Convert the new_hash value into a index into the table of symbol hashes. */
+ for (h = sym_hashes; h < sym_hashes_end; h ++)
+ {
+ if (* h == new_hash)
+ {
+ ptr->new_symndx = h - sym_hashes + num_local_syms;
+ if (DEBUG)
+ fprintf (stderr, "Converted new hash to index of %ld\n", ptr->new_symndx);
+ break;
+ }
+ }
+ /* If the new symbol is not in the hash table then it must be
+ because it is one of the newly created undefined symbols
+ manufactured above. So we extend the sym has table here to
+ include this extra symbol. */
+ if (h == sym_hashes_end)
+ {
+ struct elf_link_hash_entry ** new_sym_hashes;
+
+ /* This is not very efficient, but it works. */
+ ++ num_global_syms;
+ new_sym_hashes = bfd_alloc (input_bfd, num_global_syms * sizeof * sym_hashes);
+ if (new_sym_hashes == NULL)
+ {
+ if (DEBUG)
+ fprintf (stderr, "Out of memory extending hash table\n");
+ continue;
+ }
+ memcpy (new_sym_hashes, sym_hashes, (num_global_syms - 1) * sizeof * sym_hashes);
+ new_sym_hashes[num_global_syms - 1] = new_hash;
+ elf_sym_hashes (input_bfd) = sym_hashes = new_sym_hashes;
+ sym_hashes_end = sym_hashes + num_global_syms;
+ symtab_hdr->sh_size = (num_global_syms + num_local_syms) * sizeof (Elf32_External_Sym);
+
+ ptr->new_symndx = num_global_syms - 1 + num_local_syms;
+
+ if (DEBUG)
+ fprintf (stderr, "Extended symbol hash table to insert new symbol as index %ld\n",
+ ptr->new_symndx);
+ }
+ }
+
+ /* Walk the reloc list looking for references to renamed symbols.
+ When we find one, we alter the index in the reloc to point to the new symbol. */
+ for (rel = relocs, relend = relocs + input_section->reloc_count;
+ rel < relend;
+ rel ++)
+ {
+ int r_type;
+ unsigned long r_symndx;
+ struct elf_link_hash_entry * h;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ r_type = ELF32_R_TYPE (rel->r_info);
+
+ /* Ignore unused relocs. */
+ if ((r_type >= (int) R_SH_GNU_VTINHERIT
+ && r_type <= (int) R_SH_LABEL)
+ || r_type == (int) R_SH_NONE
+ || r_type < 0
+ || r_type >= R_SH_max)
+ continue;
+
+ /* Ignore relocs against local symbols. */
+ if (r_symndx < num_local_syms)
+ continue;
+
+ BFD_ASSERT (r_symndx < (num_global_syms + num_local_syms));
+ h = sym_hashes[r_symndx - num_local_syms];
+ BFD_ASSERT (h != NULL);
+
+ 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;
+
+ /* If the symbol is defined there is no need to rename it.
+ XXX - is this true ? */
+ if ( h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak
+ || h->root.type == bfd_link_hash_undefweak)
+ continue;
+
+ for (ptr = rename_list; ptr; ptr = ptr->next)
+ if (h == ptr->current_hash)
+ {
+ BFD_ASSERT (ptr->new_symndx);
+ if (DEBUG)
+ fprintf (stderr, "convert reloc %lx from using index %ld to using index %ld\n",
+ (long) rel->r_info, (long) ELF32_R_SYM (rel->r_info), ptr->new_symndx);
+ rel->r_info = ELF32_R_INFO (ptr->new_symndx, r_type);
+ break;
+ }
+ }
+ }
+
+ return sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
+ contents, relocs, local_syms, local_sections);
+}
+
+static bfd_boolean
+sh_symbian_check_directives (bfd *abfd, struct bfd_link_info *info)
+{
+ return bfd_elf32_sh_symbian_process_directives (info, abfd);
+}
+
+#define TARGET_LITTLE_SYM bfd_elf32_shl_symbian_vec
+#define TARGET_LITTLE_NAME "elf32-shl-symbian"
+
+#undef elf_backend_relocate_section
+#define elf_backend_relocate_section sh_symbian_relocate_section
+#undef elf_backend_check_directives
+#define elf_backend_check_directives sh_symbian_check_directives
+
+#include "elf32-target.h"
--- /dev/null
+/* BFD back-end for OpenBSD/m88k a.out binaries.
+ Copyright 2004 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. */
+
+#define TARGET_IS_BIG_ENDIAN_P
+
+#define TARGET_PAGE_SIZE 4096
+
+#define DEFAULT_ARCH bfd_arch_m88k
+#define DEFAULT_MID M_88K_OPENBSD
+
+/* Do not "beautify" the CONCAT* macro args. Traditional C will not
+ remove whitespace added here, and thus will fail to concatenate
+ the tokens. */
+#define MY(OP) CONCAT2 (m88kopenbsd_,OP)
+#define TARGETNAME "a.out-m88k-openbsd"
+
+#include "netbsd.h"
--- /dev/null
+# The -mdynamic-no-pic ensures that the compiler executable is built without
+# position-independent-code -- the usual default on Darwin. This fix speeds
+# compiles by 3-5%.
+
+BOOT_CFLAGS=-g -O2 -mdynamic-no-pic
+
--- /dev/null
+CXXFLAGS_FOR_TARGET = $(CXXFLAGS) -D_GNU_SOURCE
--- /dev/null
+/* BSD Kernel Data Access Library (libkvm) interface.
+
+ Copyright 2004 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. */
+
+#include "defs.h"
+#include "cli/cli-cmds.h"
+#include "command.h"
+#include "frame.h"
+#include "regcache.h"
+#include "target.h"
+#include "value.h"
+#include "gdbcore.h" /* for get_exec_file */
+
+#include "gdb_assert.h"
+#include <fcntl.h>
+#include <kvm.h>
+#ifdef HAVE_NLIST_H
+#include <nlist.h>
+#endif
+#include "readline/readline.h"
+#include <sys/param.h>
+#include <sys/proc.h>
+#include <sys/user.h>
+
+#include "bsd-kvm.h"
+
+/* Kernel memory interface descriptor. */
+kvm_t *core_kd;
+
+/* Address of process control block. */
+struct pcb *bsd_kvm_paddr;
+
+/* Pointer to architecture-specific function that reconstructs the
+ register state from PCB and supplies it to REGCACHE. */
+int (*bsd_kvm_supply_pcb)(struct regcache *regcache, struct pcb *pcb);
+
+/* Target ops for libkvm interface. */
+struct target_ops bsd_kvm_ops;
+
+static void
+bsd_kvm_open (char *filename, int from_tty)
+{
+ char errbuf[_POSIX2_LINE_MAX];
+ char *execfile = NULL;
+ kvm_t *temp_kd;
+
+ target_preopen (from_tty);
+
+ if (filename)
+ {
+ char *temp;
+
+ filename = tilde_expand (filename);
+ if (filename[0] != '/')
+ {
+ temp = concat (current_directory, "/", filename, NULL);
+ xfree (filename);
+ filename = temp;
+ }
+ }
+
+ execfile = get_exec_file (0);
+ temp_kd = kvm_openfiles (execfile, filename, NULL, O_RDONLY, errbuf);
+ if (temp_kd == NULL)
+ error ("%s", errbuf);
+
+ unpush_target (&bsd_kvm_ops);
+ core_kd = temp_kd;
+ push_target (&bsd_kvm_ops);
+
+ target_fetch_registers (-1);
+
+ flush_cached_frames ();
+ select_frame (get_current_frame ());
+ print_stack_frame (get_selected_frame (), -1, 1);
+}
+
+static void
+bsd_kvm_close (int quitting)
+{
+ if (core_kd)
+ {
+ if (kvm_close (core_kd) == -1)
+ warning ("%s", kvm_geterr(core_kd));
+ core_kd = NULL;
+ }
+}
+
+static int
+bsd_kvm_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
+ int write, struct mem_attrib *attrib,
+ struct target_ops *ops)
+{
+ if (write)
+ return kvm_write (core_kd, memaddr, myaddr, len);
+ else
+ return kvm_read (core_kd, memaddr, myaddr, len);
+
+ return -1;
+}
+
+/* Fetch process control block at address PADDR. */
+
+static int
+bsd_kvm_fetch_pcb (struct pcb *paddr)
+{
+ struct pcb pcb;
+
+ if (kvm_read (core_kd, (unsigned long) paddr, &pcb, sizeof pcb) == -1)
+ error ("%s", kvm_geterr (core_kd));
+
+ gdb_assert (bsd_kvm_supply_pcb);
+ return bsd_kvm_supply_pcb (current_regcache, &pcb);
+}
+
+static void
+bsd_kvm_fetch_registers (int regnum)
+{
+ struct nlist nl[2];
+
+ if (bsd_kvm_paddr)
+ {
+ bsd_kvm_fetch_pcb (bsd_kvm_paddr);
+ return;
+ }
+
+ /* On dumping core, BSD kernels store the faulting context (PCB)
+ in the variable "dumppcb". */
+ memset (nl, 0, sizeof nl);
+ nl[0].n_name = "_dumppcb";
+
+ if (kvm_nlist (core_kd, nl) == -1)
+ error ("%s", kvm_geterr (core_kd));
+
+ if (nl[0].n_value != 0)
+ {
+ /* Found dumppcb. If it contains a valid context, return
+ immediately. */
+ if (bsd_kvm_fetch_pcb ((struct pcb *) nl[0].n_value))
+ return;
+ }
+
+ /* Traditional BSD kernels have a process proc0 that should always
+ be present. The address of proc0's PCB is stored in the variable
+ "proc0paddr". */
+
+ memset (nl, 0, sizeof nl);
+ nl[0].n_name = "_proc0paddr";
+
+ if (kvm_nlist (core_kd, nl) == -1)
+ error ("%s", kvm_geterr (core_kd));
+
+ if (nl[0].n_value != 0)
+ {
+ struct pcb *paddr;
+
+ /* Found proc0paddr. */
+ if (kvm_read (core_kd, nl[0].n_value, &paddr, sizeof paddr) == -1)
+ error ("%s", kvm_geterr (core_kd));
+
+ bsd_kvm_fetch_pcb (paddr);
+ return;
+ }
+
+#ifdef HAVE_STRUCT_THREAD_TD_PCB
+ /* In FreeBSD kernels for 5.0-RELEASE and later, the PCB no longer
+ lives in `struct proc' but in `struct thread'. The `struct
+ thread' for the initial thread for proc0 can be found in the
+ variable "thread0". */
+
+ memset (nl, 0, sizeof nl);
+ nl[0].n_name = "_thread0";
+
+ if (kvm_nlist (core_kd, nl) == -1)
+ error ("%s", kvm_geterr (core_kd));
+
+ if (nl[0].n_value != 0)
+ {
+ struct pcb *paddr;
+
+ /* Found thread0. */
+ nl[0].n_value += offsetof (struct thread, td_pcb);
+ if (kvm_read (core_kd, nl[0].n_value, &paddr, sizeof paddr) == -1)
+ error ("%s", kvm_geterr (core_kd));
+
+ bsd_kvm_fetch_pcb (paddr);
+ return;
+ }
+#endif
+
+ error ("Cannot find a valid PCB");
+}
+\f
+
+/* Kernel memory interface commands. */
+struct cmd_list_element *bsd_kvm_cmdlist;
+
+static void
+bsd_kvm_cmd (char *arg, int fromtty)
+{
+ /* ??? Should this become an alias for "target kvm"? */
+}
+
+#ifndef HAVE_STRUCT_THREAD_TD_PCB
+
+static void
+bsd_kvm_proc_cmd (char *arg, int fromtty)
+{
+ CORE_ADDR addr;
+
+ if (arg == NULL)
+ error_no_arg ("proc address");
+
+ if (core_kd == NULL)
+ error ("No kernel memory image.");
+
+ addr = parse_and_eval_address (arg);
+#ifdef HAVE_STRUCT_LWP
+ addr += offsetof (struct lwp, l_addr);
+#else
+ addr += offsetof (struct proc, p_addr);
+#endif
+
+ if (kvm_read (core_kd, addr, &bsd_kvm_paddr, sizeof bsd_kvm_paddr) == -1)
+ error ("%s", kvm_geterr (core_kd));
+
+ target_fetch_registers (-1);
+
+ flush_cached_frames ();
+ select_frame (get_current_frame ());
+ print_stack_frame (get_selected_frame (), -1, 1);
+}
+
+#endif
+
+static void
+bsd_kvm_pcb_cmd (char *arg, int fromtty)
+{
+ if (arg == NULL)
+ error_no_arg ("pcb address");
+
+ if (core_kd == NULL)
+ error ("No kernel memory image.");
+
+ bsd_kvm_paddr = (struct pcb *) parse_and_eval_address (arg);
+
+ target_fetch_registers (-1);
+
+ flush_cached_frames ();
+ select_frame (get_current_frame ());
+ print_stack_frame (get_selected_frame (), -1, 1);
+}
+
+/* Add the libkvm interface to the list of all possible targets and
+ register CUPPLY_PCB as the architecture-specific process control
+ block interpreter. */
+
+void
+bsd_kvm_add_target (int (*supply_pcb)(struct regcache *, struct pcb *))
+{
+ gdb_assert (bsd_kvm_supply_pcb == NULL);
+ bsd_kvm_supply_pcb = supply_pcb;
+
+ bsd_kvm_ops.to_shortname = "kvm";
+ bsd_kvm_ops.to_longname = "Kernel memory interface";
+ bsd_kvm_ops.to_doc = "Use a kernel virtual memory image as a target.\n\
+Optionally specify the filename of a core dump.";
+ bsd_kvm_ops.to_open = bsd_kvm_open;
+ bsd_kvm_ops.to_close = bsd_kvm_close;
+ bsd_kvm_ops.to_fetch_registers = bsd_kvm_fetch_registers;
+ bsd_kvm_ops.to_xfer_memory = bsd_kvm_xfer_memory;
+ bsd_kvm_ops.to_stratum = process_stratum;
+ bsd_kvm_ops.to_has_memory = 1;
+ bsd_kvm_ops.to_has_stack = 1;
+ bsd_kvm_ops.to_has_registers = 1;
+ bsd_kvm_ops.to_magic = OPS_MAGIC;
+
+ add_target (&bsd_kvm_ops);
+
+ add_prefix_cmd ("kvm", class_obscure, bsd_kvm_cmd, "\
+Generic command for manipulating the kernel memory interface.",
+ &bsd_kvm_cmdlist, "kvm ", 0, &cmdlist);
+
+#ifndef HAVE_STRUCT_THREAD_TD_PCB
+ add_cmd ("proc", class_obscure, bsd_kvm_proc_cmd,
+ "Set current context from proc address", &bsd_kvm_cmdlist);
+#endif
+ add_cmd ("pcb", class_obscure, bsd_kvm_pcb_cmd,
+ "Set current context from pcb address", &bsd_kvm_cmdlist);
+}
--- /dev/null
+/* BSD Kernel Data Access Library (libkvm) interface.
+
+ Copyright 2004 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. */
+
+#ifndef BSD_KVM_H
+#define BSD_KVM_H
+
+struct pcb;
+struct regcache;
+
+/* Add the libkvm interface to the list of all possible targets and
+ register CUPPLY_PCB as the architecture-specific process control
+ block interpreter. */
+
+extern void
+ bsd_kvm_add_target (int (*supply_pcb)(struct regcache *, struct pcb *));
+
+#endif /* bsd-kvm.h */
--- /dev/null
+# Target: i386
+TDEPFILES= i386-tdep.o i387-tdep.o
--- /dev/null
+# Target: NetBSD/m68k
+TDEPFILES= m68k-tdep.o m68kbsd-tdep.o corelow.o solib.o solib-svr4.o
+DEPRECATED_TM_FILE= solib.h
--- /dev/null
+# Host: NetBSD/m68k ELF
+NATDEPFILES= m68kbsd-nat.o bsd-kvm.o fork-child.o infptrace.o inftarg.o
+NAT_FILE= config/nm-nbsd.h
+
+LOADLIBES= -lkvm
--- /dev/null
+# Host: OpenBSD/m68k
+NATDEPFILES= m68kbsd-nat.o bsd-kvm.o fork-child.o infptrace.o inftarg.o \
+ solib.o solib-sunos.o
+NAT_FILE= nm-nbsdaout.h
+
+LOADLIBES= -lkvm
--- /dev/null
+# Target: OpenBSD/m68k
+TDEPFILES= m68k-tdep.o m68kbsd-tdep.o corelow.o solib.o solib-svr4.o
+DEPRECATED_TM_FILE= solib.h
--- /dev/null
+# Host: OpenBSD/m88k
+NATDEPFILES= m88kbsd-nat.o fork-child.o infptrace.o inftarg.o
+NAT_FILE= config/nm-bsd.h
--- /dev/null
+# Target: OpenBSD/m88k
+TDEPFILES= m88k-tdep.o corelow.o
--- /dev/null
+# Host: Hewlett-Packard PA-RISC machine, running Linux
+XDEPFILES=
+NAT_FILE= nm-linux.h
+NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o gcore.o \
+ core-regset.o hppa-linux-nat.o linux-proc.o \
+ proc-service.o thread-db.o lin-lwp.o linux-nat.o
+
+LOADLIBES = -ldl -rdynamic
--- /dev/null
+# Target: HP PA-RISC running Linux
+TDEPFILES= hppa-tdep.o hppa-linux-tdep.o glibc-tdep.o solib.o solib-svr4.o
+DEPRECATED_TM_FILE=tm-linux.h
--- /dev/null
+/* Native support for GNU/Linux, for GDB, the GNU debugger.
+ Copyright (C) 2004 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. */
+
+#ifndef PA_NM_LINUX_H
+#define PA_NM_LINUX_H
+
+#include "config/nm-linux.h"
+
+#define U_REGS_OFFSET 0
+
+/* Override copies of {fetch,store}_inferior_registers in `infptrace.c'. */
+#define FETCH_INFERIOR_REGISTERS
+
+#endif
+
--- /dev/null
+# Host: OpenBSD/hppa
+NATDEPFILES= fork-child.o infptrace.o inftarg.o hppabsd-nat.o
+NAT_FILE= config/nm-bsd.h
--- /dev/null
+# Target: OpenBSD/hppa
+TDEPFILES= hppa-tdep.o hppabsd-tdep.o corelow.o solib.o solib-svr4.o
+DEPRECATED_TM_FILE= solib.h
--- /dev/null
+/* Definitions to target GDB to GNU/Linux on hppa-linux.
+ Copyright 2004 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. */
+
+#ifndef TM_LINUX_H
+#define TM_LINUX_H
+
+#include "pa/tm-hppa.h"
+#include "config/tm-linux.h"
+
+#undef IN_SOLIB_CALL_TRAMPOLINE
+#undef SKIP_TRAMPOLINE_CODE
+
+#endif /* #ifndef TM_LINUX_H */
--- /dev/null
+# Host: OpenBSD/powerpc
+NATDEPFILES= ppcobsd-nat.o fork-child.o infptrace.o inftarg.o
+NAT_FILE= config/nm-bsd.h
--- /dev/null
+# Target: OpenBSD/powerpc
+TDEPFILES= rs6000-tdep.o ppc-sysv-tdep.o ppcobsd-tdep.o \
+ corelow.o solib.o solib-svr4.o
+DEPRECATED_TM_FILE= tm-nbsd.h
--- /dev/null
+# Target: NetBSD/vax
+TDEPFILES= vax-tdep.o vaxnbsd-tdep.o corelow.o solib.o solib-svr4.o
+DEPRECATED_TM_FILE= solib.h
--- /dev/null
+# Host: NetBSD/vax a.out
+NATDEPFILES= vaxbsd-nat.o bsd-kvm.o fork-child.o infptrace.o inftarg.o \
+ solib.o solib-sunos.o
+NAT_FILE= nm-nbsdaout.h
+
+LOADLIBES= -lkvm
--- /dev/null
+# Host: NetBSD/vax ELF
+NATDEPFILES= vaxbsd-nat.o bsd-kvm.o fork-child.o infptrace.o inftarg.o
+NAT_FILE= config/nm-nbsd.h
+
+LOADLIBES= -lkvm
--- /dev/null
+/* Native-dependent definitions for NetBSD/vax a.out.
+
+ Copyright 2004 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. */
+
+#ifndef NM_NBSDAOUT_H
+#define NM_NBSDAOUT_H
+
+#include "config/nm-nbsd.h"
+
+/* Get generic NetBSD a.out native definitions. */
+#include "config/nm-nbsdaout.h"
+
+#endif /* nm-nbsdaout.h */
--- /dev/null
+# Host: OpenBSD/vax
+NATDEPFILES= vaxbsd-nat.o bsd-kvm.o fork-child.o infptrace.o inftarg.o
+NAT_FILE= config/nm-bsd.h
+
+LOADLIBES= -lkvm
--- /dev/null
+# Host: VAX running 4.2BSD or Ultrix
+NATDEPFILES= vax-nat.o fork-child.o infptrace.o inftarg.o \
+ corelow.o core-aout.o
+NAT_FILE= nm-vax.h
--- /dev/null
+/* Portable <sys/ptrace.h>
+
+ Copyright 2004 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. */
+
+#ifndef GDB_PTRACE_H
+#define GDB_PTRACE_H
+
+/* The <sys/ptrace.h> header was introduced with 4.4BSD, and provided
+ the PT_* symbolic constants for the ptrace(2) request numbers. The
+ ptrace(2) prototype was added later to the same header on BSD.
+ SunOS and GNU/Linux have slightly different symbolic names for the
+ constants that start with PTRACE_*. System V still doesn't have
+ (and probably never will have) a <sys/ptrace.h> with symbolic
+ constants; the ptrace(2) prototype can be found in <unistd.h>.
+ Fortunately all systems use the same numerical constants for the
+ common ptrace requests. */
+
+#ifdef HAVE_PTRACE_H
+# include <ptrace.h>
+#elif defined(HAVE_SYS_PTRACE_H)
+# include <sys/ptrace.h>
+#endif
+
+/* No need to include <unistd.h> since it's already included by
+ "defs.h". */
+
+#ifndef PT_READ_I
+# define PT_READ_I 1 /* Read word in child's I space. */
+#endif
+
+#ifndef PT_READ_D
+# define PT_READ_D 2 /* Read word in child's D space. */
+#endif
+
+#ifndef PT_READ_U
+# define PT_READ_U 3 /* Read word in child's U space. */
+#endif
+
+#ifndef PT_WRITE_I
+# define PT_WRITE_I 4 /* Write word in child's I space. */
+#endif
+
+#ifndef PT_WRITE_D
+# define PT_WRITE_D 5 /* Write word in child's D space. */
+#endif
+
+#ifndef PT_WRITE_U
+# define PT_WRITE_U 6 /* Write word in child's U space. */
+#endif
+
+/* HP-UX doesn't define PT_CONTINUE and PT_STEP. Instead of those two
+ ptrace requests, it has PT_CONTIN, PT_CONTIN1, PT_SINGLE and
+ PT_SINGLE1. PT_CONTIN1 and PT_SINGLE1 preserve pending signals,
+ which apparently is what is wanted by the HP-UX native code. */
+
+#ifndef PT_CONTINUE
+# ifdef PT_CONTIN1
+# define PT_CONTINUE PT_CONTIN1
+# else
+# define PT_CONTINUE 7 /* Continue the child. */
+# endif
+#endif
+
+#ifndef PT_KILL
+# define PT_KILL 8 /* Kill the child process. */
+#endif
+
+#ifndef PT_STEP
+# ifdef PT_SINGLE1
+# define PT_STEP PT_SINGLE1
+# else
+# define PT_STEP 9 /* Single step the child. */
+# endif
+#endif
+
+/* Not all systems support attaching and detaching. */
+
+#ifndef PT_ATTCH
+# ifdef PTRACE_DETACH
+# define PT_ATTACH PTRACE_ATTACH
+# endif
+#endif
+
+#ifndef PT_DETACH
+# ifdef PTRACE_DETACH
+# define PT_DETACH PTRACE_DETACH
+# endif
+#endif
+
+/* Some systems, in particular DEC OSF/1, Digital Unix, Compaq Tru64
+ or whatever it's called these days, don't provide a prototype for
+ ptrace. Provide one to silence compiler warnings. */
+#ifndef HAVE_DECL_PTRACE
+extern PTRACE_TYPE_RET ptrace();
+#endif
+
+#endif /* gdb_ptrace.h */
--- /dev/null
+/* Functions specific to running GDB native on HPPA running GNU/Linux.
+
+ Copyright 2004 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. */
+
+#include "defs.h"
+#include "gdbcore.h"
+#include "regcache.h"
+#include "gdb_string.h"
+#include "inferior.h"
+
+#include <sys/procfs.h>
+#include <sys/ptrace.h>
+#include <linux/version.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,43)
+#include <asm/offset.h>
+#else
+#include <asm/offsets.h>
+#endif
+
+#include "hppa-tdep.h"
+
+/* Prototypes for supply_gregset etc. */
+#include "gregset.h"
+
+/* These must match the order of the register names.
+
+ Some sort of lookup table is needed because the offsets associated
+ with the registers are all over the board. */
+
+static const int u_offsets[] =
+ {
+ /* general registers */
+ -1,
+ PT_GR1,
+ PT_GR2,
+ PT_GR3,
+ PT_GR4,
+ PT_GR5,
+ PT_GR6,
+ PT_GR7,
+ PT_GR8,
+ PT_GR9,
+ PT_GR10,
+ PT_GR11,
+ PT_GR12,
+ PT_GR13,
+ PT_GR14,
+ PT_GR15,
+ PT_GR16,
+ PT_GR17,
+ PT_GR18,
+ PT_GR19,
+ PT_GR20,
+ PT_GR21,
+ PT_GR22,
+ PT_GR23,
+ PT_GR24,
+ PT_GR25,
+ PT_GR26,
+ PT_GR27,
+ PT_GR28,
+ PT_GR29,
+ PT_GR30,
+ PT_GR31,
+
+ PT_SAR,
+ PT_IAOQ0,
+ PT_IASQ0,
+ PT_IAOQ1,
+ PT_IASQ1,
+ -1, /* eiem */
+ PT_IIR,
+ PT_ISR,
+ PT_IOR,
+ PT_PSW,
+ -1, /* goto */
+
+ PT_SR4,
+ PT_SR0,
+ PT_SR1,
+ PT_SR2,
+ PT_SR3,
+ PT_SR5,
+ PT_SR6,
+ PT_SR7,
+
+ -1, /* cr0 */
+ -1, /* pid0 */
+ -1, /* pid1 */
+ -1, /* ccr */
+ -1, /* pid2 */
+ -1, /* pid3 */
+ -1, /* cr24 */
+ -1, /* cr25 */
+ -1, /* cr26 */
+ PT_CR27,
+ -1, /* cr28 */
+ -1, /* cr29 */
+ -1, /* cr30 */
+
+ /* Floating point regs. */
+ PT_FR0, PT_FR0 + 4,
+ PT_FR1, PT_FR1 + 4,
+ PT_FR2, PT_FR2 + 4,
+ PT_FR3, PT_FR3 + 4,
+ PT_FR4, PT_FR4 + 4,
+ PT_FR5, PT_FR5 + 4,
+ PT_FR6, PT_FR6 + 4,
+ PT_FR7, PT_FR7 + 4,
+ PT_FR8, PT_FR8 + 4,
+ PT_FR9, PT_FR9 + 4,
+ PT_FR10, PT_FR10 + 4,
+ PT_FR11, PT_FR11 + 4,
+ PT_FR12, PT_FR12 + 4,
+ PT_FR13, PT_FR13 + 4,
+ PT_FR14, PT_FR14 + 4,
+ PT_FR15, PT_FR15 + 4,
+ PT_FR16, PT_FR16 + 4,
+ PT_FR17, PT_FR17 + 4,
+ PT_FR18, PT_FR18 + 4,
+ PT_FR19, PT_FR19 + 4,
+ PT_FR20, PT_FR20 + 4,
+ PT_FR21, PT_FR21 + 4,
+ PT_FR22, PT_FR22 + 4,
+ PT_FR23, PT_FR23 + 4,
+ PT_FR24, PT_FR24 + 4,
+ PT_FR25, PT_FR25 + 4,
+ PT_FR26, PT_FR26 + 4,
+ PT_FR27, PT_FR27 + 4,
+ PT_FR28, PT_FR28 + 4,
+ PT_FR29, PT_FR29 + 4,
+ PT_FR30, PT_FR30 + 4,
+ PT_FR31, PT_FR31 + 4,
+ };
+
+CORE_ADDR
+register_addr (int regno, CORE_ADDR blockend)
+{
+ CORE_ADDR addr;
+
+ if ((unsigned) regno >= NUM_REGS)
+ error ("Invalid register number %d.", regno);
+
+ if (u_offsets[regno] == -1)
+ addr = 0;
+ else
+ {
+ addr = (CORE_ADDR) u_offsets[regno];
+ }
+
+ return addr;
+}
+
+/*
+ * Registers saved in a coredump:
+ * gr0..gr31
+ * sr0..sr7
+ * iaoq0..iaoq1
+ * iasq0..iasq1
+ * sar, iir, isr, ior, ipsw
+ * cr0, cr24..cr31
+ * cr8,9,12,13
+ * cr10, cr15
+ */
+#define GR_REGNUM(_n) (HPPA_R0_REGNUM+_n)
+#define TR_REGNUM(_n) (HPPA_TR0_REGNUM+_n)
+static const int greg_map[] =
+ {
+ GR_REGNUM(0), GR_REGNUM(1), GR_REGNUM(2), GR_REGNUM(3),
+ GR_REGNUM(4), GR_REGNUM(5), GR_REGNUM(6), GR_REGNUM(7),
+ GR_REGNUM(8), GR_REGNUM(9), GR_REGNUM(10), GR_REGNUM(11),
+ GR_REGNUM(12), GR_REGNUM(13), GR_REGNUM(14), GR_REGNUM(15),
+ GR_REGNUM(16), GR_REGNUM(17), GR_REGNUM(18), GR_REGNUM(19),
+ GR_REGNUM(20), GR_REGNUM(21), GR_REGNUM(22), GR_REGNUM(23),
+ GR_REGNUM(24), GR_REGNUM(25), GR_REGNUM(26), GR_REGNUM(27),
+ GR_REGNUM(28), GR_REGNUM(29), GR_REGNUM(30), GR_REGNUM(31),
+
+ HPPA_SR4_REGNUM+1, HPPA_SR4_REGNUM+2, HPPA_SR4_REGNUM+3, HPPA_SR4_REGNUM+4,
+ HPPA_SR4_REGNUM, HPPA_SR4_REGNUM+5, HPPA_SR4_REGNUM+6, HPPA_SR4_REGNUM+7,
+
+ HPPA_PCOQ_HEAD_REGNUM, HPPA_PCOQ_TAIL_REGNUM,
+ HPPA_PCSQ_HEAD_REGNUM, HPPA_PCSQ_TAIL_REGNUM,
+
+ HPPA_SAR_REGNUM, HPPA_IIR_REGNUM, HPPA_ISR_REGNUM, HPPA_IOR_REGNUM,
+ HPPA_IPSW_REGNUM, HPPA_RCR_REGNUM,
+
+ TR_REGNUM(0), TR_REGNUM(1), TR_REGNUM(2), TR_REGNUM(3),
+ TR_REGNUM(4), TR_REGNUM(5), TR_REGNUM(6), TR_REGNUM(7),
+
+ HPPA_PID0_REGNUM, HPPA_PID1_REGNUM, HPPA_PID2_REGNUM, HPPA_PID3_REGNUM,
+ HPPA_CCR_REGNUM, HPPA_EIEM_REGNUM,
+ };
+
+
+
+/* Fetch one register. */
+
+static void
+fetch_register (int regno)
+{
+ int tid;
+ int val;
+
+ if (CANNOT_FETCH_REGISTER (regno))
+ {
+ regcache_raw_supply (current_regcache, regno, NULL);
+ return;
+ }
+
+ /* GNU/Linux LWP ID's are process ID's. */
+ tid = TIDGET (inferior_ptid);
+ if (tid == 0)
+ tid = PIDGET (inferior_ptid); /* Not a threaded program. */
+
+ errno = 0;
+ val = ptrace (PTRACE_PEEKUSER, tid, register_addr (regno, 0), 0);
+ if (errno != 0)
+ error ("Couldn't read register %s (#%d): %s.", REGISTER_NAME (regno),
+ regno, safe_strerror (errno));
+
+ regcache_raw_supply (current_regcache, regno, &val);
+}
+
+/* Store one register. */
+
+static void
+store_register (int regno)
+{
+ int tid;
+ int val;
+
+ if (CANNOT_STORE_REGISTER (regno))
+ return;
+
+ /* GNU/Linux LWP ID's are process ID's. */
+ tid = TIDGET (inferior_ptid);
+ if (tid == 0)
+ tid = PIDGET (inferior_ptid); /* Not a threaded program. */
+
+ errno = 0;
+ regcache_raw_collect (current_regcache, regno, &val);
+ ptrace (PTRACE_POKEUSER, tid, register_addr (regno, 0), val);
+ if (errno != 0)
+ error ("Couldn't write register %s (#%d): %s.", REGISTER_NAME (regno),
+ regno, safe_strerror (errno));
+}
+
+/* Fetch registers from the child process. Fetch all registers if
+ regno == -1, otherwise fetch all general registers or all floating
+ point registers depending upon the value of regno. */
+
+void
+fetch_inferior_registers (int regno)
+{
+ if (-1 == regno)
+ {
+ for (regno = 0; regno < NUM_REGS; regno++)
+ fetch_register (regno);
+ }
+ else
+ {
+ fetch_register (regno);
+ }
+}
+
+/* Store registers back into the inferior. Store all registers if
+ regno == -1, otherwise store all general registers or all floating
+ point registers depending upon the value of regno. */
+
+void
+store_inferior_registers (int regno)
+{
+ if (-1 == regno)
+ {
+ for (regno = 0; regno < NUM_REGS; regno++)
+ store_register (regno);
+ }
+ else
+ {
+ store_register (regno);
+ }
+}
+
+/* Fill GDB's register array with the general-purpose register values
+ in *gregsetp. */
+
+void
+supply_gregset (gdb_gregset_t *gregsetp)
+{
+ int i;
+ greg_t *regp = (elf_greg_t *) gregsetp;
+
+ for (i = 0; i < sizeof (greg_map) / sizeof (greg_map[0]); i++, regp++)
+ {
+ int regno = greg_map[i];
+ regcache_raw_supply (current_regcache, regno, regp);
+ }
+}
+
+/* Fill register regno (if it is a general-purpose register) in
+ *gregsetp with the appropriate value from GDB's register array.
+ If regno is -1, do this for all registers. */
+
+void
+fill_gregset (gdb_gregset_t *gregsetp, int regno)
+{
+ int i;
+
+ for (i = 0; i < sizeof (greg_map) / sizeof (greg_map[0]); i++)
+ {
+ int mregno = greg_map[i];
+
+ if (regno == -1 || regno == mregno)
+ {
+ regcache_raw_collect(current_regcache, mregno, &(*gregsetp)[i]);
+ }
+ }
+}
+
+/* Given a pointer to a floating point register set in /proc format
+ (fpregset_t *), unpack the register contents and supply them as gdb's
+ idea of the current floating point register values. */
+
+void
+supply_fpregset (gdb_fpregset_t *fpregsetp)
+{
+ int regi;
+ char *from;
+
+ for (regi = 0; regi <= 31; regi++)
+ {
+ from = (char *) &((*fpregsetp)[regi]);
+ regcache_raw_supply (current_regcache, 2*regi + HPPA_FP0_REGNUM, from);
+ regcache_raw_supply (current_regcache, 2*regi + HPPA_FP0_REGNUM + 1,
+ from + 4);
+ }
+}
+
+/* Given a pointer to a floating point register set in /proc format
+ (fpregset_t *), update the register specified by REGNO from gdb's idea
+ of the current floating point register set. If REGNO is -1, update
+ them all. */
+
+void
+fill_fpregset (gdb_fpregset_t *fpregsetp, int regno)
+{
+ int i;
+
+ for (i = HPPA_FP0_REGNUM; i < HPPA_FP0_REGNUM + 32 * 2; i++)
+ {
+ /* Gross. fpregset_t is double, registers[x] has single
+ precision reg. */
+ char *to = (char *) &((*fpregsetp)[(i - HPPA_FP0_REGNUM) / 2]);
+ if ((i - HPPA_FP0_REGNUM) & 1)
+ to += 4;
+ regcache_raw_collect (current_regcache, i, to);
+ }
+}
--- /dev/null
+/* Target-dependent code for GNU/Linux running on PA-RISC, for GDB.
+
+ Copyright 2004 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. */
+
+#include "defs.h"
+#include "gdbcore.h"
+#include "osabi.h"
+#include "target.h"
+#include "objfiles.h"
+#include "solib-svr4.h"
+#include "glibc-tdep.h"
+#include "frame-unwind.h"
+#include "trad-frame.h"
+#include "dwarf2-frame.h"
+#include "value.h"
+#include "hppa-tdep.h"
+
+#include "elf/common.h"
+
+#if 0
+/* Convert DWARF register number REG to the appropriate register
+ number used by GDB. */
+static int
+hppa_dwarf_reg_to_regnum (int reg)
+{
+ /* registers 0 - 31 are the same in both sets */
+ if (reg < 32)
+ return reg;
+
+ /* dwarf regs 32 to 85 are fpregs 4 - 31 */
+ if (reg >= 32 && reg <= 85)
+ return HPPA_FP4_REGNUM + (reg - 32);
+
+ warning ("Unmapped DWARF Register #%d encountered\n", reg);
+ return -1;
+}
+#endif
+
+static void
+hppa_linux_target_write_pc (CORE_ADDR v, ptid_t ptid)
+{
+ /* Probably this should be done by the kernel, but it isn't. */
+ write_register_pid (HPPA_PCOQ_HEAD_REGNUM, v | 0x3, ptid);
+ write_register_pid (HPPA_PCOQ_TAIL_REGNUM, (v + 4) | 0x3, ptid);
+}
+
+/* An instruction to match. */
+struct insn_pattern
+{
+ unsigned int data; /* See if it matches this.... */
+ unsigned int mask; /* ... with this mask. */
+};
+
+/* See bfd/elf32-hppa.c */
+static struct insn_pattern hppa_long_branch_stub[] = {
+ /* ldil LR'xxx,%r1 */
+ { 0x20200000, 0xffe00000 },
+ /* be,n RR'xxx(%sr4,%r1) */
+ { 0xe0202002, 0xffe02002 },
+ { 0, 0 }
+};
+
+static struct insn_pattern hppa_long_branch_pic_stub[] = {
+ /* b,l .+8, %r1 */
+ { 0xe8200000, 0xffe00000 },
+ /* addil LR'xxx - ($PIC_pcrel$0 - 4), %r1 */
+ { 0x28200000, 0xffe00000 },
+ /* be,n RR'xxxx - ($PIC_pcrel$0 - 8)(%sr4, %r1) */
+ { 0xe0202002, 0xffe02002 },
+ { 0, 0 }
+};
+
+static struct insn_pattern hppa_import_stub[] = {
+ /* addil LR'xxx, %dp */
+ { 0x2b600000, 0xffe00000 },
+ /* ldw RR'xxx(%r1), %r21 */
+ { 0x48350000, 0xffffb000 },
+ /* bv %r0(%r21) */
+ { 0xeaa0c000, 0xffffffff },
+ /* ldw RR'xxx+4(%r1), %r19 */
+ { 0x48330000, 0xffffb000 },
+ { 0, 0 }
+};
+
+static struct insn_pattern hppa_import_pic_stub[] = {
+ /* addil LR'xxx,%r19 */
+ { 0x2a600000, 0xffe00000 },
+ /* ldw RR'xxx(%r1),%r21 */
+ { 0x48350000, 0xffffb000 },
+ /* bv %r0(%r21) */
+ { 0xeaa0c000, 0xffffffff },
+ /* ldw RR'xxx+4(%r1),%r19 */
+ { 0x48330000, 0xffffb000 },
+ { 0, 0 },
+};
+
+static struct insn_pattern hppa_plt_stub[] = {
+ /* b,l 1b, %r20 - 1b is 3 insns before here */
+ { 0xea9f1fdd, 0xffffffff },
+ /* depi 0,31,2,%r20 */
+ { 0xd6801c1e, 0xffffffff },
+ { 0, 0 }
+};
+
+static struct insn_pattern hppa_sigtramp[] = {
+ /* ldi 0, %r25 or ldi 1, %r25 */
+ { 0x34190000, 0xfffffffd },
+ /* ldi __NR_rt_sigreturn, %r20 */
+ { 0x3414015a, 0xffffffff },
+ /* be,l 0x100(%sr2, %r0), %sr0, %r31 */
+ { 0xe4008200, 0xffffffff },
+ /* nop */
+ { 0x08000240, 0xffffffff },
+ { 0, 0 }
+};
+
+#define HPPA_MAX_INSN_PATTERN_LEN (4)
+
+/* Return non-zero if the instructions at PC match the series
+ described in PATTERN, or zero otherwise. PATTERN is an array of
+ 'struct insn_pattern' objects, terminated by an entry whose mask is
+ zero.
+
+ When the match is successful, fill INSN[i] with what PATTERN[i]
+ matched. */
+static int
+insns_match_pattern (CORE_ADDR pc,
+ struct insn_pattern *pattern,
+ unsigned int *insn)
+{
+ int i;
+ CORE_ADDR npc = pc;
+
+ for (i = 0; pattern[i].mask; i++)
+ {
+ char buf[4];
+
+ deprecated_read_memory_nobpt (npc, buf, 4);
+ insn[i] = extract_unsigned_integer (buf, 4);
+ if ((insn[i] & pattern[i].mask) == pattern[i].data)
+ npc += 4;
+ else
+ return 0;
+ }
+ return 1;
+}
+
+static int
+hppa_linux_in_dyncall (CORE_ADDR pc)
+{
+ return pc == hppa_symbol_address("$$dyncall");
+}
+
+/* There are several kinds of "trampolines" that we need to deal with:
+ - long branch stubs: these are inserted by the linker when a branch
+ target is too far away for a branch insn to reach
+ - plt stubs: these should go into the .plt section, so are easy to find
+ - import stubs: used to call from object to shared lib or shared lib to
+ shared lib; these go in regular text sections. In fact the linker tries
+ to put them throughout the code because branches have limited reachability.
+ We use the same mechanism as ppc64 to recognize the stub insn patterns.
+ - $$dyncall: similar to hpux, hppa-linux uses $$dyncall for indirect function
+ calls. $$dyncall is exported by libgcc.a */
+static int
+hppa_linux_in_solib_call_trampoline (CORE_ADDR pc, char *name)
+{
+ unsigned int insn[HPPA_MAX_INSN_PATTERN_LEN];
+ int r;
+
+ r = in_plt_section (pc, name)
+ || hppa_linux_in_dyncall (pc)
+ || insns_match_pattern (pc, hppa_import_stub, insn)
+ || insns_match_pattern (pc, hppa_import_pic_stub, insn)
+ || insns_match_pattern (pc, hppa_long_branch_stub, insn)
+ || insns_match_pattern (pc, hppa_long_branch_pic_stub, insn);
+
+ return r;
+}
+
+static CORE_ADDR
+hppa_linux_skip_trampoline_code (CORE_ADDR pc)
+{
+ unsigned int insn[HPPA_MAX_INSN_PATTERN_LEN];
+ int dp_rel, pic_rel;
+
+ /* dyncall handles both PLABELs and direct addresses */
+ if (hppa_linux_in_dyncall (pc))
+ {
+ pc = (CORE_ADDR) read_register (22);
+
+ /* PLABELs have bit 30 set; if it's a PLABEL, then dereference it */
+ if (pc & 0x2)
+ pc = (CORE_ADDR) read_memory_integer (pc & ~0x3, TARGET_PTR_BIT / 8);
+
+ return pc;
+ }
+
+ dp_rel = pic_rel = 0;
+ if ((dp_rel = insns_match_pattern (pc, hppa_import_stub, insn))
+ || (pic_rel = insns_match_pattern (pc, hppa_import_pic_stub, insn)))
+ {
+ /* Extract the target address from the addil/ldw sequence. */
+ pc = hppa_extract_21 (insn[0]) + hppa_extract_14 (insn[1]);
+
+ if (dp_rel)
+ pc += (CORE_ADDR) read_register (27);
+ else
+ pc += (CORE_ADDR) read_register (19);
+
+ /* fallthrough */
+ }
+
+ if (in_plt_section (pc, NULL))
+ {
+ pc = (CORE_ADDR) read_memory_integer (pc, TARGET_PTR_BIT / 8);
+
+ /* if the plt slot has not yet been resolved, the target will
+ be the plt stub */
+ if (in_plt_section (pc, NULL))
+ {
+ /* Sanity check: are we pointing to the plt stub? */
+ if (insns_match_pattern (pc, hppa_plt_stub, insn))
+ {
+ /* this should point to the fixup routine */
+ pc = (CORE_ADDR) read_memory_integer (pc + 8, TARGET_PTR_BIT / 8);
+ }
+ else
+ {
+ error ("Cannot resolve plt stub at 0x%s\n",
+ paddr_nz (pc));
+ pc = 0;
+ }
+ }
+ }
+
+ return pc;
+}
+
+/* Signal frames. */
+
+/* (This is derived from MD_FALLBACK_FRAME_STATE_FOR in gcc.)
+
+ Unfortunately, because of various bugs and changes to the kernel,
+ we have several cases to deal with.
+
+ In 2.4, the signal trampoline is 4 bytes, and pc should point directly at
+ the beginning of the trampoline and struct rt_sigframe.
+
+ In <= 2.6.5-rc2-pa3, the signal trampoline is 9 bytes, and pc points at
+ the 4th word in the trampoline structure. This is wrong, it should point
+ at the 5th word. This is fixed in 2.6.5-rc2-pa4.
+
+ To detect these cases, we first take pc, align it to 64-bytes
+ to get the beginning of the signal frame, and then check offsets 0, 4
+ and 5 to see if we found the beginning of the trampoline. This will
+ tell us how to locate the sigcontext structure.
+
+ Note that with a 2.4 64-bit kernel, the signal context is not properly
+ passed back to userspace so the unwind will not work correctly. */
+static CORE_ADDR
+hppa_linux_sigtramp_find_sigcontext (CORE_ADDR pc)
+{
+ unsigned int dummy[HPPA_MAX_INSN_PATTERN_LEN];
+ int offs = 0;
+ int try;
+ /* offsets to try to find the trampoline */
+ static int pcoffs[] = { 0, 4*4, 5*4 };
+ /* offsets to the rt_sigframe structure */
+ static int sfoffs[] = { 4*4, 10*4, 10*4 };
+ CORE_ADDR sp;
+
+ /* Most of the time, this will be correct. The one case when this will
+ fail is if the user defined an alternate stack, in which case the
+ beginning of the stack will not be align_down (pc, 64). */
+ sp = align_down (pc, 64);
+
+ /* rt_sigreturn trampoline:
+ 3419000x ldi 0, %r25 or ldi 1, %r25 (x = 0 or 2)
+ 3414015a ldi __NR_rt_sigreturn, %r20
+ e4008200 be,l 0x100(%sr2, %r0), %sr0, %r31
+ 08000240 nop */
+
+ for (try = 0; try < ARRAY_SIZE (pcoffs); try++)
+ {
+ if (insns_match_pattern (sp + pcoffs[try], hppa_sigtramp, dummy))
+ {
+ offs = sfoffs[try];
+ break;
+ }
+ }
+
+ if (offs == 0)
+ {
+ if (insns_match_pattern (pc, hppa_sigtramp, dummy))
+ {
+ /* sigaltstack case: we have no way of knowing which offset to
+ use in this case; default to new kernel handling. If this is
+ wrong the unwinding will fail. */
+ try = 2;
+ sp = pc - pcoffs[try];
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ /* sp + sfoffs[try] points to a struct rt_sigframe, which contains
+ a struct siginfo and a struct ucontext. struct ucontext contains
+ a struct sigcontext. Return an offset to this sigcontext here. Too
+ bad we cannot include system specific headers :-(.
+ sizeof(struct siginfo) == 128
+ offsetof(struct ucontext, uc_mcontext) == 24. */
+ return sp + sfoffs[try] + 128 + 24;
+}
+
+struct hppa_linux_sigtramp_unwind_cache
+{
+ CORE_ADDR base;
+ struct trad_frame_saved_reg *saved_regs;
+};
+
+static struct hppa_linux_sigtramp_unwind_cache *
+hppa_linux_sigtramp_frame_unwind_cache (struct frame_info *next_frame,
+ void **this_cache)
+{
+ struct gdbarch *gdbarch = get_frame_arch (next_frame);
+ struct hppa_linux_sigtramp_unwind_cache *info;
+ CORE_ADDR pc, scptr;
+ int i;
+
+ if (*this_cache)
+ return *this_cache;
+
+ info = FRAME_OBSTACK_ZALLOC (struct hppa_linux_sigtramp_unwind_cache);
+ *this_cache = info;
+ info->saved_regs = trad_frame_alloc_saved_regs (next_frame);
+
+ pc = frame_pc_unwind (next_frame);
+ scptr = hppa_linux_sigtramp_find_sigcontext (pc);
+
+ /* structure of struct sigcontext:
+
+ struct sigcontext {
+ unsigned long sc_flags;
+ unsigned long sc_gr[32];
+ unsigned long long sc_fr[32];
+ unsigned long sc_iasq[2];
+ unsigned long sc_iaoq[2];
+ unsigned long sc_sar; */
+
+ /* Skip sc_flags. */
+ scptr += 4;
+
+ /* GR[0] is the psw, we don't restore that. */
+ scptr += 4;
+
+ /* General registers. */
+ for (i = 1; i < 32; i++)
+ {
+ info->saved_regs[HPPA_R0_REGNUM + i].addr = scptr;
+ scptr += 4;
+ }
+
+ /* Pad. */
+ scptr += 4;
+
+ /* FP regs; FP0-3 are not restored. */
+ scptr += (8 * 4);
+
+ for (i = 4; i < 32; i++)
+ {
+ info->saved_regs[HPPA_FP0_REGNUM + (i * 2)].addr = scptr;
+ scptr += 4;
+ info->saved_regs[HPPA_FP0_REGNUM + (i * 2) + 1].addr = scptr;
+ scptr += 4;
+ }
+
+ /* IASQ/IAOQ. */
+ info->saved_regs[HPPA_PCSQ_HEAD_REGNUM].addr = scptr;
+ scptr += 4;
+ info->saved_regs[HPPA_PCSQ_TAIL_REGNUM].addr = scptr;
+ scptr += 4;
+
+ info->saved_regs[HPPA_PCOQ_HEAD_REGNUM].addr = scptr;
+ scptr += 4;
+ info->saved_regs[HPPA_PCOQ_TAIL_REGNUM].addr = scptr;
+ scptr += 4;
+
+ info->base = frame_unwind_register_unsigned (next_frame, HPPA_SP_REGNUM);
+
+ return info;
+}
+
+static void
+hppa_linux_sigtramp_frame_this_id (struct frame_info *next_frame,
+ void **this_prologue_cache,
+ struct frame_id *this_id)
+{
+ struct hppa_linux_sigtramp_unwind_cache *info
+ = hppa_linux_sigtramp_frame_unwind_cache (next_frame, this_prologue_cache);
+ *this_id = frame_id_build (info->base, frame_pc_unwind (next_frame));
+}
+
+static void
+hppa_linux_sigtramp_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, void *valuep)
+{
+ struct hppa_linux_sigtramp_unwind_cache *info
+ = hppa_linux_sigtramp_frame_unwind_cache (next_frame, this_prologue_cache);
+ hppa_frame_prev_register_helper (next_frame, info->saved_regs, regnum,
+ optimizedp, lvalp, addrp, realnump, valuep);
+}
+
+static const struct frame_unwind hppa_linux_sigtramp_frame_unwind = {
+ SIGTRAMP_FRAME,
+ hppa_linux_sigtramp_frame_this_id,
+ hppa_linux_sigtramp_frame_prev_register
+};
+
+/* hppa-linux always uses "new-style" rt-signals. The signal handler's return
+ address should point to a signal trampoline on the stack. The signal
+ trampoline is embedded in a rt_sigframe structure that is aligned on
+ the stack. We take advantage of the fact that sp must be 64-byte aligned,
+ and the trampoline is small, so by rounding down the trampoline address
+ we can find the beginning of the struct rt_sigframe. */
+static const struct frame_unwind *
+hppa_linux_sigtramp_unwind_sniffer (struct frame_info *next_frame)
+{
+ CORE_ADDR pc = frame_pc_unwind (next_frame);
+
+ if (hppa_linux_sigtramp_find_sigcontext (pc))
+ return &hppa_linux_sigtramp_frame_unwind;
+
+ return NULL;
+}
+
+/* Attempt to find (and return) the global pointer for the given
+ function.
+
+ This is a rather nasty bit of code searchs for the .dynamic section
+ in the objfile corresponding to the pc of the function we're trying
+ to call. Once it finds the addresses at which the .dynamic section
+ lives in the child process, it scans the Elf32_Dyn entries for a
+ DT_PLTGOT tag. If it finds one of these, the corresponding
+ d_un.d_ptr value is the global pointer. */
+
+static CORE_ADDR
+hppa_linux_find_global_pointer (struct value *function)
+{
+ struct obj_section *faddr_sect;
+ CORE_ADDR faddr;
+
+ faddr = value_as_address (function);
+
+ /* Is this a plabel? If so, dereference it to get the gp value. */
+ if (faddr & 2)
+ {
+ int status;
+ char buf[4];
+
+ faddr &= ~3;
+
+ status = target_read_memory (faddr + 4, buf, sizeof (buf));
+ if (status == 0)
+ return extract_unsigned_integer (buf, sizeof (buf));
+ }
+
+ /* If the address is in the plt section, then the real function hasn't
+ yet been fixed up by the linker so we cannot determine the gp of
+ that function. */
+ if (in_plt_section (faddr, NULL))
+ return 0;
+
+ faddr_sect = find_pc_section (faddr);
+ if (faddr_sect != NULL)
+ {
+ struct obj_section *osect;
+
+ ALL_OBJFILE_OSECTIONS (faddr_sect->objfile, osect)
+ {
+ if (strcmp (osect->the_bfd_section->name, ".dynamic") == 0)
+ break;
+ }
+
+ if (osect < faddr_sect->objfile->sections_end)
+ {
+ CORE_ADDR addr;
+
+ addr = osect->addr;
+ while (addr < osect->endaddr)
+ {
+ int status;
+ LONGEST tag;
+ char buf[4];
+
+ status = target_read_memory (addr, buf, sizeof (buf));
+ if (status != 0)
+ break;
+ tag = extract_signed_integer (buf, sizeof (buf));
+
+ if (tag == DT_PLTGOT)
+ {
+ CORE_ADDR global_pointer;
+
+ status = target_read_memory (addr + 4, buf, sizeof (buf));
+ if (status != 0)
+ break;
+ global_pointer = extract_unsigned_integer (buf, sizeof (buf));
+
+ /* The payoff... */
+ return global_pointer;
+ }
+
+ if (tag == DT_NULL)
+ break;
+
+ addr += 8;
+ }
+ }
+ }
+ return 0;
+}
+
+/* Forward declarations. */
+extern initialize_file_ftype _initialize_hppa_linux_tdep;
+
+static void
+hppa_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ /* GNU/Linux is always ELF. */
+ tdep->is_elf = 1;
+
+ tdep->find_global_pointer = hppa_linux_find_global_pointer;
+
+ set_gdbarch_write_pc (gdbarch, hppa_linux_target_write_pc);
+
+ frame_unwind_append_sniffer (gdbarch, hppa_linux_sigtramp_unwind_sniffer);
+
+ /* GNU/Linux uses SVR4-style shared libraries. */
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+
+ set_gdbarch_in_solib_call_trampoline
+ (gdbarch, hppa_linux_in_solib_call_trampoline);
+ set_gdbarch_skip_trampoline_code
+ (gdbarch, hppa_linux_skip_trampoline_code);
+
+ /* GNU/Linux uses the dynamic linker included in the GNU C Library. */
+ set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
+
+ /* On hppa-linux, currently, sizeof(long double) == 8. There has been
+ some discussions to support 128-bit long double, but it requires some
+ more work in gcc and glibc first. */
+ set_gdbarch_long_double_bit (gdbarch, 64);
+
+#if 0
+ /* Dwarf-2 unwinding support. Not yet working. */
+ set_gdbarch_dwarf_reg_to_regnum (gdbarch, hppa_dwarf_reg_to_regnum);
+ set_gdbarch_dwarf2_reg_to_regnum (gdbarch, hppa_dwarf_reg_to_regnum);
+ frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);
+ frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer);
+#endif
+}
+
+void
+_initialize_hppa_linux_tdep (void)
+{
+ gdbarch_register_osabi (bfd_arch_hppa, 0, GDB_OSABI_LINUX, hppa_linux_init_abi);
+}
--- /dev/null
+/* Native-dependent code for HP PA-RISC BSD's.
+
+ Copyright 2004 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. */
+
+#include "defs.h"
+#include "inferior.h"
+#include "regcache.h"
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+
+#include "hppa-tdep.h"
+
+static int
+hppabsd_gregset_supplies_p (int regnum)
+{
+ return (regnum >= HPPA_R0_REGNUM && regnum <= HPPA_PCOQ_TAIL_REGNUM);
+}
+
+/* Supply the general-purpose registers stored in GREGS to REGCACHE. */
+
+static void
+hppabsd_supply_gregset (struct regcache *regcache, const void *gregs)
+{
+ const char *regs = gregs;
+ int regnum;
+
+ for (regnum = HPPA_R1_REGNUM; regnum <= HPPA_R31_REGNUM; regnum++)
+ regcache_raw_supply (regcache, regnum, regs + regnum * 4);
+
+ regcache_raw_supply (regcache, HPPA_SAR_REGNUM, regs);
+ regcache_raw_supply (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 32 * 4);
+ regcache_raw_supply (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 33 * 4);
+}
+
+/* Collect the general-purpose registers from REGCACHE and store them
+ in GREGS. */
+
+static void
+hppabsd_collect_gregset (const struct regcache *regcache,
+ void *gregs, int regnum)
+{
+ char *regs = gregs;
+ int i;
+
+ for (i = HPPA_R1_REGNUM; i <= HPPA_R31_REGNUM; i++)
+ {
+ if (regnum == -1 || regnum == i)
+ regcache_raw_collect (regcache, i, regs + i * 4);
+ }
+
+ if (regnum == -1 || regnum == HPPA_SAR_REGNUM)
+ regcache_raw_collect (regcache, HPPA_SAR_REGNUM, regs);
+ if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM)
+ regcache_raw_collect (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 32 * 4);
+ if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM)
+ regcache_raw_collect (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 33 * 4);
+}
+\f
+
+/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
+ for all registers (including the floating-point registers). */
+
+void
+fetch_inferior_registers (int regnum)
+{
+ struct regcache *regcache = current_regcache;
+
+ if (regnum == -1 || hppabsd_gregset_supplies_p (regnum))
+ {
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name ("Couldn't get registers");
+
+ hppabsd_supply_gregset (regcache, ®s);
+ }
+}
+
+/* Store register REGNUM back into the inferior. If REGNUM is -1, do
+ this for all registers (including the floating-point registers). */
+
+void
+store_inferior_registers (int regnum)
+{
+ if (regnum == -1 || hppabsd_gregset_supplies_p (regnum))
+ {
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name ("Couldn't get registers");
+
+ hppabsd_collect_gregset (current_regcache, ®s, regnum);
+
+ if (ptrace (PT_SETREGS, PIDGET (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name ("Couldn't write registers");
+ }
+}
--- /dev/null
+/* Target-dependent code for HP PA-RISC BSD's.
+
+ Copyright 2004 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. */
+
+#include "defs.h"
+#include "arch-utils.h"
+#include "osabi.h"
+#include "regcache.h"
+#include "regset.h"
+
+#include "gdb_assert.h"
+#include "gdb_string.h"
+
+#include "hppa-tdep.h"
+#include "solib-svr4.h"
+
+/* Core file support. */
+
+/* Sizeof `struct reg' in <machine/reg.h>. */
+#define HPPABSD_SIZEOF_GREGS (34 * 4)
+
+/* Supply register REGNUM from the buffer specified by GREGS and LEN
+ in the general-purpose register set REGSET to register cache
+ REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
+
+static void
+hppabsd_supply_gregset (const struct regset *regset, struct regcache *regcache,
+ int regnum, const void *gregs, size_t len)
+{
+ const char *regs = gregs;
+ size_t offset;
+ int i;
+
+ gdb_assert (len >= HPPABSD_SIZEOF_GREGS);
+
+ for (i = HPPA_R1_REGNUM, offset = 4; i <= HPPA_R31_REGNUM; i++, offset += 4)
+ {
+ if (regnum == -1 || regnum == i)
+ regcache_raw_supply (regcache, i, regs + offset);
+ }
+
+ if (regnum == -1 || regnum == HPPA_SAR_REGNUM)
+ regcache_raw_supply (regcache, HPPA_SAR_REGNUM, regs);
+ if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM)
+ regcache_raw_supply (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 32 * 4);
+ if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM)
+ regcache_raw_supply (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 33 * 4);
+}
+
+/* OpenBSD/hppa register set. */
+
+static struct regset hppabsd_gregset =
+{
+ NULL,
+ hppabsd_supply_gregset
+};
+
+/* Return the appropriate register set for the core section identified
+ by SECT_NAME and SECT_SIZE. */
+
+static const struct regset *
+hppabsd_regset_from_core_section (struct gdbarch *gdbarch,
+ const char *sect_name, size_t sect_size)
+{
+ if (strcmp (sect_name, ".reg") == 0 && sect_size >= HPPABSD_SIZEOF_GREGS)
+ return &hppabsd_gregset;
+
+ return NULL;
+}
+\f
+
+static void
+hppabsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ /* Core file support. */
+ set_gdbarch_regset_from_core_section
+ (gdbarch, hppabsd_regset_from_core_section);
+
+ /* OpenBSD and NetBSD use ELF. */
+ tdep->is_elf = 1;
+
+ /* OpenBSD and NetBSD uses SVR4-style shared libraries. */
+ set_gdbarch_in_solib_call_trampoline
+ (gdbarch, generic_in_solib_call_trampoline);
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+}
+\f
+
+/* OpenBSD uses uses the traditional NetBSD core file format, even for
+ ports that use ELF. */
+#define GDB_OSABI_NETBSD_CORE GDB_OSABI_OPENBSD_ELF
+
+static enum gdb_osabi
+hppabsd_core_osabi_sniffer (bfd *abfd)
+{
+ if (strcmp (bfd_get_target (abfd), "netbsd-core") == 0)
+ return GDB_OSABI_NETBSD_CORE;
+
+ return GDB_OSABI_UNKNOWN;
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_hppabsd_tdep (void);
+
+void
+_initialize_hppabsd_tdep (void)
+{
+ /* BFD doesn't set a flavour for NetBSD style a.out core files. */
+ gdbarch_register_osabi_sniffer (bfd_arch_hppa, bfd_target_unknown_flavour,
+ hppabsd_core_osabi_sniffer);
+
+ gdbarch_register_osabi (bfd_arch_hppa, 0, GDB_OSABI_NETBSD_ELF,
+ hppabsd_init_abi);
+ gdbarch_register_osabi (bfd_arch_hppa, 0, GDB_OSABI_OPENBSD_ELF,
+ hppabsd_init_abi);
+}
--- /dev/null
+/* Native-dependent code for NetBSD/i386.
+
+ Copyright 2004 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. */
+
+#include "defs.h"
+#include "gdbcore.h"
+#include "regcache.h"
+
+#include "i386-tdep.h"
+
+/* Support for debugging kernel virtual memory images. */
+
+#include <sys/types.h>
+#include <machine/frame.h>
+#include <machine/pcb.h>
+
+#include "bsd-kvm.h"
+
+static int
+i386nbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
+{
+ struct switchframe sf;
+
+ /* The following is true for NetBSD 1.6.2:
+
+ The pcb contains %esp and %ebp at the point of the context switch
+ in cpu_switch(). At that point we have a stack frame as
+ described by `struct switchframe', which for NetBSD 1.6.2 has the
+ following layout:
+
+ interrupt level
+ %edi
+ %esi
+ %ebx
+ %eip
+
+ we reconstruct the register state as it would look when we just
+ returned from cpu_switch(). */
+
+ /* The stack pointer shouldn't be zero. */
+ if (pcb->pcb_esp == 0)
+ return 0;
+
+ read_memory (pcb->pcb_esp, (char *) &sf, sizeof sf);
+ pcb->pcb_esp += sizeof (struct switchframe);
+ regcache_raw_supply (regcache, I386_EDI_REGNUM, &sf.sf_edi);
+ regcache_raw_supply (regcache, I386_ESI_REGNUM, &sf.sf_esi);
+ regcache_raw_supply (regcache, I386_EBP_REGNUM, &pcb->pcb_ebp);
+ regcache_raw_supply (regcache, I386_ESP_REGNUM, &pcb->pcb_esp);
+ regcache_raw_supply (regcache, I386_EBX_REGNUM, &sf.sf_ebx);
+ regcache_raw_supply (regcache, I386_EIP_REGNUM, &sf.sf_eip);
+
+ return 1;
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_i386nbsd_nat (void);
+
+void
+_initialize_i386nbsd_nat (void)
+{
+ /* Support debugging kernel virtual memory images. */
+ bsd_kvm_add_target (i386nbsd_supply_pcb);
+}
--- /dev/null
+/* Default child (native) target interface, for GDB when running under
+ Unix.
+
+ Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
+ 1998, 1999, 2000, 2001, 2002, 2004 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. */
+
+#include "defs.h"
+#include "regcache.h"
+#include "memattr.h"
+#include "symtab.h"
+#include "target.h"
+#include "inferior.h"
+
+/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
+ for all registers. */
+
+static void
+inf_child_fetch_inferior_registers (int regnum)
+{
+ if (regnum == -1)
+ {
+ for (regnum = 0; regnum < NUM_REGS; regnum++)
+ regcache_raw_supply (current_regcache, regnum, NULL);
+ }
+ else
+ regcache_raw_supply (current_regcache, regnum, NULL);
+}
+
+/* Store register REGNUM back into the inferior. If REGNUM is -1, do
+ this for all registers (including the floating point registers). */
+
+static void
+inf_child_store_inferior_registers (int regnum)
+{
+}
+
+void
+inf_child_post_wait (ptid_t ptid, int wait_status)
+{
+ /* This version of Unix doesn't require a meaningful "post wait"
+ operation.
+ */
+}
+
+static void
+inf_child_post_attach (int pid)
+{
+ /* This version of Unix doesn't require a meaningful "post attach"
+ operation by a debugger. */
+}
+
+/* Get ready to modify the registers array. On machines which store
+ individual registers, this doesn't need to do anything. On
+ machines which store all the registers in one fell swoop, this
+ makes sure that registers contains all the registers from the
+ program being debugged. */
+
+static void
+inf_child_prepare_to_store (void)
+{
+}
+
+static void
+inf_child_open (char *arg, int from_tty)
+{
+ error ("Use the \"run\" command to start a Unix child process.");
+}
+
+static void
+inf_child_post_startup_inferior (ptid_t ptid)
+{
+ /* This version of Unix doesn't require a meaningful "post startup
+ inferior" operation by a debugger. */
+}
+
+static void
+inf_child_acknowledge_created_inferior (int pid)
+{
+ /* This version of Unix doesn't require a meaningful "acknowledge
+ created inferior" operation by a debugger. */
+}
+
+static int
+inf_child_insert_fork_catchpoint (int pid)
+{
+ /* This version of Unix doesn't support notification of fork
+ events. */
+ return 0;
+}
+
+static int
+inf_child_remove_fork_catchpoint (int pid)
+{
+ /* This version of Unix doesn't support notification of fork
+ events. */
+ return 0;
+}
+
+static int
+inf_child_insert_vfork_catchpoint (int pid)
+{
+ /* This version of Unix doesn't support notification of vfork
+ events. */
+ return 0;
+}
+
+static int
+inf_child_remove_vfork_catchpoint (int pid)
+{
+ /* This version of Unix doesn't support notification of vfork
+ events. */
+ return 0;
+}
+
+static int
+inf_child_follow_fork (int follow_child)
+{
+ /* This version of Unix doesn't support following fork or vfork
+ events. */
+ return 0;
+}
+
+static int
+inf_child_insert_exec_catchpoint (int pid)
+{
+ /* This version of Unix doesn't support notification of exec
+ events. */
+ return 0;
+}
+
+static int
+inf_child_remove_exec_catchpoint (int pid)
+{
+ /* This version of Unix doesn't support notification of exec
+ events. */
+ return 0;
+}
+
+static int
+inf_child_reported_exec_events_per_exec_call (void)
+{
+ /* This version of Unix doesn't support notification of exec
+ events. */
+ return 1;
+}
+
+static int
+inf_child_can_run (void)
+{
+ return 1;
+}
+
+static struct symtab_and_line *
+inf_child_enable_exception_callback (enum exception_event_kind kind,
+ int enable)
+{
+ return (struct symtab_and_line *) NULL;
+}
+
+static struct exception_event_record *
+inf_child_get_current_exception_event (void)
+{
+ return (struct exception_event_record *) NULL;
+}
+
+static char *
+inf_child_pid_to_exec_file (int pid)
+{
+ /* This version of Unix doesn't support translation of a process ID
+ to the filename of the executable file. */
+ return NULL;
+}
+
+static char *
+inf_child_core_file_to_sym_file (char *core)
+{
+ /* The target stratum for a running executable need not support this
+ operation. */
+ return NULL;
+}
+
+struct target_ops *
+inf_child_target (void)
+{
+ struct target_ops *t = XZALLOC (struct target_ops);
+ t->to_shortname = "child";
+ t->to_longname = "Unix child process";
+ t->to_doc = "Unix child process (started by the \"run\" command).";
+ t->to_open = inf_child_open;
+ t->to_post_attach = inf_child_post_attach;
+ t->to_post_wait = inf_child_post_wait;
+ t->to_prepare_to_store = inf_child_prepare_to_store;
+ t->to_insert_breakpoint = memory_insert_breakpoint;
+ t->to_remove_breakpoint = memory_remove_breakpoint;
+ t->to_terminal_init = terminal_init_inferior;
+ t->to_terminal_inferior = terminal_inferior;
+ t->to_terminal_ours_for_output = terminal_ours_for_output;
+ t->to_terminal_save_ours = terminal_save_ours;
+ t->to_terminal_ours = terminal_ours;
+ t->to_terminal_info = child_terminal_info;
+ t->to_post_startup_inferior = inf_child_post_startup_inferior;
+ t->to_acknowledge_created_inferior = inf_child_acknowledge_created_inferior;
+ t->to_insert_fork_catchpoint = inf_child_insert_fork_catchpoint;
+ t->to_remove_fork_catchpoint = inf_child_remove_fork_catchpoint;
+ t->to_insert_vfork_catchpoint = inf_child_insert_vfork_catchpoint;
+ t->to_remove_vfork_catchpoint = inf_child_remove_vfork_catchpoint;
+ t->to_follow_fork = inf_child_follow_fork;
+ t->to_insert_exec_catchpoint = inf_child_insert_exec_catchpoint;
+ t->to_remove_exec_catchpoint = inf_child_remove_exec_catchpoint;
+ t->to_reported_exec_events_per_exec_call =
+ inf_child_reported_exec_events_per_exec_call;
+ t->to_can_run = inf_child_can_run;
+ t->to_enable_exception_callback = inf_child_enable_exception_callback;
+ t->to_get_current_exception_event = inf_child_get_current_exception_event;
+ t->to_pid_to_exec_file = inf_child_pid_to_exec_file;
+ t->to_stratum = process_stratum;
+ t->to_has_all_memory = 1;
+ t->to_has_memory = 1;
+ t->to_has_stack = 1;
+ t->to_has_registers = 1;
+ t->to_has_execution = 1;
+ t->to_magic = OPS_MAGIC;
+ return t;
+}
--- /dev/null
+/* Low level Unix child interface, for GDB when running under Unix.
+
+ Copyright 2004 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. */
+
+#ifndef INF_CHILD_H
+#define INF_CHILD_H
+
+/* Create a prototype child target. The client can override it with
+ local methods. */
+
+extern struct target_ops *inf_child_target (void);
+
+#endif
--- /dev/null
+/* Low level Unix child interface to ptrace, for GDB when running under Unix.
+
+ Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
+ 1998, 1999, 2000, 2001, 2002, 2004 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. */
+
+#include "defs.h"
+#include "observer.h"
+#include "gdb_ptrace.h"
+#include "inflow.h"
+#include "inferior.h"
+#include "regcache.h"
+#include "command.h"
+#include "gdbcore.h"
+#include "inf-child.h"
+#include "gdbcmd.h"
+
+#include <sys/wait.h>
+#include <signal.h>
+
+/* HACK: Save the ptrace ops returned by ptrace_target. */
+static struct target_ops *ptrace_ops_hack;
+
+static void
+inf_ptrace_kill_inferior (void)
+{
+ int status;
+ int pid = PIDGET (inferior_ptid);
+
+ if (pid == 0)
+ return;
+
+ /* This once used to call "kill" to kill the inferior just in case
+ the inferior was still running. As others have noted in the past
+ (kingdon) there shouldn't be any way to get here if the inferior
+ is still running -- else there's a major problem elsewere in gdb
+ and it needs to be fixed.
+
+ The kill call causes problems under hpux10, so it's been removed;
+ if this causes problems we'll deal with them as they arise. */
+ call_ptrace (PT_KILL, pid, (PTRACE_TYPE_ARG3) 0, 0);
+ ptrace_wait (null_ptid, &status);
+ target_mourn_inferior ();
+}
+
+/* Resume execution of the inferior process. If STEP is nonzero,
+ single-step it. If SIGNAL is nonzero, give it that signal. */
+
+static void
+inf_ptrace_resume (ptid_t ptid, int step, enum target_signal signal)
+{
+ int request = PT_CONTINUE;
+ int pid = PIDGET (ptid);
+
+ if (pid == -1)
+ /* Resume all threads. */
+ /* I think this only gets used in the non-threaded case, where
+ "resume all threads" and "resume inferior_ptid" are the
+ same. */
+ pid = PIDGET (inferior_ptid);
+
+ if (step)
+ {
+ /* If this system does not support PT_STEP, a higher level
+ function will have called single_step() to transmute the step
+ request into a continue request (by setting breakpoints on
+ all possible successor instructions), so we don't have to
+ worry about that here. */
+ request = PT_STEP;
+ }
+
+ /* An address of (PTRACE_TYPE_ARG3)1 tells ptrace to continue from
+ where it was. If GDB wanted it to start some other way, we have
+ already written a new PC value to the child. */
+ errno = 0;
+ ptrace (request, pid, (PTRACE_TYPE_ARG3) 1, target_signal_to_host (signal));
+ if (errno != 0)
+ perror_with_name ("ptrace");
+}
+
+/* Set an upper limit on alloca. */
+#define GDB_MAX_ALLOCA 0x1000
+
+/* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
+ in the NEW_SUN_PTRACE case. It ought to be straightforward. But
+ it appears that writing did not write the data that I specified. I
+ cannot understand where it got the data that it actually did
+ write. */
+
+/* Copy LEN bytes to or from inferior's memory starting at MEMADDR to
+ debugger memory starting at MYADDR. Copy to inferior if WRITE is
+ nonzero. TARGET is ignored.
+
+ Returns the length copied, which is either the LEN argument or
+ zero. This xfer function does not do partial moves, since
+ ptrace_ops_hack doesn't allow memory operations to cross below us in the
+ target stack anyway. */
+
+int
+inf_ptrace_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
+ struct mem_attrib *attrib, struct target_ops *target)
+{
+ int i;
+ /* Round starting address down to longword boundary. */
+ CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_TYPE_RET);
+ /* Round ending address up; get number of longwords that makes. */
+ int count = ((((memaddr + len) - addr) + sizeof (PTRACE_TYPE_RET) - 1)
+ / sizeof (PTRACE_TYPE_RET));
+ int alloc = count * sizeof (PTRACE_TYPE_RET);
+ PTRACE_TYPE_RET *buffer;
+ struct cleanup *old_chain = NULL;
+
+#ifdef PT_IO
+ /* OpenBSD 3.1, NetBSD 1.6 and FreeBSD 5.0 have a new PT_IO request
+ that promises to be much more efficient in reading and writing
+ data in the traced process's address space. */
+
+ {
+ struct ptrace_io_desc piod;
+
+ /* NOTE: We assume that there are no distinct address spaces for
+ instruction and data. */
+ piod.piod_op = write ? PIOD_WRITE_D : PIOD_READ_D;
+ piod.piod_offs = (void *) memaddr;
+ piod.piod_addr = myaddr;
+ piod.piod_len = len;
+
+ if (ptrace (PT_IO, PIDGET (inferior_ptid), (caddr_t) & piod, 0) == -1)
+ {
+ /* If the PT_IO request is somehow not supported, fallback on
+ using PT_WRITE_D/PT_READ_D. Otherwise we will return zero
+ to indicate failure. */
+ if (errno != EINVAL)
+ return 0;
+ }
+ else
+ {
+ /* Return the actual number of bytes read or written. */
+ return piod.piod_len;
+ }
+ }
+#endif
+
+ /* Allocate buffer of that many longwords. */
+ if (len < GDB_MAX_ALLOCA)
+ {
+ buffer = (PTRACE_TYPE_RET *) alloca (alloc);
+ }
+ else
+ {
+ buffer = (PTRACE_TYPE_RET *) xmalloc (alloc);
+ old_chain = make_cleanup (xfree, buffer);
+ }
+
+ if (write)
+ {
+ /* Fill start and end extra bytes of buffer with existing memory
+ data. */
+ if (addr != memaddr || len < (int) sizeof (PTRACE_TYPE_RET))
+ {
+ /* Need part of initial word -- fetch it. */
+ buffer[0] = ptrace (PT_READ_I, PIDGET (inferior_ptid),
+ (PTRACE_TYPE_ARG3) addr, 0);
+ }
+
+ if (count > 1) /* FIXME, avoid if even boundary. */
+ {
+ buffer[count - 1] =
+ ptrace (PT_READ_I, PIDGET (inferior_ptid),
+ ((PTRACE_TYPE_ARG3)
+ (addr + (count - 1) * sizeof (PTRACE_TYPE_RET))), 0);
+ }
+
+ /* Copy data to be written over corresponding part of buffer. */
+ memcpy ((char *) buffer + (memaddr & (sizeof (PTRACE_TYPE_RET) - 1)),
+ myaddr, len);
+
+ /* Write the entire buffer. */
+ for (i = 0; i < count; i++, addr += sizeof (PTRACE_TYPE_RET))
+ {
+ errno = 0;
+ ptrace (PT_WRITE_D, PIDGET (inferior_ptid),
+ (PTRACE_TYPE_ARG3) addr, buffer[i]);
+ if (errno)
+ {
+ /* Using the appropriate one (I or D) is necessary for
+ Gould NP1, at least. */
+ errno = 0;
+ ptrace (PT_WRITE_I, PIDGET (inferior_ptid),
+ (PTRACE_TYPE_ARG3) addr, buffer[i]);
+ }
+ if (errno)
+ return 0;
+ }
+ }
+ else
+ {
+ /* Read all the longwords. */
+ for (i = 0; i < count; i++, addr += sizeof (PTRACE_TYPE_RET))
+ {
+ errno = 0;
+ buffer[i] = ptrace (PT_READ_I, PIDGET (inferior_ptid),
+ (PTRACE_TYPE_ARG3) addr, 0);
+ if (errno)
+ return 0;
+ QUIT;
+ }
+
+ /* Copy appropriate bytes out of the buffer. */
+ memcpy (myaddr,
+ (char *) buffer + (memaddr & (sizeof (PTRACE_TYPE_RET) - 1)),
+ len);
+ }
+
+ if (old_chain != NULL)
+ do_cleanups (old_chain);
+ return len;
+}
+
+/* Wait for child to do something. Return pid of child, or -1 in case
+ of error; store status through argument pointer OURSTATUS. */
+
+static ptid_t
+inf_ptrace_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
+{
+ int save_errno;
+ int status;
+ char *execd_pathname = NULL;
+ int exit_status;
+ int related_pid;
+ int syscall_id;
+ enum target_waitkind kind;
+ int pid;
+
+ do
+ {
+ set_sigint_trap (); /* Causes SIGINT to be passed on to the
+ attached process. */
+ set_sigio_trap ();
+
+ pid = ptrace_wait (inferior_ptid, &status);
+
+ save_errno = errno;
+
+ clear_sigio_trap ();
+
+ clear_sigint_trap ();
+
+ if (pid == -1)
+ {
+ if (save_errno == EINTR)
+ continue;
+
+ fprintf_unfiltered (gdb_stderr,
+ "Child process unexpectedly missing: %s.\n",
+ safe_strerror (save_errno));
+
+ /* Claim it exited with unknown signal. */
+ ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
+ ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
+ return pid_to_ptid (-1);
+ }
+
+ /* Did it exit?
+ */
+ if (target_has_exited (pid, status, &exit_status))
+ {
+ /* ??rehrauer: For now, ignore this. */
+ continue;
+ }
+
+ if (!target_thread_alive (pid_to_ptid (pid)))
+ {
+ ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
+ return pid_to_ptid (pid);
+ }
+ }
+ while (pid != PIDGET (inferior_ptid)); /* Some other child died or stopped */
+
+ store_waitstatus (ourstatus, status);
+ return pid_to_ptid (pid);
+}
+
+void
+inf_ptrace_post_wait (ptid_t ptid, int wait_status)
+{
+ /* This version of Unix doesn't require a meaningful "post wait"
+ operation.
+ */
+}
+
+/* Check to see if the given thread is alive.
+
+ FIXME: Is kill() ever the right way to do this? I doubt it, but
+ for now we're going to try and be compatable with the old thread
+ code. */
+
+static int
+inf_ptrace_thread_alive (ptid_t ptid)
+{
+ pid_t pid = PIDGET (ptid);
+
+ return (kill (pid, 0) != -1);
+}
+
+/* Attach to process PID, then initialize for debugging it. */
+
+static void
+inf_ptrace_attach (char *args, int from_tty)
+{
+ char *exec_file;
+ int pid;
+ char *dummy;
+
+ if (!args)
+ error_no_arg ("process-id to attach");
+
+ dummy = args;
+ pid = strtol (args, &dummy, 0);
+ /* Some targets don't set errno on errors, grrr! */
+ if ((pid == 0) && (args == dummy))
+ error ("Illegal process-id: %s\n", args);
+
+ if (pid == getpid ()) /* Trying to masturbate? */
+ error ("I refuse to debug myself!");
+
+ if (from_tty)
+ {
+ exec_file = (char *) get_exec_file (0);
+
+ if (exec_file)
+ printf_unfiltered ("Attaching to program: %s, %s\n", exec_file,
+ target_pid_to_str (pid_to_ptid (pid)));
+ else
+ printf_unfiltered ("Attaching to %s\n",
+ target_pid_to_str (pid_to_ptid (pid)));
+
+ gdb_flush (gdb_stdout);
+ }
+
+ attach (pid);
+
+ inferior_ptid = pid_to_ptid (pid);
+ push_target (ptrace_ops_hack);
+}
+
+static void
+inf_ptrace_post_attach (int pid)
+{
+ /* This version of Unix doesn't require a meaningful "post attach"
+ operation by a debugger. */
+}
+
+/* Take a program previously attached to and detaches it. The program
+ resumes execution and will no longer stop on signals, etc. We'd
+ better not have left any breakpoints in the program or it'll die
+ when it hits one. For this to work, it may be necessary for the
+ process to have been previously attached. It *might* work if the
+ program was started via the normal ptrace (PTRACE_TRACEME). */
+
+static void
+inf_ptrace_detach (char *args, int from_tty)
+{
+ int siggnal = 0;
+ int pid = PIDGET (inferior_ptid);
+
+ if (from_tty)
+ {
+ char *exec_file = get_exec_file (0);
+ if (exec_file == 0)
+ exec_file = "";
+ printf_unfiltered ("Detaching from program: %s, %s\n", exec_file,
+ target_pid_to_str (pid_to_ptid (pid)));
+ gdb_flush (gdb_stdout);
+ }
+ if (args)
+ siggnal = atoi (args);
+
+ detach (siggnal);
+
+ inferior_ptid = null_ptid;
+ unpush_target (ptrace_ops_hack);
+}
+
+/* Get ready to modify the registers array. On machines which store
+ individual registers, this doesn't need to do anything. On
+ machines which store all the registers in one fell swoop, this
+ makes sure that registers contains all the registers from the
+ program being debugged. */
+
+static void
+inf_ptrace_prepare_to_store (void)
+{
+}
+
+/* Print status information about what we're accessing. */
+
+static void
+inf_ptrace_files_info (struct target_ops *ignore)
+{
+ printf_unfiltered ("\tUsing the running image of %s %s.\n",
+ attach_flag ? "attached" : "child",
+ target_pid_to_str (inferior_ptid));
+}
+
+static void
+inf_ptrace_open (char *arg, int from_tty)
+{
+ error ("Use the \"run\" command to start a Unix child process.");
+}
+
+/* Stub function which causes the inferior that runs it, to be ptrace-able
+ by its parent process. */
+
+static void
+inf_ptrace_me (void)
+{
+ /* "Trace me, Dr. Memory!" */
+ call_ptrace (0, 0, (PTRACE_TYPE_ARG3) 0, 0);
+}
+
+/* Stub function which causes the GDB that runs it, to start ptrace-ing
+ the child process. */
+
+static void
+inf_ptrace_him (int pid)
+{
+ push_target (ptrace_ops_hack);
+
+ /* On some targets, there must be some explicit synchronization
+ between the parent and child processes after the debugger
+ forks, and before the child execs the debuggee program. This
+ call basically gives permission for the child to exec.
+ */
+
+ target_acknowledge_created_inferior (pid);
+
+ /* START_INFERIOR_TRAPS_EXPECTED is defined in inferior.h,
+ * and will be 1 or 2 depending on whether we're starting
+ * without or with a shell.
+ */
+ startup_inferior (START_INFERIOR_TRAPS_EXPECTED);
+
+ /* On some targets, there must be some explicit actions taken after
+ the inferior has been started up.
+ */
+ target_post_startup_inferior (pid_to_ptid (pid));
+}
+
+/* Start an inferior Unix child process and sets inferior_ptid to its
+ pid. EXEC_FILE is the file to run. ALLARGS is a string containing
+ the arguments to the program. ENV is the environment vector to
+ pass. Errors reported with error(). */
+
+static void
+inf_ptrace_create_inferior (char *exec_file, char *allargs, char **env,
+ int from_tty)
+{
+ fork_inferior (exec_file, allargs, env, inf_ptrace_me, inf_ptrace_him,
+ NULL, NULL);
+ /* We are at the first instruction we care about. */
+ observer_notify_inferior_created (¤t_target, from_tty);
+ /* Pedal to the metal... */
+ proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
+}
+
+static void
+inf_ptrace_post_startup_inferior (ptid_t ptid)
+{
+ /* This version of Unix doesn't require a meaningful "post startup inferior"
+ operation by a debugger.
+ */
+}
+
+static void
+inf_ptrace_acknowledge_created_inferior (int pid)
+{
+ /* This version of Unix doesn't require a meaningful "acknowledge created inferior"
+ operation by a debugger.
+ */
+}
+
+static int
+inf_ptrace_insert_fork_catchpoint (int pid)
+{
+ /* This version of Unix doesn't support notification of fork events. */
+ return 0;
+}
+
+static int
+inf_ptrace_remove_fork_catchpoint (int pid)
+{
+ /* This version of Unix doesn't support notification of fork events. */
+ return 0;
+}
+
+static int
+inf_ptrace_insert_vfork_catchpoint (int pid)
+{
+ /* This version of Unix doesn't support notification of vfork events. */
+ return 0;
+}
+
+static int
+inf_ptrace_remove_vfork_catchpoint (int pid)
+{
+ /* This version of Unix doesn't support notification of vfork events. */
+ return 0;
+}
+
+static int
+inf_ptrace_follow_fork (int follow_child)
+{
+ /* This version of Unix doesn't support following fork or vfork events. */
+ return 0;
+}
+
+static int
+inf_ptrace_insert_exec_catchpoint (int pid)
+{
+ /* This version of Unix doesn't support notification of exec events. */
+ return 0;
+}
+
+static int
+inf_ptrace_remove_exec_catchpoint (int pid)
+{
+ /* This version of Unix doesn't support notification of exec events. */
+ return 0;
+}
+
+static int
+inf_ptrace_reported_exec_events_per_exec_call (void)
+{
+ /* This version of Unix doesn't support notification of exec events.
+ */
+ return 1;
+}
+
+static int
+inf_ptrace_has_exited (int pid, int wait_status, int *exit_status)
+{
+ if (WIFEXITED (wait_status))
+ {
+ *exit_status = WEXITSTATUS (wait_status);
+ return 1;
+ }
+
+ if (WIFSIGNALED (wait_status))
+ {
+ *exit_status = 0; /* ?? Don't know what else to say here. */
+ return 1;
+ }
+
+ /* ?? Do we really need to consult the event state, too? Assume the
+ wait_state alone suffices.
+ */
+ return 0;
+}
+
+static void
+inf_ptrace_mourn_inferior (void)
+{
+ unpush_target (ptrace_ops_hack);
+ generic_mourn_inferior ();
+}
+
+static int
+inf_ptrace_can_run (void)
+{
+ return 1;
+}
+
+/* Send a SIGINT to the process group. This acts just like the user
+ typed a ^C on the controlling terminal.
+
+ XXX - This may not be correct for all systems. Some may want to
+ use killpg() instead of kill (-pgrp). */
+
+static void
+inf_ptrace_stop (void)
+{
+ kill (-inferior_process_group, SIGINT);
+}
+
+/* Perform a partial transfer to/from the specified object. For
+ memory transfers, fall back to the old memory xfer functions. */
+
+static LONGEST
+inf_ptrace_xfer_partial (struct target_ops *ops, enum target_object object,
+ const char *annex, void *readbuf,
+ const void *writebuf, ULONGEST offset, LONGEST len)
+{
+ switch (object)
+ {
+ case TARGET_OBJECT_MEMORY:
+ if (readbuf)
+ return inf_ptrace_xfer_memory (offset, readbuf, len, 0 /*write */ ,
+ NULL, ops);
+ if (writebuf)
+ return inf_ptrace_xfer_memory (offset, readbuf, len, 1 /*write */ ,
+ NULL, ops);
+ return -1;
+
+ case TARGET_OBJECT_UNWIND_TABLE:
+ return -1;
+
+ case TARGET_OBJECT_AUXV:
+ return -1;
+
+ case TARGET_OBJECT_WCOOKIE:
+ return -1;
+
+ default:
+ return -1;
+ }
+}
+
+static char *
+inf_ptrace_pid_to_str (ptid_t ptid)
+{
+ return normal_pid_to_str (ptid);
+}
+
+struct target_ops *
+inf_ptrace_target (void)
+{
+ struct target_ops *t = inf_child_target ();
+ t->to_open = inf_ptrace_open;
+ t->to_attach = inf_ptrace_attach;
+ t->to_post_attach = inf_ptrace_post_attach;
+ t->to_detach = inf_ptrace_detach;
+ t->to_resume = inf_ptrace_resume;
+ t->to_wait = inf_ptrace_wait;
+ t->to_post_wait = inf_ptrace_post_wait;
+ t->to_prepare_to_store = inf_ptrace_prepare_to_store;
+ t->to_xfer_memory = inf_ptrace_xfer_memory;
+ t->to_xfer_partial = inf_ptrace_xfer_partial;
+ t->to_files_info = inf_ptrace_files_info;
+ t->to_kill = inf_ptrace_kill_inferior;
+ t->to_create_inferior = inf_ptrace_create_inferior;
+ t->to_post_startup_inferior = inf_ptrace_post_startup_inferior;
+ t->to_acknowledge_created_inferior =
+ inf_ptrace_acknowledge_created_inferior;
+ t->to_insert_fork_catchpoint = inf_ptrace_insert_fork_catchpoint;
+ t->to_remove_fork_catchpoint = inf_ptrace_remove_fork_catchpoint;
+ t->to_insert_vfork_catchpoint = inf_ptrace_insert_vfork_catchpoint;
+ t->to_remove_vfork_catchpoint = inf_ptrace_remove_vfork_catchpoint;
+ t->to_follow_fork = inf_ptrace_follow_fork;
+ t->to_insert_exec_catchpoint = inf_ptrace_insert_exec_catchpoint;
+ t->to_remove_exec_catchpoint = inf_ptrace_remove_exec_catchpoint;
+ t->to_reported_exec_events_per_exec_call =
+ inf_ptrace_reported_exec_events_per_exec_call;
+ t->to_has_exited = inf_ptrace_has_exited;
+ t->to_mourn_inferior = inf_ptrace_mourn_inferior;
+ t->to_can_run = inf_ptrace_can_run;
+ t->to_thread_alive = inf_ptrace_thread_alive;
+ t->to_pid_to_str = inf_ptrace_pid_to_str;
+ t->to_stop = inf_ptrace_stop;
+ t->to_stratum = process_stratum;
+ t->to_has_all_memory = 1;
+ t->to_has_memory = 1;
+ t->to_has_stack = 1;
+ t->to_has_registers = 1;
+ t->to_has_execution = 1;
+ t->to_magic = OPS_MAGIC;
+ ptrace_ops_hack = t;
+ return t;
+}
--- /dev/null
+/* Low level Unix child interface to ptrace, for GDB when running
+ under Unix.
+
+ Copyright 2004 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. */
+
+#ifndef INF_PTRACE_H
+#define INF_PTRACE_H
+
+/* Create a prototype ptrace target. The client can override it with
+ local methods. */
+
+extern struct target_ops *inf_ptrace_target (void);
+
+#endif
--- /dev/null
+/* Native-dependent code for Motorola 68000 BSD's.
+
+ Copyright 2004 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. */
+
+#include "defs.h"
+#include "gdbcore.h"
+#include "inferior.h"
+#include "regcache.h"
+
+#include "gdb_assert.h"
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+
+#include "m68k-tdep.h"
+
+static int
+m68kbsd_gregset_supplies_p (int regnum)
+{
+ return (regnum >= M68K_D0_REGNUM && regnum <= M68K_PC_REGNUM);
+}
+
+static int
+m68kbsd_fpregset_supplies_p (int regnum)
+{
+ return (regnum >= M68K_FP0_REGNUM && regnum <= M68K_FPI_REGNUM);
+}
+
+/* Supply the general-purpose registers stored in GREGS to REGCACHE. */
+
+static void
+m68kbsd_supply_gregset (struct regcache *regcache, const void *gregs)
+{
+ const char *regs = gregs;
+ int regnum;
+
+ for (regnum = M68K_D0_REGNUM; regnum <= M68K_PC_REGNUM; regnum++)
+ regcache_raw_supply (regcache, regnum, regs + regnum * 4);
+}
+
+/* Supply the floating-point registers stored in FPREGS to REGCACHE. */
+
+static void
+m68kbsd_supply_fpregset (struct regcache *regcache, const void *fpregs)
+{
+ const char *regs = fpregs;
+ int regnum;
+
+ for (regnum = M68K_FP0_REGNUM; regnum <= M68K_FPI_REGNUM; regnum++)
+ regcache_raw_supply (regcache, regnum,
+ regs + m68kbsd_fpreg_offset (regnum));
+}
+
+/* Collect the general-purpose registers from REGCACHE and store them
+ in GREGS. */
+
+static void
+m68kbsd_collect_gregset (const struct regcache *regcache,
+ void *gregs, int regnum)
+{
+ char *regs = gregs;
+ int i;
+
+ for (i = M68K_D0_REGNUM; i <= M68K_PC_REGNUM; i++)
+ {
+ if (regnum == -1 || regnum == i)
+ regcache_raw_collect (regcache, i, regs + i * 4);
+ }
+}
+
+/* Collect the floating-point registers from REGCACHE and store them
+ in FPREGS. */
+
+static void
+m68kbsd_collect_fpregset (struct regcache *regcache,
+ void *fpregs, int regnum)
+{
+ char *regs = fpregs;
+ int i;
+
+ for (i = M68K_FP0_REGNUM; i <= M68K_FPI_REGNUM; i++)
+ {
+ if (regnum == -1 || regnum == i)
+ regcache_raw_collect (regcache, i, regs + m68kbsd_fpreg_offset (i));
+ }
+}
+\f
+
+/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
+ for all registers (including the floating-point registers). */
+
+void
+fetch_inferior_registers (int regnum)
+{
+ if (regnum == -1 || m68kbsd_gregset_supplies_p (regnum))
+ {
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name ("Couldn't get registers");
+
+ m68kbsd_supply_gregset (current_regcache, ®s);
+ }
+
+ if (regnum == -1 || m68kbsd_fpregset_supplies_p (regnum))
+ {
+ struct fpreg fpregs;
+
+ if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+ perror_with_name ("Couldn't get floating point status");
+
+ m68kbsd_supply_fpregset (current_regcache, &fpregs);
+ }
+}
+
+/* Store register REGNUM back into the inferior. If REGNUM is -1, do
+ this for all registers (including the floating-point registers). */
+
+void
+store_inferior_registers (int regnum)
+{
+ if (regnum == -1 || m68kbsd_gregset_supplies_p (regnum))
+ {
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name ("Couldn't get registers");
+
+ m68kbsd_collect_gregset (current_regcache, ®s, regnum);
+
+ if (ptrace (PT_SETREGS, PIDGET (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name ("Couldn't write registers");
+ }
+
+ if (regnum == -1 || m68kbsd_fpregset_supplies_p (regnum))
+ {
+ struct fpreg fpregs;
+
+ if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+ perror_with_name ("Couldn't get floating point status");
+
+ m68kbsd_collect_fpregset (current_regcache, &fpregs, regnum);
+
+ if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+ perror_with_name ("Couldn't write floating point status");
+ }
+}
+\f
+
+/* Support for debugging kernel virtual memory images. */
+
+#include <sys/types.h>
+#include <machine/pcb.h>
+
+#include "bsd-kvm.h"
+
+/* OpenBSD doesn't have these. */
+#ifndef PCB_REGS_FP
+#define PCB_REGS_FP 10
+#endif
+#ifndef PCB_REGS_SP
+#define PCB_REGS_SP 11
+#endif
+
+static int
+m68kbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
+{
+ int regnum, tmp;
+ int i = 0;
+
+ /* The following is true for NetBSD 1.6.2:
+
+ The pcb contains %d2...%d7, %a2...%a7 and %ps. This accounts for
+ all callee-saved registers. From this information we reconstruct
+ the register state as it would look when we just returned from
+ cpu_switch(). */
+
+ /* The stack pointer shouldn't be zero. */
+ if (pcb->pcb_regs[PCB_REGS_SP] == 0)
+ return 0;
+
+ for (regnum = M68K_D2_REGNUM; regnum <= M68K_D7_REGNUM; regnum++)
+ regcache_raw_supply (regcache, regnum, &pcb->pcb_regs[i++]);
+ for (regnum = M68K_A2_REGNUM; regnum <= M68K_SP_REGNUM; regnum++)
+ regcache_raw_supply (regcache, regnum, &pcb->pcb_regs[i++]);
+
+ tmp = pcb->pcb_ps & 0xffff;
+ regcache_raw_supply (regcache, M68K_PS_REGNUM, &tmp);
+
+ read_memory (pcb->pcb_regs[PCB_REGS_FP] + 4, (char *) &tmp, sizeof tmp);
+ regcache_raw_supply (regcache, M68K_PC_REGNUM, &tmp);
+
+ return 1;
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_m68kbsd_nat (void);
+
+void
+_initialize_m68kbsd_nat (void)
+{
+ /* Support debugging kernel virtual memory images. */
+ bsd_kvm_add_target (m68kbsd_supply_pcb);
+}
--- /dev/null
+/* Target-dependent code for Motorola 68000 BSD's.
+
+ Copyright 2004 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. */
+
+#include "defs.h"
+#include "arch-utils.h"
+#include "osabi.h"
+#include "regcache.h"
+#include "regset.h"
+
+#include "gdb_assert.h"
+#include "gdb_string.h"
+
+#include "m68k-tdep.h"
+#include "solib-svr4.h"
+
+/* Core file support. */
+
+/* Sizeof `struct reg' in <machine/reg.h>. */
+#define M68KBSD_SIZEOF_GREGS (18 * 4)
+
+/* Sizeof `struct fpreg' in <machine/reg.h. */
+#define M68KBSD_SIZEOF_FPREGS (((8 * 3) + 3) * 4)
+
+int
+m68kbsd_fpreg_offset (int regnum)
+{
+ if (regnum >= M68K_FPC_REGNUM)
+ return 8 * 12 + (regnum - M68K_FPC_REGNUM) * 4;
+
+ return (regnum - M68K_FP0_REGNUM) * 12;
+}
+
+/* Supply register REGNUM from the buffer specified by FPREGS and LEN
+ in the floating-point register set REGSET to register cache
+ REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
+
+static void
+m68kbsd_supply_fpregset (const struct regset *regset,
+ struct regcache *regcache,
+ int regnum, const void *fpregs, size_t len)
+{
+ const char *regs = fpregs;
+ int i;
+
+ gdb_assert (len >= M68KBSD_SIZEOF_FPREGS);
+
+ for (i = M68K_FP0_REGNUM; i <= M68K_PC_REGNUM; i++)
+ {
+ if (regnum == i || regnum == -1)
+ regcache_raw_supply (regcache, i, regs + m68kbsd_fpreg_offset (i));
+ }
+}
+
+/* Supply register REGNUM from the buffer specified by GREGS and LEN
+ in the general-purpose register set REGSET to register cache
+ REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
+
+static void
+m68kbsd_supply_gregset (const struct regset *regset,
+ struct regcache *regcache,
+ int regnum, const void *gregs, size_t len)
+{
+ const char *regs = gregs;
+ int i;
+
+ gdb_assert (len >= M68KBSD_SIZEOF_GREGS);
+
+ for (i = M68K_D0_REGNUM; i <= M68K_PC_REGNUM; i++)
+ {
+ if (regnum == i || regnum == -1)
+ regcache_raw_supply (regcache, i, regs + i * 4);
+ }
+
+ if (len >= M68KBSD_SIZEOF_GREGS + M68KBSD_SIZEOF_FPREGS)
+ {
+ regs += M68KBSD_SIZEOF_GREGS;
+ len -= M68KBSD_SIZEOF_GREGS;
+ m68kbsd_supply_fpregset (regset, regcache, regnum, regs, len);
+ }
+}
+
+/* Motorola 68000 register sets. */
+
+static struct regset m68kbsd_gregset =
+{
+ NULL,
+ m68kbsd_supply_gregset
+};
+
+static struct regset m68kbsd_fpregset =
+{
+ NULL,
+ m68kbsd_supply_fpregset
+};
+
+/* Return the appropriate register set for the core section identified
+ by SECT_NAME and SECT_SIZE. */
+
+static const struct regset *
+m68kbsd_regset_from_core_section (struct gdbarch *gdbarch,
+ const char *sect_name, size_t sect_size)
+{
+ if (strcmp (sect_name, ".reg") == 0 && sect_size >= M68KBSD_SIZEOF_GREGS)
+ return &m68kbsd_gregset;
+
+ if (strcmp (sect_name, ".reg2") == 0 && sect_size >= M68KBSD_SIZEOF_FPREGS)
+ return &m68kbsd_fpregset;
+
+ return NULL;
+}
+\f
+
+/* Support for shared libraries. */
+
+/* Return non-zero if we are in a shared library trampoline code stub. */
+
+int
+m68kbsd_aout_in_solib_call_trampoline (CORE_ADDR pc, char *name)
+{
+ return (name && !strcmp (name, "_DYNAMIC"));
+}
+\f
+
+static void
+m68kbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ tdep->jb_pc = 5;
+ tdep->jb_elt_size = 4;
+
+ set_gdbarch_regset_from_core_section
+ (gdbarch, m68kbsd_regset_from_core_section);
+}
+
+/* OpenBSD and NetBSD a.out. */
+
+static void
+m68kbsd_aout_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ m68kbsd_init_abi (info, gdbarch);
+
+ tdep->struct_return = reg_struct_return;
+
+ /* Assume SunOS-style shared libraries. */
+ set_gdbarch_in_solib_call_trampoline
+ (gdbarch, m68kbsd_aout_in_solib_call_trampoline);
+}
+
+/* NetBSD ELF. */
+
+static void
+m68kbsd_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ m68kbsd_init_abi (info, gdbarch);
+
+ /* NetBSD ELF uses the SVR4 ABI. */
+ m68k_svr4_init_abi (info, gdbarch);
+ tdep->struct_return = pcc_struct_return;
+
+ /* NetBSD ELF uses SVR4-style shared libraries. */
+ set_gdbarch_in_solib_call_trampoline
+ (gdbarch, generic_in_solib_call_trampoline);
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+}
+\f
+
+static enum gdb_osabi
+m68kbsd_aout_osabi_sniffer (bfd *abfd)
+{
+ if (strcmp (bfd_get_target (abfd), "a.out-m68k-netbsd") == 0
+ || strcmp (bfd_get_target (abfd), "a.out-m68k4k-netbsd") == 0)
+ return GDB_OSABI_NETBSD_AOUT;
+
+ return GDB_OSABI_UNKNOWN;
+}
+
+static enum gdb_osabi
+m68kbsd_core_osabi_sniffer (bfd *abfd)
+{
+ if (strcmp (bfd_get_target (abfd), "netbsd-core") == 0)
+ return GDB_OSABI_NETBSD_AOUT;
+
+ return GDB_OSABI_UNKNOWN;
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_m68kbsd_tdep (void);
+
+void
+_initialize_m68kbsd_tdep (void)
+{
+ gdbarch_register_osabi_sniffer (bfd_arch_m68k, bfd_target_aout_flavour,
+ m68kbsd_aout_osabi_sniffer);
+
+ /* BFD doesn't set a flavour for NetBSD style a.out core files. */
+ gdbarch_register_osabi_sniffer (bfd_arch_m68k, bfd_target_unknown_flavour,
+ m68kbsd_core_osabi_sniffer);
+
+ gdbarch_register_osabi (bfd_arch_m68k, 0, GDB_OSABI_NETBSD_AOUT,
+ m68kbsd_aout_init_abi);
+ gdbarch_register_osabi (bfd_arch_m68k, 0, GDB_OSABI_NETBSD_ELF,
+ m68kbsd_elf_init_abi);
+}
--- /dev/null
+/* Target-dependent code for the Motorola 88000 series.
+
+ Copyright 2004 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. */
+
+#include "defs.h"
+#include "arch-utils.h"
+#include "dis-asm.h"
+#include "frame.h"
+#include "frame-base.h"
+#include "frame-unwind.h"
+#include "gdbcore.h"
+#include "gdbtypes.h"
+#include "regcache.h"
+#include "regset.h"
+#include "symtab.h"
+#include "trad-frame.h"
+#include "value.h"
+
+#include "gdb_assert.h"
+#include "gdb_string.h"
+
+#include "m88k-tdep.h"
+
+/* Fetch the instruction at PC. */
+
+static unsigned long
+m88k_fetch_instruction (CORE_ADDR pc)
+{
+ return read_memory_unsigned_integer (pc, 4);
+}
+
+/* Register information. */
+
+/* Return the name of register REGNUM. */
+
+static const char *
+m88k_register_name (int regnum)
+{
+ static char *register_names[] =
+ {
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+ "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
+ "epsr", "fpsr", "fpcr", "sxip", "snip", "sfip"
+ };
+
+ if (regnum >= 0 && regnum < ARRAY_SIZE (register_names))
+ return register_names[regnum];
+
+ return NULL;
+}
+
+/* Return the GDB type object for the "standard" data type of data in
+ register REGNUM. */
+
+static struct type *
+m88k_register_type (struct gdbarch *gdbarch, int regnum)
+{
+ /* SXIP, SNIP, SFIP and R1 contain code addresses. */
+ if ((regnum >= M88K_SXIP_REGNUM && regnum <= M88K_SFIP_REGNUM)
+ || regnum == M88K_R1_REGNUM)
+ return builtin_type_void_func_ptr;
+
+ /* R30 and R31 typically contains data addresses. */
+ if (regnum == M88K_R30_REGNUM || regnum == M88K_R31_REGNUM)
+ return builtin_type_void_data_ptr;
+
+ return builtin_type_int32;
+}
+\f
+
+static CORE_ADDR
+m88k_addr_bits_remove (CORE_ADDR addr)
+{
+ /* All instructures are 4-byte aligned. The lower 2 bits of SXIP,
+ SNIP and SFIP are used for special purposes: bit 0 is the
+ exception bit and bit 1 is the valid bit. */
+ return addr & ~0x3;
+}
+
+/* Use the program counter to determine the contents and size of a
+ breakpoint instruction. Return a pointer to a string of bytes that
+ encode a breakpoint instruction, store the length of the string in
+ *LEN and optionally adjust *PC to point to the correct memory
+ location for inserting the breakpoint. */
+
+static const unsigned char *
+m88k_breakpoint_from_pc (CORE_ADDR *pc, int *len)
+{
+ /* tb 0,r0,511 */
+ static unsigned char break_insn[] = { 0xf0, 0x00, 0xd1, 0xff };
+
+ *len = sizeof (break_insn);
+ return break_insn;
+}
+
+static CORE_ADDR
+m88k_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
+{
+ CORE_ADDR pc;
+
+ pc = frame_unwind_register_unsigned (next_frame, M88K_SXIP_REGNUM);
+ return m88k_addr_bits_remove (pc);
+}
+
+static void
+m88k_write_pc (CORE_ADDR pc, ptid_t ptid)
+{
+ /* According to the MC88100 RISC Microprocessor User's Manual,
+ section 6.4.3.1.2:
+
+ "... can be made to return to a particular instruction by placing
+ a valid instruction address in the SNIP and the next sequential
+ instruction address in the SFIP (with V bits set and E bits
+ clear). The rte resumes execution at the instruction pointed to
+ by the SNIP, then the SFIP."
+
+ The E bit is the least significant bit (bit 0). The V (valid)
+ bit is bit 1. This is why we logical or 2 into the values we are
+ writing below. It turns out that SXIP plays no role when
+ returning from an exception so nothing special has to be done
+ with it. We could even (presumably) give it a totally bogus
+ value. */
+
+ write_register_pid (M88K_SXIP_REGNUM, pc, ptid);
+ write_register_pid (M88K_SNIP_REGNUM, pc | 2, ptid);
+ write_register_pid (M88K_SFIP_REGNUM, (pc + 4) | 2, ptid);
+}
+\f
+
+/* The functions on this page are intended to be used to classify
+ function arguments. */
+
+/* Check whether TYPE is "Integral or Pointer". */
+
+static int
+m88k_integral_or_pointer_p (const struct type *type)
+{
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_INT:
+ case TYPE_CODE_BOOL:
+ case TYPE_CODE_CHAR:
+ case TYPE_CODE_ENUM:
+ case TYPE_CODE_RANGE:
+ {
+ /* We have byte, half-word, word and extended-word/doubleword
+ integral types. */
+ int len = TYPE_LENGTH (type);
+ return (len == 1 || len == 2 || len == 4 || len == 8);
+ }
+ return 1;
+ case TYPE_CODE_PTR:
+ case TYPE_CODE_REF:
+ {
+ /* Allow only 32-bit pointers. */
+ return (TYPE_LENGTH (type) == 4);
+ }
+ return 1;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+/* Check whether TYPE is "Floating". */
+
+static int
+m88k_floating_p (const struct type *type)
+{
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_FLT:
+ {
+ int len = TYPE_LENGTH (type);
+ return (len == 4 || len == 8);
+ }
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+/* Check whether TYPE is "Structure or Union". */
+
+static int
+m88k_structure_or_union_p (const struct type *type)
+{
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_STRUCT:
+ case TYPE_CODE_UNION:
+ return 1;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+/* Check whether TYPE has 8-byte alignment. */
+
+static int
+m88k_8_byte_align_p (struct type *type)
+{
+ if (m88k_structure_or_union_p (type))
+ {
+ int i;
+
+ for (i = 0; i < TYPE_NFIELDS (type); i++)
+ {
+ struct type *subtype = check_typedef (TYPE_FIELD_TYPE (type, i));
+
+ if (m88k_8_byte_align_p (subtype))
+ return 1;
+ }
+ }
+
+ if (m88k_integral_or_pointer_p (type) || m88k_floating_p (type))
+ return (TYPE_LENGTH (type) == 8);
+
+ return 0;
+}
+
+/* Check whether TYPE can be passed in a register. */
+
+static int
+m88k_in_register_p (struct type *type)
+{
+ if (m88k_integral_or_pointer_p (type) || m88k_floating_p (type))
+ return 1;
+
+ if (m88k_structure_or_union_p (type) && TYPE_LENGTH (type) == 4)
+ return 1;
+
+ return 0;
+}
+
+static CORE_ADDR
+m88k_store_arguments (struct regcache *regcache, int nargs,
+ struct value **args, CORE_ADDR sp)
+{
+ int num_register_words = 0;
+ int num_stack_words = 0;
+ int i;
+
+ for (i = 0; i < nargs; i++)
+ {
+ struct type *type = VALUE_TYPE (args[i]);
+ int len = TYPE_LENGTH (type);
+
+ if (m88k_integral_or_pointer_p (type) && len < 4)
+ {
+ args[i] = value_cast (builtin_type_int32, args[i]);
+ type = VALUE_TYPE (args[i]);
+ len = TYPE_LENGTH (type);
+ }
+
+ if (m88k_in_register_p (type))
+ {
+ int num_words = 0;
+
+ if (num_register_words % 2 == 1 && m88k_8_byte_align_p (type))
+ num_words++;
+
+ num_words += ((len + 3) / 4);
+ if (num_register_words + num_words <= 8)
+ {
+ num_register_words += num_words;
+ continue;
+ }
+
+ /* We've run out of available registers. Pass the argument
+ on the stack. */
+ }
+
+ if (num_stack_words % 2 == 1 && m88k_8_byte_align_p (type))
+ num_stack_words++;
+
+ num_stack_words += ((len + 3) / 4);
+ }
+
+ /* Allocate stack space. */
+ sp = align_down (sp - 32 - num_stack_words * 4, 16);
+ num_stack_words = num_register_words = 0;
+
+ for (i = 0; i < nargs; i++)
+ {
+ char *valbuf = VALUE_CONTENTS (args[i]);
+ struct type *type = VALUE_TYPE (args[i]);
+ int len = TYPE_LENGTH (type);
+ int stack_word = num_stack_words;
+
+ if (m88k_in_register_p (type))
+ {
+ int register_word = num_register_words;
+
+ if (register_word % 2 == 1 && m88k_8_byte_align_p (type))
+ register_word++;
+
+ gdb_assert (len == 4 || len == 8);
+
+ if (register_word + len / 8 < 8)
+ {
+ int regnum = M88K_R2_REGNUM + register_word;
+
+ regcache_raw_write (regcache, regnum, valbuf);
+ if (len > 4)
+ regcache_raw_write (regcache, regnum + 1, valbuf + 4);
+
+ num_register_words = (register_word + len / 4);
+ continue;
+ }
+ }
+
+ if (stack_word % 2 == -1 && m88k_8_byte_align_p (type))
+ stack_word++;
+
+ write_memory (sp + stack_word * 4, valbuf, len);
+ num_stack_words = (stack_word + (len + 3) / 4);
+ }
+
+ return sp;
+}
+
+static CORE_ADDR
+m88k_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)
+{
+ /* Set up the function arguments. */
+ sp = m88k_store_arguments (regcache, nargs, args, sp);
+ gdb_assert (sp % 16 == 0);
+
+ /* Store return value address. */
+ if (struct_return)
+ regcache_raw_write_unsigned (regcache, M88K_R12_REGNUM, struct_addr);
+
+ /* Store the stack pointer and return address in the appropriate
+ registers. */
+ regcache_raw_write_unsigned (regcache, M88K_R31_REGNUM, sp);
+ regcache_raw_write_unsigned (regcache, M88K_R1_REGNUM, bp_addr);
+
+ /* Return the stack pointer. */
+ return sp;
+}
+
+static struct frame_id
+m88k_unwind_dummy_id (struct gdbarch *arch, struct frame_info *next_frame)
+{
+ CORE_ADDR sp;
+
+ sp = frame_unwind_register_unsigned (next_frame, M88K_R31_REGNUM);
+ return frame_id_build (sp, frame_pc_unwind (next_frame));
+}
+\f
+
+/* Determine, for architecture GDBARCH, how a return value of TYPE
+ should be returned. If it is supposed to be returned in registers,
+ and READBUF is non-zero, read the appropriate value from REGCACHE,
+ and copy it into READBUF. If WRITEBUF is non-zero, write the value
+ from WRITEBUF into REGCACHE. */
+
+static enum return_value_convention
+m88k_return_value (struct gdbarch *gdbarch, struct type *type,
+ struct regcache *regcache, void *readbuf,
+ const void *writebuf)
+{
+ int len = TYPE_LENGTH (type);
+ char buf[8];
+
+ if (!m88k_integral_or_pointer_p (type) && !m88k_floating_p (type))
+ return RETURN_VALUE_STRUCT_CONVENTION;
+
+ if (readbuf)
+ {
+ /* Read the contents of R2 and (if necessary) R3. */
+ regcache_cooked_read (regcache, M88K_R2_REGNUM, buf);
+ if (len > 4)
+ {
+ regcache_cooked_read (regcache, M88K_R3_REGNUM, buf + 4);
+ gdb_assert (len == 8);
+ memcpy (readbuf, buf, len);
+ }
+ else
+ {
+ /* Just stripping off any unused bytes should preserve the
+ signed-ness just fine. */
+ memcpy (readbuf, buf + 4 - len, len);
+ }
+ }
+
+ if (writebuf)
+ {
+ /* Read the contents to R2 and (if necessary) R3. */
+ if (len > 4)
+ {
+ gdb_assert (len == 8);
+ memcpy (buf, writebuf, 8);
+ regcache_cooked_write (regcache, M88K_R3_REGNUM, buf + 4);
+ }
+ else
+ {
+ /* ??? Do we need to do any sign-extension here? */
+ memcpy (buf + 4 - len, writebuf, len);
+ }
+ regcache_cooked_write (regcache, M88K_R2_REGNUM, buf);
+ }
+
+ return RETURN_VALUE_REGISTER_CONVENTION;
+}
+\f
+/* Default frame unwinder. */
+
+struct m88k_frame_cache
+{
+ /* Base address. */
+ CORE_ADDR base;
+ CORE_ADDR pc;
+
+ int sp_offset;
+ int fp_offset;
+
+ /* Table of saved registers. */
+ struct trad_frame_saved_reg *saved_regs;
+};
+
+/* Prologue analysis. */
+
+/* Macros for extracting fields from instructions. */
+
+#define BITMASK(pos, width) (((0x1 << (width)) - 1) << (pos))
+#define EXTRACT_FIELD(val, pos, width) ((val) >> (pos) & BITMASK (0, width))
+#define SUBU_OFFSET(x) ((unsigned)(x & 0xFFFF))
+#define ST_OFFSET(x) ((unsigned)((x) & 0xFFFF))
+#define ST_SRC(x) EXTRACT_FIELD ((x), 21, 5)
+#define ADDU_OFFSET(x) ((unsigned)(x & 0xFFFF))
+
+/* Possible actions to be taken by the prologue analyzer for the
+ instructions it encounters. */
+
+enum m88k_prologue_insn_action
+{
+ M88K_PIA_SKIP, /* Ignore. */
+ M88K_PIA_NOTE_ST, /* Note register store. */
+ M88K_PIA_NOTE_STD, /* Note register pair store. */
+ M88K_PIA_NOTE_SP_ADJUSTMENT, /* Note stack pointer adjustment. */
+ M88K_PIA_NOTE_FP_ASSIGNMENT, /* Note frame pointer assignment. */
+ M88K_PIA_NOTE_BRANCH, /* Note branch. */
+ M88K_PIA_NOTE_PROLOGUE_END /* Note end of prologue. */
+};
+
+/* Table of instructions that may comprise a function prologue. */
+
+struct m88k_prologue_insn
+{
+ unsigned long insn;
+ unsigned long mask;
+ enum m88k_prologue_insn_action action;
+};
+
+struct m88k_prologue_insn m88k_prologue_insn_table[] =
+{
+ /* Various register move instructions. */
+ { 0x58000000, 0xf800ffff, M88K_PIA_SKIP }, /* or/or.u with immed of 0 */
+ { 0xf4005800, 0xfc1fffe0, M88K_PIA_SKIP }, /* or rd,r0,rs */
+ { 0xf4005800, 0xfc00ffff, M88K_PIA_SKIP }, /* or rd,rs,r0 */
+
+ /* Various other instructions. */
+ { 0x58000000, 0xf8000000, M88K_PIA_SKIP }, /* or/or.u */
+
+ /* Stack pointer setup: "subu sp,sp,n" where n is a multiple of 8. */
+ { 0x67ff0000, 0xffff0007, M88K_PIA_NOTE_SP_ADJUSTMENT },
+
+ /* Frame pointer assignment: "addu r30,r31,n". */
+ { 0x63df0000, 0xffff0000, M88K_PIA_NOTE_FP_ASSIGNMENT },
+
+ /* Store to stack instructions; either "st rx,sp,n" or "st.d rx,sp,n". */
+ { 0x241f0000, 0xfc1f0000, M88K_PIA_NOTE_ST }, /* st rx,sp,n */
+ { 0x201f0000, 0xfc1f0000, M88K_PIA_NOTE_STD }, /* st.d rs,sp,n */
+
+ /* Instructions needed for setting up r25 for pic code. */
+ { 0x5f200000, 0xffff0000, M88K_PIA_SKIP }, /* or.u r25,r0,offset_high */
+ { 0xcc000002, 0xffffffff, M88K_PIA_SKIP }, /* bsr.n Lab */
+ { 0x5b390000, 0xffff0000, M88K_PIA_SKIP }, /* or r25,r25,offset_low */
+ { 0xf7396001, 0xffffffff, M88K_PIA_SKIP }, /* Lab: addu r25,r25,r1 */
+
+ /* Various branch or jump instructions which have a delay slot --
+ these do not form part of the prologue, but the instruction in
+ the delay slot might be a store instruction which should be
+ noted. */
+ { 0xc4000000, 0xe4000000, M88K_PIA_NOTE_BRANCH },
+ /* br.n, bsr.n, bb0.n, or bb1.n */
+ { 0xec000000, 0xfc000000, M88K_PIA_NOTE_BRANCH }, /* bcnd.n */
+ { 0xf400c400, 0xfffff7e0, M88K_PIA_NOTE_BRANCH }, /* jmp.n or jsr.n */
+
+ /* Catch all. Ends prologue analysis. */
+ { 0x00000000, 0x00000000, M88K_PIA_NOTE_PROLOGUE_END }
+};
+
+/* Do a full analysis of the function prologue at PC and update CACHE
+ accordingly. Bail out early if LIMIT is reached. Return the
+ address where the analysis stopped. If LIMIT points beyond the
+ function prologue, the return address should be the end of the
+ prologue. */
+
+static CORE_ADDR
+m88k_analyze_prologue (CORE_ADDR pc, CORE_ADDR limit,
+ struct m88k_frame_cache *cache)
+{
+ CORE_ADDR end = limit;
+
+ /* Provide a dummy cache if necessary. */
+ if (cache == NULL)
+ {
+ size_t sizeof_saved_regs =
+ (M88K_R31_REGNUM + 1) * sizeof (struct trad_frame_saved_reg);
+
+ cache = alloca (sizeof (struct m88k_frame_cache));
+ cache->saved_regs = alloca (sizeof_saved_regs);
+
+ /* We only initialize the members we care about. */
+ cache->saved_regs[M88K_R1_REGNUM].addr = -1;
+ cache->fp_offset = -1;
+ }
+
+ while (pc < limit)
+ {
+ struct m88k_prologue_insn *pi = m88k_prologue_insn_table;
+ unsigned long insn = m88k_fetch_instruction (pc);
+
+ while ((insn & pi->mask) != pi->insn)
+ pi++;
+
+ switch (pi->action)
+ {
+ case M88K_PIA_SKIP:
+ /* If we have a frame pointer, and R1 has been saved,
+ consider this instruction as not being part of the
+ prologue. */
+ if (cache->fp_offset != -1
+ && cache->saved_regs[M88K_R1_REGNUM].addr != -1)
+ return min (pc, end);
+ break;
+
+ case M88K_PIA_NOTE_ST:
+ case M88K_PIA_NOTE_STD:
+ /* If no frame has been allocated, the stores aren't part of
+ the prologue. */
+ if (cache->sp_offset == 0)
+ return min (pc, end);
+
+ /* Record location of saved registers. */
+ {
+ int regnum = ST_SRC (insn) + M88K_R0_REGNUM;
+ ULONGEST offset = ST_OFFSET (insn);
+
+ cache->saved_regs[regnum].addr = offset;
+ if (pi->action == M88K_PIA_NOTE_STD && regnum < M88K_R31_REGNUM)
+ cache->saved_regs[regnum + 1].addr = offset + 4;
+ }
+ break;
+
+ case M88K_PIA_NOTE_SP_ADJUSTMENT:
+ /* A second stack pointer adjustment isn't part of the
+ prologue. */
+ if (cache->sp_offset != 0)
+ return min (pc, end);
+
+ /* Store stack pointer adjustment. */
+ cache->sp_offset = -SUBU_OFFSET (insn);
+ break;
+
+ case M88K_PIA_NOTE_FP_ASSIGNMENT:
+ /* A second frame pointer assignment isn't part of the
+ prologue. */
+ if (cache->fp_offset != -1)
+ return min (pc, end);
+
+ /* Record frame pointer assignment. */
+ cache->fp_offset = ADDU_OFFSET (insn);
+ break;
+
+ case M88K_PIA_NOTE_BRANCH:
+ /* The branch instruction isn't part of the prologue, but
+ the instruction in the delay slot might be. Limit the
+ prologue analysis to the delay slot and record the branch
+ instruction as the end of the prologue. */
+ limit = min (limit, pc + 2 * M88K_INSN_SIZE);
+ end = pc;
+ break;
+
+ case M88K_PIA_NOTE_PROLOGUE_END:
+ return min (pc, end);
+ }
+
+ pc += M88K_INSN_SIZE;
+ }
+
+ return end;
+}
+
+/* An upper limit to the size of the prologue. */
+const int m88k_max_prologue_size = 128 * M88K_INSN_SIZE;
+
+/* Return the address of first real instruction of the function
+ starting at PC. */
+
+static CORE_ADDR
+m88k_skip_prologue (CORE_ADDR pc)
+{
+ struct symtab_and_line sal;
+ CORE_ADDR func_start, func_end;
+
+ /* This is the preferred method, find the end of the prologue by
+ using the debugging information. */
+ if (find_pc_partial_function (pc, NULL, &func_start, &func_end))
+ {
+ sal = find_pc_line (func_start, 0);
+
+ if (sal.end < func_end && pc <= sal.end)
+ return sal.end;
+ }
+
+ return m88k_analyze_prologue (pc, pc + m88k_max_prologue_size, NULL);
+}
+
+struct m88k_frame_cache *
+m88k_frame_cache (struct frame_info *next_frame, void **this_cache)
+{
+ struct m88k_frame_cache *cache;
+ CORE_ADDR frame_sp;
+
+ if (*this_cache)
+ return *this_cache;
+
+ cache = FRAME_OBSTACK_ZALLOC (struct m88k_frame_cache);
+ cache->saved_regs = trad_frame_alloc_saved_regs (next_frame);
+ cache->fp_offset = -1;
+
+ cache->pc = frame_func_unwind (next_frame);
+ if (cache->pc != 0)
+ {
+ CORE_ADDR addr_in_block = frame_unwind_address_in_block (next_frame);
+ m88k_analyze_prologue (cache->pc, addr_in_block, cache);
+ }
+
+ /* Calculate the stack pointer used in the prologue. */
+ if (cache->fp_offset != -1)
+ {
+ CORE_ADDR fp;
+
+ fp = frame_unwind_register_unsigned (next_frame, M88K_R30_REGNUM);
+ frame_sp = fp - cache->fp_offset;
+ }
+ else
+ {
+ /* If we know where the return address is saved, we can take a
+ solid guess at what the frame pointer should be. */
+ if (cache->saved_regs[M88K_R1_REGNUM].addr != -1)
+ cache->fp_offset = cache->saved_regs[M88K_R1_REGNUM].addr - 4;
+ frame_sp = frame_unwind_register_unsigned (next_frame, M88K_R31_REGNUM);
+ }
+
+ /* Now that we know the stack pointer, adjust the location of the
+ saved registers. */
+ {
+ int regnum;
+
+ for (regnum = M88K_R0_REGNUM; regnum < M88K_R31_REGNUM; regnum ++)
+ if (cache->saved_regs[regnum].addr != -1)
+ cache->saved_regs[regnum].addr += frame_sp;
+ }
+
+ /* Calculate the frame's base. */
+ cache->base = frame_sp - cache->sp_offset;
+ trad_frame_set_value (cache->saved_regs, M88K_R31_REGNUM, cache->base);
+
+ /* Identify SXIP with the return address in R1. */
+ cache->saved_regs[M88K_SXIP_REGNUM] = cache->saved_regs[M88K_R1_REGNUM];
+
+ *this_cache = cache;
+ return cache;
+}
+
+static void
+m88k_frame_this_id (struct frame_info *next_frame, void **this_cache,
+ struct frame_id *this_id)
+{
+ struct m88k_frame_cache *cache = m88k_frame_cache (next_frame, this_cache);
+
+ /* This marks the outermost frame. */
+ if (cache->base == 0)
+ return;
+
+ (*this_id) = frame_id_build (cache->base, cache->pc);
+}
+
+static void
+m88k_frame_prev_register (struct frame_info *next_frame, void **this_cache,
+ int regnum, int *optimizedp,
+ enum lval_type *lvalp, CORE_ADDR *addrp,
+ int *realnump, void *valuep)
+{
+ struct m88k_frame_cache *cache = m88k_frame_cache (next_frame, this_cache);
+
+ if (regnum == M88K_SNIP_REGNUM || regnum == M88K_SFIP_REGNUM)
+ {
+ if (valuep)
+ {
+ CORE_ADDR pc;
+
+ trad_frame_get_prev_register (next_frame, cache->saved_regs,
+ M88K_SXIP_REGNUM, optimizedp,
+ lvalp, addrp, realnump, valuep);
+
+ pc = extract_unsigned_integer (valuep, 4);
+ if (regnum == M88K_SFIP_REGNUM)
+ pc += 4;
+ store_unsigned_integer (valuep, 4, pc + 4);
+ }
+
+ /* It's a computed value. */
+ *optimizedp = 0;
+ *lvalp = not_lval;
+ *addrp = 0;
+ *realnump = -1;
+ return;
+ }
+
+ trad_frame_get_prev_register (next_frame, cache->saved_regs, regnum,
+ optimizedp, lvalp, addrp, realnump, valuep);
+}
+
+static const struct frame_unwind m88k_frame_unwind =
+{
+ NORMAL_FRAME,
+ m88k_frame_this_id,
+ m88k_frame_prev_register
+};
+
+static const struct frame_unwind *
+m88k_frame_sniffer (struct frame_info *next_frame)
+{
+ return &m88k_frame_unwind;
+}
+\f
+
+static CORE_ADDR
+m88k_frame_base_address (struct frame_info *next_frame, void **this_cache)
+{
+ struct m88k_frame_cache *cache = m88k_frame_cache (next_frame, this_cache);
+
+ if (cache->fp_offset != -1)
+ return cache->base + cache->sp_offset + cache->fp_offset;
+
+ return 0;
+}
+
+static const struct frame_base m88k_frame_base =
+{
+ &m88k_frame_unwind,
+ m88k_frame_base_address,
+ m88k_frame_base_address,
+ m88k_frame_base_address
+};
+\f
+
+/* Core file support. */
+
+/* Supply register REGNUM from the buffer specified by GREGS and LEN
+ in the general-purpose register set REGSET to register cache
+ REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
+
+static void
+m88k_supply_gregset (const struct regset *regset,
+ struct regcache *regcache,
+ int regnum, const void *gregs, size_t len)
+{
+ const char *regs = gregs;
+ int i;
+
+ for (i = 0; i < M88K_NUM_REGS; i++)
+ {
+ if (regnum == i || regnum == -1)
+ regcache_raw_supply (regcache, i, regs + i * 4);
+ }
+}
+
+/* Motorola 88000 register set. */
+
+static struct regset m88k_gregset =
+{
+ NULL,
+ m88k_supply_gregset
+};
+
+/* Return the appropriate register set for the core section identified
+ by SECT_NAME and SECT_SIZE. */
+
+static const struct regset *
+m88k_regset_from_core_section (struct gdbarch *gdbarch,
+ const char *sect_name, size_t sect_size)
+{
+ if (strcmp (sect_name, ".reg") == 0 && sect_size >= M88K_NUM_REGS * 4)
+ return &m88k_gregset;
+
+ return NULL;
+}
+\f
+
+static struct gdbarch *
+m88k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
+{
+ struct gdbarch *gdbarch;
+
+ /* If there is already a candidate, use it. */
+ arches = gdbarch_list_lookup_by_info (arches, &info);
+ if (arches != NULL)
+ return arches->gdbarch;
+
+ /* Allocate space for the new architecture. */
+ gdbarch = gdbarch_alloc (&info, NULL);
+
+ /* There is no real `long double'. */
+ set_gdbarch_long_double_bit (gdbarch, 64);
+ set_gdbarch_long_double_format (gdbarch, &floatformat_ieee_double_big);
+
+ set_gdbarch_num_regs (gdbarch, M88K_NUM_REGS);
+ set_gdbarch_register_name (gdbarch, m88k_register_name);
+ set_gdbarch_register_type (gdbarch, m88k_register_type);
+
+ /* Register numbers of various important registers. */
+ set_gdbarch_sp_regnum (gdbarch, M88K_R31_REGNUM);
+ set_gdbarch_pc_regnum (gdbarch, M88K_SXIP_REGNUM);
+
+ /* Core file support. */
+ set_gdbarch_regset_from_core_section
+ (gdbarch, m88k_regset_from_core_section);
+
+ set_gdbarch_print_insn (gdbarch, print_insn_m88k);
+
+ set_gdbarch_skip_prologue (gdbarch, m88k_skip_prologue);
+
+ /* Stack grows downward. */
+ set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
+
+ /* Call dummy code. */
+ set_gdbarch_push_dummy_call (gdbarch, m88k_push_dummy_call);
+ set_gdbarch_unwind_dummy_id (gdbarch, m88k_unwind_dummy_id);
+
+ /* Return value info */
+ set_gdbarch_return_value (gdbarch, m88k_return_value);
+
+ set_gdbarch_addr_bits_remove (gdbarch, m88k_addr_bits_remove);
+ set_gdbarch_breakpoint_from_pc (gdbarch, m88k_breakpoint_from_pc);
+ set_gdbarch_unwind_pc (gdbarch, m88k_unwind_pc);
+ set_gdbarch_write_pc (gdbarch, m88k_write_pc);
+
+ frame_base_set_default (gdbarch, &m88k_frame_base);
+ frame_unwind_append_sniffer (gdbarch, m88k_frame_sniffer);
+
+ return gdbarch;
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_m88k_tdep (void);
+
+void
+_initialize_m88k_tdep (void)
+{
+ gdbarch_register (bfd_arch_m88k, m88k_gdbarch_init, NULL);
+}
--- /dev/null
+/* Target-dependent code for the Motorola 88000 series.
+
+ Copyright 2004 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. */
+
+#ifndef M88K_TDEP_H
+#define M88K_TDEP_H
+
+/* Register numbers of various important registers. */
+
+enum m88k_regnum
+{
+ M88K_R0_REGNUM,
+ M88K_R1_REGNUM, /* Return address (hardware). */
+ M88K_R2_REGNUM,
+ M88K_R3_REGNUM,
+ M88K_R12_REGNUM = 12,
+ M88K_R30_REGNUM = 30, /* Frame pointer. */
+ M88K_R31_REGNUM, /* Stack pointer. */
+ M88K_EPSR_REGNUM,
+ M88K_FPSR_REGNUM,
+ M88K_FPCR_REGNUM,
+ M88K_SXIP_REGNUM,
+ M88K_SNIP_REGNUM,
+ M88K_SFIP_REGNUM,
+ M88K_NUM_REGS /* Number of machine registers. */
+
+};
+
+/* Instruction size. */
+#define M88K_INSN_SIZE 4
+
+#endif /* m88k-tdep.h */
--- /dev/null
+/* Native-dependent code for Motorola 88000 BSD's.
+
+ Copyright 2004 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. */
+
+#include "defs.h"
+#include "inferior.h"
+#include "regcache.h"
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+
+#include "m88k-tdep.h"
+
+/* Supply the general-purpose registers stored in GREGS to REGCACHE. */
+
+static void
+m88kbsd_supply_gregset (struct regcache *regcache, const void *gregs)
+{
+ const char *regs = gregs;
+ int regnum;
+
+ for (regnum = 0; regnum < M88K_NUM_REGS; regnum++)
+ regcache_raw_supply (regcache, regnum, regs + regnum * 4);
+}
+
+/* Collect the general-purpose registers from REGCACHE and store them
+ in GREGS. */
+
+static void
+m88kbsd_collect_gregset (const struct regcache *regcache,
+ void *gregs, int regnum)
+{
+ char *regs = gregs;
+ int i;
+
+ for (i = 0; i < M88K_NUM_REGS; i++)
+ {
+ if (regnum == -1 || regnum == i)
+ regcache_raw_collect (regcache, i, regs + i * 4);
+ }
+}
+\f
+
+/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
+ for all registers. */
+
+void
+fetch_inferior_registers (int regnum)
+{
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name ("Couldn't get registers");
+
+ m88kbsd_supply_gregset (current_regcache, ®s);
+}
+
+/* Store register REGNUM back into the inferior. If REGNUM is -1, do
+ this for all registers. */
+
+void
+store_inferior_registers (int regnum)
+{
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name ("Couldn't get registers");
+
+ m88kbsd_collect_gregset (current_regcache, ®s, regnum);
+
+ if (ptrace (PT_SETREGS, PIDGET (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name ("Couldn't write registers");
+}
--- /dev/null
+;;; gdb-mi.el (internally gdbmi6.el) - (24th May 2004)
+
+;; Run gdb with GDB/MI (-interp=mi) and access CLI using "cli-command"
+;; (could use "-interpreter-exec console cli-command")
+
+;; Author: Nick Roberts <nickrob@gnu.org>
+;; Maintainer: Nick Roberts <nickrob@gnu.org>
+;; Keywords: unix, tools
+
+;; Copyright (C) 2004 Free Software Foundation, Inc.
+
+;; This file is part of GNU GDB.
+
+;; GNU GDB 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.
+
+;; 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.
+
+;;; Commentary:
+
+;; This mode acts as a graphical user interface to GDB and requires GDB 6.1
+;; onwards. You can interact with GDB through the GUD buffer in the usual way,
+;; but there are also buffers which control the execution and describe the
+;; state of your program. It separates the input/output of your program from
+;; that of GDB and displays expressions and their current values in their own
+;; buffers. It also uses features of Emacs 21 such as the fringe/display
+;; margin for breakpoints, and the toolbar (see the GDB Graphical Interface
+;; section in the Emacs info manual).
+
+;; Start the debugger with M-x gdbmi.
+
+;; This file uses GDB/MI as the primary interface to GDB. It is still under
+;; development and is part of a process to migrate Emacs from annotations
+;; (as used in gdb-ui.el) to GDB/MI.
+
+;; Known Bugs:
+;;
+
+;;; Code:
+
+(require 'gud)
+(require 'gdb-ui)
+\f
+
+;;;###autoload
+(defun gdbmi (command-line)
+ "Run gdb on program FILE in buffer *gud-FILE*.
+The directory containing FILE becomes the initial working directory
+and source-file directory for your debugger.
+
+If `gdb-many-windows' is nil (the default value) then gdb just
+pops up the GUD buffer unless `gdb-show-main' is t. In this case
+it starts with two windows: one displaying the GUD buffer and the
+other with the source file with the main routine of the inferior.
+
+If `gdb-many-windows' is t, regardless of the value of
+`gdb-show-main', the layout below will appear. Keybindings are
+given in relevant buffer.
+
+Watch expressions appear in the speedbar/slowbar.
+
+The following interactive lisp functions help control operation :
+
+`gdb-many-windows' - Toggle the number of windows gdb uses.
+`gdb-restore-windows' - To restore the window layout.
+
+See Info node `(emacs)GDB Graphical Interface' for a more
+detailed description of this mode.
+
+
+---------------------------------------------------------------------
+ GDB Toolbar
+---------------------------------------------------------------------
+GUD buffer (I/O of GDB) | Locals buffer
+ |
+ |
+ |
+---------------------------------------------------------------------
+ Source buffer | Input/Output (of inferior) buffer
+ | (comint-mode)
+ |
+ |
+ |
+ |
+ |
+ |
+---------------------------------------------------------------------
+ Stack buffer | Breakpoints buffer
+ RET gdb-frames-select | SPC gdb-toggle-breakpoint
+ | RET gdb-goto-breakpoint
+ | d gdb-delete-breakpoint
+---------------------------------------------------------------------
+"
+ ;;
+ (interactive (list (gud-query-cmdline 'gdbmi)))
+ ;;
+ ;; Let's start with a basic gud-gdb buffer and then modify it a bit.
+ (gdb command-line)
+ ;;
+ (setq gdb-debug-log nil)
+ (set (make-local-variable 'gud-minor-mode) 'gdbmi)
+ (set (make-local-variable 'gud-marker-filter) 'gud-gdbmi-marker-filter)
+ ;;
+ (gud-def gud-break (if (not (string-equal mode-name "Machine"))
+ (gud-call "-break-insert %f:%l" arg)
+ (save-excursion
+ (beginning-of-line)
+ (forward-char 2)
+ (gud-call "-break-insert *%a" arg)))
+ "\C-b" "Set breakpoint at current line or address.")
+ ;;
+ (gud-def gud-remove (if (not (string-equal mode-name "Machine"))
+ (gud-call "clear %f:%l" arg)
+ (save-excursion
+ (beginning-of-line)
+ (forward-char 2)
+ (gud-call "clear *%a" arg)))
+ "\C-d" "Remove breakpoint at current line or address.")
+ ;;
+ (gud-def gud-until (if (not (string-equal mode-name "Machine"))
+ (gud-call "until %f:%l" arg)
+ (save-excursion
+ (beginning-of-line)
+ (forward-char 2)
+ (gud-call "until *%a" arg)))
+ "\C-u" "Continue to current line or address.")
+
+ (define-key gud-minor-mode-map [left-margin mouse-1]
+ 'gdb-mouse-toggle-breakpoint)
+ (define-key gud-minor-mode-map [left-fringe mouse-1]
+ 'gdb-mouse-toggle-breakpoint)
+
+ (setq comint-input-sender 'gdbmi-send)
+ ;;
+ ;; (re-)initialise
+ (setq gdb-main-file nil)
+ (setq gdb-current-address "main")
+ (setq gdb-previous-address nil)
+ (setq gdb-previous-frame nil)
+ (setq gdb-current-frame "main")
+ (setq gdb-view-source t)
+ (setq gdb-selected-view 'source)
+ (setq gdb-var-list nil)
+ (setq gdb-var-changed nil)
+ (setq gdb-prompting nil)
+ (setq gdb-current-item nil)
+ (setq gdb-pending-triggers nil)
+ (setq gdb-output-sink 'user)
+ (setq gdb-server-prefix nil)
+ ;;
+ (setq gdb-buffer-type 'gdbmi)
+ ;;
+ ;; FIXME: use tty command to separate io.
+ ;;(gdb-clear-inferior-io)
+ ;;
+ (if (eq window-system 'w32)
+ (gdb-enqueue-input (list "-gdb-set new-console off\n" 'ignore)))
+ ;; find source file and compilation directory here
+ (gdb-enqueue-input (list "list main\n" 'ignore)) ; C program
+ (gdb-enqueue-input (list "list MAIN__\n" 'ignore)) ; Fortran program
+ (gdb-enqueue-input (list "info source\n" 'gdbmi-source-info))
+ ;;
+ (run-hooks 'gdbmi-mode-hook))
+
+; Force nil till fixed.
+(defconst gdbmi-use-inferior-io-buffer nil)
+
+; uses --all-values Needs GDB 6.1 onwards.
+(defun gdbmi-var-list-children (varnum)
+ (gdb-enqueue-input
+ (list (concat "-var-update " varnum "\n") 'ignore))
+ (gdb-enqueue-input
+ (list (concat "-var-list-children --all-values "
+ varnum "\n")
+ `(lambda () (gdbmi-var-list-children-handler ,varnum)))))
+
+(defconst gdbmi-var-list-children-regexp
+"name=\"\\(.*?\\)\",exp=\"\\(.*?\\)\",numchild=\"\\(.*?\\)\",value=\"\\(.*?\\)\""
+)
+
+(defun gdbmi-var-list-children-handler (varnum)
+ (with-current-buffer (gdb-get-create-buffer 'gdb-partial-output-buffer)
+ (goto-char (point-min))
+ (let ((var-list nil))
+ (catch 'child-already-watched
+ (dolist (var gdb-var-list)
+ (if (string-equal varnum (cadr var))
+ (progn
+ (push var var-list)
+ (while (re-search-forward gdbmi-var-list-children-regexp nil t)
+ (let ((varchild (list (match-string 2)
+ (match-string 1)
+ (match-string 3)
+ nil
+ (match-string 4)
+ nil)))
+ (if (looking-at ",type=\"\\(.*?\\)\"")
+ (setcar (nthcdr 3 varchild) (match-string 1)))
+ (dolist (var1 gdb-var-list)
+ (if (string-equal (cadr var1) (cadr varchild))
+ (throw 'child-already-watched nil)))
+ (push varchild var-list))))
+ (push var var-list)))
+ (setq gdb-var-changed t)
+ (setq gdb-var-list (nreverse var-list))))))
+\f
+;(defun gdbmi-send (proc string)
+; "A comint send filter for gdb."
+; (setq gdb-output-sink 'user)
+; (setq gdb-prompting nil)
+; (process-send-string proc (concat "-interpreter-exec console \"" string "\"")))
+
+(defun gdbmi-send (proc string)
+ "A comint send filter for gdb."
+ (setq gdb-output-sink 'user)
+ (setq gdb-prompting nil)
+ (process-send-string proc (concat string "\n")))
+
+(defcustom gud-gdbmi-command-name "~/gdb/gdb/gdb -interp=mi"
+ "Default command to execute an executable under the GDB-UI debugger."
+ :type 'string
+ :group 'gud)
+
+(defconst gdb-stopped-regexp
+ "\\((gdb) \n\\*stopped\\|^\\^done\\),reason=.*,file=\"\\(.*\\)\",line=\"\\(.*\\)\".*")
+
+(defconst gdb-console-regexp "~\"\\(.*\\)\\\\n\"")
+
+(defconst gdb-internals-regexp "&\".*\\n\"\n")
+
+(defconst gdb-gdb-regexp "(gdb) \n")
+
+(defconst gdb-running-regexp "^\\^running")
+
+(defun gdbmi-prompt ()
+ "This handler terminates the any collection of output. It also
+ sends the next command (if any) to gdb."
+ (unless gdb-pending-triggers
+ (gdb-get-current-frame)
+ (gdbmi-invalidate-frames)
+ (gdbmi-invalidate-breakpoints)
+ (gdbmi-invalidate-locals)
+ (dolist (frame (frame-list))
+ (when (string-equal (frame-parameter frame 'name) "Speedbar")
+ (setq gdb-var-changed t) ; force update
+ (dolist (var gdb-var-list)
+ (setcar (nthcdr 5 var) nil))))
+ (gdb-var-update))
+ (let ((sink gdb-output-sink))
+ (when (eq sink 'emacs)
+ (let ((handler
+ (car (cdr gdb-current-item))))
+ (with-current-buffer (gdb-get-create-buffer 'gdb-partial-output-buffer)
+ (funcall handler)))))
+ (let ((input (gdb-dequeue-input)))
+ (if input
+ (gdb-send-item input)
+ (progn
+ (setq gud-running nil)
+ (setq gdb-prompting t)
+ (gud-display-frame)))))
+
+(defun gud-gdbmi-marker-filter (string)
+ "Filter GDB/MI output."
+ (if gdb-enable-debug-log (push (cons 'recv string) gdb-debug-log))
+ ;; Recall the left over gud-marker-acc from last time
+ (setq gud-marker-acc (concat gud-marker-acc string))
+ ;; Start accumulating output for the GUD buffer
+ (let ((output ""))
+
+ (if (string-match gdb-running-regexp gud-marker-acc)
+ (setq gud-marker-acc (substring gud-marker-acc (match-end 0))
+ gud-running t))
+
+ ;; Remove the trimmings from the console stream.
+ (while (string-match gdb-console-regexp gud-marker-acc)
+ (setq
+ gud-marker-acc (concat (substring gud-marker-acc 0 (match-beginning 0))
+ (match-string 1 gud-marker-acc)
+ (substring gud-marker-acc (match-end 0)))))
+
+ ;; Remove log stream containing debugging messages being produced by GDB's
+ ;; internals.
+ (while (string-match gdb-internals-regexp gud-marker-acc)
+ (setq
+ gud-marker-acc (concat (substring gud-marker-acc 0 (match-beginning 0))
+ (substring gud-marker-acc (match-end 0)))))
+
+ (if (string-match gdb-stopped-regexp gud-marker-acc)
+ (setq
+
+ ;; Extract the frame position from the marker.
+ gud-last-frame (cons (match-string 2 gud-marker-acc)
+ (string-to-int (match-string 3 gud-marker-acc)))
+
+ ;; Append any text before the marker to the output we're going
+ ;; to return - we don't include the marker in this text.
+ output (gdbmi-concat-output output
+ (substring gud-marker-acc 0 (match-beginning 0)))
+
+ ;; Set the accumulator to the remaining text.
+ gud-marker-acc (substring gud-marker-acc (match-end 0))))
+
+ (while (string-match gdb-gdb-regexp gud-marker-acc)
+ (setq
+
+ ;; Append any text up to and including prompt less \n to the output.
+ output (gdbmi-concat-output output
+ (substring gud-marker-acc 0 (- (match-end 0) 1)))
+
+ ;; Set the accumulator to the remaining text.
+ gud-marker-acc (substring gud-marker-acc (match-end 0)))
+ (gdbmi-prompt))
+
+ (setq output (gdbmi-concat-output output gud-marker-acc))
+ (setq gud-marker-acc "")
+ output))
+
+(defun gdbmi-concat-output (so-far new)
+ (let ((sink gdb-output-sink))
+ (cond
+ ((eq sink 'user) (concat so-far new))
+ ((eq sink 'emacs)
+ (gdb-append-to-partial-output new)
+ so-far)
+ ((eq sink 'inferior)
+ (gdb-append-to-inferior-io new)
+ so-far))))
+\f
+
+;; Breakpoint buffer : This displays the output of `-break-list'.
+;;
+(def-gdb-auto-updated-buffer gdb-breakpoints-buffer
+ ;; This defines the auto update rule for buffers of type
+ ;; `gdb-breakpoints-buffer'.
+ ;;
+ ;; It defines a function that queues the command below. That function is
+ ;; called:
+ gdbmi-invalidate-breakpoints
+ ;;
+ ;; To update the buffer, this command is sent to gdb.
+ "-break-list\n"
+ ;;
+ ;; This also defines a function to be the handler for the output
+ ;; from the command above. That function will copy the output into
+ ;; the appropriately typed buffer. That function will be called:
+ gdb-break-list-handler
+ ;; buffer specific functions
+ gdb-break-list-custom)
+
+(defconst gdb-break-list-regexp
+"number=\"\\(.*?\\)\",type=\"\\(.*?\\)\",disp=\"\\(.*?\\)\",enabled=\"\\(.\\)\",addr=\"\\(.*?\\)\",func=\"\\(.*?\\)\",file=\"\\(.*?\\)\",line=\"\\(.*?\\)\"")
+
+(defun gdb-break-list-handler ()
+ (setq gdb-pending-triggers (delq 'gdbmi-invalidate-breakpoints
+ gdb-pending-triggers))
+ (let ((breakpoint nil)
+ (breakpoints-list nil))
+ (with-current-buffer (gdb-get-create-buffer 'gdb-partial-output-buffer)
+ (goto-char (point-min))
+ (while (re-search-forward gdb-break-list-regexp nil t)
+ (let ((breakpoint (list (match-string 1)
+ (match-string 2)
+ (match-string 3)
+ (match-string 4)
+ (match-string 5)
+ (match-string 6)
+ (match-string 7)
+ (match-string 8))))
+ (push breakpoint breakpoints-list))))
+ (let ((buf (gdb-get-buffer 'gdb-breakpoints-buffer)))
+ (and buf (with-current-buffer buf
+ (let ((p (point))
+ (buffer-read-only nil))
+ (erase-buffer)
+ (insert "Num Type Disp Enb Func\tFile:Line\tAddr\n")
+ (dolist (breakpoint breakpoints-list)
+ (insert (concat
+ (nth 0 breakpoint) " "
+ (nth 1 breakpoint) " "
+ (nth 2 breakpoint) " "
+ (nth 3 breakpoint) " "
+ (nth 5 breakpoint) "\t"
+ (nth 6 breakpoint) ":" (nth 7 breakpoint) "\t"
+ (nth 4 breakpoint) "\n")))
+ (goto-char p))))))
+ (gdb-break-list-custom))
+
+;;-put breakpoint icons in relevant margins (even those set in the GUD buffer)
+(defun gdb-break-list-custom ()
+ (let ((flag)(address))
+ ;;
+ ;; remove all breakpoint-icons in source buffers but not assembler buffer
+ (dolist (buffer (buffer-list))
+ (with-current-buffer buffer
+ (if (and (eq gud-minor-mode 'gdbmi)
+ (not (string-match "\\`\\*.+\\*\\'" (buffer-name))))
+ (gdb-remove-breakpoint-icons (point-min) (point-max)))))
+ (with-current-buffer (gdb-get-buffer 'gdb-breakpoints-buffer)
+ (save-excursion
+ (goto-char (point-min))
+ (while (< (point) (- (point-max) 1))
+ (forward-line 1)
+ (if (looking-at "[0-9]*\\s-*\\S-*\\s-*\\S-*\\s-*\\(.\\)\\s-*\\S-*\\s-*\\(\\S-*\\):\\([0-9]+\\)")
+ (progn
+ (setq flag (char-after (match-beginning 1)))
+ (let ((line (match-string 3)) (buffer-read-only nil)
+ (file (match-string 2)))
+ (add-text-properties (point-at-bol) (point-at-eol)
+ '(mouse-face highlight
+ help-echo "mouse-2, RET: visit breakpoint"))
+ (with-current-buffer
+ (find-file-noselect
+ (if (file-exists-p file) file
+ (expand-file-name file gdb-cdir)))
+ (save-current-buffer
+ (set (make-local-variable 'gud-minor-mode) 'gdbmi)
+ (set (make-local-variable 'tool-bar-map)
+ gud-tool-bar-map))
+ ;; only want one breakpoint icon at each location
+ (save-excursion
+ (goto-line (string-to-number line))
+ (gdb-put-breakpoint-icon (eq flag ?y)))))))))
+ (end-of-line)))
+ (if (gdb-get-buffer 'gdb-assembler-buffer) (gdb-assembler-custom)))
+
+;; Frames buffer. This displays a perpetually correct bactrack trace.
+;;
+(def-gdb-auto-updated-buffer gdb-stack-buffer
+ gdbmi-invalidate-frames
+ "-stack-list-frames\n"
+ gdb-stack-list-frames-handler
+ gdb-stack-list-frames-custom)
+
+(defconst gdb-stack-list-frames-regexp
+"level=\"\\(.*?\\)\",addr=\"\\(.*?\\)\",func=\"\\(.*?\\)\",file=\"\\(.*?\\)\",line=\"\\(.*?\\)\"")
+
+(defun gdb-stack-list-frames-handler ()
+ (setq gdb-pending-triggers (delq 'gdbmi-invalidate-frames
+ gdb-pending-triggers))
+ (let ((frame nil)
+ (call-stack nil))
+ (with-current-buffer (gdb-get-create-buffer 'gdb-partial-output-buffer)
+ (goto-char (point-min))
+ (while (re-search-forward gdb-stack-list-frames-regexp nil t)
+ (let ((frame (list (match-string 1)
+ (match-string 2)
+ (match-string 3)
+ (match-string 4)
+ (match-string 5))))
+ (push frame call-stack))))
+ (let ((buf (gdb-get-buffer 'gdb-stack-buffer)))
+ (and buf (with-current-buffer buf
+ (let ((p (point))
+ (buffer-read-only nil))
+ (erase-buffer)
+ (insert "Level\tFunc\tFile:Line\tAddr\n")
+ (dolist (frame (nreverse call-stack))
+ (insert (concat
+ (nth 0 frame) "\t"
+ (nth 2 frame) "\t"
+ (nth 3 frame) ":" (nth 4 frame) "\t"
+ (nth 1 frame) "\n")))
+ (goto-char p))))))
+ (gdb-stack-list-frames-custom))
+
+(defun gdb-stack-list-frames-custom ()
+ (with-current-buffer (gdb-get-buffer 'gdb-stack-buffer)
+ (save-excursion
+ (let ((buffer-read-only nil))
+ (goto-char (point-min))
+ (forward-line 1)
+ (while (< (point) (point-max))
+ (add-text-properties (point-at-bol) (point-at-eol)
+ '(mouse-face highlight
+ help-echo "mouse-2, RET: Select frame"))
+ (beginning-of-line)
+ (when (and (or (looking-at "^#[0-9]*\\s-*\\S-* in \\(\\S-*\\)")
+ (looking-at "^#[0-9]*\\s-*\\(\\S-*\\)"))
+ (equal (match-string 1) gdb-current-frame))
+ (put-text-property (point-at-bol) (point-at-eol)
+ 'face '(:inverse-video t)))
+ (forward-line 1))))))
+
+;; Locals buffer.
+;; uses "-stack-list-locals 2". Needs GDB 6.1 onwards.
+(def-gdb-auto-updated-buffer gdb-locals-buffer
+ gdbmi-invalidate-locals
+ "-stack-list-locals 2\n"
+ gdb-stack-list-locals-handler
+ gdb-stack-list-locals-custom)
+
+(defconst gdb-stack-list-locals-regexp
+ (concat "name=\"\\(.*?\\)\",type=\"\\(.*?\\)\""))
+
+;; Dont display values of arrays or structures.
+;; These can be expanded using gud-watch.
+(defun gdb-stack-list-locals-handler nil
+ (setq gdb-pending-triggers (delq 'gdbmi-invalidate-locals
+ gdb-pending-triggers))
+ (let ((local nil)
+ (locals-list nil))
+ (with-current-buffer (gdb-get-create-buffer 'gdb-partial-output-buffer)
+ (goto-char (point-min))
+ (while (re-search-forward gdb-stack-list-locals-regexp nil t)
+ (let ((local (list (match-string 1)
+ (match-string 2)
+ nil)))
+ (if (looking-at ",value=\"\\(.*?\\)\"")
+ (setcar (nthcdr 2 local) (match-string 1)))
+ (push local locals-list))))
+ (let ((buf (gdb-get-buffer 'gdb-locals-buffer)))
+ (and buf (with-current-buffer buf
+ (let ((p (point))
+ (buffer-read-only nil))
+ (erase-buffer)
+ (dolist (local locals-list)
+ (insert
+ (concat (car local) "\t" (nth 1 local) "\t"
+ (or (nth 2 local)
+ (if (string-match "struct" (nth 1 local))
+ "(structure)"
+ "(array)"))
+ "\n")))
+ (goto-char p)))))))
+
+(defun gdb-stack-list-locals-custom ()
+ nil)
+
+(defun gdbmi-source-info ()
+ "Find the source file where the program starts and displays it with related
+buffers."
+ (goto-char (point-min))
+ (if (search-forward "source file is " nil t)
+ (if (looking-at "\\S-*")
+ (setq gdb-main-file (match-string 0)))
+ (setq gdb-view-source nil))
+ (if (search-forward "directory is " nil t)
+ (if (looking-at "\\S-*:\\(\\S-*\\)")
+ (setq gdb-cdir (match-string 1))
+ (looking-at "\\S-*")
+ (setq gdb-cdir (match-string 0))))
+
+;temporary heuristic
+ (if gdb-main-file
+ (setq gdb-main-file (expand-file-name gdb-main-file gdb-cdir)))
+
+ (if gdb-many-windows
+ (gdb-setup-windows)
+ (gdb-get-create-buffer 'gdb-breakpoints-buffer)
+ (when gdb-show-main
+ (switch-to-buffer gud-comint-buffer)
+ (delete-other-windows)
+ (split-window)
+ (other-window 1)
+ (switch-to-buffer
+ (if gdb-view-source
+ (gud-find-file gdb-main-file)
+ (gdb-get-create-buffer 'gdb-assembler-buffer)))
+ (other-window 1))))
+
+(provide 'gdb-mi)
+;;; gdbmi.el ends here
--- /dev/null
+#!/bin/sh -e
+
+if test $# -ne 3
+then
+ echo "Usage: $0 <h|inc> <observer.texi> <observer.out>" 1>&2
+ exit 0
+fi
+
+lang=$1 ; shift
+texi=$1 ; shift
+o=$1 ; shift
+echo "Creating ${o}-tmp" 1>&2
+rm -f ${o}-tmp
+
+# Can use any of the following: cat cmp cp diff echo egrep expr false
+# grep install-info ln ls mkdir mv pwd rm rmdir sed sleep sort tar
+# test touch true
+
+cat <<EOF >>${o}-tmp
+/* GDB Notifications to Observers.
+
+ Copyright 2004 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.
+
+ --
+
+ This file was generated using observer.sh and observer.texi. */
+
+EOF
+
+
+case $lang in
+ h) cat <<EOF >>${o}-tmp
+#ifndef OBSERVER_H
+#define OBSERVER_H
+
+struct observer;
+struct bpstats;
+struct so_list;
+EOF
+ ;;
+esac
+
+
+# generate a list of events that can be observed
+
+IFS=:
+sed -n '
+/@deftypefun void/{
+# Save original line for later processing into the actual parameter
+ h
+# Convert from: @deftypefun void EVENT (TYPE @var{PARAM},...)
+# to event and formals: EVENT:TYPE PARAM, ...:
+ s/^.* void \([a-z_][a-z_]*\) (\(.*\))$/\1:\2/
+ s/@var{//g
+ s/}//g
+# Switch to held
+ x
+# Convert from: @deftypefun void FUNC (TYPE @var{PARAM},...)
+# to actuals: PARAM, ...
+ s/^[^{]*[{]*//
+ s/[}]*[^}]*$//
+ s/}[^{]*{/, /g
+# Combine held (EVENT:TYPE PARAM, ...:) and pattern (PARAM, ...) into
+# FUNC:TYPE PARAM, ...:PARAM, ...
+ H
+ x
+ s/\n/:/g
+ p
+}
+' $texi | while read event formal actual
+do
+ case $lang in
+ h) cat <<EOF >>${o}-tmp
+
+/* ${event} notifications. */
+
+typedef void (observer_${event}_ftype) (${formal});
+
+extern struct observer *observer_attach_${event} (observer_${event}_ftype *f);
+extern void observer_detach_${event} (struct observer *observer);
+extern void observer_notify_${event} (${formal});
+EOF
+ ;;
+
+ inc)
+ cat <<EOF >>${o}-tmp
+
+/* ${event} notifications. */
+
+static struct observer_list *${event}_subject = NULL;
+
+struct ${event}_args { `echo "${formal}" | sed -e 's/,/;/g'`; };
+
+static void
+observer_${event}_notification_stub (const void *data, const void *args_data)
+{
+ observer_${event}_ftype *notify = (observer_${event}_ftype *) data;
+ const struct ${event}_args *args = args_data;
+ notify (`echo ${actual} | sed -e 's/\([a-z0-9_][a-z0-9_]*\)/args->\1/g'`);
+}
+
+struct observer *
+observer_attach_${event} (observer_${event}_ftype *f)
+{
+ return generic_observer_attach (&${event}_subject,
+ &observer_${event}_notification_stub,
+ (void *) f);
+}
+
+void
+observer_detach_${event} (struct observer *observer)
+{
+ generic_observer_detach (&${event}_subject, observer);
+}
+
+void
+observer_notify_${event} (${formal})
+{
+ struct ${event}_args args;
+ `echo ${actual} | sed -e 's/\([a-z0-9_][a-z0-9_]*\)/args.\1 = \1/g'`;
+ if (observer_debug)
+ fprintf_unfiltered (gdb_stdlog, "observer_notify_${event}() called\n");
+ generic_observer_notify (${event}_subject, &args);
+}
+EOF
+ ;;
+ esac
+done
+
+
+case $lang in
+ h) cat <<EOF >>${o}-tmp
+
+#endif /* OBSERVER_H */
+EOF
+esac
+
+
+echo Moving ${o}-tmp to ${o}
+mv ${o}-tmp ${o}
--- /dev/null
+#!/bin/sh -e
+
+if test $# -lt 3
+then
+ echo "Usage: $0 <xgettext> <package> <directory> ..." 1>&2
+ exit 0
+fi
+
+xgettext=$1 ; shift
+package=$1 ; shift
+
+for d in "$@"
+do
+ __directories="$__directories --directory=$d"
+done
+
+for d in "$@"
+do
+ (
+ cd $d
+ find * \
+ -name '*-stub.c' -prune -o \
+ -name 'testsuite' -prune -o \
+ -name 'init.c' -prune -o \
+ -name '*.[hc]' -print
+ )
+done | ${xgettext} \
+ --default-domain=${package} \
+ --copyright-holder="Free Software Foundation, Inc." \
+ --add-comments \
+ --files-from=- \
+ --force-po \
+ --debug \
+ --language=c \
+ --keyword=_ \
+ --keyword=N_ \
+ ${__directories} \
+ -o po/${package}.pot
--- /dev/null
+/* Native-dependent code for OpenBSD/powerpc.
+
+ Copyright 2004 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. */
+
+#include "defs.h"
+#include "inferior.h"
+#include "regcache.h"
+
+#include <stddef.h>
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+
+#include "ppc-tdep.h"
+#include "ppcobsd-tdep.h"
+
+/* OpenBSD/powerpc doesn't have PT_GETFPREGS/PT_SETFPREGS like
+ NetBSD/powerpc and FreeBSD/powerpc. */
+
+/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
+ for all registers. */
+
+void
+fetch_inferior_registers (int regnum)
+{
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name ("Couldn't get registers");
+
+ ppcobsd_supply_gregset (&ppcobsd_gregset, current_regcache, -1,
+ ®s, sizeof regs);
+}
+
+/* Store register REGNUM back into the inferior. If REGNUM is -1, do
+ this for all registers. */
+
+void
+store_inferior_registers (int regnum)
+{
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name ("Couldn't get registers");
+
+ ppcobsd_collect_gregset (&ppcobsd_gregset, current_regcache,
+ regnum, ®s, sizeof regs);
+
+ if (ptrace (PT_SETREGS, PIDGET (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name ("Couldn't write registers");
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_ppcobsd_nat (void);
+
+void
+_initialize_ppcobsd_nat (void)
+{
+ /* General-purpose registers. */
+ ppcobsd_reg_offsets.r0_offset = offsetof (struct reg, gpr);
+ ppcobsd_reg_offsets.pc_offset = offsetof (struct reg, pc);
+ ppcobsd_reg_offsets.ps_offset = offsetof (struct reg, ps);
+ ppcobsd_reg_offsets.cr_offset = offsetof (struct reg, cnd);
+ ppcobsd_reg_offsets.lr_offset = offsetof (struct reg, lr);
+ ppcobsd_reg_offsets.ctr_offset = offsetof (struct reg, cnt);
+ ppcobsd_reg_offsets.xer_offset = offsetof (struct reg, xer);
+ ppcobsd_reg_offsets.mq_offset = offsetof (struct reg, mq);
+
+ /* Floating-point registers. */
+ ppcobsd_reg_offsets.f0_offset = offsetof (struct reg, fpr);
+ ppcobsd_reg_offsets.fpscr_offset = -1;
+
+ /* AltiVec registers. */
+ ppcobsd_reg_offsets.vr0_offset = offsetof (struct vreg, vreg);
+ ppcobsd_reg_offsets.vscr_offset = offsetof (struct vreg, vscr);
+ ppcobsd_reg_offsets.vrsave_offset = offsetof (struct vreg, vrsave);
+}
--- /dev/null
+/* Target-dependent code for OpenBSD/powerpc.
+
+ Copyright 2004 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. */
+
+#include "defs.h"
+#include "arch-utils.h"
+#include "osabi.h"
+#include "regcache.h"
+#include "regset.h"
+#include "gdb_assert.h"
+
+#include "gdb_string.h"
+
+#include "ppc-tdep.h"
+#include "ppcobsd-tdep.h"
+#include "solib-svr4.h"
+
+/* Register offsets from <machine/reg.h>. */
+struct ppc_reg_offsets ppcobsd_reg_offsets;
+\f
+
+/* Core file support. */
+
+/* Supply register REGNUM in the general-purpose register set REGSET
+ from the buffer specified by GREGS and LEN to register cache
+ REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
+
+void
+ppcobsd_supply_gregset (const struct regset *regset,
+ struct regcache *regcache, int regnum,
+ const void *gregs, size_t len)
+{
+ /* FIXME: jimb/2004-05-05: Some PPC variants don't have floating
+ point registers. Traditionally, GDB's register set has still
+ listed the floating point registers for such machines, so this
+ code is harmless. However, the new E500 port actually omits the
+ floating point registers entirely from the register set --- they
+ don't even have register numbers assigned to them.
+
+ It's not clear to me how best to update this code, so this assert
+ will alert the first person to encounter the OpenBSD/E500
+ combination to the problem. */
+ gdb_assert (ppc_floating_point_unit_p (current_gdbarch));
+
+ ppc_supply_gregset (regset, regcache, regnum, gregs, len);
+ ppc_supply_fpregset (regset, regcache, regnum, gregs, len);
+}
+
+/* Collect register REGNUM in the general-purpose register set
+ REGSET. from register cache REGCACHE into the buffer specified by
+ GREGS and LEN. If REGNUM is -1, do this for all registers in
+ REGSET. */
+
+void
+ppcobsd_collect_gregset (const struct regset *regset,
+ const struct regcache *regcache, int regnum,
+ void *gregs, size_t len)
+{
+ /* FIXME: jimb/2004-05-05: Some PPC variants don't have floating
+ point registers. Traditionally, GDB's register set has still
+ listed the floating point registers for such machines, so this
+ code is harmless. However, the new E500 port actually omits the
+ floating point registers entirely from the register set --- they
+ don't even have register numbers assigned to them.
+
+ It's not clear to me how best to update this code, so this assert
+ will alert the first person to encounter the OpenBSD/E500
+ combination to the problem. */
+ gdb_assert (ppc_floating_point_unit_p (current_gdbarch));
+
+ ppc_collect_gregset (regset, regcache, regnum, gregs, len);
+ ppc_collect_fpregset (regset, regcache, regnum, gregs, len);
+}
+
+/* OpenBS/powerpc register set. */
+
+struct regset ppcobsd_gregset =
+{
+ &ppcobsd_reg_offsets,
+ ppcobsd_supply_gregset
+};
+
+/* Return the appropriate register set for the core section identified
+ by SECT_NAME and SECT_SIZE. */
+
+static const struct regset *
+ppcobsd_regset_from_core_section (struct gdbarch *gdbarch,
+ const char *sect_name, size_t sect_size)
+{
+ if (strcmp (sect_name, ".reg") == 0 && sect_size >= 412)
+ return &ppcobsd_gregset;
+
+ return NULL;
+}
+\f
+
+static void
+ppcobsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ /* OpenBSD uses SVR4-style shared libraries. */
+ set_gdbarch_in_solib_call_trampoline
+ (gdbarch, generic_in_solib_call_trampoline);
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+
+ set_gdbarch_regset_from_core_section
+ (gdbarch, ppcobsd_regset_from_core_section);
+}
+\f
+
+/* OpenBSD uses uses the traditional NetBSD core file format, even for
+ ports that use ELF. */
+#define GDB_OSABI_NETBSD_CORE GDB_OSABI_OPENBSD_ELF
+
+static enum gdb_osabi
+ppcobsd_core_osabi_sniffer (bfd *abfd)
+{
+ if (strcmp (bfd_get_target (abfd), "netbsd-core") == 0)
+ return GDB_OSABI_NETBSD_CORE;
+
+ return GDB_OSABI_UNKNOWN;
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_ppcobsd_tdep (void);
+
+void
+_initialize_ppcobsd_tdep (void)
+{
+ /* BFD doesn't set a flavour for NetBSD style a.out core files. */
+ gdbarch_register_osabi_sniffer (bfd_arch_powerpc, bfd_target_unknown_flavour,
+ ppcobsd_core_osabi_sniffer);
+
+ gdbarch_register_osabi (bfd_arch_powerpc, 0, GDB_OSABI_OPENBSD_ELF,
+ ppcobsd_init_abi);
+
+ /* Avoid initializing the register offsets again if they were
+ already initailized by ppcobsd-nat.c. */
+ if (ppcobsd_reg_offsets.pc_offset == 0)
+ {
+ /* General-purpose registers. */
+ ppcobsd_reg_offsets.r0_offset = 0;
+ ppcobsd_reg_offsets.pc_offset = 384;
+ ppcobsd_reg_offsets.ps_offset = 388;
+ ppcobsd_reg_offsets.cr_offset = 392;
+ ppcobsd_reg_offsets.lr_offset = 396;
+ ppcobsd_reg_offsets.ctr_offset = 400;
+ ppcobsd_reg_offsets.xer_offset = 404;
+ ppcobsd_reg_offsets.mq_offset = 408;
+
+ /* Floating-point registers. */
+ ppcobsd_reg_offsets.f0_offset = 128;
+ ppcobsd_reg_offsets.fpscr_offset = -1;
+
+ /* AltiVec registers. */
+ ppcobsd_reg_offsets.vr0_offset = 0;
+ ppcobsd_reg_offsets.vscr_offset = 512;
+ ppcobsd_reg_offsets.vrsave_offset = 520;
+ }
+}
--- /dev/null
+/* Target-dependent code for OpenBSD/powerpc.
+
+ Copyright 2004 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. */
+
+#ifndef PPCOBSD_TDEP_H
+#define PPCOBSD_TDEP_H
+
+#include <stddef.h>
+
+struct regset;
+struct regcache;
+
+/* Register offsets for OpenBSD/powerpc. */
+extern struct ppc_reg_offsets ppcobsd_reg_offsets;
+
+/* Register sets for OpenBSD/powerpc. */
+extern struct regset ppcobsd_gregset;
+\f
+
+/* Supply register REGNUM in the general-purpose register set REGSET
+ from the buffer specified by GREGS and LEN to register cache
+ REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
+
+extern void ppcobsd_supply_gregset (const struct regset *regset,
+ struct regcache *regcache, int regnum,
+ const void *gregs, size_t len);
+
+/* Collect register REGNUM in the general-purpose register set
+ REGSET. from register cache REGCACHE into the buffer specified by
+ GREGS and LEN. If REGNUM is -1, do this for all registers in
+ REGSET. */
+
+extern void ppcobsd_collect_gregset (const struct regset *regset,
+ const struct regcache *regcache,
+ int regnum, void *gregs, size_t len);
+
+#endif /* ppcobsd-tdep.h */
--- /dev/null
+/* Manage register sets.
+
+ Copyright 2004 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. */
+
+#include "defs.h"
+#include "regset.h"
+
+#include "gdb_assert.h"
+
+/* Allocate a fresh 'struct regset' whose supply_regset function is
+ SUPPLY_REGSET, and whose collect_regset function is COLLECT_REGSET.
+ If the regset has no collect_regset function, pass NULL for
+ COLLECT_REGSET.
+
+ The object returned is allocated on ARCH's obstack. */
+
+struct regset *
+regset_alloc (struct gdbarch *arch,
+ supply_regset_ftype *supply_regset,
+ collect_regset_ftype *collect_regset)
+{
+ struct regset *regset = GDBARCH_OBSTACK_ZALLOC (arch, struct regset);
+
+ regset->arch = arch;
+ regset->supply_regset = supply_regset;
+ regset->collect_regset = collect_regset;
+
+ return regset;
+}
--- /dev/null
+/* Reading symbol files from memory.
+
+ Copyright 1986, 1987, 1989, 1991, 1994, 1995, 1996, 1998, 2000,
+ 2001, 2002, 2003, 2004 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. */
+
+/* This file defines functions (and commands to exercise those
+ functions) for reading debugging information from object files
+ whose images are mapped directly into the inferior's memory. For
+ example, the Linux kernel maps a "syscall DSO" into each process's
+ address space; this DSO provides kernel-specific code for some
+ system calls.
+
+ At the moment, BFD only has functions for parsing object files from
+ memory for the ELF format, even though the general idea isn't
+ ELF-specific. This means that BFD only provides the functions GDB
+ needs when configured for ELF-based targets. So these functions
+ may only be compiled on ELF-based targets.
+
+ GDB has no idea whether it has been configured for an ELF-based
+ target or not: it just tries to handle whatever files it is given.
+ But this means there are no preprocessor symbols on which we could
+ make these functions' compilation conditional.
+
+ So, for the time being, we put these functions alone in this file,
+ and have .mt files reference them as appropriate. In the future, I
+ hope BFD will provide a format-independent bfd_from_remote_memory
+ entry point. */
+
+
+#include "defs.h"
+#include "symtab.h"
+#include "gdbcore.h"
+#include "objfiles.h"
+#include "gdbcmd.h"
+#include "target.h"
+#include "value.h"
+#include "symfile.h"
+
+
+/* Read inferior memory at ADDR to find the header of a loaded object file
+ and read its in-core symbols out of inferior memory. TEMPL is a bfd
+ representing the target's format. */
+static struct objfile *
+symbol_file_add_from_memory (struct bfd *templ, CORE_ADDR addr, int from_tty)
+{
+ struct objfile *objf;
+ struct bfd *nbfd;
+ struct bfd_section *sec;
+ bfd_vma loadbase;
+ struct section_addr_info *sai;
+ unsigned int i;
+
+ if (bfd_get_flavour (templ) != bfd_target_elf_flavour)
+ error ("add-symbol-file-from-memory not supported for this target");
+
+ nbfd = bfd_elf_bfd_from_remote_memory (templ, addr, &loadbase,
+ target_read_memory);
+ if (nbfd == NULL)
+ error ("Failed to read a valid object file image from memory.");
+
+ nbfd->filename = xstrdup ("shared object read from target memory");
+
+ if (!bfd_check_format (nbfd, bfd_object))
+ {
+ /* FIXME: should be checking for errors from bfd_close (for one thing,
+ on error it does not free all the storage associated with the
+ bfd). */
+ bfd_close (nbfd);
+ error ("Got object file from memory but can't read symbols: %s.",
+ bfd_errmsg (bfd_get_error ()));
+ }
+
+ sai = alloc_section_addr_info (bfd_count_sections (nbfd));
+ make_cleanup (xfree, sai);
+ i = 0;
+ for (sec = nbfd->sections; sec != NULL; sec = sec->next)
+ if ((bfd_get_section_flags (nbfd, sec) & (SEC_ALLOC|SEC_LOAD)) != 0)
+ {
+ sai->other[i].addr = bfd_get_section_vma (nbfd, sec) + loadbase;
+ sai->other[i].name = (char *) bfd_get_section_name (nbfd, sec);
+ sai->other[i].sectindex = sec->index;
+ ++i;
+ }
+
+ objf = symbol_file_add_from_bfd (nbfd, from_tty,
+ sai, 0, OBJF_SHARED);
+
+ /* This might change our ideas about frames already looked at. */
+ reinit_frame_cache ();
+
+ return objf;
+}
+
+
+static void
+add_symbol_file_from_memory_command (char *args, int from_tty)
+{
+ CORE_ADDR addr;
+ struct bfd *templ;
+
+ if (args == NULL)
+ error ("add-symbol-file-from-memory requires an expression argument");
+
+ addr = parse_and_eval_address (args);
+
+ /* We need some representative bfd to know the target we are looking at. */
+ if (symfile_objfile != NULL)
+ templ = symfile_objfile->obfd;
+ else
+ templ = exec_bfd;
+ if (templ == NULL)
+ error ("\
+Must use symbol-file or exec-file before add-symbol-file-from-memory.");
+
+ symbol_file_add_from_memory (templ, addr, from_tty);
+}
+
+\f
+void
+_initialize_symfile_mem (void)
+{
+ add_cmd ("add-symbol-file-from-memory", class_files,
+ add_symbol_file_from_memory_command,
+ "\
+Load the symbols out of memory from a dynamically loaded object file.\n\
+Give an expression for the address of the file's shared object file header.",
+ &cmdlist);
+
+}
--- /dev/null
+-- Copyright 2004 Free Software Foundation, Inc.
+--
+-- 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.
+
+-- This project file allows us to control the location where the
+-- compilation artifacts produced when building the Ada examples
+-- are stored.
+
+project Gnat_Ada is
+
+ for Source_Dirs use ("@srcdir@");
+ -- No need to set the Object_Dir, it is set to "." by default
+ -- (which means the same directory as this project file).
+
+end Gnat_Ada;
--- /dev/null
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2004 Free Software Foundation, Inc.
+
+ 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. */
+
+void arg_passing_test2 (void);
+
+int
+main (void)
+{
+ arg_passing_test2 ();
+ return 0;
+}
+
+
+/* Asm for procedure arg_passing_test2.
+
+ The challenge here is getting past the 'mr 0,3' and 'stb'
+ instructions. */
+
+asm (" .section \".text\"\n"
+ " .align 2\n"
+ " .globl arg_passing_test2\n"
+ " .type arg_passing_test2, @function\n"
+ "arg_passing_test2:\n"
+ " stwu 1,-64(1)\n"
+ " stw 31,60(1)\n"
+ " mr 31,1\n"
+ " mr 0,3\n"
+ " evstdd 4,16(31)\n"
+ " stw 5,24(31)\n"
+ " stw 7,32(31)\n"
+ " stw 8,36(31)\n"
+ " stw 9,40(31)\n"
+ " stb 0,8(31)\n"
+ " lwz 11,0(1)\n"
+ " lwz 31,-4(11)\n"
+ " mr 1,11\n"
+ " blr\n"
+ " .size arg_passing_test2, .-arg_passing_test2\n");
--- /dev/null
+# Copyright 2004 Free Software Foundation, Inc.
+#
+# 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.
+#
+# This file is part of the gdb testsuite.
+
+if $tracelevel {
+ strace $tracelevel
+}
+
+# Test PowerPC E500 prologue analyzer.
+
+set prms_id 0
+set bug_id 0
+
+if ![istarget "powerpc-*"] then {
+ verbose "Skipping powerpc E500 prologue tests."
+ return
+}
+
+set testfile "e500-prologue"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {}] != "" } {
+ unsupported "Testcase compile failed."
+ return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# Insert a breakpoint in FUNCTION and verifies that the breakpoint was
+# inserted at the expected location. EXPECTED_LOCATION should be an
+# offset relative to the function start address.
+proc insert_breakpoint {function expected_location} {
+ global gdb_prompt
+ global expect_out
+ global hex
+
+ set address ""
+
+ # Insert a breakpoint using the given function name, and extract
+ # the breakpoint address for the output.
+ gdb_test_multiple "break $function" "set breakpoint in $function" {
+ -re "Breakpoint 1 at ($hex).*$gdb_prompt $" {
+ set address $expect_out(1,string)
+ }
+ default {
+ fail "set breakpoint in $function"
+ }
+ }
+
+ # If we managed to get the breakpoing address, then check that
+ # we inserted it at the expected location by examining the
+ # instruction at that address (we're not interested in the insn
+ # itself, but rather at the address printed at the begining of
+ # the instruction).
+ if { $address != "" } then {
+ gdb_test "x /i $address" \
+ ".*<$function\\+$expected_location>.*" \
+ "check $function breakpoint address"
+ } else {
+ fail "unable to compute breakpoint address"
+ }
+
+}
+
+insert_breakpoint "arg_passing_test2" 40
--- /dev/null
+/* Helper file for i386 platform. Runtime check for MMX/SSE/SSE2 support.
+
+ Copyright 2004 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. */
+
+/* Used by 20020523-2.c and i386-sse-6.c, and possibly others. */
+/* Plagarized from 20020523-2.c. */
+/* Plagarized from gcc. */
+
+#define bit_CMOV (1 << 15)
+#define bit_MMX (1 << 23)
+#define bit_SSE (1 << 25)
+#define bit_SSE2 (1 << 26)
+
+#ifndef NOINLINE
+#define NOINLINE __attribute__ ((noinline))
+#endif
+
+unsigned int i386_cpuid (void) NOINLINE;
+
+unsigned int NOINLINE
+i386_cpuid (void)
+{
+ int fl1, fl2;
+
+#ifndef __x86_64__
+ /* See if we can use cpuid. On AMD64 we always can. */
+ __asm__ ("pushfl; pushfl; popl %0; movl %0,%1; xorl %2,%0;"
+ "pushl %0; popfl; pushfl; popl %0; popfl"
+ : "=&r" (fl1), "=&r" (fl2)
+ : "i" (0x00200000));
+ if (((fl1 ^ fl2) & 0x00200000) == 0)
+ return (0);
+#endif
+
+ /* Host supports cpuid. See if cpuid gives capabilities, try
+ CPUID(0). Preserve %ebx and %ecx; cpuid insn clobbers these, we
+ don't need their CPUID values here, and %ebx may be the PIC
+ register. */
+#ifdef __x86_64__
+ __asm__ ("pushq %%rcx; pushq %%rbx; cpuid; popq %%rbx; popq %%rcx"
+ : "=a" (fl1) : "0" (0) : "rdx", "cc");
+#else
+ __asm__ ("pushl %%ecx; pushl %%ebx; cpuid; popl %%ebx; popl %%ecx"
+ : "=a" (fl1) : "0" (0) : "edx", "cc");
+#endif
+ if (fl1 == 0)
+ return (0);
+
+ /* Invoke CPUID(1), return %edx; caller can examine bits to
+ determine what's supported. */
+#ifdef __x86_64__
+ __asm__ ("pushq %%rcx; pushq %%rbx; cpuid; popq %%rbx; popq %%rcx"
+ : "=d" (fl2), "=a" (fl1) : "1" (1) : "cc");
+#else
+ __asm__ ("pushl %%ecx; pushl %%ebx; cpuid; popl %%ebx; popl %%ecx"
+ : "=d" (fl2), "=a" (fl1) : "1" (1) : "cc");
+#endif
+
+ return fl2;
+}
--- /dev/null
+/* Test program for SSE registers.
+
+ Copyright 2004 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. */
+
+#include <stdio.h>
+#include "i386-cpuid.h"
+
+typedef struct {
+ float f[4];
+} v4sf_t;
+
+
+v4sf_t data[8] =
+ {
+ { { 0.0, 0.25, 0.50, 0.75 } },
+ { { 1.0, 1.25, 1.50, 1.75 } },
+ { { 2.0, 2.25, 2.50, 2.75 } },
+ { { 3.0, 3.25, 3.50, 3.75 } },
+ { { 4.0, 4.25, 4.50, 4.75 } },
+ { { 5.0, 5.25, 5.50, 5.75 } },
+ { { 6.0, 6.25, 6.50, 6.75 } },
+ { { 7.0, 7.25, 7.50, 7.75 } },
+ };
+
+
+int
+have_sse (void)
+{
+ int edx = i386_cpuid ();
+
+ if (edx & bit_SSE)
+ return 1;
+ else
+ return 0;
+}
+
+int
+main (int argc, char **argv)
+{
+ if (have_sse ())
+ {
+ asm ("movaps 0(%0), %%xmm0\n\t"
+ "movaps 16(%0), %%xmm1\n\t"
+ "movaps 32(%0), %%xmm2\n\t"
+ "movaps 48(%0), %%xmm3\n\t"
+ "movaps 64(%0), %%xmm4\n\t"
+ "movaps 80(%0), %%xmm5\n\t"
+ "movaps 96(%0), %%xmm6\n\t"
+ "movaps 112(%0), %%xmm7\n\t"
+ : /* no output operands */
+ : "r" (data)
+ : "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7");
+
+ puts ("Hi!"); /* first breakpoint here */
+
+ asm (
+ "movaps %%xmm0, 0(%0)\n\t"
+ "movaps %%xmm1, 16(%0)\n\t"
+ "movaps %%xmm2, 32(%0)\n\t"
+ "movaps %%xmm3, 48(%0)\n\t"
+ "movaps %%xmm4, 64(%0)\n\t"
+ "movaps %%xmm5, 80(%0)\n\t"
+ "movaps %%xmm6, 96(%0)\n\t"
+ "movaps %%xmm7, 112(%0)\n\t"
+ : /* no output operands */
+ : "r" (data)
+ : "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7");
+
+ puts ("Bye!"); /* second breakpoint here */
+ }
+
+ return 0;
+}
--- /dev/null
+# Copyright 2004 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@gnu.org
+
+# This file is part of the gdb testsuite.
+
+if $tracelevel {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+if ![istarget "i?86-*-*"] then {
+ verbose "Skipping i386 SSE tests."
+ return
+}
+
+set testfile "i386-sse"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ unsupported "compiler does not support SSE"
+ return
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if ![runto_main] then {
+ gdb_suppress_tests
+}
+
+send_gdb "print have_sse ()\r"
+gdb_expect {
+ -re ".. = 1\r\n$gdb_prompt " {
+ pass "check whether processor supports SSE"
+ }
+ -re ".. = 0\r\n$gdb_prompt " {
+ verbose "processor does not support SSE; skipping SSE tests"
+ return
+ }
+ -re ".*$gdb_prompt $" {
+ fail "check whether processor supports SSE"
+ }
+ timeout {
+ fail "check whether processor supports SSE (timeout)"
+ }
+}
+
+gdb_test "break [gdb_get_line_number "first breakpoint here"]" \
+ "Breakpoint .* at .*i386-sse.c.*" \
+ "set breakpoint in main"
+gdb_continue_to_breakpoint "continue to first breakpoint in main"
+
+foreach r {0 1 2 3 4 5 6 7} {
+ gdb_test "print \$xmm$r.v4_float" \
+ ".. = \\{$r, $r.25, $r.5, $r.75\\}.*" \
+ "check contents of %xmm$r"
+}
+
+foreach r {0 1 2 3 4 5 6 7} {
+ gdb_test "set var \$xmm$r.v4_float\[0\] = $r + 10" "" "set %xmm$r"
+}
+
+gdb_test "break [gdb_get_line_number "second breakpoint here"]" \
+ "Breakpoint .* at .*i386-sse.c.*" \
+ "set breakpoint in main"
+gdb_continue_to_breakpoint "continue to second breakpoint in main"
+
+foreach r {0 1 2 3 4 5 6 7} {
+ gdb_test "print data\[$r\]" \
+ ".. = \\{f = \\{[expr $r + 10], $r.25, $r.5, $r.75\\}\\}.*" \
+ "check contents of data\[$r\]"
+}
--- /dev/null
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2004 Free Software Foundation, Inc.
+
+ 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. */
+
+void li_stw (void);
+
+int
+main (void)
+{
+ li_stw ();
+ return 0;
+}
+
+/* Asm for procedure li_stw().
+
+ The purpose of this function is to verify that GDB does not
+ include the li insn as part of the function prologue (only part
+ of the prologue if part of a pair of insns saving vector registers).
+ Similarly, GDB should not include the stw insn following the li insn,
+ because the source register is not used for parameter passing. */
+
+
+asm (" .csect .text[PR]\n"
+ " .align 2\n"
+ " .lglobl .li_stw\n"
+ " .csect li_stw[DS]\n"
+ "li_stw:\n"
+ " .long .li_stw, TOC[tc0], 0\n"
+ " .csect .text[PR]\n"
+ ".li_stw:\n"
+ " stw 31,-4(1)\n"
+ " stwu 1,-48(1)\n"
+ " mr 31,1\n"
+ " stw 11,24(31)\n"
+ " li 0,8765\n"
+ " stw 0,28(31)\n"
+ " lwz 1,0(1)\n"
+ " lwz 31,-4(1)\n"
+ " blr\n");
+
--- /dev/null
+# Copyright 2004 Free Software Foundation, Inc.
+#
+# 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.
+#
+# This file is part of the gdb testsuite.
+
+if $tracelevel {
+ strace $tracelevel
+}
+
+# Test rs6000 prologue analyzer.
+
+set prms_id 0
+set bug_id 0
+
+if ![istarget "powerpc-*-aix*"] then {
+ verbose "Skipping powerpc-aix prologue tests."
+ return
+}
+
+set testfile "powerpc-aix-prologue"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {}] != "" } {
+ unsupported "Testcase compile failed."
+ return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# Insert a breakpoint in FUNCTION and verifies that the breakpoint was
+# inserted at the expected location. EXPECTED_LOCATION should be an
+# offset relative to the function start address.
+proc insert_breakpoint {function expected_location} {
+ global gdb_prompt
+ global expect_out
+ global hex
+
+ set address ""
+
+ # Insert a breakpoint using the given function name, and extract
+ # the breakpoint address for the output.
+ gdb_test_multiple "break $function" "set breakpoint in $function" {
+ -re "Breakpoint 1 at ($hex).*$gdb_prompt $" {
+ set address $expect_out(1,string)
+ }
+ default {
+ fail "set breakpoint in $function"
+ }
+ }
+
+ # If we managed to get the breakpoing address, then check that
+ # we inserted it at the expected location by examining the
+ # instruction at that address (we're not interested in the insn
+ # itself, but rather at the address printed at the begining of
+ # the instruction).
+ if { $address != "" } then {
+ gdb_test "x /i $address" \
+ ".*<$function\\+$expected_location>.*" \
+ "check $function breakpoint address"
+ } else {
+ fail "unable to compute breakpoint address"
+ }
+
+}
+
+insert_breakpoint "li_stw" 12
--- /dev/null
+ comment "subroutine prologue"
+ .macro gdbasm_enter
+ stw %rp, -20(%sp)
+ copy %r3, %r1
+ copy %sp, %r3
+ stwm %r1, 64(%sp)
+ .endm
+
+ comment "subroutine epilogue"
+ .macro gdbasm_leave
+ ldw -20(%r3), %rp
+ bv %r0(%rp)
+ ldwm -64(%sp), %r3
+ .endm
+
+ .macro gdbasm_call subr
+ bl \subr , %rp
+ nop
+ .endm
+
+ .macro gdbasm_several_nops
+ nop
+ nop
+ nop
+ nop
+ .endm
+
+ comment "exit (0)"
+ .macro gdbasm_exit0
+ comment "Don't know how to exit, but this will certainly halt..."
+ ldw 0(%r0), %r1
+ .endm
+
+ comment "crt0 startup"
+ .macro gdbasm_startup
+ .align 4
+ .endm
+
+ comment "Declare a data variable"
+ .macro gdbasm_datavar name value
+ .data
+\name:
+ .long \value
+ .endm
--- /dev/null
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2004 Free Software Foundation, Inc.
+
+ 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.
+
+*/
+
+/* Useful abreviations. */
+typedef void t;
+typedef char tc;
+typedef short ts;
+typedef int ti;
+typedef long tl;
+typedef long long tll;
+typedef float tf;
+typedef double td;
+typedef long double tld;
+typedef enum { e = '1' } te;
+
+/* Force the type of each field. */
+#ifndef T
+typedef t T;
+#endif
+
+T foo = '1', L;
+
+T fun()
+{
+ return foo;
+}
+
+#ifdef PROTOTYPES
+void Fun(T foo)
+#else
+void Fun(foo)
+ T foo;
+#endif
+{
+ L = foo;
+}
+
+zed ()
+{
+ L = 'Z';
+}
+
+int main()
+{
+#ifdef usestubs
+ set_debug_traps();
+ breakpoint();
+#endif
+ int i;
+
+ Fun(foo);
+
+ /* An infinite loop that first clears all the variables and then
+ calls the function. This "hack" is to make re-testing easier -
+ "advance fun" is guaranteed to have always been preceeded by a
+ global variable clearing zed call. */
+
+ zed ();
+ while (1)
+ {
+ L = fun ();
+ zed ();
+ }
+
+ return 0;
+}
--- /dev/null
+# This testcase is part of GDB, the GNU debugger.
+
+# Copyright 2004 Free Software Foundation, Inc.
+
+# 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.
+
+# Test "return", "finish", and "call" of functions that a scalar (int,
+# float, enum) and/or take a single scalar parameter.
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+# Some targets can't call functions, so don't even bother with this
+# test.
+
+if [target_info exists gdb,cannot_call_functions] {
+ setup_xfail "*-*-*"
+ fail "This target can not call functions"
+ continue
+}
+
+set testfile "call-sc"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+# Create and source the file that provides information about the
+# compiler used to compile the test case.
+
+if [get_compiler_info ${binfile}] {
+ return -1;
+}
+
+# Use the file name, compiler and tuples to set up any needed KFAILs.
+
+proc setup_kfails { file tuples bug } {
+ global testfile
+ if [string match $file $testfile] {
+ foreach f $tuples { setup_kfail $f $bug }
+ }
+}
+
+proc setup_compiler_kfails { file compiler format tuples bug } {
+ global testfile
+ if {[string match $file $testfile] && [test_compiler_info $compiler] && [test_debug_format $format]} {
+ foreach f $tuples { setup_kfail $f $bug }
+ }
+}
+
+# Compile a variant of scalars.c using TYPE to specify the type of the
+# parameter and return-type. Run the compiled program up to "main".
+# Also updates the global "testfile" to reflect the most recent build.
+
+proc start_scalars_test { type } {
+ global testfile
+ global srcfile
+ global binfile
+ global objdir
+ global subdir
+ global srcdir
+ global gdb_prompt
+ global expect_out
+
+ # Create the additional flags
+ set flags "debug additional_flags=-DT=${type}"
+ set testfile "call-sc-${type}"
+
+ set binfile ${objdir}/${subdir}/${testfile}
+ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable "${flags}"] != "" } {
+ # built the second test case since we can't use prototypes
+ warning "Prototypes not supported, rebuilding with -DNO_PROTOTYPES"
+ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable "${flags} additional_flags=-DNO_PROTOTYPES"] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+ }
+ }
+
+ # Start with a fresh gdb.
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load ${binfile}
+
+ # Make certain that the output is consistent
+ gdb_test "set print sevenbit-strings" "" \
+ "set print sevenbit-strings; ${testfile}"
+ gdb_test "set print address off" "" \
+ "set print address off; ${testfile}"
+ gdb_test "set width 0" "" \
+ "set width 0; ${testfile}"
+
+ # Advance to main
+ if { ![runto_main] } then {
+ gdb_suppress_tests;
+ }
+
+ # Get the debug format
+ get_debug_format
+
+ # check that type matches what was passed in
+ set test "ptype; ${testfile}"
+ set foo_t "xxx"
+ gdb_test_multiple "ptype ${type}" "${test}" {
+ -re "type = (\[^\r\n\]*)\r\n$gdb_prompt $" {
+ set foo_t "$expect_out(1,string)"
+ pass "$test (${foo_t})"
+ }
+ }
+ gdb_test "ptype foo" "type = ${foo_t}" "ptype foo; ${testfile} $expect_out(1,string)"
+}
+
+
+# Given N (0..25), return the corresponding alphabetic letter in lower
+# or upper case. This is ment to be i18n proof.
+
+proc i2a { n } {
+ return [string range "abcdefghijklmnopqrstuvwxyz" $n $n]
+}
+
+proc I2A { n } {
+ return [string toupper [i2a $n]]
+}
+
+
+# Use the file name, compiler and tuples to set up any needed KFAILs.
+
+proc setup_kfails { file tuples bug } {
+ global testfile
+ if [string match $file $testfile] {
+ foreach f $tuples { setup_kfail $f $bug }
+ }
+}
+
+proc setup_compiler_kfails { file compiler format tuples bug } {
+ global testfile
+ if {[string match $file $testfile] && [test_compiler_info $compiler] && [test_debug_format $format]} {
+ foreach f $tuples { setup_kfail $f $bug }
+ }
+}
+
+# Test GDB's ability to make inferior function calls to functions
+# returning (or passing) in a single scalar.
+
+# start_scalars_test() will have previously built a program with a
+# specified scalar type. To ensure robustness of the output, "p/c" is
+# used.
+
+# This tests the code paths "which return-value convention?" and
+# "extract return-value from registers" called by "infcall.c".
+
+proc test_scalar_calls { } {
+ global testfile
+ global gdb_prompt
+
+ # Check that GDB can always extract a scalar-return value from an
+ # inferior function call. Since GDB always knows the location of
+ # an inferior function call's return value these should never fail
+
+ # Implemented by calling the parameterless function "fun" and then
+ # examining the return value printed by GDB.
+
+ set tests "call ${testfile}"
+
+ # Call fun, checking the printed return-value.
+ gdb_test "p/c fun()" "= 49 '1'" "p/c fun(); ${tests}"
+
+ # Check that GDB can always pass a structure to an inferior function.
+ # This test can never fail.
+
+ # Implemented by calling the one parameter function "Fun" which
+ # stores its parameter in the global variable "L". GDB then
+ # examining that global to confirm that the value is as expected.
+
+ gdb_test "call Fun(foo)" "" "call Fun(foo); ${tests}"
+ gdb_test "p/c L" " = 49 '1'" "p/c L; ${tests}"
+}
+
+# Test GDB's ability to both return a function (with "return" or
+# "finish") and correctly extract/store any corresponding
+# return-value.
+
+# Check that GDB can consistently extract/store structure return
+# values. There are two cases - returned in registers and returned in
+# memory. For the latter case, the return value can't be found and a
+# failure is "expected". However GDB must still both return the
+# function and display the final source and line information.
+
+# N identifies the number of elements in the struct that will be used
+# for the test case. FAILS is a list of target tuples that will fail
+# this test.
+
+# This tests the code paths "which return-value convention?", "extract
+# return-value from registers", and "store return-value in registers".
+# Unlike "test struct calls", this test is expected to "fail" when the
+# return-value is in memory (GDB can't find the location). The test
+# is in three parts: test "return"; test "finish"; check that the two
+# are consistent. GDB can sometimes work for one command and not the
+# other.
+
+proc test_scalar_returns { } {
+ global gdb_prompt
+ global testfile
+
+ set tests "return ${testfile}"
+
+
+ # Check that "return" works.
+
+ # GDB must always force the return of a function that has
+ # a struct result. Dependant on the ABI, it may, or may not be
+ # possible to store the return value in a register.
+
+ # The relevant code looks like "L{n} = fun{n}()". The test forces
+ # "fun{n}" to "return" with an explicit value. Since that code
+ # snippet will store the the returned value in "L{n}" the return
+ # is tested by examining "L{n}". This assumes that the
+ # compiler implemented this as fun{n}(&L{n}) and hence that when
+ # the value isn't stored "L{n}" remains unchanged. Also check for
+ # consistency between this and the "finish" case.
+
+ # Get into a call of fun
+ gdb_test "advance fun" \
+ "fun .*\[\r\n\]+\[0-9\].*return foo.*" \
+ "advance to fun for return; ${tests}"
+
+ # Check that the program invalidated the relevant global.
+ gdb_test "p/c L" " = 90 'Z'" "zed L for return; ${tests}"
+
+ # Force the "return". This checks that the return is always
+ # performed, and that GDB correctly reported this to the user.
+ # GDB 6.0 and earlier, when the return-value's location wasn't
+ # known, both failed to print a final "source and line" and misplaced
+ # the frame ("No frame").
+
+ # The test is writen so that it only reports one FAIL/PASS for the
+ # entire operation. The value returned is checked further down.
+ # "return_value_unknown", if non-empty, records why GDB realised
+ # that it didn't know where the return value was.
+
+ set test "return foo; ${tests}"
+ set return_value_unknown 0
+ set return_value_unimplemented 0
+ gdb_test_multiple "return foo" "${test}" {
+ -re "The location" {
+ # Ulgh, a struct return, remember this (still need prompt).
+ set return_value_unknown 1
+ exp_continue
+ }
+ -re "A structure or union" {
+ # Ulgh, a struct return, remember this (still need prompt).
+ set return_value_unknown 1
+ # Double ulgh. Architecture doesn't use return_value and
+ # hence hasn't implemented small structure return.
+ set return_value_unimplemented 1
+ exp_continue
+ }
+ -re "Make fun return now.*y or n. $" {
+ gdb_test_multiple "y" "${test}" {
+ -re "L *= fun.*${gdb_prompt} $" {
+ # Need to step off the function call
+ gdb_test "next" "zed.*" "${test}"
+ }
+ -re "zed \\(\\);.*$gdb_prompt $" {
+ pass "${test}"
+ }
+ }
+ }
+ }
+
+ # If the previous test did not work, the program counter might
+ # still be inside foo() rather than main(). Make sure the program
+ # counter is is main().
+ #
+ # This happens on ppc64 GNU/Linux with gcc 3.4.1 and a buggy GDB
+
+ set test "return foo; synchronize pc to main()"
+ for {set loop_count 0} {$loop_count < 2} {incr loop_count} {
+ gdb_test_multiple "backtrace 1" $test {
+ -re "#0.*main \\(\\).*${gdb_prompt} $" {
+ pass $test
+ set loop_count 2
+ }
+ -re "#0.*fun \\(\\).*${gdb_prompt} $" {
+ if {$loop_count < 1} {
+ gdb_test "finish" ".*" ""
+ } else {
+ fail $test
+ set loop_count 2
+ }
+ }
+ }
+ }
+
+ # Check that the return-value is as expected. At this stage we're
+ # just checking that GDB has returned a value consistent with
+ # "return_value_unknown" set above.
+
+ set test "value foo returned; ${tests}"
+ gdb_test_multiple "p/c L" "${test}" {
+ -re " = 49 '1'.*${gdb_prompt} $" {
+ if $return_value_unknown {
+ # This contradicts the above claim that GDB didn't
+ # know the location of the return-value.
+ fail "${test}"
+ } else {
+ pass "${test}"
+ }
+ }
+ -re " = 90 .*${gdb_prompt} $" {
+ if $return_value_unknown {
+ # The struct return case. Since any modification
+ # would be by reference, and that can't happen, the
+ # value should be unmodified and hence Z is expected.
+ # Is this a reasonable assumption?
+ pass "${test}"
+ } else {
+ # This contradicts the above claim that GDB knew
+ # the location of the return-value.
+ fail "${test}"
+ }
+ }
+ -re ".*${gdb_prompt} $" {
+ if $return_value_unimplemented {
+ # What a suprize. The architecture hasn't implemented
+ # return_value, and hence has to fail.
+ kfail "$test" gdb/1444
+ } else {
+ fail "$test"
+ }
+ }
+ }
+
+ # Check that a "finish" works.
+
+ # This is almost but not quite the same as "call struct funcs".
+ # Architectures can have subtle differences in the two code paths.
+
+ # The relevant code snippet is "L{n} = fun{n}()". The program is
+ # advanced into a call to "fun{n}" and then that function is
+ # finished. The returned value that GDB prints, reformatted using
+ # "p/c", is checked.
+
+ # Get into "fun()".
+ gdb_test "advance fun" \
+ "fun .*\[\r\n\]+\[0-9\].*return foo.*" \
+ "advance to fun for finish; ${tests}"
+
+ # Check that the program invalidated the relevant global.
+ gdb_test "p/c L" " = 90 'Z'" "zed L for finish; ${tests}"
+
+ # Finish the function, set 'finish_value_unknown" to non-empty if the
+ # return-value was not found.
+ set test "finish foo; ${tests}"
+ set finish_value_unknown 0
+ gdb_test_multiple "finish" "${test}" {
+ -re "Value returned is .*${gdb_prompt} $" {
+ pass "${test}"
+ }
+ -re "Cannot determine contents.*${gdb_prompt} $" {
+ # Expected bad value. For the moment this is ok.
+ set finish_value_unknown 1
+ pass "${test}"
+ }
+ }
+
+ # Re-print the last (return-value) using the more robust
+ # "p/c". If no return value was found, the 'Z' from the previous
+ # check that the variable was cleared, is printed.
+ set test "value foo finished; ${tests}"
+ gdb_test_multiple "p/c" "${test}" {
+ -re " = 49 '1'\[\r\n\]+${gdb_prompt} $" {
+ if $finish_value_unknown {
+ # This contradicts the above claim that GDB didn't
+ # know the location of the return-value.
+ fail "${test}"
+ } else {
+ pass "${test}"
+ }
+ }
+ -re " = 90 'Z'\[\r\n\]+${gdb_prompt} $" {
+ # The value didn't get found. This is "expected".
+ if $finish_value_unknown {
+ pass "${test}"
+ } else {
+ # This contradicts the above claim that GDB did
+ # know the location of the return-value.
+ fail "${test}"
+ }
+ }
+ }
+
+ # Finally, check that "return" and finish" have consistent
+ # behavior.
+
+ # Since both "return" and "finish" use equivalent "which
+ # return-value convention" logic, both commands should have
+ # identical can/can-not find return-value messages.
+
+ # Note that since "call" and "finish" use common code paths, a
+ # failure here is a strong indicator of problems with "store
+ # return-value" code paths. Suggest looking at "return_value"
+ # when investigating a fix.
+
+ set test "return and finish use same convention; ${tests}"
+ if {$finish_value_unknown == $return_value_unknown} {
+ pass "${test}"
+ } else {
+ kfail gdb/1444 "${test}"
+ }
+}
+
+# ABIs pass anything >8 or >16 bytes in memory but below that things
+# randomly use register and/and structure conventions. Check all
+# possible sized char scalars in that range. But only a restricted
+# range of the other types.
+
+# NetBSD/PPC returns "unnatural" (3, 5, 6, 7) sized scalars in memory.
+
+# d10v is weird. 5/6 byte scalars go in memory. 2 or more char
+# scalars go in memory. Everything else is in a register!
+
+# Test every single char struct from 1..17 in size. This is what the
+# original "scalars" test was doing.
+
+start_scalars_test tc
+test_scalar_calls
+test_scalar_returns
+
+
+# Let the fun begin.
+
+# Assuming that any integer struct larger than 8 bytes goes in memory,
+# come up with many and varied combinations of a return struct. For
+# "struct calls" test just beyond that 8 byte boundary, for "struct
+# returns" test up to that boundary.
+
+# For floats, assumed that up to two struct elements can be stored in
+# floating point registers, regardless of their size.
+
+# The approx size of each structure it is computed assumed that tc=1,
+# ts=2, ti=4, tl=4, tll=8, tf=4, td=8, tld=16, and that all fields are
+# naturally aligned. Padding being added where needed. Note that
+# these numbers are just approx, the d10v has ti=2, a 64-bit has has
+# tl=8.
+
+# Approx size: 2, 4, ...
+start_scalars_test ts
+test_scalar_calls
+test_scalar_returns
+
+# Approx size: 4, 8, ...
+start_scalars_test ti
+test_scalar_calls
+test_scalar_returns
+
+# Approx size: 4, 8, ...
+start_scalars_test tl
+test_scalar_calls
+test_scalar_returns
+
+# Approx size: 8, 16, ...
+start_scalars_test tll
+test_scalar_calls
+test_scalar_returns
+
+# Approx size: 4, 8, ...
+start_scalars_test tf
+test_scalar_calls
+test_scalar_returns
+
+# Approx size: 8, 16, ...
+start_scalars_test td
+test_scalar_calls
+test_scalar_returns
+
+# Approx size: 16, 32, ...
+start_scalars_test tld
+test_scalar_calls
+test_scalar_returns
+
+# Approx size: 4, 8, ...
+start_scalars_test te
+test_scalar_calls
+test_scalar_returns
+
+return 0
--- /dev/null
+/* The following is written to tickle a specific bug in the macro
+ table code (now hopefully fixed), which doesn't insert new included
+ files in the #including file's list in the proper place. They
+ should be sorted by the number of the line which #included them, in
+ increasing order, but the sense of the comparison was reversed, so
+ the list ends up being built backwards. This isn't a problem by
+ itself, but the code to pick new, non-conflicting line numbers for
+ headers alleged to be #included at the same line as some other
+ header assumes that the list's line numbers are in ascending order.
+
+ So, given the following input, lineinc1.h gets added to lineinc.c's
+ #inclusion list first, at line 10. When the debug info reader
+ tries to add lineinc2.h at line 10 as well, the code will notice the
+ duplication --- since there's only one extant element in the list,
+ it'll find it --- and insert it after lineinc1.h, with line 11.
+ Since the code is putting the list in order of descending
+ #inclusion line number, the list is now out of order. When we try
+ to #include lineinc3.h at line 11, we won't notice the duplication. */
+
+#line 10
+#include "lineinc1.h"
+#line 10
+#include "lineinc2.h"
+#line 11
+#include "lineinc3.h"
+
+int
+main (int argc, char **argv)
+{
+}
--- /dev/null
+# Test macro handling of #included files.
+# Copyright 2003 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# The test program lineinc.c contains a mix of #line directives and
+# #include directives that will cause the compiler to attribute more
+# than one #inclusion to the same source line. You can get similar
+# effects using things like GCC's '-imacros' flag.
+#
+# Compiling lineinc.c with Dwarf 2 macro information will produce
+# something like this:
+#
+# $ gcc -g3 lineinc.c -o lineinc
+# $ readelf -wml lineinc
+# ...
+# The File Name Table:
+# Entry Dir Time Size Name
+# 1 0 0 0 lineinc.c
+# 2 0 0 0 lineinc1.h
+# 3 0 0 0 lineinc2.h
+# 4 0 0 0 lineinc3.h
+# ...
+# Contents of the .debug_macinfo section:
+#
+# DW_MACINFO_start_file - lineno: 0 filenum: 1
+# DW_MACINFO_define - lineno : 1 macro : __VERSION__ "3.2 20020903 (Red Hat Linux 8.0 3.2-7)"
+# DW_MACINFO_define - lineno : 2 macro : __USER_LABEL_PREFIX__
+# ...
+# DW_MACINFO_define - lineno : 1 macro : __i386__ 1
+# DW_MACINFO_define - lineno : 1 macro : __tune_i386__ 1
+# DW_MACINFO_start_file - lineno: 10 filenum: 2
+# DW_MACINFO_define - lineno : 1 macro : FOO 1
+# DW_MACINFO_end_file
+# DW_MACINFO_start_file - lineno: 10 filenum: 3
+# DW_MACINFO_undef - lineno : 1 macro : FOO
+# DW_MACINFO_define - lineno : 2 macro : FOO 2
+# DW_MACINFO_end_file
+# DW_MACINFO_start_file - lineno: 11 filenum: 4
+# DW_MACINFO_undef - lineno : 1 macro : FOO
+# DW_MACINFO_define - lineno : 2 macro : FOO 3
+# DW_MACINFO_end_file
+# DW_MACINFO_end_file
+# $
+#
+# Note how the inclusions of lineinc1.h and lineinc2.h are both
+# attributed to line 10 of lineinc.c, and the #inclusion of lineinc3.h
+# is attributed to line 11. This is all correct, given the #line
+# directives in lineinc.c.
+#
+# Dwarf 2 macro information doesn't contain enough information to
+# allow GDB to figure out what's really going on here --- it makes no
+# mention of the #line directives --- so we just try to cope as best
+# we can. If the macro table were to attribute more than one
+# #inclusion to the same source line, then GDB wouldn't be able to
+# tell which #included file's #definitions and #undefinitions come
+# first, so it can't tell which #definitions are in scope following
+# all the #inclusions. To cope with this, GDB puts all the files
+# #included by a given source file in a list sorted by the line at
+# which they were #included; this gives GDB the chance to detect
+# multiple #inclusions at the same line, complain, and assign
+# distinct, albiet incorrect, line numbers to each #inclusion.
+#
+# However, at one point GDB was sorting the list in reverse order,
+# while the code to assign new, distinct line numbers assumed it was
+# sorted in ascending order; GDB would get an internal error trying to
+# read the above debugging info.
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "lineinc"
+set binfile ${objdir}/${subdir}/${testfile}
+
+
+if {[gdb_compile "${srcdir}/${subdir}/${testfile}.c" ${binfile} executable {debug}] != ""} {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# Any command that causes GDB to read the debugging info for the
+# lineinc.c compilation unit will do here.
+set test_name "tolerate macro info with multiple #inclusions per line"
+gdb_test_multiple "break main" $test_name {
+ -re "Breakpoint 1 at 0x.*: file .*lineinc.c.*\\.\r\n${gdb_prompt}" {
+ pass $test_name
+ }
+ -re ".*internal-error:.*.y or n. " {
+ fail $test_name
+ send_gdb "y\n"
+ gdb_expect {
+ -re ".*.y or n. " {
+ send_gdb "n\n"
+ exp_continue
+ }
+ -re "$gdb_prompt" {
+ }
+ timeout {
+ fail "$test_name (timeout)"
+ }
+ }
+ }
+}
--- /dev/null
+#define FOO 1
--- /dev/null
+#undef FOO
+#define FOO 2
--- /dev/null
+#undef FOO
+#define FOO 3
--- /dev/null
+/* This file is part of GDB, the GNU debugger.
+
+ Copyright 2004 Free Software Foundation, Inc.
+
+ 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.
+
+ Please email any bugs, comments, and/or additions to this file to:
+ bug-gdb@prep.ai.mit.edu */
+
+void
+say_hello (void)
+{
+ printf ("Hello world.\n");
+}
--- /dev/null
+/* This file is part of GDB, the GNU debugger.
+
+ Copyright 2004 Free Software Foundation, Inc.
+
+ 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.
+
+ Please email any bugs, comments, and/or additions to this file to:
+ bug-gdb@prep.ai.mit.edu */
+
+#include <stdio.h>
+
+/* Include a .c file. This is usually considered bad practice in C,
+ but this emulate a practice which is common in other languages.
+ One such language is Ada and its concept of "separates", for instance. */
+#include "sep-proc.c"
+
+int
+main (void)
+{
+ say_hello ();
+ return 0;
+}
+
--- /dev/null
+# Copyright 2004 Free Software Foundation, Inc.
+#
+# 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.
+#
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set testfile "sep"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-w}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# Try to display the source code inside a file which is included by
+# another source file. The purpose of this test is to verify that
+# this operation works, even before we have loaded full symbols for
+# that file (by doing a "break say_hello" for instance).
+#
+# We just check that the command succeeds, so no need to match the
+# complete exact output. Simply verifying that we get procedure
+# say_hello is good enough, and avoid unnecessary failures is someone
+# decides later to reformat sep-proc.c.
+
+gdb_test "list sep-proc.c:23" \
+ "void.*say_hello.*" \
+ "list using location inside included file"
+
+# Try the same, but this time with a breakpoint. We need to exit
+# GDB to make sure that we havn't loaded the full symbols yet when
+# we test the breakpoint insertion.
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+set test "breakpoint inside included file"
+gdb_test_multiple "break sep-proc.c:25" "$test" {
+ -re "Breakpoint.*at.* file .*sep-proc.c, line .*" {
+ pass "$test"
+ }
+ -re "No source file named sep-proc.c.*" {
+ fail "$test"
+ }
+}
+
--- /dev/null
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2004 Free Software Foundation, Inc.
+
+ 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.
+
+ Please email any bugs, comments, and/or additions to this file to:
+ bug-gdb@prep.ai.mit.edu */
+
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+
+enum level { MAIN, OUTER, INNER, LEAF, NR_LEVELS };
+
+/* Levels completed flag. */
+volatile enum level level = NR_LEVELS;
+
+void catcher (int signal);
+
+void
+thrower (enum level next_level, int sig, int itimer, int on_stack)
+{
+ level = next_level;
+ /* Set up the signal handler. */
+ {
+ struct sigaction act;
+ memset (&act, 0, sizeof (act));
+ act.sa_handler = catcher;
+ act.sa_flags |= on_stack;
+ sigaction (sig, &act, NULL);
+ }
+ /* Set up a one-off timer. A timer, rather than SIGSEGV, is used as
+ after a timer handler finishes the interrupted code can safely
+ resume. */
+ {
+ struct itimerval itime;
+ memset (&itime, 0, sizeof (itime));
+ itime.it_value.tv_usec = 250 * 1000;
+ setitimer (itimer, &itime, NULL);
+ }
+ /* Wait. */
+ while (level != LEAF);
+}
+
+void
+catcher (int signal)
+{
+ /* Find the next level. */
+ switch (level)
+ {
+ case MAIN:
+ thrower (OUTER, SIGALRM, ITIMER_REAL, SA_ONSTACK);
+ break;
+ case OUTER:
+ thrower (INNER, SIGVTALRM, ITIMER_VIRTUAL, SA_ONSTACK);
+ break;
+ case INNER:
+ level = LEAF;
+ return;
+ }
+}
+
+
+main ()
+{
+ /* Set up the altstack. */
+ {
+ static char stack[SIGSTKSZ * NR_LEVELS];
+ struct sigaltstack alt;
+ memset (&alt, 0, sizeof (alt));
+ alt.ss_sp = stack;
+ alt.ss_size = SIGSTKSZ;
+ alt.ss_flags = 0;
+ if (sigaltstack (&alt, NULL) < 0)
+ {
+ perror ("sigaltstack");
+ exit (0);
+ }
+ }
+ level = MAIN;
+ catcher (0);
+}
--- /dev/null
+# Copyright 2004 Free Software Foundation, Inc.
+
+# 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.
+
+
+# The program sigaltstack.c creates a backtrace containing nested
+# signal handlers on an alternative stack. This in turn leads to a
+# non-contiguous (and possibly non-monotonic) backtrace - stack
+# address jump at the normal-alt stack boundary.
+
+# This test confirms that GDB can both backtrace through and finish
+# such a stack.
+
+if [target_info exists gdb,nosignals] {
+ verbose "Skipping signals.exp because of nosignals."
+ continue
+}
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile sigaltstack
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ untested "Couldn't compile ${module}.c"
+ return -1
+}
+
+# get things started
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# Pass all the alarms straight through (but verbosely)
+gdb_test "handle SIGALRM print pass nostop"
+gdb_test "handle SIGVTALRM print pass nostop"
+gdb_test "handle SIGPROF print pass nostop"
+
+# Advance to main
+if { ![runto_main] } then {
+ gdb_suppress_tests;
+}
+
+# Stop in handle, when at the inner most level
+gdb_test "break catcher if level == INNER"
+gdb_test "continue" ".* catcher .*" "continue to catch"
+# step off the assignment
+gdb_test "next"
+
+# Full backtrace?
+send_gdb "bt\n"
+gdb_expect_list "backtrace" ".*$gdb_prompt $" {
+ "\[\r\n\]+.0 \[^\r\n\]* catcher "
+ "\[\r\n\]+.1 .signal handler called."
+ "\[\r\n\]+.2 \[^\r\n\]* thrower .next_level=INNER"
+ "\[\r\n\]+.3 \[^\r\n\]* catcher "
+ "\[\r\n\]+.4 .signal handler called."
+ "\[\r\n\]+.5 \[^\r\n\]* thrower .next_level=OUTER"
+ "\[\r\n\]+.6 \[^\r\n\]* catcher "
+ "\[\r\n\]+.7 \[^\r\n\]* main .*"
+}
+
+proc finish_test { pattern msg } {
+ global gdb_prompt
+
+ gdb_test_multiple "finish" $msg {
+ -re "Cannot insert breakpoint 0.*${gdb_prompt} $" {
+ # Some platforms use a special read-only page for signal
+ # trampolines. We can't set a breakpoint there, and we
+ # don't gracefully fall back to single-stepping.
+ setup_kfail "i?86-*-linux*" gdb/1736
+ fail "$msg (could not set breakpoint)"
+ }
+ -re "$pattern.*${gdb_prompt} $" {
+ pass $msg
+ }
+ }
+}
+
+# Finish?
+finish_test "signal handler called." "finish from catch LEAF"
+finish_test "thrower .next_level=INNER, .*" "finish to throw INNER"
+finish_test "catcher .*" "finish to catch INNER"
+finish_test "signal handler called.*" "finish from catch INNER"
+finish_test "thrower .next_level=OUTER, .*" "finish to OUTER"
+finish_test "catcher .*" "finish to catch MAIN"
+finish_test "main .*" "finish to MAIN"
--- /dev/null
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2004 Free Software Foundation, Inc.
+
+ 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 <signal.h>
+#include <stdlib.h>
+#include <string.h>
+
+extern void
+keeper (int sig)
+{
+}
+
+volatile long v1 = 0;
+volatile long v2 = 0;
+volatile long v3 = 0;
+
+extern long
+bowler (void)
+{
+ /* Try to read address zero. Do it in a slightly convoluted way so
+ that more than one instruction is used. */
+ return *(char *) (v1 + v2 + v3);
+}
+
+int
+main ()
+{
+ static volatile int i;
+
+ struct sigaction act;
+ memset (&act, 0, sizeof act);
+ act.sa_handler = keeper;
+ sigaction (SIGSEGV, &act, NULL);
+
+ bowler ();
+ return 0;
+}
--- /dev/null
+# This testcase is part of GDB, the GNU debugger.
+
+# Copyright 2004 Free Software Foundation, Inc.
+
+# 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.
+
+# Check that GDB can and only executes single instructions when
+# stepping through a sequence of breakpoints interleaved by a signal
+# handler.
+
+# This test is known to tickle the following problems: kernel letting
+# the inferior execute both the system call, and the instruction
+# following, when single-stepping a system call; kernel failing to
+# propogate the single-step state when single-stepping the sigreturn
+# system call, instead resuming the inferior at full speed; GDB
+# doesn't know how to software single-step across a sigreturn
+# instruction. Since the kernel problems can be "fixed" using
+# software single-step this is KFAILed rather than XFAILed.
+
+if $tracelevel {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "sigbpt"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+#
+# Run to `main' where we begin our tests.
+#
+
+if ![runto_main] then {
+ gdb_suppress_tests
+}
+
+# If we can examine what's at memory address 0, it is possible that we
+# could also execute it. This could probably make us run away,
+# executing random code, which could have all sorts of ill effects,
+# especially on targets without an MMU. Don't run the tests in that
+# case.
+
+send_gdb "x 0\n"
+gdb_expect {
+ -re "0x0:.*Cannot access memory at address 0x0.*$gdb_prompt $" { }
+ -re "0x0:.*Error accessing memory address 0x0.*$gdb_prompt $" { }
+ -re ".*$gdb_prompt $" {
+ untested "Memory at address 0 is possibly executable"
+ return
+ }
+}
+
+gdb_test "break keeper"
+
+# Run to bowler, and then single step until there's a SIGSEGV. Record
+# the address of each single-step instruction (up to and including the
+# instruction that causes the SIGSEGV) in bowler_addrs, and the address
+# of the actual SIGSEGV in segv_addr.
+
+set bowler_addrs bowler
+gdb_test {display/i $pc}
+gdb_test "advance *bowler" "bowler.*" "advance to the bowler"
+set test "stepping to SIGSEGV"
+gdb_test_multiple "stepi" "$test" {
+ -re "Program received signal SIGSEGV.*pc *(0x\[0-9a-f\]*).*$gdb_prompt $" {
+ set segv_addr $expect_out(1,string)
+ pass "$test"
+ }
+ -re " .*pc *(0x\[0-9a-f\]*).*bowler.*$gdb_prompt $" {
+ set bowler_addrs [concat $expect_out(1,string) $bowler_addrs]
+ send_gdb "stepi\n"
+ exp_continue
+ }
+}
+
+# Now record the address of the instruction following the faulting
+# instruction in bowler_addrs.
+
+set test "get insn after fault"
+gdb_test_multiple {x/2i $pc} "$test" {
+ -re "(0x\[0-9a-f\]*).*bowler.*(0x\[0-9a-f\]*).*bowler.*$gdb_prompt $" {
+ set bowler_addrs [concat $expect_out(2,string) $bowler_addrs]
+ pass "$test"
+ }
+}
+
+# Procedures for returning the address of the instruction before, at
+# and after, the faulting instruction.
+
+proc before_segv { } {
+ global bowler_addrs
+ return [lindex $bowler_addrs 2]
+}
+
+proc at_segv { } {
+ global bowler_addrs
+ return [lindex $bowler_addrs 1]
+}
+
+proc after_segv { } {
+ global bowler_addrs
+ return [lindex $bowler_addrs 0]
+}
+
+# Check that the address table and SIGSEGV correspond.
+
+set test "Verify that SIGSEGV occurs at the last STEPI insn"
+if {[string compare $segv_addr [at_segv]] == 0} {
+ pass "$test"
+} else {
+ fail "$test ($segv_addr [at_segv])"
+}
+
+# Check that the inferior is correctly single stepped all the way back
+# to a faulting instruction.
+
+proc stepi_out { name args } {
+ global gdb_prompt
+
+ # Set SIGSEGV to pass+nostop and then run the inferior all the way
+ # through to the signal handler. With the handler is reached,
+ # disable SIGSEGV, ensuring that further signals stop the
+ # inferior. Stops a SIGSEGV infinite loop when a broke system
+ # keeps re-executing the faulting instruction.
+ rerun_to_main
+ gdb_test "handle SIGSEGV nostop print pass" "" "${name}; pass SIGSEGV"
+ gdb_test "continue" "keeper.*" "${name}; continue to keeper"
+ gdb_test "handle SIGSEGV stop print nopass" "" "${name}; nopass SIGSEGV"
+
+ # Insert all the breakpoints. To avoid the need to step over
+ # these instructions, this is delayed until after the keeper has
+ # been reached.
+ for {set i 0} {$i < [llength $args]} {incr i} {
+ gdb_test "break [lindex $args $i]" "Breakpoint.*" \
+ "${name}; set breakpoint $i of [llength $args]"
+ }
+
+ # Single step our way out of the keeper, through the signal
+ # trampoline, and back to the instruction that faulted.
+ set test "${name}; stepi out of handler"
+ gdb_test_multiple "stepi" "$test" {
+ -re "keeper.*$gdb_prompt $" {
+ send_gdb "stepi\n"
+ exp_continue
+ }
+ -re "signal handler.*$gdb_prompt $" {
+ send_gdb "stepi\n"
+ exp_continue
+ }
+ -re "Program received signal SIGSEGV.*$gdb_prompt $" {
+ kfail gdb/1702 "$test (executed fault insn)"
+ }
+ -re "Breakpoint.*pc *[at_segv] .*bowler.*$gdb_prompt $" {
+ pass "$test (at breakpoint)"
+ }
+ -re "Breakpoint.*pc *[after_segv] .*bowler.*$gdb_prompt $" {
+ kfail gdb/1702 "$test (executed breakpoint)"
+ }
+ -re "pc *[at_segv] .*bowler.*$gdb_prompt $" {
+ pass "$test"
+ }
+ -re "pc *[after_segv] .*bowler.*$gdb_prompt $" {
+ kfail gdb/1702 "$test (skipped fault insn)"
+ }
+ -re "pc *0x\[a-z0-9\]* .*bowler.*$gdb_prompt $" {
+ kfail gdb/1702 "$test (corrupt pc)"
+ }
+ }
+
+ # Clear any breakpoints
+ for {set i 0} {$i < [llength $args]} {incr i} {
+ gdb_test "clear [lindex $args $i]" "Deleted .*" \
+ "${name}; clear breakpoint $i of [llength $args]"
+ }
+}
+
+# Let a signal handler exit, returning to a breakpoint instruction
+# inserted at the original fault instruction. Check that the
+# breakpoint is hit, and that single stepping off that breakpoint
+# executes the underlying fault instruction causing a SIGSEGV.
+
+proc cont_out { name args } {
+ global gdb_prompt
+
+ # Set SIGSEGV to pass+nostop and then run the inferior all the way
+ # through to the signal handler. With the handler is reached,
+ # disable SIGSEGV, ensuring that further signals stop the
+ # inferior. Stops a SIGSEGV infinite loop when a broke system
+ # keeps re-executing the faulting instruction.
+ rerun_to_main
+ gdb_test "handle SIGSEGV nostop print pass" "" "${name}; pass SIGSEGV"
+ gdb_test "continue" "keeper.*" "${name}; continue to keeper"
+ gdb_test "handle SIGSEGV stop print nopass" "" "${name}; nopass SIGSEGV"
+
+ # Insert all the breakpoints. To avoid the need to step over
+ # these instructions, this is delayed until after the keeper has
+ # been reached. Always set a breakpoint at the signal trampoline
+ # instruction.
+ set args [concat $args "*[at_segv]"]
+ for {set i 0} {$i < [llength $args]} {incr i} {
+ gdb_test "break [lindex $args $i]" "Breakpoint.*" \
+ "${name}; set breakpoint $i of [llength $args]"
+ }
+
+ # Let the handler return, it should "appear to hit" the breakpoint
+ # inserted at the faulting instruction. Note that the breakpoint
+ # instruction wasn't executed, rather the inferior was SIGTRAPed
+ # with the PC at the breakpoint.
+ gdb_test "continue" "Breakpoint.*pc *[at_segv] .*" \
+ "${name}; continue to breakpoint at fault"
+
+ # Now single step the faulted instrction at that breakpoint.
+ gdb_test "stepi" \
+ "Program received signal SIGSEGV.*pc *[at_segv] .*" \
+ "${name}; stepi fault"
+
+ # Clear any breakpoints
+ for {set i 0} {$i < [llength $args]} {incr i} {
+ gdb_test "clear [lindex $args $i]" "Deleted .*" \
+ "${name}; clear breakpoint $i of [llength $args]"
+ }
+
+}
+
+
+
+# Try to confuse DECR_PC_AFTER_BREAK architectures by scattering
+# breakpoints around the faulting address. In all cases the inferior
+# should single-step out of the signal trampoline halting (but not
+# executing) the fault instruction.
+
+stepi_out "stepi"
+stepi_out "stepi bp before segv" "*[before_segv]"
+stepi_out "stepi bp at segv" "*[at_segv]"
+stepi_out "stepi bp before and at segv" "*[at_segv]" "*[before_segv]"
+
+
+# Try to confuse DECR_PC_AFTER_BREAK architectures by scattering
+# breakpoints around the faulting address. In all cases the inferior
+# should exit the signal trampoline halting at the breakpoint that
+# replaced the fault instruction.
+cont_out "cont"
+cont_out "cont bp after segv" "*[before_segv]"
+cont_out "cont bp before and after segv" "*[before_segv]" "*[after_segv]"
--- /dev/null
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2004 Free Software Foundation, Inc.
+
+ 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 <stdio.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/time.h>
+
+static volatile int done;
+
+#ifdef SA_SIGINFO
+static void /* HANDLER */
+handler (int sig, siginfo_t *info, void *context)
+{
+ done = 1;
+} /* handler */
+#else
+static void
+handler (int sig)
+{
+ done = 1;
+} /* handler */
+#endif
+
+main ()
+{
+ /* Set up the signal handler. */
+ {
+ struct sigaction action;
+ memset (&action, 0, sizeof (action));
+#ifdef SA_SIGINFO
+ action.sa_sigaction = handler;
+ action.sa_flags |= SA_SIGINFO;
+#else
+ action.sa_handler = handler;
+#endif
+ sigaction (SIGVTALRM, &action, NULL);
+ }
+
+ /* Set up a one-off timer. A timer, rather than SIGSEGV, is used as
+ after a timer handler finishes the interrupted code can safely
+ resume. */
+ {
+ struct itimerval itime;
+ memset (&itime, 0, sizeof (itime));
+ itime.it_value.tv_usec = 250 * 1000;
+ setitimer (ITIMER_VIRTUAL, &itime, NULL);
+ }
+ /* Wait. */
+ while (!done);
+ return 0;
+} /* main */
--- /dev/null
+# Copyright 2004 Free Software Foundation, Inc.
+
+# 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.
+
+
+# The program siginfo.c creates a backtrace containing a signal
+# handler registered using sigaction's sa_sigaction / SA_SIGINFO.
+# Some OS's (e.g., GNU/Linux) use different signal trampolines for
+# sa_sigaction and sa_handler.
+
+# This test first confirms that GDB can backtrace through the
+# alternative sa_sigaction signal handler, and second that GDB can
+# nexti/stepi out of such a handler.
+
+if [target_info exists gdb,nosignals] {
+ verbose "Skipping signals.exp because of nosignals."
+ continue
+}
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile siginfo
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ untested "Couldn't compile ${module}.c"
+ return -1
+}
+
+# get things started
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+gdb_test "display/i \$pc"
+
+# Advance to main
+if { ![runto_main] } then {
+ gdb_suppress_tests;
+}
+
+# Pass all the alarms straight through (but verbosely)
+# gdb_test "handle SIGALRM print pass nostop"
+# gdb_test "handle SIGVTALRM print pass nostop"
+# gdb_test "handle SIGPROF print pass nostop"
+
+# Run to the signal handler, validate the backtrace.
+gdb_test "break handler"
+gdb_test "continue" ".* handler .*" "continue to stepi handler"
+send_gdb "bt\n"
+gdb_expect_list "backtrace for nexti" ".*$gdb_prompt $" {
+ "\[\r\n\]+.0 \[^\r\n\]* handler "
+ "\[\r\n\]+.1 .signal handler called."
+ "\[\r\n\]+.2 \[^\r\n\]* main .*"
+}
+
+# Check that GDB can step the inferior back to main
+set test "step out of handler"
+gdb_test_multiple "step" "${test}" {
+ -re "done = 1;.*${gdb_prompt} $" {
+ send_gdb "$i\n"
+ exp_continue
+ }
+ -re "\} .. handler .*${gdb_prompt} $" {
+ send_gdb "step\n"
+ exp_continue
+ }
+ -re "Program exited normally.*${gdb_prompt} $" {
+ kfail gdb/1613 "$test (program exited)"
+ }
+ -re "(while ..done|return 0).*${gdb_prompt} $" {
+ # After stepping out of a function /r signal-handler, GDB will
+ # advance the inferior until it is at the first instruction of
+ # a code-line. While typically things return to the middle of
+ # the "while..." (and hence GDB advances the inferior to the
+ # "return..." line) it is also possible for the return to land
+ # on the first instruction of "while...". Accept both cases.
+ pass "$test"
+ }
+}
--- /dev/null
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 1996, 1999, 2003, 2004 Free Software Foundation, Inc.
+
+ 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 <signal.h>
+#include <setjmp.h>
+#include <stdlib.h>
+#include <string.h>
+
+enum tests {
+ code_entry_point, code_descriptor, data_read, data_write
+};
+
+static volatile enum tests test;
+
+/* Some basic types and zero buffers. */
+
+typedef long data_t;
+typedef long code_t (void);
+data_t *volatile data;
+code_t *volatile code;
+/* "desc" is intentionally initialized to a data object. This is
+ needed to test function descriptors on arches like ia64. */
+data_t zero[10];
+code_t *volatile desc = (code_t *) (void *) zero;
+
+sigjmp_buf env;
+
+extern void
+keeper (int sig)
+{
+ siglongjmp (env, 0);
+}
+
+extern long
+bowler (void)
+{
+ switch (test)
+ {
+ case data_read:
+ /* Try to read address zero. */
+ return (*data);
+ case data_write:
+ /* Try to write (the assignment) to address zero. */
+ return (*data) = 1;
+ case code_entry_point:
+ /* For typical architectures, call a function at address
+ zero. */
+ return (*code) ();
+ case code_descriptor:
+ /* For atypical architectures that use function descriptors,
+ call a function descriptor, the code field of which is zero
+ (which has the effect of jumping to address zero). */
+ return (*desc) ();
+ }
+}
+
+int
+main ()
+{
+ static volatile int i;
+
+ struct sigaction act;
+ memset (&act, 0, sizeof act);
+ act.sa_handler = keeper;
+ sigaction (SIGSEGV, &act, NULL);
+
+ for (i = 0; i < 10; i++)
+ {
+ sigsetjmp (env, 1);
+ bowler ();
+ }
+}
--- /dev/null
+# This testcase is part of GDB, the GNU debugger.
+
+# Copyright 2004 Free Software Foundation, Inc.
+
+# 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.
+
+# Check that GDB can trigger and backtrace SIGSEGV signal stacks
+# caused by both accessing (data) and executing (code) at address
+# zero.
+
+# On function descriptor architectures, a zero descriptor, instead of
+# a NULL pointer, is used. That way the NULL code test always
+# contains a zero code reference.
+
+# For recovery, sigjmp/longjmp are used.
+
+# This also tests backtrace/gdb1476.
+
+if $tracelevel {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "signull"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+#
+# Run to `main' where we begin our tests.
+#
+
+if ![runto_main] then {
+ gdb_suppress_tests
+}
+
+# If we can examine what's at memory address 0, it is possible that we
+# could also execute it. This could probably make us run away,
+# executing random code, which could have all sorts of ill effects,
+# especially on targets without an MMU. Don't run the tests in that
+# case.
+
+send_gdb "x 0\n"
+gdb_expect {
+ -re "0x0:.*Cannot access memory at address 0x0.*$gdb_prompt $" { }
+ -re "0x0:.*Error accessing memory address 0x0.*$gdb_prompt $" { }
+ -re ".*$gdb_prompt $" {
+ untested "Memory at address 0 is possibly executable"
+ return
+ }
+}
+
+# If an attempt to call a NULL pointer leaves the inferior in main,
+# then function pointers are descriptors, probe this and remember the
+# result.
+
+gdb_test "set test = code_entry_point" "" "set for function pointer probe"
+set test "probe function pointer"
+set function_pointer code_entry_point
+gdb_test_multiple "continue" "$test" {
+ -re "Program received signal SIGSEGV.*bowler .*$gdb_prompt $" {
+ set function_pointer code_descriptor
+ pass "$test (function descriptor)"
+ }
+ -re "Program received signal SIGSEGV.*0.*$gdb_prompt $" {
+ pass "$test (function entry-point)"
+ }
+}
+
+# Re-start from scratch, breakpoint the bowler so that control is
+# regained after each test, and run up to that.
+rerun_to_main
+gdb_test "break bowler"
+gdb_test "break keeper"
+# By default Stop:Yes Print:Yes Pass:Yes
+gdb_test "handle SIGSEGV" "SIGSEGV.*Yes.*Yes.*Yes.*Segmentation fault"
+
+# For the given signal type, check that: the SIGSEGV occures; a
+# backtrace from the SEGV works; the sigsegv is delivered; a backtrace
+# through the SEGV works.
+
+proc test_segv { name tag bt_from_segv bt_from_keeper } {
+ gdb_test continue "Breakpoint.* bowler.*" "${name}; start with the bowler"
+ # NB: Don't use $tag in the testname - changes across systems.
+ gdb_test "set test = $tag" "" "${name}; select the pointer type"
+ gdb_test continue "Program received signal SIGSEGV.*" \
+ "${name}; take the SIGSEGV"
+ gdb_test backtrace $bt_from_segv "${name}; backtrace from SIGSEGV"
+ gdb_test continue "Breakpoint.* keeper.*" "${name}; continue to the keeper"
+ gdb_test backtrace $bt_from_keeper "${name}; backtrace from keeper through SIGSEGV"
+}
+
+test_segv "data read" data_read \
+ {#0 .* bowler .*#1 .* main .*} \
+ {#0 .* keeper .*#1 .* handler .*#2 .* bowler .*#3 .* main .*}
+test_segv "data write" data_write \
+ {#0 .* bowler .*#1 .* main .*} \
+ {#0 .* keeper .*#1 .* handler .*#2 .* bowler .*#3 .* main .*}
+test_segv code $function_pointer \
+ {#0 .* 0x0+ .*#1 .* bowler .*#2 .* main .*} \
+ {#0 .* keeper .*#1 .* handler .*#2 .* 0x0+ .*#3 .* bowler .*#4 .* main .*}
--- /dev/null
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2004 Free Software Foundation, Inc.
+
+ 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 <stdio.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/time.h>
+
+static volatile int done;
+
+static void
+handler (int sig)
+{
+ done = 1;
+} /* handler */
+
+struct itimerval itime;
+struct sigaction action;
+
+/* The enum is so that GDB can easily see these macro values. */
+enum {
+ itimer_real = ITIMER_REAL,
+ itimer_virtual = ITIMER_VIRTUAL
+} itimer = ITIMER_VIRTUAL;
+
+main ()
+{
+
+ /* Set up the signal handler. */
+ memset (&action, 0, sizeof (action));
+ action.sa_handler = handler;
+ sigaction (SIGVTALRM, &action, NULL);
+ sigaction (SIGALRM, &action, NULL);
+
+ /* The values needed for the itimer. This needs to be at least long
+ enough for the setitimer() call to return. */
+ memset (&itime, 0, sizeof (itime));
+ itime.it_value.tv_usec = 250 * 1000;
+
+ /* Loop for ever, constantly taking an interrupt. */
+ while (1)
+ {
+ /* Set up a one-off timer. A timer, rather than SIGSEGV, is
+ used as after a timer handler finishes the interrupted code
+ can safely resume. */
+ setitimer (itimer, &itime, NULL);
+ /* Wait. */
+ while (!done);
+ done = 0;
+ }
+}
--- /dev/null
+# Copyright 2004 Free Software Foundation, Inc.
+
+# 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.
+
+
+# The program sigstep.c creates a very simple backtrace containing one
+# signal handler and signal trampoline. A flag is set and then the
+# handler returns. This is repeated at infinitum.
+
+# This test runs the program up to the signal handler, and then
+# attempts to step/next out of the handler and back into main.
+
+if [target_info exists gdb,nosignals] {
+ verbose "Skipping sigstep.exp because of nosignals."
+ continue
+}
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile sigstep
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ untested "Couldn't compile ${module}.c"
+ return -1
+}
+
+# get things started
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+gdb_test "display/i \$pc"
+
+# Advance to main
+if { ![runto_main] } then {
+ gdb_suppress_tests;
+}
+
+# Pass all the alarms straight through (but verbosely)
+# gdb_test "handle SIGALRM print pass nostop"
+# gdb_test "handle SIGVTALRM print pass nostop"
+# gdb_test "handle SIGPROF print pass nostop"
+
+# Run to the signal handler, validate the backtrace.
+gdb_test "break handler"
+gdb_test "continue" ".* handler .*" "continue to stepi handler"
+send_gdb "bt\n"
+gdb_expect_list "backtrace for nexti" ".*$gdb_prompt $" {
+ "\[\r\n\]+.0 \[^\r\n\]* handler "
+ "\[\r\n\]+.1 .signal handler called."
+ "\[\r\n\]+.2 \[^\r\n\]* main .*"
+}
+
+proc advance { i } {
+ global gdb_prompt
+ set prefix "$i from handler"
+
+ # Get us back into the handler
+ gdb_test "continue" ".* handler .*" "$prefix; continue to handler"
+
+ set test "$prefix; leave handler"
+ gdb_test_multiple "$i" "${test}" {
+ -re "done = 1;.*${gdb_prompt} $" {
+ send_gdb "$i\n"
+ exp_continue -continue_timer
+ }
+ -re "\} .. handler .*${gdb_prompt} $" {
+ send_gdb "$i\n"
+ exp_continue -continue_timer
+ }
+ -re "Program exited normally.*${gdb_prompt} $" {
+ setup_kfail powerpc-*-*bsd* gdb/1639
+ fail "$test (program exited)"
+ }
+ -re "(while ..done|done = 0).*${gdb_prompt} $" {
+ # After stepping out of a function /r signal-handler, GDB will
+ # advance the inferior until it is at the first instruction of
+ # a code-line. While typically things return to the middle of
+ # the "while..." (and hence GDB advances the inferior to the
+ # "return..." line) it is also possible for the return to land
+ # on the first instruction of "while...". Accept both cases.
+ pass "$test"
+ }
+ }
+}
+
+proc advancei { i } {
+ global gdb_prompt
+ set prefix "$i from handleri"
+ set program_exited 0
+
+ # Get us back into the handler
+ gdb_test "continue" ".* handler .*" "$prefix; continue to handler"
+
+ set test "$prefix; leave handler"
+ gdb_test_multiple "$i" "${test}" {
+ -re "Cannot insert breakpoint 0.*${gdb_prompt} $" {
+ # Some platforms use a special read-only page for signal
+ # trampolines. We can't set a breakpoint there, and we
+ # don't gracefully fall back to single-stepping.
+ setup_kfail "i?86-*-linux*" gdb/1736
+ fail "$test (could not set breakpoint)"
+ return
+ }
+ -re "done = 1;.*${gdb_prompt} $" {
+ send_gdb "$i\n"
+ exp_continue -continue_timer
+ }
+ -re "\} .. handler .*${gdb_prompt} $" {
+ send_gdb "$i\n"
+ exp_continue -continue_timer
+ }
+ -re "signal handler called.*${gdb_prompt} $" {
+ pass "$test"
+ }
+ -re "main .*${gdb_prompt} $" {
+ fail "$test (in main)"
+ }
+ -re "Program exited normally.*${gdb_prompt} $" {
+ fail "$test (program exited)"
+ set program_exited 1
+ }
+ -re "Make handler return now.*y or n. $" {
+ send_gdb "y\n"
+ exp_continue -continue_timer
+ }
+ }
+
+ set test "$prefix; leave signal trampoline"
+ gdb_test_multiple "$i" "${test}" {
+ -re "while .*${gdb_prompt} $" {
+ pass "$test (in main)"
+ }
+ -re "signal handler called.*${gdb_prompt} $" {
+ send_gdb "$i\n"
+ exp_continue -continue_timer
+ }
+ -re "return .*${gdb_prompt} $" {
+ fail "$test (stepped)"
+ }
+ -re "Make .*frame return now.*y or n. $" {
+ send_gdb "y\n"
+ exp_continue -continue_timer
+ }
+ -re "Program exited normally.*${gdb_prompt} $" {
+ kfail gdb/1639 "$test (program exited)"
+ set program_exited 1
+ }
+ -re "The program is not being run.*${gdb_prompt} $" {
+ if { $program_exited } {
+ # Previously kfailed with an exit
+ pass "$test (the program is not being run)"
+ } else {
+ fail "$test (the program is not being run)"
+ }
+ }
+ }
+}
+
+# Check that we can step/next our way out of a signal handler.
+
+advance step
+advancei stepi
+
+advance next
+advancei nexti
+
+advancei finish
+advancei return
+gdb_test "set done = 1" "" "Set done as return will have skipped it"
+
+
+# Check that we can step/next our way into / over a signal handler.
+
+# There are at least the following cases: breakpoint @pc VS breakpoint
+# in handler VS step / next / continue.
+
+# Use the real-time itimer, as otherwize the process never gets enough
+# time to expire the timer.
+
+delete_breakpoints
+set infinite_loop [gdb_get_line_number {while (!done)}]
+gdb_test "set itimer = itimer_real"
+gdb_test "break [gdb_get_line_number {done = 0}]"
+
+# Try stepping when there's a signal pending, and a breakpoint at the
+# handler. Should step into the signal handler.
+
+proc skip_to_handler { i } {
+ global gdb_prompt
+ global infinite_loop
+ set prefix "$i to handler"
+
+ # Run around to the done
+ set test "$prefix; resync"
+ gdb_test_multiple "continue" "$test" {
+ -re "done = 0.*$gdb_prompt " {
+ pass "$test"
+ }
+ # other patterns can go here
+ }
+
+ # Advance to the infinite loop
+ gdb_test "advance $infinite_loop" "" "$prefix; advance to infinite loop"
+
+ # Make the signal pending
+ sleep 1
+
+ # Insert / remove the handler breakpoint.
+ gdb_test "break handler" "" "$prefix; break handler"
+ gdb_test "$i" " handler .*" "$prefix; performing $i"
+ gdb_test "clear handler" "" "$prefix; clear handler"
+}
+
+skip_to_handler step
+skip_to_handler next
+skip_to_handler continue
+
+# Try stepping when there's a signal pending, and a breakpoint at the
+# handler's entry-point. Should step into the signal handler stopping
+# at the entry-point.
+
+# Some systems (e.x., GNU/Linux as of 2004-08-30), when delivering a
+# signal, resume the process at the first instruction of the signal
+# handler and not the first instruction of the signal trampoline. The
+# stack is constructed such that the signal handler still appears to
+# have been called by the trampoline code. This test checks that it
+# is possible to stop the inferior, even at that first instruction.
+
+proc skip_to_handler_entry { i } {
+ global gdb_prompt
+ global infinite_loop
+ set prefix "$i to handler entry"
+
+ # Run around to the done
+ set test "$prefix; resync"
+ gdb_test_multiple "continue" "$test" {
+ -re "done = 0.*$gdb_prompt " {
+ pass "$test"
+ }
+ # other patterns can go here
+ }
+
+ # Advance to the infinite loop
+ gdb_test "advance $infinite_loop" "" "$prefix; advance to infinite loop"
+
+ # Make the signal pending
+ sleep 1
+
+ # Insert / remove the handler breakpoint.
+ gdb_test "break *handler" "" "$prefix; break handler"
+ gdb_test "$i" " handler .*" "$prefix; performing $i"
+ gdb_test "clear *handler" "" "$prefix; clear handler"
+}
+
+skip_to_handler_entry step
+skip_to_handler_entry next
+skip_to_handler_entry continue
+
+# Try stepping when there's a signal pending but no breakpoints.
+# Should skip the handler advancing to the next line.
+
+proc skip_over_handler { i } {
+ global gdb_prompt
+ global infinite_loop
+ set prefix "$i over handler"
+
+ # Run around to the done
+ set test "$prefix; resync"
+ gdb_test_multiple "continue" "$test" {
+ -re "done = 0.*$gdb_prompt " {
+ pass "$test"
+ }
+ # other patterns can go here
+ }
+
+ # Advance to the infinite loop
+ gdb_test "advance $infinite_loop" "" "$prefix; advance to infinite loop"
+
+ # Make the signal pending
+ sleep 1
+
+ gdb_test "$i" "done = 0.*" "$prefix; performing $i"
+}
+
+skip_over_handler step
+skip_over_handler next
+skip_over_handler continue
+
+# Try stepping when there's a signal pending, a pre-existing
+# breakpoint at the current instruction, and a breakpoint in the
+# handler. Should advance to the signal handler.
+
+proc breakpoint_to_handler { i } {
+ global gdb_prompt
+ global infinite_loop
+ set prefix "$i on breakpoint, to handler"
+
+ # Run around to the done
+ set test "$prefix; resync"
+ gdb_test_multiple "continue" "$test" {
+ -re "done = 0.*$gdb_prompt " {
+ pass "$test"
+ }
+ # other patterns can go here
+ }
+
+ gdb_test "break $infinite_loop" "" "$prefix; break infinite loop"
+ gdb_test "break handler" "" "$prefix; break handler"
+
+ # Continue to the infinite loop
+ gdb_test "continue" "while ..done.*" "$prefix; continue to infinite loop"
+
+ # Make the signal pending
+ sleep 1
+
+ setup_kfail "i*86-*-*" gdb/1738
+ gdb_test "$i" " handler .*" "$prefix; performing $i"
+ gdb_test "clear $infinite_loop" "" "$prefix; clear infinite loop"
+ gdb_test "clear handler" "" "$prefix; clear handler"
+}
+
+breakpoint_to_handler step
+breakpoint_to_handler next
+breakpoint_to_handler continue
+
+# Try stepping when there's a signal pending, and a breakpoint at the
+# handler's entry instruction and a breakpoint at the current
+# instruction. Should step into the signal handler and breakpoint at
+# that entry instruction.
+
+# Some systems (e.x., GNU/Linux as of 2004-08-30), when delivering a
+# signal, resume the process at the first instruction of the signal
+# handler and not the first instruction of the signal trampoline. The
+# stack is constructed such that the signal handler still appears to
+# have been called by the trampoline code. This test checks that it
+# is possible to stop the inferior, even at that first instruction.
+
+proc breakpoint_to_handler_entry { i } {
+ global gdb_prompt
+ global infinite_loop
+ set prefix "$i on breakpoint, to handler entry"
+
+ # Run around to the done
+ set test "$prefix; resync"
+ gdb_test_multiple "continue" "$test" {
+ -re "done = 0.*$gdb_prompt " {
+ pass "$test"
+ }
+ # other patterns can go here
+ }
+
+ gdb_test "break $infinite_loop" "" "$prefix; break infinite loop"
+ gdb_test "break *handler" "" "$prefix; break handler"
+
+ # Continue to the infinite loop
+ gdb_test "continue" "while ..done.*" "$prefix; continue to infinite loop"
+
+ # Make the signal pending
+ sleep 1
+
+ setup_kfail "i*86-*-*" gdb/1738
+ gdb_test "$i" " handler .*" "$prefix; performing $i"
+ gdb_test "clear $infinite_loop" "" "$prefix; clear infinite loop"
+ gdb_test "clear *handler" "" "$prefix; clear handler"
+}
+
+breakpoint_to_handler_entry step
+breakpoint_to_handler_entry next
+breakpoint_to_handler_entry continue
+
+# Try stepping when there's a signal pending, and a pre-existing
+# breakpoint at the current instruction, and no breakpoint in the
+# handler. Should advance to the next line.
+
+proc breakpoint_over_handler { i } {
+ global gdb_prompt
+ global infinite_loop
+ set prefix "$i on breakpoint, skip handler"
+
+ # Run around to the done
+ set test "$prefix; resync"
+ gdb_test_multiple "continue" "$test" {
+ -re "done = 0.*$gdb_prompt " {
+ pass "$test"
+ }
+ # other patterns can go here
+ }
+
+ gdb_test "break $infinite_loop" "" "$prefix; break infinite loop"
+
+ # Continue to the infinite loop
+ gdb_test "continue" "while ..done.*" "$prefix; continue to infinite loop"
+
+ # Make the signal pending
+ sleep 1
+
+ gdb_test "$i" "done = 0.*" "$prefix; performing $i"
+ gdb_test "clear $infinite_loop" "" "$prefix; clear infinite loop"
+}
+
+breakpoint_over_handler step
+breakpoint_over_handler next
+breakpoint_over_handler continue
--- /dev/null
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2004 Free Software Foundation, Inc.
+
+ 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 <stdio.h>
+#include <stdlib.h>
+#include <dlfcn.h>
+
+int k = 0;
+
+#define SHLIB_NAME SHLIB_DIR "/unloadshr.sl"
+
+int main()
+{
+ void *handle;
+ int (*unloadshr) (int);
+ int y;
+ const char *msg;
+
+ handle = dlopen (SHLIB_NAME, RTLD_LAZY);
+ msg = dlerror ();
+
+ if (!handle)
+ {
+ fprintf (stderr, msg);
+ exit (1);
+ }
+
+ unloadshr = (int (*)(int))dlsym (handle, "shrfunc1");
+
+ if (!unloadshr)
+ {
+ fprintf (stderr, dlerror ());
+ exit (1);
+ }
+
+ y = (*unloadshr)(3);
+
+ printf ("y is %d\n", y);
+
+ dlclose (handle);
+
+ return 0;
+}
--- /dev/null
+# Copyright 2003, 2004
+# Free Software Foundation, Inc.
+
+# 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.
+
+# This file was created by Jeff Johnston. (jjohnstn@redhat.com)
+# The shared library compilation portion was copied from shlib-call.exp which was
+# written by Elena Zannoni (ezannoni@redhat.com).
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+# are we on a target board?
+if ![isnative] then {
+ return 0
+}
+
+set testfile "unload"
+set libfile "unloadshr"
+set libsrcfile ${libfile}.c
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+set shlibdir ${objdir}/${subdir}
+
+if [get_compiler_info ${binfile}] {
+ return -1
+}
+
+set dl_lib_flag ""
+switch -glob [istarget] {
+ "hppa*-hp-hpux*" { }
+ "*-*-linux*" { set dl_lib_flag "libs=-ldl" }
+ "*-*-solaris*" { set dl_lib_flag "libs=-ldl" }
+ default { }
+}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "additional_flags=-DSHLIB_DIR\=\"${shlibdir}\"" $dl_lib_flag]] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+# Build the shared libraries this test case needs.
+#
+
+if {$gcc_compiled == 0} {
+ if [istarget "hppa*-hp-hpux*"] then {
+ set additional_flags "additional_flags=+z"
+ } elseif { [istarget "mips-sgi-irix*"] } {
+ # Disable SGI compiler's implicit -Dsgi
+ set additional_flags "additional_flags=-Usgi"
+ } else {
+ # don't know what the compiler is...
+ set additional_flags ""
+ }
+} else {
+ if { ([istarget "powerpc*-*-aix*"]
+ || [istarget "rs6000*-*-aix*"]) } {
+ set additional_flags ""
+ } else {
+ set additional_flags "additional_flags=-fpic"
+ }
+}
+
+if {[gdb_compile "${srcdir}/${subdir}/${libsrcfile}" "${objdir}/${subdir}/${libfile}.o" object [list debug $additional_flags]] != ""} {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+if [istarget "hppa*-*-hpux*"] {
+ remote_exec build "ld -b ${objdir}/${subdir}/${libfile}.o -o ${objdir}/${subdir}/${libfile}.sl"
+} else {
+ set additional_flags "additional_flags=-shared"
+ if {[gdb_compile "${objdir}/${subdir}/${libfile}.o" "${objdir}/${subdir}/${libfile}.sl" executable [list debug $additional_flags]] != ""} {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+ }
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if [target_info exists gdb_stub] {
+ gdb_step_for_stub;
+}
+
+#
+# Test setting a breakpoint in a dynamically loaded library which is
+# manually loaded and unloaded
+#
+
+gdb_test_multiple "break shrfunc1" "set pending breakpoint" {
+ -re ".*Make breakpoint pending.*y or \\\[n\\\]. $" {
+ gdb_test "y" "Breakpoint.*shrfunc1.*pending." "set pending breakpoint"
+ }
+}
+
+gdb_test "info break" \
+ "Num Type\[ \]+Disp Enb Address\[ \]+What.*
+\[0-9\]+\[\t \]+breakpoint keep y.*PENDING.*shrfunc1.*" \
+"single pending breakpoint info"
+
+set unloadshr_line [gdb_get_line_number "unloadshr break" ${srcdir}/${subdir}/${libsrcfile}]
+
+gdb_test "run" \
+"Starting program.*unload.*
+Breakpoint.*at.*
+Pending breakpoint \"shrfunc1\" resolved.*
+Breakpoint.*, shrfunc1 \\\(x=3\\\).*unloadshr.c:$unloadshr_line.*" \
+"running program"
+
+gdb_test "continue" \
+"Continuing.*y is 7.*warning: Temporarily disabling breakpoints for.*unloadshr.sl.*Program exited normally." \
+"continuing to end of program"
+
+#
+# Try to rerun program and verify that shared breakpoint is reset properly
+#
+
+gdb_test "run" \
+".*Breakpoint.*shrfunc1.*at.*unloadshr.c:$unloadshr_line.*" \
+"rerun to shared library breakpoint"
+
+gdb_test "continue" \
+"Continuing.*y is 7.*warning: Temporarily disabling breakpoints for.*unloadshr.sl.*Program exited normally." \
+"continuing to end of program second time"
+
--- /dev/null
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2004 Free Software Foundation, Inc.
+
+ 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 <stdio.h>
+
+int shrfunc1 (int x)
+{
+ return x + 4; /* unloadshr break */
+}
--- /dev/null
+# Makefile for regression testing the GNU debugger.
+# Copyright 1992, 1993, 1994, 1995, 1996, 1999, 2001, 2003, 2004
+# Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB 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.
+
+# GDB 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.
+
+VPATH = @srcdir@
+srcdir = @srcdir@
+
+EXECUTABLES =
+
+all info install-info dvi install uninstall installcheck check:
+ @echo "Nothing to be done for $@..."
+
+clean mostlyclean:
+ -rm -f *~ *.o *.ci
+ -rm -f core ${EXECUTABLES}
+
+distclean maintainer-clean realclean: clean
+ -rm -f Makefile config.status config.log
--- /dev/null
+# Copyright 1988, 1990, 1991, 1992, 1994, 1997, 1999, 2000, 2002,
+# 2003, 2004 Free Software Foundation, Inc.
+
+# 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.
+
+# This file was written by Rob Savoye. (rob@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+# are we on a target board
+if [is_remote target] {
+ return
+}
+
+# Not all of the lines of code near the start of main are executed for
+# every machine. Also, optimization may reorder some of the lines.
+# So all we do is try to step or next over everything until we get
+# to a line that we know is always executed.
+
+proc do_steps_and_nexts {} {
+ global gdb_prompt
+ global srcdir
+
+ gdb_reinitialize_dir $srcdir/..
+
+ for {set count 0} {$count < 32} {incr count} {
+ send_gdb "list\n"
+ # NOTE: carlton/2002-12-11: The "initial brace" and
+ # "current_directory initialization" possibilities happen to
+ # me with GCC 3.1 on i686-pc-linux-gnu when I compile with
+ # optimization.
+ gdb_expect {
+ -re ".*context = data.*$gdb_prompt $" {
+ set description "step over context initialization"
+ set command "step"
+ }
+ -re ".*argc = context->argc.*$gdb_prompt $" {
+ set description "step over argc initialization"
+ set command "step"
+ }
+ -re ".*argv = context->argv.*$gdb_prompt $" {
+ set description "step over argv initialization"
+ set command "step"
+ }
+ -re ".*quiet = 0.*$gdb_prompt $" {
+ set description "step over quiet initialization"
+ set command "step"
+ }
+ -re ".*batch = 0.*$gdb_prompt $" {
+ set description "step over batch initialization"
+ set command "step"
+ }
+ -re ".*symarg = NULL.*$gdb_prompt $" {
+ set description "step over symarg initialization"
+ set command "step"
+ }
+ -re ".*execarg = NULL.*$gdb_prompt $" {
+ set description "step over execarg initialization"
+ set command "step"
+ }
+ -re ".*corearg = NULL.*$gdb_prompt $" {
+ set description "step over corearg initialization"
+ set command "step"
+ }
+ -re ".*cdarg = NULL.*$gdb_prompt $" {
+ set description "step over cdarg initialization"
+ set command "step"
+ }
+ -re ".*ttyarg = NULL.*$gdb_prompt $" {
+ set description "step over ttyarg initialization"
+ set command "step"
+ }
+ -re ".*time_at_startup = get_run_time.*$gdb_prompt $" {
+ set description "next over get_run_time and everything it calls"
+ set command "next"
+ }
+ -re ".*START_PROGRESS.*$gdb_prompt $" {
+ # Note: ezannoni/2004/02/17: This check should be
+ # removed, since as of today that source line is not
+ # in gdb anymore.
+ set description "next over START_PROGRESS and everything it calls"
+ set command "next"
+ }
+ -re ".*mac_init.*$gdb_prompt $" {
+ set description "next over mac_init and everything it calls"
+ set command "next"
+ }
+ -re ".*init_malloc.*$gdb_prompt $" {
+ # gdb 6.2.X is the last gdb which called init_malloc
+ set description "next over init_malloc and everything it calls"
+ set command "next"
+ }
+ -re ".*lim_at_start.*$gdb_prompt $" {
+ set description "next over lim_at_start initialization"
+ set command "next"
+ }
+ -re ".*count . 0x3.*$gdb_prompt $" {
+ set description "next over conditional stack alignment code 1"
+ set command "next"
+ }
+ -re ".*if .i != 0.*$gdb_prompt $" {
+ set description "next over conditional stack alignment code 2"
+ set command "next"
+ }
+ -re ".*alloca .i - 4.*$gdb_prompt $" {
+ set description "next over conditional stack alignment alloca"
+ set command "next"
+ }
+ -re ".*cmdsize = 1.*$gdb_prompt $" {
+ set description "step over cmdsize initialization"
+ set command "next"
+ }
+ -re ".*cmdarg = .* xmalloc.*$gdb_prompt $" {
+ set description "next over cmdarg initialization via xmalloc"
+ set command "next"
+ }
+ -re ".*ncmd = 0.*$gdb_prompt $" {
+ set description "next over ncmd initialization"
+ set command "next"
+ }
+ -re ".*dirsize = 1.*$gdb_prompt $" {
+ set description "next over dirsize initialization"
+ set command "next"
+ }
+ -re ".*dirarg = .* xmalloc.*$gdb_prompt $" {
+ return
+ }
+ -re ".*setlocale .LC_MESSAGES,.*$gdb_prompt $" {
+ set description "next over setlocale LC_MESSAGES"
+ set command "next"
+ }
+ -re ".*setlocale .LC_CTYPE,.*$gdb_prompt $" {
+ set description "next over setlocale LC_CTYPE"
+ set command "next"
+ }
+ -re ".*bindtextdomain .PACKAGE, LOCALEDIR.;.*$gdb_prompt $" {
+ set description "next over bindtextdomain"
+ set command "next"
+ }
+ -re ".*textdomain .PACKAGE.;.*$gdb_prompt $" {
+ set description "next over textdomain PACKAGE"
+ set command "next"
+ }
+ -re "\[0-9\]*\t\{\r\n$gdb_prompt $" {
+ set description "step over initial brace"
+ set command "step"
+ }
+ -re ".*current_directory = gdb_dirbuf.*$gdb_prompt $" {
+ set description "step over current_directory initialization"
+ set command "step"
+ }
+ -re ".*gdb_sysroot = .*$gdb_prompt $" {
+ # NOTE: carlton/2003-01-15: More optimization reordering,
+ # observed on GCC 3.1.
+ set description "step over gdb_sysroot initialization"
+ set command "step"
+ }
+ -re ".*ndir = 0.*$gdb_prompt $" {
+ set description "step over ndir initialization"
+ set command "step"
+ }
+ -re ".*instream = stdin.*$gdb_prompt $" {
+ set description "step over instream initialization"
+ set command "step"
+ }
+ -re ".*getcwd .gdb_dirbuf, sizeof .gdb_dirbuf..;.*$gdb_prompt $" {
+ set description "next over getcwd"
+ set command "next"
+ }
+ -re "\[ \t\]+\{\r\n$gdb_prompt $" {
+ setup_xfail "mips-*-irix5*"
+ fail "$description ended up at odd location"
+ }
+ -re ".*main.c.*No such file or directory.*$gdb_prompt $" {
+ setup_xfail "rs6000-*-aix3*"
+ fail "must be able to list source lines"
+ return
+ }
+ -re ".*$gdb_prompt $" {
+ fail "unknown source line after $description"
+ return
+ }
+ default {
+ fail "unknown source line near main"
+ return
+ }
+ }
+ send_gdb "$command\n"
+ gdb_expect {
+ -re ".*No such file or directory.\r\n$gdb_prompt $" {
+ fail "$description (no source available)"
+ }
+ -re ".*A file or directory .* does not exist..\r\n$gdb_prompt $" {
+ fail "$description (no source available)"
+ }
+ -re ".*$gdb_prompt $" {
+ pass "$description"
+ }
+ timeout {
+ fail "$description (timeout)"
+ }
+ }
+ }
+}
+
+proc test_with_self { executable } {
+ global gdb_prompt
+ global tool
+ global det_file
+ global decimal
+ global timeout
+
+ # load yourself into the debugger
+ # This can take a relatively long time, particularly for testing where
+ # the executable is being accessed over a network, or where gdb does not
+ # support partial symbols for a particular target and has to load the
+ # entire symbol table. Set the timeout to 10 minutes, which should be
+ # adequate for most environments (it *has* timed out with 5 min on a
+ # SPARCstation SLC under moderate load, so this isn't unreasonable).
+ # After gdb is started, set the timeout to 30 seconds for the duration
+ # of this test, and then back to the original value.
+
+ set oldtimeout $timeout
+ set timeout 600
+ verbose "Timeout is now $timeout seconds" 2
+
+ global gdb_file_cmd_debug_info
+ set gdb_file_cmd_debug_info "unset"
+
+ set result [gdb_load $executable]
+ set timeout $oldtimeout
+ verbose "Timeout is now $timeout seconds" 2
+
+ if { $result != 0 } then {
+ return -1
+ }
+
+ if { $gdb_file_cmd_debug_info != "debug" } then {
+ untested "No debug information, skipping testcase."
+ return -1
+ }
+
+ # disassemble yourself
+ gdb_test "x/10i main" \
+ "x/10i.*main.*main.$decimal.*main.$decimal.*" \
+ "Disassemble main"
+
+ # Set a breakpoint at main
+ gdb_test "break captured_main" \
+ "Breakpoint.*at.* file.*, line.*" \
+ "breakpoint in captured_main"
+
+ # We'll need this when we send a ^C to GDB. Need to do it before we
+ # run the program and gdb starts saving and restoring tty states.
+ # On Ultrix, we don't need it and it is really slow (because shell_escape
+ # doesn't use vfork).
+ if ![istarget "*-*-ultrix*"] then {
+ gdb_test "shell stty intr '^C'" "" \
+ "set interrupt character in test_with_self"
+ }
+
+ # FIXME: If we put this after the run to main, the first list
+ # command doesn't print the same line as the current line where
+ # gdb is stopped.
+ gdb_test "set listsize 1" "" "set listsize to 1"
+
+ # run yourself
+ # It may take a very long time for the inferior gdb to start (lynx),
+ # so we bump it back up for the duration of this command.
+ set timeout 600
+
+ set description "run until breakpoint at captured_main"
+ send_gdb "run -nw\n"
+ gdb_expect {
+ -re "Starting program.*Breakpoint \[0-9\]+,.*captured_main .data.* at .*main.c:.*$gdb_prompt $" {
+ pass "$description"
+ }
+ -re "Starting program.*Breakpoint \[0-9\]+,.*captured_main .data.*$gdb_prompt $" {
+ xfail "$description (line numbers scrambled?)"
+ }
+ -re "vfork: No more processes.*$gdb_prompt $" {
+ fail "$description (out of virtual memory)"
+ set timeout $oldtimeout
+ verbose "Timeout is now $timeout seconds" 2
+ return -1
+ }
+ -re ".*$gdb_prompt $" {
+ fail "$description"
+ set timeout $oldtimeout
+ verbose "Timeout is now $timeout seconds" 2
+ return -1
+ }
+ timeout {
+ fail "$description (timeout)"
+ }
+ }
+
+ set timeout $oldtimeout
+ verbose "Timeout is now $timeout seconds" 2
+
+ # do we have a version number ?
+ send_gdb "print version\n"
+ gdb_expect {
+ -re ".\[0-9\]+ = .\[0-9.\]+.*$gdb_prompt $" {
+ pass "printed version as string"
+ }
+ -re ".\[0-9\]+ = +0x.*\[0-9.\]+.*$gdb_prompt $" {
+ pass "printed version as pointer"
+ }
+ -re ".\[0-9\]+ = +.+ +0x.*\[0-9.\]+.*$gdb_prompt $" {
+ pass "printed version with cast"
+ }
+ -re ".*$gdb_prompt $" { fail "printed version" }
+ timeout { fail "(timeout) printed version" }
+ }
+
+ do_steps_and_nexts
+
+ gdb_test "print \"foo\"" ".\[0-9\]+ = \"foo\"" "print a string"
+
+ # do_steps_and_nexts left us ready to execute an xmalloc call,
+ # so give that a try.
+ # If we don't actually enter the xmalloc call when we give a
+ # step command that seems like a genuine bug. It seems to happen
+ # on most RISC processors.
+ # NOTE drow/2003-06-22: However, if we step back to the preceding two
+ # lines, just keep stepping until we enter.
+ set stepped_back 0
+ setup_xfail "alpha-*-*" "mips-*-*"
+ set description "step into xmalloc call"
+ send_gdb "step\n"
+ gdb_expect {
+ -re "ncmd = 0;.*$gdb_prompt $" {
+ set stepped_back 1
+ send_gdb "step\n"
+ exp_continue
+ }
+ -re ".*cmdarg = .* xmalloc.*$gdb_prompt $" {
+ set stepped_back 1
+ send_gdb "step\n"
+ exp_continue
+ }
+ -re "dirsize = 1;.*$gdb_prompt $" {
+ set stepped_back 1
+ send_gdb "step\n"
+ exp_continue
+ }
+ -re ".*dirarg = .* xmalloc.*$gdb_prompt $" {
+ if { $stepped_back == 1 } {
+ send_gdb "step\n"
+ exp_continue
+ } else {
+ fail "$description"
+ }
+ }
+ -re "xmalloc.*size=.*at.*utils.c.*$gdb_prompt $" {
+ pass "$description"
+ }
+ -re ".*No such file or directory.\r\n$gdb_prompt $" {
+ pass "$description (no source available)"
+ }
+ -re "A file or directory .* does not exist..\r\n$gdb_prompt $" {
+ pass "$description (no source available)"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "$description"
+ }
+ timeout {
+ fail "$description (timeout)"
+ }
+ }
+
+ # start the "xgdb" process
+ send_gdb "continue\n"
+ gdb_expect {
+ -re "GNU gdb \[0-9\.\]*.*
+Copyright \[0-9\]* Free Software Foundation, Inc.*
+GDB is free software, covered by the GNU General Public License, and you are.*
+welcome to change it and/or distribute copies of it under certain conditions.*
+Type \"show copying\" to see the conditions.*
+There is absolutely no warranty for GDB. Type \"show warranty\" for details.*
+This GDB was configured as .*$gdb_prompt $"\
+ { pass "xgdb is at prompt" }
+ -re "GDB is free software and you are welcome to distribute copies of it.*
+ under certain conditions; type \"show copying\" to see the conditions..*
+There is absolutely no warranty for GDB; type \"show warranty\" for details..*
+GDB.*Copyright \[0-9\]+ Free Software Foundation, Inc..*$gdb_prompt $"\
+ { pass "xgdb is at prompt (obsolescent gdb)" }
+ -re ".*$gdb_prompt $" { fail "xgdb is at prompt" }
+ timeout { fail "(timeout) xgdb is at prompt" }
+ }
+
+ # set xgdb prompt so we can tell which is which
+ send_gdb "set prompt (xgdb) \n"
+ gdb_expect {
+ -re "\[(\]xgdb\[)\].*\[(\]xgdb\[)\] $" { pass "Set xgdb prompt" }
+ -re ".*$gdb_prompt $" { fail "Set xgdb prompt" }
+ default { fail "(timeout) Set xgdb prompt" }
+ }
+
+ # kill the xgdb process
+ set description "send ^C to child process"
+ send_gdb "\003"
+ gdb_expect {
+ -re "Program received signal SIGINT.*$gdb_prompt $" {
+ pass "$description"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "$description"
+ }
+ timeout {
+ fail "$description (timeout)"
+ }
+ }
+
+ set description "send SIGINT signal to child process"
+ send_gdb "signal SIGINT\n"
+ gdb_expect {
+ -re "Continuing with signal SIGINT.*$gdb_prompt $" {
+ pass "$description"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "$description"
+ }
+ timeout {
+ fail "$description (timeout)"
+ }
+ }
+
+ # get a stack trace
+ #
+ # This fails on some linux systems for unknown reasons. On the
+ # systems where it fails, sometimes it works fine when run manually.
+ # The testsuite failures may not be limited to just aout systems.
+ setup_xfail "i*86-pc-linuxaout-gnu"
+ set description "backtrace through signal handler"
+ send_gdb "backtrace\n"
+ gdb_expect {
+ -re "#0.*(read|poll).*in main \\(.*\\) at .*gdb\\.c.*$gdb_prompt $" {
+ pass "$description"
+ }
+ -re ".*$gdb_prompt $" {
+ # On the alpha, we hit the infamous problem about gdb
+ # being unable to get the frame pointer (mentioned in
+ # gdb/README). As it is intermittent, there is no way to
+ # XFAIL it which will give us an XPASS if the problem goes
+ # away.
+ setup_xfail "alpha*-*-osf*"
+ fail "$description"
+ }
+ timeout {
+ fail "$description (timeout)"
+ }
+ }
+
+
+ # Set the timeout back to the value it had when we were called.
+ set timeout $oldtimeout
+ verbose "Timeout is now $timeout seconds" 2
+
+ # Restart gdb in case next test expects it to be started already.
+ return 0
+}
+
+# Find a pathname to a file that we would execute if the shell was asked
+# to run $arg using the current PATH.
+
+proc find_gdb { arg } {
+
+ # If the arg directly specifies an existing executable file, then
+ # simply use it.
+
+ if [file executable $arg] then {
+ return $arg
+ }
+
+ set result [which $arg]
+ if [string match "/" [ string range $result 0 0 ]] then {
+ return $result
+ }
+
+ # If everything fails, just return the unqualified pathname as default
+ # and hope for best.
+
+ return $arg
+}
+
+# Run the test with self.
+# Copy the file executable file in case this OS doesn't like to edit its own
+# text space.
+
+set GDB_FULLPATH [find_gdb $GDB]
+
+# Remove any old copy lying around.
+remote_file host delete x$tool
+
+gdb_start
+set file [remote_download host $GDB_FULLPATH x$tool]
+set result [test_with_self $file];
+gdb_exit;
+catch "remote_file host delete $file";
+
+if {$result <0} then {
+ warning "Couldn't test self"
+ return -1
+}
--- /dev/null
+# Copyright 2000, 2004 Free Software Foundation, Inc.
+
+# 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.
+
+# This file was based on jmisc.exp which in turn was written by
+# Anthony Green. (green@redhat.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+load_lib "java.exp"
+
+set testfile "jmain"
+set srcfile ${srcdir}/$subdir/${testfile}.java
+set binfile ${objdir}/${subdir}/${testfile}
+if { [compile_java_from_source ${srcfile} ${binfile} "-g"] != "" } {
+ untested "Couldn't compile ${srcfile}"
+ return -1
+}
+
+set prms_id 0
+set bug_id 0
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+gdb_test "set print sevenbit-strings" ".*"
+
+# Check that plain old "main" works. The load should both set the
+# language to java and (since --main=jmain), some how set the scope to
+# jmain's main.
+
+# Where the breakpoint should always land
+
+set bpmain "Breakpoint .* file .*jmain.java, line 5\."
+
+gdb_load "${binfile}"
+setup_kfail *-*-* java/1567
+gdb_test "break main" "${bpmain}"
+
+# Check that an unqualified "main" works.
+
+
+gdb_load "${binfile}"
+setup_kfail *-*-* java/1565
+gdb_test "break jmain.main" "${bpmain}"
+
+# Check that a fully qualified "main" works.
+gdb_load "${binfile}"
+setup_xfail *-*-* gcc/16439
+gdb_test "break \'${testfile}.main(java.lang.String\[\])\'" "${bpmain}"
--- /dev/null
+public class jmain
+{
+ public static void main (String[] args)
+ {
+ return;
+ }
+}
--- /dev/null
+# Copyright 2004 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@gnu.org
+
+if $tracelevel {
+ strace $tracelevel
+}
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+set testfile exclfwd
+set binfile ${objdir}/${subdir}/${testfile}
+
+foreach file {exclfwd1 exclfwd2} {
+ if {[gdb_compile "${srcdir}/${subdir}/${file}.c" "${file}.o" object {debug}] != ""} {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+ }
+}
+
+if {[gdb_compile "exclfwd1.o exclfwd2.o" ${binfile} executable {debug}] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if ![runto_main] then {
+ perror "couldn't run to breakpoint"
+ continue
+}
+
+get_debug_format
+
+set eol "\[ \t\]*\[\n\r\]+"
+
+gdb_test "ptype v1" "type = struct a {$eol
+ int x;$eol
+ int y;$eol
+}$eol"
+
+if { [test_debug_format "stabs"] } then {
+ setup_kfail "gdb/1602" *-*-*
+}
+gdb_test "ptype v2" "type = struct a {$eol
+ const char .c;$eol
+}$eol"
+
+if { [test_debug_format "stabs"] } then {
+ setup_kfail "gdb/1603" *-*-*
+}
+gdb_test "ptype v3" "type = const char ."
--- /dev/null
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2004 Free Software Foundation, Inc.
+
+ 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.
+
+ Please email any bugs, comments, and/or additions to this file to:
+ bug-gdb@gnu.org */
+
+typedef struct a a_t;
--- /dev/null
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2004 Free Software Foundation, Inc.
+
+ 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.
+
+ Please email any bugs, comments, and/or additions to this file to:
+ bug-gdb@gnu.org */
+
+#include "exclfwd.h"
+
+struct a
+{
+ int x, y;
+};
+
+a_t v1;
+
+int
+main ()
+{
+}
--- /dev/null
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2004 Free Software Foundation, Inc.
+
+ 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.
+
+ Please email any bugs, comments, and/or additions to this file to:
+ bug-gdb@gnu.org */
+
+#include "exclfwd.h"
+
+struct a
+{
+ const char *c;
+};
+
+a_t v2;
+const char *v3;
--- /dev/null
+# Copyright (C) 2004 Free Software Foundation, Inc.
+
+# 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.
+
+# gdb 6.1.1 on AIX had a bug where the aix-threads code called
+# getthrds() incorrectly so that gdb lost track of breakpoints.
+# GDB reported a SIGTRAP signal in a random thread when hitting
+# a breakpoint.
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set testfile "pthread_cond_wait"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "incdir=${objdir}"]] != "" } {
+ return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+gdb_test "break noreturn" \
+ "Breakpoint 1 at .*: file .*${srcfile}, line .*" \
+ "breakpoint on noreturn"
+
+# Run the program and make sure GDB reports that we stopped after
+# hitting breakpoint 1 in noreturn().
+
+gdb_test "run" \
+ ".*Breakpoint 1, noreturn ().*" \
+ "run to noreturn"
+
--- /dev/null
+/* Manythreads test program.
+ Copyright 2004
+ Free Software Foundation, Inc.
+
+ Written by Jeff Johnston <jjohnstn@redhat.com>
+ Contributed by Red Hat
+
+ 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. */
+
+#include <pthread.h>
+#include <stdio.h>
+#include <limits.h>
+
+void *
+thread_function (void *arg)
+{
+ int x = (int)arg;
+
+ printf ("Thread <%d> executing\n", x);
+
+ return NULL;
+}
+
+int
+main (int argc, char **argv)
+{
+ pthread_attr_t attr;
+ pthread_t threads[256];
+ int i, j;
+
+ pthread_attr_init (&attr);
+ pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN);
+
+ /* Create a ton of quick-executing threads, then wait for them to
+ complete. */
+ for (i = 0; i < 1000; ++i)
+ {
+ for (j = 0; j < 256; ++j)
+ {
+ pthread_create (&threads[j], &attr, thread_function,
+ (void *)(i * 1000 + j));
+ }
+
+ for (j = 0; j < 256; ++j)
+ {
+ pthread_join (threads[j], NULL);
+ }
+ }
+
+ pthread_attr_destroy (&attr);
+
+ return 0;
+}
--- /dev/null
+# manythreads.exp -- Expect script to test stopping many threads
+# Copyright (C) 2004 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Jeff Johnston. (jjohnstn@redhat.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "manythreads"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "incdir=${objdir}"]] != "" } {
+ return -1
+}
+
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+gdb_test "set print sevenbit-strings" ""
+runto_main
+
+# We'll need this when we send_gdb a ^C to GDB. Need to do it before we
+# run the program and gdb starts saving and restoring tty states.
+# On Ultrix, we don't need it and it is really slow (because shell_escape
+# doesn't use vfork).
+if ![istarget "*-*-ultrix*"] then {
+ gdb_test "shell stty intr '^C'" ""
+}
+
+set message "first continue"
+gdb_test_multiple "continue" "first continue" {
+ -re "error:.*$gdb_prompt $" {
+ fail "$message"
+ }
+ -re "Continuing" {
+ pass "$message"
+ }
+}
+
+# Send a Ctrl-C and verify that we can do info threads and continue
+after 1000
+send_gdb "\003"
+set message "stop threads 1"
+gdb_test_multiple "" "stop threads 1" {
+ -re "\\\[New \[^\]\]*\\\]\r\n" {
+ exp_continue
+ }
+ -re "\\\[\[^\]\]* exited\\\]\r\n" {
+ exp_continue
+ }
+ -re "Thread \[^\n\]* executing\r\n" {
+ exp_continue
+ }
+ -re "Program received signal SIGINT.*$gdb_prompt $" {
+ pass "$message"
+ }
+ timeout {
+ fail "$message (timeout)"
+ }
+}
+
+gdb_test "info threads" ".*1 Thread.*.LWP.*"
+
+set message "second continue"
+gdb_test_multiple "continue" "second continue" {
+ -re "error:.*$gdb_prompt $" {
+ fail "$message"
+ }
+ -re "Continuing" {
+ pass "$message"
+ }
+}
+
+# Send another Ctrl-C and verify that we can do info threads and quit
+after 1000
+send_gdb "\003"
+set message "stop threads 2"
+gdb_test_multiple "" "stop threads 2" {
+ -re "\\\[New \[^\]\]*\\\]\r\n" {
+ exp_continue
+ }
+ -re "\\\[\[^\]\]* exited\\\]\r\n" {
+ exp_continue
+ }
+ -re "Thread \[^\n\]* executing\r\n" {
+ exp_continue
+ }
+ -re "Program received signal SIGINT.*$gdb_prompt $" {
+ pass "stop threads 2"
+ }
+}
+
+gdb_test_multiple "quit" "GDB exits after stopping multithreaded program" {
+ -re "The program is running. Exit anyway\\? \\(y or n\\) $" {
+ send_gdb "y\n"
+ exp_continue
+ }
+ eof {
+ pass "GDB exits after stopping multithreaded program"
+ }
+ timeout {
+ fail "GDB exits after stopping multithreaded program (timeout)"
+ }
+}
+
--- /dev/null
+/* A small multi-threaded test case.
+
+ Copyright 2004
+ 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. */
+
+#include <pthread.h>
+#include <stdio.h>
+#include <time.h>
+
+void
+cond_wait (pthread_cond_t *cond, pthread_mutex_t *mut)
+{
+ pthread_mutex_lock(mut);
+ pthread_cond_wait (cond, mut);
+ pthread_mutex_unlock (mut);
+}
+
+void
+noreturn (void)
+{
+ pthread_mutex_t mut;
+ pthread_cond_t cond;
+
+ pthread_mutex_init (&mut, NULL);
+ pthread_cond_init (&cond, NULL);
+
+ /* Wait for a condition that will never be signaled, so we effectively
+ block the thread here. */
+ cond_wait (&cond, &mut);
+}
+
+void *
+forever_pthread (void *unused)
+{
+ noreturn ();
+}
+
+void
+break_me (void)
+{
+ /* Just an anchor to help putting a breakpoint. */
+}
+
+int
+main (void)
+{
+ pthread_t forever;
+ const struct timespec ts = { 0, 10000000 }; /* 0.01 sec */
+
+ pthread_create (&forever, NULL, forever_pthread, NULL);
+ for (;;)
+ {
+ nanosleep (&ts, NULL);
+ break_me();
+ }
+
+ return 0;
+}
+
--- /dev/null
+# Copyright (C) 2004 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@gnu.org
+
+# This file verifies that GDB is able to compute a backtrace for a thread
+# being blocked on a call to pthread_cond_wait().
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set testfile "pthread_cond_wait"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "incdir=${objdir}"]] != "" } {
+ return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+gdb_test "break break_me" \
+ "Breakpoint 1 at .*: file .*${srcfile}, line .*" \
+ "breakpoint on break_me"
+
+gdb_test "run" \
+ ".*Breakpoint 1, break_me ().*" \
+ "run to break_me"
+
+#
+# Backtrace all threads, find the one running noreturn, and
+# verify that we are able to get a sensible backtrace, including
+# the frame for the pthread_cond_wait() call.
+#
+# The string below will only match if the functions named
+# occur in a single thread's backtrace, in the given order.
+#
+
+global hex
+global decimal
+
+#
+# This is a "backtrace break" ("btb"):
+#
+set btb "\[^\r\n\]+\[\r\n\]+\#${decimal}\[ \t\]+${hex} in "
+
+# One of the threads is blocked on a call to pthread_cond_wait, and
+# we want to verify that we are able to get a sensible backtrace for
+# that thread. Because we don't know its thread ID, we can't switch
+# to it before doing the backtrace. So we get a backtrace for all
+# threads, and verify that one them returns the expected backtrace.
+gdb_test "thread apply all backtrace" \
+ "pthread_cond_wait${btb}cond_wait${btb}noreturn${btb}forever_pthread.*" \
+ "backtrace in blocked thread"
+
--- /dev/null
+/* This test program is part of GDB, The GNU debugger.
+
+ Copyright 2004 Free Software Foundation, Inc.
+
+ Originally written by Jeff Johnston <jjohnstn@redhat.com>,
+ contributed by Red Hat
+
+ 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. */
+
+#include <pthread.h>
+#include <semaphore.h>
+#include <stdio.h>
+#include <limits.h>
+#include <errno.h>
+
+sem_t semaphore;
+
+void *
+thread_function (void *arg)
+{
+ printf ("Thread executing\n");
+ while (sem_wait (&semaphore) != 0)
+ {
+ if (errno != EINTR)
+ {
+ perror ("thread_function");
+ return;
+ }
+ }
+ return NULL;
+}
+
+int
+main (int argc, char **argv)
+{
+ pthread_attr_t attr;
+
+ pthread_attr_init (&attr);
+ pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN);
+
+ if (sem_init (&semaphore, 0, 0) == -1)
+ {
+ perror ("semaphore");
+ return -1;
+ }
+
+
+ /* Create a thread, wait for it to complete. */
+ {
+ pthread_t thread;
+ pthread_create (&thread, &attr, thread_function, NULL);
+ sem_post (&semaphore);
+ pthread_join (thread, NULL);
+ }
+
+ pthread_attr_destroy (&attr);
+ return 0;
+}
--- /dev/null
+# static.exp -- test script, for GDB, the GNU debugger.
+
+# Copyright 2004 Free Software Foundation, Inc.
+
+# 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.
+
+# Based on manythreads written by Jeff Johnston, contributed by Red
+# Hat.
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "staticthreads"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+set static_flag "-static"
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" \
+ executable \
+ [list debug "incdir=${objdir}" "additional_flags=${static_flag}" \
+ ]] != "" } {
+ return -1
+}
+
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+gdb_test "set print sevenbit-strings" ""
+
+
+# See if the static multi-threaded program runs.
+
+runto_main
+gdb_test "break sem_post"
+set test "Continue to main's call of sem_post"
+gdb_test_multiple "continue" "$test" {
+ -re " sem_post .*$gdb_prompt " {
+ pass "$test"
+ }
+ -re "Program received signal .*$gdb_prompt " {
+ kfail gdb/1328 "$test"
+ }
+}
+
+
+# See if handle SIG32 helps (a little) with a static multi-threaded
+# program.
+
+rerun_to_main
+gdb_test "handle SIG32 nostop noprint pass"
+set test "Handle SIG32 helps"
+gdb_test "continue" " sem_post .*" "handle SIG32 helps"
+
+
+# See if info threads produces anything approaching a thread list.
+
+set test "info threads"
+gdb_test_multiple "info threads" "$test" {
+ -re " Thread .*$gdb_prompt " {
+ pass "$test"
+ }
+ -re "$gdb_prompt " {
+ kfail gdb/1328 "$test"
+ }
+}
+
+
+# Check that the program can be quit.
+
+set test "GDB exits with static thread program"
+gdb_test_multiple "quit" "$test" {
+ -re "The program is running. Exit anyway\\? \\(y or n\\) $" {
+ send_gdb "y\n"
+ exp_continue
+ }
+ eof {
+ pass "$test"
+ }
+}
--- /dev/null
+/*
+* Copyright (C) 2004 Free Software Foundation, Inc.
+
+* 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.
+
+* This file was written by Steve Munroe. (sjmunroe@us.ibm.com)
+* Test break points and single step on thread functions.
+*/
+
+#include <string.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+
+#define N 2
+
+static void *
+tf (void *arg)
+{
+ int n = (int) (long int) arg;
+ char number[160];
+ int unslept = 10;
+
+ sprintf(number, "tf(%ld): begin", (long)arg);
+ puts (number);
+
+ while (unslept > 0)
+ unslept = sleep(unslept);
+
+ sprintf(number, "tf(%ld): end", (long)arg);
+ puts (number);
+ return NULL;
+}
+
+int main (int argc, char *argv[])
+{
+ int n;
+ int unslept = 2;
+ pthread_t th[N];
+
+ for (n = 0; n < N; ++n)
+ if (pthread_create (&th[n], NULL, tf, (void *) (long int) n) != 0)
+ {
+ while (unslept > 0)
+ unslept = sleep(2);
+ puts ("create failed");
+ exit (1);
+ }
+
+ puts("after create");
+
+ for (n = 0; n < N; ++n)
+ if (pthread_join (th[n], NULL) != 0)
+ {
+ puts ("join failed");
+ exit (1);
+ }
+
+ puts("after join");
+ return 0;
+}
--- /dev/null
+# Copyright (C) 2004 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Manoj Iyer. (manjo@austin.ibm.com)
+# Test break points and single step on thread functions.
+#
+# Test Purpose:
+# - Test that breakpoints, continue in a threaded application works.
+# On powerpc64-unknown-linux-gnu system, running kernel version
+# 2.6.5-7.71-pseries64 this test is known to fail due to kernel bug
+# in ptrace system call.
+#
+# Test Strategy:
+# - tbug.c creates 2 threads
+# - start gdb
+# - create 2 breakpoints #1 main() #2 tf() (the thread function)
+# - run gdb till #1 main() breakpoint is reached
+# - continue to breakpoint #2 tf()
+# - delete all breakpoints
+# - exit gdb.
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "thread_check"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "incdir=${objdir}"]] != "" } {
+ return -1
+}
+
+
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if ![runto_main] then {
+ fail "Can't run to main"
+ return 1;
+}
+
+
+#
+# set breakpoint at thread fucntion tf
+#
+gdb_test "break tf" \
+ "Breakpoint.*at.* file .*$srcfile, line.*" \
+ "breakpoint at tf"
+
+
+#
+#
+# continue to tf() breakpoint #2
+#
+gdb_test "continue" \
+ ".*Breakpoint 2.*tf.* at .*tbug.* .*\r\n.*$gdb_prompt $" \
+ "continue to tf"
+
+#
+# backtrace from thread function.
+#
+gdb_test "backtrace" \
+ "#0 .*tf .*at .*tbug.*" \
+ "backtrace from thread function"
+
+
+#
+# delete all breakpoints
+#
+delete_breakpoints
+
+#
+# exit gdb
+#
+gdb_exit
--- /dev/null
+# This testcase is part of GDB, the GNU debugger.
+
+# Copyright 2004 Free Software Foundation, Inc.
+
+# 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.
+
+# Check that GDB can support multiple watchpoints across threads.
+
+if $tracelevel {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+# This test verifies that a watchpoint is detected in the proper thread
+# so the test is only meaningful on a system with hardware watchpoints.
+if [target_info exists gdb,no_hardware_watchpoints] {
+ return 0;
+}
+
+set testfile "schedlock"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "incdir=${objdir}"]] != "" } {
+ return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+gdb_test "set can-use-hw-watchpoints 1" "" ""
+
+#
+# Run to `main' where we begin our tests.
+#
+
+if ![runto_main] then {
+ gdb_suppress_tests
+}
+
+set args_0 0
+set args_1 0
+
+# Watch values that will be modified by distinct threads.
+gdb_test "watch args\[0\]" "Hardware watchpoint 2: args\\\[0\\\]"
+gdb_test "watch args\[1\]" "Hardware watchpoint 3: args\\\[1\\\]"
+
+# Loop and continue to allow both watchpoints to be triggered.
+for {set i 0} {$i < 30} {incr i} {
+ set test_flag 0
+ gdb_test_multiple "continue" "threaded watch loop" {
+ -re "Hardware watchpoint 2: args\\\[0\\\].*Old value = 0.*New value = 1.*main \\\(\\\) at .*schedlock.c:21.*$gdb_prompt $"
+ { set args_0 1; set test_flag 1 }
+ -re "Hardware watchpoint 3: args\\\[1\\\].*Old value = 0.*New value = 1.*main \\\(\\\) at .*schedlock.c:21.*$gdb_prompt $"
+ { set args_1 1; set test_flag 1 }
+ -re "Hardware watchpoint 2: args\\\[0\\\].*Old value = $args_0.*New value = [expr $args_0+1].*in thread_function \\\(arg=0x0\\\) at .*schedlock.c:42.*$gdb_prompt $"
+ { set args_0 [expr $args_0+1]; set test_flag 1 }
+ -re "Hardware watchpoint 3: args\\\[1\\\].*Old value = $args_1.*New value = [expr $args_1+1].*in thread_function \\\(arg=0x1\\\) at .*schedlock.c:42.*$gdb_prompt $"
+ { set args_1 [expr $args_1+1]; set test_flag 1 }
+ }
+ # If we fail above, don't bother continuing loop
+ if { $test_flag == 0 } {
+ set i 30;
+ }
+}
+
+# Print success message if loop succeeded.
+if { $test_flag == 1 } {
+ pass "threaded watch loop"
+}
+
+# Verify that we hit first watchpoint in main thread.
+set message "first watchpoint on args\[0\] hit"
+if { $args_0 > 0 } {
+ pass $message
+} else {
+ fail $message
+}
+
+# Verify that we hit second watchpoint in main thread.
+set message "first watchpoint on args\[1\] hit"
+if { $args_1 > 0 } {
+ pass $message
+} else {
+ fail $message
+}
+
+# Verify that we hit first watchpoint in child thread.
+set message "watchpoint on args\[0\] hit in thread"
+if { $args_0 > 1 } {
+ pass $message
+} else {
+ fail $message
+}
+
+# Verify that we hit second watchpoint in child thread.
+set message "watchpoint on args\[1\] hit in thread"
+if { $args_1 > 1 } {
+ pass $message
+} else {
+ fail $message
+}
+
+# Verify that all watchpoint hits are accounted for.
+set message "combination of threaded watchpoints = 30"
+if { [expr $args_0+$args_1] == 30 } {
+ pass $message
+} else {
+ fail $message
+}
--- /dev/null
+# This test code is part of GDB, the GNU debugger.
+
+# Copyright 2003, 2004 Free Software Foundation, Inc.
+
+# 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.
+
+# Auxiliary function to check for known problems.
+#
+# EXPECTED_STRING is the string expected by the test.
+#
+# ACTUAL_STRING is the actual string output by gdb.
+#
+# ERRATA_TABLE is a list of lines of the form:
+#
+# { expected-string broken-string {eval-block} }
+#
+# If there is a line for the given EXPECTED_STRING, and if the
+# ACTUAL_STRING output by gdb is the same as the BROKEN_STRING in the
+# table, then I eval the eval-block.
+
+proc cp_check_errata { expected_string actual_string errata_table } {
+ foreach erratum $errata_table {
+ if { "$expected_string" == [lindex $erratum 0]
+ && "$actual_string" == [lindex $erratum 1] } then {
+ eval [lindex $erratum 2]
+ }
+ }
+}
+
+# Test ptype of a class.
+#
+# Different C++ compilers produce different output. To accommodate all
+# the variations listed below, I read the output of "ptype" and process
+# each line, matching it to the class description given in the
+# parameters.
+#
+# IN_COMMAND and IN_TESTNAME are the command and testname for
+# gdb_test_multiple. If IN_TESTNAME is the empty string, then it
+# defaults to IN_COMMAND.
+#
+# IN_KEY is "class" or "struct". For now, I ignore it, and allow either
+# "class" or "struct" in the output, as long as the access specifiers all
+# work out okay.
+#
+# IN_TAG is the class tag or structure tag.
+#
+# IN_CLASS_TABLE is a list of class information. Each entry contains a
+# keyword and some values. The keywords and their values are:
+#
+# { base "base-declaration" }
+#
+# the class has a base with the given declaration.
+#
+# { vbase "name" }
+#
+# the class has a virtual base pointer with the given name. this
+# is for gcc 2.95.3, which emits ptype entries for the virtual base
+# pointers. the vbase list includes both indirect and direct
+# virtual base classes (indeed, a virtual base is usually
+# indirect), so this information cannot be derived from the base
+# declarations.
+#
+# { field "access" "declaration" }
+#
+# the class has a data field with the given access type and the
+# given declaration.
+#
+# { method "access" "declaration" }
+#
+# the class has a member function with the given access type
+# and the given declaration.
+#
+# If you test the same class declaration more than once, you can specify
+# IN_CLASS_TABLE as "ibid". "ibid" means: look for a previous class
+# table that had the same IN_KEY and IN_TAG, and re-use that table.
+#
+# IN_TAIL is the expected text after the close brace, specifically the "*"
+# in "struct { ... } *". This is an optional parameter. The default
+# value is "", for no tail.
+#
+# IN_ERRATA_TABLE is a list of errata entries. See cp_check_errata for the
+# format of the errata table. Note: the errata entries are not subject to
+# demangler syntax adjustment, so you have to make a bigger table
+# with lines for each output variation.
+#
+# gdb can vary the output of ptype in several ways:
+#
+# . CLASS/STRUCT
+#
+# The output can start with either "class" or "struct", depending on
+# what the symbol table reader in gdb decides. This is usually
+# unrelated to the original source code.
+#
+# dwarf-2 debug info distinguishes class/struct, but gdb ignores it
+# stabs+ debug info does not distinguish class/struct
+# hp debug info distinguishes class/struct, and gdb honors it
+#
+# I tried to accommodate this with regular expressions such as
+# "((class|struct) A \{ public:|struct A \{)", but that turns into a
+# hairy mess because of optional private virtual base pointers and
+# optional public synthetic operators. This is the big reason I gave
+# up on regular expressions and started parsing the output.
+#
+# . REDUNDANT ACCESS SPECIFIER
+#
+# In "class { private: ... }" or "struct { public: ... }", gdb might
+# or might not emit a redundant initial access specifier, depending
+# on the gcc version.
+#
+# . VIRTUAL BASE POINTERS
+#
+# If a class has virtual bases, either direct or indirect, the class
+# will have virtual base pointers. With gcc 2.95.3, gdb prints lines
+# for these virtual base pointers. This does not happen with gcc
+# 3.3.4, gcc 3.4.1, or hp acc A.03.45.
+#
+# I accept these lines. These lines are optional; but if I see one of
+# these lines, then I expect to see all of them.
+#
+# Note: drow considers printing these lines to be a bug in gdb.
+#
+# . SYNTHETIC METHODS
+#
+# A C++ compiler may synthesize some methods: an assignment
+# operator, a copy constructor, a constructor, and a destructor. The
+# compiler might include debug information for these methods.
+#
+# dwarf-2 gdb does not show these methods
+# stabs+ gdb shows these methods
+# hp gdb does not show these methods
+#
+# I accept these methods. These lines are optional, and any or
+# all of them might appear, mixed in anywhere in the regular methods.
+#
+# With gcc v2, the synthetic copy-ctor and ctor have an additional
+# "int" parameter at the beginning, the "in-charge" flag.
+#
+# . DEMANGLER SYNTAX VARIATIONS
+#
+# Different demanglers produce "int foo(void)" versus "int foo()",
+# "const A&" versus "const A &", and so on.
+#
+# TESTED WITH
+#
+# gcc 2.95.3 -gdwarf-2
+# gcc 2.95.3 -gstabs+
+# gcc 3.3.4 -gdwarf-2
+# gcc 3.3.4 -gstabs+
+# gcc 3.4.1 -gdwarf-2
+# gcc 3.4.1 -gstabs+
+# gcc HEAD 20040731 -gdwarf-2
+# gcc HEAD 20040731 -gstabs+
+#
+# TODO
+#
+# Tagless structs.
+#
+# "A*" versus "A *" and "A&" versus "A &" in user methods.
+#
+# Test with hp ACC.
+#
+# -- chastain 2004-08-07
+
+proc cp_test_ptype_class { in_command in_testname in_key in_tag in_class_table { in_tail "" } { in_errata_table { } } } {
+ global gdb_prompt
+ set wsopt "\[\r\n\t \]*"
+
+ # The test name defaults to the command.
+
+ if { "$in_testname" == "" } then { set in_testname "$in_command" }
+
+ # Save class tables in a history array for reuse.
+
+ global cp_class_table_history
+ if { $in_class_table == "ibid" } then {
+ if { ! [info exists cp_class_table_history("$in_key,$in_tag") ] } then {
+ fail "$in_testname // bad ibid"
+ return
+ }
+ set in_class_table $cp_class_table_history("$in_key,$in_tag")
+ } else {
+ set cp_class_table_history("$in_key,$in_tag") $in_class_table
+ }
+
+ # Split the class table into separate tables.
+
+ set list_bases { }
+ set list_vbases { }
+ set list_fields { }
+ set list_methods { }
+
+ foreach class_line $in_class_table {
+ switch [lindex $class_line 0] {
+ "base" { lappend list_bases [lindex $class_line 1] }
+ "vbase" { lappend list_vbases [lindex $class_line 1] }
+ "field" { lappend list_fields [lrange $class_line 1 2] }
+ "method" { lappend list_methods [lrange $class_line 1 2] }
+ default { fail "$in_testname // bad line in class table: $class_line"; return; }
+ }
+ }
+
+ # Construct a list of synthetic operators.
+ # These are: { count ccess-type regular-expression }.
+
+ set list_synth { }
+ lappend list_synth [list 0 "public" "$in_tag & operator=\\($in_tag const ?&\\);"]
+ lappend list_synth [list 0 "public" "$in_tag\\((int,|) ?$in_tag const ?&\\);"]
+ lappend list_synth [list 0 "public" "$in_tag\\((int|void|)\\);"]
+
+ # Actually do the ptype.
+
+ set parse_okay 0
+ gdb_test_multiple "$in_command" "$in_testname // parse failed" {
+ -re "type = (struct|class)${wsopt}(\[A-Za-z0-9_\]*)${wsopt}((:\[^\{\]*)?)${wsopt}\{(.*)\}${wsopt}(\[^\r\n\]*)\[\r\n\]+$gdb_prompt $" {
+ set parse_okay 1
+ set actual_key $expect_out(1,string)
+ set actual_tag $expect_out(2,string)
+ set actual_base_string $expect_out(3,string)
+ set actual_body $expect_out(5,string)
+ set actual_tail $expect_out(6,string)
+ }
+ }
+ if { ! $parse_okay } then { return }
+
+ # Check the actual key. It would be nice to require that it match
+ # the input key, but gdb does not support that. For now, accept any
+ # $actual_key as long as the access property of each field/method
+ # matches.
+
+ switch "$actual_key" {
+ "class" { set access "private" }
+ "struct" { set access "public" }
+ default {
+ cp_check_errata "class" "$actual_key" $in_errata_table
+ cp_check_errata "struct" "$actual_key" $in_errata_table
+ fail "$in_testname // wrong key: $actual_key"
+ return
+ }
+ }
+
+ # Check the actual tag.
+
+ if { "$actual_tag" != "$in_tag" } then {
+ cp_check_errata "$in_tag" "$actual_tag" $in_errata_table
+ fail "$in_testname // wrong tag: $actual_tag"
+ return
+ }
+
+ # Check the actual bases.
+ # First parse them into a list.
+
+ set list_actual_bases { }
+ if { "$actual_base_string" != "" } then {
+ regsub "^:${wsopt}" $actual_base_string "" actual_base_string
+ set list_actual_bases [split $actual_base_string ","]
+ }
+
+ # Check the base count.
+
+ if { [llength $list_actual_bases] < [llength $list_bases] } then {
+ fail "$in_testname // too few bases"
+ return
+ }
+ if { [llength $list_actual_bases] > [llength $list_bases] } then {
+ fail "$in_testname // too many bases"
+ return
+ }
+
+ # Check each base.
+
+ foreach actual_base $list_actual_bases {
+ set actual_base [string trim $actual_base]
+ set base [lindex $list_bases 0]
+ if { "$actual_base" != "$base" } then {
+ cp_check_errata "$base" "$actual_base" $in_errata_table
+ fail "$in_testname // wrong base: $actual_base"
+ return
+ }
+ set list_bases [lreplace $list_bases 0 0]
+ }
+
+ # Parse each line in the body.
+
+ set last_was_access 0
+ set vbase_match 0
+
+ foreach actual_line [split $actual_body "\r\n"] {
+
+ # Chomp the line.
+
+ set actual_line [string trim $actual_line]
+ if { "$actual_line" == "" } then { continue }
+
+ # Access specifiers.
+
+ if { [regexp "^(public|protected|private)${wsopt}:\$" "$actual_line" s0 s1] } then {
+ set access "$s1"
+ if { $last_was_access } then {
+ fail "$in_testname // redundant access specifier"
+ return
+ }
+ set last_was_access 1
+ continue
+ } else {
+ set last_was_access 0
+ }
+
+ # Optional virtual base pointer.
+
+ if { [ llength $list_vbases ] > 0 } then {
+ set vbase [lindex $list_vbases 0]
+ if { [ regexp "$vbase \\*(_vb.|_vb\\\$|__vb_)\[0-9\]*$vbase;" $actual_line ] } then {
+ if { "$access" != "private" } then {
+ cp_check_errata "private" "$access" $in_errata_table
+ fail "$in_testname // wrong access specifier for virtual base: $access"
+ return
+ }
+ set list_vbases [lreplace $list_vbases 0 0]
+ set vbase_match 1
+ continue
+ }
+ }
+
+ # Data field.
+
+ if { [llength $list_fields] > 0 } then {
+ set field_access [lindex [lindex $list_fields 0] 0]
+ set field_decl [lindex [lindex $list_fields 0] 1]
+ if { "$actual_line" == "$field_decl" } then {
+ if { "$access" != "$field_access" } then {
+ cp_check_errata "$field_access" "$access" $in_errata_table
+ fail "$in_testname // wrong access specifier for field: $access"
+ return
+ }
+ set list_fields [lreplace $list_fields 0 0]
+ continue
+ }
+
+ # Data fields must appear before synths and methods.
+ cp_check_errata "$field_decl" "$actual_line" $in_errata_table
+ fail "$in_testname // unrecognized line type 1: $actual_line"
+ return
+ }
+
+ # Method function.
+
+ if { [llength $list_methods] > 0 } then {
+ set method_access [lindex [lindex $list_methods 0] 0]
+ set method_decl [lindex [lindex $list_methods 0] 1]
+ if { "$actual_line" == "$method_decl" } then {
+ if { "$access" != "$method_access" } then {
+ cp_check_errata "$method_access" "$access" $in_errata_table
+ fail "$in_testname // wrong access specifier for method: $access"
+ return
+ }
+ set list_methods [lreplace $list_methods 0 0]
+ continue
+ }
+
+ # gcc 2.95.3 shows "foo()" as "foo(void)".
+ regsub -all "\\(\\)" $method_decl "(void)" method_decl
+ if { "$actual_line" == "$method_decl" } then {
+ if { "$access" != "$method_access" } then {
+ cp_check_errata "$method_access" "$access" $in_errata_table
+ fail "$in_testname // wrong access specifier for method: $access"
+ return
+ }
+ set list_methods [lreplace $list_methods 0 0]
+ continue
+ }
+ }
+
+ # Synthetic operators. These are optional and can be mixed in
+ # with the methods in any order, but duplicates are wrong.
+ #
+ # This test must come after the user methods, so that a user
+ # method which matches a synth-method pattern is treated
+ # properly as a user method.
+
+ set synth_match 0
+ for { set isynth 0 } { $isynth < [llength $list_synth] } { incr isynth } {
+ set synth [lindex $list_synth $isynth]
+ set synth_count [lindex $synth 0]
+ set synth_access [lindex $synth 1]
+ set synth_re [lindex $synth 2]
+
+ if { [ regexp "$synth_re" "$actual_line" ] } then {
+
+ if { "$access" != "$synth_access" } then {
+ cp_check_errata "$synth_access" "$access" $in_errata_table
+ fail "$in_testname // wrong access specifier for synthetic operator: $access"
+ return
+ }
+
+ if { $synth_count > 0 } then {
+ cp_check_errata "$actual_line" "$actual_line" $in_errata_table
+ fail "$in_testname // duplicate synthetic operator: $actual_line"
+ }
+
+ # Update the count in list_synth.
+
+ incr synth_count
+ set synth [list $synth_count $synth_access "$synth_re"]
+ set list_synth [lreplace $list_synth $isynth $isynth $synth]
+
+ # Match found.
+
+ set synth_match 1
+ break
+ }
+ }
+ if { $synth_match } then { continue }
+
+ # Unrecognized line.
+
+ if { [llength $list_methods] > 0 } then {
+ set method_decl [lindex [lindex $list_methods 0] 1]
+ cp_check_errata "$method_decl" "$actual_line" $in_errata_table
+ }
+
+ fail "$in_testname // unrecognized line type 2: $actual_line"
+ return
+ }
+
+ # Check for missing elements.
+
+ if { $vbase_match } then {
+ if { [llength $list_vbases] > 0 } then {
+ fail "$in_testname // missing virtual base pointers"
+ return
+ }
+ }
+
+ if { [llength $list_fields] > 0 } then {
+ fail "$in_testname // missing fields"
+ return
+ }
+
+ if { [llength $list_methods] > 0 } then {
+ fail "$in_testname // missing methods"
+ return
+ }
+
+ # Check the tail.
+
+ set actual_tail [string trim $actual_tail]
+ if { "$actual_tail" != "$in_tail" } then {
+ cp_check_errata "$in_tail" "$actual_tail" $in_errata_table
+ fail "$in_testname // wrong tail: $actual_tail"
+ return
+ }
+
+ # It all worked!
+
+ pass "$in_testname"
+ return
+}
--- /dev/null
+/* Native-dependent code for VAX UNIXen (including older BSD's).
+
+ Copyright 2004 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. */
+
+#include "defs.h"
+#include "inferior.h"
+
+#include "gdb_assert.h"
+#include <sys/types.h>
+#include <sys/dir.h>
+#include <sys/user.h>
+
+#ifdef HAVE_SYS_PTRACE_H
+#include <sys/ptrace.h>
+#endif
+
+#ifndef PT_READ_U
+#define PT_READ_U 3
+#endif
+
+#ifdef SYS_REG_H
+/* UNIX 32V and derivatives (including 3BSD). */
+#include <sys/reg.h>
+#else
+/* 4.2BSD and derivatives. */
+#include <machine/reg.h>
+#endif
+
+#include "vax-tdep.h"
+
+/* Address of the user structure. This is the the value for 32V; 3BSD
+ uses a different value, but hey, who's still using those systems? */
+CORE_ADDR vax_kernel_u_addr = 0x80020000;
+
+/* Location of the user's stored registers; usage is `u.u_ar0[XX]'.
+ For 4.2BSD and ULTRIX these are negative! See <machine/reg.h>. */
+static int vax_register_index[] =
+{
+ R0, R1, R2, R3, R4, R5,
+ R6, R7, R8, R9, R10, R11,
+ AP, FP, SP, PC, PS
+};
+
+CORE_ADDR
+vax_register_u_addr (CORE_ADDR u_ar0, int regnum)
+{
+ gdb_assert (regnum >= 0 && regnum < ARRAY_SIZE (vax_register_index));
+
+ /* Type is `int *u_ar0'. See <sys/user.h>. */
+ return u_ar0 + vax_register_index[regnum - VAX_R0_REGNUM] * 4;
+}
+\f
+
+CORE_ADDR
+vax_register_u_offset (int regnum)
+{
+ size_t u_ar0_offset = offsetof (struct user, u_ar0);
+ CORE_ADDR u_ar0;
+ int pid;
+
+ errno = 0;
+ pid = PIDGET (inferior_ptid);
+ u_ar0 = ptrace (PT_READ_U, pid, u_ar0_offset, 0);
+ if (errno)
+ perror_with_name ("Unable to determine location of registers");
+
+ return vax_register_u_addr (u_ar0, regnum) - vax_kernel_u_addr;
+}
+\f
+
+#include <nlist.h>
+
+#ifndef _PATH_UNIX
+#define _PATH_UNIX "/vmunix"
+#endif
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_vax_nat (void);
+
+void
+_initialize_vax_nat (void)
+{
+ struct nlist names[2];
+
+ names[0].n_name = "_u";
+ names[1].n_name = NULL;
+ if (nlist (_PATH_UNIX, names) == 0)
+ vax_kernel_u_addr = names[0].n_value;
+}
--- /dev/null
+/* Native-dependent code for modern VAX BSD's.
+
+ Copyright 2004 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. */
+
+#include "defs.h"
+#include "inferior.h"
+#include "regcache.h"
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+
+#include "vax-tdep.h"
+
+/* Supply the general-purpose registers stored in GREGS to REGCACHE. */
+
+static void
+vaxbsd_supply_gregset (struct regcache *regcache, const void *gregs)
+{
+ const char *regs = gregs;
+ int regnum;
+
+ for (regnum = 0; regnum < VAX_NUM_REGS; regnum++)
+ regcache_raw_supply (regcache, regnum, regs + regnum * 4);
+}
+
+/* Collect the general-purpose registers from REGCACHE and store them
+ in GREGS. */
+
+static void
+vaxbsd_collect_gregset (const struct regcache *regcache,
+ void *gregs, int regnum)
+{
+ char *regs = gregs;
+ int i;
+
+ for (i = 0; i <= VAX_NUM_REGS; i++)
+ {
+ if (regnum == -1 || regnum == i)
+ regcache_raw_collect (regcache, i, regs + i * 4);
+ }
+}
+\f
+
+/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
+ for all registers. */
+
+void
+fetch_inferior_registers (int regnum)
+{
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name ("Couldn't get registers");
+
+ vaxbsd_supply_gregset (current_regcache, ®s);
+}
+
+/* Store register REGNUM back into the inferior. If REGNUM is -1, do
+ this for all registers. */
+
+void
+store_inferior_registers (int regnum)
+{
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name ("Couldn't get registers");
+
+ vaxbsd_collect_gregset (current_regcache, ®s, regnum);
+
+ if (ptrace (PT_SETREGS, PIDGET (inferior_ptid),
+ (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name ("Couldn't write registers");
+}
+\f
+
+/* Support for debugging kernel virtual memory images. */
+
+#include <sys/types.h>
+#include <machine/pcb.h>
+
+#include "bsd-kvm.h"
+
+static int
+vaxbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
+{
+ int regnum;
+
+ /* The following is true for OpenBSD 3.5:
+
+ The pcb contains the register state at the context switch inside
+ cpu_switch(). */
+
+ /* The stack pointer shouldn't be zero. */
+ if (pcb->KSP == 0)
+ return 0;
+
+ for (regnum = VAX_R0_REGNUM; regnum < VAX_AP_REGNUM; regnum++)
+ regcache_raw_supply (regcache, regnum, &pcb->R[regnum - VAX_R0_REGNUM]);
+ regcache_raw_supply (regcache, VAX_AP_REGNUM, &pcb->AP);
+ regcache_raw_supply (regcache, VAX_FP_REGNUM, &pcb->FP);
+ regcache_raw_supply (regcache, VAX_SP_REGNUM, &pcb->KSP);
+ regcache_raw_supply (regcache, VAX_PC_REGNUM, &pcb->PC);
+ regcache_raw_supply (regcache, VAX_PS_REGNUM, &pcb->PSL);
+
+ return 1;
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_vaxbsd_nat (void);
+
+void
+_initialize_vaxbsd_nat (void)
+{
+ /* Support debugging kernel virtual memory images. */
+ bsd_kvm_add_target (vaxbsd_supply_pcb);
+}
--- /dev/null
+/* Target-dependent code for NetBSD/vax.
+
+ Copyright 2004 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. */
+
+#include "defs.h"
+#include "arch-utils.h"
+#include "osabi.h"
+
+#include "vax-tdep.h"
+#include "solib-svr4.h"
+
+#include "gdb_string.h"
+
+/* Support for shared libraries. */
+
+/* Return non-zero if we are in a shared library trampoline code stub. */
+
+int
+vaxnbsd_aout_in_solib_call_trampoline (CORE_ADDR pc, char *name)
+{
+ return (name && !strcmp (name, "_DYNAMIC"));
+}
+\f
+
+/* NetBSD a.out. */
+
+static void
+vaxnbsd_aout_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ /* Assume SunOS-style shared libraries. */
+ set_gdbarch_in_solib_call_trampoline
+ (gdbarch, vaxnbsd_aout_in_solib_call_trampoline);
+}
+
+/* NetBSD ELF. */
+
+static void
+vaxnbsd_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ /* NetBSD ELF uses SVR4-style shared libraries. */
+ set_gdbarch_in_solib_call_trampoline
+ (gdbarch, generic_in_solib_call_trampoline);
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_vaxnbsd_tdep (void);
+
+void
+_initialize_vaxnbsd_tdep (void)
+{
+ gdbarch_register_osabi (bfd_arch_vax, 0, GDB_OSABI_NETBSD_AOUT,
+ vaxnbsd_aout_init_abi);
+ gdbarch_register_osabi (bfd_arch_vax, 0, GDB_OSABI_NETBSD_ELF,
+ vaxnbsd_elf_init_abi);
+}
--- /dev/null
+/* CRX ELF support for BFD.
+ Copyright 2004 Free Software Foundation, Inc.
+ Contributed by Tomer Levi, NSC, Israel.
+ Originally written for GAS 2.12 by Tomer Levi, NSC, Israel.
+ Updates, BFDizing, GNUifying and ELF support by Tomer Levi.
+
+ 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_CRX_H
+#define _ELF_CRX_H
+
+#include "elf/reloc-macros.h"
+
+/* Creating indices for reloc_map_index array. */
+START_RELOC_NUMBERS(elf_crx_reloc_type)
+ RELOC_NUMBER (R_CRX_NONE, 0)
+ RELOC_NUMBER (R_CRX_REL4, 1)
+ RELOC_NUMBER (R_CRX_REL8, 2)
+ RELOC_NUMBER (R_CRX_REL8_CMP, 3)
+ RELOC_NUMBER (R_CRX_REL16, 4)
+ RELOC_NUMBER (R_CRX_REL24, 5)
+ RELOC_NUMBER (R_CRX_REL32, 6)
+ RELOC_NUMBER (R_CRX_REGREL12, 7)
+ RELOC_NUMBER (R_CRX_REGREL22, 8)
+ RELOC_NUMBER (R_CRX_REGREL28, 9)
+ RELOC_NUMBER (R_CRX_REGREL32, 10)
+ RELOC_NUMBER (R_CRX_ABS16, 11)
+ RELOC_NUMBER (R_CRX_ABS32, 12)
+ RELOC_NUMBER (R_CRX_NUM8, 13)
+ RELOC_NUMBER (R_CRX_NUM16, 14)
+ RELOC_NUMBER (R_CRX_NUM32, 15)
+ RELOC_NUMBER (R_CRX_IMM16, 16)
+ RELOC_NUMBER (R_CRX_IMM32, 17)
+ RELOC_NUMBER (R_CRX_SWITCH8, 18)
+ RELOC_NUMBER (R_CRX_SWITCH16, 19)
+ RELOC_NUMBER (R_CRX_SWITCH32, 20)
+END_RELOC_NUMBERS(R_CRX_MAX)
+
+#endif /* _ELF_CRX_H */
--- /dev/null
+/* sim-ppc.h --- interface between PowerPC simulator and GDB.
+
+ Copyright 2004 Free Software Foundation, Inc.
+
+ Contributed by Red Hat.
+
+ 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. */
+
+#if !defined (SIM_PPC_H)
+#define SIM_PPC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* The register access functions, sim_fetch_register and
+ sim_store_register, use the following numbering for PowerPC
+ registers. */
+
+enum sim_ppc_regnum
+ {
+ /* General-purpose registers, r0 -- r31. */
+ sim_ppc_r0_regnum,
+ sim_ppc_r1_regnum,
+ sim_ppc_r2_regnum,
+ sim_ppc_r3_regnum,
+ sim_ppc_r4_regnum,
+ sim_ppc_r5_regnum,
+ sim_ppc_r6_regnum,
+ sim_ppc_r7_regnum,
+ sim_ppc_r8_regnum,
+ sim_ppc_r9_regnum,
+ sim_ppc_r10_regnum,
+ sim_ppc_r11_regnum,
+ sim_ppc_r12_regnum,
+ sim_ppc_r13_regnum,
+ sim_ppc_r14_regnum,
+ sim_ppc_r15_regnum,
+ sim_ppc_r16_regnum,
+ sim_ppc_r17_regnum,
+ sim_ppc_r18_regnum,
+ sim_ppc_r19_regnum,
+ sim_ppc_r20_regnum,
+ sim_ppc_r21_regnum,
+ sim_ppc_r22_regnum,
+ sim_ppc_r23_regnum,
+ sim_ppc_r24_regnum,
+ sim_ppc_r25_regnum,
+ sim_ppc_r26_regnum,
+ sim_ppc_r27_regnum,
+ sim_ppc_r28_regnum,
+ sim_ppc_r29_regnum,
+ sim_ppc_r30_regnum,
+ sim_ppc_r31_regnum,
+
+ /* Floating-point registers, f0 -- f31. */
+ sim_ppc_f0_regnum,
+ sim_ppc_f1_regnum,
+ sim_ppc_f2_regnum,
+ sim_ppc_f3_regnum,
+ sim_ppc_f4_regnum,
+ sim_ppc_f5_regnum,
+ sim_ppc_f6_regnum,
+ sim_ppc_f7_regnum,
+ sim_ppc_f8_regnum,
+ sim_ppc_f9_regnum,
+ sim_ppc_f10_regnum,
+ sim_ppc_f11_regnum,
+ sim_ppc_f12_regnum,
+ sim_ppc_f13_regnum,
+ sim_ppc_f14_regnum,
+ sim_ppc_f15_regnum,
+ sim_ppc_f16_regnum,
+ sim_ppc_f17_regnum,
+ sim_ppc_f18_regnum,
+ sim_ppc_f19_regnum,
+ sim_ppc_f20_regnum,
+ sim_ppc_f21_regnum,
+ sim_ppc_f22_regnum,
+ sim_ppc_f23_regnum,
+ sim_ppc_f24_regnum,
+ sim_ppc_f25_regnum,
+ sim_ppc_f26_regnum,
+ sim_ppc_f27_regnum,
+ sim_ppc_f28_regnum,
+ sim_ppc_f29_regnum,
+ sim_ppc_f30_regnum,
+ sim_ppc_f31_regnum,
+
+ /* Altivec vector registers, vr0 -- vr31. */
+ sim_ppc_vr0_regnum,
+ sim_ppc_vr1_regnum,
+ sim_ppc_vr2_regnum,
+ sim_ppc_vr3_regnum,
+ sim_ppc_vr4_regnum,
+ sim_ppc_vr5_regnum,
+ sim_ppc_vr6_regnum,
+ sim_ppc_vr7_regnum,
+ sim_ppc_vr8_regnum,
+ sim_ppc_vr9_regnum,
+ sim_ppc_vr10_regnum,
+ sim_ppc_vr11_regnum,
+ sim_ppc_vr12_regnum,
+ sim_ppc_vr13_regnum,
+ sim_ppc_vr14_regnum,
+ sim_ppc_vr15_regnum,
+ sim_ppc_vr16_regnum,
+ sim_ppc_vr17_regnum,
+ sim_ppc_vr18_regnum,
+ sim_ppc_vr19_regnum,
+ sim_ppc_vr20_regnum,
+ sim_ppc_vr21_regnum,
+ sim_ppc_vr22_regnum,
+ sim_ppc_vr23_regnum,
+ sim_ppc_vr24_regnum,
+ sim_ppc_vr25_regnum,
+ sim_ppc_vr26_regnum,
+ sim_ppc_vr27_regnum,
+ sim_ppc_vr28_regnum,
+ sim_ppc_vr29_regnum,
+ sim_ppc_vr30_regnum,
+ sim_ppc_vr31_regnum,
+
+ /* SPE APU GPR upper halves. These are the upper 32 bits of the
+ gprs; there is one upper-half register for each gpr, so it is
+ appropriate to use sim_ppc_num_gprs for iterating through
+ these. */
+ sim_ppc_rh0_regnum,
+ sim_ppc_rh1_regnum,
+ sim_ppc_rh2_regnum,
+ sim_ppc_rh3_regnum,
+ sim_ppc_rh4_regnum,
+ sim_ppc_rh5_regnum,
+ sim_ppc_rh6_regnum,
+ sim_ppc_rh7_regnum,
+ sim_ppc_rh8_regnum,
+ sim_ppc_rh9_regnum,
+ sim_ppc_rh10_regnum,
+ sim_ppc_rh11_regnum,
+ sim_ppc_rh12_regnum,
+ sim_ppc_rh13_regnum,
+ sim_ppc_rh14_regnum,
+ sim_ppc_rh15_regnum,
+ sim_ppc_rh16_regnum,
+ sim_ppc_rh17_regnum,
+ sim_ppc_rh18_regnum,
+ sim_ppc_rh19_regnum,
+ sim_ppc_rh20_regnum,
+ sim_ppc_rh21_regnum,
+ sim_ppc_rh22_regnum,
+ sim_ppc_rh23_regnum,
+ sim_ppc_rh24_regnum,
+ sim_ppc_rh25_regnum,
+ sim_ppc_rh26_regnum,
+ sim_ppc_rh27_regnum,
+ sim_ppc_rh28_regnum,
+ sim_ppc_rh29_regnum,
+ sim_ppc_rh30_regnum,
+ sim_ppc_rh31_regnum,
+
+ /* SPE APU GPR full registers. Each of these registers is the
+ 64-bit concatenation of a 32-bit GPR (providing the lower bits)
+ and a 32-bit upper-half register (providing the higher bits).
+ As for the upper-half registers, it is appropriate to use
+ sim_ppc_num_gprs with these. */
+ sim_ppc_ev0_regnum,
+ sim_ppc_ev1_regnum,
+ sim_ppc_ev2_regnum,
+ sim_ppc_ev3_regnum,
+ sim_ppc_ev4_regnum,
+ sim_ppc_ev5_regnum,
+ sim_ppc_ev6_regnum,
+ sim_ppc_ev7_regnum,
+ sim_ppc_ev8_regnum,
+ sim_ppc_ev9_regnum,
+ sim_ppc_ev10_regnum,
+ sim_ppc_ev11_regnum,
+ sim_ppc_ev12_regnum,
+ sim_ppc_ev13_regnum,
+ sim_ppc_ev14_regnum,
+ sim_ppc_ev15_regnum,
+ sim_ppc_ev16_regnum,
+ sim_ppc_ev17_regnum,
+ sim_ppc_ev18_regnum,
+ sim_ppc_ev19_regnum,
+ sim_ppc_ev20_regnum,
+ sim_ppc_ev21_regnum,
+ sim_ppc_ev22_regnum,
+ sim_ppc_ev23_regnum,
+ sim_ppc_ev24_regnum,
+ sim_ppc_ev25_regnum,
+ sim_ppc_ev26_regnum,
+ sim_ppc_ev27_regnum,
+ sim_ppc_ev28_regnum,
+ sim_ppc_ev29_regnum,
+ sim_ppc_ev30_regnum,
+ sim_ppc_ev31_regnum,
+
+ /* Segment registers, sr0 -- sr15. */
+ sim_ppc_sr0_regnum,
+ sim_ppc_sr1_regnum,
+ sim_ppc_sr2_regnum,
+ sim_ppc_sr3_regnum,
+ sim_ppc_sr4_regnum,
+ sim_ppc_sr5_regnum,
+ sim_ppc_sr6_regnum,
+ sim_ppc_sr7_regnum,
+ sim_ppc_sr8_regnum,
+ sim_ppc_sr9_regnum,
+ sim_ppc_sr10_regnum,
+ sim_ppc_sr11_regnum,
+ sim_ppc_sr12_regnum,
+ sim_ppc_sr13_regnum,
+ sim_ppc_sr14_regnum,
+ sim_ppc_sr15_regnum,
+
+ /* Miscellaneous --- but non-SPR --- registers. */
+ sim_ppc_pc_regnum,
+ sim_ppc_ps_regnum,
+ sim_ppc_cr_regnum,
+ sim_ppc_fpscr_regnum,
+ sim_ppc_acc_regnum,
+ sim_ppc_vscr_regnum,
+
+ /* Special-purpose registers. */
+ sim_ppc_spr0_regnum, sim_ppc_spr1_regnum,
+ sim_ppc_spr2_regnum, sim_ppc_spr3_regnum,
+ sim_ppc_spr4_regnum, sim_ppc_spr5_regnum,
+ sim_ppc_spr6_regnum, sim_ppc_spr7_regnum,
+ sim_ppc_spr8_regnum, sim_ppc_spr9_regnum,
+ sim_ppc_spr10_regnum, sim_ppc_spr11_regnum,
+ sim_ppc_spr12_regnum, sim_ppc_spr13_regnum,
+ sim_ppc_spr14_regnum, sim_ppc_spr15_regnum,
+ sim_ppc_spr16_regnum, sim_ppc_spr17_regnum,
+ sim_ppc_spr18_regnum, sim_ppc_spr19_regnum,
+ sim_ppc_spr20_regnum, sim_ppc_spr21_regnum,
+ sim_ppc_spr22_regnum, sim_ppc_spr23_regnum,
+ sim_ppc_spr24_regnum, sim_ppc_spr25_regnum,
+ sim_ppc_spr26_regnum, sim_ppc_spr27_regnum,
+ sim_ppc_spr28_regnum, sim_ppc_spr29_regnum,
+ sim_ppc_spr30_regnum, sim_ppc_spr31_regnum,
+ sim_ppc_spr32_regnum, sim_ppc_spr33_regnum,
+ sim_ppc_spr34_regnum, sim_ppc_spr35_regnum,
+ sim_ppc_spr36_regnum, sim_ppc_spr37_regnum,
+ sim_ppc_spr38_regnum, sim_ppc_spr39_regnum,
+ sim_ppc_spr40_regnum, sim_ppc_spr41_regnum,
+ sim_ppc_spr42_regnum, sim_ppc_spr43_regnum,
+ sim_ppc_spr44_regnum, sim_ppc_spr45_regnum,
+ sim_ppc_spr46_regnum, sim_ppc_spr47_regnum,
+ sim_ppc_spr48_regnum, sim_ppc_spr49_regnum,
+ sim_ppc_spr50_regnum, sim_ppc_spr51_regnum,
+ sim_ppc_spr52_regnum, sim_ppc_spr53_regnum,
+ sim_ppc_spr54_regnum, sim_ppc_spr55_regnum,
+ sim_ppc_spr56_regnum, sim_ppc_spr57_regnum,
+ sim_ppc_spr58_regnum, sim_ppc_spr59_regnum,
+ sim_ppc_spr60_regnum, sim_ppc_spr61_regnum,
+ sim_ppc_spr62_regnum, sim_ppc_spr63_regnum,
+ sim_ppc_spr64_regnum, sim_ppc_spr65_regnum,
+ sim_ppc_spr66_regnum, sim_ppc_spr67_regnum,
+ sim_ppc_spr68_regnum, sim_ppc_spr69_regnum,
+ sim_ppc_spr70_regnum, sim_ppc_spr71_regnum,
+ sim_ppc_spr72_regnum, sim_ppc_spr73_regnum,
+ sim_ppc_spr74_regnum, sim_ppc_spr75_regnum,
+ sim_ppc_spr76_regnum, sim_ppc_spr77_regnum,
+ sim_ppc_spr78_regnum, sim_ppc_spr79_regnum,
+ sim_ppc_spr80_regnum, sim_ppc_spr81_regnum,
+ sim_ppc_spr82_regnum, sim_ppc_spr83_regnum,
+ sim_ppc_spr84_regnum, sim_ppc_spr85_regnum,
+ sim_ppc_spr86_regnum, sim_ppc_spr87_regnum,
+ sim_ppc_spr88_regnum, sim_ppc_spr89_regnum,
+ sim_ppc_spr90_regnum, sim_ppc_spr91_regnum,
+ sim_ppc_spr92_regnum, sim_ppc_spr93_regnum,
+ sim_ppc_spr94_regnum, sim_ppc_spr95_regnum,
+ sim_ppc_spr96_regnum, sim_ppc_spr97_regnum,
+ sim_ppc_spr98_regnum, sim_ppc_spr99_regnum,
+ sim_ppc_spr100_regnum, sim_ppc_spr101_regnum,
+ sim_ppc_spr102_regnum, sim_ppc_spr103_regnum,
+ sim_ppc_spr104_regnum, sim_ppc_spr105_regnum,
+ sim_ppc_spr106_regnum, sim_ppc_spr107_regnum,
+ sim_ppc_spr108_regnum, sim_ppc_spr109_regnum,
+ sim_ppc_spr110_regnum, sim_ppc_spr111_regnum,
+ sim_ppc_spr112_regnum, sim_ppc_spr113_regnum,
+ sim_ppc_spr114_regnum, sim_ppc_spr115_regnum,
+ sim_ppc_spr116_regnum, sim_ppc_spr117_regnum,
+ sim_ppc_spr118_regnum, sim_ppc_spr119_regnum,
+ sim_ppc_spr120_regnum, sim_ppc_spr121_regnum,
+ sim_ppc_spr122_regnum, sim_ppc_spr123_regnum,
+ sim_ppc_spr124_regnum, sim_ppc_spr125_regnum,
+ sim_ppc_spr126_regnum, sim_ppc_spr127_regnum,
+ sim_ppc_spr128_regnum, sim_ppc_spr129_regnum,
+ sim_ppc_spr130_regnum, sim_ppc_spr131_regnum,
+ sim_ppc_spr132_regnum, sim_ppc_spr133_regnum,
+ sim_ppc_spr134_regnum, sim_ppc_spr135_regnum,
+ sim_ppc_spr136_regnum, sim_ppc_spr137_regnum,
+ sim_ppc_spr138_regnum, sim_ppc_spr139_regnum,
+ sim_ppc_spr140_regnum, sim_ppc_spr141_regnum,
+ sim_ppc_spr142_regnum, sim_ppc_spr143_regnum,
+ sim_ppc_spr144_regnum, sim_ppc_spr145_regnum,
+ sim_ppc_spr146_regnum, sim_ppc_spr147_regnum,
+ sim_ppc_spr148_regnum, sim_ppc_spr149_regnum,
+ sim_ppc_spr150_regnum, sim_ppc_spr151_regnum,
+ sim_ppc_spr152_regnum, sim_ppc_spr153_regnum,
+ sim_ppc_spr154_regnum, sim_ppc_spr155_regnum,
+ sim_ppc_spr156_regnum, sim_ppc_spr157_regnum,
+ sim_ppc_spr158_regnum, sim_ppc_spr159_regnum,
+ sim_ppc_spr160_regnum, sim_ppc_spr161_regnum,
+ sim_ppc_spr162_regnum, sim_ppc_spr163_regnum,
+ sim_ppc_spr164_regnum, sim_ppc_spr165_regnum,
+ sim_ppc_spr166_regnum, sim_ppc_spr167_regnum,
+ sim_ppc_spr168_regnum, sim_ppc_spr169_regnum,
+ sim_ppc_spr170_regnum, sim_ppc_spr171_regnum,
+ sim_ppc_spr172_regnum, sim_ppc_spr173_regnum,
+ sim_ppc_spr174_regnum, sim_ppc_spr175_regnum,
+ sim_ppc_spr176_regnum, sim_ppc_spr177_regnum,
+ sim_ppc_spr178_regnum, sim_ppc_spr179_regnum,
+ sim_ppc_spr180_regnum, sim_ppc_spr181_regnum,
+ sim_ppc_spr182_regnum, sim_ppc_spr183_regnum,
+ sim_ppc_spr184_regnum, sim_ppc_spr185_regnum,
+ sim_ppc_spr186_regnum, sim_ppc_spr187_regnum,
+ sim_ppc_spr188_regnum, sim_ppc_spr189_regnum,
+ sim_ppc_spr190_regnum, sim_ppc_spr191_regnum,
+ sim_ppc_spr192_regnum, sim_ppc_spr193_regnum,
+ sim_ppc_spr194_regnum, sim_ppc_spr195_regnum,
+ sim_ppc_spr196_regnum, sim_ppc_spr197_regnum,
+ sim_ppc_spr198_regnum, sim_ppc_spr199_regnum,
+ sim_ppc_spr200_regnum, sim_ppc_spr201_regnum,
+ sim_ppc_spr202_regnum, sim_ppc_spr203_regnum,
+ sim_ppc_spr204_regnum, sim_ppc_spr205_regnum,
+ sim_ppc_spr206_regnum, sim_ppc_spr207_regnum,
+ sim_ppc_spr208_regnum, sim_ppc_spr209_regnum,
+ sim_ppc_spr210_regnum, sim_ppc_spr211_regnum,
+ sim_ppc_spr212_regnum, sim_ppc_spr213_regnum,
+ sim_ppc_spr214_regnum, sim_ppc_spr215_regnum,
+ sim_ppc_spr216_regnum, sim_ppc_spr217_regnum,
+ sim_ppc_spr218_regnum, sim_ppc_spr219_regnum,
+ sim_ppc_spr220_regnum, sim_ppc_spr221_regnum,
+ sim_ppc_spr222_regnum, sim_ppc_spr223_regnum,
+ sim_ppc_spr224_regnum, sim_ppc_spr225_regnum,
+ sim_ppc_spr226_regnum, sim_ppc_spr227_regnum,
+ sim_ppc_spr228_regnum, sim_ppc_spr229_regnum,
+ sim_ppc_spr230_regnum, sim_ppc_spr231_regnum,
+ sim_ppc_spr232_regnum, sim_ppc_spr233_regnum,
+ sim_ppc_spr234_regnum, sim_ppc_spr235_regnum,
+ sim_ppc_spr236_regnum, sim_ppc_spr237_regnum,
+ sim_ppc_spr238_regnum, sim_ppc_spr239_regnum,
+ sim_ppc_spr240_regnum, sim_ppc_spr241_regnum,
+ sim_ppc_spr242_regnum, sim_ppc_spr243_regnum,
+ sim_ppc_spr244_regnum, sim_ppc_spr245_regnum,
+ sim_ppc_spr246_regnum, sim_ppc_spr247_regnum,
+ sim_ppc_spr248_regnum, sim_ppc_spr249_regnum,
+ sim_ppc_spr250_regnum, sim_ppc_spr251_regnum,
+ sim_ppc_spr252_regnum, sim_ppc_spr253_regnum,
+ sim_ppc_spr254_regnum, sim_ppc_spr255_regnum,
+ sim_ppc_spr256_regnum, sim_ppc_spr257_regnum,
+ sim_ppc_spr258_regnum, sim_ppc_spr259_regnum,
+ sim_ppc_spr260_regnum, sim_ppc_spr261_regnum,
+ sim_ppc_spr262_regnum, sim_ppc_spr263_regnum,
+ sim_ppc_spr264_regnum, sim_ppc_spr265_regnum,
+ sim_ppc_spr266_regnum, sim_ppc_spr267_regnum,
+ sim_ppc_spr268_regnum, sim_ppc_spr269_regnum,
+ sim_ppc_spr270_regnum, sim_ppc_spr271_regnum,
+ sim_ppc_spr272_regnum, sim_ppc_spr273_regnum,
+ sim_ppc_spr274_regnum, sim_ppc_spr275_regnum,
+ sim_ppc_spr276_regnum, sim_ppc_spr277_regnum,
+ sim_ppc_spr278_regnum, sim_ppc_spr279_regnum,
+ sim_ppc_spr280_regnum, sim_ppc_spr281_regnum,
+ sim_ppc_spr282_regnum, sim_ppc_spr283_regnum,
+ sim_ppc_spr284_regnum, sim_ppc_spr285_regnum,
+ sim_ppc_spr286_regnum, sim_ppc_spr287_regnum,
+ sim_ppc_spr288_regnum, sim_ppc_spr289_regnum,
+ sim_ppc_spr290_regnum, sim_ppc_spr291_regnum,
+ sim_ppc_spr292_regnum, sim_ppc_spr293_regnum,
+ sim_ppc_spr294_regnum, sim_ppc_spr295_regnum,
+ sim_ppc_spr296_regnum, sim_ppc_spr297_regnum,
+ sim_ppc_spr298_regnum, sim_ppc_spr299_regnum,
+ sim_ppc_spr300_regnum, sim_ppc_spr301_regnum,
+ sim_ppc_spr302_regnum, sim_ppc_spr303_regnum,
+ sim_ppc_spr304_regnum, sim_ppc_spr305_regnum,
+ sim_ppc_spr306_regnum, sim_ppc_spr307_regnum,
+ sim_ppc_spr308_regnum, sim_ppc_spr309_regnum,
+ sim_ppc_spr310_regnum, sim_ppc_spr311_regnum,
+ sim_ppc_spr312_regnum, sim_ppc_spr313_regnum,
+ sim_ppc_spr314_regnum, sim_ppc_spr315_regnum,
+ sim_ppc_spr316_regnum, sim_ppc_spr317_regnum,
+ sim_ppc_spr318_regnum, sim_ppc_spr319_regnum,
+ sim_ppc_spr320_regnum, sim_ppc_spr321_regnum,
+ sim_ppc_spr322_regnum, sim_ppc_spr323_regnum,
+ sim_ppc_spr324_regnum, sim_ppc_spr325_regnum,
+ sim_ppc_spr326_regnum, sim_ppc_spr327_regnum,
+ sim_ppc_spr328_regnum, sim_ppc_spr329_regnum,
+ sim_ppc_spr330_regnum, sim_ppc_spr331_regnum,
+ sim_ppc_spr332_regnum, sim_ppc_spr333_regnum,
+ sim_ppc_spr334_regnum, sim_ppc_spr335_regnum,
+ sim_ppc_spr336_regnum, sim_ppc_spr337_regnum,
+ sim_ppc_spr338_regnum, sim_ppc_spr339_regnum,
+ sim_ppc_spr340_regnum, sim_ppc_spr341_regnum,
+ sim_ppc_spr342_regnum, sim_ppc_spr343_regnum,
+ sim_ppc_spr344_regnum, sim_ppc_spr345_regnum,
+ sim_ppc_spr346_regnum, sim_ppc_spr347_regnum,
+ sim_ppc_spr348_regnum, sim_ppc_spr349_regnum,
+ sim_ppc_spr350_regnum, sim_ppc_spr351_regnum,
+ sim_ppc_spr352_regnum, sim_ppc_spr353_regnum,
+ sim_ppc_spr354_regnum, sim_ppc_spr355_regnum,
+ sim_ppc_spr356_regnum, sim_ppc_spr357_regnum,
+ sim_ppc_spr358_regnum, sim_ppc_spr359_regnum,
+ sim_ppc_spr360_regnum, sim_ppc_spr361_regnum,
+ sim_ppc_spr362_regnum, sim_ppc_spr363_regnum,
+ sim_ppc_spr364_regnum, sim_ppc_spr365_regnum,
+ sim_ppc_spr366_regnum, sim_ppc_spr367_regnum,
+ sim_ppc_spr368_regnum, sim_ppc_spr369_regnum,
+ sim_ppc_spr370_regnum, sim_ppc_spr371_regnum,
+ sim_ppc_spr372_regnum, sim_ppc_spr373_regnum,
+ sim_ppc_spr374_regnum, sim_ppc_spr375_regnum,
+ sim_ppc_spr376_regnum, sim_ppc_spr377_regnum,
+ sim_ppc_spr378_regnum, sim_ppc_spr379_regnum,
+ sim_ppc_spr380_regnum, sim_ppc_spr381_regnum,
+ sim_ppc_spr382_regnum, sim_ppc_spr383_regnum,
+ sim_ppc_spr384_regnum, sim_ppc_spr385_regnum,
+ sim_ppc_spr386_regnum, sim_ppc_spr387_regnum,
+ sim_ppc_spr388_regnum, sim_ppc_spr389_regnum,
+ sim_ppc_spr390_regnum, sim_ppc_spr391_regnum,
+ sim_ppc_spr392_regnum, sim_ppc_spr393_regnum,
+ sim_ppc_spr394_regnum, sim_ppc_spr395_regnum,
+ sim_ppc_spr396_regnum, sim_ppc_spr397_regnum,
+ sim_ppc_spr398_regnum, sim_ppc_spr399_regnum,
+ sim_ppc_spr400_regnum, sim_ppc_spr401_regnum,
+ sim_ppc_spr402_regnum, sim_ppc_spr403_regnum,
+ sim_ppc_spr404_regnum, sim_ppc_spr405_regnum,
+ sim_ppc_spr406_regnum, sim_ppc_spr407_regnum,
+ sim_ppc_spr408_regnum, sim_ppc_spr409_regnum,
+ sim_ppc_spr410_regnum, sim_ppc_spr411_regnum,
+ sim_ppc_spr412_regnum, sim_ppc_spr413_regnum,
+ sim_ppc_spr414_regnum, sim_ppc_spr415_regnum,
+ sim_ppc_spr416_regnum, sim_ppc_spr417_regnum,
+ sim_ppc_spr418_regnum, sim_ppc_spr419_regnum,
+ sim_ppc_spr420_regnum, sim_ppc_spr421_regnum,
+ sim_ppc_spr422_regnum, sim_ppc_spr423_regnum,
+ sim_ppc_spr424_regnum, sim_ppc_spr425_regnum,
+ sim_ppc_spr426_regnum, sim_ppc_spr427_regnum,
+ sim_ppc_spr428_regnum, sim_ppc_spr429_regnum,
+ sim_ppc_spr430_regnum, sim_ppc_spr431_regnum,
+ sim_ppc_spr432_regnum, sim_ppc_spr433_regnum,
+ sim_ppc_spr434_regnum, sim_ppc_spr435_regnum,
+ sim_ppc_spr436_regnum, sim_ppc_spr437_regnum,
+ sim_ppc_spr438_regnum, sim_ppc_spr439_regnum,
+ sim_ppc_spr440_regnum, sim_ppc_spr441_regnum,
+ sim_ppc_spr442_regnum, sim_ppc_spr443_regnum,
+ sim_ppc_spr444_regnum, sim_ppc_spr445_regnum,
+ sim_ppc_spr446_regnum, sim_ppc_spr447_regnum,
+ sim_ppc_spr448_regnum, sim_ppc_spr449_regnum,
+ sim_ppc_spr450_regnum, sim_ppc_spr451_regnum,
+ sim_ppc_spr452_regnum, sim_ppc_spr453_regnum,
+ sim_ppc_spr454_regnum, sim_ppc_spr455_regnum,
+ sim_ppc_spr456_regnum, sim_ppc_spr457_regnum,
+ sim_ppc_spr458_regnum, sim_ppc_spr459_regnum,
+ sim_ppc_spr460_regnum, sim_ppc_spr461_regnum,
+ sim_ppc_spr462_regnum, sim_ppc_spr463_regnum,
+ sim_ppc_spr464_regnum, sim_ppc_spr465_regnum,
+ sim_ppc_spr466_regnum, sim_ppc_spr467_regnum,
+ sim_ppc_spr468_regnum, sim_ppc_spr469_regnum,
+ sim_ppc_spr470_regnum, sim_ppc_spr471_regnum,
+ sim_ppc_spr472_regnum, sim_ppc_spr473_regnum,
+ sim_ppc_spr474_regnum, sim_ppc_spr475_regnum,
+ sim_ppc_spr476_regnum, sim_ppc_spr477_regnum,
+ sim_ppc_spr478_regnum, sim_ppc_spr479_regnum,
+ sim_ppc_spr480_regnum, sim_ppc_spr481_regnum,
+ sim_ppc_spr482_regnum, sim_ppc_spr483_regnum,
+ sim_ppc_spr484_regnum, sim_ppc_spr485_regnum,
+ sim_ppc_spr486_regnum, sim_ppc_spr487_regnum,
+ sim_ppc_spr488_regnum, sim_ppc_spr489_regnum,
+ sim_ppc_spr490_regnum, sim_ppc_spr491_regnum,
+ sim_ppc_spr492_regnum, sim_ppc_spr493_regnum,
+ sim_ppc_spr494_regnum, sim_ppc_spr495_regnum,
+ sim_ppc_spr496_regnum, sim_ppc_spr497_regnum,
+ sim_ppc_spr498_regnum, sim_ppc_spr499_regnum,
+ sim_ppc_spr500_regnum, sim_ppc_spr501_regnum,
+ sim_ppc_spr502_regnum, sim_ppc_spr503_regnum,
+ sim_ppc_spr504_regnum, sim_ppc_spr505_regnum,
+ sim_ppc_spr506_regnum, sim_ppc_spr507_regnum,
+ sim_ppc_spr508_regnum, sim_ppc_spr509_regnum,
+ sim_ppc_spr510_regnum, sim_ppc_spr511_regnum,
+ sim_ppc_spr512_regnum, sim_ppc_spr513_regnum,
+ sim_ppc_spr514_regnum, sim_ppc_spr515_regnum,
+ sim_ppc_spr516_regnum, sim_ppc_spr517_regnum,
+ sim_ppc_spr518_regnum, sim_ppc_spr519_regnum,
+ sim_ppc_spr520_regnum, sim_ppc_spr521_regnum,
+ sim_ppc_spr522_regnum, sim_ppc_spr523_regnum,
+ sim_ppc_spr524_regnum, sim_ppc_spr525_regnum,
+ sim_ppc_spr526_regnum, sim_ppc_spr527_regnum,
+ sim_ppc_spr528_regnum, sim_ppc_spr529_regnum,
+ sim_ppc_spr530_regnum, sim_ppc_spr531_regnum,
+ sim_ppc_spr532_regnum, sim_ppc_spr533_regnum,
+ sim_ppc_spr534_regnum, sim_ppc_spr535_regnum,
+ sim_ppc_spr536_regnum, sim_ppc_spr537_regnum,
+ sim_ppc_spr538_regnum, sim_ppc_spr539_regnum,
+ sim_ppc_spr540_regnum, sim_ppc_spr541_regnum,
+ sim_ppc_spr542_regnum, sim_ppc_spr543_regnum,
+ sim_ppc_spr544_regnum, sim_ppc_spr545_regnum,
+ sim_ppc_spr546_regnum, sim_ppc_spr547_regnum,
+ sim_ppc_spr548_regnum, sim_ppc_spr549_regnum,
+ sim_ppc_spr550_regnum, sim_ppc_spr551_regnum,
+ sim_ppc_spr552_regnum, sim_ppc_spr553_regnum,
+ sim_ppc_spr554_regnum, sim_ppc_spr555_regnum,
+ sim_ppc_spr556_regnum, sim_ppc_spr557_regnum,
+ sim_ppc_spr558_regnum, sim_ppc_spr559_regnum,
+ sim_ppc_spr560_regnum, sim_ppc_spr561_regnum,
+ sim_ppc_spr562_regnum, sim_ppc_spr563_regnum,
+ sim_ppc_spr564_regnum, sim_ppc_spr565_regnum,
+ sim_ppc_spr566_regnum, sim_ppc_spr567_regnum,
+ sim_ppc_spr568_regnum, sim_ppc_spr569_regnum,
+ sim_ppc_spr570_regnum, sim_ppc_spr571_regnum,
+ sim_ppc_spr572_regnum, sim_ppc_spr573_regnum,
+ sim_ppc_spr574_regnum, sim_ppc_spr575_regnum,
+ sim_ppc_spr576_regnum, sim_ppc_spr577_regnum,
+ sim_ppc_spr578_regnum, sim_ppc_spr579_regnum,
+ sim_ppc_spr580_regnum, sim_ppc_spr581_regnum,
+ sim_ppc_spr582_regnum, sim_ppc_spr583_regnum,
+ sim_ppc_spr584_regnum, sim_ppc_spr585_regnum,
+ sim_ppc_spr586_regnum, sim_ppc_spr587_regnum,
+ sim_ppc_spr588_regnum, sim_ppc_spr589_regnum,
+ sim_ppc_spr590_regnum, sim_ppc_spr591_regnum,
+ sim_ppc_spr592_regnum, sim_ppc_spr593_regnum,
+ sim_ppc_spr594_regnum, sim_ppc_spr595_regnum,
+ sim_ppc_spr596_regnum, sim_ppc_spr597_regnum,
+ sim_ppc_spr598_regnum, sim_ppc_spr599_regnum,
+ sim_ppc_spr600_regnum, sim_ppc_spr601_regnum,
+ sim_ppc_spr602_regnum, sim_ppc_spr603_regnum,
+ sim_ppc_spr604_regnum, sim_ppc_spr605_regnum,
+ sim_ppc_spr606_regnum, sim_ppc_spr607_regnum,
+ sim_ppc_spr608_regnum, sim_ppc_spr609_regnum,
+ sim_ppc_spr610_regnum, sim_ppc_spr611_regnum,
+ sim_ppc_spr612_regnum, sim_ppc_spr613_regnum,
+ sim_ppc_spr614_regnum, sim_ppc_spr615_regnum,
+ sim_ppc_spr616_regnum, sim_ppc_spr617_regnum,
+ sim_ppc_spr618_regnum, sim_ppc_spr619_regnum,
+ sim_ppc_spr620_regnum, sim_ppc_spr621_regnum,
+ sim_ppc_spr622_regnum, sim_ppc_spr623_regnum,
+ sim_ppc_spr624_regnum, sim_ppc_spr625_regnum,
+ sim_ppc_spr626_regnum, sim_ppc_spr627_regnum,
+ sim_ppc_spr628_regnum, sim_ppc_spr629_regnum,
+ sim_ppc_spr630_regnum, sim_ppc_spr631_regnum,
+ sim_ppc_spr632_regnum, sim_ppc_spr633_regnum,
+ sim_ppc_spr634_regnum, sim_ppc_spr635_regnum,
+ sim_ppc_spr636_regnum, sim_ppc_spr637_regnum,
+ sim_ppc_spr638_regnum, sim_ppc_spr639_regnum,
+ sim_ppc_spr640_regnum, sim_ppc_spr641_regnum,
+ sim_ppc_spr642_regnum, sim_ppc_spr643_regnum,
+ sim_ppc_spr644_regnum, sim_ppc_spr645_regnum,
+ sim_ppc_spr646_regnum, sim_ppc_spr647_regnum,
+ sim_ppc_spr648_regnum, sim_ppc_spr649_regnum,
+ sim_ppc_spr650_regnum, sim_ppc_spr651_regnum,
+ sim_ppc_spr652_regnum, sim_ppc_spr653_regnum,
+ sim_ppc_spr654_regnum, sim_ppc_spr655_regnum,
+ sim_ppc_spr656_regnum, sim_ppc_spr657_regnum,
+ sim_ppc_spr658_regnum, sim_ppc_spr659_regnum,
+ sim_ppc_spr660_regnum, sim_ppc_spr661_regnum,
+ sim_ppc_spr662_regnum, sim_ppc_spr663_regnum,
+ sim_ppc_spr664_regnum, sim_ppc_spr665_regnum,
+ sim_ppc_spr666_regnum, sim_ppc_spr667_regnum,
+ sim_ppc_spr668_regnum, sim_ppc_spr669_regnum,
+ sim_ppc_spr670_regnum, sim_ppc_spr671_regnum,
+ sim_ppc_spr672_regnum, sim_ppc_spr673_regnum,
+ sim_ppc_spr674_regnum, sim_ppc_spr675_regnum,
+ sim_ppc_spr676_regnum, sim_ppc_spr677_regnum,
+ sim_ppc_spr678_regnum, sim_ppc_spr679_regnum,
+ sim_ppc_spr680_regnum, sim_ppc_spr681_regnum,
+ sim_ppc_spr682_regnum, sim_ppc_spr683_regnum,
+ sim_ppc_spr684_regnum, sim_ppc_spr685_regnum,
+ sim_ppc_spr686_regnum, sim_ppc_spr687_regnum,
+ sim_ppc_spr688_regnum, sim_ppc_spr689_regnum,
+ sim_ppc_spr690_regnum, sim_ppc_spr691_regnum,
+ sim_ppc_spr692_regnum, sim_ppc_spr693_regnum,
+ sim_ppc_spr694_regnum, sim_ppc_spr695_regnum,
+ sim_ppc_spr696_regnum, sim_ppc_spr697_regnum,
+ sim_ppc_spr698_regnum, sim_ppc_spr699_regnum,
+ sim_ppc_spr700_regnum, sim_ppc_spr701_regnum,
+ sim_ppc_spr702_regnum, sim_ppc_spr703_regnum,
+ sim_ppc_spr704_regnum, sim_ppc_spr705_regnum,
+ sim_ppc_spr706_regnum, sim_ppc_spr707_regnum,
+ sim_ppc_spr708_regnum, sim_ppc_spr709_regnum,
+ sim_ppc_spr710_regnum, sim_ppc_spr711_regnum,
+ sim_ppc_spr712_regnum, sim_ppc_spr713_regnum,
+ sim_ppc_spr714_regnum, sim_ppc_spr715_regnum,
+ sim_ppc_spr716_regnum, sim_ppc_spr717_regnum,
+ sim_ppc_spr718_regnum, sim_ppc_spr719_regnum,
+ sim_ppc_spr720_regnum, sim_ppc_spr721_regnum,
+ sim_ppc_spr722_regnum, sim_ppc_spr723_regnum,
+ sim_ppc_spr724_regnum, sim_ppc_spr725_regnum,
+ sim_ppc_spr726_regnum, sim_ppc_spr727_regnum,
+ sim_ppc_spr728_regnum, sim_ppc_spr729_regnum,
+ sim_ppc_spr730_regnum, sim_ppc_spr731_regnum,
+ sim_ppc_spr732_regnum, sim_ppc_spr733_regnum,
+ sim_ppc_spr734_regnum, sim_ppc_spr735_regnum,
+ sim_ppc_spr736_regnum, sim_ppc_spr737_regnum,
+ sim_ppc_spr738_regnum, sim_ppc_spr739_regnum,
+ sim_ppc_spr740_regnum, sim_ppc_spr741_regnum,
+ sim_ppc_spr742_regnum, sim_ppc_spr743_regnum,
+ sim_ppc_spr744_regnum, sim_ppc_spr745_regnum,
+ sim_ppc_spr746_regnum, sim_ppc_spr747_regnum,
+ sim_ppc_spr748_regnum, sim_ppc_spr749_regnum,
+ sim_ppc_spr750_regnum, sim_ppc_spr751_regnum,
+ sim_ppc_spr752_regnum, sim_ppc_spr753_regnum,
+ sim_ppc_spr754_regnum, sim_ppc_spr755_regnum,
+ sim_ppc_spr756_regnum, sim_ppc_spr757_regnum,
+ sim_ppc_spr758_regnum, sim_ppc_spr759_regnum,
+ sim_ppc_spr760_regnum, sim_ppc_spr761_regnum,
+ sim_ppc_spr762_regnum, sim_ppc_spr763_regnum,
+ sim_ppc_spr764_regnum, sim_ppc_spr765_regnum,
+ sim_ppc_spr766_regnum, sim_ppc_spr767_regnum,
+ sim_ppc_spr768_regnum, sim_ppc_spr769_regnum,
+ sim_ppc_spr770_regnum, sim_ppc_spr771_regnum,
+ sim_ppc_spr772_regnum, sim_ppc_spr773_regnum,
+ sim_ppc_spr774_regnum, sim_ppc_spr775_regnum,
+ sim_ppc_spr776_regnum, sim_ppc_spr777_regnum,
+ sim_ppc_spr778_regnum, sim_ppc_spr779_regnum,
+ sim_ppc_spr780_regnum, sim_ppc_spr781_regnum,
+ sim_ppc_spr782_regnum, sim_ppc_spr783_regnum,
+ sim_ppc_spr784_regnum, sim_ppc_spr785_regnum,
+ sim_ppc_spr786_regnum, sim_ppc_spr787_regnum,
+ sim_ppc_spr788_regnum, sim_ppc_spr789_regnum,
+ sim_ppc_spr790_regnum, sim_ppc_spr791_regnum,
+ sim_ppc_spr792_regnum, sim_ppc_spr793_regnum,
+ sim_ppc_spr794_regnum, sim_ppc_spr795_regnum,
+ sim_ppc_spr796_regnum, sim_ppc_spr797_regnum,
+ sim_ppc_spr798_regnum, sim_ppc_spr799_regnum,
+ sim_ppc_spr800_regnum, sim_ppc_spr801_regnum,
+ sim_ppc_spr802_regnum, sim_ppc_spr803_regnum,
+ sim_ppc_spr804_regnum, sim_ppc_spr805_regnum,
+ sim_ppc_spr806_regnum, sim_ppc_spr807_regnum,
+ sim_ppc_spr808_regnum, sim_ppc_spr809_regnum,
+ sim_ppc_spr810_regnum, sim_ppc_spr811_regnum,
+ sim_ppc_spr812_regnum, sim_ppc_spr813_regnum,
+ sim_ppc_spr814_regnum, sim_ppc_spr815_regnum,
+ sim_ppc_spr816_regnum, sim_ppc_spr817_regnum,
+ sim_ppc_spr818_regnum, sim_ppc_spr819_regnum,
+ sim_ppc_spr820_regnum, sim_ppc_spr821_regnum,
+ sim_ppc_spr822_regnum, sim_ppc_spr823_regnum,
+ sim_ppc_spr824_regnum, sim_ppc_spr825_regnum,
+ sim_ppc_spr826_regnum, sim_ppc_spr827_regnum,
+ sim_ppc_spr828_regnum, sim_ppc_spr829_regnum,
+ sim_ppc_spr830_regnum, sim_ppc_spr831_regnum,
+ sim_ppc_spr832_regnum, sim_ppc_spr833_regnum,
+ sim_ppc_spr834_regnum, sim_ppc_spr835_regnum,
+ sim_ppc_spr836_regnum, sim_ppc_spr837_regnum,
+ sim_ppc_spr838_regnum, sim_ppc_spr839_regnum,
+ sim_ppc_spr840_regnum, sim_ppc_spr841_regnum,
+ sim_ppc_spr842_regnum, sim_ppc_spr843_regnum,
+ sim_ppc_spr844_regnum, sim_ppc_spr845_regnum,
+ sim_ppc_spr846_regnum, sim_ppc_spr847_regnum,
+ sim_ppc_spr848_regnum, sim_ppc_spr849_regnum,
+ sim_ppc_spr850_regnum, sim_ppc_spr851_regnum,
+ sim_ppc_spr852_regnum, sim_ppc_spr853_regnum,
+ sim_ppc_spr854_regnum, sim_ppc_spr855_regnum,
+ sim_ppc_spr856_regnum, sim_ppc_spr857_regnum,
+ sim_ppc_spr858_regnum, sim_ppc_spr859_regnum,
+ sim_ppc_spr860_regnum, sim_ppc_spr861_regnum,
+ sim_ppc_spr862_regnum, sim_ppc_spr863_regnum,
+ sim_ppc_spr864_regnum, sim_ppc_spr865_regnum,
+ sim_ppc_spr866_regnum, sim_ppc_spr867_regnum,
+ sim_ppc_spr868_regnum, sim_ppc_spr869_regnum,
+ sim_ppc_spr870_regnum, sim_ppc_spr871_regnum,
+ sim_ppc_spr872_regnum, sim_ppc_spr873_regnum,
+ sim_ppc_spr874_regnum, sim_ppc_spr875_regnum,
+ sim_ppc_spr876_regnum, sim_ppc_spr877_regnum,
+ sim_ppc_spr878_regnum, sim_ppc_spr879_regnum,
+ sim_ppc_spr880_regnum, sim_ppc_spr881_regnum,
+ sim_ppc_spr882_regnum, sim_ppc_spr883_regnum,
+ sim_ppc_spr884_regnum, sim_ppc_spr885_regnum,
+ sim_ppc_spr886_regnum, sim_ppc_spr887_regnum,
+ sim_ppc_spr888_regnum, sim_ppc_spr889_regnum,
+ sim_ppc_spr890_regnum, sim_ppc_spr891_regnum,
+ sim_ppc_spr892_regnum, sim_ppc_spr893_regnum,
+ sim_ppc_spr894_regnum, sim_ppc_spr895_regnum,
+ sim_ppc_spr896_regnum, sim_ppc_spr897_regnum,
+ sim_ppc_spr898_regnum, sim_ppc_spr899_regnum,
+ sim_ppc_spr900_regnum, sim_ppc_spr901_regnum,
+ sim_ppc_spr902_regnum, sim_ppc_spr903_regnum,
+ sim_ppc_spr904_regnum, sim_ppc_spr905_regnum,
+ sim_ppc_spr906_regnum, sim_ppc_spr907_regnum,
+ sim_ppc_spr908_regnum, sim_ppc_spr909_regnum,
+ sim_ppc_spr910_regnum, sim_ppc_spr911_regnum,
+ sim_ppc_spr912_regnum, sim_ppc_spr913_regnum,
+ sim_ppc_spr914_regnum, sim_ppc_spr915_regnum,
+ sim_ppc_spr916_regnum, sim_ppc_spr917_regnum,
+ sim_ppc_spr918_regnum, sim_ppc_spr919_regnum,
+ sim_ppc_spr920_regnum, sim_ppc_spr921_regnum,
+ sim_ppc_spr922_regnum, sim_ppc_spr923_regnum,
+ sim_ppc_spr924_regnum, sim_ppc_spr925_regnum,
+ sim_ppc_spr926_regnum, sim_ppc_spr927_regnum,
+ sim_ppc_spr928_regnum, sim_ppc_spr929_regnum,
+ sim_ppc_spr930_regnum, sim_ppc_spr931_regnum,
+ sim_ppc_spr932_regnum, sim_ppc_spr933_regnum,
+ sim_ppc_spr934_regnum, sim_ppc_spr935_regnum,
+ sim_ppc_spr936_regnum, sim_ppc_spr937_regnum,
+ sim_ppc_spr938_regnum, sim_ppc_spr939_regnum,
+ sim_ppc_spr940_regnum, sim_ppc_spr941_regnum,
+ sim_ppc_spr942_regnum, sim_ppc_spr943_regnum,
+ sim_ppc_spr944_regnum, sim_ppc_spr945_regnum,
+ sim_ppc_spr946_regnum, sim_ppc_spr947_regnum,
+ sim_ppc_spr948_regnum, sim_ppc_spr949_regnum,
+ sim_ppc_spr950_regnum, sim_ppc_spr951_regnum,
+ sim_ppc_spr952_regnum, sim_ppc_spr953_regnum,
+ sim_ppc_spr954_regnum, sim_ppc_spr955_regnum,
+ sim_ppc_spr956_regnum, sim_ppc_spr957_regnum,
+ sim_ppc_spr958_regnum, sim_ppc_spr959_regnum,
+ sim_ppc_spr960_regnum, sim_ppc_spr961_regnum,
+ sim_ppc_spr962_regnum, sim_ppc_spr963_regnum,
+ sim_ppc_spr964_regnum, sim_ppc_spr965_regnum,
+ sim_ppc_spr966_regnum, sim_ppc_spr967_regnum,
+ sim_ppc_spr968_regnum, sim_ppc_spr969_regnum,
+ sim_ppc_spr970_regnum, sim_ppc_spr971_regnum,
+ sim_ppc_spr972_regnum, sim_ppc_spr973_regnum,
+ sim_ppc_spr974_regnum, sim_ppc_spr975_regnum,
+ sim_ppc_spr976_regnum, sim_ppc_spr977_regnum,
+ sim_ppc_spr978_regnum, sim_ppc_spr979_regnum,
+ sim_ppc_spr980_regnum, sim_ppc_spr981_regnum,
+ sim_ppc_spr982_regnum, sim_ppc_spr983_regnum,
+ sim_ppc_spr984_regnum, sim_ppc_spr985_regnum,
+ sim_ppc_spr986_regnum, sim_ppc_spr987_regnum,
+ sim_ppc_spr988_regnum, sim_ppc_spr989_regnum,
+ sim_ppc_spr990_regnum, sim_ppc_spr991_regnum,
+ sim_ppc_spr992_regnum, sim_ppc_spr993_regnum,
+ sim_ppc_spr994_regnum, sim_ppc_spr995_regnum,
+ sim_ppc_spr996_regnum, sim_ppc_spr997_regnum,
+ sim_ppc_spr998_regnum, sim_ppc_spr999_regnum,
+ sim_ppc_spr1000_regnum, sim_ppc_spr1001_regnum,
+ sim_ppc_spr1002_regnum, sim_ppc_spr1003_regnum,
+ sim_ppc_spr1004_regnum, sim_ppc_spr1005_regnum,
+ sim_ppc_spr1006_regnum, sim_ppc_spr1007_regnum,
+ sim_ppc_spr1008_regnum, sim_ppc_spr1009_regnum,
+ sim_ppc_spr1010_regnum, sim_ppc_spr1011_regnum,
+ sim_ppc_spr1012_regnum, sim_ppc_spr1013_regnum,
+ sim_ppc_spr1014_regnum, sim_ppc_spr1015_regnum,
+ sim_ppc_spr1016_regnum, sim_ppc_spr1017_regnum,
+ sim_ppc_spr1018_regnum, sim_ppc_spr1019_regnum,
+ sim_ppc_spr1020_regnum, sim_ppc_spr1021_regnum,
+ sim_ppc_spr1022_regnum, sim_ppc_spr1023_regnum
+ };
+
+
+/* Sizes of various register sets. */
+enum
+ {
+ sim_ppc_num_gprs = 32,
+ sim_ppc_num_fprs = 32,
+ sim_ppc_num_vrs = 32,
+ sim_ppc_num_srs = 16,
+ sim_ppc_num_sprs = 1024,
+ };
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SIM_PPC_H */
--- /dev/null
+/* crx.h -- Header file for CRX opcode and register tables.
+ Copyright 2004 Free Software Foundation, Inc.
+ Contributed by Tomer Levi, NSC, Israel.
+ Originally written for GAS 2.12 by Tomer Levi, NSC, Israel.
+ Updates, BFDizing, GNUifying and ELF support by Tomer Levi.
+
+ This file is part of GAS, GDB and the GNU binutils.
+
+ GAS, GDB, and GNU binutils 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, GDB, and GNU binutils are distributed in the hope that they 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 _CRX_H_
+#define _CRX_H_
+
+/* CRX core/debug Registers :
+ The enums are used as indices to CRX registers table (crx_regtab).
+ Therefore, order MUST be preserved. */
+
+typedef enum
+ {
+ /* 32-bit general purpose registers. */
+ r0, r1, r2, r3, r4, r5, r6, r7, r8, r9,
+ r10, r11, r12, r13, r14, r15, ra, sp,
+ /* 32-bit user registers. */
+ u0, u1, u2, u3, u4, u5, u6, u7, u8, u9,
+ u10, u11, u12, u13, u14, u15, ura, usp,
+ /* hi and lo registers. */
+ hi, lo,
+ /* hi and lo user registers. */
+ uhi, ulo,
+ /* Processor Status Register. */
+ psr,
+ /* Configuration Register. */
+ cfg,
+ /* Coprocessor Configuration Register. */
+ cpcfg,
+ /* Cashe Configuration Register. */
+ ccfg,
+ /* Interrupt Base Register. */
+ intbase,
+ /* Interrupt Stack Pointer Register. */
+ isp,
+ /* Coprocessor Enable Register. */
+ cen,
+ /* Program Counter Register. */
+ pc,
+ /* Not a register. */
+ nullregister,
+ MAX_REG
+ }
+reg;
+
+/* CRX Coprocessor registers and special registers :
+ The enums are used as indices to CRX coprocessor registers table
+ (crx_copregtab). Therefore, order MUST be preserved. */
+
+typedef enum
+ {
+ /* Coprocessor registers. */
+ c0 = MAX_REG, c1, c2, c3, c4, c5, c6, c7, c8,
+ c9, c10, c11, c12, c13, c14, c15,
+ /* Coprocessor special registers. */
+ cs0, cs1 ,cs2, cs3, cs4, cs5, cs6, cs7, cs8,
+ cs9, cs10, cs11, cs12, cs13, cs14, cs15,
+ /* Not a Coprocessor register. */
+ nullcopregister,
+ MAX_COPREG
+ }
+copreg;
+
+/* CRX Register types. */
+
+typedef enum
+ {
+ CRX_PC_REGTYPE, /* pc type */
+ CRX_R_REGTYPE, /* r<N> */
+ CRX_U_REGTYPE, /* u<N> */
+ CRX_C_REGTYPE, /* c<N> */
+ CRX_CS_REGTYPE, /* cs<N> */
+ CRX_MTPR_REGTYPE, /* mtpr */
+ CRX_CFG_REGTYPE /* *hi|lo, *cfg, psr */
+ }
+reg_type;
+
+/* CRX argument types :
+ The argument types correspond to instructions operands
+
+ Argument types :
+ r - register
+ c - constant
+ d - displacement
+ ic - immediate
+ icr - index register
+ rbase - register base
+ s - star ('*')
+ copr - coprocessor register
+ copsr - coprocessor special register. */
+
+typedef enum
+ {
+ arg_r, arg_c, arg_cr, arg_dc, arg_dcr, arg_sc,
+ arg_ic, arg_icr, arg_rbase, arg_copr, arg_copsr,
+ /* Not an argument. */
+ nullargs
+ }
+argtype;
+
+/* CRX operand types :
+ The operand types correspond to instructions operands
+
+ Operand Types :
+ cst4 - 4-bit encoded constant
+ iN - N-bit immediate field
+ d, dispsN - N-bit immediate signed displacement
+ dispuN - N-bit immediate unsigned displacement
+ absN - N-bit absolute address
+ rbase - 4-bit genaral-purpose register specifier
+ regr - 4-bit genaral-purpose register specifier
+ regr8 - 8-bit register address space
+ copregr - coprocessor register
+ copsregr - coprocessor special register
+ scl2 - 2-bit scaling factor for memory index
+ ridx - register index. */
+
+typedef enum
+ {
+ dummy, cst4, disps9,
+ i3, i4, i5, i8, i12, i16, i32,
+ d5, d9, d17, d25, d33,
+ abs16, abs32,
+ rbase, rbase_cst4,
+ rbase_dispu8, rbase_dispu12, rbase_dispu16, rbase_dispu28, rbase_dispu32,
+ rbase_ridx_scl2_dispu6, rbase_ridx_scl2_dispu22,
+ regr, regr8, copregr,copregr8,copsregr,
+ /* Not an operand. */
+ nulloperand,
+ /* Maximum supported operand. */
+ MAX_OPRD
+ }
+operand_type;
+
+/* CRX instruction types. */
+
+#define ARITH_INS 1
+#define LD_STOR_INS 2
+#define BRANCH_INS 3
+#define ARITH_BYTE_INS 4
+#define CMPBR_INS 5
+#define SHIFT_INS 6
+#define BRANCH_NEQ_INS 7
+#define LD_STOR_INS_INC 8
+#define STOR_IMM_INS 9
+#define CSTBIT_INS 10
+#define SYS_INS 11
+#define JMP_INS 12
+#define MUL_INS 13
+#define DIV_INS 14
+#define COP_BRANCH_INS 15
+#define COP_REG_INS 16
+#define DCR_BRANCH_INS 17
+#define MMC_INS 18
+#define MMU_INS 19
+
+/* Maximum value supported for instruction types. */
+#define CRX_INS_MAX (1 << 5)
+/* Mask to record an instruction type. */
+#define CRX_INS_MASK (CRX_INS_MAX - 1)
+/* Return instruction type, given instruction's attributes. */
+#define CRX_INS_TYPE(attr) ((attr) & CRX_INS_MASK)
+
+/* Indicates whether this instruction has a register list as parameter. */
+#define REG_LIST CRX_INS_MAX
+/* The operands in binary and assembly are placed in reverse order.
+ load - (REVERSE_MATCH)/store - (! REVERSE_MATCH). */
+#define REVERSE_MATCH (REG_LIST << 1)
+
+/* Kind of displacement map used DISPU[BWD]4. */
+#define DISPUB4 (REVERSE_MATCH << 1)
+#define DISPUW4 (DISPUB4 << 1)
+#define DISPUD4 (DISPUW4 << 1)
+#define CST4MAP (DISPUB4 | DISPUW4 | DISPUD4)
+
+/* Printing formats, where the instruction prefix isn't consecutive. */
+#define FMT_1 (DISPUD4 << 1) /* 0xF0F00000 */
+#define FMT_2 (FMT_1 << 1) /* 0xFFF0FF00 */
+#define FMT_3 (FMT_2 << 1) /* 0xFFF00F00 */
+#define FMT_4 (FMT_3 << 1) /* 0xFFF0F000 */
+#define FMT_5 (FMT_4 << 1) /* 0xFFF0FFF0 */
+#define FMT_CRX (FMT_1 | FMT_2 | FMT_3 | FMT_4 | FMT_5)
+
+#define RELAXABLE (FMT_5 << 1)
+
+/* Maximum operands per instruction. */
+#define MAX_OPERANDS 5
+/* Maximum words per instruction. */
+#define MAX_WORDS 3
+/* Maximum register name length. */
+#define MAX_REGNAME_LEN 10
+/* Maximum instruction length. */
+#define MAX_INST_LEN 256
+
+/* Single operand description. */
+
+typedef struct
+ {
+ /* Operand type. */
+ operand_type op_type;
+ /* Operand location within the opcode. */
+ unsigned int shift;
+ }
+operand_desc;
+
+/* Instruction data structure used in instruction table. */
+
+typedef struct
+ {
+ /* Name. */
+ const char *mnemonic;
+ /* Size (in words). */
+ unsigned int size;
+ /* Constant prefix (matched by the disassembler). */
+ unsigned long match;
+ /* Match size (in bits). */
+ int match_bits;
+ /* Attributes. */
+ unsigned int flags;
+ /* Operands (always last, so unreferenced operands are initialized). */
+ operand_desc operands[MAX_OPERANDS];
+ }
+inst;
+
+/* Data structure for a single instruction's arguments (Operands). */
+
+typedef struct
+ {
+ /* Register or base register. */
+ reg r;
+ /* Index register. */
+ reg i_r;
+ /* Coprocessor register. */
+ copreg cr;
+ /* Constant/immediate/absolute value. */
+ unsigned long int constant;
+ /* Scaled index mode. */
+ unsigned int scale;
+ /* Argument type. */
+ argtype type;
+ /* Size of the argument (in bits) required to represent. */
+ int size;
+ /* Indicates whether a constant is positive or negative. */
+ int signflag;
+ }
+argument;
+
+/* Internal structure to hold the various entities
+ corresponding to the current assembling instruction. */
+
+typedef struct
+ {
+ /* Number of arguments. */
+ int nargs;
+ /* The argument data structure for storing args (operands). */
+ argument arg[MAX_OPERANDS];
+/* The following fields are required only by CRX-assembler. */
+#ifdef TC_CRX
+ /* Expression used for setting the fixups (if any). */
+ expressionS exp;
+ bfd_reloc_code_real_type rtype;
+#endif /* TC_CRX */
+ /* Instruction size (in bytes). */
+ int size;
+ }
+ins;
+
+/* Structure to hold information about predefined operands. */
+
+typedef struct
+ {
+ /* Size (in bits). */
+ unsigned int bit_size;
+ /* Argument type. */
+ argtype arg_type;
+ }
+operand_entry;
+
+/* Structure to hold trap handler information. */
+
+typedef struct
+ {
+ /* Trap name. */
+ char *name;
+ /* Index in dispatch table. */
+ unsigned int entry;
+ }
+trap_entry;
+
+/* Structure to hold information about predefined registers. */
+
+typedef struct
+ {
+ /* Name (string representation). */
+ char *name;
+ /* Value (enum representation). */
+ union
+ {
+ /* Register. */
+ reg reg_val;
+ /* Coprocessor register. */
+ copreg copreg_val;
+ } value;
+ /* Register image. */
+ int image;
+ /* Register type. */
+ reg_type type;
+ }
+reg_entry;
+
+/* Structure to hold a cst4 operand mapping. */
+
+typedef struct
+ {
+ /* The binary value which is written to the object file. */
+ int binary;
+ /* The value which is mapped. */
+ int value;
+ }
+cst4_entry;
+
+/* CRX opcode table. */
+extern const inst crx_instruction[];
+extern const int crx_num_opcodes;
+#define NUMOPCODES crx_num_opcodes
+
+/* CRX operands table. */
+extern const operand_entry crx_optab[];
+
+/* CRX registers table. */
+extern const reg_entry crx_regtab[];
+extern const int crx_num_regs;
+#define NUMREGS crx_num_regs
+
+/* CRX coprocessor registers table. */
+extern const reg_entry crx_copregtab[];
+extern const int crx_num_copregs;
+#define NUMCOPREGS crx_num_copregs
+
+/* CRX trap/interrupt table. */
+extern const trap_entry crx_traps[];
+extern const int crx_num_traps;
+#define NUMTRAPS crx_num_traps
+
+/* cst4 operand mapping. */
+extern const cst4_entry cst4_map[];
+extern const int cst4_maps;
+
+/* Current instruction we're assembling. */
+extern const inst *instruction;
+
+/* A macro for representing the instruction "constant" opcode, that is,
+ the FIXED part of the instruction. The "constant" opcode is represented
+ as a 32-bit unsigned long, where OPC is expanded (by a left SHIFT)
+ over that range. */
+#define BIN(OPC,SHIFT) (OPC << SHIFT)
+
+/* Is the current instruction type is TYPE ? */
+#define IS_INSN_TYPE(TYPE) \
+ (CRX_INS_TYPE(instruction->flags) == TYPE)
+
+/* Is the current instruction mnemonic is MNEMONIC ? */
+#define IS_INSN_MNEMONIC(MNEMONIC) \
+ (strcmp(instruction->mnemonic,MNEMONIC) == 0)
+
+/* Does the current instruction has register list ? */
+#define INST_HAS_REG_LIST \
+ (instruction->flags & REG_LIST)
+
+/* Long long type handling. */
+/* Replace all appearances of 'long long int' with LONGLONG. */
+typedef long long int LONGLONG;
+typedef unsigned long long ULONGLONG;
+/* A mask for the upper 31 bits of a 64 bits type. */
+#define UPPER31_MASK 0xFFFFFFFE00000000LL
+
+#endif /* _CRX_H_ */
--- /dev/null
+/* Disassembler code for CRX.
+ Copyright 2004 Free Software Foundation, Inc.
+ Contributed by Tomer Levi, NSC, Israel.
+ Written by Tomer Levi.
+
+ This file is part of the GNU binutils and GDB, the GNU debugger.
+
+ 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, 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 "dis-asm.h"
+#include "sysdep.h"
+#include "opcode/crx.h"
+
+/* String to print when opcode was not matched. */
+#define ILLEGAL "illegal"
+ /* Escape to 16-bit immediate. */
+#define ESCAPE_16_BIT 0xE
+
+/* Extract 'n_bits' from 'a' starting from offset 'offs'. */
+#define EXTRACT(a, offs, n_bits) \
+ (n_bits == 32 ? (((a) >> (offs)) & ~0L) \
+ : (((a) >> (offs)) & ((1 << (n_bits)) -1)))
+
+/* Set Bit Mask - a mask to set all bits starting from offset 'offs'. */
+#define SBM(offs) ((((1 << (32 - offs)) -1) << (offs)))
+
+typedef unsigned long dwordU;
+typedef unsigned short wordU;
+
+typedef struct
+{
+ dwordU val;
+ int nbits;
+} parameter;
+
+/* Structure to hold valid 'cinv' instruction options. */
+
+typedef struct
+ {
+ /* Cinv printed string. */
+ char *str;
+ /* Value corresponding to the string. */
+ unsigned int value;
+ }
+cinv_entry;
+
+/* CRX 'cinv' options. */
+const cinv_entry crx_cinvs[] =
+{
+ {"[i]", 2}, {"[i,u]", 3}, {"[d]", 4},
+ {"[d,u]", 5}, {"[d,i]", 6}, {"[d,i,u]", 7}
+};
+
+/* Number of valid 'cinv' instruction options. */
+int NUMCINVS = ((sizeof crx_cinvs)/(sizeof crx_cinvs[0]));
+/* Current opcode table entry we're disassembling. */
+const inst *instruction;
+/* Current instruction we're disassembling. */
+ins currInsn;
+/* The current instruction is read into 3 consecutive words. */
+wordU words[3];
+/* Contains all words in appropriate order. */
+ULONGLONG allWords;
+/* Holds the current processed argument number. */
+int processing_argument_number;
+/* Nonzero means a CST4 instruction. */
+int cst4flag;
+/* Nonzero means the instruction's original size is
+ incremented (escape sequence is used). */
+int size_changed;
+
+static int get_number_of_operands (void);
+static argtype getargtype (operand_type);
+static int getbits (operand_type);
+static char *getregname (reg);
+static char *getcopregname (copreg, reg_type);
+static char * getprocregname (int);
+static char *gettrapstring (unsigned);
+static char *getcinvstring (unsigned);
+static void getregliststring (int, char *, int);
+static wordU get_word_at_PC (bfd_vma, struct disassemble_info *);
+static void get_words_at_PC (bfd_vma, struct disassemble_info *);
+static unsigned long build_mask (void);
+static int powerof2 (int);
+static int match_opcode (void);
+static void make_instruction (void);
+static void print_arguments (ins *, struct disassemble_info *);
+static void print_arg (argument *, struct disassemble_info *);
+
+/* Retrieve the number of operands for the current assembled instruction. */
+
+static int
+get_number_of_operands (void)
+{
+ int i;
+
+ for (i = 0; instruction->operands[i].op_type && i < MAX_OPERANDS; i++)
+ ;
+
+ return i;
+}
+
+/* Return the bit size for a given operand. */
+
+static int
+getbits (operand_type op)
+{
+ if (op < MAX_OPRD)
+ return crx_optab[op].bit_size;
+ else
+ return 0;
+}
+
+/* Return the argument type of a given operand. */
+
+static argtype
+getargtype (operand_type op)
+{
+ if (op < MAX_OPRD)
+ return crx_optab[op].arg_type;
+ else
+ return nullargs;
+}
+
+/* Given the trap index in dispatch table, return its name.
+ This routine is used when disassembling the 'excp' instruction. */
+
+static char *
+gettrapstring (unsigned int index)
+{
+ const trap_entry *trap;
+
+ for (trap = crx_traps; trap < crx_traps + NUMTRAPS; trap++)
+ if (trap->entry == index)
+ return trap->name;
+
+ return ILLEGAL;
+}
+
+/* Given a 'cinv' instruction constant operand, return its corresponding string.
+ This routine is used when disassembling the 'cinv' instruction. */
+
+static char *
+getcinvstring (unsigned int num)
+{
+ const cinv_entry *cinv;
+
+ for (cinv = crx_cinvs; cinv < (crx_cinvs + NUMCINVS); cinv++)
+ if (cinv->value == num)
+ return cinv->str;
+
+ return ILLEGAL;
+}
+
+/* Given a register enum value, retrieve its name. */
+
+char *
+getregname (reg r)
+{
+ const reg_entry *reg = &crx_regtab[r];
+
+ if (reg->type != CRX_R_REGTYPE)
+ return ILLEGAL;
+ else
+ return reg->name;
+}
+
+/* Given a coprocessor register enum value, retrieve its name. */
+
+char *
+getcopregname (copreg r, reg_type type)
+{
+ const reg_entry *reg;
+
+ if (type == CRX_C_REGTYPE)
+ reg = &crx_copregtab[r];
+ else if (type == CRX_CS_REGTYPE)
+ reg = &crx_copregtab[r+(cs0-c0)];
+ else
+ return ILLEGAL;
+
+ return reg->name;
+}
+
+
+/* Getting a processor register name. */
+
+static char *
+getprocregname (int index)
+{
+ const reg_entry *r;
+
+ for (r = crx_regtab; r < crx_regtab + NUMREGS; r++)
+ if (r->image == index)
+ return r->name;
+
+ return "ILLEGAL REGISTER";
+}
+
+/* Get the power of two for a given integer. */
+
+static int
+powerof2 (int x)
+{
+ int product, i;
+
+ for (i = 0, product = 1; i < x; i++)
+ product *= 2;
+
+ return product;
+}
+
+/* Transform a register bit mask to a register list. */
+
+void
+getregliststring (int trap, char *string, int core_cop)
+{
+ char temp_string[5];
+ int i;
+
+ string[0] = '{';
+ string[1] = '\0';
+
+ for (i = 0; i < 16; i++)
+ {
+ if (trap & 0x1)
+ {
+ if (core_cop)
+ sprintf (temp_string, "r%d", i);
+ else
+ sprintf (temp_string, "c%d", i);
+ strcat (string, temp_string);
+ if (trap & 0xfffe)
+ strcat (string, ",");
+ }
+ trap = trap >> 1;
+ }
+
+ strcat (string, "}");
+}
+
+/* START and END are relating 'allWords' struct, which is 48 bits size.
+
+ START|--------|END
+ +---------+---------+---------+---------+
+ | | V | A | L |
+ +---------+---------+---------+---------+
+ 0 16 32 48
+ words [0] [1] [2] */
+
+static parameter
+makelongparameter (ULONGLONG val, int start, int end)
+{
+ parameter p;
+
+ p.val = (dwordU) EXTRACT(val, 48 - end, end - start);
+ p.nbits = end - start;
+ return p;
+}
+
+/* Build a mask of the instruction's 'constant' opcode,
+ based on the instruction's printing flags. */
+
+static unsigned long
+build_mask (void)
+{
+ unsigned int print_flags;
+ unsigned long mask;
+
+ print_flags = instruction->flags & FMT_CRX;
+ switch (print_flags)
+ {
+ case FMT_1:
+ mask = 0xF0F00000;
+ break;
+ case FMT_2:
+ mask = 0xFFF0FF00;
+ break;
+ case FMT_3:
+ mask = 0xFFF00F00;
+ break;
+ case FMT_4:
+ mask = 0xFFF0F000;
+ break;
+ case FMT_5:
+ mask = 0xFFF0FFF0;
+ break;
+ default:
+ mask = SBM(instruction->match_bits);
+ break;
+ }
+
+ return mask;
+}
+
+/* Search for a matching opcode. Return 1 for success, 0 for failure. */
+
+static int
+match_opcode (void)
+{
+ unsigned long mask;
+
+ /* The instruction 'constant' opcode doewsn't exceed 32 bits. */
+ unsigned long doubleWord = words[1] + (words[0] << 16);
+
+ /* Start searching from end of instruction table. */
+ instruction = &crx_instruction[NUMOPCODES - 2];
+
+ /* Loop over instruction table until a full match is found. */
+ while (instruction >= crx_instruction)
+ {
+ mask = build_mask ();
+ if ((doubleWord & mask) == BIN(instruction->match, instruction->match_bits))
+ return 1;
+ else
+ instruction--;
+ }
+ return 0;
+}
+
+/* Set the proper parameter value for different type of arguments. */
+
+static void
+make_argument (argument * a, int start_bits)
+{
+ int inst_bit_size, total_size;
+ parameter p;
+
+ if ((instruction->size == 3) && a->size >= 16)
+ inst_bit_size = 48;
+ else
+ inst_bit_size = 32;
+
+ switch (a->type)
+ {
+ case arg_copr:
+ case arg_copsr:
+ p = makelongparameter (allWords, inst_bit_size - (start_bits + a->size),
+ inst_bit_size - start_bits);
+ a->cr = p.val;
+ break;
+
+ case arg_r:
+ p = makelongparameter (allWords, inst_bit_size - (start_bits + a->size),
+ inst_bit_size - start_bits);
+ a->r = p.val;
+ break;
+
+ case arg_ic:
+ p = makelongparameter (allWords, inst_bit_size - (start_bits + a->size),
+ inst_bit_size - start_bits);
+
+ if ((p.nbits == 4) && cst4flag)
+ {
+ if (IS_INSN_TYPE (CMPBR_INS) && (p.val == ESCAPE_16_BIT))
+ {
+ /* A special case, where the value is actually stored
+ in the last 4 bits. */
+ p = makelongparameter (allWords, 44, 48);
+ /* The size of the instruction should be incremented. */
+ size_changed = 1;
+ }
+
+ if (p.val == 6)
+ p.val = -1;
+ else if (p.val == 13)
+ p.val = 48;
+ else if (p.val == 5)
+ p.val = -4;
+ else if (p.val == 10)
+ p.val = 32;
+ else if (p.val == 11)
+ p.val = 20;
+ else if (p.val == 9)
+ p.val = 16;
+ }
+
+ a->constant = p.val;
+ break;
+
+ case arg_icr:
+ a->scale = 0;
+ total_size = a->size + 10; /* sizeof(rbase + ridx + scl2) = 10. */
+ p = makelongparameter (allWords, inst_bit_size - total_size,
+ inst_bit_size - (total_size - 4));
+ a->r = p.val;
+ p = makelongparameter (allWords, inst_bit_size - (total_size - 4),
+ inst_bit_size - (total_size - 8));
+ a->i_r = p.val;
+ p = makelongparameter (allWords, inst_bit_size - (total_size - 8),
+ inst_bit_size - (total_size - 10));
+ a->scale = p.val;
+ p = makelongparameter (allWords, inst_bit_size - (total_size - 10),
+ inst_bit_size);
+ a->constant = p.val;
+ break;
+
+ case arg_rbase:
+ p = makelongparameter (allWords, inst_bit_size - (start_bits + 4),
+ inst_bit_size - start_bits);
+ a->r = p.val;
+ break;
+
+ case arg_cr:
+ if (a->size <= 8)
+ {
+ p = makelongparameter (allWords, inst_bit_size - (start_bits + 4),
+ inst_bit_size - start_bits);
+ a->r = p.val;
+ /* Case for opc4 r dispu rbase. */
+ p = makelongparameter (allWords, inst_bit_size - (start_bits + 8),
+ inst_bit_size - (start_bits + 4));
+ }
+ else
+ {
+ /* The 'rbase' start_bits is always relative to a 32-bit data type. */
+ p = makelongparameter (allWords, 32 - (start_bits + 4),
+ 32 - start_bits);
+ a->r = p.val;
+ p = makelongparameter (allWords, 32 - start_bits,
+ inst_bit_size);
+ }
+ if ((p.nbits == 4) && cst4flag)
+ {
+ if (instruction->flags & DISPUW4)
+ p.val *= 2;
+ else if (instruction->flags & DISPUD4)
+ p.val *= 4;
+ }
+ a->constant = p.val;
+ break;
+
+ case arg_c:
+ p = makelongparameter (allWords, inst_bit_size - (start_bits + a->size),
+ inst_bit_size - start_bits);
+ a->constant = p.val;
+ break;
+ default:
+ break;
+ }
+}
+
+/* Print a single argument. */
+
+static void
+print_arg (argument *a, struct disassemble_info *info)
+{
+ LONGLONG longdisp, mask;
+ char sign_flag;
+ int op_index = 0;
+ char string[200];
+ PTR stream = info->stream;
+ fprintf_ftype func = info->fprintf_func;
+
+ switch (a->type)
+ {
+ case arg_copr:
+ func (stream, "%s", getcopregname (a->cr, CRX_C_REGTYPE));
+ break;
+
+ case arg_copsr:
+ func (stream, "%s", getcopregname (a->cr, CRX_CS_REGTYPE));
+ break;
+
+ case arg_r:
+ if (IS_INSN_MNEMONIC ("mtpr") || IS_INSN_MNEMONIC ("mfpr"))
+ func (stream, "%s", getprocregname (a->r));
+ else
+ func (stream, "%s", getregname (a->r));
+ break;
+
+ case arg_ic:
+ if (IS_INSN_MNEMONIC ("excp"))
+ func (stream, "%s", gettrapstring (a->constant));
+
+ else if (IS_INSN_MNEMONIC ("cinv"))
+ func (stream, "%s", getcinvstring (a->constant));
+
+ else if (INST_HAS_REG_LIST)
+ {
+ if (!IS_INSN_TYPE (COP_REG_INS))
+ {
+ getregliststring (a->constant, string, 1);
+ func (stream, "%s", string);
+ }
+ else
+ {
+ /* Check for proper argument number. */
+ if (processing_argument_number == 2)
+ {
+ getregliststring (a->constant, string, 0);
+ func (stream, "%s", string);
+ }
+ else
+ func (stream, "$0x%x", a->constant);
+ }
+ }
+ else
+ func (stream, "$0x%x", a->constant);
+ break;
+
+ case arg_icr:
+ func (stream, "0x%x(%s,%s,%d)", a->constant, getregname (a->r),
+ getregname (a->i_r), powerof2 (a->scale));
+ break;
+
+ case arg_rbase:
+ func (stream, "(%s)", getregname (a->r));
+ break;
+
+ case arg_cr:
+ func (stream, "0x%x(%s)", a->constant, getregname (a->r));
+
+ if (IS_INSN_TYPE (LD_STOR_INS_INC))
+ func (stream, "+");
+ break;
+
+ case arg_c:
+ /* Removed the *2 part as because implicit zeros are no more required.
+ Have to fix this as this needs a bit of extension in terms of branchins.
+ Have to add support for cmp and branch instructions. */
+ if (IS_INSN_TYPE (BRANCH_INS) || IS_INSN_MNEMONIC ("bal")
+ || IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (DCR_BRANCH_INS)
+ || IS_INSN_TYPE (COP_BRANCH_INS))
+ {
+ func (stream, "%c", '*');
+ longdisp = a->constant;
+ longdisp <<= 1;
+ sign_flag = '+';
+
+ switch (a->size)
+ {
+ case 8:
+ case 16:
+ case 24:
+ case 32:
+ mask = ((LONGLONG)1 << a->size) - 1;
+ if (longdisp & ((LONGLONG)1 << a->size))
+ {
+ sign_flag = '-';
+ longdisp = ~(longdisp) + 1;
+ }
+ a->constant = (unsigned long int) (longdisp & mask);
+ break;
+ default:
+ func (stream,
+ "Wrong offset used in branch/bal instruction");
+ break;
+ }
+
+ func (stream, "%c", sign_flag);
+ }
+ /* For branch Neq instruction it is 2*offset + 2. */
+ if (IS_INSN_TYPE (BRANCH_NEQ_INS))
+ a->constant = 2 * a->constant + 2;
+ if (IS_INSN_TYPE (LD_STOR_INS_INC)
+ || IS_INSN_TYPE (LD_STOR_INS)
+ || IS_INSN_TYPE (STOR_IMM_INS)
+ || IS_INSN_TYPE (CSTBIT_INS))
+ {
+ op_index = instruction->flags & REVERSE_MATCH ? 0 : 1;
+ if (instruction->operands[op_index].op_type == abs16)
+ a->constant |= 0xFFFF0000;
+ }
+ func (stream, "0x%x", a->constant);
+ break;
+ default:
+ break;
+ }
+}
+
+/* Print all the arguments of CURRINSN instruction. */
+
+static void
+print_arguments (ins *currInsn, struct disassemble_info *info)
+{
+ int i;
+
+ for (i = 0; i < currInsn->nargs; i++)
+ {
+ processing_argument_number = i;
+
+ print_arg (&currInsn->arg[i], info);
+
+ if (i != currInsn->nargs - 1)
+ info->fprintf_func (info->stream, ", ");
+ }
+}
+
+/* Build the instruction's arguments. */
+
+static void
+make_instruction (void)
+{
+ int i;
+ unsigned int temp_value, shift;
+ argument a;
+
+ for (i = 0; i < currInsn.nargs; i++)
+ {
+ a.type = getargtype (instruction->operands[i].op_type);
+ if (instruction->operands[i].op_type == cst4
+ || instruction->operands[i].op_type == rbase_cst4)
+ cst4flag = 1;
+ a.size = getbits (instruction->operands[i].op_type);
+ shift = instruction->operands[i].shift;
+
+ make_argument (&a, shift);
+ currInsn.arg[i] = a;
+ }
+
+ /* Calculate instruction size (in bytes). */
+ currInsn.size = instruction->size + (size_changed ? 1 : 0);
+ currInsn.size *= 2;
+
+ /* Swapping first and second arguments. */
+ if (IS_INSN_TYPE (COP_BRANCH_INS))
+ {
+ temp_value = currInsn.arg[0].constant;
+ currInsn.arg[0].constant = currInsn.arg[1].constant;
+ currInsn.arg[1].constant = temp_value;
+ }
+}
+
+/* Retrieve a single word from a given memory address. */
+
+static wordU
+get_word_at_PC (bfd_vma memaddr, struct disassemble_info *info)
+{
+ bfd_byte buffer[4];
+ int status;
+ wordU insn = 0;
+
+ status = info->read_memory_func (memaddr, buffer, 2, info);
+
+ if (status == 0)
+ insn = (wordU) bfd_getl16 (buffer);
+
+ return insn;
+}
+
+/* Retrieve multiple words (3) from a given memory address. */
+
+static void
+get_words_at_PC (bfd_vma memaddr, struct disassemble_info *info)
+{
+ int i;
+ bfd_vma mem;
+
+ for (i = 0, mem = memaddr; i < 3; i++, mem += 2)
+ words[i] = get_word_at_PC (mem, info);
+
+ allWords =
+ ((ULONGLONG) words[0] << 32) + ((unsigned long) words[1] << 16) + words[2];
+}
+
+/* Prints the instruction by calling print_arguments after proper matching. */
+
+int
+print_insn_crx (memaddr, info)
+ bfd_vma memaddr;
+ struct disassemble_info *info;
+{
+ int is_decoded; /* Nonzero means instruction has a match. */
+
+ /* Initialize global variables. */
+ cst4flag = 0;
+ size_changed = 0;
+
+ /* Retrieve the encoding from current memory location. */
+ get_words_at_PC (memaddr, info);
+ /* Find a matching opcode in table. */
+ is_decoded = match_opcode ();
+ /* If found, print the instruction's mnemonic and arguments. */
+ if (is_decoded > 0 && (words[0] << 16 || words[1]) != 0)
+ {
+ info->fprintf_func (info->stream, "%s", instruction->mnemonic);
+ if ((currInsn.nargs = get_number_of_operands ()) != 0)
+ info->fprintf_func (info->stream, "\t");
+ make_instruction ();
+ print_arguments (&currInsn, info);
+ return currInsn.size;
+ }
+
+ /* No match found. */
+ info->fprintf_func (info->stream,"%s ",ILLEGAL);
+ return 2;
+}
--- /dev/null
+/* crx-opc.c -- Table of opcodes for the CRX processor.
+ Copyright 2004 Free Software Foundation, Inc.
+ Contributed by Tomer Levi NSC, Israel.
+ Originally written for GAS 2.12 by Tomer Levi.
+
+ This file is part of GAS, GDB and the GNU binutils.
+
+ GAS, GDB, and GNU binutils 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, GDB, and GNU binutils are distributed in the hope that they 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 <stdio.h>
+#include "libiberty.h"
+#include "symcat.h"
+#include "opcode/crx.h"
+
+const inst crx_instruction[] =
+{
+/* Create an arithmetic instruction - INST[bw]. */
+#define ARITH_BYTE_INST(NAME, OPC) \
+ /* opc8 cst4 r */ \
+ {NAME, 1, OPC, 24, ARITH_BYTE_INS, {{cst4,20}, {regr,16}}}, \
+ /* opc8 i16 r */ \
+ {NAME, 2, (OPC<<4)+0xE, 20, ARITH_BYTE_INS, {{i16,0}, {regr,16}}}, \
+ /* opc8 r r */ \
+ {NAME, 1, OPC+0x40, 24, ARITH_BYTE_INS, {{regr,20}, {regr,16}}}
+
+ ARITH_BYTE_INST ("addub", 0x0),
+ ARITH_BYTE_INST ("addb", 0x1),
+ ARITH_BYTE_INST ("addcb", 0x2),
+ ARITH_BYTE_INST ("andb", 0x3),
+ ARITH_BYTE_INST ("cmpb", 0x4),
+ ARITH_BYTE_INST ("movb", 0x5),
+ ARITH_BYTE_INST ("orb", 0x6),
+ ARITH_BYTE_INST ("subb", 0x7),
+ ARITH_BYTE_INST ("subcb", 0x8),
+ ARITH_BYTE_INST ("xorb", 0x9),
+ ARITH_BYTE_INST ("mulb", 0xA),
+
+ ARITH_BYTE_INST ("adduw", 0x10),
+ ARITH_BYTE_INST ("addw", 0x11),
+ ARITH_BYTE_INST ("addcw", 0x12),
+ ARITH_BYTE_INST ("andw", 0x13),
+ ARITH_BYTE_INST ("cmpw", 0x14),
+ ARITH_BYTE_INST ("movw", 0x15),
+ ARITH_BYTE_INST ("orw", 0x16),
+ ARITH_BYTE_INST ("subw", 0x17),
+ ARITH_BYTE_INST ("subcw", 0x18),
+ ARITH_BYTE_INST ("xorw", 0x19),
+ ARITH_BYTE_INST ("mulw", 0x1A),
+
+/* Create an arithmetic instruction - INST[d]. */
+#define ARITH_INST(NAME, OPC) \
+ /* opc8 cst4 r */ \
+ {NAME, 1, OPC, 24, ARITH_INS, {{cst4,20}, {regr,16}}}, \
+ /* opc8 i16 r */ \
+ {NAME, 2, (OPC<<4)+0xE, 20, ARITH_INS, {{i16,0}, {regr,16}}}, \
+ /* opc8 i32 r */ \
+ {NAME, 3, (OPC<<4)+0xF, 20, ARITH_INS, {{i32,0}, {regr,16}}}, \
+ /* opc8 r r */ \
+ {NAME, 1, OPC+0x40, 24, ARITH_INS, {{regr,20}, {regr,16}}}
+
+ ARITH_INST ("addud", 0x20),
+ ARITH_INST ("addd", 0x21),
+ ARITH_INST ("addcd", 0x22),
+ ARITH_INST ("andd", 0x23),
+ ARITH_INST ("cmpd", 0x24),
+ ARITH_INST ("movd", 0x25),
+ ARITH_INST ("ord", 0x26),
+ ARITH_INST ("subd", 0x27),
+ ARITH_INST ("subcd", 0x28),
+ ARITH_INST ("xord", 0x29),
+ ARITH_INST ("muld", 0x2A),
+
+/* Create a shift instruction. */
+#define SHIFT_INST(NAME, OPRD, OPC1, SHIFT1, OPC2) \
+ /* OPRD=i3 -->> opc9 i3 r */ \
+ /* OPRD=i4 -->> opc8 i4 r */ \
+ /* OPRD=i5 -->> opc7 i5 r */ \
+ {NAME, 1, OPC1, SHIFT1, SHIFT_INS, {{OPRD,20}, {regr,16}}}, \
+ /* opc8 r r */ \
+ {NAME, 1, OPC2, 24, SHIFT_INS, {{regr,20}, {regr,16}}}
+
+ SHIFT_INST ("sllb", i3, 0x1F8, 23, 0x4D),
+ SHIFT_INST ("srlb", i3, 0x1F9, 23, 0x4E),
+ SHIFT_INST ("srab", i3, 0x1FA, 23, 0x4F),
+
+ SHIFT_INST ("sllw", i4, 0xB6, 24, 0x5D),
+ SHIFT_INST ("srlw", i4, 0xB7, 24, 0x5E),
+ SHIFT_INST ("sraw", i4, 0xB8, 24, 0x5F),
+
+ SHIFT_INST ("slld", i5, 0x78, 25, 0x6D),
+ SHIFT_INST ("srld", i5, 0x79, 25, 0x6E),
+ SHIFT_INST ("srad", i5, 0x7A, 25, 0x6F),
+
+/* Create a conditional branch instruction. */
+#define BRANCH_INST(NAME, OPC) \
+ /* opc4 c4 dispe9 */ \
+ {NAME, 1, OPC, 24, BRANCH_INS | RELAXABLE, {{d9,16}}}, \
+ /* opc4 c4 disps17 */ \
+ {NAME, 2, (OPC<<8)+0x7E, 16, BRANCH_INS | RELAXABLE, {{d17,0}}}, \
+ /* opc4 c4 disps33 */ \
+ {NAME, 3, (OPC<<8)+0x7F, 16, BRANCH_INS | RELAXABLE, {{d33,0}}}
+
+ BRANCH_INST ("beq", 0x70),
+ BRANCH_INST ("bne", 0x71),
+ BRANCH_INST ("bcs", 0x72),
+ BRANCH_INST ("bcc", 0x73),
+ BRANCH_INST ("bhi", 0x74),
+ BRANCH_INST ("bls", 0x75),
+ BRANCH_INST ("bgt", 0x76),
+ BRANCH_INST ("ble", 0x77),
+ BRANCH_INST ("bfs", 0x78),
+ BRANCH_INST ("bfc", 0x79),
+ BRANCH_INST ("blo", 0x7A),
+ BRANCH_INST ("bhs", 0x7B),
+ BRANCH_INST ("blt", 0x7C),
+ BRANCH_INST ("bge", 0x7D),
+ BRANCH_INST ("br", 0x7E),
+
+/* Create a 'Branch if Equal to 0' instruction. */
+#define BRANCH_NEQ_INST(NAME, OPC) \
+ /* opc8 dispu5 r */ \
+ {NAME, 1, OPC, 24, BRANCH_NEQ_INS, {{regr,16}, {d5,20}}}
+
+ BRANCH_NEQ_INST ("beq0b", 0xB0),
+ BRANCH_NEQ_INST ("bne0b", 0xB1),
+ BRANCH_NEQ_INST ("beq0w", 0xB2),
+ BRANCH_NEQ_INST ("bne0w", 0xB3),
+ BRANCH_NEQ_INST ("beq0d", 0xB4),
+ BRANCH_NEQ_INST ("bne0d", 0xB5),
+
+/* Create instruction with no operands. */
+#define NO_OP_INST(NAME, OPC) \
+ /* opc16 */ \
+ {NAME, 1, OPC, 16, 0, {{0, 0}}}
+
+ NO_OP_INST ("nop", 0x3002),
+ NO_OP_INST ("retx", 0x3003),
+ NO_OP_INST ("di", 0x3004),
+ NO_OP_INST ("ei", 0x3005),
+ NO_OP_INST ("wait", 0x3006),
+ NO_OP_INST ("eiwait", 0x3007),
+
+/* Create a 'Compare & Branch' instruction. */
+#define CMPBR_INST(NAME, OPC1, OPC2, C4) \
+ /* opc12 r r c4 disps9 */ \
+ {NAME, 2, ((0x300+OPC1)<<12)+C4, 8, CMPBR_INS | FMT_3 | RELAXABLE, {{regr,16}, {regr,12}, {d9,0}}}, \
+ /* opc12 r r c4 disps25 */ \
+ {NAME, 3, ((0x310+OPC1)<<12)+C4, 8, CMPBR_INS | FMT_3 | RELAXABLE, {{regr,16}, {regr,12}, {d25,0}}}, \
+ /* opc12 i4cst4 r c4 disps9 */ \
+ {NAME, 2, ((0x300+OPC2)<<12)+C4, 8, CMPBR_INS | FMT_3 | RELAXABLE, {{cst4,16}, {regr,12}, {d9,0}}}, \
+ /* opc12 i4cst4 r c4 disps25 */ \
+ {NAME, 3, ((0x310+OPC2)<<12)+C4, 8, CMPBR_INS | FMT_3 | RELAXABLE, {{cst4,16}, {regr,12}, {d25,0}}}
+
+ CMPBR_INST ("cmpbeqb", 0x8, 0xC, 0x0),
+ CMPBR_INST ("cmpbneb", 0x8, 0xC, 0x1),
+ CMPBR_INST ("cmpbhib", 0x8, 0xC, 0x4),
+ CMPBR_INST ("cmpblsb", 0x8, 0xC, 0x5),
+ CMPBR_INST ("cmpbgtb", 0x8, 0xC, 0x6),
+ CMPBR_INST ("cmpbleb", 0x8, 0xC, 0x7),
+ CMPBR_INST ("cmpblob", 0x8, 0xC, 0xA),
+ CMPBR_INST ("cmpbhsb", 0x8, 0xC, 0xB),
+ CMPBR_INST ("cmpbltb", 0x8, 0xC, 0xC),
+ CMPBR_INST ("cmpbgeb", 0x8, 0xC, 0xD),
+
+ CMPBR_INST ("cmpbeqw", 0x9, 0xD, 0x0),
+ CMPBR_INST ("cmpbnew", 0x9, 0xD, 0x1),
+ CMPBR_INST ("cmpbhiw", 0x9, 0xD, 0x4),
+ CMPBR_INST ("cmpblsw", 0x9, 0xD, 0x5),
+ CMPBR_INST ("cmpbgtw", 0x9, 0xD, 0x6),
+ CMPBR_INST ("cmpblew", 0x9, 0xD, 0x7),
+ CMPBR_INST ("cmpblow", 0x9, 0xD, 0xA),
+ CMPBR_INST ("cmpbhsw", 0x9, 0xD, 0xB),
+ CMPBR_INST ("cmpbltw", 0x9, 0xD, 0xC),
+ CMPBR_INST ("cmpbgew", 0x9, 0xD, 0xD),
+
+ CMPBR_INST ("cmpbeqd", 0xA, 0xE, 0x0),
+ CMPBR_INST ("cmpbned", 0xA, 0xE, 0x1),
+ CMPBR_INST ("cmpbhid", 0xA, 0xE, 0x4),
+ CMPBR_INST ("cmpblsd", 0xA, 0xE, 0x5),
+ CMPBR_INST ("cmpbgtd", 0xA, 0xE, 0x6),
+ CMPBR_INST ("cmpbled", 0xA, 0xE, 0x7),
+ CMPBR_INST ("cmpblod", 0xA, 0xE, 0xA),
+ CMPBR_INST ("cmpbhsd", 0xA, 0xE, 0xB),
+ CMPBR_INST ("cmpbltd", 0xA, 0xE, 0xC),
+ CMPBR_INST ("cmpbged", 0xA, 0xE, 0xD),
+
+/* Create an instruction using a single register operand. */
+#define REG1_INST(NAME, OPC) \
+ /* opc8 c4 r */ \
+ {NAME, 1, OPC, 20, 0, {{regr,16}}}
+
+ /* JCond instructions */
+ REG1_INST ("jeq", 0xBA0),
+ REG1_INST ("jne", 0xBA1),
+ REG1_INST ("jcs", 0xBA2),
+ REG1_INST ("jcc", 0xBA3),
+ REG1_INST ("jhi", 0xBA4),
+ REG1_INST ("jls", 0xBA5),
+ REG1_INST ("jgt", 0xBA6),
+ REG1_INST ("jle", 0xBA7),
+ REG1_INST ("jfs", 0xBA8),
+ REG1_INST ("jfc", 0xBA9),
+ REG1_INST ("jlo", 0xBAA),
+ REG1_INST ("jhs", 0xBAB),
+ REG1_INST ("jlt", 0xBAC),
+ REG1_INST ("jge", 0xBAD),
+ REG1_INST ("jump", 0xBAE),
+
+ /* SCond instructions */
+ REG1_INST ("seq", 0xBB0),
+ REG1_INST ("sne", 0xBB1),
+ REG1_INST ("scs", 0xBB2),
+ REG1_INST ("scc", 0xBB3),
+ REG1_INST ("shi", 0xBB4),
+ REG1_INST ("sls", 0xBB5),
+ REG1_INST ("sgt", 0xBB6),
+ REG1_INST ("sle", 0xBB7),
+ REG1_INST ("sfs", 0xBB8),
+ REG1_INST ("sfc", 0xBB9),
+ REG1_INST ("slo", 0xBBA),
+ REG1_INST ("shs", 0xBBB),
+ REG1_INST ("slt", 0xBBC),
+ REG1_INST ("sge", 0xBBD),
+
+/* Create an instruction using two register operands. */
+#define REG2_INST(NAME, OPC) \
+ /* opc24 r r OR opc20 c4 r r */ \
+ {NAME, 2, 0x300800+OPC, 8, 0, {{regr,4}, {regr,0}}}
+
+ /* MULTIPLY INSTRUCTIONS */
+ REG2_INST ("macsb", 0x40),
+ REG2_INST ("macub", 0x41),
+ REG2_INST ("macqb", 0x42),
+
+ REG2_INST ("macsw", 0x50),
+ REG2_INST ("macuw", 0x51),
+ REG2_INST ("macqw", 0x52),
+
+ REG2_INST ("macsd", 0x60),
+ REG2_INST ("macud", 0x61),
+ REG2_INST ("macqd", 0x62),
+
+ REG2_INST ("mullsd", 0x65),
+ REG2_INST ("mullud", 0x66),
+
+ REG2_INST ("mulsbw", 0x3B),
+ REG2_INST ("mulubw", 0x3C),
+ REG2_INST ("mulswd", 0x3D),
+ REG2_INST ("muluwd", 0x3E),
+
+ /* SIGNEXTEND STUFF */
+ REG2_INST ("sextbw", 0x30),
+ REG2_INST ("sextbd", 0x31),
+ REG2_INST ("sextwd", 0x32),
+ REG2_INST ("zextbw", 0x34),
+ REG2_INST ("zextbd", 0x35),
+ REG2_INST ("zextwd", 0x36),
+
+ REG2_INST ("bswap", 0x3F),
+
+ REG2_INST ("maxsb", 0x80),
+ REG2_INST ("minsb", 0x81),
+ REG2_INST ("maxub", 0x82),
+ REG2_INST ("minub", 0x83),
+ REG2_INST ("absb", 0x84),
+ REG2_INST ("negb", 0x85),
+ REG2_INST ("cntl0b", 0x86),
+ REG2_INST ("cntl1b", 0x87),
+ REG2_INST ("popcntb",0x88),
+ REG2_INST ("rotlb", 0x89),
+ REG2_INST ("rotrb", 0x8A),
+ REG2_INST ("mulqb", 0x8B),
+ REG2_INST ("addqb", 0x8C),
+ REG2_INST ("subqb", 0x8D),
+ REG2_INST ("cntlsb", 0x8E),
+
+ REG2_INST ("maxsw", 0x90),
+ REG2_INST ("minsw", 0x91),
+ REG2_INST ("maxuw", 0x92),
+ REG2_INST ("minuw", 0x93),
+ REG2_INST ("absw", 0x94),
+ REG2_INST ("negw", 0x95),
+ REG2_INST ("cntl0w", 0x96),
+ REG2_INST ("cntl1w", 0x97),
+ REG2_INST ("popcntw",0x98),
+ REG2_INST ("rotlw", 0x99),
+ REG2_INST ("rotrw", 0x9A),
+ REG2_INST ("mulqw", 0x9B),
+ REG2_INST ("addqw", 0x9C),
+ REG2_INST ("subqw", 0x9D),
+ REG2_INST ("cntlsw", 0x9E),
+
+ REG2_INST ("maxsd", 0xA0),
+ REG2_INST ("minsd", 0xA1),
+ REG2_INST ("maxud", 0xA2),
+ REG2_INST ("minud", 0xA3),
+ REG2_INST ("absd", 0xA4),
+ REG2_INST ("negd", 0xA5),
+ REG2_INST ("cntl0d", 0xA6),
+ REG2_INST ("cntl1d", 0xA7),
+ REG2_INST ("popcntd",0xA8),
+ REG2_INST ("rotld", 0xA9),
+ REG2_INST ("rotrd", 0xAA),
+ REG2_INST ("mulqd", 0xAB),
+ REG2_INST ("addqd", 0xAC),
+ REG2_INST ("subqd", 0xAD),
+ REG2_INST ("cntlsd", 0xAE),
+
+/* Conditional move instructions */
+ REG2_INST ("cmoveqd", 0x70),
+ REG2_INST ("cmovned", 0x71),
+ REG2_INST ("cmovcsd", 0x72),
+ REG2_INST ("cmovccd", 0x73),
+ REG2_INST ("cmovhid", 0x74),
+ REG2_INST ("cmovlsd", 0x75),
+ REG2_INST ("cmovgtd", 0x76),
+ REG2_INST ("cmovled", 0x77),
+ REG2_INST ("cmovfsd", 0x78),
+ REG2_INST ("cmovfcd", 0x79),
+ REG2_INST ("cmovlod", 0x7A),
+ REG2_INST ("cmovhsd", 0x7B),
+ REG2_INST ("cmovltd", 0x7C),
+ REG2_INST ("cmovged", 0x7D),
+
+/* Load instructions (from memory to register). */
+#define LD_REG_INST(NAME, OPC1, OPC2, DISP) \
+ /* opc12 r abs16 */ \
+ {NAME, 2, 0x320+OPC1, 20, LD_STOR_INS | REVERSE_MATCH, {{abs16,0}, {regr,16}}}, \
+ /* opc12 r abs32 */ \
+ {NAME, 3, 0x330+OPC1, 20, LD_STOR_INS | REVERSE_MATCH, {{abs32,0}, {regr,16}}}, \
+ /* opc4 r c4 rbase */ \
+ {NAME, 1, ((0x8+OPC2)<<8), 20, LD_STOR_INS | DISP | FMT_1 | REVERSE_MATCH, {{rbase,20}, {regr,24}}},\
+ /* opc4 r rbase dispu[bwd]4 */ \
+ {NAME, 1, 0x8+OPC2, 28, LD_STOR_INS | DISP | REVERSE_MATCH, {{rbase_cst4,16}, {regr,24}}}, \
+ /* opc4 r rbase disps16 */ \
+ {NAME, 2, ((0x8+OPC2)<<8)+0xE, 20, LD_STOR_INS | DISP | FMT_1 | REVERSE_MATCH, {{rbase_dispu16,16}, {regr,24}}}, \
+ /* opc4 r rbase disps32 */ \
+ {NAME, 3, ((0x8+OPC2)<<8)+0xF, 20, LD_STOR_INS | FMT_1 | REVERSE_MATCH, {{rbase_dispu32,16}, {regr,24}}}, \
+ /* opc12 r rbase */ \
+ {NAME, 2, 0x328+OPC1, 20, LD_STOR_INS_INC | REVERSE_MATCH, {{rbase,12}, {regr,16}}}, \
+ /* opc12 r rbase disps12 */ \
+ {NAME, 2, 0x328+OPC1, 20, LD_STOR_INS_INC | REVERSE_MATCH, {{rbase_dispu12,12}, {regr,16}}}, \
+ /* opc12 r rbase ridx scl2 disps6 */ \
+ {NAME, 2, 0x32C+OPC1, 20, LD_STOR_INS | REVERSE_MATCH, {{rbase_ridx_scl2_dispu6,0}, {regr,16}}}, \
+ /* opc12 r rbase ridx scl2 disps22 */ \
+ {NAME, 3, 0x33C+OPC1, 20, LD_STOR_INS | REVERSE_MATCH, {{rbase_ridx_scl2_dispu22,0}, {regr,16}}}
+
+ LD_REG_INST ("loadb", 0x0, 0x0, DISPUB4),
+ LD_REG_INST ("loadw", 0x1, 0x1, DISPUW4),
+ LD_REG_INST ("loadd", 0x2, 0x2, DISPUD4),
+
+/* Store instructions (from Register to Memory). */
+#define ST_REG_INST(NAME, OPC1, OPC2, DISP) \
+ /* opc12 r abs16 */ \
+ {NAME, 2, 0x320+OPC1, 20, LD_STOR_INS, {{regr,16}, {abs16,0}}}, \
+ /* opc12 r abs32 */ \
+ {NAME, 3, 0x330+OPC1, 20, LD_STOR_INS, {{regr,16}, {abs32,0}}}, \
+ /* opc4 r c4 rbase */ \
+ {NAME, 1, ((0x8+OPC2)<<8), 20, LD_STOR_INS | DISP | FMT_1, {{regr,24}, {rbase,20}}},\
+ /* opc4 r rbase dispu[bwd]4 */ \
+ {NAME, 1, 0x8+OPC2, 28, LD_STOR_INS | DISP, {{regr,24}, {rbase_cst4,16}}}, \
+ /* opc4 r rbase disps16 */ \
+ {NAME, 2, ((0x8+OPC2)<<8)+0xE, 20, LD_STOR_INS | DISP | FMT_1, {{regr,24}, {rbase_dispu16,16}}}, \
+ /* opc4 r rbase disps32 */ \
+ {NAME, 3, ((0x8+OPC2)<<8)+0xF, 20, LD_STOR_INS | FMT_1, {{regr,24}, {rbase_dispu32,16}}}, \
+ /* opc12 r rbase */ \
+ {NAME, 2, 0x328+OPC1, 20, LD_STOR_INS_INC, {{regr,16}, {rbase,12}}}, \
+ /* opc12 r rbase disps12 */ \
+ {NAME, 2, 0x328+OPC1, 20, LD_STOR_INS_INC, {{regr,16}, {rbase_dispu12,12}}}, \
+ /* opc12 r rbase ridx scl2 disps6 */ \
+ {NAME, 2, 0x32C+OPC1, 20, LD_STOR_INS, {{regr,16}, {rbase_ridx_scl2_dispu6,0}}}, \
+ /* opc12 r rbase ridx scl2 disps22 */ \
+ {NAME, 3, 0x33C+OPC1, 20, LD_STOR_INS, {{regr,16}, {rbase_ridx_scl2_dispu22,0}}}
+
+/* Store instructions (Immediate to Memory). */
+#define ST_I_INST(NAME, OPC) \
+ /* opc12 i4 abs16 */ \
+ {NAME, 2, 0x360+OPC, 20, STOR_IMM_INS, {{i4,16}, {abs16,0}}}, \
+ /* opc12 i4 abs32 */ \
+ {NAME, 3, 0x370+OPC, 20, STOR_IMM_INS, {{i4,16}, {abs32,0}}}, \
+ /* opc12 i4 c4 rbase */ \
+ {NAME, 1, 0x368+OPC, 20, LD_STOR_INS_INC, {{i4,16}, {rbase,12}}}, \
+ /* opc12 i4 rbase disps12 */ \
+ {NAME, 2, 0x368+OPC, 20, LD_STOR_INS_INC, {{i4,16}, {rbase_dispu12,12}}}, \
+ /* opc4 i4 c4 rbase */ \
+ {NAME, 1, 0x364+OPC, 20, STOR_IMM_INS, {{i4,16}, {rbase,12}}}, \
+ /* opc12 i4 rbase disps12 */ \
+ {NAME, 2, 0x364+OPC, 20, STOR_IMM_INS, {{i4,16}, {rbase_dispu12,12}}}, \
+ /* opc12 i4 rbase disps28 */ \
+ {NAME, 3, 0x374+OPC, 20, STOR_IMM_INS, {{i4,16}, {rbase_dispu28,12}}}, \
+ /* opc12 i4 rbase ridx scl2 disps6 */ \
+ {NAME, 2, 0x36C+OPC, 20, STOR_IMM_INS, {{i4,16}, {rbase_ridx_scl2_dispu6,0}}},\
+ /* opc12 i4 rbase ridx scl2 disps22 */ \
+ {NAME, 3, 0x37C+OPC, 20, STOR_IMM_INS, {{i4,16}, {rbase_ridx_scl2_dispu22,0}}}
+
+ ST_REG_INST ("storb", 0x20, 0x4, DISPUB4),
+ ST_I_INST ("storb", 0x0),
+
+ ST_REG_INST ("storw", 0x21, 0x5, DISPUW4),
+ ST_I_INST ("storw", 0x1),
+
+ ST_REG_INST ("stord", 0x22, 0x6, DISPUD4),
+ ST_I_INST ("stord", 0x2),
+
+/* Create a bit instruction. */
+#define CSTBIT_INST(NAME, OP, OPC1, DIFF, SHIFT, OPC2) \
+ /* OP=i3 -->> opc13 i3 */ \
+ /* OP=i4 -->> opc12 i4 */ \
+ /* OP=i5 -->> opc11 i5 */ \
+ \
+ /* opcNN iN abs16 */ \
+ {NAME, 2, OPC1+0*DIFF, SHIFT, CSTBIT_INS, {{OP,16}, {abs16,0}}}, \
+ /* opcNN iN abs32 */ \
+ {NAME, 3, OPC1+1*DIFF, SHIFT, CSTBIT_INS, {{OP,16}, {abs32,0}}}, \
+ /* opcNN iN rbase */ \
+ {NAME, 1, OPC2, SHIFT+4, CSTBIT_INS, {{OP,20}, {rbase,16}}}, \
+ /* opcNN iN rbase disps12 */ \
+ {NAME, 2, OPC1+2*DIFF, SHIFT, CSTBIT_INS, {{OP,16}, {rbase_dispu12,12}}}, \
+ /* opcNN iN rbase disps28 */ \
+ {NAME, 3, OPC1+3*DIFF, SHIFT, CSTBIT_INS, {{OP,16}, {rbase_dispu28,12}}}, \
+ /* opcNN iN rbase ridx scl2 disps6 */ \
+ {NAME, 2, OPC1+4*DIFF, SHIFT, CSTBIT_INS, {{OP,16}, {rbase_ridx_scl2_dispu6,0}}}, \
+ /* opcNN iN rbase ridx scl2 disps22 */ \
+ {NAME, 3, OPC1+5*DIFF, SHIFT, CSTBIT_INS, {{OP,16}, {rbase_ridx_scl2_dispu22,0}}}
+
+ CSTBIT_INST ("cbitb", i3, 0x700, 0x20, 19, 0x1FC),
+ CSTBIT_INST ("cbitw", i4, 0x382, 0x10, 20, 0xBD),
+ CSTBIT_INST ("cbitd", i5, 0x1C3, 0x8, 21, 0x7B),
+ {"cbitd", 2, 0x300838, 8, CSTBIT_INS, {{regr,4}, {regr,0}}},
+ {"cbitd", 2, 0x18047B, 9, CSTBIT_INS, {{i5,4}, {regr,0}}},
+
+ CSTBIT_INST ("sbitb", i3, 0x701, 0x20, 19, 0x1FD),
+ CSTBIT_INST ("sbitw", i4, 0x383, 0x10, 20, 0xBE),
+ CSTBIT_INST ("sbitd", i5, 0x1C4, 0x8, 21, 0x7C),
+ {"sbitd", 2, 0x300839, 8, CSTBIT_INS, {{regr,4}, {regr,0}}},
+ {"sbitd", 2, 0x18047C, 9, CSTBIT_INS, {{i5,4}, {regr,0}}},
+
+ CSTBIT_INST ("tbitb", i3, 0x702, 0x20, 19, 0x1FE),
+ CSTBIT_INST ("tbitw", i4, 0x384, 0x10, 20, 0xBF),
+ CSTBIT_INST ("tbitd", i5, 0x1C5, 0x8, 21, 0x7D),
+ {"tbitd", 2, 0x30083A, 8, CSTBIT_INS, {{regr,4}, {regr,0}}},
+ {"tbitd", 2, 0x18047D, 9, CSTBIT_INS, {{i5,4}, {regr,0}}},
+
+/* Instructions including a register list (opcode is represented as a mask). */
+#define REGLIST_INST(NAME, OPC) \
+ /* opc12 r mask16 */ \
+ {NAME, 2, OPC, 20, REG_LIST, {{regr,16}, {i16,0}}}
+
+ REG1_INST ("getrfid", 0xFF9),
+ REG1_INST ("setrfid", 0xFFA),
+
+ REGLIST_INST ("push", 0x346),
+ REG1_INST ("push", 0xFFB),
+ REGLIST_INST ("pushx", 0x347),
+
+ REGLIST_INST ("pop", 0x324),
+ REG1_INST ("pop", 0xFFC),
+ REGLIST_INST ("popx", 0x327),
+
+ REGLIST_INST ("popret", 0x326),
+ REG1_INST ("popret", 0xFFD),
+
+ REGLIST_INST ("loadm", 0x324),
+ REGLIST_INST ("loadma", 0x325),
+ REGLIST_INST ("popa", 0x325),
+
+ REGLIST_INST ("storm", 0x344),
+ REGLIST_INST ("storma", 0x345),
+
+/* Create a branch instruction. */
+#define BR_INST(NAME, OPC1, OPC2, INS_TYPE) \
+ /* opc12 r disps17 */ \
+ {NAME, 2, OPC1, 20, INS_TYPE | RELAXABLE, {{regr,16}, {d17,0}}}, \
+ /* opc12 r disps33 */ \
+ {NAME, 3, OPC2, 20, INS_TYPE | RELAXABLE, {{regr,16}, {d33,0}}}
+
+ BR_INST ("bal", 0x307, 0x317, 0),
+
+ /* Decrement and Branch instructions */
+ BR_INST ("dbnzb", 0x304, 0x314, DCR_BRANCH_INS),
+ BR_INST ("dbnzw", 0x305, 0x315, DCR_BRANCH_INS),
+ BR_INST ("dbnzd", 0x306, 0x316, DCR_BRANCH_INS),
+
+ /* Jump and link instructions */
+ REG1_INST ("jal", 0xFF8),
+ REG2_INST ("jal", 0x37),
+ REG2_INST ("jalid", 0x33),
+
+ /* opc12 c4 opc12 r mask16 */
+ {"loadmcr", 3, 0x3110300, 4, COP_REG_INS | REG_LIST | FMT_5, {{i4,16}, {regr,0}, {i16,0}}},
+ {"stormcr", 3, 0x3110301, 4, COP_REG_INS | REG_LIST | FMT_5, {{i4,16}, {regr,0}, {i16,0}}},
+
+ /* esc16 r procreg */
+ {"mtpr", 2, 0x3009, 16, 0, {{regr8,8}, {regr8,0}}},
+ /* esc16 procreg r */
+ {"mfpr", 2, 0x300A, 16, 0, {{regr8,8}, {regr8,0}}},
+ /* opc12 c4 opc8 r copreg */
+ {"mtcr", 2, 0x301030, 8, COP_REG_INS | FMT_2, {{i4,16}, {regr,4}, {copregr,0}}},
+ /* opc12 c4 opc8 copreg r */
+ {"mfcr", 2, 0x301031, 8, COP_REG_INS | FMT_2, {{i4,16}, {copregr,4}, {regr,0}}},
+ /* opc12 c4 opc8 r copsreg */
+ {"mtcsr", 2, 0x301032, 8, COP_REG_INS | FMT_2, {{i4,16}, {regr,4}, {copsregr,0}}},
+ /* opc12 c4 opc8 copsreg r */
+ {"mfcsr", 2, 0x301033, 8, COP_REG_INS | FMT_2, {{i4,16}, {copsregr,4}, {regr,0}}},
+
+ /* CO-processor extensions */
+ /* opc12 c4 opc4 i4 disps9 */
+ {"bcop", 2, 0x30107, 12, COP_BRANCH_INS | FMT_4, {{i4,16}, {i4,8}, {d9,0}}},
+ /* opc12 c4 opc4 i4 disps25 */
+ {"bcop", 3, 0x31107, 12, COP_BRANCH_INS | FMT_4, {{i4,16}, {i4,8}, {d25,0}}},
+
+ /* opc12 i4 */
+ {"excp", 1, 0xFFF, 20, 0, {{i4,16}}},
+ /* opc28 i4 */
+ {"cinv", 2, 0x3010000, 4, 0, {{i4,0}}},
+
+ /* opc9 i5 i5 i5 r r */
+ {"ram", 2, 0x7C, 23, 0, {{i5,18}, {i5,13}, {i5,8}, {regr,4}, {regr,0}}},
+ {"rim", 2, 0x7D, 23, 0, {{i5,18}, {i5,13}, {i5,8}, {regr,4}, {regr,0}}},
+
+ /* opc9 i3 r */
+ {"rotb", 1, 0x1FB, 23, 0, {{i3,20}, {regr,16}}},
+ /* opc8 i4 r */
+ {"rotw", 1, 0xB9, 24, 0, {{i4,20}, {regr,16}}},
+ /* opc23 i5 r */
+ {"rotd", 2, 0x180478, 9, 0, {{i5,4}, {regr,0}}},
+
+ {NULL, 0, 0, 0, 0, {{0, 0}}}
+};
+
+const int crx_num_opcodes = ARRAY_SIZE (crx_instruction);
+
+/* Macro to build a reg_entry, which have an opcode image :
+ For example :
+ REG(u4, 0x84, CRX_U_REGTYPE)
+ is interpreted as :
+ {"u4", u4, 0x84, CRX_U_REGTYPE} */
+#define REG(NAME, N, TYPE) {STRINGX(NAME), {NAME}, N, TYPE}
+
+const reg_entry crx_regtab[] =
+{
+/* Build a general purpose register r<N>. */
+#define REG_R(N) REG(CONCAT2(r,N), N, CRX_R_REGTYPE)
+
+ REG_R(0), REG_R(1), REG_R(2), REG_R(3),
+ REG_R(4), REG_R(5), REG_R(6), REG_R(7),
+ REG_R(8), REG_R(9), REG_R(10), REG_R(11),
+ REG_R(12), REG_R(13), REG_R(14), REG_R(15),
+ REG(ra, 0xe, CRX_R_REGTYPE),
+ REG(sp, 0xf, CRX_R_REGTYPE),
+
+/* Build a user register u<N>. */
+#define REG_U(N) REG(CONCAT2(u,N), 0x80 + N, CRX_U_REGTYPE)
+
+ REG_U(0), REG_U(1), REG_U(2), REG_U(3),
+ REG_U(4), REG_U(5), REG_U(6), REG_U(7),
+ REG_U(8), REG_U(9), REG_U(10), REG_U(11),
+ REG_U(12), REG_U(13), REG_U(14), REG_U(15),
+ REG(ura, 0x8e, CRX_U_REGTYPE),
+ REG(usp, 0x8f, CRX_U_REGTYPE),
+
+/* Build a configuration register. */
+#define REG_CFG(NAME, N) REG(NAME, N, CRX_CFG_REGTYPE)
+
+ REG_CFG(hi, 0x10),
+ REG_CFG(lo, 0x11),
+ REG_CFG(uhi, 0x90),
+ REG_CFG(ulo, 0x91),
+ REG_CFG(psr, 0x12),
+ REG_CFG(cfg, 0x15),
+ REG_CFG(cpcfg, 0x16),
+ REG_CFG(ccfg, 0x1b),
+
+/* Build a mptr register. */
+#define REG_MPTR(NAME, N) REG(NAME, N, CRX_MTPR_REGTYPE)
+
+ REG_MPTR(intbase, 0x13),
+ REG_MPTR(isp, 0x14),
+ REG_MPTR(cen, 0x17),
+
+/* Build a pc register. */
+#define REG_PC(NAME, N) REG(NAME, N, CRX_PC_REGTYPE)
+
+ REG_PC(pc, 0x0)
+};
+
+const int crx_num_regs = ARRAY_SIZE (crx_regtab);
+
+const reg_entry crx_copregtab[] =
+{
+/* Build a Coprocessor register c<N>. */
+#define REG_C(N) REG(CONCAT2(c,N), N, CRX_C_REGTYPE)
+
+ REG_C(0), REG_C(1), REG_C(2), REG_C(3),
+ REG_C(4), REG_C(5), REG_C(6), REG_C(7),
+ REG_C(8), REG_C(9), REG_C(10), REG_C(11),
+ REG_C(12), REG_C(13), REG_C(14), REG_C(15),
+
+/* Build a Coprocessor Special register cs<N>. */
+#define REG_CS(N) REG(CONCAT2(cs,N), N, CRX_CS_REGTYPE)
+
+ REG_CS(0), REG_CS(1), REG_CS(2), REG_CS(3),
+ REG_CS(4), REG_CS(5), REG_CS(6), REG_CS(7),
+ REG_CS(8), REG_CS(9), REG_CS(10), REG_CS(11),
+ REG_CS(12), REG_CS(13), REG_CS(14), REG_CS(15)
+};
+
+const int crx_num_copregs = ARRAY_SIZE (crx_copregtab);
+
+/* CRX operands table. */
+const operand_entry crx_optab[] =
+{
+ /* Index 0 is dummy, so we can count the instruction's operands. */
+ {0, nullargs}, /* dummy */
+ {4, arg_ic}, /* cst4 */
+ {8, arg_c}, /* disps9 */
+ {3, arg_ic}, /* i3 */
+ {4, arg_ic}, /* i4 */
+ {5, arg_ic}, /* i5 */
+ {8, arg_ic}, /* i8 */
+ {12, arg_ic}, /* i12 */
+ {16, arg_ic}, /* i16 */
+ {32, arg_ic}, /* i32 */
+ {4, arg_c}, /* d5 */
+ {8, arg_c}, /* d9 */
+ {16, arg_c}, /* d17 */
+ {24, arg_c}, /* d25 */
+ {32, arg_c}, /* d33 */
+ {16, arg_c}, /* abs16 */
+ {32, arg_c}, /* abs32 */
+ {4, arg_rbase}, /* rbase */
+ {4, arg_cr}, /* rbase_cst4 */
+ {8, arg_cr}, /* rbase_dispu8 */
+ {12, arg_cr}, /* rbase_dispu12 */
+ {16, arg_cr}, /* rbase_dispu16 */
+ {28, arg_cr}, /* rbase_dispu28 */
+ {32, arg_cr}, /* rbase_dispu32 */
+ {6, arg_icr}, /* rbase_ridx_scl2_dispu6 */
+ {22, arg_icr}, /* rbase_ridx_scl2_dispu22 */
+ {4, arg_r}, /* regr */
+ {8, arg_r}, /* regr8 */
+ {4, arg_copr}, /* copregr */
+ {8, arg_copr}, /* copregr8 */
+ {4, arg_copsr} /* copsregr */
+};
+
+/* CRX traps/interrupts. */
+const trap_entry crx_traps[] =
+{
+ {"nmi", 1}, {"svc", 5}, {"dvz", 6}, {"flg", 7},
+ {"bpt", 8}, {"und", 10}, {"prv", 11}, {"iberr", 12}
+};
+
+const int crx_num_traps = ARRAY_SIZE (crx_traps);
+
+/* cst4 operand mapping. */
+const cst4_entry cst4_map[] =
+{
+ {0,0}, {1,1}, {2,2}, {3,3}, {4,4}, {5,-4}, {6,-1},
+ {7,7}, {8,8}, {9,16}, {10,32}, {11,20}, {12,12}, {13,48}
+};
+
+const int cst4_maps = ARRAY_SIZE (cst4_map);
--- /dev/null
+// data cache pre-fetch:
+
+// 1111 1001 1010 0110 Rm.. 0000; dcpf (Rm)
+8.0xf9+8.0xa6+4.RN2,4.0000:D1a:::dcpf
+"dcpf"
+*am33_2
+{
+ int srcreg;
+
+ PC = cia;
+
+ srcreg = translate_rreg (SD_, RN2);
+ load_word (State.regs[srcreg]);
+}
+
+// 1111 1001 1010 0111 0000 0000; dcpf (sp)
+8.0xf9+8.0xa7+8.0x00:D1b:::dcpf
+"dcpf"
+*am33_2
+{
+ PC = cia;
+
+ load_word (SP);
+}
+
+// 1111 1011 1010 0110 Ri.. Rm.. 0000 0000; dcpf (Ri,Rm)
+8.0xfb+8.0xa6+4.RN2,4.RN0+8.0x00:D2a:::dcpf
+"dcpf"
+*am33_2
+{
+ int srci, srcm;
+
+ PC = cia;
+
+ srci = translate_rreg (SD_, RN2);
+ srcm = translate_rreg (SD_, RN0);
+
+ load_word (State.regs[srci] + State.regs[srcm]);
+}
+
+// 1111 1011 1010 0111 Rm.. 0000 IMM8; dcpf (d8,Rm)
+8.0xfb+8.0xa7+4.RN2,4.0000+8.IMM8:D2b:::dcpf
+"dcpf"
+*am33_2
+{
+ int srcreg;
+
+ PC = cia;
+
+ srcreg = translate_rreg (SD_, RN2);
+
+ load_word (State.regs[srcreg] + EXTEND8 (IMM8));
+}
+
+// 1111 1101 1010 0111 Rm.. 0000 IMM24; dcpf (d24,Rm)
+8.0xfd+8.0xa7+4.RN2,4.0000+8.IMM24A+8.IMM24B+8.IMM24C:D4a:::dcpf
+"dcpf"
+*am33_2
+{
+ int srcreg;
+
+ PC = cia;
+
+ srcreg = translate_rreg (SD_, RN2);
+
+ load_word (State.regs[srcreg] + EXTEND24 (FETCH24 (IMM24A,
+ IMM24B, IMM24C)));
+}
+
+// 1111 1110 0100 0110 Rm.. 0000 IMM32; dcpf (d32,Rm)
+8.0xfe+8.0x46+4.RN2,4.0000+8.IMM32A+8.IMM32B+8.IMM32C+8.IMM32D:D5a:::dcpf
+"dcpf"
+*am33_2
+{
+ int srcreg;
+
+ PC = cia;
+
+ srcreg = translate_rreg (SD_, RN2);
+
+ load_word (State.regs[srcreg]
+ + FETCH32 (IMM32A, IMM32B, IMM32C, IMM32D));
+}
+
+// bit operations with imm8,(abs16) addressing mode:
+
+// 1111 1110 1000 0010 ABS16 IMM8; btst imm8,(abs16)
+8.0xfe+8.0x82+8.IMM16A+8.IMM16B+8.IMM8:D3:::btst
+"btst"
+*am33_2
+{
+ PC = cia;
+ genericBtst (IMM8, FETCH16 (IMM16A, IMM16B));
+}
+
+// 1111 1110 1000 0000 ABS16 IMM8; bset imm8,(abs16)
+8.0xfe+8.0x80+8.IMM16A+8.IMM16B+8.IMM8:D3:::bset
+"bset"
+*am33_2
+{
+ unsigned32 temp;
+ int z;
+
+ PC = cia;
+ temp = load_byte (FETCH16 (IMM16A, IMM16B));
+ z = (temp & IMM8) == 0;
+ temp |= IMM8;
+ store_byte (FETCH16 (IMM16A, IMM16B), temp);
+ PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
+ PSW |= (z ? PSW_Z : 0);
+}
+
+// 1111 1110 1000 0001 ABS16 IMM8; bclr imm8,(abs16)
+8.0xfe+8.0x81+8.IMM16A+8.IMM16B+8.IMM8:D3:::bclr
+"bclr"
+*am33_2
+{
+ unsigned32 temp;
+ int z;
+
+ PC = cia;
+ temp = load_byte (FETCH16 (IMM16A, IMM16B));
+ z = (temp & IMM8) == 0;
+ temp = temp & ~(IMM8);
+ store_byte (FETCH16 (IMM16A, IMM16B), temp);
+ PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
+ PSW |= (z ? PSW_Z : 0);
+}
+
+// single precision fmov:
+
+// 1111 1001 0010 000X Rm.. Sn..; fmov (Rm),FSn
+8.0xf9+4.2,3.0,1.X+4.Rm,4.Sn:D1a:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = translate_rreg (SD_, Rm);
+ XS2FS (X,Sn) = load_word (State.regs[reg]);
+ }
+}
+
+// 1111 1001 0010 001X Rm.. Sn..; fmov (Rm+),FSn
+8.0xf9+4.2,3.1,1.X+4.Rm,4.Sn:D1b:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = translate_rreg (SD_, Rm);
+ XS2FS (X,Sn) = load_word (State.regs[reg]);
+ State.regs[reg] += 4;
+ }
+}
+
+// 1111 1001 0010 010X ---- Sn..; fmov (SP),FSn
+8.0xf9+4.2,3.2,1.X+4.0,4.Sn:D1c:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = REG_SP;
+ XS2FS (X,Sn) = load_word (State.regs[reg]);
+ }
+}
+
+// 1111 1001 0010 011X Rm.. Sn..; fmov Rm,FSn
+8.0xf9+4.2,3.3,1.X+4.Rm,4.Sn:D1d:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = translate_rreg (SD_, Rm);
+ XS2FS (X,Sn) = State.regs[reg];
+ }
+}
+
+// 1111 1001 0011 00Y0 Sm.. Rn..; fmov FSm,(Rn)
+8.0xf9+4.3,2.0,1.Y,1.0+4.Sm,4.Rn:D1e:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = translate_rreg (SD_, Rn);
+ store_word (State.regs[reg], XS2FS (Y,Sm));
+ }
+}
+
+// 1111 1001 0011 00Y1 Sm.. Rn..; fmov FSm,(Rn+)
+8.0xf9+4.3,2.0,1.Y,1.1+4.Sm,4.Rn:D1f:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = translate_rreg (SD_, Rn);
+ store_word (State.regs[reg], XS2FS (Y,Sm));
+ State.regs[reg] += 4;
+ }
+}
+
+// 1111 1001 0011 01Y0 Sm.. ----; fmov FSm,(SP)
+8.0xf9+4.3,2.1,1.Y,1.0+4.Sm,4.0:D1g:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = REG_SP;
+ store_word (State.regs[reg], XS2FS (Y,Sm));
+ }
+}
+
+// 1111 1001 0011 01Y1 Sm.. Rn..; fmov FSm,Rn
+8.0xf9+4.3,2.1,1.Y,1.1+4.Sm,4.Rn:D1h:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = translate_rreg (SD_, Rn);
+ State.regs[reg] = XS2FS (Y,Sm);
+ }
+}
+
+// 1111 1001 0100 00YX Sm.. Sn..; fmov FSm,FSn
+8.0xf9+4.4,2.0,1.Y,1.X+4.Sm,4.Sn:D1i:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ XS2FS (X,Sn) = XS2FS (Y,Sm);
+}
+
+// 1111 1011 0010 000X Rm.. Sn.. d8; fmov (d8,Rm),FSn
+8.0xfb+4.2,3.0,1.X+4.Rm,4.Sn+8.IMM8:D2a:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = translate_rreg (SD_, Rm);
+ XS2FS (X, Sn) = load_word (State.regs[reg] + EXTEND8 (IMM8));
+ }
+}
+
+// 1111 1011 0010 001X Rm.. Sn.. d8; fmov (Rm+,imm8),FSn
+8.0xfb+4.2,3.1,1.X+4.Rm,4.Sn+8.IMM8:D2b:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = translate_rreg (SD_, Rm);
+ XS2FS (X, Sn) = load_word (State.regs[reg] + EXTEND8 (IMM8));
+ State.regs[reg] += 4;
+ }
+}
+
+// 1111 1011 0010 010X ---- Sn.. d8; fmov (d8,SP),FSn
+8.0xfb+4.2,3.2,1.X+4.0,4.Sn+8.IMM8:D2c:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = REG_SP;
+ XS2FS (X, Sn) = load_word (State.regs[reg] + IMM8);
+ }
+}
+
+// 1111 1011 0010 0111 Ri.. Rm.. Sn.. --Z-; fmov (Ri,Rm),FSn
+8.0xfb+8.0x27+4.Ri,4.Rm+4.Sn,2.0,1.Z,1.0:D2d:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int ri = translate_rreg (SD_, Ri);
+ int rm = translate_rreg (SD_, Rm);
+ XS2FS (Z, Sn) = load_word (State.regs[ri] + State.regs[rm]);
+ }
+}
+
+// 1111 1011 0011 00Y0 Sm.. Rn.. d8; fmov FSm,(d8,Rn)
+8.0xfb+4.3,2.0,1.Y,1.0+4.Sm,4.Rn+8.IMM8:D2e:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = translate_rreg (SD_, Rn);
+ store_word (State.regs[reg] + EXTEND8 (IMM8), XS2FS (Y, Sm));
+ }
+}
+
+// 1111 1011 0011 00Y1 Sm.. Rn.. d8; fmov FSm,(Rn+,d8)
+8.0xfb+4.3,2.0,1.Y,1.1+4.Sm,4.Rn+8.IMM8:D2f:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = translate_rreg (SD_, Rn);
+ store_word (State.regs[reg] + EXTEND8 (IMM8), XS2FS (Y, Sm));
+ State.regs[reg] += 4;
+ }
+}
+
+// 1111 1011 0011 01Y0 Sm.. ---- d8; fmov FSm,(d8,SP)
+8.0xfb+4.3,2.1,1.Y,1.0+4.Sm,4.0+8.IMM8:D2g:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = REG_SP;
+ store_word (State.regs[reg] + IMM8, XS2FS (Y, Sm));
+ }
+}
+
+// 1111 1011 0011 0111 Ri.. Rm.. Sm.. --Z-; fmov FSm,(Ri,Rm)
+8.0xfb+8.0x37+4.Ri,4.Rm+4.Sm,2.0,1.Z,1.0:D2h:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int ri = translate_rreg (SD_, Ri);
+ int rm = translate_rreg (SD_, Rm);
+ store_word (State.regs[ri] + State.regs[rm], XS2FS (Z, Sm));
+ }
+}
+
+// 1111 1101 0010 000X Rm.. Sn.. d24; fmov (d24,Rm),FSn
+8.0xfd+4.2,3.0,1.X+4.Rm,4.Sn+8.IMM24A+8.IMM24B+8.IMM24C:D4a:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = translate_rreg (SD_, Rm);
+ XS2FS (X, Sn) = load_word (State.regs[reg]
+ + EXTEND24 (FETCH24 (IMM24A,
+ IMM24B, IMM24C)));
+ }
+}
+
+// 1111 1101 0010 001X Rm.. Sn.. d24; fmov (Rm+,imm24),FSn
+8.0xfd+4.2,3.1,1.X+4.Rm,4.Sn+8.IMM24A+8.IMM24B+8.IMM24C:D4b:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = translate_rreg (SD_, Rm);
+ XS2FS (X, Sn) = load_word (State.regs[reg]
+ + EXTEND24 (FETCH24 (IMM24A,
+ IMM24B, IMM24C)));
+ State.regs[reg] += 4;
+ }
+}
+
+// 1111 1101 0010 010X ---- Sn.. d24; fmov (d24,SP),FSn
+8.0xfd+4.2,3.2,1.X+4.0,4.Sn+8.IMM24A+8.IMM24B+8.IMM24C:D4c:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = REG_SP;
+ XS2FS (X, Sn) = load_word (State.regs[reg] + FETCH24 (IMM24A,
+ IMM24B, IMM24C));
+ }
+}
+
+// 1111 1101 0011 00Y0 Sm.. Rn.. d24; fmov FSm,(d24,Rn)
+8.0xfd+4.3,2.0,1.Y,1.0+4.Sm,4.Rn+8.IMM24A+8.IMM24B+8.IMM24C:D4e:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = translate_rreg (SD_, Rn);
+ store_word (State.regs[reg]
+ + EXTEND24 (FETCH24 (IMM24A,
+ IMM24B, IMM24C)), XS2FS (Y, Sm));
+ }
+}
+
+// 1111 1101 0011 00Y1 Sm.. Rn.. d24; fmov FSm,(Rn+,d24)
+8.0xfd+4.3,2.0,1.Y,1.1+4.Sm,4.Rn+8.IMM24A+8.IMM24B+8.IMM24C:D4f:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = translate_rreg (SD_, Rn);
+ store_word (State.regs[reg]
+ + EXTEND24 (FETCH24 (IMM24A,
+ IMM24B, IMM24C)), XS2FS (Y, Sm));
+ State.regs[reg] += 4;
+ }
+}
+
+// 1111 1101 0011 01Y0 Sm.. ---- d24; fmov FSm,(d24,SP)
+8.0xfd+4.3,2.1,1.Y,1.0+4.Sm,4.0+8.IMM24A+8.IMM24B+8.IMM24C:D4g:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = REG_SP;
+ store_word (State.regs[reg]
+ + FETCH24 (IMM24A,
+ IMM24B, IMM24C), XS2FS (Y, Sm));
+ }
+}
+
+// 1111 1110 0010 000X Rm.. Sn.. d32; fmov (d32,Rm),FSn
+8.0xfe+4.2,3.0,1.X+4.Rm,4.Sn+8.IMM32A+8.IMM32B+8.IMM32C+8.IMM32D:D5a:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = translate_rreg (SD_, Rm);
+ XS2FS (X, Sn) = load_word (State.regs[reg]
+ + EXTEND32 (FETCH32 (IMM32A, IMM32B,
+ IMM32C, IMM32D)));
+ }
+}
+
+// 1111 1110 0010 001X Rm.. Sn.. d32; fmov (Rm+,imm32),FSn
+8.0xfe+4.2,3.1,1.X+4.Rm,4.Sn+8.IMM32A+8.IMM32B+8.IMM32C+8.IMM32D:D5b:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = translate_rreg (SD_, Rm);
+ XS2FS (X, Sn) = load_word (State.regs[reg]
+ + EXTEND32 (FETCH32 (IMM32A, IMM32B,
+ IMM32C, IMM32D)));
+ State.regs[reg] += 4;
+ }
+}
+
+// 1111 1110 0010 010X ---- Sn.. d32; fmov (d32,SP),FSn
+8.0xfe+4.2,3.2,1.X+4.0,4.Sn+8.IMM32A+8.IMM32B+8.IMM32C+8.IMM32D:D5c:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = REG_SP;
+ XS2FS (X, Sn) = load_word (State.regs[reg]
+ + FETCH32 (IMM32A, IMM32B,
+ IMM32C, IMM32D));
+ }
+}
+
+// 1111 1110 0010 011X ---- Sn.. d32; fmov imm32,FSn
+8.0xfe+4.2,3.3,1.X+4.0,4.Sn+8.IMM32A+8.IMM32B+8.IMM32C+8.IMM32D:D5d:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ XS2FS (X, Sn) = FETCH32 (IMM32A, IMM32B, IMM32C, IMM32D);
+}
+
+// 1111 1110 0011 00Y0 Sm.. Rn.. d32; fmov FSm,(d32,Rn)
+8.0xfe+4.3,2.0,1.Y,1.0+4.Sm,4.Rn+8.IMM32A+8.IMM32B+8.IMM32C+8.IMM32D:D5e:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = translate_rreg (SD_, Rn);
+ store_word (State.regs[reg]
+ + EXTEND32 (FETCH32 (IMM32A, IMM32B,
+ IMM32C, IMM32D)), XS2FS (Y, Sm));
+ }
+}
+
+// 1111 1110 0011 00Y1 Sm.. Rn.. d32; fmov FSm,(Rn+,d32)
+8.0xfe+4.3,2.0,1.Y,1.1+4.Sm,4.Rn+8.IMM32A+8.IMM32B+8.IMM32C+8.IMM32D:D5f:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = translate_rreg (SD_, Rn);
+ store_word (State.regs[reg]
+ + EXTEND32 (FETCH32 (IMM32A, IMM32B,
+ IMM32C, IMM32D)), XS2FS (Y, Sm));
+ State.regs[reg] += 4;
+ }
+}
+
+// 1111 1110 0011 01Y0 Sm.. ---- d32; fmov FSm,(d32,SP)
+8.0xfe+4.3,2.1,1.Y,1.0+4.Sm,4.0+8.IMM32A+8.IMM32B+8.IMM32C+8.IMM32D:D5g:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = REG_SP;
+ store_word (State.regs[reg]
+ + FETCH32 (IMM32A, IMM32B,
+ IMM32C, IMM32D), XS2FS (Y, Sm));
+ }
+}
+
+// double precision fmov:
+
+// 1111 1001 1010 000X Rm.. fn.-; fmov (Rm),FDn
+8.0xf9+4.0xa,3.0,1.X+4.Rm,3.fn,1.0:D1j:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = translate_rreg (SD_, Rm);
+ Xf2FD (X,fn) = load_dword (State.regs[reg]);
+ }
+}
+
+// 1111 1001 1010 001X Rm.. fn.-; fmov (Rm+),FDn
+8.0xf9+4.0xa,3.1,1.X+4.Rm,3.fn,1.0:D1k:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = translate_rreg (SD_, Rm);
+ Xf2FD (X,fn) = load_dword (State.regs[reg]);
+ State.regs[reg] += 8;
+ }
+}
+
+// 1111 1001 1010 010X ---- fn.-; fmov (SP),FDn
+8.0xf9+4.0xa,3.2,1.X+4.0,3.fn,1.0:D1l:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = REG_SP;
+ Xf2FD (X,fn) = load_dword (State.regs[reg]);
+ }
+}
+
+// 1111 1001 1011 00Y0 fm.- Rn..; fmov FDm,(Rn)
+8.0xf9+4.0xb,2.0,1.Y,1.0+3.fm,1.0,4.Rn:D1m:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = translate_rreg (SD_, Rn);
+ store_dword (State.regs[reg], Xf2FD (Y,fm));
+ }
+}
+
+// 1111 1001 1011 00Y1 fm.- Rn..; fmov FDm,(Rn+)
+8.0xf9+4.0xb,2.0,1.Y,1.1+3.fm,1.0,4.Rn:D1n:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = translate_rreg (SD_, Rn);
+ store_dword (State.regs[reg], Xf2FD (Y,fm));
+ State.regs[reg] += 8;
+ }
+}
+
+// 1111 1001 1011 01Y0 fm.- ----; fmov FDm,(SP)
+8.0xf9+4.0xb,2.1,1.Y,1.0+3.fm,1.0,4.0:D1o:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = REG_SP;
+ store_dword (State.regs[reg], Xf2FD (Y,fm));
+ }
+}
+
+// 1111 1001 1100 00YX fm.- fn.-; fmov FDm,FDn
+8.0xf9+4.0xc,2.0,1.Y,1.X+3.fm,1.0,3.fn,1.0:D1p:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ fpu_unimp_exception (SD, CPU, cia);
+}
+
+// 1111 1011 0100 0111 Ri.. Rm.. fn.- --Z-; fmov (Ri,Rm),FDn
+8.0xfb+8.0x47+4.Ri,4.Rm+3.fn,1.0,2.0,1.Z,1.0:D2i:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int ri = translate_rreg (SD_, Ri);
+ int rm = translate_rreg (SD_, Rm);
+ Xf2FD (Z,fn) = load_dword (State.regs[ri] + State.regs[rm]);
+ }
+}
+
+// 1111 1011 0101 0111 Ri.. Rn.. fm.- --Z-; fmov FDm,(Ri,Rn)
+8.0xfb+8.0x57+4.Ri,4.Rn+3.fm,1.0,2.0,1.Z,1.0:D2j:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int ri = translate_rreg (SD_, Ri);
+ int rn = translate_rreg (SD_, Rn);
+ store_dword (State.regs[ri] + State.regs[rn], Xf2FD (Z,fm));
+ }
+}
+
+// 1111 1011 1010 000X Rm.. fn.- d8; fmov (d8,Rm),FDn
+8.0xfb+4.0xa,3.0,1.X+4.Rm,4.fn+8.IMM8:D2k:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = translate_rreg (SD_, Rm);
+ Xf2FD (X, fn) = load_dword (State.regs[reg] + EXTEND8 (IMM8));
+ }
+}
+
+// 1111 1011 1010 001X Rm.. fn.- d8; fmov (Rm+,imm8),FDn
+8.0xfb+4.0xa,3.1,1.X+4.Rm,4.fn+8.IMM8:D2l:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = translate_rreg (SD_, Rm);
+ Xf2FD (X, fn) = load_dword (State.regs[reg] + EXTEND8 (IMM8));
+ State.regs[reg] += 8;
+ }
+}
+
+// 1111 1011 1010 010X ---- fn.- d8; fmov (d8,SP),FDn
+8.0xfb+4.0xa,3.2,1.X+4.0,4.fn+8.IMM8:D2m:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = REG_SP;
+ Xf2FD (X, fn) = load_dword (State.regs[reg] + IMM8);
+ }
+}
+
+// 1111 1011 1011 00Y0 fm.- Rn.. d8; fmov FDm,(d8,Rn)
+8.0xfb+4.0xb,2.0,1.Y,1.0+4.fm,4.Rn+8.IMM8:D2n:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = translate_rreg (SD_, Rn);
+ store_dword (State.regs[reg] + EXTEND8 (IMM8), Xf2FD (Y, fm));
+ }
+}
+
+// 1111 1011 1011 00Y1 fm.- Rn.. d8; fmov FDm,(Rn+,d8)
+8.0xfb+4.0xb,2.0,1.Y,1.1+4.fm,4.Rn+8.IMM8:D2o:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = translate_rreg (SD_, Rn);
+ store_dword (State.regs[reg] + EXTEND8 (IMM8), Xf2FD (Y, fm));
+ State.regs[reg] += 8;
+ }
+}
+
+// 1111 1011 1011 01Y0 fm.- ---- d8; fmov FDm,(d8,SP)
+8.0xfb+4.0xb,2.1,1.Y,1.0+4.fm,4.0+8.IMM8:D2p:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = REG_SP;
+ store_dword (State.regs[reg] + IMM8, Xf2FD (Y, fm));
+ }
+}
+
+// 1111 1101 1010 000X Rm.. fn.- d24; fmov (d24,Rm),FDn
+8.0xfd+4.0xa,3.0,1.X+4.Rm,4.fn+8.IMM24A+8.IMM24B+8.IMM24C:D4k:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = translate_rreg (SD_, Rm);
+ Xf2FD (X, fn) = load_dword (State.regs[reg]
+ + EXTEND24 (FETCH24 (IMM24A,
+ IMM24B, IMM24C)));
+ }
+}
+
+// 1111 1101 1010 001X Rm.. fn.- d24; fmov (Rm+,imm24),FDn
+8.0xfd+4.0xa,3.1,1.X+4.Rm,4.fn+8.IMM24A+8.IMM24B+8.IMM24C:D4l:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = translate_rreg (SD_, Rm);
+ Xf2FD (X, fn) = load_dword (State.regs[reg]
+ + EXTEND24 (FETCH24 (IMM24A,
+ IMM24B, IMM24C)));
+ State.regs[reg] += 8;
+ }
+}
+
+// 1111 1101 1010 010X ---- fn.- d24; fmov (d24,SP),FDn
+8.0xfd+4.0xa,3.2,1.X+4.0,4.fn+8.IMM24A+8.IMM24B+8.IMM24C:D4m:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = REG_SP;
+ Xf2FD (X, fn) = load_dword (State.regs[reg]
+ + FETCH24 (IMM24A,
+ IMM24B, IMM24C));
+ }
+}
+
+// 1111 1101 1011 00Y0 fm.- Rn.. d24; fmov FDm,(d24,Rn)
+8.0xfd+4.0xb,2.0,1.Y,1.0+4.fm,4.Rn+8.IMM24A+8.IMM24B+8.IMM24C:D4n:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = translate_rreg (SD_, Rn);
+ store_dword (State.regs[reg]
+ + EXTEND24 (FETCH24 (IMM24A,
+ IMM24B, IMM24C)), Xf2FD (Y, fm));
+ }
+}
+
+// 1111 1101 1011 00Y1 fm.- Rn.. d24; fmov FDm,(Rn+,d24)
+8.0xfd+4.0xb,2.0,1.Y,1.1+4.fm,4.Rn+8.IMM24A+8.IMM24B+8.IMM24C:D4o:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = translate_rreg (SD_, Rn);
+ store_dword (State.regs[reg]
+ + EXTEND24 (FETCH24 (IMM24A,
+ IMM24B, IMM24C)), Xf2FD (Y, fm));
+ State.regs[reg] += 8;
+ }
+}
+
+// 1111 1101 1011 01Y0 fm.- ---- d24; fmov FDm,(d24,SP)
+8.0xfd+4.0xb,2.1,1.Y,1.0+4.fm,4.0+8.IMM24A+8.IMM24B+8.IMM24C:D4p:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = REG_SP;
+ store_dword (State.regs[reg] + FETCH24 (IMM24A,
+ IMM24B, IMM24C), Xf2FD (Y, fm));
+ }
+}
+
+// 1111 1110 1010 000X Rm.. fn.- d32; fmov (d32,Rm),FDn
+8.0xfe+4.0xa,3.0,1.X+4.Rm,4.fn+8.IMM32A+8.IMM32B+8.IMM32C+8.IMM32D:D5k:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = translate_rreg (SD_, Rm);
+ Xf2FD (X, fn) = load_dword (State.regs[reg]
+ + EXTEND32 (FETCH32 (IMM32A, IMM32B,
+ IMM32C, IMM32D)));
+ }
+}
+
+// 1111 1110 1010 001X Rm.. fn.- d32; fmov (Rm+,imm32),FDn
+8.0xfe+4.0xa,3.1,1.X+4.Rm,4.fn+8.IMM32A+8.IMM32B+8.IMM32C+8.IMM32D:D5l:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = translate_rreg (SD_, Rm);
+ Xf2FD (X, fn) = load_dword (State.regs[reg]
+ + EXTEND32 (FETCH32 (IMM32A, IMM32B,
+ IMM32C, IMM32D)));
+ State.regs[reg] += 8;
+ }
+}
+
+// 1111 1110 1010 010X ---- fn.- d32; fmov (d32,SP),FDn
+8.0xfe+4.0xa,3.2,1.X+4.0,4.fn+8.IMM32A+8.IMM32B+8.IMM32C+8.IMM32D:D5m:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = REG_SP;
+ Xf2FD (X, fn) = load_dword (State.regs[reg]
+ + FETCH32 (IMM32A, IMM32B,
+ IMM32C, IMM32D));
+ }
+}
+
+// 1111 1110 1011 00Y0 fm.- Rn.. d32; fmov FDm,(d32,Rn)
+8.0xfe+4.0xb,2.0,1.Y,1.0+4.fm,4.Rn+8.IMM32A+8.IMM32B+8.IMM32C+8.IMM32D:D5n:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = translate_rreg (SD_, Rn);
+ store_dword (State.regs[reg]
+ + EXTEND32 (FETCH32 (IMM32A, IMM32B,
+ IMM32C, IMM32D)), Xf2FD (Y, fm));
+ }
+}
+
+// 1111 1110 1011 00Y1 fm.- Rn.. d32; fmov FDm,(Rn+,d32)
+8.0xfe+4.0xb,2.0,1.Y,1.1+4.fm,4.Rn+8.IMM32A+8.IMM32B+8.IMM32C+8.IMM32D:D5o:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = translate_rreg (SD_, Rn);
+ store_dword (State.regs[reg]
+ + EXTEND32 (FETCH32 (IMM32A, IMM32B,
+ IMM32C, IMM32D)), Xf2FD (Y, fm));
+ State.regs[reg] += 8;
+ }
+}
+
+// 1111 1110 1011 01Y0 fm.- ---- d32; fmov FDm,(d32,SP)
+8.0xfe+4.0xb,2.1,1.Y,1.0+4.fm,4.0+8.IMM32A+8.IMM32B+8.IMM32C+8.IMM32D:D5p:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = REG_SP;
+ store_dword (State.regs[reg]
+ + FETCH32 (IMM32A, IMM32B,
+ IMM32C, IMM32D), Xf2FD (Y, fm));
+ }
+}
+
+// FPCR fmov:
+
+// 1111 1001 1011 0101 Rm.. ----; fmov Rm,FPCR
+8.0xf9+8.0xb5+4.Rm,4.0:D1q:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = translate_rreg (SD_, Rm);
+ unsigned32 val = State.regs[reg];
+ FPCR = (val & (EC_MASK | EE_MASK | FCC_MASK))
+ | ((FPCR & ~val) & EF_MASK);
+ }
+}
+
+// 1111 1001 1011 0111 ---- Rn..; fmov FPCR,Rn
+8.0xf9+8.0xb7+4.0,4.Rn:D1r:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ int reg = translate_rreg (SD_, Rn);
+ State.regs[reg] = FPCR & FPCR_MASK;
+ }
+}
+
+// 1111 1101 1011 0101 imm32; fmov imm32,FPCR
+8.0xfd+8.0xb5+8.IMM32A+8.IMM32B+8.IMM32C+8.IMM32D:D5:::fmov
+"fmov"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ unsigned32 val = FETCH32 (IMM32A, IMM32B, IMM32C, IMM32D);
+ FPCR = (val & (EC_MASK | EE_MASK | FCC_MASK))
+ | ((FPCR & ~val) & EF_MASK);
+ }
+}
+
+// fabs:
+
+// 1111 1001 0100 010X ---- Sn..; fabs FSn
+8.0xf9+4.4,3.2,1.X+4.0,4.Sn:D1a:::fabs
+"fabs"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ sim_fpu in, out;
+
+ FS2FPU (XS2FS (X,Sn), in);
+ sim_fpu_abs (&out, &in);
+ FPU2FS (out, XS2FS (X,Sn));
+ }
+}
+
+// 1111 1001 1100 010X ---- Sn..; fabs FDn
+8.0xf9+4.0xc,3.2,1.X+4.0,3.fn,1.0:D1b:::fabs
+"fabs"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ fpu_unimp_exception (SD, CPU, cia);
+}
+
+// 1111 1011 0100 0100 Sm.. ---- Sn.. X-Z-; fabs FSm,FSn
+8.0xfb+8.0x44+4.Sm,4.0+4.Sn,1.X,1.0,1.Z,1.0:D2a:::fabs
+"fabs"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ sim_fpu in, out;
+
+ FS2FPU (XS2FS (X,Sm), in);
+ sim_fpu_abs (&out, &in);
+ FPU2FS (out, XS2FS (Z,Sn));
+ }
+}
+
+// 1111 1011 1100 0100 fm.- ---- fn.- X-Z-; fabs FDm,FDn
+8.0xfb+8.0xc4+3.fm,1.0,4.0+3.fn,1.0,1.X,1.0,1.Z,1.0:D2b:::fabs
+"fabs"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ fpu_unimp_exception (SD, CPU, cia);
+}
+
+// 1111 1001 0100 011X ---- Sn..; fneg FSn
+8.0xf9+4.4,3.3,1.X+4.0,4.Sn:D1a:::fneg
+"fneg"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ sim_fpu in, out;
+
+ FS2FPU (XS2FS (X,Sn), in);
+ sim_fpu_neg (&out, &in);
+ FPU2FS (out, XS2FS (X,Sn));
+ }
+}
+
+// 1111 1001 1100 011X ---- Sn..; fneg FDn
+8.0xf9+4.0xc,3.3,1.X+4.0,3.fn,1.0:D1b:::fneg
+"fneg"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ fpu_unimp_exception (SD, CPU, cia);
+}
+
+// 1111 1011 0100 0110 Sm.. ---- Sn.. X-Z-; fneg FSm,FSn
+8.0xfb+8.0x46+4.Sm,4.0+4.Sn,1.X,1.0,1.Z,1.0:D2a:::fneg
+"fneg"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ sim_fpu in, out;
+
+ FS2FPU (XS2FS (X,Sm), in);
+ sim_fpu_neg (&out, &in);
+ FPU2FS (out, XS2FS (Z,Sn));
+ }
+}
+
+// 1111 1011 1100 0110 fm.- ---- fn.- X-Z-; fneg FDm,FDn
+8.0xfb+8.0xc6+3.fm,1.0,4.0+3.fn,1.0,1.X,1.0,1.Z,1.0:D2b:::fneg
+"fneg"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ fpu_unimp_exception (SD, CPU, cia);
+}
+
+// 1111 1001 0101 000X ---- Sn..; frsqrt FSn
+8.0xf9+4.5,3.0,1.X+4.0,4.Sn:D1a:::frsqrt
+"frsqrt"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ fpu_rsqrt (SD, CPU, cia, &XS2FS (X,Sn), &XS2FS (X,Sn), FP_SINGLE);
+}
+
+// 1111 1001 1101 000X ---- fn.-; frsqrt FDn
+8.0xf9+4.0xd,3.0,1.X+4.0,3.fn,1.0:D1b:::frsqrt
+"frsqrt"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ fpu_unimp_exception (SD, CPU, cia);
+}
+
+// 1111 1011 0101 0000 Sm.. ---- Sn.. X-Z-; frsqrt FSm,FSn
+8.0xfb+8.0x50+4.Sm,4.0+4.Sn,1.X,1.0,1.Z,1.0:D2a:::frsqrt
+"frsqrt"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ fpu_rsqrt (SD, CPU, cia, &XS2FS (X,Sm), &XS2FS (Z,Sn), FP_SINGLE);
+}
+
+// 1111 1011 1101 0000 fm.- ---- fn.- X-Z-; frsqrt FDm,FDn
+8.0xfb+8.0xd0+3.fm,1.0,4.0+3.fn,1.0,1.X,1.0,1.Z,1.0:D2b:::frsqrt
+"frsqrt"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ fpu_unimp_exception (SD, CPU, cia);
+}
+
+// 1111 1001 0101 001X ---- Sn..; fsqrt FSn
+8.0xf9+4.5,3.1,1.X+4.0,4.Sn:D1a:::fsqrt
+"fsqrt"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ fpu_unimp_exception (SD, CPU, cia);
+}
+
+// 1111 1001 1101 001X ---- fn.-; fsqrt FDn
+8.0xf9+4.0xd,3.1,1.X+4.0,3.fn,1.0:D1b:::fsqrt
+"fsqrt"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ fpu_unimp_exception (SD, CPU, cia);
+}
+
+// 1111 1011 0101 0100 Sm.. ---- Sn.. X-Z-; fsqrt FSm,FSn
+8.0xfb+8.0x54+4.Sm,4.0+4.Sn,1.X,1.0,1.Z,1.0:D2a:::fsqrt
+"fsqrt"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ fpu_unimp_exception (SD, CPU, cia);
+}
+
+// 1111 1011 1101 0100 fm.- ---- fn.- X-Z-; fsqrt FDm,FDn
+8.0xfb+8.0xd4+3.fm,1.0,4.0+3.fn,1.0,1.X,1.0,1.Z,1.0:D2b:::fsqrt
+"fsqrt"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ fpu_unimp_exception (SD, CPU, cia);
+}
+
+// 1111 1001 0101 01YX Sm.. Sn..; fcmp FSm, FSn
+8.0xf9+4.5,2.1,1.Y,1.X+4.Sm,4.Sn:D1a:::fcmp
+"fcmp"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ fpu_cmp (SD, CPU, cia, &XS2FS (X,Sn), &XS2FS (Y,Sm), FP_SINGLE);
+}
+
+// 1111 1001 1101 01YX fm.- fn.-; fcmp FDm, FDn
+8.0xf9+4.0xd,2.1,1.Y,1.X+3.fm,1.0,3.fn,1.0:D1b:::fcmp
+"fcmp"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ fpu_unimp_exception (SD, CPU, cia);
+}
+
+// 1111 1110 0011 01Y1 Sm.. ---- IMM32; fcmp imm32, FSm
+8.0xfe+4.3,2.1,1.Y,1.1+4.Sm,4.0+8.IMM32A+8.IMM32B+8.IMM32C+8.IMM32D:D5:::fcmp
+"fcmp"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ uint32 imm = FETCH32 (IMM32A, IMM32B, IMM32C, IMM32D);
+
+ fpu_cmp (SD, CPU, cia, &XS2FS (Y,Sm), &imm, FP_SINGLE);
+ }
+}
+
+// 1111 1001 0110 00YX Sm.. Sn..; fadd FSm, FSn
+8.0xf9+4.6,2.0,1.Y,1.X+4.Sm,4.Sn:D1a:::fadd
+"fadd"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ fpu_add (SD, CPU, cia,
+ &XS2FS (Y,Sm), &XS2FS (X,Sn), &XS2FS (X,Sn), FP_SINGLE);
+}
+
+// 1111 1001 1110 00YX fm.- fn.-; fadd FDm, FDn
+8.0xf9+4.0xe,2.0,1.Y,1.X+3.fm,1.0,3.fn,1.0:D1b:::fadd
+"fadd"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ fpu_unimp_exception (SD, CPU, cia);
+}
+
+// 1111 1011 0110 0000 Sm1. Sm2. Sn.. XYZ-; fadd FSm1, FSm2, FSn
+8.0xfb+8.0x60+4.Sm1,4.Sm2+4.Sn,1.X,1.Y,1.Z,1.0:D2a:::fadd
+"fadd"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ fpu_add (SD, CPU, cia,
+ &XS2FS (X,Sm1), &XS2FS (Y,Sm2), &XS2FS (Z,Sn), FP_SINGLE);
+}
+
+// 1111 1011 1110 0000 fm1- fm2- fn.- XYZ-; fadd FDm1, FDm2, FDn
+8.0xfb+8.0xe0+3.fm1,1.0,3.fm2,1.0+3.fn,1.0,1.X,1.Y,1.Z,1.0:D2b:::fadd
+"fadd"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ fpu_unimp_exception (SD, CPU, cia);
+}
+
+
+// 1111 1110 0110 00YX Sm.. Sn.. IMM32; fadd imm32, FSm, FSn
+8.0xfe+4.6,2.0,1.Y,1.X+4.Sm,4.Sn+8.IMM32A+8.IMM32B+8.IMM32C+8.IMM32D:D5:::fadd
+"fadd"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ uint32 imm = FETCH32 (IMM32A, IMM32B, IMM32C, IMM32D);
+
+ fpu_add (SD, CPU, cia,
+ &XS2FS (Y,Sm), &imm, &XS2FS (X,Sn), FP_SINGLE);
+ }
+}
+
+// 1111 1001 0110 01YX Sm.. Sn..; fsub FSm, FSn
+8.0xf9+4.6,2.1,1.Y,1.X+4.Sm,4.Sn:D1a:::fsub
+"fsub"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ fpu_sub (SD, CPU, cia,
+ &XS2FS (X,Sn), &XS2FS (Y,Sm), &XS2FS (X,Sn), FP_SINGLE);
+}
+
+// 1111 1001 1110 01YX fm.- fn.-; fsub FDm, FDn
+8.0xf9+4.0xe,2.1,1.Y,1.X+3.fm,1.0,3.fn,1.0:D1b:::fsub
+"fsub"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ fpu_unimp_exception (SD, CPU, cia);
+}
+
+// 1111 1011 0110 0100 Sm1. Sm2. Sn.. XYZ-; fsub FSm1, FSm2, FSn
+8.0xfb+8.0x64+4.Sm1,4.Sm2+4.Sn,1.X,1.Y,1.Z,1.0:D2a:::fsub
+"fsub"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ fpu_sub (SD, CPU, cia,
+ &XS2FS (Y,Sm2), &XS2FS (X,Sm1), &XS2FS (Z,Sn), FP_SINGLE);
+}
+
+// 1111 1011 1110 0100 fm1- fm2- fn.- XYZ-; fsub FDm1, FDm2, FDn
+8.0xfb+8.0xe4+3.fm1,1.0,3.fm2,1.0+3.fn,1.0,1.X,1.Y,1.Z,1.0:D2b:::fsub
+"fsub"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ fpu_unimp_exception (SD, CPU, cia);
+}
+
+
+// 1111 1110 0110 01YX Sm.. Sn.. IMM32; fsub imm32, FSm, FSn
+8.0xfe+4.6,2.1,1.Y,1.X+4.Sm,4.Sn+8.IMM32A+8.IMM32B+8.IMM32C+8.IMM32D:D5:::fsub
+"fsub"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ uint32 imm = FETCH32 (IMM32A, IMM32B, IMM32C, IMM32D);
+
+ fpu_sub (SD, CPU, cia,
+ &XS2FS (Y,Sm), &imm, &XS2FS (X,Sn), FP_SINGLE);
+ }
+}
+
+// 1111 1001 0111 00YX Sm.. Sn..; fmul FSm, FSn
+8.0xf9+4.7,2.0,1.Y,1.X+4.Sm,4.Sn:D1a:::fmul
+"fmul"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ fpu_mul (SD, CPU, cia,
+ &XS2FS (Y,Sm), &XS2FS (X,Sn), &XS2FS (X,Sn), FP_SINGLE);
+}
+
+// 1111 1001 1111 00YX fm.- fn.-; fmul FDm, FDn
+8.0xf9+4.0xf,2.0,1.Y,1.X+3.fm,1.0,3.fn,1.0:D1b:::fmul
+"fmul"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ fpu_unimp_exception (SD, CPU, cia);
+}
+
+// 1111 1011 0111 0000 Sm1. Sm2. Sn.. XYZ-; fmul FSm1, FSm2, FSn
+8.0xfb+8.0x70+4.Sm1,4.Sm2+4.Sn,1.X,1.Y,1.Z,1.0:D2a:::fmul
+"fmul"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ fpu_mul (SD, CPU, cia,
+ &XS2FS (X,Sm1), &XS2FS (Y,Sm2), &XS2FS (Z,Sn), FP_SINGLE);
+}
+
+// 1111 1011 1111 0000 fm1- fm2- fn.- XYZ-; fmul FDm1, FDm2, FDn
+8.0xfb+8.0xf0+3.fm1,1.0,3.fm2,1.0+3.fn,1.0,1.X,1.Y,1.Z,1.0:D2b:::fmul
+"fmul"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ fpu_unimp_exception (SD, CPU, cia);
+}
+
+
+// 1111 1110 0111 00YX Sm.. Sn.. IMM32; fmul imm32, FSm, FSn
+8.0xfe+4.7,2.0,1.Y,1.X+4.Sm,4.Sn+8.IMM32A+8.IMM32B+8.IMM32C+8.IMM32D:D5:::fmul
+"fmul"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ uint32 imm = FETCH32 (IMM32A, IMM32B, IMM32C, IMM32D);
+
+ fpu_mul (SD, CPU, cia,
+ &imm, &XS2FS (Y,Sm), &XS2FS (X,Sn), FP_SINGLE);
+ }
+}
+
+// 1111 1001 0111 01YX Sm.. Sn..; fdiv FSm, FSn
+8.0xf9+4.7,2.1,1.Y,1.X+4.Sm,4.Sn:D1a:::fdiv
+"fdiv"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ fpu_div (SD, CPU, cia,
+ &XS2FS (X,Sn), &XS2FS (Y,Sm), &XS2FS (X,Sn), FP_SINGLE);
+}
+
+// 1111 1001 1111 01YX fm.- fn.-; fdiv FDm, FDn
+8.0xf9+4.0xf,2.1,1.Y,1.X+3.fm,1.0,3.fn,1.0:D1b:::fdiv
+"fdiv"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ fpu_unimp_exception (SD, CPU, cia);
+}
+
+// 1111 1011 0111 0100 Sm1. Sm2. Sn.. XYZ-; fdiv FSm1, FSm2, FSn
+8.0xfb+8.0x74+4.Sm1,4.Sm2+4.Sn,1.X,1.Y,1.Z,1.0:D2a:::fdiv
+"fdiv"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ fpu_div (SD, CPU, cia,
+ &XS2FS (Y,Sm2), &XS2FS (X,Sm1), &XS2FS (Z,Sn), FP_SINGLE);
+}
+
+// 1111 1011 1111 0100 fm1- fm2- fn.- XYZ-; fdiv FDm1, FDm2, FDn
+8.0xfb+8.0xf4+3.fm1,1.0,3.fm2,1.0+3.fn,1.0,1.X,1.Y,1.Z,1.0:D2b:::fdiv
+"fdiv"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ fpu_unimp_exception (SD, CPU, cia);
+}
+
+
+// 1111 1110 0111 01YX Sm.. Sn.. IMM32; fdiv imm32, FSm, FSn
+8.0xfe+4.7,2.1,1.Y,1.X+4.Sm,4.Sn+8.IMM32A+8.IMM32B+8.IMM32C+8.IMM32D:D5:::fdiv
+"fdiv"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ {
+ uint32 imm = FETCH32 (IMM32A, IMM32B, IMM32C, IMM32D);
+
+ fpu_div (SD, CPU, cia,
+ &XS2FS (Y,Sm), &imm, &XS2FS (X,Sn), FP_SINGLE);
+ }
+}
+
+// 1111 1011 1000 00Sn Sm1. Sm2. Sm3. XYZA; fmadd FSm1, FSm2, FSm3, FSn
+8.0xfb+4.8,2.0,2.Sn+4.Sm1,4.Sm2+4.Sm3,1.X,1.Y,1.Z,1.A:D2:::fmadd
+"fmadd"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ fpu_fmadd (SD, CPU, cia,
+ &XS2FS (X,Sm1), &XS2FS (Y,Sm2), &XS2FS (Z,Sm3),
+ &AS2FS (A,Sn), FP_SINGLE);
+}
+
+// 1111 1011 1000 01Sn Sm1. Sm2. Sm3. XYZA; fmsub FSm1, FSm2, FSm3, FSn
+8.0xfb+4.8,2.1,2.Sn+4.Sm1,4.Sm2+4.Sm3,1.X,1.Y,1.Z,1.A:D2:::fmsub
+"fmsub"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ fpu_fmsub (SD, CPU, cia,
+ &XS2FS (X,Sm1), &XS2FS (Y,Sm2), &XS2FS (Z,Sm3),
+ &AS2FS (A,Sn), FP_SINGLE);
+}
+
+// 1111 1011 1001 00Sn Sm1. Sm2. Sm3. XYZA; fnmadd FSm1, FSm2, FSm3, FSn
+8.0xfb+4.9,2.0,2.Sn+4.Sm1,4.Sm2+4.Sm3,1.X,1.Y,1.Z,1.A:D2:::fnmadd
+"fnmadd"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ fpu_fnmadd (SD, CPU, cia,
+ &XS2FS (X,Sm1), &XS2FS (Y,Sm2), &XS2FS (Z,Sm3),
+ &AS2FS (A,Sn), FP_SINGLE);
+}
+
+// 1111 1011 1001 01Sn Sm1. Sm2. Sm3. XYZA; fnmsub FSm1, FSm2, FSm3, FSn
+8.0xfb+4.9,2.1,2.Sn+4.Sm1,4.Sm2+4.Sm3,1.X,1.Y,1.Z,1.A:D2:::fnmsub
+"fnmsub"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ fpu_fnmsub (SD, CPU, cia,
+ &XS2FS (X,Sm1), &XS2FS (Y,Sm2), &XS2FS (Z,Sm3),
+ &AS2FS (A,Sn), FP_SINGLE);
+}
+
+// conversion:
+
+// 1111 1011 0100 0000 Sm.. ---- Sn.. X-Z-; ftoi FSm,FSn
+8.0xfb+8.0x40+4.Sm,4.0+4.Sn,1.X,1.0,1.Z,1.0:D2:::ftoi
+"ftoi"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ fpu_unimp_exception (SD, CPU, cia);
+}
+
+// 1111 1011 0100 0010 Sm.. ---- Sn.. X-Z-; itof FSm,FSn
+8.0xfb+8.0x42+4.Sm,4.0+4.Sn,1.X,1.0,1.Z,1.0:D2:::itof
+"itof"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ fpu_unimp_exception (SD, CPU, cia);
+}
+
+// 1111 1011 0101 0010 Sm.. ---- fn.- X-Z-; ftod FSm,FDn
+8.0xfb+8.0x52+4.Sm,4.0+3.fn,1.0,1.X,1.0,1.Z,1.0:D2:::ftod
+"ftod"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ fpu_unimp_exception (SD, CPU, cia);
+}
+
+// 1111 1011 0101 0110 fm.- ---- Sn.. X-Z-; dtof FDm,FSn
+8.0xfb+8.0x56+3.fm,1.0,4.0+4.Sn,1.X,1.0,1.Z,1.0:D2:::dtof
+"dtof"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else
+ fpu_unimp_exception (SD, CPU, cia);
+}
+
+// branching:
+
+// 1111 1000 1101 0000 d8; fbeq (d8,PC) (d8 is sign-extended)
+8.0xf8+8.0xd0+8.D8:D1:::fbeq
+"fbeq"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else if ((FPCR & FCC_E))
+ {
+ State.regs[REG_PC] += EXTEND8 (D8);
+ nia = PC;
+ }
+}
+
+// 1111 1000 1101 0001 d8; fbne (d8,PC) (d8 is sign-extended)
+8.0xf8+8.0xd1+8.D8:D1:::fbne
+"fbne"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else if ((FPCR & (FCC_U | FCC_L | FCC_G)))
+ {
+ State.regs[REG_PC] += EXTEND8 (D8);
+ nia = PC;
+ }
+}
+
+// 1111 1000 1101 0010 d8; fbgt (d8,PC) (d8 is sign-extended)
+8.0xf8+8.0xd2+8.D8:D1:::fbgt
+"fbgt"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else if ((FPCR & FCC_G))
+ {
+ State.regs[REG_PC] += EXTEND8 (D8);
+ nia = PC;
+ }
+}
+
+// 1111 1000 1101 0011 d8; fbge (d8,PC) (d8 is sign-extended)
+8.0xf8+8.0xd3+8.D8:D1:::fbge
+"fbge"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else if ((FPCR & (FCC_G | FCC_E)))
+ {
+ State.regs[REG_PC] += EXTEND8 (D8);
+ nia = PC;
+ }
+}
+
+// 1111 1000 1101 0100 d8; fblt (d8,PC) (d8 is sign-extended)
+8.0xf8+8.0xd4+8.D8:D1:::fblt
+"fblt"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else if ((FPCR & FCC_L))
+ {
+ State.regs[REG_PC] += EXTEND8 (D8);
+ nia = PC;
+ }
+}
+
+// 1111 1000 1101 0101 d8; fble (d8,PC) (d8 is sign-extended)
+8.0xf8+8.0xd5+8.D8:D1:::fble
+"fble"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else if ((FPCR & (FCC_L | FCC_E)))
+ {
+ State.regs[REG_PC] += EXTEND8 (D8);
+ nia = PC;
+ }
+}
+
+// 1111 1000 1101 0110 d8; fbuo (d8,PC) (d8 is sign-extended)
+8.0xf8+8.0xd6+8.D8:D1:::fbuo
+"fbuo"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else if ((FPCR & FCC_U))
+ {
+ State.regs[REG_PC] += EXTEND8 (D8);
+ nia = PC;
+ }
+}
+
+// 1111 1000 1101 0111 d8; fblg (d8,PC) (d8 is sign-extended)
+8.0xf8+8.0xd7+8.D8:D1:::fblg
+"fblg"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else if ((FPCR & (FCC_L | FCC_G)))
+ {
+ State.regs[REG_PC] += EXTEND8 (D8);
+ nia = PC;
+ }
+}
+// 1111 1000 1101 1000 d8; fbleg (d8,PC) (d8 is sign-extended)
+8.0xf8+8.0xd8+8.D8:D1:::fbleg
+"fbleg"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else if ((FPCR & (FCC_L | FCC_E | FCC_G)))
+ {
+ State.regs[REG_PC] += EXTEND8 (D8);
+ nia = PC;
+ }
+}
+
+// 1111 1000 1101 1001 d8; fbug (d8,PC) (d8 is sign-extended)
+8.0xf8+8.0xd9+8.D8:D1:::fbug
+"fbug"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else if ((FPCR & (FCC_U | FCC_G)))
+ {
+ State.regs[REG_PC] += EXTEND8 (D8);
+ nia = PC;
+ }
+}
+
+// 1111 1000 1101 1010 d8; fbuge (d8,PC) (d8 is sign-extended)
+8.0xf8+8.0xda+8.D8:D1:::fbuge
+"fbuge"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else if ((FPCR & (FCC_U | FCC_G | FCC_E)))
+ {
+ State.regs[REG_PC] += EXTEND8 (D8);
+ nia = PC;
+ }
+}
+
+// 1111 1000 1101 1011 d8; fbul (d8,PC) (d8 is sign-extended)
+8.0xf8+8.0xdb+8.D8:D1:::fbul
+"fbul"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else if ((FPCR & (FCC_U | FCC_L)))
+ {
+ State.regs[REG_PC] += EXTEND8 (D8);
+ nia = PC;
+ }
+}
+
+// 1111 1000 1101 1100 d8; fbule (d8,PC) (d8 is sign-extended)
+8.0xf8+8.0xdc+8.D8:D1:::fbule
+"fbule"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else if ((FPCR & (FCC_U | FCC_L | FCC_E)))
+ {
+ State.regs[REG_PC] += EXTEND8 (D8);
+ nia = PC;
+ }
+}
+
+// 1111 1000 1101 1101 d8; fbue (d8,PC) (d8 is sign-extended)
+8.0xf8+8.0xdd+8.D8:D1:::fbue
+"fbue"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else if ((FPCR & (FCC_U | FCC_E)))
+ {
+ State.regs[REG_PC] += EXTEND8 (D8);
+ nia = PC;
+ }
+}
+
+// 1111 0000 1101 0000; fleq
+8.0xf0+8.0xd0:D0:::fleq
+"fleq"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else if ((FPCR & FCC_E))
+ {
+ State.regs[REG_PC] = State.regs[REG_LAR] - 4;
+ nia = PC;
+ }
+}
+
+// 1111 0000 1101 0001; flne
+8.0xf0+8.0xd1:D0:::flne
+"flne"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else if ((FPCR & (FCC_U | FCC_L | FCC_G)))
+ {
+ State.regs[REG_PC] = State.regs[REG_LAR] - 4;
+ nia = PC;
+ }
+}
+
+// 1111 0000 1101 0010; flgt
+8.0xf0+8.0xd2:D0:::flgt
+"flgt"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else if ((FPCR & FCC_G))
+ {
+ State.regs[REG_PC] = State.regs[REG_LAR] - 4;
+ nia = PC;
+ }
+}
+
+// 1111 0000 1101 0011; flge
+8.0xf0+8.0xd3:D0:::flge
+"flge"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else if ((FPCR & (FCC_G | FCC_E)))
+ {
+ State.regs[REG_PC] = State.regs[REG_LAR] - 4;
+ nia = PC;
+ }
+}
+
+// 1111 0000 1101 0100; fllt
+8.0xf0+8.0xd4:D0:::fllt
+"fllt"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else if ((FPCR & FCC_L))
+ {
+ State.regs[REG_PC] = State.regs[REG_LAR] - 4;
+ nia = PC;
+ }
+}
+
+// 1111 0000 1101 0101; flle
+8.0xf0+8.0xd5:D0:::flle
+"flle"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else if ((FPCR & (FCC_L | FCC_E)))
+ {
+ State.regs[REG_PC] = State.regs[REG_LAR] - 4;
+ nia = PC;
+ }
+}
+
+// 1111 0000 1101 0110; fluo
+8.0xf0+8.0xd6:D0:::fluo
+"fluo"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else if ((FPCR & FCC_U))
+ {
+ State.regs[REG_PC] = State.regs[REG_LAR] - 4;
+ nia = PC;
+ }
+}
+
+// 1111 0000 1101 0111; fllg
+8.0xf0+8.0xd7:D0:::fllg
+"fllg"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else if ((FPCR & (FCC_L | FCC_G)))
+ {
+ State.regs[REG_PC] = State.regs[REG_LAR] - 4;
+ nia = PC;
+ }
+}
+// 1111 0000 1101 1000; flleg
+8.0xf0+8.0xd8:D0:::flleg
+"flleg"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else if ((FPCR & (FCC_L | FCC_E | FCC_G)))
+ {
+ State.regs[REG_PC] = State.regs[REG_LAR] - 4;
+ nia = PC;
+ }
+}
+
+// 1111 0000 1101 1001; flug
+8.0xf0+8.0xd9:D0:::flug
+"flug"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else if ((FPCR & (FCC_U | FCC_G)))
+ {
+ State.regs[REG_PC] = State.regs[REG_LAR] - 4;
+ nia = PC;
+ }
+}
+
+// 1111 0000 1101 1010; fluge
+8.0xf0+8.0xda:D0:::fluge
+"fluge"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else if ((FPCR & (FCC_U | FCC_G | FCC_E)))
+ {
+ State.regs[REG_PC] = State.regs[REG_LAR] - 4;
+ nia = PC;
+ }
+}
+
+// 1111 0000 1101 1011; flul
+8.0xf0+8.0xdb:D0:::flul
+"flul"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else if ((FPCR & (FCC_U | FCC_L)))
+ {
+ State.regs[REG_PC] = State.regs[REG_LAR] - 4;
+ nia = PC;
+ }
+}
+
+// 1111 0000 1101 1100; flule
+8.0xf0+8.0xdc:D0:::flule
+"flule"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else if ((FPCR & (FCC_U | FCC_L | FCC_E)))
+ {
+ State.regs[REG_PC] = State.regs[REG_LAR] - 4;
+ nia = PC;
+ }
+}
+
+// 1111 0000 1101 1101; flue
+8.0xf0+8.0xdd:D0:::flue
+"flue"
+*am33_2
+{
+ PC = cia;
+
+ if (FPU_DISABLED)
+ fpu_disabled_exception (SD, CPU, cia);
+ else if ((FPCR & (FCC_U | FCC_E)))
+ {
+ State.regs[REG_PC] = State.regs[REG_LAR] - 4;
+ nia = PC;
+ }
+}
--- /dev/null
+/* This file is part of GDB.
+
+ Copyright 2004 Free Software Foundation, Inc.
+
+ 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 "psim.h"
+#include "options.h"
+#include "registers.h"
+
+#include "ansidecl.h"
+#include "sim_callbacks.h"
+#include "gdb/callback.h"
+#include "gdb/remote-sim.h"
+#include "gdb/sim-ppc.h"
+
+/* Return the name of the register whose number is REGNUM, or zero if
+ REGNUM is an invalid register number. */
+
+static const char *
+regnum2spr (int spr)
+{
+ if (spr_is_valid (spr))
+ return spr_name (spr);
+ else
+ return NULL;
+}
+
+static const char *
+regnum2name (int regnum)
+{
+ switch (regnum)
+ {
+ case sim_ppc_r0_regnum: return "r0";
+ case sim_ppc_r1_regnum: return "r1";
+ case sim_ppc_r2_regnum: return "r2";
+ case sim_ppc_r3_regnum: return "r3";
+ case sim_ppc_r4_regnum: return "r4";
+ case sim_ppc_r5_regnum: return "r5";
+ case sim_ppc_r6_regnum: return "r6";
+ case sim_ppc_r7_regnum: return "r7";
+ case sim_ppc_r8_regnum: return "r8";
+ case sim_ppc_r9_regnum: return "r9";
+ case sim_ppc_r10_regnum: return "r10";
+ case sim_ppc_r11_regnum: return "r11";
+ case sim_ppc_r12_regnum: return "r12";
+ case sim_ppc_r13_regnum: return "r13";
+ case sim_ppc_r14_regnum: return "r14";
+ case sim_ppc_r15_regnum: return "r15";
+ case sim_ppc_r16_regnum: return "r16";
+ case sim_ppc_r17_regnum: return "r17";
+ case sim_ppc_r18_regnum: return "r18";
+ case sim_ppc_r19_regnum: return "r19";
+ case sim_ppc_r20_regnum: return "r20";
+ case sim_ppc_r21_regnum: return "r21";
+ case sim_ppc_r22_regnum: return "r22";
+ case sim_ppc_r23_regnum: return "r23";
+ case sim_ppc_r24_regnum: return "r24";
+ case sim_ppc_r25_regnum: return "r25";
+ case sim_ppc_r26_regnum: return "r26";
+ case sim_ppc_r27_regnum: return "r27";
+ case sim_ppc_r28_regnum: return "r28";
+ case sim_ppc_r29_regnum: return "r29";
+ case sim_ppc_r30_regnum: return "r30";
+ case sim_ppc_r31_regnum: return "r31";
+
+ case sim_ppc_f0_regnum: return "f0";
+ case sim_ppc_f1_regnum: return "f1";
+ case sim_ppc_f2_regnum: return "f2";
+ case sim_ppc_f3_regnum: return "f3";
+ case sim_ppc_f4_regnum: return "f4";
+ case sim_ppc_f5_regnum: return "f5";
+ case sim_ppc_f6_regnum: return "f6";
+ case sim_ppc_f7_regnum: return "f7";
+ case sim_ppc_f8_regnum: return "f8";
+ case sim_ppc_f9_regnum: return "f9";
+ case sim_ppc_f10_regnum: return "f10";
+ case sim_ppc_f11_regnum: return "f11";
+ case sim_ppc_f12_regnum: return "f12";
+ case sim_ppc_f13_regnum: return "f13";
+ case sim_ppc_f14_regnum: return "f14";
+ case sim_ppc_f15_regnum: return "f15";
+ case sim_ppc_f16_regnum: return "f16";
+ case sim_ppc_f17_regnum: return "f17";
+ case sim_ppc_f18_regnum: return "f18";
+ case sim_ppc_f19_regnum: return "f19";
+ case sim_ppc_f20_regnum: return "f20";
+ case sim_ppc_f21_regnum: return "f21";
+ case sim_ppc_f22_regnum: return "f22";
+ case sim_ppc_f23_regnum: return "f23";
+ case sim_ppc_f24_regnum: return "f24";
+ case sim_ppc_f25_regnum: return "f25";
+ case sim_ppc_f26_regnum: return "f26";
+ case sim_ppc_f27_regnum: return "f27";
+ case sim_ppc_f28_regnum: return "f28";
+ case sim_ppc_f29_regnum: return "f29";
+ case sim_ppc_f30_regnum: return "f30";
+ case sim_ppc_f31_regnum: return "f31";
+
+ case sim_ppc_vr0_regnum: return "vr0";
+ case sim_ppc_vr1_regnum: return "vr1";
+ case sim_ppc_vr2_regnum: return "vr2";
+ case sim_ppc_vr3_regnum: return "vr3";
+ case sim_ppc_vr4_regnum: return "vr4";
+ case sim_ppc_vr5_regnum: return "vr5";
+ case sim_ppc_vr6_regnum: return "vr6";
+ case sim_ppc_vr7_regnum: return "vr7";
+ case sim_ppc_vr8_regnum: return "vr8";
+ case sim_ppc_vr9_regnum: return "vr9";
+ case sim_ppc_vr10_regnum: return "vr10";
+ case sim_ppc_vr11_regnum: return "vr11";
+ case sim_ppc_vr12_regnum: return "vr12";
+ case sim_ppc_vr13_regnum: return "vr13";
+ case sim_ppc_vr14_regnum: return "vr14";
+ case sim_ppc_vr15_regnum: return "vr15";
+ case sim_ppc_vr16_regnum: return "vr16";
+ case sim_ppc_vr17_regnum: return "vr17";
+ case sim_ppc_vr18_regnum: return "vr18";
+ case sim_ppc_vr19_regnum: return "vr19";
+ case sim_ppc_vr20_regnum: return "vr20";
+ case sim_ppc_vr21_regnum: return "vr21";
+ case sim_ppc_vr22_regnum: return "vr22";
+ case sim_ppc_vr23_regnum: return "vr23";
+ case sim_ppc_vr24_regnum: return "vr24";
+ case sim_ppc_vr25_regnum: return "vr25";
+ case sim_ppc_vr26_regnum: return "vr26";
+ case sim_ppc_vr27_regnum: return "vr27";
+ case sim_ppc_vr28_regnum: return "vr28";
+ case sim_ppc_vr29_regnum: return "vr29";
+ case sim_ppc_vr30_regnum: return "vr30";
+ case sim_ppc_vr31_regnum: return "vr31";
+ case sim_ppc_rh0_regnum: return "rh0";
+ case sim_ppc_rh1_regnum: return "rh1";
+ case sim_ppc_rh2_regnum: return "rh2";
+ case sim_ppc_rh3_regnum: return "rh3";
+ case sim_ppc_rh4_regnum: return "rh4";
+ case sim_ppc_rh5_regnum: return "rh5";
+ case sim_ppc_rh6_regnum: return "rh6";
+ case sim_ppc_rh7_regnum: return "rh7";
+ case sim_ppc_rh8_regnum: return "rh8";
+ case sim_ppc_rh9_regnum: return "rh9";
+ case sim_ppc_rh10_regnum: return "rh10";
+ case sim_ppc_rh11_regnum: return "rh11";
+ case sim_ppc_rh12_regnum: return "rh12";
+ case sim_ppc_rh13_regnum: return "rh13";
+ case sim_ppc_rh14_regnum: return "rh14";
+ case sim_ppc_rh15_regnum: return "rh15";
+ case sim_ppc_rh16_regnum: return "rh16";
+ case sim_ppc_rh17_regnum: return "rh17";
+ case sim_ppc_rh18_regnum: return "rh18";
+ case sim_ppc_rh19_regnum: return "rh19";
+ case sim_ppc_rh20_regnum: return "rh20";
+ case sim_ppc_rh21_regnum: return "rh21";
+ case sim_ppc_rh22_regnum: return "rh22";
+ case sim_ppc_rh23_regnum: return "rh23";
+ case sim_ppc_rh24_regnum: return "rh24";
+ case sim_ppc_rh25_regnum: return "rh25";
+ case sim_ppc_rh26_regnum: return "rh26";
+ case sim_ppc_rh27_regnum: return "rh27";
+ case sim_ppc_rh28_regnum: return "rh28";
+ case sim_ppc_rh29_regnum: return "rh29";
+ case sim_ppc_rh30_regnum: return "rh30";
+ case sim_ppc_rh31_regnum: return "rh31";
+
+ case sim_ppc_ev0_regnum: return "ev0";
+ case sim_ppc_ev1_regnum: return "ev1";
+ case sim_ppc_ev2_regnum: return "ev2";
+ case sim_ppc_ev3_regnum: return "ev3";
+ case sim_ppc_ev4_regnum: return "ev4";
+ case sim_ppc_ev5_regnum: return "ev5";
+ case sim_ppc_ev6_regnum: return "ev6";
+ case sim_ppc_ev7_regnum: return "ev7";
+ case sim_ppc_ev8_regnum: return "ev8";
+ case sim_ppc_ev9_regnum: return "ev9";
+ case sim_ppc_ev10_regnum: return "ev10";
+ case sim_ppc_ev11_regnum: return "ev11";
+ case sim_ppc_ev12_regnum: return "ev12";
+ case sim_ppc_ev13_regnum: return "ev13";
+ case sim_ppc_ev14_regnum: return "ev14";
+ case sim_ppc_ev15_regnum: return "ev15";
+ case sim_ppc_ev16_regnum: return "ev16";
+ case sim_ppc_ev17_regnum: return "ev17";
+ case sim_ppc_ev18_regnum: return "ev18";
+ case sim_ppc_ev19_regnum: return "ev19";
+ case sim_ppc_ev20_regnum: return "ev20";
+ case sim_ppc_ev21_regnum: return "ev21";
+ case sim_ppc_ev22_regnum: return "ev22";
+ case sim_ppc_ev23_regnum: return "ev23";
+ case sim_ppc_ev24_regnum: return "ev24";
+ case sim_ppc_ev25_regnum: return "ev25";
+ case sim_ppc_ev26_regnum: return "ev26";
+ case sim_ppc_ev27_regnum: return "ev27";
+ case sim_ppc_ev28_regnum: return "ev28";
+ case sim_ppc_ev29_regnum: return "ev29";
+ case sim_ppc_ev30_regnum: return "ev30";
+ case sim_ppc_ev31_regnum: return "ev31";
+
+ case sim_ppc_sr0_regnum: return "sr0";
+ case sim_ppc_sr1_regnum: return "sr1";
+ case sim_ppc_sr2_regnum: return "sr2";
+ case sim_ppc_sr3_regnum: return "sr3";
+ case sim_ppc_sr4_regnum: return "sr4";
+ case sim_ppc_sr5_regnum: return "sr5";
+ case sim_ppc_sr6_regnum: return "sr6";
+ case sim_ppc_sr7_regnum: return "sr7";
+ case sim_ppc_sr8_regnum: return "sr8";
+ case sim_ppc_sr9_regnum: return "sr9";
+ case sim_ppc_sr10_regnum: return "sr10";
+ case sim_ppc_sr11_regnum: return "sr11";
+ case sim_ppc_sr12_regnum: return "sr12";
+ case sim_ppc_sr13_regnum: return "sr13";
+ case sim_ppc_sr14_regnum: return "sr14";
+ case sim_ppc_sr15_regnum: return "sr15";
+
+ case sim_ppc_pc_regnum: return "pc";
+ case sim_ppc_ps_regnum: return "ps";
+ case sim_ppc_cr_regnum: return "cr";
+ case sim_ppc_fpscr_regnum: return "fpscr";
+ case sim_ppc_acc_regnum: return "acc";
+ case sim_ppc_vscr_regnum: return "vscr";
+
+ case sim_ppc_spr0_regnum: return regnum2spr (0);
+ case sim_ppc_spr1_regnum: return regnum2spr (1);
+ case sim_ppc_spr2_regnum: return regnum2spr (2);
+ case sim_ppc_spr3_regnum: return regnum2spr (3);
+ case sim_ppc_spr4_regnum: return regnum2spr (4);
+ case sim_ppc_spr5_regnum: return regnum2spr (5);
+ case sim_ppc_spr6_regnum: return regnum2spr (6);
+ case sim_ppc_spr7_regnum: return regnum2spr (7);
+ case sim_ppc_spr8_regnum: return regnum2spr (8);
+ case sim_ppc_spr9_regnum: return regnum2spr (9);
+ case sim_ppc_spr10_regnum: return regnum2spr (10);
+ case sim_ppc_spr11_regnum: return regnum2spr (11);
+ case sim_ppc_spr12_regnum: return regnum2spr (12);
+ case sim_ppc_spr13_regnum: return regnum2spr (13);
+ case sim_ppc_spr14_regnum: return regnum2spr (14);
+ case sim_ppc_spr15_regnum: return regnum2spr (15);
+ case sim_ppc_spr16_regnum: return regnum2spr (16);
+ case sim_ppc_spr17_regnum: return regnum2spr (17);
+ case sim_ppc_spr18_regnum: return regnum2spr (18);
+ case sim_ppc_spr19_regnum: return regnum2spr (19);
+ case sim_ppc_spr20_regnum: return regnum2spr (20);
+ case sim_ppc_spr21_regnum: return regnum2spr (21);
+ case sim_ppc_spr22_regnum: return regnum2spr (22);
+ case sim_ppc_spr23_regnum: return regnum2spr (23);
+ case sim_ppc_spr24_regnum: return regnum2spr (24);
+ case sim_ppc_spr25_regnum: return regnum2spr (25);
+ case sim_ppc_spr26_regnum: return regnum2spr (26);
+ case sim_ppc_spr27_regnum: return regnum2spr (27);
+ case sim_ppc_spr28_regnum: return regnum2spr (28);
+ case sim_ppc_spr29_regnum: return regnum2spr (29);
+ case sim_ppc_spr30_regnum: return regnum2spr (30);
+ case sim_ppc_spr31_regnum: return regnum2spr (31);
+ case sim_ppc_spr32_regnum: return regnum2spr (32);
+ case sim_ppc_spr33_regnum: return regnum2spr (33);
+ case sim_ppc_spr34_regnum: return regnum2spr (34);
+ case sim_ppc_spr35_regnum: return regnum2spr (35);
+ case sim_ppc_spr36_regnum: return regnum2spr (36);
+ case sim_ppc_spr37_regnum: return regnum2spr (37);
+ case sim_ppc_spr38_regnum: return regnum2spr (38);
+ case sim_ppc_spr39_regnum: return regnum2spr (39);
+ case sim_ppc_spr40_regnum: return regnum2spr (40);
+ case sim_ppc_spr41_regnum: return regnum2spr (41);
+ case sim_ppc_spr42_regnum: return regnum2spr (42);
+ case sim_ppc_spr43_regnum: return regnum2spr (43);
+ case sim_ppc_spr44_regnum: return regnum2spr (44);
+ case sim_ppc_spr45_regnum: return regnum2spr (45);
+ case sim_ppc_spr46_regnum: return regnum2spr (46);
+ case sim_ppc_spr47_regnum: return regnum2spr (47);
+ case sim_ppc_spr48_regnum: return regnum2spr (48);
+ case sim_ppc_spr49_regnum: return regnum2spr (49);
+ case sim_ppc_spr50_regnum: return regnum2spr (50);
+ case sim_ppc_spr51_regnum: return regnum2spr (51);
+ case sim_ppc_spr52_regnum: return regnum2spr (52);
+ case sim_ppc_spr53_regnum: return regnum2spr (53);
+ case sim_ppc_spr54_regnum: return regnum2spr (54);
+ case sim_ppc_spr55_regnum: return regnum2spr (55);
+ case sim_ppc_spr56_regnum: return regnum2spr (56);
+ case sim_ppc_spr57_regnum: return regnum2spr (57);
+ case sim_ppc_spr58_regnum: return regnum2spr (58);
+ case sim_ppc_spr59_regnum: return regnum2spr (59);
+ case sim_ppc_spr60_regnum: return regnum2spr (60);
+ case sim_ppc_spr61_regnum: return regnum2spr (61);
+ case sim_ppc_spr62_regnum: return regnum2spr (62);
+ case sim_ppc_spr63_regnum: return regnum2spr (63);
+ case sim_ppc_spr64_regnum: return regnum2spr (64);
+ case sim_ppc_spr65_regnum: return regnum2spr (65);
+ case sim_ppc_spr66_regnum: return regnum2spr (66);
+ case sim_ppc_spr67_regnum: return regnum2spr (67);
+ case sim_ppc_spr68_regnum: return regnum2spr (68);
+ case sim_ppc_spr69_regnum: return regnum2spr (69);
+ case sim_ppc_spr70_regnum: return regnum2spr (70);
+ case sim_ppc_spr71_regnum: return regnum2spr (71);
+ case sim_ppc_spr72_regnum: return regnum2spr (72);
+ case sim_ppc_spr73_regnum: return regnum2spr (73);
+ case sim_ppc_spr74_regnum: return regnum2spr (74);
+ case sim_ppc_spr75_regnum: return regnum2spr (75);
+ case sim_ppc_spr76_regnum: return regnum2spr (76);
+ case sim_ppc_spr77_regnum: return regnum2spr (77);
+ case sim_ppc_spr78_regnum: return regnum2spr (78);
+ case sim_ppc_spr79_regnum: return regnum2spr (79);
+ case sim_ppc_spr80_regnum: return regnum2spr (80);
+ case sim_ppc_spr81_regnum: return regnum2spr (81);
+ case sim_ppc_spr82_regnum: return regnum2spr (82);
+ case sim_ppc_spr83_regnum: return regnum2spr (83);
+ case sim_ppc_spr84_regnum: return regnum2spr (84);
+ case sim_ppc_spr85_regnum: return regnum2spr (85);
+ case sim_ppc_spr86_regnum: return regnum2spr (86);
+ case sim_ppc_spr87_regnum: return regnum2spr (87);
+ case sim_ppc_spr88_regnum: return regnum2spr (88);
+ case sim_ppc_spr89_regnum: return regnum2spr (89);
+ case sim_ppc_spr90_regnum: return regnum2spr (90);
+ case sim_ppc_spr91_regnum: return regnum2spr (91);
+ case sim_ppc_spr92_regnum: return regnum2spr (92);
+ case sim_ppc_spr93_regnum: return regnum2spr (93);
+ case sim_ppc_spr94_regnum: return regnum2spr (94);
+ case sim_ppc_spr95_regnum: return regnum2spr (95);
+ case sim_ppc_spr96_regnum: return regnum2spr (96);
+ case sim_ppc_spr97_regnum: return regnum2spr (97);
+ case sim_ppc_spr98_regnum: return regnum2spr (98);
+ case sim_ppc_spr99_regnum: return regnum2spr (99);
+ case sim_ppc_spr100_regnum: return regnum2spr (100);
+ case sim_ppc_spr101_regnum: return regnum2spr (101);
+ case sim_ppc_spr102_regnum: return regnum2spr (102);
+ case sim_ppc_spr103_regnum: return regnum2spr (103);
+ case sim_ppc_spr104_regnum: return regnum2spr (104);
+ case sim_ppc_spr105_regnum: return regnum2spr (105);
+ case sim_ppc_spr106_regnum: return regnum2spr (106);
+ case sim_ppc_spr107_regnum: return regnum2spr (107);
+ case sim_ppc_spr108_regnum: return regnum2spr (108);
+ case sim_ppc_spr109_regnum: return regnum2spr (109);
+ case sim_ppc_spr110_regnum: return regnum2spr (110);
+ case sim_ppc_spr111_regnum: return regnum2spr (111);
+ case sim_ppc_spr112_regnum: return regnum2spr (112);
+ case sim_ppc_spr113_regnum: return regnum2spr (113);
+ case sim_ppc_spr114_regnum: return regnum2spr (114);
+ case sim_ppc_spr115_regnum: return regnum2spr (115);
+ case sim_ppc_spr116_regnum: return regnum2spr (116);
+ case sim_ppc_spr117_regnum: return regnum2spr (117);
+ case sim_ppc_spr118_regnum: return regnum2spr (118);
+ case sim_ppc_spr119_regnum: return regnum2spr (119);
+ case sim_ppc_spr120_regnum: return regnum2spr (120);
+ case sim_ppc_spr121_regnum: return regnum2spr (121);
+ case sim_ppc_spr122_regnum: return regnum2spr (122);
+ case sim_ppc_spr123_regnum: return regnum2spr (123);
+ case sim_ppc_spr124_regnum: return regnum2spr (124);
+ case sim_ppc_spr125_regnum: return regnum2spr (125);
+ case sim_ppc_spr126_regnum: return regnum2spr (126);
+ case sim_ppc_spr127_regnum: return regnum2spr (127);
+ case sim_ppc_spr128_regnum: return regnum2spr (128);
+ case sim_ppc_spr129_regnum: return regnum2spr (129);
+ case sim_ppc_spr130_regnum: return regnum2spr (130);
+ case sim_ppc_spr131_regnum: return regnum2spr (131);
+ case sim_ppc_spr132_regnum: return regnum2spr (132);
+ case sim_ppc_spr133_regnum: return regnum2spr (133);
+ case sim_ppc_spr134_regnum: return regnum2spr (134);
+ case sim_ppc_spr135_regnum: return regnum2spr (135);
+ case sim_ppc_spr136_regnum: return regnum2spr (136);
+ case sim_ppc_spr137_regnum: return regnum2spr (137);
+ case sim_ppc_spr138_regnum: return regnum2spr (138);
+ case sim_ppc_spr139_regnum: return regnum2spr (139);
+ case sim_ppc_spr140_regnum: return regnum2spr (140);
+ case sim_ppc_spr141_regnum: return regnum2spr (141);
+ case sim_ppc_spr142_regnum: return regnum2spr (142);
+ case sim_ppc_spr143_regnum: return regnum2spr (143);
+ case sim_ppc_spr144_regnum: return regnum2spr (144);
+ case sim_ppc_spr145_regnum: return regnum2spr (145);
+ case sim_ppc_spr146_regnum: return regnum2spr (146);
+ case sim_ppc_spr147_regnum: return regnum2spr (147);
+ case sim_ppc_spr148_regnum: return regnum2spr (148);
+ case sim_ppc_spr149_regnum: return regnum2spr (149);
+ case sim_ppc_spr150_regnum: return regnum2spr (150);
+ case sim_ppc_spr151_regnum: return regnum2spr (151);
+ case sim_ppc_spr152_regnum: return regnum2spr (152);
+ case sim_ppc_spr153_regnum: return regnum2spr (153);
+ case sim_ppc_spr154_regnum: return regnum2spr (154);
+ case sim_ppc_spr155_regnum: return regnum2spr (155);
+ case sim_ppc_spr156_regnum: return regnum2spr (156);
+ case sim_ppc_spr157_regnum: return regnum2spr (157);
+ case sim_ppc_spr158_regnum: return regnum2spr (158);
+ case sim_ppc_spr159_regnum: return regnum2spr (159);
+ case sim_ppc_spr160_regnum: return regnum2spr (160);
+ case sim_ppc_spr161_regnum: return regnum2spr (161);
+ case sim_ppc_spr162_regnum: return regnum2spr (162);
+ case sim_ppc_spr163_regnum: return regnum2spr (163);
+ case sim_ppc_spr164_regnum: return regnum2spr (164);
+ case sim_ppc_spr165_regnum: return regnum2spr (165);
+ case sim_ppc_spr166_regnum: return regnum2spr (166);
+ case sim_ppc_spr167_regnum: return regnum2spr (167);
+ case sim_ppc_spr168_regnum: return regnum2spr (168);
+ case sim_ppc_spr169_regnum: return regnum2spr (169);
+ case sim_ppc_spr170_regnum: return regnum2spr (170);
+ case sim_ppc_spr171_regnum: return regnum2spr (171);
+ case sim_ppc_spr172_regnum: return regnum2spr (172);
+ case sim_ppc_spr173_regnum: return regnum2spr (173);
+ case sim_ppc_spr174_regnum: return regnum2spr (174);
+ case sim_ppc_spr175_regnum: return regnum2spr (175);
+ case sim_ppc_spr176_regnum: return regnum2spr (176);
+ case sim_ppc_spr177_regnum: return regnum2spr (177);
+ case sim_ppc_spr178_regnum: return regnum2spr (178);
+ case sim_ppc_spr179_regnum: return regnum2spr (179);
+ case sim_ppc_spr180_regnum: return regnum2spr (180);
+ case sim_ppc_spr181_regnum: return regnum2spr (181);
+ case sim_ppc_spr182_regnum: return regnum2spr (182);
+ case sim_ppc_spr183_regnum: return regnum2spr (183);
+ case sim_ppc_spr184_regnum: return regnum2spr (184);
+ case sim_ppc_spr185_regnum: return regnum2spr (185);
+ case sim_ppc_spr186_regnum: return regnum2spr (186);
+ case sim_ppc_spr187_regnum: return regnum2spr (187);
+ case sim_ppc_spr188_regnum: return regnum2spr (188);
+ case sim_ppc_spr189_regnum: return regnum2spr (189);
+ case sim_ppc_spr190_regnum: return regnum2spr (190);
+ case sim_ppc_spr191_regnum: return regnum2spr (191);
+ case sim_ppc_spr192_regnum: return regnum2spr (192);
+ case sim_ppc_spr193_regnum: return regnum2spr (193);
+ case sim_ppc_spr194_regnum: return regnum2spr (194);
+ case sim_ppc_spr195_regnum: return regnum2spr (195);
+ case sim_ppc_spr196_regnum: return regnum2spr (196);
+ case sim_ppc_spr197_regnum: return regnum2spr (197);
+ case sim_ppc_spr198_regnum: return regnum2spr (198);
+ case sim_ppc_spr199_regnum: return regnum2spr (199);
+ case sim_ppc_spr200_regnum: return regnum2spr (200);
+ case sim_ppc_spr201_regnum: return regnum2spr (201);
+ case sim_ppc_spr202_regnum: return regnum2spr (202);
+ case sim_ppc_spr203_regnum: return regnum2spr (203);
+ case sim_ppc_spr204_regnum: return regnum2spr (204);
+ case sim_ppc_spr205_regnum: return regnum2spr (205);
+ case sim_ppc_spr206_regnum: return regnum2spr (206);
+ case sim_ppc_spr207_regnum: return regnum2spr (207);
+ case sim_ppc_spr208_regnum: return regnum2spr (208);
+ case sim_ppc_spr209_regnum: return regnum2spr (209);
+ case sim_ppc_spr210_regnum: return regnum2spr (210);
+ case sim_ppc_spr211_regnum: return regnum2spr (211);
+ case sim_ppc_spr212_regnum: return regnum2spr (212);
+ case sim_ppc_spr213_regnum: return regnum2spr (213);
+ case sim_ppc_spr214_regnum: return regnum2spr (214);
+ case sim_ppc_spr215_regnum: return regnum2spr (215);
+ case sim_ppc_spr216_regnum: return regnum2spr (216);
+ case sim_ppc_spr217_regnum: return regnum2spr (217);
+ case sim_ppc_spr218_regnum: return regnum2spr (218);
+ case sim_ppc_spr219_regnum: return regnum2spr (219);
+ case sim_ppc_spr220_regnum: return regnum2spr (220);
+ case sim_ppc_spr221_regnum: return regnum2spr (221);
+ case sim_ppc_spr222_regnum: return regnum2spr (222);
+ case sim_ppc_spr223_regnum: return regnum2spr (223);
+ case sim_ppc_spr224_regnum: return regnum2spr (224);
+ case sim_ppc_spr225_regnum: return regnum2spr (225);
+ case sim_ppc_spr226_regnum: return regnum2spr (226);
+ case sim_ppc_spr227_regnum: return regnum2spr (227);
+ case sim_ppc_spr228_regnum: return regnum2spr (228);
+ case sim_ppc_spr229_regnum: return regnum2spr (229);
+ case sim_ppc_spr230_regnum: return regnum2spr (230);
+ case sim_ppc_spr231_regnum: return regnum2spr (231);
+ case sim_ppc_spr232_regnum: return regnum2spr (232);
+ case sim_ppc_spr233_regnum: return regnum2spr (233);
+ case sim_ppc_spr234_regnum: return regnum2spr (234);
+ case sim_ppc_spr235_regnum: return regnum2spr (235);
+ case sim_ppc_spr236_regnum: return regnum2spr (236);
+ case sim_ppc_spr237_regnum: return regnum2spr (237);
+ case sim_ppc_spr238_regnum: return regnum2spr (238);
+ case sim_ppc_spr239_regnum: return regnum2spr (239);
+ case sim_ppc_spr240_regnum: return regnum2spr (240);
+ case sim_ppc_spr241_regnum: return regnum2spr (241);
+ case sim_ppc_spr242_regnum: return regnum2spr (242);
+ case sim_ppc_spr243_regnum: return regnum2spr (243);
+ case sim_ppc_spr244_regnum: return regnum2spr (244);
+ case sim_ppc_spr245_regnum: return regnum2spr (245);
+ case sim_ppc_spr246_regnum: return regnum2spr (246);
+ case sim_ppc_spr247_regnum: return regnum2spr (247);
+ case sim_ppc_spr248_regnum: return regnum2spr (248);
+ case sim_ppc_spr249_regnum: return regnum2spr (249);
+ case sim_ppc_spr250_regnum: return regnum2spr (250);
+ case sim_ppc_spr251_regnum: return regnum2spr (251);
+ case sim_ppc_spr252_regnum: return regnum2spr (252);
+ case sim_ppc_spr253_regnum: return regnum2spr (253);
+ case sim_ppc_spr254_regnum: return regnum2spr (254);
+ case sim_ppc_spr255_regnum: return regnum2spr (255);
+ case sim_ppc_spr256_regnum: return regnum2spr (256);
+ case sim_ppc_spr257_regnum: return regnum2spr (257);
+ case sim_ppc_spr258_regnum: return regnum2spr (258);
+ case sim_ppc_spr259_regnum: return regnum2spr (259);
+ case sim_ppc_spr260_regnum: return regnum2spr (260);
+ case sim_ppc_spr261_regnum: return regnum2spr (261);
+ case sim_ppc_spr262_regnum: return regnum2spr (262);
+ case sim_ppc_spr263_regnum: return regnum2spr (263);
+ case sim_ppc_spr264_regnum: return regnum2spr (264);
+ case sim_ppc_spr265_regnum: return regnum2spr (265);
+ case sim_ppc_spr266_regnum: return regnum2spr (266);
+ case sim_ppc_spr267_regnum: return regnum2spr (267);
+ case sim_ppc_spr268_regnum: return regnum2spr (268);
+ case sim_ppc_spr269_regnum: return regnum2spr (269);
+ case sim_ppc_spr270_regnum: return regnum2spr (270);
+ case sim_ppc_spr271_regnum: return regnum2spr (271);
+ case sim_ppc_spr272_regnum: return regnum2spr (272);
+ case sim_ppc_spr273_regnum: return regnum2spr (273);
+ case sim_ppc_spr274_regnum: return regnum2spr (274);
+ case sim_ppc_spr275_regnum: return regnum2spr (275);
+ case sim_ppc_spr276_regnum: return regnum2spr (276);
+ case sim_ppc_spr277_regnum: return regnum2spr (277);
+ case sim_ppc_spr278_regnum: return regnum2spr (278);
+ case sim_ppc_spr279_regnum: return regnum2spr (279);
+ case sim_ppc_spr280_regnum: return regnum2spr (280);
+ case sim_ppc_spr281_regnum: return regnum2spr (281);
+ case sim_ppc_spr282_regnum: return regnum2spr (282);
+ case sim_ppc_spr283_regnum: return regnum2spr (283);
+ case sim_ppc_spr284_regnum: return regnum2spr (284);
+ case sim_ppc_spr285_regnum: return regnum2spr (285);
+ case sim_ppc_spr286_regnum: return regnum2spr (286);
+ case sim_ppc_spr287_regnum: return regnum2spr (287);
+ case sim_ppc_spr288_regnum: return regnum2spr (288);
+ case sim_ppc_spr289_regnum: return regnum2spr (289);
+ case sim_ppc_spr290_regnum: return regnum2spr (290);
+ case sim_ppc_spr291_regnum: return regnum2spr (291);
+ case sim_ppc_spr292_regnum: return regnum2spr (292);
+ case sim_ppc_spr293_regnum: return regnum2spr (293);
+ case sim_ppc_spr294_regnum: return regnum2spr (294);
+ case sim_ppc_spr295_regnum: return regnum2spr (295);
+ case sim_ppc_spr296_regnum: return regnum2spr (296);
+ case sim_ppc_spr297_regnum: return regnum2spr (297);
+ case sim_ppc_spr298_regnum: return regnum2spr (298);
+ case sim_ppc_spr299_regnum: return regnum2spr (299);
+ case sim_ppc_spr300_regnum: return regnum2spr (300);
+ case sim_ppc_spr301_regnum: return regnum2spr (301);
+ case sim_ppc_spr302_regnum: return regnum2spr (302);
+ case sim_ppc_spr303_regnum: return regnum2spr (303);
+ case sim_ppc_spr304_regnum: return regnum2spr (304);
+ case sim_ppc_spr305_regnum: return regnum2spr (305);
+ case sim_ppc_spr306_regnum: return regnum2spr (306);
+ case sim_ppc_spr307_regnum: return regnum2spr (307);
+ case sim_ppc_spr308_regnum: return regnum2spr (308);
+ case sim_ppc_spr309_regnum: return regnum2spr (309);
+ case sim_ppc_spr310_regnum: return regnum2spr (310);
+ case sim_ppc_spr311_regnum: return regnum2spr (311);
+ case sim_ppc_spr312_regnum: return regnum2spr (312);
+ case sim_ppc_spr313_regnum: return regnum2spr (313);
+ case sim_ppc_spr314_regnum: return regnum2spr (314);
+ case sim_ppc_spr315_regnum: return regnum2spr (315);
+ case sim_ppc_spr316_regnum: return regnum2spr (316);
+ case sim_ppc_spr317_regnum: return regnum2spr (317);
+ case sim_ppc_spr318_regnum: return regnum2spr (318);
+ case sim_ppc_spr319_regnum: return regnum2spr (319);
+ case sim_ppc_spr320_regnum: return regnum2spr (320);
+ case sim_ppc_spr321_regnum: return regnum2spr (321);
+ case sim_ppc_spr322_regnum: return regnum2spr (322);
+ case sim_ppc_spr323_regnum: return regnum2spr (323);
+ case sim_ppc_spr324_regnum: return regnum2spr (324);
+ case sim_ppc_spr325_regnum: return regnum2spr (325);
+ case sim_ppc_spr326_regnum: return regnum2spr (326);
+ case sim_ppc_spr327_regnum: return regnum2spr (327);
+ case sim_ppc_spr328_regnum: return regnum2spr (328);
+ case sim_ppc_spr329_regnum: return regnum2spr (329);
+ case sim_ppc_spr330_regnum: return regnum2spr (330);
+ case sim_ppc_spr331_regnum: return regnum2spr (331);
+ case sim_ppc_spr332_regnum: return regnum2spr (332);
+ case sim_ppc_spr333_regnum: return regnum2spr (333);
+ case sim_ppc_spr334_regnum: return regnum2spr (334);
+ case sim_ppc_spr335_regnum: return regnum2spr (335);
+ case sim_ppc_spr336_regnum: return regnum2spr (336);
+ case sim_ppc_spr337_regnum: return regnum2spr (337);
+ case sim_ppc_spr338_regnum: return regnum2spr (338);
+ case sim_ppc_spr339_regnum: return regnum2spr (339);
+ case sim_ppc_spr340_regnum: return regnum2spr (340);
+ case sim_ppc_spr341_regnum: return regnum2spr (341);
+ case sim_ppc_spr342_regnum: return regnum2spr (342);
+ case sim_ppc_spr343_regnum: return regnum2spr (343);
+ case sim_ppc_spr344_regnum: return regnum2spr (344);
+ case sim_ppc_spr345_regnum: return regnum2spr (345);
+ case sim_ppc_spr346_regnum: return regnum2spr (346);
+ case sim_ppc_spr347_regnum: return regnum2spr (347);
+ case sim_ppc_spr348_regnum: return regnum2spr (348);
+ case sim_ppc_spr349_regnum: return regnum2spr (349);
+ case sim_ppc_spr350_regnum: return regnum2spr (350);
+ case sim_ppc_spr351_regnum: return regnum2spr (351);
+ case sim_ppc_spr352_regnum: return regnum2spr (352);
+ case sim_ppc_spr353_regnum: return regnum2spr (353);
+ case sim_ppc_spr354_regnum: return regnum2spr (354);
+ case sim_ppc_spr355_regnum: return regnum2spr (355);
+ case sim_ppc_spr356_regnum: return regnum2spr (356);
+ case sim_ppc_spr357_regnum: return regnum2spr (357);
+ case sim_ppc_spr358_regnum: return regnum2spr (358);
+ case sim_ppc_spr359_regnum: return regnum2spr (359);
+ case sim_ppc_spr360_regnum: return regnum2spr (360);
+ case sim_ppc_spr361_regnum: return regnum2spr (361);
+ case sim_ppc_spr362_regnum: return regnum2spr (362);
+ case sim_ppc_spr363_regnum: return regnum2spr (363);
+ case sim_ppc_spr364_regnum: return regnum2spr (364);
+ case sim_ppc_spr365_regnum: return regnum2spr (365);
+ case sim_ppc_spr366_regnum: return regnum2spr (366);
+ case sim_ppc_spr367_regnum: return regnum2spr (367);
+ case sim_ppc_spr368_regnum: return regnum2spr (368);
+ case sim_ppc_spr369_regnum: return regnum2spr (369);
+ case sim_ppc_spr370_regnum: return regnum2spr (370);
+ case sim_ppc_spr371_regnum: return regnum2spr (371);
+ case sim_ppc_spr372_regnum: return regnum2spr (372);
+ case sim_ppc_spr373_regnum: return regnum2spr (373);
+ case sim_ppc_spr374_regnum: return regnum2spr (374);
+ case sim_ppc_spr375_regnum: return regnum2spr (375);
+ case sim_ppc_spr376_regnum: return regnum2spr (376);
+ case sim_ppc_spr377_regnum: return regnum2spr (377);
+ case sim_ppc_spr378_regnum: return regnum2spr (378);
+ case sim_ppc_spr379_regnum: return regnum2spr (379);
+ case sim_ppc_spr380_regnum: return regnum2spr (380);
+ case sim_ppc_spr381_regnum: return regnum2spr (381);
+ case sim_ppc_spr382_regnum: return regnum2spr (382);
+ case sim_ppc_spr383_regnum: return regnum2spr (383);
+ case sim_ppc_spr384_regnum: return regnum2spr (384);
+ case sim_ppc_spr385_regnum: return regnum2spr (385);
+ case sim_ppc_spr386_regnum: return regnum2spr (386);
+ case sim_ppc_spr387_regnum: return regnum2spr (387);
+ case sim_ppc_spr388_regnum: return regnum2spr (388);
+ case sim_ppc_spr389_regnum: return regnum2spr (389);
+ case sim_ppc_spr390_regnum: return regnum2spr (390);
+ case sim_ppc_spr391_regnum: return regnum2spr (391);
+ case sim_ppc_spr392_regnum: return regnum2spr (392);
+ case sim_ppc_spr393_regnum: return regnum2spr (393);
+ case sim_ppc_spr394_regnum: return regnum2spr (394);
+ case sim_ppc_spr395_regnum: return regnum2spr (395);
+ case sim_ppc_spr396_regnum: return regnum2spr (396);
+ case sim_ppc_spr397_regnum: return regnum2spr (397);
+ case sim_ppc_spr398_regnum: return regnum2spr (398);
+ case sim_ppc_spr399_regnum: return regnum2spr (399);
+ case sim_ppc_spr400_regnum: return regnum2spr (400);
+ case sim_ppc_spr401_regnum: return regnum2spr (401);
+ case sim_ppc_spr402_regnum: return regnum2spr (402);
+ case sim_ppc_spr403_regnum: return regnum2spr (403);
+ case sim_ppc_spr404_regnum: return regnum2spr (404);
+ case sim_ppc_spr405_regnum: return regnum2spr (405);
+ case sim_ppc_spr406_regnum: return regnum2spr (406);
+ case sim_ppc_spr407_regnum: return regnum2spr (407);
+ case sim_ppc_spr408_regnum: return regnum2spr (408);
+ case sim_ppc_spr409_regnum: return regnum2spr (409);
+ case sim_ppc_spr410_regnum: return regnum2spr (410);
+ case sim_ppc_spr411_regnum: return regnum2spr (411);
+ case sim_ppc_spr412_regnum: return regnum2spr (412);
+ case sim_ppc_spr413_regnum: return regnum2spr (413);
+ case sim_ppc_spr414_regnum: return regnum2spr (414);
+ case sim_ppc_spr415_regnum: return regnum2spr (415);
+ case sim_ppc_spr416_regnum: return regnum2spr (416);
+ case sim_ppc_spr417_regnum: return regnum2spr (417);
+ case sim_ppc_spr418_regnum: return regnum2spr (418);
+ case sim_ppc_spr419_regnum: return regnum2spr (419);
+ case sim_ppc_spr420_regnum: return regnum2spr (420);
+ case sim_ppc_spr421_regnum: return regnum2spr (421);
+ case sim_ppc_spr422_regnum: return regnum2spr (422);
+ case sim_ppc_spr423_regnum: return regnum2spr (423);
+ case sim_ppc_spr424_regnum: return regnum2spr (424);
+ case sim_ppc_spr425_regnum: return regnum2spr (425);
+ case sim_ppc_spr426_regnum: return regnum2spr (426);
+ case sim_ppc_spr427_regnum: return regnum2spr (427);
+ case sim_ppc_spr428_regnum: return regnum2spr (428);
+ case sim_ppc_spr429_regnum: return regnum2spr (429);
+ case sim_ppc_spr430_regnum: return regnum2spr (430);
+ case sim_ppc_spr431_regnum: return regnum2spr (431);
+ case sim_ppc_spr432_regnum: return regnum2spr (432);
+ case sim_ppc_spr433_regnum: return regnum2spr (433);
+ case sim_ppc_spr434_regnum: return regnum2spr (434);
+ case sim_ppc_spr435_regnum: return regnum2spr (435);
+ case sim_ppc_spr436_regnum: return regnum2spr (436);
+ case sim_ppc_spr437_regnum: return regnum2spr (437);
+ case sim_ppc_spr438_regnum: return regnum2spr (438);
+ case sim_ppc_spr439_regnum: return regnum2spr (439);
+ case sim_ppc_spr440_regnum: return regnum2spr (440);
+ case sim_ppc_spr441_regnum: return regnum2spr (441);
+ case sim_ppc_spr442_regnum: return regnum2spr (442);
+ case sim_ppc_spr443_regnum: return regnum2spr (443);
+ case sim_ppc_spr444_regnum: return regnum2spr (444);
+ case sim_ppc_spr445_regnum: return regnum2spr (445);
+ case sim_ppc_spr446_regnum: return regnum2spr (446);
+ case sim_ppc_spr447_regnum: return regnum2spr (447);
+ case sim_ppc_spr448_regnum: return regnum2spr (448);
+ case sim_ppc_spr449_regnum: return regnum2spr (449);
+ case sim_ppc_spr450_regnum: return regnum2spr (450);
+ case sim_ppc_spr451_regnum: return regnum2spr (451);
+ case sim_ppc_spr452_regnum: return regnum2spr (452);
+ case sim_ppc_spr453_regnum: return regnum2spr (453);
+ case sim_ppc_spr454_regnum: return regnum2spr (454);
+ case sim_ppc_spr455_regnum: return regnum2spr (455);
+ case sim_ppc_spr456_regnum: return regnum2spr (456);
+ case sim_ppc_spr457_regnum: return regnum2spr (457);
+ case sim_ppc_spr458_regnum: return regnum2spr (458);
+ case sim_ppc_spr459_regnum: return regnum2spr (459);
+ case sim_ppc_spr460_regnum: return regnum2spr (460);
+ case sim_ppc_spr461_regnum: return regnum2spr (461);
+ case sim_ppc_spr462_regnum: return regnum2spr (462);
+ case sim_ppc_spr463_regnum: return regnum2spr (463);
+ case sim_ppc_spr464_regnum: return regnum2spr (464);
+ case sim_ppc_spr465_regnum: return regnum2spr (465);
+ case sim_ppc_spr466_regnum: return regnum2spr (466);
+ case sim_ppc_spr467_regnum: return regnum2spr (467);
+ case sim_ppc_spr468_regnum: return regnum2spr (468);
+ case sim_ppc_spr469_regnum: return regnum2spr (469);
+ case sim_ppc_spr470_regnum: return regnum2spr (470);
+ case sim_ppc_spr471_regnum: return regnum2spr (471);
+ case sim_ppc_spr472_regnum: return regnum2spr (472);
+ case sim_ppc_spr473_regnum: return regnum2spr (473);
+ case sim_ppc_spr474_regnum: return regnum2spr (474);
+ case sim_ppc_spr475_regnum: return regnum2spr (475);
+ case sim_ppc_spr476_regnum: return regnum2spr (476);
+ case sim_ppc_spr477_regnum: return regnum2spr (477);
+ case sim_ppc_spr478_regnum: return regnum2spr (478);
+ case sim_ppc_spr479_regnum: return regnum2spr (479);
+ case sim_ppc_spr480_regnum: return regnum2spr (480);
+ case sim_ppc_spr481_regnum: return regnum2spr (481);
+ case sim_ppc_spr482_regnum: return regnum2spr (482);
+ case sim_ppc_spr483_regnum: return regnum2spr (483);
+ case sim_ppc_spr484_regnum: return regnum2spr (484);
+ case sim_ppc_spr485_regnum: return regnum2spr (485);
+ case sim_ppc_spr486_regnum: return regnum2spr (486);
+ case sim_ppc_spr487_regnum: return regnum2spr (487);
+ case sim_ppc_spr488_regnum: return regnum2spr (488);
+ case sim_ppc_spr489_regnum: return regnum2spr (489);
+ case sim_ppc_spr490_regnum: return regnum2spr (490);
+ case sim_ppc_spr491_regnum: return regnum2spr (491);
+ case sim_ppc_spr492_regnum: return regnum2spr (492);
+ case sim_ppc_spr493_regnum: return regnum2spr (493);
+ case sim_ppc_spr494_regnum: return regnum2spr (494);
+ case sim_ppc_spr495_regnum: return regnum2spr (495);
+ case sim_ppc_spr496_regnum: return regnum2spr (496);
+ case sim_ppc_spr497_regnum: return regnum2spr (497);
+ case sim_ppc_spr498_regnum: return regnum2spr (498);
+ case sim_ppc_spr499_regnum: return regnum2spr (499);
+ case sim_ppc_spr500_regnum: return regnum2spr (500);
+ case sim_ppc_spr501_regnum: return regnum2spr (501);
+ case sim_ppc_spr502_regnum: return regnum2spr (502);
+ case sim_ppc_spr503_regnum: return regnum2spr (503);
+ case sim_ppc_spr504_regnum: return regnum2spr (504);
+ case sim_ppc_spr505_regnum: return regnum2spr (505);
+ case sim_ppc_spr506_regnum: return regnum2spr (506);
+ case sim_ppc_spr507_regnum: return regnum2spr (507);
+ case sim_ppc_spr508_regnum: return regnum2spr (508);
+ case sim_ppc_spr509_regnum: return regnum2spr (509);
+ case sim_ppc_spr510_regnum: return regnum2spr (510);
+ case sim_ppc_spr511_regnum: return regnum2spr (511);
+ case sim_ppc_spr512_regnum: return regnum2spr (512);
+ case sim_ppc_spr513_regnum: return regnum2spr (513);
+ case sim_ppc_spr514_regnum: return regnum2spr (514);
+ case sim_ppc_spr515_regnum: return regnum2spr (515);
+ case sim_ppc_spr516_regnum: return regnum2spr (516);
+ case sim_ppc_spr517_regnum: return regnum2spr (517);
+ case sim_ppc_spr518_regnum: return regnum2spr (518);
+ case sim_ppc_spr519_regnum: return regnum2spr (519);
+ case sim_ppc_spr520_regnum: return regnum2spr (520);
+ case sim_ppc_spr521_regnum: return regnum2spr (521);
+ case sim_ppc_spr522_regnum: return regnum2spr (522);
+ case sim_ppc_spr523_regnum: return regnum2spr (523);
+ case sim_ppc_spr524_regnum: return regnum2spr (524);
+ case sim_ppc_spr525_regnum: return regnum2spr (525);
+ case sim_ppc_spr526_regnum: return regnum2spr (526);
+ case sim_ppc_spr527_regnum: return regnum2spr (527);
+ case sim_ppc_spr528_regnum: return regnum2spr (528);
+ case sim_ppc_spr529_regnum: return regnum2spr (529);
+ case sim_ppc_spr530_regnum: return regnum2spr (530);
+ case sim_ppc_spr531_regnum: return regnum2spr (531);
+ case sim_ppc_spr532_regnum: return regnum2spr (532);
+ case sim_ppc_spr533_regnum: return regnum2spr (533);
+ case sim_ppc_spr534_regnum: return regnum2spr (534);
+ case sim_ppc_spr535_regnum: return regnum2spr (535);
+ case sim_ppc_spr536_regnum: return regnum2spr (536);
+ case sim_ppc_spr537_regnum: return regnum2spr (537);
+ case sim_ppc_spr538_regnum: return regnum2spr (538);
+ case sim_ppc_spr539_regnum: return regnum2spr (539);
+ case sim_ppc_spr540_regnum: return regnum2spr (540);
+ case sim_ppc_spr541_regnum: return regnum2spr (541);
+ case sim_ppc_spr542_regnum: return regnum2spr (542);
+ case sim_ppc_spr543_regnum: return regnum2spr (543);
+ case sim_ppc_spr544_regnum: return regnum2spr (544);
+ case sim_ppc_spr545_regnum: return regnum2spr (545);
+ case sim_ppc_spr546_regnum: return regnum2spr (546);
+ case sim_ppc_spr547_regnum: return regnum2spr (547);
+ case sim_ppc_spr548_regnum: return regnum2spr (548);
+ case sim_ppc_spr549_regnum: return regnum2spr (549);
+ case sim_ppc_spr550_regnum: return regnum2spr (550);
+ case sim_ppc_spr551_regnum: return regnum2spr (551);
+ case sim_ppc_spr552_regnum: return regnum2spr (552);
+ case sim_ppc_spr553_regnum: return regnum2spr (553);
+ case sim_ppc_spr554_regnum: return regnum2spr (554);
+ case sim_ppc_spr555_regnum: return regnum2spr (555);
+ case sim_ppc_spr556_regnum: return regnum2spr (556);
+ case sim_ppc_spr557_regnum: return regnum2spr (557);
+ case sim_ppc_spr558_regnum: return regnum2spr (558);
+ case sim_ppc_spr559_regnum: return regnum2spr (559);
+ case sim_ppc_spr560_regnum: return regnum2spr (560);
+ case sim_ppc_spr561_regnum: return regnum2spr (561);
+ case sim_ppc_spr562_regnum: return regnum2spr (562);
+ case sim_ppc_spr563_regnum: return regnum2spr (563);
+ case sim_ppc_spr564_regnum: return regnum2spr (564);
+ case sim_ppc_spr565_regnum: return regnum2spr (565);
+ case sim_ppc_spr566_regnum: return regnum2spr (566);
+ case sim_ppc_spr567_regnum: return regnum2spr (567);
+ case sim_ppc_spr568_regnum: return regnum2spr (568);
+ case sim_ppc_spr569_regnum: return regnum2spr (569);
+ case sim_ppc_spr570_regnum: return regnum2spr (570);
+ case sim_ppc_spr571_regnum: return regnum2spr (571);
+ case sim_ppc_spr572_regnum: return regnum2spr (572);
+ case sim_ppc_spr573_regnum: return regnum2spr (573);
+ case sim_ppc_spr574_regnum: return regnum2spr (574);
+ case sim_ppc_spr575_regnum: return regnum2spr (575);
+ case sim_ppc_spr576_regnum: return regnum2spr (576);
+ case sim_ppc_spr577_regnum: return regnum2spr (577);
+ case sim_ppc_spr578_regnum: return regnum2spr (578);
+ case sim_ppc_spr579_regnum: return regnum2spr (579);
+ case sim_ppc_spr580_regnum: return regnum2spr (580);
+ case sim_ppc_spr581_regnum: return regnum2spr (581);
+ case sim_ppc_spr582_regnum: return regnum2spr (582);
+ case sim_ppc_spr583_regnum: return regnum2spr (583);
+ case sim_ppc_spr584_regnum: return regnum2spr (584);
+ case sim_ppc_spr585_regnum: return regnum2spr (585);
+ case sim_ppc_spr586_regnum: return regnum2spr (586);
+ case sim_ppc_spr587_regnum: return regnum2spr (587);
+ case sim_ppc_spr588_regnum: return regnum2spr (588);
+ case sim_ppc_spr589_regnum: return regnum2spr (589);
+ case sim_ppc_spr590_regnum: return regnum2spr (590);
+ case sim_ppc_spr591_regnum: return regnum2spr (591);
+ case sim_ppc_spr592_regnum: return regnum2spr (592);
+ case sim_ppc_spr593_regnum: return regnum2spr (593);
+ case sim_ppc_spr594_regnum: return regnum2spr (594);
+ case sim_ppc_spr595_regnum: return regnum2spr (595);
+ case sim_ppc_spr596_regnum: return regnum2spr (596);
+ case sim_ppc_spr597_regnum: return regnum2spr (597);
+ case sim_ppc_spr598_regnum: return regnum2spr (598);
+ case sim_ppc_spr599_regnum: return regnum2spr (599);
+ case sim_ppc_spr600_regnum: return regnum2spr (600);
+ case sim_ppc_spr601_regnum: return regnum2spr (601);
+ case sim_ppc_spr602_regnum: return regnum2spr (602);
+ case sim_ppc_spr603_regnum: return regnum2spr (603);
+ case sim_ppc_spr604_regnum: return regnum2spr (604);
+ case sim_ppc_spr605_regnum: return regnum2spr (605);
+ case sim_ppc_spr606_regnum: return regnum2spr (606);
+ case sim_ppc_spr607_regnum: return regnum2spr (607);
+ case sim_ppc_spr608_regnum: return regnum2spr (608);
+ case sim_ppc_spr609_regnum: return regnum2spr (609);
+ case sim_ppc_spr610_regnum: return regnum2spr (610);
+ case sim_ppc_spr611_regnum: return regnum2spr (611);
+ case sim_ppc_spr612_regnum: return regnum2spr (612);
+ case sim_ppc_spr613_regnum: return regnum2spr (613);
+ case sim_ppc_spr614_regnum: return regnum2spr (614);
+ case sim_ppc_spr615_regnum: return regnum2spr (615);
+ case sim_ppc_spr616_regnum: return regnum2spr (616);
+ case sim_ppc_spr617_regnum: return regnum2spr (617);
+ case sim_ppc_spr618_regnum: return regnum2spr (618);
+ case sim_ppc_spr619_regnum: return regnum2spr (619);
+ case sim_ppc_spr620_regnum: return regnum2spr (620);
+ case sim_ppc_spr621_regnum: return regnum2spr (621);
+ case sim_ppc_spr622_regnum: return regnum2spr (622);
+ case sim_ppc_spr623_regnum: return regnum2spr (623);
+ case sim_ppc_spr624_regnum: return regnum2spr (624);
+ case sim_ppc_spr625_regnum: return regnum2spr (625);
+ case sim_ppc_spr626_regnum: return regnum2spr (626);
+ case sim_ppc_spr627_regnum: return regnum2spr (627);
+ case sim_ppc_spr628_regnum: return regnum2spr (628);
+ case sim_ppc_spr629_regnum: return regnum2spr (629);
+ case sim_ppc_spr630_regnum: return regnum2spr (630);
+ case sim_ppc_spr631_regnum: return regnum2spr (631);
+ case sim_ppc_spr632_regnum: return regnum2spr (632);
+ case sim_ppc_spr633_regnum: return regnum2spr (633);
+ case sim_ppc_spr634_regnum: return regnum2spr (634);
+ case sim_ppc_spr635_regnum: return regnum2spr (635);
+ case sim_ppc_spr636_regnum: return regnum2spr (636);
+ case sim_ppc_spr637_regnum: return regnum2spr (637);
+ case sim_ppc_spr638_regnum: return regnum2spr (638);
+ case sim_ppc_spr639_regnum: return regnum2spr (639);
+ case sim_ppc_spr640_regnum: return regnum2spr (640);
+ case sim_ppc_spr641_regnum: return regnum2spr (641);
+ case sim_ppc_spr642_regnum: return regnum2spr (642);
+ case sim_ppc_spr643_regnum: return regnum2spr (643);
+ case sim_ppc_spr644_regnum: return regnum2spr (644);
+ case sim_ppc_spr645_regnum: return regnum2spr (645);
+ case sim_ppc_spr646_regnum: return regnum2spr (646);
+ case sim_ppc_spr647_regnum: return regnum2spr (647);
+ case sim_ppc_spr648_regnum: return regnum2spr (648);
+ case sim_ppc_spr649_regnum: return regnum2spr (649);
+ case sim_ppc_spr650_regnum: return regnum2spr (650);
+ case sim_ppc_spr651_regnum: return regnum2spr (651);
+ case sim_ppc_spr652_regnum: return regnum2spr (652);
+ case sim_ppc_spr653_regnum: return regnum2spr (653);
+ case sim_ppc_spr654_regnum: return regnum2spr (654);
+ case sim_ppc_spr655_regnum: return regnum2spr (655);
+ case sim_ppc_spr656_regnum: return regnum2spr (656);
+ case sim_ppc_spr657_regnum: return regnum2spr (657);
+ case sim_ppc_spr658_regnum: return regnum2spr (658);
+ case sim_ppc_spr659_regnum: return regnum2spr (659);
+ case sim_ppc_spr660_regnum: return regnum2spr (660);
+ case sim_ppc_spr661_regnum: return regnum2spr (661);
+ case sim_ppc_spr662_regnum: return regnum2spr (662);
+ case sim_ppc_spr663_regnum: return regnum2spr (663);
+ case sim_ppc_spr664_regnum: return regnum2spr (664);
+ case sim_ppc_spr665_regnum: return regnum2spr (665);
+ case sim_ppc_spr666_regnum: return regnum2spr (666);
+ case sim_ppc_spr667_regnum: return regnum2spr (667);
+ case sim_ppc_spr668_regnum: return regnum2spr (668);
+ case sim_ppc_spr669_regnum: return regnum2spr (669);
+ case sim_ppc_spr670_regnum: return regnum2spr (670);
+ case sim_ppc_spr671_regnum: return regnum2spr (671);
+ case sim_ppc_spr672_regnum: return regnum2spr (672);
+ case sim_ppc_spr673_regnum: return regnum2spr (673);
+ case sim_ppc_spr674_regnum: return regnum2spr (674);
+ case sim_ppc_spr675_regnum: return regnum2spr (675);
+ case sim_ppc_spr676_regnum: return regnum2spr (676);
+ case sim_ppc_spr677_regnum: return regnum2spr (677);
+ case sim_ppc_spr678_regnum: return regnum2spr (678);
+ case sim_ppc_spr679_regnum: return regnum2spr (679);
+ case sim_ppc_spr680_regnum: return regnum2spr (680);
+ case sim_ppc_spr681_regnum: return regnum2spr (681);
+ case sim_ppc_spr682_regnum: return regnum2spr (682);
+ case sim_ppc_spr683_regnum: return regnum2spr (683);
+ case sim_ppc_spr684_regnum: return regnum2spr (684);
+ case sim_ppc_spr685_regnum: return regnum2spr (685);
+ case sim_ppc_spr686_regnum: return regnum2spr (686);
+ case sim_ppc_spr687_regnum: return regnum2spr (687);
+ case sim_ppc_spr688_regnum: return regnum2spr (688);
+ case sim_ppc_spr689_regnum: return regnum2spr (689);
+ case sim_ppc_spr690_regnum: return regnum2spr (690);
+ case sim_ppc_spr691_regnum: return regnum2spr (691);
+ case sim_ppc_spr692_regnum: return regnum2spr (692);
+ case sim_ppc_spr693_regnum: return regnum2spr (693);
+ case sim_ppc_spr694_regnum: return regnum2spr (694);
+ case sim_ppc_spr695_regnum: return regnum2spr (695);
+ case sim_ppc_spr696_regnum: return regnum2spr (696);
+ case sim_ppc_spr697_regnum: return regnum2spr (697);
+ case sim_ppc_spr698_regnum: return regnum2spr (698);
+ case sim_ppc_spr699_regnum: return regnum2spr (699);
+ case sim_ppc_spr700_regnum: return regnum2spr (700);
+ case sim_ppc_spr701_regnum: return regnum2spr (701);
+ case sim_ppc_spr702_regnum: return regnum2spr (702);
+ case sim_ppc_spr703_regnum: return regnum2spr (703);
+ case sim_ppc_spr704_regnum: return regnum2spr (704);
+ case sim_ppc_spr705_regnum: return regnum2spr (705);
+ case sim_ppc_spr706_regnum: return regnum2spr (706);
+ case sim_ppc_spr707_regnum: return regnum2spr (707);
+ case sim_ppc_spr708_regnum: return regnum2spr (708);
+ case sim_ppc_spr709_regnum: return regnum2spr (709);
+ case sim_ppc_spr710_regnum: return regnum2spr (710);
+ case sim_ppc_spr711_regnum: return regnum2spr (711);
+ case sim_ppc_spr712_regnum: return regnum2spr (712);
+ case sim_ppc_spr713_regnum: return regnum2spr (713);
+ case sim_ppc_spr714_regnum: return regnum2spr (714);
+ case sim_ppc_spr715_regnum: return regnum2spr (715);
+ case sim_ppc_spr716_regnum: return regnum2spr (716);
+ case sim_ppc_spr717_regnum: return regnum2spr (717);
+ case sim_ppc_spr718_regnum: return regnum2spr (718);
+ case sim_ppc_spr719_regnum: return regnum2spr (719);
+ case sim_ppc_spr720_regnum: return regnum2spr (720);
+ case sim_ppc_spr721_regnum: return regnum2spr (721);
+ case sim_ppc_spr722_regnum: return regnum2spr (722);
+ case sim_ppc_spr723_regnum: return regnum2spr (723);
+ case sim_ppc_spr724_regnum: return regnum2spr (724);
+ case sim_ppc_spr725_regnum: return regnum2spr (725);
+ case sim_ppc_spr726_regnum: return regnum2spr (726);
+ case sim_ppc_spr727_regnum: return regnum2spr (727);
+ case sim_ppc_spr728_regnum: return regnum2spr (728);
+ case sim_ppc_spr729_regnum: return regnum2spr (729);
+ case sim_ppc_spr730_regnum: return regnum2spr (730);
+ case sim_ppc_spr731_regnum: return regnum2spr (731);
+ case sim_ppc_spr732_regnum: return regnum2spr (732);
+ case sim_ppc_spr733_regnum: return regnum2spr (733);
+ case sim_ppc_spr734_regnum: return regnum2spr (734);
+ case sim_ppc_spr735_regnum: return regnum2spr (735);
+ case sim_ppc_spr736_regnum: return regnum2spr (736);
+ case sim_ppc_spr737_regnum: return regnum2spr (737);
+ case sim_ppc_spr738_regnum: return regnum2spr (738);
+ case sim_ppc_spr739_regnum: return regnum2spr (739);
+ case sim_ppc_spr740_regnum: return regnum2spr (740);
+ case sim_ppc_spr741_regnum: return regnum2spr (741);
+ case sim_ppc_spr742_regnum: return regnum2spr (742);
+ case sim_ppc_spr743_regnum: return regnum2spr (743);
+ case sim_ppc_spr744_regnum: return regnum2spr (744);
+ case sim_ppc_spr745_regnum: return regnum2spr (745);
+ case sim_ppc_spr746_regnum: return regnum2spr (746);
+ case sim_ppc_spr747_regnum: return regnum2spr (747);
+ case sim_ppc_spr748_regnum: return regnum2spr (748);
+ case sim_ppc_spr749_regnum: return regnum2spr (749);
+ case sim_ppc_spr750_regnum: return regnum2spr (750);
+ case sim_ppc_spr751_regnum: return regnum2spr (751);
+ case sim_ppc_spr752_regnum: return regnum2spr (752);
+ case sim_ppc_spr753_regnum: return regnum2spr (753);
+ case sim_ppc_spr754_regnum: return regnum2spr (754);
+ case sim_ppc_spr755_regnum: return regnum2spr (755);
+ case sim_ppc_spr756_regnum: return regnum2spr (756);
+ case sim_ppc_spr757_regnum: return regnum2spr (757);
+ case sim_ppc_spr758_regnum: return regnum2spr (758);
+ case sim_ppc_spr759_regnum: return regnum2spr (759);
+ case sim_ppc_spr760_regnum: return regnum2spr (760);
+ case sim_ppc_spr761_regnum: return regnum2spr (761);
+ case sim_ppc_spr762_regnum: return regnum2spr (762);
+ case sim_ppc_spr763_regnum: return regnum2spr (763);
+ case sim_ppc_spr764_regnum: return regnum2spr (764);
+ case sim_ppc_spr765_regnum: return regnum2spr (765);
+ case sim_ppc_spr766_regnum: return regnum2spr (766);
+ case sim_ppc_spr767_regnum: return regnum2spr (767);
+ case sim_ppc_spr768_regnum: return regnum2spr (768);
+ case sim_ppc_spr769_regnum: return regnum2spr (769);
+ case sim_ppc_spr770_regnum: return regnum2spr (770);
+ case sim_ppc_spr771_regnum: return regnum2spr (771);
+ case sim_ppc_spr772_regnum: return regnum2spr (772);
+ case sim_ppc_spr773_regnum: return regnum2spr (773);
+ case sim_ppc_spr774_regnum: return regnum2spr (774);
+ case sim_ppc_spr775_regnum: return regnum2spr (775);
+ case sim_ppc_spr776_regnum: return regnum2spr (776);
+ case sim_ppc_spr777_regnum: return regnum2spr (777);
+ case sim_ppc_spr778_regnum: return regnum2spr (778);
+ case sim_ppc_spr779_regnum: return regnum2spr (779);
+ case sim_ppc_spr780_regnum: return regnum2spr (780);
+ case sim_ppc_spr781_regnum: return regnum2spr (781);
+ case sim_ppc_spr782_regnum: return regnum2spr (782);
+ case sim_ppc_spr783_regnum: return regnum2spr (783);
+ case sim_ppc_spr784_regnum: return regnum2spr (784);
+ case sim_ppc_spr785_regnum: return regnum2spr (785);
+ case sim_ppc_spr786_regnum: return regnum2spr (786);
+ case sim_ppc_spr787_regnum: return regnum2spr (787);
+ case sim_ppc_spr788_regnum: return regnum2spr (788);
+ case sim_ppc_spr789_regnum: return regnum2spr (789);
+ case sim_ppc_spr790_regnum: return regnum2spr (790);
+ case sim_ppc_spr791_regnum: return regnum2spr (791);
+ case sim_ppc_spr792_regnum: return regnum2spr (792);
+ case sim_ppc_spr793_regnum: return regnum2spr (793);
+ case sim_ppc_spr794_regnum: return regnum2spr (794);
+ case sim_ppc_spr795_regnum: return regnum2spr (795);
+ case sim_ppc_spr796_regnum: return regnum2spr (796);
+ case sim_ppc_spr797_regnum: return regnum2spr (797);
+ case sim_ppc_spr798_regnum: return regnum2spr (798);
+ case sim_ppc_spr799_regnum: return regnum2spr (799);
+ case sim_ppc_spr800_regnum: return regnum2spr (800);
+ case sim_ppc_spr801_regnum: return regnum2spr (801);
+ case sim_ppc_spr802_regnum: return regnum2spr (802);
+ case sim_ppc_spr803_regnum: return regnum2spr (803);
+ case sim_ppc_spr804_regnum: return regnum2spr (804);
+ case sim_ppc_spr805_regnum: return regnum2spr (805);
+ case sim_ppc_spr806_regnum: return regnum2spr (806);
+ case sim_ppc_spr807_regnum: return regnum2spr (807);
+ case sim_ppc_spr808_regnum: return regnum2spr (808);
+ case sim_ppc_spr809_regnum: return regnum2spr (809);
+ case sim_ppc_spr810_regnum: return regnum2spr (810);
+ case sim_ppc_spr811_regnum: return regnum2spr (811);
+ case sim_ppc_spr812_regnum: return regnum2spr (812);
+ case sim_ppc_spr813_regnum: return regnum2spr (813);
+ case sim_ppc_spr814_regnum: return regnum2spr (814);
+ case sim_ppc_spr815_regnum: return regnum2spr (815);
+ case sim_ppc_spr816_regnum: return regnum2spr (816);
+ case sim_ppc_spr817_regnum: return regnum2spr (817);
+ case sim_ppc_spr818_regnum: return regnum2spr (818);
+ case sim_ppc_spr819_regnum: return regnum2spr (819);
+ case sim_ppc_spr820_regnum: return regnum2spr (820);
+ case sim_ppc_spr821_regnum: return regnum2spr (821);
+ case sim_ppc_spr822_regnum: return regnum2spr (822);
+ case sim_ppc_spr823_regnum: return regnum2spr (823);
+ case sim_ppc_spr824_regnum: return regnum2spr (824);
+ case sim_ppc_spr825_regnum: return regnum2spr (825);
+ case sim_ppc_spr826_regnum: return regnum2spr (826);
+ case sim_ppc_spr827_regnum: return regnum2spr (827);
+ case sim_ppc_spr828_regnum: return regnum2spr (828);
+ case sim_ppc_spr829_regnum: return regnum2spr (829);
+ case sim_ppc_spr830_regnum: return regnum2spr (830);
+ case sim_ppc_spr831_regnum: return regnum2spr (831);
+ case sim_ppc_spr832_regnum: return regnum2spr (832);
+ case sim_ppc_spr833_regnum: return regnum2spr (833);
+ case sim_ppc_spr834_regnum: return regnum2spr (834);
+ case sim_ppc_spr835_regnum: return regnum2spr (835);
+ case sim_ppc_spr836_regnum: return regnum2spr (836);
+ case sim_ppc_spr837_regnum: return regnum2spr (837);
+ case sim_ppc_spr838_regnum: return regnum2spr (838);
+ case sim_ppc_spr839_regnum: return regnum2spr (839);
+ case sim_ppc_spr840_regnum: return regnum2spr (840);
+ case sim_ppc_spr841_regnum: return regnum2spr (841);
+ case sim_ppc_spr842_regnum: return regnum2spr (842);
+ case sim_ppc_spr843_regnum: return regnum2spr (843);
+ case sim_ppc_spr844_regnum: return regnum2spr (844);
+ case sim_ppc_spr845_regnum: return regnum2spr (845);
+ case sim_ppc_spr846_regnum: return regnum2spr (846);
+ case sim_ppc_spr847_regnum: return regnum2spr (847);
+ case sim_ppc_spr848_regnum: return regnum2spr (848);
+ case sim_ppc_spr849_regnum: return regnum2spr (849);
+ case sim_ppc_spr850_regnum: return regnum2spr (850);
+ case sim_ppc_spr851_regnum: return regnum2spr (851);
+ case sim_ppc_spr852_regnum: return regnum2spr (852);
+ case sim_ppc_spr853_regnum: return regnum2spr (853);
+ case sim_ppc_spr854_regnum: return regnum2spr (854);
+ case sim_ppc_spr855_regnum: return regnum2spr (855);
+ case sim_ppc_spr856_regnum: return regnum2spr (856);
+ case sim_ppc_spr857_regnum: return regnum2spr (857);
+ case sim_ppc_spr858_regnum: return regnum2spr (858);
+ case sim_ppc_spr859_regnum: return regnum2spr (859);
+ case sim_ppc_spr860_regnum: return regnum2spr (860);
+ case sim_ppc_spr861_regnum: return regnum2spr (861);
+ case sim_ppc_spr862_regnum: return regnum2spr (862);
+ case sim_ppc_spr863_regnum: return regnum2spr (863);
+ case sim_ppc_spr864_regnum: return regnum2spr (864);
+ case sim_ppc_spr865_regnum: return regnum2spr (865);
+ case sim_ppc_spr866_regnum: return regnum2spr (866);
+ case sim_ppc_spr867_regnum: return regnum2spr (867);
+ case sim_ppc_spr868_regnum: return regnum2spr (868);
+ case sim_ppc_spr869_regnum: return regnum2spr (869);
+ case sim_ppc_spr870_regnum: return regnum2spr (870);
+ case sim_ppc_spr871_regnum: return regnum2spr (871);
+ case sim_ppc_spr872_regnum: return regnum2spr (872);
+ case sim_ppc_spr873_regnum: return regnum2spr (873);
+ case sim_ppc_spr874_regnum: return regnum2spr (874);
+ case sim_ppc_spr875_regnum: return regnum2spr (875);
+ case sim_ppc_spr876_regnum: return regnum2spr (876);
+ case sim_ppc_spr877_regnum: return regnum2spr (877);
+ case sim_ppc_spr878_regnum: return regnum2spr (878);
+ case sim_ppc_spr879_regnum: return regnum2spr (879);
+ case sim_ppc_spr880_regnum: return regnum2spr (880);
+ case sim_ppc_spr881_regnum: return regnum2spr (881);
+ case sim_ppc_spr882_regnum: return regnum2spr (882);
+ case sim_ppc_spr883_regnum: return regnum2spr (883);
+ case sim_ppc_spr884_regnum: return regnum2spr (884);
+ case sim_ppc_spr885_regnum: return regnum2spr (885);
+ case sim_ppc_spr886_regnum: return regnum2spr (886);
+ case sim_ppc_spr887_regnum: return regnum2spr (887);
+ case sim_ppc_spr888_regnum: return regnum2spr (888);
+ case sim_ppc_spr889_regnum: return regnum2spr (889);
+ case sim_ppc_spr890_regnum: return regnum2spr (890);
+ case sim_ppc_spr891_regnum: return regnum2spr (891);
+ case sim_ppc_spr892_regnum: return regnum2spr (892);
+ case sim_ppc_spr893_regnum: return regnum2spr (893);
+ case sim_ppc_spr894_regnum: return regnum2spr (894);
+ case sim_ppc_spr895_regnum: return regnum2spr (895);
+ case sim_ppc_spr896_regnum: return regnum2spr (896);
+ case sim_ppc_spr897_regnum: return regnum2spr (897);
+ case sim_ppc_spr898_regnum: return regnum2spr (898);
+ case sim_ppc_spr899_regnum: return regnum2spr (899);
+ case sim_ppc_spr900_regnum: return regnum2spr (900);
+ case sim_ppc_spr901_regnum: return regnum2spr (901);
+ case sim_ppc_spr902_regnum: return regnum2spr (902);
+ case sim_ppc_spr903_regnum: return regnum2spr (903);
+ case sim_ppc_spr904_regnum: return regnum2spr (904);
+ case sim_ppc_spr905_regnum: return regnum2spr (905);
+ case sim_ppc_spr906_regnum: return regnum2spr (906);
+ case sim_ppc_spr907_regnum: return regnum2spr (907);
+ case sim_ppc_spr908_regnum: return regnum2spr (908);
+ case sim_ppc_spr909_regnum: return regnum2spr (909);
+ case sim_ppc_spr910_regnum: return regnum2spr (910);
+ case sim_ppc_spr911_regnum: return regnum2spr (911);
+ case sim_ppc_spr912_regnum: return regnum2spr (912);
+ case sim_ppc_spr913_regnum: return regnum2spr (913);
+ case sim_ppc_spr914_regnum: return regnum2spr (914);
+ case sim_ppc_spr915_regnum: return regnum2spr (915);
+ case sim_ppc_spr916_regnum: return regnum2spr (916);
+ case sim_ppc_spr917_regnum: return regnum2spr (917);
+ case sim_ppc_spr918_regnum: return regnum2spr (918);
+ case sim_ppc_spr919_regnum: return regnum2spr (919);
+ case sim_ppc_spr920_regnum: return regnum2spr (920);
+ case sim_ppc_spr921_regnum: return regnum2spr (921);
+ case sim_ppc_spr922_regnum: return regnum2spr (922);
+ case sim_ppc_spr923_regnum: return regnum2spr (923);
+ case sim_ppc_spr924_regnum: return regnum2spr (924);
+ case sim_ppc_spr925_regnum: return regnum2spr (925);
+ case sim_ppc_spr926_regnum: return regnum2spr (926);
+ case sim_ppc_spr927_regnum: return regnum2spr (927);
+ case sim_ppc_spr928_regnum: return regnum2spr (928);
+ case sim_ppc_spr929_regnum: return regnum2spr (929);
+ case sim_ppc_spr930_regnum: return regnum2spr (930);
+ case sim_ppc_spr931_regnum: return regnum2spr (931);
+ case sim_ppc_spr932_regnum: return regnum2spr (932);
+ case sim_ppc_spr933_regnum: return regnum2spr (933);
+ case sim_ppc_spr934_regnum: return regnum2spr (934);
+ case sim_ppc_spr935_regnum: return regnum2spr (935);
+ case sim_ppc_spr936_regnum: return regnum2spr (936);
+ case sim_ppc_spr937_regnum: return regnum2spr (937);
+ case sim_ppc_spr938_regnum: return regnum2spr (938);
+ case sim_ppc_spr939_regnum: return regnum2spr (939);
+ case sim_ppc_spr940_regnum: return regnum2spr (940);
+ case sim_ppc_spr941_regnum: return regnum2spr (941);
+ case sim_ppc_spr942_regnum: return regnum2spr (942);
+ case sim_ppc_spr943_regnum: return regnum2spr (943);
+ case sim_ppc_spr944_regnum: return regnum2spr (944);
+ case sim_ppc_spr945_regnum: return regnum2spr (945);
+ case sim_ppc_spr946_regnum: return regnum2spr (946);
+ case sim_ppc_spr947_regnum: return regnum2spr (947);
+ case sim_ppc_spr948_regnum: return regnum2spr (948);
+ case sim_ppc_spr949_regnum: return regnum2spr (949);
+ case sim_ppc_spr950_regnum: return regnum2spr (950);
+ case sim_ppc_spr951_regnum: return regnum2spr (951);
+ case sim_ppc_spr952_regnum: return regnum2spr (952);
+ case sim_ppc_spr953_regnum: return regnum2spr (953);
+ case sim_ppc_spr954_regnum: return regnum2spr (954);
+ case sim_ppc_spr955_regnum: return regnum2spr (955);
+ case sim_ppc_spr956_regnum: return regnum2spr (956);
+ case sim_ppc_spr957_regnum: return regnum2spr (957);
+ case sim_ppc_spr958_regnum: return regnum2spr (958);
+ case sim_ppc_spr959_regnum: return regnum2spr (959);
+ case sim_ppc_spr960_regnum: return regnum2spr (960);
+ case sim_ppc_spr961_regnum: return regnum2spr (961);
+ case sim_ppc_spr962_regnum: return regnum2spr (962);
+ case sim_ppc_spr963_regnum: return regnum2spr (963);
+ case sim_ppc_spr964_regnum: return regnum2spr (964);
+ case sim_ppc_spr965_regnum: return regnum2spr (965);
+ case sim_ppc_spr966_regnum: return regnum2spr (966);
+ case sim_ppc_spr967_regnum: return regnum2spr (967);
+ case sim_ppc_spr968_regnum: return regnum2spr (968);
+ case sim_ppc_spr969_regnum: return regnum2spr (969);
+ case sim_ppc_spr970_regnum: return regnum2spr (970);
+ case sim_ppc_spr971_regnum: return regnum2spr (971);
+ case sim_ppc_spr972_regnum: return regnum2spr (972);
+ case sim_ppc_spr973_regnum: return regnum2spr (973);
+ case sim_ppc_spr974_regnum: return regnum2spr (974);
+ case sim_ppc_spr975_regnum: return regnum2spr (975);
+ case sim_ppc_spr976_regnum: return regnum2spr (976);
+ case sim_ppc_spr977_regnum: return regnum2spr (977);
+ case sim_ppc_spr978_regnum: return regnum2spr (978);
+ case sim_ppc_spr979_regnum: return regnum2spr (979);
+ case sim_ppc_spr980_regnum: return regnum2spr (980);
+ case sim_ppc_spr981_regnum: return regnum2spr (981);
+ case sim_ppc_spr982_regnum: return regnum2spr (982);
+ case sim_ppc_spr983_regnum: return regnum2spr (983);
+ case sim_ppc_spr984_regnum: return regnum2spr (984);
+ case sim_ppc_spr985_regnum: return regnum2spr (985);
+ case sim_ppc_spr986_regnum: return regnum2spr (986);
+ case sim_ppc_spr987_regnum: return regnum2spr (987);
+ case sim_ppc_spr988_regnum: return regnum2spr (988);
+ case sim_ppc_spr989_regnum: return regnum2spr (989);
+ case sim_ppc_spr990_regnum: return regnum2spr (990);
+ case sim_ppc_spr991_regnum: return regnum2spr (991);
+ case sim_ppc_spr992_regnum: return regnum2spr (992);
+ case sim_ppc_spr993_regnum: return regnum2spr (993);
+ case sim_ppc_spr994_regnum: return regnum2spr (994);
+ case sim_ppc_spr995_regnum: return regnum2spr (995);
+ case sim_ppc_spr996_regnum: return regnum2spr (996);
+ case sim_ppc_spr997_regnum: return regnum2spr (997);
+ case sim_ppc_spr998_regnum: return regnum2spr (998);
+ case sim_ppc_spr999_regnum: return regnum2spr (999);
+ case sim_ppc_spr1000_regnum: return regnum2spr (1000);
+ case sim_ppc_spr1001_regnum: return regnum2spr (1001);
+ case sim_ppc_spr1002_regnum: return regnum2spr (1002);
+ case sim_ppc_spr1003_regnum: return regnum2spr (1003);
+ case sim_ppc_spr1004_regnum: return regnum2spr (1004);
+ case sim_ppc_spr1005_regnum: return regnum2spr (1005);
+ case sim_ppc_spr1006_regnum: return regnum2spr (1006);
+ case sim_ppc_spr1007_regnum: return regnum2spr (1007);
+ case sim_ppc_spr1008_regnum: return regnum2spr (1008);
+ case sim_ppc_spr1009_regnum: return regnum2spr (1009);
+ case sim_ppc_spr1010_regnum: return regnum2spr (1010);
+ case sim_ppc_spr1011_regnum: return regnum2spr (1011);
+ case sim_ppc_spr1012_regnum: return regnum2spr (1012);
+ case sim_ppc_spr1013_regnum: return regnum2spr (1013);
+ case sim_ppc_spr1014_regnum: return regnum2spr (1014);
+ case sim_ppc_spr1015_regnum: return regnum2spr (1015);
+ case sim_ppc_spr1016_regnum: return regnum2spr (1016);
+ case sim_ppc_spr1017_regnum: return regnum2spr (1017);
+ case sim_ppc_spr1018_regnum: return regnum2spr (1018);
+ case sim_ppc_spr1019_regnum: return regnum2spr (1019);
+ case sim_ppc_spr1020_regnum: return regnum2spr (1020);
+ case sim_ppc_spr1021_regnum: return regnum2spr (1021);
+ case sim_ppc_spr1022_regnum: return regnum2spr (1022);
+ case sim_ppc_spr1023_regnum: return regnum2spr (1023);
+ default:
+ /* Not a valid register number at all. */
+ return NULL;
+ }
+}
+
+
+int
+sim_fetch_register (SIM_DESC sd, int regno, unsigned char *buf, int length)
+{
+ const char *regname = regnum2name (regno);
+
+ if (simulator == NULL || regname == NULL)
+ return -1;
+
+ TRACE(trace_gdb, ("sim_fetch_register(regno=%d(%s), buf=0x%lx)\n",
+ regno, regname, (long)buf));
+ return psim_read_register(simulator, MAX_NR_PROCESSORS,
+ buf, regname, raw_transfer);
+}
+
+
+int
+sim_store_register (SIM_DESC sd, int regno, unsigned char *buf, int length)
+{
+ const char *regname = regnum2name (regno);
+
+ if (simulator == NULL || regname == NULL)
+ return -1;
+
+ TRACE(trace_gdb, ("sim_store_register(regno=%d(%s), buf=0x%lx)\n",
+ regno, regname, (long)buf));
+ return psim_write_register(simulator, MAX_NR_PROCESSORS,
+ buf, regname, raw_transfer);
+}
--- /dev/null
+# mips test sanity, expected to pass.
+# mach: sb1
+# as: -mabi=eabi
+# ld: -N -Ttext=0x80010000
+# output: *\\npass\\n
+
+ .include "testutils.inc"
+
+ .macro check_ps psval, upperval, lowerval
+ .set push
+ .set noreorder
+ cvt.s.pu $f0, \psval # upper
+ cvt.s.pl $f2, \psval # lower
+ li.s $f4, \upperval
+ li.s $f6, \lowerval
+ c.eq.s $fcc0, $f0, $f4
+ bc1f $fcc0, _fail
+ c.eq.s $fcc0, $f2, $f6
+ bc1f $fcc0, _fail
+ nop
+ .set pop
+ .endm
+
+ setup
+
+ .set noreorder
+
+ .ent DIAG
+DIAG:
+
+ # make sure that Status.FR, .CU1, and .SBX are set.
+ mfc0 $2, $12
+ or $2, $2, (1 << 26) | (1 << 29) | (1 << 16)
+ mtc0 $2, $12
+
+
+ li.s $f10, 4.0
+ li.s $f12, 16.0
+ cvt.ps.s $f20, $f10, $f12 # $f20: u=4.0, l=16.0
+
+ li.s $f10, -1.0
+ li.s $f12, 2.0
+ cvt.ps.s $f22, $f10, $f12 # $f22: u=-1.0, l=2.0
+
+
+ writemsg "div.ps"
+
+ div.ps $f8, $f20, $f22
+ check_ps $f8, -4.0, 8.0
+
+
+ writemsg "recip.ps"
+
+ recip.ps $f8, $f20
+ check_ps $f8, 0.25, 0.0625
+
+
+ writemsg "rsqrt.ps"
+
+ rsqrt.ps $f8, $f20
+ check_ps $f8, 0.5, 0.25
+
+
+ writemsg "sqrt.ps"
+
+ sqrt.ps $f8, $f20
+ check_ps $f8, 2.0, 4.0
+
+
+ pass
+
+ .end DIAG
--- /dev/null
+# mips test sanity, expected to pass.
+# mach: mips64 sb1
+# as: -mabi=eabi
+# ld: -N -Ttext=0x80010000
+# output: *\\npass\\n
+
+ .include "testutils.inc"
+
+ .macro check_ps psval, upperval, lowerval
+ .set push
+ .set noreorder
+ cvt.s.pu $f0, \psval # upper
+ cvt.s.pl $f2, \psval # lower
+ li.s $f4, \upperval
+ li.s $f6, \lowerval
+ c.eq.s $fcc0, $f0, $f4
+ bc1f $fcc0, _fail
+ c.eq.s $fcc0, $f2, $f6
+ bc1f $fcc0, _fail
+ nop
+ .set pop
+ .endm
+
+ setup
+
+ .set noreorder
+
+ .ent DIAG
+DIAG:
+
+ # make sure that Status.FR and .CU1 are set.
+ mfc0 $2, $12
+ or $2, $2, (1 << 26) | (1 << 29)
+ mtc0 $2, $12
+
+
+ writemsg "ldc1"
+
+ .data
+1: .dword 0xc1a8000042200000 # -21.0, 40.0
+ .text
+ la $2, 1b
+ ldc1 $f8, 0($2)
+ check_ps $f8, -21.0, 40.0
+
+
+ writemsg "cvt.ps.s"
+
+ li.s $f10, 1.0
+ li.s $f12, 3.0
+ cvt.ps.s $f8, $f10, $f12 # upper, lower
+ check_ps $f8, 1.0, 3.0
+
+
+ writemsg "cvt.ps.s, sdc1, copy, ldc1"
+
+ .data
+1: .dword 0
+ .dword 0
+ .text
+ la $2, 1b
+ li.s $f12, -4.0
+ li.s $f14, 32.0
+ cvt.ps.s $f10, $f12, $f14 # upper, lower
+ sdc1 $f10, 8($2)
+ lw $3, 8($2)
+ lw $4, 12($2)
+ sw $3, 0($2)
+ sw $4, 4($2)
+ ldc1 $f8, 0($2)
+ check_ps $f8, -4.0, 32.0
+
+
+ # Load some constants for later use
+
+ li.s $f10, 4.0
+ li.s $f12, 16.0
+ cvt.ps.s $f20, $f10, $f12 # $f20: u=4.0, l=16.0
+
+ li.s $f10, -1.0
+ li.s $f12, 2.0
+ cvt.ps.s $f22, $f10, $f12 # $f22: u=-1.0, l=2.0
+
+ li.s $f10, 17.0
+ li.s $f12, -8.0
+ cvt.ps.s $f24, $f10, $f12 # $f24: u=17.0, l=-8.0
+
+
+ writemsg "pll.ps"
+
+ pll.ps $f8, $f20, $f22
+ check_ps $f8, 16.0, 2.0
+
+
+ writemsg "plu.ps"
+
+ plu.ps $f8, $f20, $f22
+ check_ps $f8, 16.0, -1.0
+
+
+ writemsg "pul.ps"
+
+ pul.ps $f8, $f20, $f22
+ check_ps $f8, 4.0, 2.0
+
+
+ writemsg "puu.ps"
+
+ puu.ps $f8, $f20, $f22
+ check_ps $f8, 4.0, -1.0
+
+
+ writemsg "abs.ps"
+
+ abs.ps $f8, $f22
+ check_ps $f8, 1.0, 2.0
+
+
+ writemsg "mov.ps"
+
+ mov.ps $f8, $f22
+ check_ps $f8, -1.0, 2.0
+
+
+ writemsg "neg.ps"
+
+ neg.ps $f8, $f22
+ check_ps $f8, 1.0, -2.0
+
+
+ writemsg "add.ps"
+
+ add.ps $f8, $f20, $f22
+ check_ps $f8, 3.0, 18.0
+
+
+ writemsg "mul.ps"
+
+ mul.ps $f8, $f20, $f22
+ check_ps $f8, -4.0, 32.0
+
+
+ writemsg "sub.ps"
+
+ sub.ps $f8, $f20, $f22
+ check_ps $f8, 5.0, 14.0
+
+
+ writemsg "madd.ps"
+
+ madd.ps $f8, $f24, $f20, $f22
+ check_ps $f8, 13.0, 24.0
+
+
+ writemsg "msub.ps"
+
+ msub.ps $f8, $f24, $f20, $f22
+ check_ps $f8, -21.0, 40.0
+
+
+ writemsg "nmadd.ps"
+
+ nmadd.ps $f8, $f24, $f20, $f22
+ check_ps $f8, -13.0, -24.0
+
+
+ writemsg "nmsub.ps"
+
+ nmsub.ps $f8, $f24, $f20, $f22
+ check_ps $f8, 21.0, -40.0
+
+
+ writemsg "movn.ps (n)"
+
+ li $2, 0
+ mov.ps $f8, $f20
+ movn.ps $f8, $f22, $2 # doesn't move
+ check_ps $f8, 4.0, 16.0
+
+
+ writemsg "movn.ps (y)"
+
+ li $2, 1
+ mov.ps $f8, $f20
+ movn.ps $f8, $f22, $2 # does move
+ check_ps $f8, -1.0, 2.0
+
+
+ writemsg "movz.ps (y)"
+
+ li $2, 0
+ mov.ps $f8, $f20
+ movz.ps $f8, $f22, $2 # does move
+ check_ps $f8, -1.0, 2.0
+
+
+ writemsg "movz.ps (n)"
+
+ li $2, 1
+ mov.ps $f8, $f20
+ movz.ps $f8, $f22, $2 # doesn't move
+ check_ps $f8, 4.0, 16.0
+
+
+ writemsg "movf.ps (y,y)"
+
+ cfc1 $2, $31
+ or $2, $2, (1 << 23) | (1 << 25)
+ xor $2, $2, (1 << 23) | (1 << 25)
+ ctc1 $2, $31 # clear fcc0, clear fcc1
+ mov.ps $f8, $f20
+ movf.ps $f8, $f22, $fcc0 # moves both halves
+ check_ps $f8, -1.0, 2.0
+
+
+ writemsg "movf.ps (y,n)"
+
+ cfc1 $2, $31
+ or $2, $2, (1 << 23) | (1 << 25)
+ xor $2, $2, (0 << 23) | (1 << 25)
+ ctc1 $2, $31 # set fcc0, clear fcc1
+ mov.ps $f8, $f20
+ movf.ps $f8, $f22, $fcc0 # moves upper half only
+ check_ps $f8, -1.0, 16.0
+
+
+ writemsg "movf.ps (n,y)"
+
+ cfc1 $2, $31
+ or $2, $2, (1 << 23) | (1 << 25)
+ xor $2, $2, (1 << 23) | (0 << 25)
+ ctc1 $2, $31 # clear fcc0, set fcc1
+ mov.ps $f8, $f20
+ movf.ps $f8, $f22, $fcc0 # moves lower half only
+ check_ps $f8, 4.0, 2.0
+
+
+ writemsg "movf.ps (n,n)"
+
+ cfc1 $2, $31
+ or $2, $2, (1 << 23) | (1 << 25)
+ xor $2, $2, (0 << 23) | (0 << 25)
+ ctc1 $2, $31 # set fcc0, set fcc1
+ mov.ps $f8, $f20
+ movf.ps $f8, $f22, $fcc0 # doesn't move either half
+ check_ps $f8, 4.0, 16.0
+
+
+ writemsg "movt.ps (n,n)"
+
+ cfc1 $2, $31
+ or $2, $2, (1 << 23) | (1 << 25)
+ xor $2, $2, (1 << 23) | (1 << 25)
+ ctc1 $2, $31 # clear fcc0, clear fcc1
+ mov.ps $f8, $f20
+ movt.ps $f8, $f22, $fcc0 # doesn't move either half
+ check_ps $f8, 4.0, 16.0
+
+
+ writemsg "movt.ps (n,y)"
+
+ cfc1 $2, $31
+ or $2, $2, (1 << 23) | (1 << 25)
+ xor $2, $2, (0 << 23) | (1 << 25)
+ ctc1 $2, $31 # set fcc0, clear fcc1
+ mov.ps $f8, $f20
+ movt.ps $f8, $f22, $fcc0 # moves lower half only
+ check_ps $f8, 4.0, 2.0
+
+
+ writemsg "movt.ps (y,n)"
+
+ cfc1 $2, $31
+ or $2, $2, (1 << 23) | (1 << 25)
+ xor $2, $2, (1 << 23) | (0 << 25)
+ ctc1 $2, $31 # clear fcc0, set fcc1
+ mov.ps $f8, $f20
+ movt.ps $f8, $f22, $fcc0 # moves upper half only
+ check_ps $f8, -1.0, 16.0
+
+
+ writemsg "movt.ps (y,y)"
+
+ cfc1 $2, $31
+ or $2, $2, (1 << 23) | (1 << 25)
+ xor $2, $2, (0 << 23) | (0 << 25)
+ ctc1 $2, $31 # set fcc0, set fcc1
+ mov.ps $f8, $f20
+ movt.ps $f8, $f22, $fcc0 # moves both halves
+ check_ps $f8, -1.0, 2.0
+
+
+ writemsg "alnv.ps (aligned)"
+
+ .data
+1: .dword 0xc1a8000042200000 # -21.0, 40.0
+ .dword 0xc228000041a00000 # -42.0, 20.0
+ .text
+ la $2, 1b
+ li $3, 0
+ addu $4, $3, 8
+ luxc1 $f10, $3($2)
+ luxc1 $f12, $4($2)
+ alnv.ps $f8, $f10, $f12, $3
+ check_ps $f8, -21.0, 40.0
+
+
+ writemsg "alnv.ps (unaligned)"
+
+ .data
+1: .dword 0xc1a8000042200000 # -21.0, 40.0
+ .dword 0xc228000041a00000 # -42.0, 20.0
+ .hword 0x0001
+ .text
+ la $2, 1b
+ li $3, 4
+ addu $4, $3, 8
+ luxc1 $f10, $3($2)
+ luxc1 $f12, $4($2)
+ alnv.ps $f8, $f10, $f12, $3
+
+ lb $5, 16($2)
+ bnez $5, 2f # little endian
+ nop
+
+ # big endian
+ check_ps $f8, 40.0, -42.0
+ b 3f
+ nop
+2:
+ # little endian
+ check_ps $f8, 20.0, -21.0
+3:
+
+
+ # We test c.cond.ps only lightly, just to make sure it modifies
+ # two bits and compares the halves separately. Perhaps it should
+ # be tested more thoroughly.
+
+ writemsg "c.f.ps"
+
+ cfc1 $2, $31
+ or $2, $2, (1 << 23) | (0x7f << 25)
+ ctc1 $2, $31 # set all fcc bits
+ c.f.ps $fcc0, $f8, $f8 # -> f, f
+ bc1t $fcc0, _fail
+ nop
+ bc1t $fcc1, _fail
+ nop
+
+
+ writemsg "c.olt.ps"
+
+ cfc1 $2, $31
+ or $2, $2, (1 << 23) | (0x7f << 25)
+ xor $2, $2, (1 << 23) | (0x7f << 25)
+ ctc1 $2, $31 # clear all fcc bits
+ c.lt.ps $fcc0, $f22, $f24 # -> f, t
+ bc1t $fcc0, _fail
+ nop
+ bc1f $fcc1, _fail
+ nop
+
+
+ pass
+
+ .end DIAG
--- /dev/null
+# MDMX .OB op tests.
+# mach: sb1
+# as: -mabi=eabi
+# ld: -N -Ttext=0x80010000
+# output: *\\npass\\n
+
+ .include "testutils.inc"
+ .include "utils-mdmx.inc"
+
+ setup
+
+ .set noreorder
+
+ .ent DIAG
+DIAG:
+
+ enable_mdmx
+
+ # set Status.SBX to enable SB-1 extensions.
+ mfc0 $2, $12
+ or $2, $2, (1 << 16)
+ mtc0 $2, $12
+
+
+ ###
+ ### SB-1 Non-accumulator .ob format ops.
+ ###
+ ### Key: v = vector
+ ### ev = vector of single element
+ ### cv = vector of constant.
+ ###
+
+
+ writemsg "pavg.ob (v)"
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x66778899aabbccdd
+ pavg.ob $f10, $f8, $f9
+ ck_ob $f10, 0x3c4d5e6f8091a2b3
+
+ writemsg "pavg.ob (ev)"
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x66778899aabbccdd
+ pavg.ob $f10, $f8, $f9[6]
+ ck_ob $f10, 0x444d555e666f7780
+
+ writemsg "pavg.ob (cv)"
+ ld_ob $f8, 0x1122334455667788
+ pavg.ob $f10, $f8, 0x10
+ ck_ob $f10, 0x1119222a333b444c
+
+
+ writemsg "pabsdiff.ob (v)"
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x66778899aabbccdd
+ pabsdiff.ob $f10, $f8, $f9
+ ck_ob $f10, 0x5555555555555555
+
+ writemsg "pabsdiff.ob (ev)"
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x66778899aabbccdd
+ pabsdiff.ob $f10, $f8, $f9[7]
+ ck_ob $f10, 0x5544332211001122
+
+ writemsg "pabsdiff.ob (cv)"
+ ld_ob $f8, 0x0001020304050607
+ pabsdiff.ob $f10, $f8, 0x04
+ ck_ob $f10, 0x0403020100010203
+
+
+ ###
+ ### SB-1 Accumulator .ob format ops
+ ###
+ ### Key: v = vector
+ ### ev = vector of single element
+ ### cv = vector of constant.
+ ###
+
+
+ writemsg "pabsdiffc.ob (v)"
+ ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x66778899aabbccdd
+ pabsdiffc.ob $f8, $f9
+ ck_acc_ob 0x0001020304050607, 0x0000000000000000, 0x5555555555555555
+
+ writemsg "pabsdiffc.ob (ev)"
+ ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x66778899aabbccdd
+ pabsdiffc.ob $f8, $f9[7]
+ ck_acc_ob 0x0001020304050607, 0x0000000000000000, 0x5544332211001122
+
+ writemsg "pabsdiffc.ob (cv)"
+ ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+ ld_ob $f8, 0x0001020304050607
+ pabsdiffc.ob $f8, 0x04
+ ck_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0403020100010203
+
+
+ pass
+
+ .end DIAG
--- /dev/null
+# MDMX .OB op tests.
+# mach: mips64 sb1
+# as: -mabi=eabi
+# as(mips64): -mabi=eabi -mdmx
+# ld: -N -Ttext=0x80010000
+# output: *\\npass\\n
+
+ .include "testutils.inc"
+ .include "utils-fpu.inc"
+ .include "utils-mdmx.inc"
+
+ setup
+
+ .set noreorder
+
+ .ent DIAG
+DIAG:
+
+ enable_mdmx
+
+
+ ###
+ ### Non-accumulator, non-CC-using .ob format ops.
+ ###
+ ### Key: v = vector
+ ### ev = vector of single element
+ ### cv = vector of constant.
+ ###
+
+
+ writemsg "add.ob (v)"
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x66778899aabbccdd
+ add.ob $f10, $f8, $f9
+ ck_ob $f10, 0x7799bbddffffffff
+
+ writemsg "add.ob (ev)"
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x66778899aabbccdd
+ add.ob $f10, $f8, $f9[6]
+ ck_ob $f10, 0x8899aabbccddeeff
+
+ writemsg "add.ob (cv)"
+ ld_ob $f8, 0x1122334455667788
+ add.ob $f10, $f8, 0x10
+ ck_ob $f10, 0x2132435465768798
+
+
+ writemsg "alni.ob"
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x66778899aabbccdd
+ alni.ob $f10, $f8, $f9, 3
+ ck_ob $f10, 0x4455667788667788
+
+
+ writemsg "alnv.ob"
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x66778899aabbccdd
+ li $4, 5
+ alnv.ob $f10, $f8, $f9, $4
+ ck_ob $f10, 0x66778866778899aa
+
+
+ writemsg "and.ob (v)"
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x66778899aabbccdd
+ and.ob $f10, $f8, $f9
+ ck_ob $f10, 0x0022000000224488
+
+ writemsg "and.ob (ev)"
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x66778899aabbccdd
+ and.ob $f10, $f8, $f9[4]
+ ck_ob $f10, 0x1100110011001188
+
+ writemsg "and.ob (cv)"
+ ld_ob $f8, 0x1122334455667788
+ and.ob $f10, $f8, 0x1e
+ ck_ob $f10, 0x1002120414061608
+
+
+ writemsg "max.ob (v)"
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x66778899aabbccdd
+ max.ob $f10, $f8, $f9
+ ck_ob $f10, 0x66778899aabbccdd
+
+ writemsg "max.ob (ev)"
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x66778899aabbccdd
+ max.ob $f10, $f8, $f9[7]
+ ck_ob $f10, 0x6666666666667788
+
+ writemsg "max.ob (cv)"
+ ld_ob $f8, 0x1122334455667788
+ max.ob $f10, $f8, 0x15
+ ck_ob $f10, 0x1522334455667788
+
+
+ writemsg "min.ob (v)"
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x66778899aabbccdd
+ min.ob $f10, $f8, $f9
+ ck_ob $f10, 0x1122334455667788
+
+ writemsg "min.ob (ev)"
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x66778899aabbccdd
+ min.ob $f10, $f8, $f9[7]
+ ck_ob $f10, 0x1122334455666666
+
+ writemsg "min.ob (cv)"
+ ld_ob $f8, 0x1122334455667788
+ min.ob $f10, $f8, 0x15
+ ck_ob $f10, 0x1115151515151515
+
+
+ writemsg "mul.ob (v)"
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x0001020304050607
+ mul.ob $f10, $f8, $f9
+ ck_ob $f10, 0x002266ccffffffff
+
+ writemsg "mul.ob (ev)"
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x0001020304050607
+ mul.ob $f10, $f8, $f9[4]
+ ck_ob $f10, 0x336699ccffffffff
+
+ writemsg "mul.ob (cv)"
+ ld_ob $f8, 0x1122334455667788
+ mul.ob $f10, $f8, 2
+ ck_ob $f10, 0x22446688aacceeff
+
+
+ writemsg "nor.ob (v)"
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x66778899aabbccdd
+ nor.ob $f10, $f8, $f9
+ ck_ob $f10, 0x8888442200000022
+
+ writemsg "nor.ob (ev)"
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x66778899aabbccdd
+ nor.ob $f10, $f8, $f9[6]
+ ck_ob $f10, 0x8888888888888800
+
+ writemsg "nor.ob (cv)"
+ ld_ob $f8, 0x1122334455667788
+ nor.ob $f10, $f8, 0x08
+ ck_ob $f10, 0xe6d5c4b3a2918077
+
+
+ writemsg "or.ob (v)"
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x66778899aabbccdd
+ or.ob $f10, $f8, $f9
+ ck_ob $f10, 0x7777bbddffffffdd
+
+ writemsg "or.ob (ev)"
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x66778899aabbccdd
+ or.ob $f10, $f8, $f9[6]
+ ck_ob $f10, 0x77777777777777ff
+
+ writemsg "or.ob (cv)"
+ ld_ob $f8, 0x1122334455667788
+ or.ob $f10, $f8, 0x08
+ ck_ob $f10, 0x192a3b4c5d6e7f88
+
+
+ writemsg "shfl.mixh.ob"
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x66778899aabbccdd
+ shfl.mixh.ob $f10, $f8, $f9
+ ck_ob $f10, 0x1166227733884499
+
+
+ writemsg "shfl.mixl.ob"
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x66778899aabbccdd
+ shfl.mixl.ob $f10, $f8, $f9
+ ck_ob $f10, 0x55aa66bb77cc88dd
+
+
+ writemsg "shfl.pach.ob"
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x66778899aabbccdd
+ shfl.pach.ob $f10, $f8, $f9
+ ck_ob $f10, 0x113355776688aacc
+
+
+ writemsg "shfl.upsl.ob"
+ ld_ob $f8, 0x1122334455667788
+ shfl.upsl.ob $f10, $f8, $f8
+ ck_ob $f10, 0x005500660077ff88
+
+
+ writemsg "sll.ob (v)"
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x0001020304050607
+ sll.ob $f10, $f8, $f9
+ ck_ob $f10, 0x1144cc2050c0c000
+
+ writemsg "sll.ob (ev)"
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x0001020304050607
+ sll.ob $f10, $f8, $f9[3]
+ ck_ob $f10, 0x1020304050607080
+
+ writemsg "sll.ob (cv)"
+ ld_ob $f8, 0x1122334455667788
+ sll.ob $f10, $f8, 1
+ ck_ob $f10, 0x22446688aaccee10
+
+
+ writemsg "srl.ob (v)"
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x0001020304050607
+ srl.ob $f10, $f8, $f9
+ ck_ob $f10, 0x11110c0805030101
+
+ writemsg "srl.ob (ev)"
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x0001020304050607
+ srl.ob $f10, $f8, $f9[3]
+ ck_ob $f10, 0x0102030405060708
+
+ writemsg "srl.ob (cv)"
+ ld_ob $f8, 0x1122334455667788
+ srl.ob $f10, $f8, 1
+ ck_ob $f10, 0x081119222a333b44
+
+
+ writemsg "sub.ob (v)"
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x0001020304050607
+ sub.ob $f10, $f8, $f9
+ ck_ob $f10, 0x1121314151617181
+
+ writemsg "sub.ob (ev)"
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x66778899aabbccdd
+ sub.ob $f10, $f8, $f9[7]
+ ck_ob $f10, 0x0000000000001122
+
+ writemsg "sub.ob (cv)"
+ ld_ob $f8, 0x1122334455667788
+ sub.ob $f10, $f8, 0x10
+ ck_ob $f10, 0x0112233445566778
+
+
+ writemsg "xor.ob (v)"
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x66778899aabbccdd
+ xor.ob $f10, $f8, $f9
+ ck_ob $f10, 0x7755bbddffddbb55
+
+ writemsg "xor.ob (ev)"
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x66778899aabbccdd
+ xor.ob $f10, $f8, $f9[6]
+ ck_ob $f10, 0x66554433221100ff
+
+ writemsg "xor.ob (cv)"
+ ld_ob $f8, 0x1122334455667788
+ xor.ob $f10, $f8, 0x08
+ ck_ob $f10, 0x192a3b4c5d6e7f80
+
+
+ ###
+ ### Accumulator .ob format ops (in order: rd/wr, math, scale/round)
+ ###
+ ### Key: v = vector
+ ### ev = vector of single element
+ ### cv = vector of constant.
+ ###
+
+
+ writemsg "wacl.ob / rac[hml].ob"
+ ld_ob $f8, 0x8001028304850687
+ ld_ob $f9, 0x1011121314151617
+ wacl.ob $f8, $f9
+ ck_acc_ob 0xff0000ff00ff00ff, 0x8001028304850687, 0x1011121314151617
+
+ # Note: relies on data left in accumulator by previous test.
+ writemsg "wach.ob / rac[hml].ob"
+ ld_ob $f8, 0x2021222324252627
+ wach.ob $f8
+ ck_acc_ob 0x2021222324252627, 0x8001028304850687, 0x1011121314151617
+
+
+ writemsg "adda.ob (v)"
+ ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x66778899aabbccdd
+ adda.ob $f8, $f9
+ ck_acc_ob 0x0001020304050607, 0x0000000000010101, 0x7799bbddff214365
+
+ writemsg "adda.ob (ev)"
+ ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x66778899aabbccdd
+ adda.ob $f8, $f9[2]
+ ck_acc_ob 0x0001020304050607, 0x0000000001010101, 0xccddeeff10213243
+
+ writemsg "adda.ob (cv)"
+ ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+ ld_ob $f8, 0x1122334455667788
+ adda.ob $f8, 0x1f
+ ck_acc_ob 0x0001020304050607, 0x0000000000000000, 0x30415263748596a7
+
+
+ writemsg "addl.ob (v)"
+ ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x66778899aabbccdd
+ addl.ob $f8, $f9
+ ck_acc_ob 0x0000000000000000, 0x0000000000010101, 0x7799bbddff214365
+
+ writemsg "addl.ob (ev)"
+ ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x66778899aabbccdd
+ addl.ob $f8, $f9[2]
+ ck_acc_ob 0x0000000000000000, 0x0000000001010101, 0xccddeeff10213243
+
+ writemsg "addl.ob (cv)"
+ ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+ ld_ob $f8, 0x1122334455667788
+ addl.ob $f8, 0x1f
+ ck_acc_ob 0x0000000000000000, 0x0000000000000000, 0x30415263748596a7
+
+
+ writemsg "mula.ob (v)"
+ ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x66778899aabbccdd
+ mula.ob $f8, $f9
+ ck_acc_ob 0x0001020304050607, 0x060f1b28384a5e75, 0xc6ce18a47282d468
+
+ writemsg "mula.ob (ev)"
+ ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x66778899aabbccdd
+ mula.ob $f8, $f9[2]
+ ck_acc_ob 0x0001020304050607, 0x0c1825313e4a5663, 0x6bd641ac1782ed58
+
+ writemsg "mula.ob (cv)"
+ ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+ ld_ob $f8, 0x1122334455667788
+ mula.ob $f8, 0x1f
+ ck_acc_ob 0x0001020304050607, 0x020406080a0c0e10, 0x0f1e2d3c4b5a6978
+
+
+ writemsg "mull.ob (v)"
+ ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x66778899aabbccdd
+ mull.ob $f8, $f9
+ ck_acc_ob 0x0000000000000000, 0x060f1b28384a5e75, 0xc6ce18a47282d468
+
+ writemsg "mull.ob (ev)"
+ ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x66778899aabbccdd
+ mull.ob $f8, $f9[2]
+ ck_acc_ob 0x0000000000000000, 0x0c1825313e4a5663, 0x6bd641ac1782ed58
+
+ writemsg "mull.ob (cv)"
+ ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+ ld_ob $f8, 0x1122334455667788
+ mull.ob $f8, 0x1f
+ ck_acc_ob 0x0000000000000000, 0x020406080a0c0e10, 0x0f1e2d3c4b5a6978
+
+
+ writemsg "muls.ob (v)"
+ ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x66778899aabbccdd
+ muls.ob $f8, $f9
+ ck_acc_ob 0xff00010203040506, 0xf9f0e4d7c7b5a18a, 0x3a32e85c8e7e2c98
+
+ writemsg "muls.ob (ev)"
+ ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x66778899aabbccdd
+ muls.ob $f8, $f9[2]
+ ck_acc_ob 0xff00010203040506, 0xf3e7dacec1b5a99c, 0x952abf54e97e13a8
+
+ writemsg "muls.ob (cv)"
+ ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+ ld_ob $f8, 0x1122334455667788
+ muls.ob $f8, 0x1f
+ ck_acc_ob 0xff00010203040506, 0xfdfbf9f7f5f3f1ef, 0xf1e2d3c4b5a69788
+
+
+ writemsg "mulsl.ob (v)"
+ ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x66778899aabbccdd
+ mulsl.ob $f8, $f9
+ ck_acc_ob 0xffffffffffffffff, 0xf9f0e4d7c7b5a18a, 0x3a32e85c8e7e2c98
+
+ writemsg "mulsl.ob (ev)"
+ ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x66778899aabbccdd
+ mulsl.ob $f8, $f9[2]
+ ck_acc_ob 0xffffffffffffffff, 0xf3e7dacec1b5a99c, 0x952abf54e97e13a8
+
+ writemsg "mulsl.ob (cv)"
+ ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+ ld_ob $f8, 0x1122334455667788
+ mulsl.ob $f8, 0x1f
+ ck_acc_ob 0xffffffffffffffff, 0xfdfbf9f7f5f3f1ef, 0xf1e2d3c4b5a69788
+
+
+ writemsg "suba.ob (v)"
+ ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x66778899aabbccdd
+ suba.ob $f8, $f9
+ ck_acc_ob 0xff00010203040506, 0xffffffffffffffff, 0xabababababababab
+
+ writemsg "suba.ob (ev)"
+ ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x66778899aabbccdd
+ suba.ob $f8, $f9[2]
+ ck_acc_ob 0xff00010203040506, 0xffffffffffffffff, 0x566778899aabbccd
+
+ writemsg "suba.ob (cv)"
+ ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+ ld_ob $f8, 0x1122334455667788
+ suba.ob $f8, 0x1f
+ ck_acc_ob 0xff01020304050607, 0xff00000000000000, 0xf203142536475869
+
+
+ writemsg "subl.ob (v)"
+ ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x66778899aabbccdd
+ subl.ob $f8, $f9
+ ck_acc_ob 0xffffffffffffffff, 0xffffffffffffffff, 0xabababababababab
+
+ writemsg "subl.ob (ev)"
+ ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+ ld_ob $f8, 0x1122334455667788
+ ld_ob $f9, 0x66778899aabbccdd
+ subl.ob $f8, $f9[2]
+ ck_acc_ob 0xffffffffffffffff, 0xffffffffffffffff, 0x566778899aabbccd
+
+ writemsg "subl.ob (cv)"
+ ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+ ld_ob $f8, 0x1122334455667788
+ subl.ob $f8, 0x1f
+ ck_acc_ob 0xff00000000000000, 0xff00000000000000, 0xf203142536475869
+
+
+ writemsg "rnau.ob (v)"
+ ld_acc_ob 0x0000000000000000, 0x0000000003030303, 0x40424446f8fafcfe
+ ld_ob $f8, 0x0001020304050607
+ rnau.ob $f9, $f8
+ ck_ob $f9, 0x4021110940201008
+
+ writemsg "rnau.ob (ev)"
+ ld_acc_ob 0x0000000000000000, 0x0000000003030303, 0x40424446f8fafcfe
+ ld_ob $f8, 0x0001020304050607
+ rnau.ob $f9, $f8[4]
+ ck_ob $f9, 0x080809097f7f8080
+
+ writemsg "rnau.ob (cv)"
+ ld_acc_ob 0x0000000000000000, 0x0000000003030303, 0x40424446f8fafcfe
+ rnau.ob $f9, 2
+ ck_ob $f9, 0x10111112feffffff
+
+
+ writemsg "rneu.ob (v)"
+ ld_acc_ob 0x0000000000000000, 0x0000000003030303, 0x40424446f8fafcfe
+ ld_ob $f8, 0x0001020304050607
+ rneu.ob $f9, $f8
+ ck_ob $f9, 0x4021110940201008
+
+ writemsg "rneu.ob (ev)"
+ ld_acc_ob 0x0000000000000000, 0x0000000003030303, 0x40424446f8fafcfe
+ ld_ob $f8, 0x0001020304050607
+ rneu.ob $f9, $f8[4]
+ ck_ob $f9, 0x080808097f7f8080
+
+ writemsg "rneu.ob (cv)"
+ ld_acc_ob 0x0000000000000000, 0x0000000003030303, 0x40424446f8fafcfe
+ rneu.ob $f9, 2
+ ck_ob $f9, 0x10101112fefeffff
+
+
+ writemsg "rzu.ob (v)"
+ ld_acc_ob 0x0000000000000000, 0x0000000003030303, 0x40424446f8fafcfe
+ ld_ob $f8, 0x0001020304050607
+ rzu.ob $f9, $f8
+ ck_ob $f9, 0x402111083f1f0f07
+
+ writemsg "rzu.ob (ev)"
+ ld_acc_ob 0x0000000000000000, 0x0000000003030303, 0x40424446f8fafcfe
+ ld_ob $f8, 0x0001020304050607
+ rzu.ob $f9, $f8[4]
+ ck_ob $f9, 0x080808087f7f7f7f
+
+ writemsg "rzu.ob (cv)"
+ ld_acc_ob 0x0000000000000000, 0x0000000003030303, 0x40424446f8fafcfe
+ rzu.ob $f9, 2
+ ck_ob $f9, 0x10101111fefeffff
+
+
+ ###
+ ### CC-using .ob format ops.
+ ###
+ ### Key: v = vector
+ ### ev = vector of single element
+ ### cv = vector of constant.
+ ###
+
+
+ writemsg "c.eq.ob (v)"
+ ld_ob $f8, 0x0001010202030304
+ ld_ob $f9, 0x0101020203030404
+ clr_fp_cc 0xff
+ c.eq.ob $f8, $f9
+ ck_fp_cc 0x55
+
+ writemsg "c.eq.ob (ev)"
+ ld_ob $f8, 0x0001010202030304
+ ld_ob $f9, 0x0101020203030404
+ clr_fp_cc 0xff
+ c.eq.ob $f8, $f9[5]
+ ck_fp_cc 0x18
+
+ writemsg "c.eq.ob (cv)"
+ ld_ob $f8, 0x0001010202030304
+ clr_fp_cc 0xff
+ c.eq.ob $f8, 0x03
+ ck_fp_cc 0x06
+
+
+ writemsg "c.le.ob (v)"
+ ld_ob $f8, 0x0001010202030304
+ ld_ob $f9, 0x0101020203030404
+ clr_fp_cc 0xff
+ c.le.ob $f8, $f9
+ ck_fp_cc 0xff
+
+ writemsg "c.le.ob (ev)"
+ ld_ob $f8, 0x0001010202030304
+ ld_ob $f9, 0x0101020203030404
+ clr_fp_cc 0xff
+ c.le.ob $f8, $f9[5]
+ ck_fp_cc 0xf8
+
+ writemsg "c.le.ob (cv)"
+ ld_ob $f8, 0x0001010202030304
+ clr_fp_cc 0xff
+ c.le.ob $f8, 0x03
+ ck_fp_cc 0xfe
+
+
+ writemsg "c.lt.ob (v)"
+ ld_ob $f8, 0x0001010202030304
+ ld_ob $f9, 0x0101020203030404
+ clr_fp_cc 0xff
+ c.lt.ob $f8, $f9
+ ck_fp_cc 0xaa
+
+ writemsg "c.lt.ob (ev)"
+ ld_ob $f8, 0x0001010202030304
+ ld_ob $f9, 0x0101020203030404
+ clr_fp_cc 0xff
+ c.lt.ob $f8, $f9[5]
+ ck_fp_cc 0xe0
+
+ writemsg "c.lt.ob (cv)"
+ ld_ob $f8, 0x0001010202030304
+ clr_fp_cc 0xff
+ c.lt.ob $f8, 0x03
+ ck_fp_cc 0xf8
+
+
+ writemsg "pickf.ob (v)"
+ ld_ob $f8, 0x0001020304050607
+ ld_ob $f9, 0x08090a0b0c0d0e0f
+ clrset_fp_cc 0xff, 0xaa
+ pickf.ob $f10, $f8, $f9
+ ck_ob $f10, 0x08010a030c050e07
+
+ writemsg "pickf.ob (ev)"
+ ld_ob $f8, 0x0001020304050607
+ ld_ob $f9, 0x08090a0b0c0d0e0f
+ clrset_fp_cc 0xff, 0xaa
+ pickf.ob $f10, $f8, $f9[4]
+ ck_ob $f10, 0x0b010b030b050b07
+
+ writemsg "pickf.ob (cv)"
+ ld_ob $f8, 0x0001020304050607
+ clrset_fp_cc 0xff, 0xaa
+ pickf.ob $f10, $f8, 0x10
+ ck_ob $f10, 0x1001100310051007
+
+
+ writemsg "pickt.ob (v)"
+ ld_ob $f8, 0x0001020304050607
+ ld_ob $f9, 0x08090a0b0c0d0e0f
+ clrset_fp_cc 0xff, 0xaa
+ pickt.ob $f10, $f8, $f9
+ ck_ob $f10, 0x0009020b040d060f
+
+ writemsg "pickt.ob (ev)"
+ ld_ob $f8, 0x0001020304050607
+ ld_ob $f9, 0x08090a0b0c0d0e0f
+ clrset_fp_cc 0xff, 0xaa
+ pickt.ob $f10, $f8, $f9[5]
+ ck_ob $f10, 0x000a020a040a060a
+
+ writemsg "pickt.ob (cv)"
+ ld_ob $f8, 0x0001020304050607
+ clrset_fp_cc 0xff, 0xaa
+ pickt.ob $f10, $f8, 0x10
+ ck_ob $f10, 0x0010021004100610
+
+
+ pass
+
+ .end DIAG
--- /dev/null
+# MIPS simulator testsuite FPU utility functions.
+# Copyright (C) 2004 Free Software Foundation, Inc.
+# Contributed by Chris Demetriou of Broadcom Corporation.
+#
+# This file is part of the GNU simulators.
+#
+# 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, 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. */
+
+ .macro enable_fpu fr
+ mfc0 $20, $12
+ or $20, $20, (1 << 29) | (\fr << 26)
+ mtc0 $20, $20
+ .endm
+
+ ###
+ ### Data movement macros
+ ###
+
+ .macro ld_fp_df r, v
+ .data
+1: .double \v
+ .previous
+ ldc1 \r, 1b
+ .endm
+
+ .macro ld_fp_di r, v
+ .data
+1: .dword \v
+ .previous
+ ldc1 \r, 1b
+ .endm
+
+ .macro ld_fp_sf r, v
+ .data
+1: .float \v
+ .previous
+ lwc1 \r, 1b
+ .endm
+
+ .macro ld_fp_si r, v
+ .data
+1: .word \v
+ .previous
+ lwc1 \r, 1b
+ .endm
+
+
+ ###
+ ### FP condition code manipulation macros
+ ###
+
+ .macro clrset_fp_cc clr, set
+ cfc1 $20, $31
+ or $20, $20, (((\clr & 0xfe) << 24) | ((\clr & 0x01) << 23))
+ xor $20, $20, (((\clr & 0xfe) << 24) | ((\clr & 0x01) << 23))
+ or $20, $20, (((\set & 0xfe) << 24) | ((\set & 0x01) << 23))
+ ctc1 $20, $31
+ .endm
+
+ .macro clr_fp_cc clr
+ clrset_fp_cc \clr, 0
+ .endm
+
+ .macro set_fp_cc set
+ clrset_fp_cc 0, \set
+ .endm
+
+ .macro get_fp_cc r
+ .set push
+ .set noat
+ cfc1 $1, $31
+ srl $1, $1, 23
+ andi \r, $1, 0x1fc
+ andi $1, $1, 0x1
+ srl \r, \r, 1
+ or \r, \r, $1
+ .set pop
+ .endm
+
+ .macro ck_fp_cc v
+ get_fp_cc $20
+ xori $20, $20, \v
+ bnez $20, _fail
+ nop
+ .endm
+
+ .macro ckm_fp_cc v, mask
+ get_fp_cc $20
+ xori $20, $20, \v
+ andi $20, $20, \mask
+ bnez $20, _fail
+ nop
+ .endm
--- /dev/null
+# MIPS simulator testsuite MDMX utility functions.
+# Copyright (C) 2004 Free Software Foundation, Inc.
+# Contributed by Chris Demetriou of Broadcom Corporation.
+#
+# This file is part of the GNU simulators.
+#
+# 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, 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 "utils-fpu.inc"
+
+ ###
+ ### Shared macros
+ ###
+
+ # Enable MDMX: enable the FPU w/ FR=1, then set Status.MX
+ .macro enable_mdmx
+ enable_fpu 1
+ mfc0 $20, $12
+ or $20, $20, (1 << 24)
+ mtc0 $20, $12
+ .endm
+
+
+ ###
+ ### .OB-format macros
+ ###
+
+ .macro ld_ob r, v
+ .data
+1: .dword \v
+ .previous
+ ldc1 \r, 1b
+ .endm
+
+ .macro ck_ob r, v
+ .data
+1: .dword \v
+ .previous
+ dmfc1 $20, \r
+ ld $21, 1b
+ bne $20, $21, _fail
+ nop
+ .endm
+
+ .macro ld_acc_ob h, m, l
+ ld_ob $f20, \m
+ ld_ob $f21, \l
+ wacl.ob $f20, $f21
+ ld_ob $f20, \h
+ wach.ob $f20
+ .endm
+
+ .macro ck_acc_ob h, m, l
+ rach.ob $f20
+ ck_ob $f20, \h
+ racm.ob $f20
+ ck_ob $f20, \m
+ racl.ob $f20
+ ck_ob $f20, \l
+ .endm
--- /dev/null
+# sh testcase for band, bor
+# mach: all
+# as(sh): -defsym sim_cpu=0
+# as(shdsp): -defsym sim_cpu=1 -dsp
+
+ .include "testutils.inc"
+
+ .align 2
+_x: .long 0xa5a5a5a5
+
+ start
+
+bandor_b_imm_disp12_reg:
+ set_grs_a5a5
+ # Make sure T is true to start.
+ sett
+
+ mov.l x, r1
+
+ band.b #0, @(3, r1)
+ bf8k mfail
+ bor.b #1, @(3, r1)
+ bf8k mfail
+ band.b #2, @(3, r1)
+ bf8k mfail
+ bor.b #3, @(3, r1)
+ bf8k mfail
+
+ bor.b #4, @(3, r1)
+ bf8k mfail
+ band.b #5, @(3, r1)
+ bf8k mfail
+ bor.b #6, @(3, r1)
+ bf8k mfail
+ band.b #7, @(3, r1)
+ bf8k mfail
+
+ band.b #0, @(2, r1)
+ bf8k mfail
+ bor.b #1, @(2, r1)
+ bf8k mfail
+ band.b #2, @(2, r1)
+ bf8k mfail
+ bor.b #3, @(2, r1)
+ bf8k mfail
+
+ bra .L2
+ nop
+
+ .align 2
+x: .long _x
+
+.L2:
+ bor.b #4, @(2, r1)
+ bf8k mfail
+ band.b #5, @(2, r1)
+ bf8k mfail
+ bor.b #6, @(2, r1)
+ bf8k mfail
+ band.b #7, @(2, r1)
+ bf8k mfail
+
+ band.b #0, @(1, r1)
+ bf8k mfail
+ bor.b #1, @(1, r1)
+ bf8k mfail
+ band.b #2, @(1, r1)
+ bf8k mfail
+ bor.b #3, @(1, r1)
+ bf8k mfail
+
+ bor.b #4, @(1, r1)
+ bf8k mfail
+ band.b #5, @(1, r1)
+ bf8k mfail
+ bor.b #6, @(1, r1)
+ bf8k mfail
+ band.b #7, @(1, r1)
+ bf8k mfail
+
+ band.b #0, @(0, r1)
+ bf8k mfail
+ bor.b #1, @(0, r1)
+ bf8k mfail
+ band.b #2, @(0, r1)
+ bf8k mfail
+ bor.b #3, @(0, r1)
+ bf8k mfail
+
+ bor.b #4, @(0, r1)
+ bf8k mfail
+ band.b #5, @(0, r1)
+ bf8k mfail
+ bor.b #6, @(0, r1)
+ bf8k mfail
+ band.b #7, @(0, r1)
+ bf8k mfail
+
+ assertreg _x, r1
+
+ test_gr_a5a5 r0
+ test_gr_a5a5 r2
+ test_gr_a5a5 r3
+ test_gr_a5a5 r4
+ test_gr_a5a5 r5
+ test_gr_a5a5 r6
+ test_gr_a5a5 r7
+ test_gr_a5a5 r8
+ test_gr_a5a5 r9
+ test_gr_a5a5 r10
+ test_gr_a5a5 r11
+ test_gr_a5a5 r12
+ test_gr_a5a5 r13
+ test_gr_a5a5 r14
+
+ pass
+
+ exit 0
+
+
--- /dev/null
+# sh testcase for bandnot, bornot
+# mach: all
+# as(sh): -defsym sim_cpu=0
+# as(shdsp): -defsym sim_cpu=1 -dsp
+
+ .include "testutils.inc"
+
+ .align 2
+_x: .long 0xa5a5a5a5
+
+ start
+
+bandor_b_imm_disp12_reg:
+ set_grs_a5a5
+ # Make sure T is true to start.
+ sett
+
+ mov.l x, r1
+
+ bandnot.b #0, @(3, r1)
+ bt8k mfail
+ bornot.b #1, @(3, r1)
+ bf8k mfail
+ bandnot.b #2, @(3, r1)
+ bt8k mfail
+ bornot.b #3, @(3, r1)
+ bf8k mfail
+
+ bornot.b #4, @(3, r1)
+ bf8k mfail
+ bandnot.b #5, @(3, r1)
+ bt8k mfail
+ bornot.b #6, @(3, r1)
+ bf8k mfail
+ bandnot.b #7, @(3, r1)
+ bt8k mfail
+
+ bandnot.b #0, @(2, r1)
+ bt8k mfail
+ bornot.b #1, @(2, r1)
+ bf8k mfail
+ bandnot.b #2, @(2, r1)
+ bt8k mfail
+ bornot.b #3, @(2, r1)
+ bf8k mfail
+
+ bra .L2
+ nop
+
+ .align 2
+x: .long _x
+
+.L2:
+ bornot.b #4, @(2, r1)
+ bf8k mfail
+ bandnot.b #5, @(2, r1)
+ bt8k mfail
+ bornot.b #6, @(2, r1)
+ bf8k mfail
+ bandnot.b #7, @(2, r1)
+ bt8k mfail
+
+ bandnot.b #0, @(1, r1)
+ bt8k mfail
+ bornot.b #1, @(1, r1)
+ bf8k mfail
+ bandnot.b #2, @(1, r1)
+ bt8k mfail
+ bornot.b #3, @(1, r1)
+ bf8k mfail
+
+ bornot.b #4, @(1, r1)
+ bf8k mfail
+ bandnot.b #5, @(1, r1)
+ bt8k mfail
+ bornot.b #6, @(1, r1)
+ bf8k mfail
+ bandnot.b #7, @(1, r1)
+ bt8k mfail
+
+ bandnot.b #0, @(0, r1)
+ bt8k mfail
+ bornot.b #1, @(0, r1)
+ bf8k mfail
+ bandnot.b #2, @(0, r1)
+ bt8k mfail
+ bornot.b #3, @(0, r1)
+ bf8k mfail
+
+ bornot.b #4, @(0, r1)
+ bf8k mfail
+ bandnot.b #5, @(0, r1)
+ bt8k mfail
+ bornot.b #6, @(0, r1)
+ bf8k mfail
+ bandnot.b #7, @(0, r1)
+ bt8k mfail
+
+ assertreg _x, r1
+
+ test_gr_a5a5 r0
+ test_gr_a5a5 r2
+ test_gr_a5a5 r3
+ test_gr_a5a5 r4
+ test_gr_a5a5 r5
+ test_gr_a5a5 r6
+ test_gr_a5a5 r7
+ test_gr_a5a5 r8
+ test_gr_a5a5 r9
+ test_gr_a5a5 r10
+ test_gr_a5a5 r11
+ test_gr_a5a5 r12
+ test_gr_a5a5 r13
+ test_gr_a5a5 r14
+
+ pass
+
+ exit 0
+
+
--- /dev/null
+# sh testcase for bclr
+# mach: all
+# as(sh): -defsym sim_cpu=0
+# as(shdsp): -defsym sim_cpu=1 -dsp
+
+ .include "testutils.inc"
+
+ .align 2
+_x: .long 0xffffffff
+_y: .long 0x55555555
+
+ start
+
+bclr_b_imm_disp12_reg:
+ set_grs_a5a5
+ mov.l x, r1
+
+ bclr.b #0, @(3, r1)
+ assertmem _x, 0xfffffffe
+ bclr.b #1, @(3, r1)
+ assertmem _x, 0xfffffffc
+ bclr.b #2, @(3, r1)
+ assertmem _x, 0xfffffff8
+ bclr.b #3, @(3, r1)
+ assertmem _x, 0xfffffff0
+
+ bclr.b #4, @(3, r1)
+ assertmem _x, 0xffffffe0
+ bclr.b #5, @(3, r1)
+ assertmem _x, 0xffffffc0
+ bclr.b #6, @(3, r1)
+ assertmem _x, 0xffffff80
+ bclr.b #7, @(3, r1)
+ assertmem _x, 0xffffff00
+
+ bclr.b #0, @(2, r1)
+ assertmem _x, 0xfffffe00
+ bclr.b #1, @(2, r1)
+ assertmem _x, 0xfffffc00
+ bclr.b #2, @(2, r1)
+ assertmem _x, 0xfffff800
+ bclr.b #3, @(2, r1)
+ assertmem _x, 0xfffff000
+
+ bra .L2
+ nop
+
+ .align 2
+x: .long _x
+y: .long _y
+
+.L2:
+ bclr.b #4, @(2, r1)
+ assertmem _x, 0xffffe000
+ bclr.b #5, @(2, r1)
+ assertmem _x, 0xffffc000
+ bclr.b #6, @(2, r1)
+ assertmem _x, 0xffff8000
+ bclr.b #7, @(2, r1)
+ assertmem _x, 0xffff0000
+
+ bclr.b #0, @(1, r1)
+ assertmem _x, 0xfffe0000
+ bclr.b #1, @(1, r1)
+ assertmem _x, 0xfffc0000
+ bclr.b #2, @(1, r1)
+ assertmem _x, 0xfff80000
+ bclr.b #3, @(1, r1)
+ assertmem _x, 0xfff00000
+
+ bclr.b #4, @(1, r1)
+ assertmem _x, 0xffe00000
+ bclr.b #5, @(1, r1)
+ assertmem _x, 0xffc00000
+ bclr.b #6, @(1, r1)
+ assertmem _x, 0xff800000
+ bclr.b #7, @(1, r1)
+ assertmem _x, 0xff000000
+
+ bclr.b #0, @(0, r1)
+ assertmem _x, 0xfe000000
+ bclr.b #1, @(0, r1)
+ assertmem _x, 0xfc000000
+ bclr.b #2, @(0, r1)
+ assertmem _x, 0xf8000000
+ bclr.b #3, @(0, r1)
+ assertmem _x, 0xf0000000
+
+ bclr.b #4, @(0, r1)
+ assertmem _x, 0xe0000000
+ bclr.b #5, @(0, r1)
+ assertmem _x, 0xc0000000
+ bclr.b #6, @(0, r1)
+ assertmem _x, 0x80000000
+ bclr.b #7, @(0, r1)
+ assertmem _x, 0x00000000
+
+ assertreg _x, r1
+
+bclr_imm_reg:
+ set_greg 0xff, r1
+ bclr #0, r1
+ assertreg 0xfe, r1
+ bclr #1, r1
+ assertreg 0xfc, r1
+ bclr #2, r1
+ assertreg 0xf8, r1
+ bclr #3, r1
+ assertreg 0xf0, r1
+
+ bclr #4, r1
+ assertreg 0xe0, r1
+ bclr #5, r1
+ assertreg 0xc0, r1
+ bclr #6, r1
+ assertreg 0x80, r1
+ bclr #7, r1
+ assertreg 0x00, r1
+
+ test_gr_a5a5 r0
+ test_gr_a5a5 r2
+ test_gr_a5a5 r3
+ test_gr_a5a5 r4
+ test_gr_a5a5 r5
+ test_gr_a5a5 r6
+ test_gr_a5a5 r7
+ test_gr_a5a5 r8
+ test_gr_a5a5 r9
+ test_gr_a5a5 r10
+ test_gr_a5a5 r11
+ test_gr_a5a5 r12
+ test_gr_a5a5 r13
+ test_gr_a5a5 r14
+
+ pass
+
+ exit 0
+
+
--- /dev/null
+# sh testcase for bld
+# mach: all
+# as(sh): -defsym sim_cpu=0
+# as(shdsp): -defsym sim_cpu=1 -dsp
+
+ .include "testutils.inc"
+
+ .align 2
+_x: .long 0xa5a5a5a5
+_y: .long 0x55555555
+
+ start
+
+bld_b_imm_disp12_reg:
+ set_grs_a5a5
+ mov.l x, r1
+
+ bld.b #0, @(0, r1)
+ bf8k mfail
+ bld.b #1, @(0, r1)
+ bt8k mfail
+ bld.b #2, @(0, r1)
+ bf8k mfail
+ bld.b #3, @(0, r1)
+ bt8k mfail
+
+ bld.b #4, @(0, r1)
+ bt8k mfail
+ bld.b #5, @(0, r1)
+ bf8k mfail
+ bld.b #6, @(0, r1)
+ bt8k mfail
+ bld.b #7, @(0, r1)
+ bf8k mfail
+
+ bld.b #0, @(1, r1)
+ bf8k mfail
+ bld.b #1, @(1, r1)
+ bt8k mfail
+ bld.b #2, @(1, r1)
+ bf8k mfail
+ bld.b #3, @(1, r1)
+ bt8k mfail
+
+ bld.b #4, @(1, r1)
+ bt8k mfail
+ bld.b #5, @(1, r1)
+ bf8k mfail
+ bld.b #6, @(1, r1)
+ bt8k mfail
+ bld.b #7, @(1, r1)
+ bf8k mfail
+
+ bld.b #0, @(2, r1)
+ bf8k mfail
+ bld.b #1, @(2, r1)
+ bt8k mfail
+ bld.b #2, @(2, r1)
+ bf8k mfail
+ bld.b #3, @(2, r1)
+ bt8k mfail
+
+ bld.b #4, @(2, r1)
+ bt8k mfail
+ bld.b #5, @(2, r1)
+ bf8k mfail
+ bld.b #6, @(2, r1)
+ bt8k mfail
+ bld.b #7, @(2, r1)
+ bf8k mfail
+
+ bld.b #0, @(3, r1)
+ bf8k mfail
+ bld.b #1, @(3, r1)
+ bt8k mfail
+ bld.b #2, @(3, r1)
+ bf8k mfail
+ bld.b #3, @(3, r1)
+ bt8k mfail
+
+ bld.b #4, @(3, r1)
+ bt8k mfail
+ bld.b #5, @(3, r1)
+ bf8k mfail
+ bld.b #6, @(3, r1)
+ bt8k mfail
+ bld.b #7, @(3, r1)
+ bf8k mfail
+
+ assertreg _x, r1
+
+bld_imm_reg:
+ set_greg 0xa5a5a5a5, r1
+ bld #0, r1
+ bf8k mfail
+ bld #1, r1
+ bt8k mfail
+ bld #2, r1
+ bf8k mfail
+ bld #3, r1
+ bt8k mfail
+
+ bld #4, r1
+ bt8k mfail
+ bld #5, r1
+ bf8k mfail
+ bld #6, r1
+ bt8k mfail
+ bld #7, r1
+ bf8k mfail
+
+ test_grs_a5a5
+
+ pass
+
+ exit 0
+
+ .align 2
+x: .long _x
+y: .long _y
+
--- /dev/null
+# sh testcase for bldnot
+# mach: all
+# as(sh): -defsym sim_cpu=0
+# as(shdsp): -defsym sim_cpu=1 -dsp
+
+ .include "testutils.inc"
+
+ .align 2
+_x: .long 0xa5a5a5a5
+_y: .long 0x55555555
+
+ start
+
+bldnot_b_imm_disp12_reg:
+ set_grs_a5a5
+ mov.l x, r1
+
+ bldnot.b #0, @(0, r1)
+ bt8k mfail
+ bldnot.b #1, @(0, r1)
+ bf8k mfail
+ bldnot.b #2, @(0, r1)
+ bt8k mfail
+ bldnot.b #3, @(0, r1)
+ bf8k mfail
+
+ bldnot.b #4, @(0, r1)
+ bf8k mfail
+ bldnot.b #5, @(0, r1)
+ bt8k mfail
+ bldnot.b #6, @(0, r1)
+ bf8k mfail
+ bldnot.b #7, @(0, r1)
+ bt8k mfail
+
+ bldnot.b #0, @(1, r1)
+ bt8k mfail
+ bldnot.b #1, @(1, r1)
+ bf8k mfail
+ bldnot.b #2, @(1, r1)
+ bt8k mfail
+ bldnot.b #3, @(1, r1)
+ bf8k mfail
+
+ bldnot.b #4, @(1, r1)
+ bf8k mfail
+ bldnot.b #5, @(1, r1)
+ bt8k mfail
+ bldnot.b #6, @(1, r1)
+ bf8k mfail
+ bldnot.b #7, @(1, r1)
+ bt8k mfail
+
+ bldnot.b #0, @(2, r1)
+ bt8k mfail
+ bldnot.b #1, @(2, r1)
+ bf8k mfail
+ bldnot.b #2, @(2, r1)
+ bt8k mfail
+ bldnot.b #3, @(2, r1)
+ bf8k mfail
+
+ bldnot.b #4, @(2, r1)
+ bf8k mfail
+ bldnot.b #5, @(2, r1)
+ bt8k mfail
+ bldnot.b #6, @(2, r1)
+ bf8k mfail
+ bldnot.b #7, @(2, r1)
+ bt8k mfail
+
+ bldnot.b #0, @(3, r1)
+ bt8k mfail
+ bldnot.b #1, @(3, r1)
+ bf8k mfail
+ bldnot.b #2, @(3, r1)
+ bt8k mfail
+ bldnot.b #3, @(3, r1)
+ bf8k mfail
+
+ bldnot.b #4, @(3, r1)
+ bf8k mfail
+ bldnot.b #5, @(3, r1)
+ bt8k mfail
+ bldnot.b #6, @(3, r1)
+ bf8k mfail
+ bldnot.b #7, @(3, r1)
+ bt8k mfail
+
+ assertreg _x, r1
+ set_greg 0xa5a5a5a5, r1
+
+ test_grs_a5a5
+
+ pass
+
+ exit 0
+
+ .align 2
+x: .long _x
+y: .long _y
+
--- /dev/null
+# sh testcase for bset
+# mach: all
+# as(sh): -defsym sim_cpu=0
+# as(shdsp): -defsym sim_cpu=1 -dsp
+
+ .include "testutils.inc"
+
+ .align 2
+_x: .long 0
+_y: .long 0x55555555
+
+ start
+
+bset_b_imm_disp12_reg:
+ set_grs_a5a5
+ mov.l x, r1
+
+ bset.b #0, @(3, r1)
+ assertmem _x, 0x1
+ bset.b #1, @(3, r1)
+ assertmem _x, 0x3
+ bset.b #2, @(3, r1)
+ assertmem _x, 0x7
+ bset.b #3, @(3, r1)
+ assertmem _x, 0xf
+
+ bset.b #4, @(3, r1)
+ assertmem _x, 0x1f
+ bset.b #5, @(3, r1)
+ assertmem _x, 0x3f
+ bset.b #6, @(3, r1)
+ assertmem _x, 0x7f
+ bset.b #7, @(3, r1)
+ assertmem _x, 0xff
+
+ bset.b #0, @(2, r1)
+ assertmem _x, 0x1ff
+ bset.b #1, @(2, r1)
+ assertmem _x, 0x3ff
+ bset.b #2, @(2, r1)
+ assertmem _x, 0x7ff
+ bset.b #3, @(2, r1)
+ assertmem _x, 0xfff
+
+ bra .L2
+ nop
+
+ .align 2
+x: .long _x
+y: .long _y
+
+.L2:
+ bset.b #4, @(2, r1)
+ assertmem _x, 0x1fff
+ bset.b #5, @(2, r1)
+ assertmem _x, 0x3fff
+ bset.b #6, @(2, r1)
+ assertmem _x, 0x7fff
+ bset.b #7, @(2, r1)
+ assertmem _x, 0xffff
+
+ bset.b #0, @(1, r1)
+ assertmem _x, 0x1ffff
+ bset.b #1, @(1, r1)
+ assertmem _x, 0x3ffff
+ bset.b #2, @(1, r1)
+ assertmem _x, 0x7ffff
+ bset.b #3, @(1, r1)
+ assertmem _x, 0xfffff
+
+ bset.b #4, @(1, r1)
+ assertmem _x, 0x1fffff
+ bset.b #5, @(1, r1)
+ assertmem _x, 0x3fffff
+ bset.b #6, @(1, r1)
+ assertmem _x, 0x7fffff
+ bset.b #7, @(1, r1)
+ assertmem _x, 0xffffff
+
+ bset.b #0, @(0, r1)
+ assertmem _x, 0x1ffffff
+ bset.b #1, @(0, r1)
+ assertmem _x, 0x3ffffff
+ bset.b #2, @(0, r1)
+ assertmem _x, 0x7ffffff
+ bset.b #3, @(0, r1)
+ assertmem _x, 0xfffffff
+
+ bset.b #4, @(0, r1)
+ assertmem _x, 0x1fffffff
+ bset.b #5, @(0, r1)
+ assertmem _x, 0x3fffffff
+ bset.b #6, @(0, r1)
+ assertmem _x, 0x7fffffff
+ bset.b #7, @(0, r1)
+ assertmem _x, 0xffffffff
+
+ assertreg _x, r1
+
+bset_imm_reg:
+ set_greg 0, r1
+ bset #0, r1
+ assertreg 0x1, r1
+ bset #1, r1
+ assertreg 0x3, r1
+ bset #2, r1
+ assertreg 0x7, r1
+ bset #3, r1
+ assertreg 0xf, r1
+
+ bset #4, r1
+ assertreg 0x1f, r1
+ bset #5, r1
+ assertreg 0x3f, r1
+ bset #6, r1
+ assertreg 0x7f, r1
+ bset #7, r1
+ assertreg 0xff, r1
+
+ test_gr_a5a5 r0
+ test_gr_a5a5 r2
+ test_gr_a5a5 r3
+ test_gr_a5a5 r4
+ test_gr_a5a5 r5
+ test_gr_a5a5 r6
+ test_gr_a5a5 r7
+ test_gr_a5a5 r8
+ test_gr_a5a5 r9
+ test_gr_a5a5 r10
+ test_gr_a5a5 r11
+ test_gr_a5a5 r12
+ test_gr_a5a5 r13
+ test_gr_a5a5 r14
+
+ pass
+
+ exit 0
+
+
--- /dev/null
+# sh testcase for bst
+# mach: all
+# as(sh): -defsym sim_cpu=0
+# as(shdsp): -defsym sim_cpu=1 -dsp
+
+ .include "testutils.inc"
+
+ .align 2
+_x: .long 0
+_y: .long 0x55555555
+
+ start
+
+bst_b_imm_disp12_reg:
+ set_grs_a5a5
+ # Make sure T is true to start.
+ sett
+
+ mov.l x, r1
+
+ bst.b #0, @(3, r1)
+ assertmem _x, 0x1
+ bst.b #1, @(3, r1)
+ assertmem _x, 0x3
+ bst.b #2, @(3, r1)
+ assertmem _x, 0x7
+ bst.b #3, @(3, r1)
+ assertmem _x, 0xf
+
+ bst.b #4, @(3, r1)
+ assertmem _x, 0x1f
+ bst.b #5, @(3, r1)
+ assertmem _x, 0x3f
+ bst.b #6, @(3, r1)
+ assertmem _x, 0x7f
+ bst.b #7, @(3, r1)
+ assertmem _x, 0xff
+
+ bst.b #0, @(2, r1)
+ assertmem _x, 0x1ff
+ bst.b #1, @(2, r1)
+ assertmem _x, 0x3ff
+ bst.b #2, @(2, r1)
+ assertmem _x, 0x7ff
+ bst.b #3, @(2, r1)
+ assertmem _x, 0xfff
+
+ bra .L2
+ nop
+
+ .align 2
+x: .long _x
+y: .long _y
+
+.L2:
+ bst.b #4, @(2, r1)
+ assertmem _x, 0x1fff
+ bst.b #5, @(2, r1)
+ assertmem _x, 0x3fff
+ bst.b #6, @(2, r1)
+ assertmem _x, 0x7fff
+ bst.b #7, @(2, r1)
+ assertmem _x, 0xffff
+
+ bst.b #0, @(1, r1)
+ assertmem _x, 0x1ffff
+ bst.b #1, @(1, r1)
+ assertmem _x, 0x3ffff
+ bst.b #2, @(1, r1)
+ assertmem _x, 0x7ffff
+ bst.b #3, @(1, r1)
+ assertmem _x, 0xfffff
+
+ bst.b #4, @(1, r1)
+ assertmem _x, 0x1fffff
+ bst.b #5, @(1, r1)
+ assertmem _x, 0x3fffff
+ bst.b #6, @(1, r1)
+ assertmem _x, 0x7fffff
+ bst.b #7, @(1, r1)
+ assertmem _x, 0xffffff
+
+ bst.b #0, @(0, r1)
+ assertmem _x, 0x1ffffff
+ bst.b #1, @(0, r1)
+ assertmem _x, 0x3ffffff
+ bst.b #2, @(0, r1)
+ assertmem _x, 0x7ffffff
+ bst.b #3, @(0, r1)
+ assertmem _x, 0xfffffff
+
+ bst.b #4, @(0, r1)
+ assertmem _x, 0x1fffffff
+ bst.b #5, @(0, r1)
+ assertmem _x, 0x3fffffff
+ bst.b #6, @(0, r1)
+ assertmem _x, 0x7fffffff
+ bst.b #7, @(0, r1)
+ assertmem _x, 0xffffffff
+
+ assertreg _x, r1
+
+bst_imm_reg:
+ set_greg 0, r1
+ bst #0, r1
+ assertreg 0x1, r1
+ bst #1, r1
+ assertreg 0x3, r1
+ bst #2, r1
+ assertreg 0x7, r1
+ bst #3, r1
+ assertreg 0xf, r1
+
+ bst #4, r1
+ assertreg 0x1f, r1
+ bst #5, r1
+ assertreg 0x3f, r1
+ bst #6, r1
+ assertreg 0x7f, r1
+ bst #7, r1
+ assertreg 0xff, r1
+
+ test_gr_a5a5 r0
+ test_gr_a5a5 r2
+ test_gr_a5a5 r3
+ test_gr_a5a5 r4
+ test_gr_a5a5 r5
+ test_gr_a5a5 r6
+ test_gr_a5a5 r7
+ test_gr_a5a5 r8
+ test_gr_a5a5 r9
+ test_gr_a5a5 r10
+ test_gr_a5a5 r11
+ test_gr_a5a5 r12
+ test_gr_a5a5 r13
+ test_gr_a5a5 r14
+
+ pass
+
+ exit 0
+
+
--- /dev/null
+# sh testcase for bxor
+# mach: all
+# as(sh): -defsym sim_cpu=0
+# as(shdsp): -defsym sim_cpu=1 -dsp
+
+ .include "testutils.inc"
+
+ .align 2
+_x: .long 0xa5a5a5a5
+
+ start
+
+bxor_b_imm_disp12_reg:
+ set_grs_a5a5
+ # Make sure T is true to start.
+ sett
+
+ mov.l x, r1
+
+ bxor.b #0, @(3, r1)
+ bt8k mfail
+ bxor.b #1, @(3, r1)
+ bt8k mfail
+ bxor.b #2, @(3, r1)
+ bf8k mfail
+ bxor.b #3, @(3, r1)
+ bf8k mfail
+
+ bxor.b #4, @(3, r1)
+ bf8k mfail
+ bxor.b #5, @(3, r1)
+ bt8k mfail
+ bxor.b #6, @(3, r1)
+ bt8k mfail
+ bxor.b #7, @(3, r1)
+ bf8k mfail
+
+ bxor.b #0, @(2, r1)
+ bt8k mfail
+ bxor.b #1, @(2, r1)
+ bt8k mfail
+ bxor.b #2, @(2, r1)
+ bf8k mfail
+ bxor.b #3, @(2, r1)
+ bf8k mfail
+
+ bra .L2
+ nop
+
+ .align 2
+x: .long _x
+
+.L2:
+ bxor.b #4, @(2, r1)
+ bf8k mfail
+ bxor.b #5, @(2, r1)
+ bt8k mfail
+ bxor.b #6, @(2, r1)
+ bt8k mfail
+ bxor.b #7, @(2, r1)
+ bf8k mfail
+
+ bxor.b #0, @(1, r1)
+ bt8k mfail
+ bxor.b #1, @(1, r1)
+ bt8k mfail
+ bxor.b #2, @(1, r1)
+ bf8k mfail
+ bxor.b #3, @(1, r1)
+ bf8k mfail
+
+ bxor.b #4, @(1, r1)
+ bf8k mfail
+ bxor.b #5, @(1, r1)
+ bt8k mfail
+ bxor.b #6, @(1, r1)
+ bt8k mfail
+ bxor.b #7, @(1, r1)
+ bf8k mfail
+
+ bxor.b #0, @(0, r1)
+ bt8k mfail
+ bxor.b #1, @(0, r1)
+ bt8k mfail
+ bxor.b #2, @(0, r1)
+ bf8k mfail
+ bxor.b #3, @(0, r1)
+ bf8k mfail
+
+ bxor.b #4, @(0, r1)
+ bf8k mfail
+ bxor.b #5, @(0, r1)
+ bt8k mfail
+ bxor.b #6, @(0, r1)
+ bt8k mfail
+ bxor.b #7, @(0, r1)
+ bf8k mfail
+
+ assertreg _x, r1
+
+ test_gr_a5a5 r0
+ test_gr_a5a5 r2
+ test_gr_a5a5 r3
+ test_gr_a5a5 r4
+ test_gr_a5a5 r5
+ test_gr_a5a5 r6
+ test_gr_a5a5 r7
+ test_gr_a5a5 r8
+ test_gr_a5a5 r9
+ test_gr_a5a5 r10
+ test_gr_a5a5 r11
+ test_gr_a5a5 r12
+ test_gr_a5a5 r13
+ test_gr_a5a5 r14
+
+ pass
+
+ exit 0
+
+
--- /dev/null
+# sh testcase for clips, clipu
+# mach: all
+# as(sh): -defsym sim_cpu=0
+# as(shdsp): -defsym sim_cpu=1 -dsp
+
+ .include "testutils.inc"
+
+ start
+
+clips_b:
+ set_grs_a5a5
+ clips.b r1
+ test_gr0_a5a5
+ assertreg 0xffffff80 r1
+ test_gr_a5a5 r2
+ test_gr_a5a5 r3
+ test_gr_a5a5 r4
+ test_gr_a5a5 r5
+ test_gr_a5a5 r6
+ test_gr_a5a5 r7
+ test_gr_a5a5 r8
+ test_gr_a5a5 r9
+ test_gr_a5a5 r10
+ test_gr_a5a5 r11
+ test_gr_a5a5 r12
+ test_gr_a5a5 r13
+ test_gr_a5a5 r14
+
+clipu_b:
+ set_grs_a5a5
+ clipu.b r1
+ test_gr0_a5a5
+ assertreg 0xff r1
+ test_gr_a5a5 r2
+ test_gr_a5a5 r3
+ test_gr_a5a5 r4
+ test_gr_a5a5 r5
+ test_gr_a5a5 r6
+ test_gr_a5a5 r7
+ test_gr_a5a5 r8
+ test_gr_a5a5 r9
+ test_gr_a5a5 r10
+ test_gr_a5a5 r11
+ test_gr_a5a5 r12
+ test_gr_a5a5 r13
+ test_gr_a5a5 r14
+
+clips_w:
+ set_grs_a5a5
+ clips.w r1
+ test_gr0_a5a5
+ assertreg 0xffff8000 r1
+ test_gr_a5a5 r2
+ test_gr_a5a5 r3
+ test_gr_a5a5 r4
+ test_gr_a5a5 r5
+ test_gr_a5a5 r6
+ test_gr_a5a5 r7
+ test_gr_a5a5 r8
+ test_gr_a5a5 r9
+ test_gr_a5a5 r10
+ test_gr_a5a5 r11
+ test_gr_a5a5 r12
+ test_gr_a5a5 r13
+ test_gr_a5a5 r14
+
+clipu_w:
+ set_grs_a5a5
+ clipu.w r1
+ test_gr0_a5a5
+ assertreg 0xffff r1
+ test_gr_a5a5 r2
+ test_gr_a5a5 r3
+ test_gr_a5a5 r4
+ test_gr_a5a5 r5
+ test_gr_a5a5 r6
+ test_gr_a5a5 r7
+ test_gr_a5a5 r8
+ test_gr_a5a5 r9
+ test_gr_a5a5 r10
+ test_gr_a5a5 r11
+ test_gr_a5a5 r12
+ test_gr_a5a5 r13
+ test_gr_a5a5 r14
+
+ pass
+
+ exit 0
+
--- /dev/null
+# sh testcase for divs and divu
+# mach: all
+# as(sh): -defsym sim_cpu=0
+# as(shdsp): -defsym sim_cpu=1 -dsp
+
+ .include "testutils.inc"
+
+ start
+
+divs_1: ! divide by one
+ set_grs_a5a5
+ mov #1, r0
+ divs r0, r1
+ assertreg0 1
+ test_gr_a5a5 r1
+ test_gr_a5a5 r2
+ test_gr_a5a5 r3
+ test_gr_a5a5 r4
+ test_gr_a5a5 r5
+ test_gr_a5a5 r6
+ test_gr_a5a5 r7
+ test_gr_a5a5 r8
+ test_gr_a5a5 r9
+ test_gr_a5a5 r10
+ test_gr_a5a5 r11
+ test_gr_a5a5 r12
+ test_gr_a5a5 r13
+ test_gr_a5a5 r14
+
+divs_2: ! divide by two
+ set_grs_a5a5
+ mov #2, r0
+ divs r0, r1
+ assertreg0 2
+ assertreg 0xd2d2d2d3, r1
+ test_gr_a5a5 r2
+ test_gr_a5a5 r3
+ test_gr_a5a5 r4
+ test_gr_a5a5 r5
+ test_gr_a5a5 r6
+ test_gr_a5a5 r7
+ test_gr_a5a5 r8
+ test_gr_a5a5 r9
+ test_gr_a5a5 r10
+ test_gr_a5a5 r11
+ test_gr_a5a5 r12
+ test_gr_a5a5 r13
+ test_gr_a5a5 r14
+
+divs_3: ! divide by three
+ set_grs_a5a5
+ mov #3, r0
+ divs r0, r1
+ assertreg0 3
+ assertreg 0xe1e1e1e2, r1
+ test_gr_a5a5 r2
+ test_gr_a5a5 r3
+ test_gr_a5a5 r4
+ test_gr_a5a5 r5
+ test_gr_a5a5 r6
+ test_gr_a5a5 r7
+ test_gr_a5a5 r8
+ test_gr_a5a5 r9
+ test_gr_a5a5 r10
+ test_gr_a5a5 r11
+ test_gr_a5a5 r12
+ test_gr_a5a5 r13
+ test_gr_a5a5 r14
+
+divs_0: ! divide by zero
+ set_grs_a5a5
+ mov #0, r0
+ divs r0, r1
+ assertreg0 0
+ assertreg 0x7fffffff, r1
+ test_gr_a5a5 r2
+ test_gr_a5a5 r3
+ test_gr_a5a5 r4
+ test_gr_a5a5 r5
+ test_gr_a5a5 r6
+ test_gr_a5a5 r7
+ test_gr_a5a5 r8
+ test_gr_a5a5 r9
+ test_gr_a5a5 r10
+ test_gr_a5a5 r11
+ test_gr_a5a5 r12
+ test_gr_a5a5 r13
+ test_gr_a5a5 r14
+
+divs_o: ! divide signed overflow
+ set_grs_a5a5
+ mov #16, r0
+ movi20 #0x8000, r1
+ shad r0, r1 ! r1 == 0x80000000
+ mov #-1, r0
+ divs r0, r1
+ assertreg0 -1
+ assertreg 0x7fffffff, r1
+ test_gr_a5a5 r2
+ test_gr_a5a5 r3
+ test_gr_a5a5 r4
+ test_gr_a5a5 r5
+ test_gr_a5a5 r6
+ test_gr_a5a5 r7
+ test_gr_a5a5 r8
+ test_gr_a5a5 r9
+ test_gr_a5a5 r10
+ test_gr_a5a5 r11
+ test_gr_a5a5 r12
+ test_gr_a5a5 r13
+ test_gr_a5a5 r14
+
+
+divu_1: ! divide by one, unsigned
+ set_grs_a5a5
+ mov #1, r0
+ divu r0, r1
+ assertreg0 1
+ test_gr_a5a5 r1
+ test_gr_a5a5 r2
+ test_gr_a5a5 r3
+ test_gr_a5a5 r4
+ test_gr_a5a5 r5
+ test_gr_a5a5 r6
+ test_gr_a5a5 r7
+ test_gr_a5a5 r8
+ test_gr_a5a5 r9
+ test_gr_a5a5 r10
+ test_gr_a5a5 r11
+ test_gr_a5a5 r12
+ test_gr_a5a5 r13
+ test_gr_a5a5 r14
+
+divu_2: ! divide by two, unsigned
+ set_grs_a5a5
+ mov #2, r0
+ divu r0, r1
+ assertreg0 2
+ assertreg 0x52d2d2d2, r1
+ test_gr_a5a5 r2
+ test_gr_a5a5 r3
+ test_gr_a5a5 r4
+ test_gr_a5a5 r5
+ test_gr_a5a5 r6
+ test_gr_a5a5 r7
+ test_gr_a5a5 r8
+ test_gr_a5a5 r9
+ test_gr_a5a5 r10
+ test_gr_a5a5 r11
+ test_gr_a5a5 r12
+ test_gr_a5a5 r13
+ test_gr_a5a5 r14
+
+divu_3: ! divide by three, unsigned
+ set_grs_a5a5
+ mov #3, r0
+ divu r0, r1
+ assertreg0 3
+ assertreg 0x37373737, r1
+ test_gr_a5a5 r2
+ test_gr_a5a5 r3
+ test_gr_a5a5 r4
+ test_gr_a5a5 r5
+ test_gr_a5a5 r6
+ test_gr_a5a5 r7
+ test_gr_a5a5 r8
+ test_gr_a5a5 r9
+ test_gr_a5a5 r10
+ test_gr_a5a5 r11
+ test_gr_a5a5 r12
+ test_gr_a5a5 r13
+ test_gr_a5a5 r14
+
+divu_0: ! divide by zero, unsigned
+ set_grs_a5a5
+ mov #0, r0
+ divu r0, r1
+ assertreg0 0
+ assertreg 0xffffffff, r1
+ test_gr_a5a5 r2
+ test_gr_a5a5 r3
+ test_gr_a5a5 r4
+ test_gr_a5a5 r5
+ test_gr_a5a5 r6
+ test_gr_a5a5 r7
+ test_gr_a5a5 r8
+ test_gr_a5a5 r9
+ test_gr_a5a5 r10
+ test_gr_a5a5 r11
+ test_gr_a5a5 r12
+ test_gr_a5a5 r13
+ test_gr_a5a5 r14
+
+
+ pass
+
+ exit 0
+
+
\ No newline at end of file
--- /dev/null
+# sh testcase, fail
+# mach: all
+# as(sh): -defsym sim_cpu=0
+# as(shdsp): -defsym sim_cpu=1 -dsp
+
+ .include "testutils.inc"
+
+ start
+
+ fail
+
+ exit 0
+
--- /dev/null
+# sh testcase for fsca
+# mach: sh
+# as(sh): -defsym sim_cpu=0
+
+ .include "testutils.inc"
+
+ start
+fsca:
+ set_grs_a5a5
+ set_fprs_a5a5
+ # Start with angle zero
+ mov.l zero, r0
+ lds r0, fpul
+ fsca fpul, dr2
+ assert_fpreg_i 0, fr2
+ assert_fpreg_i 1, fr3
+
+ mov.l plus_90, r0
+ lds r0, fpul
+ fsca fpul, dr2
+ assert_fpreg_i 1, fr2
+ assert_fpreg_i 0, fr3
+
+ mov.l plus_180, r0
+ lds r0, fpul
+ fsca fpul, dr2
+ assert_fpreg_i 0, fr2
+ assert_fpreg_i -1, fr3
+
+ mov.l plus_270, r0
+ lds r0, fpul
+ fsca fpul, dr2
+ assert_fpreg_i -1, fr2
+ assert_fpreg_i 0, fr3
+
+ mov.l plus_360, r0
+ lds r0, fpul
+ fsca fpul, dr2
+ assert_fpreg_i 0, fr2
+ assert_fpreg_i 1, fr3
+
+ mov.l minus_90, r0
+ lds r0, fpul
+ fsca fpul, dr2
+ assert_fpreg_i -1, fr2
+ assert_fpreg_i 0, fr3
+
+ mov.l minus_180, r0
+ lds r0, fpul
+ fsca fpul, dr2
+ assert_fpreg_i 0, fr2
+ assert_fpreg_i -1, fr3
+
+ mov.l minus_270, r0
+ lds r0, fpul
+ fsca fpul, dr2
+ assert_fpreg_i 1, fr2
+ assert_fpreg_i 0, fr3
+
+ mov.l minus_360, r0
+ lds r0, fpul
+ fsca fpul, dr2
+ assert_fpreg_i 0, fr2
+ assert_fpreg_i 1, fr3
+
+ assertreg0 0xffff0000
+ set_greg 0xa5a5a5a5, r0
+ test_grs_a5a5
+ test_fpr_a5a5 fr0
+ test_fpr_a5a5 fr1
+ test_fpr_a5a5 fr4
+ test_fpr_a5a5 fr5
+ test_fpr_a5a5 fr6
+ test_fpr_a5a5 fr7
+ test_fpr_a5a5 fr8
+ test_fpr_a5a5 fr9
+ test_fpr_a5a5 fr10
+ test_fpr_a5a5 fr11
+ test_fpr_a5a5 fr12
+ test_fpr_a5a5 fr13
+ test_fpr_a5a5 fr14
+ test_fpr_a5a5 fr15
+ pass
+ exit 0
+
+ .align 2
+zero: .long 0
+one_bitty: .long 1
+plus_90: .long 0x04000
+plus_180: .long 0x08000
+plus_270: .long 0x0c000
+plus_360: .long 0x10000
+minus_90: .long 0xffffc000
+minus_180: .long 0xffff8000
+minus_270: .long 0xffff4000
+minus_360: .long 0xffff0000
+minus_1_bitty: .long 0xffffffff
--- /dev/null
+# sh testcase for fsrra
+# mach: sh
+# as(sh): -defsym sim_cpu=0
+
+ .include "testutils.inc"
+
+ start
+fsrra_single:
+ set_grs_a5a5
+ set_fprs_a5a5
+ # 1/sqrt(0.0) = +infinity.
+ fldi0 fr0
+ fsrra fr0
+ assert_fpreg_x 0x7f800000, fr0
+
+ # 1/sqrt(1.0) = 1.0.
+ fldi1 fr0
+ fsrra fr0
+ assert_fpreg_i 1, fr0
+
+ # 1/sqrt(4.0) = 1/2.0
+ fldi1 fr0
+ # Double it.
+ fadd fr0, fr0
+ # Double it again.
+ fadd fr0, fr0
+ fsrra fr0
+ fldi1 fr2
+ # Double it.
+ fadd fr2, fr2
+ fldi1 fr1
+ # Divide
+ fdiv fr2, fr1
+ fcmp/eq fr0, fr1
+ bt .L2
+ fail
+.L2:
+ # Double-check (pun intended)
+ fadd fr0, fr0
+ assert_fpreg_i 1, fr0
+ fadd fr1, fr1
+ assert_fpreg_i 1, fr1
+
+ # And make sure the rest of the regs are un-affected.
+ assert_fpreg_i 2, fr2
+ test_fpr_a5a5 fr3
+ test_fpr_a5a5 fr4
+ test_fpr_a5a5 fr5
+ test_fpr_a5a5 fr6
+ test_fpr_a5a5 fr7
+ test_fpr_a5a5 fr8
+ test_fpr_a5a5 fr9
+ test_fpr_a5a5 fr10
+ test_fpr_a5a5 fr11
+ test_fpr_a5a5 fr12
+ test_fpr_a5a5 fr13
+ test_fpr_a5a5 fr14
+ test_fpr_a5a5 fr15
+ test_grs_a5a5
+
+ pass
+ exit 0
--- /dev/null
+# sh testcase for all mov.[bwl] instructions
+# mach: sh
+# as(sh): -defsym sim_cpu=0
+
+ .include "testutils.inc"
+
+ .align 2
+_lsrc: .long 0x55555555
+_wsrc: .long 0x55550000
+_bsrc: .long 0x55000000
+
+ .align 2
+_ldst: .long 0
+_wdst: .long 0
+_bdst: .long 0
+
+
+ start
+
+movb_disp12_reg: # Test 8-bit @(disp12,gr) -> gr
+ set_grs_a5a5
+ mov.l bsrc, r1
+ add #-111, r1
+ add #-111, r1
+ add #-111, r1
+ add #-111, r1
+ mov.b @(444,r1), r2
+
+ assertreg _bsrc-444, r1
+ assertreg 0x55, r2
+
+movb_reg_disp12: # Test 8-bit gr -> @(disp12,gr)
+ set_grs_a5a5
+ mov.l bdst, r1
+ add #-111, r1
+ add #-111, r1
+ add #-111, r1
+ add #-111, r1
+ mov.b r2, @(444,r1)
+
+ assertreg _bdst-444, r1
+ assertmem _bdst, 0xa5000000
+
+movw_disp12_reg: # Test 16-bit @(disp12,gr) -> gr
+ set_grs_a5a5
+ mov.l wsrc, r1
+ add #-111, r1
+ add #-111, r1
+ add #-111, r1
+ add #-111, r1
+ mov.w @(444,r1), r2
+
+ assertreg _wsrc-444, r1
+ assertreg 0x5555, r2
+
+movw_reg_disp12: # Test 16-bit gr -> @(disp12,gr)
+ set_grs_a5a5
+ mov.l wdst, r1
+ add #-111, r1
+ add #-111, r1
+ add #-111, r1
+ add #-111, r1
+ mov.w r2, @(444,r1)
+
+ assertreg _wdst-444, r1
+ assertmem _wdst, 0xa5a50000
+
+movl_disp12_reg: # Test 32-bit @(disp12,gr) -> gr
+ set_grs_a5a5
+ mov.l lsrc, r1
+ add #-111, r1
+ add #-111, r1
+ add #-111, r1
+ add #-111, r1
+ mov.l @(444,r1), r2
+
+ assertreg _lsrc-444, r1
+ assertreg 0x55555555, r2
+
+movl_reg_disp12: # Test 32-bit gr -> @(disp12,gr)
+ set_grs_a5a5
+ mov.l ldst, r1
+ add #-111, r1
+ add #-111, r1
+ add #-111, r1
+ add #-111, r1
+ mov.l r2, @(444,r1)
+
+ assertreg _ldst-444, r1
+ assertmem _ldst, 0xa5a5a5a5
+
+ test_gr_a5a5 r0
+ test_gr_a5a5 r2
+ test_gr_a5a5 r3
+ test_gr_a5a5 r4
+ test_gr_a5a5 r5
+ test_gr_a5a5 r6
+ test_gr_a5a5 r7
+ test_gr_a5a5 r8
+ test_gr_a5a5 r9
+ test_gr_a5a5 r10
+ test_gr_a5a5 r11
+ test_gr_a5a5 r12
+ test_gr_a5a5 r13
+ test_gr_a5a5 r14
+
+ pass
+
+ exit 0
+
+lsrc: .long _lsrc
+wsrc: .long _wsrc
+bsrc: .long _bsrc
+
+ldst: .long _ldst
+wdst: .long _wdst
+bdst: .long _bdst
+
--- /dev/null
+# sh testcase for mulr
+# mach: all
+# as(sh): -defsym sim_cpu=0
+# as(shdsp): -defsym sim_cpu=1 -dsp
+
+ .include "testutils.inc"
+
+ start
+
+mulr_1: ! multiply by one
+ set_grs_a5a5
+ mov #1, r0
+ mulr r0, r1
+ assertreg0 1
+ test_gr_a5a5 r1
+ test_gr_a5a5 r2
+ test_gr_a5a5 r3
+ test_gr_a5a5 r4
+ test_gr_a5a5 r5
+ test_gr_a5a5 r6
+ test_gr_a5a5 r7
+ test_gr_a5a5 r8
+ test_gr_a5a5 r9
+ test_gr_a5a5 r10
+ test_gr_a5a5 r11
+ test_gr_a5a5 r12
+ test_gr_a5a5 r13
+ test_gr_a5a5 r14
+
+mulr_2: ! multiply by two
+ set_grs_a5a5
+ mov #2, r0
+ mov #12, r1
+ mulr r0, r1
+ assertreg0 2
+ assertreg 24, r1
+ test_gr_a5a5 r2
+ test_gr_a5a5 r3
+ test_gr_a5a5 r4
+ test_gr_a5a5 r5
+ test_gr_a5a5 r6
+ test_gr_a5a5 r7
+ test_gr_a5a5 r8
+ test_gr_a5a5 r9
+ test_gr_a5a5 r10
+ test_gr_a5a5 r11
+ test_gr_a5a5 r12
+ test_gr_a5a5 r13
+ test_gr_a5a5 r14
+
+mulr_3: ! multiply five by five
+ set_grs_a5a5
+ mov #5, r0
+ mov #5, r1
+ mulr r0, r1
+ assertreg0 5
+ assertreg 25, r1
+ test_gr_a5a5 r2
+ test_gr_a5a5 r3
+ test_gr_a5a5 r4
+ test_gr_a5a5 r5
+ test_gr_a5a5 r6
+ test_gr_a5a5 r7
+ test_gr_a5a5 r8
+ test_gr_a5a5 r9
+ test_gr_a5a5 r10
+ test_gr_a5a5 r11
+ test_gr_a5a5 r12
+ test_gr_a5a5 r13
+ test_gr_a5a5 r14
+
+
+mulr_4: ! multiply 127 by 127
+ set_grs_a5a5
+ mov #127, r0
+ mov #127, r1
+ mulr r0, r1
+ assertreg0 127
+ assertreg 0x3f01, r1
+ test_gr_a5a5 r2
+ test_gr_a5a5 r3
+ test_gr_a5a5 r4
+ test_gr_a5a5 r5
+ test_gr_a5a5 r6
+ test_gr_a5a5 r7
+ test_gr_a5a5 r8
+ test_gr_a5a5 r9
+ test_gr_a5a5 r10
+ test_gr_a5a5 r11
+ test_gr_a5a5 r12
+ test_gr_a5a5 r13
+ test_gr_a5a5 r14
+
+mulr_5: ! multiply -1 by -1
+ set_grs_a5a5
+ mov #-1, r0
+ mov #-1, r1
+ mulr r0, r1
+ assertreg0 -1
+ assertreg 1, r1
+ test_gr_a5a5 r2
+ test_gr_a5a5 r3
+ test_gr_a5a5 r4
+ test_gr_a5a5 r5
+ test_gr_a5a5 r6
+ test_gr_a5a5 r7
+ test_gr_a5a5 r8
+ test_gr_a5a5 r9
+ test_gr_a5a5 r10
+ test_gr_a5a5 r11
+ test_gr_a5a5 r12
+ test_gr_a5a5 r13
+ test_gr_a5a5 r14
+
+mulr_6: ! multiply 46340 by 46340
+ set_grs_a5a5
+ movi20 #46340, r0
+ movi20 #46340, r1
+ mulr r0, r1
+ assertreg0 46340
+ assertreg 0x7ffea810, r1
+ test_gr_a5a5 r2
+ test_gr_a5a5 r3
+ test_gr_a5a5 r4
+ test_gr_a5a5 r5
+ test_gr_a5a5 r6
+ test_gr_a5a5 r7
+ test_gr_a5a5 r8
+ test_gr_a5a5 r9
+ test_gr_a5a5 r10
+ test_gr_a5a5 r11
+ test_gr_a5a5 r12
+ test_gr_a5a5 r13
+ test_gr_a5a5 r14
+
+mulr_7: ! multiply 7ffff by 7ffff (overflow)
+ set_grs_a5a5
+ movi20 #0x7ffff, r0
+ movi20 #0x7ffff, r1
+ mulr r0, r1
+ assertreg0 0x7ffff
+ assertreg 0xfff00001, r1
+ test_gr_a5a5 r2
+ test_gr_a5a5 r3
+ test_gr_a5a5 r4
+ test_gr_a5a5 r5
+ test_gr_a5a5 r6
+ test_gr_a5a5 r7
+ test_gr_a5a5 r8
+ test_gr_a5a5 r9
+ test_gr_a5a5 r10
+ test_gr_a5a5 r11
+ test_gr_a5a5 r12
+ test_gr_a5a5 r13
+ test_gr_a5a5 r14
+
+
+ pass
+
+ exit 0
+
+
\ No newline at end of file
--- /dev/null
+# sh testcase, pass
+# mach: all
+# as(sh): -defsym sim_cpu=0
+# as(shdsp): -defsym sim_cpu=1 -dsp
+
+ .include "testutils.inc"
+
+ start
+ set_grs_a5a5
+ test_grs_a5a5
+ pass
+
+ exit 0
+
--- /dev/null
+# sh testcase for push/pop (mov,movml,movmu...) insns.
+# mach: all
+# as(sh): -defsym sim_cpu=0
+# as(shdsp): -defsym sim_cpu=1 -dsp
+
+ .include "testutils.inc"
+
+ start
+movml_1:
+ set_greg 0, r0
+ set_greg 1, r1
+ set_greg 2, r2
+ set_greg 3, r3
+ set_greg 4, r4
+ set_greg 5, r5
+ set_greg 6, r6
+ set_greg 7, r7
+ set_greg 8, r8
+ set_greg 9, r9
+ set_greg 10, r10
+ set_greg 11, r11
+ set_greg 12, r12
+ set_greg 13, r13
+ set_greg 14, r14
+ set_sreg 15, pr
+
+ movml.l r15,@-r15
+
+ assertmem stackt-4, 15
+ assertmem stackt-8, 14
+ assertmem stackt-12, 13
+ assertmem stackt-16, 12
+ assertmem stackt-20, 11
+ assertmem stackt-24, 10
+ assertmem stackt-28, 9
+ assertmem stackt-32, 8
+ assertmem stackt-36, 7
+ assertmem stackt-40, 6
+ assertmem stackt-44, 5
+ assertmem stackt-48, 4
+ assertmem stackt-52, 3
+ assertmem stackt-56, 2
+ assertmem stackt-60, 1
+ assertmem stackt-64, 0
+
+ assertreg0 0
+ assertreg 1, r1
+ assertreg 2, r2
+ assertreg 3, r3
+ assertreg 4, r4
+ assertreg 5, r5
+ assertreg 6, r6
+ assertreg 7, r7
+ assertreg 8, r8
+ assertreg 9, r9
+ assertreg 10, r10
+ assertreg 11, r11
+ assertreg 12, r12
+ assertreg 13, r13
+ assertreg 14, r14
+ mov r15, r0
+ assertreg0 stackt-64
+
+movml_2:
+ set_grs_a5a5
+ movml.l @r15+, r15
+ assert_sreg 15, pr
+ assertreg0 0
+ assertreg 1, r1
+ assertreg 2, r2
+ assertreg 3, r3
+ assertreg 4, r4
+ assertreg 5, r5
+ assertreg 6, r6
+ assertreg 7, r7
+ assertreg 8, r8
+ assertreg 9, r9
+ assertreg 10, r10
+ assertreg 11, r11
+ assertreg 12, r12
+ assertreg 13, r13
+ assertreg 14, r14
+ mov r15, r0
+ assertreg0 stackt
+
+movmu_1:
+ set_grs_a5a5
+ add #1,r14
+ add #2,r13
+ add #3,r12
+ set_sreg 0xa5a5,pr
+
+ movmu.l r12,@-r15
+
+ assert_sreg 0xa5a5,pr
+ assertreg 0xa5a5a5a6, r14
+ assertreg 0xa5a5a5a7, r13
+ assertreg 0xa5a5a5a8, r12
+ test_gr_a5a5 r11
+ test_gr_a5a5 r10
+ test_gr_a5a5 r9
+ test_gr_a5a5 r8
+ test_gr_a5a5 r7
+ test_gr_a5a5 r6
+ test_gr_a5a5 r5
+ test_gr_a5a5 r4
+ test_gr_a5a5 r3
+ test_gr_a5a5 r2
+ test_gr_a5a5 r1
+ test_gr_a5a5 r0
+ mov r15, r0
+ assertreg stackt-16, r0
+
+ assertmem stackt-4, 0xa5a5
+ assertmem stackt-8, 0xa5a5a5a6
+ assertmem stackt-12, 0xa5a5a5a7
+ assertmem stackt-16, 0xa5a5a5a8
+
+movmu_2:
+ set_grs_a5a5
+ movmu.l @r15+,r12
+
+ assert_sreg 0xa5a5, pr
+ assertreg 0xa5a5a5a6, r14
+ assertreg 0xa5a5a5a7, r13
+ assertreg 0xa5a5a5a8, r12
+ test_gr_a5a5 r11
+ test_gr_a5a5 r10
+ test_gr_a5a5 r9
+ test_gr_a5a5 r8
+ test_gr_a5a5 r7
+ test_gr_a5a5 r6
+ test_gr_a5a5 r5
+ test_gr_a5a5 r4
+ test_gr_a5a5 r3
+ test_gr_a5a5 r2
+ test_gr_a5a5 r1
+ test_gr_a5a5 r0
+ mov r15, r0
+ assertreg stackt, r0
+
+ pass
+
+ exit 0
+
+
\ No newline at end of file
--- /dev/null
+# sh testcase for ldbank stbank resbank
+# mach: all
+# as(sh): -defsym sim_cpu=0
+# as(shdsp): -defsym sim_cpu=1 -dsp
+
+ .include "testutils.inc"
+
+ .macro SEND reg bankno regno
+ set_greg ((\bankno << 7) + (\regno << 2)), \reg
+ .endm
+
+ start
+
+stbank_1:
+ set_grs_a5a5
+ mov #0, r0
+ SEND r1, 0, 0
+ stbank r0, @r1
+ mov #1, r0
+ SEND r1, 0, 1
+ stbank r0, @r1
+ mov #2, r0
+ SEND r1, 0, 2
+ stbank r0, @r1
+ mov #3, r0
+ SEND r1, 0, 3
+ stbank r0, @r1
+ mov #4, r0
+ SEND r1, 0, 4
+ stbank r0, @r1
+ mov #5, r0
+ SEND r1, 0, 5
+ stbank r0, @r1
+ mov #6, r0
+ SEND r1, 0, 6
+ stbank r0, @r1
+ mov #7, r0
+ SEND r1, 0, 7
+ stbank r0, @r1
+ mov #8, r0
+ SEND r1, 0, 8
+ stbank r0, @r1
+ mov #9, r0
+ SEND r1, 0, 9
+ stbank r0, @r1
+ mov #10, r0
+ SEND r1, 0, 10
+ stbank r0, @r1
+ mov #11, r0
+ SEND r1, 0, 11
+ stbank r0, @r1
+ mov #12, r0
+ SEND r1, 0, 12
+ stbank r0, @r1
+ mov #13, r0
+ SEND r1, 0, 13
+ stbank r0, @r1
+ mov #14, r0
+ SEND r1, 0, 14
+ stbank r0, @r1
+ mov #15, r0
+ SEND r1, 0, 15
+ stbank r0, @r1
+ mov #16, r0
+ SEND r1, 0, 16
+ stbank r0, @r1
+ mov #17, r0
+ SEND r1, 0, 17
+ stbank r0, @r1
+ mov #18, r0
+ SEND r1, 0, 18
+ stbank r0, @r1
+ mov #19, r0
+ SEND r1, 0, 19
+ stbank r0, @r1
+
+ assertreg0 19
+ assertreg 19 << 2, r1
+ test_gr_a5a5 r2
+ test_gr_a5a5 r3
+ test_gr_a5a5 r4
+ test_gr_a5a5 r5
+ test_gr_a5a5 r6
+ test_gr_a5a5 r7
+ test_gr_a5a5 r8
+ test_gr_a5a5 r9
+ test_gr_a5a5 r10
+ test_gr_a5a5 r11
+ test_gr_a5a5 r12
+ test_gr_a5a5 r13
+ test_gr_a5a5 r14
+
+ldbank_1:
+ set_grs_a5a5
+ SEND r1, 0, 0
+ ldbank @r1, r0
+ assertreg0 0
+ SEND r1, 0, 1
+ ldbank @r1, r0
+ assertreg0 1
+ SEND r1, 0, 2
+ ldbank @r1, r0
+ assertreg0 2
+ SEND r1, 0, 3
+ ldbank @r1, r0
+ assertreg0 3
+ SEND r1, 0, 4
+ ldbank @r1, r0
+ assertreg0 4
+ SEND r1, 0, 5
+ ldbank @r1, r0
+ assertreg0 5
+ SEND r1, 0, 6
+ ldbank @r1, r0
+ assertreg0 6
+ SEND r1, 0, 7
+ ldbank @r1, r0
+ assertreg0 7
+ SEND r1, 0, 8
+ ldbank @r1, r0
+ assertreg0 8
+ SEND r1, 0, 9
+ ldbank @r1, r0
+ assertreg0 9
+ SEND r1, 0, 10
+ ldbank @r1, r0
+ assertreg0 10
+ SEND r1, 0, 11
+ ldbank @r1, r0
+ assertreg0 11
+ SEND r1, 0, 12
+ ldbank @r1, r0
+ assertreg0 12
+ SEND r1, 0, 13
+ ldbank @r1, r0
+ assertreg0 13
+ SEND r1, 0, 14
+ ldbank @r1, r0
+ assertreg0 14
+ SEND r1, 0, 15
+ ldbank @r1, r0
+ assertreg0 15
+ SEND r1, 0, 16
+ ldbank @r1, r0
+ assertreg0 16
+ SEND r1, 0, 17
+ ldbank @r1, r0
+ assertreg0 17
+ SEND r1, 0, 18
+ ldbank @r1, r0
+ assertreg0 18
+ SEND r1, 0, 19
+ ldbank @r1, r0
+ assertreg0 19
+
+ assertreg (19 << 2), r1
+ test_gr_a5a5 r2
+ test_gr_a5a5 r3
+ test_gr_a5a5 r4
+ test_gr_a5a5 r5
+ test_gr_a5a5 r6
+ test_gr_a5a5 r7
+ test_gr_a5a5 r8
+ test_gr_a5a5 r9
+ test_gr_a5a5 r10
+ test_gr_a5a5 r11
+ test_gr_a5a5 r12
+ test_gr_a5a5 r13
+ test_gr_a5a5 r14
+
+resbank_1:
+ set_grs_a5a5
+ mov #1, r0
+ trapa #13 ! magic trap, sets ibnr
+
+ resbank
+
+ assertreg0 0
+ assertreg 1, r1
+ assertreg 2, r2
+ assertreg 3, r3
+ assertreg 4, r4
+ assertreg 5, r5
+ assertreg 6, r6
+ assertreg 7, r7
+ assertreg 8, r8
+ assertreg 9, r9
+ assertreg 10, r10
+ assertreg 11, r11
+ assertreg 12, r12
+ assertreg 13, r13
+ assertreg 14, r14
+ assert_sreg 15, mach
+ assert_sreg 17, pr
+ assert_creg 18, gbr
+ assert_sreg 19, macl
+
+resbank_2:
+ set_grs_a5a5
+ movi20 #555, r0
+ mov.l r0, @-r15
+ add #-1, r0
+ mov.l r0, @-r15
+ add #-1, r0
+ mov.l r0, @-r15
+ add #-1, r0
+ mov.l r0, @-r15
+ add #-1, r0
+ mov.l r0, @-r15
+ add #-1, r0
+ mov.l r0, @-r15
+ add #-1, r0
+ mov.l r0, @-r15
+ add #-1, r0
+ mov.l r0, @-r15
+ add #-1, r0
+ mov.l r0, @-r15
+ add #-1, r0
+ mov.l r0, @-r15
+ add #-1, r0
+ mov.l r0, @-r15
+ add #-1, r0
+ mov.l r0, @-r15
+ add #-1, r0
+ mov.l r0, @-r15
+ add #-1, r0
+ mov.l r0, @-r15
+ add #-1, r0
+ mov.l r0, @-r15
+ add #-1, r0
+ mov.l r0, @-r15
+ add #-1, r0
+ mov.l r0, @-r15
+ add #-1, r0
+ mov.l r0, @-r15
+ add #-1, r0
+ mov.l r0, @-r15
+
+ set_sr_bit (1 << 14) ! set BO
+
+ resbank
+
+ assert_sreg 555, macl
+ assert_sreg 554, mach
+ assert_creg 553, gbr
+ assert_sreg 552, pr
+ assertreg 551, r14
+ assertreg 550, r13
+ assertreg 549, r12
+ assertreg 548, r11
+ assertreg 547, r10
+ assertreg 546, r9
+ assertreg 545, r8
+ assertreg 544, r7
+ assertreg 543, r6
+ assertreg 542, r5
+ assertreg 541, r4
+ assertreg 540, r3
+ assertreg 539, r2
+ assertreg 538, r1
+ assertreg0 537
+
+ mov r15, r0
+ assertreg0 stackt
+
+ pass
+
+ exit 0