From b4e397edc3619279f3e370d5c76551a7f9e843d7 Mon Sep 17 00:00:00 2001 From: nobody <> Date: Wed, 19 Jun 2002 16:55:29 +0000 Subject: This commit was manufactured by cvs2svn to create branch 'kseitz_interps-20020528-branch'. Cherrypick from master 2002-06-19 16:55:28 UTC Daniel Jacobowitz '2002-06-19 Daniel Jacobowitz ': bfd/cpu-frv.c bfd/elf32-frv.c gdb/ada-lang.c gdb/config/sparc/nbsd.mt gdb/i386-sol2-tdep.c include/elf/frv.h include/gdb/sim-arm.h opcodes/frv-asm.c opcodes/frv-desc.c opcodes/frv-desc.h opcodes/frv-dis.c opcodes/frv-ibld.c opcodes/frv-opc.c opcodes/frv-opc.h sim/mips/mdmx.c --- bfd/cpu-frv.c | 64 + bfd/elf32-frv.c | 1405 ++++++++ gdb/ada-lang.c | 8618 ++++++++++++++++++++++++++++++++++++++++++++++ gdb/config/sparc/nbsd.mt | 4 + gdb/i386-sol2-tdep.c | 74 + include/elf/frv.h | 95 + include/gdb/sim-arm.h | 65 + opcodes/frv-asm.c | 1023 ++++++ opcodes/frv-desc.c | 6311 +++++++++++++++++++++++++++++++++ opcodes/frv-desc.h | 748 ++++ opcodes/frv-dis.c | 789 +++++ opcodes/frv-ibld.c | 2051 +++++++++++ opcodes/frv-opc.c | 5842 +++++++++++++++++++++++++++++++ opcodes/frv-opc.h | 372 ++ sim/mips/mdmx.c | 1476 ++++++++ 15 files changed, 28937 insertions(+) create mode 100644 bfd/cpu-frv.c create mode 100644 bfd/elf32-frv.c create mode 100644 gdb/ada-lang.c create mode 100644 gdb/config/sparc/nbsd.mt create mode 100644 gdb/i386-sol2-tdep.c create mode 100644 include/elf/frv.h create mode 100644 include/gdb/sim-arm.h create mode 100644 opcodes/frv-asm.c create mode 100644 opcodes/frv-desc.c create mode 100644 opcodes/frv-desc.h create mode 100644 opcodes/frv-dis.c create mode 100644 opcodes/frv-ibld.c create mode 100644 opcodes/frv-opc.c create mode 100644 opcodes/frv-opc.h create mode 100644 sim/mips/mdmx.c diff --git a/bfd/cpu-frv.c b/bfd/cpu-frv.c new file mode 100644 index 0000000..cd9ff1e --- /dev/null +++ b/bfd/cpu-frv.c @@ -0,0 +1,64 @@ +/* BFD support for the FRV processor. + Copyright (C) 2002 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" + +enum { + I_frv_generic, + I_frv_simple, + I_frv_500, + I_frv_300, +}; + +#define FRV_ARCH(MACHINE, NAME, DEFAULT, NEXT) \ +{ \ + 32, /* 32 bits in a word */ \ + 32, /* 32 bits in an address */ \ + 8, /* 8 bits in a byte */ \ + bfd_arch_frv, /* architecture */ \ + MACHINE, /* which machine */ \ + "frv", /* architecture name */ \ + NAME, /* machine name */ \ + 4, /* default alignment */ \ + DEFAULT, /* is this the default? */ \ + bfd_default_compatible, /* architecture comparison fn */ \ + bfd_default_scan, /* string to architecture convert fn */ \ + NEXT /* next in list */ \ +} + +static const bfd_arch_info_type arch_info_300 + = FRV_ARCH (bfd_mach_fr300, "fr300", false, (bfd_arch_info_type *)0); + +static const bfd_arch_info_type arch_info_400 + = FRV_ARCH (bfd_mach_fr400, "fr400", false, &arch_info_300); + +static const bfd_arch_info_type arch_info_500 + = FRV_ARCH (bfd_mach_fr500, "fr500", false, &arch_info_400); + +static const bfd_arch_info_type arch_info_simple + = FRV_ARCH (bfd_mach_frvsimple, "simple", false, &arch_info_500); + +static const bfd_arch_info_type arch_info_tomcat + = FRV_ARCH (bfd_mach_frvtomcat, "tomcat", false, &arch_info_simple); + +const bfd_arch_info_type bfd_frv_arch + = FRV_ARCH (bfd_mach_frv, "frv", true, &arch_info_tomcat); + diff --git a/bfd/elf32-frv.c b/bfd/elf32-frv.c new file mode 100644 index 0000000..cc26b96 --- /dev/null +++ b/bfd/elf32-frv.c @@ -0,0 +1,1405 @@ +/* FRV-specific support for 32-bit ELF. + Copyright (C) 2002 Free Software Foundation, Inc. + +This file is part of BFD, the Binary File Descriptor library. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#include "bfd.h" +#include "sysdep.h" +#include "libbfd.h" +#include "elf-bfd.h" +#include "elf/frv.h" + +/* Forward declarations. */ +static bfd_reloc_status_type elf32_frv_relocate_lo16 + PARAMS ((bfd *, Elf_Internal_Rela *, bfd_byte *, bfd_vma)); +static bfd_reloc_status_type elf32_frv_relocate_hi16 + PARAMS ((bfd *, Elf_Internal_Rela *, bfd_byte *, bfd_vma)); +static bfd_reloc_status_type elf32_frv_relocate_label24 + PARAMS ((bfd *, asection *, Elf_Internal_Rela *, bfd_byte *, bfd_vma)); +static bfd_reloc_status_type elf32_frv_relocate_gprel12 + PARAMS ((struct bfd_link_info *, bfd *, asection *, Elf_Internal_Rela *, bfd_byte *, bfd_vma)); +static bfd_reloc_status_type elf32_frv_relocate_gprelu12 + PARAMS ((struct bfd_link_info *, bfd *, asection *, Elf_Internal_Rela *, bfd_byte *, bfd_vma)); +static bfd_reloc_status_type elf32_frv_relocate_gprello + PARAMS ((struct bfd_link_info *, bfd *, asection *, Elf_Internal_Rela *, bfd_byte *, bfd_vma)); +static bfd_reloc_status_type elf32_frv_relocate_gprelhi + PARAMS ((struct bfd_link_info *, bfd *, asection *, Elf_Internal_Rela *, bfd_byte *, bfd_vma)); +static reloc_howto_type *frv_reloc_type_lookup + PARAMS ((bfd *, bfd_reloc_code_real_type)); +static void frv_info_to_howto_rela + PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *)); +static boolean elf32_frv_relocate_section + PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); +static boolean elf32_frv_add_symbol_hook + PARAMS (( bfd *, struct bfd_link_info *, const Elf_Internal_Sym *, const char **, flagword *, asection **, bfd_vma *)); +static bfd_reloc_status_type frv_final_link_relocate + PARAMS ((reloc_howto_type *, bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, bfd_vma)); +static boolean elf32_frv_gc_sweep_hook + PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *)); +static asection * elf32_frv_gc_mark_hook + PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *, struct elf_link_hash_entry *, Elf_Internal_Sym *)); +static boolean elf32_frv_check_relocs + PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *)); +static int elf32_frv_machine PARAMS ((bfd *)); +static boolean elf32_frv_object_p PARAMS ((bfd *)); +static boolean frv_elf_set_private_flags PARAMS ((bfd *, flagword)); +static boolean frv_elf_copy_private_bfd_data PARAMS ((bfd *, bfd *)); +static boolean frv_elf_merge_private_bfd_data PARAMS ((bfd *, bfd *)); +static boolean frv_elf_print_private_bfd_data PARAMS ((bfd *, PTR)); + +static reloc_howto_type elf32_frv_howto_table [] = +{ + /* This reloc does nothing. */ + HOWTO (R_FRV_NONE, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_FRV_NONE", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false), /* pcrel_offset */ + + /* A 32 bit absolute relocation. */ + HOWTO (R_FRV_32, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_FRV_32", /* name */ + false, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* A 16 bit pc-relative relocation. */ + HOWTO (R_FRV_LABEL16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_FRV_LABEL16", /* name */ + false, /* partial_inplace */ + 0xffff, /* src_mask */ + 0xffff, /* dst_mask */ + true), /* pcrel_offset */ + + /* A 24-bit pc-relative relocation. */ + HOWTO (R_FRV_LABEL24, /* type */ + 2, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 26, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_FRV_LABEL24", /* name */ + false, /* partial_inplace */ + 0x7e03ffff, /* src_mask */ + 0x7e03ffff, /* dst_mask */ + true), /* pcrel_offset */ + + HOWTO (R_FRV_LO16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_FRV_LO16", /* name */ + false, /* partial_inplace */ + 0xffff, /* src_mask */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ + + HOWTO (R_FRV_HI16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_FRV_HI16", /* name */ + false, /* partial_inplace */ + 0xffff, /* src_mask */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ + + HOWTO (R_FRV_GPREL12, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 12, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_FRV_GPREL12", /* name */ + false, /* partial_inplace */ + 0xfff, /* src_mask */ + 0xfff, /* dst_mask */ + false), /* pcrel_offset */ + + HOWTO (R_FRV_GPRELU12, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 12, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_FRV_GPRELU12", /* name */ + false, /* partial_inplace */ + 0xfff, /* src_mask */ + 0x3f03f, /* dst_mask */ + false), /* pcrel_offset */ + + HOWTO (R_FRV_GPREL32, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_FRV_GPREL32", /* name */ + false, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + HOWTO (R_FRV_GPRELHI, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_FRV_GPRELHI", /* name */ + false, /* partial_inplace */ + 0xffff, /* src_mask */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ + + HOWTO (R_FRV_GPRELLO, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_FRV_GPRELLO", /* name */ + false, /* partial_inplace */ + 0xffff, /* src_mask */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ +}; + +/* GNU extension to record C++ vtable hierarchy. */ +static reloc_howto_type elf32_frv_vtinherit_howto = + HOWTO (R_FRV_GNU_VTINHERIT, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + NULL, /* special_function */ + "R_FRV_GNU_VTINHERIT", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false); /* pcrel_offset */ + + /* GNU extension to record C++ vtable member usage. */ +static reloc_howto_type elf32_frv_vtentry_howto = + HOWTO (R_FRV_GNU_VTENTRY, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_elf_rel_vtable_reloc_fn, /* special_function */ + "R_FRV_GNU_VTENTRY", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false); /* pcrel_offset */ + +/* Map BFD reloc types to FRV ELF reloc types. */ +#if 0 +struct frv_reloc_map +{ + unsigned int bfd_reloc_val; + unsigned int frv_reloc_val; +}; + +static const struct frv_reloc_map frv_reloc_map [] = +{ + { BFD_RELOC_NONE, R_FRV_NONE }, + { BFD_RELOC_32, R_FRV_32 }, + { BFD_RELOC_FRV_LABEL16, R_FRV_LABEL16 }, + { BFD_RELOC_FRV_LABEL24, R_FRV_LABEL24 }, + { BFD_RELOC_FRV_LO16, R_FRV_LO16 }, + { BFD_RELOC_FRV_HI16, R_FRV_HI16 }, + { BFD_RELOC_FRV_GPREL12, R_FRV_GPREL12 }, + { BFD_RELOC_FRV_GPRELU12, R_FRV_GPRELU12 }, + { BFD_RELOC_FRV_GPREL32, R_FRV_GPREL32 }, + { BFD_RELOC_FRV_GPRELHI, R_FRV_GPRELHI }, + { BFD_RELOC_FRV_GPRELLO, R_FRV_GPRELLO }, + { BFD_RELOC_VTABLE_INHERIT, R_FRV_GNU_VTINHERIT }, + { BFD_RELOC_VTABLE_ENTRY, R_FRV_GNU_VTENTRY }, +}; +#endif + +/* Handle an FRV small data reloc. */ + +static bfd_reloc_status_type +elf32_frv_relocate_gprel12 (info, input_bfd, input_section, relocation, contents, value) + struct bfd_link_info *info; + bfd *input_bfd; + asection *input_section; + Elf_Internal_Rela *relocation; + bfd_byte *contents; + bfd_vma value; +{ + bfd_vma insn; + bfd_vma gp; + struct bfd_link_hash_entry *h; + + h = bfd_link_hash_lookup (info->hash, "_gp", false, false, true); + + gp = (h->u.def.value + + h->u.def.section->output_section->vma + + h->u.def.section->output_offset); + + value -= input_section->output_section->vma; + value -= (gp - input_section->output_section->vma); + + insn = bfd_get_32 (input_bfd, contents + relocation->r_offset); + + value += relocation->r_addend; + + if ((long) value > 0x7ff || (long) value < -0x800) + return bfd_reloc_overflow; + + bfd_put_32 (input_bfd, + (insn & 0xfffff000) | (value & 0xfff), + contents + relocation->r_offset); + + return bfd_reloc_ok; +} + +/* Handle an FRV small data reloc. for the u12 field. */ + +static bfd_reloc_status_type +elf32_frv_relocate_gprelu12 (info, input_bfd, input_section, relocation, contents, value) + struct bfd_link_info *info; + bfd *input_bfd; + asection *input_section; + Elf_Internal_Rela *relocation; + bfd_byte *contents; + bfd_vma value; +{ + bfd_vma insn; + bfd_vma gp; + struct bfd_link_hash_entry *h; + bfd_vma mask; + + h = bfd_link_hash_lookup (info->hash, "_gp", false, false, true); + + gp = (h->u.def.value + + h->u.def.section->output_section->vma + + h->u.def.section->output_offset); + + value -= input_section->output_section->vma; + value -= (gp - input_section->output_section->vma); + + insn = bfd_get_32 (input_bfd, contents + relocation->r_offset); + + value += relocation->r_addend; + + if ((long) value > 0x7ff || (long) value < -0x800) + return bfd_reloc_overflow; + + /* The high 6 bits go into bits 17-12. The low 6 bits go into bits 5-0. */ + mask = 0x3f03f; + insn = (insn & ~mask) | ((value & 0xfc0) << 12) | (value & 0x3f); + + bfd_put_32 (input_bfd, insn, contents + relocation->r_offset); + + return bfd_reloc_ok; +} + +/* Handle an FRV ELF HI16 reloc. */ + +static bfd_reloc_status_type +elf32_frv_relocate_hi16 (input_bfd, relhi, contents, value) + bfd *input_bfd; + Elf_Internal_Rela *relhi; + bfd_byte *contents; + bfd_vma value; +{ + bfd_vma insn; + + insn = bfd_get_32 (input_bfd, contents + relhi->r_offset); + + value += relhi->r_addend; + value = ((value >> 16) & 0xffff); + + insn = (insn & 0xffff0000) | value; + + if ((long) value > 0xffff || (long) value < -0x10000) + return bfd_reloc_overflow; + + bfd_put_32 (input_bfd, insn, contents + relhi->r_offset); + return bfd_reloc_ok; + +} +static bfd_reloc_status_type +elf32_frv_relocate_lo16 (input_bfd, rello, contents, value) + bfd *input_bfd; + Elf_Internal_Rela *rello; + bfd_byte *contents; + bfd_vma value; +{ + bfd_vma insn; + + insn = bfd_get_32 (input_bfd, contents + rello->r_offset); + + value += rello->r_addend; + value = value & 0xffff; + + insn = (insn & 0xffff0000) | value; + + if ((long) value > 0xffff || (long) value < -0x10000) + return bfd_reloc_overflow; + + bfd_put_32 (input_bfd, insn, contents + rello->r_offset); + return bfd_reloc_ok; +} + +/* Perform the relocation for the CALL label24 instruction. */ + +static bfd_reloc_status_type +elf32_frv_relocate_label24 (input_bfd, input_section, rello, contents, value) + bfd *input_bfd; + asection *input_section; + Elf_Internal_Rela *rello; + bfd_byte *contents; + bfd_vma value; +{ + bfd_vma insn; + bfd_vma label6; + bfd_vma label18; + + /* The format for the call instruction is: + + 0 000000 0001111 000000000000000000 + label6 opcode label18 + + The branch calculation is: pc + (4*label24) + where label24 is the concatenation of label6 and label18. */ + + /* Grab the instruction. */ + insn = bfd_get_32 (input_bfd, contents + rello->r_offset); + + value -= input_section->output_section->vma + input_section->output_offset; + value -= rello->r_offset; + value += rello->r_addend; + + value = value >> 2; + + label6 = value & 0xfc0000; + label6 = label6 << 7; + + label18 = value & 0x3ffff; + + insn = insn & 0x803c0000; + insn = insn | label6; + insn = insn | label18; + + bfd_put_32 (input_bfd, insn, contents + rello->r_offset); + + return bfd_reloc_ok; +} + +static bfd_reloc_status_type +elf32_frv_relocate_gprelhi (info, input_bfd, input_section, relocation, contents, value) + struct bfd_link_info *info; + bfd *input_bfd; + asection *input_section; + Elf_Internal_Rela *relocation; + bfd_byte *contents; + bfd_vma value; +{ + bfd_vma insn; + bfd_vma gp; + struct bfd_link_hash_entry *h; + + h = bfd_link_hash_lookup (info->hash, "_gp", false, false, true); + + gp = (h->u.def.value + + h->u.def.section->output_section->vma + + h->u.def.section->output_offset); + + value -= input_section->output_section->vma; + value -= (gp - input_section->output_section->vma); + value += relocation->r_addend; + value = ((value >> 16) & 0xffff); + + if ((long) value > 0xffff || (long) value < -0x10000) + return bfd_reloc_overflow; + + insn = bfd_get_32 (input_bfd, contents + relocation->r_offset); + insn = (insn & 0xffff0000) | value; + + bfd_put_32 (input_bfd, insn, contents + relocation->r_offset); + return bfd_reloc_ok; +} + +static bfd_reloc_status_type +elf32_frv_relocate_gprello (info, input_bfd, input_section, relocation, contents, value) + struct bfd_link_info *info; + bfd *input_bfd; + asection *input_section; + Elf_Internal_Rela *relocation; + bfd_byte *contents; + bfd_vma value; +{ + bfd_vma insn; + bfd_vma gp; + struct bfd_link_hash_entry *h; + + h = bfd_link_hash_lookup (info->hash, "_gp", false, false, true); + + gp = (h->u.def.value + + h->u.def.section->output_section->vma + + h->u.def.section->output_offset); + + value -= input_section->output_section->vma; + value -= (gp - input_section->output_section->vma); + value += relocation->r_addend; + value = value & 0xffff; + + if ((long) value > 0xffff || (long) value < -0x10000) + return bfd_reloc_overflow; + + insn = bfd_get_32 (input_bfd, contents + relocation->r_offset); + insn = (insn & 0xffff0000) | value; + + bfd_put_32 (input_bfd, insn, contents + relocation->r_offset); + + return bfd_reloc_ok; +} + +static reloc_howto_type * +frv_reloc_type_lookup (abfd, code) + bfd * abfd ATTRIBUTE_UNUSED; + bfd_reloc_code_real_type code; +{ + switch (code) + { + default: + break; + + case BFD_RELOC_NONE: + return &elf32_frv_howto_table[ (int) R_FRV_NONE]; + + case BFD_RELOC_32: + case BFD_RELOC_CTOR: + return &elf32_frv_howto_table[ (int) R_FRV_32]; + + case BFD_RELOC_FRV_LABEL16: + return &elf32_frv_howto_table[ (int) R_FRV_LABEL16]; + + case BFD_RELOC_FRV_LABEL24: + return &elf32_frv_howto_table[ (int) R_FRV_LABEL24]; + + case BFD_RELOC_FRV_LO16: + return &elf32_frv_howto_table[ (int) R_FRV_LO16]; + + case BFD_RELOC_FRV_HI16: + return &elf32_frv_howto_table[ (int) R_FRV_HI16]; + + case BFD_RELOC_FRV_GPREL12: + return &elf32_frv_howto_table[ (int) R_FRV_GPREL12]; + + case BFD_RELOC_FRV_GPRELU12: + return &elf32_frv_howto_table[ (int) R_FRV_GPRELU12]; + + case BFD_RELOC_FRV_GPREL32: + return &elf32_frv_howto_table[ (int) R_FRV_GPREL32]; + + case BFD_RELOC_FRV_GPRELHI: + return &elf32_frv_howto_table[ (int) R_FRV_GPRELHI]; + + case BFD_RELOC_FRV_GPRELLO: + return &elf32_frv_howto_table[ (int) R_FRV_GPRELLO]; + + case BFD_RELOC_VTABLE_INHERIT: + return &elf32_frv_vtinherit_howto; + + case BFD_RELOC_VTABLE_ENTRY: + return &elf32_frv_vtentry_howto; + } + + return NULL; +} + +/* Set the howto pointer for an FRV ELF reloc. */ + +static void +frv_info_to_howto_rela (abfd, cache_ptr, dst) + bfd * abfd ATTRIBUTE_UNUSED; + arelent * cache_ptr; + Elf32_Internal_Rela * dst; +{ + unsigned int r_type; + + r_type = ELF32_R_TYPE (dst->r_info); + switch (r_type) + { + case R_FRV_GNU_VTINHERIT: + cache_ptr->howto = &elf32_frv_vtinherit_howto; + break; + + case R_FRV_GNU_VTENTRY: + cache_ptr->howto = &elf32_frv_vtentry_howto; + break; + + default: + cache_ptr->howto = & elf32_frv_howto_table [r_type]; + break; + } +} + +/* Perform a single relocation. By default we use the standard BFD + routines, but a few relocs, we have to do them ourselves. */ + +static bfd_reloc_status_type +frv_final_link_relocate (howto, input_bfd, input_section, contents, rel, relocation) + reloc_howto_type * howto; + bfd * input_bfd; + asection * input_section; + bfd_byte * contents; + Elf_Internal_Rela * rel; + bfd_vma relocation; +{ + return _bfd_final_link_relocate (howto, input_bfd, input_section, + contents, rel->r_offset, relocation, + rel->r_addend); +} + + +/* Relocate an FRV ELF section. + There is some attempt to make this function usable for many architectures, + both USE_REL and USE_RELA ['twould be nice if such a critter existed], + if only to serve as a learning tool. + + The RELOCATE_SECTION function is called by the new ELF backend linker + to handle the relocations for a section. + + The relocs are always passed as Rela structures; if the section + actually uses Rel structures, the r_addend field will always be + zero. + + This function is responsible for adjusting the section contents as + necessary, and (if using Rela relocs and generating a relocateable + output file) adjusting the reloc addend as necessary. + + This function does not have to worry about setting the reloc + address or the reloc symbol index. + + LOCAL_SYMS is a pointer to the swapped in local symbols. + + LOCAL_SECTIONS is an array giving the section in the input file + corresponding to the st_shndx field of each local symbol. + + The global hash table entry for the global symbols can be found + via elf_sym_hashes (input_bfd). + + When generating relocateable output, this function must handle + STB_LOCAL/STT_SECTION symbols specially. The output symbol is + going to be the section symbol corresponding to the output + section, which means that the addend must be adjusted + accordingly. */ + +static boolean +elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section, + contents, relocs, local_syms, local_sections) + bfd * output_bfd ATTRIBUTE_UNUSED; + struct bfd_link_info * info; + bfd * input_bfd; + asection * input_section; + bfd_byte * contents; + Elf_Internal_Rela * relocs; + Elf_Internal_Sym * local_syms; + asection ** local_sections; +{ + Elf_Internal_Shdr * symtab_hdr; + struct elf_link_hash_entry ** sym_hashes; + Elf_Internal_Rela * rel; + Elf_Internal_Rela * relend; + + symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr; + sym_hashes = elf_sym_hashes (input_bfd); + relend = relocs + input_section->reloc_count; + + for (rel = relocs; rel < relend; rel ++) + { + reloc_howto_type * howto; + unsigned long r_symndx; + Elf_Internal_Sym * sym; + asection * sec; + struct elf_link_hash_entry * h; + bfd_vma relocation; + bfd_reloc_status_type r; + const char * name = NULL; + int r_type; + + r_type = ELF32_R_TYPE (rel->r_info); + + if ( r_type == R_FRV_GNU_VTINHERIT + || r_type == R_FRV_GNU_VTENTRY) + continue; + + r_symndx = ELF32_R_SYM (rel->r_info); + + if (info->relocateable) + { + /* This is a relocateable link. We don't have to change + anything, unless the reloc is against a section symbol, + in which case we have to adjust according to where the + section symbol winds up in the output section. */ + if (r_symndx < symtab_hdr->sh_info) + { + sym = local_syms + r_symndx; + + if (ELF_ST_TYPE (sym->st_info) == STT_SECTION) + { + sec = local_sections [r_symndx]; + rel->r_addend += sec->output_offset + sym->st_value; + } + } + + continue; + } + + /* This is a final link. */ + howto = elf32_frv_howto_table + ELF32_R_TYPE (rel->r_info); + h = NULL; + sym = NULL; + sec = NULL; + + if (r_symndx < symtab_hdr->sh_info) + { + sym = local_syms + r_symndx; + sec = local_sections [r_symndx]; + relocation = (sec->output_section->vma + + sec->output_offset + + sym->st_value); + + name = bfd_elf_string_from_elf_section + (input_bfd, symtab_hdr->sh_link, sym->st_name); + name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name; + } + else + { + h = sym_hashes [r_symndx - symtab_hdr->sh_info]; + + while (h->root.type == bfd_link_hash_indirect + || h->root.type == bfd_link_hash_warning) + h = (struct elf_link_hash_entry *) h->root.u.i.link; + + name = h->root.root.string; + + if (h->root.type == bfd_link_hash_defined + || h->root.type == bfd_link_hash_defweak) + { + sec = h->root.u.def.section; + relocation = (h->root.u.def.value + + sec->output_section->vma + + sec->output_offset); + } + else if (h->root.type == bfd_link_hash_undefweak) + { + relocation = 0; + } + else + { + if (! ((*info->callbacks->undefined_symbol) + (info, h->root.root.string, input_bfd, + input_section, rel->r_offset, true))) + return false; + relocation = 0; + } + } + + if (r_type == R_FRV_HI16) + r = elf32_frv_relocate_hi16 (input_bfd, rel, contents, relocation); + + else if (r_type == R_FRV_LO16) + r = elf32_frv_relocate_lo16 (input_bfd, rel, contents, relocation); + + else if (r_type == R_FRV_LABEL24) + r = elf32_frv_relocate_label24 (input_bfd, input_section, rel, contents, relocation); + + else if (r_type == R_FRV_GPREL12) + r = elf32_frv_relocate_gprel12 (info, input_bfd, input_section, rel, contents, relocation); + + else if (r_type == R_FRV_GPRELU12) + r = elf32_frv_relocate_gprelu12 (info, input_bfd, input_section, rel, contents, relocation); + + else if (r_type == R_FRV_GPRELLO) + r = elf32_frv_relocate_gprello (info, input_bfd, input_section, rel, contents, relocation); + + else if (r_type == R_FRV_GPRELHI) + r = elf32_frv_relocate_gprelhi (info, input_bfd, input_section, rel, contents, relocation); + + else + r = frv_final_link_relocate (howto, input_bfd, input_section, contents, rel, relocation); + + if (r != bfd_reloc_ok) + { + const char * msg = (const char *) NULL; + + switch (r) + { + case bfd_reloc_overflow: + r = info->callbacks->reloc_overflow + (info, name, howto->name, (bfd_vma) 0, + input_bfd, input_section, rel->r_offset); + break; + + case bfd_reloc_undefined: + r = info->callbacks->undefined_symbol + (info, name, input_bfd, input_section, rel->r_offset, true); + break; + + case bfd_reloc_outofrange: + msg = _("internal error: out of range error"); + break; + + case bfd_reloc_notsupported: + msg = _("internal error: unsupported relocation error"); + break; + + case bfd_reloc_dangerous: + msg = _("internal error: dangerous relocation"); + break; + + default: + msg = _("internal error: unknown error"); + break; + } + + if (msg) + r = info->callbacks->warning + (info, msg, name, input_bfd, input_section, rel->r_offset); + + if (! r) + return false; + } + } + + return true; +} + +/* Return the section that should be marked against GC for a given + relocation. */ + +static asection * +elf32_frv_gc_mark_hook (abfd, info, rel, h, sym) + bfd * abfd; + struct bfd_link_info * info ATTRIBUTE_UNUSED; + Elf_Internal_Rela * rel; + struct elf_link_hash_entry * h; + Elf_Internal_Sym * sym; +{ + if (h != NULL) + { + switch (ELF32_R_TYPE (rel->r_info)) + { + case R_FRV_GNU_VTINHERIT: + case R_FRV_GNU_VTENTRY: + break; + + default: + switch (h->root.type) + { + default: + break; + + 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; + } + } + } + else + { + if (!(elf_bad_symtab (abfd) + && ELF_ST_BIND (sym->st_info) != STB_LOCAL) + && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE) + && sym->st_shndx != SHN_COMMON)) + return bfd_section_from_elf_index (abfd, sym->st_shndx); + } + + return NULL; +} + +/* Update the got entry reference counts for the section being removed. */ + +static boolean +elf32_frv_gc_sweep_hook (abfd, info, sec, relocs) + bfd * abfd ATTRIBUTE_UNUSED; + struct bfd_link_info * info ATTRIBUTE_UNUSED; + asection * sec ATTRIBUTE_UNUSED; + const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED; +{ + return true; +} + + +/* Hook called by the linker routine which adds symbols from an object + file. We use it to put .comm items in .scomm, and not .comm. */ + +static boolean +elf32_frv_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp) + bfd *abfd; + struct bfd_link_info *info; + const Elf_Internal_Sym *sym; + const char **namep ATTRIBUTE_UNUSED; + flagword *flagsp ATTRIBUTE_UNUSED; + asection **secp; + bfd_vma *valp; +{ + if (sym->st_shndx == SHN_COMMON + && !info->relocateable + && (int)sym->st_size <= (int)bfd_get_gp_size (abfd)) + { + /* Common symbols less than or equal to -G nn bytes are + automatically put into .sbss. */ + + asection *scomm = bfd_get_section_by_name (abfd, ".scommon"); + + if (scomm == NULL) + { + scomm = bfd_make_section (abfd, ".scommon"); + if (scomm == NULL + || !bfd_set_section_flags (abfd, scomm, (SEC_ALLOC + | SEC_IS_COMMON + | SEC_LINKER_CREATED))) + return false; + } + + *secp = scomm; + *valp = sym->st_size; + } + + return true; +} +/* Look through the relocs for a section during the first phase. + Since we don't do .gots or .plts, we just need to consider the + virtual table relocs for gc. */ + +static boolean +elf32_frv_check_relocs (abfd, info, sec, relocs) + bfd *abfd; + struct bfd_link_info *info; + asection *sec; + const Elf_Internal_Rela *relocs; +{ + Elf_Internal_Shdr *symtab_hdr; + struct elf_link_hash_entry **sym_hashes, **sym_hashes_end; + const Elf_Internal_Rela *rel; + const Elf_Internal_Rela *rel_end; + + if (info->relocateable) + return true; + + symtab_hdr = &elf_tdata (abfd)->symtab_hdr; + sym_hashes = elf_sym_hashes (abfd); + sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof(Elf32_External_Sym); + if (!elf_bad_symtab (abfd)) + sym_hashes_end -= symtab_hdr->sh_info; + + rel_end = relocs + sec->reloc_count; + for (rel = relocs; rel < rel_end; rel++) + { + struct elf_link_hash_entry *h; + unsigned long r_symndx; + + r_symndx = ELF32_R_SYM (rel->r_info); + if (r_symndx < symtab_hdr->sh_info) + h = NULL; + else + h = sym_hashes[r_symndx - symtab_hdr->sh_info]; + + switch (ELF32_R_TYPE (rel->r_info)) + { + /* This relocation describes the C++ object vtable hierarchy. + Reconstruct it for later use during GC. */ + case R_FRV_GNU_VTINHERIT: + if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) + return false; + break; + + /* This relocation describes which C++ vtable entries are actually + used. Record for later use during GC. */ + case R_FRV_GNU_VTENTRY: + if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend)) + return false; + break; + } + } + + return true; +} + + +/* Return the machine subcode from the ELF e_flags header. */ + +static int +elf32_frv_machine (abfd) + bfd *abfd; +{ + switch (elf_elfheader (abfd)->e_flags & EF_FRV_CPU_MASK) + { + default: break; + case EF_FRV_CPU_FR500: return bfd_mach_fr500; + case EF_FRV_CPU_FR400: return bfd_mach_fr400; + case EF_FRV_CPU_FR300: return bfd_mach_fr300; + case EF_FRV_CPU_SIMPLE: return bfd_mach_frvsimple; + case EF_FRV_CPU_TOMCAT: return bfd_mach_frvtomcat; + } + + return bfd_mach_frv; +} + +/* Set the right machine number for a FRV ELF file. */ + +static boolean +elf32_frv_object_p (abfd) + bfd *abfd; +{ + bfd_default_set_arch_mach (abfd, bfd_arch_frv, elf32_frv_machine (abfd)); + return true; +} + +/* Function to set the ELF flag bits. */ + +static boolean +frv_elf_set_private_flags (abfd, flags) + bfd *abfd; + flagword flags; +{ + elf_elfheader (abfd)->e_flags = flags; + elf_flags_init (abfd) = true; + return true; +} + +/* Copy backend specific data from one object module to another. */ + +static boolean +frv_elf_copy_private_bfd_data (ibfd, obfd) + bfd *ibfd; + bfd *obfd; +{ + if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour + || bfd_get_flavour (obfd) != bfd_target_elf_flavour) + return true; + + BFD_ASSERT (!elf_flags_init (obfd) + || elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags); + + elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags; + elf_flags_init (obfd) = true; + return true; +} + +/* Merge backend specific data from an object file to the output + object file when linking. */ + +static boolean +frv_elf_merge_private_bfd_data (ibfd, obfd) + bfd *ibfd; + bfd *obfd; +{ + flagword old_flags, old_partial; + flagword new_flags, new_partial; + boolean error = false; + char new_opt[80]; + char old_opt[80]; + + new_opt[0] = old_opt[0] = '\0'; + new_flags = elf_elfheader (ibfd)->e_flags; + old_flags = elf_elfheader (obfd)->e_flags; + +#ifdef DEBUG + (*_bfd_error_handler) ("old_flags = 0x%.8lx, new_flags = 0x%.8lx, init = %s, filename = %s", + old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no", + bfd_get_filename (ibfd)); +#endif + + if (!elf_flags_init (obfd)) /* First call, no flags set. */ + { + elf_flags_init (obfd) = true; + old_flags = new_flags; + } + + else if (new_flags == old_flags) /* Compatible flags are ok. */ + ; + + else /* Possibly incompatible flags. */ + { + /* Warn if different # of gprs are used. Note, 0 means nothing is + said about the size of gprs. */ + new_partial = (new_flags & EF_FRV_GPR_MASK); + old_partial = (old_flags & EF_FRV_GPR_MASK); + if (new_partial == old_partial) + ; + + else if (new_partial == 0) + ; + + else if (old_partial == 0) + old_flags |= new_partial; + + else + { + switch (new_partial) + { + default: strcat (new_opt, " -mgpr-??"); break; + case EF_FRV_GPR_32: strcat (new_opt, " -mgpr-32"); break; + case EF_FRV_GPR_64: strcat (new_opt, " -mgpr-64"); break; + } + + switch (old_partial) + { + default: strcat (old_opt, " -mgpr-??"); break; + case EF_FRV_GPR_32: strcat (old_opt, " -mgpr-32"); break; + case EF_FRV_GPR_64: strcat (old_opt, " -mgpr-64"); break; + } + } + + /* Warn if different # of fprs are used. Note, 0 means nothing is + said about the size of fprs. */ + new_partial = (new_flags & EF_FRV_FPR_MASK); + old_partial = (old_flags & EF_FRV_FPR_MASK); + if (new_partial == old_partial) + ; + + else if (new_partial == 0) + ; + + else if (old_partial == 0) + old_flags |= new_partial; + + else + { + switch (new_partial) + { + default: strcat (new_opt, " -mfpr-?"); break; + case EF_FRV_FPR_32: strcat (new_opt, " -mfpr-32"); break; + case EF_FRV_FPR_64: strcat (new_opt, " -mfpr-64"); break; + case EF_FRV_FPR_NONE: strcat (new_opt, " -msoft-float"); break; + } + + switch (old_partial) + { + default: strcat (old_opt, " -mfpr-?"); break; + case EF_FRV_FPR_32: strcat (old_opt, " -mfpr-32"); break; + case EF_FRV_FPR_64: strcat (old_opt, " -mfpr-64"); break; + case EF_FRV_FPR_NONE: strcat (old_opt, " -msoft-float"); break; + } + } + + /* Warn if different dword support was used. Note, 0 means nothing is + said about the dword support. */ + new_partial = (new_flags & EF_FRV_DWORD_MASK); + old_partial = (old_flags & EF_FRV_DWORD_MASK); + if (new_partial == old_partial) + ; + + else if (new_partial == 0) + ; + + else if (old_partial == 0) + old_flags |= new_partial; + + else + { + switch (new_partial) + { + default: strcat (new_opt, " -mdword-?"); break; + case EF_FRV_DWORD_YES: strcat (new_opt, " -mdword"); break; + case EF_FRV_DWORD_NO: strcat (new_opt, " -mno-dword"); break; + } + + switch (old_partial) + { + default: strcat (old_opt, " -mdword-?"); break; + case EF_FRV_DWORD_YES: strcat (old_opt, " -mdword"); break; + case EF_FRV_DWORD_NO: strcat (old_opt, " -mno-dword"); break; + } + } + + /* Or in flags that accumulate (ie, if one module uses it, mark that the + feature is used. */ + old_flags |= new_flags & (EF_FRV_DOUBLE + | EF_FRV_MEDIA + | EF_FRV_MULADD + | EF_FRV_NON_PIC_RELOCS); + + /* If any module was compiled without -G0, clear the G0 bit. */ + old_flags = ((old_flags & ~ EF_FRV_G0) + | (old_flags & new_flags & EF_FRV_G0)); + + /* If any module was compiled without -mnopack, clear the mnopack bit. */ + old_flags = ((old_flags & ~ EF_FRV_NOPACK) + | (old_flags & new_flags & EF_FRV_NOPACK)); + + /* We don't have to do anything if the pic flags are the same, or the new + module(s) were compiled with -mlibrary-pic. */ + new_partial = (new_flags & EF_FRV_PIC_FLAGS); + old_partial = (old_flags & EF_FRV_PIC_FLAGS); + if ((new_partial == old_partial) || ((new_partial & EF_FRV_LIBPIC) != 0)) + ; + + /* If the old module(s) were compiled with -mlibrary-pic, copy in the pic + flags if any from the new module. */ + else if ((old_partial & EF_FRV_LIBPIC) != 0) + old_flags = (old_flags & ~ EF_FRV_PIC_FLAGS) | new_partial; + + /* If we have mixtures of -fpic and -fPIC, or in both bits. */ + else if (new_partial != 0 && old_partial != 0) + old_flags |= new_partial; + + /* One module was compiled for pic and the other was not, see if we have + had any relocations that are not pic-safe. */ + else + { + if ((old_flags & EF_FRV_NON_PIC_RELOCS) == 0) + old_flags |= new_partial; + else + { + old_flags &= ~ EF_FRV_PIC_FLAGS; +#ifndef FRV_NO_PIC_ERROR + error = true; + (*_bfd_error_handler) + (_("%s: compiled with %s and linked with modules that use non-pic relocations"), + bfd_get_filename (ibfd), + (new_flags & EF_FRV_BIGPIC) ? "-fPIC" : "-fpic"); +#endif + } + } + + /* Warn if different cpu is used (allow a specific cpu to override + the generic cpu). */ + new_partial = (new_flags & EF_FRV_CPU_MASK); + old_partial = (old_flags & EF_FRV_CPU_MASK); + if (new_partial == old_partial) + ; + + else if (new_partial == EF_FRV_CPU_GENERIC) + ; + + else if (old_partial == EF_FRV_CPU_GENERIC) + old_flags = (old_flags & ~EF_FRV_CPU_MASK) | new_partial; + + else + { + switch (new_partial) + { + default: strcat (new_opt, " -mcpu=?"); break; + case EF_FRV_CPU_GENERIC: strcat (new_opt, " -mcpu=frv"); break; + case EF_FRV_CPU_SIMPLE: strcat (new_opt, " -mcpu=simple"); break; + case EF_FRV_CPU_FR500: strcat (new_opt, " -mcpu=fr500"); break; + case EF_FRV_CPU_FR400: strcat (new_opt, " -mcpu=fr400"); break; + case EF_FRV_CPU_FR300: strcat (new_opt, " -mcpu=fr300"); break; + case EF_FRV_CPU_TOMCAT: strcat (new_opt, " -mcpu=tomcat"); break; + } + + switch (old_partial) + { + default: strcat (old_opt, " -mcpu=?"); break; + case EF_FRV_CPU_GENERIC: strcat (old_opt, " -mcpu=frv"); break; + case EF_FRV_CPU_SIMPLE: strcat (old_opt, " -mcpu=simple"); break; + case EF_FRV_CPU_FR500: strcat (old_opt, " -mcpu=fr500"); break; + case EF_FRV_CPU_FR400: strcat (old_opt, " -mcpu=fr400"); break; + case EF_FRV_CPU_FR300: strcat (old_opt, " -mcpu=fr300"); break; + case EF_FRV_CPU_TOMCAT: strcat (old_opt, " -mcpu=tomcat"); break; + } + } + + /* Print out any mismatches from above. */ + if (new_opt[0]) + { + error = true; + (*_bfd_error_handler) + (_("%s: compiled with %s and linked with modules compiled with %s"), + bfd_get_filename (ibfd), new_opt, old_opt); + } + + /* Warn about any other mismatches */ + new_partial = (new_flags & ~ EF_FRV_ALL_FLAGS); + old_partial = (old_flags & ~ EF_FRV_ALL_FLAGS); + if (new_partial != old_partial) + { + old_flags |= new_partial; + error = true; + (*_bfd_error_handler) + (_("%s: uses different unknown e_flags (0x%lx) fields than previous modules (0x%lx)"), + bfd_get_filename (ibfd), (long)new_partial, (long)old_partial); + } + } + + /* If the cpu is -mcpu=simple, then set the -mnopack bit. */ + if ((old_flags & EF_FRV_CPU_MASK) == EF_FRV_CPU_SIMPLE) + old_flags |= EF_FRV_NOPACK; + + /* Update the old flags now with changes made above. */ + old_partial = elf_elfheader (obfd)->e_flags & EF_FRV_CPU_MASK; + elf_elfheader (obfd)->e_flags = old_flags; + if (old_partial != (old_flags & EF_FRV_CPU_MASK)) + bfd_default_set_arch_mach (obfd, bfd_arch_frv, elf32_frv_machine (obfd)); + + if (error) + bfd_set_error (bfd_error_bad_value); + + return !error; +} + + +boolean +frv_elf_print_private_bfd_data (abfd, ptr) + bfd *abfd; + PTR ptr; +{ + FILE *file = (FILE *) ptr; + flagword flags; + + BFD_ASSERT (abfd != NULL && ptr != NULL); + + /* Print normal ELF private data. */ + _bfd_elf_print_private_bfd_data (abfd, ptr); + + flags = elf_elfheader (abfd)->e_flags; + fprintf (file, _("private flags = 0x%lx:"), (long)flags); + + switch (flags & EF_FRV_CPU_MASK) + { + default: break; + case EF_FRV_CPU_SIMPLE: fprintf (file, " -mcpu=simple"); break; + case EF_FRV_CPU_FR500: fprintf (file, " -mcpu=fr500"); break; + case EF_FRV_CPU_FR400: fprintf (file, " -mcpu=fr400"); break; + case EF_FRV_CPU_FR300: fprintf (file, " -mcpu=fr300"); break; + case EF_FRV_CPU_TOMCAT: fprintf (file, " -mcpu=tomcat"); break; + } + + switch (flags & EF_FRV_GPR_MASK) + { + default: break; + case EF_FRV_GPR_32: fprintf (file, " -mgpr-32"); break; + case EF_FRV_GPR_64: fprintf (file, " -mgpr-64"); break; + } + + switch (flags & EF_FRV_FPR_MASK) + { + default: break; + case EF_FRV_FPR_32: fprintf (file, " -mfpr-32"); break; + case EF_FRV_FPR_64: fprintf (file, " -mfpr-64"); break; + case EF_FRV_FPR_NONE: fprintf (file, " -msoft-float"); break; + } + + switch (flags & EF_FRV_DWORD_MASK) + { + default: break; + case EF_FRV_DWORD_YES: fprintf (file, " -mdword"); break; + case EF_FRV_DWORD_NO: fprintf (file, " -mno-dword"); break; + } + + if (flags & EF_FRV_DOUBLE) + fprintf (file, " -mdouble"); + + if (flags & EF_FRV_MEDIA) + fprintf (file, " -mmedia"); + + if (flags & EF_FRV_MULADD) + fprintf (file, " -mmuladd"); + + if (flags & EF_FRV_PIC) + fprintf (file, " -fpic"); + + if (flags & EF_FRV_BIGPIC) + fprintf (file, " -fPIC"); + + if (flags & EF_FRV_NON_PIC_RELOCS) + fprintf (file, " non-pic relocations"); + + if (flags & EF_FRV_G0) + fprintf (file, " -G0"); + + fputc ('\n', file); + return true; +} + + +#define ELF_ARCH bfd_arch_frv +#define ELF_MACHINE_CODE EM_CYGNUS_FRV +#define ELF_MAXPAGESIZE 0x1000 + +#define TARGET_BIG_SYM bfd_elf32_frv_vec +#define TARGET_BIG_NAME "elf32-frv" + +#define elf_info_to_howto_rel NULL +#define elf_info_to_howto frv_info_to_howto_rela +#define elf_backend_relocate_section elf32_frv_relocate_section +#define elf_backend_gc_mark_hook elf32_frv_gc_mark_hook +#define elf_backend_gc_sweep_hook elf32_frv_gc_sweep_hook +#define elf_backend_check_relocs elf32_frv_check_relocs +#define elf_backend_object_p elf32_frv_object_p +#define elf_backend_add_symbol_hook elf32_frv_add_symbol_hook + +#define elf_backend_can_gc_sections 1 + +#define bfd_elf32_bfd_reloc_type_lookup frv_reloc_type_lookup +#define bfd_elf32_bfd_set_private_flags frv_elf_set_private_flags +#define bfd_elf32_bfd_copy_private_bfd_data frv_elf_copy_private_bfd_data +#define bfd_elf32_bfd_merge_private_bfd_data frv_elf_merge_private_bfd_data +#define bfd_elf32_bfd_print_private_bfd_data frv_elf_print_private_bfd_data + +#include "elf32-target.h" diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c new file mode 100644 index 0000000..db1d7d4 --- /dev/null +++ b/gdb/ada-lang.c @@ -0,0 +1,8618 @@ +/* Ada language support routines for GDB, the GNU debugger. Copyright + 1992, 1993, 1994, 1997, 1998, 1999, 2000 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include +#include +#include +#include +#include "demangle.h" +#include "defs.h" +#include "symtab.h" +#include "gdbtypes.h" +#include "gdbcmd.h" +#include "expression.h" +#include "parser-defs.h" +#include "language.h" +#include "c-lang.h" +#include "inferior.h" +#include "symfile.h" +#include "objfiles.h" +#include "breakpoint.h" +#include "gdbcore.h" +#include "ada-lang.h" +#ifdef UI_OUT +#include "ui-out.h" +#endif + +struct cleanup* unresolved_names; + +void extract_string (CORE_ADDR addr, char *buf); + +static struct type * ada_create_fundamental_type (struct objfile *, int); + +static void modify_general_field (char *, LONGEST, int, int); + +static struct type* desc_base_type (struct type*); + +static struct type* desc_bounds_type (struct type*); + +static struct value* desc_bounds (struct value*); + +static int fat_pntr_bounds_bitpos (struct type*); + +static int fat_pntr_bounds_bitsize (struct type*); + +static struct type* desc_data_type (struct type*); + +static struct value* desc_data (struct value*); + +static int fat_pntr_data_bitpos (struct type*); + +static int fat_pntr_data_bitsize (struct type*); + +static struct value* desc_one_bound (struct value*, int, int); + +static int desc_bound_bitpos (struct type*, int, int); + +static int desc_bound_bitsize (struct type*, int, int); + +static struct type* desc_index_type (struct type*, int); + +static int desc_arity (struct type*); + +static int ada_type_match (struct type*, struct type*, int); + +static int ada_args_match (struct symbol*, struct value**, int); + +static struct value* place_on_stack (struct value*, CORE_ADDR*); + +static struct value* convert_actual (struct value*, struct type*, CORE_ADDR*); + +static struct value* make_array_descriptor (struct type*, struct value*, CORE_ADDR*); + +static void ada_add_block_symbols (struct block*, const char*, + namespace_enum, struct objfile*, int); + +static void fill_in_ada_prototype (struct symbol*); + +static int is_nonfunction (struct symbol**, int); + +static void add_defn_to_vec (struct symbol*, struct block*); + +static struct partial_symbol* +ada_lookup_partial_symbol (struct partial_symtab*, const char*, + int, namespace_enum, int); + +static struct symtab* symtab_for_sym (struct symbol*); + +static struct value* ada_resolve_subexp (struct expression**, int*, int, struct type*); + +static void replace_operator_with_call (struct expression**, int, int, int, + struct symbol*, struct block*); + +static int possible_user_operator_p (enum exp_opcode, struct value**); + +static const char* ada_op_name (enum exp_opcode); + +static int numeric_type_p (struct type*); + +static int integer_type_p (struct type*); + +static int scalar_type_p (struct type*); + +static int discrete_type_p (struct type*); + +static char* extended_canonical_line_spec (struct symtab_and_line, const char*); + +static struct value* evaluate_subexp (struct type*, struct expression*, int*, enum noside); + +static struct value* evaluate_subexp_type (struct expression*, int*); + +static struct type * ada_create_fundamental_type (struct objfile*, int); + +static int is_dynamic_field (struct type *, int); + +static struct type* +to_fixed_variant_branch_type (struct type*, char*, CORE_ADDR, struct value*); + +static struct type* to_fixed_range_type (char*, struct value*, struct objfile*); + +static struct type* to_static_fixed_type (struct type*); + +static struct value* unwrap_value (struct value*); + +static struct type* packed_array_type (struct type*, long*); + +static struct type* decode_packed_array_type (struct type*); + +static struct value* decode_packed_array (struct value*); + +static struct value* value_subscript_packed (struct value*, int, struct value**); + +static struct value* coerce_unspec_val_to_type (struct value*, long, struct type*); + +static struct value* get_var_value (char*, char*); + +static int lesseq_defined_than (struct symbol*, struct symbol*); + +static int equiv_types (struct type*, struct type*); + +static int is_name_suffix (const char*); + +static int wild_match (const char*, int, const char*); + +static struct symtabs_and_lines find_sal_from_funcs_and_line (const char*, int, struct symbol**, int); + +static int +find_line_in_linetable (struct linetable*, int, struct symbol**, int, int*); + +static int find_next_line_in_linetable (struct linetable*, int, int, int); + +static struct symtabs_and_lines all_sals_for_line (const char*, int, char***); + +static void read_all_symtabs (const char*); + +static int is_plausible_func_for_line (struct symbol*, int); + +static struct value* ada_coerce_ref (struct value*); + +static struct value* value_pos_atr (struct value*); + +static struct value* value_val_atr (struct type*, struct value*); + +static struct symbol* standard_lookup (const char*, namespace_enum); + +extern void markTimeStart (int index); +extern void markTimeStop (int index); + + + +/* Maximum-sized dynamic type. */ +static unsigned int varsize_limit; + +static const char* ada_completer_word_break_characters = + " \t\n!@#$%^&*()+=|~`}{[]\";:?/,-"; + +/* The name of the symbol to use to get the name of the main subprogram */ +#define ADA_MAIN_PROGRAM_SYMBOL_NAME "__gnat_ada_main_program_name" + + /* Utilities */ + +/* extract_string + * + * read the string located at ADDR from the inferior and store the + * result into BUF + */ +void +extract_string (CORE_ADDR addr, char *buf) +{ + int char_index = 0; + + /* Loop, reading one byte at a time, until we reach the '\000' + end-of-string marker */ + do + { + target_read_memory (addr + char_index * sizeof (char), + buf + char_index * sizeof (char), + sizeof (char)); + char_index++; + } + while (buf[char_index - 1] != '\000'); +} + +/* Assuming *OLD_VECT points to an array of *SIZE objects of size + ELEMENT_SIZE, grow it to contain at least MIN_SIZE objects, + updating *OLD_VECT and *SIZE as necessary. */ + +void +grow_vect (old_vect, size, min_size, element_size) + void** old_vect; + size_t* size; + size_t min_size; + int element_size; +{ + if (*size < min_size) { + *size *= 2; + if (*size < min_size) + *size = min_size; + *old_vect = xrealloc (*old_vect, *size * element_size); + } +} + +/* True (non-zero) iff TARGET matches FIELD_NAME up to any trailing + suffix of FIELD_NAME beginning "___" */ + +static int +field_name_match (field_name, target) + const char *field_name; + const char *target; +{ + int len = strlen (target); + return + STREQN (field_name, target, len) + && (field_name[len] == '\0' + || (STREQN (field_name + len, "___", 3) + && ! STREQ (field_name + strlen (field_name) - 6, "___XVN"))); +} + + +/* The length of the prefix of NAME prior to any "___" suffix. */ + +int +ada_name_prefix_len (name) + const char* name; +{ + if (name == NULL) + return 0; + else + { + const char* p = strstr (name, "___"); + if (p == NULL) + return strlen (name); + else + return p - name; + } +} + +/* SUFFIX is a suffix of STR. False if STR is null. */ +static int +is_suffix (const char* str, const char* suffix) +{ + int len1, len2; + if (str == NULL) + return 0; + len1 = strlen (str); + len2 = strlen (suffix); + return (len1 >= len2 && STREQ (str + len1 - len2, suffix)); +} + +/* Create a value of type TYPE whose contents come from VALADDR, if it + * is non-null, and whose memory address (in the inferior) is + * ADDRESS. */ +struct value* +value_from_contents_and_address (type, valaddr, address) + struct type* type; + char* valaddr; + CORE_ADDR address; +{ + struct value* v = allocate_value (type); + if (valaddr == NULL) + VALUE_LAZY (v) = 1; + else + memcpy (VALUE_CONTENTS_RAW (v), valaddr, TYPE_LENGTH (type)); + VALUE_ADDRESS (v) = address; + if (address != 0) + VALUE_LVAL (v) = lval_memory; + return v; +} + +/* The contents of value VAL, beginning at offset OFFSET, treated as a + value of type TYPE. The result is an lval in memory if VAL is. */ + +static struct value* +coerce_unspec_val_to_type (val, offset, type) + struct value* val; + long offset; + struct type *type; +{ + CHECK_TYPEDEF (type); + if (VALUE_LVAL (val) == lval_memory) + return value_at_lazy (type, + VALUE_ADDRESS (val) + VALUE_OFFSET (val) + offset, NULL); + else + { + struct value* result = allocate_value (type); + VALUE_LVAL (result) = not_lval; + if (VALUE_ADDRESS (val) == 0) + memcpy (VALUE_CONTENTS_RAW (result), VALUE_CONTENTS (val) + offset, + TYPE_LENGTH (type) > TYPE_LENGTH (VALUE_TYPE (val)) + ? TYPE_LENGTH (VALUE_TYPE (val)) : TYPE_LENGTH (type)); + else + { + VALUE_ADDRESS (result) = + VALUE_ADDRESS (val) + VALUE_OFFSET (val) + offset; + VALUE_LAZY (result) = 1; + } + return result; + } +} + +static char* +cond_offset_host (valaddr, offset) + char* valaddr; + long offset; +{ + if (valaddr == NULL) + return NULL; + else + return valaddr + offset; +} + +static CORE_ADDR +cond_offset_target (address, offset) + CORE_ADDR address; + long offset; +{ + if (address == 0) + return 0; + else + return address + offset; +} + +/* Perform execute_command on the result of concatenating all + arguments up to NULL. */ +static void +do_command (const char* arg, ...) +{ + int len; + char* cmd; + const char* s; + va_list ap; + + va_start (ap, arg); + len = 0; + s = arg; + cmd = ""; + for (; s != NULL; s = va_arg (ap, const char*)) + { + char* cmd1; + len += strlen (s); + cmd1 = alloca (len+1); + strcpy (cmd1, cmd); + strcat (cmd1, s); + cmd = cmd1; + } + va_end (ap); + execute_command (cmd, 0); +} + + + /* Language Selection */ + +/* If the main program is in Ada, return language_ada, otherwise return LANG + (the main program is in Ada iif the adainit symbol is found). + + MAIN_PST is not used. */ + +enum language +ada_update_initial_language (lang, main_pst) + enum language lang; + struct partial_symtab* main_pst; +{ + if (lookup_minimal_symbol ("adainit", (const char*) NULL, + (struct objfile*) NULL) != NULL) + /* return language_ada; */ + /* FIXME: language_ada should be defined in defs.h */ + return language_unknown; + + return lang; +} + + + /* Symbols */ + +/* Table of Ada operators and their GNAT-mangled names. Last entry is pair + of NULLs. */ + +const struct ada_opname_map ada_opname_table[] = +{ + { "Oadd", "\"+\"", BINOP_ADD }, + { "Osubtract", "\"-\"", BINOP_SUB }, + { "Omultiply", "\"*\"", BINOP_MUL }, + { "Odivide", "\"/\"", BINOP_DIV }, + { "Omod", "\"mod\"", BINOP_MOD }, + { "Orem", "\"rem\"", BINOP_REM }, + { "Oexpon", "\"**\"", BINOP_EXP }, + { "Olt", "\"<\"", BINOP_LESS }, + { "Ole", "\"<=\"", BINOP_LEQ }, + { "Ogt", "\">\"", BINOP_GTR }, + { "Oge", "\">=\"", BINOP_GEQ }, + { "Oeq", "\"=\"", BINOP_EQUAL }, + { "One", "\"/=\"", BINOP_NOTEQUAL }, + { "Oand", "\"and\"", BINOP_BITWISE_AND }, + { "Oor", "\"or\"", BINOP_BITWISE_IOR }, + { "Oxor", "\"xor\"", BINOP_BITWISE_XOR }, + { "Oconcat", "\"&\"", BINOP_CONCAT }, + { "Oabs", "\"abs\"", UNOP_ABS }, + { "Onot", "\"not\"", UNOP_LOGICAL_NOT }, + { "Oadd", "\"+\"", UNOP_PLUS }, + { "Osubtract", "\"-\"", UNOP_NEG }, + { NULL, NULL } +}; + +/* True if STR should be suppressed in info listings. */ +static int +is_suppressed_name (str) + const char* str; +{ + if (STREQN (str, "_ada_", 5)) + str += 5; + if (str[0] == '_' || str[0] == '\000') + return 1; + else + { + const char* p; + const char* suffix = strstr (str, "___"); + if (suffix != NULL && suffix[3] != 'X') + return 1; + if (suffix == NULL) + suffix = str + strlen (str); + for (p = suffix-1; p != str; p -= 1) + if (isupper (*p)) + { + int i; + if (p[0] == 'X' && p[-1] != '_') + goto OK; + if (*p != 'O') + return 1; + for (i = 0; ada_opname_table[i].mangled != NULL; i += 1) + if (STREQN (ada_opname_table[i].mangled, p, + strlen (ada_opname_table[i].mangled))) + goto OK; + return 1; + OK: ; + } + return 0; + } +} + +/* The "mangled" form of DEMANGLED, according to GNAT conventions. + * The result is valid until the next call to ada_mangle. */ +char * +ada_mangle (demangled) + const char* demangled; +{ + static char* mangling_buffer = NULL; + static size_t mangling_buffer_size = 0; + const char* p; + int k; + + if (demangled == NULL) + return NULL; + + GROW_VECT (mangling_buffer, mangling_buffer_size, 2*strlen (demangled) + 10); + + k = 0; + for (p = demangled; *p != '\0'; p += 1) + { + if (*p == '.') + { + mangling_buffer[k] = mangling_buffer[k+1] = '_'; + k += 2; + } + else if (*p == '"') + { + const struct ada_opname_map* mapping; + + for (mapping = ada_opname_table; + mapping->mangled != NULL && + ! STREQN (mapping->demangled, p, strlen (mapping->demangled)); + p += 1) + ; + if (mapping->mangled == NULL) + error ("invalid Ada operator name: %s", p); + strcpy (mangling_buffer+k, mapping->mangled); + k += strlen (mapping->mangled); + break; + } + else + { + mangling_buffer[k] = *p; + k += 1; + } + } + + mangling_buffer[k] = '\0'; + return mangling_buffer; +} + +/* Return NAME folded to lower case, or, if surrounded by single + * quotes, unfolded, but with the quotes stripped away. Result good + * to next call. */ +char* +ada_fold_name (const char* name) +{ + static char* fold_buffer = NULL; + static size_t fold_buffer_size = 0; + + int len = strlen (name); + GROW_VECT (fold_buffer, fold_buffer_size, len+1); + + if (name[0] == '\'') + { + strncpy (fold_buffer, name+1, len-2); + fold_buffer[len-2] = '\000'; + } + else + { + int i; + for (i = 0; i <= len; i += 1) + fold_buffer[i] = tolower (name[i]); + } + + return fold_buffer; +} + +/* Demangle: + 1. Discard final __{DIGIT}+ or ${DIGIT}+ + 2. Convert other instances of embedded "__" to `.'. + 3. Discard leading _ada_. + 4. Convert operator names to the appropriate quoted symbols. + 5. Remove everything after first ___ if it is followed by + 'X'. + 6. Replace TK__ with __, and a trailing B or TKB with nothing. + 7. Put symbols that should be suppressed in <...> brackets. + 8. Remove trailing X[bn]* suffix (indicating names in package bodies). + The resulting string is valid until the next call of ada_demangle. + */ + +char * +ada_demangle (mangled) + const char* mangled; +{ + int i, j; + int len0; + const char* p; + char* demangled; + int at_start_name; + static char* demangling_buffer = NULL; + static size_t demangling_buffer_size = 0; + + if (STREQN (mangled, "_ada_", 5)) + mangled += 5; + + if (mangled[0] == '_' || mangled[0] == '<') + goto Suppress; + + p = strstr (mangled, "___"); + if (p == NULL) + len0 = strlen (mangled); + else + { + if (p[3] == 'X') + len0 = p - mangled; + else + goto Suppress; + } + if (len0 > 3 && STREQ (mangled + len0 - 3, "TKB")) + len0 -= 3; + if (len0 > 1 && STREQ (mangled + len0 - 1, "B")) + len0 -= 1; + + /* Make demangled big enough for possible expansion by operator name. */ + GROW_VECT (demangling_buffer, demangling_buffer_size, 2*len0+1); + demangled = demangling_buffer; + + if (isdigit (mangled[len0 - 1])) { + for (i = len0-2; i >= 0 && isdigit (mangled[i]); i -= 1) + ; + if (i > 1 && mangled[i] == '_' && mangled[i-1] == '_') + len0 = i - 1; + else if (mangled[i] == '$') + len0 = i; + } + + for (i = 0, j = 0; i < len0 && ! isalpha (mangled[i]); i += 1, j += 1) + demangled[j] = mangled[i]; + + at_start_name = 1; + while (i < len0) + { + if (at_start_name && mangled[i] == 'O') + { + int k; + for (k = 0; ada_opname_table[k].mangled != NULL; k += 1) + { + int op_len = strlen (ada_opname_table[k].mangled); + if (STREQN (ada_opname_table[k].mangled+1, mangled+i+1, op_len-1) + && ! isalnum (mangled[i + op_len])) + { + strcpy (demangled + j, ada_opname_table[k].demangled); + at_start_name = 0; + i += op_len; + j += strlen (ada_opname_table[k].demangled); + break; + } + } + if (ada_opname_table[k].mangled != NULL) + continue; + } + at_start_name = 0; + + if (i < len0-4 && STREQN (mangled+i, "TK__", 4)) + i += 2; + if (mangled[i] == 'X' && i != 0 && isalnum (mangled[i-1])) + { + do + i += 1; + while (i < len0 && (mangled[i] == 'b' || mangled[i] == 'n')); + if (i < len0) + goto Suppress; + } + else if (i < len0-2 && mangled[i] == '_' && mangled[i+1] == '_') + { + demangled[j] = '.'; + at_start_name = 1; + i += 2; j += 1; + } + else + { + demangled[j] = mangled[i]; + i += 1; j += 1; + } + } + demangled[j] = '\000'; + + for (i = 0; demangled[i] != '\0'; i += 1) + if (isupper (demangled[i]) || demangled[i] == ' ') + goto Suppress; + + return demangled; + +Suppress: + GROW_VECT (demangling_buffer, demangling_buffer_size, + strlen (mangled) + 3); + demangled = demangling_buffer; + if (mangled[0] == '<') + strcpy (demangled, mangled); + else + sprintf (demangled, "<%s>", mangled); + return demangled; + +} + +/* Returns non-zero iff SYM_NAME matches NAME, ignoring any trailing + * suffixes that encode debugging information or leading _ada_ on + * SYM_NAME (see is_name_suffix commentary for the debugging + * information that is ignored). If WILD, then NAME need only match a + * suffix of SYM_NAME minus the same suffixes. Also returns 0 if + * either argument is NULL. */ + +int +ada_match_name (sym_name, name, wild) + const char* sym_name; + const char* name; + int wild; +{ + if (sym_name == NULL || name == NULL) + return 0; + else if (wild) + return wild_match (name, strlen (name), sym_name); + else { + int len_name = strlen (name); + return (STREQN (sym_name, name, len_name) + && is_name_suffix (sym_name+len_name)) + || (STREQN (sym_name, "_ada_", 5) + && STREQN (sym_name+5, name, len_name) + && is_name_suffix (sym_name+len_name+5)); + } +} + +/* True (non-zero) iff in Ada mode, the symbol SYM should be + suppressed in info listings. */ + +int +ada_suppress_symbol_printing (sym) + struct symbol *sym; +{ + if (SYMBOL_NAMESPACE (sym) == STRUCT_NAMESPACE) + return 1; + else + return is_suppressed_name (SYMBOL_NAME (sym)); +} + + + /* Arrays */ + +/* Names of MAX_ADA_DIMENS bounds in P_BOUNDS fields of + array descriptors. */ + +static char* bound_name[] = { + "LB0", "UB0", "LB1", "UB1", "LB2", "UB2", "LB3", "UB3", + "LB4", "UB4", "LB5", "UB5", "LB6", "UB6", "LB7", "UB7" +}; + +/* Maximum number of array dimensions we are prepared to handle. */ + +#define MAX_ADA_DIMENS (sizeof(bound_name) / (2*sizeof(char*))) + +/* Like modify_field, but allows bitpos > wordlength. */ + +static void +modify_general_field (addr, fieldval, bitpos, bitsize) + char *addr; + LONGEST fieldval; + int bitpos, bitsize; +{ + modify_field (addr + sizeof (LONGEST) * bitpos / (8 * sizeof (LONGEST)), + fieldval, bitpos % (8 * sizeof (LONGEST)), + bitsize); +} + + +/* The desc_* routines return primitive portions of array descriptors + (fat pointers). */ + +/* The descriptor or array type, if any, indicated by TYPE; removes + level of indirection, if needed. */ +static struct type* +desc_base_type (type) + struct type* type; +{ + if (type == NULL) + return NULL; + CHECK_TYPEDEF (type); + if (type != NULL && TYPE_CODE (type) == TYPE_CODE_PTR) + return check_typedef (TYPE_TARGET_TYPE (type)); + else + return type; +} + +/* True iff TYPE indicates a "thin" array pointer type. */ +static int +is_thin_pntr (struct type* type) +{ + return + is_suffix (ada_type_name (desc_base_type (type)), "___XUT") + || is_suffix (ada_type_name (desc_base_type (type)), "___XUT___XVE"); +} + +/* The descriptor type for thin pointer type TYPE. */ +static struct type* +thin_descriptor_type (struct type* type) +{ + struct type* base_type = desc_base_type (type); + if (base_type == NULL) + return NULL; + if (is_suffix (ada_type_name (base_type), "___XVE")) + return base_type; + else + { + struct type* alt_type = + ada_find_parallel_type (base_type, "___XVE"); + if (alt_type == NULL) + return base_type; + else + return alt_type; + } +} + +/* A pointer to the array data for thin-pointer value VAL. */ +static struct value* +thin_data_pntr (struct value* val) +{ + struct type* type = VALUE_TYPE (val); + if (TYPE_CODE (type) == TYPE_CODE_PTR) + return value_cast (desc_data_type (thin_descriptor_type (type)), + value_copy (val)); + else + return value_from_longest (desc_data_type (thin_descriptor_type (type)), + VALUE_ADDRESS (val) + VALUE_OFFSET (val)); +} + +/* True iff TYPE indicates a "thick" array pointer type. */ +static int +is_thick_pntr (struct type* type) +{ + type = desc_base_type (type); + return (type != NULL && TYPE_CODE (type) == TYPE_CODE_STRUCT + && lookup_struct_elt_type (type, "P_BOUNDS", 1) != NULL); +} + +/* If TYPE is the type of an array descriptor (fat or thin pointer) or a + pointer to one, the type of its bounds data; otherwise, NULL. */ +static struct type* +desc_bounds_type (type) + struct type* type; +{ + struct type* r; + + type = desc_base_type (type); + + if (type == NULL) + return NULL; + else if (is_thin_pntr (type)) + { + type = thin_descriptor_type (type); + if (type == NULL) + return NULL; + r = lookup_struct_elt_type (type, "BOUNDS", 1); + if (r != NULL) + return check_typedef (r); + } + else if (TYPE_CODE (type) == TYPE_CODE_STRUCT) + { + r = lookup_struct_elt_type (type, "P_BOUNDS", 1); + if (r != NULL) + return check_typedef (TYPE_TARGET_TYPE (check_typedef (r))); + } + return NULL; +} + +/* If ARR is an array descriptor (fat or thin pointer), or pointer to + one, a pointer to its bounds data. Otherwise NULL. */ +static struct value* +desc_bounds (arr) + struct value* arr; +{ + struct type* type = check_typedef (VALUE_TYPE (arr)); + if (is_thin_pntr (type)) + { + struct type* bounds_type = desc_bounds_type (thin_descriptor_type (type)); + LONGEST addr; + + if (desc_bounds_type == NULL) + error ("Bad GNAT array descriptor"); + + /* NOTE: The following calculation is not really kosher, but + since desc_type is an XVE-encoded type (and shouldn't be), + the correct calculation is a real pain. FIXME (and fix GCC). */ + if (TYPE_CODE (type) == TYPE_CODE_PTR) + addr = value_as_long (arr); + else + addr = VALUE_ADDRESS (arr) + VALUE_OFFSET (arr); + + return + value_from_longest (lookup_pointer_type (bounds_type), + addr - TYPE_LENGTH (bounds_type)); + } + + else if (is_thick_pntr (type)) + return value_struct_elt (&arr, NULL, "P_BOUNDS", NULL, + "Bad GNAT array descriptor"); + else + return NULL; +} + +/* If TYPE is the type of an array-descriptor (fat pointer), the bit + position of the field containing the address of the bounds data. */ +static int +fat_pntr_bounds_bitpos (type) + struct type* type; +{ + return TYPE_FIELD_BITPOS (desc_base_type (type), 1); +} + +/* If TYPE is the type of an array-descriptor (fat pointer), the bit + size of the field containing the address of the bounds data. */ +static int +fat_pntr_bounds_bitsize (type) + struct type* type; +{ + type = desc_base_type (type); + + if (TYPE_FIELD_BITSIZE (type, 1) > 0) + return TYPE_FIELD_BITSIZE (type, 1); + else + return 8 * TYPE_LENGTH (check_typedef (TYPE_FIELD_TYPE (type, 1))); +} + +/* If TYPE is the type of an array descriptor (fat or thin pointer) or a + pointer to one, the type of its array data (a + pointer-to-array-with-no-bounds type); otherwise, NULL. Use + ada_type_of_array to get an array type with bounds data. */ +static struct type* +desc_data_type (type) + struct type* type; +{ + type = desc_base_type (type); + + /* NOTE: The following is bogus; see comment in desc_bounds. */ + if (is_thin_pntr (type)) + return lookup_pointer_type + (desc_base_type (TYPE_FIELD_TYPE (thin_descriptor_type (type),1))); + else if (is_thick_pntr (type)) + return lookup_struct_elt_type (type, "P_ARRAY", 1); + else + return NULL; +} + +/* If ARR is an array descriptor (fat or thin pointer), a pointer to + its array data. */ +static struct value* +desc_data (arr) + struct value* arr; +{ + struct type* type = VALUE_TYPE (arr); + if (is_thin_pntr (type)) + return thin_data_pntr (arr); + else if (is_thick_pntr (type)) + return value_struct_elt (&arr, NULL, "P_ARRAY", NULL, + "Bad GNAT array descriptor"); + else + return NULL; +} + + +/* If TYPE is the type of an array-descriptor (fat pointer), the bit + position of the field containing the address of the data. */ +static int +fat_pntr_data_bitpos (type) + struct type* type; +{ + return TYPE_FIELD_BITPOS (desc_base_type (type), 0); +} + +/* If TYPE is the type of an array-descriptor (fat pointer), the bit + size of the field containing the address of the data. */ +static int +fat_pntr_data_bitsize (type) + struct type* type; +{ + type = desc_base_type (type); + + if (TYPE_FIELD_BITSIZE (type, 0) > 0) + return TYPE_FIELD_BITSIZE (type, 0); + else + return TARGET_CHAR_BIT * TYPE_LENGTH (TYPE_FIELD_TYPE (type, 0)); +} + +/* If BOUNDS is an array-bounds structure (or pointer to one), return + the Ith lower bound stored in it, if WHICH is 0, and the Ith upper + bound, if WHICH is 1. The first bound is I=1. */ +static struct value* +desc_one_bound (bounds, i, which) + struct value* bounds; + int i; + int which; +{ + return value_struct_elt (&bounds, NULL, bound_name[2*i+which-2], NULL, + "Bad GNAT array descriptor bounds"); +} + +/* If BOUNDS is an array-bounds structure type, return the bit position + of the Ith lower bound stored in it, if WHICH is 0, and the Ith upper + bound, if WHICH is 1. The first bound is I=1. */ +static int +desc_bound_bitpos (type, i, which) + struct type* type; + int i; + int which; +{ + return TYPE_FIELD_BITPOS (desc_base_type (type), 2*i+which-2); +} + +/* If BOUNDS is an array-bounds structure type, return the bit field size + of the Ith lower bound stored in it, if WHICH is 0, and the Ith upper + bound, if WHICH is 1. The first bound is I=1. */ +static int +desc_bound_bitsize (type, i, which) + struct type* type; + int i; + int which; +{ + type = desc_base_type (type); + + if (TYPE_FIELD_BITSIZE (type, 2*i+which-2) > 0) + return TYPE_FIELD_BITSIZE (type, 2*i+which-2); + else + return 8 * TYPE_LENGTH (TYPE_FIELD_TYPE (type, 2*i+which-2)); +} + +/* If TYPE is the type of an array-bounds structure, the type of its + Ith bound (numbering from 1). Otherwise, NULL. */ +static struct type* +desc_index_type (type, i) + struct type* type; + int i; +{ + type = desc_base_type (type); + + if (TYPE_CODE (type) == TYPE_CODE_STRUCT) + return lookup_struct_elt_type (type, bound_name[2*i-2], 1); + else + return NULL; +} + +/* The number of index positions in the array-bounds type TYPE. 0 + if TYPE is NULL. */ +static int +desc_arity (type) + struct type* type; +{ + type = desc_base_type (type); + + if (type != NULL) + return TYPE_NFIELDS (type) / 2; + return 0; +} + + +/* Non-zero iff type is a simple array type (or pointer to one). */ +int +ada_is_simple_array (type) + struct type* type; +{ + if (type == NULL) + return 0; + CHECK_TYPEDEF (type); + return (TYPE_CODE (type) == TYPE_CODE_ARRAY + || (TYPE_CODE (type) == TYPE_CODE_PTR + && TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_ARRAY)); +} + +/* Non-zero iff type belongs to a GNAT array descriptor. */ +int +ada_is_array_descriptor (type) + struct type* type; +{ + struct type* data_type = desc_data_type (type); + + if (type == NULL) + return 0; + CHECK_TYPEDEF (type); + return + data_type != NULL + && ((TYPE_CODE (data_type) == TYPE_CODE_PTR + && TYPE_TARGET_TYPE (data_type) != NULL + && TYPE_CODE (TYPE_TARGET_TYPE (data_type)) == TYPE_CODE_ARRAY) + || + TYPE_CODE (data_type) == TYPE_CODE_ARRAY) + && desc_arity (desc_bounds_type (type)) > 0; +} + +/* Non-zero iff type is a partially mal-formed GNAT array + descriptor. (FIXME: This is to compensate for some problems with + debugging output from GNAT. Re-examine periodically to see if it + is still needed. */ +int +ada_is_bogus_array_descriptor (type) + struct type *type; +{ + return + type != NULL + && TYPE_CODE (type) == TYPE_CODE_STRUCT + && (lookup_struct_elt_type (type, "P_BOUNDS", 1) != NULL + || lookup_struct_elt_type (type, "P_ARRAY", 1) != NULL) + && ! ada_is_array_descriptor (type); +} + + +/* If ARR has a record type in the form of a standard GNAT array descriptor, + (fat pointer) returns the type of the array data described---specifically, + a pointer-to-array type. If BOUNDS is non-zero, the bounds data are filled + in from the descriptor; otherwise, they are left unspecified. If + the ARR denotes a null array descriptor and BOUNDS is non-zero, + returns NULL. The result is simply the type of ARR if ARR is not + a descriptor. */ +struct type* +ada_type_of_array (arr, bounds) + struct value* arr; + int bounds; +{ + if (ada_is_packed_array_type (VALUE_TYPE (arr))) + return decode_packed_array_type (VALUE_TYPE (arr)); + + if (! ada_is_array_descriptor (VALUE_TYPE (arr))) + return VALUE_TYPE (arr); + + if (! bounds) + return check_typedef (TYPE_TARGET_TYPE (desc_data_type (VALUE_TYPE (arr)))); + else + { + struct type* elt_type; + int arity; + struct value* descriptor; + struct objfile *objf = TYPE_OBJFILE (VALUE_TYPE (arr)); + + elt_type = ada_array_element_type (VALUE_TYPE (arr), -1); + arity = ada_array_arity (VALUE_TYPE (arr)); + + if (elt_type == NULL || arity == 0) + return check_typedef (VALUE_TYPE (arr)); + + descriptor = desc_bounds (arr); + if (value_as_long (descriptor) == 0) + return NULL; + while (arity > 0) { + struct type* range_type = alloc_type (objf); + struct type* array_type = alloc_type (objf); + struct value* low = desc_one_bound (descriptor, arity, 0); + struct value* high = desc_one_bound (descriptor, arity, 1); + arity -= 1; + + create_range_type (range_type, VALUE_TYPE (low), + (int) value_as_long (low), + (int) value_as_long (high)); + elt_type = create_array_type (array_type, elt_type, range_type); + } + + return lookup_pointer_type (elt_type); + } +} + +/* If ARR does not represent an array, returns ARR unchanged. + Otherwise, returns either a standard GDB array with bounds set + appropriately or, if ARR is a non-null fat pointer, a pointer to a standard + GDB array. Returns NULL if ARR is a null fat pointer. */ +struct value* +ada_coerce_to_simple_array_ptr (arr) + struct value* arr; +{ + if (ada_is_array_descriptor (VALUE_TYPE (arr))) + { + struct type* arrType = ada_type_of_array (arr, 1); + if (arrType == NULL) + return NULL; + return value_cast (arrType, value_copy (desc_data (arr))); + } + else if (ada_is_packed_array_type (VALUE_TYPE (arr))) + return decode_packed_array (arr); + else + return arr; +} + +/* If ARR does not represent an array, returns ARR unchanged. + Otherwise, returns a standard GDB array describing ARR (which may + be ARR itself if it already is in the proper form). */ +struct value* +ada_coerce_to_simple_array (arr) + struct value* arr; +{ + if (ada_is_array_descriptor (VALUE_TYPE (arr))) + { + struct value* arrVal = ada_coerce_to_simple_array_ptr (arr); + if (arrVal == NULL) + error ("Bounds unavailable for null array pointer."); + return value_ind (arrVal); + } + else if (ada_is_packed_array_type (VALUE_TYPE (arr))) + return decode_packed_array (arr); + else + return arr; +} + +/* If TYPE represents a GNAT array type, return it translated to an + ordinary GDB array type (possibly with BITSIZE fields indicating + packing). For other types, is the identity. */ +struct type* +ada_coerce_to_simple_array_type (type) + struct type* type; +{ + struct value* mark = value_mark (); + struct value* dummy = value_from_longest (builtin_type_long, 0); + struct type* result; + VALUE_TYPE (dummy) = type; + result = ada_type_of_array (dummy, 0); + value_free_to_mark (dummy); + return result; +} + +/* Non-zero iff TYPE represents a standard GNAT packed-array type. */ +int +ada_is_packed_array_type (type) + struct type* type; +{ + if (type == NULL) + return 0; + CHECK_TYPEDEF (type); + return + ada_type_name (type) != NULL + && strstr (ada_type_name (type), "___XP") != NULL; +} + +/* Given that TYPE is a standard GDB array type with all bounds filled + in, and that the element size of its ultimate scalar constituents + (that is, either its elements, or, if it is an array of arrays, its + elements' elements, etc.) is *ELT_BITS, return an identical type, + but with the bit sizes of its elements (and those of any + constituent arrays) recorded in the BITSIZE components of its + TYPE_FIELD_BITSIZE values, and with *ELT_BITS set to its total size + in bits. */ +static struct type* +packed_array_type (type, elt_bits) + struct type* type; + long* elt_bits; +{ + struct type* new_elt_type; + struct type* new_type; + LONGEST low_bound, high_bound; + + CHECK_TYPEDEF (type); + if (TYPE_CODE (type) != TYPE_CODE_ARRAY) + return type; + + new_type = alloc_type (TYPE_OBJFILE (type)); + new_elt_type = packed_array_type (check_typedef (TYPE_TARGET_TYPE (type)), + elt_bits); + create_array_type (new_type, new_elt_type, TYPE_FIELD_TYPE (type, 0)); + TYPE_FIELD_BITSIZE (new_type, 0) = *elt_bits; + TYPE_NAME (new_type) = ada_type_name (type); + + if (get_discrete_bounds (TYPE_FIELD_TYPE (type, 0), + &low_bound, &high_bound) < 0) + low_bound = high_bound = 0; + if (high_bound < low_bound) + *elt_bits = TYPE_LENGTH (new_type) = 0; + else + { + *elt_bits *= (high_bound - low_bound + 1); + TYPE_LENGTH (new_type) = + (*elt_bits + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT; + } + + /* TYPE_FLAGS (new_type) |= TYPE_FLAG_FIXED_INSTANCE; */ + /* FIXME: TYPE_FLAG_FIXED_INSTANCE should be defined in gdbtypes.h */ + return new_type; +} + +/* The array type encoded by TYPE, where ada_is_packed_array_type (TYPE). + */ +static struct type* +decode_packed_array_type (type) + struct type* type; +{ + struct symbol** syms; + struct block** blocks; + const char* raw_name = ada_type_name (check_typedef (type)); + char* name = (char*) alloca (strlen (raw_name) + 1); + char* tail = strstr (raw_name, "___XP"); + struct type* shadow_type; + long bits; + int i, n; + + memcpy (name, raw_name, tail - raw_name); + name[tail - raw_name] = '\000'; + + /* NOTE: Use ada_lookup_symbol_list because of bug in some versions + * of gcc (Solaris, e.g.). FIXME when compiler is fixed. */ + n = ada_lookup_symbol_list (name, get_selected_block (NULL), + VAR_NAMESPACE, &syms, &blocks); + for (i = 0; i < n; i += 1) + if (syms[i] != NULL && SYMBOL_CLASS (syms[i]) == LOC_TYPEDEF + && STREQ (name, ada_type_name (SYMBOL_TYPE (syms[i])))) + break; + if (i >= n) + { + warning ("could not find bounds information on packed array"); + return NULL; + } + shadow_type = SYMBOL_TYPE (syms[i]); + + if (TYPE_CODE (shadow_type) != TYPE_CODE_ARRAY) + { + warning ("could not understand bounds information on packed array"); + return NULL; + } + + if (sscanf (tail + sizeof ("___XP") - 1, "%ld", &bits) != 1) + { + warning ("could not understand bit size information on packed array"); + return NULL; + } + + return packed_array_type (shadow_type, &bits); +} + +/* Given that ARR is a struct value* indicating a GNAT packed array, + returns a simple array that denotes that array. Its type is a + standard GDB array type except that the BITSIZEs of the array + target types are set to the number of bits in each element, and the + type length is set appropriately. */ + +static struct value* +decode_packed_array (arr) + struct value* arr; +{ + struct type* type = decode_packed_array_type (VALUE_TYPE (arr)); + + if (type == NULL) + { + error ("can't unpack array"); + return NULL; + } + else + return coerce_unspec_val_to_type (arr, 0, type); +} + + +/* The value of the element of packed array ARR at the ARITY indices + given in IND. ARR must be a simple array. */ + +static struct value* +value_subscript_packed (arr, arity, ind) + struct value* arr; + int arity; + struct value** ind; +{ + int i; + int bits, elt_off, bit_off; + long elt_total_bit_offset; + struct type* elt_type; + struct value* v; + + bits = 0; + elt_total_bit_offset = 0; + elt_type = check_typedef (VALUE_TYPE (arr)); + for (i = 0; i < arity; i += 1) + { + if (TYPE_CODE (elt_type) != TYPE_CODE_ARRAY + || TYPE_FIELD_BITSIZE (elt_type, 0) == 0) + error ("attempt to do packed indexing of something other than a packed array"); + else + { + struct type *range_type = TYPE_INDEX_TYPE (elt_type); + LONGEST lowerbound, upperbound; + LONGEST idx; + + if (get_discrete_bounds (range_type, &lowerbound, + &upperbound) < 0) + { + warning ("don't know bounds of array"); + lowerbound = upperbound = 0; + } + + idx = value_as_long (value_pos_atr (ind[i])); + if (idx < lowerbound || idx > upperbound) + warning ("packed array index %ld out of bounds", (long) idx); + bits = TYPE_FIELD_BITSIZE (elt_type, 0); + elt_total_bit_offset += (idx - lowerbound) * bits; + elt_type = check_typedef (TYPE_TARGET_TYPE (elt_type)); + } + } + elt_off = elt_total_bit_offset / HOST_CHAR_BIT; + bit_off = elt_total_bit_offset % HOST_CHAR_BIT; + + v = ada_value_primitive_packed_val (arr, NULL, elt_off, bit_off, + bits, elt_type); + if (VALUE_LVAL (arr) == lval_internalvar) + VALUE_LVAL (v) = lval_internalvar_component; + else + VALUE_LVAL (v) = VALUE_LVAL (arr); + return v; +} + +/* Non-zero iff TYPE includes negative integer values. */ + +static int +has_negatives (type) + struct type* type; +{ + switch (TYPE_CODE (type)) { + default: + return 0; + case TYPE_CODE_INT: + return ! TYPE_UNSIGNED (type); + case TYPE_CODE_RANGE: + return TYPE_LOW_BOUND (type) < 0; + } +} + + +/* Create a new value of type TYPE from the contents of OBJ starting + at byte OFFSET, and bit offset BIT_OFFSET within that byte, + proceeding for BIT_SIZE bits. If OBJ is an lval in memory, then + assigning through the result will set the field fetched from. OBJ + may also be NULL, in which case, VALADDR+OFFSET must address the + start of storage containing the packed value. The value returned + in this case is never an lval. + Assumes 0 <= BIT_OFFSET < HOST_CHAR_BIT. */ + +struct value* +ada_value_primitive_packed_val (obj, valaddr, offset, bit_offset, + bit_size, type) + struct value* obj; + char* valaddr; + long offset; + int bit_offset; + int bit_size; + struct type* type; +{ + struct value* v; + int src, /* Index into the source area. */ + targ, /* Index into the target area. */ + i, + srcBitsLeft, /* Number of source bits left to move. */ + nsrc, ntarg, /* Number of source and target bytes. */ + unusedLS, /* Number of bits in next significant + * byte of source that are unused. */ + accumSize; /* Number of meaningful bits in accum */ + unsigned char* bytes; /* First byte containing data to unpack. */ + unsigned char* unpacked; + unsigned long accum; /* Staging area for bits being transferred */ + unsigned char sign; + int len = (bit_size + bit_offset + HOST_CHAR_BIT - 1) / 8; + /* Transmit bytes from least to most significant; delta is the + * direction the indices move. */ + int delta = BITS_BIG_ENDIAN ? -1 : 1; + + CHECK_TYPEDEF (type); + + if (obj == NULL) + { + v = allocate_value (type); + bytes = (unsigned char*) (valaddr + offset); + } + else if (VALUE_LAZY (obj)) + { + v = value_at (type, + VALUE_ADDRESS (obj) + VALUE_OFFSET (obj) + offset, NULL); + bytes = (unsigned char*) alloca (len); + read_memory (VALUE_ADDRESS (v), bytes, len); + } + else + { + v = allocate_value (type); + bytes = (unsigned char*) VALUE_CONTENTS (obj) + offset; + } + + if (obj != NULL) + { + VALUE_LVAL (v) = VALUE_LVAL (obj); + if (VALUE_LVAL (obj) == lval_internalvar) + VALUE_LVAL (v) = lval_internalvar_component; + VALUE_ADDRESS (v) = VALUE_ADDRESS (obj) + VALUE_OFFSET (obj) + offset; + VALUE_BITPOS (v) = bit_offset + VALUE_BITPOS (obj); + VALUE_BITSIZE (v) = bit_size; + if (VALUE_BITPOS (v) >= HOST_CHAR_BIT) + { + VALUE_ADDRESS (v) += 1; + VALUE_BITPOS (v) -= HOST_CHAR_BIT; + } + } + else + VALUE_BITSIZE (v) = bit_size; + unpacked = (unsigned char*) VALUE_CONTENTS (v); + + srcBitsLeft = bit_size; + nsrc = len; + ntarg = TYPE_LENGTH (type); + sign = 0; + if (bit_size == 0) + { + memset (unpacked, 0, TYPE_LENGTH (type)); + return v; + } + else if (BITS_BIG_ENDIAN) + { + src = len-1; + if (has_negatives (type) && + ((bytes[0] << bit_offset) & (1 << (HOST_CHAR_BIT-1)))) + sign = ~0; + + unusedLS = + (HOST_CHAR_BIT - (bit_size + bit_offset) % HOST_CHAR_BIT) + % HOST_CHAR_BIT; + + switch (TYPE_CODE (type)) + { + case TYPE_CODE_ARRAY: + case TYPE_CODE_UNION: + case TYPE_CODE_STRUCT: + /* Non-scalar values must be aligned at a byte boundary. */ + accumSize = + (HOST_CHAR_BIT - bit_size % HOST_CHAR_BIT) % HOST_CHAR_BIT; + /* And are placed at the beginning (most-significant) bytes + * of the target. */ + targ = src; + break; + default: + accumSize = 0; + targ = TYPE_LENGTH (type) - 1; + break; + } + } + else + { + int sign_bit_offset = (bit_size + bit_offset - 1) % 8; + + src = targ = 0; + unusedLS = bit_offset; + accumSize = 0; + + if (has_negatives (type) && (bytes[len-1] & (1 << sign_bit_offset))) + sign = ~0; + } + + accum = 0; + while (nsrc > 0) + { + /* Mask for removing bits of the next source byte that are not + * part of the value. */ + unsigned int unusedMSMask = + (1 << (srcBitsLeft >= HOST_CHAR_BIT ? HOST_CHAR_BIT : srcBitsLeft))-1; + /* Sign-extend bits for this byte. */ + unsigned int signMask = sign & ~unusedMSMask; + accum |= + (((bytes[src] >> unusedLS) & unusedMSMask) | signMask) << accumSize; + accumSize += HOST_CHAR_BIT - unusedLS; + if (accumSize >= HOST_CHAR_BIT) + { + unpacked[targ] = accum & ~(~0L << HOST_CHAR_BIT); + accumSize -= HOST_CHAR_BIT; + accum >>= HOST_CHAR_BIT; + ntarg -= 1; + targ += delta; + } + srcBitsLeft -= HOST_CHAR_BIT - unusedLS; + unusedLS = 0; + nsrc -= 1; + src += delta; + } + while (ntarg > 0) + { + accum |= sign << accumSize; + unpacked[targ] = accum & ~(~0L << HOST_CHAR_BIT); + accumSize -= HOST_CHAR_BIT; + accum >>= HOST_CHAR_BIT; + ntarg -= 1; + targ += delta; + } + + return v; +} + +/* Move N bits from SOURCE, starting at bit offset SRC_OFFSET to + TARGET, starting at bit offset TARG_OFFSET. SOURCE and TARGET must + not overlap. */ +static void +move_bits (char* target, int targ_offset, char* source, int src_offset, int n) +{ + unsigned int accum, mask; + int accum_bits, chunk_size; + + target += targ_offset / HOST_CHAR_BIT; + targ_offset %= HOST_CHAR_BIT; + source += src_offset / HOST_CHAR_BIT; + src_offset %= HOST_CHAR_BIT; + if (BITS_BIG_ENDIAN) + { + accum = (unsigned char) *source; + source += 1; + accum_bits = HOST_CHAR_BIT - src_offset; + + while (n > 0) + { + int unused_right; + accum = (accum << HOST_CHAR_BIT) + (unsigned char) *source; + accum_bits += HOST_CHAR_BIT; + source += 1; + chunk_size = HOST_CHAR_BIT - targ_offset; + if (chunk_size > n) + chunk_size = n; + unused_right = HOST_CHAR_BIT - (chunk_size + targ_offset); + mask = ((1 << chunk_size) - 1) << unused_right; + *target = + (*target & ~mask) + | ((accum >> (accum_bits - chunk_size - unused_right)) & mask); + n -= chunk_size; + accum_bits -= chunk_size; + target += 1; + targ_offset = 0; + } + } + else + { + accum = (unsigned char) *source >> src_offset; + source += 1; + accum_bits = HOST_CHAR_BIT - src_offset; + + while (n > 0) + { + accum = accum + ((unsigned char) *source << accum_bits); + accum_bits += HOST_CHAR_BIT; + source += 1; + chunk_size = HOST_CHAR_BIT - targ_offset; + if (chunk_size > n) + chunk_size = n; + mask = ((1 << chunk_size) - 1) << targ_offset; + *target = + (*target & ~mask) | ((accum << targ_offset) & mask); + n -= chunk_size; + accum_bits -= chunk_size; + accum >>= chunk_size; + target += 1; + targ_offset = 0; + } + } +} + + +/* Store the contents of FROMVAL into the location of TOVAL. + Return a new value with the location of TOVAL and contents of + FROMVAL. Handles assignment into packed fields that have + floating-point or non-scalar types. */ + +static struct value* +ada_value_assign (struct value* toval, struct value* fromval) +{ + struct type* type = VALUE_TYPE (toval); + int bits = VALUE_BITSIZE (toval); + + if (!toval->modifiable) + error ("Left operand of assignment is not a modifiable lvalue."); + + COERCE_REF (toval); + + if (VALUE_LVAL (toval) == lval_memory + && bits > 0 + && (TYPE_CODE (type) == TYPE_CODE_FLT + || TYPE_CODE (type) == TYPE_CODE_STRUCT)) + { + int len = + (VALUE_BITPOS (toval) + bits + HOST_CHAR_BIT - 1) + / HOST_CHAR_BIT; + char* buffer = (char*) alloca (len); + struct value* val; + + if (TYPE_CODE (type) == TYPE_CODE_FLT) + fromval = value_cast (type, fromval); + + read_memory (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval), buffer, len); + if (BITS_BIG_ENDIAN) + move_bits (buffer, VALUE_BITPOS (toval), + VALUE_CONTENTS (fromval), + TYPE_LENGTH (VALUE_TYPE (fromval)) * TARGET_CHAR_BIT - bits, + bits); + else + move_bits (buffer, VALUE_BITPOS (toval), VALUE_CONTENTS (fromval), + 0, bits); + write_memory (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval), buffer, len); + + val = value_copy (toval); + memcpy (VALUE_CONTENTS_RAW (val), VALUE_CONTENTS (fromval), + TYPE_LENGTH (type)); + VALUE_TYPE (val) = type; + + return val; + } + + return value_assign (toval, fromval); +} + + +/* The value of the element of array ARR at the ARITY indices given in IND. + ARR may be either a simple array, GNAT array descriptor, or pointer + thereto. */ + +struct value* +ada_value_subscript (arr, arity, ind) + struct value* arr; + int arity; + struct value** ind; +{ + int k; + struct value* elt; + struct type* elt_type; + + elt = ada_coerce_to_simple_array (arr); + + elt_type = check_typedef (VALUE_TYPE (elt)); + if (TYPE_CODE (elt_type) == TYPE_CODE_ARRAY + && TYPE_FIELD_BITSIZE (elt_type, 0) > 0) + return value_subscript_packed (elt, arity, ind); + + for (k = 0; k < arity; k += 1) + { + if (TYPE_CODE (elt_type) != TYPE_CODE_ARRAY) + error("too many subscripts (%d expected)", k); + elt = value_subscript (elt, value_pos_atr (ind[k])); + } + return elt; +} + +/* Assuming ARR is a pointer to a standard GDB array of type TYPE, the + value of the element of *ARR at the ARITY indices given in + IND. Does not read the entire array into memory. */ + +struct value* +ada_value_ptr_subscript (arr, type, arity, ind) + struct value* arr; + struct type* type; + int arity; + struct value** ind; +{ + int k; + + for (k = 0; k < arity; k += 1) + { + LONGEST lwb, upb; + struct value* idx; + + if (TYPE_CODE (type) != TYPE_CODE_ARRAY) + error("too many subscripts (%d expected)", k); + arr = value_cast (lookup_pointer_type (TYPE_TARGET_TYPE (type)), + value_copy (arr)); + get_discrete_bounds (TYPE_INDEX_TYPE (type), &lwb, &upb); + if (lwb == 0) + idx = ind[k]; + else + idx = value_sub (ind[k], value_from_longest (builtin_type_int, lwb)); + arr = value_add (arr, idx); + type = TYPE_TARGET_TYPE (type); + } + + return value_ind (arr); +} + +/* If type is a record type in the form of a standard GNAT array + descriptor, returns the number of dimensions for type. If arr is a + simple array, returns the number of "array of"s that prefix its + type designation. Otherwise, returns 0. */ + +int +ada_array_arity (type) + struct type* type; +{ + int arity; + + if (type == NULL) + return 0; + + type = desc_base_type (type); + + arity = 0; + if (TYPE_CODE (type) == TYPE_CODE_STRUCT) + return desc_arity (desc_bounds_type (type)); + else + while (TYPE_CODE (type) == TYPE_CODE_ARRAY) + { + arity += 1; + type = check_typedef (TYPE_TARGET_TYPE (type)); + } + + return arity; +} + +/* If TYPE is a record type in the form of a standard GNAT array + descriptor or a simple array type, returns the element type for + TYPE after indexing by NINDICES indices, or by all indices if + NINDICES is -1. Otherwise, returns NULL. */ + +struct type* +ada_array_element_type (type, nindices) + struct type* type; + int nindices; +{ + type = desc_base_type (type); + + if (TYPE_CODE (type) == TYPE_CODE_STRUCT) + { + int k; + struct type* p_array_type; + + p_array_type = desc_data_type (type); + + k = ada_array_arity (type); + if (k == 0) + return NULL; + + /* Initially p_array_type = elt_type(*)[]...(k times)...[] */ + if (nindices >= 0 && k > nindices) + k = nindices; + p_array_type = TYPE_TARGET_TYPE (p_array_type); + while (k > 0 && p_array_type != NULL) + { + p_array_type = check_typedef (TYPE_TARGET_TYPE (p_array_type)); + k -= 1; + } + return p_array_type; + } + else if (TYPE_CODE (type) == TYPE_CODE_ARRAY) + { + while (nindices != 0 && TYPE_CODE (type) == TYPE_CODE_ARRAY) + { + type = TYPE_TARGET_TYPE (type); + nindices -= 1; + } + return type; + } + + return NULL; +} + +/* The type of nth index in arrays of given type (n numbering from 1). Does + not examine memory. */ + +struct type* +ada_index_type (type, n) + struct type* type; + int n; +{ + type = desc_base_type (type); + + if (n > ada_array_arity (type)) + return NULL; + + if (ada_is_simple_array (type)) + { + int i; + + for (i = 1; i < n; i += 1) + type = TYPE_TARGET_TYPE (type); + + return TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type, 0)); + } + else + return desc_index_type (desc_bounds_type (type), n); +} + +/* Given that arr is an array type, returns the lower bound of the + Nth index (numbering from 1) if WHICH is 0, and the upper bound if + WHICH is 1. This returns bounds 0 .. -1 if ARR_TYPE is an + array-descriptor type. If TYPEP is non-null, *TYPEP is set to the + bounds type. It works for other arrays with bounds supplied by + run-time quantities other than discriminants. */ + +LONGEST +ada_array_bound_from_type (arr_type, n, which, typep) + struct type* arr_type; + int n; + int which; + struct type** typep; +{ + struct type* type; + struct type* index_type_desc; + + if (ada_is_packed_array_type (arr_type)) + arr_type = decode_packed_array_type (arr_type); + + if (arr_type == NULL || ! ada_is_simple_array (arr_type)) + { + if (typep != NULL) + *typep = builtin_type_int; + return (LONGEST) -which; + } + + if (TYPE_CODE (arr_type) == TYPE_CODE_PTR) + type = TYPE_TARGET_TYPE (arr_type); + else + type = arr_type; + + index_type_desc = ada_find_parallel_type (type, "___XA"); + if (index_type_desc == NULL) + { + struct type* range_type; + struct type* index_type; + + while (n > 1) + { + type = TYPE_TARGET_TYPE (type); + n -= 1; + } + + range_type = TYPE_INDEX_TYPE (type); + index_type = TYPE_TARGET_TYPE (range_type); + if (TYPE_CODE (index_type) == TYPE_CODE_UNDEF) + index_type = builtin_type_long; + if (typep != NULL) + *typep = index_type; + return + (LONGEST) (which == 0 + ? TYPE_LOW_BOUND (range_type) + : TYPE_HIGH_BOUND (range_type)); + } + else + { + struct type* index_type = + to_fixed_range_type (TYPE_FIELD_NAME (index_type_desc, n-1), + NULL, TYPE_OBJFILE (arr_type)); + if (typep != NULL) + *typep = TYPE_TARGET_TYPE (index_type); + return + (LONGEST) (which == 0 + ? TYPE_LOW_BOUND (index_type) + : TYPE_HIGH_BOUND (index_type)); + } +} + +/* Given that arr is an array value, returns the lower bound of the + nth index (numbering from 1) if which is 0, and the upper bound if + which is 1. This routine will also work for arrays with bounds + supplied by run-time quantities other than discriminants. */ + +struct value* +ada_array_bound (arr, n, which) + struct value* arr; + int n; + int which; +{ + struct type* arr_type = VALUE_TYPE (arr); + + if (ada_is_packed_array_type (arr_type)) + return ada_array_bound (decode_packed_array (arr), n, which); + else if (ada_is_simple_array (arr_type)) + { + struct type* type; + LONGEST v = ada_array_bound_from_type (arr_type, n, which, &type); + return value_from_longest (type, v); + } + else + return desc_one_bound (desc_bounds (arr), n, which); +} + +/* Given that arr is an array value, returns the length of the + nth index. This routine will also work for arrays with bounds + supplied by run-time quantities other than discriminants. Does not + work for arrays indexed by enumeration types with representation + clauses at the moment. */ + +struct value* +ada_array_length (arr, n) + struct value* arr; + int n; +{ + struct type* arr_type = check_typedef (VALUE_TYPE (arr)); + struct type* index_type_desc; + + if (ada_is_packed_array_type (arr_type)) + return ada_array_length (decode_packed_array (arr), n); + + if (ada_is_simple_array (arr_type)) + { + struct type* type; + LONGEST v = + ada_array_bound_from_type (arr_type, n, 1, &type) - + ada_array_bound_from_type (arr_type, n, 0, NULL) + 1; + return value_from_longest (type, v); + } + else + return + value_from_longest (builtin_type_ada_int, + value_as_long (desc_one_bound (desc_bounds (arr), + n, 1)) + - value_as_long (desc_one_bound (desc_bounds (arr), + n, 0)) + + 1); +} + + + /* Name resolution */ + +/* The "demangled" name for the user-definable Ada operator corresponding + to op. */ + +static const char* +ada_op_name (op) + enum exp_opcode op; +{ + int i; + + for (i = 0; ada_opname_table[i].mangled != NULL; i += 1) + { + if (ada_opname_table[i].op == op) + return ada_opname_table[i].demangled; + } + error ("Could not find operator name for opcode"); +} + + +/* Same as evaluate_type (*EXP), but resolves ambiguous symbol + references (OP_UNRESOLVED_VALUES) and converts operators that are + user-defined into appropriate function calls. If CONTEXT_TYPE is + non-null, it provides a preferred result type [at the moment, only + type void has any effect---causing procedures to be preferred over + functions in calls]. A null CONTEXT_TYPE indicates that a non-void + return type is preferred. The variable unresolved_names contains a list + of character strings referenced by expout that should be freed. + May change (expand) *EXP. */ + +void +ada_resolve (expp, context_type) + struct expression** expp; + struct type* context_type; +{ + int pc; + pc = 0; + ada_resolve_subexp (expp, &pc, 1, context_type); +} + +/* Resolve the operator of the subexpression beginning at + position *POS of *EXPP. "Resolving" consists of replacing + OP_UNRESOLVED_VALUE with an appropriate OP_VAR_VALUE, replacing + built-in operators with function calls to user-defined operators, + where appropriate, and (when DEPROCEDURE_P is non-zero), converting + function-valued variables into parameterless calls. May expand + EXP. The CONTEXT_TYPE functions as in ada_resolve, above. */ + +static struct value* +ada_resolve_subexp (expp, pos, deprocedure_p, context_type) + struct expression** expp; + int *pos; + int deprocedure_p; + struct type* context_type; +{ + int pc = *pos; + int i; + struct expression* exp; /* Convenience: == *expp */ + enum exp_opcode op = (*expp)->elts[pc].opcode; + struct value** argvec; /* Vector of operand types (alloca'ed). */ + int nargs; /* Number of operands */ + + argvec = NULL; + nargs = 0; + exp = *expp; + + /* Pass one: resolve operands, saving their types and updating *pos. */ + switch (op) + { + case OP_VAR_VALUE: + /* case OP_UNRESOLVED_VALUE:*/ + /* FIXME: OP_UNRESOLVED_VALUE should be defined in expression.h */ + *pos += 4; + break; + + case OP_FUNCALL: + nargs = longest_to_int (exp->elts[pc + 1].longconst) + 1; + /* FIXME: OP_UNRESOLVED_VALUE should be defined in expression.h */ + /* if (exp->elts[pc+3].opcode == OP_UNRESOLVED_VALUE) + { + *pos += 7; + + argvec = (struct value* *) alloca (sizeof (struct value*) * (nargs + 1)); + for (i = 0; i < nargs-1; i += 1) + argvec[i] = ada_resolve_subexp (expp, pos, 1, NULL); + argvec[i] = NULL; + } + else + { + *pos += 3; + ada_resolve_subexp (expp, pos, 0, NULL); + for (i = 1; i < nargs; i += 1) + ada_resolve_subexp (expp, pos, 1, NULL); + } + */ + exp = *expp; + break; + + /* FIXME: UNOP_QUAL should be defined in expression.h */ + /* case UNOP_QUAL: + nargs = 1; + *pos += 3; + ada_resolve_subexp (expp, pos, 1, exp->elts[pc + 1].type); + exp = *expp; + break; + */ + /* FIXME: OP_ATTRIBUTE should be defined in expression.h */ + /* case OP_ATTRIBUTE: + nargs = longest_to_int (exp->elts[pc + 1].longconst) + 1; + *pos += 4; + for (i = 0; i < nargs; i += 1) + ada_resolve_subexp (expp, pos, 1, NULL); + exp = *expp; + break; + */ + case UNOP_ADDR: + nargs = 1; + *pos += 1; + ada_resolve_subexp (expp, pos, 0, NULL); + exp = *expp; + break; + + case BINOP_ASSIGN: + { + struct value* arg1; + nargs = 2; + *pos += 1; + arg1 = ada_resolve_subexp (expp, pos, 0, NULL); + if (arg1 == NULL) + ada_resolve_subexp (expp, pos, 1, NULL); + else + ada_resolve_subexp (expp, pos, 1, VALUE_TYPE (arg1)); + break; + } + + default: + switch (op) + { + default: + error ("Unexpected operator during name resolution"); + case UNOP_CAST: + /* case UNOP_MBR: + nargs = 1; + *pos += 3; + break; + */ + case BINOP_ADD: + case BINOP_SUB: + case BINOP_MUL: + case BINOP_DIV: + case BINOP_REM: + case BINOP_MOD: + case BINOP_EXP: + case BINOP_CONCAT: + case BINOP_LOGICAL_AND: + case BINOP_LOGICAL_OR: + case BINOP_BITWISE_AND: + case BINOP_BITWISE_IOR: + case BINOP_BITWISE_XOR: + + case BINOP_EQUAL: + case BINOP_NOTEQUAL: + case BINOP_LESS: + case BINOP_GTR: + case BINOP_LEQ: + case BINOP_GEQ: + + case BINOP_REPEAT: + case BINOP_SUBSCRIPT: + case BINOP_COMMA: + nargs = 2; + *pos += 1; + break; + + case UNOP_NEG: + case UNOP_PLUS: + case UNOP_LOGICAL_NOT: + case UNOP_ABS: + case UNOP_IND: + nargs = 1; + *pos += 1; + break; + + case OP_LONG: + case OP_DOUBLE: + case OP_VAR_VALUE: + *pos += 4; + break; + + case OP_TYPE: + case OP_BOOL: + case OP_LAST: + case OP_REGISTER: + case OP_INTERNALVAR: + *pos += 3; + break; + + case UNOP_MEMVAL: + *pos += 3; + nargs = 1; + break; + + case STRUCTOP_STRUCT: + case STRUCTOP_PTR: + nargs = 1; + *pos += 4 + BYTES_TO_EXP_ELEM (exp->elts[pc + 1].longconst + 1); + break; + + case OP_ARRAY: + *pos += 4; + nargs = longest_to_int (exp->elts[pc + 2].longconst) + 1; + nargs -= longest_to_int (exp->elts[pc + 1].longconst); + /* A null array contains one dummy element to give the type. */ + /* if (nargs == 0) + nargs = 1; + break;*/ + + case TERNOP_SLICE: + /* FIXME: TERNOP_MBR should be defined in expression.h */ + /* case TERNOP_MBR: + *pos += 1; + nargs = 3; + break; + */ + /* FIXME: BINOP_MBR should be defined in expression.h */ + /* case BINOP_MBR: + *pos += 3; + nargs = 2; + break;*/ + } + + argvec = (struct value* *) alloca (sizeof (struct value*) * (nargs + 1)); + for (i = 0; i < nargs; i += 1) + argvec[i] = ada_resolve_subexp (expp, pos, 1, NULL); + argvec[i] = NULL; + exp = *expp; + break; + } + + /* Pass two: perform any resolution on principal operator. */ + switch (op) + { + default: + break; + + /* FIXME: OP_UNRESOLVED_VALUE should be defined in expression.h */ + /* case OP_UNRESOLVED_VALUE: + { + struct symbol** candidate_syms; + struct block** candidate_blocks; + int n_candidates; + + n_candidates = ada_lookup_symbol_list (exp->elts[pc + 2].name, + exp->elts[pc + 1].block, + VAR_NAMESPACE, + &candidate_syms, + &candidate_blocks); + + if (n_candidates > 1) + {*/ + /* Types tend to get re-introduced locally, so if there + are any local symbols that are not types, first filter + out all types.*/ /* + int j; + for (j = 0; j < n_candidates; j += 1) + switch (SYMBOL_CLASS (candidate_syms[j])) + { + case LOC_REGISTER: + case LOC_ARG: + case LOC_REF_ARG: + case LOC_REGPARM: + case LOC_REGPARM_ADDR: + case LOC_LOCAL: + case LOC_LOCAL_ARG: + case LOC_BASEREG: + case LOC_BASEREG_ARG: + goto FoundNonType; + default: + break; + } + FoundNonType: + if (j < n_candidates) + { + j = 0; + while (j < n_candidates) + { + if (SYMBOL_CLASS (candidate_syms[j]) == LOC_TYPEDEF) + { + candidate_syms[j] = candidate_syms[n_candidates-1]; + candidate_blocks[j] = candidate_blocks[n_candidates-1]; + n_candidates -= 1; + } + else + j += 1; + } + } + } + + if (n_candidates == 0) + error ("No definition found for %s", + ada_demangle (exp->elts[pc + 2].name)); + else if (n_candidates == 1) + i = 0; + else if (deprocedure_p + && ! is_nonfunction (candidate_syms, n_candidates)) + { + i = ada_resolve_function (candidate_syms, candidate_blocks, + n_candidates, NULL, 0, + exp->elts[pc + 2].name, context_type); + if (i < 0) + error ("Could not find a match for %s", + ada_demangle (exp->elts[pc + 2].name)); + } + else + { + printf_filtered ("Multiple matches for %s\n", + ada_demangle (exp->elts[pc+2].name)); + user_select_syms (candidate_syms, candidate_blocks, + n_candidates, 1); + i = 0; + } + + exp->elts[pc].opcode = exp->elts[pc + 3].opcode = OP_VAR_VALUE; + exp->elts[pc + 1].block = candidate_blocks[i]; + exp->elts[pc + 2].symbol = candidate_syms[i]; + if (innermost_block == NULL || + contained_in (candidate_blocks[i], innermost_block)) + innermost_block = candidate_blocks[i]; + }*/ + /* FALL THROUGH */ + + case OP_VAR_VALUE: + if (deprocedure_p && + TYPE_CODE (SYMBOL_TYPE (exp->elts[pc+2].symbol)) == TYPE_CODE_FUNC) + { + replace_operator_with_call (expp, pc, 0, 0, + exp->elts[pc+2].symbol, + exp->elts[pc+1].block); + exp = *expp; + } + break; + + case OP_FUNCALL: + { + /* FIXME: OP_UNRESOLVED_VALUE should be defined in expression.h */ + /* if (exp->elts[pc+3].opcode == OP_UNRESOLVED_VALUE) + { + struct symbol** candidate_syms; + struct block** candidate_blocks; + int n_candidates; + + n_candidates = ada_lookup_symbol_list (exp->elts[pc + 5].name, + exp->elts[pc + 4].block, + VAR_NAMESPACE, + &candidate_syms, + &candidate_blocks); + if (n_candidates == 1) + i = 0; + else + { + i = ada_resolve_function (candidate_syms, candidate_blocks, + n_candidates, argvec, nargs-1, + exp->elts[pc + 5].name, context_type); + if (i < 0) + error ("Could not find a match for %s", + ada_demangle (exp->elts[pc + 5].name)); + } + + exp->elts[pc + 3].opcode = exp->elts[pc + 6].opcode = OP_VAR_VALUE; + exp->elts[pc + 4].block = candidate_blocks[i]; + exp->elts[pc + 5].symbol = candidate_syms[i]; + if (innermost_block == NULL || + contained_in (candidate_blocks[i], innermost_block)) + innermost_block = candidate_blocks[i]; + }*/ + + } + break; + case BINOP_ADD: + case BINOP_SUB: + case BINOP_MUL: + case BINOP_DIV: + case BINOP_REM: + case BINOP_MOD: + case BINOP_CONCAT: + case BINOP_BITWISE_AND: + case BINOP_BITWISE_IOR: + case BINOP_BITWISE_XOR: + case BINOP_EQUAL: + case BINOP_NOTEQUAL: + case BINOP_LESS: + case BINOP_GTR: + case BINOP_LEQ: + case BINOP_GEQ: + case BINOP_EXP: + case UNOP_NEG: + case UNOP_PLUS: + case UNOP_LOGICAL_NOT: + case UNOP_ABS: + if (possible_user_operator_p (op, argvec)) + { + struct symbol** candidate_syms; + struct block** candidate_blocks; + int n_candidates; + + n_candidates = ada_lookup_symbol_list (ada_mangle (ada_op_name (op)), + (struct block*) NULL, + VAR_NAMESPACE, + &candidate_syms, + &candidate_blocks); + i = ada_resolve_function (candidate_syms, candidate_blocks, + n_candidates, argvec, nargs, + ada_op_name (op), NULL); + if (i < 0) + break; + + replace_operator_with_call (expp, pc, nargs, 1, + candidate_syms[i], candidate_blocks[i]); + exp = *expp; + } + break; + } + + *pos = pc; + return evaluate_subexp_type (exp, pos); +} + +/* Return non-zero if formal type FTYPE matches actual type ATYPE. If + MAY_DEREF is non-zero, the formal may be a pointer and the actual + a non-pointer. */ +/* The term "match" here is rather loose. The match is heuristic and + liberal. FIXME: TOO liberal, in fact. */ + +static int +ada_type_match (ftype, atype, may_deref) + struct type* ftype; + struct type* atype; + int may_deref; +{ + CHECK_TYPEDEF (ftype); + CHECK_TYPEDEF (atype); + + if (TYPE_CODE (ftype) == TYPE_CODE_REF) + ftype = TYPE_TARGET_TYPE (ftype); + if (TYPE_CODE (atype) == TYPE_CODE_REF) + atype = TYPE_TARGET_TYPE (atype); + + if (TYPE_CODE (ftype) == TYPE_CODE_VOID + || TYPE_CODE (atype) == TYPE_CODE_VOID) + return 1; + + switch (TYPE_CODE (ftype)) + { + default: + return 1; + case TYPE_CODE_PTR: + if (TYPE_CODE (atype) == TYPE_CODE_PTR) + return ada_type_match (TYPE_TARGET_TYPE (ftype), + TYPE_TARGET_TYPE (atype), 0); + else return (may_deref && + ada_type_match (TYPE_TARGET_TYPE (ftype), atype, 0)); + case TYPE_CODE_INT: + case TYPE_CODE_ENUM: + case TYPE_CODE_RANGE: + switch (TYPE_CODE (atype)) + { + case TYPE_CODE_INT: + case TYPE_CODE_ENUM: + case TYPE_CODE_RANGE: + return 1; + default: + return 0; + } + + case TYPE_CODE_ARRAY: + return (TYPE_CODE (atype) == TYPE_CODE_ARRAY + || ada_is_array_descriptor (atype)); + + case TYPE_CODE_STRUCT: + if (ada_is_array_descriptor (ftype)) + return (TYPE_CODE (atype) == TYPE_CODE_ARRAY + || ada_is_array_descriptor (atype)); + else + return (TYPE_CODE (atype) == TYPE_CODE_STRUCT + && ! ada_is_array_descriptor (atype)); + + case TYPE_CODE_UNION: + case TYPE_CODE_FLT: + return (TYPE_CODE (atype) == TYPE_CODE (ftype)); + } +} + +/* Return non-zero if the formals of FUNC "sufficiently match" the + vector of actual argument types ACTUALS of size N_ACTUALS. FUNC + may also be an enumeral, in which case it is treated as a 0- + argument function. */ + +static int +ada_args_match (func, actuals, n_actuals) + struct symbol* func; + struct value** actuals; + int n_actuals; +{ + int i; + struct type* func_type = SYMBOL_TYPE (func); + + if (SYMBOL_CLASS (func) == LOC_CONST && + TYPE_CODE (func_type) == TYPE_CODE_ENUM) + return (n_actuals == 0); + else if (func_type == NULL || TYPE_CODE (func_type) != TYPE_CODE_FUNC) + return 0; + + if (TYPE_NFIELDS (func_type) != n_actuals) + return 0; + + for (i = 0; i < n_actuals; i += 1) + { + struct type* ftype = check_typedef (TYPE_FIELD_TYPE (func_type, i)); + struct type* atype = check_typedef (VALUE_TYPE (actuals[i])); + + if (! ada_type_match (TYPE_FIELD_TYPE (func_type, i), + VALUE_TYPE (actuals[i]), 1)) + return 0; + } + return 1; +} + +/* False iff function type FUNC_TYPE definitely does not produce a value + compatible with type CONTEXT_TYPE. Conservatively returns 1 if + FUNC_TYPE is not a valid function type with a non-null return type + or an enumerated type. A null CONTEXT_TYPE indicates any non-void type. */ + +static int +return_match (func_type, context_type) + struct type* func_type; + struct type* context_type; +{ + struct type* return_type; + + if (func_type == NULL) + return 1; + + /* FIXME: base_type should be declared in gdbtypes.h, implemented in valarith.c */ + /* if (TYPE_CODE (func_type) == TYPE_CODE_FUNC) + return_type = base_type (TYPE_TARGET_TYPE (func_type)); + else + return_type = base_type (func_type);*/ + if (return_type == NULL) + return 1; + + /* FIXME: base_type should be declared in gdbtypes.h, implemented in valarith.c */ + /* context_type = base_type (context_type);*/ + + if (TYPE_CODE (return_type) == TYPE_CODE_ENUM) + return context_type == NULL || return_type == context_type; + else if (context_type == NULL) + return TYPE_CODE (return_type) != TYPE_CODE_VOID; + else + return TYPE_CODE (return_type) == TYPE_CODE (context_type); +} + + +/* Return the index in SYMS[0..NSYMS-1] of symbol for the + function (if any) that matches the types of the NARGS arguments in + ARGS. If CONTEXT_TYPE is non-null, and there is at least one match + that returns type CONTEXT_TYPE, then eliminate other matches. If + CONTEXT_TYPE is null, prefer a non-void-returning function. + Asks the user if there is more than one match remaining. Returns -1 + if there is no such symbol or none is selected. NAME is used + solely for messages. May re-arrange and modify SYMS in + the process; the index returned is for the modified vector. BLOCKS + is modified in parallel to SYMS. */ + +int +ada_resolve_function (syms, blocks, nsyms, args, nargs, name, context_type) + struct symbol* syms[]; + struct block* blocks[]; + struct value** args; + int nsyms, nargs; + const char* name; + struct type* context_type; +{ + int k; + int m; /* Number of hits */ + struct type* fallback; + struct type* return_type; + + return_type = context_type; + if (context_type == NULL) + fallback = builtin_type_void; + else + fallback = NULL; + + m = 0; + while (1) + { + for (k = 0; k < nsyms; k += 1) + { + struct type* type = check_typedef (SYMBOL_TYPE (syms[k])); + + if (ada_args_match (syms[k], args, nargs) + && return_match (SYMBOL_TYPE (syms[k]), return_type)) + { + syms[m] = syms[k]; + if (blocks != NULL) + blocks[m] = blocks[k]; + m += 1; + } + } + if (m > 0 || return_type == fallback) + break; + else + return_type = fallback; + } + + if (m == 0) + return -1; + else if (m > 1) + { + printf_filtered ("Multiple matches for %s\n", name); + user_select_syms (syms, blocks, m, 1); + return 0; + } + return 0; +} + +/* Returns true (non-zero) iff demangled name N0 should appear before N1 */ +/* in a listing of choices during disambiguation (see sort_choices, below). */ +/* The idea is that overloadings of a subprogram name from the */ +/* same package should sort in their source order. We settle for ordering */ +/* such symbols by their trailing number (__N or $N). */ +static int +mangled_ordered_before (char* N0, char* N1) +{ + if (N1 == NULL) + return 0; + else if (N0 == NULL) + return 1; + else + { + int k0, k1; + for (k0 = strlen (N0)-1; k0 > 0 && isdigit (N0[k0]); k0 -= 1) + ; + for (k1 = strlen (N1)-1; k1 > 0 && isdigit (N1[k1]); k1 -= 1) + ; + if ((N0[k0] == '_' || N0[k0] == '$') && N0[k0+1] != '\000' + && (N1[k1] == '_' || N1[k1] == '$') && N1[k1+1] != '\000') + { + int n0, n1; + n0 = k0; + while (N0[n0] == '_' && n0 > 0 && N0[n0-1] == '_') + n0 -= 1; + n1 = k1; + while (N1[n1] == '_' && n1 > 0 && N1[n1-1] == '_') + n1 -= 1; + if (n0 == n1 && STREQN (N0, N1, n0)) + return (atoi (N0+k0+1) < atoi (N1+k1+1)); + } + return (strcmp (N0, N1) < 0); + } +} + +/* Sort SYMS[0..NSYMS-1] to put the choices in a canonical order by their */ +/* mangled names, rearranging BLOCKS[0..NSYMS-1] according to the same */ +/* permutation. */ +static void +sort_choices (syms, blocks, nsyms) + struct symbol* syms[]; + struct block* blocks[]; + int nsyms; +{ + int i, j; + for (i = 1; i < nsyms; i += 1) + { + struct symbol* sym = syms[i]; + struct block* block = blocks[i]; + int j; + + for (j = i-1; j >= 0; j -= 1) + { + if (mangled_ordered_before (SYMBOL_NAME (syms[j]), + SYMBOL_NAME (sym))) + break; + syms[j+1] = syms[j]; + blocks[j+1] = blocks[j]; + } + syms[j+1] = sym; + blocks[j+1] = block; + } +} + +/* Given a list of NSYMS symbols in SYMS and corresponding blocks in */ +/* BLOCKS, select up to MAX_RESULTS>0 by asking the user (if */ +/* necessary), returning the number selected, and setting the first */ +/* elements of SYMS and BLOCKS to the selected symbols and */ +/* corresponding blocks. Error if no symbols selected. BLOCKS may */ +/* be NULL, in which case it is ignored. */ + +/* NOTE: Adapted from decode_line_2 in symtab.c, with which it ought + to be re-integrated one of these days. */ + +int +user_select_syms (syms, blocks, nsyms, max_results) + struct symbol* syms[]; + struct block* blocks[]; + int nsyms; + int max_results; +{ + int i; + int* chosen = (int*) alloca (sizeof(int) * nsyms); + int n_chosen; + int first_choice = (max_results == 1) ? 1 : 2; + + if (max_results < 1) + error ("Request to select 0 symbols!"); + if (nsyms <= 1) + return nsyms; + + printf_unfiltered("[0] cancel\n"); + if (max_results > 1) + printf_unfiltered("[1] all\n"); + + sort_choices (syms, blocks, nsyms); + + for (i = 0; i < nsyms; i += 1) + { + if (syms[i] == NULL) + continue; + + if (SYMBOL_CLASS (syms[i]) == LOC_BLOCK) + { + struct symtab_and_line sal = find_function_start_sal (syms[i], 1); + printf_unfiltered ("[%d] %s at %s:%d\n", + i + first_choice, + SYMBOL_SOURCE_NAME (syms[i]), + sal.symtab == NULL + ? "" + : sal.symtab->filename, + sal.line); + continue; + } + else + { + int is_enumeral = + (SYMBOL_CLASS (syms[i]) == LOC_CONST + && SYMBOL_TYPE (syms[i]) != NULL + && TYPE_CODE (SYMBOL_TYPE (syms[i])) + == TYPE_CODE_ENUM); + struct symtab* symtab = symtab_for_sym (syms[i]); + + if (SYMBOL_LINE (syms[i]) != 0 && symtab != NULL) + printf_unfiltered ("[%d] %s at %s:%d\n", + i + first_choice, + SYMBOL_SOURCE_NAME (syms[i]), + symtab->filename, SYMBOL_LINE (syms[i])); + else if (is_enumeral && + TYPE_NAME (SYMBOL_TYPE (syms[i])) != NULL) + { + printf_unfiltered ("[%d] ", i + first_choice); + ada_print_type (SYMBOL_TYPE (syms[i]), NULL, gdb_stdout, -1, 0); + printf_unfiltered ("'(%s) (enumeral)\n", + SYMBOL_SOURCE_NAME (syms[i])); + } + else if (symtab != NULL) + printf_unfiltered (is_enumeral + ? "[%d] %s in %s (enumeral)\n" + : "[%d] %s at %s:?\n", + i + first_choice, + SYMBOL_SOURCE_NAME (syms[i]), + symtab->filename); + else + printf_unfiltered (is_enumeral + ? "[%d] %s (enumeral)\n" + : "[%d] %s at ?\n", + i + first_choice, SYMBOL_SOURCE_NAME (syms[i])); + } + } + + n_chosen = get_selections (chosen, nsyms, max_results, max_results > 1, + "overload-choice"); + + for (i = 0; i < n_chosen; i += 1) + { + syms[i] = syms[chosen[i]]; + if (blocks != NULL) + blocks[i] = blocks[chosen[i]]; + } + + return n_chosen; +} + +/* Read and validate a set of numeric choices from the user in the + range 0 .. N_CHOICES-1. Place the results in increasing + order in CHOICES[0 .. N-1], and return N. + + The user types choices as a sequence of numbers on one line + separated by blanks, encoding them as follows: + + + A choice of 0 means to cancel the selection, throwing an error. + + If IS_ALL_CHOICE, a choice of 1 selects the entire set 0 .. N_CHOICES-1. + + The user chooses k by typing k+IS_ALL_CHOICE+1. + + The user is not allowed to choose more than MAX_RESULTS values. + + ANNOTATION_SUFFIX, if present, is used to annotate the input + prompts (for use with the -f switch). */ + +int +get_selections (choices, n_choices, max_results, is_all_choice, + annotation_suffix) + int* choices; + int n_choices; + int max_results; + int is_all_choice; + char* annotation_suffix; +{ + int i; + char* args; + const char* prompt; + int n_chosen; + int first_choice = is_all_choice ? 2 : 1; + + prompt = getenv ("PS2"); + if (prompt == NULL) + prompt = ">"; + + printf_unfiltered ("%s ", prompt); + gdb_flush (gdb_stdout); + + args = command_line_input ((char *) NULL, 0, annotation_suffix); + + if (args == NULL) + error_no_arg ("one or more choice numbers"); + + n_chosen = 0; + + /* Set choices[0 .. n_chosen-1] to the users' choices in ascending + order, as given in args. Choices are validated. */ + while (1) + { + char* args2; + int choice, j; + + while (isspace (*args)) + args += 1; + if (*args == '\0' && n_chosen == 0) + error_no_arg ("one or more choice numbers"); + else if (*args == '\0') + break; + + choice = strtol (args, &args2, 10); + if (args == args2 || choice < 0 || choice > n_choices + first_choice - 1) + error ("Argument must be choice number"); + args = args2; + + if (choice == 0) + error ("cancelled"); + + if (choice < first_choice) + { + n_chosen = n_choices; + for (j = 0; j < n_choices; j += 1) + choices[j] = j; + break; + } + choice -= first_choice; + + for (j = n_chosen-1; j >= 0 && choice < choices[j]; j -= 1) + {} + + if (j < 0 || choice != choices[j]) + { + int k; + for (k = n_chosen-1; k > j; k -= 1) + choices[k+1] = choices[k]; + choices[j+1] = choice; + n_chosen += 1; + } + } + + if (n_chosen > max_results) + error ("Select no more than %d of the above", max_results); + + return n_chosen; +} + +/* Replace the operator of length OPLEN at position PC in *EXPP with a call */ +/* on the function identified by SYM and BLOCK, and taking NARGS */ +/* arguments. Update *EXPP as needed to hold more space. */ + +static void +replace_operator_with_call (expp, pc, nargs, oplen, sym, block) + struct expression** expp; + int pc, nargs, oplen; + struct symbol* sym; + struct block* block; +{ + /* A new expression, with 6 more elements (3 for funcall, 4 for function + symbol, -oplen for operator being replaced). */ + struct expression* newexp = (struct expression*) + xmalloc (sizeof (struct expression) + + EXP_ELEM_TO_BYTES ((*expp)->nelts + 7 - oplen)); + struct expression* exp = *expp; + + newexp->nelts = exp->nelts + 7 - oplen; + newexp->language_defn = exp->language_defn; + memcpy (newexp->elts, exp->elts, EXP_ELEM_TO_BYTES (pc)); + memcpy (newexp->elts + pc + 7, exp->elts + pc + oplen, + EXP_ELEM_TO_BYTES (exp->nelts - pc - oplen)); + + newexp->elts[pc].opcode = newexp->elts[pc + 2].opcode = OP_FUNCALL; + newexp->elts[pc + 1].longconst = (LONGEST) nargs; + + newexp->elts[pc + 3].opcode = newexp->elts[pc + 6].opcode = OP_VAR_VALUE; + newexp->elts[pc + 4].block = block; + newexp->elts[pc + 5].symbol = sym; + + *expp = newexp; + free (exp); +} + +/* Type-class predicates */ + +/* True iff TYPE is numeric (i.e., an INT, RANGE (of numeric type), or */ +/* FLOAT.) */ + +static int +numeric_type_p (type) + struct type* type; +{ + if (type == NULL) + return 0; + else { + switch (TYPE_CODE (type)) + { + case TYPE_CODE_INT: + case TYPE_CODE_FLT: + return 1; + case TYPE_CODE_RANGE: + return (type == TYPE_TARGET_TYPE (type) + || numeric_type_p (TYPE_TARGET_TYPE (type))); + default: + return 0; + } + } +} + +/* True iff TYPE is integral (an INT or RANGE of INTs). */ + +static int +integer_type_p (type) + struct type* type; +{ + if (type == NULL) + return 0; + else { + switch (TYPE_CODE (type)) + { + case TYPE_CODE_INT: + return 1; + case TYPE_CODE_RANGE: + return (type == TYPE_TARGET_TYPE (type) + || integer_type_p (TYPE_TARGET_TYPE (type))); + default: + return 0; + } + } +} + +/* True iff TYPE is scalar (INT, RANGE, FLOAT, ENUM). */ + +static int +scalar_type_p (type) + struct type* type; +{ + if (type == NULL) + return 0; + else { + switch (TYPE_CODE (type)) + { + case TYPE_CODE_INT: + case TYPE_CODE_RANGE: + case TYPE_CODE_ENUM: + case TYPE_CODE_FLT: + return 1; + default: + return 0; + } + } +} + +/* True iff TYPE is discrete (INT, RANGE, ENUM). */ + +static int +discrete_type_p (type) + struct type* type; +{ + if (type == NULL) + return 0; + else { + switch (TYPE_CODE (type)) + { + case TYPE_CODE_INT: + case TYPE_CODE_RANGE: + case TYPE_CODE_ENUM: + return 1; + default: + return 0; + } + } +} + +/* Returns non-zero if OP with operatands in the vector ARGS could be + a user-defined function. Errs on the side of pre-defined operators + (i.e., result 0). */ + +static int +possible_user_operator_p (op, args) + enum exp_opcode op; + struct value* args[]; +{ + struct type* type0 = check_typedef (VALUE_TYPE (args[0])); + struct type* type1 = + (args[1] == NULL) ? NULL : check_typedef (VALUE_TYPE (args[1])); + + switch (op) + { + default: + return 0; + + case BINOP_ADD: + case BINOP_SUB: + case BINOP_MUL: + case BINOP_DIV: + return (! (numeric_type_p (type0) && numeric_type_p (type1))); + + case BINOP_REM: + case BINOP_MOD: + case BINOP_BITWISE_AND: + case BINOP_BITWISE_IOR: + case BINOP_BITWISE_XOR: + return (! (integer_type_p (type0) && integer_type_p (type1))); + + case BINOP_EQUAL: + case BINOP_NOTEQUAL: + case BINOP_LESS: + case BINOP_GTR: + case BINOP_LEQ: + case BINOP_GEQ: + return (! (scalar_type_p (type0) && scalar_type_p (type1))); + + case BINOP_CONCAT: + return ((TYPE_CODE (type0) != TYPE_CODE_ARRAY && + (TYPE_CODE (type0) != TYPE_CODE_PTR || + TYPE_CODE (TYPE_TARGET_TYPE (type0)) + != TYPE_CODE_ARRAY)) + || (TYPE_CODE (type1) != TYPE_CODE_ARRAY && + (TYPE_CODE (type1) != TYPE_CODE_PTR || + TYPE_CODE (TYPE_TARGET_TYPE (type1)) + != TYPE_CODE_ARRAY))); + + case BINOP_EXP: + return (! (numeric_type_p (type0) && integer_type_p (type1))); + + case UNOP_NEG: + case UNOP_PLUS: + case UNOP_LOGICAL_NOT: + case UNOP_ABS: + return (! numeric_type_p (type0)); + + } +} + + /* Renaming */ + +/** NOTE: In the following, we assume that a renaming type's name may + * have an ___XD suffix. It would be nice if this went away at some + * point. */ + +/* If TYPE encodes a renaming, returns the renaming suffix, which + * is XR for an object renaming, XRP for a procedure renaming, XRE for + * an exception renaming, and XRS for a subprogram renaming. Returns + * NULL if NAME encodes none of these. */ +const char* +ada_renaming_type (type) + struct type* type; +{ + if (type != NULL && TYPE_CODE (type) == TYPE_CODE_ENUM) + { + const char* name = type_name_no_tag (type); + const char* suffix = (name == NULL) ? NULL : strstr (name, "___XR"); + if (suffix == NULL + || (suffix[5] != '\000' && strchr ("PES_", suffix[5]) == NULL)) + return NULL; + else + return suffix + 3; + } + else + return NULL; +} + +/* Return non-zero iff SYM encodes an object renaming. */ +int +ada_is_object_renaming (sym) + struct symbol* sym; +{ + const char* renaming_type = ada_renaming_type (SYMBOL_TYPE (sym)); + return renaming_type != NULL + && (renaming_type[2] == '\0' || renaming_type[2] == '_'); +} + +/* Assuming that SYM encodes a non-object renaming, returns the original + * name of the renamed entity. The name is good until the end of + * parsing. */ +const char* +ada_simple_renamed_entity (sym) + struct symbol* sym; +{ + struct type* type; + const char* raw_name; + int len; + char* result; + + type = SYMBOL_TYPE (sym); + if (type == NULL || TYPE_NFIELDS (type) < 1) + error ("Improperly encoded renaming."); + + raw_name = TYPE_FIELD_NAME (type, 0); + len = (raw_name == NULL ? 0 : strlen (raw_name)) - 5; + if (len <= 0) + error ("Improperly encoded renaming."); + + result = xmalloc (len + 1); + /* FIXME: add_name_string_cleanup should be defined in parse.c */ + /* add_name_string_cleanup (result);*/ + strncpy (result, raw_name, len); + result[len] = '\000'; + return result; +} + + + /* Evaluation: Function Calls */ + +/* Copy VAL onto the stack, using and updating *SP as the stack + pointer. Return VAL as an lvalue. */ + +static struct value* +place_on_stack (val, sp) + struct value* val; + CORE_ADDR* sp; +{ + CORE_ADDR old_sp = *sp; + +#ifdef STACK_ALIGN + *sp = push_bytes (*sp, VALUE_CONTENTS_RAW (val), + STACK_ALIGN (TYPE_LENGTH (check_typedef (VALUE_TYPE (val))))); +#else + *sp = push_bytes (*sp, VALUE_CONTENTS_RAW (val), + TYPE_LENGTH (check_typedef (VALUE_TYPE (val)))); +#endif + + VALUE_LVAL (val) = lval_memory; + if (INNER_THAN (1, 2)) + VALUE_ADDRESS (val) = *sp; + else + VALUE_ADDRESS (val) = old_sp; + + return val; +} + +/* Return the value ACTUAL, converted to be an appropriate value for a + formal of type FORMAL_TYPE. Use *SP as a stack pointer for + allocating any necessary descriptors (fat pointers), or copies of + values not residing in memory, updating it as needed. */ + +static struct value* +convert_actual (actual, formal_type0, sp) + struct value* actual; + struct type* formal_type0; + CORE_ADDR* sp; +{ + struct type* actual_type = check_typedef (VALUE_TYPE (actual)); + struct type* formal_type = check_typedef (formal_type0); + struct type* formal_target = + TYPE_CODE (formal_type) == TYPE_CODE_PTR + ? check_typedef (TYPE_TARGET_TYPE (formal_type)) : formal_type; + struct type* actual_target = + TYPE_CODE (actual_type) == TYPE_CODE_PTR + ? check_typedef (TYPE_TARGET_TYPE (actual_type)) : actual_type; + + if (ada_is_array_descriptor (formal_target) + && TYPE_CODE (actual_target) == TYPE_CODE_ARRAY) + return make_array_descriptor (formal_type, actual, sp); + else if (TYPE_CODE (formal_type) == TYPE_CODE_PTR) + { + if (TYPE_CODE (formal_target) == TYPE_CODE_ARRAY + && ada_is_array_descriptor (actual_target)) + return desc_data (actual); + else if (TYPE_CODE (actual_type) != TYPE_CODE_PTR) + { + if (VALUE_LVAL (actual) != lval_memory) + { + struct value* val; + actual_type = check_typedef (VALUE_TYPE (actual)); + val = allocate_value (actual_type); + memcpy ((char*) VALUE_CONTENTS_RAW (val), + (char*) VALUE_CONTENTS (actual), + TYPE_LENGTH (actual_type)); + actual = place_on_stack (val, sp); + } + return value_addr (actual); + } + } + else if (TYPE_CODE (actual_type) == TYPE_CODE_PTR) + return ada_value_ind (actual); + + return actual; +} + + +/* Push a descriptor of type TYPE for array value ARR on the stack at + *SP, updating *SP to reflect the new descriptor. Return either + an lvalue representing the new descriptor, or (if TYPE is a pointer- + to-descriptor type rather than a descriptor type), a struct value* + representing a pointer to this descriptor. */ + +static struct value* +make_array_descriptor (type, arr, sp) + struct type* type; + struct value* arr; + CORE_ADDR* sp; +{ + struct type* bounds_type = desc_bounds_type (type); + struct type* desc_type = desc_base_type (type); + struct value* descriptor = allocate_value (desc_type); + struct value* bounds = allocate_value (bounds_type); + CORE_ADDR bounds_addr; + int i; + + for (i = ada_array_arity (check_typedef (VALUE_TYPE (arr))); i > 0; i -= 1) + { + modify_general_field (VALUE_CONTENTS (bounds), + value_as_long (ada_array_bound (arr, i, 0)), + desc_bound_bitpos (bounds_type, i, 0), + desc_bound_bitsize (bounds_type, i, 0)); + modify_general_field (VALUE_CONTENTS (bounds), + value_as_long (ada_array_bound (arr, i, 1)), + desc_bound_bitpos (bounds_type, i, 1), + desc_bound_bitsize (bounds_type, i, 1)); + } + + bounds = place_on_stack (bounds, sp); + + modify_general_field (VALUE_CONTENTS (descriptor), + arr, + fat_pntr_data_bitpos (desc_type), + fat_pntr_data_bitsize (desc_type)); + modify_general_field (VALUE_CONTENTS (descriptor), + VALUE_ADDRESS (bounds), + fat_pntr_bounds_bitpos (desc_type), + fat_pntr_bounds_bitsize (desc_type)); + + descriptor = place_on_stack (descriptor, sp); + + if (TYPE_CODE (type) == TYPE_CODE_PTR) + return value_addr (descriptor); + else + return descriptor; +} + + +/* Assuming a dummy frame has been established on the target, perform any + conversions needed for calling function FUNC on the NARGS actual + parameters in ARGS, other than standard C conversions. Does + nothing if FUNC does not have Ada-style prototype data, or if NARGS + does not match the number of arguments expected. Use *SP as a + stack pointer for additional data that must be pushed, updating its + value as needed. */ + +void +ada_convert_actuals (func, nargs, args, sp) + struct value* func; + int nargs; + struct value* args[]; + CORE_ADDR* sp; +{ + int i; + + if (TYPE_NFIELDS (VALUE_TYPE (func)) == 0 + || nargs != TYPE_NFIELDS (VALUE_TYPE (func))) + return; + + for (i = 0; i < nargs; i += 1) + args[i] = + convert_actual (args[i], + TYPE_FIELD_TYPE (VALUE_TYPE (func), i), + sp); +} + + + /* Symbol Lookup */ + + +/* The vectors of symbols and blocks ultimately returned from */ +/* ada_lookup_symbol_list. */ + +/* Current size of defn_symbols and defn_blocks */ +static size_t defn_vector_size = 0; + +/* Current number of symbols found. */ +static int ndefns = 0; + +static struct symbol** defn_symbols = NULL; +static struct block** defn_blocks = NULL; + +/* Return the result of a standard (literal, C-like) lookup of NAME in + * given NAMESPACE. */ + +static struct symbol* +standard_lookup (name, namespace) + const char* name; + namespace_enum namespace; +{ + struct symbol* sym; + struct symtab* symtab; + sym = lookup_symbol (name, (struct block*) NULL, namespace, 0, &symtab); + return sym; +} + + +/* Non-zero iff there is at least one non-function/non-enumeral symbol */ +/* in SYMS[0..N-1]. We treat enumerals as functions, since they */ +/* contend in overloading in the same way. */ +static int +is_nonfunction (syms, n) + struct symbol* syms[]; + int n; +{ + int i; + + for (i = 0; i < n; i += 1) + if (TYPE_CODE (SYMBOL_TYPE (syms[i])) != TYPE_CODE_FUNC + && TYPE_CODE (SYMBOL_TYPE (syms[i])) != TYPE_CODE_ENUM) + return 1; + + return 0; +} + +/* If true (non-zero), then TYPE0 and TYPE1 represent equivalent + struct types. Otherwise, they may not. */ + +static int +equiv_types (type0, type1) + struct type* type0; + struct type* type1; +{ + if (type0 == type1) + return 1; + if (type0 == NULL || type1 == NULL + || TYPE_CODE (type0) != TYPE_CODE (type1)) + return 0; + if ((TYPE_CODE (type0) == TYPE_CODE_STRUCT + || TYPE_CODE (type0) == TYPE_CODE_ENUM) + && ada_type_name (type0) != NULL && ada_type_name (type1) != NULL + && STREQ (ada_type_name (type0), ada_type_name (type1))) + return 1; + + return 0; +} + +/* True iff SYM0 represents the same entity as SYM1, or one that is + no more defined than that of SYM1. */ + +static int +lesseq_defined_than (sym0, sym1) + struct symbol* sym0; + struct symbol* sym1; +{ + if (sym0 == sym1) + return 1; + if (SYMBOL_NAMESPACE (sym0) != SYMBOL_NAMESPACE (sym1) + || SYMBOL_CLASS (sym0) != SYMBOL_CLASS (sym1)) + return 0; + + switch (SYMBOL_CLASS (sym0)) + { + case LOC_UNDEF: + return 1; + case LOC_TYPEDEF: + { + struct type* type0 = SYMBOL_TYPE (sym0); + struct type* type1 = SYMBOL_TYPE (sym1); + char* name0 = SYMBOL_NAME (sym0); + char* name1 = SYMBOL_NAME (sym1); + int len0 = strlen (name0); + return + TYPE_CODE (type0) == TYPE_CODE (type1) + && (equiv_types (type0, type1) + || (len0 < strlen (name1) && STREQN (name0, name1, len0) + && STREQN (name1 + len0, "___XV", 5))); + } + case LOC_CONST: + return SYMBOL_VALUE (sym0) == SYMBOL_VALUE (sym1) + && equiv_types (SYMBOL_TYPE (sym0), SYMBOL_TYPE (sym1)); + default: + return 0; + } +} + +/* Append SYM to the end of defn_symbols, and BLOCK to the end of + defn_blocks, updating ndefns, and expanding defn_symbols and + defn_blocks as needed. Do not include SYM if it is a duplicate. */ + +static void +add_defn_to_vec (sym, block) + struct symbol* sym; + struct block* block; +{ + int i; + size_t tmp; + + if (SYMBOL_TYPE (sym) != NULL) + CHECK_TYPEDEF (SYMBOL_TYPE (sym)); + for (i = 0; i < ndefns; i += 1) + { + if (lesseq_defined_than (sym, defn_symbols[i])) + return; + else if (lesseq_defined_than (defn_symbols[i], sym)) + { + defn_symbols[i] = sym; + defn_blocks[i] = block; + return; + } + } + + tmp = defn_vector_size; + GROW_VECT (defn_symbols, tmp, ndefns+2); + GROW_VECT (defn_blocks, defn_vector_size, ndefns+2); + + defn_symbols[ndefns] = sym; + defn_blocks[ndefns] = block; + ndefns += 1; +} + +/* Look, in partial_symtab PST, for symbol NAME in given namespace. + Check the global symbols if GLOBAL, the static symbols if not. Do + wild-card match if WILD. */ + +static struct partial_symbol * +ada_lookup_partial_symbol (pst, name, global, namespace, wild) + struct partial_symtab *pst; + const char *name; + int global; + namespace_enum namespace; + int wild; +{ + struct partial_symbol **start; + int name_len = strlen (name); + int length = (global ? pst->n_global_syms : pst->n_static_syms); + int i; + + if (length == 0) + { + return (NULL); + } + + start = (global ? + pst->objfile->global_psymbols.list + pst->globals_offset : + pst->objfile->static_psymbols.list + pst->statics_offset ); + + if (wild) + { + for (i = 0; i < length; i += 1) + { + struct partial_symbol* psym = start[i]; + + if (SYMBOL_NAMESPACE (psym) == namespace && + wild_match (name, name_len, SYMBOL_NAME (psym))) + return psym; + } + return NULL; + } + else + { + if (global) + { + int U; + i = 0; U = length-1; + while (U - i > 4) + { + int M = (U+i) >> 1; + struct partial_symbol* psym = start[M]; + if (SYMBOL_NAME (psym)[0] < name[0]) + i = M+1; + else if (SYMBOL_NAME (psym)[0] > name[0]) + U = M-1; + else if (strcmp (SYMBOL_NAME (psym), name) < 0) + i = M+1; + else + U = M; + } + } + else + i = 0; + + while (i < length) + { + struct partial_symbol *psym = start[i]; + + if (SYMBOL_NAMESPACE (psym) == namespace) + { + int cmp = strncmp (name, SYMBOL_NAME (psym), name_len); + + if (cmp < 0) + { + if (global) + break; + } + else if (cmp == 0 + && is_name_suffix (SYMBOL_NAME (psym) + name_len)) + return psym; + } + i += 1; + } + + if (global) + { + int U; + i = 0; U = length-1; + while (U - i > 4) + { + int M = (U+i) >> 1; + struct partial_symbol *psym = start[M]; + if (SYMBOL_NAME (psym)[0] < '_') + i = M+1; + else if (SYMBOL_NAME (psym)[0] > '_') + U = M-1; + else if (strcmp (SYMBOL_NAME (psym), "_ada_") < 0) + i = M+1; + else + U = M; + } + } + else + i = 0; + + while (i < length) + { + struct partial_symbol* psym = start[i]; + + if (SYMBOL_NAMESPACE (psym) == namespace) + { + int cmp; + + cmp = (int) '_' - (int) SYMBOL_NAME (psym)[0]; + if (cmp == 0) + { + cmp = strncmp ("_ada_", SYMBOL_NAME (psym), 5); + if (cmp == 0) + cmp = strncmp (name, SYMBOL_NAME (psym) + 5, name_len); + } + + if (cmp < 0) + { + if (global) + break; + } + else if (cmp == 0 + && is_name_suffix (SYMBOL_NAME (psym) + name_len + 5)) + return psym; + } + i += 1; + } + + } + return NULL; +} + + +/* Find a symbol table containing symbol SYM or NULL if none. */ +static struct symtab* +symtab_for_sym (sym) + struct symbol* sym; +{ + struct symtab* s; + struct objfile *objfile; + struct block *b; + int i, j; + + ALL_SYMTABS (objfile, s) + { + switch (SYMBOL_CLASS (sym)) + { + case LOC_CONST: + case LOC_STATIC: + case LOC_TYPEDEF: + case LOC_REGISTER: + case LOC_LABEL: + case LOC_BLOCK: + case LOC_CONST_BYTES: + b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK); + for (i = 0; i < BLOCK_NSYMS (b); i += 1) + if (sym == BLOCK_SYM (b, i)) + return s; + b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK); + for (i = 0; i < BLOCK_NSYMS (b); i += 1) + if (sym == BLOCK_SYM (b, i)) + return s; + break; + default: + break; + } + switch (SYMBOL_CLASS (sym)) + { + case LOC_REGISTER: + case LOC_ARG: + case LOC_REF_ARG: + case LOC_REGPARM: + case LOC_REGPARM_ADDR: + case LOC_LOCAL: + case LOC_TYPEDEF: + case LOC_LOCAL_ARG: + case LOC_BASEREG: + case LOC_BASEREG_ARG: + for (j = FIRST_LOCAL_BLOCK; + j < BLOCKVECTOR_NBLOCKS (BLOCKVECTOR (s)); j += 1) + { + b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), j); + for (i = 0; i < BLOCK_NSYMS (b); i += 1) + if (sym == BLOCK_SYM (b, i)) + return s; + } + break; + default: + break; + } + } + return NULL; +} + +/* Return a minimal symbol matching NAME according to Ada demangling + rules. Returns NULL if there is no such minimal symbol. */ + +struct minimal_symbol* +ada_lookup_minimal_symbol (name) + const char* name; +{ + struct objfile* objfile; + struct minimal_symbol* msymbol; + int wild_match = (strstr (name, "__") == NULL); + + ALL_MSYMBOLS (objfile, msymbol) + { + if (ada_match_name (SYMBOL_NAME (msymbol), name, wild_match) + && MSYMBOL_TYPE (msymbol) != mst_solib_trampoline) + return msymbol; + } + + return NULL; +} + +/* For all subprograms that statically enclose the subprogram of the + * selected frame, add symbols matching identifier NAME in NAMESPACE + * and their blocks to vectors *defn_symbols and *defn_blocks, as for + * ada_add_block_symbols (q.v.). If WILD, treat as NAME with a + * wildcard prefix. At the moment, this function uses a heuristic to + * find the frames of enclosing subprograms: it treats the + * pointer-sized value at location 0 from the local-variable base of a + * frame as a static link, and then searches up the call stack for a + * frame with that same local-variable base. */ +static void +add_symbols_from_enclosing_procs (name, namespace, wild_match) + const char* name; + namespace_enum namespace; + int wild_match; +{ +#ifdef i386 + static struct symbol static_link_sym; + static struct symbol *static_link; + + struct cleanup* old_chain = make_cleanup (null_cleanup, NULL); + struct frame_info* frame; + struct frame_info* target_frame; + + if (static_link == NULL) + { + /* Initialize the local variable symbol that stands for the + * static link (when it exists). */ + static_link = &static_link_sym; + SYMBOL_NAME (static_link) = ""; + SYMBOL_LANGUAGE (static_link) = language_unknown; + SYMBOL_CLASS (static_link) = LOC_LOCAL; + SYMBOL_NAMESPACE (static_link) = VAR_NAMESPACE; + SYMBOL_TYPE (static_link) = lookup_pointer_type (builtin_type_void); + SYMBOL_VALUE (static_link) = + - (long) TYPE_LENGTH (SYMBOL_TYPE (static_link)); + } + + frame = selected_frame; + while (frame != NULL && ndefns == 0) + { + struct block* block; + struct value* target_link_val = read_var_value (static_link, frame); + CORE_ADDR target_link; + + if (target_link_val == NULL) + break; + QUIT; + + target_link = target_link_val; + do { + QUIT; + frame = get_prev_frame (frame); + } while (frame != NULL && FRAME_LOCALS_ADDRESS (frame) != target_link); + + if (frame == NULL) + break; + + block = get_frame_block (frame, 0); + while (block != NULL && block_function (block) != NULL && ndefns == 0) + { + ada_add_block_symbols (block, name, namespace, NULL, wild_match); + + block = BLOCK_SUPERBLOCK (block); + } + } + + do_cleanups (old_chain); +#endif +} + +/* True if TYPE is definitely an artificial type supplied to a symbol + * for which no debugging information was given in the symbol file. */ +static int +is_nondebugging_type (type) + struct type* type; +{ + char* name = ada_type_name (type); + return (name != NULL && STREQ (name, "")); +} + +/* Remove any non-debugging symbols in SYMS[0 .. NSYMS-1] that definitely + * duplicate other symbols in the list. (The only case I know of where + * this happens is when object files containing stabs-in-ecoff are + * linked with files containing ordinary ecoff debugging symbols (or no + * debugging symbols)). Modifies SYMS to squeeze out deleted symbols, + * and applies the same modification to BLOCKS to maintain the + * correspondence between SYMS[i] and BLOCKS[i]. Returns the number + * of symbols in the modified list. */ +static int +remove_extra_symbols (syms, blocks, nsyms) + struct symbol** syms; + struct block** blocks; + int nsyms; +{ + int i, j; + + i = 0; + while (i < nsyms) + { + if (SYMBOL_NAME (syms[i]) != NULL && SYMBOL_CLASS (syms[i]) == LOC_STATIC + && is_nondebugging_type (SYMBOL_TYPE (syms[i]))) + { + for (j = 0; j < nsyms; j += 1) + { + if (i != j + && SYMBOL_NAME (syms[j]) != NULL + && STREQ (SYMBOL_NAME (syms[i]), SYMBOL_NAME (syms[j])) + && SYMBOL_CLASS (syms[i]) == SYMBOL_CLASS (syms[j]) + && SYMBOL_VALUE_ADDRESS (syms[i]) + == SYMBOL_VALUE_ADDRESS (syms[j])) + { + int k; + for (k = i+1; k < nsyms; k += 1) + { + syms[k-1] = syms[k]; + blocks[k-1] = blocks[k]; + } + nsyms -= 1; + goto NextSymbol; + } + } + } + i += 1; + NextSymbol: + ; + } + return nsyms; +} + +/* Find symbols in NAMESPACE matching NAME, in BLOCK0 and enclosing + scope and in global scopes, returning the number of matches. Sets + *SYMS to point to a vector of matching symbols, with *BLOCKS + pointing to the vector of corresponding blocks in which those + symbols reside. These two vectors are transient---good only to the + next call of ada_lookup_symbol_list. Any non-function/non-enumeral symbol + match within the nest of blocks whose innermost member is BLOCK0, + is the outermost match returned (no other matches in that or + enclosing blocks is returned). If there are any matches in or + surrounding BLOCK0, then these alone are returned. */ + +int +ada_lookup_symbol_list (name, block0, namespace, syms, blocks) + const char *name; + struct block *block0; + namespace_enum namespace; + struct symbol*** syms; + struct block*** blocks; +{ + struct symbol *sym; + struct symtab *s; + struct partial_symtab *ps; + struct blockvector *bv; + struct objfile *objfile; + struct block *b; + struct block *block; + struct minimal_symbol *msymbol; + int wild_match = (strstr (name, "__") == NULL); + int cacheIfUnique; + +#ifdef TIMING + markTimeStart (0); +#endif + + ndefns = 0; + cacheIfUnique = 0; + + /* Search specified block and its superiors. */ + + block = block0; + while (block != NULL) + { + ada_add_block_symbols (block, name, namespace, NULL, wild_match); + + /* If we found a non-function match, assume that's the one. */ + if (is_nonfunction (defn_symbols, ndefns)) + goto done; + + block = BLOCK_SUPERBLOCK (block); + } + + /* If we found ANY matches in the specified BLOCK, we're done. */ + + if (ndefns > 0) + goto done; + + cacheIfUnique = 1; + + /* Now add symbols from all global blocks: symbol tables, minimal symbol + tables, and psymtab's */ + + ALL_SYMTABS (objfile, s) + { + QUIT; + if (! s->primary) + continue; + bv = BLOCKVECTOR (s); + block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); + ada_add_block_symbols (block, name, namespace, objfile, wild_match); + } + + if (namespace == VAR_NAMESPACE) + { + ALL_MSYMBOLS (objfile, msymbol) + { + if (ada_match_name (SYMBOL_NAME (msymbol), name, wild_match)) + { + switch (MSYMBOL_TYPE (msymbol)) + { + case mst_solib_trampoline: + break; + default: + s = find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol)); + if (s != NULL) + { + int old_ndefns = ndefns; + QUIT; + bv = BLOCKVECTOR (s); + block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); + ada_add_block_symbols (block, + SYMBOL_NAME (msymbol), + namespace, objfile, wild_match); + if (ndefns == old_ndefns) + { + block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); + ada_add_block_symbols (block, + SYMBOL_NAME (msymbol), + namespace, objfile, + wild_match); + } + } + } + } + } + } + + ALL_PSYMTABS (objfile, ps) + { + QUIT; + if (!ps->readin + && ada_lookup_partial_symbol (ps, name, 1, namespace, wild_match)) + { + s = PSYMTAB_TO_SYMTAB (ps); + if (! s->primary) + continue; + bv = BLOCKVECTOR (s); + block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); + ada_add_block_symbols (block, name, namespace, objfile, wild_match); + } + } + + /* Now add symbols from all per-file blocks if we've gotten no hits. + (Not strictly correct, but perhaps better than an error). + Do the symtabs first, then check the psymtabs */ + + if (ndefns == 0) + { + + ALL_SYMTABS (objfile, s) + { + QUIT; + if (! s->primary) + continue; + bv = BLOCKVECTOR (s); + block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); + ada_add_block_symbols (block, name, namespace, objfile, wild_match); + } + + ALL_PSYMTABS (objfile, ps) + { + QUIT; + if (!ps->readin + && ada_lookup_partial_symbol (ps, name, 0, namespace, wild_match)) + { + s = PSYMTAB_TO_SYMTAB(ps); + bv = BLOCKVECTOR (s); + if (! s->primary) + continue; + block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); + ada_add_block_symbols (block, name, namespace, + objfile, wild_match); + } + } + } + + /* Finally, we try to find NAME as a local symbol in some lexically + enclosing block. We do this last, expecting this case to be + rare. */ + if (ndefns == 0) + { + add_symbols_from_enclosing_procs (name, namespace, wild_match); + if (ndefns > 0) + goto done; + } + + done: + ndefns = remove_extra_symbols (defn_symbols, defn_blocks, ndefns); + + + *syms = defn_symbols; + *blocks = defn_blocks; +#ifdef TIMING + markTimeStop (0); +#endif + return ndefns; +} + +/* Return a symbol in NAMESPACE matching NAME, in BLOCK0 and enclosing + * scope and in global scopes, or NULL if none. NAME is folded to + * lower case first, unless it is surrounded in single quotes. + * Otherwise, the result is as for ada_lookup_symbol_list, but is + * disambiguated by user query if needed. */ + +struct symbol* +ada_lookup_symbol (name, block0, namespace) + const char *name; + struct block *block0; + namespace_enum namespace; +{ + struct symbol** candidate_syms; + struct block** candidate_blocks; + int n_candidates; + + n_candidates = ada_lookup_symbol_list (name, + block0, namespace, + &candidate_syms, &candidate_blocks); + + if (n_candidates == 0) + return NULL; + else if (n_candidates != 1) + user_select_syms (candidate_syms, candidate_blocks, n_candidates, 1); + + return candidate_syms[0]; +} + + +/* True iff STR is a possible encoded suffix of a normal Ada name + * that is to be ignored for matching purposes. Suffixes of parallel + * names (e.g., XVE) are not included here. Currently, the possible suffixes + * are given by the regular expression: + * (X[nb]*)?(__[0-9]+|\$[0-9]+|___(LJM|X([FDBUP].*|R[^T]?)))?$ + * + */ +static int +is_name_suffix (str) + const char* str; +{ + int k; + if (str[0] == 'X') + { + str += 1; + while (str[0] != '_' && str[0] != '\0') + { + if (str[0] != 'n' && str[0] != 'b') + return 0; + str += 1; + } + } + if (str[0] == '\000') + return 1; + if (str[0] == '_') + { + if (str[1] != '_' || str[2] == '\000') + return 0; + if (str[2] == '_') + { + if (STREQ (str+3, "LJM")) + return 1; + if (str[3] != 'X') + return 0; + if (str[4] == 'F' || str[4] == 'D' || str[4] == 'B' || + str[4] == 'U' || str[4] == 'P') + return 1; + if (str[4] == 'R' && str[5] != 'T') + return 1; + return 0; + } + for (k = 2; str[k] != '\0'; k += 1) + if (!isdigit (str[k])) + return 0; + return 1; + } + if (str[0] == '$' && str[1] != '\000') + { + for (k = 1; str[k] != '\0'; k += 1) + if (!isdigit (str[k])) + return 0; + return 1; + } + return 0; +} + +/* True if NAME represents a name of the form A1.A2....An, n>=1 and + * PATN[0..PATN_LEN-1] = Ak.Ak+1.....An for some k >= 1. Ignores + * informational suffixes of NAME (i.e., for which is_name_suffix is + * true). */ +static int +wild_match (patn, patn_len, name) + const char* patn; + int patn_len; + const char* name; +{ + int name_len; + int s, e; + + name_len = strlen (name); + if (name_len >= patn_len+5 && STREQN (name, "_ada_", 5) + && STREQN (patn, name+5, patn_len) + && is_name_suffix (name+patn_len+5)) + return 1; + + while (name_len >= patn_len) + { + if (STREQN (patn, name, patn_len) + && is_name_suffix (name+patn_len)) + return 1; + do { + name += 1; name_len -= 1; + } while (name_len > 0 + && name[0] != '.' && (name[0] != '_' || name[1] != '_')); + if (name_len <= 0) + return 0; + if (name[0] == '_') + { + if (! islower (name[2])) + return 0; + name += 2; name_len -= 2; + } + else + { + if (! islower (name[1])) + return 0; + name += 1; name_len -= 1; + } + } + + return 0; +} + + +/* Add symbols from BLOCK matching identifier NAME in NAMESPACE to + vector *defn_symbols, updating *defn_symbols (if necessary), *SZ (the size of + the vector *defn_symbols), and *ndefns (the number of symbols + currently stored in *defn_symbols). If WILD, treat as NAME with a + wildcard prefix. OBJFILE is the section containing BLOCK. */ + +static void +ada_add_block_symbols (block, name, namespace, objfile, wild) + struct block* block; + const char* name; + namespace_enum namespace; + struct objfile* objfile; + int wild; +{ + int i; + int name_len = strlen (name); + /* A matching argument symbol, if any. */ + struct symbol *arg_sym; + /* Set true when we find a matching non-argument symbol */ + int found_sym; + int is_sorted = BLOCK_SHOULD_SORT (block); + + arg_sym = NULL; found_sym = 0; + if (wild) + { + for (i = 0; i < BLOCK_NSYMS (block); i += 1) + { + struct symbol *sym = BLOCK_SYM (block, i); + + if (SYMBOL_NAMESPACE (sym) == namespace && + wild_match (name, name_len, SYMBOL_NAME (sym))) + { + switch (SYMBOL_CLASS (sym)) + { + case LOC_ARG: + case LOC_LOCAL_ARG: + case LOC_REF_ARG: + case LOC_REGPARM: + case LOC_REGPARM_ADDR: + case LOC_BASEREG_ARG: + arg_sym = sym; + break; + case LOC_UNRESOLVED: + continue; + default: + found_sym = 1; + fill_in_ada_prototype (sym); + add_defn_to_vec (fixup_symbol_section (sym, objfile), block); + break; + } + } + } + } + else + { + if (is_sorted) + { + int U; + i = 0; U = BLOCK_NSYMS (block)-1; + while (U - i > 4) + { + int M = (U+i) >> 1; + struct symbol *sym = BLOCK_SYM (block, M); + if (SYMBOL_NAME (sym)[0] < name[0]) + i = M+1; + else if (SYMBOL_NAME (sym)[0] > name[0]) + U = M-1; + else if (strcmp (SYMBOL_NAME (sym), name) < 0) + i = M+1; + else + U = M; + } + } + else + i = 0; + + for (; i < BLOCK_NSYMS (block); i += 1) + { + struct symbol *sym = BLOCK_SYM (block, i); + + if (SYMBOL_NAMESPACE (sym) == namespace) + { + int cmp = strncmp (name, SYMBOL_NAME (sym), name_len); + + if (cmp < 0) + { + if (is_sorted) + break; + } + else if (cmp == 0 + && is_name_suffix (SYMBOL_NAME (sym) + name_len)) + { + switch (SYMBOL_CLASS (sym)) + { + case LOC_ARG: + case LOC_LOCAL_ARG: + case LOC_REF_ARG: + case LOC_REGPARM: + case LOC_REGPARM_ADDR: + case LOC_BASEREG_ARG: + arg_sym = sym; + break; + case LOC_UNRESOLVED: + break; + default: + found_sym = 1; + fill_in_ada_prototype (sym); + add_defn_to_vec (fixup_symbol_section (sym, objfile), + block); + break; + } + } + } + } + } + + if (! found_sym && arg_sym != NULL) + { + fill_in_ada_prototype (arg_sym); + add_defn_to_vec (fixup_symbol_section (arg_sym, objfile), block); + } + + if (! wild) + { + arg_sym = NULL; found_sym = 0; + if (is_sorted) + { + int U; + i = 0; U = BLOCK_NSYMS (block)-1; + while (U - i > 4) + { + int M = (U+i) >> 1; + struct symbol *sym = BLOCK_SYM (block, M); + if (SYMBOL_NAME (sym)[0] < '_') + i = M+1; + else if (SYMBOL_NAME (sym)[0] > '_') + U = M-1; + else if (strcmp (SYMBOL_NAME (sym), "_ada_") < 0) + i = M+1; + else + U = M; + } + } + else + i = 0; + + for (; i < BLOCK_NSYMS (block); i += 1) + { + struct symbol *sym = BLOCK_SYM (block, i); + + if (SYMBOL_NAMESPACE (sym) == namespace) + { + int cmp; + + cmp = (int) '_' - (int) SYMBOL_NAME (sym)[0]; + if (cmp == 0) + { + cmp = strncmp ("_ada_", SYMBOL_NAME (sym), 5); + if (cmp == 0) + cmp = strncmp (name, SYMBOL_NAME (sym) + 5, name_len); + } + + if (cmp < 0) + { + if (is_sorted) + break; + } + else if (cmp == 0 + && is_name_suffix (SYMBOL_NAME (sym) + name_len + 5)) + { + switch (SYMBOL_CLASS (sym)) + { + case LOC_ARG: + case LOC_LOCAL_ARG: + case LOC_REF_ARG: + case LOC_REGPARM: + case LOC_REGPARM_ADDR: + case LOC_BASEREG_ARG: + arg_sym = sym; + break; + case LOC_UNRESOLVED: + break; + default: + found_sym = 1; + fill_in_ada_prototype (sym); + add_defn_to_vec (fixup_symbol_section (sym, objfile), + block); + break; + } + } + } + } + + /* NOTE: This really shouldn't be needed for _ada_ symbols. + They aren't parameters, right? */ + if (! found_sym && arg_sym != NULL) + { + fill_in_ada_prototype (arg_sym); + add_defn_to_vec (fixup_symbol_section (arg_sym, objfile), block); + } + } +} + + + /* Function Types */ + +/* Assuming that SYM is the symbol for a function, fill in its type + with prototype information, if it is not already there. */ + +static void +fill_in_ada_prototype (func) + struct symbol* func; +{ + struct block* b; + int nargs, nsyms; + int i; + struct type* ftype; + struct type* rtype; + size_t max_fields; + + if (func == NULL + || TYPE_CODE (SYMBOL_TYPE (func)) != TYPE_CODE_FUNC + || TYPE_FIELDS (SYMBOL_TYPE (func)) != NULL) + return; + + /* We make each function type unique, so that each may have its own */ + /* parameter types. This particular way of doing so wastes space: */ + /* it would be nicer to build the argument types while the original */ + /* function type is being built (FIXME). */ + rtype = check_typedef (TYPE_TARGET_TYPE (SYMBOL_TYPE (func))); + ftype = alloc_type (TYPE_OBJFILE (SYMBOL_TYPE (func))); + make_function_type (rtype, &ftype); + SYMBOL_TYPE (func) = ftype; + + b = SYMBOL_BLOCK_VALUE (func); + nsyms = BLOCK_NSYMS (b); + + nargs = 0; + max_fields = 8; + TYPE_FIELDS (ftype) = + (struct field*) xmalloc (sizeof (struct field) * max_fields); + for (i = 0; i < nsyms; i += 1) + { + struct symbol *sym = BLOCK_SYM (b, i); + + GROW_VECT (TYPE_FIELDS (ftype), max_fields, nargs+1); + + switch (SYMBOL_CLASS (sym)) + { + case LOC_REF_ARG: + case LOC_REGPARM_ADDR: + TYPE_FIELD_BITPOS (ftype, nargs) = nargs; + TYPE_FIELD_BITSIZE (ftype, nargs) = 0; + TYPE_FIELD_TYPE (ftype, nargs) = + lookup_pointer_type (check_typedef (SYMBOL_TYPE (sym))); + TYPE_FIELD_NAME (ftype, nargs) = SYMBOL_NAME (sym); + nargs += 1; + + break; + + case LOC_ARG: + case LOC_REGPARM: + case LOC_LOCAL_ARG: + case LOC_BASEREG_ARG: + TYPE_FIELD_BITPOS (ftype, nargs) = nargs; + TYPE_FIELD_BITSIZE (ftype, nargs) = 0; + TYPE_FIELD_TYPE (ftype, nargs) = check_typedef (SYMBOL_TYPE (sym)); + TYPE_FIELD_NAME (ftype, nargs) = SYMBOL_NAME (sym); + nargs += 1; + + break; + + default: + break; + } + } + + /* Re-allocate fields vector; if there are no fields, make the */ + /* fields pointer non-null anyway, to mark that this function type */ + /* has been filled in. */ + + TYPE_NFIELDS (ftype) = nargs; + if (nargs == 0) + { + static struct field dummy_field = {0, 0, 0, 0}; + free (TYPE_FIELDS (ftype)); + TYPE_FIELDS (ftype) = &dummy_field; + } + else + { + struct field* fields = + (struct field*) TYPE_ALLOC (ftype, nargs * sizeof (struct field)); + memcpy ((char*) fields, + (char*) TYPE_FIELDS (ftype), + nargs * sizeof (struct field)); + free (TYPE_FIELDS (ftype)); + TYPE_FIELDS (ftype) = fields; + } +} + + + /* Breakpoint-related */ + +char no_symtab_msg[] = "No symbol table is loaded. Use the \"file\" command."; + +/* Assuming that LINE is pointing at the beginning of an argument to + 'break', return a pointer to the delimiter for the initial segment + of that name. This is the first ':', ' ', or end of LINE. +*/ +char* +ada_start_decode_line_1 (line) + char* line; +{ + /* [NOTE: strpbrk would be more elegant, but I am reluctant to be + the first to use such a library function in GDB code.] */ + char* p; + for (p = line; *p != '\000' && *p != ' ' && *p != ':'; p += 1) + ; + return p; +} + +/* *SPEC points to a function and line number spec (as in a break + command), following any initial file name specification. + + Return all symbol table/line specfications (sals) consistent with the + information in *SPEC and FILE_TABLE in the + following sense: + + FILE_TABLE is null, or the sal refers to a line in the file + named by FILE_TABLE. + + If *SPEC points to an argument with a trailing ':LINENUM', + then the sal refers to that line (or one following it as closely as + possible). + + If *SPEC does not start with '*', the sal is in a function with + that name. + + Returns with 0 elements if no matching non-minimal symbols found. + + If *SPEC begins with a function name of the form , then NAME + is taken as a literal name; otherwise the function name is subject + to the usual mangling. + + *SPEC is updated to point after the function/line number specification. + + FUNFIRSTLINE is non-zero if we desire the first line of real code + in each function (this is ignored in the presence of a LINENUM spec.). + + If CANONICAL is non-NULL, and if any of the sals require a + 'canonical line spec', then *CANONICAL is set to point to an array + of strings, corresponding to and equal in length to the returned + list of sals, such that (*CANONICAL)[i] is non-null and contains a + canonical line spec for the ith returned sal, if needed. If no + canonical line specs are required and CANONICAL is non-null, + *CANONICAL is set to NULL. + + A 'canonical line spec' is simply a name (in the format of the + breakpoint command) that uniquely identifies a breakpoint position, + with no further contextual information or user selection. It is + needed whenever the file name, function name, and line number + information supplied is insufficient for this unique + identification. Currently overloaded functions, the name '*', + or static functions without a filename yield a canonical line spec. + The array and the line spec strings are allocated on the heap; it + is the caller's responsibility to free them. */ + +struct symtabs_and_lines +ada_finish_decode_line_1 (spec, file_table, funfirstline, canonical) + char** spec; + struct symtab* file_table; + int funfirstline; + char*** canonical; +{ + struct symbol** symbols; + struct block** blocks; + struct block* block; + int n_matches, i, line_num; + struct symtabs_and_lines selected; + struct cleanup* old_chain = make_cleanup (null_cleanup, NULL); + char* name; + + int len; + char* lower_name; + char* unquoted_name; + + if (file_table == NULL) + block = get_selected_block (NULL); + else + block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (file_table), STATIC_BLOCK); + + if (canonical != NULL) + *canonical = (char**) NULL; + + name = *spec; + if (**spec == '*') + *spec += 1; + else + { + while (**spec != '\000' && + ! strchr (ada_completer_word_break_characters, **spec)) + *spec += 1; + } + len = *spec - name; + + line_num = -1; + if (file_table != NULL && (*spec)[0] == ':' && isdigit ((*spec)[1])) + { + line_num = strtol (*spec + 1, spec, 10); + while (**spec == ' ' || **spec == '\t') + *spec += 1; + } + + if (name[0] == '*') + { + if (line_num == -1) + error ("Wild-card function with no line number or file name."); + + return all_sals_for_line (file_table->filename, line_num, canonical); + } + + if (name[0] == '\'') + { + name += 1; + len -= 2; + } + + if (name[0] == '<') + { + unquoted_name = (char*) alloca (len-1); + memcpy (unquoted_name, name+1, len-2); + unquoted_name[len-2] = '\000'; + lower_name = NULL; + } + else + { + unquoted_name = (char*) alloca (len+1); + memcpy (unquoted_name, name, len); + unquoted_name[len] = '\000'; + lower_name = (char*) alloca (len + 1); + for (i = 0; i < len; i += 1) + lower_name[i] = tolower (name[i]); + lower_name[len] = '\000'; + } + + n_matches = 0; + if (lower_name != NULL) + n_matches = ada_lookup_symbol_list (ada_mangle (lower_name), block, + VAR_NAMESPACE, &symbols, &blocks); + if (n_matches == 0) + n_matches = ada_lookup_symbol_list (unquoted_name, block, + VAR_NAMESPACE, &symbols, &blocks); + if (n_matches == 0 && line_num >= 0) + error ("No line number information found for %s.", unquoted_name); + else if (n_matches == 0) + { +#ifdef HPPA_COMPILER_BUG + /* FIXME: See comment in symtab.c::decode_line_1 */ +#undef volatile + volatile struct symtab_and_line val; +#define volatile /*nothing*/ +#else + struct symtab_and_line val; +#endif + struct minimal_symbol* msymbol; + + INIT_SAL (&val); + + msymbol = NULL; + if (lower_name != NULL) + msymbol = ada_lookup_minimal_symbol (ada_mangle (lower_name)); + if (msymbol == NULL) + msymbol = ada_lookup_minimal_symbol (unquoted_name); + if (msymbol != NULL) + { + val.pc = SYMBOL_VALUE_ADDRESS (msymbol); + val.section = SYMBOL_BFD_SECTION (msymbol); + if (funfirstline) + { + val.pc += FUNCTION_START_OFFSET; + SKIP_PROLOGUE (val.pc); + } + selected.sals = (struct symtab_and_line *) + xmalloc (sizeof (struct symtab_and_line)); + selected.sals[0] = val; + selected.nelts = 1; + return selected; + } + + if (!have_full_symbols () && + !have_partial_symbols () && !have_minimal_symbols ()) + error (no_symtab_msg); + + error ("Function \"%s\" not defined.", unquoted_name); + return selected; /* for lint */ + } + + if (line_num >= 0) + { + return + find_sal_from_funcs_and_line (file_table->filename, line_num, + symbols, n_matches); + } + else + { + selected.nelts = user_select_syms (symbols, blocks, n_matches, n_matches); + } + + selected.sals = (struct symtab_and_line*) + xmalloc (sizeof (struct symtab_and_line) * selected.nelts); + memset (selected.sals, 0, selected.nelts * sizeof (selected.sals[i])); + make_cleanup (free, selected.sals); + + i = 0; + while (i < selected.nelts) + { + if (SYMBOL_CLASS (symbols[i]) == LOC_BLOCK) + selected.sals[i] = find_function_start_sal (symbols[i], funfirstline); + else if (SYMBOL_LINE (symbols[i]) != 0) + { + selected.sals[i].symtab = symtab_for_sym (symbols[i]); + selected.sals[i].line = SYMBOL_LINE (symbols[i]); + } + else if (line_num >= 0) + { + /* Ignore this choice */ + symbols[i] = symbols[selected.nelts-1]; + blocks[i] = blocks[selected.nelts-1]; + selected.nelts -= 1; + continue; + } + else + error ("Line number not known for symbol \"%s\"", unquoted_name); + i += 1; + } + + if (canonical != NULL && (line_num >= 0 || n_matches > 1)) + { + *canonical = (char**) xmalloc (sizeof(char*) * selected.nelts); + for (i = 0; i < selected.nelts; i += 1) + (*canonical)[i] = + extended_canonical_line_spec (selected.sals[i], + SYMBOL_SOURCE_NAME (symbols[i])); + } + + discard_cleanups (old_chain); + return selected; +} + +/* The (single) sal corresponding to line LINE_NUM in a symbol table + with file name FILENAME that occurs in one of the functions listed + in SYMBOLS[0 .. NSYMS-1]. */ +static struct symtabs_and_lines +find_sal_from_funcs_and_line (filename, line_num, symbols, nsyms) + const char* filename; + int line_num; + struct symbol** symbols; + int nsyms; +{ + struct symtabs_and_lines sals; + int best_index, best; + struct linetable* best_linetable; + struct objfile* objfile; + struct symtab* s; + struct symtab* best_symtab; + + read_all_symtabs (filename); + + best_index = 0; best_linetable = NULL; best_symtab = NULL; + best = 0; + ALL_SYMTABS (objfile, s) + { + struct linetable *l; + int ind, exact; + + QUIT; + + if (!STREQ (filename, s->filename)) + continue; + l = LINETABLE (s); + ind = find_line_in_linetable (l, line_num, symbols, nsyms, &exact); + if (ind >= 0) + { + if (exact) + { + best_index = ind; + best_linetable = l; + best_symtab = s; + goto done; + } + if (best == 0 || l->item[ind].line < best) + { + best = l->item[ind].line; + best_index = ind; + best_linetable = l; + best_symtab = s; + } + } + } + + if (best == 0) + error ("Line number not found in designated function."); + + done: + + sals.nelts = 1; + sals.sals = (struct symtab_and_line*) xmalloc (sizeof (sals.sals[0])); + + INIT_SAL (&sals.sals[0]); + + sals.sals[0].line = best_linetable->item[best_index].line; + sals.sals[0].pc = best_linetable->item[best_index].pc; + sals.sals[0].symtab = best_symtab; + + return sals; +} + +/* Return the index in LINETABLE of the best match for LINE_NUM whose + pc falls within one of the functions denoted by SYMBOLS[0..NSYMS-1]. + Set *EXACTP to the 1 if the match is exact, and 0 otherwise. */ +static int +find_line_in_linetable (linetable, line_num, symbols, nsyms, exactp) + struct linetable* linetable; + int line_num; + struct symbol** symbols; + int nsyms; + int* exactp; +{ + int i, len, best_index, best; + + if (line_num <= 0 || linetable == NULL) + return -1; + + len = linetable->nitems; + for (i = 0, best_index = -1, best = 0; i < len; i += 1) + { + int k; + struct linetable_entry* item = &(linetable->item[i]); + + for (k = 0; k < nsyms; k += 1) + { + if (symbols[k] != NULL && SYMBOL_CLASS (symbols[k]) == LOC_BLOCK + && item->pc >= BLOCK_START (SYMBOL_BLOCK_VALUE (symbols[k])) + && item->pc < BLOCK_END (SYMBOL_BLOCK_VALUE (symbols[k]))) + goto candidate; + } + continue; + + candidate: + + if (item->line == line_num) + { + *exactp = 1; + return i; + } + + if (item->line > line_num && (best == 0 || item->line < best)) + { + best = item->line; + best_index = i; + } + } + + *exactp = 0; + return best_index; +} + +/* Find the smallest k >= LINE_NUM such that k is a line number in + LINETABLE, and k falls strictly within a named function that begins at + or before LINE_NUM. Return -1 if there is no such k. */ +static int +nearest_line_number_in_linetable (linetable, line_num) + struct linetable* linetable; + int line_num; +{ + int i, len, best; + + if (line_num <= 0 || linetable == NULL || linetable->nitems == 0) + return -1; + len = linetable->nitems; + + i = 0; best = INT_MAX; + while (i < len) + { + int k; + struct linetable_entry* item = &(linetable->item[i]); + + if (item->line >= line_num && item->line < best) + { + char* func_name; + CORE_ADDR start, end; + + func_name = NULL; + find_pc_partial_function (item->pc, &func_name, &start, &end); + + if (func_name != NULL && item->pc < end) + { + if (item->line == line_num) + return line_num; + else + { + struct symbol* sym = + standard_lookup (func_name, VAR_NAMESPACE); + if (is_plausible_func_for_line (sym, line_num)) + best = item->line; + else + { + do + i += 1; + while (i < len && linetable->item[i].pc < end); + continue; + } + } + } + } + + i += 1; + } + + return (best == INT_MAX) ? -1 : best; +} + + +/* Return the next higher index, k, into LINETABLE such that k > IND, + entry k in LINETABLE has a line number equal to LINE_NUM, k + corresponds to a PC that is in a function different from that + corresponding to IND, and falls strictly within a named function + that begins at a line at or preceding STARTING_LINE. + Return -1 if there is no such k. + IND == -1 corresponds to no function. */ + +static int +find_next_line_in_linetable (linetable, line_num, starting_line, ind) + struct linetable* linetable; + int line_num; + int starting_line; + int ind; +{ + int i, len; + + if (line_num <= 0 || linetable == NULL || ind >= linetable->nitems) + return -1; + len = linetable->nitems; + + if (ind >= 0) + { + CORE_ADDR start, end; + + if (find_pc_partial_function (linetable->item[ind].pc, + (char**) NULL, &start, &end)) + { + while (ind < len && linetable->item[ind].pc < end) + ind += 1; + } + else + ind += 1; + } + else + ind = 0; + + i = ind; + while (i < len) + { + int k; + struct linetable_entry* item = &(linetable->item[i]); + + if (item->line >= line_num) + { + char* func_name; + CORE_ADDR start, end; + + func_name = NULL; + find_pc_partial_function (item->pc, &func_name, &start, &end); + + if (func_name != NULL && item->pc < end) + { + if (item->line == line_num) + { + struct symbol* sym = + standard_lookup (func_name, VAR_NAMESPACE); + if (is_plausible_func_for_line (sym, starting_line)) + return i; + else + { + while ((i+1) < len && linetable->item[i+1].pc < end) + i += 1; + } + } + } + } + i += 1; + } + + return -1; +} + +/* True iff function symbol SYM starts somewhere at or before line # + LINE_NUM. */ +static int +is_plausible_func_for_line (sym, line_num) + struct symbol* sym; + int line_num; +{ + struct symtab_and_line start_sal; + + if (sym == NULL) + return 0; + + start_sal = find_function_start_sal (sym, 0); + + return (start_sal.line != 0 && line_num >= start_sal.line); +} + +static void +debug_print_lines (lt) + struct linetable* lt; +{ + int i; + + if (lt == NULL) + return; + + fprintf (stderr, "\t"); + for (i = 0; i < lt->nitems; i += 1) + fprintf (stderr, "(%d->%p) ", lt->item[i].line, (void *) lt->item[i].pc); + fprintf (stderr, "\n"); +} + +static void +debug_print_block (b) + struct block* b; +{ + int i; + fprintf (stderr, "Block: %p; [0x%lx, 0x%lx]", + b, BLOCK_START(b), BLOCK_END(b)); + if (BLOCK_FUNCTION(b) != NULL) + fprintf (stderr, " Function: %s", SYMBOL_NAME (BLOCK_FUNCTION(b))); + fprintf (stderr, "\n"); + fprintf (stderr, "\t Superblock: %p\n", BLOCK_SUPERBLOCK(b)); + fprintf (stderr, "\t Symbols:"); + for (i = 0; i < BLOCK_NSYMS (b); i += 1) + { + if (i > 0 && i % 4 == 0) + fprintf (stderr, "\n\t\t "); + fprintf (stderr, " %s", SYMBOL_NAME (BLOCK_SYM (b, i))); + } + fprintf (stderr, "\n"); +} + +static void +debug_print_blocks (bv) + struct blockvector* bv; +{ + int i; + + if (bv == NULL) + return; + for (i = 0; i < BLOCKVECTOR_NBLOCKS (bv); i += 1) { + fprintf (stderr, "%6d. ", i); + debug_print_block (BLOCKVECTOR_BLOCK (bv, i)); + } +} + +static void +debug_print_symtab (s) + struct symtab* s; +{ + fprintf (stderr, "Symtab %p\n File: %s; Dir: %s\n", s, + s->filename, s->dirname); + fprintf (stderr, " Blockvector: %p, Primary: %d\n", + BLOCKVECTOR(s), s->primary); + debug_print_blocks (BLOCKVECTOR(s)); + fprintf (stderr, " Line table: %p\n", LINETABLE (s)); + debug_print_lines (LINETABLE(s)); +} + +/* Read in all symbol tables corresponding to partial symbol tables + with file name FILENAME. */ +static void +read_all_symtabs (filename) + const char* filename; +{ + struct partial_symtab* ps; + struct objfile* objfile; + + ALL_PSYMTABS (objfile, ps) + { + QUIT; + + if (STREQ (filename, ps->filename)) + PSYMTAB_TO_SYMTAB (ps); + } +} + +/* All sals corresponding to line LINE_NUM in a symbol table from file + FILENAME, as filtered by the user. If CANONICAL is not null, set + it to a corresponding array of canonical line specs. */ +static struct symtabs_and_lines +all_sals_for_line (filename, line_num, canonical) + const char* filename; + int line_num; + char*** canonical; +{ + struct symtabs_and_lines result; + struct objfile* objfile; + struct symtab* s; + struct cleanup* old_chain = make_cleanup (null_cleanup, NULL); + size_t len; + + read_all_symtabs (filename); + + result.sals = (struct symtab_and_line*) xmalloc (4 * sizeof (result.sals[0])); + result.nelts = 0; + len = 4; + make_cleanup (free_current_contents, &result.sals); + + ALL_SYMTABS (objfile, s) + { + int ind, target_line_num; + + QUIT; + + if (!STREQ (s->filename, filename)) + continue; + + target_line_num = + nearest_line_number_in_linetable (LINETABLE (s), line_num); + if (target_line_num == -1) + continue; + + ind = -1; + while (1) + { + ind = + find_next_line_in_linetable (LINETABLE (s), + target_line_num, line_num, ind); + + if (ind < 0) + break; + + GROW_VECT (result.sals, len, result.nelts+1); + INIT_SAL (&result.sals[result.nelts]); + result.sals[result.nelts].line = LINETABLE(s)->item[ind].line; + result.sals[result.nelts].pc = LINETABLE(s)->item[ind].pc; + result.sals[result.nelts].symtab = s; + result.nelts += 1; + } + } + + if (canonical != NULL || result.nelts > 1) + { + int k; + char** func_names = (char**) alloca (result.nelts * sizeof (char*)); + int first_choice = (result.nelts > 1) ? 2 : 1; + int n; + int* choices = (int*) alloca (result.nelts * sizeof (int)); + + for (k = 0; k < result.nelts; k += 1) + { + find_pc_partial_function (result.sals[k].pc, &func_names[k], + (CORE_ADDR*) NULL, (CORE_ADDR*) NULL); + if (func_names[k] == NULL) + error ("Could not find function for one or more breakpoints."); + } + + if (result.nelts > 1) + { + printf_unfiltered("[0] cancel\n"); + if (result.nelts > 1) + printf_unfiltered("[1] all\n"); + for (k = 0; k < result.nelts; k += 1) + printf_unfiltered ("[%d] %s\n", k + first_choice, + ada_demangle (func_names[k])); + + n = get_selections (choices, result.nelts, result.nelts, + result.nelts > 1, "instance-choice"); + + for (k = 0; k < n; k += 1) + { + result.sals[k] = result.sals[choices[k]]; + func_names[k] = func_names[choices[k]]; + } + result.nelts = n; + } + + if (canonical != NULL) + { + *canonical = (char**) xmalloc (result.nelts * sizeof (char**)); + make_cleanup (free, *canonical); + for (k = 0; k < result.nelts; k += 1) + { + (*canonical)[k] = + extended_canonical_line_spec (result.sals[k], func_names[k]); + if ((*canonical)[k] == NULL) + error ("Could not locate one or more breakpoints."); + make_cleanup (free, (*canonical)[k]); + } + } + } + + discard_cleanups (old_chain); + return result; +} + + +/* A canonical line specification of the form FILE:NAME:LINENUM for + symbol table and line data SAL. NULL if insufficient + information. The caller is responsible for releasing any space + allocated. */ + +static char* +extended_canonical_line_spec (sal, name) + struct symtab_and_line sal; + const char* name; +{ + char* r; + + if (sal.symtab == NULL || sal.symtab->filename == NULL || + sal.line <= 0) + return NULL; + + r = (char*) xmalloc (strlen (name) + strlen (sal.symtab->filename) + + sizeof(sal.line)*3 + 3); + sprintf (r, "%s:'%s':%d", sal.symtab->filename, name, sal.line); + return r; +} + +#if 0 +int begin_bnum = -1; +#endif +int begin_annotate_level = 0; + +static void +begin_cleanup (void* dummy) +{ + begin_annotate_level = 0; +} + +static void +begin_command (args, from_tty) + char *args; + int from_tty; +{ + struct minimal_symbol *msym; + CORE_ADDR main_program_name_addr; + char main_program_name[1024]; + struct cleanup* old_chain = make_cleanup (begin_cleanup, NULL); + begin_annotate_level = 2; + + /* Check that there is a program to debug */ + if (!have_full_symbols () && !have_partial_symbols ()) + error ("No symbol table is loaded. Use the \"file\" command."); + + /* Check that we are debugging an Ada program */ + /* if (ada_update_initial_language (language_unknown, NULL) != language_ada) + error ("Cannot find the Ada initialization procedure. Is this an Ada main program?"); + */ + /* FIXME: language_ada should be defined in defs.h */ + + /* Get the address of the name of the main procedure */ + msym = lookup_minimal_symbol (ADA_MAIN_PROGRAM_SYMBOL_NAME, NULL, NULL); + + if (msym != NULL) + { + main_program_name_addr = SYMBOL_VALUE_ADDRESS (msym); + if (main_program_name_addr == 0) + error ("Invalid address for Ada main program name."); + + /* Read the name of the main procedure */ + extract_string (main_program_name_addr, main_program_name); + + /* Put a temporary breakpoint in the Ada main program and run */ + do_command ("tbreak ", main_program_name, 0); + do_command ("run ", args, 0); + } + else + { + /* If we could not find the symbol containing the name of the + main program, that means that the compiler that was used to build + was not recent enough. In that case, we fallback to the previous + mechanism, which is a little bit less reliable, but has proved to work + in most cases. The only cases where it will fail is when the user + has set some breakpoints which will be hit before the end of the + begin command processing (eg in the initialization code). + + The begining of the main Ada subprogram is located by breaking + on the adainit procedure. Since we know that the binder generates + the call to this procedure exactly 2 calls before the call to the + Ada main subprogram, it is then easy to put a breakpoint on this + Ada main subprogram once we hit adainit. + */ + do_command ("tbreak adainit", 0); + do_command ("run ", args, 0); + do_command ("up", 0); + do_command ("tbreak +2", 0); + do_command ("continue", 0); + do_command ("step", 0); + } + + do_cleanups (old_chain); +} + +int +is_ada_runtime_file (filename) + char *filename; +{ + return (STREQN (filename, "s-", 2) || + STREQN (filename, "a-", 2) || + STREQN (filename, "g-", 2) || + STREQN (filename, "i-", 2)); +} + +/* find the first frame that contains debugging information and that is not + part of the Ada run-time, starting from fi and moving upward. */ + +int +find_printable_frame (fi, level) + struct frame_info *fi; + int level; +{ + struct symtab_and_line sal; + + for (; fi != NULL; level += 1, fi = get_prev_frame (fi)) + { + /* If fi is not the innermost frame, that normally means that fi->pc + points to *after* the call instruction, and we want to get the line + containing the call, never the next line. But if the next frame is + a signal_handler_caller or a dummy frame, then the next frame was + not entered as the result of a call, and we want to get the line + containing fi->pc. */ + sal = + find_pc_line (fi->pc, + fi->next != NULL + && !fi->next->signal_handler_caller + && !frame_in_dummy (fi->next)); + if (sal.symtab && !is_ada_runtime_file (sal.symtab->filename)) + { +#if defined(__alpha__) && defined(__osf__) && !defined(VXWORKS_TARGET) + /* libpthread.so contains some debugging information that prevents us + from finding the right frame */ + + if (sal.symtab->objfile && + STREQ (sal.symtab->objfile->name, "/usr/shlib/libpthread.so")) + continue; +#endif + selected_frame = fi; + break; + } + } + + return level; +} + +void +ada_report_exception_break (b) + struct breakpoint *b; +{ +#ifdef UI_OUT + /* FIXME: break_on_exception should be defined in breakpoint.h */ + /* if (b->break_on_exception == 1) + { + /* Assume that cond has 16 elements, the 15th + being the exception */ /* + if (b->cond && b->cond->nelts == 16) + { + ui_out_text (uiout, "on "); + ui_out_field_string (uiout, "exception", + SYMBOL_NAME (b->cond->elts[14].symbol)); + } + else + ui_out_text (uiout, "on all exceptions"); + } + else if (b->break_on_exception == 2) + ui_out_text (uiout, "on unhandled exception"); + else if (b->break_on_exception == 3) + ui_out_text (uiout, "on assert failure"); +#else + if (b->break_on_exception == 1) + {*/ + /* Assume that cond has 16 elements, the 15th + being the exception */ /* + if (b->cond && b->cond->nelts == 16) + { + fputs_filtered ("on ", gdb_stdout); + fputs_filtered (SYMBOL_NAME + (b->cond->elts[14].symbol), gdb_stdout); + } + else + fputs_filtered ("on all exceptions", gdb_stdout); + } + else if (b->break_on_exception == 2) + fputs_filtered ("on unhandled exception", gdb_stdout); + else if (b->break_on_exception == 3) + fputs_filtered ("on assert failure", gdb_stdout); +*/ +#endif +} + +int +ada_is_exception_sym (struct symbol* sym) +{ + char *type_name = type_name_no_tag (SYMBOL_TYPE (sym)); + + return (SYMBOL_CLASS (sym) != LOC_TYPEDEF + && SYMBOL_CLASS (sym) != LOC_BLOCK + && SYMBOL_CLASS (sym) != LOC_CONST + && type_name != NULL + && STREQ (type_name, "exception")); +} + +int +ada_maybe_exception_partial_symbol (struct partial_symbol* sym) +{ + return (SYMBOL_CLASS (sym) != LOC_TYPEDEF + && SYMBOL_CLASS (sym) != LOC_BLOCK + && SYMBOL_CLASS (sym) != LOC_CONST); +} + +/* If ARG points to an Ada exception or assert breakpoint, rewrite + into equivalent form. Return resulting argument string. Set + *BREAK_ON_EXCEPTIONP to 1 for ordinary break on exception, 2 for + break on unhandled, 3 for assert, 0 otherwise. */ +char* ada_breakpoint_rewrite (char* arg, int* break_on_exceptionp) +{ + if (arg == NULL) + return arg; + *break_on_exceptionp = 0; + /* FIXME: language_ada should be defined in defs.h */ + /* if (current_language->la_language == language_ada + && STREQN (arg, "exception", 9) && + (arg[9] == ' ' || arg[9] == '\t' || arg[9] == '\0')) + { + char *tok, *end_tok; + int toklen; + + *break_on_exceptionp = 1; + + tok = arg+9; + while (*tok == ' ' || *tok == '\t') + tok += 1; + + end_tok = tok; + + while (*end_tok != ' ' && *end_tok != '\t' && *end_tok != '\000') + end_tok += 1; + + toklen = end_tok - tok; + + arg = (char*) xmalloc (sizeof ("__gnat_raise_nodefer_with_msg if " + "long_integer(e) = long_integer(&)") + + toklen + 1); + make_cleanup (free, arg); + if (toklen == 0) + strcpy (arg, "__gnat_raise_nodefer_with_msg"); + else if (STREQN (tok, "unhandled", toklen)) + { + *break_on_exceptionp = 2; + strcpy (arg, "__gnat_unhandled_exception"); + } + else + { + sprintf (arg, "__gnat_raise_nodefer_with_msg if " + "long_integer(e) = long_integer(&%.*s)", + toklen, tok); + } + } + else if (current_language->la_language == language_ada + && STREQN (arg, "assert", 6) && + (arg[6] == ' ' || arg[6] == '\t' || arg[6] == '\0')) + { + char *tok = arg + 6; + + *break_on_exceptionp = 3; + + arg = (char*) + xmalloc (sizeof ("system__assertions__raise_assert_failure") + + strlen (tok) + 1); + make_cleanup (free, arg); + sprintf (arg, "system__assertions__raise_assert_failure%s", tok); + } + */ + return arg; +} + + + /* Field Access */ + +/* True if field number FIELD_NUM in struct or union type TYPE is supposed + to be invisible to users. */ + +int +ada_is_ignored_field (type, field_num) + struct type *type; + int field_num; +{ + if (field_num < 0 || field_num > TYPE_NFIELDS (type)) + return 1; + else + { + const char* name = TYPE_FIELD_NAME (type, field_num); + return (name == NULL + || (name[0] == '_' && ! STREQN (name, "_parent", 7))); + } +} + +/* True iff structure type TYPE has a tag field. */ + +int +ada_is_tagged_type (type) + struct type *type; +{ + if (type == NULL || TYPE_CODE (type) != TYPE_CODE_STRUCT) + return 0; + + return (ada_lookup_struct_elt_type (type, "_tag", 1, NULL) != NULL); +} + +/* The type of the tag on VAL. */ + +struct type* +ada_tag_type (val) + struct value* val; +{ + return ada_lookup_struct_elt_type (VALUE_TYPE (val), "_tag", 0, NULL); +} + +/* The value of the tag on VAL. */ + +struct value* +ada_value_tag (val) + struct value* val; +{ + return ada_value_struct_elt (val, "_tag", "record"); +} + +/* The parent type of TYPE, or NULL if none. */ + +struct type* +ada_parent_type (type) + struct type *type; +{ + int i; + + CHECK_TYPEDEF (type); + + if (type == NULL || TYPE_CODE (type) != TYPE_CODE_STRUCT) + return NULL; + + for (i = 0; i < TYPE_NFIELDS (type); i += 1) + if (ada_is_parent_field (type, i)) + return check_typedef (TYPE_FIELD_TYPE (type, i)); + + return NULL; +} + +/* True iff field number FIELD_NUM of structure type TYPE contains the + parent-type (inherited) fields of a derived type. Assumes TYPE is + a structure type with at least FIELD_NUM+1 fields. */ + +int +ada_is_parent_field (type, field_num) + struct type *type; + int field_num; +{ + const char* name = TYPE_FIELD_NAME (check_typedef (type), field_num); + return (name != NULL && + (STREQN (name, "PARENT", 6) || STREQN (name, "_parent", 7))); +} + +/* True iff field number FIELD_NUM of structure type TYPE is a + transparent wrapper field (which should be silently traversed when doing + field selection and flattened when printing). Assumes TYPE is a + structure type with at least FIELD_NUM+1 fields. Such fields are always + structures. */ + +int +ada_is_wrapper_field (type, field_num) + struct type *type; + int field_num; +{ + const char* name = TYPE_FIELD_NAME (type, field_num); + return (name != NULL + && (STREQN (name, "PARENT", 6) || STREQ (name, "REP") + || STREQN (name, "_parent", 7) + || name[0] == 'S' || name[0] == 'R' || name[0] == 'O')); +} + +/* True iff field number FIELD_NUM of structure or union type TYPE + is a variant wrapper. Assumes TYPE is a structure type with at least + FIELD_NUM+1 fields. */ + +int +ada_is_variant_part (type, field_num) + struct type *type; + int field_num; +{ + struct type* field_type = TYPE_FIELD_TYPE (type, field_num); + return (TYPE_CODE (field_type) == TYPE_CODE_UNION + || (is_dynamic_field (type, field_num) + && TYPE_CODE (TYPE_TARGET_TYPE (field_type)) == TYPE_CODE_UNION)); +} + +/* Assuming that VAR_TYPE is a variant wrapper (type of the variant part) + whose discriminants are contained in the record type OUTER_TYPE, + returns the type of the controlling discriminant for the variant. */ + +struct type* +ada_variant_discrim_type (var_type, outer_type) + struct type *var_type; + struct type *outer_type; +{ + char* name = ada_variant_discrim_name (var_type); + struct type *type = + ada_lookup_struct_elt_type (outer_type, name, 1, NULL); + if (type == NULL) + return builtin_type_int; + else + return type; +} + +/* Assuming that TYPE is the type of a variant wrapper, and FIELD_NUM is a + valid field number within it, returns 1 iff field FIELD_NUM of TYPE + represents a 'when others' clause; otherwise 0. */ + +int +ada_is_others_clause (type, field_num) + struct type *type; + int field_num; +{ + const char* name = TYPE_FIELD_NAME (type, field_num); + return (name != NULL && name[0] == 'O'); +} + +/* Assuming that TYPE0 is the type of the variant part of a record, + returns the name of the discriminant controlling the variant. The + value is valid until the next call to ada_variant_discrim_name. */ + +char * +ada_variant_discrim_name (type0) + struct type *type0; +{ + static char* result = NULL; + static size_t result_len = 0; + struct type* type; + const char* name; + const char* discrim_end; + const char* discrim_start; + + if (TYPE_CODE (type0) == TYPE_CODE_PTR) + type = TYPE_TARGET_TYPE (type0); + else + type = type0; + + name = ada_type_name (type); + + if (name == NULL || name[0] == '\000') + return ""; + + for (discrim_end = name + strlen (name) - 6; discrim_end != name; + discrim_end -= 1) + { + if (STREQN (discrim_end, "___XVN", 6)) + break; + } + if (discrim_end == name) + return ""; + + for (discrim_start = discrim_end; discrim_start != name+3; + discrim_start -= 1) + { + if (discrim_start == name+1) + return ""; + if ((discrim_start > name+3 && STREQN (discrim_start-3, "___", 3)) + || discrim_start[-1] == '.') + break; + } + + GROW_VECT (result, result_len, discrim_end - discrim_start + 1); + strncpy (result, discrim_start, discrim_end - discrim_start); + result[discrim_end-discrim_start] = '\0'; + return result; +} + +/* Scan STR for a subtype-encoded number, beginning at position K. Put the + position of the character just past the number scanned in *NEW_K, + if NEW_K!=NULL. Put the scanned number in *R, if R!=NULL. Return 1 + if there was a valid number at the given position, and 0 otherwise. A + "subtype-encoded" number consists of the absolute value in decimal, + followed by the letter 'm' to indicate a negative number. Assumes 0m + does not occur. */ + +int +ada_scan_number (str, k, R, new_k) + const char str[]; + int k; + LONGEST *R; + int *new_k; +{ + ULONGEST RU; + + if (! isdigit (str[k])) + return 0; + + /* Do it the hard way so as not to make any assumption about + the relationship of unsigned long (%lu scan format code) and + LONGEST. */ + RU = 0; + while (isdigit (str[k])) + { + RU = RU*10 + (str[k] - '0'); + k += 1; + } + + if (str[k] == 'm') + { + if (R != NULL) + *R = (- (LONGEST) (RU-1)) - 1; + k += 1; + } + else if (R != NULL) + *R = (LONGEST) RU; + + /* NOTE on the above: Technically, C does not say what the results of + - (LONGEST) RU or (LONGEST) -RU are for RU == largest positive + number representable as a LONGEST (although either would probably work + in most implementations). When RU>0, the locution in the then branch + above is always equivalent to the negative of RU. */ + + if (new_k != NULL) + *new_k = k; + return 1; +} + +/* Assuming that TYPE is a variant part wrapper type (a VARIANTS field), + and FIELD_NUM is a valid field number within it, returns 1 iff VAL is + in the range encoded by field FIELD_NUM of TYPE; otherwise 0. */ + +int +ada_in_variant (val, type, field_num) + LONGEST val; + struct type *type; + int field_num; +{ + const char* name = TYPE_FIELD_NAME (type, field_num); + int p; + + p = 0; + while (1) + { + switch (name[p]) + { + case '\0': + return 0; + case 'S': + { + LONGEST W; + if (! ada_scan_number (name, p + 1, &W, &p)) + return 0; + if (val == W) + return 1; + break; + } + case 'R': + { + LONGEST L, U; + if (! ada_scan_number (name, p + 1, &L, &p) + || name[p] != 'T' + || ! ada_scan_number (name, p + 1, &U, &p)) + return 0; + if (val >= L && val <= U) + return 1; + break; + } + case 'O': + return 1; + default: + return 0; + } + } +} + +/* Given a value ARG1 (offset by OFFSET bytes) + of a struct or union type ARG_TYPE, + extract and return the value of one of its (non-static) fields. + FIELDNO says which field. Differs from value_primitive_field only + in that it can handle packed values of arbitrary type. */ + +struct value* +ada_value_primitive_field (arg1, offset, fieldno, arg_type) + struct value* arg1; + int offset; + int fieldno; + struct type *arg_type; +{ + struct value* v; + struct type *type; + + CHECK_TYPEDEF (arg_type); + type = TYPE_FIELD_TYPE (arg_type, fieldno); + + /* Handle packed fields */ + + if (TYPE_FIELD_BITSIZE (arg_type, fieldno) != 0) + { + int bit_pos = TYPE_FIELD_BITPOS (arg_type, fieldno); + int bit_size = TYPE_FIELD_BITSIZE (arg_type, fieldno); + + return ada_value_primitive_packed_val (arg1, VALUE_CONTENTS (arg1), + offset + bit_pos/8, bit_pos % 8, + bit_size, type); + } + else + return value_primitive_field (arg1, offset, fieldno, arg_type); +} + + +/* Look for a field NAME in ARG. Adjust the address of ARG by OFFSET bytes, + and search in it assuming it has (class) type TYPE. + If found, return value, else return NULL. + + Searches recursively through wrapper fields (e.g., '_parent'). */ + +struct value* +ada_search_struct_field (name, arg, offset, type) + char *name; + struct value* arg; + int offset; + struct type *type; +{ + int i; + CHECK_TYPEDEF (type); + + for (i = TYPE_NFIELDS (type)-1; i >= 0; i -= 1) + { + char *t_field_name = TYPE_FIELD_NAME (type, i); + + if (t_field_name == NULL) + continue; + + else if (field_name_match (t_field_name, name)) + return ada_value_primitive_field (arg, offset, i, type); + + else if (ada_is_wrapper_field (type, i)) + { + struct value* v = + ada_search_struct_field (name, arg, + offset + TYPE_FIELD_BITPOS (type, i) / 8, + TYPE_FIELD_TYPE (type, i)); + if (v != NULL) + return v; + } + + else if (ada_is_variant_part (type, i)) + { + int j; + struct type *field_type = check_typedef (TYPE_FIELD_TYPE (type, i)); + int var_offset = offset + TYPE_FIELD_BITPOS (type, i) / 8; + + for (j = TYPE_NFIELDS (field_type) - 1; j >= 0; j -= 1) + { + struct value* v = + ada_search_struct_field (name, arg, + var_offset + + TYPE_FIELD_BITPOS (field_type, j)/8, + TYPE_FIELD_TYPE (field_type, j)); + if (v != NULL) + return v; + } + } + } + return NULL; +} + +/* Given ARG, a value of type (pointer to a)* structure/union, + extract the component named NAME from the ultimate target structure/union + and return it as a value with its appropriate type. + + The routine searches for NAME among all members of the structure itself + and (recursively) among all members of any wrapper members + (e.g., '_parent'). + + ERR is a name (for use in error messages) that identifies the class + of entity that ARG is supposed to be. */ + +struct value* +ada_value_struct_elt (arg, name, err) + struct value* arg; + char *name; + char *err; +{ + struct type *t; + struct value* v; + + arg = ada_coerce_ref (arg); + t = check_typedef (VALUE_TYPE (arg)); + + /* Follow pointers until we get to a non-pointer. */ + + while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_CODE (t) == TYPE_CODE_REF) + { + arg = ada_value_ind (arg); + t = check_typedef (VALUE_TYPE (arg)); + } + + if ( TYPE_CODE (t) != TYPE_CODE_STRUCT + && TYPE_CODE (t) != TYPE_CODE_UNION) + error ("Attempt to extract a component of a value that is not a %s.", err); + + v = ada_search_struct_field (name, arg, 0, t); + if (v == NULL) + error ("There is no member named %s.", name); + + return v; +} + +/* Given a type TYPE, look up the type of the component of type named NAME. + If DISPP is non-null, add its byte displacement from the beginning of a + structure (pointed to by a value) of type TYPE to *DISPP (does not + work for packed fields). + + Matches any field whose name has NAME as a prefix, possibly + followed by "___". + + TYPE can be either a struct or union, or a pointer or reference to + a struct or union. If it is a pointer or reference, its target + type is automatically used. + + Looks recursively into variant clauses and parent types. + + If NOERR is nonzero, return NULL if NAME is not suitably defined. */ + +struct type * +ada_lookup_struct_elt_type (type, name, noerr, dispp) + struct type *type; + char *name; + int noerr; + int *dispp; +{ + int i; + + if (name == NULL) + goto BadName; + + while (1) + { + CHECK_TYPEDEF (type); + if (TYPE_CODE (type) != TYPE_CODE_PTR + && TYPE_CODE (type) != TYPE_CODE_REF) + break; + type = TYPE_TARGET_TYPE (type); + } + + if (TYPE_CODE (type) != TYPE_CODE_STRUCT && + TYPE_CODE (type) != TYPE_CODE_UNION) + { + target_terminal_ours (); + gdb_flush (gdb_stdout); + fprintf_unfiltered (gdb_stderr, "Type "); + type_print (type, "", gdb_stderr, -1); + error (" is not a structure or union type"); + } + + type = to_static_fixed_type (type); + + for (i = 0; i < TYPE_NFIELDS (type); i += 1) + { + char *t_field_name = TYPE_FIELD_NAME (type, i); + struct type *t; + int disp; + + if (t_field_name == NULL) + continue; + + else if (field_name_match (t_field_name, name)) + { + if (dispp != NULL) + *dispp += TYPE_FIELD_BITPOS (type, i) / 8; + return check_typedef (TYPE_FIELD_TYPE (type, i)); + } + + else if (ada_is_wrapper_field (type, i)) + { + disp = 0; + t = ada_lookup_struct_elt_type (TYPE_FIELD_TYPE (type, i), name, + 1, &disp); + if (t != NULL) + { + if (dispp != NULL) + *dispp += disp + TYPE_FIELD_BITPOS (type, i) / 8; + return t; + } + } + + else if (ada_is_variant_part (type, i)) + { + int j; + struct type *field_type = check_typedef (TYPE_FIELD_TYPE (type, i)); + + for (j = TYPE_NFIELDS (field_type) - 1; j >= 0; j -= 1) + { + disp = 0; + t = ada_lookup_struct_elt_type (TYPE_FIELD_TYPE (field_type, j), + name, 1, &disp); + if (t != NULL) + { + if (dispp != NULL) + *dispp += disp + TYPE_FIELD_BITPOS (type, i) / 8; + return t; + } + } + } + + } + +BadName: + if (! noerr) + { + target_terminal_ours (); + gdb_flush (gdb_stdout); + fprintf_unfiltered (gdb_stderr, "Type "); + type_print (type, "", gdb_stderr, -1); + fprintf_unfiltered (gdb_stderr, " has no component named "); + error ("%s", name == NULL ? "" : name); + } + + return NULL; +} + +/* Assuming that VAR_TYPE is the type of a variant part of a record (a union), + within a value of type OUTER_TYPE that is stored in GDB at + OUTER_VALADDR, determine which variant clause (field number in VAR_TYPE, + numbering from 0) is applicable. Returns -1 if none are. */ + +int +ada_which_variant_applies (var_type, outer_type, outer_valaddr) + struct type *var_type; + struct type *outer_type; + char* outer_valaddr; +{ + int others_clause; + int i; + int disp; + struct type* discrim_type; + char* discrim_name = ada_variant_discrim_name (var_type); + LONGEST discrim_val; + + disp = 0; + discrim_type = + ada_lookup_struct_elt_type (outer_type, discrim_name, 1, &disp); + if (discrim_type == NULL) + return -1; + discrim_val = unpack_long (discrim_type, outer_valaddr + disp); + + others_clause = -1; + for (i = 0; i < TYPE_NFIELDS (var_type); i += 1) + { + if (ada_is_others_clause (var_type, i)) + others_clause = i; + else if (ada_in_variant (discrim_val, var_type, i)) + return i; + } + + return others_clause; +} + + + + /* Dynamic-Sized Records */ + +/* Strategy: The type ostensibly attached to a value with dynamic size + (i.e., a size that is not statically recorded in the debugging + data) does not accurately reflect the size or layout of the value. + Our strategy is to convert these values to values with accurate, + conventional types that are constructed on the fly. */ + +/* There is a subtle and tricky problem here. In general, we cannot + determine the size of dynamic records without its data. However, + the 'struct value' data structure, which GDB uses to represent + quantities in the inferior process (the target), requires the size + of the type at the time of its allocation in order to reserve space + for GDB's internal copy of the data. That's why the + 'to_fixed_xxx_type' routines take (target) addresses as parameters, + rather than struct value*s. + + However, GDB's internal history variables ($1, $2, etc.) are + struct value*s containing internal copies of the data that are not, in + general, the same as the data at their corresponding addresses in + the target. Fortunately, the types we give to these values are all + conventional, fixed-size types (as per the strategy described + above), so that we don't usually have to perform the + 'to_fixed_xxx_type' conversions to look at their values. + Unfortunately, there is one exception: if one of the internal + history variables is an array whose elements are unconstrained + records, then we will need to create distinct fixed types for each + element selected. */ + +/* The upshot of all of this is that many routines take a (type, host + address, target address) triple as arguments to represent a value. + The host address, if non-null, is supposed to contain an internal + copy of the relevant data; otherwise, the program is to consult the + target at the target address. */ + +/* Assuming that VAL0 represents a pointer value, the result of + dereferencing it. Differs from value_ind in its treatment of + dynamic-sized types. */ + +struct value* +ada_value_ind (val0) + struct value* val0; +{ + struct value* val = unwrap_value (value_ind (val0)); + return ada_to_fixed_value (VALUE_TYPE (val), 0, + VALUE_ADDRESS (val) + VALUE_OFFSET (val), + val); +} + +/* The value resulting from dereferencing any "reference to" + * qualifiers on VAL0. */ +static struct value* +ada_coerce_ref (val0) + struct value* val0; +{ + if (TYPE_CODE (VALUE_TYPE (val0)) == TYPE_CODE_REF) { + struct value* val = val0; + COERCE_REF (val); + val = unwrap_value (val); + return ada_to_fixed_value (VALUE_TYPE (val), 0, + VALUE_ADDRESS (val) + VALUE_OFFSET (val), + val); + } else + return val0; +} + +/* Return OFF rounded upward if necessary to a multiple of + ALIGNMENT (a power of 2). */ + +static unsigned int +align_value (off, alignment) + unsigned int off; + unsigned int alignment; +{ + return (off + alignment - 1) & ~(alignment - 1); +} + +/* Return the additional bit offset required by field F of template + type TYPE. */ + +static unsigned int +field_offset (type, f) + struct type *type; + int f; +{ + int n = TYPE_FIELD_BITPOS (type, f); + /* Kludge (temporary?) to fix problem with dwarf output. */ + if (n < 0) + return (unsigned int) n & 0xffff; + else + return n; +} + + +/* Return the bit alignment required for field #F of template type TYPE. */ + +static unsigned int +field_alignment (type, f) + struct type *type; + int f; +{ + const char* name = TYPE_FIELD_NAME (type, f); + int len = (name == NULL) ? 0 : strlen (name); + int align_offset; + + if (len < 8 || ! isdigit (name[len-1])) + return TARGET_CHAR_BIT; + + if (isdigit (name[len-2])) + align_offset = len - 2; + else + align_offset = len - 1; + + if (align_offset < 7 || ! STREQN ("___XV", name+align_offset-6, 5)) + return TARGET_CHAR_BIT; + + return atoi (name+align_offset) * TARGET_CHAR_BIT; +} + +/* Find a type named NAME. Ignores ambiguity. */ +struct type* +ada_find_any_type (name) + const char *name; +{ + struct symbol* sym; + + sym = standard_lookup (name, VAR_NAMESPACE); + if (sym != NULL && SYMBOL_CLASS (sym) == LOC_TYPEDEF) + return SYMBOL_TYPE (sym); + + sym = standard_lookup (name, STRUCT_NAMESPACE); + if (sym != NULL) + return SYMBOL_TYPE (sym); + + return NULL; +} + +/* Because of GNAT encoding conventions, several GDB symbols may match a + given type name. If the type denoted by TYPE0 is to be preferred to + that of TYPE1 for purposes of type printing, return non-zero; + otherwise return 0. */ +int +ada_prefer_type (type0, type1) + struct type* type0; + struct type* type1; +{ + if (type1 == NULL) + return 1; + else if (type0 == NULL) + return 0; + else if (TYPE_CODE (type1) == TYPE_CODE_VOID) + return 1; + else if (TYPE_CODE (type0) == TYPE_CODE_VOID) + return 0; + else if (ada_is_packed_array_type (type0)) + return 1; + else if (ada_is_array_descriptor (type0) && ! ada_is_array_descriptor (type1)) + return 1; + else if (ada_renaming_type (type0) != NULL + && ada_renaming_type (type1) == NULL) + return 1; + return 0; +} + +/* The name of TYPE, which is either its TYPE_NAME, or, if that is + null, its TYPE_TAG_NAME. Null if TYPE is null. */ +char* +ada_type_name (type) + struct type* type; +{ + if (type == NULL) + return NULL; + else if (TYPE_NAME (type) != NULL) + return TYPE_NAME (type); + else + return TYPE_TAG_NAME (type); +} + +/* Find a parallel type to TYPE whose name is formed by appending + SUFFIX to the name of TYPE. */ + +struct type* +ada_find_parallel_type (type, suffix) + struct type *type; + const char *suffix; +{ + static char* name; + static size_t name_len = 0; + struct symbol** syms; + struct block** blocks; + int nsyms; + int len; + char* typename = ada_type_name (type); + + if (typename == NULL) + return NULL; + + len = strlen (typename); + + GROW_VECT (name, name_len, len+strlen (suffix)+1); + + strcpy (name, typename); + strcpy (name + len, suffix); + + return ada_find_any_type (name); +} + + +/* If TYPE is a variable-size record type, return the corresponding template + type describing its fields. Otherwise, return NULL. */ + +static struct type* +dynamic_template_type (type) + struct type* type; +{ + CHECK_TYPEDEF (type); + + if (type == NULL || TYPE_CODE (type) != TYPE_CODE_STRUCT + || ada_type_name (type) == NULL) + return NULL; + else + { + int len = strlen (ada_type_name (type)); + if (len > 6 && STREQ (ada_type_name (type) + len - 6, "___XVE")) + return type; + else + return ada_find_parallel_type (type, "___XVE"); + } +} + +/* Assuming that TEMPL_TYPE is a union or struct type, returns + non-zero iff field FIELD_NUM of TEMPL_TYPE has dynamic size. */ + +static int +is_dynamic_field (templ_type, field_num) + struct type* templ_type; + int field_num; +{ + const char *name = TYPE_FIELD_NAME (templ_type, field_num); + return name != NULL + && TYPE_CODE (TYPE_FIELD_TYPE (templ_type, field_num)) == TYPE_CODE_PTR + && strstr (name, "___XVL") != NULL; +} + +/* Assuming that TYPE is a struct type, returns non-zero iff TYPE + contains a variant part. */ + +static int +contains_variant_part (type) + struct type* type; +{ + int f; + + if (type == NULL || TYPE_CODE (type) != TYPE_CODE_STRUCT + || TYPE_NFIELDS (type) <= 0) + return 0; + return ada_is_variant_part (type, TYPE_NFIELDS (type) - 1); +} + +/* A record type with no fields, . */ +static struct type* +empty_record (objfile) + struct objfile* objfile; +{ + struct type* type = alloc_type (objfile); + TYPE_CODE (type) = TYPE_CODE_STRUCT; + TYPE_NFIELDS (type) = 0; + TYPE_FIELDS (type) = NULL; + TYPE_NAME (type) = ""; + TYPE_TAG_NAME (type) = NULL; + TYPE_FLAGS (type) = 0; + TYPE_LENGTH (type) = 0; + return type; +} + +/* An ordinary record type (with fixed-length fields) that describes + the value of type TYPE at VALADDR or ADDRESS (see comments at + the beginning of this section) VAL according to GNAT conventions. + DVAL0 should describe the (portion of a) record that contains any + necessary discriminants. It should be NULL if VALUE_TYPE (VAL) is + an outer-level type (i.e., as opposed to a branch of a variant.) A + variant field (unless unchecked) is replaced by a particular branch + of the variant. */ +/* NOTE: Limitations: For now, we assume that dynamic fields and + * variants occupy whole numbers of bytes. However, they need not be + * byte-aligned. */ + +static struct type* +template_to_fixed_record_type (type, valaddr, address, dval0) + struct type* type; + char* valaddr; + CORE_ADDR address; + struct value* dval0; + +{ + struct value* mark = value_mark(); + struct value* dval; + struct type* rtype; + int nfields, bit_len; + long off; + int f; + + nfields = TYPE_NFIELDS (type); + rtype = alloc_type (TYPE_OBJFILE (type)); + TYPE_CODE (rtype) = TYPE_CODE_STRUCT; + INIT_CPLUS_SPECIFIC (rtype); + TYPE_NFIELDS (rtype) = nfields; + TYPE_FIELDS (rtype) = (struct field*) + TYPE_ALLOC (rtype, nfields * sizeof (struct field)); + memset (TYPE_FIELDS (rtype), 0, sizeof (struct field) * nfields); + TYPE_NAME (rtype) = ada_type_name (type); + TYPE_TAG_NAME (rtype) = NULL; + /* FIXME: TYPE_FLAG_FIXED_INSTANCE should be defined in + gdbtypes.h */ + /* TYPE_FLAGS (rtype) |= TYPE_FLAG_FIXED_INSTANCE;*/ + + off = 0; bit_len = 0; + for (f = 0; f < nfields; f += 1) + { + int fld_bit_len, bit_incr; + off = + align_value (off, field_alignment (type, f))+TYPE_FIELD_BITPOS (type,f); + /* NOTE: used to use field_offset above, but that causes + * problems with really negative bit positions. So, let's + * rediscover why we needed field_offset and fix it properly. */ + TYPE_FIELD_BITPOS (rtype, f) = off; + TYPE_FIELD_BITSIZE (rtype, f) = 0; + + if (ada_is_variant_part (type, f)) + { + struct type *branch_type; + + if (dval0 == NULL) + dval = + value_from_contents_and_address (rtype, valaddr, address); + else + dval = dval0; + + branch_type = + to_fixed_variant_branch_type + (TYPE_FIELD_TYPE (type, f), + cond_offset_host (valaddr, off / TARGET_CHAR_BIT), + cond_offset_target (address, off / TARGET_CHAR_BIT), + dval); + if (branch_type == NULL) + TYPE_NFIELDS (rtype) -= 1; + else + { + TYPE_FIELD_TYPE (rtype, f) = branch_type; + TYPE_FIELD_NAME (rtype, f) = "S"; + } + bit_incr = 0; + fld_bit_len = + TYPE_LENGTH (TYPE_FIELD_TYPE (rtype, f)) * TARGET_CHAR_BIT; + } + else if (is_dynamic_field (type, f)) + { + if (dval0 == NULL) + dval = + value_from_contents_and_address (rtype, valaddr, address); + else + dval = dval0; + + TYPE_FIELD_TYPE (rtype, f) = + ada_to_fixed_type + (ada_get_base_type + (TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type, f))), + cond_offset_host (valaddr, off / TARGET_CHAR_BIT), + cond_offset_target (address, off / TARGET_CHAR_BIT), + dval); + TYPE_FIELD_NAME (rtype, f) = TYPE_FIELD_NAME (type, f); + bit_incr = fld_bit_len = + TYPE_LENGTH (TYPE_FIELD_TYPE (rtype, f)) * TARGET_CHAR_BIT; + } + else + { + TYPE_FIELD_TYPE (rtype, f) = TYPE_FIELD_TYPE (type, f); + TYPE_FIELD_NAME (rtype, f) = TYPE_FIELD_NAME (type, f); + if (TYPE_FIELD_BITSIZE (type, f) > 0) + bit_incr = fld_bit_len = + TYPE_FIELD_BITSIZE (rtype, f) = TYPE_FIELD_BITSIZE (type, f); + else + bit_incr = fld_bit_len = + TYPE_LENGTH (TYPE_FIELD_TYPE (type, f)) * TARGET_CHAR_BIT; + } + if (off + fld_bit_len > bit_len) + bit_len = off + fld_bit_len; + off += bit_incr; + TYPE_LENGTH (rtype) = bit_len / TARGET_CHAR_BIT; + } + TYPE_LENGTH (rtype) = align_value (TYPE_LENGTH (rtype), TYPE_LENGTH (type)); + + value_free_to_mark (mark); + if (TYPE_LENGTH (rtype) > varsize_limit) + error ("record type with dynamic size is larger than varsize-limit"); + return rtype; +} + +/* As for template_to_fixed_record_type, but uses no run-time values. + As a result, this type can only be approximate, but that's OK, + since it is used only for type determinations. Works on both + structs and unions. + Representation note: to save space, we memoize the result of this + function in the TYPE_TARGET_TYPE of the template type. */ + +static struct type* +template_to_static_fixed_type (templ_type) + struct type* templ_type; +{ + struct type *type; + int nfields; + int f; + + if (TYPE_TARGET_TYPE (templ_type) != NULL) + return TYPE_TARGET_TYPE (templ_type); + + nfields = TYPE_NFIELDS (templ_type); + TYPE_TARGET_TYPE (templ_type) = type = alloc_type (TYPE_OBJFILE (templ_type)); + TYPE_CODE (type) = TYPE_CODE (templ_type); + INIT_CPLUS_SPECIFIC (type); + TYPE_NFIELDS (type) = nfields; + TYPE_FIELDS (type) = (struct field*) + TYPE_ALLOC (type, nfields * sizeof (struct field)); + memset (TYPE_FIELDS (type), 0, sizeof (struct field) * nfields); + TYPE_NAME (type) = ada_type_name (templ_type); + TYPE_TAG_NAME (type) = NULL; + /* FIXME: TYPE_FLAG_FIXED_INSTANCE should be defined in gdbtypes.h */ + /* TYPE_FLAGS (type) |= TYPE_FLAG_FIXED_INSTANCE; */ + TYPE_LENGTH (type) = 0; + + for (f = 0; f < nfields; f += 1) + { + TYPE_FIELD_BITPOS (type, f) = 0; + TYPE_FIELD_BITSIZE (type, f) = 0; + + if (is_dynamic_field (templ_type, f)) + { + TYPE_FIELD_TYPE (type, f) = + to_static_fixed_type (TYPE_TARGET_TYPE + (TYPE_FIELD_TYPE (templ_type, f))); + TYPE_FIELD_NAME (type, f) = TYPE_FIELD_NAME (templ_type, f); + } + else + { + TYPE_FIELD_TYPE (type, f) = + check_typedef (TYPE_FIELD_TYPE (templ_type, f)); + TYPE_FIELD_NAME (type, f) = TYPE_FIELD_NAME (templ_type, f); + } + } + + return type; +} + +/* A revision of TYPE0 -- a non-dynamic-sized record with a variant + part -- in which the variant part is replaced with the appropriate + branch. */ +static struct type* +to_record_with_fixed_variant_part (type, valaddr, address, dval) + struct type* type; + char* valaddr; + CORE_ADDR address; + struct value* dval; +{ + struct value* mark = value_mark(); + struct type* rtype; + struct type *branch_type; + int nfields = TYPE_NFIELDS (type); + + if (dval == NULL) + return type; + + rtype = alloc_type (TYPE_OBJFILE (type)); + TYPE_CODE (rtype) = TYPE_CODE_STRUCT; + INIT_CPLUS_SPECIFIC (type); + TYPE_NFIELDS (rtype) = TYPE_NFIELDS (type); + TYPE_FIELDS (rtype) = + (struct field*) TYPE_ALLOC (rtype, nfields * sizeof (struct field)); + memcpy (TYPE_FIELDS (rtype), TYPE_FIELDS (type), + sizeof (struct field) * nfields); + TYPE_NAME (rtype) = ada_type_name (type); + TYPE_TAG_NAME (rtype) = NULL; + /* FIXME: TYPE_FLAG_FIXED_INSTANCE should be defined in gdbtypes.h */ + /* TYPE_FLAGS (rtype) |= TYPE_FLAG_FIXED_INSTANCE; */ + TYPE_LENGTH (rtype) = TYPE_LENGTH (type); + + branch_type = + to_fixed_variant_branch_type + (TYPE_FIELD_TYPE (type, nfields - 1), + cond_offset_host (valaddr, + TYPE_FIELD_BITPOS (type, nfields-1) / TARGET_CHAR_BIT), + cond_offset_target (address, + TYPE_FIELD_BITPOS (type, nfields-1) / TARGET_CHAR_BIT), + dval); + if (branch_type == NULL) + { + TYPE_NFIELDS (rtype) -= 1; + TYPE_LENGTH (rtype) -= TYPE_LENGTH (TYPE_FIELD_TYPE (type, nfields - 1)); + } + else + { + TYPE_FIELD_TYPE (rtype, nfields-1) = branch_type; + TYPE_FIELD_NAME (rtype, nfields-1) = "S"; + TYPE_FIELD_BITSIZE (rtype, nfields-1) = 0; + TYPE_LENGTH (rtype) += TYPE_LENGTH (branch_type); + - TYPE_LENGTH (TYPE_FIELD_TYPE (type, nfields - 1)); + } + + return rtype; +} + +/* An ordinary record type (with fixed-length fields) that describes + the value at (TYPE0, VALADDR, ADDRESS) [see explanation at + beginning of this section]. Any necessary discriminants' values + should be in DVAL, a record value; it should be NULL if the object + at ADDR itself contains any necessary discriminant values. A + variant field (unless unchecked) is replaced by a particular branch + of the variant. */ + +static struct type* +to_fixed_record_type (type0, valaddr, address, dval) + struct type* type0; + char* valaddr; + CORE_ADDR address; + struct value* dval; +{ + struct type* templ_type; + + /* FIXME: TYPE_FLAG_FIXED_INSTANCE should be defined in gdbtypes.h */ + /* if (TYPE_FLAGS (type0) & TYPE_FLAG_FIXED_INSTANCE) + return type0; + */ + templ_type = dynamic_template_type (type0); + + if (templ_type != NULL) + return template_to_fixed_record_type (templ_type, valaddr, address, dval); + else if (contains_variant_part (type0)) + return to_record_with_fixed_variant_part (type0, valaddr, address, dval); + else + { + /* FIXME: TYPE_FLAG_FIXED_INSTANCE should be defined in gdbtypes.h */ + /* TYPE_FLAGS (type0) |= TYPE_FLAG_FIXED_INSTANCE; */ + return type0; + } + +} + +/* An ordinary record type (with fixed-length fields) that describes + the value at (VAR_TYPE0, VALADDR, ADDRESS), where VAR_TYPE0 is a + union type. Any necessary discriminants' values should be in DVAL, + a record value. That is, this routine selects the appropriate + branch of the union at ADDR according to the discriminant value + indicated in the union's type name. */ + +static struct type* +to_fixed_variant_branch_type (var_type0, valaddr, address, dval) + struct type* var_type0; + char* valaddr; + CORE_ADDR address; + struct value* dval; +{ + int which; + struct type* templ_type; + struct type* var_type; + + if (TYPE_CODE (var_type0) == TYPE_CODE_PTR) + var_type = TYPE_TARGET_TYPE (var_type0); + else + var_type = var_type0; + + templ_type = ada_find_parallel_type (var_type, "___XVU"); + + if (templ_type != NULL) + var_type = templ_type; + + which = + ada_which_variant_applies (var_type, + VALUE_TYPE (dval), VALUE_CONTENTS (dval)); + + if (which < 0) + return empty_record (TYPE_OBJFILE (var_type)); + else if (is_dynamic_field (var_type, which)) + return + to_fixed_record_type + (TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (var_type, which)), + valaddr, address, dval); + else if (contains_variant_part (TYPE_FIELD_TYPE (var_type, which))) + return + to_fixed_record_type + (TYPE_FIELD_TYPE (var_type, which), valaddr, address, dval); + else + return TYPE_FIELD_TYPE (var_type, which); +} + +/* Assuming that TYPE0 is an array type describing the type of a value + at ADDR, and that DVAL describes a record containing any + discriminants used in TYPE0, returns a type for the value that + contains no dynamic components (that is, no components whose sizes + are determined by run-time quantities). Unless IGNORE_TOO_BIG is + true, gives an error message if the resulting type's size is over + varsize_limit. +*/ + +static struct type* +to_fixed_array_type (type0, dval, ignore_too_big) + struct type* type0; + struct value* dval; + int ignore_too_big; +{ + struct type* index_type_desc; + struct type* result; + + /* FIXME: TYPE_FLAG_FIXED_INSTANCE should be defined in gdbtypes.h */ + /* if (ada_is_packed_array_type (type0) /* revisit? */ /* + || (TYPE_FLAGS (type0) & TYPE_FLAG_FIXED_INSTANCE)) + return type0;*/ + + index_type_desc = ada_find_parallel_type (type0, "___XA"); + if (index_type_desc == NULL) + { + struct type *elt_type0 = check_typedef (TYPE_TARGET_TYPE (type0)); + /* NOTE: elt_type---the fixed version of elt_type0---should never + * depend on the contents of the array in properly constructed + * debugging data. */ + struct type *elt_type = + ada_to_fixed_type (elt_type0, 0, 0, dval); + + if (elt_type0 == elt_type) + result = type0; + else + result = create_array_type (alloc_type (TYPE_OBJFILE (type0)), + elt_type, TYPE_INDEX_TYPE (type0)); + } + else + { + int i; + struct type *elt_type0; + + elt_type0 = type0; + for (i = TYPE_NFIELDS (index_type_desc); i > 0; i -= 1) + elt_type0 = TYPE_TARGET_TYPE (elt_type0); + + /* NOTE: result---the fixed version of elt_type0---should never + * depend on the contents of the array in properly constructed + * debugging data. */ + result = + ada_to_fixed_type (check_typedef (elt_type0), 0, 0, dval); + for (i = TYPE_NFIELDS (index_type_desc) - 1; i >= 0; i -= 1) + { + struct type *range_type = + to_fixed_range_type (TYPE_FIELD_NAME (index_type_desc, i), + dval, TYPE_OBJFILE (type0)); + result = create_array_type (alloc_type (TYPE_OBJFILE (type0)), + result, range_type); + } + if (! ignore_too_big && TYPE_LENGTH (result) > varsize_limit) + error ("array type with dynamic size is larger than varsize-limit"); + } + +/* FIXME: TYPE_FLAG_FIXED_INSTANCE should be defined in gdbtypes.h */ +/* TYPE_FLAGS (result) |= TYPE_FLAG_FIXED_INSTANCE; */ + return result; +} + + +/* A standard type (containing no dynamically sized components) + corresponding to TYPE for the value (TYPE, VALADDR, ADDRESS) + DVAL describes a record containing any discriminants used in TYPE0, + and may be NULL if there are none. */ + +struct type* +ada_to_fixed_type (type, valaddr, address, dval) + struct type* type; + char* valaddr; + CORE_ADDR address; + struct value* dval; +{ + CHECK_TYPEDEF (type); + switch (TYPE_CODE (type)) { + default: + return type; + case TYPE_CODE_STRUCT: + return to_fixed_record_type (type, valaddr, address, NULL); + case TYPE_CODE_ARRAY: + return to_fixed_array_type (type, dval, 0); + case TYPE_CODE_UNION: + if (dval == NULL) + return type; + else + return to_fixed_variant_branch_type (type, valaddr, address, dval); + } +} + +/* A standard (static-sized) type corresponding as well as possible to + TYPE0, but based on no runtime data. */ + +static struct type* +to_static_fixed_type (type0) + struct type* type0; +{ + struct type* type; + + if (type0 == NULL) + return NULL; + + /* FIXME: TYPE_FLAG_FIXED_INSTANCE should be defined in gdbtypes.h */ + /* if (TYPE_FLAGS (type0) & TYPE_FLAG_FIXED_INSTANCE) + return type0; + */ + CHECK_TYPEDEF (type0); + + switch (TYPE_CODE (type0)) + { + default: + return type0; + case TYPE_CODE_STRUCT: + type = dynamic_template_type (type0); + if (type != NULL) + return template_to_static_fixed_type (type); + return type0; + case TYPE_CODE_UNION: + type = ada_find_parallel_type (type0, "___XVU"); + if (type != NULL) + return template_to_static_fixed_type (type); + return type0; + } +} + +/* A static approximation of TYPE with all type wrappers removed. */ +static struct type* +static_unwrap_type (type) + struct type* type; +{ + if (ada_is_aligner_type (type)) + { + struct type* type1 = TYPE_FIELD_TYPE (check_typedef (type), 0); + if (ada_type_name (type1) == NULL) + TYPE_NAME (type1) = ada_type_name (type); + + return static_unwrap_type (type1); + } + else + { + struct type* raw_real_type = ada_get_base_type (type); + if (raw_real_type == type) + return type; + else + return to_static_fixed_type (raw_real_type); + } +} + +/* In some cases, incomplete and private types require + cross-references that are not resolved as records (for example, + type Foo; + type FooP is access Foo; + V: FooP; + type Foo is array ...; + ). In these cases, since there is no mechanism for producing + cross-references to such types, we instead substitute for FooP a + stub enumeration type that is nowhere resolved, and whose tag is + the name of the actual type. Call these types "non-record stubs". */ + +/* A type equivalent to TYPE that is not a non-record stub, if one + exists, otherwise TYPE. */ +struct type* +ada_completed_type (type) + struct type* type; +{ + CHECK_TYPEDEF (type); + if (type == NULL || TYPE_CODE (type) != TYPE_CODE_ENUM + || (TYPE_FLAGS (type) & TYPE_FLAG_STUB) == 0 + || TYPE_TAG_NAME (type) == NULL) + return type; + else + { + char* name = TYPE_TAG_NAME (type); + struct type* type1 = ada_find_any_type (name); + return (type1 == NULL) ? type : type1; + } +} + +/* A value representing the data at VALADDR/ADDRESS as described by + type TYPE0, but with a standard (static-sized) type that correctly + describes it. If VAL0 is not NULL and TYPE0 already is a standard + type, then return VAL0 [this feature is simply to avoid redundant + creation of struct values]. */ + +struct value* +ada_to_fixed_value (type0, valaddr, address, val0) + struct type* type0; + char* valaddr; + CORE_ADDR address; + struct value* val0; +{ + struct type* type = ada_to_fixed_type (type0, valaddr, address, NULL); + if (type == type0 && val0 != NULL) + return val0; + else return value_from_contents_and_address (type, valaddr, address); +} + +/* A value representing VAL, but with a standard (static-sized) type + chosen to approximate the real type of VAL as well as possible, but + without consulting any runtime values. For Ada dynamic-sized + types, therefore, the type of the result is likely to be inaccurate. */ + +struct value* +ada_to_static_fixed_value (val) + struct value* val; +{ + struct type *type = + to_static_fixed_type (static_unwrap_type (VALUE_TYPE (val))); + if (type == VALUE_TYPE (val)) + return val; + else + return coerce_unspec_val_to_type (val, 0, type); +} + + + + + +/* Attributes */ + +/* Table mapping attribute numbers to names */ +/* NOTE: Keep up to date with enum ada_attribute definition in ada-lang.h */ + +static const char* attribute_names[] = { + "", + + "first", + "last", + "length", + "image", + "img", + "max", + "min", + "pos" + "tag", + "val", + + 0 +}; + +const char* +ada_attribute_name (n) + int n; +{ + if (n > 0 && n < (int) ATR_END) + return attribute_names[n]; + else + return attribute_names[0]; +} + +/* Evaluate the 'POS attribute applied to ARG. */ + +static struct value* +value_pos_atr (arg) + struct value* arg; +{ + struct type *type = VALUE_TYPE (arg); + + if (! discrete_type_p (type)) + error ("'POS only defined on discrete types"); + + if (TYPE_CODE (type) == TYPE_CODE_ENUM) + { + int i; + LONGEST v = value_as_long (arg); + + for (i = 0; i < TYPE_NFIELDS (type); i += 1) + { + if (v == TYPE_FIELD_BITPOS (type, i)) + return value_from_longest (builtin_type_ada_int, i); + } + error ("enumeration value is invalid: can't find 'POS"); + } + else + return value_from_longest (builtin_type_ada_int, value_as_long (arg)); +} + +/* Evaluate the TYPE'VAL attribute applied to ARG. */ + +static struct value* +value_val_atr (type, arg) + struct type *type; + struct value* arg; +{ + if (! discrete_type_p (type)) + error ("'VAL only defined on discrete types"); + if (! integer_type_p (VALUE_TYPE (arg))) + error ("'VAL requires integral argument"); + + if (TYPE_CODE (type) == TYPE_CODE_ENUM) + { + long pos = value_as_long (arg); + if (pos < 0 || pos >= TYPE_NFIELDS (type)) + error ("argument to 'VAL out of range"); + return + value_from_longest (type, TYPE_FIELD_BITPOS (type, pos)); + } + else + return value_from_longest (type, value_as_long (arg)); +} + + + /* Evaluation */ + +/* True if TYPE appears to be an Ada character type. + * [At the moment, this is true only for Character and Wide_Character; + * It is a heuristic test that could stand improvement]. */ + +int +ada_is_character_type (type) + struct type* type; +{ + const char* name = ada_type_name (type); + return + name != NULL + && (TYPE_CODE (type) == TYPE_CODE_CHAR + || TYPE_CODE (type) == TYPE_CODE_INT + || TYPE_CODE (type) == TYPE_CODE_RANGE) + && (STREQ (name, "character") || STREQ (name, "wide_character") + || STREQ (name, "unsigned char")); +} + +/* True if TYPE appears to be an Ada string type. */ + +int +ada_is_string_type (type) + struct type *type; +{ + CHECK_TYPEDEF (type); + if (type != NULL + && TYPE_CODE (type) != TYPE_CODE_PTR + && (ada_is_simple_array (type) || ada_is_array_descriptor (type)) + && ada_array_arity (type) == 1) + { + struct type *elttype = ada_array_element_type (type, 1); + + return ada_is_character_type (elttype); + } + else + return 0; +} + + +/* True if TYPE is a struct type introduced by the compiler to force the + alignment of a value. Such types have a single field with a + distinctive name. */ + +int +ada_is_aligner_type (type) + struct type *type; +{ + CHECK_TYPEDEF (type); + return (TYPE_CODE (type) == TYPE_CODE_STRUCT + && TYPE_NFIELDS (type) == 1 + && STREQ (TYPE_FIELD_NAME (type, 0), "F")); +} + +/* If there is an ___XVS-convention type parallel to SUBTYPE, return + the parallel type. */ + +struct type* +ada_get_base_type (raw_type) + struct type* raw_type; +{ + struct type* real_type_namer; + struct type* raw_real_type; + struct type* real_type; + + if (raw_type == NULL || TYPE_CODE (raw_type) != TYPE_CODE_STRUCT) + return raw_type; + + real_type_namer = ada_find_parallel_type (raw_type, "___XVS"); + if (real_type_namer == NULL + || TYPE_CODE (real_type_namer) != TYPE_CODE_STRUCT + || TYPE_NFIELDS (real_type_namer) != 1) + return raw_type; + + raw_real_type = ada_find_any_type (TYPE_FIELD_NAME (real_type_namer, 0)); + if (raw_real_type == NULL) + return raw_type; + else + return raw_real_type; +} + +/* The type of value designated by TYPE, with all aligners removed. */ + +struct type* +ada_aligned_type (type) + struct type* type; +{ + if (ada_is_aligner_type (type)) + return ada_aligned_type (TYPE_FIELD_TYPE (type, 0)); + else + return ada_get_base_type (type); +} + + +/* The address of the aligned value in an object at address VALADDR + having type TYPE. Assumes ada_is_aligner_type (TYPE). */ + +char* +ada_aligned_value_addr (type, valaddr) + struct type *type; + char *valaddr; +{ + if (ada_is_aligner_type (type)) + return ada_aligned_value_addr (TYPE_FIELD_TYPE (type, 0), + valaddr + + TYPE_FIELD_BITPOS (type, 0)/TARGET_CHAR_BIT); + else + return valaddr; +} + +/* The printed representation of an enumeration literal with encoded + name NAME. The value is good to the next call of ada_enum_name. */ +const char* +ada_enum_name (name) + const char* name; +{ + char* tmp; + + while (1) + { + if ((tmp = strstr (name, "__")) != NULL) + name = tmp+2; + else if ((tmp = strchr (name, '.')) != NULL) + name = tmp+1; + else + break; + } + + if (name[0] == 'Q') + { + static char result[16]; + int v; + if (name[1] == 'U' || name[1] == 'W') + { + if (sscanf (name+2, "%x", &v) != 1) + return name; + } + else + return name; + + if (isascii (v) && isprint (v)) + sprintf (result, "'%c'", v); + else if (name[1] == 'U') + sprintf (result, "[\"%02x\"]", v); + else + sprintf (result, "[\"%04x\"]", v); + + return result; + } + else + return name; +} + +static struct value* +evaluate_subexp (expect_type, exp, pos, noside) + struct type *expect_type; + struct expression *exp; + int *pos; + enum noside noside; +{ + return (*exp->language_defn->evaluate_exp) (expect_type, exp, pos, noside); +} + +/* Evaluate the subexpression of EXP starting at *POS as for + evaluate_type, updating *POS to point just past the evaluated + expression. */ + +static struct value* +evaluate_subexp_type (exp, pos) + struct expression* exp; + int* pos; +{ + return (*exp->language_defn->evaluate_exp) + (NULL_TYPE, exp, pos, EVAL_AVOID_SIDE_EFFECTS); +} + +/* If VAL is wrapped in an aligner or subtype wrapper, return the + value it wraps. */ + +static struct value* +unwrap_value (val) + struct value* val; +{ + struct type* type = check_typedef (VALUE_TYPE (val)); + if (ada_is_aligner_type (type)) + { + struct value* v = value_struct_elt (&val, NULL, "F", + NULL, "internal structure"); + struct type* val_type = check_typedef (VALUE_TYPE (v)); + if (ada_type_name (val_type) == NULL) + TYPE_NAME (val_type) = ada_type_name (type); + + return unwrap_value (v); + } + else + { + struct type* raw_real_type = + ada_completed_type (ada_get_base_type (type)); + + if (type == raw_real_type) + return val; + + return + coerce_unspec_val_to_type + (val, 0, ada_to_fixed_type (raw_real_type, 0, + VALUE_ADDRESS (val) + VALUE_OFFSET (val), + NULL)); + } +} + +static struct value* +cast_to_fixed (type, arg) + struct type *type; + struct value* arg; +{ + LONGEST val; + + if (type == VALUE_TYPE (arg)) + return arg; + else if (ada_is_fixed_point_type (VALUE_TYPE (arg))) + val = ada_float_to_fixed (type, + ada_fixed_to_float (VALUE_TYPE (arg), + value_as_long (arg))); + else + { + DOUBLEST argd = + value_as_double (value_cast (builtin_type_double, value_copy (arg))); + val = ada_float_to_fixed (type, argd); + } + + return value_from_longest (type, val); +} + +static struct value* +cast_from_fixed_to_double (arg) + struct value* arg; +{ + DOUBLEST val = ada_fixed_to_float (VALUE_TYPE (arg), + value_as_long (arg)); + return value_from_double (builtin_type_double, val); +} + +/* Coerce VAL as necessary for assignment to an lval of type TYPE, and + * return the converted value. */ +static struct value* +coerce_for_assign (type, val) + struct type* type; + struct value* val; +{ + struct type* type2 = VALUE_TYPE (val); + if (type == type2) + return val; + + CHECK_TYPEDEF (type2); + CHECK_TYPEDEF (type); + + if (TYPE_CODE (type2) == TYPE_CODE_PTR && TYPE_CODE (type) == TYPE_CODE_ARRAY) + { + val = ada_value_ind (val); + type2 = VALUE_TYPE (val); + } + + if (TYPE_CODE (type2) == TYPE_CODE_ARRAY + && TYPE_CODE (type) == TYPE_CODE_ARRAY) + { + if (TYPE_LENGTH (type2) != TYPE_LENGTH (type) + || TYPE_LENGTH (TYPE_TARGET_TYPE (type2)) + != TYPE_LENGTH (TYPE_TARGET_TYPE (type2))) + error ("Incompatible types in assignment"); + VALUE_TYPE (val) = type; + } + return val; +} + +struct value* +ada_evaluate_subexp (expect_type, exp, pos, noside) + struct type *expect_type; + struct expression *exp; + int *pos; + enum noside noside; +{ + enum exp_opcode op; + enum ada_attribute atr; + int tem, tem2, tem3; + int pc; + struct value *arg1 = NULL, *arg2 = NULL, *arg3; + struct type *type; + int nargs; + struct value* *argvec; + + pc = *pos; *pos += 1; + op = exp->elts[pc].opcode; + + switch (op) + { + default: + *pos -= 1; + return unwrap_value (evaluate_subexp_standard (expect_type, exp, pos, noside)); + + case UNOP_CAST: + (*pos) += 2; + type = exp->elts[pc + 1].type; + arg1 = evaluate_subexp (type, exp, pos, noside); + if (noside == EVAL_SKIP) + goto nosideret; + if (type != check_typedef (VALUE_TYPE (arg1))) + { + if (ada_is_fixed_point_type (type)) + arg1 = cast_to_fixed (type, arg1); + else if (ada_is_fixed_point_type (VALUE_TYPE (arg1))) + arg1 = value_cast (type, cast_from_fixed_to_double (arg1)); + else if (VALUE_LVAL (arg1) == lval_memory) + { + /* This is in case of the really obscure (and undocumented, + but apparently expected) case of (Foo) Bar.all, where Bar + is an integer constant and Foo is a dynamic-sized type. + If we don't do this, ARG1 will simply be relabeled with + TYPE. */ + if (noside == EVAL_AVOID_SIDE_EFFECTS) + return value_zero (to_static_fixed_type (type), not_lval); + arg1 = + ada_to_fixed_value + (type, 0, VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1), 0); + } + else + arg1 = value_cast (type, arg1); + } + return arg1; + + /* FIXME: UNOP_QUAL should be defined in expression.h */ + /* case UNOP_QUAL: + (*pos) += 2; + type = exp->elts[pc + 1].type; + return ada_evaluate_subexp (type, exp, pos, noside); + */ + case BINOP_ASSIGN: + arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + arg2 = evaluate_subexp (VALUE_TYPE (arg1), exp, pos, noside); + if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS) + return arg1; + if (binop_user_defined_p (op, arg1, arg2)) + return value_x_binop (arg1, arg2, op, OP_NULL, EVAL_NORMAL); + else + { + if (ada_is_fixed_point_type (VALUE_TYPE (arg1))) + arg2 = cast_to_fixed (VALUE_TYPE (arg1), arg2); + else if (ada_is_fixed_point_type (VALUE_TYPE (arg2))) + error ("Fixed-point values must be assigned to fixed-point variables"); + else + arg2 = coerce_for_assign (VALUE_TYPE (arg1), arg2); + return ada_value_assign (arg1, arg2); + } + + case BINOP_ADD: + arg1 = evaluate_subexp_with_coercion (exp, pos, noside); + arg2 = evaluate_subexp_with_coercion (exp, pos, noside); + if (noside == EVAL_SKIP) + goto nosideret; + if (binop_user_defined_p (op, arg1, arg2)) + return value_x_binop (arg1, arg2, op, OP_NULL, EVAL_NORMAL); + else + { + if ((ada_is_fixed_point_type (VALUE_TYPE (arg1)) + || ada_is_fixed_point_type (VALUE_TYPE (arg2))) + && VALUE_TYPE (arg1) != VALUE_TYPE (arg2)) + error ("Operands of fixed-point addition must have the same type"); + return value_cast (VALUE_TYPE (arg1), value_add (arg1, arg2)); + } + + case BINOP_SUB: + arg1 = evaluate_subexp_with_coercion (exp, pos, noside); + arg2 = evaluate_subexp_with_coercion (exp, pos, noside); + if (noside == EVAL_SKIP) + goto nosideret; + if (binop_user_defined_p (op, arg1, arg2)) + return value_x_binop (arg1, arg2, op, OP_NULL, EVAL_NORMAL); + else + { + if ((ada_is_fixed_point_type (VALUE_TYPE (arg1)) + || ada_is_fixed_point_type (VALUE_TYPE (arg2))) + && VALUE_TYPE (arg1) != VALUE_TYPE (arg2)) + error ("Operands of fixed-point subtraction must have the same type"); + return value_cast (VALUE_TYPE (arg1), value_sub (arg1, arg2)); + } + + case BINOP_MUL: + case BINOP_DIV: + arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + if (noside == EVAL_SKIP) + goto nosideret; + if (binop_user_defined_p (op, arg1, arg2)) + return value_x_binop (arg1, arg2, op, OP_NULL, EVAL_NORMAL); + else + if (noside == EVAL_AVOID_SIDE_EFFECTS + && (op == BINOP_DIV || op == BINOP_REM || op == BINOP_MOD)) + return value_zero (VALUE_TYPE (arg1), not_lval); + else + { + if (ada_is_fixed_point_type (VALUE_TYPE (arg1))) + arg1 = cast_from_fixed_to_double (arg1); + if (ada_is_fixed_point_type (VALUE_TYPE (arg2))) + arg2 = cast_from_fixed_to_double (arg2); + return value_binop (arg1, arg2, op); + } + + case UNOP_NEG: + arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + if (noside == EVAL_SKIP) + goto nosideret; + if (unop_user_defined_p (op, arg1)) + return value_x_unop (arg1, op, EVAL_NORMAL); + else if (ada_is_fixed_point_type (VALUE_TYPE (arg1))) + return value_cast (VALUE_TYPE (arg1), value_neg (arg1)); + else + return value_neg (arg1); + + /* FIXME: OP_UNRESOLVED_VALUE should be defined in expression.h */ + /* case OP_UNRESOLVED_VALUE: + /* Only encountered when an unresolved symbol occurs in a + context other than a function call, in which case, it is + illegal. *//* + (*pos) += 3; + if (noside == EVAL_SKIP) + goto nosideret; + else + error ("Unexpected unresolved symbol, %s, during evaluation", + ada_demangle (exp->elts[pc + 2].name)); + */ + case OP_VAR_VALUE: + *pos -= 1; + if (noside == EVAL_SKIP) + { + *pos += 4; + goto nosideret; + } + else if (noside == EVAL_AVOID_SIDE_EFFECTS) + { + *pos += 4; + return value_zero + (to_static_fixed_type + (static_unwrap_type (SYMBOL_TYPE (exp->elts[pc+2].symbol))), + not_lval); + } + else + { + arg1 = unwrap_value (evaluate_subexp_standard (expect_type, exp, pos, + noside)); + return ada_to_fixed_value (VALUE_TYPE (arg1), 0, + VALUE_ADDRESS (arg1) + VALUE_OFFSET(arg1), + arg1); + } + + case OP_ARRAY: + (*pos) += 3; + tem2 = longest_to_int (exp->elts[pc + 1].longconst); + tem3 = longest_to_int (exp->elts[pc + 2].longconst); + nargs = tem3 - tem2 + 1; + type = expect_type ? check_typedef (expect_type) : NULL_TYPE; + + argvec = (struct value* *) alloca (sizeof (struct value*) * (nargs + 1)); + for (tem = 0; tem == 0 || tem < nargs; tem += 1) + /* At least one element gets inserted for the type */ + { + /* Ensure that array expressions are coerced into pointer objects. */ + argvec[tem] = evaluate_subexp_with_coercion (exp, pos, noside); + } + if (noside == EVAL_SKIP) + goto nosideret; + return value_array (tem2, tem3, argvec); + + case OP_FUNCALL: + (*pos) += 2; + + /* Allocate arg vector, including space for the function to be + called in argvec[0] and a terminating NULL */ + nargs = longest_to_int (exp->elts[pc + 1].longconst); + argvec = (struct value* *) alloca (sizeof (struct value*) * (nargs + 2)); + + /* FIXME: OP_UNRESOLVED_VALUE should be defined in expression.h */ + /* FIXME: name should be defined in expresion.h */ + /* if (exp->elts[*pos].opcode == OP_UNRESOLVED_VALUE) + error ("Unexpected unresolved symbol, %s, during evaluation", + ada_demangle (exp->elts[pc + 5].name)); + */ + if (0) + { + error ("unexpected code path, FIXME"); + } + else + { + for (tem = 0; tem <= nargs; tem += 1) + argvec[tem] = evaluate_subexp (NULL_TYPE, exp, pos, noside); + argvec[tem] = 0; + + if (noside == EVAL_SKIP) + goto nosideret; + } + + if (TYPE_CODE (VALUE_TYPE (argvec[0])) == TYPE_CODE_REF) + argvec[0] = value_addr (argvec[0]); + + if (ada_is_packed_array_type (VALUE_TYPE (argvec[0]))) + argvec[0] = ada_coerce_to_simple_array (argvec[0]); + + type = check_typedef (VALUE_TYPE (argvec[0])); + if (TYPE_CODE (type) == TYPE_CODE_PTR) + { + switch (TYPE_CODE (check_typedef (TYPE_TARGET_TYPE (type)))) + { + case TYPE_CODE_FUNC: + type = check_typedef (TYPE_TARGET_TYPE (type)); + break; + case TYPE_CODE_ARRAY: + break; + case TYPE_CODE_STRUCT: + if (noside != EVAL_AVOID_SIDE_EFFECTS) + argvec[0] = ada_value_ind (argvec[0]); + type = check_typedef (TYPE_TARGET_TYPE (type)); + break; + default: + error ("cannot subscript or call something of type `%s'", + ada_type_name (VALUE_TYPE (argvec[0]))); + break; + } + } + + switch (TYPE_CODE (type)) + { + case TYPE_CODE_FUNC: + if (noside == EVAL_AVOID_SIDE_EFFECTS) + return allocate_value (TYPE_TARGET_TYPE (type)); + return call_function_by_hand (argvec[0], nargs, argvec + 1); + case TYPE_CODE_STRUCT: + { + int arity = ada_array_arity (type); + type = ada_array_element_type (type, nargs); + if (type == NULL) + error ("cannot subscript or call a record"); + if (arity != nargs) + error ("wrong number of subscripts; expecting %d", arity); + if (noside == EVAL_AVOID_SIDE_EFFECTS) + return allocate_value (ada_aligned_type (type)); + return unwrap_value (ada_value_subscript (argvec[0], nargs, argvec+1)); + } + case TYPE_CODE_ARRAY: + if (noside == EVAL_AVOID_SIDE_EFFECTS) + { + type = ada_array_element_type (type, nargs); + if (type == NULL) + error ("element type of array unknown"); + else + return allocate_value (ada_aligned_type (type)); + } + return + unwrap_value (ada_value_subscript + (ada_coerce_to_simple_array (argvec[0]), + nargs, argvec+1)); + case TYPE_CODE_PTR: /* Pointer to array */ + type = to_fixed_array_type (TYPE_TARGET_TYPE (type), NULL, 1); + if (noside == EVAL_AVOID_SIDE_EFFECTS) + { + type = ada_array_element_type (type, nargs); + if (type == NULL) + error ("element type of array unknown"); + else + return allocate_value (ada_aligned_type (type)); + } + return + unwrap_value (ada_value_ptr_subscript (argvec[0], type, + nargs, argvec+1)); + + default: + error ("Internal error in evaluate_subexp"); + } + + case TERNOP_SLICE: + { + struct value* array = evaluate_subexp (NULL_TYPE, exp, pos, noside); + int lowbound + = value_as_long (evaluate_subexp (NULL_TYPE, exp, pos, noside)); + int upper + = value_as_long (evaluate_subexp (NULL_TYPE, exp, pos, noside)); + if (noside == EVAL_SKIP) + goto nosideret; + + /* If this is a reference to an array, then dereference it */ + if (TYPE_CODE (VALUE_TYPE (array)) == TYPE_CODE_REF + && TYPE_TARGET_TYPE (VALUE_TYPE (array)) != NULL + && TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (array))) == + TYPE_CODE_ARRAY + && !ada_is_array_descriptor (check_typedef (VALUE_TYPE + (array)))) + { + array = ada_coerce_ref (array); + } + + if (noside == EVAL_AVOID_SIDE_EFFECTS && + ada_is_array_descriptor (check_typedef (VALUE_TYPE (array)))) + { + /* Try to dereference the array, in case it is an access to array */ + struct type * arrType = ada_type_of_array (array, 0); + if (arrType != NULL) + array = value_at_lazy (arrType, 0, NULL); + } + if (ada_is_array_descriptor (VALUE_TYPE (array))) + array = ada_coerce_to_simple_array (array); + + /* If at this point we have a pointer to an array, it means that + it is a pointer to a simple (non-ada) array. We just then + dereference it */ + if (TYPE_CODE (VALUE_TYPE (array)) == TYPE_CODE_PTR + && TYPE_TARGET_TYPE (VALUE_TYPE (array)) != NULL + && TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (array))) == + TYPE_CODE_ARRAY) + { + array = ada_value_ind (array); + } + + if (noside == EVAL_AVOID_SIDE_EFFECTS) + /* The following will get the bounds wrong, but only in contexts + where the value is not being requested (FIXME?). */ + return array; + else + return value_slice (array, lowbound, upper - lowbound + 1); + } + + /* FIXME: UNOP_MBR should be defined in expression.h */ + /* case UNOP_MBR: + (*pos) += 2; + arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + type = exp->elts[pc + 1].type; + + if (noside == EVAL_SKIP) + goto nosideret; + + switch (TYPE_CODE (type)) + { + default: + warning ("Membership test incompletely implemented; always returns true"); + return value_from_longest (builtin_type_int, (LONGEST) 1); + + case TYPE_CODE_RANGE: + arg2 = value_from_longest (builtin_type_int, + (LONGEST) TYPE_LOW_BOUND (type)); + arg3 = value_from_longest (builtin_type_int, + (LONGEST) TYPE_HIGH_BOUND (type)); + return + value_from_longest (builtin_type_int, + (value_less (arg1,arg3) + || value_equal (arg1,arg3)) + && (value_less (arg2,arg1) + || value_equal (arg2,arg1))); + } + */ + /* FIXME: BINOP_MBR should be defined in expression.h */ + /* case BINOP_MBR: + (*pos) += 2; + arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + + if (noside == EVAL_SKIP) + goto nosideret; + + if (noside == EVAL_AVOID_SIDE_EFFECTS) + return value_zero (builtin_type_int, not_lval); + + tem = longest_to_int (exp->elts[pc + 1].longconst); + + if (tem < 1 || tem > ada_array_arity (VALUE_TYPE (arg2))) + error ("invalid dimension number to '%s", "range"); + + arg3 = ada_array_bound (arg2, tem, 1); + arg2 = ada_array_bound (arg2, tem, 0); + + return + value_from_longest (builtin_type_int, + (value_less (arg1,arg3) + || value_equal (arg1,arg3)) + && (value_less (arg2,arg1) + || value_equal (arg2,arg1))); + */ + /* FIXME: TERNOP_MBR should be defined in expression.h */ + /* case TERNOP_MBR: + arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + arg3 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + + if (noside == EVAL_SKIP) + goto nosideret; + + return + value_from_longest (builtin_type_int, + (value_less (arg1,arg3) + || value_equal (arg1,arg3)) + && (value_less (arg2,arg1) + || value_equal (arg2,arg1))); + */ + /* FIXME: OP_ATTRIBUTE should be defined in expression.h */ + /* case OP_ATTRIBUTE: + *pos += 3; + atr = (enum ada_attribute) longest_to_int (exp->elts[pc + 2].longconst); + switch (atr) + { + default: + error ("unexpected attribute encountered"); + + case ATR_FIRST: + case ATR_LAST: + case ATR_LENGTH: + { + struct type* type_arg; + if (exp->elts[*pos].opcode == OP_TYPE) + { + evaluate_subexp (NULL_TYPE, exp, pos, EVAL_SKIP); + arg1 = NULL; + type_arg = exp->elts[pc + 5].type; + } + else + { + arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + type_arg = NULL; + } + + if (exp->elts[*pos].opcode != OP_LONG) + error ("illegal operand to '%s", ada_attribute_name (atr)); + tem = longest_to_int (exp->elts[*pos+2].longconst); + *pos += 4; + + if (noside == EVAL_SKIP) + goto nosideret; + + if (type_arg == NULL) + { + arg1 = ada_coerce_ref (arg1); + + if (ada_is_packed_array_type (VALUE_TYPE (arg1))) + arg1 = ada_coerce_to_simple_array (arg1); + + if (tem < 1 || tem > ada_array_arity (VALUE_TYPE (arg1))) + error ("invalid dimension number to '%s", + ada_attribute_name (atr)); + + if (noside == EVAL_AVOID_SIDE_EFFECTS) + { + type = ada_index_type (VALUE_TYPE (arg1), tem); + if (type == NULL) + error ("attempt to take bound of something that is not an array"); + return allocate_value (type); + } + + switch (atr) + { + default: + error ("unexpected attribute encountered"); + case ATR_FIRST: + return ada_array_bound (arg1, tem, 0); + case ATR_LAST: + return ada_array_bound (arg1, tem, 1); + case ATR_LENGTH: + return ada_array_length (arg1, tem); + } + } + else if (TYPE_CODE (type_arg) == TYPE_CODE_RANGE + || TYPE_CODE (type_arg) == TYPE_CODE_INT) + { + struct type* range_type; + char* name = ada_type_name (type_arg); + if (name == NULL) + { + if (TYPE_CODE (type_arg) == TYPE_CODE_RANGE) + range_type = type_arg; + else + error ("unimplemented type attribute"); + } + else + range_type = + to_fixed_range_type (name, NULL, TYPE_OBJFILE (type_arg)); + switch (atr) + { + default: + error ("unexpected attribute encountered"); + case ATR_FIRST: + return value_from_longest (TYPE_TARGET_TYPE (range_type), + TYPE_LOW_BOUND (range_type)); + case ATR_LAST: + return value_from_longest (TYPE_TARGET_TYPE (range_type), + TYPE_HIGH_BOUND (range_type)); + } + } + else if (TYPE_CODE (type_arg) == TYPE_CODE_ENUM) + { + switch (atr) + { + default: + error ("unexpected attribute encountered"); + case ATR_FIRST: + return value_from_longest + (type_arg, TYPE_FIELD_BITPOS (type_arg, 0)); + case ATR_LAST: + return value_from_longest + (type_arg, + TYPE_FIELD_BITPOS (type_arg, + TYPE_NFIELDS (type_arg) - 1)); + } + } + else if (TYPE_CODE (type_arg) == TYPE_CODE_FLT) + error ("unimplemented type attribute"); + else + { + LONGEST low, high; + + if (ada_is_packed_array_type (type_arg)) + type_arg = decode_packed_array_type (type_arg); + + if (tem < 1 || tem > ada_array_arity (type_arg)) + error ("invalid dimension number to '%s", + ada_attribute_name (atr)); + + if (noside == EVAL_AVOID_SIDE_EFFECTS) + { + type = ada_index_type (type_arg, tem); + if (type == NULL) + error ("attempt to take bound of something that is not an array"); + return allocate_value (type); + } + + switch (atr) + { + default: + error ("unexpected attribute encountered"); + case ATR_FIRST: + low = ada_array_bound_from_type (type_arg, tem, 0, &type); + return value_from_longest (type, low); + case ATR_LAST: + high = ada_array_bound_from_type (type_arg, tem, 1, &type); + return value_from_longest (type, high); + case ATR_LENGTH: + low = ada_array_bound_from_type (type_arg, tem, 0, &type); + high = ada_array_bound_from_type (type_arg, tem, 1, NULL); + return value_from_longest (type, high-low+1); + } + } + } + + case ATR_TAG: + arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + if (noside == EVAL_SKIP) + goto nosideret; + + if (noside == EVAL_AVOID_SIDE_EFFECTS) + return + value_zero (ada_tag_type (arg1), not_lval); + + return ada_value_tag (arg1); + + case ATR_MIN: + case ATR_MAX: + evaluate_subexp (NULL_TYPE, exp, pos, EVAL_SKIP); + arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + if (noside == EVAL_SKIP) + goto nosideret; + else if (noside == EVAL_AVOID_SIDE_EFFECTS) + return value_zero (VALUE_TYPE (arg1), not_lval); + else + return value_binop (arg1, arg2, + atr == ATR_MIN ? BINOP_MIN : BINOP_MAX); + + case ATR_MODULUS: + { + struct type* type_arg = exp->elts[pc + 5].type; + evaluate_subexp (NULL_TYPE, exp, pos, EVAL_SKIP); + *pos += 4; + + if (noside == EVAL_SKIP) + goto nosideret; + + if (! ada_is_modular_type (type_arg)) + error ("'modulus must be applied to modular type"); + + return value_from_longest (TYPE_TARGET_TYPE (type_arg), + ada_modulus (type_arg)); + } + + + case ATR_POS: + evaluate_subexp (NULL_TYPE, exp, pos, EVAL_SKIP); + arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + if (noside == EVAL_SKIP) + goto nosideret; + else if (noside == EVAL_AVOID_SIDE_EFFECTS) + return value_zero (builtin_type_ada_int, not_lval); + else + return value_pos_atr (arg1); + + case ATR_SIZE: + arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + if (noside == EVAL_SKIP) + goto nosideret; + else if (noside == EVAL_AVOID_SIDE_EFFECTS) + return value_zero (builtin_type_ada_int, not_lval); + else + return value_from_longest (builtin_type_ada_int, + TARGET_CHAR_BIT + * TYPE_LENGTH (VALUE_TYPE (arg1))); + + case ATR_VAL: + evaluate_subexp (NULL_TYPE, exp, pos, EVAL_SKIP); + arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + type = exp->elts[pc + 5].type; + if (noside == EVAL_SKIP) + goto nosideret; + else if (noside == EVAL_AVOID_SIDE_EFFECTS) + return value_zero (type, not_lval); + else + return value_val_atr (type, arg1); + }*/ + case BINOP_EXP: + arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + if (noside == EVAL_SKIP) + goto nosideret; + if (binop_user_defined_p (op, arg1, arg2)) + return unwrap_value (value_x_binop (arg1, arg2, op, OP_NULL, + EVAL_NORMAL)); + else + if (noside == EVAL_AVOID_SIDE_EFFECTS) + return value_zero (VALUE_TYPE (arg1), not_lval); + else + return value_binop (arg1, arg2, op); + + case UNOP_PLUS: + arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + if (noside == EVAL_SKIP) + goto nosideret; + if (unop_user_defined_p (op, arg1)) + return unwrap_value (value_x_unop (arg1, op, EVAL_NORMAL)); + else + return arg1; + + case UNOP_ABS: + arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + if (noside == EVAL_SKIP) + goto nosideret; + if (value_less (arg1, value_zero (VALUE_TYPE (arg1), not_lval))) + return value_neg (arg1); + else + return arg1; + + case UNOP_IND: + if (expect_type && TYPE_CODE (expect_type) == TYPE_CODE_PTR) + expect_type = TYPE_TARGET_TYPE (check_typedef (expect_type)); + arg1 = evaluate_subexp (expect_type, exp, pos, noside); + if (noside == EVAL_SKIP) + goto nosideret; + type = check_typedef (VALUE_TYPE (arg1)); + if (noside == EVAL_AVOID_SIDE_EFFECTS) + { + if (ada_is_array_descriptor (type)) + /* GDB allows dereferencing GNAT array descriptors. */ + { + struct type* arrType = ada_type_of_array (arg1, 0); + if (arrType == NULL) + error ("Attempt to dereference null array pointer."); + return value_at_lazy (arrType, 0, NULL); + } + else if (TYPE_CODE (type) == TYPE_CODE_PTR + || TYPE_CODE (type) == TYPE_CODE_REF + /* In C you can dereference an array to get the 1st elt. */ + || TYPE_CODE (type) == TYPE_CODE_ARRAY + ) + return + value_zero + (to_static_fixed_type + (ada_aligned_type (check_typedef (TYPE_TARGET_TYPE (type)))), + lval_memory); + else if (TYPE_CODE (type) == TYPE_CODE_INT) + /* GDB allows dereferencing an int. */ + return value_zero (builtin_type_int, lval_memory); + else + error ("Attempt to take contents of a non-pointer value."); + } + arg1 = ada_coerce_ref (arg1); + type = check_typedef (VALUE_TYPE (arg1)); + + if (ada_is_array_descriptor (type)) + /* GDB allows dereferencing GNAT array descriptors. */ + return ada_coerce_to_simple_array (arg1); + else + return ada_value_ind (arg1); + + case STRUCTOP_STRUCT: + tem = longest_to_int (exp->elts[pc + 1].longconst); + (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1); + arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + if (noside == EVAL_SKIP) + goto nosideret; + if (noside == EVAL_AVOID_SIDE_EFFECTS) + return value_zero (ada_aligned_type + (ada_lookup_struct_elt_type (VALUE_TYPE (arg1), + &exp->elts[pc + 2].string, + 0, NULL)), + lval_memory); + else + return unwrap_value (ada_value_struct_elt (arg1, + &exp->elts[pc + 2].string, + "record")); + case OP_TYPE: + /* The value is not supposed to be used. This is here to make it + easier to accommodate expressions that contain types. */ + (*pos) += 2; + if (noside == EVAL_SKIP) + goto nosideret; + else if (noside == EVAL_AVOID_SIDE_EFFECTS) + return allocate_value (builtin_type_void); + else + error ("Attempt to use a type name as an expression"); + + case STRUCTOP_PTR: + tem = longest_to_int (exp->elts[pc + 1].longconst); + (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1); + arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + if (noside == EVAL_SKIP) + goto nosideret; + if (noside == EVAL_AVOID_SIDE_EFFECTS) + return value_zero (ada_aligned_type + (ada_lookup_struct_elt_type (VALUE_TYPE (arg1), + &exp->elts[pc + 2].string, + 0, NULL)), + lval_memory); + else + return unwrap_value (ada_value_struct_elt (arg1, + &exp->elts[pc + 2].string, + "record access")); + } + +nosideret: + return value_from_longest (builtin_type_long, (LONGEST) 1); +} + + + /* Fixed point */ + +/* If TYPE encodes an Ada fixed-point type, return the suffix of the + type name that encodes the 'small and 'delta information. + Otherwise, return NULL. */ + +static const char* +fixed_type_info (type) + struct type *type; +{ + const char* name = ada_type_name (type); + enum type_code code = (type == NULL) ? TYPE_CODE_UNDEF : TYPE_CODE (type); + + if ((code == TYPE_CODE_INT || code == TYPE_CODE_RANGE) + && name != NULL) + { + const char *tail = strstr (name, "___XF_"); + if (tail == NULL) + return NULL; + else + return tail + 5; + } + else if (code == TYPE_CODE_RANGE && TYPE_TARGET_TYPE (type) != type) + return fixed_type_info (TYPE_TARGET_TYPE (type)); + else + return NULL; +} + +/* Returns non-zero iff TYPE represents an Ada fixed-point type. */ + +int +ada_is_fixed_point_type (type) + struct type *type; +{ + return fixed_type_info (type) != NULL; +} + +/* Assuming that TYPE is the representation of an Ada fixed-point + type, return its delta, or -1 if the type is malformed and the + delta cannot be determined. */ + +DOUBLEST +ada_delta (type) + struct type *type; +{ + const char *encoding = fixed_type_info (type); + long num, den; + + if (sscanf (encoding, "_%ld_%ld", &num, &den) < 2) + return -1.0; + else + return (DOUBLEST) num / (DOUBLEST) den; +} + +/* Assuming that ada_is_fixed_point_type (TYPE), return the scaling + factor ('SMALL value) associated with the type. */ + +static DOUBLEST +scaling_factor (type) + struct type *type; +{ + const char *encoding = fixed_type_info (type); + unsigned long num0, den0, num1, den1; + int n; + + n = sscanf (encoding, "_%lu_%lu_%lu_%lu", &num0, &den0, &num1, &den1); + + if (n < 2) + return 1.0; + else if (n == 4) + return (DOUBLEST) num1 / (DOUBLEST) den1; + else + return (DOUBLEST) num0 / (DOUBLEST) den0; +} + + +/* Assuming that X is the representation of a value of fixed-point + type TYPE, return its floating-point equivalent. */ + +DOUBLEST +ada_fixed_to_float (type, x) + struct type *type; + LONGEST x; +{ + return (DOUBLEST) x * scaling_factor (type); +} + +/* The representation of a fixed-point value of type TYPE + corresponding to the value X. */ + +LONGEST +ada_float_to_fixed (type, x) + struct type *type; + DOUBLEST x; +{ + return (LONGEST) (x / scaling_factor (type) + 0.5); +} + + + /* VAX floating formats */ + +/* Non-zero iff TYPE represents one of the special VAX floating-point + types. */ +int +ada_is_vax_floating_type (type) + struct type* type; +{ + int name_len = + (ada_type_name (type) == NULL) ? 0 : strlen (ada_type_name (type)); + return + name_len > 6 + && (TYPE_CODE (type) == TYPE_CODE_INT + || TYPE_CODE (type) == TYPE_CODE_RANGE) + && STREQN (ada_type_name (type) + name_len - 6, "___XF", 5); +} + +/* The type of special VAX floating-point type this is, assuming + ada_is_vax_floating_point */ +int +ada_vax_float_type_suffix (type) + struct type* type; +{ + return ada_type_name (type)[strlen (ada_type_name (type))-1]; +} + +/* A value representing the special debugging function that outputs + VAX floating-point values of the type represented by TYPE. Assumes + ada_is_vax_floating_type (TYPE). */ +struct value* +ada_vax_float_print_function (type) + + struct type* type; +{ + switch (ada_vax_float_type_suffix (type)) { + case 'F': + return + get_var_value ("DEBUG_STRING_F", 0); + case 'D': + return + get_var_value ("DEBUG_STRING_D", 0); + case 'G': + return + get_var_value ("DEBUG_STRING_G", 0); + default: + error ("invalid VAX floating-point type"); + } +} + + + /* Range types */ + +/* Scan STR beginning at position K for a discriminant name, and + return the value of that discriminant field of DVAL in *PX. If + PNEW_K is not null, put the position of the character beyond the + name scanned in *PNEW_K. Return 1 if successful; return 0 and do + not alter *PX and *PNEW_K if unsuccessful. */ + +static int +scan_discrim_bound (str, k, dval, px, pnew_k) + char *str; + int k; + struct value* dval; + LONGEST *px; + int *pnew_k; +{ + static char *bound_buffer = NULL; + static size_t bound_buffer_len = 0; + char *bound; + char *pend; + struct value* bound_val; + + if (dval == NULL || str == NULL || str[k] == '\0') + return 0; + + pend = strstr (str+k, "__"); + if (pend == NULL) + { + bound = str+k; + k += strlen (bound); + } + else + { + GROW_VECT (bound_buffer, bound_buffer_len, pend - (str+k) + 1); + bound = bound_buffer; + strncpy (bound_buffer, str+k, pend-(str+k)); + bound[pend-(str+k)] = '\0'; + k = pend-str; + } + + bound_val = + ada_search_struct_field (bound, dval, 0, VALUE_TYPE (dval)); + if (bound_val == NULL) + return 0; + + *px = value_as_long (bound_val); + if (pnew_k != NULL) + *pnew_k = k; + return 1; +} + +/* Value of variable named NAME in the current environment. If + no such variable found, then if ERR_MSG is null, returns 0, and + otherwise causes an error with message ERR_MSG. */ +static struct value* +get_var_value (name, err_msg) + char* name; + char* err_msg; +{ + struct symbol** syms; + struct block** blocks; + int nsyms; + + nsyms = ada_lookup_symbol_list (name, get_selected_block (NULL), VAR_NAMESPACE, + &syms, &blocks); + + if (nsyms != 1) + { + if (err_msg == NULL) + return 0; + else + error ("%s", err_msg); + } + + return value_of_variable (syms[0], blocks[0]); +} + +/* Value of integer variable named NAME in the current environment. If + no such variable found, then if ERR_MSG is null, returns 0, and sets + *FLAG to 0. If successful, sets *FLAG to 1. */ +LONGEST +get_int_var_value (name, err_msg, flag) + char* name; + char* err_msg; + int* flag; +{ + struct value* var_val = get_var_value (name, err_msg); + + if (var_val == 0) + { + if (flag != NULL) + *flag = 0; + return 0; + } + else + { + if (flag != NULL) + *flag = 1; + return value_as_long (var_val); + } +} + + +/* Return a range type whose base type is that of the range type named + NAME in the current environment, and whose bounds are calculated + from NAME according to the GNAT range encoding conventions. + Extract discriminant values, if needed, from DVAL. If a new type + must be created, allocate in OBJFILE's space. The bounds + information, in general, is encoded in NAME, the base type given in + the named range type. */ + +static struct type* +to_fixed_range_type (name, dval, objfile) + char *name; + struct value *dval; + struct objfile *objfile; +{ + struct type *raw_type = ada_find_any_type (name); + struct type *base_type; + LONGEST low, high; + char* subtype_info; + + if (raw_type == NULL) + base_type = builtin_type_int; + else if (TYPE_CODE (raw_type) == TYPE_CODE_RANGE) + base_type = TYPE_TARGET_TYPE (raw_type); + else + base_type = raw_type; + + subtype_info = strstr (name, "___XD"); + if (subtype_info == NULL) + return raw_type; + else + { + static char *name_buf = NULL; + static size_t name_len = 0; + int prefix_len = subtype_info - name; + LONGEST L, U; + struct type *type; + char *bounds_str; + int n; + + GROW_VECT (name_buf, name_len, prefix_len + 5); + strncpy (name_buf, name, prefix_len); + name_buf[prefix_len] = '\0'; + + subtype_info += 5; + bounds_str = strchr (subtype_info, '_'); + n = 1; + + if (*subtype_info == 'L') + { + if (! ada_scan_number (bounds_str, n, &L, &n) + && ! scan_discrim_bound (bounds_str, n, dval, &L, &n)) + return raw_type; + if (bounds_str[n] == '_') + n += 2; + else if (bounds_str[n] == '.') /* FIXME? SGI Workshop kludge. */ + n += 1; + subtype_info += 1; + } + else + { + strcpy (name_buf+prefix_len, "___L"); + L = get_int_var_value (name_buf, "Index bound unknown.", NULL); + } + + if (*subtype_info == 'U') + { + if (! ada_scan_number (bounds_str, n, &U, &n) + && !scan_discrim_bound (bounds_str, n, dval, &U, &n)) + return raw_type; + } + else + { + strcpy (name_buf+prefix_len, "___U"); + U = get_int_var_value (name_buf, "Index bound unknown.", NULL); + } + + if (objfile == NULL) + objfile = TYPE_OBJFILE (base_type); + type = create_range_type (alloc_type (objfile), base_type, L, U); + TYPE_NAME (type) = name; + return type; + } +} + +/* True iff NAME is the name of a range type. */ +int +ada_is_range_type_name (name) + const char* name; +{ + return (name != NULL && strstr (name, "___XD")); +} + + + /* Modular types */ + +/* True iff TYPE is an Ada modular type. */ +int +ada_is_modular_type (type) + struct type* type; +{ + /* FIXME: base_type should be declared in gdbtypes.h, implemented in + valarith.c */ + struct type* subranged_type; /* = base_type (type);*/ + + return (subranged_type != NULL && TYPE_CODE (type) == TYPE_CODE_RANGE + && TYPE_CODE (subranged_type) != TYPE_CODE_ENUM + && TYPE_UNSIGNED (subranged_type)); +} + +/* Assuming ada_is_modular_type (TYPE), the modulus of TYPE. */ +LONGEST +ada_modulus (type) + struct type* type; +{ + return TYPE_HIGH_BOUND (type) + 1; +} + + + + /* Operators */ + +/* Table mapping opcodes into strings for printing operators + and precedences of the operators. */ + +static const struct op_print ada_op_print_tab[] = + { + {":=", BINOP_ASSIGN, PREC_ASSIGN, 1}, + {"or else", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0}, + {"and then", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0}, + {"or", BINOP_BITWISE_IOR, PREC_BITWISE_IOR, 0}, + {"xor", BINOP_BITWISE_XOR, PREC_BITWISE_XOR, 0}, + {"and", BINOP_BITWISE_AND, PREC_BITWISE_AND, 0}, + {"=", BINOP_EQUAL, PREC_EQUAL, 0}, + {"/=", BINOP_NOTEQUAL, PREC_EQUAL, 0}, + {"<=", BINOP_LEQ, PREC_ORDER, 0}, + {">=", BINOP_GEQ, PREC_ORDER, 0}, + {">", BINOP_GTR, PREC_ORDER, 0}, + {"<", BINOP_LESS, PREC_ORDER, 0}, + {">>", BINOP_RSH, PREC_SHIFT, 0}, + {"<<", BINOP_LSH, PREC_SHIFT, 0}, + {"+", BINOP_ADD, PREC_ADD, 0}, + {"-", BINOP_SUB, PREC_ADD, 0}, + {"&", BINOP_CONCAT, PREC_ADD, 0}, + {"*", BINOP_MUL, PREC_MUL, 0}, + {"/", BINOP_DIV, PREC_MUL, 0}, + {"rem", BINOP_REM, PREC_MUL, 0}, + {"mod", BINOP_MOD, PREC_MUL, 0}, + {"**", BINOP_EXP, PREC_REPEAT, 0 }, + {"@", BINOP_REPEAT, PREC_REPEAT, 0}, + {"-", UNOP_NEG, PREC_PREFIX, 0}, + {"+", UNOP_PLUS, PREC_PREFIX, 0}, + {"not ", UNOP_LOGICAL_NOT, PREC_PREFIX, 0}, + {"not ", UNOP_COMPLEMENT, PREC_PREFIX, 0}, + {"abs ", UNOP_ABS, PREC_PREFIX, 0}, + {".all", UNOP_IND, PREC_SUFFIX, 1}, /* FIXME: postfix .ALL */ + {"'access", UNOP_ADDR, PREC_SUFFIX, 1}, /* FIXME: postfix 'ACCESS */ + {NULL, 0, 0, 0} +}; + + /* Assorted Types and Interfaces */ + +struct type* builtin_type_ada_int; +struct type* builtin_type_ada_short; +struct type* builtin_type_ada_long; +struct type* builtin_type_ada_long_long; +struct type* builtin_type_ada_char; +struct type* builtin_type_ada_float; +struct type* builtin_type_ada_double; +struct type* builtin_type_ada_long_double; +struct type* builtin_type_ada_natural; +struct type* builtin_type_ada_positive; +struct type* builtin_type_ada_system_address; + +struct type ** const (ada_builtin_types[]) = +{ + + &builtin_type_ada_int, + &builtin_type_ada_long, + &builtin_type_ada_short, + &builtin_type_ada_char, + &builtin_type_ada_float, + &builtin_type_ada_double, + &builtin_type_ada_long_long, + &builtin_type_ada_long_double, + &builtin_type_ada_natural, + &builtin_type_ada_positive, + + /* The following types are carried over from C for convenience. */ + &builtin_type_int, + &builtin_type_long, + &builtin_type_short, + &builtin_type_char, + &builtin_type_float, + &builtin_type_double, + &builtin_type_long_long, + &builtin_type_void, + &builtin_type_signed_char, + &builtin_type_unsigned_char, + &builtin_type_unsigned_short, + &builtin_type_unsigned_int, + &builtin_type_unsigned_long, + &builtin_type_unsigned_long_long, + &builtin_type_long_double, + &builtin_type_complex, + &builtin_type_double_complex, + 0 +}; + +/* Not really used, but needed in the ada_language_defn. */ +static void emit_char (int c, struct ui_file* stream, int quoter) +{ + ada_emit_char (c, stream, quoter, 1); +} + +const struct language_defn ada_language_defn = { + "ada", /* Language name */ + /* language_ada, */ + language_unknown, + /* FIXME: language_ada should be defined in defs.h */ + ada_builtin_types, + range_check_off, + type_check_off, + case_sensitive_on, /* Yes, Ada is case-insensitive, but + * that's not quite what this means. */ + ada_parse, + ada_error, + ada_evaluate_subexp, + ada_printchar, /* Print a character constant */ + ada_printstr, /* Function to print string constant */ + emit_char, /* Function to print single char (not used) */ + ada_create_fundamental_type, /* Create fundamental type in this language */ + ada_print_type, /* Print a type using appropriate syntax */ + ada_val_print, /* Print a value using appropriate syntax */ + ada_value_print, /* Print a top-level value */ + {"", "", "", ""}, /* Binary format info */ +#if 0 + {"8#%lo#", "8#", "o", "#"}, /* Octal format info */ + {"%ld", "", "d", ""}, /* Decimal format info */ + {"16#%lx#", "16#", "x", "#"}, /* Hex format info */ +#else + /* Copied from c-lang.c. */ + {"0%lo", "0", "o", ""}, /* Octal format info */ + {"%ld", "", "d", ""}, /* Decimal format info */ + {"0x%lx", "0x", "x", ""}, /* Hex format info */ +#endif + ada_op_print_tab, /* expression operators for printing */ + 1, /* c-style arrays (FIXME?) */ + 0, /* String lower bound (FIXME?) */ + &builtin_type_ada_char, + LANG_MAGIC +}; + +void +_initialize_ada_language () +{ + builtin_type_ada_int = + init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT, + 0, + "integer", (struct objfile *) NULL); + builtin_type_ada_long = + init_type (TYPE_CODE_INT, TARGET_LONG_BIT / TARGET_CHAR_BIT, + 0, + "long_integer", (struct objfile *) NULL); + builtin_type_ada_short = + init_type (TYPE_CODE_INT, TARGET_SHORT_BIT / TARGET_CHAR_BIT, + 0, + "short_integer", (struct objfile *) NULL); + builtin_type_ada_char = + init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT, + 0, + "character", (struct objfile *) NULL); + builtin_type_ada_float = + init_type (TYPE_CODE_FLT, TARGET_FLOAT_BIT / TARGET_CHAR_BIT, + 0, + "float", (struct objfile *) NULL); + builtin_type_ada_double = + init_type (TYPE_CODE_FLT, TARGET_DOUBLE_BIT / TARGET_CHAR_BIT, + 0, + "long_float", (struct objfile *) NULL); + builtin_type_ada_long_long = + init_type (TYPE_CODE_INT, TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT, + 0, + "long_long_integer", (struct objfile *) NULL); + builtin_type_ada_long_double = + init_type (TYPE_CODE_FLT, TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT, + 0, + "long_long_float", (struct objfile *) NULL); + builtin_type_ada_natural = + init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT, + 0, + "natural", (struct objfile *) NULL); + builtin_type_ada_positive = + init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT, + 0, + "positive", (struct objfile *) NULL); + + + builtin_type_ada_system_address = + lookup_pointer_type (init_type (TYPE_CODE_VOID, 1, 0, "void", + (struct objfile *) NULL)); + TYPE_NAME (builtin_type_ada_system_address) = "system__address"; + + add_language (&ada_language_defn); + + add_show_from_set + (add_set_cmd ("varsize-limit", class_support, var_uinteger, + (char*) &varsize_limit, + "Set maximum bytes in dynamic-sized object.", + &setlist), + &showlist); + varsize_limit = 65536; + + add_com ("begin", class_breakpoint, begin_command, + "Start the debugged program, stopping at the beginning of the\n\ +main program. You may specify command-line arguments to give it, as for\n\ +the \"run\" command (q.v.)."); +} + + +/* Create a fundamental Ada type using default reasonable for the current + target machine. + + Some object/debugging file formats (DWARF version 1, COFF, etc) do not + define fundamental types such as "int" or "double". Others (stabs or + DWARF version 2, etc) do define fundamental types. For the formats which + don't provide fundamental types, gdb can create such types using this + function. + + FIXME: Some compilers distinguish explicitly signed integral types + (signed short, signed int, signed long) from "regular" integral types + (short, int, long) in the debugging information. There is some dis- + agreement as to how useful this feature is. In particular, gcc does + not support this. Also, only some debugging formats allow the + distinction to be passed on to a debugger. For now, we always just + use "short", "int", or "long" as the type name, for both the implicit + and explicitly signed types. This also makes life easier for the + gdb test suite since we don't have to account for the differences + in output depending upon what the compiler and debugging format + support. We will probably have to re-examine the issue when gdb + starts taking it's fundamental type information directly from the + debugging information supplied by the compiler. fnf@cygnus.com */ + +static struct type * +ada_create_fundamental_type (objfile, typeid) + struct objfile *objfile; + int typeid; +{ + struct type *type = NULL; + + switch (typeid) + { + default: + /* FIXME: For now, if we are asked to produce a type not in this + language, create the equivalent of a C integer type with the + name "". When all the dust settles from the type + reconstruction work, this should probably become an error. */ + type = init_type (TYPE_CODE_INT, + TARGET_INT_BIT / TARGET_CHAR_BIT, + 0, "", objfile); + warning ("internal error: no Ada fundamental type %d", typeid); + break; + case FT_VOID: + type = init_type (TYPE_CODE_VOID, + TARGET_CHAR_BIT / TARGET_CHAR_BIT, + 0, "void", objfile); + break; + case FT_CHAR: + type = init_type (TYPE_CODE_INT, + TARGET_CHAR_BIT / TARGET_CHAR_BIT, + 0, "character", objfile); + break; + case FT_SIGNED_CHAR: + type = init_type (TYPE_CODE_INT, + TARGET_CHAR_BIT / TARGET_CHAR_BIT, + 0, "signed char", objfile); + break; + case FT_UNSIGNED_CHAR: + type = init_type (TYPE_CODE_INT, + TARGET_CHAR_BIT / TARGET_CHAR_BIT, + TYPE_FLAG_UNSIGNED, "unsigned char", objfile); + break; + case FT_SHORT: + type = init_type (TYPE_CODE_INT, + TARGET_SHORT_BIT / TARGET_CHAR_BIT, + 0, "short_integer", objfile); + break; + case FT_SIGNED_SHORT: + type = init_type (TYPE_CODE_INT, + TARGET_SHORT_BIT / TARGET_CHAR_BIT, + 0, "short_integer", objfile); + break; + case FT_UNSIGNED_SHORT: + type = init_type (TYPE_CODE_INT, + TARGET_SHORT_BIT / TARGET_CHAR_BIT, + TYPE_FLAG_UNSIGNED, "unsigned short", objfile); + break; + case FT_INTEGER: + type = init_type (TYPE_CODE_INT, + TARGET_INT_BIT / TARGET_CHAR_BIT, + 0, "integer", objfile); + break; + case FT_SIGNED_INTEGER: + type = init_type (TYPE_CODE_INT, + TARGET_INT_BIT / TARGET_CHAR_BIT, + 0, "integer", objfile); /* FIXME -fnf */ + break; + case FT_UNSIGNED_INTEGER: + type = init_type (TYPE_CODE_INT, + TARGET_INT_BIT / TARGET_CHAR_BIT, + TYPE_FLAG_UNSIGNED, "unsigned int", objfile); + break; + case FT_LONG: + type = init_type (TYPE_CODE_INT, + TARGET_LONG_BIT / TARGET_CHAR_BIT, + 0, "long_integer", objfile); + break; + case FT_SIGNED_LONG: + type = init_type (TYPE_CODE_INT, + TARGET_LONG_BIT / TARGET_CHAR_BIT, + 0, "long_integer", objfile); + break; + case FT_UNSIGNED_LONG: + type = init_type (TYPE_CODE_INT, + TARGET_LONG_BIT / TARGET_CHAR_BIT, + TYPE_FLAG_UNSIGNED, "unsigned long", objfile); + break; + case FT_LONG_LONG: + type = init_type (TYPE_CODE_INT, + TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT, + 0, "long_long_integer", objfile); + break; + case FT_SIGNED_LONG_LONG: + type = init_type (TYPE_CODE_INT, + TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT, + 0, "long_long_integer", objfile); + break; + case FT_UNSIGNED_LONG_LONG: + type = init_type (TYPE_CODE_INT, + TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT, + TYPE_FLAG_UNSIGNED, "unsigned long long", objfile); + break; + case FT_FLOAT: + type = init_type (TYPE_CODE_FLT, + TARGET_FLOAT_BIT / TARGET_CHAR_BIT, + 0, "float", objfile); + break; + case FT_DBL_PREC_FLOAT: + type = init_type (TYPE_CODE_FLT, + TARGET_DOUBLE_BIT / TARGET_CHAR_BIT, + 0, "long_float", objfile); + break; + case FT_EXT_PREC_FLOAT: + type = init_type (TYPE_CODE_FLT, + TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT, + 0, "long_long_float", objfile); + break; + } + return (type); +} + +void ada_dump_symtab (struct symtab* s) +{ + int i; + fprintf (stderr, "New symtab: [\n"); + fprintf (stderr, " Name: %s/%s;\n", + s->dirname ? s->dirname : "?", + s->filename ? s->filename : "?"); + fprintf (stderr, " Format: %s;\n", s->debugformat); + if (s->linetable != NULL) + { + fprintf (stderr, " Line table (section %d):\n", s->block_line_section); + for (i = 0; i < s->linetable->nitems; i += 1) + { + struct linetable_entry* e = s->linetable->item + i; + fprintf (stderr, " %4ld: %8lx\n", (long) e->line, (long) e->pc); + } + } + fprintf (stderr, "]\n"); +} + diff --git a/gdb/config/sparc/nbsd.mt b/gdb/config/sparc/nbsd.mt new file mode 100644 index 0000000..b04dd42 --- /dev/null +++ b/gdb/config/sparc/nbsd.mt @@ -0,0 +1,4 @@ +# Target: SPARC running NetBSD +TDEPFILES= sparc-tdep.o sparcnbsd-tdep.o nbsd-tdep.o corelow.o solib.o \ + solib-svr4.o +TM_FILE= tm-nbsd.h diff --git a/gdb/i386-sol2-tdep.c b/gdb/i386-sol2-tdep.c new file mode 100644 index 0000000..206e85c --- /dev/null +++ b/gdb/i386-sol2-tdep.c @@ -0,0 +1,74 @@ +/* Target-dependent code for Solaris x86. + Copyright 2002 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 "i386-tdep.h" + +static int +i386_sol2_pc_in_sigtramp (CORE_ADDR pc, char *name) +{ + /* Signal handler frames under Solaris 2 are recognized by a return + address of 0xffffffff. */ + return (pc == 0xffffffff); +} + +/* Solaris 2. */ + +static void +i386_sol2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + /* Solaris is SVR4-based. */ + i386_svr4_init_abi (info, gdbarch); + + /* Signal trampolines are different from SVR4, in fact they're + rather similar to BSD. */ + set_gdbarch_pc_in_sigtramp (gdbarch, i386_sol2_pc_in_sigtramp); + tdep->sigtramp_saved_pc = i386bsd_sigtramp_saved_pc; + tdep->sc_pc_offset = 36 + 14 * 4; +} + + +static enum gdb_osabi +i386_sol2_osabi_sniffer (bfd *abfd) +{ + /* If we have a section named .SUNW_version, then it is almost + certainly Solaris 2. */ + if (bfd_get_section_by_name (abfd, ".SUNW_version")) + return GDB_OSABI_SOLARIS; + + return GDB_OSABI_UNKNOWN; +} + +/* Provide a prototype to silence -Wmissing-prototypes. */ +void _initialize_i386_sol2_tdep (void); + +void +_initialize_i386_sol2_tdep (void) +{ + /* Register and ELF OS ABI sniffer for Solaris 2 binaries. */ + gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_elf_flavour, + i386_sol2_osabi_sniffer); + + gdbarch_register_osabi (bfd_arch_i386, GDB_OSABI_SOLARIS, + i386_sol2_init_abi); +} diff --git a/include/elf/frv.h b/include/elf/frv.h new file mode 100644 index 0000000..65ce97d --- /dev/null +++ b/include/elf/frv.h @@ -0,0 +1,95 @@ +/* FRV ELF support for BFD. + Copyright (C) 2002 Free Software Foundation, Inc. + +This file is part of BFD, the Binary File Descriptor library. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software Foundation, Inc., +59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef _ELF_FRV_H +#define _ELF_FRV_H + +#include "elf/reloc-macros.h" + +/* Relocations. */ +START_RELOC_NUMBERS (elf_frv_reloc_type) + RELOC_NUMBER (R_FRV_NONE, 0) + RELOC_NUMBER (R_FRV_32, 1) + RELOC_NUMBER (R_FRV_LABEL16, 2) + RELOC_NUMBER (R_FRV_LABEL24, 3) + RELOC_NUMBER (R_FRV_LO16, 4) + RELOC_NUMBER (R_FRV_HI16, 5) + RELOC_NUMBER (R_FRV_GPREL12, 6) + RELOC_NUMBER (R_FRV_GPRELU12, 7) + RELOC_NUMBER (R_FRV_GPREL32, 8) + RELOC_NUMBER (R_FRV_GPRELHI, 9) + RELOC_NUMBER (R_FRV_GPRELLO, 10) + RELOC_NUMBER (R_FRV_GNU_VTINHERIT, 200) + RELOC_NUMBER (R_FRV_GNU_VTENTRY, 201) +END_RELOC_NUMBERS(R_FRV_max) + +/* Processor specific flags for the ELF header e_flags field. */ + /* gpr support */ +#define EF_FRV_GPR_MASK 0x00000003 /* mask for # of gprs */ +#define EF_FRV_GPR_32 0x00000001 /* -mgpr-32 */ +#define EF_FRV_GPR_64 0x00000002 /* -mgpr-64 */ + + /* fpr support */ +#define EF_FRV_FPR_MASK 0x0000000c /* mask for # of fprs */ +#define EF_FRV_FPR_32 0x00000004 /* -mfpr-32 */ +#define EF_FRV_FPR_64 0x00000008 /* -mfpr-64 */ +#define EF_FRV_FPR_NONE 0x0000000c /* -msoft-float */ + + /* double word support */ +#define EF_FRV_DWORD_MASK 0x00000030 /* mask for dword support */ +#define EF_FRV_DWORD_YES 0x00000010 /* use double word insns */ +#define EF_FRV_DWORD_NO 0x00000020 /* don't use double word insn*/ + +#define EF_FRV_DOUBLE 0x00000040 /* -mdouble */ +#define EF_FRV_MEDIA 0x00000080 /* -mmedia */ + +#define EF_FRV_PIC 0x00000100 /* -fpic */ +#define EF_FRV_NON_PIC_RELOCS 0x00000200 /* used non pic safe relocs */ + +#define EF_FRV_MULADD 0x00000400 /* -mmuladd */ +#define EF_FRV_BIGPIC 0x00000800 /* -fPIC */ +#define EF_FRV_LIBPIC 0x00001000 /* -mlibrary-pic */ +#define EF_FRV_G0 0x00002000 /* -G 0, no small data ptr */ +#define EF_FRV_NOPACK 0x00004000 /* -mnopack */ + +#define EF_FRV_CPU_MASK 0xff000000 /* specific cpu bits */ +#define EF_FRV_CPU_GENERIC 0x00000000 /* generic FRV */ +#define EF_FRV_CPU_FR500 0x01000000 /* FRV500 */ +#define EF_FRV_CPU_FR300 0x02000000 /* FRV300 */ +#define EF_FRV_CPU_SIMPLE 0x03000000 /* SIMPLE */ +#define EF_FRV_CPU_TOMCAT 0x04000000 /* Tomcat, FR500 prototype */ +#define EF_FRV_CPU_FR400 0x05000000 /* FRV400 */ + + /* Mask of PIC related bits */ +#define EF_FRV_PIC_FLAGS (EF_FRV_PIC | EF_FRV_LIBPIC | EF_FRV_BIGPIC) + + /* Mask of all flags */ +#define EF_FRV_ALL_FLAGS (EF_FRV_GPR_MASK | \ + EF_FRV_FPR_MASK | \ + EF_FRV_DWORD_MASK | \ + EF_FRV_DOUBLE | \ + EF_FRV_MEDIA | \ + EF_FRV_PIC_FLAGS | \ + EF_FRV_NON_PIC_RELOCS | \ + EF_FRV_MULADD | \ + EF_FRV_G0 | \ + EF_FRV_NOPACK | \ + EF_FRV_CPU_MASK) + +#endif /* _ELF_FRV_H */ diff --git a/include/gdb/sim-arm.h b/include/gdb/sim-arm.h new file mode 100644 index 0000000..6d80700 --- /dev/null +++ b/include/gdb/sim-arm.h @@ -0,0 +1,65 @@ +/* This file defines the interface between the Arm simulator and GDB. + + Copyright 2002 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_ARM_H) +#define SIM_ARM_H + +#ifdef __cplusplus +extern "C" { // } +#endif + +enum sim_arm_regs +{ + SIM_ARM_R0_REGNUM, + SIM_ARM_R1_REGNUM, + SIM_ARM_R2_REGNUM, + SIM_ARM_R3_REGNUM, + SIM_ARM_R4_REGNUM, + SIM_ARM_R5_REGNUM, + SIM_ARM_R6_REGNUM, + SIM_ARM_R7_REGNUM, + SIM_ARM_R8_REGNUM, + SIM_ARM_R9_REGNUM, + SIM_ARM_R10_REGNUM, + SIM_ARM_R11_REGNUM, + SIM_ARM_R12_REGNUM, + SIM_ARM_R13_REGNUM, + SIM_ARM_R14_REGNUM, + SIM_ARM_R15_REGNUM, /* PC */ + SIM_ARM_FP0_REGNUM, + SIM_ARM_FP1_REGNUM, + SIM_ARM_FP2_REGNUM, + SIM_ARM_FP3_REGNUM, + SIM_ARM_FP4_REGNUM, + SIM_ARM_FP5_REGNUM, + SIM_ARM_FP6_REGNUM, + SIM_ARM_FP7_REGNUM, + SIM_ARM_FPS_REGNUM, + SIM_ARM_PS_REGNUM +}; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/opcodes/frv-asm.c b/opcodes/frv-asm.c new file mode 100644 index 0000000..538ed2d --- /dev/null +++ b/opcodes/frv-asm.c @@ -0,0 +1,1023 @@ +/* Assembler interface for targets using CGEN. -*- C -*- + CGEN: Cpu tools GENerator + +THIS FILE IS MACHINE GENERATED WITH CGEN. +- the resultant file is machine generated, cgen-asm.in isn't + +Copyright 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + +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. */ + +/* ??? Eventually more and more of this stuff can go to cpu-independent files. + Keep that in mind. */ + +#include "sysdep.h" +#include +#include "ansidecl.h" +#include "bfd.h" +#include "symcat.h" +#include "frv-desc.h" +#include "frv-opc.h" +#include "opintl.h" +#include "xregex.h" +#include "libiberty.h" +#include "safe-ctype.h" + +#undef min +#define min(a,b) ((a) < (b) ? (a) : (b)) +#undef max +#define max(a,b) ((a) > (b) ? (a) : (b)) + +static const char * parse_insn_normal + PARAMS ((CGEN_CPU_DESC, const CGEN_INSN *, const char **, CGEN_FIELDS *)); + +/* -- assembler routines inserted here. */ + +/* -- asm.c */ +static const char * parse_ulo16 + PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *)); +static const char * parse_uslo16 + PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *)); +static const char * parse_uhi16 + PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *)); +static long parse_register_number + PARAMS ((const char **)); +static const char * parse_spr + PARAMS ((CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *)); +static const char * parse_d12 + PARAMS ((CGEN_CPU_DESC, const char **, int, long *)); +static const char * parse_s12 + PARAMS ((CGEN_CPU_DESC, const char **, int, long *)); +static const char * parse_u12 + PARAMS ((CGEN_CPU_DESC, const char **, int, long *)); + +static const char * +parse_ulo16 (cd, strp, opindex, valuep) + CGEN_CPU_DESC cd; + const char **strp; + int opindex; + unsigned long *valuep; +{ + const char *errmsg; + enum cgen_parse_operand_result result_type; + bfd_vma value; + + if (**strp == '#' || **strp == '%') + { + if (strncasecmp (*strp + 1, "lo(", 3) == 0) + { + *strp += 4; + errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_LO16, + &result_type, &value); + if (**strp != ')') + return "missing `)'"; + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + value &= 0xffff; + *valuep = value; + return errmsg; + } + if (strncasecmp (*strp + 1, "gprello(", 8) == 0) + { + *strp += 9; + errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPRELLO, + &result_type, &value); + if (**strp != ')') + return "missing ')'"; + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + value >>= 16; + *valuep = value; + return errmsg; + } + } + return cgen_parse_signed_integer (cd, strp, opindex, valuep); +} + +static const char * +parse_uslo16 (cd, strp, opindex, valuep) + CGEN_CPU_DESC cd; + const char **strp; + int opindex; + unsigned long *valuep; +{ + const char *errmsg; + enum cgen_parse_operand_result result_type; + bfd_vma value; + + if (**strp == '#' || **strp == '%') + { + if (strncasecmp (*strp + 1, "lo(", 3) == 0) + { + *strp += 4; + errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_LO16, + &result_type, &value); + if (**strp != ')') + return "missing `)'"; + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + value &= 0xffff; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp + 1, "gprello(", 8) == 0) + { + *strp += 9; + errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPRELLO, + &result_type, &value); + if (**strp != ')') + return "missing ')'"; + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + value &= 0xffff; + *valuep = value; + return errmsg; + } + } + return cgen_parse_unsigned_integer (cd, strp, opindex, valuep); +} + +static const char * +parse_uhi16 (cd, strp, opindex, valuep) + CGEN_CPU_DESC cd; + const char **strp; + int opindex; + unsigned long *valuep; +{ + const char *errmsg; + enum cgen_parse_operand_result result_type; + bfd_vma value; + + if (**strp == '#' || **strp == '%') + { + if (strncasecmp (*strp + 1, "hi(", 3) == 0) + { + *strp += 4; + errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_HI16, + &result_type, &value); + if (**strp != ')') + return "missing `)'"; + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + value >>= 16; + *valuep = value; + return errmsg; + } + else if (strncasecmp (*strp + 1, "gprelhi(", 8) == 0) + { + *strp += 9; + errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPRELHI, + &result_type, &value); + if (**strp != ')') + return "missing ')'"; + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + value >>= 16; + *valuep = value; + return errmsg; + } + } + return cgen_parse_unsigned_integer (cd, strp, opindex, valuep); +} + +static long +parse_register_number (strp) + const char **strp; +{ + int regno; + if (**strp < '0' || **strp > '9') + return -1; /* error */ + + regno = **strp - '0'; + for (++*strp; **strp >= '0' && **strp <= '9'; ++*strp) + regno = regno * 10 + (**strp - '0'); + + return regno; +} + +static const char * +parse_spr (cd, strp, table, valuep) + CGEN_CPU_DESC cd; + const char **strp; + CGEN_KEYWORD * table; + long *valuep; +{ + const char *save_strp; + long regno; + + /* Check for spr index notation. */ + if (strncasecmp (*strp, "spr[", 4) == 0) + { + *strp += 4; + regno = parse_register_number (strp); + if (**strp != ']') + return "missing `]'"; + ++*strp; + if (! spr_valid (regno)) + return "Special purpose register number is out of range"; + *valuep = regno; + return NULL; + } + + save_strp = *strp; + regno = parse_register_number (strp); + if (regno != -1) + { + if (! spr_valid (regno)) + return "Special purpose register number is out of range"; + *valuep = regno; + return NULL; + } + + *strp = save_strp; + return cgen_parse_keyword (cd, strp, table, valuep); +} + +static const char * +parse_d12 (cd, strp, opindex, valuep) + CGEN_CPU_DESC cd; + const char **strp; + int opindex; + long *valuep; +{ + const char *errmsg; + enum cgen_parse_operand_result result_type; + bfd_vma value; + + /* Check for small data reference. */ + if (**strp == '#' || **strp == '%') + { + if (strncasecmp (*strp + 1, "gprel12(", 8) == 0) + { + *strp += 9; + errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPREL12, + &result_type, &value); + if (**strp != ')') + return "missing `)'"; + ++*strp; + *valuep = value; + return errmsg; + } + } + return cgen_parse_signed_integer (cd, strp, opindex, valuep); +} + +static const char * +parse_s12 (cd, strp, opindex, valuep) + CGEN_CPU_DESC cd; + const char **strp; + int opindex; + long *valuep; +{ + const char *errmsg; + enum cgen_parse_operand_result result_type; + bfd_vma value; + + /* Check for small data reference. */ + if ((**strp == '#' || **strp == '%') + && strncasecmp (*strp + 1, "gprel12(", 8) == 0) + { + *strp += 9; + errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPREL12, + &result_type, &value); + if (**strp != ')') + return "missing `)'"; + ++*strp; + *valuep = value; + return errmsg; + } + else + { + if (**strp == '#') + ++*strp; + return cgen_parse_signed_integer (cd, strp, opindex, valuep); + } +} + +static const char * +parse_u12 (cd, strp, opindex, valuep) + CGEN_CPU_DESC cd; + const char **strp; + int opindex; + long *valuep; +{ + const char *errmsg; + enum cgen_parse_operand_result result_type; + bfd_vma value; + + /* Check for small data reference. */ + if ((**strp == '#' || **strp == '%') + && strncasecmp (*strp + 1, "gprel12(", 8) == 0) + { + *strp += 9; + errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPRELU12, + &result_type, &value); + if (**strp != ')') + return "missing `)'"; + ++*strp; + *valuep = value; + return errmsg; + } + else + { + if (**strp == '#') + ++*strp; + return cgen_parse_signed_integer (cd, strp, opindex, valuep); + } +} + +/* -- */ + +const char * frv_cgen_parse_operand + PARAMS ((CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *)); + +/* Main entry point for operand parsing. + + This function is basically just a big switch statement. Earlier versions + used tables to look up the function to use, but + - if the table contains both assembler and disassembler functions then + the disassembler contains much of the assembler and vice-versa, + - there's a lot of inlining possibilities as things grow, + - using a switch statement avoids the function call overhead. + + This function could be moved into `parse_insn_normal', but keeping it + separate makes clear the interface between `parse_insn_normal' and each of + the handlers. */ + +const char * +frv_cgen_parse_operand (cd, opindex, strp, fields) + CGEN_CPU_DESC cd; + int opindex; + const char ** strp; + CGEN_FIELDS * fields; +{ + const char * errmsg = NULL; + /* Used by scalar operands that still need to be parsed. */ + long junk ATTRIBUTE_UNUSED; + + switch (opindex) + { + case FRV_OPERAND_A : + errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_A, &fields->f_A); + break; + case FRV_OPERAND_ACC40SI : + errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Si); + break; + case FRV_OPERAND_ACC40SK : + errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Sk); + break; + case FRV_OPERAND_ACC40UI : + errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Ui); + break; + case FRV_OPERAND_ACC40UK : + errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Uk); + break; + case FRV_OPERAND_ACCGI : + errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_accg_names, & fields->f_ACCGi); + break; + case FRV_OPERAND_ACCGK : + errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_accg_names, & fields->f_ACCGk); + break; + case FRV_OPERAND_CCI : + errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CCi); + break; + case FRV_OPERAND_CPRDOUBLEK : + errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRk); + break; + case FRV_OPERAND_CPRI : + errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRi); + break; + case FRV_OPERAND_CPRJ : + errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRj); + break; + case FRV_OPERAND_CPRK : + errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRk); + break; + case FRV_OPERAND_CRI : + errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRi); + break; + case FRV_OPERAND_CRJ : + errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRj); + break; + case FRV_OPERAND_CRJ_FLOAT : + errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRj_float); + break; + case FRV_OPERAND_CRJ_INT : + errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRj_int); + break; + case FRV_OPERAND_CRK : + errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRk); + break; + case FRV_OPERAND_FCCI_1 : + errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCi_1); + break; + case FRV_OPERAND_FCCI_2 : + errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCi_2); + break; + case FRV_OPERAND_FCCI_3 : + errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCi_3); + break; + case FRV_OPERAND_FCCK : + errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCk); + break; + case FRV_OPERAND_FRDOUBLEI : + errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRi); + break; + case FRV_OPERAND_FRDOUBLEJ : + errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRj); + break; + case FRV_OPERAND_FRDOUBLEK : + errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk); + break; + case FRV_OPERAND_FRI : + errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRi); + break; + case FRV_OPERAND_FRINTI : + errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRi); + break; + case FRV_OPERAND_FRINTJ : + errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRj); + break; + case FRV_OPERAND_FRINTK : + errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk); + break; + case FRV_OPERAND_FRJ : + errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRj); + break; + case FRV_OPERAND_FRK : + errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk); + break; + case FRV_OPERAND_FRKHI : + errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk); + break; + case FRV_OPERAND_FRKLO : + errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk); + break; + case FRV_OPERAND_GRDOUBLEK : + errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk); + break; + case FRV_OPERAND_GRI : + errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRi); + break; + case FRV_OPERAND_GRJ : + errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRj); + break; + case FRV_OPERAND_GRK : + errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk); + break; + case FRV_OPERAND_GRKHI : + errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk); + break; + case FRV_OPERAND_GRKLO : + errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk); + break; + case FRV_OPERAND_ICCI_1 : + errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_iccr_names, & fields->f_ICCi_1); + break; + case FRV_OPERAND_ICCI_2 : + errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_iccr_names, & fields->f_ICCi_2); + break; + case FRV_OPERAND_ICCI_3 : + errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_iccr_names, & fields->f_ICCi_3); + break; + case FRV_OPERAND_LI : + errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_LI, &fields->f_LI); + break; + case FRV_OPERAND_AE : + errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_AE, &fields->f_ae); + break; + case FRV_OPERAND_CCOND : + errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_CCOND, &fields->f_ccond); + break; + case FRV_OPERAND_COND : + errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_COND, &fields->f_cond); + break; + case FRV_OPERAND_D12 : + errmsg = parse_d12 (cd, strp, FRV_OPERAND_D12, &fields->f_d12); + break; + case FRV_OPERAND_DEBUG : + errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_DEBUG, &fields->f_debug); + break; + case FRV_OPERAND_EIR : + errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_EIR, &fields->f_eir); + break; + case FRV_OPERAND_HINT : + errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_HINT, &fields->f_hint); + break; + case FRV_OPERAND_HINT_NOT_TAKEN : + errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_h_hint_not_taken, & fields->f_hint); + break; + case FRV_OPERAND_HINT_TAKEN : + errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_h_hint_taken, & fields->f_hint); + break; + case FRV_OPERAND_LABEL16 : + { + bfd_vma value; + errmsg = cgen_parse_address (cd, strp, FRV_OPERAND_LABEL16, 0, NULL, & value); + fields->f_label16 = value; + } + break; + case FRV_OPERAND_LABEL24 : + { + bfd_vma value; + errmsg = cgen_parse_address (cd, strp, FRV_OPERAND_LABEL24, 0, NULL, & value); + fields->f_label24 = value; + } + break; + case FRV_OPERAND_LOCK : + errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_LOCK, &fields->f_lock); + break; + case FRV_OPERAND_PACK : + errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_h_pack, & fields->f_pack); + break; + case FRV_OPERAND_S10 : + errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S10, &fields->f_s10); + break; + case FRV_OPERAND_S12 : + errmsg = parse_s12 (cd, strp, FRV_OPERAND_S12, &fields->f_d12); + break; + case FRV_OPERAND_S16 : + errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S16, &fields->f_s16); + break; + case FRV_OPERAND_S5 : + errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S5, &fields->f_s5); + break; + case FRV_OPERAND_S6 : + errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S6, &fields->f_s6); + break; + case FRV_OPERAND_S6_1 : + errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S6_1, &fields->f_s6_1); + break; + case FRV_OPERAND_SLO16 : + errmsg = parse_uslo16 (cd, strp, FRV_OPERAND_SLO16, &fields->f_s16); + break; + case FRV_OPERAND_SPR : + errmsg = parse_spr (cd, strp, & frv_cgen_opval_spr_names, & fields->f_spr); + break; + case FRV_OPERAND_U12 : + errmsg = parse_u12 (cd, strp, FRV_OPERAND_U12, &fields->f_u12); + break; + case FRV_OPERAND_U16 : + errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_U16, &fields->f_u16); + break; + case FRV_OPERAND_U6 : + errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_U6, &fields->f_u6); + break; + case FRV_OPERAND_UHI16 : + errmsg = parse_uhi16 (cd, strp, FRV_OPERAND_UHI16, &fields->f_u16); + break; + case FRV_OPERAND_ULO16 : + errmsg = parse_ulo16 (cd, strp, FRV_OPERAND_ULO16, &fields->f_u16); + break; + + default : + /* xgettext:c-format */ + fprintf (stderr, _("Unrecognized field %d while parsing.\n"), opindex); + abort (); + } + + return errmsg; +} + +cgen_parse_fn * const frv_cgen_parse_handlers[] = +{ + parse_insn_normal, +}; + +void +frv_cgen_init_asm (cd) + CGEN_CPU_DESC cd; +{ + frv_cgen_init_opcode_table (cd); + frv_cgen_init_ibld_table (cd); + cd->parse_handlers = & frv_cgen_parse_handlers[0]; + cd->parse_operand = frv_cgen_parse_operand; +} + + + +/* Regex construction routine. + + This translates an opcode syntax string into a regex string, + by replacing any non-character syntax element (such as an + opcode) with the pattern '.*' + + It then compiles the regex and stores it in the opcode, for + later use by frv_cgen_assemble_insn + + Returns NULL for success, an error message for failure. */ + +char * +frv_cgen_build_insn_regex (insn) + CGEN_INSN *insn; +{ + CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn); + const char *mnem = CGEN_INSN_MNEMONIC (insn); + char rxbuf[CGEN_MAX_RX_ELEMENTS]; + char *rx = rxbuf; + const CGEN_SYNTAX_CHAR_TYPE *syn; + int reg_err; + + syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc)); + + /* Mnemonics come first in the syntax string. */ + if (! CGEN_SYNTAX_MNEMONIC_P (* syn)) + return _("missing mnemonic in syntax string"); + ++syn; + + /* Generate a case sensitive regular expression that emulates case + insensitive matching in the "C" locale. We cannot generate a case + insensitive regular expression because in Turkish locales, 'i' and 'I' + are not equal modulo case conversion. */ + + /* Copy the literal mnemonic out of the insn. */ + for (; *mnem; mnem++) + { + char c = *mnem; + + if (ISALPHA (c)) + { + *rx++ = '['; + *rx++ = TOLOWER (c); + *rx++ = TOUPPER (c); + *rx++ = ']'; + } + else + *rx++ = c; + } + + /* Copy any remaining literals from the syntax string into the rx. */ + for(; * syn != 0 && rx <= rxbuf + (CGEN_MAX_RX_ELEMENTS - 7 - 4); ++syn) + { + if (CGEN_SYNTAX_CHAR_P (* syn)) + { + char c = CGEN_SYNTAX_CHAR (* syn); + + switch (c) + { + /* Escape any regex metacharacters in the syntax. */ + case '.': case '[': case '\\': + case '*': case '^': case '$': + +#ifdef CGEN_ESCAPE_EXTENDED_REGEX + case '?': case '{': case '}': + case '(': case ')': case '*': + case '|': case '+': case ']': +#endif + *rx++ = '\\'; + *rx++ = c; + break; + + default: + if (ISALPHA (c)) + { + *rx++ = '['; + *rx++ = TOLOWER (c); + *rx++ = TOUPPER (c); + *rx++ = ']'; + } + else + *rx++ = c; + break; + } + } + else + { + /* Replace non-syntax fields with globs. */ + *rx++ = '.'; + *rx++ = '*'; + } + } + + /* Trailing whitespace ok. */ + * rx++ = '['; + * rx++ = ' '; + * rx++ = '\t'; + * rx++ = ']'; + * rx++ = '*'; + + /* But anchor it after that. */ + * rx++ = '$'; + * rx = '\0'; + + CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t)); + reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB); + + if (reg_err == 0) + return NULL; + else + { + static char msg[80]; + + regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80); + regfree ((regex_t *) CGEN_INSN_RX (insn)); + free (CGEN_INSN_RX (insn)); + (CGEN_INSN_RX (insn)) = NULL; + return msg; + } +} + + +/* Default insn parser. + + The syntax string is scanned and operands are parsed and stored in FIELDS. + Relocs are queued as we go via other callbacks. + + ??? Note that this is currently an all-or-nothing parser. If we fail to + parse the instruction, we return 0 and the caller will start over from + the beginning. Backtracking will be necessary in parsing subexpressions, + but that can be handled there. Not handling backtracking here may get + expensive in the case of the m68k. Deal with later. + + Returns NULL for success, an error message for failure. */ + +static const char * +parse_insn_normal (cd, insn, strp, fields) + CGEN_CPU_DESC cd; + const CGEN_INSN *insn; + const char **strp; + CGEN_FIELDS *fields; +{ + /* ??? Runtime added insns not handled yet. */ + const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn); + const char *str = *strp; + const char *errmsg; + const char *p; + const CGEN_SYNTAX_CHAR_TYPE * syn; +#ifdef CGEN_MNEMONIC_OPERANDS + /* FIXME: wip */ + int past_opcode_p; +#endif + + /* For now we assume the mnemonic is first (there are no leading operands). + We can parse it without needing to set up operand parsing. + GAS's input scrubber will ensure mnemonics are lowercase, but we may + not be called from GAS. */ + p = CGEN_INSN_MNEMONIC (insn); + while (*p && TOLOWER (*p) == TOLOWER (*str)) + ++p, ++str; + + if (* p) + return _("unrecognized instruction"); + +#ifndef CGEN_MNEMONIC_OPERANDS + if (* str && ! ISSPACE (* str)) + return _("unrecognized instruction"); +#endif + + CGEN_INIT_PARSE (cd); + cgen_init_parse_operand (cd); +#ifdef CGEN_MNEMONIC_OPERANDS + past_opcode_p = 0; +#endif + + /* We don't check for (*str != '\0') here because we want to parse + any trailing fake arguments in the syntax string. */ + syn = CGEN_SYNTAX_STRING (syntax); + + /* Mnemonics come first for now, ensure valid string. */ + if (! CGEN_SYNTAX_MNEMONIC_P (* syn)) + abort (); + + ++syn; + + while (* syn != 0) + { + /* Non operand chars must match exactly. */ + if (CGEN_SYNTAX_CHAR_P (* syn)) + { + /* FIXME: While we allow for non-GAS callers above, we assume the + first char after the mnemonic part is a space. */ + /* FIXME: We also take inappropriate advantage of the fact that + GAS's input scrubber will remove extraneous blanks. */ + if (TOLOWER (*str) == TOLOWER (CGEN_SYNTAX_CHAR (* syn))) + { +#ifdef CGEN_MNEMONIC_OPERANDS + if (CGEN_SYNTAX_CHAR(* syn) == ' ') + past_opcode_p = 1; +#endif + ++ syn; + ++ str; + } + else if (*str) + { + /* Syntax char didn't match. Can't be this insn. */ + static char msg [80]; + + /* xgettext:c-format */ + sprintf (msg, _("syntax error (expected char `%c', found `%c')"), + CGEN_SYNTAX_CHAR(*syn), *str); + return msg; + } + else + { + /* Ran out of input. */ + static char msg [80]; + + /* xgettext:c-format */ + sprintf (msg, _("syntax error (expected char `%c', found end of instruction)"), + CGEN_SYNTAX_CHAR(*syn)); + return msg; + } + continue; + } + + /* We have an operand of some sort. */ + errmsg = cd->parse_operand (cd, CGEN_SYNTAX_FIELD (*syn), + &str, fields); + if (errmsg) + return errmsg; + + /* Done with this operand, continue with next one. */ + ++ syn; + } + + /* If we're at the end of the syntax string, we're done. */ + if (* syn == 0) + { + /* FIXME: For the moment we assume a valid `str' can only contain + blanks now. IE: We needn't try again with a longer version of + the insn and it is assumed that longer versions of insns appear + before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */ + while (ISSPACE (* str)) + ++ str; + + if (* str != '\0') + return _("junk at end of line"); /* FIXME: would like to include `str' */ + + return NULL; + } + + /* We couldn't parse it. */ + return _("unrecognized instruction"); +} + +/* Main entry point. + This routine is called for each instruction to be assembled. + STR points to the insn to be assembled. + We assume all necessary tables have been initialized. + The assembled instruction, less any fixups, is stored in BUF. + Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value + still needs to be converted to target byte order, otherwise BUF is an array + of bytes in target byte order. + The result is a pointer to the insn's entry in the opcode table, + or NULL if an error occured (an error message will have already been + printed). + + Note that when processing (non-alias) macro-insns, + this function recurses. + + ??? It's possible to make this cpu-independent. + One would have to deal with a few minor things. + At this point in time doing so would be more of a curiosity than useful + [for example this file isn't _that_ big], but keeping the possibility in + mind helps keep the design clean. */ + +const CGEN_INSN * +frv_cgen_assemble_insn (cd, str, fields, buf, errmsg) + CGEN_CPU_DESC cd; + const char *str; + CGEN_FIELDS *fields; + CGEN_INSN_BYTES_PTR buf; + char **errmsg; +{ + const char *start; + CGEN_INSN_LIST *ilist; + const char *parse_errmsg = NULL; + const char *insert_errmsg = NULL; + int recognized_mnemonic = 0; + + /* Skip leading white space. */ + while (ISSPACE (* str)) + ++ str; + + /* The instructions are stored in hashed lists. + Get the first in the list. */ + ilist = CGEN_ASM_LOOKUP_INSN (cd, str); + + /* Keep looking until we find a match. */ + start = str; + for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist)) + { + const CGEN_INSN *insn = ilist->insn; + recognized_mnemonic = 1; + +#ifdef CGEN_VALIDATE_INSN_SUPPORTED + /* Not usually needed as unsupported opcodes + shouldn't be in the hash lists. */ + /* Is this insn supported by the selected cpu? */ + if (! frv_cgen_insn_supported (cd, insn)) + continue; +#endif + /* If the RELAX attribute is set, this is an insn that shouldn't be + chosen immediately. Instead, it is used during assembler/linker + relaxation if possible. */ + if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAX) != 0) + continue; + + str = start; + + /* Skip this insn if str doesn't look right lexically. */ + if (CGEN_INSN_RX (insn) != NULL && + regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH) + continue; + + /* Allow parse/insert handlers to obtain length of insn. */ + CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn); + + parse_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields); + if (parse_errmsg != NULL) + continue; + + /* ??? 0 is passed for `pc'. */ + insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf, + (bfd_vma) 0); + if (insert_errmsg != NULL) + continue; + + /* It is up to the caller to actually output the insn and any + queued relocs. */ + return insn; + } + + { + static char errbuf[150]; +#ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS + const char *tmp_errmsg; + + /* If requesting verbose error messages, use insert_errmsg. + Failing that, use parse_errmsg. */ + tmp_errmsg = (insert_errmsg ? insert_errmsg : + parse_errmsg ? parse_errmsg : + recognized_mnemonic ? + _("unrecognized form of instruction") : + _("unrecognized instruction")); + + if (strlen (start) > 50) + /* xgettext:c-format */ + sprintf (errbuf, "%s `%.50s...'", tmp_errmsg, start); + else + /* xgettext:c-format */ + sprintf (errbuf, "%s `%.50s'", tmp_errmsg, start); +#else + if (strlen (start) > 50) + /* xgettext:c-format */ + sprintf (errbuf, _("bad instruction `%.50s...'"), start); + else + /* xgettext:c-format */ + sprintf (errbuf, _("bad instruction `%.50s'"), start); +#endif + + *errmsg = errbuf; + return NULL; + } +} + +#if 0 /* This calls back to GAS which we can't do without care. */ + +/* Record each member of OPVALS in the assembler's symbol table. + This lets GAS parse registers for us. + ??? Interesting idea but not currently used. */ + +/* Record each member of OPVALS in the assembler's symbol table. + FIXME: Not currently used. */ + +void +frv_cgen_asm_hash_keywords (cd, opvals) + CGEN_CPU_DESC cd; + CGEN_KEYWORD *opvals; +{ + CGEN_KEYWORD_SEARCH search = cgen_keyword_search_init (opvals, NULL); + const CGEN_KEYWORD_ENTRY * ke; + + while ((ke = cgen_keyword_search_next (& search)) != NULL) + { +#if 0 /* Unnecessary, should be done in the search routine. */ + if (! frv_cgen_opval_supported (ke)) + continue; +#endif + cgen_asm_record_register (cd, ke->name, ke->value); + } +} + +#endif /* 0 */ diff --git a/opcodes/frv-desc.c b/opcodes/frv-desc.c new file mode 100644 index 0000000..8b8274c --- /dev/null +++ b/opcodes/frv-desc.c @@ -0,0 +1,6311 @@ +/* CPU data for frv. + +THIS FILE IS MACHINE GENERATED WITH CGEN. + +Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + +This file is part of the GNU Binutils and/or 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 "sysdep.h" +#include +#include +#include "ansidecl.h" +#include "bfd.h" +#include "symcat.h" +#include "frv-desc.h" +#include "frv-opc.h" +#include "opintl.h" +#include "libiberty.h" + +/* Attributes. */ + +static const CGEN_ATTR_ENTRY bool_attr[] = +{ + { "#f", 0 }, + { "#t", 1 }, + { 0, 0 } +}; + +static const CGEN_ATTR_ENTRY MACH_attr[] = +{ + { "base", MACH_BASE }, + { "frv", MACH_FRV }, + { "fr500", MACH_FR500 }, + { "fr400", MACH_FR400 }, + { "tomcat", MACH_TOMCAT }, + { "simple", MACH_SIMPLE }, + { "max", MACH_MAX }, + { 0, 0 } +}; + +static const CGEN_ATTR_ENTRY ISA_attr[] = +{ + { "frv", ISA_FRV }, + { "max", ISA_MAX }, + { 0, 0 } +}; + +static const CGEN_ATTR_ENTRY UNIT_attr[] = +{ + { "NIL", UNIT_NIL }, + { "I0", UNIT_I0 }, + { "I1", UNIT_I1 }, + { "I01", UNIT_I01 }, + { "FM0", UNIT_FM0 }, + { "FM1", UNIT_FM1 }, + { "FM01", UNIT_FM01 }, + { "B0", UNIT_B0 }, + { "B1", UNIT_B1 }, + { "B01", UNIT_B01 }, + { "C", UNIT_C }, + { "MULT_DIV", UNIT_MULT_DIV }, + { "LOAD", UNIT_LOAD }, + { "NUM_UNITS", UNIT_NUM_UNITS }, + { 0, 0 } +}; + +static const CGEN_ATTR_ENTRY FR400_MAJOR_attr[] = +{ + { "NONE", FR400_MAJOR_NONE }, + { "I_1", FR400_MAJOR_I_1 }, + { "I_2", FR400_MAJOR_I_2 }, + { "I_3", FR400_MAJOR_I_3 }, + { "I_4", FR400_MAJOR_I_4 }, + { "I_5", FR400_MAJOR_I_5 }, + { "B_1", FR400_MAJOR_B_1 }, + { "B_2", FR400_MAJOR_B_2 }, + { "B_3", FR400_MAJOR_B_3 }, + { "B_4", FR400_MAJOR_B_4 }, + { "B_5", FR400_MAJOR_B_5 }, + { "B_6", FR400_MAJOR_B_6 }, + { "C_1", FR400_MAJOR_C_1 }, + { "C_2", FR400_MAJOR_C_2 }, + { "M_1", FR400_MAJOR_M_1 }, + { "M_2", FR400_MAJOR_M_2 }, + { 0, 0 } +}; + +static const CGEN_ATTR_ENTRY FR500_MAJOR_attr[] = +{ + { "NONE", FR500_MAJOR_NONE }, + { "I_1", FR500_MAJOR_I_1 }, + { "I_2", FR500_MAJOR_I_2 }, + { "I_3", FR500_MAJOR_I_3 }, + { "I_4", FR500_MAJOR_I_4 }, + { "I_5", FR500_MAJOR_I_5 }, + { "I_6", FR500_MAJOR_I_6 }, + { "B_1", FR500_MAJOR_B_1 }, + { "B_2", FR500_MAJOR_B_2 }, + { "B_3", FR500_MAJOR_B_3 }, + { "B_4", FR500_MAJOR_B_4 }, + { "B_5", FR500_MAJOR_B_5 }, + { "B_6", FR500_MAJOR_B_6 }, + { "C_1", FR500_MAJOR_C_1 }, + { "C_2", FR500_MAJOR_C_2 }, + { "F_1", FR500_MAJOR_F_1 }, + { "F_2", FR500_MAJOR_F_2 }, + { "F_3", FR500_MAJOR_F_3 }, + { "F_4", FR500_MAJOR_F_4 }, + { "F_5", FR500_MAJOR_F_5 }, + { "F_6", FR500_MAJOR_F_6 }, + { "F_7", FR500_MAJOR_F_7 }, + { "F_8", FR500_MAJOR_F_8 }, + { "M_1", FR500_MAJOR_M_1 }, + { "M_2", FR500_MAJOR_M_2 }, + { "M_3", FR500_MAJOR_M_3 }, + { "M_4", FR500_MAJOR_M_4 }, + { "M_5", FR500_MAJOR_M_5 }, + { "M_6", FR500_MAJOR_M_6 }, + { "M_7", FR500_MAJOR_M_7 }, + { "M_8", FR500_MAJOR_M_8 }, + { 0, 0 } +}; + +const CGEN_ATTR_TABLE frv_cgen_ifield_attr_table[] = +{ + { "MACH", & MACH_attr[0], & MACH_attr[0] }, + { "VIRTUAL", &bool_attr[0], &bool_attr[0] }, + { "PCREL-ADDR", &bool_attr[0], &bool_attr[0] }, + { "ABS-ADDR", &bool_attr[0], &bool_attr[0] }, + { "RESERVED", &bool_attr[0], &bool_attr[0] }, + { "SIGN-OPT", &bool_attr[0], &bool_attr[0] }, + { "SIGNED", &bool_attr[0], &bool_attr[0] }, + { 0, 0, 0 } +}; + +const CGEN_ATTR_TABLE frv_cgen_hardware_attr_table[] = +{ + { "MACH", & MACH_attr[0], & MACH_attr[0] }, + { "VIRTUAL", &bool_attr[0], &bool_attr[0] }, + { "CACHE-ADDR", &bool_attr[0], &bool_attr[0] }, + { "PC", &bool_attr[0], &bool_attr[0] }, + { "PROFILE", &bool_attr[0], &bool_attr[0] }, + { 0, 0, 0 } +}; + +const CGEN_ATTR_TABLE frv_cgen_operand_attr_table[] = +{ + { "MACH", & MACH_attr[0], & MACH_attr[0] }, + { "VIRTUAL", &bool_attr[0], &bool_attr[0] }, + { "PCREL-ADDR", &bool_attr[0], &bool_attr[0] }, + { "ABS-ADDR", &bool_attr[0], &bool_attr[0] }, + { "SIGN-OPT", &bool_attr[0], &bool_attr[0] }, + { "SIGNED", &bool_attr[0], &bool_attr[0] }, + { "NEGATIVE", &bool_attr[0], &bool_attr[0] }, + { "RELAX", &bool_attr[0], &bool_attr[0] }, + { "SEM-ONLY", &bool_attr[0], &bool_attr[0] }, + { "HASH-PREFIX", &bool_attr[0], &bool_attr[0] }, + { 0, 0, 0 } +}; + +const CGEN_ATTR_TABLE frv_cgen_insn_attr_table[] = +{ + { "MACH", & MACH_attr[0], & MACH_attr[0] }, + { "UNIT", & UNIT_attr[0], & UNIT_attr[0] }, + { "FR400-MAJOR", & FR400_MAJOR_attr[0], & FR400_MAJOR_attr[0] }, + { "FR500-MAJOR", & FR500_MAJOR_attr[0], & FR500_MAJOR_attr[0] }, + { "ALIAS", &bool_attr[0], &bool_attr[0] }, + { "VIRTUAL", &bool_attr[0], &bool_attr[0] }, + { "UNCOND-CTI", &bool_attr[0], &bool_attr[0] }, + { "COND-CTI", &bool_attr[0], &bool_attr[0] }, + { "SKIP-CTI", &bool_attr[0], &bool_attr[0] }, + { "DELAY-SLOT", &bool_attr[0], &bool_attr[0] }, + { "RELAXABLE", &bool_attr[0], &bool_attr[0] }, + { "RELAX", &bool_attr[0], &bool_attr[0] }, + { "NO-DIS", &bool_attr[0], &bool_attr[0] }, + { "PBB", &bool_attr[0], &bool_attr[0] }, + { "PRIVILEGED", &bool_attr[0], &bool_attr[0] }, + { "NON-EXCEPTING", &bool_attr[0], &bool_attr[0] }, + { "CONDITIONAL", &bool_attr[0], &bool_attr[0] }, + { "FR-ACCESS", &bool_attr[0], &bool_attr[0] }, + { "PRESERVE-OVF", &bool_attr[0], &bool_attr[0] }, + { 0, 0, 0 } +}; + +/* Instruction set variants. */ + +static const CGEN_ISA frv_cgen_isa_table[] = { + { "frv", 32, 32, 32, 32 }, + { 0, 0, 0, 0, 0 } +}; + +/* Machine variants. */ + +static const CGEN_MACH frv_cgen_mach_table[] = { + { "frv", "frv", MACH_FRV, 0 }, + { "fr500", "fr500", MACH_FR500, 0 }, + { "tomcat", "tomcat", MACH_TOMCAT, 0 }, + { "fr400", "fr400", MACH_FR400, 0 }, + { "simple", "simple", MACH_SIMPLE, 0 }, + { 0, 0, 0, 0 } +}; + +static CGEN_KEYWORD_ENTRY frv_cgen_opval_gr_names_entries[] = +{ + { "sp", 1, {0, {0}}, 0, 0 }, + { "fp", 2, {0, {0}}, 0, 0 }, + { "gr0", 0, {0, {0}}, 0, 0 }, + { "gr1", 1, {0, {0}}, 0, 0 }, + { "gr2", 2, {0, {0}}, 0, 0 }, + { "gr3", 3, {0, {0}}, 0, 0 }, + { "gr4", 4, {0, {0}}, 0, 0 }, + { "gr5", 5, {0, {0}}, 0, 0 }, + { "gr6", 6, {0, {0}}, 0, 0 }, + { "gr7", 7, {0, {0}}, 0, 0 }, + { "gr8", 8, {0, {0}}, 0, 0 }, + { "gr9", 9, {0, {0}}, 0, 0 }, + { "gr10", 10, {0, {0}}, 0, 0 }, + { "gr11", 11, {0, {0}}, 0, 0 }, + { "gr12", 12, {0, {0}}, 0, 0 }, + { "gr13", 13, {0, {0}}, 0, 0 }, + { "gr14", 14, {0, {0}}, 0, 0 }, + { "gr15", 15, {0, {0}}, 0, 0 }, + { "gr16", 16, {0, {0}}, 0, 0 }, + { "gr17", 17, {0, {0}}, 0, 0 }, + { "gr18", 18, {0, {0}}, 0, 0 }, + { "gr19", 19, {0, {0}}, 0, 0 }, + { "gr20", 20, {0, {0}}, 0, 0 }, + { "gr21", 21, {0, {0}}, 0, 0 }, + { "gr22", 22, {0, {0}}, 0, 0 }, + { "gr23", 23, {0, {0}}, 0, 0 }, + { "gr24", 24, {0, {0}}, 0, 0 }, + { "gr25", 25, {0, {0}}, 0, 0 }, + { "gr26", 26, {0, {0}}, 0, 0 }, + { "gr27", 27, {0, {0}}, 0, 0 }, + { "gr28", 28, {0, {0}}, 0, 0 }, + { "gr29", 29, {0, {0}}, 0, 0 }, + { "gr30", 30, {0, {0}}, 0, 0 }, + { "gr31", 31, {0, {0}}, 0, 0 }, + { "gr32", 32, {0, {0}}, 0, 0 }, + { "gr33", 33, {0, {0}}, 0, 0 }, + { "gr34", 34, {0, {0}}, 0, 0 }, + { "gr35", 35, {0, {0}}, 0, 0 }, + { "gr36", 36, {0, {0}}, 0, 0 }, + { "gr37", 37, {0, {0}}, 0, 0 }, + { "gr38", 38, {0, {0}}, 0, 0 }, + { "gr39", 39, {0, {0}}, 0, 0 }, + { "gr40", 40, {0, {0}}, 0, 0 }, + { "gr41", 41, {0, {0}}, 0, 0 }, + { "gr42", 42, {0, {0}}, 0, 0 }, + { "gr43", 43, {0, {0}}, 0, 0 }, + { "gr44", 44, {0, {0}}, 0, 0 }, + { "gr45", 45, {0, {0}}, 0, 0 }, + { "gr46", 46, {0, {0}}, 0, 0 }, + { "gr47", 47, {0, {0}}, 0, 0 }, + { "gr48", 48, {0, {0}}, 0, 0 }, + { "gr49", 49, {0, {0}}, 0, 0 }, + { "gr50", 50, {0, {0}}, 0, 0 }, + { "gr51", 51, {0, {0}}, 0, 0 }, + { "gr52", 52, {0, {0}}, 0, 0 }, + { "gr53", 53, {0, {0}}, 0, 0 }, + { "gr54", 54, {0, {0}}, 0, 0 }, + { "gr55", 55, {0, {0}}, 0, 0 }, + { "gr56", 56, {0, {0}}, 0, 0 }, + { "gr57", 57, {0, {0}}, 0, 0 }, + { "gr58", 58, {0, {0}}, 0, 0 }, + { "gr59", 59, {0, {0}}, 0, 0 }, + { "gr60", 60, {0, {0}}, 0, 0 }, + { "gr61", 61, {0, {0}}, 0, 0 }, + { "gr62", 62, {0, {0}}, 0, 0 }, + { "gr63", 63, {0, {0}}, 0, 0 } +}; + +CGEN_KEYWORD frv_cgen_opval_gr_names = +{ + & frv_cgen_opval_gr_names_entries[0], + 66, + 0, 0, 0, 0, "" +}; + +static CGEN_KEYWORD_ENTRY frv_cgen_opval_fr_names_entries[] = +{ + { "fr0", 0, {0, {0}}, 0, 0 }, + { "fr1", 1, {0, {0}}, 0, 0 }, + { "fr2", 2, {0, {0}}, 0, 0 }, + { "fr3", 3, {0, {0}}, 0, 0 }, + { "fr4", 4, {0, {0}}, 0, 0 }, + { "fr5", 5, {0, {0}}, 0, 0 }, + { "fr6", 6, {0, {0}}, 0, 0 }, + { "fr7", 7, {0, {0}}, 0, 0 }, + { "fr8", 8, {0, {0}}, 0, 0 }, + { "fr9", 9, {0, {0}}, 0, 0 }, + { "fr10", 10, {0, {0}}, 0, 0 }, + { "fr11", 11, {0, {0}}, 0, 0 }, + { "fr12", 12, {0, {0}}, 0, 0 }, + { "fr13", 13, {0, {0}}, 0, 0 }, + { "fr14", 14, {0, {0}}, 0, 0 }, + { "fr15", 15, {0, {0}}, 0, 0 }, + { "fr16", 16, {0, {0}}, 0, 0 }, + { "fr17", 17, {0, {0}}, 0, 0 }, + { "fr18", 18, {0, {0}}, 0, 0 }, + { "fr19", 19, {0, {0}}, 0, 0 }, + { "fr20", 20, {0, {0}}, 0, 0 }, + { "fr21", 21, {0, {0}}, 0, 0 }, + { "fr22", 22, {0, {0}}, 0, 0 }, + { "fr23", 23, {0, {0}}, 0, 0 }, + { "fr24", 24, {0, {0}}, 0, 0 }, + { "fr25", 25, {0, {0}}, 0, 0 }, + { "fr26", 26, {0, {0}}, 0, 0 }, + { "fr27", 27, {0, {0}}, 0, 0 }, + { "fr28", 28, {0, {0}}, 0, 0 }, + { "fr29", 29, {0, {0}}, 0, 0 }, + { "fr30", 30, {0, {0}}, 0, 0 }, + { "fr31", 31, {0, {0}}, 0, 0 }, + { "fr32", 32, {0, {0}}, 0, 0 }, + { "fr33", 33, {0, {0}}, 0, 0 }, + { "fr34", 34, {0, {0}}, 0, 0 }, + { "fr35", 35, {0, {0}}, 0, 0 }, + { "fr36", 36, {0, {0}}, 0, 0 }, + { "fr37", 37, {0, {0}}, 0, 0 }, + { "fr38", 38, {0, {0}}, 0, 0 }, + { "fr39", 39, {0, {0}}, 0, 0 }, + { "fr40", 40, {0, {0}}, 0, 0 }, + { "fr41", 41, {0, {0}}, 0, 0 }, + { "fr42", 42, {0, {0}}, 0, 0 }, + { "fr43", 43, {0, {0}}, 0, 0 }, + { "fr44", 44, {0, {0}}, 0, 0 }, + { "fr45", 45, {0, {0}}, 0, 0 }, + { "fr46", 46, {0, {0}}, 0, 0 }, + { "fr47", 47, {0, {0}}, 0, 0 }, + { "fr48", 48, {0, {0}}, 0, 0 }, + { "fr49", 49, {0, {0}}, 0, 0 }, + { "fr50", 50, {0, {0}}, 0, 0 }, + { "fr51", 51, {0, {0}}, 0, 0 }, + { "fr52", 52, {0, {0}}, 0, 0 }, + { "fr53", 53, {0, {0}}, 0, 0 }, + { "fr54", 54, {0, {0}}, 0, 0 }, + { "fr55", 55, {0, {0}}, 0, 0 }, + { "fr56", 56, {0, {0}}, 0, 0 }, + { "fr57", 57, {0, {0}}, 0, 0 }, + { "fr58", 58, {0, {0}}, 0, 0 }, + { "fr59", 59, {0, {0}}, 0, 0 }, + { "fr60", 60, {0, {0}}, 0, 0 }, + { "fr61", 61, {0, {0}}, 0, 0 }, + { "fr62", 62, {0, {0}}, 0, 0 }, + { "fr63", 63, {0, {0}}, 0, 0 } +}; + +CGEN_KEYWORD frv_cgen_opval_fr_names = +{ + & frv_cgen_opval_fr_names_entries[0], + 64, + 0, 0, 0, 0, "" +}; + +static CGEN_KEYWORD_ENTRY frv_cgen_opval_cpr_names_entries[] = +{ + { "cpr0", 0, {0, {0}}, 0, 0 }, + { "cpr1", 1, {0, {0}}, 0, 0 }, + { "cpr2", 2, {0, {0}}, 0, 0 }, + { "cpr3", 3, {0, {0}}, 0, 0 }, + { "cpr4", 4, {0, {0}}, 0, 0 }, + { "cpr5", 5, {0, {0}}, 0, 0 }, + { "cpr6", 6, {0, {0}}, 0, 0 }, + { "cpr7", 7, {0, {0}}, 0, 0 }, + { "cpr8", 8, {0, {0}}, 0, 0 }, + { "cpr9", 9, {0, {0}}, 0, 0 }, + { "cpr10", 10, {0, {0}}, 0, 0 }, + { "cpr11", 11, {0, {0}}, 0, 0 }, + { "cpr12", 12, {0, {0}}, 0, 0 }, + { "cpr13", 13, {0, {0}}, 0, 0 }, + { "cpr14", 14, {0, {0}}, 0, 0 }, + { "cpr15", 15, {0, {0}}, 0, 0 }, + { "cpr16", 16, {0, {0}}, 0, 0 }, + { "cpr17", 17, {0, {0}}, 0, 0 }, + { "cpr18", 18, {0, {0}}, 0, 0 }, + { "cpr19", 19, {0, {0}}, 0, 0 }, + { "cpr20", 20, {0, {0}}, 0, 0 }, + { "cpr21", 21, {0, {0}}, 0, 0 }, + { "cpr22", 22, {0, {0}}, 0, 0 }, + { "cpr23", 23, {0, {0}}, 0, 0 }, + { "cpr24", 24, {0, {0}}, 0, 0 }, + { "cpr25", 25, {0, {0}}, 0, 0 }, + { "cpr26", 26, {0, {0}}, 0, 0 }, + { "cpr27", 27, {0, {0}}, 0, 0 }, + { "cpr28", 28, {0, {0}}, 0, 0 }, + { "cpr29", 29, {0, {0}}, 0, 0 }, + { "cpr30", 30, {0, {0}}, 0, 0 }, + { "cpr31", 31, {0, {0}}, 0, 0 }, + { "cpr32", 32, {0, {0}}, 0, 0 }, + { "cpr33", 33, {0, {0}}, 0, 0 }, + { "cpr34", 34, {0, {0}}, 0, 0 }, + { "cpr35", 35, {0, {0}}, 0, 0 }, + { "cpr36", 36, {0, {0}}, 0, 0 }, + { "cpr37", 37, {0, {0}}, 0, 0 }, + { "cpr38", 38, {0, {0}}, 0, 0 }, + { "cpr39", 39, {0, {0}}, 0, 0 }, + { "cpr40", 40, {0, {0}}, 0, 0 }, + { "cpr41", 41, {0, {0}}, 0, 0 }, + { "cpr42", 42, {0, {0}}, 0, 0 }, + { "cpr43", 43, {0, {0}}, 0, 0 }, + { "cpr44", 44, {0, {0}}, 0, 0 }, + { "cpr45", 45, {0, {0}}, 0, 0 }, + { "cpr46", 46, {0, {0}}, 0, 0 }, + { "cpr47", 47, {0, {0}}, 0, 0 }, + { "cpr48", 48, {0, {0}}, 0, 0 }, + { "cpr49", 49, {0, {0}}, 0, 0 }, + { "cpr50", 50, {0, {0}}, 0, 0 }, + { "cpr51", 51, {0, {0}}, 0, 0 }, + { "cpr52", 52, {0, {0}}, 0, 0 }, + { "cpr53", 53, {0, {0}}, 0, 0 }, + { "cpr54", 54, {0, {0}}, 0, 0 }, + { "cpr55", 55, {0, {0}}, 0, 0 }, + { "cpr56", 56, {0, {0}}, 0, 0 }, + { "cpr57", 57, {0, {0}}, 0, 0 }, + { "cpr58", 58, {0, {0}}, 0, 0 }, + { "cpr59", 59, {0, {0}}, 0, 0 }, + { "cpr60", 60, {0, {0}}, 0, 0 }, + { "cpr61", 61, {0, {0}}, 0, 0 }, + { "cpr62", 62, {0, {0}}, 0, 0 }, + { "cpr63", 63, {0, {0}}, 0, 0 } +}; + +CGEN_KEYWORD frv_cgen_opval_cpr_names = +{ + & frv_cgen_opval_cpr_names_entries[0], + 64, + 0, 0, 0, 0, "" +}; + +static CGEN_KEYWORD_ENTRY frv_cgen_opval_spr_names_entries[] = +{ + { "psr", 0, {0, {0}}, 0, 0 }, + { "pcsr", 1, {0, {0}}, 0, 0 }, + { "bpcsr", 2, {0, {0}}, 0, 0 }, + { "tbr", 3, {0, {0}}, 0, 0 }, + { "bpsr", 4, {0, {0}}, 0, 0 }, + { "hsr0", 16, {0, {0}}, 0, 0 }, + { "hsr1", 17, {0, {0}}, 0, 0 }, + { "hsr2", 18, {0, {0}}, 0, 0 }, + { "hsr3", 19, {0, {0}}, 0, 0 }, + { "hsr4", 20, {0, {0}}, 0, 0 }, + { "hsr5", 21, {0, {0}}, 0, 0 }, + { "hsr6", 22, {0, {0}}, 0, 0 }, + { "hsr7", 23, {0, {0}}, 0, 0 }, + { "hsr8", 24, {0, {0}}, 0, 0 }, + { "hsr9", 25, {0, {0}}, 0, 0 }, + { "hsr10", 26, {0, {0}}, 0, 0 }, + { "hsr11", 27, {0, {0}}, 0, 0 }, + { "hsr12", 28, {0, {0}}, 0, 0 }, + { "hsr13", 29, {0, {0}}, 0, 0 }, + { "hsr14", 30, {0, {0}}, 0, 0 }, + { "hsr15", 31, {0, {0}}, 0, 0 }, + { "hsr16", 32, {0, {0}}, 0, 0 }, + { "hsr17", 33, {0, {0}}, 0, 0 }, + { "hsr18", 34, {0, {0}}, 0, 0 }, + { "hsr19", 35, {0, {0}}, 0, 0 }, + { "hsr20", 36, {0, {0}}, 0, 0 }, + { "hsr21", 37, {0, {0}}, 0, 0 }, + { "hsr22", 38, {0, {0}}, 0, 0 }, + { "hsr23", 39, {0, {0}}, 0, 0 }, + { "hsr24", 40, {0, {0}}, 0, 0 }, + { "hsr25", 41, {0, {0}}, 0, 0 }, + { "hsr26", 42, {0, {0}}, 0, 0 }, + { "hsr27", 43, {0, {0}}, 0, 0 }, + { "hsr28", 44, {0, {0}}, 0, 0 }, + { "hsr29", 45, {0, {0}}, 0, 0 }, + { "hsr30", 46, {0, {0}}, 0, 0 }, + { "hsr31", 47, {0, {0}}, 0, 0 }, + { "hsr32", 48, {0, {0}}, 0, 0 }, + { "hsr33", 49, {0, {0}}, 0, 0 }, + { "hsr34", 50, {0, {0}}, 0, 0 }, + { "hsr35", 51, {0, {0}}, 0, 0 }, + { "hsr36", 52, {0, {0}}, 0, 0 }, + { "hsr37", 53, {0, {0}}, 0, 0 }, + { "hsr38", 54, {0, {0}}, 0, 0 }, + { "hsr39", 55, {0, {0}}, 0, 0 }, + { "hsr40", 56, {0, {0}}, 0, 0 }, + { "hsr41", 57, {0, {0}}, 0, 0 }, + { "hsr42", 58, {0, {0}}, 0, 0 }, + { "hsr43", 59, {0, {0}}, 0, 0 }, + { "hsr44", 60, {0, {0}}, 0, 0 }, + { "hsr45", 61, {0, {0}}, 0, 0 }, + { "hsr46", 62, {0, {0}}, 0, 0 }, + { "hsr47", 63, {0, {0}}, 0, 0 }, + { "hsr48", 64, {0, {0}}, 0, 0 }, + { "hsr49", 65, {0, {0}}, 0, 0 }, + { "hsr50", 66, {0, {0}}, 0, 0 }, + { "hsr51", 67, {0, {0}}, 0, 0 }, + { "hsr52", 68, {0, {0}}, 0, 0 }, + { "hsr53", 69, {0, {0}}, 0, 0 }, + { "hsr54", 70, {0, {0}}, 0, 0 }, + { "hsr55", 71, {0, {0}}, 0, 0 }, + { "hsr56", 72, {0, {0}}, 0, 0 }, + { "hsr57", 73, {0, {0}}, 0, 0 }, + { "hsr58", 74, {0, {0}}, 0, 0 }, + { "hsr59", 75, {0, {0}}, 0, 0 }, + { "hsr60", 76, {0, {0}}, 0, 0 }, + { "hsr61", 77, {0, {0}}, 0, 0 }, + { "hsr62", 78, {0, {0}}, 0, 0 }, + { "hsr63", 79, {0, {0}}, 0, 0 }, + { "ccr", 256, {0, {0}}, 0, 0 }, + { "cccr", 263, {0, {0}}, 0, 0 }, + { "lr", 272, {0, {0}}, 0, 0 }, + { "lcr", 273, {0, {0}}, 0, 0 }, + { "isr", 288, {0, {0}}, 0, 0 }, + { "neear0", 352, {0, {0}}, 0, 0 }, + { "neear1", 353, {0, {0}}, 0, 0 }, + { "neear2", 354, {0, {0}}, 0, 0 }, + { "neear3", 355, {0, {0}}, 0, 0 }, + { "neear4", 356, {0, {0}}, 0, 0 }, + { "neear5", 357, {0, {0}}, 0, 0 }, + { "neear6", 358, {0, {0}}, 0, 0 }, + { "neear7", 359, {0, {0}}, 0, 0 }, + { "neear8", 360, {0, {0}}, 0, 0 }, + { "neear9", 361, {0, {0}}, 0, 0 }, + { "neear10", 362, {0, {0}}, 0, 0 }, + { "neear11", 363, {0, {0}}, 0, 0 }, + { "neear12", 364, {0, {0}}, 0, 0 }, + { "neear13", 365, {0, {0}}, 0, 0 }, + { "neear14", 366, {0, {0}}, 0, 0 }, + { "neear15", 367, {0, {0}}, 0, 0 }, + { "neear16", 368, {0, {0}}, 0, 0 }, + { "neear17", 369, {0, {0}}, 0, 0 }, + { "neear18", 370, {0, {0}}, 0, 0 }, + { "neear19", 371, {0, {0}}, 0, 0 }, + { "neear20", 372, {0, {0}}, 0, 0 }, + { "neear21", 373, {0, {0}}, 0, 0 }, + { "neear22", 374, {0, {0}}, 0, 0 }, + { "neear23", 375, {0, {0}}, 0, 0 }, + { "neear24", 376, {0, {0}}, 0, 0 }, + { "neear25", 377, {0, {0}}, 0, 0 }, + { "neear26", 378, {0, {0}}, 0, 0 }, + { "neear27", 379, {0, {0}}, 0, 0 }, + { "neear28", 380, {0, {0}}, 0, 0 }, + { "neear29", 381, {0, {0}}, 0, 0 }, + { "neear30", 382, {0, {0}}, 0, 0 }, + { "neear31", 383, {0, {0}}, 0, 0 }, + { "nesr0", 384, {0, {0}}, 0, 0 }, + { "nesr1", 385, {0, {0}}, 0, 0 }, + { "nesr2", 386, {0, {0}}, 0, 0 }, + { "nesr3", 387, {0, {0}}, 0, 0 }, + { "nesr4", 388, {0, {0}}, 0, 0 }, + { "nesr5", 389, {0, {0}}, 0, 0 }, + { "nesr6", 390, {0, {0}}, 0, 0 }, + { "nesr7", 391, {0, {0}}, 0, 0 }, + { "nesr8", 392, {0, {0}}, 0, 0 }, + { "nesr9", 393, {0, {0}}, 0, 0 }, + { "nesr10", 394, {0, {0}}, 0, 0 }, + { "nesr11", 395, {0, {0}}, 0, 0 }, + { "nesr12", 396, {0, {0}}, 0, 0 }, + { "nesr13", 397, {0, {0}}, 0, 0 }, + { "nesr14", 398, {0, {0}}, 0, 0 }, + { "nesr15", 399, {0, {0}}, 0, 0 }, + { "nesr16", 400, {0, {0}}, 0, 0 }, + { "nesr17", 401, {0, {0}}, 0, 0 }, + { "nesr18", 402, {0, {0}}, 0, 0 }, + { "nesr19", 403, {0, {0}}, 0, 0 }, + { "nesr20", 404, {0, {0}}, 0, 0 }, + { "nesr21", 405, {0, {0}}, 0, 0 }, + { "nesr22", 406, {0, {0}}, 0, 0 }, + { "nesr23", 407, {0, {0}}, 0, 0 }, + { "nesr24", 408, {0, {0}}, 0, 0 }, + { "nesr25", 409, {0, {0}}, 0, 0 }, + { "nesr26", 410, {0, {0}}, 0, 0 }, + { "nesr27", 411, {0, {0}}, 0, 0 }, + { "nesr28", 412, {0, {0}}, 0, 0 }, + { "nesr29", 413, {0, {0}}, 0, 0 }, + { "nesr30", 414, {0, {0}}, 0, 0 }, + { "nesr31", 415, {0, {0}}, 0, 0 }, + { "necr", 416, {0, {0}}, 0, 0 }, + { "gner0", 432, {0, {0}}, 0, 0 }, + { "gner1", 433, {0, {0}}, 0, 0 }, + { "fner0", 434, {0, {0}}, 0, 0 }, + { "fner1", 435, {0, {0}}, 0, 0 }, + { "epcr0", 512, {0, {0}}, 0, 0 }, + { "epcr1", 513, {0, {0}}, 0, 0 }, + { "epcr2", 514, {0, {0}}, 0, 0 }, + { "epcr3", 515, {0, {0}}, 0, 0 }, + { "epcr4", 516, {0, {0}}, 0, 0 }, + { "epcr5", 517, {0, {0}}, 0, 0 }, + { "epcr6", 518, {0, {0}}, 0, 0 }, + { "epcr7", 519, {0, {0}}, 0, 0 }, + { "epcr8", 520, {0, {0}}, 0, 0 }, + { "epcr9", 521, {0, {0}}, 0, 0 }, + { "epcr10", 522, {0, {0}}, 0, 0 }, + { "epcr11", 523, {0, {0}}, 0, 0 }, + { "epcr12", 524, {0, {0}}, 0, 0 }, + { "epcr13", 525, {0, {0}}, 0, 0 }, + { "epcr14", 526, {0, {0}}, 0, 0 }, + { "epcr15", 527, {0, {0}}, 0, 0 }, + { "epcr16", 528, {0, {0}}, 0, 0 }, + { "epcr17", 529, {0, {0}}, 0, 0 }, + { "epcr18", 530, {0, {0}}, 0, 0 }, + { "epcr19", 531, {0, {0}}, 0, 0 }, + { "epcr20", 532, {0, {0}}, 0, 0 }, + { "epcr21", 533, {0, {0}}, 0, 0 }, + { "epcr22", 534, {0, {0}}, 0, 0 }, + { "epcr23", 535, {0, {0}}, 0, 0 }, + { "epcr24", 536, {0, {0}}, 0, 0 }, + { "epcr25", 537, {0, {0}}, 0, 0 }, + { "epcr26", 538, {0, {0}}, 0, 0 }, + { "epcr27", 539, {0, {0}}, 0, 0 }, + { "epcr28", 540, {0, {0}}, 0, 0 }, + { "epcr29", 541, {0, {0}}, 0, 0 }, + { "epcr30", 542, {0, {0}}, 0, 0 }, + { "epcr31", 543, {0, {0}}, 0, 0 }, + { "epcr32", 544, {0, {0}}, 0, 0 }, + { "epcr33", 545, {0, {0}}, 0, 0 }, + { "epcr34", 546, {0, {0}}, 0, 0 }, + { "epcr35", 547, {0, {0}}, 0, 0 }, + { "epcr36", 548, {0, {0}}, 0, 0 }, + { "epcr37", 549, {0, {0}}, 0, 0 }, + { "epcr38", 550, {0, {0}}, 0, 0 }, + { "epcr39", 551, {0, {0}}, 0, 0 }, + { "epcr40", 552, {0, {0}}, 0, 0 }, + { "epcr41", 553, {0, {0}}, 0, 0 }, + { "epcr42", 554, {0, {0}}, 0, 0 }, + { "epcr43", 555, {0, {0}}, 0, 0 }, + { "epcr44", 556, {0, {0}}, 0, 0 }, + { "epcr45", 557, {0, {0}}, 0, 0 }, + { "epcr46", 558, {0, {0}}, 0, 0 }, + { "epcr47", 559, {0, {0}}, 0, 0 }, + { "epcr48", 560, {0, {0}}, 0, 0 }, + { "epcr49", 561, {0, {0}}, 0, 0 }, + { "epcr50", 562, {0, {0}}, 0, 0 }, + { "epcr51", 563, {0, {0}}, 0, 0 }, + { "epcr52", 564, {0, {0}}, 0, 0 }, + { "epcr53", 565, {0, {0}}, 0, 0 }, + { "epcr54", 566, {0, {0}}, 0, 0 }, + { "epcr55", 567, {0, {0}}, 0, 0 }, + { "epcr56", 568, {0, {0}}, 0, 0 }, + { "epcr57", 569, {0, {0}}, 0, 0 }, + { "epcr58", 570, {0, {0}}, 0, 0 }, + { "epcr59", 571, {0, {0}}, 0, 0 }, + { "epcr60", 572, {0, {0}}, 0, 0 }, + { "epcr61", 573, {0, {0}}, 0, 0 }, + { "epcr62", 574, {0, {0}}, 0, 0 }, + { "epcr63", 575, {0, {0}}, 0, 0 }, + { "esr0", 576, {0, {0}}, 0, 0 }, + { "esr1", 577, {0, {0}}, 0, 0 }, + { "esr2", 578, {0, {0}}, 0, 0 }, + { "esr3", 579, {0, {0}}, 0, 0 }, + { "esr4", 580, {0, {0}}, 0, 0 }, + { "esr5", 581, {0, {0}}, 0, 0 }, + { "esr6", 582, {0, {0}}, 0, 0 }, + { "esr7", 583, {0, {0}}, 0, 0 }, + { "esr8", 584, {0, {0}}, 0, 0 }, + { "esr9", 585, {0, {0}}, 0, 0 }, + { "esr10", 586, {0, {0}}, 0, 0 }, + { "esr11", 587, {0, {0}}, 0, 0 }, + { "esr12", 588, {0, {0}}, 0, 0 }, + { "esr13", 589, {0, {0}}, 0, 0 }, + { "esr14", 590, {0, {0}}, 0, 0 }, + { "esr15", 591, {0, {0}}, 0, 0 }, + { "esr16", 592, {0, {0}}, 0, 0 }, + { "esr17", 593, {0, {0}}, 0, 0 }, + { "esr18", 594, {0, {0}}, 0, 0 }, + { "esr19", 595, {0, {0}}, 0, 0 }, + { "esr20", 596, {0, {0}}, 0, 0 }, + { "esr21", 597, {0, {0}}, 0, 0 }, + { "esr22", 598, {0, {0}}, 0, 0 }, + { "esr23", 599, {0, {0}}, 0, 0 }, + { "esr24", 600, {0, {0}}, 0, 0 }, + { "esr25", 601, {0, {0}}, 0, 0 }, + { "esr26", 602, {0, {0}}, 0, 0 }, + { "esr27", 603, {0, {0}}, 0, 0 }, + { "esr28", 604, {0, {0}}, 0, 0 }, + { "esr29", 605, {0, {0}}, 0, 0 }, + { "esr30", 606, {0, {0}}, 0, 0 }, + { "esr31", 607, {0, {0}}, 0, 0 }, + { "esr32", 608, {0, {0}}, 0, 0 }, + { "esr33", 609, {0, {0}}, 0, 0 }, + { "esr34", 610, {0, {0}}, 0, 0 }, + { "esr35", 611, {0, {0}}, 0, 0 }, + { "esr36", 612, {0, {0}}, 0, 0 }, + { "esr37", 613, {0, {0}}, 0, 0 }, + { "esr38", 614, {0, {0}}, 0, 0 }, + { "esr39", 615, {0, {0}}, 0, 0 }, + { "esr40", 616, {0, {0}}, 0, 0 }, + { "esr41", 617, {0, {0}}, 0, 0 }, + { "esr42", 618, {0, {0}}, 0, 0 }, + { "esr43", 619, {0, {0}}, 0, 0 }, + { "esr44", 620, {0, {0}}, 0, 0 }, + { "esr45", 621, {0, {0}}, 0, 0 }, + { "esr46", 622, {0, {0}}, 0, 0 }, + { "esr47", 623, {0, {0}}, 0, 0 }, + { "esr48", 624, {0, {0}}, 0, 0 }, + { "esr49", 625, {0, {0}}, 0, 0 }, + { "esr50", 626, {0, {0}}, 0, 0 }, + { "esr51", 627, {0, {0}}, 0, 0 }, + { "esr52", 628, {0, {0}}, 0, 0 }, + { "esr53", 629, {0, {0}}, 0, 0 }, + { "esr54", 630, {0, {0}}, 0, 0 }, + { "esr55", 631, {0, {0}}, 0, 0 }, + { "esr56", 632, {0, {0}}, 0, 0 }, + { "esr57", 633, {0, {0}}, 0, 0 }, + { "esr58", 634, {0, {0}}, 0, 0 }, + { "esr59", 635, {0, {0}}, 0, 0 }, + { "esr60", 636, {0, {0}}, 0, 0 }, + { "esr61", 637, {0, {0}}, 0, 0 }, + { "esr62", 638, {0, {0}}, 0, 0 }, + { "esr63", 639, {0, {0}}, 0, 0 }, + { "eir0", 640, {0, {0}}, 0, 0 }, + { "eir1", 641, {0, {0}}, 0, 0 }, + { "eir2", 642, {0, {0}}, 0, 0 }, + { "eir3", 643, {0, {0}}, 0, 0 }, + { "eir4", 644, {0, {0}}, 0, 0 }, + { "eir5", 645, {0, {0}}, 0, 0 }, + { "eir6", 646, {0, {0}}, 0, 0 }, + { "eir7", 647, {0, {0}}, 0, 0 }, + { "eir8", 648, {0, {0}}, 0, 0 }, + { "eir9", 649, {0, {0}}, 0, 0 }, + { "eir10", 650, {0, {0}}, 0, 0 }, + { "eir11", 651, {0, {0}}, 0, 0 }, + { "eir12", 652, {0, {0}}, 0, 0 }, + { "eir13", 653, {0, {0}}, 0, 0 }, + { "eir14", 654, {0, {0}}, 0, 0 }, + { "eir15", 655, {0, {0}}, 0, 0 }, + { "eir16", 656, {0, {0}}, 0, 0 }, + { "eir17", 657, {0, {0}}, 0, 0 }, + { "eir18", 658, {0, {0}}, 0, 0 }, + { "eir19", 659, {0, {0}}, 0, 0 }, + { "eir20", 660, {0, {0}}, 0, 0 }, + { "eir21", 661, {0, {0}}, 0, 0 }, + { "eir22", 662, {0, {0}}, 0, 0 }, + { "eir23", 663, {0, {0}}, 0, 0 }, + { "eir24", 664, {0, {0}}, 0, 0 }, + { "eir25", 665, {0, {0}}, 0, 0 }, + { "eir26", 666, {0, {0}}, 0, 0 }, + { "eir27", 667, {0, {0}}, 0, 0 }, + { "eir28", 668, {0, {0}}, 0, 0 }, + { "eir29", 669, {0, {0}}, 0, 0 }, + { "eir30", 670, {0, {0}}, 0, 0 }, + { "eir31", 671, {0, {0}}, 0, 0 }, + { "esfr0", 672, {0, {0}}, 0, 0 }, + { "esfr1", 673, {0, {0}}, 0, 0 }, + { "sr0", 768, {0, {0}}, 0, 0 }, + { "sr1", 769, {0, {0}}, 0, 0 }, + { "sr2", 770, {0, {0}}, 0, 0 }, + { "sr3", 771, {0, {0}}, 0, 0 }, + { "fsr0", 1024, {0, {0}}, 0, 0 }, + { "fsr1", 1025, {0, {0}}, 0, 0 }, + { "fsr2", 1026, {0, {0}}, 0, 0 }, + { "fsr3", 1027, {0, {0}}, 0, 0 }, + { "fsr4", 1028, {0, {0}}, 0, 0 }, + { "fsr5", 1029, {0, {0}}, 0, 0 }, + { "fsr6", 1030, {0, {0}}, 0, 0 }, + { "fsr7", 1031, {0, {0}}, 0, 0 }, + { "fsr8", 1032, {0, {0}}, 0, 0 }, + { "fsr9", 1033, {0, {0}}, 0, 0 }, + { "fsr10", 1034, {0, {0}}, 0, 0 }, + { "fsr11", 1035, {0, {0}}, 0, 0 }, + { "fsr12", 1036, {0, {0}}, 0, 0 }, + { "fsr13", 1037, {0, {0}}, 0, 0 }, + { "fsr14", 1038, {0, {0}}, 0, 0 }, + { "fsr15", 1039, {0, {0}}, 0, 0 }, + { "fsr16", 1040, {0, {0}}, 0, 0 }, + { "fsr17", 1041, {0, {0}}, 0, 0 }, + { "fsr18", 1042, {0, {0}}, 0, 0 }, + { "fsr19", 1043, {0, {0}}, 0, 0 }, + { "fsr20", 1044, {0, {0}}, 0, 0 }, + { "fsr21", 1045, {0, {0}}, 0, 0 }, + { "fsr22", 1046, {0, {0}}, 0, 0 }, + { "fsr23", 1047, {0, {0}}, 0, 0 }, + { "fsr24", 1048, {0, {0}}, 0, 0 }, + { "fsr25", 1049, {0, {0}}, 0, 0 }, + { "fsr26", 1050, {0, {0}}, 0, 0 }, + { "fsr27", 1051, {0, {0}}, 0, 0 }, + { "fsr28", 1052, {0, {0}}, 0, 0 }, + { "fsr29", 1053, {0, {0}}, 0, 0 }, + { "fsr30", 1054, {0, {0}}, 0, 0 }, + { "fsr31", 1055, {0, {0}}, 0, 0 }, + { "fsr32", 1056, {0, {0}}, 0, 0 }, + { "fsr33", 1057, {0, {0}}, 0, 0 }, + { "fsr34", 1058, {0, {0}}, 0, 0 }, + { "fsr35", 1059, {0, {0}}, 0, 0 }, + { "fsr36", 1060, {0, {0}}, 0, 0 }, + { "fsr37", 1061, {0, {0}}, 0, 0 }, + { "fsr38", 1062, {0, {0}}, 0, 0 }, + { "fsr39", 1063, {0, {0}}, 0, 0 }, + { "fsr40", 1064, {0, {0}}, 0, 0 }, + { "fsr41", 1065, {0, {0}}, 0, 0 }, + { "fsr42", 1066, {0, {0}}, 0, 0 }, + { "fsr43", 1067, {0, {0}}, 0, 0 }, + { "fsr44", 1068, {0, {0}}, 0, 0 }, + { "fsr45", 1069, {0, {0}}, 0, 0 }, + { "fsr46", 1070, {0, {0}}, 0, 0 }, + { "fsr47", 1071, {0, {0}}, 0, 0 }, + { "fsr48", 1072, {0, {0}}, 0, 0 }, + { "fsr49", 1073, {0, {0}}, 0, 0 }, + { "fsr50", 1074, {0, {0}}, 0, 0 }, + { "fsr51", 1075, {0, {0}}, 0, 0 }, + { "fsr52", 1076, {0, {0}}, 0, 0 }, + { "fsr53", 1077, {0, {0}}, 0, 0 }, + { "fsr54", 1078, {0, {0}}, 0, 0 }, + { "fsr55", 1079, {0, {0}}, 0, 0 }, + { "fsr56", 1080, {0, {0}}, 0, 0 }, + { "fsr57", 1081, {0, {0}}, 0, 0 }, + { "fsr58", 1082, {0, {0}}, 0, 0 }, + { "fsr59", 1083, {0, {0}}, 0, 0 }, + { "fsr60", 1084, {0, {0}}, 0, 0 }, + { "fsr61", 1085, {0, {0}}, 0, 0 }, + { "fsr62", 1086, {0, {0}}, 0, 0 }, + { "fsr63", 1087, {0, {0}}, 0, 0 }, + { "fqop0", 1088, {0, {0}}, 0, 0 }, + { "fqop1", 1090, {0, {0}}, 0, 0 }, + { "fqop2", 1092, {0, {0}}, 0, 0 }, + { "fqop3", 1094, {0, {0}}, 0, 0 }, + { "fqop4", 1096, {0, {0}}, 0, 0 }, + { "fqop5", 1098, {0, {0}}, 0, 0 }, + { "fqop6", 1100, {0, {0}}, 0, 0 }, + { "fqop7", 1102, {0, {0}}, 0, 0 }, + { "fqop8", 1104, {0, {0}}, 0, 0 }, + { "fqop9", 1106, {0, {0}}, 0, 0 }, + { "fqop10", 1108, {0, {0}}, 0, 0 }, + { "fqop11", 1110, {0, {0}}, 0, 0 }, + { "fqop12", 1112, {0, {0}}, 0, 0 }, + { "fqop13", 1114, {0, {0}}, 0, 0 }, + { "fqop14", 1116, {0, {0}}, 0, 0 }, + { "fqop15", 1118, {0, {0}}, 0, 0 }, + { "fqop16", 1120, {0, {0}}, 0, 0 }, + { "fqop17", 1122, {0, {0}}, 0, 0 }, + { "fqop18", 1124, {0, {0}}, 0, 0 }, + { "fqop19", 1126, {0, {0}}, 0, 0 }, + { "fqop20", 1128, {0, {0}}, 0, 0 }, + { "fqop21", 1130, {0, {0}}, 0, 0 }, + { "fqop22", 1132, {0, {0}}, 0, 0 }, + { "fqop23", 1134, {0, {0}}, 0, 0 }, + { "fqop24", 1136, {0, {0}}, 0, 0 }, + { "fqop25", 1138, {0, {0}}, 0, 0 }, + { "fqop26", 1140, {0, {0}}, 0, 0 }, + { "fqop27", 1142, {0, {0}}, 0, 0 }, + { "fqop28", 1144, {0, {0}}, 0, 0 }, + { "fqop29", 1146, {0, {0}}, 0, 0 }, + { "fqop30", 1148, {0, {0}}, 0, 0 }, + { "fqop31", 1150, {0, {0}}, 0, 0 }, + { "fqst0", 1089, {0, {0}}, 0, 0 }, + { "fqst1", 1091, {0, {0}}, 0, 0 }, + { "fqst2", 1093, {0, {0}}, 0, 0 }, + { "fqst3", 1095, {0, {0}}, 0, 0 }, + { "fqst4", 1097, {0, {0}}, 0, 0 }, + { "fqst5", 1099, {0, {0}}, 0, 0 }, + { "fqst6", 1101, {0, {0}}, 0, 0 }, + { "fqst7", 1103, {0, {0}}, 0, 0 }, + { "fqst8", 1105, {0, {0}}, 0, 0 }, + { "fqst9", 1107, {0, {0}}, 0, 0 }, + { "fqst10", 1109, {0, {0}}, 0, 0 }, + { "fqst11", 1111, {0, {0}}, 0, 0 }, + { "fqst12", 1113, {0, {0}}, 0, 0 }, + { "fqst13", 1115, {0, {0}}, 0, 0 }, + { "fqst14", 1117, {0, {0}}, 0, 0 }, + { "fqst15", 1119, {0, {0}}, 0, 0 }, + { "fqst16", 1121, {0, {0}}, 0, 0 }, + { "fqst17", 1123, {0, {0}}, 0, 0 }, + { "fqst18", 1125, {0, {0}}, 0, 0 }, + { "fqst19", 1127, {0, {0}}, 0, 0 }, + { "fqst20", 1129, {0, {0}}, 0, 0 }, + { "fqst21", 1131, {0, {0}}, 0, 0 }, + { "fqst22", 1133, {0, {0}}, 0, 0 }, + { "fqst23", 1135, {0, {0}}, 0, 0 }, + { "fqst24", 1137, {0, {0}}, 0, 0 }, + { "fqst25", 1139, {0, {0}}, 0, 0 }, + { "fqst26", 1141, {0, {0}}, 0, 0 }, + { "fqst27", 1143, {0, {0}}, 0, 0 }, + { "fqst28", 1145, {0, {0}}, 0, 0 }, + { "fqst29", 1147, {0, {0}}, 0, 0 }, + { "fqst30", 1149, {0, {0}}, 0, 0 }, + { "fqst31", 1151, {0, {0}}, 0, 0 }, + { "mcilr0", 1272, {0, {0}}, 0, 0 }, + { "mcilr1", 1273, {0, {0}}, 0, 0 }, + { "msr0", 1280, {0, {0}}, 0, 0 }, + { "msr1", 1281, {0, {0}}, 0, 0 }, + { "msr2", 1282, {0, {0}}, 0, 0 }, + { "msr3", 1283, {0, {0}}, 0, 0 }, + { "msr4", 1284, {0, {0}}, 0, 0 }, + { "msr5", 1285, {0, {0}}, 0, 0 }, + { "msr6", 1286, {0, {0}}, 0, 0 }, + { "msr7", 1287, {0, {0}}, 0, 0 }, + { "msr8", 1288, {0, {0}}, 0, 0 }, + { "msr9", 1289, {0, {0}}, 0, 0 }, + { "msr10", 1290, {0, {0}}, 0, 0 }, + { "msr11", 1291, {0, {0}}, 0, 0 }, + { "msr12", 1292, {0, {0}}, 0, 0 }, + { "msr13", 1293, {0, {0}}, 0, 0 }, + { "msr14", 1294, {0, {0}}, 0, 0 }, + { "msr15", 1295, {0, {0}}, 0, 0 }, + { "msr16", 1296, {0, {0}}, 0, 0 }, + { "msr17", 1297, {0, {0}}, 0, 0 }, + { "msr18", 1298, {0, {0}}, 0, 0 }, + { "msr19", 1299, {0, {0}}, 0, 0 }, + { "msr20", 1300, {0, {0}}, 0, 0 }, + { "msr21", 1301, {0, {0}}, 0, 0 }, + { "msr22", 1302, {0, {0}}, 0, 0 }, + { "msr23", 1303, {0, {0}}, 0, 0 }, + { "msr24", 1304, {0, {0}}, 0, 0 }, + { "msr25", 1305, {0, {0}}, 0, 0 }, + { "msr26", 1306, {0, {0}}, 0, 0 }, + { "msr27", 1307, {0, {0}}, 0, 0 }, + { "msr28", 1308, {0, {0}}, 0, 0 }, + { "msr29", 1309, {0, {0}}, 0, 0 }, + { "msr30", 1310, {0, {0}}, 0, 0 }, + { "msr31", 1311, {0, {0}}, 0, 0 }, + { "msr32", 1312, {0, {0}}, 0, 0 }, + { "msr33", 1313, {0, {0}}, 0, 0 }, + { "msr34", 1314, {0, {0}}, 0, 0 }, + { "msr35", 1315, {0, {0}}, 0, 0 }, + { "msr36", 1316, {0, {0}}, 0, 0 }, + { "msr37", 1317, {0, {0}}, 0, 0 }, + { "msr38", 1318, {0, {0}}, 0, 0 }, + { "msr39", 1319, {0, {0}}, 0, 0 }, + { "msr40", 1320, {0, {0}}, 0, 0 }, + { "msr41", 1321, {0, {0}}, 0, 0 }, + { "msr42", 1322, {0, {0}}, 0, 0 }, + { "msr43", 1323, {0, {0}}, 0, 0 }, + { "msr44", 1324, {0, {0}}, 0, 0 }, + { "msr45", 1325, {0, {0}}, 0, 0 }, + { "msr46", 1326, {0, {0}}, 0, 0 }, + { "msr47", 1327, {0, {0}}, 0, 0 }, + { "msr48", 1328, {0, {0}}, 0, 0 }, + { "msr49", 1329, {0, {0}}, 0, 0 }, + { "msr50", 1330, {0, {0}}, 0, 0 }, + { "msr51", 1331, {0, {0}}, 0, 0 }, + { "msr52", 1332, {0, {0}}, 0, 0 }, + { "msr53", 1333, {0, {0}}, 0, 0 }, + { "msr54", 1334, {0, {0}}, 0, 0 }, + { "msr55", 1335, {0, {0}}, 0, 0 }, + { "msr56", 1336, {0, {0}}, 0, 0 }, + { "msr57", 1337, {0, {0}}, 0, 0 }, + { "msr58", 1338, {0, {0}}, 0, 0 }, + { "msr59", 1339, {0, {0}}, 0, 0 }, + { "msr60", 1340, {0, {0}}, 0, 0 }, + { "msr61", 1341, {0, {0}}, 0, 0 }, + { "msr62", 1342, {0, {0}}, 0, 0 }, + { "msr63", 1343, {0, {0}}, 0, 0 }, + { "mqop0", 1344, {0, {0}}, 0, 0 }, + { "mqop1", 1346, {0, {0}}, 0, 0 }, + { "mqop2", 1348, {0, {0}}, 0, 0 }, + { "mqop3", 1350, {0, {0}}, 0, 0 }, + { "mqop4", 1352, {0, {0}}, 0, 0 }, + { "mqop5", 1354, {0, {0}}, 0, 0 }, + { "mqop6", 1356, {0, {0}}, 0, 0 }, + { "mqop7", 1358, {0, {0}}, 0, 0 }, + { "mqop8", 1360, {0, {0}}, 0, 0 }, + { "mqop9", 1362, {0, {0}}, 0, 0 }, + { "mqop10", 1364, {0, {0}}, 0, 0 }, + { "mqop11", 1366, {0, {0}}, 0, 0 }, + { "mqop12", 1368, {0, {0}}, 0, 0 }, + { "mqop13", 1370, {0, {0}}, 0, 0 }, + { "mqop14", 1372, {0, {0}}, 0, 0 }, + { "mqop15", 1374, {0, {0}}, 0, 0 }, + { "mqop16", 1376, {0, {0}}, 0, 0 }, + { "mqop17", 1378, {0, {0}}, 0, 0 }, + { "mqop18", 1380, {0, {0}}, 0, 0 }, + { "mqop19", 1382, {0, {0}}, 0, 0 }, + { "mqop20", 1384, {0, {0}}, 0, 0 }, + { "mqop21", 1386, {0, {0}}, 0, 0 }, + { "mqop22", 1388, {0, {0}}, 0, 0 }, + { "mqop23", 1390, {0, {0}}, 0, 0 }, + { "mqop24", 1392, {0, {0}}, 0, 0 }, + { "mqop25", 1394, {0, {0}}, 0, 0 }, + { "mqop26", 1396, {0, {0}}, 0, 0 }, + { "mqop27", 1398, {0, {0}}, 0, 0 }, + { "mqop28", 1400, {0, {0}}, 0, 0 }, + { "mqop29", 1402, {0, {0}}, 0, 0 }, + { "mqop30", 1404, {0, {0}}, 0, 0 }, + { "mqop31", 1406, {0, {0}}, 0, 0 }, + { "mqst0", 1345, {0, {0}}, 0, 0 }, + { "mqst1", 1347, {0, {0}}, 0, 0 }, + { "mqst2", 1349, {0, {0}}, 0, 0 }, + { "mqst3", 1351, {0, {0}}, 0, 0 }, + { "mqst4", 1353, {0, {0}}, 0, 0 }, + { "mqst5", 1355, {0, {0}}, 0, 0 }, + { "mqst6", 1357, {0, {0}}, 0, 0 }, + { "mqst7", 1359, {0, {0}}, 0, 0 }, + { "mqst8", 1361, {0, {0}}, 0, 0 }, + { "mqst9", 1363, {0, {0}}, 0, 0 }, + { "mqst10", 1365, {0, {0}}, 0, 0 }, + { "mqst11", 1367, {0, {0}}, 0, 0 }, + { "mqst12", 1369, {0, {0}}, 0, 0 }, + { "mqst13", 1371, {0, {0}}, 0, 0 }, + { "mqst14", 1373, {0, {0}}, 0, 0 }, + { "mqst15", 1375, {0, {0}}, 0, 0 }, + { "mqst16", 1377, {0, {0}}, 0, 0 }, + { "mqst17", 1379, {0, {0}}, 0, 0 }, + { "mqst18", 1381, {0, {0}}, 0, 0 }, + { "mqst19", 1383, {0, {0}}, 0, 0 }, + { "mqst20", 1385, {0, {0}}, 0, 0 }, + { "mqst21", 1387, {0, {0}}, 0, 0 }, + { "mqst22", 1389, {0, {0}}, 0, 0 }, + { "mqst23", 1391, {0, {0}}, 0, 0 }, + { "mqst24", 1393, {0, {0}}, 0, 0 }, + { "mqst25", 1395, {0, {0}}, 0, 0 }, + { "mqst26", 1397, {0, {0}}, 0, 0 }, + { "mqst27", 1399, {0, {0}}, 0, 0 }, + { "mqst28", 1401, {0, {0}}, 0, 0 }, + { "mqst29", 1403, {0, {0}}, 0, 0 }, + { "mqst30", 1405, {0, {0}}, 0, 0 }, + { "mqst31", 1407, {0, {0}}, 0, 0 }, + { "ear0", 1536, {0, {0}}, 0, 0 }, + { "ear1", 1537, {0, {0}}, 0, 0 }, + { "ear2", 1538, {0, {0}}, 0, 0 }, + { "ear3", 1539, {0, {0}}, 0, 0 }, + { "ear4", 1540, {0, {0}}, 0, 0 }, + { "ear5", 1541, {0, {0}}, 0, 0 }, + { "ear6", 1542, {0, {0}}, 0, 0 }, + { "ear7", 1543, {0, {0}}, 0, 0 }, + { "ear8", 1544, {0, {0}}, 0, 0 }, + { "ear9", 1545, {0, {0}}, 0, 0 }, + { "ear10", 1546, {0, {0}}, 0, 0 }, + { "ear11", 1547, {0, {0}}, 0, 0 }, + { "ear12", 1548, {0, {0}}, 0, 0 }, + { "ear13", 1549, {0, {0}}, 0, 0 }, + { "ear14", 1550, {0, {0}}, 0, 0 }, + { "ear15", 1551, {0, {0}}, 0, 0 }, + { "ear16", 1552, {0, {0}}, 0, 0 }, + { "ear17", 1553, {0, {0}}, 0, 0 }, + { "ear18", 1554, {0, {0}}, 0, 0 }, + { "ear19", 1555, {0, {0}}, 0, 0 }, + { "ear20", 1556, {0, {0}}, 0, 0 }, + { "ear21", 1557, {0, {0}}, 0, 0 }, + { "ear22", 1558, {0, {0}}, 0, 0 }, + { "ear23", 1559, {0, {0}}, 0, 0 }, + { "ear24", 1560, {0, {0}}, 0, 0 }, + { "ear25", 1561, {0, {0}}, 0, 0 }, + { "ear26", 1562, {0, {0}}, 0, 0 }, + { "ear27", 1563, {0, {0}}, 0, 0 }, + { "ear28", 1564, {0, {0}}, 0, 0 }, + { "ear29", 1565, {0, {0}}, 0, 0 }, + { "ear30", 1566, {0, {0}}, 0, 0 }, + { "ear31", 1567, {0, {0}}, 0, 0 }, + { "ear32", 1568, {0, {0}}, 0, 0 }, + { "ear33", 1569, {0, {0}}, 0, 0 }, + { "ear34", 1570, {0, {0}}, 0, 0 }, + { "ear35", 1571, {0, {0}}, 0, 0 }, + { "ear36", 1572, {0, {0}}, 0, 0 }, + { "ear37", 1573, {0, {0}}, 0, 0 }, + { "ear38", 1574, {0, {0}}, 0, 0 }, + { "ear39", 1575, {0, {0}}, 0, 0 }, + { "ear40", 1576, {0, {0}}, 0, 0 }, + { "ear41", 1577, {0, {0}}, 0, 0 }, + { "ear42", 1578, {0, {0}}, 0, 0 }, + { "ear43", 1579, {0, {0}}, 0, 0 }, + { "ear44", 1580, {0, {0}}, 0, 0 }, + { "ear45", 1581, {0, {0}}, 0, 0 }, + { "ear46", 1582, {0, {0}}, 0, 0 }, + { "ear47", 1583, {0, {0}}, 0, 0 }, + { "ear48", 1584, {0, {0}}, 0, 0 }, + { "ear49", 1585, {0, {0}}, 0, 0 }, + { "ear50", 1586, {0, {0}}, 0, 0 }, + { "ear51", 1587, {0, {0}}, 0, 0 }, + { "ear52", 1588, {0, {0}}, 0, 0 }, + { "ear53", 1589, {0, {0}}, 0, 0 }, + { "ear54", 1590, {0, {0}}, 0, 0 }, + { "ear55", 1591, {0, {0}}, 0, 0 }, + { "ear56", 1592, {0, {0}}, 0, 0 }, + { "ear57", 1593, {0, {0}}, 0, 0 }, + { "ear58", 1594, {0, {0}}, 0, 0 }, + { "ear59", 1595, {0, {0}}, 0, 0 }, + { "ear60", 1596, {0, {0}}, 0, 0 }, + { "ear61", 1597, {0, {0}}, 0, 0 }, + { "ear62", 1598, {0, {0}}, 0, 0 }, + { "ear63", 1599, {0, {0}}, 0, 0 }, + { "edr0", 1600, {0, {0}}, 0, 0 }, + { "edr1", 1601, {0, {0}}, 0, 0 }, + { "edr2", 1602, {0, {0}}, 0, 0 }, + { "edr3", 1603, {0, {0}}, 0, 0 }, + { "edr4", 1604, {0, {0}}, 0, 0 }, + { "edr5", 1605, {0, {0}}, 0, 0 }, + { "edr6", 1606, {0, {0}}, 0, 0 }, + { "edr7", 1607, {0, {0}}, 0, 0 }, + { "edr8", 1608, {0, {0}}, 0, 0 }, + { "edr9", 1609, {0, {0}}, 0, 0 }, + { "edr10", 1610, {0, {0}}, 0, 0 }, + { "edr11", 1611, {0, {0}}, 0, 0 }, + { "edr12", 1612, {0, {0}}, 0, 0 }, + { "edr13", 1613, {0, {0}}, 0, 0 }, + { "edr14", 1614, {0, {0}}, 0, 0 }, + { "edr15", 1615, {0, {0}}, 0, 0 }, + { "edr16", 1616, {0, {0}}, 0, 0 }, + { "edr17", 1617, {0, {0}}, 0, 0 }, + { "edr18", 1618, {0, {0}}, 0, 0 }, + { "edr19", 1619, {0, {0}}, 0, 0 }, + { "edr20", 1620, {0, {0}}, 0, 0 }, + { "edr21", 1621, {0, {0}}, 0, 0 }, + { "edr22", 1622, {0, {0}}, 0, 0 }, + { "edr23", 1623, {0, {0}}, 0, 0 }, + { "edr24", 1624, {0, {0}}, 0, 0 }, + { "edr25", 1625, {0, {0}}, 0, 0 }, + { "edr26", 1626, {0, {0}}, 0, 0 }, + { "edr27", 1627, {0, {0}}, 0, 0 }, + { "edr28", 1628, {0, {0}}, 0, 0 }, + { "edr29", 1629, {0, {0}}, 0, 0 }, + { "edr30", 1630, {0, {0}}, 0, 0 }, + { "edr31", 1631, {0, {0}}, 0, 0 }, + { "edr32", 1632, {0, {0}}, 0, 0 }, + { "edr33", 1636, {0, {0}}, 0, 0 }, + { "edr34", 1634, {0, {0}}, 0, 0 }, + { "edr35", 1635, {0, {0}}, 0, 0 }, + { "edr36", 1636, {0, {0}}, 0, 0 }, + { "edr37", 1637, {0, {0}}, 0, 0 }, + { "edr38", 1638, {0, {0}}, 0, 0 }, + { "edr39", 1639, {0, {0}}, 0, 0 }, + { "edr40", 1640, {0, {0}}, 0, 0 }, + { "edr41", 1641, {0, {0}}, 0, 0 }, + { "edr42", 1642, {0, {0}}, 0, 0 }, + { "edr43", 1643, {0, {0}}, 0, 0 }, + { "edr44", 1644, {0, {0}}, 0, 0 }, + { "edr45", 1645, {0, {0}}, 0, 0 }, + { "edr46", 1646, {0, {0}}, 0, 0 }, + { "edr47", 1647, {0, {0}}, 0, 0 }, + { "edr48", 1648, {0, {0}}, 0, 0 }, + { "edr49", 1649, {0, {0}}, 0, 0 }, + { "edr50", 1650, {0, {0}}, 0, 0 }, + { "edr51", 1651, {0, {0}}, 0, 0 }, + { "edr52", 1652, {0, {0}}, 0, 0 }, + { "edr53", 1653, {0, {0}}, 0, 0 }, + { "edr54", 1654, {0, {0}}, 0, 0 }, + { "edr55", 1655, {0, {0}}, 0, 0 }, + { "edr56", 1656, {0, {0}}, 0, 0 }, + { "edr57", 1657, {0, {0}}, 0, 0 }, + { "edr58", 1658, {0, {0}}, 0, 0 }, + { "edr59", 1659, {0, {0}}, 0, 0 }, + { "edr60", 1660, {0, {0}}, 0, 0 }, + { "edr61", 1661, {0, {0}}, 0, 0 }, + { "edr62", 1662, {0, {0}}, 0, 0 }, + { "edr63", 1663, {0, {0}}, 0, 0 }, + { "iamlr0", 1664, {0, {0}}, 0, 0 }, + { "iamlr1", 1665, {0, {0}}, 0, 0 }, + { "iamlr2", 1666, {0, {0}}, 0, 0 }, + { "iamlr3", 1667, {0, {0}}, 0, 0 }, + { "iamlr4", 1668, {0, {0}}, 0, 0 }, + { "iamlr5", 1669, {0, {0}}, 0, 0 }, + { "iamlr6", 1670, {0, {0}}, 0, 0 }, + { "iamlr7", 1671, {0, {0}}, 0, 0 }, + { "iamlr8", 1672, {0, {0}}, 0, 0 }, + { "iamlr9", 1673, {0, {0}}, 0, 0 }, + { "iamlr10", 1674, {0, {0}}, 0, 0 }, + { "iamlr11", 1675, {0, {0}}, 0, 0 }, + { "iamlr12", 1676, {0, {0}}, 0, 0 }, + { "iamlr13", 1677, {0, {0}}, 0, 0 }, + { "iamlr14", 1678, {0, {0}}, 0, 0 }, + { "iamlr15", 1679, {0, {0}}, 0, 0 }, + { "iamlr16", 1680, {0, {0}}, 0, 0 }, + { "iamlr17", 1681, {0, {0}}, 0, 0 }, + { "iamlr18", 1682, {0, {0}}, 0, 0 }, + { "iamlr19", 1683, {0, {0}}, 0, 0 }, + { "iamlr20", 1684, {0, {0}}, 0, 0 }, + { "iamlr21", 1685, {0, {0}}, 0, 0 }, + { "iamlr22", 1686, {0, {0}}, 0, 0 }, + { "iamlr23", 1687, {0, {0}}, 0, 0 }, + { "iamlr24", 1688, {0, {0}}, 0, 0 }, + { "iamlr25", 1689, {0, {0}}, 0, 0 }, + { "iamlr26", 1690, {0, {0}}, 0, 0 }, + { "iamlr27", 1691, {0, {0}}, 0, 0 }, + { "iamlr28", 1692, {0, {0}}, 0, 0 }, + { "iamlr29", 1693, {0, {0}}, 0, 0 }, + { "iamlr30", 1694, {0, {0}}, 0, 0 }, + { "iamlr31", 1695, {0, {0}}, 0, 0 }, + { "iamlr32", 1696, {0, {0}}, 0, 0 }, + { "iamlr33", 1697, {0, {0}}, 0, 0 }, + { "iamlr34", 1698, {0, {0}}, 0, 0 }, + { "iamlr35", 1699, {0, {0}}, 0, 0 }, + { "iamlr36", 1700, {0, {0}}, 0, 0 }, + { "iamlr37", 1701, {0, {0}}, 0, 0 }, + { "iamlr38", 1702, {0, {0}}, 0, 0 }, + { "iamlr39", 1703, {0, {0}}, 0, 0 }, + { "iamlr40", 1704, {0, {0}}, 0, 0 }, + { "iamlr41", 1705, {0, {0}}, 0, 0 }, + { "iamlr42", 1706, {0, {0}}, 0, 0 }, + { "iamlr43", 1707, {0, {0}}, 0, 0 }, + { "iamlr44", 1708, {0, {0}}, 0, 0 }, + { "iamlr45", 1709, {0, {0}}, 0, 0 }, + { "iamlr46", 1710, {0, {0}}, 0, 0 }, + { "iamlr47", 1711, {0, {0}}, 0, 0 }, + { "iamlr48", 1712, {0, {0}}, 0, 0 }, + { "iamlr49", 1713, {0, {0}}, 0, 0 }, + { "iamlr50", 1714, {0, {0}}, 0, 0 }, + { "iamlr51", 1715, {0, {0}}, 0, 0 }, + { "iamlr52", 1716, {0, {0}}, 0, 0 }, + { "iamlr53", 1717, {0, {0}}, 0, 0 }, + { "iamlr54", 1718, {0, {0}}, 0, 0 }, + { "iamlr55", 1719, {0, {0}}, 0, 0 }, + { "iamlr56", 1720, {0, {0}}, 0, 0 }, + { "iamlr57", 1721, {0, {0}}, 0, 0 }, + { "iamlr58", 1722, {0, {0}}, 0, 0 }, + { "iamlr59", 1723, {0, {0}}, 0, 0 }, + { "iamlr60", 1724, {0, {0}}, 0, 0 }, + { "iamlr61", 1725, {0, {0}}, 0, 0 }, + { "iamlr62", 1726, {0, {0}}, 0, 0 }, + { "iamlr63", 1727, {0, {0}}, 0, 0 }, + { "iampr0", 1728, {0, {0}}, 0, 0 }, + { "iampr1", 1729, {0, {0}}, 0, 0 }, + { "iampr2", 1730, {0, {0}}, 0, 0 }, + { "iampr3", 1731, {0, {0}}, 0, 0 }, + { "iampr4", 1732, {0, {0}}, 0, 0 }, + { "iampr5", 1733, {0, {0}}, 0, 0 }, + { "iampr6", 1734, {0, {0}}, 0, 0 }, + { "iampr7", 1735, {0, {0}}, 0, 0 }, + { "iampr8", 1736, {0, {0}}, 0, 0 }, + { "iampr9", 1737, {0, {0}}, 0, 0 }, + { "iampr10", 1738, {0, {0}}, 0, 0 }, + { "iampr11", 1739, {0, {0}}, 0, 0 }, + { "iampr12", 1740, {0, {0}}, 0, 0 }, + { "iampr13", 1741, {0, {0}}, 0, 0 }, + { "iampr14", 1742, {0, {0}}, 0, 0 }, + { "iampr15", 1743, {0, {0}}, 0, 0 }, + { "iampr16", 1744, {0, {0}}, 0, 0 }, + { "iampr17", 1745, {0, {0}}, 0, 0 }, + { "iampr18", 1746, {0, {0}}, 0, 0 }, + { "iampr19", 1747, {0, {0}}, 0, 0 }, + { "iampr20", 1748, {0, {0}}, 0, 0 }, + { "iampr21", 1749, {0, {0}}, 0, 0 }, + { "iampr22", 1750, {0, {0}}, 0, 0 }, + { "iampr23", 1751, {0, {0}}, 0, 0 }, + { "iampr24", 1752, {0, {0}}, 0, 0 }, + { "iampr25", 1753, {0, {0}}, 0, 0 }, + { "iampr26", 1754, {0, {0}}, 0, 0 }, + { "iampr27", 1755, {0, {0}}, 0, 0 }, + { "iampr28", 1756, {0, {0}}, 0, 0 }, + { "iampr29", 1757, {0, {0}}, 0, 0 }, + { "iampr30", 1758, {0, {0}}, 0, 0 }, + { "iampr31", 1759, {0, {0}}, 0, 0 }, + { "iampr32", 1760, {0, {0}}, 0, 0 }, + { "iampr33", 1761, {0, {0}}, 0, 0 }, + { "iampr34", 1762, {0, {0}}, 0, 0 }, + { "iampr35", 1763, {0, {0}}, 0, 0 }, + { "iampr36", 1764, {0, {0}}, 0, 0 }, + { "iampr37", 1765, {0, {0}}, 0, 0 }, + { "iampr38", 1766, {0, {0}}, 0, 0 }, + { "iampr39", 1767, {0, {0}}, 0, 0 }, + { "iampr40", 1768, {0, {0}}, 0, 0 }, + { "iampr41", 1769, {0, {0}}, 0, 0 }, + { "iampr42", 1770, {0, {0}}, 0, 0 }, + { "iampr43", 1771, {0, {0}}, 0, 0 }, + { "iampr44", 1772, {0, {0}}, 0, 0 }, + { "iampr45", 1773, {0, {0}}, 0, 0 }, + { "iampr46", 1774, {0, {0}}, 0, 0 }, + { "iampr47", 1775, {0, {0}}, 0, 0 }, + { "iampr48", 1776, {0, {0}}, 0, 0 }, + { "iampr49", 1777, {0, {0}}, 0, 0 }, + { "iampr50", 1778, {0, {0}}, 0, 0 }, + { "iampr51", 1779, {0, {0}}, 0, 0 }, + { "iampr52", 1780, {0, {0}}, 0, 0 }, + { "iampr53", 1781, {0, {0}}, 0, 0 }, + { "iampr54", 1782, {0, {0}}, 0, 0 }, + { "iampr55", 1783, {0, {0}}, 0, 0 }, + { "iampr56", 1784, {0, {0}}, 0, 0 }, + { "iampr57", 1785, {0, {0}}, 0, 0 }, + { "iampr58", 1786, {0, {0}}, 0, 0 }, + { "iampr59", 1787, {0, {0}}, 0, 0 }, + { "iampr60", 1788, {0, {0}}, 0, 0 }, + { "iampr61", 1789, {0, {0}}, 0, 0 }, + { "iampr62", 1790, {0, {0}}, 0, 0 }, + { "iampr63", 1791, {0, {0}}, 0, 0 }, + { "damlr0", 1792, {0, {0}}, 0, 0 }, + { "damlr1", 1793, {0, {0}}, 0, 0 }, + { "damlr2", 1794, {0, {0}}, 0, 0 }, + { "damlr3", 1795, {0, {0}}, 0, 0 }, + { "damlr4", 1796, {0, {0}}, 0, 0 }, + { "damlr5", 1797, {0, {0}}, 0, 0 }, + { "damlr6", 1798, {0, {0}}, 0, 0 }, + { "damlr7", 1799, {0, {0}}, 0, 0 }, + { "damlr8", 1800, {0, {0}}, 0, 0 }, + { "damlr9", 1801, {0, {0}}, 0, 0 }, + { "damlr10", 1802, {0, {0}}, 0, 0 }, + { "damlr11", 1803, {0, {0}}, 0, 0 }, + { "damlr12", 1804, {0, {0}}, 0, 0 }, + { "damlr13", 1805, {0, {0}}, 0, 0 }, + { "damlr14", 1806, {0, {0}}, 0, 0 }, + { "damlr15", 1807, {0, {0}}, 0, 0 }, + { "damlr16", 1808, {0, {0}}, 0, 0 }, + { "damlr17", 1809, {0, {0}}, 0, 0 }, + { "damlr18", 1810, {0, {0}}, 0, 0 }, + { "damlr19", 1811, {0, {0}}, 0, 0 }, + { "damlr20", 1812, {0, {0}}, 0, 0 }, + { "damlr21", 1813, {0, {0}}, 0, 0 }, + { "damlr22", 1814, {0, {0}}, 0, 0 }, + { "damlr23", 1815, {0, {0}}, 0, 0 }, + { "damlr24", 1816, {0, {0}}, 0, 0 }, + { "damlr25", 1817, {0, {0}}, 0, 0 }, + { "damlr26", 1818, {0, {0}}, 0, 0 }, + { "damlr27", 1819, {0, {0}}, 0, 0 }, + { "damlr28", 1820, {0, {0}}, 0, 0 }, + { "damlr29", 1821, {0, {0}}, 0, 0 }, + { "damlr30", 1822, {0, {0}}, 0, 0 }, + { "damlr31", 1823, {0, {0}}, 0, 0 }, + { "damlr32", 1824, {0, {0}}, 0, 0 }, + { "damlr33", 1825, {0, {0}}, 0, 0 }, + { "damlr34", 1826, {0, {0}}, 0, 0 }, + { "damlr35", 1827, {0, {0}}, 0, 0 }, + { "damlr36", 1828, {0, {0}}, 0, 0 }, + { "damlr37", 1829, {0, {0}}, 0, 0 }, + { "damlr38", 1830, {0, {0}}, 0, 0 }, + { "damlr39", 1831, {0, {0}}, 0, 0 }, + { "damlr40", 1832, {0, {0}}, 0, 0 }, + { "damlr41", 1833, {0, {0}}, 0, 0 }, + { "damlr42", 1834, {0, {0}}, 0, 0 }, + { "damlr43", 1835, {0, {0}}, 0, 0 }, + { "damlr44", 1836, {0, {0}}, 0, 0 }, + { "damlr45", 1837, {0, {0}}, 0, 0 }, + { "damlr46", 1838, {0, {0}}, 0, 0 }, + { "damlr47", 1839, {0, {0}}, 0, 0 }, + { "damlr48", 1840, {0, {0}}, 0, 0 }, + { "damlr49", 1841, {0, {0}}, 0, 0 }, + { "damlr50", 1842, {0, {0}}, 0, 0 }, + { "damlr51", 1843, {0, {0}}, 0, 0 }, + { "damlr52", 1844, {0, {0}}, 0, 0 }, + { "damlr53", 1845, {0, {0}}, 0, 0 }, + { "damlr54", 1846, {0, {0}}, 0, 0 }, + { "damlr55", 1847, {0, {0}}, 0, 0 }, + { "damlr56", 1848, {0, {0}}, 0, 0 }, + { "damlr57", 1849, {0, {0}}, 0, 0 }, + { "damlr58", 1850, {0, {0}}, 0, 0 }, + { "damlr59", 1851, {0, {0}}, 0, 0 }, + { "damlr60", 1852, {0, {0}}, 0, 0 }, + { "damlr61", 1853, {0, {0}}, 0, 0 }, + { "damlr62", 1854, {0, {0}}, 0, 0 }, + { "damlr63", 1855, {0, {0}}, 0, 0 }, + { "dampr0", 1856, {0, {0}}, 0, 0 }, + { "dampr1", 1857, {0, {0}}, 0, 0 }, + { "dampr2", 1858, {0, {0}}, 0, 0 }, + { "dampr3", 1859, {0, {0}}, 0, 0 }, + { "dampr4", 1860, {0, {0}}, 0, 0 }, + { "dampr5", 1861, {0, {0}}, 0, 0 }, + { "dampr6", 1862, {0, {0}}, 0, 0 }, + { "dampr7", 1863, {0, {0}}, 0, 0 }, + { "dampr8", 1864, {0, {0}}, 0, 0 }, + { "dampr9", 1865, {0, {0}}, 0, 0 }, + { "dampr10", 1866, {0, {0}}, 0, 0 }, + { "dampr11", 1867, {0, {0}}, 0, 0 }, + { "dampr12", 1868, {0, {0}}, 0, 0 }, + { "dampr13", 1869, {0, {0}}, 0, 0 }, + { "dampr14", 1870, {0, {0}}, 0, 0 }, + { "dampr15", 1871, {0, {0}}, 0, 0 }, + { "dampr16", 1872, {0, {0}}, 0, 0 }, + { "dampr17", 1873, {0, {0}}, 0, 0 }, + { "dampr18", 1874, {0, {0}}, 0, 0 }, + { "dampr19", 1875, {0, {0}}, 0, 0 }, + { "dampr20", 1876, {0, {0}}, 0, 0 }, + { "dampr21", 1877, {0, {0}}, 0, 0 }, + { "dampr22", 1878, {0, {0}}, 0, 0 }, + { "dampr23", 1879, {0, {0}}, 0, 0 }, + { "dampr24", 1880, {0, {0}}, 0, 0 }, + { "dampr25", 1881, {0, {0}}, 0, 0 }, + { "dampr26", 1882, {0, {0}}, 0, 0 }, + { "dampr27", 1883, {0, {0}}, 0, 0 }, + { "dampr28", 1884, {0, {0}}, 0, 0 }, + { "dampr29", 1885, {0, {0}}, 0, 0 }, + { "dampr30", 1886, {0, {0}}, 0, 0 }, + { "dampr31", 1887, {0, {0}}, 0, 0 }, + { "dampr32", 1888, {0, {0}}, 0, 0 }, + { "dampr33", 1889, {0, {0}}, 0, 0 }, + { "dampr34", 1890, {0, {0}}, 0, 0 }, + { "dampr35", 1891, {0, {0}}, 0, 0 }, + { "dampr36", 1892, {0, {0}}, 0, 0 }, + { "dampr37", 1893, {0, {0}}, 0, 0 }, + { "dampr38", 1894, {0, {0}}, 0, 0 }, + { "dampr39", 1895, {0, {0}}, 0, 0 }, + { "dampr40", 1896, {0, {0}}, 0, 0 }, + { "dampr41", 1897, {0, {0}}, 0, 0 }, + { "dampr42", 1898, {0, {0}}, 0, 0 }, + { "dampr43", 1899, {0, {0}}, 0, 0 }, + { "dampr44", 1900, {0, {0}}, 0, 0 }, + { "dampr45", 1901, {0, {0}}, 0, 0 }, + { "dampr46", 1902, {0, {0}}, 0, 0 }, + { "dampr47", 1903, {0, {0}}, 0, 0 }, + { "dampr48", 1904, {0, {0}}, 0, 0 }, + { "dampr49", 1905, {0, {0}}, 0, 0 }, + { "dampr50", 1906, {0, {0}}, 0, 0 }, + { "dampr51", 1907, {0, {0}}, 0, 0 }, + { "dampr52", 1908, {0, {0}}, 0, 0 }, + { "dampr53", 1909, {0, {0}}, 0, 0 }, + { "dampr54", 1910, {0, {0}}, 0, 0 }, + { "dampr55", 1911, {0, {0}}, 0, 0 }, + { "dampr56", 1912, {0, {0}}, 0, 0 }, + { "dampr57", 1913, {0, {0}}, 0, 0 }, + { "dampr58", 1914, {0, {0}}, 0, 0 }, + { "dampr59", 1915, {0, {0}}, 0, 0 }, + { "dampr60", 1916, {0, {0}}, 0, 0 }, + { "dampr61", 1917, {0, {0}}, 0, 0 }, + { "dampr62", 1918, {0, {0}}, 0, 0 }, + { "dampr63", 1919, {0, {0}}, 0, 0 }, + { "amcr", 1920, {0, {0}}, 0, 0 }, + { "stbar", 1921, {0, {0}}, 0, 0 }, + { "mmcr", 1922, {0, {0}}, 0, 0 }, + { "dcr", 2048, {0, {0}}, 0, 0 }, + { "brr", 2049, {0, {0}}, 0, 0 }, + { "nmar", 2050, {0, {0}}, 0, 0 }, + { "ibar0", 2052, {0, {0}}, 0, 0 }, + { "ibar1", 2053, {0, {0}}, 0, 0 }, + { "ibar2", 2054, {0, {0}}, 0, 0 }, + { "ibar3", 2055, {0, {0}}, 0, 0 }, + { "dbar0", 2056, {0, {0}}, 0, 0 }, + { "dbar1", 2057, {0, {0}}, 0, 0 }, + { "dbar2", 2058, {0, {0}}, 0, 0 }, + { "dbar3", 2059, {0, {0}}, 0, 0 }, + { "dbdr00", 2060, {0, {0}}, 0, 0 }, + { "dbdr01", 2061, {0, {0}}, 0, 0 }, + { "dbdr02", 2062, {0, {0}}, 0, 0 }, + { "dbdr03", 2063, {0, {0}}, 0, 0 }, + { "dbdr10", 2064, {0, {0}}, 0, 0 }, + { "dbdr11", 2065, {0, {0}}, 0, 0 }, + { "dbdr12", 2066, {0, {0}}, 0, 0 }, + { "dbdr13", 2067, {0, {0}}, 0, 0 }, + { "dbdr20", 2068, {0, {0}}, 0, 0 }, + { "dbdr21", 2069, {0, {0}}, 0, 0 }, + { "dbdr22", 2070, {0, {0}}, 0, 0 }, + { "dbdr23", 2071, {0, {0}}, 0, 0 }, + { "dbdr30", 2072, {0, {0}}, 0, 0 }, + { "dbdr31", 2073, {0, {0}}, 0, 0 }, + { "dbdr32", 2074, {0, {0}}, 0, 0 }, + { "dbdr33", 2075, {0, {0}}, 0, 0 }, + { "dbmr00", 2076, {0, {0}}, 0, 0 }, + { "dbmr01", 2077, {0, {0}}, 0, 0 }, + { "dbmr02", 2078, {0, {0}}, 0, 0 }, + { "dbmr03", 2079, {0, {0}}, 0, 0 }, + { "dbmr10", 2080, {0, {0}}, 0, 0 }, + { "dbmr11", 2081, {0, {0}}, 0, 0 }, + { "dbmr12", 2082, {0, {0}}, 0, 0 }, + { "dbmr13", 2083, {0, {0}}, 0, 0 }, + { "dbmr20", 2084, {0, {0}}, 0, 0 }, + { "dbmr21", 2085, {0, {0}}, 0, 0 }, + { "dbmr22", 2086, {0, {0}}, 0, 0 }, + { "dbmr23", 2087, {0, {0}}, 0, 0 }, + { "dbmr30", 2088, {0, {0}}, 0, 0 }, + { "dbmr31", 2089, {0, {0}}, 0, 0 }, + { "dbmr32", 2090, {0, {0}}, 0, 0 }, + { "dbmr33", 2091, {0, {0}}, 0, 0 }, + { "cpcfr", 2092, {0, {0}}, 0, 0 }, + { "cpcr", 2093, {0, {0}}, 0, 0 }, + { "cpsr", 2094, {0, {0}}, 0, 0 }, + { "cpesr0", 2096, {0, {0}}, 0, 0 }, + { "cpesr1", 2097, {0, {0}}, 0, 0 }, + { "cpemr0", 2098, {0, {0}}, 0, 0 }, + { "cpemr1", 2099, {0, {0}}, 0, 0 }, + { "ihsr8", 3848, {0, {0}}, 0, 0 } +}; + +CGEN_KEYWORD frv_cgen_opval_spr_names = +{ + & frv_cgen_opval_spr_names_entries[0], + 1005, + 0, 0, 0, 0, "" +}; + +static CGEN_KEYWORD_ENTRY frv_cgen_opval_accg_names_entries[] = +{ + { "accg0", 0, {0, {0}}, 0, 0 }, + { "accg1", 1, {0, {0}}, 0, 0 }, + { "accg2", 2, {0, {0}}, 0, 0 }, + { "accg3", 3, {0, {0}}, 0, 0 }, + { "accg4", 4, {0, {0}}, 0, 0 }, + { "accg5", 5, {0, {0}}, 0, 0 }, + { "accg6", 6, {0, {0}}, 0, 0 }, + { "accg7", 7, {0, {0}}, 0, 0 }, + { "accg8", 8, {0, {0}}, 0, 0 }, + { "accg9", 9, {0, {0}}, 0, 0 }, + { "accg10", 10, {0, {0}}, 0, 0 }, + { "accg11", 11, {0, {0}}, 0, 0 }, + { "accg12", 12, {0, {0}}, 0, 0 }, + { "accg13", 13, {0, {0}}, 0, 0 }, + { "accg14", 14, {0, {0}}, 0, 0 }, + { "accg15", 15, {0, {0}}, 0, 0 }, + { "accg16", 16, {0, {0}}, 0, 0 }, + { "accg17", 17, {0, {0}}, 0, 0 }, + { "accg18", 18, {0, {0}}, 0, 0 }, + { "accg19", 19, {0, {0}}, 0, 0 }, + { "accg20", 20, {0, {0}}, 0, 0 }, + { "accg21", 21, {0, {0}}, 0, 0 }, + { "accg22", 22, {0, {0}}, 0, 0 }, + { "accg23", 23, {0, {0}}, 0, 0 }, + { "accg24", 24, {0, {0}}, 0, 0 }, + { "accg25", 25, {0, {0}}, 0, 0 }, + { "accg26", 26, {0, {0}}, 0, 0 }, + { "accg27", 27, {0, {0}}, 0, 0 }, + { "accg28", 28, {0, {0}}, 0, 0 }, + { "accg29", 29, {0, {0}}, 0, 0 }, + { "accg30", 30, {0, {0}}, 0, 0 }, + { "accg31", 31, {0, {0}}, 0, 0 }, + { "accg32", 32, {0, {0}}, 0, 0 }, + { "accg33", 33, {0, {0}}, 0, 0 }, + { "accg34", 34, {0, {0}}, 0, 0 }, + { "accg35", 35, {0, {0}}, 0, 0 }, + { "accg36", 36, {0, {0}}, 0, 0 }, + { "accg37", 37, {0, {0}}, 0, 0 }, + { "accg38", 38, {0, {0}}, 0, 0 }, + { "accg39", 39, {0, {0}}, 0, 0 }, + { "accg40", 40, {0, {0}}, 0, 0 }, + { "accg41", 41, {0, {0}}, 0, 0 }, + { "accg42", 42, {0, {0}}, 0, 0 }, + { "accg43", 43, {0, {0}}, 0, 0 }, + { "accg44", 44, {0, {0}}, 0, 0 }, + { "accg45", 45, {0, {0}}, 0, 0 }, + { "accg46", 46, {0, {0}}, 0, 0 }, + { "accg47", 47, {0, {0}}, 0, 0 }, + { "accg48", 48, {0, {0}}, 0, 0 }, + { "accg49", 49, {0, {0}}, 0, 0 }, + { "accg50", 50, {0, {0}}, 0, 0 }, + { "accg51", 51, {0, {0}}, 0, 0 }, + { "accg52", 52, {0, {0}}, 0, 0 }, + { "accg53", 53, {0, {0}}, 0, 0 }, + { "accg54", 54, {0, {0}}, 0, 0 }, + { "accg55", 55, {0, {0}}, 0, 0 }, + { "accg56", 56, {0, {0}}, 0, 0 }, + { "accg57", 57, {0, {0}}, 0, 0 }, + { "accg58", 58, {0, {0}}, 0, 0 }, + { "accg59", 59, {0, {0}}, 0, 0 }, + { "accg60", 60, {0, {0}}, 0, 0 }, + { "accg61", 61, {0, {0}}, 0, 0 }, + { "accg62", 62, {0, {0}}, 0, 0 }, + { "accg63", 63, {0, {0}}, 0, 0 } +}; + +CGEN_KEYWORD frv_cgen_opval_accg_names = +{ + & frv_cgen_opval_accg_names_entries[0], + 64, + 0, 0, 0, 0, "" +}; + +static CGEN_KEYWORD_ENTRY frv_cgen_opval_acc_names_entries[] = +{ + { "acc0", 0, {0, {0}}, 0, 0 }, + { "acc1", 1, {0, {0}}, 0, 0 }, + { "acc2", 2, {0, {0}}, 0, 0 }, + { "acc3", 3, {0, {0}}, 0, 0 }, + { "acc4", 4, {0, {0}}, 0, 0 }, + { "acc5", 5, {0, {0}}, 0, 0 }, + { "acc6", 6, {0, {0}}, 0, 0 }, + { "acc7", 7, {0, {0}}, 0, 0 }, + { "acc8", 8, {0, {0}}, 0, 0 }, + { "acc9", 9, {0, {0}}, 0, 0 }, + { "acc10", 10, {0, {0}}, 0, 0 }, + { "acc11", 11, {0, {0}}, 0, 0 }, + { "acc12", 12, {0, {0}}, 0, 0 }, + { "acc13", 13, {0, {0}}, 0, 0 }, + { "acc14", 14, {0, {0}}, 0, 0 }, + { "acc15", 15, {0, {0}}, 0, 0 }, + { "acc16", 16, {0, {0}}, 0, 0 }, + { "acc17", 17, {0, {0}}, 0, 0 }, + { "acc18", 18, {0, {0}}, 0, 0 }, + { "acc19", 19, {0, {0}}, 0, 0 }, + { "acc20", 20, {0, {0}}, 0, 0 }, + { "acc21", 21, {0, {0}}, 0, 0 }, + { "acc22", 22, {0, {0}}, 0, 0 }, + { "acc23", 23, {0, {0}}, 0, 0 }, + { "acc24", 24, {0, {0}}, 0, 0 }, + { "acc25", 25, {0, {0}}, 0, 0 }, + { "acc26", 26, {0, {0}}, 0, 0 }, + { "acc27", 27, {0, {0}}, 0, 0 }, + { "acc28", 28, {0, {0}}, 0, 0 }, + { "acc29", 29, {0, {0}}, 0, 0 }, + { "acc30", 30, {0, {0}}, 0, 0 }, + { "acc31", 31, {0, {0}}, 0, 0 }, + { "acc32", 32, {0, {0}}, 0, 0 }, + { "acc33", 33, {0, {0}}, 0, 0 }, + { "acc34", 34, {0, {0}}, 0, 0 }, + { "acc35", 35, {0, {0}}, 0, 0 }, + { "acc36", 36, {0, {0}}, 0, 0 }, + { "acc37", 37, {0, {0}}, 0, 0 }, + { "acc38", 38, {0, {0}}, 0, 0 }, + { "acc39", 39, {0, {0}}, 0, 0 }, + { "acc40", 40, {0, {0}}, 0, 0 }, + { "acc41", 41, {0, {0}}, 0, 0 }, + { "acc42", 42, {0, {0}}, 0, 0 }, + { "acc43", 43, {0, {0}}, 0, 0 }, + { "acc44", 44, {0, {0}}, 0, 0 }, + { "acc45", 45, {0, {0}}, 0, 0 }, + { "acc46", 46, {0, {0}}, 0, 0 }, + { "acc47", 47, {0, {0}}, 0, 0 }, + { "acc48", 48, {0, {0}}, 0, 0 }, + { "acc49", 49, {0, {0}}, 0, 0 }, + { "acc50", 50, {0, {0}}, 0, 0 }, + { "acc51", 51, {0, {0}}, 0, 0 }, + { "acc52", 52, {0, {0}}, 0, 0 }, + { "acc53", 53, {0, {0}}, 0, 0 }, + { "acc54", 54, {0, {0}}, 0, 0 }, + { "acc55", 55, {0, {0}}, 0, 0 }, + { "acc56", 56, {0, {0}}, 0, 0 }, + { "acc57", 57, {0, {0}}, 0, 0 }, + { "acc58", 58, {0, {0}}, 0, 0 }, + { "acc59", 59, {0, {0}}, 0, 0 }, + { "acc60", 60, {0, {0}}, 0, 0 }, + { "acc61", 61, {0, {0}}, 0, 0 }, + { "acc62", 62, {0, {0}}, 0, 0 }, + { "acc63", 63, {0, {0}}, 0, 0 } +}; + +CGEN_KEYWORD frv_cgen_opval_acc_names = +{ + & frv_cgen_opval_acc_names_entries[0], + 64, + 0, 0, 0, 0, "" +}; + +static CGEN_KEYWORD_ENTRY frv_cgen_opval_iccr_names_entries[] = +{ + { "icc0", 0, {0, {0}}, 0, 0 }, + { "icc1", 1, {0, {0}}, 0, 0 }, + { "icc2", 2, {0, {0}}, 0, 0 }, + { "icc3", 3, {0, {0}}, 0, 0 } +}; + +CGEN_KEYWORD frv_cgen_opval_iccr_names = +{ + & frv_cgen_opval_iccr_names_entries[0], + 4, + 0, 0, 0, 0, "" +}; + +static CGEN_KEYWORD_ENTRY frv_cgen_opval_fccr_names_entries[] = +{ + { "fcc0", 0, {0, {0}}, 0, 0 }, + { "fcc1", 1, {0, {0}}, 0, 0 }, + { "fcc2", 2, {0, {0}}, 0, 0 }, + { "fcc3", 3, {0, {0}}, 0, 0 } +}; + +CGEN_KEYWORD frv_cgen_opval_fccr_names = +{ + & frv_cgen_opval_fccr_names_entries[0], + 4, + 0, 0, 0, 0, "" +}; + +static CGEN_KEYWORD_ENTRY frv_cgen_opval_cccr_names_entries[] = +{ + { "cc0", 0, {0, {0}}, 0, 0 }, + { "cc1", 1, {0, {0}}, 0, 0 }, + { "cc2", 2, {0, {0}}, 0, 0 }, + { "cc3", 3, {0, {0}}, 0, 0 }, + { "cc4", 4, {0, {0}}, 0, 0 }, + { "cc5", 5, {0, {0}}, 0, 0 }, + { "cc6", 6, {0, {0}}, 0, 0 }, + { "cc7", 7, {0, {0}}, 0, 0 } +}; + +CGEN_KEYWORD frv_cgen_opval_cccr_names = +{ + & frv_cgen_opval_cccr_names_entries[0], + 8, + 0, 0, 0, 0, "" +}; + +static CGEN_KEYWORD_ENTRY frv_cgen_opval_h_pack_entries[] = +{ + { "", 1, {0, {0}}, 0, 0 }, + { ".p", 0, {0, {0}}, 0, 0 }, + { ".P", 0, {0, {0}}, 0, 0 } +}; + +CGEN_KEYWORD frv_cgen_opval_h_pack = +{ + & frv_cgen_opval_h_pack_entries[0], + 3, + 0, 0, 0, 0, "" +}; + +static CGEN_KEYWORD_ENTRY frv_cgen_opval_h_hint_taken_entries[] = +{ + { "", 2, {0, {0}}, 0, 0 }, + { "", 0, {0, {0}}, 0, 0 }, + { "", 1, {0, {0}}, 0, 0 }, + { "", 3, {0, {0}}, 0, 0 } +}; + +CGEN_KEYWORD frv_cgen_opval_h_hint_taken = +{ + & frv_cgen_opval_h_hint_taken_entries[0], + 4, + 0, 0, 0, 0, "" +}; + +static CGEN_KEYWORD_ENTRY frv_cgen_opval_h_hint_not_taken_entries[] = +{ + { "", 0, {0, {0}}, 0, 0 }, + { "", 1, {0, {0}}, 0, 0 }, + { "", 2, {0, {0}}, 0, 0 }, + { "", 3, {0, {0}}, 0, 0 } +}; + +CGEN_KEYWORD frv_cgen_opval_h_hint_not_taken = +{ + & frv_cgen_opval_h_hint_not_taken_entries[0], + 4, + 0, 0, 0, 0, "" +}; + + +/* The hardware table. */ + +#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE) +#define A(a) (1 << CGEN_HW_##a) +#else +#define A(a) (1 << CGEN_HW_/**/a) +#endif + +const CGEN_HW_ENTRY frv_cgen_hw_table[] = +{ + { "h-memory", HW_H_MEMORY, CGEN_ASM_NONE, 0, { 0, { (1<name) + { + if (strcmp (name, table->bfd_name) == 0) + return table; + ++table; + } + abort (); +} + +/* Subroutine of frv_cgen_cpu_open to build the hardware table. */ + +static void +build_hw_table (cd) + CGEN_CPU_TABLE *cd; +{ + int i; + int machs = cd->machs; + const CGEN_HW_ENTRY *init = & frv_cgen_hw_table[0]; + /* MAX_HW is only an upper bound on the number of selected entries. + However each entry is indexed by it's enum so there can be holes in + the table. */ + const CGEN_HW_ENTRY **selected = + (const CGEN_HW_ENTRY **) xmalloc (MAX_HW * sizeof (CGEN_HW_ENTRY *)); + + cd->hw_table.init_entries = init; + cd->hw_table.entry_size = sizeof (CGEN_HW_ENTRY); + memset (selected, 0, MAX_HW * sizeof (CGEN_HW_ENTRY *)); + /* ??? For now we just use machs to determine which ones we want. */ + for (i = 0; init[i].name != NULL; ++i) + if (CGEN_HW_ATTR_VALUE (&init[i], CGEN_HW_MACH) + & machs) + selected[init[i].type] = &init[i]; + cd->hw_table.entries = selected; + cd->hw_table.num_entries = MAX_HW; +} + +/* Subroutine of frv_cgen_cpu_open to build the hardware table. */ + +static void +build_ifield_table (cd) + CGEN_CPU_TABLE *cd; +{ + cd->ifld_table = & frv_cgen_ifld_table[0]; +} + +/* Subroutine of frv_cgen_cpu_open to build the hardware table. */ + +static void +build_operand_table (cd) + CGEN_CPU_TABLE *cd; +{ + int i; + int machs = cd->machs; + const CGEN_OPERAND *init = & frv_cgen_operand_table[0]; + /* MAX_OPERANDS is only an upper bound on the number of selected entries. + However each entry is indexed by it's enum so there can be holes in + the table. */ + const CGEN_OPERAND **selected = + (const CGEN_OPERAND **) xmalloc (MAX_OPERANDS * sizeof (CGEN_OPERAND *)); + + cd->operand_table.init_entries = init; + cd->operand_table.entry_size = sizeof (CGEN_OPERAND); + memset (selected, 0, MAX_OPERANDS * sizeof (CGEN_OPERAND *)); + /* ??? For now we just use mach to determine which ones we want. */ + for (i = 0; init[i].name != NULL; ++i) + if (CGEN_OPERAND_ATTR_VALUE (&init[i], CGEN_OPERAND_MACH) + & machs) + selected[init[i].type] = &init[i]; + cd->operand_table.entries = selected; + cd->operand_table.num_entries = MAX_OPERANDS; +} + +/* Subroutine of frv_cgen_cpu_open to build the hardware table. + ??? This could leave out insns not supported by the specified mach/isa, + but that would cause errors like "foo only supported by bar" to become + "unknown insn", so for now we include all insns and require the app to + do the checking later. + ??? On the other hand, parsing of such insns may require their hardware or + operand elements to be in the table [which they mightn't be]. */ + +static void +build_insn_table (cd) + CGEN_CPU_TABLE *cd; +{ + int i; + const CGEN_IBASE *ib = & frv_cgen_insn_table[0]; + CGEN_INSN *insns = (CGEN_INSN *) xmalloc (MAX_INSNS * sizeof (CGEN_INSN)); + + memset (insns, 0, MAX_INSNS * sizeof (CGEN_INSN)); + for (i = 0; i < MAX_INSNS; ++i) + insns[i].base = &ib[i]; + cd->insn_table.init_entries = insns; + cd->insn_table.entry_size = sizeof (CGEN_IBASE); + cd->insn_table.num_init_entries = MAX_INSNS; +} + +/* Subroutine of frv_cgen_cpu_open to rebuild the tables. */ + +static void +frv_cgen_rebuild_tables (cd) + CGEN_CPU_TABLE *cd; +{ + int i; + unsigned int isas = cd->isas; + unsigned int machs = cd->machs; + + cd->int_insn_p = CGEN_INT_INSN_P; + + /* Data derived from the isa spec. */ +#define UNSET (CGEN_SIZE_UNKNOWN + 1) + cd->default_insn_bitsize = UNSET; + cd->base_insn_bitsize = UNSET; + cd->min_insn_bitsize = 65535; /* some ridiculously big number */ + cd->max_insn_bitsize = 0; + for (i = 0; i < MAX_ISAS; ++i) + if (((1 << i) & isas) != 0) + { + const CGEN_ISA *isa = & frv_cgen_isa_table[i]; + + /* Default insn sizes of all selected isas must be + equal or we set the result to 0, meaning "unknown". */ + if (cd->default_insn_bitsize == UNSET) + cd->default_insn_bitsize = isa->default_insn_bitsize; + else if (isa->default_insn_bitsize == cd->default_insn_bitsize) + ; /* this is ok */ + else + cd->default_insn_bitsize = CGEN_SIZE_UNKNOWN; + + /* Base insn sizes of all selected isas must be equal + or we set the result to 0, meaning "unknown". */ + if (cd->base_insn_bitsize == UNSET) + cd->base_insn_bitsize = isa->base_insn_bitsize; + else if (isa->base_insn_bitsize == cd->base_insn_bitsize) + ; /* this is ok */ + else + cd->base_insn_bitsize = CGEN_SIZE_UNKNOWN; + + /* Set min,max insn sizes. */ + if (isa->min_insn_bitsize < cd->min_insn_bitsize) + cd->min_insn_bitsize = isa->min_insn_bitsize; + if (isa->max_insn_bitsize > cd->max_insn_bitsize) + cd->max_insn_bitsize = isa->max_insn_bitsize; + } + + /* Data derived from the mach spec. */ + for (i = 0; i < MAX_MACHS; ++i) + if (((1 << i) & machs) != 0) + { + const CGEN_MACH *mach = & frv_cgen_mach_table[i]; + + if (mach->insn_chunk_bitsize != 0) + { + if (cd->insn_chunk_bitsize != 0 && cd->insn_chunk_bitsize != mach->insn_chunk_bitsize) + { + fprintf (stderr, "frv_cgen_rebuild_tables: conflicting insn-chunk-bitsize values: `%d' vs. `%d'\n", + cd->insn_chunk_bitsize, mach->insn_chunk_bitsize); + abort (); + } + + cd->insn_chunk_bitsize = mach->insn_chunk_bitsize; + } + } + + /* Determine which hw elements are used by MACH. */ + build_hw_table (cd); + + /* Build the ifield table. */ + build_ifield_table (cd); + + /* Determine which operands are used by MACH/ISA. */ + build_operand_table (cd); + + /* Build the instruction table. */ + build_insn_table (cd); +} + +/* Initialize a cpu table and return a descriptor. + It's much like opening a file, and must be the first function called. + The arguments are a set of (type/value) pairs, terminated with + CGEN_CPU_OPEN_END. + + Currently supported values: + CGEN_CPU_OPEN_ISAS: bitmap of values in enum isa_attr + CGEN_CPU_OPEN_MACHS: bitmap of values in enum mach_attr + CGEN_CPU_OPEN_BFDMACH: specify 1 mach using bfd name + CGEN_CPU_OPEN_ENDIAN: specify endian choice + CGEN_CPU_OPEN_END: terminates arguments + + ??? Simultaneous multiple isas might not make sense, but it's not (yet) + precluded. + + ??? We only support ISO C stdargs here, not K&R. + Laziness, plus experiment to see if anything requires K&R - eventually + K&R will no longer be supported - e.g. GDB is currently trying this. */ + +CGEN_CPU_DESC +frv_cgen_cpu_open (enum cgen_cpu_open_arg arg_type, ...) +{ + CGEN_CPU_TABLE *cd = (CGEN_CPU_TABLE *) xmalloc (sizeof (CGEN_CPU_TABLE)); + static int init_p; + unsigned int isas = 0; /* 0 = "unspecified" */ + unsigned int machs = 0; /* 0 = "unspecified" */ + enum cgen_endian endian = CGEN_ENDIAN_UNKNOWN; + va_list ap; + + if (! init_p) + { + init_tables (); + init_p = 1; + } + + memset (cd, 0, sizeof (*cd)); + + va_start (ap, arg_type); + while (arg_type != CGEN_CPU_OPEN_END) + { + switch (arg_type) + { + case CGEN_CPU_OPEN_ISAS : + isas = va_arg (ap, unsigned int); + break; + case CGEN_CPU_OPEN_MACHS : + machs = va_arg (ap, unsigned int); + break; + case CGEN_CPU_OPEN_BFDMACH : + { + const char *name = va_arg (ap, const char *); + const CGEN_MACH *mach = + lookup_mach_via_bfd_name (frv_cgen_mach_table, name); + + machs |= 1 << mach->num; + break; + } + case CGEN_CPU_OPEN_ENDIAN : + endian = va_arg (ap, enum cgen_endian); + break; + default : + fprintf (stderr, "frv_cgen_cpu_open: unsupported argument `%d'\n", + arg_type); + abort (); /* ??? return NULL? */ + } + arg_type = va_arg (ap, enum cgen_cpu_open_arg); + } + va_end (ap); + + /* mach unspecified means "all" */ + if (machs == 0) + machs = (1 << MAX_MACHS) - 1; + /* base mach is always selected */ + machs |= 1; + /* isa unspecified means "all" */ + if (isas == 0) + isas = (1 << MAX_ISAS) - 1; + if (endian == CGEN_ENDIAN_UNKNOWN) + { + /* ??? If target has only one, could have a default. */ + fprintf (stderr, "frv_cgen_cpu_open: no endianness specified\n"); + abort (); + } + + cd->isas = isas; + cd->machs = machs; + cd->endian = endian; + /* FIXME: for the sparc case we can determine insn-endianness statically. + The worry here is where both data and insn endian can be independently + chosen, in which case this function will need another argument. + Actually, will want to allow for more arguments in the future anyway. */ + cd->insn_endian = endian; + + /* Table (re)builder. */ + cd->rebuild_tables = frv_cgen_rebuild_tables; + frv_cgen_rebuild_tables (cd); + + /* Default to not allowing signed overflow. */ + cd->signed_overflow_ok_p = 0; + + return (CGEN_CPU_DESC) cd; +} + +/* Cover fn to frv_cgen_cpu_open to handle the simple case of 1 isa, 1 mach. + MACH_NAME is the bfd name of the mach. */ + +CGEN_CPU_DESC +frv_cgen_cpu_open_1 (mach_name, endian) + const char *mach_name; + enum cgen_endian endian; +{ + return frv_cgen_cpu_open (CGEN_CPU_OPEN_BFDMACH, mach_name, + CGEN_CPU_OPEN_ENDIAN, endian, + CGEN_CPU_OPEN_END); +} + +/* Close a cpu table. + ??? This can live in a machine independent file, but there's currently + no place to put this file (there's no libcgen). libopcodes is the wrong + place as some simulator ports use this but they don't use libopcodes. */ + +void +frv_cgen_cpu_close (cd) + CGEN_CPU_DESC cd; +{ + unsigned int i; + CGEN_INSN *insns; + + if (cd->macro_insn_table.init_entries) + { + insns = cd->macro_insn_table.init_entries; + for (i = 0; i < cd->macro_insn_table.num_init_entries; ++i, ++insns) + { + if (CGEN_INSN_RX ((insns))) + regfree(CGEN_INSN_RX (insns)); + } + } + + if (cd->insn_table.init_entries) + { + insns = cd->insn_table.init_entries; + for (i = 0; i < cd->insn_table.num_init_entries; ++i, ++insns) + { + if (CGEN_INSN_RX (insns)) + regfree(CGEN_INSN_RX (insns)); + } + } + + + + if (cd->macro_insn_table.init_entries) + free ((CGEN_INSN *) cd->macro_insn_table.init_entries); + + if (cd->insn_table.init_entries) + free ((CGEN_INSN *) cd->insn_table.init_entries); + + if (cd->hw_table.entries) + free ((CGEN_HW_ENTRY *) cd->hw_table.entries); + + if (cd->operand_table.entries) + free ((CGEN_HW_ENTRY *) cd->operand_table.entries); + + free (cd); +} + diff --git a/opcodes/frv-desc.h b/opcodes/frv-desc.h new file mode 100644 index 0000000..893919f --- /dev/null +++ b/opcodes/frv-desc.h @@ -0,0 +1,748 @@ +/* CPU data header for frv. + +THIS FILE IS MACHINE GENERATED WITH CGEN. + +Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + +This file is part of the GNU Binutils and/or 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. + +*/ + +#ifndef FRV_CPU_H +#define FRV_CPU_H + +#define CGEN_ARCH frv + +/* Given symbol S, return frv_cgen_. */ +#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE) +#define CGEN_SYM(s) frv##_cgen_##s +#else +#define CGEN_SYM(s) frv/**/_cgen_/**/s +#endif + + +/* Selected cpu families. */ +#define HAVE_CPU_FRVBF + +#define CGEN_INSN_LSB0_P 1 + +/* Minimum size of any insn (in bytes). */ +#define CGEN_MIN_INSN_SIZE 4 + +/* Maximum size of any insn (in bytes). */ +#define CGEN_MAX_INSN_SIZE 4 + +#define CGEN_INT_INSN_P 1 + +/* Maximum number of syntax elements in an instruction. */ +#define CGEN_ACTUAL_MAX_SYNTAX_ELEMENTS 22 + +/* CGEN_MNEMONIC_OPERANDS is defined if mnemonics have operands. + e.g. In "b,a foo" the ",a" is an operand. If mnemonics have operands + we can't hash on everything up to the space. */ +#define CGEN_MNEMONIC_OPERANDS + +/* Maximum number of fields in an instruction. */ +#define CGEN_ACTUAL_MAX_IFMT_OPERANDS 10 + +/* Enums. */ + +/* Enum declaration for insn op enums. */ +typedef enum insn_op { + OP_00, OP_01, OP_02, OP_03 + , OP_04, OP_05, OP_06, OP_07 + , OP_08, OP_09, OP_0A, OP_0B + , OP_0C, OP_0D, OP_0E, OP_0F + , OP_10, OP_11, OP_12, OP_13 + , OP_14, OP_15, OP_16, OP_17 + , OP_18, OP_19, OP_1A, OP_1B + , OP_1C, OP_1D, OP_1E, OP_1F + , OP_20, OP_21, OP_22, OP_23 + , OP_24, OP_25, OP_26, OP_27 + , OP_28, OP_29, OP_2A, OP_2B + , OP_2C, OP_2D, OP_2E, OP_2F + , OP_30, OP_31, OP_32, OP_33 + , OP_34, OP_35, OP_36, OP_37 + , OP_38, OP_39, OP_3A, OP_3B + , OP_3C, OP_3D, OP_3E, OP_3F + , OP_40, OP_41, OP_42, OP_43 + , OP_44, OP_45, OP_46, OP_47 + , OP_48, OP_49, OP_4A, OP_4B + , OP_4C, OP_4D, OP_4E, OP_4F + , OP_50, OP_51, OP_52, OP_53 + , OP_54, OP_55, OP_56, OP_57 + , OP_58, OP_59, OP_5A, OP_5B + , OP_5C, OP_5D, OP_5E, OP_5F + , OP_60, OP_61, OP_62, OP_63 + , OP_64, OP_65, OP_66, OP_67 + , OP_68, OP_69, OP_6A, OP_6B + , OP_6C, OP_6D, OP_6E, OP_6F + , OP_70, OP_71, OP_72, OP_73 + , OP_74, OP_75, OP_76, OP_77 + , OP_78, OP_79, OP_7A, OP_7B + , OP_7C, OP_7D, OP_7E, OP_7F +} INSN_OP; + +/* Enum declaration for insn ope enums. */ +typedef enum insn_ope1 { + OPE1_00, OPE1_01, OPE1_02, OPE1_03 + , OPE1_04, OPE1_05, OPE1_06, OPE1_07 + , OPE1_08, OPE1_09, OPE1_0A, OPE1_0B + , OPE1_0C, OPE1_0D, OPE1_0E, OPE1_0F + , OPE1_10, OPE1_11, OPE1_12, OPE1_13 + , OPE1_14, OPE1_15, OPE1_16, OPE1_17 + , OPE1_18, OPE1_19, OPE1_1A, OPE1_1B + , OPE1_1C, OPE1_1D, OPE1_1E, OPE1_1F + , OPE1_20, OPE1_21, OPE1_22, OPE1_23 + , OPE1_24, OPE1_25, OPE1_26, OPE1_27 + , OPE1_28, OPE1_29, OPE1_2A, OPE1_2B + , OPE1_2C, OPE1_2D, OPE1_2E, OPE1_2F + , OPE1_30, OPE1_31, OPE1_32, OPE1_33 + , OPE1_34, OPE1_35, OPE1_36, OPE1_37 + , OPE1_38, OPE1_39, OPE1_3A, OPE1_3B + , OPE1_3C, OPE1_3D, OPE1_3E, OPE1_3F +} INSN_OPE1; + +/* Enum declaration for insn ope enums. */ +typedef enum insn_ope2 { + OPE2_00, OPE2_01, OPE2_02, OPE2_03 + , OPE2_04, OPE2_05, OPE2_06, OPE2_07 + , OPE2_08, OPE2_09, OPE2_0A, OPE2_0B + , OPE2_0C, OPE2_0D, OPE2_0E, OPE2_0F +} INSN_OPE2; + +/* Enum declaration for insn ope enums. */ +typedef enum insn_ope3 { + OPE3_00, OPE3_01, OPE3_02, OPE3_03 + , OPE3_04, OPE3_05, OPE3_06, OPE3_07 +} INSN_OPE3; + +/* Enum declaration for insn ope enums. */ +typedef enum insn_ope4 { + OPE4_0, OPE4_1, OPE4_2, OPE4_3 +} INSN_OPE4; + +/* Enum declaration for integer branch cond enums. */ +typedef enum int_cc { + ICC_NEV, ICC_C, ICC_V, ICC_LT + , ICC_EQ, ICC_LS, ICC_N, ICC_LE + , ICC_RA, ICC_NC, ICC_NV, ICC_GE + , ICC_NE, ICC_HI, ICC_P, ICC_GT +} INT_CC; + +/* Enum declaration for float branch cond enums. */ +typedef enum flt_cc { + FCC_NEV, FCC_U, FCC_GT, FCC_UG + , FCC_LT, FCC_UL, FCC_LG, FCC_NE + , FCC_EQ, FCC_UE, FCC_GE, FCC_UGE + , FCC_LE, FCC_ULE, FCC_O, FCC_RA +} FLT_CC; + +/* Enum declaration for . */ +typedef enum gr_names { + H_GR_SP = 1, H_GR_FP = 2, H_GR_GR0 = 0, H_GR_GR1 = 1 + , H_GR_GR2 = 2, H_GR_GR3 = 3, H_GR_GR4 = 4, H_GR_GR5 = 5 + , H_GR_GR6 = 6, H_GR_GR7 = 7, H_GR_GR8 = 8, H_GR_GR9 = 9 + , H_GR_GR10 = 10, H_GR_GR11 = 11, H_GR_GR12 = 12, H_GR_GR13 = 13 + , H_GR_GR14 = 14, H_GR_GR15 = 15, H_GR_GR16 = 16, H_GR_GR17 = 17 + , H_GR_GR18 = 18, H_GR_GR19 = 19, H_GR_GR20 = 20, H_GR_GR21 = 21 + , H_GR_GR22 = 22, H_GR_GR23 = 23, H_GR_GR24 = 24, H_GR_GR25 = 25 + , H_GR_GR26 = 26, H_GR_GR27 = 27, H_GR_GR28 = 28, H_GR_GR29 = 29 + , H_GR_GR30 = 30, H_GR_GR31 = 31, H_GR_GR32 = 32, H_GR_GR33 = 33 + , H_GR_GR34 = 34, H_GR_GR35 = 35, H_GR_GR36 = 36, H_GR_GR37 = 37 + , H_GR_GR38 = 38, H_GR_GR39 = 39, H_GR_GR40 = 40, H_GR_GR41 = 41 + , H_GR_GR42 = 42, H_GR_GR43 = 43, H_GR_GR44 = 44, H_GR_GR45 = 45 + , H_GR_GR46 = 46, H_GR_GR47 = 47, H_GR_GR48 = 48, H_GR_GR49 = 49 + , H_GR_GR50 = 50, H_GR_GR51 = 51, H_GR_GR52 = 52, H_GR_GR53 = 53 + , H_GR_GR54 = 54, H_GR_GR55 = 55, H_GR_GR56 = 56, H_GR_GR57 = 57 + , H_GR_GR58 = 58, H_GR_GR59 = 59, H_GR_GR60 = 60, H_GR_GR61 = 61 + , H_GR_GR62 = 62, H_GR_GR63 = 63 +} GR_NAMES; + +/* Enum declaration for . */ +typedef enum fr_names { + H_FR_FR0, H_FR_FR1, H_FR_FR2, H_FR_FR3 + , H_FR_FR4, H_FR_FR5, H_FR_FR6, H_FR_FR7 + , H_FR_FR8, H_FR_FR9, H_FR_FR10, H_FR_FR11 + , H_FR_FR12, H_FR_FR13, H_FR_FR14, H_FR_FR15 + , H_FR_FR16, H_FR_FR17, H_FR_FR18, H_FR_FR19 + , H_FR_FR20, H_FR_FR21, H_FR_FR22, H_FR_FR23 + , H_FR_FR24, H_FR_FR25, H_FR_FR26, H_FR_FR27 + , H_FR_FR28, H_FR_FR29, H_FR_FR30, H_FR_FR31 + , H_FR_FR32, H_FR_FR33, H_FR_FR34, H_FR_FR35 + , H_FR_FR36, H_FR_FR37, H_FR_FR38, H_FR_FR39 + , H_FR_FR40, H_FR_FR41, H_FR_FR42, H_FR_FR43 + , H_FR_FR44, H_FR_FR45, H_FR_FR46, H_FR_FR47 + , H_FR_FR48, H_FR_FR49, H_FR_FR50, H_FR_FR51 + , H_FR_FR52, H_FR_FR53, H_FR_FR54, H_FR_FR55 + , H_FR_FR56, H_FR_FR57, H_FR_FR58, H_FR_FR59 + , H_FR_FR60, H_FR_FR61, H_FR_FR62, H_FR_FR63 +} FR_NAMES; + +/* Enum declaration for . */ +typedef enum cpr_names { + H_CPR_CPR0, H_CPR_CPR1, H_CPR_CPR2, H_CPR_CPR3 + , H_CPR_CPR4, H_CPR_CPR5, H_CPR_CPR6, H_CPR_CPR7 + , H_CPR_CPR8, H_CPR_CPR9, H_CPR_CPR10, H_CPR_CPR11 + , H_CPR_CPR12, H_CPR_CPR13, H_CPR_CPR14, H_CPR_CPR15 + , H_CPR_CPR16, H_CPR_CPR17, H_CPR_CPR18, H_CPR_CPR19 + , H_CPR_CPR20, H_CPR_CPR21, H_CPR_CPR22, H_CPR_CPR23 + , H_CPR_CPR24, H_CPR_CPR25, H_CPR_CPR26, H_CPR_CPR27 + , H_CPR_CPR28, H_CPR_CPR29, H_CPR_CPR30, H_CPR_CPR31 + , H_CPR_CPR32, H_CPR_CPR33, H_CPR_CPR34, H_CPR_CPR35 + , H_CPR_CPR36, H_CPR_CPR37, H_CPR_CPR38, H_CPR_CPR39 + , H_CPR_CPR40, H_CPR_CPR41, H_CPR_CPR42, H_CPR_CPR43 + , H_CPR_CPR44, H_CPR_CPR45, H_CPR_CPR46, H_CPR_CPR47 + , H_CPR_CPR48, H_CPR_CPR49, H_CPR_CPR50, H_CPR_CPR51 + , H_CPR_CPR52, H_CPR_CPR53, H_CPR_CPR54, H_CPR_CPR55 + , H_CPR_CPR56, H_CPR_CPR57, H_CPR_CPR58, H_CPR_CPR59 + , H_CPR_CPR60, H_CPR_CPR61, H_CPR_CPR62, H_CPR_CPR63 +} CPR_NAMES; + +/* Enum declaration for . */ +typedef enum spr_names { + H_SPR_PSR = 0, H_SPR_PCSR = 1, H_SPR_BPCSR = 2, H_SPR_TBR = 3 + , H_SPR_BPSR = 4, H_SPR_HSR0 = 16, H_SPR_HSR1 = 17, H_SPR_HSR2 = 18 + , H_SPR_HSR3 = 19, H_SPR_HSR4 = 20, H_SPR_HSR5 = 21, H_SPR_HSR6 = 22 + , H_SPR_HSR7 = 23, H_SPR_HSR8 = 24, H_SPR_HSR9 = 25, H_SPR_HSR10 = 26 + , H_SPR_HSR11 = 27, H_SPR_HSR12 = 28, H_SPR_HSR13 = 29, H_SPR_HSR14 = 30 + , H_SPR_HSR15 = 31, H_SPR_HSR16 = 32, H_SPR_HSR17 = 33, H_SPR_HSR18 = 34 + , H_SPR_HSR19 = 35, H_SPR_HSR20 = 36, H_SPR_HSR21 = 37, H_SPR_HSR22 = 38 + , H_SPR_HSR23 = 39, H_SPR_HSR24 = 40, H_SPR_HSR25 = 41, H_SPR_HSR26 = 42 + , H_SPR_HSR27 = 43, H_SPR_HSR28 = 44, H_SPR_HSR29 = 45, H_SPR_HSR30 = 46 + , H_SPR_HSR31 = 47, H_SPR_HSR32 = 48, H_SPR_HSR33 = 49, H_SPR_HSR34 = 50 + , H_SPR_HSR35 = 51, H_SPR_HSR36 = 52, H_SPR_HSR37 = 53, H_SPR_HSR38 = 54 + , H_SPR_HSR39 = 55, H_SPR_HSR40 = 56, H_SPR_HSR41 = 57, H_SPR_HSR42 = 58 + , H_SPR_HSR43 = 59, H_SPR_HSR44 = 60, H_SPR_HSR45 = 61, H_SPR_HSR46 = 62 + , H_SPR_HSR47 = 63, H_SPR_HSR48 = 64, H_SPR_HSR49 = 65, H_SPR_HSR50 = 66 + , H_SPR_HSR51 = 67, H_SPR_HSR52 = 68, H_SPR_HSR53 = 69, H_SPR_HSR54 = 70 + , H_SPR_HSR55 = 71, H_SPR_HSR56 = 72, H_SPR_HSR57 = 73, H_SPR_HSR58 = 74 + , H_SPR_HSR59 = 75, H_SPR_HSR60 = 76, H_SPR_HSR61 = 77, H_SPR_HSR62 = 78 + , H_SPR_HSR63 = 79, H_SPR_CCR = 256, H_SPR_CCCR = 263, H_SPR_LR = 272 + , H_SPR_LCR = 273, H_SPR_ISR = 288, H_SPR_NEEAR0 = 352, H_SPR_NEEAR1 = 353 + , H_SPR_NEEAR2 = 354, H_SPR_NEEAR3 = 355, H_SPR_NEEAR4 = 356, H_SPR_NEEAR5 = 357 + , H_SPR_NEEAR6 = 358, H_SPR_NEEAR7 = 359, H_SPR_NEEAR8 = 360, H_SPR_NEEAR9 = 361 + , H_SPR_NEEAR10 = 362, H_SPR_NEEAR11 = 363, H_SPR_NEEAR12 = 364, H_SPR_NEEAR13 = 365 + , H_SPR_NEEAR14 = 366, H_SPR_NEEAR15 = 367, H_SPR_NEEAR16 = 368, H_SPR_NEEAR17 = 369 + , H_SPR_NEEAR18 = 370, H_SPR_NEEAR19 = 371, H_SPR_NEEAR20 = 372, H_SPR_NEEAR21 = 373 + , H_SPR_NEEAR22 = 374, H_SPR_NEEAR23 = 375, H_SPR_NEEAR24 = 376, H_SPR_NEEAR25 = 377 + , H_SPR_NEEAR26 = 378, H_SPR_NEEAR27 = 379, H_SPR_NEEAR28 = 380, H_SPR_NEEAR29 = 381 + , H_SPR_NEEAR30 = 382, H_SPR_NEEAR31 = 383, H_SPR_NESR0 = 384, H_SPR_NESR1 = 385 + , H_SPR_NESR2 = 386, H_SPR_NESR3 = 387, H_SPR_NESR4 = 388, H_SPR_NESR5 = 389 + , H_SPR_NESR6 = 390, H_SPR_NESR7 = 391, H_SPR_NESR8 = 392, H_SPR_NESR9 = 393 + , H_SPR_NESR10 = 394, H_SPR_NESR11 = 395, H_SPR_NESR12 = 396, H_SPR_NESR13 = 397 + , H_SPR_NESR14 = 398, H_SPR_NESR15 = 399, H_SPR_NESR16 = 400, H_SPR_NESR17 = 401 + , H_SPR_NESR18 = 402, H_SPR_NESR19 = 403, H_SPR_NESR20 = 404, H_SPR_NESR21 = 405 + , H_SPR_NESR22 = 406, H_SPR_NESR23 = 407, H_SPR_NESR24 = 408, H_SPR_NESR25 = 409 + , H_SPR_NESR26 = 410, H_SPR_NESR27 = 411, H_SPR_NESR28 = 412, H_SPR_NESR29 = 413 + , H_SPR_NESR30 = 414, H_SPR_NESR31 = 415, H_SPR_NECR = 416, H_SPR_GNER0 = 432 + , H_SPR_GNER1 = 433, H_SPR_FNER0 = 434, H_SPR_FNER1 = 435, H_SPR_EPCR0 = 512 + , H_SPR_EPCR1 = 513, H_SPR_EPCR2 = 514, H_SPR_EPCR3 = 515, H_SPR_EPCR4 = 516 + , H_SPR_EPCR5 = 517, H_SPR_EPCR6 = 518, H_SPR_EPCR7 = 519, H_SPR_EPCR8 = 520 + , H_SPR_EPCR9 = 521, H_SPR_EPCR10 = 522, H_SPR_EPCR11 = 523, H_SPR_EPCR12 = 524 + , H_SPR_EPCR13 = 525, H_SPR_EPCR14 = 526, H_SPR_EPCR15 = 527, H_SPR_EPCR16 = 528 + , H_SPR_EPCR17 = 529, H_SPR_EPCR18 = 530, H_SPR_EPCR19 = 531, H_SPR_EPCR20 = 532 + , H_SPR_EPCR21 = 533, H_SPR_EPCR22 = 534, H_SPR_EPCR23 = 535, H_SPR_EPCR24 = 536 + , H_SPR_EPCR25 = 537, H_SPR_EPCR26 = 538, H_SPR_EPCR27 = 539, H_SPR_EPCR28 = 540 + , H_SPR_EPCR29 = 541, H_SPR_EPCR30 = 542, H_SPR_EPCR31 = 543, H_SPR_EPCR32 = 544 + , H_SPR_EPCR33 = 545, H_SPR_EPCR34 = 546, H_SPR_EPCR35 = 547, H_SPR_EPCR36 = 548 + , H_SPR_EPCR37 = 549, H_SPR_EPCR38 = 550, H_SPR_EPCR39 = 551, H_SPR_EPCR40 = 552 + , H_SPR_EPCR41 = 553, H_SPR_EPCR42 = 554, H_SPR_EPCR43 = 555, H_SPR_EPCR44 = 556 + , H_SPR_EPCR45 = 557, H_SPR_EPCR46 = 558, H_SPR_EPCR47 = 559, H_SPR_EPCR48 = 560 + , H_SPR_EPCR49 = 561, H_SPR_EPCR50 = 562, H_SPR_EPCR51 = 563, H_SPR_EPCR52 = 564 + , H_SPR_EPCR53 = 565, H_SPR_EPCR54 = 566, H_SPR_EPCR55 = 567, H_SPR_EPCR56 = 568 + , H_SPR_EPCR57 = 569, H_SPR_EPCR58 = 570, H_SPR_EPCR59 = 571, H_SPR_EPCR60 = 572 + , H_SPR_EPCR61 = 573, H_SPR_EPCR62 = 574, H_SPR_EPCR63 = 575, H_SPR_ESR0 = 576 + , H_SPR_ESR1 = 577, H_SPR_ESR2 = 578, H_SPR_ESR3 = 579, H_SPR_ESR4 = 580 + , H_SPR_ESR5 = 581, H_SPR_ESR6 = 582, H_SPR_ESR7 = 583, H_SPR_ESR8 = 584 + , H_SPR_ESR9 = 585, H_SPR_ESR10 = 586, H_SPR_ESR11 = 587, H_SPR_ESR12 = 588 + , H_SPR_ESR13 = 589, H_SPR_ESR14 = 590, H_SPR_ESR15 = 591, H_SPR_ESR16 = 592 + , H_SPR_ESR17 = 593, H_SPR_ESR18 = 594, H_SPR_ESR19 = 595, H_SPR_ESR20 = 596 + , H_SPR_ESR21 = 597, H_SPR_ESR22 = 598, H_SPR_ESR23 = 599, H_SPR_ESR24 = 600 + , H_SPR_ESR25 = 601, H_SPR_ESR26 = 602, H_SPR_ESR27 = 603, H_SPR_ESR28 = 604 + , H_SPR_ESR29 = 605, H_SPR_ESR30 = 606, H_SPR_ESR31 = 607, H_SPR_ESR32 = 608 + , H_SPR_ESR33 = 609, H_SPR_ESR34 = 610, H_SPR_ESR35 = 611, H_SPR_ESR36 = 612 + , H_SPR_ESR37 = 613, H_SPR_ESR38 = 614, H_SPR_ESR39 = 615, H_SPR_ESR40 = 616 + , H_SPR_ESR41 = 617, H_SPR_ESR42 = 618, H_SPR_ESR43 = 619, H_SPR_ESR44 = 620 + , H_SPR_ESR45 = 621, H_SPR_ESR46 = 622, H_SPR_ESR47 = 623, H_SPR_ESR48 = 624 + , H_SPR_ESR49 = 625, H_SPR_ESR50 = 626, H_SPR_ESR51 = 627, H_SPR_ESR52 = 628 + , H_SPR_ESR53 = 629, H_SPR_ESR54 = 630, H_SPR_ESR55 = 631, H_SPR_ESR56 = 632 + , H_SPR_ESR57 = 633, H_SPR_ESR58 = 634, H_SPR_ESR59 = 635, H_SPR_ESR60 = 636 + , H_SPR_ESR61 = 637, H_SPR_ESR62 = 638, H_SPR_ESR63 = 639, H_SPR_EIR0 = 640 + , H_SPR_EIR1 = 641, H_SPR_EIR2 = 642, H_SPR_EIR3 = 643, H_SPR_EIR4 = 644 + , H_SPR_EIR5 = 645, H_SPR_EIR6 = 646, H_SPR_EIR7 = 647, H_SPR_EIR8 = 648 + , H_SPR_EIR9 = 649, H_SPR_EIR10 = 650, H_SPR_EIR11 = 651, H_SPR_EIR12 = 652 + , H_SPR_EIR13 = 653, H_SPR_EIR14 = 654, H_SPR_EIR15 = 655, H_SPR_EIR16 = 656 + , H_SPR_EIR17 = 657, H_SPR_EIR18 = 658, H_SPR_EIR19 = 659, H_SPR_EIR20 = 660 + , H_SPR_EIR21 = 661, H_SPR_EIR22 = 662, H_SPR_EIR23 = 663, H_SPR_EIR24 = 664 + , H_SPR_EIR25 = 665, H_SPR_EIR26 = 666, H_SPR_EIR27 = 667, H_SPR_EIR28 = 668 + , H_SPR_EIR29 = 669, H_SPR_EIR30 = 670, H_SPR_EIR31 = 671, H_SPR_ESFR0 = 672 + , H_SPR_ESFR1 = 673, H_SPR_SR0 = 768, H_SPR_SR1 = 769, H_SPR_SR2 = 770 + , H_SPR_SR3 = 771, H_SPR_FSR0 = 1024, H_SPR_FSR1 = 1025, H_SPR_FSR2 = 1026 + , H_SPR_FSR3 = 1027, H_SPR_FSR4 = 1028, H_SPR_FSR5 = 1029, H_SPR_FSR6 = 1030 + , H_SPR_FSR7 = 1031, H_SPR_FSR8 = 1032, H_SPR_FSR9 = 1033, H_SPR_FSR10 = 1034 + , H_SPR_FSR11 = 1035, H_SPR_FSR12 = 1036, H_SPR_FSR13 = 1037, H_SPR_FSR14 = 1038 + , H_SPR_FSR15 = 1039, H_SPR_FSR16 = 1040, H_SPR_FSR17 = 1041, H_SPR_FSR18 = 1042 + , H_SPR_FSR19 = 1043, H_SPR_FSR20 = 1044, H_SPR_FSR21 = 1045, H_SPR_FSR22 = 1046 + , H_SPR_FSR23 = 1047, H_SPR_FSR24 = 1048, H_SPR_FSR25 = 1049, H_SPR_FSR26 = 1050 + , H_SPR_FSR27 = 1051, H_SPR_FSR28 = 1052, H_SPR_FSR29 = 1053, H_SPR_FSR30 = 1054 + , H_SPR_FSR31 = 1055, H_SPR_FSR32 = 1056, H_SPR_FSR33 = 1057, H_SPR_FSR34 = 1058 + , H_SPR_FSR35 = 1059, H_SPR_FSR36 = 1060, H_SPR_FSR37 = 1061, H_SPR_FSR38 = 1062 + , H_SPR_FSR39 = 1063, H_SPR_FSR40 = 1064, H_SPR_FSR41 = 1065, H_SPR_FSR42 = 1066 + , H_SPR_FSR43 = 1067, H_SPR_FSR44 = 1068, H_SPR_FSR45 = 1069, H_SPR_FSR46 = 1070 + , H_SPR_FSR47 = 1071, H_SPR_FSR48 = 1072, H_SPR_FSR49 = 1073, H_SPR_FSR50 = 1074 + , H_SPR_FSR51 = 1075, H_SPR_FSR52 = 1076, H_SPR_FSR53 = 1077, H_SPR_FSR54 = 1078 + , H_SPR_FSR55 = 1079, H_SPR_FSR56 = 1080, H_SPR_FSR57 = 1081, H_SPR_FSR58 = 1082 + , H_SPR_FSR59 = 1083, H_SPR_FSR60 = 1084, H_SPR_FSR61 = 1085, H_SPR_FSR62 = 1086 + , H_SPR_FSR63 = 1087, H_SPR_FQOP0 = 1088, H_SPR_FQOP1 = 1090, H_SPR_FQOP2 = 1092 + , H_SPR_FQOP3 = 1094, H_SPR_FQOP4 = 1096, H_SPR_FQOP5 = 1098, H_SPR_FQOP6 = 1100 + , H_SPR_FQOP7 = 1102, H_SPR_FQOP8 = 1104, H_SPR_FQOP9 = 1106, H_SPR_FQOP10 = 1108 + , H_SPR_FQOP11 = 1110, H_SPR_FQOP12 = 1112, H_SPR_FQOP13 = 1114, H_SPR_FQOP14 = 1116 + , H_SPR_FQOP15 = 1118, H_SPR_FQOP16 = 1120, H_SPR_FQOP17 = 1122, H_SPR_FQOP18 = 1124 + , H_SPR_FQOP19 = 1126, H_SPR_FQOP20 = 1128, H_SPR_FQOP21 = 1130, H_SPR_FQOP22 = 1132 + , H_SPR_FQOP23 = 1134, H_SPR_FQOP24 = 1136, H_SPR_FQOP25 = 1138, H_SPR_FQOP26 = 1140 + , H_SPR_FQOP27 = 1142, H_SPR_FQOP28 = 1144, H_SPR_FQOP29 = 1146, H_SPR_FQOP30 = 1148 + , H_SPR_FQOP31 = 1150, H_SPR_FQST0 = 1089, H_SPR_FQST1 = 1091, H_SPR_FQST2 = 1093 + , H_SPR_FQST3 = 1095, H_SPR_FQST4 = 1097, H_SPR_FQST5 = 1099, H_SPR_FQST6 = 1101 + , H_SPR_FQST7 = 1103, H_SPR_FQST8 = 1105, H_SPR_FQST9 = 1107, H_SPR_FQST10 = 1109 + , H_SPR_FQST11 = 1111, H_SPR_FQST12 = 1113, H_SPR_FQST13 = 1115, H_SPR_FQST14 = 1117 + , H_SPR_FQST15 = 1119, H_SPR_FQST16 = 1121, H_SPR_FQST17 = 1123, H_SPR_FQST18 = 1125 + , H_SPR_FQST19 = 1127, H_SPR_FQST20 = 1129, H_SPR_FQST21 = 1131, H_SPR_FQST22 = 1133 + , H_SPR_FQST23 = 1135, H_SPR_FQST24 = 1137, H_SPR_FQST25 = 1139, H_SPR_FQST26 = 1141 + , H_SPR_FQST27 = 1143, H_SPR_FQST28 = 1145, H_SPR_FQST29 = 1147, H_SPR_FQST30 = 1149 + , H_SPR_FQST31 = 1151, H_SPR_MCILR0 = 1272, H_SPR_MCILR1 = 1273, H_SPR_MSR0 = 1280 + , H_SPR_MSR1 = 1281, H_SPR_MSR2 = 1282, H_SPR_MSR3 = 1283, H_SPR_MSR4 = 1284 + , H_SPR_MSR5 = 1285, H_SPR_MSR6 = 1286, H_SPR_MSR7 = 1287, H_SPR_MSR8 = 1288 + , H_SPR_MSR9 = 1289, H_SPR_MSR10 = 1290, H_SPR_MSR11 = 1291, H_SPR_MSR12 = 1292 + , H_SPR_MSR13 = 1293, H_SPR_MSR14 = 1294, H_SPR_MSR15 = 1295, H_SPR_MSR16 = 1296 + , H_SPR_MSR17 = 1297, H_SPR_MSR18 = 1298, H_SPR_MSR19 = 1299, H_SPR_MSR20 = 1300 + , H_SPR_MSR21 = 1301, H_SPR_MSR22 = 1302, H_SPR_MSR23 = 1303, H_SPR_MSR24 = 1304 + , H_SPR_MSR25 = 1305, H_SPR_MSR26 = 1306, H_SPR_MSR27 = 1307, H_SPR_MSR28 = 1308 + , H_SPR_MSR29 = 1309, H_SPR_MSR30 = 1310, H_SPR_MSR31 = 1311, H_SPR_MSR32 = 1312 + , H_SPR_MSR33 = 1313, H_SPR_MSR34 = 1314, H_SPR_MSR35 = 1315, H_SPR_MSR36 = 1316 + , H_SPR_MSR37 = 1317, H_SPR_MSR38 = 1318, H_SPR_MSR39 = 1319, H_SPR_MSR40 = 1320 + , H_SPR_MSR41 = 1321, H_SPR_MSR42 = 1322, H_SPR_MSR43 = 1323, H_SPR_MSR44 = 1324 + , H_SPR_MSR45 = 1325, H_SPR_MSR46 = 1326, H_SPR_MSR47 = 1327, H_SPR_MSR48 = 1328 + , H_SPR_MSR49 = 1329, H_SPR_MSR50 = 1330, H_SPR_MSR51 = 1331, H_SPR_MSR52 = 1332 + , H_SPR_MSR53 = 1333, H_SPR_MSR54 = 1334, H_SPR_MSR55 = 1335, H_SPR_MSR56 = 1336 + , H_SPR_MSR57 = 1337, H_SPR_MSR58 = 1338, H_SPR_MSR59 = 1339, H_SPR_MSR60 = 1340 + , H_SPR_MSR61 = 1341, H_SPR_MSR62 = 1342, H_SPR_MSR63 = 1343, H_SPR_MQOP0 = 1344 + , H_SPR_MQOP1 = 1346, H_SPR_MQOP2 = 1348, H_SPR_MQOP3 = 1350, H_SPR_MQOP4 = 1352 + , H_SPR_MQOP5 = 1354, H_SPR_MQOP6 = 1356, H_SPR_MQOP7 = 1358, H_SPR_MQOP8 = 1360 + , H_SPR_MQOP9 = 1362, H_SPR_MQOP10 = 1364, H_SPR_MQOP11 = 1366, H_SPR_MQOP12 = 1368 + , H_SPR_MQOP13 = 1370, H_SPR_MQOP14 = 1372, H_SPR_MQOP15 = 1374, H_SPR_MQOP16 = 1376 + , H_SPR_MQOP17 = 1378, H_SPR_MQOP18 = 1380, H_SPR_MQOP19 = 1382, H_SPR_MQOP20 = 1384 + , H_SPR_MQOP21 = 1386, H_SPR_MQOP22 = 1388, H_SPR_MQOP23 = 1390, H_SPR_MQOP24 = 1392 + , H_SPR_MQOP25 = 1394, H_SPR_MQOP26 = 1396, H_SPR_MQOP27 = 1398, H_SPR_MQOP28 = 1400 + , H_SPR_MQOP29 = 1402, H_SPR_MQOP30 = 1404, H_SPR_MQOP31 = 1406, H_SPR_MQST0 = 1345 + , H_SPR_MQST1 = 1347, H_SPR_MQST2 = 1349, H_SPR_MQST3 = 1351, H_SPR_MQST4 = 1353 + , H_SPR_MQST5 = 1355, H_SPR_MQST6 = 1357, H_SPR_MQST7 = 1359, H_SPR_MQST8 = 1361 + , H_SPR_MQST9 = 1363, H_SPR_MQST10 = 1365, H_SPR_MQST11 = 1367, H_SPR_MQST12 = 1369 + , H_SPR_MQST13 = 1371, H_SPR_MQST14 = 1373, H_SPR_MQST15 = 1375, H_SPR_MQST16 = 1377 + , H_SPR_MQST17 = 1379, H_SPR_MQST18 = 1381, H_SPR_MQST19 = 1383, H_SPR_MQST20 = 1385 + , H_SPR_MQST21 = 1387, H_SPR_MQST22 = 1389, H_SPR_MQST23 = 1391, H_SPR_MQST24 = 1393 + , H_SPR_MQST25 = 1395, H_SPR_MQST26 = 1397, H_SPR_MQST27 = 1399, H_SPR_MQST28 = 1401 + , H_SPR_MQST29 = 1403, H_SPR_MQST30 = 1405, H_SPR_MQST31 = 1407, H_SPR_EAR0 = 1536 + , H_SPR_EAR1 = 1537, H_SPR_EAR2 = 1538, H_SPR_EAR3 = 1539, H_SPR_EAR4 = 1540 + , H_SPR_EAR5 = 1541, H_SPR_EAR6 = 1542, H_SPR_EAR7 = 1543, H_SPR_EAR8 = 1544 + , H_SPR_EAR9 = 1545, H_SPR_EAR10 = 1546, H_SPR_EAR11 = 1547, H_SPR_EAR12 = 1548 + , H_SPR_EAR13 = 1549, H_SPR_EAR14 = 1550, H_SPR_EAR15 = 1551, H_SPR_EAR16 = 1552 + , H_SPR_EAR17 = 1553, H_SPR_EAR18 = 1554, H_SPR_EAR19 = 1555, H_SPR_EAR20 = 1556 + , H_SPR_EAR21 = 1557, H_SPR_EAR22 = 1558, H_SPR_EAR23 = 1559, H_SPR_EAR24 = 1560 + , H_SPR_EAR25 = 1561, H_SPR_EAR26 = 1562, H_SPR_EAR27 = 1563, H_SPR_EAR28 = 1564 + , H_SPR_EAR29 = 1565, H_SPR_EAR30 = 1566, H_SPR_EAR31 = 1567, H_SPR_EAR32 = 1568 + , H_SPR_EAR33 = 1569, H_SPR_EAR34 = 1570, H_SPR_EAR35 = 1571, H_SPR_EAR36 = 1572 + , H_SPR_EAR37 = 1573, H_SPR_EAR38 = 1574, H_SPR_EAR39 = 1575, H_SPR_EAR40 = 1576 + , H_SPR_EAR41 = 1577, H_SPR_EAR42 = 1578, H_SPR_EAR43 = 1579, H_SPR_EAR44 = 1580 + , H_SPR_EAR45 = 1581, H_SPR_EAR46 = 1582, H_SPR_EAR47 = 1583, H_SPR_EAR48 = 1584 + , H_SPR_EAR49 = 1585, H_SPR_EAR50 = 1586, H_SPR_EAR51 = 1587, H_SPR_EAR52 = 1588 + , H_SPR_EAR53 = 1589, H_SPR_EAR54 = 1590, H_SPR_EAR55 = 1591, H_SPR_EAR56 = 1592 + , H_SPR_EAR57 = 1593, H_SPR_EAR58 = 1594, H_SPR_EAR59 = 1595, H_SPR_EAR60 = 1596 + , H_SPR_EAR61 = 1597, H_SPR_EAR62 = 1598, H_SPR_EAR63 = 1599, H_SPR_EDR0 = 1600 + , H_SPR_EDR1 = 1601, H_SPR_EDR2 = 1602, H_SPR_EDR3 = 1603, H_SPR_EDR4 = 1604 + , H_SPR_EDR5 = 1605, H_SPR_EDR6 = 1606, H_SPR_EDR7 = 1607, H_SPR_EDR8 = 1608 + , H_SPR_EDR9 = 1609, H_SPR_EDR10 = 1610, H_SPR_EDR11 = 1611, H_SPR_EDR12 = 1612 + , H_SPR_EDR13 = 1613, H_SPR_EDR14 = 1614, H_SPR_EDR15 = 1615, H_SPR_EDR16 = 1616 + , H_SPR_EDR17 = 1617, H_SPR_EDR18 = 1618, H_SPR_EDR19 = 1619, H_SPR_EDR20 = 1620 + , H_SPR_EDR21 = 1621, H_SPR_EDR22 = 1622, H_SPR_EDR23 = 1623, H_SPR_EDR24 = 1624 + , H_SPR_EDR25 = 1625, H_SPR_EDR26 = 1626, H_SPR_EDR27 = 1627, H_SPR_EDR28 = 1628 + , H_SPR_EDR29 = 1629, H_SPR_EDR30 = 1630, H_SPR_EDR31 = 1631, H_SPR_EDR32 = 1632 + , H_SPR_EDR33 = 1636, H_SPR_EDR34 = 1634, H_SPR_EDR35 = 1635, H_SPR_EDR36 = 1636 + , H_SPR_EDR37 = 1637, H_SPR_EDR38 = 1638, H_SPR_EDR39 = 1639, H_SPR_EDR40 = 1640 + , H_SPR_EDR41 = 1641, H_SPR_EDR42 = 1642, H_SPR_EDR43 = 1643, H_SPR_EDR44 = 1644 + , H_SPR_EDR45 = 1645, H_SPR_EDR46 = 1646, H_SPR_EDR47 = 1647, H_SPR_EDR48 = 1648 + , H_SPR_EDR49 = 1649, H_SPR_EDR50 = 1650, H_SPR_EDR51 = 1651, H_SPR_EDR52 = 1652 + , H_SPR_EDR53 = 1653, H_SPR_EDR54 = 1654, H_SPR_EDR55 = 1655, H_SPR_EDR56 = 1656 + , H_SPR_EDR57 = 1657, H_SPR_EDR58 = 1658, H_SPR_EDR59 = 1659, H_SPR_EDR60 = 1660 + , H_SPR_EDR61 = 1661, H_SPR_EDR62 = 1662, H_SPR_EDR63 = 1663, H_SPR_IAMLR0 = 1664 + , H_SPR_IAMLR1 = 1665, H_SPR_IAMLR2 = 1666, H_SPR_IAMLR3 = 1667, H_SPR_IAMLR4 = 1668 + , H_SPR_IAMLR5 = 1669, H_SPR_IAMLR6 = 1670, H_SPR_IAMLR7 = 1671, H_SPR_IAMLR8 = 1672 + , H_SPR_IAMLR9 = 1673, H_SPR_IAMLR10 = 1674, H_SPR_IAMLR11 = 1675, H_SPR_IAMLR12 = 1676 + , H_SPR_IAMLR13 = 1677, H_SPR_IAMLR14 = 1678, H_SPR_IAMLR15 = 1679, H_SPR_IAMLR16 = 1680 + , H_SPR_IAMLR17 = 1681, H_SPR_IAMLR18 = 1682, H_SPR_IAMLR19 = 1683, H_SPR_IAMLR20 = 1684 + , H_SPR_IAMLR21 = 1685, H_SPR_IAMLR22 = 1686, H_SPR_IAMLR23 = 1687, H_SPR_IAMLR24 = 1688 + , H_SPR_IAMLR25 = 1689, H_SPR_IAMLR26 = 1690, H_SPR_IAMLR27 = 1691, H_SPR_IAMLR28 = 1692 + , H_SPR_IAMLR29 = 1693, H_SPR_IAMLR30 = 1694, H_SPR_IAMLR31 = 1695, H_SPR_IAMLR32 = 1696 + , H_SPR_IAMLR33 = 1697, H_SPR_IAMLR34 = 1698, H_SPR_IAMLR35 = 1699, H_SPR_IAMLR36 = 1700 + , H_SPR_IAMLR37 = 1701, H_SPR_IAMLR38 = 1702, H_SPR_IAMLR39 = 1703, H_SPR_IAMLR40 = 1704 + , H_SPR_IAMLR41 = 1705, H_SPR_IAMLR42 = 1706, H_SPR_IAMLR43 = 1707, H_SPR_IAMLR44 = 1708 + , H_SPR_IAMLR45 = 1709, H_SPR_IAMLR46 = 1710, H_SPR_IAMLR47 = 1711, H_SPR_IAMLR48 = 1712 + , H_SPR_IAMLR49 = 1713, H_SPR_IAMLR50 = 1714, H_SPR_IAMLR51 = 1715, H_SPR_IAMLR52 = 1716 + , H_SPR_IAMLR53 = 1717, H_SPR_IAMLR54 = 1718, H_SPR_IAMLR55 = 1719, H_SPR_IAMLR56 = 1720 + , H_SPR_IAMLR57 = 1721, H_SPR_IAMLR58 = 1722, H_SPR_IAMLR59 = 1723, H_SPR_IAMLR60 = 1724 + , H_SPR_IAMLR61 = 1725, H_SPR_IAMLR62 = 1726, H_SPR_IAMLR63 = 1727, H_SPR_IAMPR0 = 1728 + , H_SPR_IAMPR1 = 1729, H_SPR_IAMPR2 = 1730, H_SPR_IAMPR3 = 1731, H_SPR_IAMPR4 = 1732 + , H_SPR_IAMPR5 = 1733, H_SPR_IAMPR6 = 1734, H_SPR_IAMPR7 = 1735, H_SPR_IAMPR8 = 1736 + , H_SPR_IAMPR9 = 1737, H_SPR_IAMPR10 = 1738, H_SPR_IAMPR11 = 1739, H_SPR_IAMPR12 = 1740 + , H_SPR_IAMPR13 = 1741, H_SPR_IAMPR14 = 1742, H_SPR_IAMPR15 = 1743, H_SPR_IAMPR16 = 1744 + , H_SPR_IAMPR17 = 1745, H_SPR_IAMPR18 = 1746, H_SPR_IAMPR19 = 1747, H_SPR_IAMPR20 = 1748 + , H_SPR_IAMPR21 = 1749, H_SPR_IAMPR22 = 1750, H_SPR_IAMPR23 = 1751, H_SPR_IAMPR24 = 1752 + , H_SPR_IAMPR25 = 1753, H_SPR_IAMPR26 = 1754, H_SPR_IAMPR27 = 1755, H_SPR_IAMPR28 = 1756 + , H_SPR_IAMPR29 = 1757, H_SPR_IAMPR30 = 1758, H_SPR_IAMPR31 = 1759, H_SPR_IAMPR32 = 1760 + , H_SPR_IAMPR33 = 1761, H_SPR_IAMPR34 = 1762, H_SPR_IAMPR35 = 1763, H_SPR_IAMPR36 = 1764 + , H_SPR_IAMPR37 = 1765, H_SPR_IAMPR38 = 1766, H_SPR_IAMPR39 = 1767, H_SPR_IAMPR40 = 1768 + , H_SPR_IAMPR41 = 1769, H_SPR_IAMPR42 = 1770, H_SPR_IAMPR43 = 1771, H_SPR_IAMPR44 = 1772 + , H_SPR_IAMPR45 = 1773, H_SPR_IAMPR46 = 1774, H_SPR_IAMPR47 = 1775, H_SPR_IAMPR48 = 1776 + , H_SPR_IAMPR49 = 1777, H_SPR_IAMPR50 = 1778, H_SPR_IAMPR51 = 1779, H_SPR_IAMPR52 = 1780 + , H_SPR_IAMPR53 = 1781, H_SPR_IAMPR54 = 1782, H_SPR_IAMPR55 = 1783, H_SPR_IAMPR56 = 1784 + , H_SPR_IAMPR57 = 1785, H_SPR_IAMPR58 = 1786, H_SPR_IAMPR59 = 1787, H_SPR_IAMPR60 = 1788 + , H_SPR_IAMPR61 = 1789, H_SPR_IAMPR62 = 1790, H_SPR_IAMPR63 = 1791, H_SPR_DAMLR0 = 1792 + , H_SPR_DAMLR1 = 1793, H_SPR_DAMLR2 = 1794, H_SPR_DAMLR3 = 1795, H_SPR_DAMLR4 = 1796 + , H_SPR_DAMLR5 = 1797, H_SPR_DAMLR6 = 1798, H_SPR_DAMLR7 = 1799, H_SPR_DAMLR8 = 1800 + , H_SPR_DAMLR9 = 1801, H_SPR_DAMLR10 = 1802, H_SPR_DAMLR11 = 1803, H_SPR_DAMLR12 = 1804 + , H_SPR_DAMLR13 = 1805, H_SPR_DAMLR14 = 1806, H_SPR_DAMLR15 = 1807, H_SPR_DAMLR16 = 1808 + , H_SPR_DAMLR17 = 1809, H_SPR_DAMLR18 = 1810, H_SPR_DAMLR19 = 1811, H_SPR_DAMLR20 = 1812 + , H_SPR_DAMLR21 = 1813, H_SPR_DAMLR22 = 1814, H_SPR_DAMLR23 = 1815, H_SPR_DAMLR24 = 1816 + , H_SPR_DAMLR25 = 1817, H_SPR_DAMLR26 = 1818, H_SPR_DAMLR27 = 1819, H_SPR_DAMLR28 = 1820 + , H_SPR_DAMLR29 = 1821, H_SPR_DAMLR30 = 1822, H_SPR_DAMLR31 = 1823, H_SPR_DAMLR32 = 1824 + , H_SPR_DAMLR33 = 1825, H_SPR_DAMLR34 = 1826, H_SPR_DAMLR35 = 1827, H_SPR_DAMLR36 = 1828 + , H_SPR_DAMLR37 = 1829, H_SPR_DAMLR38 = 1830, H_SPR_DAMLR39 = 1831, H_SPR_DAMLR40 = 1832 + , H_SPR_DAMLR41 = 1833, H_SPR_DAMLR42 = 1834, H_SPR_DAMLR43 = 1835, H_SPR_DAMLR44 = 1836 + , H_SPR_DAMLR45 = 1837, H_SPR_DAMLR46 = 1838, H_SPR_DAMLR47 = 1839, H_SPR_DAMLR48 = 1840 + , H_SPR_DAMLR49 = 1841, H_SPR_DAMLR50 = 1842, H_SPR_DAMLR51 = 1843, H_SPR_DAMLR52 = 1844 + , H_SPR_DAMLR53 = 1845, H_SPR_DAMLR54 = 1846, H_SPR_DAMLR55 = 1847, H_SPR_DAMLR56 = 1848 + , H_SPR_DAMLR57 = 1849, H_SPR_DAMLR58 = 1850, H_SPR_DAMLR59 = 1851, H_SPR_DAMLR60 = 1852 + , H_SPR_DAMLR61 = 1853, H_SPR_DAMLR62 = 1854, H_SPR_DAMLR63 = 1855, H_SPR_DAMPR0 = 1856 + , H_SPR_DAMPR1 = 1857, H_SPR_DAMPR2 = 1858, H_SPR_DAMPR3 = 1859, H_SPR_DAMPR4 = 1860 + , H_SPR_DAMPR5 = 1861, H_SPR_DAMPR6 = 1862, H_SPR_DAMPR7 = 1863, H_SPR_DAMPR8 = 1864 + , H_SPR_DAMPR9 = 1865, H_SPR_DAMPR10 = 1866, H_SPR_DAMPR11 = 1867, H_SPR_DAMPR12 = 1868 + , H_SPR_DAMPR13 = 1869, H_SPR_DAMPR14 = 1870, H_SPR_DAMPR15 = 1871, H_SPR_DAMPR16 = 1872 + , H_SPR_DAMPR17 = 1873, H_SPR_DAMPR18 = 1874, H_SPR_DAMPR19 = 1875, H_SPR_DAMPR20 = 1876 + , H_SPR_DAMPR21 = 1877, H_SPR_DAMPR22 = 1878, H_SPR_DAMPR23 = 1879, H_SPR_DAMPR24 = 1880 + , H_SPR_DAMPR25 = 1881, H_SPR_DAMPR26 = 1882, H_SPR_DAMPR27 = 1883, H_SPR_DAMPR28 = 1884 + , H_SPR_DAMPR29 = 1885, H_SPR_DAMPR30 = 1886, H_SPR_DAMPR31 = 1887, H_SPR_DAMPR32 = 1888 + , H_SPR_DAMPR33 = 1889, H_SPR_DAMPR34 = 1890, H_SPR_DAMPR35 = 1891, H_SPR_DAMPR36 = 1892 + , H_SPR_DAMPR37 = 1893, H_SPR_DAMPR38 = 1894, H_SPR_DAMPR39 = 1895, H_SPR_DAMPR40 = 1896 + , H_SPR_DAMPR41 = 1897, H_SPR_DAMPR42 = 1898, H_SPR_DAMPR43 = 1899, H_SPR_DAMPR44 = 1900 + , H_SPR_DAMPR45 = 1901, H_SPR_DAMPR46 = 1902, H_SPR_DAMPR47 = 1903, H_SPR_DAMPR48 = 1904 + , H_SPR_DAMPR49 = 1905, H_SPR_DAMPR50 = 1906, H_SPR_DAMPR51 = 1907, H_SPR_DAMPR52 = 1908 + , H_SPR_DAMPR53 = 1909, H_SPR_DAMPR54 = 1910, H_SPR_DAMPR55 = 1911, H_SPR_DAMPR56 = 1912 + , H_SPR_DAMPR57 = 1913, H_SPR_DAMPR58 = 1914, H_SPR_DAMPR59 = 1915, H_SPR_DAMPR60 = 1916 + , H_SPR_DAMPR61 = 1917, H_SPR_DAMPR62 = 1918, H_SPR_DAMPR63 = 1919, H_SPR_AMCR = 1920 + , H_SPR_STBAR = 1921, H_SPR_MMCR = 1922, H_SPR_DCR = 2048, H_SPR_BRR = 2049 + , H_SPR_NMAR = 2050, H_SPR_IBAR0 = 2052, H_SPR_IBAR1 = 2053, H_SPR_IBAR2 = 2054 + , H_SPR_IBAR3 = 2055, H_SPR_DBAR0 = 2056, H_SPR_DBAR1 = 2057, H_SPR_DBAR2 = 2058 + , H_SPR_DBAR3 = 2059, H_SPR_DBDR00 = 2060, H_SPR_DBDR01 = 2061, H_SPR_DBDR02 = 2062 + , H_SPR_DBDR03 = 2063, H_SPR_DBDR10 = 2064, H_SPR_DBDR11 = 2065, H_SPR_DBDR12 = 2066 + , H_SPR_DBDR13 = 2067, H_SPR_DBDR20 = 2068, H_SPR_DBDR21 = 2069, H_SPR_DBDR22 = 2070 + , H_SPR_DBDR23 = 2071, H_SPR_DBDR30 = 2072, H_SPR_DBDR31 = 2073, H_SPR_DBDR32 = 2074 + , H_SPR_DBDR33 = 2075, H_SPR_DBMR00 = 2076, H_SPR_DBMR01 = 2077, H_SPR_DBMR02 = 2078 + , H_SPR_DBMR03 = 2079, H_SPR_DBMR10 = 2080, H_SPR_DBMR11 = 2081, H_SPR_DBMR12 = 2082 + , H_SPR_DBMR13 = 2083, H_SPR_DBMR20 = 2084, H_SPR_DBMR21 = 2085, H_SPR_DBMR22 = 2086 + , H_SPR_DBMR23 = 2087, H_SPR_DBMR30 = 2088, H_SPR_DBMR31 = 2089, H_SPR_DBMR32 = 2090 + , H_SPR_DBMR33 = 2091, H_SPR_CPCFR = 2092, H_SPR_CPCR = 2093, H_SPR_CPSR = 2094 + , H_SPR_CPESR0 = 2096, H_SPR_CPESR1 = 2097, H_SPR_CPEMR0 = 2098, H_SPR_CPEMR1 = 2099 + , H_SPR_IHSR8 = 3848 +} SPR_NAMES; + +/* Enum declaration for . */ +typedef enum accg_names { + H_ACCG_ACCG0, H_ACCG_ACCG1, H_ACCG_ACCG2, H_ACCG_ACCG3 + , H_ACCG_ACCG4, H_ACCG_ACCG5, H_ACCG_ACCG6, H_ACCG_ACCG7 + , H_ACCG_ACCG8, H_ACCG_ACCG9, H_ACCG_ACCG10, H_ACCG_ACCG11 + , H_ACCG_ACCG12, H_ACCG_ACCG13, H_ACCG_ACCG14, H_ACCG_ACCG15 + , H_ACCG_ACCG16, H_ACCG_ACCG17, H_ACCG_ACCG18, H_ACCG_ACCG19 + , H_ACCG_ACCG20, H_ACCG_ACCG21, H_ACCG_ACCG22, H_ACCG_ACCG23 + , H_ACCG_ACCG24, H_ACCG_ACCG25, H_ACCG_ACCG26, H_ACCG_ACCG27 + , H_ACCG_ACCG28, H_ACCG_ACCG29, H_ACCG_ACCG30, H_ACCG_ACCG31 + , H_ACCG_ACCG32, H_ACCG_ACCG33, H_ACCG_ACCG34, H_ACCG_ACCG35 + , H_ACCG_ACCG36, H_ACCG_ACCG37, H_ACCG_ACCG38, H_ACCG_ACCG39 + , H_ACCG_ACCG40, H_ACCG_ACCG41, H_ACCG_ACCG42, H_ACCG_ACCG43 + , H_ACCG_ACCG44, H_ACCG_ACCG45, H_ACCG_ACCG46, H_ACCG_ACCG47 + , H_ACCG_ACCG48, H_ACCG_ACCG49, H_ACCG_ACCG50, H_ACCG_ACCG51 + , H_ACCG_ACCG52, H_ACCG_ACCG53, H_ACCG_ACCG54, H_ACCG_ACCG55 + , H_ACCG_ACCG56, H_ACCG_ACCG57, H_ACCG_ACCG58, H_ACCG_ACCG59 + , H_ACCG_ACCG60, H_ACCG_ACCG61, H_ACCG_ACCG62, H_ACCG_ACCG63 +} ACCG_NAMES; + +/* Enum declaration for . */ +typedef enum acc_names { + H_ACC40_ACC0, H_ACC40_ACC1, H_ACC40_ACC2, H_ACC40_ACC3 + , H_ACC40_ACC4, H_ACC40_ACC5, H_ACC40_ACC6, H_ACC40_ACC7 + , H_ACC40_ACC8, H_ACC40_ACC9, H_ACC40_ACC10, H_ACC40_ACC11 + , H_ACC40_ACC12, H_ACC40_ACC13, H_ACC40_ACC14, H_ACC40_ACC15 + , H_ACC40_ACC16, H_ACC40_ACC17, H_ACC40_ACC18, H_ACC40_ACC19 + , H_ACC40_ACC20, H_ACC40_ACC21, H_ACC40_ACC22, H_ACC40_ACC23 + , H_ACC40_ACC24, H_ACC40_ACC25, H_ACC40_ACC26, H_ACC40_ACC27 + , H_ACC40_ACC28, H_ACC40_ACC29, H_ACC40_ACC30, H_ACC40_ACC31 + , H_ACC40_ACC32, H_ACC40_ACC33, H_ACC40_ACC34, H_ACC40_ACC35 + , H_ACC40_ACC36, H_ACC40_ACC37, H_ACC40_ACC38, H_ACC40_ACC39 + , H_ACC40_ACC40, H_ACC40_ACC41, H_ACC40_ACC42, H_ACC40_ACC43 + , H_ACC40_ACC44, H_ACC40_ACC45, H_ACC40_ACC46, H_ACC40_ACC47 + , H_ACC40_ACC48, H_ACC40_ACC49, H_ACC40_ACC50, H_ACC40_ACC51 + , H_ACC40_ACC52, H_ACC40_ACC53, H_ACC40_ACC54, H_ACC40_ACC55 + , H_ACC40_ACC56, H_ACC40_ACC57, H_ACC40_ACC58, H_ACC40_ACC59 + , H_ACC40_ACC60, H_ACC40_ACC61, H_ACC40_ACC62, H_ACC40_ACC63 +} ACC_NAMES; + +/* Enum declaration for . */ +typedef enum iccr_names { + H_ICCR_ICC0, H_ICCR_ICC1, H_ICCR_ICC2, H_ICCR_ICC3 +} ICCR_NAMES; + +/* Enum declaration for . */ +typedef enum fccr_names { + H_FCCR_FCC0, H_FCCR_FCC1, H_FCCR_FCC2, H_FCCR_FCC3 +} FCCR_NAMES; + +/* Enum declaration for . */ +typedef enum cccr_names { + H_CCCR_CC0, H_CCCR_CC1, H_CCCR_CC2, H_CCCR_CC3 + , H_CCCR_CC4, H_CCCR_CC5, H_CCCR_CC6, H_CCCR_CC7 +} CCCR_NAMES; + +/* Attributes. */ + +/* Enum declaration for machine type selection. */ +typedef enum mach_attr { + MACH_BASE, MACH_FRV, MACH_FR500, MACH_FR400 + , MACH_TOMCAT, MACH_SIMPLE, MACH_MAX +} MACH_ATTR; + +/* Enum declaration for instruction set selection. */ +typedef enum isa_attr { + ISA_FRV, ISA_MAX +} ISA_ATTR; + +/* Enum declaration for parallel execution pipeline selection. */ +typedef enum unit_attr { + UNIT_NIL, UNIT_I0, UNIT_I1, UNIT_I01 + , UNIT_FM0, UNIT_FM1, UNIT_FM01, UNIT_B0 + , UNIT_B1, UNIT_B01, UNIT_C, UNIT_MULT_DIV + , UNIT_LOAD, UNIT_NUM_UNITS +} UNIT_ATTR; + +/* Enum declaration for fr400 major insn categories. */ +typedef enum fr400_major_attr { + FR400_MAJOR_NONE, FR400_MAJOR_I_1, FR400_MAJOR_I_2, FR400_MAJOR_I_3 + , FR400_MAJOR_I_4, FR400_MAJOR_I_5, FR400_MAJOR_B_1, FR400_MAJOR_B_2 + , FR400_MAJOR_B_3, FR400_MAJOR_B_4, FR400_MAJOR_B_5, FR400_MAJOR_B_6 + , FR400_MAJOR_C_1, FR400_MAJOR_C_2, FR400_MAJOR_M_1, FR400_MAJOR_M_2 +} FR400_MAJOR_ATTR; + +/* Enum declaration for fr500 major insn categories. */ +typedef enum fr500_major_attr { + FR500_MAJOR_NONE, FR500_MAJOR_I_1, FR500_MAJOR_I_2, FR500_MAJOR_I_3 + , FR500_MAJOR_I_4, FR500_MAJOR_I_5, FR500_MAJOR_I_6, FR500_MAJOR_B_1 + , FR500_MAJOR_B_2, FR500_MAJOR_B_3, FR500_MAJOR_B_4, FR500_MAJOR_B_5 + , FR500_MAJOR_B_6, FR500_MAJOR_C_1, FR500_MAJOR_C_2, FR500_MAJOR_F_1 + , FR500_MAJOR_F_2, FR500_MAJOR_F_3, FR500_MAJOR_F_4, FR500_MAJOR_F_5 + , FR500_MAJOR_F_6, FR500_MAJOR_F_7, FR500_MAJOR_F_8, FR500_MAJOR_M_1 + , FR500_MAJOR_M_2, FR500_MAJOR_M_3, FR500_MAJOR_M_4, FR500_MAJOR_M_5 + , FR500_MAJOR_M_6, FR500_MAJOR_M_7, FR500_MAJOR_M_8 +} FR500_MAJOR_ATTR; + +/* Number of architecture variants. */ +#define MAX_ISAS 1 +#define MAX_MACHS ((int) MACH_MAX) + +/* Ifield support. */ + +extern const struct cgen_ifld frv_cgen_ifld_table[]; + +/* Ifield attribute indices. */ + +/* Enum declaration for cgen_ifld attrs. */ +typedef enum cgen_ifld_attr { + CGEN_IFLD_VIRTUAL, CGEN_IFLD_PCREL_ADDR, CGEN_IFLD_ABS_ADDR, CGEN_IFLD_RESERVED + , CGEN_IFLD_SIGN_OPT, CGEN_IFLD_SIGNED, CGEN_IFLD_END_BOOLS, CGEN_IFLD_START_NBOOLS = 31 + , CGEN_IFLD_MACH, CGEN_IFLD_END_NBOOLS +} CGEN_IFLD_ATTR; + +/* Number of non-boolean elements in cgen_ifld_attr. */ +#define CGEN_IFLD_NBOOL_ATTRS (CGEN_IFLD_END_NBOOLS - CGEN_IFLD_START_NBOOLS - 1) + +/* Enum declaration for frv ifield types. */ +typedef enum ifield_type { + FRV_F_NIL, FRV_F_ANYOF, FRV_F_PACK, FRV_F_OP + , FRV_F_OPE1, FRV_F_OPE2, FRV_F_OPE3, FRV_F_OPE4 + , FRV_F_GRI, FRV_F_GRJ, FRV_F_GRK, FRV_F_FRI + , FRV_F_FRJ, FRV_F_FRK, FRV_F_CPRI, FRV_F_CPRJ + , FRV_F_CPRK, FRV_F_ACCGI, FRV_F_ACCGK, FRV_F_ACC40SI + , FRV_F_ACC40UI, FRV_F_ACC40SK, FRV_F_ACC40UK, FRV_F_CRI + , FRV_F_CRJ, FRV_F_CRK, FRV_F_CCI, FRV_F_CRJ_INT + , FRV_F_CRJ_FLOAT, FRV_F_ICCI_1, FRV_F_ICCI_2, FRV_F_ICCI_3 + , FRV_F_FCCI_1, FRV_F_FCCI_2, FRV_F_FCCI_3, FRV_F_FCCK + , FRV_F_EIR, FRV_F_S10, FRV_F_S12, FRV_F_D12 + , FRV_F_U16, FRV_F_S16, FRV_F_S6, FRV_F_S6_1 + , FRV_F_U6, FRV_F_S5, FRV_F_U12_H, FRV_F_U12_L + , FRV_F_U12, FRV_F_INT_CC, FRV_F_FLT_CC, FRV_F_COND + , FRV_F_CCOND, FRV_F_HINT, FRV_F_LI, FRV_F_LOCK + , FRV_F_DEBUG, FRV_F_A, FRV_F_AE, FRV_F_SPR_H + , FRV_F_SPR_L, FRV_F_SPR, FRV_F_LABEL16, FRV_F_LABELH6 + , FRV_F_LABELL18, FRV_F_LABEL24, FRV_F_ICCI_1_NULL, FRV_F_ICCI_2_NULL + , FRV_F_ICCI_3_NULL, FRV_F_FCCI_1_NULL, FRV_F_FCCI_2_NULL, FRV_F_FCCI_3_NULL + , FRV_F_RS_NULL, FRV_F_GRI_NULL, FRV_F_GRJ_NULL, FRV_F_GRK_NULL + , FRV_F_FRI_NULL, FRV_F_FRJ_NULL, FRV_F_ACCJ_NULL, FRV_F_RD_NULL + , FRV_F_COND_NULL, FRV_F_CCOND_NULL, FRV_F_S12_NULL, FRV_F_LABEL16_NULL + , FRV_F_MISC_NULL_1, FRV_F_MISC_NULL_2, FRV_F_MISC_NULL_3, FRV_F_MISC_NULL_4 + , FRV_F_MISC_NULL_5, FRV_F_MISC_NULL_6, FRV_F_MISC_NULL_7, FRV_F_MISC_NULL_8 + , FRV_F_MISC_NULL_9, FRV_F_MISC_NULL_10, FRV_F_MISC_NULL_11, FRV_F_LI_OFF + , FRV_F_LI_ON, FRV_F_MAX +} IFIELD_TYPE; + +#define MAX_IFLD ((int) FRV_F_MAX) + +/* Hardware attribute indices. */ + +/* Enum declaration for cgen_hw attrs. */ +typedef enum cgen_hw_attr { + CGEN_HW_VIRTUAL, CGEN_HW_CACHE_ADDR, CGEN_HW_PC, CGEN_HW_PROFILE + , CGEN_HW_END_BOOLS, CGEN_HW_START_NBOOLS = 31, CGEN_HW_MACH, CGEN_HW_END_NBOOLS +} CGEN_HW_ATTR; + +/* Number of non-boolean elements in cgen_hw_attr. */ +#define CGEN_HW_NBOOL_ATTRS (CGEN_HW_END_NBOOLS - CGEN_HW_START_NBOOLS - 1) + +/* Enum declaration for frv hardware types. */ +typedef enum cgen_hw_type { + HW_H_MEMORY, HW_H_SINT, HW_H_UINT, HW_H_ADDR + , HW_H_IADDR, HW_H_PC, HW_H_PSR_IMPLE, HW_H_PSR_VER + , HW_H_PSR_ICE, HW_H_PSR_NEM, HW_H_PSR_CM, HW_H_PSR_BE + , HW_H_PSR_ESR, HW_H_PSR_EF, HW_H_PSR_EM, HW_H_PSR_PIL + , HW_H_PSR_PS, HW_H_PSR_ET, HW_H_PSR_S, HW_H_TBR_TBA + , HW_H_TBR_TT, HW_H_BPSR_BS, HW_H_BPSR_BET, HW_H_GR + , HW_H_GR_DOUBLE, HW_H_GR_HI, HW_H_GR_LO, HW_H_FR + , HW_H_FR_DOUBLE, HW_H_FR_INT, HW_H_FR_HI, HW_H_FR_LO + , HW_H_FR_0, HW_H_FR_1, HW_H_FR_2, HW_H_FR_3 + , HW_H_CPR, HW_H_CPR_DOUBLE, HW_H_SPR, HW_H_ACCG + , HW_H_ACC40S, HW_H_ACC40U, HW_H_ICCR, HW_H_FCCR + , HW_H_CCCR, HW_H_PACK, HW_H_HINT_TAKEN, HW_H_HINT_NOT_TAKEN + , HW_MAX +} CGEN_HW_TYPE; + +#define MAX_HW ((int) HW_MAX) + +/* Operand attribute indices. */ + +/* Enum declaration for cgen_operand attrs. */ +typedef enum cgen_operand_attr { + CGEN_OPERAND_VIRTUAL, CGEN_OPERAND_PCREL_ADDR, CGEN_OPERAND_ABS_ADDR, CGEN_OPERAND_SIGN_OPT + , CGEN_OPERAND_SIGNED, CGEN_OPERAND_NEGATIVE, CGEN_OPERAND_RELAX, CGEN_OPERAND_SEM_ONLY + , CGEN_OPERAND_HASH_PREFIX, CGEN_OPERAND_END_BOOLS, CGEN_OPERAND_START_NBOOLS = 31, CGEN_OPERAND_MACH + , CGEN_OPERAND_END_NBOOLS +} CGEN_OPERAND_ATTR; + +/* Number of non-boolean elements in cgen_operand_attr. */ +#define CGEN_OPERAND_NBOOL_ATTRS (CGEN_OPERAND_END_NBOOLS - CGEN_OPERAND_START_NBOOLS - 1) + +/* Enum declaration for frv operand types. */ +typedef enum cgen_operand_type { + FRV_OPERAND_PC, FRV_OPERAND_PACK, FRV_OPERAND_GRI, FRV_OPERAND_GRJ + , FRV_OPERAND_GRK, FRV_OPERAND_GRKHI, FRV_OPERAND_GRKLO, FRV_OPERAND_GRDOUBLEK + , FRV_OPERAND_ACC40SI, FRV_OPERAND_ACC40UI, FRV_OPERAND_ACC40SK, FRV_OPERAND_ACC40UK + , FRV_OPERAND_ACCGI, FRV_OPERAND_ACCGK, FRV_OPERAND_CPRI, FRV_OPERAND_CPRJ + , FRV_OPERAND_CPRK, FRV_OPERAND_CPRDOUBLEK, FRV_OPERAND_FRINTI, FRV_OPERAND_FRINTJ + , FRV_OPERAND_FRINTK, FRV_OPERAND_FRI, FRV_OPERAND_FRJ, FRV_OPERAND_FRK + , FRV_OPERAND_FRKHI, FRV_OPERAND_FRKLO, FRV_OPERAND_FRDOUBLEI, FRV_OPERAND_FRDOUBLEJ + , FRV_OPERAND_FRDOUBLEK, FRV_OPERAND_CRI, FRV_OPERAND_CRJ, FRV_OPERAND_CRJ_INT + , FRV_OPERAND_CRJ_FLOAT, FRV_OPERAND_CRK, FRV_OPERAND_CCI, FRV_OPERAND_ICCI_1 + , FRV_OPERAND_ICCI_2, FRV_OPERAND_ICCI_3, FRV_OPERAND_FCCI_1, FRV_OPERAND_FCCI_2 + , FRV_OPERAND_FCCI_3, FRV_OPERAND_FCCK, FRV_OPERAND_EIR, FRV_OPERAND_S10 + , FRV_OPERAND_U16, FRV_OPERAND_S16, FRV_OPERAND_S6, FRV_OPERAND_S6_1 + , FRV_OPERAND_U6, FRV_OPERAND_S5, FRV_OPERAND_COND, FRV_OPERAND_CCOND + , FRV_OPERAND_HINT, FRV_OPERAND_HINT_TAKEN, FRV_OPERAND_HINT_NOT_TAKEN, FRV_OPERAND_LI + , FRV_OPERAND_LOCK, FRV_OPERAND_DEBUG, FRV_OPERAND_A, FRV_OPERAND_AE + , FRV_OPERAND_LABEL16, FRV_OPERAND_LABEL24, FRV_OPERAND_D12, FRV_OPERAND_S12 + , FRV_OPERAND_U12, FRV_OPERAND_SPR, FRV_OPERAND_ULO16, FRV_OPERAND_SLO16 + , FRV_OPERAND_UHI16, FRV_OPERAND_PSR_ESR, FRV_OPERAND_PSR_S, FRV_OPERAND_PSR_PS + , FRV_OPERAND_PSR_ET, FRV_OPERAND_BPSR_BS, FRV_OPERAND_BPSR_BET, FRV_OPERAND_TBR_TBA + , FRV_OPERAND_TBR_TT, FRV_OPERAND_MAX +} CGEN_OPERAND_TYPE; + +/* Number of operands types. */ +#define MAX_OPERANDS 77 + +/* Maximum number of operands referenced by any insn. */ +#define MAX_OPERAND_INSTANCES 8 + +/* Insn attribute indices. */ + +/* Enum declaration for cgen_insn attrs. */ +typedef enum cgen_insn_attr { + CGEN_INSN_ALIAS, CGEN_INSN_VIRTUAL, CGEN_INSN_UNCOND_CTI, CGEN_INSN_COND_CTI + , CGEN_INSN_SKIP_CTI, CGEN_INSN_DELAY_SLOT, CGEN_INSN_RELAXABLE, CGEN_INSN_RELAX + , CGEN_INSN_NO_DIS, CGEN_INSN_PBB, CGEN_INSN_PRIVILEGED, CGEN_INSN_NON_EXCEPTING + , CGEN_INSN_CONDITIONAL, CGEN_INSN_FR_ACCESS, CGEN_INSN_PRESERVE_OVF, CGEN_INSN_END_BOOLS + , CGEN_INSN_START_NBOOLS = 31, CGEN_INSN_MACH, CGEN_INSN_UNIT, CGEN_INSN_FR400_MAJOR + , CGEN_INSN_FR500_MAJOR, CGEN_INSN_END_NBOOLS +} CGEN_INSN_ATTR; + +/* Number of non-boolean elements in cgen_insn_attr. */ +#define CGEN_INSN_NBOOL_ATTRS (CGEN_INSN_END_NBOOLS - CGEN_INSN_START_NBOOLS - 1) + +/* cgen.h uses things we just defined. */ +#include "opcode/cgen.h" + +/* Attributes. */ +extern const CGEN_ATTR_TABLE frv_cgen_hardware_attr_table[]; +extern const CGEN_ATTR_TABLE frv_cgen_ifield_attr_table[]; +extern const CGEN_ATTR_TABLE frv_cgen_operand_attr_table[]; +extern const CGEN_ATTR_TABLE frv_cgen_insn_attr_table[]; + +/* Hardware decls. */ + +extern CGEN_KEYWORD frv_cgen_opval_gr_names; +extern CGEN_KEYWORD frv_cgen_opval_gr_names; +extern CGEN_KEYWORD frv_cgen_opval_gr_names; +extern CGEN_KEYWORD frv_cgen_opval_gr_names; +extern CGEN_KEYWORD frv_cgen_opval_fr_names; +extern CGEN_KEYWORD frv_cgen_opval_fr_names; +extern CGEN_KEYWORD frv_cgen_opval_fr_names; +extern CGEN_KEYWORD frv_cgen_opval_fr_names; +extern CGEN_KEYWORD frv_cgen_opval_fr_names; +extern CGEN_KEYWORD frv_cgen_opval_fr_names; +extern CGEN_KEYWORD frv_cgen_opval_fr_names; +extern CGEN_KEYWORD frv_cgen_opval_fr_names; +extern CGEN_KEYWORD frv_cgen_opval_fr_names; +extern CGEN_KEYWORD frv_cgen_opval_cpr_names; +extern CGEN_KEYWORD frv_cgen_opval_cpr_names; +extern CGEN_KEYWORD frv_cgen_opval_spr_names; +extern CGEN_KEYWORD frv_cgen_opval_accg_names; +extern CGEN_KEYWORD frv_cgen_opval_acc_names; +extern CGEN_KEYWORD frv_cgen_opval_acc_names; +extern CGEN_KEYWORD frv_cgen_opval_iccr_names; +extern CGEN_KEYWORD frv_cgen_opval_fccr_names; +extern CGEN_KEYWORD frv_cgen_opval_cccr_names; +extern CGEN_KEYWORD frv_cgen_opval_h_pack; +extern CGEN_KEYWORD frv_cgen_opval_h_hint_taken; +extern CGEN_KEYWORD frv_cgen_opval_h_hint_not_taken; + + + + +#endif /* FRV_CPU_H */ diff --git a/opcodes/frv-dis.c b/opcodes/frv-dis.c new file mode 100644 index 0000000..a637876 --- /dev/null +++ b/opcodes/frv-dis.c @@ -0,0 +1,789 @@ +/* Disassembler interface for targets using CGEN. -*- C -*- + CGEN: Cpu tools GENerator + +THIS FILE IS MACHINE GENERATED WITH CGEN. +- the resultant file is machine generated, cgen-dis.in isn't + +Copyright 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + +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. */ + +/* ??? Eventually more and more of this stuff can go to cpu-independent files. + Keep that in mind. */ + +#include "sysdep.h" +#include +#include "ansidecl.h" +#include "dis-asm.h" +#include "bfd.h" +#include "symcat.h" +#include "frv-desc.h" +#include "frv-opc.h" +#include "opintl.h" + +/* Default text to print if an instruction isn't recognized. */ +#define UNKNOWN_INSN_MSG _("*unknown*") + +static void print_normal + PARAMS ((CGEN_CPU_DESC, PTR, long, unsigned int, bfd_vma, int)); +static void print_address + PARAMS ((CGEN_CPU_DESC, PTR, bfd_vma, unsigned int, bfd_vma, int)); +static void print_keyword + PARAMS ((CGEN_CPU_DESC, PTR, CGEN_KEYWORD *, long, unsigned int)); +static void print_insn_normal + PARAMS ((CGEN_CPU_DESC, PTR, const CGEN_INSN *, CGEN_FIELDS *, + bfd_vma, int)); +static int print_insn + PARAMS ((CGEN_CPU_DESC, bfd_vma, disassemble_info *, char *, unsigned)); +static int default_print_insn + PARAMS ((CGEN_CPU_DESC, bfd_vma, disassemble_info *)); +static int read_insn + PARAMS ((CGEN_CPU_DESC, bfd_vma, disassemble_info *, char *, int, + CGEN_EXTRACT_INFO *, unsigned long *)); + +/* -- disassembler routines inserted here */ + +/* -- dis.c */ +static void print_spr + PARAMS ((CGEN_CPU_DESC, PTR, CGEN_KEYWORD *, long, unsigned)); +static void print_hi + PARAMS ((CGEN_CPU_DESC, PTR, long, unsigned, bfd_vma, int)); +static void print_lo + PARAMS ((CGEN_CPU_DESC, PTR, long, unsigned, bfd_vma, int)); + +static void +print_spr (cd, dis_info, names, regno, attrs) + CGEN_CPU_DESC cd; + PTR dis_info; + CGEN_KEYWORD *names; + long regno; + unsigned int attrs; +{ + /* Use the register index format for any unnamed registers. */ + if (cgen_keyword_lookup_value (names, regno) == NULL) + { + disassemble_info *info = (disassemble_info *) dis_info; + (*info->fprintf_func) (info->stream, "spr[%ld]", regno); + } + else + print_keyword (cd, dis_info, names, regno, attrs); +} + +static void +print_hi (cd, dis_info, value, attrs, pc, length) + CGEN_CPU_DESC cd ATTRIBUTE_UNUSED; + PTR dis_info; + long value; + unsigned int attrs ATTRIBUTE_UNUSED; + bfd_vma pc ATTRIBUTE_UNUSED; + int length ATTRIBUTE_UNUSED; +{ + disassemble_info *info = (disassemble_info *) dis_info; + if (value) + (*info->fprintf_func) (info->stream, "0x%lx", value); + else + (*info->fprintf_func) (info->stream, "hi(0x%lx)", value); +} + +static void +print_lo (cd, dis_info, value, attrs, pc, length) + CGEN_CPU_DESC cd ATTRIBUTE_UNUSED; + PTR dis_info; + long value; + unsigned int attrs ATTRIBUTE_UNUSED; + bfd_vma pc ATTRIBUTE_UNUSED; + int length ATTRIBUTE_UNUSED; +{ + disassemble_info *info = (disassemble_info *) dis_info; + if (value) + (*info->fprintf_func) (info->stream, "0x%lx", value); + else + (*info->fprintf_func) (info->stream, "lo(0x%lx)", value); +} + +/* -- */ + +void frv_cgen_print_operand + PARAMS ((CGEN_CPU_DESC, int, PTR, CGEN_FIELDS *, + void const *, bfd_vma, int)); + +/* Main entry point for printing operands. + XINFO is a `void *' and not a `disassemble_info *' to not put a requirement + of dis-asm.h on cgen.h. + + This function is basically just a big switch statement. Earlier versions + used tables to look up the function to use, but + - if the table contains both assembler and disassembler functions then + the disassembler contains much of the assembler and vice-versa, + - there's a lot of inlining possibilities as things grow, + - using a switch statement avoids the function call overhead. + + This function could be moved into `print_insn_normal', but keeping it + separate makes clear the interface between `print_insn_normal' and each of + the handlers. */ + +void +frv_cgen_print_operand (cd, opindex, xinfo, fields, attrs, pc, length) + CGEN_CPU_DESC cd; + int opindex; + PTR xinfo; + CGEN_FIELDS *fields; + void const *attrs ATTRIBUTE_UNUSED; + bfd_vma pc; + int length; +{ + disassemble_info *info = (disassemble_info *) xinfo; + + switch (opindex) + { + case FRV_OPERAND_A : + print_normal (cd, info, fields->f_A, 0|(1<f_ACC40Si, 0); + break; + case FRV_OPERAND_ACC40SK : + print_keyword (cd, info, & frv_cgen_opval_acc_names, fields->f_ACC40Sk, 0); + break; + case FRV_OPERAND_ACC40UI : + print_keyword (cd, info, & frv_cgen_opval_acc_names, fields->f_ACC40Ui, 0); + break; + case FRV_OPERAND_ACC40UK : + print_keyword (cd, info, & frv_cgen_opval_acc_names, fields->f_ACC40Uk, 0); + break; + case FRV_OPERAND_ACCGI : + print_keyword (cd, info, & frv_cgen_opval_accg_names, fields->f_ACCGi, 0); + break; + case FRV_OPERAND_ACCGK : + print_keyword (cd, info, & frv_cgen_opval_accg_names, fields->f_ACCGk, 0); + break; + case FRV_OPERAND_CCI : + print_keyword (cd, info, & frv_cgen_opval_cccr_names, fields->f_CCi, 0); + break; + case FRV_OPERAND_CPRDOUBLEK : + print_keyword (cd, info, & frv_cgen_opval_cpr_names, fields->f_CPRk, 0); + break; + case FRV_OPERAND_CPRI : + print_keyword (cd, info, & frv_cgen_opval_cpr_names, fields->f_CPRi, 0); + break; + case FRV_OPERAND_CPRJ : + print_keyword (cd, info, & frv_cgen_opval_cpr_names, fields->f_CPRj, 0); + break; + case FRV_OPERAND_CPRK : + print_keyword (cd, info, & frv_cgen_opval_cpr_names, fields->f_CPRk, 0); + break; + case FRV_OPERAND_CRI : + print_keyword (cd, info, & frv_cgen_opval_cccr_names, fields->f_CRi, 0); + break; + case FRV_OPERAND_CRJ : + print_keyword (cd, info, & frv_cgen_opval_cccr_names, fields->f_CRj, 0); + break; + case FRV_OPERAND_CRJ_FLOAT : + print_keyword (cd, info, & frv_cgen_opval_cccr_names, fields->f_CRj_float, 0); + break; + case FRV_OPERAND_CRJ_INT : + print_keyword (cd, info, & frv_cgen_opval_cccr_names, fields->f_CRj_int, 0); + break; + case FRV_OPERAND_CRK : + print_keyword (cd, info, & frv_cgen_opval_cccr_names, fields->f_CRk, 0); + break; + case FRV_OPERAND_FCCI_1 : + print_keyword (cd, info, & frv_cgen_opval_fccr_names, fields->f_FCCi_1, 0); + break; + case FRV_OPERAND_FCCI_2 : + print_keyword (cd, info, & frv_cgen_opval_fccr_names, fields->f_FCCi_2, 0); + break; + case FRV_OPERAND_FCCI_3 : + print_keyword (cd, info, & frv_cgen_opval_fccr_names, fields->f_FCCi_3, 0); + break; + case FRV_OPERAND_FCCK : + print_keyword (cd, info, & frv_cgen_opval_fccr_names, fields->f_FCCk, 0); + break; + case FRV_OPERAND_FRDOUBLEI : + print_keyword (cd, info, & frv_cgen_opval_fr_names, fields->f_FRi, 0); + break; + case FRV_OPERAND_FRDOUBLEJ : + print_keyword (cd, info, & frv_cgen_opval_fr_names, fields->f_FRj, 0); + break; + case FRV_OPERAND_FRDOUBLEK : + print_keyword (cd, info, & frv_cgen_opval_fr_names, fields->f_FRk, 0); + break; + case FRV_OPERAND_FRI : + print_keyword (cd, info, & frv_cgen_opval_fr_names, fields->f_FRi, 0); + break; + case FRV_OPERAND_FRINTI : + print_keyword (cd, info, & frv_cgen_opval_fr_names, fields->f_FRi, 0); + break; + case FRV_OPERAND_FRINTJ : + print_keyword (cd, info, & frv_cgen_opval_fr_names, fields->f_FRj, 0); + break; + case FRV_OPERAND_FRINTK : + print_keyword (cd, info, & frv_cgen_opval_fr_names, fields->f_FRk, 0); + break; + case FRV_OPERAND_FRJ : + print_keyword (cd, info, & frv_cgen_opval_fr_names, fields->f_FRj, 0); + break; + case FRV_OPERAND_FRK : + print_keyword (cd, info, & frv_cgen_opval_fr_names, fields->f_FRk, 0); + break; + case FRV_OPERAND_FRKHI : + print_keyword (cd, info, & frv_cgen_opval_fr_names, fields->f_FRk, 0); + break; + case FRV_OPERAND_FRKLO : + print_keyword (cd, info, & frv_cgen_opval_fr_names, fields->f_FRk, 0); + break; + case FRV_OPERAND_GRDOUBLEK : + print_keyword (cd, info, & frv_cgen_opval_gr_names, fields->f_GRk, 0); + break; + case FRV_OPERAND_GRI : + print_keyword (cd, info, & frv_cgen_opval_gr_names, fields->f_GRi, 0); + break; + case FRV_OPERAND_GRJ : + print_keyword (cd, info, & frv_cgen_opval_gr_names, fields->f_GRj, 0); + break; + case FRV_OPERAND_GRK : + print_keyword (cd, info, & frv_cgen_opval_gr_names, fields->f_GRk, 0); + break; + case FRV_OPERAND_GRKHI : + print_keyword (cd, info, & frv_cgen_opval_gr_names, fields->f_GRk, 0); + break; + case FRV_OPERAND_GRKLO : + print_keyword (cd, info, & frv_cgen_opval_gr_names, fields->f_GRk, 0); + break; + case FRV_OPERAND_ICCI_1 : + print_keyword (cd, info, & frv_cgen_opval_iccr_names, fields->f_ICCi_1, 0); + break; + case FRV_OPERAND_ICCI_2 : + print_keyword (cd, info, & frv_cgen_opval_iccr_names, fields->f_ICCi_2, 0); + break; + case FRV_OPERAND_ICCI_3 : + print_keyword (cd, info, & frv_cgen_opval_iccr_names, fields->f_ICCi_3, 0); + break; + case FRV_OPERAND_LI : + print_normal (cd, info, fields->f_LI, 0, pc, length); + break; + case FRV_OPERAND_AE : + print_normal (cd, info, fields->f_ae, 0|(1<f_ccond, 0|(1<f_cond, 0|(1<f_d12, 0|(1<f_debug, 0|(1<f_eir, 0, pc, length); + break; + case FRV_OPERAND_HINT : + print_normal (cd, info, fields->f_hint, 0|(1<f_hint, 0); + break; + case FRV_OPERAND_HINT_TAKEN : + print_keyword (cd, info, & frv_cgen_opval_h_hint_taken, fields->f_hint, 0); + break; + case FRV_OPERAND_LABEL16 : + print_address (cd, info, fields->f_label16, 0|(1<f_label24, 0|(1<f_lock, 0|(1<f_pack, 0); + break; + case FRV_OPERAND_S10 : + print_normal (cd, info, fields->f_s10, 0|(1<f_d12, 0|(1<f_s16, 0|(1<f_s5, 0|(1<f_s6, 0|(1<f_s6_1, 0|(1<f_s16, 0|(1<f_spr, 0|(1<f_u12, 0|(1<f_u16, 0|(1<f_u6, 0|(1<f_u16, 0, pc, length); + break; + case FRV_OPERAND_ULO16 : + print_lo (cd, info, fields->f_u16, 0, pc, length); + break; + + default : + /* xgettext:c-format */ + fprintf (stderr, _("Unrecognized field %d while printing insn.\n"), + opindex); + abort (); + } +} + +cgen_print_fn * const frv_cgen_print_handlers[] = +{ + print_insn_normal, +}; + + +void +frv_cgen_init_dis (cd) + CGEN_CPU_DESC cd; +{ + frv_cgen_init_opcode_table (cd); + frv_cgen_init_ibld_table (cd); + cd->print_handlers = & frv_cgen_print_handlers[0]; + cd->print_operand = frv_cgen_print_operand; +} + + +/* Default print handler. */ + +static void +print_normal (cd, dis_info, value, attrs, pc, length) + CGEN_CPU_DESC cd ATTRIBUTE_UNUSED; + PTR dis_info; + long value; + unsigned int attrs; + bfd_vma pc ATTRIBUTE_UNUSED; + int length ATTRIBUTE_UNUSED; +{ + disassemble_info *info = (disassemble_info *) dis_info; + +#ifdef CGEN_PRINT_NORMAL + CGEN_PRINT_NORMAL (cd, info, value, attrs, pc, length); +#endif + + /* Print the operand as directed by the attributes. */ + if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY)) + ; /* nothing to do */ + else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SIGNED)) + (*info->fprintf_func) (info->stream, "%ld", value); + else + (*info->fprintf_func) (info->stream, "0x%lx", value); +} + +/* Default address handler. */ + +static void +print_address (cd, dis_info, value, attrs, pc, length) + CGEN_CPU_DESC cd ATTRIBUTE_UNUSED; + PTR dis_info; + bfd_vma value; + unsigned int attrs; + bfd_vma pc ATTRIBUTE_UNUSED; + int length ATTRIBUTE_UNUSED; +{ + disassemble_info *info = (disassemble_info *) dis_info; + +#ifdef CGEN_PRINT_ADDRESS + CGEN_PRINT_ADDRESS (cd, info, value, attrs, pc, length); +#endif + + /* Print the operand as directed by the attributes. */ + if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY)) + ; /* nothing to do */ + else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_PCREL_ADDR)) + (*info->print_address_func) (value, info); + else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_ABS_ADDR)) + (*info->print_address_func) (value, info); + else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SIGNED)) + (*info->fprintf_func) (info->stream, "%ld", (long) value); + else + (*info->fprintf_func) (info->stream, "0x%lx", (long) value); +} + +/* Keyword print handler. */ + +static void +print_keyword (cd, dis_info, keyword_table, value, attrs) + CGEN_CPU_DESC cd ATTRIBUTE_UNUSED; + PTR dis_info; + CGEN_KEYWORD *keyword_table; + long value; + unsigned int attrs ATTRIBUTE_UNUSED; +{ + disassemble_info *info = (disassemble_info *) dis_info; + const CGEN_KEYWORD_ENTRY *ke; + + ke = cgen_keyword_lookup_value (keyword_table, value); + if (ke != NULL) + (*info->fprintf_func) (info->stream, "%s", ke->name); + else + (*info->fprintf_func) (info->stream, "???"); +} + +/* Default insn printer. + + DIS_INFO is defined as `PTR' so the disassembler needn't know anything + about disassemble_info. */ + +static void +print_insn_normal (cd, dis_info, insn, fields, pc, length) + CGEN_CPU_DESC cd; + PTR dis_info; + const CGEN_INSN *insn; + CGEN_FIELDS *fields; + bfd_vma pc; + int length; +{ + const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn); + disassemble_info *info = (disassemble_info *) dis_info; + const CGEN_SYNTAX_CHAR_TYPE *syn; + + CGEN_INIT_PRINT (cd); + + for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn) + { + if (CGEN_SYNTAX_MNEMONIC_P (*syn)) + { + (*info->fprintf_func) (info->stream, "%s", CGEN_INSN_MNEMONIC (insn)); + continue; + } + if (CGEN_SYNTAX_CHAR_P (*syn)) + { + (*info->fprintf_func) (info->stream, "%c", CGEN_SYNTAX_CHAR (*syn)); + continue; + } + + /* We have an operand. */ + frv_cgen_print_operand (cd, CGEN_SYNTAX_FIELD (*syn), info, + fields, CGEN_INSN_ATTRS (insn), pc, length); + } +} + +/* Subroutine of print_insn. Reads an insn into the given buffers and updates + the extract info. + Returns 0 if all is well, non-zero otherwise. */ + +static int +read_insn (cd, pc, info, buf, buflen, ex_info, insn_value) + CGEN_CPU_DESC cd ATTRIBUTE_UNUSED; + bfd_vma pc; + disassemble_info *info; + char *buf; + int buflen; + CGEN_EXTRACT_INFO *ex_info; + unsigned long *insn_value; +{ + int status = (*info->read_memory_func) (pc, buf, buflen, info); + if (status != 0) + { + (*info->memory_error_func) (status, pc, info); + return -1; + } + + ex_info->dis_info = info; + ex_info->valid = (1 << buflen) - 1; + ex_info->insn_bytes = buf; + + *insn_value = bfd_get_bits (buf, buflen * 8, info->endian == BFD_ENDIAN_BIG); + return 0; +} + +/* Utility to print an insn. + BUF is the base part of the insn, target byte order, BUFLEN bytes long. + The result is the size of the insn in bytes or zero for an unknown insn + or -1 if an error occurs fetching data (memory_error_func will have + been called). */ + +static int +print_insn (cd, pc, info, buf, buflen) + CGEN_CPU_DESC cd; + bfd_vma pc; + disassemble_info *info; + char *buf; + unsigned int buflen; +{ + CGEN_INSN_INT insn_value; + const CGEN_INSN_LIST *insn_list; + CGEN_EXTRACT_INFO ex_info; + int basesize; + + /* Extract base part of instruction, just in case CGEN_DIS_* uses it. */ + basesize = cd->base_insn_bitsize < buflen * 8 ? + cd->base_insn_bitsize : buflen * 8; + insn_value = cgen_get_insn_value (cd, buf, basesize); + + + /* Fill in ex_info fields like read_insn would. Don't actually call + read_insn, since the incoming buffer is already read (and possibly + modified a la m32r). */ + ex_info.valid = (1 << buflen) - 1; + ex_info.dis_info = info; + ex_info.insn_bytes = buf; + + /* The instructions are stored in hash lists. + Pick the first one and keep trying until we find the right one. */ + + insn_list = CGEN_DIS_LOOKUP_INSN (cd, buf, insn_value); + while (insn_list != NULL) + { + const CGEN_INSN *insn = insn_list->insn; + CGEN_FIELDS fields; + int length; + unsigned long insn_value_cropped; + +#ifdef CGEN_VALIDATE_INSN_SUPPORTED + /* Not needed as insn shouldn't be in hash lists if not supported. */ + /* Supported by this cpu? */ + if (! frv_cgen_insn_supported (cd, insn)) + { + insn_list = CGEN_DIS_NEXT_INSN (insn_list); + continue; + } +#endif + + /* Basic bit mask must be correct. */ + /* ??? May wish to allow target to defer this check until the extract + handler. */ + + /* Base size may exceed this instruction's size. Extract the + relevant part from the buffer. */ + if ((unsigned) (CGEN_INSN_BITSIZE (insn) / 8) < buflen && + (unsigned) (CGEN_INSN_BITSIZE (insn) / 8) <= sizeof (unsigned long)) + insn_value_cropped = bfd_get_bits (buf, CGEN_INSN_BITSIZE (insn), + info->endian == BFD_ENDIAN_BIG); + else + insn_value_cropped = insn_value; + + if ((insn_value_cropped & CGEN_INSN_BASE_MASK (insn)) + == CGEN_INSN_BASE_VALUE (insn)) + { + /* Printing is handled in two passes. The first pass parses the + machine insn and extracts the fields. The second pass prints + them. */ + + /* Make sure the entire insn is loaded into insn_value, if it + can fit. */ + if (((unsigned) CGEN_INSN_BITSIZE (insn) > cd->base_insn_bitsize) && + (unsigned) (CGEN_INSN_BITSIZE (insn) / 8) <= sizeof (unsigned long)) + { + unsigned long full_insn_value; + int rc = read_insn (cd, pc, info, buf, + CGEN_INSN_BITSIZE (insn) / 8, + & ex_info, & full_insn_value); + if (rc != 0) + return rc; + length = CGEN_EXTRACT_FN (cd, insn) + (cd, insn, &ex_info, full_insn_value, &fields, pc); + } + else + length = CGEN_EXTRACT_FN (cd, insn) + (cd, insn, &ex_info, insn_value_cropped, &fields, pc); + + /* length < 0 -> error */ + if (length < 0) + return length; + if (length > 0) + { + CGEN_PRINT_FN (cd, insn) (cd, info, insn, &fields, pc, length); + /* length is in bits, result is in bytes */ + return length / 8; + } + } + + insn_list = CGEN_DIS_NEXT_INSN (insn_list); + } + + return 0; +} + +/* Default value for CGEN_PRINT_INSN. + The result is the size of the insn in bytes or zero for an unknown insn + or -1 if an error occured fetching bytes. */ + +#ifndef CGEN_PRINT_INSN +#define CGEN_PRINT_INSN default_print_insn +#endif + +static int +default_print_insn (cd, pc, info) + CGEN_CPU_DESC cd; + bfd_vma pc; + disassemble_info *info; +{ + char buf[CGEN_MAX_INSN_SIZE]; + int buflen; + int status; + + /* Attempt to read the base part of the insn. */ + buflen = cd->base_insn_bitsize / 8; + status = (*info->read_memory_func) (pc, buf, buflen, info); + + /* Try again with the minimum part, if min < base. */ + if (status != 0 && (cd->min_insn_bitsize < cd->base_insn_bitsize)) + { + buflen = cd->min_insn_bitsize / 8; + status = (*info->read_memory_func) (pc, buf, buflen, info); + } + + if (status != 0) + { + (*info->memory_error_func) (status, pc, info); + return -1; + } + + return print_insn (cd, pc, info, buf, buflen); +} + +/* Main entry point. + Print one instruction from PC on INFO->STREAM. + Return the size of the instruction (in bytes). */ + +typedef struct cpu_desc_list { + struct cpu_desc_list *next; + int isa; + int mach; + int endian; + CGEN_CPU_DESC cd; +} cpu_desc_list; + +int +print_insn_frv (pc, info) + bfd_vma pc; + disassemble_info *info; +{ + static cpu_desc_list *cd_list = 0; + cpu_desc_list *cl = 0; + static CGEN_CPU_DESC cd = 0; + static int prev_isa; + static int prev_mach; + static int prev_endian; + int length; + int isa,mach; + int endian = (info->endian == BFD_ENDIAN_BIG + ? CGEN_ENDIAN_BIG + : CGEN_ENDIAN_LITTLE); + enum bfd_architecture arch; + + /* ??? gdb will set mach but leave the architecture as "unknown" */ +#ifndef CGEN_BFD_ARCH +#define CGEN_BFD_ARCH bfd_arch_frv +#endif + arch = info->arch; + if (arch == bfd_arch_unknown) + arch = CGEN_BFD_ARCH; + + /* There's no standard way to compute the machine or isa number + so we leave it to the target. */ +#ifdef CGEN_COMPUTE_MACH + mach = CGEN_COMPUTE_MACH (info); +#else + mach = info->mach; +#endif + +#ifdef CGEN_COMPUTE_ISA + isa = CGEN_COMPUTE_ISA (info); +#else + isa = info->insn_sets; +#endif + + /* If we've switched cpu's, try to find a handle we've used before */ + if (cd + && (isa != prev_isa + || mach != prev_mach + || endian != prev_endian)) + { + cd = 0; + for (cl = cd_list; cl; cl = cl->next) + { + if (cl->isa == isa && + cl->mach == mach && + cl->endian == endian) + { + cd = cl->cd; + break; + } + } + } + + /* If we haven't initialized yet, initialize the opcode table. */ + if (! cd) + { + const bfd_arch_info_type *arch_type = bfd_lookup_arch (arch, mach); + const char *mach_name; + + if (!arch_type) + abort (); + mach_name = arch_type->printable_name; + + prev_isa = isa; + prev_mach = mach; + prev_endian = endian; + cd = frv_cgen_cpu_open (CGEN_CPU_OPEN_ISAS, prev_isa, + CGEN_CPU_OPEN_BFDMACH, mach_name, + CGEN_CPU_OPEN_ENDIAN, prev_endian, + CGEN_CPU_OPEN_END); + if (!cd) + abort (); + + /* save this away for future reference */ + cl = xmalloc (sizeof (struct cpu_desc_list)); + cl->cd = cd; + cl->isa = isa; + cl->mach = mach; + cl->endian = endian; + cl->next = cd_list; + cd_list = cl; + + frv_cgen_init_dis (cd); + } + + /* We try to have as much common code as possible. + But at this point some targets need to take over. */ + /* ??? Some targets may need a hook elsewhere. Try to avoid this, + but if not possible try to move this hook elsewhere rather than + have two hooks. */ + length = CGEN_PRINT_INSN (cd, pc, info); + if (length > 0) + return length; + if (length < 0) + return -1; + + (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG); + return cd->default_insn_bitsize / 8; +} diff --git a/opcodes/frv-ibld.c b/opcodes/frv-ibld.c new file mode 100644 index 0000000..316b2cc --- /dev/null +++ b/opcodes/frv-ibld.c @@ -0,0 +1,2051 @@ +/* Instruction building/extraction support for frv. -*- C -*- + +THIS FILE IS MACHINE GENERATED WITH CGEN: Cpu tools GENerator. +- the resultant file is machine generated, cgen-ibld.in isn't + +Copyright 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + +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. */ + +/* ??? Eventually more and more of this stuff can go to cpu-independent files. + Keep that in mind. */ + +#include "sysdep.h" +#include +#include "ansidecl.h" +#include "dis-asm.h" +#include "bfd.h" +#include "symcat.h" +#include "frv-desc.h" +#include "frv-opc.h" +#include "opintl.h" +#include "safe-ctype.h" + +#undef min +#define min(a,b) ((a) < (b) ? (a) : (b)) +#undef max +#define max(a,b) ((a) > (b) ? (a) : (b)) + +/* Used by the ifield rtx function. */ +#define FLD(f) (fields->f) + +static const char * insert_normal + PARAMS ((CGEN_CPU_DESC, long, unsigned int, unsigned int, unsigned int, + unsigned int, unsigned int, unsigned int, CGEN_INSN_BYTES_PTR)); +static const char * insert_insn_normal + PARAMS ((CGEN_CPU_DESC, const CGEN_INSN *, + CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma)); +static int extract_normal + PARAMS ((CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, + unsigned int, unsigned int, unsigned int, unsigned int, + unsigned int, unsigned int, bfd_vma, long *)); +static int extract_insn_normal + PARAMS ((CGEN_CPU_DESC, const CGEN_INSN *, CGEN_EXTRACT_INFO *, + CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma)); +#if CGEN_INT_INSN_P +static void put_insn_int_value + PARAMS ((CGEN_CPU_DESC, CGEN_INSN_BYTES_PTR, int, int, CGEN_INSN_INT)); +#endif +#if ! CGEN_INT_INSN_P +static CGEN_INLINE void insert_1 + PARAMS ((CGEN_CPU_DESC, unsigned long, int, int, int, unsigned char *)); +static CGEN_INLINE int fill_cache + PARAMS ((CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, int, int, bfd_vma)); +static CGEN_INLINE long extract_1 + PARAMS ((CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, int, int, int, + unsigned char *, bfd_vma)); +#endif + +/* Operand insertion. */ + +#if ! CGEN_INT_INSN_P + +/* Subroutine of insert_normal. */ + +static CGEN_INLINE void +insert_1 (cd, value, start, length, word_length, bufp) + CGEN_CPU_DESC cd; + unsigned long value; + int start,length,word_length; + unsigned char *bufp; +{ + unsigned long x,mask; + int shift; + + x = cgen_get_insn_value (cd, bufp, word_length); + + /* Written this way to avoid undefined behaviour. */ + mask = (((1L << (length - 1)) - 1) << 1) | 1; + if (CGEN_INSN_LSB0_P) + shift = (start + 1) - length; + else + shift = (word_length - (start + length)); + x = (x & ~(mask << shift)) | ((value & mask) << shift); + + cgen_put_insn_value (cd, bufp, word_length, (bfd_vma) x); +} + +#endif /* ! CGEN_INT_INSN_P */ + +/* Default insertion routine. + + ATTRS is a mask of the boolean attributes. + WORD_OFFSET is the offset in bits from the start of the insn of the value. + WORD_LENGTH is the length of the word in bits in which the value resides. + START is the starting bit number in the word, architecture origin. + LENGTH is the length of VALUE in bits. + TOTAL_LENGTH is the total length of the insn in bits. + + The result is an error message or NULL if success. */ + +/* ??? This duplicates functionality with bfd's howto table and + bfd_install_relocation. */ +/* ??? This doesn't handle bfd_vma's. Create another function when + necessary. */ + +static const char * +insert_normal (cd, value, attrs, word_offset, start, length, word_length, + total_length, buffer) + CGEN_CPU_DESC cd; + long value; + unsigned int attrs; + unsigned int word_offset, start, length, word_length, total_length; + CGEN_INSN_BYTES_PTR buffer; +{ + static char errbuf[100]; + /* Written this way to avoid undefined behaviour. */ + unsigned long mask = (((1L << (length - 1)) - 1) << 1) | 1; + + /* If LENGTH is zero, this operand doesn't contribute to the value. */ + if (length == 0) + return NULL; + +#if 0 + if (CGEN_INT_INSN_P + && word_offset != 0) + abort (); +#endif + + if (word_length > 32) + abort (); + + /* For architectures with insns smaller than the base-insn-bitsize, + word_length may be too big. */ + if (cd->min_insn_bitsize < cd->base_insn_bitsize) + { + if (word_offset == 0 + && word_length > total_length) + word_length = total_length; + } + + /* Ensure VALUE will fit. */ + if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGN_OPT)) + { + long minval = - (1L << (length - 1)); + unsigned long maxval = mask; + + if ((value > 0 && (unsigned long) value > maxval) + || value < minval) + { + /* xgettext:c-format */ + sprintf (errbuf, + _("operand out of range (%ld not between %ld and %lu)"), + value, minval, maxval); + return errbuf; + } + } + else if (! CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED)) + { + unsigned long maxval = mask; + + if ((unsigned long) value > maxval) + { + /* xgettext:c-format */ + sprintf (errbuf, + _("operand out of range (%lu not between 0 and %lu)"), + value, maxval); + return errbuf; + } + } + else + { + if (! cgen_signed_overflow_ok_p (cd)) + { + long minval = - (1L << (length - 1)); + long maxval = (1L << (length - 1)) - 1; + + if (value < minval || value > maxval) + { + sprintf + /* xgettext:c-format */ + (errbuf, _("operand out of range (%ld not between %ld and %ld)"), + value, minval, maxval); + return errbuf; + } + } + } + +#if CGEN_INT_INSN_P + + { + int shift; + + if (CGEN_INSN_LSB0_P) + shift = (word_offset + start + 1) - length; + else + shift = total_length - (word_offset + start + length); + *buffer = (*buffer & ~(mask << shift)) | ((value & mask) << shift); + } + +#else /* ! CGEN_INT_INSN_P */ + + { + unsigned char *bufp = (unsigned char *) buffer + word_offset / 8; + + insert_1 (cd, value, start, length, word_length, bufp); + } + +#endif /* ! CGEN_INT_INSN_P */ + + return NULL; +} + +/* Default insn builder (insert handler). + The instruction is recorded in CGEN_INT_INSN_P byte order (meaning + that if CGEN_INSN_BYTES_PTR is an int * and thus, the value is + recorded in host byte order, otherwise BUFFER is an array of bytes + and the value is recorded in target byte order). + The result is an error message or NULL if success. */ + +static const char * +insert_insn_normal (cd, insn, fields, buffer, pc) + CGEN_CPU_DESC cd; + const CGEN_INSN * insn; + CGEN_FIELDS * fields; + CGEN_INSN_BYTES_PTR buffer; + bfd_vma pc; +{ + const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn); + unsigned long value; + const CGEN_SYNTAX_CHAR_TYPE * syn; + + CGEN_INIT_INSERT (cd); + value = CGEN_INSN_BASE_VALUE (insn); + + /* If we're recording insns as numbers (rather than a string of bytes), + target byte order handling is deferred until later. */ + +#if CGEN_INT_INSN_P + + put_insn_int_value (cd, buffer, cd->base_insn_bitsize, + CGEN_FIELDS_BITSIZE (fields), value); + +#else + + cgen_put_insn_value (cd, buffer, min ((unsigned) cd->base_insn_bitsize, + (unsigned) CGEN_FIELDS_BITSIZE (fields)), + value); + +#endif /* ! CGEN_INT_INSN_P */ + + /* ??? It would be better to scan the format's fields. + Still need to be able to insert a value based on the operand though; + e.g. storing a branch displacement that got resolved later. + Needs more thought first. */ + + for (syn = CGEN_SYNTAX_STRING (syntax); * syn; ++ syn) + { + const char *errmsg; + + if (CGEN_SYNTAX_CHAR_P (* syn)) + continue; + + errmsg = (* cd->insert_operand) (cd, CGEN_SYNTAX_FIELD (*syn), + fields, buffer, pc); + if (errmsg) + return errmsg; + } + + return NULL; +} + +#if CGEN_INT_INSN_P +/* Cover function to store an insn value into an integral insn. Must go here + because it needs -desc.h for CGEN_INT_INSN_P. */ + +static void +put_insn_int_value (cd, buf, length, insn_length, value) + CGEN_CPU_DESC cd ATTRIBUTE_UNUSED; + CGEN_INSN_BYTES_PTR buf; + int length; + int insn_length; + CGEN_INSN_INT value; +{ + /* For architectures with insns smaller than the base-insn-bitsize, + length may be too big. */ + if (length > insn_length) + *buf = value; + else + { + int shift = insn_length - length; + /* Written this way to avoid undefined behaviour. */ + CGEN_INSN_INT mask = (((1L << (length - 1)) - 1) << 1) | 1; + *buf = (*buf & ~(mask << shift)) | ((value & mask) << shift); + } +} +#endif + +/* Operand extraction. */ + +#if ! CGEN_INT_INSN_P + +/* Subroutine of extract_normal. + Ensure sufficient bytes are cached in EX_INFO. + OFFSET is the offset in bytes from the start of the insn of the value. + BYTES is the length of the needed value. + Returns 1 for success, 0 for failure. */ + +static CGEN_INLINE int +fill_cache (cd, ex_info, offset, bytes, pc) + CGEN_CPU_DESC cd ATTRIBUTE_UNUSED; + CGEN_EXTRACT_INFO *ex_info; + int offset, bytes; + bfd_vma pc; +{ + /* It's doubtful that the middle part has already been fetched so + we don't optimize that case. kiss. */ + unsigned int mask; + disassemble_info *info = (disassemble_info *) ex_info->dis_info; + + /* First do a quick check. */ + mask = (1 << bytes) - 1; + if (((ex_info->valid >> offset) & mask) == mask) + return 1; + + /* Search for the first byte we need to read. */ + for (mask = 1 << offset; bytes > 0; --bytes, ++offset, mask <<= 1) + if (! (mask & ex_info->valid)) + break; + + if (bytes) + { + int status; + + pc += offset; + status = (*info->read_memory_func) + (pc, ex_info->insn_bytes + offset, bytes, info); + + if (status != 0) + { + (*info->memory_error_func) (status, pc, info); + return 0; + } + + ex_info->valid |= ((1 << bytes) - 1) << offset; + } + + return 1; +} + +/* Subroutine of extract_normal. */ + +static CGEN_INLINE long +extract_1 (cd, ex_info, start, length, word_length, bufp, pc) + CGEN_CPU_DESC cd; + CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED; + int start,length,word_length; + unsigned char *bufp; + bfd_vma pc ATTRIBUTE_UNUSED; +{ + unsigned long x; + int shift; +#if 0 + int big_p = CGEN_CPU_INSN_ENDIAN (cd) == CGEN_ENDIAN_BIG; +#endif + x = cgen_get_insn_value (cd, bufp, word_length); + + if (CGEN_INSN_LSB0_P) + shift = (start + 1) - length; + else + shift = (word_length - (start + length)); + return x >> shift; +} + +#endif /* ! CGEN_INT_INSN_P */ + +/* Default extraction routine. + + INSN_VALUE is the first base_insn_bitsize bits of the insn in host order, + or sometimes less for cases like the m32r where the base insn size is 32 + but some insns are 16 bits. + ATTRS is a mask of the boolean attributes. We only need `SIGNED', + but for generality we take a bitmask of all of them. + WORD_OFFSET is the offset in bits from the start of the insn of the value. + WORD_LENGTH is the length of the word in bits in which the value resides. + START is the starting bit number in the word, architecture origin. + LENGTH is the length of VALUE in bits. + TOTAL_LENGTH is the total length of the insn in bits. + + Returns 1 for success, 0 for failure. */ + +/* ??? The return code isn't properly used. wip. */ + +/* ??? This doesn't handle bfd_vma's. Create another function when + necessary. */ + +static int +extract_normal (cd, ex_info, insn_value, attrs, word_offset, start, length, + word_length, total_length, pc, valuep) + CGEN_CPU_DESC cd; +#if ! CGEN_INT_INSN_P + CGEN_EXTRACT_INFO *ex_info; +#else + CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED; +#endif + CGEN_INSN_INT insn_value; + unsigned int attrs; + unsigned int word_offset, start, length, word_length, total_length; +#if ! CGEN_INT_INSN_P + bfd_vma pc; +#else + bfd_vma pc ATTRIBUTE_UNUSED; +#endif + long *valuep; +{ + long value, mask; + + /* If LENGTH is zero, this operand doesn't contribute to the value + so give it a standard value of zero. */ + if (length == 0) + { + *valuep = 0; + return 1; + } + +#if 0 + if (CGEN_INT_INSN_P + && word_offset != 0) + abort (); +#endif + + if (word_length > 32) + abort (); + + /* For architectures with insns smaller than the insn-base-bitsize, + word_length may be too big. */ + if (cd->min_insn_bitsize < cd->base_insn_bitsize) + { + if (word_offset == 0 + && word_length > total_length) + word_length = total_length; + } + + /* Does the value reside in INSN_VALUE, and at the right alignment? */ + + if (CGEN_INT_INSN_P || (word_offset == 0 && word_length == total_length)) + { + if (CGEN_INSN_LSB0_P) + value = insn_value >> ((word_offset + start + 1) - length); + else + value = insn_value >> (total_length - ( word_offset + start + length)); + } + +#if ! CGEN_INT_INSN_P + + else + { + unsigned char *bufp = ex_info->insn_bytes + word_offset / 8; + + if (word_length > 32) + abort (); + + if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0) + return 0; + + value = extract_1 (cd, ex_info, start, length, word_length, bufp, pc); + } + +#endif /* ! CGEN_INT_INSN_P */ + + /* Written this way to avoid undefined behaviour. */ + mask = (((1L << (length - 1)) - 1) << 1) | 1; + + value &= mask; + /* sign extend? */ + if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED) + && (value & (1L << (length - 1)))) + value |= ~mask; + + *valuep = value; + + return 1; +} + +/* Default insn extractor. + + INSN_VALUE is the first base_insn_bitsize bits, translated to host order. + The extracted fields are stored in FIELDS. + EX_INFO is used to handle reading variable length insns. + Return the length of the insn in bits, or 0 if no match, + or -1 if an error occurs fetching data (memory_error_func will have + been called). */ + +static int +extract_insn_normal (cd, insn, ex_info, insn_value, fields, pc) + CGEN_CPU_DESC cd; + const CGEN_INSN *insn; + CGEN_EXTRACT_INFO *ex_info; + CGEN_INSN_INT insn_value; + CGEN_FIELDS *fields; + bfd_vma pc; +{ + const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn); + const CGEN_SYNTAX_CHAR_TYPE *syn; + + CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn); + + CGEN_INIT_EXTRACT (cd); + + for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn) + { + int length; + + if (CGEN_SYNTAX_CHAR_P (*syn)) + continue; + + length = (* cd->extract_operand) (cd, CGEN_SYNTAX_FIELD (*syn), + ex_info, insn_value, fields, pc); + if (length <= 0) + return length; + } + + /* We recognized and successfully extracted this insn. */ + return CGEN_INSN_BITSIZE (insn); +} + +/* machine generated code added here */ + +const char * frv_cgen_insert_operand + PARAMS ((CGEN_CPU_DESC, int, CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma)); + +/* Main entry point for operand insertion. + + This function is basically just a big switch statement. Earlier versions + used tables to look up the function to use, but + - if the table contains both assembler and disassembler functions then + the disassembler contains much of the assembler and vice-versa, + - there's a lot of inlining possibilities as things grow, + - using a switch statement avoids the function call overhead. + + This function could be moved into `parse_insn_normal', but keeping it + separate makes clear the interface between `parse_insn_normal' and each of + the handlers. It's also needed by GAS to insert operands that couldn't be + resolved during parsing. */ + +const char * +frv_cgen_insert_operand (cd, opindex, fields, buffer, pc) + CGEN_CPU_DESC cd; + int opindex; + CGEN_FIELDS * fields; + CGEN_INSN_BYTES_PTR buffer; + bfd_vma pc ATTRIBUTE_UNUSED; +{ + const char * errmsg = NULL; + unsigned int total_length = CGEN_FIELDS_BITSIZE (fields); + + switch (opindex) + { + case FRV_OPERAND_A : + errmsg = insert_normal (cd, fields->f_A, 0, 0, 17, 1, 32, total_length, buffer); + break; + case FRV_OPERAND_ACC40SI : + errmsg = insert_normal (cd, fields->f_ACC40Si, 0, 0, 17, 6, 32, total_length, buffer); + break; + case FRV_OPERAND_ACC40SK : + errmsg = insert_normal (cd, fields->f_ACC40Sk, 0, 0, 30, 6, 32, total_length, buffer); + break; + case FRV_OPERAND_ACC40UI : + errmsg = insert_normal (cd, fields->f_ACC40Ui, 0, 0, 17, 6, 32, total_length, buffer); + break; + case FRV_OPERAND_ACC40UK : + errmsg = insert_normal (cd, fields->f_ACC40Uk, 0, 0, 30, 6, 32, total_length, buffer); + break; + case FRV_OPERAND_ACCGI : + errmsg = insert_normal (cd, fields->f_ACCGi, 0, 0, 17, 6, 32, total_length, buffer); + break; + case FRV_OPERAND_ACCGK : + errmsg = insert_normal (cd, fields->f_ACCGk, 0, 0, 30, 6, 32, total_length, buffer); + break; + case FRV_OPERAND_CCI : + errmsg = insert_normal (cd, fields->f_CCi, 0, 0, 11, 3, 32, total_length, buffer); + break; + case FRV_OPERAND_CPRDOUBLEK : + errmsg = insert_normal (cd, fields->f_CPRk, 0, 0, 30, 6, 32, total_length, buffer); + break; + case FRV_OPERAND_CPRI : + errmsg = insert_normal (cd, fields->f_CPRi, 0, 0, 17, 6, 32, total_length, buffer); + break; + case FRV_OPERAND_CPRJ : + errmsg = insert_normal (cd, fields->f_CPRj, 0, 0, 5, 6, 32, total_length, buffer); + break; + case FRV_OPERAND_CPRK : + errmsg = insert_normal (cd, fields->f_CPRk, 0, 0, 30, 6, 32, total_length, buffer); + break; + case FRV_OPERAND_CRI : + errmsg = insert_normal (cd, fields->f_CRi, 0, 0, 14, 3, 32, total_length, buffer); + break; + case FRV_OPERAND_CRJ : + errmsg = insert_normal (cd, fields->f_CRj, 0, 0, 2, 3, 32, total_length, buffer); + break; + case FRV_OPERAND_CRJ_FLOAT : + errmsg = insert_normal (cd, fields->f_CRj_float, 0, 0, 26, 2, 32, total_length, buffer); + break; + case FRV_OPERAND_CRJ_INT : + { + long value = fields->f_CRj_int; + value = ((value) - (4)); + errmsg = insert_normal (cd, value, 0, 0, 26, 2, 32, total_length, buffer); + } + break; + case FRV_OPERAND_CRK : + errmsg = insert_normal (cd, fields->f_CRk, 0, 0, 27, 3, 32, total_length, buffer); + break; + case FRV_OPERAND_FCCI_1 : + errmsg = insert_normal (cd, fields->f_FCCi_1, 0, 0, 11, 2, 32, total_length, buffer); + break; + case FRV_OPERAND_FCCI_2 : + errmsg = insert_normal (cd, fields->f_FCCi_2, 0, 0, 26, 2, 32, total_length, buffer); + break; + case FRV_OPERAND_FCCI_3 : + errmsg = insert_normal (cd, fields->f_FCCi_3, 0, 0, 1, 2, 32, total_length, buffer); + break; + case FRV_OPERAND_FCCK : + errmsg = insert_normal (cd, fields->f_FCCk, 0, 0, 26, 2, 32, total_length, buffer); + break; + case FRV_OPERAND_FRDOUBLEI : + errmsg = insert_normal (cd, fields->f_FRi, 0, 0, 17, 6, 32, total_length, buffer); + break; + case FRV_OPERAND_FRDOUBLEJ : + errmsg = insert_normal (cd, fields->f_FRj, 0, 0, 5, 6, 32, total_length, buffer); + break; + case FRV_OPERAND_FRDOUBLEK : + errmsg = insert_normal (cd, fields->f_FRk, 0, 0, 30, 6, 32, total_length, buffer); + break; + case FRV_OPERAND_FRI : + errmsg = insert_normal (cd, fields->f_FRi, 0, 0, 17, 6, 32, total_length, buffer); + break; + case FRV_OPERAND_FRINTI : + errmsg = insert_normal (cd, fields->f_FRi, 0, 0, 17, 6, 32, total_length, buffer); + break; + case FRV_OPERAND_FRINTJ : + errmsg = insert_normal (cd, fields->f_FRj, 0, 0, 5, 6, 32, total_length, buffer); + break; + case FRV_OPERAND_FRINTK : + errmsg = insert_normal (cd, fields->f_FRk, 0, 0, 30, 6, 32, total_length, buffer); + break; + case FRV_OPERAND_FRJ : + errmsg = insert_normal (cd, fields->f_FRj, 0, 0, 5, 6, 32, total_length, buffer); + break; + case FRV_OPERAND_FRK : + errmsg = insert_normal (cd, fields->f_FRk, 0, 0, 30, 6, 32, total_length, buffer); + break; + case FRV_OPERAND_FRKHI : + errmsg = insert_normal (cd, fields->f_FRk, 0, 0, 30, 6, 32, total_length, buffer); + break; + case FRV_OPERAND_FRKLO : + errmsg = insert_normal (cd, fields->f_FRk, 0, 0, 30, 6, 32, total_length, buffer); + break; + case FRV_OPERAND_GRDOUBLEK : + errmsg = insert_normal (cd, fields->f_GRk, 0, 0, 30, 6, 32, total_length, buffer); + break; + case FRV_OPERAND_GRI : + errmsg = insert_normal (cd, fields->f_GRi, 0, 0, 17, 6, 32, total_length, buffer); + break; + case FRV_OPERAND_GRJ : + errmsg = insert_normal (cd, fields->f_GRj, 0, 0, 5, 6, 32, total_length, buffer); + break; + case FRV_OPERAND_GRK : + errmsg = insert_normal (cd, fields->f_GRk, 0, 0, 30, 6, 32, total_length, buffer); + break; + case FRV_OPERAND_GRKHI : + errmsg = insert_normal (cd, fields->f_GRk, 0, 0, 30, 6, 32, total_length, buffer); + break; + case FRV_OPERAND_GRKLO : + errmsg = insert_normal (cd, fields->f_GRk, 0, 0, 30, 6, 32, total_length, buffer); + break; + case FRV_OPERAND_ICCI_1 : + errmsg = insert_normal (cd, fields->f_ICCi_1, 0, 0, 11, 2, 32, total_length, buffer); + break; + case FRV_OPERAND_ICCI_2 : + errmsg = insert_normal (cd, fields->f_ICCi_2, 0, 0, 26, 2, 32, total_length, buffer); + break; + case FRV_OPERAND_ICCI_3 : + errmsg = insert_normal (cd, fields->f_ICCi_3, 0, 0, 1, 2, 32, total_length, buffer); + break; + case FRV_OPERAND_LI : + errmsg = insert_normal (cd, fields->f_LI, 0, 0, 25, 1, 32, total_length, buffer); + break; + case FRV_OPERAND_AE : + errmsg = insert_normal (cd, fields->f_ae, 0, 0, 25, 1, 32, total_length, buffer); + break; + case FRV_OPERAND_CCOND : + errmsg = insert_normal (cd, fields->f_ccond, 0, 0, 12, 1, 32, total_length, buffer); + break; + case FRV_OPERAND_COND : + errmsg = insert_normal (cd, fields->f_cond, 0, 0, 8, 1, 32, total_length, buffer); + break; + case FRV_OPERAND_D12 : + errmsg = insert_normal (cd, fields->f_d12, 0|(1<f_debug, 0, 0, 25, 1, 32, total_length, buffer); + break; + case FRV_OPERAND_EIR : + errmsg = insert_normal (cd, fields->f_eir, 0, 0, 17, 6, 32, total_length, buffer); + break; + case FRV_OPERAND_HINT : + errmsg = insert_normal (cd, fields->f_hint, 0, 0, 17, 2, 32, total_length, buffer); + break; + case FRV_OPERAND_HINT_NOT_TAKEN : + errmsg = insert_normal (cd, fields->f_hint, 0, 0, 17, 2, 32, total_length, buffer); + break; + case FRV_OPERAND_HINT_TAKEN : + errmsg = insert_normal (cd, fields->f_hint, 0, 0, 17, 2, 32, total_length, buffer); + break; + case FRV_OPERAND_LABEL16 : + { + long value = fields->f_label16; + value = ((int) (((value) - (pc))) >> (2)); + errmsg = insert_normal (cd, value, 0|(1<> (20)); + FLD (f_labelL18) = ((((unsigned int) (((FLD (f_label24)) - (pc))) >> (2))) & (262143)); +} + errmsg = insert_normal (cd, fields->f_labelH6, 0|(1<f_labelL18, 0, 0, 17, 18, 32, total_length, buffer); + if (errmsg) + break; + } + break; + case FRV_OPERAND_LOCK : + errmsg = insert_normal (cd, fields->f_lock, 0, 0, 25, 1, 32, total_length, buffer); + break; + case FRV_OPERAND_PACK : + errmsg = insert_normal (cd, fields->f_pack, 0, 0, 31, 1, 32, total_length, buffer); + break; + case FRV_OPERAND_S10 : + errmsg = insert_normal (cd, fields->f_s10, 0|(1<f_d12, 0|(1<f_s16, 0|(1<f_s5, 0|(1<f_s6, 0|(1<f_s6_1, 0|(1<f_s16, 0|(1<> (6)); + FLD (f_spr_l) = ((FLD (f_spr)) & (63)); +} + errmsg = insert_normal (cd, fields->f_spr_h, 0, 0, 30, 6, 32, total_length, buffer); + if (errmsg) + break; + errmsg = insert_normal (cd, fields->f_spr_l, 0, 0, 17, 6, 32, total_length, buffer); + if (errmsg) + break; + } + break; + case FRV_OPERAND_U12 : + { +{ + FLD (f_u12_h) = ((int) (FLD (f_u12)) >> (6)); + FLD (f_u12_l) = ((FLD (f_u12)) & (63)); +} + errmsg = insert_normal (cd, fields->f_u12_h, 0|(1<f_u12_l, 0, 0, 5, 6, 32, total_length, buffer); + if (errmsg) + break; + } + break; + case FRV_OPERAND_U16 : + errmsg = insert_normal (cd, fields->f_u16, 0, 0, 15, 16, 32, total_length, buffer); + break; + case FRV_OPERAND_U6 : + errmsg = insert_normal (cd, fields->f_u6, 0, 0, 5, 6, 32, total_length, buffer); + break; + case FRV_OPERAND_UHI16 : + errmsg = insert_normal (cd, fields->f_u16, 0, 0, 15, 16, 32, total_length, buffer); + break; + case FRV_OPERAND_ULO16 : + errmsg = insert_normal (cd, fields->f_u16, 0, 0, 15, 16, 32, total_length, buffer); + break; + + default : + /* xgettext:c-format */ + fprintf (stderr, _("Unrecognized field %d while building insn.\n"), + opindex); + abort (); + } + + return errmsg; +} + +int frv_cgen_extract_operand + PARAMS ((CGEN_CPU_DESC, int, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, + CGEN_FIELDS *, bfd_vma)); + +/* Main entry point for operand extraction. + The result is <= 0 for error, >0 for success. + ??? Actual values aren't well defined right now. + + This function is basically just a big switch statement. Earlier versions + used tables to look up the function to use, but + - if the table contains both assembler and disassembler functions then + the disassembler contains much of the assembler and vice-versa, + - there's a lot of inlining possibilities as things grow, + - using a switch statement avoids the function call overhead. + + This function could be moved into `print_insn_normal', but keeping it + separate makes clear the interface between `print_insn_normal' and each of + the handlers. */ + +int +frv_cgen_extract_operand (cd, opindex, ex_info, insn_value, fields, pc) + CGEN_CPU_DESC cd; + int opindex; + CGEN_EXTRACT_INFO *ex_info; + CGEN_INSN_INT insn_value; + CGEN_FIELDS * fields; + bfd_vma pc; +{ + /* Assume success (for those operands that are nops). */ + int length = 1; + unsigned int total_length = CGEN_FIELDS_BITSIZE (fields); + + switch (opindex) + { + case FRV_OPERAND_A : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 17, 1, 32, total_length, pc, & fields->f_A); + break; + case FRV_OPERAND_ACC40SI : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 17, 6, 32, total_length, pc, & fields->f_ACC40Si); + break; + case FRV_OPERAND_ACC40SK : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 30, 6, 32, total_length, pc, & fields->f_ACC40Sk); + break; + case FRV_OPERAND_ACC40UI : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 17, 6, 32, total_length, pc, & fields->f_ACC40Ui); + break; + case FRV_OPERAND_ACC40UK : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 30, 6, 32, total_length, pc, & fields->f_ACC40Uk); + break; + case FRV_OPERAND_ACCGI : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 17, 6, 32, total_length, pc, & fields->f_ACCGi); + break; + case FRV_OPERAND_ACCGK : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 30, 6, 32, total_length, pc, & fields->f_ACCGk); + break; + case FRV_OPERAND_CCI : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 11, 3, 32, total_length, pc, & fields->f_CCi); + break; + case FRV_OPERAND_CPRDOUBLEK : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 30, 6, 32, total_length, pc, & fields->f_CPRk); + break; + case FRV_OPERAND_CPRI : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 17, 6, 32, total_length, pc, & fields->f_CPRi); + break; + case FRV_OPERAND_CPRJ : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 5, 6, 32, total_length, pc, & fields->f_CPRj); + break; + case FRV_OPERAND_CPRK : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 30, 6, 32, total_length, pc, & fields->f_CPRk); + break; + case FRV_OPERAND_CRI : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 14, 3, 32, total_length, pc, & fields->f_CRi); + break; + case FRV_OPERAND_CRJ : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 2, 3, 32, total_length, pc, & fields->f_CRj); + break; + case FRV_OPERAND_CRJ_FLOAT : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 26, 2, 32, total_length, pc, & fields->f_CRj_float); + break; + case FRV_OPERAND_CRJ_INT : + { + long value; + length = extract_normal (cd, ex_info, insn_value, 0, 0, 26, 2, 32, total_length, pc, & value); + value = ((value) + (4)); + fields->f_CRj_int = value; + } + break; + case FRV_OPERAND_CRK : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 27, 3, 32, total_length, pc, & fields->f_CRk); + break; + case FRV_OPERAND_FCCI_1 : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 11, 2, 32, total_length, pc, & fields->f_FCCi_1); + break; + case FRV_OPERAND_FCCI_2 : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 26, 2, 32, total_length, pc, & fields->f_FCCi_2); + break; + case FRV_OPERAND_FCCI_3 : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 1, 2, 32, total_length, pc, & fields->f_FCCi_3); + break; + case FRV_OPERAND_FCCK : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 26, 2, 32, total_length, pc, & fields->f_FCCk); + break; + case FRV_OPERAND_FRDOUBLEI : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 17, 6, 32, total_length, pc, & fields->f_FRi); + break; + case FRV_OPERAND_FRDOUBLEJ : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 5, 6, 32, total_length, pc, & fields->f_FRj); + break; + case FRV_OPERAND_FRDOUBLEK : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 30, 6, 32, total_length, pc, & fields->f_FRk); + break; + case FRV_OPERAND_FRI : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 17, 6, 32, total_length, pc, & fields->f_FRi); + break; + case FRV_OPERAND_FRINTI : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 17, 6, 32, total_length, pc, & fields->f_FRi); + break; + case FRV_OPERAND_FRINTJ : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 5, 6, 32, total_length, pc, & fields->f_FRj); + break; + case FRV_OPERAND_FRINTK : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 30, 6, 32, total_length, pc, & fields->f_FRk); + break; + case FRV_OPERAND_FRJ : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 5, 6, 32, total_length, pc, & fields->f_FRj); + break; + case FRV_OPERAND_FRK : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 30, 6, 32, total_length, pc, & fields->f_FRk); + break; + case FRV_OPERAND_FRKHI : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 30, 6, 32, total_length, pc, & fields->f_FRk); + break; + case FRV_OPERAND_FRKLO : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 30, 6, 32, total_length, pc, & fields->f_FRk); + break; + case FRV_OPERAND_GRDOUBLEK : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 30, 6, 32, total_length, pc, & fields->f_GRk); + break; + case FRV_OPERAND_GRI : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 17, 6, 32, total_length, pc, & fields->f_GRi); + break; + case FRV_OPERAND_GRJ : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 5, 6, 32, total_length, pc, & fields->f_GRj); + break; + case FRV_OPERAND_GRK : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 30, 6, 32, total_length, pc, & fields->f_GRk); + break; + case FRV_OPERAND_GRKHI : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 30, 6, 32, total_length, pc, & fields->f_GRk); + break; + case FRV_OPERAND_GRKLO : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 30, 6, 32, total_length, pc, & fields->f_GRk); + break; + case FRV_OPERAND_ICCI_1 : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 11, 2, 32, total_length, pc, & fields->f_ICCi_1); + break; + case FRV_OPERAND_ICCI_2 : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 26, 2, 32, total_length, pc, & fields->f_ICCi_2); + break; + case FRV_OPERAND_ICCI_3 : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 1, 2, 32, total_length, pc, & fields->f_ICCi_3); + break; + case FRV_OPERAND_LI : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 1, 32, total_length, pc, & fields->f_LI); + break; + case FRV_OPERAND_AE : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 1, 32, total_length, pc, & fields->f_ae); + break; + case FRV_OPERAND_CCOND : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 1, 32, total_length, pc, & fields->f_ccond); + break; + case FRV_OPERAND_COND : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 1, 32, total_length, pc, & fields->f_cond); + break; + case FRV_OPERAND_D12 : + length = extract_normal (cd, ex_info, insn_value, 0|(1<f_d12); + break; + case FRV_OPERAND_DEBUG : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 1, 32, total_length, pc, & fields->f_debug); + break; + case FRV_OPERAND_EIR : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 17, 6, 32, total_length, pc, & fields->f_eir); + break; + case FRV_OPERAND_HINT : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 17, 2, 32, total_length, pc, & fields->f_hint); + break; + case FRV_OPERAND_HINT_NOT_TAKEN : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 17, 2, 32, total_length, pc, & fields->f_hint); + break; + case FRV_OPERAND_HINT_TAKEN : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 17, 2, 32, total_length, pc, & fields->f_hint); + break; + case FRV_OPERAND_LABEL16 : + { + long value; + length = extract_normal (cd, ex_info, insn_value, 0|(1<f_label16 = value; + } + break; + case FRV_OPERAND_LABEL24 : + { + length = extract_normal (cd, ex_info, insn_value, 0|(1<f_labelH6); + if (length <= 0) break; + length = extract_normal (cd, ex_info, insn_value, 0, 0, 17, 18, 32, total_length, pc, & fields->f_labelL18); + if (length <= 0) break; +{ + FLD (f_label24) = ((((((((FLD (f_labelH6)) << (18))) | (FLD (f_labelL18)))) << (2))) + (pc)); +} + } + break; + case FRV_OPERAND_LOCK : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 1, 32, total_length, pc, & fields->f_lock); + break; + case FRV_OPERAND_PACK : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 31, 1, 32, total_length, pc, & fields->f_pack); + break; + case FRV_OPERAND_S10 : + length = extract_normal (cd, ex_info, insn_value, 0|(1<f_s10); + break; + case FRV_OPERAND_S12 : + length = extract_normal (cd, ex_info, insn_value, 0|(1<f_d12); + break; + case FRV_OPERAND_S16 : + length = extract_normal (cd, ex_info, insn_value, 0|(1<f_s16); + break; + case FRV_OPERAND_S5 : + length = extract_normal (cd, ex_info, insn_value, 0|(1<f_s5); + break; + case FRV_OPERAND_S6 : + length = extract_normal (cd, ex_info, insn_value, 0|(1<f_s6); + break; + case FRV_OPERAND_S6_1 : + length = extract_normal (cd, ex_info, insn_value, 0|(1<f_s6_1); + break; + case FRV_OPERAND_SLO16 : + length = extract_normal (cd, ex_info, insn_value, 0|(1<f_s16); + break; + case FRV_OPERAND_SPR : + { + length = extract_normal (cd, ex_info, insn_value, 0, 0, 30, 6, 32, total_length, pc, & fields->f_spr_h); + if (length <= 0) break; + length = extract_normal (cd, ex_info, insn_value, 0, 0, 17, 6, 32, total_length, pc, & fields->f_spr_l); + if (length <= 0) break; +{ + FLD (f_spr) = ((((FLD (f_spr_h)) << (6))) | (FLD (f_spr_l))); +} + } + break; + case FRV_OPERAND_U12 : + { + length = extract_normal (cd, ex_info, insn_value, 0|(1<f_u12_h); + if (length <= 0) break; + length = extract_normal (cd, ex_info, insn_value, 0, 0, 5, 6, 32, total_length, pc, & fields->f_u12_l); + if (length <= 0) break; +{ + FLD (f_u12) = ((((FLD (f_u12_h)) << (6))) | (FLD (f_u12_l))); +} + } + break; + case FRV_OPERAND_U16 : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 16, 32, total_length, pc, & fields->f_u16); + break; + case FRV_OPERAND_U6 : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 5, 6, 32, total_length, pc, & fields->f_u6); + break; + case FRV_OPERAND_UHI16 : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 16, 32, total_length, pc, & fields->f_u16); + break; + case FRV_OPERAND_ULO16 : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 16, 32, total_length, pc, & fields->f_u16); + break; + + default : + /* xgettext:c-format */ + fprintf (stderr, _("Unrecognized field %d while decoding insn.\n"), + opindex); + abort (); + } + + return length; +} + +cgen_insert_fn * const frv_cgen_insert_handlers[] = +{ + insert_insn_normal, +}; + +cgen_extract_fn * const frv_cgen_extract_handlers[] = +{ + extract_insn_normal, +}; + +int frv_cgen_get_int_operand + PARAMS ((CGEN_CPU_DESC, int, const CGEN_FIELDS *)); +bfd_vma frv_cgen_get_vma_operand + PARAMS ((CGEN_CPU_DESC, int, const CGEN_FIELDS *)); + +/* Getting values from cgen_fields is handled by a collection of functions. + They are distinguished by the type of the VALUE argument they return. + TODO: floating point, inlining support, remove cases where result type + not appropriate. */ + +int +frv_cgen_get_int_operand (cd, opindex, fields) + CGEN_CPU_DESC cd ATTRIBUTE_UNUSED; + int opindex; + const CGEN_FIELDS * fields; +{ + int value; + + switch (opindex) + { + case FRV_OPERAND_A : + value = fields->f_A; + break; + case FRV_OPERAND_ACC40SI : + value = fields->f_ACC40Si; + break; + case FRV_OPERAND_ACC40SK : + value = fields->f_ACC40Sk; + break; + case FRV_OPERAND_ACC40UI : + value = fields->f_ACC40Ui; + break; + case FRV_OPERAND_ACC40UK : + value = fields->f_ACC40Uk; + break; + case FRV_OPERAND_ACCGI : + value = fields->f_ACCGi; + break; + case FRV_OPERAND_ACCGK : + value = fields->f_ACCGk; + break; + case FRV_OPERAND_CCI : + value = fields->f_CCi; + break; + case FRV_OPERAND_CPRDOUBLEK : + value = fields->f_CPRk; + break; + case FRV_OPERAND_CPRI : + value = fields->f_CPRi; + break; + case FRV_OPERAND_CPRJ : + value = fields->f_CPRj; + break; + case FRV_OPERAND_CPRK : + value = fields->f_CPRk; + break; + case FRV_OPERAND_CRI : + value = fields->f_CRi; + break; + case FRV_OPERAND_CRJ : + value = fields->f_CRj; + break; + case FRV_OPERAND_CRJ_FLOAT : + value = fields->f_CRj_float; + break; + case FRV_OPERAND_CRJ_INT : + value = fields->f_CRj_int; + break; + case FRV_OPERAND_CRK : + value = fields->f_CRk; + break; + case FRV_OPERAND_FCCI_1 : + value = fields->f_FCCi_1; + break; + case FRV_OPERAND_FCCI_2 : + value = fields->f_FCCi_2; + break; + case FRV_OPERAND_FCCI_3 : + value = fields->f_FCCi_3; + break; + case FRV_OPERAND_FCCK : + value = fields->f_FCCk; + break; + case FRV_OPERAND_FRDOUBLEI : + value = fields->f_FRi; + break; + case FRV_OPERAND_FRDOUBLEJ : + value = fields->f_FRj; + break; + case FRV_OPERAND_FRDOUBLEK : + value = fields->f_FRk; + break; + case FRV_OPERAND_FRI : + value = fields->f_FRi; + break; + case FRV_OPERAND_FRINTI : + value = fields->f_FRi; + break; + case FRV_OPERAND_FRINTJ : + value = fields->f_FRj; + break; + case FRV_OPERAND_FRINTK : + value = fields->f_FRk; + break; + case FRV_OPERAND_FRJ : + value = fields->f_FRj; + break; + case FRV_OPERAND_FRK : + value = fields->f_FRk; + break; + case FRV_OPERAND_FRKHI : + value = fields->f_FRk; + break; + case FRV_OPERAND_FRKLO : + value = fields->f_FRk; + break; + case FRV_OPERAND_GRDOUBLEK : + value = fields->f_GRk; + break; + case FRV_OPERAND_GRI : + value = fields->f_GRi; + break; + case FRV_OPERAND_GRJ : + value = fields->f_GRj; + break; + case FRV_OPERAND_GRK : + value = fields->f_GRk; + break; + case FRV_OPERAND_GRKHI : + value = fields->f_GRk; + break; + case FRV_OPERAND_GRKLO : + value = fields->f_GRk; + break; + case FRV_OPERAND_ICCI_1 : + value = fields->f_ICCi_1; + break; + case FRV_OPERAND_ICCI_2 : + value = fields->f_ICCi_2; + break; + case FRV_OPERAND_ICCI_3 : + value = fields->f_ICCi_3; + break; + case FRV_OPERAND_LI : + value = fields->f_LI; + break; + case FRV_OPERAND_AE : + value = fields->f_ae; + break; + case FRV_OPERAND_CCOND : + value = fields->f_ccond; + break; + case FRV_OPERAND_COND : + value = fields->f_cond; + break; + case FRV_OPERAND_D12 : + value = fields->f_d12; + break; + case FRV_OPERAND_DEBUG : + value = fields->f_debug; + break; + case FRV_OPERAND_EIR : + value = fields->f_eir; + break; + case FRV_OPERAND_HINT : + value = fields->f_hint; + break; + case FRV_OPERAND_HINT_NOT_TAKEN : + value = fields->f_hint; + break; + case FRV_OPERAND_HINT_TAKEN : + value = fields->f_hint; + break; + case FRV_OPERAND_LABEL16 : + value = fields->f_label16; + break; + case FRV_OPERAND_LABEL24 : + value = fields->f_label24; + break; + case FRV_OPERAND_LOCK : + value = fields->f_lock; + break; + case FRV_OPERAND_PACK : + value = fields->f_pack; + break; + case FRV_OPERAND_S10 : + value = fields->f_s10; + break; + case FRV_OPERAND_S12 : + value = fields->f_d12; + break; + case FRV_OPERAND_S16 : + value = fields->f_s16; + break; + case FRV_OPERAND_S5 : + value = fields->f_s5; + break; + case FRV_OPERAND_S6 : + value = fields->f_s6; + break; + case FRV_OPERAND_S6_1 : + value = fields->f_s6_1; + break; + case FRV_OPERAND_SLO16 : + value = fields->f_s16; + break; + case FRV_OPERAND_SPR : + value = fields->f_spr; + break; + case FRV_OPERAND_U12 : + value = fields->f_u12; + break; + case FRV_OPERAND_U16 : + value = fields->f_u16; + break; + case FRV_OPERAND_U6 : + value = fields->f_u6; + break; + case FRV_OPERAND_UHI16 : + value = fields->f_u16; + break; + case FRV_OPERAND_ULO16 : + value = fields->f_u16; + break; + + default : + /* xgettext:c-format */ + fprintf (stderr, _("Unrecognized field %d while getting int operand.\n"), + opindex); + abort (); + } + + return value; +} + +bfd_vma +frv_cgen_get_vma_operand (cd, opindex, fields) + CGEN_CPU_DESC cd ATTRIBUTE_UNUSED; + int opindex; + const CGEN_FIELDS * fields; +{ + bfd_vma value; + + switch (opindex) + { + case FRV_OPERAND_A : + value = fields->f_A; + break; + case FRV_OPERAND_ACC40SI : + value = fields->f_ACC40Si; + break; + case FRV_OPERAND_ACC40SK : + value = fields->f_ACC40Sk; + break; + case FRV_OPERAND_ACC40UI : + value = fields->f_ACC40Ui; + break; + case FRV_OPERAND_ACC40UK : + value = fields->f_ACC40Uk; + break; + case FRV_OPERAND_ACCGI : + value = fields->f_ACCGi; + break; + case FRV_OPERAND_ACCGK : + value = fields->f_ACCGk; + break; + case FRV_OPERAND_CCI : + value = fields->f_CCi; + break; + case FRV_OPERAND_CPRDOUBLEK : + value = fields->f_CPRk; + break; + case FRV_OPERAND_CPRI : + value = fields->f_CPRi; + break; + case FRV_OPERAND_CPRJ : + value = fields->f_CPRj; + break; + case FRV_OPERAND_CPRK : + value = fields->f_CPRk; + break; + case FRV_OPERAND_CRI : + value = fields->f_CRi; + break; + case FRV_OPERAND_CRJ : + value = fields->f_CRj; + break; + case FRV_OPERAND_CRJ_FLOAT : + value = fields->f_CRj_float; + break; + case FRV_OPERAND_CRJ_INT : + value = fields->f_CRj_int; + break; + case FRV_OPERAND_CRK : + value = fields->f_CRk; + break; + case FRV_OPERAND_FCCI_1 : + value = fields->f_FCCi_1; + break; + case FRV_OPERAND_FCCI_2 : + value = fields->f_FCCi_2; + break; + case FRV_OPERAND_FCCI_3 : + value = fields->f_FCCi_3; + break; + case FRV_OPERAND_FCCK : + value = fields->f_FCCk; + break; + case FRV_OPERAND_FRDOUBLEI : + value = fields->f_FRi; + break; + case FRV_OPERAND_FRDOUBLEJ : + value = fields->f_FRj; + break; + case FRV_OPERAND_FRDOUBLEK : + value = fields->f_FRk; + break; + case FRV_OPERAND_FRI : + value = fields->f_FRi; + break; + case FRV_OPERAND_FRINTI : + value = fields->f_FRi; + break; + case FRV_OPERAND_FRINTJ : + value = fields->f_FRj; + break; + case FRV_OPERAND_FRINTK : + value = fields->f_FRk; + break; + case FRV_OPERAND_FRJ : + value = fields->f_FRj; + break; + case FRV_OPERAND_FRK : + value = fields->f_FRk; + break; + case FRV_OPERAND_FRKHI : + value = fields->f_FRk; + break; + case FRV_OPERAND_FRKLO : + value = fields->f_FRk; + break; + case FRV_OPERAND_GRDOUBLEK : + value = fields->f_GRk; + break; + case FRV_OPERAND_GRI : + value = fields->f_GRi; + break; + case FRV_OPERAND_GRJ : + value = fields->f_GRj; + break; + case FRV_OPERAND_GRK : + value = fields->f_GRk; + break; + case FRV_OPERAND_GRKHI : + value = fields->f_GRk; + break; + case FRV_OPERAND_GRKLO : + value = fields->f_GRk; + break; + case FRV_OPERAND_ICCI_1 : + value = fields->f_ICCi_1; + break; + case FRV_OPERAND_ICCI_2 : + value = fields->f_ICCi_2; + break; + case FRV_OPERAND_ICCI_3 : + value = fields->f_ICCi_3; + break; + case FRV_OPERAND_LI : + value = fields->f_LI; + break; + case FRV_OPERAND_AE : + value = fields->f_ae; + break; + case FRV_OPERAND_CCOND : + value = fields->f_ccond; + break; + case FRV_OPERAND_COND : + value = fields->f_cond; + break; + case FRV_OPERAND_D12 : + value = fields->f_d12; + break; + case FRV_OPERAND_DEBUG : + value = fields->f_debug; + break; + case FRV_OPERAND_EIR : + value = fields->f_eir; + break; + case FRV_OPERAND_HINT : + value = fields->f_hint; + break; + case FRV_OPERAND_HINT_NOT_TAKEN : + value = fields->f_hint; + break; + case FRV_OPERAND_HINT_TAKEN : + value = fields->f_hint; + break; + case FRV_OPERAND_LABEL16 : + value = fields->f_label16; + break; + case FRV_OPERAND_LABEL24 : + value = fields->f_label24; + break; + case FRV_OPERAND_LOCK : + value = fields->f_lock; + break; + case FRV_OPERAND_PACK : + value = fields->f_pack; + break; + case FRV_OPERAND_S10 : + value = fields->f_s10; + break; + case FRV_OPERAND_S12 : + value = fields->f_d12; + break; + case FRV_OPERAND_S16 : + value = fields->f_s16; + break; + case FRV_OPERAND_S5 : + value = fields->f_s5; + break; + case FRV_OPERAND_S6 : + value = fields->f_s6; + break; + case FRV_OPERAND_S6_1 : + value = fields->f_s6_1; + break; + case FRV_OPERAND_SLO16 : + value = fields->f_s16; + break; + case FRV_OPERAND_SPR : + value = fields->f_spr; + break; + case FRV_OPERAND_U12 : + value = fields->f_u12; + break; + case FRV_OPERAND_U16 : + value = fields->f_u16; + break; + case FRV_OPERAND_U6 : + value = fields->f_u6; + break; + case FRV_OPERAND_UHI16 : + value = fields->f_u16; + break; + case FRV_OPERAND_ULO16 : + value = fields->f_u16; + break; + + default : + /* xgettext:c-format */ + fprintf (stderr, _("Unrecognized field %d while getting vma operand.\n"), + opindex); + abort (); + } + + return value; +} + +void frv_cgen_set_int_operand + PARAMS ((CGEN_CPU_DESC, int, CGEN_FIELDS *, int)); +void frv_cgen_set_vma_operand + PARAMS ((CGEN_CPU_DESC, int, CGEN_FIELDS *, bfd_vma)); + +/* Stuffing values in cgen_fields is handled by a collection of functions. + They are distinguished by the type of the VALUE argument they accept. + TODO: floating point, inlining support, remove cases where argument type + not appropriate. */ + +void +frv_cgen_set_int_operand (cd, opindex, fields, value) + CGEN_CPU_DESC cd ATTRIBUTE_UNUSED; + int opindex; + CGEN_FIELDS * fields; + int value; +{ + switch (opindex) + { + case FRV_OPERAND_A : + fields->f_A = value; + break; + case FRV_OPERAND_ACC40SI : + fields->f_ACC40Si = value; + break; + case FRV_OPERAND_ACC40SK : + fields->f_ACC40Sk = value; + break; + case FRV_OPERAND_ACC40UI : + fields->f_ACC40Ui = value; + break; + case FRV_OPERAND_ACC40UK : + fields->f_ACC40Uk = value; + break; + case FRV_OPERAND_ACCGI : + fields->f_ACCGi = value; + break; + case FRV_OPERAND_ACCGK : + fields->f_ACCGk = value; + break; + case FRV_OPERAND_CCI : + fields->f_CCi = value; + break; + case FRV_OPERAND_CPRDOUBLEK : + fields->f_CPRk = value; + break; + case FRV_OPERAND_CPRI : + fields->f_CPRi = value; + break; + case FRV_OPERAND_CPRJ : + fields->f_CPRj = value; + break; + case FRV_OPERAND_CPRK : + fields->f_CPRk = value; + break; + case FRV_OPERAND_CRI : + fields->f_CRi = value; + break; + case FRV_OPERAND_CRJ : + fields->f_CRj = value; + break; + case FRV_OPERAND_CRJ_FLOAT : + fields->f_CRj_float = value; + break; + case FRV_OPERAND_CRJ_INT : + fields->f_CRj_int = value; + break; + case FRV_OPERAND_CRK : + fields->f_CRk = value; + break; + case FRV_OPERAND_FCCI_1 : + fields->f_FCCi_1 = value; + break; + case FRV_OPERAND_FCCI_2 : + fields->f_FCCi_2 = value; + break; + case FRV_OPERAND_FCCI_3 : + fields->f_FCCi_3 = value; + break; + case FRV_OPERAND_FCCK : + fields->f_FCCk = value; + break; + case FRV_OPERAND_FRDOUBLEI : + fields->f_FRi = value; + break; + case FRV_OPERAND_FRDOUBLEJ : + fields->f_FRj = value; + break; + case FRV_OPERAND_FRDOUBLEK : + fields->f_FRk = value; + break; + case FRV_OPERAND_FRI : + fields->f_FRi = value; + break; + case FRV_OPERAND_FRINTI : + fields->f_FRi = value; + break; + case FRV_OPERAND_FRINTJ : + fields->f_FRj = value; + break; + case FRV_OPERAND_FRINTK : + fields->f_FRk = value; + break; + case FRV_OPERAND_FRJ : + fields->f_FRj = value; + break; + case FRV_OPERAND_FRK : + fields->f_FRk = value; + break; + case FRV_OPERAND_FRKHI : + fields->f_FRk = value; + break; + case FRV_OPERAND_FRKLO : + fields->f_FRk = value; + break; + case FRV_OPERAND_GRDOUBLEK : + fields->f_GRk = value; + break; + case FRV_OPERAND_GRI : + fields->f_GRi = value; + break; + case FRV_OPERAND_GRJ : + fields->f_GRj = value; + break; + case FRV_OPERAND_GRK : + fields->f_GRk = value; + break; + case FRV_OPERAND_GRKHI : + fields->f_GRk = value; + break; + case FRV_OPERAND_GRKLO : + fields->f_GRk = value; + break; + case FRV_OPERAND_ICCI_1 : + fields->f_ICCi_1 = value; + break; + case FRV_OPERAND_ICCI_2 : + fields->f_ICCi_2 = value; + break; + case FRV_OPERAND_ICCI_3 : + fields->f_ICCi_3 = value; + break; + case FRV_OPERAND_LI : + fields->f_LI = value; + break; + case FRV_OPERAND_AE : + fields->f_ae = value; + break; + case FRV_OPERAND_CCOND : + fields->f_ccond = value; + break; + case FRV_OPERAND_COND : + fields->f_cond = value; + break; + case FRV_OPERAND_D12 : + fields->f_d12 = value; + break; + case FRV_OPERAND_DEBUG : + fields->f_debug = value; + break; + case FRV_OPERAND_EIR : + fields->f_eir = value; + break; + case FRV_OPERAND_HINT : + fields->f_hint = value; + break; + case FRV_OPERAND_HINT_NOT_TAKEN : + fields->f_hint = value; + break; + case FRV_OPERAND_HINT_TAKEN : + fields->f_hint = value; + break; + case FRV_OPERAND_LABEL16 : + fields->f_label16 = value; + break; + case FRV_OPERAND_LABEL24 : + fields->f_label24 = value; + break; + case FRV_OPERAND_LOCK : + fields->f_lock = value; + break; + case FRV_OPERAND_PACK : + fields->f_pack = value; + break; + case FRV_OPERAND_S10 : + fields->f_s10 = value; + break; + case FRV_OPERAND_S12 : + fields->f_d12 = value; + break; + case FRV_OPERAND_S16 : + fields->f_s16 = value; + break; + case FRV_OPERAND_S5 : + fields->f_s5 = value; + break; + case FRV_OPERAND_S6 : + fields->f_s6 = value; + break; + case FRV_OPERAND_S6_1 : + fields->f_s6_1 = value; + break; + case FRV_OPERAND_SLO16 : + fields->f_s16 = value; + break; + case FRV_OPERAND_SPR : + fields->f_spr = value; + break; + case FRV_OPERAND_U12 : + fields->f_u12 = value; + break; + case FRV_OPERAND_U16 : + fields->f_u16 = value; + break; + case FRV_OPERAND_U6 : + fields->f_u6 = value; + break; + case FRV_OPERAND_UHI16 : + fields->f_u16 = value; + break; + case FRV_OPERAND_ULO16 : + fields->f_u16 = value; + break; + + default : + /* xgettext:c-format */ + fprintf (stderr, _("Unrecognized field %d while setting int operand.\n"), + opindex); + abort (); + } +} + +void +frv_cgen_set_vma_operand (cd, opindex, fields, value) + CGEN_CPU_DESC cd ATTRIBUTE_UNUSED; + int opindex; + CGEN_FIELDS * fields; + bfd_vma value; +{ + switch (opindex) + { + case FRV_OPERAND_A : + fields->f_A = value; + break; + case FRV_OPERAND_ACC40SI : + fields->f_ACC40Si = value; + break; + case FRV_OPERAND_ACC40SK : + fields->f_ACC40Sk = value; + break; + case FRV_OPERAND_ACC40UI : + fields->f_ACC40Ui = value; + break; + case FRV_OPERAND_ACC40UK : + fields->f_ACC40Uk = value; + break; + case FRV_OPERAND_ACCGI : + fields->f_ACCGi = value; + break; + case FRV_OPERAND_ACCGK : + fields->f_ACCGk = value; + break; + case FRV_OPERAND_CCI : + fields->f_CCi = value; + break; + case FRV_OPERAND_CPRDOUBLEK : + fields->f_CPRk = value; + break; + case FRV_OPERAND_CPRI : + fields->f_CPRi = value; + break; + case FRV_OPERAND_CPRJ : + fields->f_CPRj = value; + break; + case FRV_OPERAND_CPRK : + fields->f_CPRk = value; + break; + case FRV_OPERAND_CRI : + fields->f_CRi = value; + break; + case FRV_OPERAND_CRJ : + fields->f_CRj = value; + break; + case FRV_OPERAND_CRJ_FLOAT : + fields->f_CRj_float = value; + break; + case FRV_OPERAND_CRJ_INT : + fields->f_CRj_int = value; + break; + case FRV_OPERAND_CRK : + fields->f_CRk = value; + break; + case FRV_OPERAND_FCCI_1 : + fields->f_FCCi_1 = value; + break; + case FRV_OPERAND_FCCI_2 : + fields->f_FCCi_2 = value; + break; + case FRV_OPERAND_FCCI_3 : + fields->f_FCCi_3 = value; + break; + case FRV_OPERAND_FCCK : + fields->f_FCCk = value; + break; + case FRV_OPERAND_FRDOUBLEI : + fields->f_FRi = value; + break; + case FRV_OPERAND_FRDOUBLEJ : + fields->f_FRj = value; + break; + case FRV_OPERAND_FRDOUBLEK : + fields->f_FRk = value; + break; + case FRV_OPERAND_FRI : + fields->f_FRi = value; + break; + case FRV_OPERAND_FRINTI : + fields->f_FRi = value; + break; + case FRV_OPERAND_FRINTJ : + fields->f_FRj = value; + break; + case FRV_OPERAND_FRINTK : + fields->f_FRk = value; + break; + case FRV_OPERAND_FRJ : + fields->f_FRj = value; + break; + case FRV_OPERAND_FRK : + fields->f_FRk = value; + break; + case FRV_OPERAND_FRKHI : + fields->f_FRk = value; + break; + case FRV_OPERAND_FRKLO : + fields->f_FRk = value; + break; + case FRV_OPERAND_GRDOUBLEK : + fields->f_GRk = value; + break; + case FRV_OPERAND_GRI : + fields->f_GRi = value; + break; + case FRV_OPERAND_GRJ : + fields->f_GRj = value; + break; + case FRV_OPERAND_GRK : + fields->f_GRk = value; + break; + case FRV_OPERAND_GRKHI : + fields->f_GRk = value; + break; + case FRV_OPERAND_GRKLO : + fields->f_GRk = value; + break; + case FRV_OPERAND_ICCI_1 : + fields->f_ICCi_1 = value; + break; + case FRV_OPERAND_ICCI_2 : + fields->f_ICCi_2 = value; + break; + case FRV_OPERAND_ICCI_3 : + fields->f_ICCi_3 = value; + break; + case FRV_OPERAND_LI : + fields->f_LI = value; + break; + case FRV_OPERAND_AE : + fields->f_ae = value; + break; + case FRV_OPERAND_CCOND : + fields->f_ccond = value; + break; + case FRV_OPERAND_COND : + fields->f_cond = value; + break; + case FRV_OPERAND_D12 : + fields->f_d12 = value; + break; + case FRV_OPERAND_DEBUG : + fields->f_debug = value; + break; + case FRV_OPERAND_EIR : + fields->f_eir = value; + break; + case FRV_OPERAND_HINT : + fields->f_hint = value; + break; + case FRV_OPERAND_HINT_NOT_TAKEN : + fields->f_hint = value; + break; + case FRV_OPERAND_HINT_TAKEN : + fields->f_hint = value; + break; + case FRV_OPERAND_LABEL16 : + fields->f_label16 = value; + break; + case FRV_OPERAND_LABEL24 : + fields->f_label24 = value; + break; + case FRV_OPERAND_LOCK : + fields->f_lock = value; + break; + case FRV_OPERAND_PACK : + fields->f_pack = value; + break; + case FRV_OPERAND_S10 : + fields->f_s10 = value; + break; + case FRV_OPERAND_S12 : + fields->f_d12 = value; + break; + case FRV_OPERAND_S16 : + fields->f_s16 = value; + break; + case FRV_OPERAND_S5 : + fields->f_s5 = value; + break; + case FRV_OPERAND_S6 : + fields->f_s6 = value; + break; + case FRV_OPERAND_S6_1 : + fields->f_s6_1 = value; + break; + case FRV_OPERAND_SLO16 : + fields->f_s16 = value; + break; + case FRV_OPERAND_SPR : + fields->f_spr = value; + break; + case FRV_OPERAND_U12 : + fields->f_u12 = value; + break; + case FRV_OPERAND_U16 : + fields->f_u16 = value; + break; + case FRV_OPERAND_U6 : + fields->f_u6 = value; + break; + case FRV_OPERAND_UHI16 : + fields->f_u16 = value; + break; + case FRV_OPERAND_ULO16 : + fields->f_u16 = value; + break; + + default : + /* xgettext:c-format */ + fprintf (stderr, _("Unrecognized field %d while setting vma operand.\n"), + opindex); + abort (); + } +} + +/* Function to call before using the instruction builder tables. */ + +void +frv_cgen_init_ibld_table (cd) + CGEN_CPU_DESC cd; +{ + cd->insert_handlers = & frv_cgen_insert_handlers[0]; + cd->extract_handlers = & frv_cgen_extract_handlers[0]; + + cd->insert_operand = frv_cgen_insert_operand; + cd->extract_operand = frv_cgen_extract_operand; + + cd->get_int_operand = frv_cgen_get_int_operand; + cd->set_int_operand = frv_cgen_set_int_operand; + cd->get_vma_operand = frv_cgen_get_vma_operand; + cd->set_vma_operand = frv_cgen_set_vma_operand; +} diff --git a/opcodes/frv-opc.c b/opcodes/frv-opc.c new file mode 100644 index 0000000..9632557 --- /dev/null +++ b/opcodes/frv-opc.c @@ -0,0 +1,5842 @@ +/* Instruction opcode table for frv. + +THIS FILE IS MACHINE GENERATED WITH CGEN. + +Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + +This file is part of the GNU Binutils and/or 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 "sysdep.h" +#include "ansidecl.h" +#include "bfd.h" +#include "symcat.h" +#include "frv-desc.h" +#include "frv-opc.h" +#include "libiberty.h" + +/* -- opc.c */ +#include "elf/frv.h" + +static int match_unit + PARAMS ((FRV_VLIW *, CGEN_ATTR_VALUE_TYPE, CGEN_ATTR_VALUE_TYPE)); +static int match_vliw + PARAMS ((VLIW_COMBO *, VLIW_COMBO *, int)); +static VLIW_COMBO * add_next_to_vliw + PARAMS ((FRV_VLIW *, CGEN_ATTR_VALUE_TYPE)); +static int find_major_in_vliw + PARAMS ((FRV_VLIW *, CGEN_ATTR_VALUE_TYPE)); +static int fr400_check_insn_major_constraints + PARAMS ((FRV_VLIW *, CGEN_ATTR_VALUE_TYPE)); +static int fr500_check_insn_major_constraints + PARAMS ((FRV_VLIW *, CGEN_ATTR_VALUE_TYPE)); +static int check_insn_major_constraints + PARAMS ((FRV_VLIW *, CGEN_ATTR_VALUE_TYPE)); + +int +frv_is_branch_major (CGEN_ATTR_VALUE_TYPE major, unsigned long mach) +{ + switch (mach) + { + case bfd_mach_fr400: + if (major >= FR400_MAJOR_B_1 && major <= FR400_MAJOR_B_6) + return 1; /* is a branch */ + break; + default: + if (major >= FR500_MAJOR_B_1 && major <= FR500_MAJOR_B_6) + return 1; /* is a branch */ + break; + } + + return 0; /* not a branch */ +} + +int +frv_is_float_major (CGEN_ATTR_VALUE_TYPE major, unsigned long mach) +{ + switch (mach) + { + case bfd_mach_fr400: + return 0; /* No float insns */ + default: + if (major >= FR500_MAJOR_F_1 && major <= FR500_MAJOR_F_8) + return 1; /* is a float insn */ + break; + } + + return 0; /* not a branch */ +} + +int +frv_is_media_major (CGEN_ATTR_VALUE_TYPE major, unsigned long mach) +{ + switch (mach) + { + case bfd_mach_fr400: + if (major >= FR400_MAJOR_M_1 && major <= FR400_MAJOR_M_2) + return 1; /* is a media insn */ + break; + default: + if (major >= FR500_MAJOR_M_1 && major <= FR500_MAJOR_M_8) + return 1; /* is a media insn */ + break; + } + + return 0; /* not a branch */ +} + +int +frv_is_branch_insn (const CGEN_INSN *insn) +{ + if (frv_is_branch_major (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR400_MAJOR), + bfd_mach_fr400)) + return 1; + if (frv_is_branch_major (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR500_MAJOR), + bfd_mach_fr500)) + return 1; + + return 0; +} + +int +frv_is_float_insn (const CGEN_INSN *insn) +{ + if (frv_is_float_major (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR400_MAJOR), + bfd_mach_fr400)) + return 1; + if (frv_is_float_major (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR500_MAJOR), + bfd_mach_fr500)) + return 1; + + return 0; +} + +int +frv_is_media_insn (const CGEN_INSN *insn) +{ + if (frv_is_media_major (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR400_MAJOR), + bfd_mach_fr400)) + return 1; + if (frv_is_media_major (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR500_MAJOR), + bfd_mach_fr500)) + return 1; + + return 0; +} + +/* This table represents the allowable packing for vliw insns for the fr400. + The fr400 has only 2 vliw slots. Represent this by not allowing any insns + in slots 2 and 3. + Subsets of any given row are also allowed. */ +static VLIW_COMBO fr400_allowed_vliw[] = +{ + /* slot0 slot1 slot2 slot3 */ + { UNIT_I0, UNIT_I1, UNIT_NIL, UNIT_NIL }, + { UNIT_I0, UNIT_FM0, UNIT_NIL, UNIT_NIL }, + { UNIT_I0, UNIT_B0, UNIT_NIL, UNIT_NIL }, + { UNIT_FM0, UNIT_FM1, UNIT_NIL, UNIT_NIL }, + { UNIT_FM0, UNIT_B0, UNIT_NIL, UNIT_NIL }, + { UNIT_B0, UNIT_NIL, UNIT_NIL, UNIT_NIL }, + { UNIT_C, UNIT_NIL, UNIT_NIL, UNIT_NIL }, + { UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL } +}; + +/* This table represents the allowable packing for vliw insns for the fr500. + Subsets of any given row are also allowed. */ +static VLIW_COMBO fr500_allowed_vliw[] = +{ + /* slot0 slot1 slot2 slot3 */ + { UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_FM1 }, + { UNIT_I0, UNIT_FM0, UNIT_I1, UNIT_B0 }, + { UNIT_I0, UNIT_FM0, UNIT_FM1, UNIT_B0 }, + { UNIT_I0, UNIT_FM0, UNIT_B0, UNIT_B1 }, + { UNIT_I0, UNIT_I1, UNIT_B0, UNIT_B1 }, + { UNIT_I0, UNIT_B0, UNIT_B1, UNIT_NIL }, + { UNIT_FM0, UNIT_FM1, UNIT_B0, UNIT_B1 }, + { UNIT_FM0, UNIT_B0, UNIT_B1, UNIT_NIL }, + { UNIT_B0, UNIT_B1, UNIT_NIL, UNIT_NIL }, + { UNIT_C, UNIT_NIL, UNIT_NIL, UNIT_NIL }, + { UNIT_NIL, UNIT_NIL, UNIT_NIL, UNIT_NIL } +}; + +/* Some insns are assigned specialized implementation units which map to + different actual implementation units on different machines. These + tables perform that mapping. */ +static CGEN_ATTR_VALUE_TYPE fr400_unit_mapping[] = +{ +/* unit in insn actual unit */ +/* NIL */ UNIT_NIL, +/* I0 */ UNIT_I0, +/* I1 */ UNIT_I1, +/* I01 */ UNIT_I01, +/* FM0 */ UNIT_FM0, +/* FM1 */ UNIT_FM1, +/* FM01 */ UNIT_FM01, +/* B0 */ UNIT_B0, /* branches only in B0 unit. */ +/* B1 */ UNIT_B0, +/* B01 */ UNIT_B0, +/* C */ UNIT_C, +/* MULT-DIV */ UNIT_I0, /* multiply and divide only in I0 unit. */ +/* LOAD */ UNIT_I0 /* load only in I0 unit. */ +}; + +static CGEN_ATTR_VALUE_TYPE fr500_unit_mapping[] = +{ +/* unit in insn actual unit */ +/* NIL */ UNIT_NIL, +/* I0 */ UNIT_I0, +/* I1 */ UNIT_I1, +/* I01 */ UNIT_I01, +/* FM0 */ UNIT_FM0, +/* FM1 */ UNIT_FM1, +/* FM01 */ UNIT_FM01, +/* B0 */ UNIT_B0, +/* B1 */ UNIT_B1, +/* B01 */ UNIT_B01, +/* C */ UNIT_C, +/* MULT-DIV */ UNIT_I01, /* multiply and divide in I0 or I1 unit. */ +/* LOAD */ UNIT_I01 /* load in I0 or I1 unit. */ +}; + +void +frv_vliw_reset (FRV_VLIW *vliw, unsigned long mach, unsigned long elf_flags) +{ + vliw->next_slot = 0; + vliw->constraint_violation = 0; + vliw->mach = mach; + vliw->elf_flags = elf_flags; + + switch (mach) + { + case bfd_mach_fr400: + vliw->current_vliw = fr400_allowed_vliw; + vliw->unit_mapping = fr400_unit_mapping; + break; + default: + vliw->current_vliw = fr500_allowed_vliw; + vliw->unit_mapping = fr500_unit_mapping; + break; + } +} + +/* Return 1 if unit1 is a match for unit2. + Unit1 comes from the insn's UNIT attribute. unit2 comes from one of the + *_allowed_vliw tables above. */ +static int +match_unit (FRV_VLIW *vliw, + CGEN_ATTR_VALUE_TYPE unit1, CGEN_ATTR_VALUE_TYPE unit2) +{ + /* Map any specialized implementation units to actual ones. */ + unit1 = vliw->unit_mapping[unit1]; + + if (unit1 == unit2) + return 1; + if (unit1 < unit2) + return 0; + + switch (unit1) + { + case UNIT_I01: + case UNIT_FM01: + case UNIT_B01: + /* The 01 versions of these units are within 2 enums of the 0 or 1 + versions. */ + if (unit1 - unit2 <= 2) + return 1; + break; + default: + break; + } + + return 0; +} + +/* Return 1 if the vliws match, 0 otherwise. */ + +static int +match_vliw (VLIW_COMBO *vliw1, VLIW_COMBO *vliw2, int vliw_size) +{ + int i; + + for (i = 0; i < vliw_size; ++i) + { + if ((*vliw1)[i] != (*vliw2)[i]) + return 0; + } + + return 1; +} + +/* Find the next vliw vliw in the table that can accomodate the new insn. + If one is found then return it. Otherwise return NULL. */ + +static VLIW_COMBO * +add_next_to_vliw (FRV_VLIW *vliw, CGEN_ATTR_VALUE_TYPE unit) +{ + int next = vliw->next_slot; + VLIW_COMBO *current = vliw->current_vliw; + VLIW_COMBO *potential; + + if (next <= 0) + abort (); /* Should never happen */ + + /* The table is sorted by units allowed within slots, so vliws with + identical starting sequences are together. */ + potential = current; + do + { + if (match_unit (vliw, unit, (*potential)[next])) + return potential; + ++potential; + } + while (match_vliw (potential, current, next)); + + return NULL; +} + +/* Look for the given major insn type in the given vliw. Return 1 if found, + return 0 otherwise. */ + +static int +find_major_in_vliw (FRV_VLIW *vliw, CGEN_ATTR_VALUE_TYPE major) +{ + int i; + + for (i = 0; i < vliw->next_slot; ++i) + if (vliw->major[i] == major) + return 1; + + return 0; +} + +/* Check for constraints between the insns in the vliw due to major insn + types. */ + +static int +fr400_check_insn_major_constraints ( + FRV_VLIW *vliw, CGEN_ATTR_VALUE_TYPE major +) +{ + /* In the cpu file, all media insns are represented as being allowed in + both media units. This makes it easier since this is the case for fr500. + Catch the invalid combinations here. Insns of major class FR400_MAJOR_M_2 + cannot coexist with any other media insn in a vliw. */ + switch (major) + { + case FR400_MAJOR_M_2: + return ! find_major_in_vliw (vliw, FR400_MAJOR_M_1) + && ! find_major_in_vliw (vliw, FR400_MAJOR_M_2); + default: + break; + } + return 1; +} + +static int +fr500_check_insn_major_constraints ( + FRV_VLIW *vliw, CGEN_ATTR_VALUE_TYPE major +) +{ + /* TODO: A table might be faster for some of the more complex instances + here. */ + switch (major) + { + case FR500_MAJOR_I_1: + case FR500_MAJOR_I_4: + case FR500_MAJOR_I_5: + case FR500_MAJOR_I_6: + case FR500_MAJOR_B_1: + case FR500_MAJOR_B_2: + case FR500_MAJOR_B_3: + case FR500_MAJOR_B_4: + case FR500_MAJOR_B_5: + case FR500_MAJOR_B_6: + case FR500_MAJOR_F_4: + case FR500_MAJOR_F_8: + case FR500_MAJOR_M_8: + return 1; /* OK */ + case FR500_MAJOR_I_2: + /* Cannot coexist with I-3 insn. */ + return ! find_major_in_vliw (vliw, FR500_MAJOR_I_3); + case FR500_MAJOR_I_3: + /* Cannot coexist with I-2 insn. */ + return ! find_major_in_vliw (vliw, FR500_MAJOR_I_2); + case FR500_MAJOR_F_1: + case FR500_MAJOR_F_2: + /* Cannot coexist with F-5, F-6, or M-7 insn. */ + return ! find_major_in_vliw (vliw, FR500_MAJOR_F_5) + && ! find_major_in_vliw (vliw, FR500_MAJOR_F_6) + && ! find_major_in_vliw (vliw, FR500_MAJOR_M_7); + case FR500_MAJOR_F_3: + /* Cannot coexist with F-7, or M-7 insn. */ + return ! find_major_in_vliw (vliw, FR500_MAJOR_F_7) + && ! find_major_in_vliw (vliw, FR500_MAJOR_M_7); + case FR500_MAJOR_F_5: + /* Cannot coexist with F-1, F-2, F-6, F-7, or M-7 insn. */ + return ! find_major_in_vliw (vliw, FR500_MAJOR_F_1) + && ! find_major_in_vliw (vliw, FR500_MAJOR_F_2) + && ! find_major_in_vliw (vliw, FR500_MAJOR_F_6) + && ! find_major_in_vliw (vliw, FR500_MAJOR_F_7) + && ! find_major_in_vliw (vliw, FR500_MAJOR_M_7); + case FR500_MAJOR_F_6: + /* Cannot coexist with F-1, F-2, F-5, F-6, or M-7 insn. */ + return ! find_major_in_vliw (vliw, FR500_MAJOR_F_1) + && ! find_major_in_vliw (vliw, FR500_MAJOR_F_2) + && ! find_major_in_vliw (vliw, FR500_MAJOR_F_5) + && ! find_major_in_vliw (vliw, FR500_MAJOR_F_6) + && ! find_major_in_vliw (vliw, FR500_MAJOR_M_7); + case FR500_MAJOR_F_7: + /* Cannot coexist with F-3, F-5, F-7, or M-7 insn. */ + return ! find_major_in_vliw (vliw, FR500_MAJOR_F_3) + && ! find_major_in_vliw (vliw, FR500_MAJOR_F_5) + && ! find_major_in_vliw (vliw, FR500_MAJOR_F_7) + && ! find_major_in_vliw (vliw, FR500_MAJOR_M_7); + case FR500_MAJOR_M_1: + /* Cannot coexist with M-7 insn. */ + return ! find_major_in_vliw (vliw, FR500_MAJOR_M_7); + case FR500_MAJOR_M_2: + case FR500_MAJOR_M_3: + /* Cannot coexist with M-5, M-6 or M-7 insn. */ + return ! find_major_in_vliw (vliw, FR500_MAJOR_M_5) + && ! find_major_in_vliw (vliw, FR500_MAJOR_M_6) + && ! find_major_in_vliw (vliw, FR500_MAJOR_M_7); + case FR500_MAJOR_M_4: + /* Cannot coexist with M-6 insn. */ + return ! find_major_in_vliw (vliw, FR500_MAJOR_M_6); + case FR500_MAJOR_M_5: + /* Cannot coexist with M-2, M-3, M-5, M-6 or M-7 insn. */ + return ! find_major_in_vliw (vliw, FR500_MAJOR_M_2) + && ! find_major_in_vliw (vliw, FR500_MAJOR_M_3) + && ! find_major_in_vliw (vliw, FR500_MAJOR_M_5) + && ! find_major_in_vliw (vliw, FR500_MAJOR_M_6) + && ! find_major_in_vliw (vliw, FR500_MAJOR_M_7); + case FR500_MAJOR_M_6: + /* Cannot coexist with M-2, M-3, M-4, M-5, M-6 or M-7 insn. */ + return ! find_major_in_vliw (vliw, FR500_MAJOR_M_2) + && ! find_major_in_vliw (vliw, FR500_MAJOR_M_3) + && ! find_major_in_vliw (vliw, FR500_MAJOR_M_4) + && ! find_major_in_vliw (vliw, FR500_MAJOR_M_5) + && ! find_major_in_vliw (vliw, FR500_MAJOR_M_6) + && ! find_major_in_vliw (vliw, FR500_MAJOR_M_7); + case FR500_MAJOR_M_7: + /* Cannot coexist with M-1, M-2, M-3, M-5, M-6 or M-7 insn. */ + return ! find_major_in_vliw (vliw, FR500_MAJOR_M_1) + && ! find_major_in_vliw (vliw, FR500_MAJOR_M_2) + && ! find_major_in_vliw (vliw, FR500_MAJOR_M_3) + && ! find_major_in_vliw (vliw, FR500_MAJOR_M_5) + && ! find_major_in_vliw (vliw, FR500_MAJOR_M_6) + && ! find_major_in_vliw (vliw, FR500_MAJOR_M_7) + && ! find_major_in_vliw (vliw, FR500_MAJOR_F_1) + && ! find_major_in_vliw (vliw, FR500_MAJOR_F_2) + && ! find_major_in_vliw (vliw, FR500_MAJOR_F_3) + && ! find_major_in_vliw (vliw, FR500_MAJOR_F_5) + && ! find_major_in_vliw (vliw, FR500_MAJOR_F_6) + && ! find_major_in_vliw (vliw, FR500_MAJOR_F_7); + default: + abort (); + break; + } + return 1; +} + +static int +check_insn_major_constraints ( + FRV_VLIW *vliw, CGEN_ATTR_VALUE_TYPE major +) +{ + int rc; + switch (vliw->mach) + { + case bfd_mach_fr400: + rc = fr400_check_insn_major_constraints (vliw, major); + break; + default: + rc = fr500_check_insn_major_constraints (vliw, major); + break; + } + return rc; +} + +/* Add in insn to the VLIW vliw if possible. Return 0 if successful, + non-zero otherwise. */ +int +frv_vliw_add_insn (FRV_VLIW *vliw, const CGEN_INSN *insn) +{ + int index; + CGEN_ATTR_VALUE_TYPE major; + CGEN_ATTR_VALUE_TYPE unit; + VLIW_COMBO *new_vliw; + + if (vliw->constraint_violation || CGEN_INSN_INVALID_P (insn)) + return 1; + + index = vliw->next_slot; + if (index >= FRV_VLIW_SIZE) + return 1; + + unit = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_UNIT); + if (unit == UNIT_NIL) + abort (); /* no UNIT specified for this insn in frv.cpu */ + + if (vliw->mach == bfd_mach_fr400) + major = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR400_MAJOR); + else + major = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR500_MAJOR); + + if (index <= 0) + { + /* Any insn can be added to slot 0. */ + while (! match_unit (vliw, unit, (*vliw->current_vliw)[0])) + ++vliw->current_vliw; + vliw->major[0] = major; + vliw->next_slot = 1; + return 0; + } + + /* If there are already insns in the vliw(s) check to see that + this one can be added. Do this by finding an allowable vliw + combination that can accept the new insn. */ + if (! (vliw->elf_flags & EF_FRV_NOPACK)) + { + new_vliw = add_next_to_vliw (vliw, unit); + if (new_vliw && check_insn_major_constraints (vliw, major)) + { + vliw->current_vliw = new_vliw; + vliw->major[index] = major; + vliw->next_slot++; + return 0; + } + + /* The frv machine supports all packing conbinations. If we fail, + to add the insn, then it could not be handled as if it was the fr500. + Just return as if it was handled ok. */ + if (vliw->mach == bfd_mach_frv) + return 0; + } + + vliw->constraint_violation = 1; + return 1; +} + +int +spr_valid (regno) + long regno; +{ + if (regno < 0) return 0; + if (regno <= 4095) return 1; + return 0; +} +/* -- */ +/* The hash functions are recorded here to help keep assembler code out of + the disassembler and vice versa. */ + +static int asm_hash_insn_p PARAMS ((const CGEN_INSN *)); +static unsigned int asm_hash_insn PARAMS ((const char *)); +static int dis_hash_insn_p PARAMS ((const CGEN_INSN *)); +static unsigned int dis_hash_insn PARAMS ((const char *, CGEN_INSN_INT)); + +/* Instruction formats. */ + +#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE) +#define F(f) & frv_cgen_ifld_table[FRV_##f] +#else +#define F(f) & frv_cgen_ifld_table[FRV_/**/f] +#endif +static const CGEN_IFMT ifmt_empty = { + 0, 0, 0x0, { { 0 } } +}; + +static const CGEN_IFMT ifmt_add = { + 32, 32, 0x1fc0fc0, { { F (F_PACK) }, { F (F_GRK) }, { F (F_OP) }, { F (F_GRI) }, { F (F_ICCI_1_NULL) }, { F (F_OPE2) }, { F (F_GRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_not = { + 32, 32, 0x1ffffc0, { { F (F_PACK) }, { F (F_GRK) }, { F (F_OP) }, { F (F_RS_NULL) }, { F (F_ICCI_1_NULL) }, { F (F_OPE2) }, { F (F_GRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_smul = { + 32, 32, 0x1fc0fc0, { { F (F_PACK) }, { F (F_GRK) }, { F (F_OP) }, { F (F_GRI) }, { F (F_ICCI_1_NULL) }, { F (F_OPE2) }, { F (F_GRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_cadd = { + 32, 32, 0x1fc00c0, { { F (F_PACK) }, { F (F_GRK) }, { F (F_OP) }, { F (F_GRI) }, { F (F_CCI) }, { F (F_COND) }, { F (F_OPE4) }, { F (F_GRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_cnot = { + 32, 32, 0x1fff0c0, { { F (F_PACK) }, { F (F_GRK) }, { F (F_OP) }, { F (F_RS_NULL) }, { F (F_CCI) }, { F (F_COND) }, { F (F_OPE4) }, { F (F_GRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_csmul = { + 32, 32, 0x1fc00c0, { { F (F_PACK) }, { F (F_GRK) }, { F (F_OP) }, { F (F_GRI) }, { F (F_CCI) }, { F (F_COND) }, { F (F_OPE4) }, { F (F_GRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_addcc = { + 32, 32, 0x1fc03c0, { { F (F_PACK) }, { F (F_GRK) }, { F (F_OP) }, { F (F_GRI) }, { F (F_ICCI_1) }, { F (F_OPE2) }, { F (F_GRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_smulcc = { + 32, 32, 0x1fc03c0, { { F (F_PACK) }, { F (F_GRK) }, { F (F_OP) }, { F (F_GRI) }, { F (F_ICCI_1) }, { F (F_OPE2) }, { F (F_GRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_addi = { + 32, 32, 0x1fc0000, { { F (F_PACK) }, { F (F_GRK) }, { F (F_OP) }, { F (F_GRI) }, { F (F_D12) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_smuli = { + 32, 32, 0x1fc0000, { { F (F_PACK) }, { F (F_GRK) }, { F (F_OP) }, { F (F_GRI) }, { F (F_D12) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_addicc = { + 32, 32, 0x1fc0000, { { F (F_PACK) }, { F (F_GRK) }, { F (F_OP) }, { F (F_GRI) }, { F (F_ICCI_1) }, { F (F_S10) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_smulicc = { + 32, 32, 0x1fc0000, { { F (F_PACK) }, { F (F_GRK) }, { F (F_OP) }, { F (F_GRI) }, { F (F_ICCI_1) }, { F (F_S10) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_cmpb = { + 32, 32, 0x7ffc03c0, { { F (F_PACK) }, { F (F_GRK_NULL) }, { F (F_OP) }, { F (F_GRI) }, { F (F_ICCI_1) }, { F (F_OPE2) }, { F (F_GRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_setlo = { + 32, 32, 0x1ff0000, { { F (F_PACK) }, { F (F_GRK) }, { F (F_OP) }, { F (F_MISC_NULL_4) }, { F (F_U16) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_sethi = { + 32, 32, 0x1ff0000, { { F (F_PACK) }, { F (F_GRK) }, { F (F_OP) }, { F (F_MISC_NULL_4) }, { F (F_U16) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_setlos = { + 32, 32, 0x1ff0000, { { F (F_PACK) }, { F (F_GRK) }, { F (F_OP) }, { F (F_MISC_NULL_4) }, { F (F_S16) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_ldsb = { + 32, 32, 0x1fc0fc0, { { F (F_PACK) }, { F (F_GRK) }, { F (F_OP) }, { F (F_GRI) }, { F (F_OPE1) }, { F (F_GRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_ldbf = { + 32, 32, 0x1fc0fc0, { { F (F_PACK) }, { F (F_FRK) }, { F (F_OP) }, { F (F_GRI) }, { F (F_OPE1) }, { F (F_GRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_ldc = { + 32, 32, 0x1fc0fc0, { { F (F_PACK) }, { F (F_CPRK) }, { F (F_OP) }, { F (F_GRI) }, { F (F_OPE1) }, { F (F_GRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_ldd = { + 32, 32, 0x1fc0fc0, { { F (F_PACK) }, { F (F_GRK) }, { F (F_OP) }, { F (F_GRI) }, { F (F_OPE1) }, { F (F_GRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_lddf = { + 32, 32, 0x1fc0fc0, { { F (F_PACK) }, { F (F_FRK) }, { F (F_OP) }, { F (F_GRI) }, { F (F_OPE1) }, { F (F_GRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_lddc = { + 32, 32, 0x1fc0fc0, { { F (F_PACK) }, { F (F_CPRK) }, { F (F_OP) }, { F (F_GRI) }, { F (F_OPE1) }, { F (F_GRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_ldsbi = { + 32, 32, 0x1fc0000, { { F (F_PACK) }, { F (F_GRK) }, { F (F_OP) }, { F (F_GRI) }, { F (F_D12) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_ldbfi = { + 32, 32, 0x1fc0000, { { F (F_PACK) }, { F (F_FRK) }, { F (F_OP) }, { F (F_GRI) }, { F (F_D12) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_lddi = { + 32, 32, 0x1fc0000, { { F (F_PACK) }, { F (F_GRK) }, { F (F_OP) }, { F (F_GRI) }, { F (F_D12) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_lddfi = { + 32, 32, 0x1fc0000, { { F (F_PACK) }, { F (F_FRK) }, { F (F_OP) }, { F (F_GRI) }, { F (F_D12) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_stdf = { + 32, 32, 0x1fc0fc0, { { F (F_PACK) }, { F (F_FRK) }, { F (F_OP) }, { F (F_GRI) }, { F (F_OPE1) }, { F (F_GRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_cldbf = { + 32, 32, 0x1fc00c0, { { F (F_PACK) }, { F (F_FRK) }, { F (F_OP) }, { F (F_GRI) }, { F (F_CCI) }, { F (F_COND) }, { F (F_OPE4) }, { F (F_GRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_clddf = { + 32, 32, 0x1fc00c0, { { F (F_PACK) }, { F (F_FRK) }, { F (F_OP) }, { F (F_GRI) }, { F (F_CCI) }, { F (F_COND) }, { F (F_OPE4) }, { F (F_GRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_cstdf = { + 32, 32, 0x1fc00c0, { { F (F_PACK) }, { F (F_FRK) }, { F (F_OP) }, { F (F_GRI) }, { F (F_CCI) }, { F (F_COND) }, { F (F_OPE4) }, { F (F_GRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_stdfi = { + 32, 32, 0x1fc0000, { { F (F_PACK) }, { F (F_FRK) }, { F (F_OP) }, { F (F_GRI) }, { F (F_D12) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_movgf = { + 32, 32, 0x1ffffc0, { { F (F_PACK) }, { F (F_FRK) }, { F (F_OP) }, { F (F_RS_NULL) }, { F (F_OPE1) }, { F (F_GRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_cmovgf = { + 32, 32, 0x1fff0c0, { { F (F_PACK) }, { F (F_FRK) }, { F (F_OP) }, { F (F_RS_NULL) }, { F (F_CCI) }, { F (F_COND) }, { F (F_OPE4) }, { F (F_GRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_movgs = { + 32, 32, 0x1fc0fc0, { { F (F_PACK) }, { F (F_OP) }, { F (F_SPR) }, { F (F_OPE1) }, { F (F_GRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_bra = { + 32, 32, 0x7ffc0000, { { F (F_PACK) }, { F (F_INT_CC) }, { F (F_ICCI_2_NULL) }, { F (F_OP) }, { F (F_HINT) }, { F (F_LABEL16) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_bno = { + 32, 32, 0x7ffcffff, { { F (F_PACK) }, { F (F_INT_CC) }, { F (F_ICCI_2_NULL) }, { F (F_OP) }, { F (F_HINT) }, { F (F_LABEL16_NULL) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_beq = { + 32, 32, 0x79fc0000, { { F (F_PACK) }, { F (F_INT_CC) }, { F (F_ICCI_2) }, { F (F_OP) }, { F (F_HINT) }, { F (F_LABEL16) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_fbra = { + 32, 32, 0x7ffc0000, { { F (F_PACK) }, { F (F_FLT_CC) }, { F (F_FCCI_2_NULL) }, { F (F_OP) }, { F (F_HINT) }, { F (F_LABEL16) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_fbno = { + 32, 32, 0x7ffcffff, { { F (F_PACK) }, { F (F_FLT_CC) }, { F (F_FCCI_2_NULL) }, { F (F_OP) }, { F (F_HINT) }, { F (F_LABEL16_NULL) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_fbne = { + 32, 32, 0x79fc0000, { { F (F_PACK) }, { F (F_FLT_CC) }, { F (F_FCCI_2) }, { F (F_OP) }, { F (F_HINT) }, { F (F_LABEL16) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_bctrlr = { + 32, 32, 0x7ffcefff, { { F (F_PACK) }, { F (F_COND_NULL) }, { F (F_ICCI_2_NULL) }, { F (F_OP) }, { F (F_HINT) }, { F (F_OPE3) }, { F (F_CCOND) }, { F (F_S12_NULL) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_bralr = { + 32, 32, 0x7ffcffff, { { F (F_PACK) }, { F (F_INT_CC) }, { F (F_ICCI_2_NULL) }, { F (F_OP) }, { F (F_HINT) }, { F (F_OPE3) }, { F (F_CCOND_NULL) }, { F (F_S12_NULL) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_bnolr = { + 32, 32, 0x7ffcffff, { { F (F_PACK) }, { F (F_INT_CC) }, { F (F_ICCI_2_NULL) }, { F (F_OP) }, { F (F_HINT) }, { F (F_OPE3) }, { F (F_CCOND_NULL) }, { F (F_S12_NULL) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_beqlr = { + 32, 32, 0x79fcffff, { { F (F_PACK) }, { F (F_INT_CC) }, { F (F_ICCI_2) }, { F (F_OP) }, { F (F_HINT) }, { F (F_OPE3) }, { F (F_CCOND_NULL) }, { F (F_S12_NULL) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_fbralr = { + 32, 32, 0x7ffcffff, { { F (F_PACK) }, { F (F_FLT_CC) }, { F (F_FCCI_2_NULL) }, { F (F_OP) }, { F (F_HINT) }, { F (F_OPE3) }, { F (F_CCOND_NULL) }, { F (F_S12_NULL) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_fbnolr = { + 32, 32, 0x7ffcffff, { { F (F_PACK) }, { F (F_FLT_CC) }, { F (F_FCCI_2_NULL) }, { F (F_OP) }, { F (F_HINT) }, { F (F_OPE3) }, { F (F_CCOND_NULL) }, { F (F_S12_NULL) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_fbeqlr = { + 32, 32, 0x79fcffff, { { F (F_PACK) }, { F (F_FLT_CC) }, { F (F_FCCI_2) }, { F (F_OP) }, { F (F_HINT) }, { F (F_OPE3) }, { F (F_CCOND_NULL) }, { F (F_S12_NULL) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_bcralr = { + 32, 32, 0x7ffcefff, { { F (F_PACK) }, { F (F_INT_CC) }, { F (F_ICCI_2_NULL) }, { F (F_OP) }, { F (F_HINT) }, { F (F_OPE3) }, { F (F_CCOND) }, { F (F_S12_NULL) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_bceqlr = { + 32, 32, 0x79fcefff, { { F (F_PACK) }, { F (F_INT_CC) }, { F (F_ICCI_2) }, { F (F_OP) }, { F (F_HINT) }, { F (F_OPE3) }, { F (F_CCOND) }, { F (F_S12_NULL) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_fcbralr = { + 32, 32, 0x7ffcefff, { { F (F_PACK) }, { F (F_FLT_CC) }, { F (F_FCCI_2_NULL) }, { F (F_OP) }, { F (F_HINT) }, { F (F_OPE3) }, { F (F_CCOND) }, { F (F_S12_NULL) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_fcbeqlr = { + 32, 32, 0x79fcefff, { { F (F_PACK) }, { F (F_FLT_CC) }, { F (F_FCCI_2) }, { F (F_OP) }, { F (F_HINT) }, { F (F_OPE3) }, { F (F_CCOND) }, { F (F_S12_NULL) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_jmpl = { + 32, 32, 0x7ffc0fc0, { { F (F_PACK) }, { F (F_MISC_NULL_1) }, { F (F_LI_OFF) }, { F (F_OP) }, { F (F_GRI) }, { F (F_MISC_NULL_2) }, { F (F_GRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_calll = { + 32, 32, 0x7ffc0fc0, { { F (F_PACK) }, { F (F_MISC_NULL_1) }, { F (F_LI_ON) }, { F (F_OP) }, { F (F_GRI) }, { F (F_MISC_NULL_2) }, { F (F_GRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_jmpil = { + 32, 32, 0x7ffc0000, { { F (F_PACK) }, { F (F_MISC_NULL_1) }, { F (F_LI_OFF) }, { F (F_OP) }, { F (F_GRI) }, { F (F_D12) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_callil = { + 32, 32, 0x7ffc0000, { { F (F_PACK) }, { F (F_MISC_NULL_1) }, { F (F_LI_ON) }, { F (F_OP) }, { F (F_GRI) }, { F (F_D12) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_call = { + 32, 32, 0x1fc0000, { { F (F_PACK) }, { F (F_OP) }, { F (F_LABEL24) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_rett = { + 32, 32, 0x7dffffff, { { F (F_PACK) }, { F (F_MISC_NULL_1) }, { F (F_DEBUG) }, { F (F_OP) }, { F (F_RS_NULL) }, { F (F_S12_NULL) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_rei = { + 32, 32, 0x7ffc0fff, { { F (F_PACK) }, { F (F_RD_NULL) }, { F (F_OP) }, { F (F_EIR) }, { F (F_S12_NULL) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_tra = { + 32, 32, 0x7ffc0fc0, { { F (F_PACK) }, { F (F_INT_CC) }, { F (F_ICCI_2_NULL) }, { F (F_OP) }, { F (F_GRI) }, { F (F_MISC_NULL_3) }, { F (F_OPE4) }, { F (F_GRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_tno = { + 32, 32, 0x7fffffff, { { F (F_PACK) }, { F (F_INT_CC) }, { F (F_ICCI_2_NULL) }, { F (F_OP) }, { F (F_GRI_NULL) }, { F (F_MISC_NULL_3) }, { F (F_OPE4) }, { F (F_GRJ_NULL) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_teq = { + 32, 32, 0x79fc0fc0, { { F (F_PACK) }, { F (F_INT_CC) }, { F (F_ICCI_2) }, { F (F_OP) }, { F (F_GRI) }, { F (F_MISC_NULL_3) }, { F (F_OPE4) }, { F (F_GRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_ftra = { + 32, 32, 0x7ffc0fc0, { { F (F_PACK) }, { F (F_FLT_CC) }, { F (F_FCCI_2_NULL) }, { F (F_OP) }, { F (F_GRI) }, { F (F_MISC_NULL_3) }, { F (F_OPE4) }, { F (F_GRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_ftno = { + 32, 32, 0x7fffffff, { { F (F_PACK) }, { F (F_FLT_CC) }, { F (F_FCCI_2_NULL) }, { F (F_OP) }, { F (F_GRI_NULL) }, { F (F_MISC_NULL_3) }, { F (F_OPE4) }, { F (F_GRJ_NULL) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_ftne = { + 32, 32, 0x79fc0fc0, { { F (F_PACK) }, { F (F_FLT_CC) }, { F (F_FCCI_2) }, { F (F_OP) }, { F (F_GRI) }, { F (F_MISC_NULL_3) }, { F (F_OPE4) }, { F (F_GRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_tira = { + 32, 32, 0x7ffc0000, { { F (F_PACK) }, { F (F_INT_CC) }, { F (F_ICCI_2_NULL) }, { F (F_OP) }, { F (F_GRI) }, { F (F_D12) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_tino = { + 32, 32, 0x7fffffff, { { F (F_PACK) }, { F (F_INT_CC) }, { F (F_ICCI_2_NULL) }, { F (F_OP) }, { F (F_GRI_NULL) }, { F (F_S12_NULL) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_tieq = { + 32, 32, 0x79fc0000, { { F (F_PACK) }, { F (F_INT_CC) }, { F (F_ICCI_2) }, { F (F_OP) }, { F (F_GRI) }, { F (F_D12) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_ftira = { + 32, 32, 0x7ffc0000, { { F (F_PACK) }, { F (F_FLT_CC) }, { F (F_ICCI_2_NULL) }, { F (F_OP) }, { F (F_GRI) }, { F (F_D12) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_ftino = { + 32, 32, 0x7fffffff, { { F (F_PACK) }, { F (F_FLT_CC) }, { F (F_FCCI_2_NULL) }, { F (F_OP) }, { F (F_GRI_NULL) }, { F (F_S12_NULL) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_ftine = { + 32, 32, 0x79fc0000, { { F (F_PACK) }, { F (F_FLT_CC) }, { F (F_FCCI_2) }, { F (F_OP) }, { F (F_GRI) }, { F (F_D12) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_break = { + 32, 32, 0x7fffffff, { { F (F_PACK) }, { F (F_RD_NULL) }, { F (F_OP) }, { F (F_RS_NULL) }, { F (F_MISC_NULL_3) }, { F (F_OPE4) }, { F (F_GRJ_NULL) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_andcr = { + 32, 32, 0x71ff8ff8, { { F (F_PACK) }, { F (F_MISC_NULL_6) }, { F (F_CRK) }, { F (F_OP) }, { F (F_MISC_NULL_7) }, { F (F_CRI) }, { F (F_OPE1) }, { F (F_MISC_NULL_8) }, { F (F_CRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_notcr = { + 32, 32, 0x71fffff8, { { F (F_PACK) }, { F (F_MISC_NULL_6) }, { F (F_CRK) }, { F (F_OP) }, { F (F_RS_NULL) }, { F (F_OPE1) }, { F (F_MISC_NULL_8) }, { F (F_CRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_ckra = { + 32, 32, 0x79ffffff, { { F (F_PACK) }, { F (F_INT_CC) }, { F (F_CRJ_INT) }, { F (F_OP) }, { F (F_MISC_NULL_5) }, { F (F_ICCI_3_NULL) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_ckeq = { + 32, 32, 0x79fffffc, { { F (F_PACK) }, { F (F_INT_CC) }, { F (F_CRJ_INT) }, { F (F_OP) }, { F (F_MISC_NULL_5) }, { F (F_ICCI_3) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_fckra = { + 32, 32, 0x79fffffc, { { F (F_PACK) }, { F (F_FLT_CC) }, { F (F_CRJ_FLOAT) }, { F (F_OP) }, { F (F_MISC_NULL_5) }, { F (F_FCCI_3) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_cckra = { + 32, 32, 0x79fff0ff, { { F (F_PACK) }, { F (F_INT_CC) }, { F (F_CRJ_INT) }, { F (F_OP) }, { F (F_RS_NULL) }, { F (F_CCI) }, { F (F_COND) }, { F (F_OPE4) }, { F (F_MISC_NULL_9) }, { F (F_ICCI_3_NULL) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_cckeq = { + 32, 32, 0x79fff0fc, { { F (F_PACK) }, { F (F_INT_CC) }, { F (F_CRJ_INT) }, { F (F_OP) }, { F (F_RS_NULL) }, { F (F_CCI) }, { F (F_COND) }, { F (F_OPE4) }, { F (F_MISC_NULL_9) }, { F (F_ICCI_3) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_cfckra = { + 32, 32, 0x79fff0ff, { { F (F_PACK) }, { F (F_FLT_CC) }, { F (F_CRJ_FLOAT) }, { F (F_OP) }, { F (F_RS_NULL) }, { F (F_CCI) }, { F (F_COND) }, { F (F_OPE4) }, { F (F_MISC_NULL_9) }, { F (F_FCCI_3_NULL) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_cfckne = { + 32, 32, 0x79fff0fc, { { F (F_PACK) }, { F (F_FLT_CC) }, { F (F_CRJ_FLOAT) }, { F (F_OP) }, { F (F_RS_NULL) }, { F (F_CCI) }, { F (F_COND) }, { F (F_OPE4) }, { F (F_MISC_NULL_9) }, { F (F_FCCI_3) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_cjmpl = { + 32, 32, 0x7ffc00c0, { { F (F_PACK) }, { F (F_MISC_NULL_1) }, { F (F_LI_OFF) }, { F (F_OP) }, { F (F_GRI) }, { F (F_CCI) }, { F (F_COND) }, { F (F_OPE4) }, { F (F_GRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_ccalll = { + 32, 32, 0x7ffc00c0, { { F (F_PACK) }, { F (F_MISC_NULL_1) }, { F (F_LI_ON) }, { F (F_OP) }, { F (F_GRI) }, { F (F_CCI) }, { F (F_COND) }, { F (F_OPE4) }, { F (F_GRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_ici = { + 32, 32, 0x7ffc0fc0, { { F (F_PACK) }, { F (F_RD_NULL) }, { F (F_OP) }, { F (F_GRI) }, { F (F_OPE1) }, { F (F_GRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_icei = { + 32, 32, 0x7dfc0fc0, { { F (F_PACK) }, { F (F_MISC_NULL_1) }, { F (F_AE) }, { F (F_OP) }, { F (F_GRI) }, { F (F_OPE1) }, { F (F_GRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_icpl = { + 32, 32, 0x7dfc0fc0, { { F (F_PACK) }, { F (F_MISC_NULL_1) }, { F (F_LOCK) }, { F (F_OP) }, { F (F_GRI) }, { F (F_OPE1) }, { F (F_GRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_icul = { + 32, 32, 0x7ffc0fff, { { F (F_PACK) }, { F (F_RD_NULL) }, { F (F_OP) }, { F (F_GRI) }, { F (F_OPE1) }, { F (F_GRJ_NULL) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_bar = { + 32, 32, 0x7fffffff, { { F (F_PACK) }, { F (F_RD_NULL) }, { F (F_OP) }, { F (F_RS_NULL) }, { F (F_OPE1) }, { F (F_GRJ_NULL) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_cop1 = { + 32, 32, 0x1fc0000, { { F (F_PACK) }, { F (F_CPRK) }, { F (F_OP) }, { F (F_CPRI) }, { F (F_S6_1) }, { F (F_CPRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_clrgr = { + 32, 32, 0x1ffffff, { { F (F_PACK) }, { F (F_GRK) }, { F (F_OP) }, { F (F_RS_NULL) }, { F (F_OPE1) }, { F (F_GRJ_NULL) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_clrfr = { + 32, 32, 0x1ffffff, { { F (F_PACK) }, { F (F_FRK) }, { F (F_OP) }, { F (F_RS_NULL) }, { F (F_OPE1) }, { F (F_GRJ_NULL) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_fitos = { + 32, 32, 0x1ffffc0, { { F (F_PACK) }, { F (F_FRK) }, { F (F_OP) }, { F (F_RS_NULL) }, { F (F_OPE1) }, { F (F_FRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_fstoi = { + 32, 32, 0x1ffffc0, { { F (F_PACK) }, { F (F_FRK) }, { F (F_OP) }, { F (F_RS_NULL) }, { F (F_OPE1) }, { F (F_FRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_fitod = { + 32, 32, 0x1ffffc0, { { F (F_PACK) }, { F (F_FRK) }, { F (F_OP) }, { F (F_RS_NULL) }, { F (F_OPE1) }, { F (F_FRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_fdtoi = { + 32, 32, 0x1ffffc0, { { F (F_PACK) }, { F (F_FRK) }, { F (F_OP) }, { F (F_RS_NULL) }, { F (F_OPE1) }, { F (F_FRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_cfitos = { + 32, 32, 0x1fff0c0, { { F (F_PACK) }, { F (F_FRK) }, { F (F_OP) }, { F (F_RS_NULL) }, { F (F_CCI) }, { F (F_COND) }, { F (F_OPE4) }, { F (F_FRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_cfstoi = { + 32, 32, 0x1fff0c0, { { F (F_PACK) }, { F (F_FRK) }, { F (F_OP) }, { F (F_RS_NULL) }, { F (F_CCI) }, { F (F_COND) }, { F (F_OPE4) }, { F (F_FRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_fmovs = { + 32, 32, 0x1ffffc0, { { F (F_PACK) }, { F (F_FRK) }, { F (F_OP) }, { F (F_RS_NULL) }, { F (F_OPE1) }, { F (F_FRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_fmovd = { + 32, 32, 0x1ffffc0, { { F (F_PACK) }, { F (F_FRK) }, { F (F_OP) }, { F (F_RS_NULL) }, { F (F_OPE1) }, { F (F_FRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_cfmovs = { + 32, 32, 0x1fff0c0, { { F (F_PACK) }, { F (F_FRK) }, { F (F_OP) }, { F (F_RS_NULL) }, { F (F_CCI) }, { F (F_COND) }, { F (F_OPE4) }, { F (F_FRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_fadds = { + 32, 32, 0x1fc0fc0, { { F (F_PACK) }, { F (F_FRK) }, { F (F_OP) }, { F (F_FRI) }, { F (F_OPE1) }, { F (F_FRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_faddd = { + 32, 32, 0x1fc0fc0, { { F (F_PACK) }, { F (F_FRK) }, { F (F_OP) }, { F (F_FRI) }, { F (F_OPE1) }, { F (F_FRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_cfadds = { + 32, 32, 0x1fc00c0, { { F (F_PACK) }, { F (F_FRK) }, { F (F_OP) }, { F (F_FRI) }, { F (F_CCI) }, { F (F_COND) }, { F (F_OPE4) }, { F (F_FRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_fcmps = { + 32, 32, 0x79fc0fc0, { { F (F_PACK) }, { F (F_COND_NULL) }, { F (F_FCCI_2) }, { F (F_OP) }, { F (F_FRI) }, { F (F_OPE1) }, { F (F_FRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_fcmpd = { + 32, 32, 0x79fc0fc0, { { F (F_PACK) }, { F (F_COND_NULL) }, { F (F_FCCI_2) }, { F (F_OP) }, { F (F_FRI) }, { F (F_OPE1) }, { F (F_FRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_cfcmps = { + 32, 32, 0x79fc00c0, { { F (F_PACK) }, { F (F_COND_NULL) }, { F (F_FCCI_2) }, { F (F_OP) }, { F (F_FRI) }, { F (F_CCI) }, { F (F_COND) }, { F (F_OPE4) }, { F (F_FRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_mhsetlos = { + 32, 32, 0x1fc0fc0, { { F (F_PACK) }, { F (F_FRK) }, { F (F_OP) }, { F (F_OPE1) }, { F (F_U12) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_mhsethis = { + 32, 32, 0x1fc0fc0, { { F (F_PACK) }, { F (F_FRK) }, { F (F_OP) }, { F (F_OPE1) }, { F (F_U12) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_mhdsets = { + 32, 32, 0x1fc0fc0, { { F (F_PACK) }, { F (F_FRK) }, { F (F_OP) }, { F (F_OPE1) }, { F (F_U12) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_mhsetloh = { + 32, 32, 0x1ffffe0, { { F (F_PACK) }, { F (F_FRK) }, { F (F_OP) }, { F (F_FRI_NULL) }, { F (F_OPE1) }, { F (F_MISC_NULL_11) }, { F (F_S5) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_mhsethih = { + 32, 32, 0x1ffffe0, { { F (F_PACK) }, { F (F_FRK) }, { F (F_OP) }, { F (F_FRI_NULL) }, { F (F_OPE1) }, { F (F_MISC_NULL_11) }, { F (F_S5) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_mhdseth = { + 32, 32, 0x1ffffe0, { { F (F_PACK) }, { F (F_FRK) }, { F (F_OP) }, { F (F_FRI_NULL) }, { F (F_OPE1) }, { F (F_MISC_NULL_11) }, { F (F_S5) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_mand = { + 32, 32, 0x1fc0fc0, { { F (F_PACK) }, { F (F_FRK) }, { F (F_OP) }, { F (F_FRI) }, { F (F_OPE1) }, { F (F_FRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_cmand = { + 32, 32, 0x1fc00c0, { { F (F_PACK) }, { F (F_FRK) }, { F (F_OP) }, { F (F_FRI) }, { F (F_CCI) }, { F (F_COND) }, { F (F_OPE4) }, { F (F_FRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_mnot = { + 32, 32, 0x1ffffc0, { { F (F_PACK) }, { F (F_FRK) }, { F (F_OP) }, { F (F_RS_NULL) }, { F (F_OPE1) }, { F (F_FRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_cmnot = { + 32, 32, 0x1fff0c0, { { F (F_PACK) }, { F (F_FRK) }, { F (F_OP) }, { F (F_RS_NULL) }, { F (F_CCI) }, { F (F_COND) }, { F (F_OPE4) }, { F (F_FRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_mrotli = { + 32, 32, 0x1fc0fc0, { { F (F_PACK) }, { F (F_FRK) }, { F (F_OP) }, { F (F_FRI) }, { F (F_OPE1) }, { F (F_U6) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_mcut = { + 32, 32, 0x1fc0fc0, { { F (F_PACK) }, { F (F_FRK) }, { F (F_OP) }, { F (F_ACC40SI) }, { F (F_OPE1) }, { F (F_FRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_mcuti = { + 32, 32, 0x1fc0fc0, { { F (F_PACK) }, { F (F_FRK) }, { F (F_OP) }, { F (F_ACC40SI) }, { F (F_OPE1) }, { F (F_S6) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_mcmpsh = { + 32, 32, 0x79fc0fc0, { { F (F_PACK) }, { F (F_COND_NULL) }, { F (F_FCCK) }, { F (F_OP) }, { F (F_FRI) }, { F (F_OPE1) }, { F (F_FRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_mabshs = { + 32, 32, 0x1ffffc0, { { F (F_PACK) }, { F (F_FRK) }, { F (F_OP) }, { F (F_FRI_NULL) }, { F (F_OPE1) }, { F (F_FRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_maddaccs = { + 32, 32, 0x1fc0fff, { { F (F_PACK) }, { F (F_ACC40SK) }, { F (F_OP) }, { F (F_ACC40SI) }, { F (F_OPE1) }, { F (F_ACCJ_NULL) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_mmulhs = { + 32, 32, 0x1fc0fc0, { { F (F_PACK) }, { F (F_ACC40SK) }, { F (F_OP) }, { F (F_FRI) }, { F (F_OPE1) }, { F (F_FRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_cmmulhs = { + 32, 32, 0x1fc00c0, { { F (F_PACK) }, { F (F_ACC40SK) }, { F (F_OP) }, { F (F_FRI) }, { F (F_CCI) }, { F (F_COND) }, { F (F_OPE4) }, { F (F_FRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_mmachu = { + 32, 32, 0x1fc0fc0, { { F (F_PACK) }, { F (F_ACC40UK) }, { F (F_OP) }, { F (F_FRI) }, { F (F_OPE1) }, { F (F_FRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_cmmachu = { + 32, 32, 0x1fc00c0, { { F (F_PACK) }, { F (F_ACC40UK) }, { F (F_OP) }, { F (F_FRI) }, { F (F_CCI) }, { F (F_COND) }, { F (F_OPE4) }, { F (F_FRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_cmexpdhw = { + 32, 32, 0x1fc00c0, { { F (F_PACK) }, { F (F_FRK) }, { F (F_OP) }, { F (F_FRI) }, { F (F_CCI) }, { F (F_COND) }, { F (F_OPE4) }, { F (F_U6) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_munpackh = { + 32, 32, 0x1fc0fff, { { F (F_PACK) }, { F (F_FRK) }, { F (F_OP) }, { F (F_FRI) }, { F (F_OPE1) }, { F (F_FRJ_NULL) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_cmbtoh = { + 32, 32, 0x1fff0c0, { { F (F_PACK) }, { F (F_FRK) }, { F (F_OP) }, { F (F_FRI_NULL) }, { F (F_CCI) }, { F (F_COND) }, { F (F_OPE4) }, { F (F_FRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_mclracc = { + 32, 32, 0x1fdffff, { { F (F_PACK) }, { F (F_ACC40SK) }, { F (F_OP) }, { F (F_A) }, { F (F_MISC_NULL_10) }, { F (F_OPE1) }, { F (F_FRJ_NULL) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_mrdacc = { + 32, 32, 0x1fc0fff, { { F (F_PACK) }, { F (F_FRK) }, { F (F_OP) }, { F (F_ACC40SI) }, { F (F_OPE1) }, { F (F_FRJ_NULL) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_mrdaccg = { + 32, 32, 0x1fc0fff, { { F (F_PACK) }, { F (F_FRK) }, { F (F_OP) }, { F (F_ACCGI) }, { F (F_OPE1) }, { F (F_FRJ_NULL) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_mwtacc = { + 32, 32, 0x1fc0fff, { { F (F_PACK) }, { F (F_ACC40SK) }, { F (F_OP) }, { F (F_FRI) }, { F (F_OPE1) }, { F (F_FRJ_NULL) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_mwtaccg = { + 32, 32, 0x1fc0fff, { { F (F_PACK) }, { F (F_ACCGK) }, { F (F_OP) }, { F (F_FRI) }, { F (F_OPE1) }, { F (F_FRJ_NULL) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_fnop = { + 32, 32, 0x7fffffff, { { F (F_PACK) }, { F (F_RD_NULL) }, { F (F_OP) }, { F (F_FRI_NULL) }, { F (F_OPE1) }, { F (F_FRJ_NULL) }, { 0 } } +}; + +#undef F + +#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE) +#define A(a) (1 << CGEN_INSN_##a) +#else +#define A(a) (1 << CGEN_INSN_/**/a) +#endif +#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE) +#define OPERAND(op) FRV_OPERAND_##op +#else +#define OPERAND(op) FRV_OPERAND_/**/op +#endif +#define MNEM CGEN_SYNTAX_MNEMONIC /* syntax value for mnemonic */ +#define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field)) + +/* The instruction table. */ + +static const CGEN_OPCODE frv_cgen_insn_opcode_table[MAX_INSNS] = +{ + /* Special null first entry. + A `num' value of zero is thus invalid. + Also, the special `invalid' insn resides here. */ + { { 0, 0, 0, 0 }, {{0}}, 0, {0}}, +/* add$pack $GRi,$GRj,$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRK), 0 } }, + & ifmt_add, { 0x0 } + }, +/* sub$pack $GRi,$GRj,$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRK), 0 } }, + & ifmt_add, { 0x100 } + }, +/* and$pack $GRi,$GRj,$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRK), 0 } }, + & ifmt_add, { 0x40000 } + }, +/* or$pack $GRi,$GRj,$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRK), 0 } }, + & ifmt_add, { 0x40080 } + }, +/* xor$pack $GRi,$GRj,$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRK), 0 } }, + & ifmt_add, { 0x40100 } + }, +/* not$pack $GRj,$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRJ), ',', OP (GRK), 0 } }, + & ifmt_not, { 0x40180 } + }, +/* sdiv$pack $GRi,$GRj,$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRK), 0 } }, + & ifmt_add, { 0x380 } + }, +/* nsdiv$pack $GRi,$GRj,$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRK), 0 } }, + & ifmt_add, { 0x40380 } + }, +/* udiv$pack $GRi,$GRj,$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRK), 0 } }, + & ifmt_add, { 0x3c0 } + }, +/* nudiv$pack $GRi,$GRj,$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRK), 0 } }, + & ifmt_add, { 0x403c0 } + }, +/* smul$pack $GRi,$GRj,$GRdoublek */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRDOUBLEK), 0 } }, + & ifmt_smul, { 0x200 } + }, +/* umul$pack $GRi,$GRj,$GRdoublek */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRDOUBLEK), 0 } }, + & ifmt_smul, { 0x280 } + }, +/* sll$pack $GRi,$GRj,$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRK), 0 } }, + & ifmt_add, { 0x40200 } + }, +/* srl$pack $GRi,$GRj,$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRK), 0 } }, + & ifmt_add, { 0x40280 } + }, +/* sra$pack $GRi,$GRj,$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRK), 0 } }, + & ifmt_add, { 0x40300 } + }, +/* scan$pack $GRi,$GRj,$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRK), 0 } }, + & ifmt_add, { 0x2c0000 } + }, +/* cadd$pack $GRi,$GRj,$GRk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cadd, { 0x1600000 } + }, +/* csub$pack $GRi,$GRj,$GRk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cadd, { 0x1600040 } + }, +/* cand$pack $GRi,$GRj,$GRk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cadd, { 0x1680000 } + }, +/* cor$pack $GRi,$GRj,$GRk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cadd, { 0x1680040 } + }, +/* cxor$pack $GRi,$GRj,$GRk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cadd, { 0x1680080 } + }, +/* cnot$pack $GRj,$GRk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRJ), ',', OP (GRK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cnot, { 0x16800c0 } + }, +/* csmul$pack $GRi,$GRj,$GRdoublek,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRDOUBLEK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_csmul, { 0x1600080 } + }, +/* csdiv$pack $GRi,$GRj,$GRk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cadd, { 0x16000c0 } + }, +/* cudiv$pack $GRi,$GRj,$GRk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cadd, { 0x16400c0 } + }, +/* csll$pack $GRi,$GRj,$GRk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cadd, { 0x1700000 } + }, +/* csrl$pack $GRi,$GRj,$GRk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cadd, { 0x1700040 } + }, +/* csra$pack $GRi,$GRj,$GRk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cadd, { 0x1700080 } + }, +/* cscan$pack $GRi,$GRj,$GRk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cadd, { 0x19400c0 } + }, +/* addcc$pack $GRi,$GRj,$GRk,$ICCi_1 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRK), ',', OP (ICCI_1), 0 } }, + & ifmt_addcc, { 0x40 } + }, +/* subcc$pack $GRi,$GRj,$GRk,$ICCi_1 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRK), ',', OP (ICCI_1), 0 } }, + & ifmt_addcc, { 0x140 } + }, +/* andcc$pack $GRi,$GRj,$GRk,$ICCi_1 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRK), ',', OP (ICCI_1), 0 } }, + & ifmt_addcc, { 0x40040 } + }, +/* orcc$pack $GRi,$GRj,$GRk,$ICCi_1 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRK), ',', OP (ICCI_1), 0 } }, + & ifmt_addcc, { 0x400c0 } + }, +/* xorcc$pack $GRi,$GRj,$GRk,$ICCi_1 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRK), ',', OP (ICCI_1), 0 } }, + & ifmt_addcc, { 0x40140 } + }, +/* sllcc$pack $GRi,$GRj,$GRk,$ICCi_1 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRK), ',', OP (ICCI_1), 0 } }, + & ifmt_addcc, { 0x40240 } + }, +/* srlcc$pack $GRi,$GRj,$GRk,$ICCi_1 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRK), ',', OP (ICCI_1), 0 } }, + & ifmt_addcc, { 0x402c0 } + }, +/* sracc$pack $GRi,$GRj,$GRk,$ICCi_1 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRK), ',', OP (ICCI_1), 0 } }, + & ifmt_addcc, { 0x40340 } + }, +/* smulcc$pack $GRi,$GRj,$GRdoublek,$ICCi_1 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRDOUBLEK), ',', OP (ICCI_1), 0 } }, + & ifmt_smulcc, { 0x240 } + }, +/* umulcc$pack $GRi,$GRj,$GRdoublek,$ICCi_1 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRDOUBLEK), ',', OP (ICCI_1), 0 } }, + & ifmt_smulcc, { 0x2c0 } + }, +/* caddcc$pack $GRi,$GRj,$GRk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cadd, { 0x1640000 } + }, +/* csubcc$pack $GRi,$GRj,$GRk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cadd, { 0x1640040 } + }, +/* csmulcc$pack $GRi,$GRj,$GRdoublek,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRDOUBLEK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_csmul, { 0x1640080 } + }, +/* candcc$pack $GRi,$GRj,$GRk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cadd, { 0x16c0000 } + }, +/* corcc$pack $GRi,$GRj,$GRk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cadd, { 0x16c0040 } + }, +/* cxorcc$pack $GRi,$GRj,$GRk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cadd, { 0x16c0080 } + }, +/* csllcc$pack $GRi,$GRj,$GRk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cadd, { 0x1740000 } + }, +/* csrlcc$pack $GRi,$GRj,$GRk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cadd, { 0x1740040 } + }, +/* csracc$pack $GRi,$GRj,$GRk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cadd, { 0x1740080 } + }, +/* addx$pack $GRi,$GRj,$GRk,$ICCi_1 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRK), ',', OP (ICCI_1), 0 } }, + & ifmt_addcc, { 0x80 } + }, +/* subx$pack $GRi,$GRj,$GRk,$ICCi_1 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRK), ',', OP (ICCI_1), 0 } }, + & ifmt_addcc, { 0x180 } + }, +/* addxcc$pack $GRi,$GRj,$GRk,$ICCi_1 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRK), ',', OP (ICCI_1), 0 } }, + & ifmt_addcc, { 0xc0 } + }, +/* subxcc$pack $GRi,$GRj,$GRk,$ICCi_1 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (GRK), ',', OP (ICCI_1), 0 } }, + & ifmt_addcc, { 0x1c0 } + }, +/* addi$pack $GRi,$s12,$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (S12), ',', OP (GRK), 0 } }, + & ifmt_addi, { 0x400000 } + }, +/* subi$pack $GRi,$s12,$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (S12), ',', OP (GRK), 0 } }, + & ifmt_addi, { 0x500000 } + }, +/* andi$pack $GRi,$s12,$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (S12), ',', OP (GRK), 0 } }, + & ifmt_addi, { 0x800000 } + }, +/* ori$pack $GRi,$s12,$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (S12), ',', OP (GRK), 0 } }, + & ifmt_addi, { 0x880000 } + }, +/* xori$pack $GRi,$s12,$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (S12), ',', OP (GRK), 0 } }, + & ifmt_addi, { 0x900000 } + }, +/* sdivi$pack $GRi,$s12,$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (S12), ',', OP (GRK), 0 } }, + & ifmt_addi, { 0x780000 } + }, +/* nsdivi$pack $GRi,$s12,$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (S12), ',', OP (GRK), 0 } }, + & ifmt_addi, { 0xb80000 } + }, +/* udivi$pack $GRi,$s12,$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (S12), ',', OP (GRK), 0 } }, + & ifmt_addi, { 0x7c0000 } + }, +/* nudivi$pack $GRi,$s12,$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (S12), ',', OP (GRK), 0 } }, + & ifmt_addi, { 0xbc0000 } + }, +/* smuli$pack $GRi,$s12,$GRdoublek */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (S12), ',', OP (GRDOUBLEK), 0 } }, + & ifmt_smuli, { 0x600000 } + }, +/* umuli$pack $GRi,$s12,$GRdoublek */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (S12), ',', OP (GRDOUBLEK), 0 } }, + & ifmt_smuli, { 0x680000 } + }, +/* slli$pack $GRi,$s12,$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (S12), ',', OP (GRK), 0 } }, + & ifmt_addi, { 0xa00000 } + }, +/* srli$pack $GRi,$s12,$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (S12), ',', OP (GRK), 0 } }, + & ifmt_addi, { 0xa80000 } + }, +/* srai$pack $GRi,$s12,$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (S12), ',', OP (GRK), 0 } }, + & ifmt_addi, { 0xb00000 } + }, +/* scani$pack $GRi,$s12,$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (S12), ',', OP (GRK), 0 } }, + & ifmt_addi, { 0x11c0000 } + }, +/* addicc$pack $GRi,$s10,$GRk,$ICCi_1 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (S10), ',', OP (GRK), ',', OP (ICCI_1), 0 } }, + & ifmt_addicc, { 0x440000 } + }, +/* subicc$pack $GRi,$s10,$GRk,$ICCi_1 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (S10), ',', OP (GRK), ',', OP (ICCI_1), 0 } }, + & ifmt_addicc, { 0x540000 } + }, +/* andicc$pack $GRi,$s10,$GRk,$ICCi_1 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (S10), ',', OP (GRK), ',', OP (ICCI_1), 0 } }, + & ifmt_addicc, { 0x840000 } + }, +/* oricc$pack $GRi,$s10,$GRk,$ICCi_1 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (S10), ',', OP (GRK), ',', OP (ICCI_1), 0 } }, + & ifmt_addicc, { 0x8c0000 } + }, +/* xoricc$pack $GRi,$s10,$GRk,$ICCi_1 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (S10), ',', OP (GRK), ',', OP (ICCI_1), 0 } }, + & ifmt_addicc, { 0x940000 } + }, +/* smulicc$pack $GRi,$s10,$GRdoublek,$ICCi_1 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (S10), ',', OP (GRDOUBLEK), ',', OP (ICCI_1), 0 } }, + & ifmt_smulicc, { 0x640000 } + }, +/* umulicc$pack $GRi,$s10,$GRdoublek,$ICCi_1 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (S10), ',', OP (GRDOUBLEK), ',', OP (ICCI_1), 0 } }, + & ifmt_smulicc, { 0x6c0000 } + }, +/* sllicc$pack $GRi,$s10,$GRk,$ICCi_1 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (S10), ',', OP (GRK), ',', OP (ICCI_1), 0 } }, + & ifmt_addicc, { 0xa40000 } + }, +/* srlicc$pack $GRi,$s10,$GRk,$ICCi_1 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (S10), ',', OP (GRK), ',', OP (ICCI_1), 0 } }, + & ifmt_addicc, { 0xac0000 } + }, +/* sraicc$pack $GRi,$s10,$GRk,$ICCi_1 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (S10), ',', OP (GRK), ',', OP (ICCI_1), 0 } }, + & ifmt_addicc, { 0xb40000 } + }, +/* addxi$pack $GRi,$s10,$GRk,$ICCi_1 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (S10), ',', OP (GRK), ',', OP (ICCI_1), 0 } }, + & ifmt_addicc, { 0x480000 } + }, +/* subxi$pack $GRi,$s10,$GRk,$ICCi_1 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (S10), ',', OP (GRK), ',', OP (ICCI_1), 0 } }, + & ifmt_addicc, { 0x580000 } + }, +/* addxicc$pack $GRi,$s10,$GRk,$ICCi_1 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (S10), ',', OP (GRK), ',', OP (ICCI_1), 0 } }, + & ifmt_addicc, { 0x4c0000 } + }, +/* subxicc$pack $GRi,$s10,$GRk,$ICCi_1 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (S10), ',', OP (GRK), ',', OP (ICCI_1), 0 } }, + & ifmt_addicc, { 0x5c0000 } + }, +/* cmpb$pack $GRi,$GRj,$ICCi_1 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (ICCI_1), 0 } }, + & ifmt_cmpb, { 0x300 } + }, +/* cmpba$pack $GRi,$GRj,$ICCi_1 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (ICCI_1), 0 } }, + & ifmt_cmpb, { 0x340 } + }, +/* setlo$pack $ulo16,$GRklo */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ULO16), ',', OP (GRKLO), 0 } }, + & ifmt_setlo, { 0xf40000 } + }, +/* sethi$pack $uhi16,$GRkhi */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (UHI16), ',', OP (GRKHI), 0 } }, + & ifmt_sethi, { 0xf80000 } + }, +/* setlos$pack $slo16,$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (SLO16), ',', OP (GRK), 0 } }, + & ifmt_setlos, { 0xfc0000 } + }, +/* ldsb$pack @($GRi,$GRj),$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (GRK), 0 } }, + & ifmt_ldsb, { 0x80000 } + }, +/* ldub$pack @($GRi,$GRj),$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (GRK), 0 } }, + & ifmt_ldsb, { 0x80040 } + }, +/* ldsh$pack @($GRi,$GRj),$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (GRK), 0 } }, + & ifmt_ldsb, { 0x80080 } + }, +/* lduh$pack @($GRi,$GRj),$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (GRK), 0 } }, + & ifmt_ldsb, { 0x800c0 } + }, +/* ld$pack @($GRi,$GRj),$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (GRK), 0 } }, + & ifmt_ldsb, { 0x80100 } + }, +/* ldbf$pack @($GRi,$GRj),$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (FRINTK), 0 } }, + & ifmt_ldbf, { 0x80200 } + }, +/* ldhf$pack @($GRi,$GRj),$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (FRINTK), 0 } }, + & ifmt_ldbf, { 0x80240 } + }, +/* ldf$pack @($GRi,$GRj),$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (FRINTK), 0 } }, + & ifmt_ldbf, { 0x80280 } + }, +/* ldc$pack @($GRi,$GRj),$CPRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (CPRK), 0 } }, + & ifmt_ldc, { 0x80340 } + }, +/* nldsb$pack @($GRi,$GRj),$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (GRK), 0 } }, + & ifmt_ldsb, { 0x80800 } + }, +/* nldub$pack @($GRi,$GRj),$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (GRK), 0 } }, + & ifmt_ldsb, { 0x80840 } + }, +/* nldsh$pack @($GRi,$GRj),$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (GRK), 0 } }, + & ifmt_ldsb, { 0x80880 } + }, +/* nlduh$pack @($GRi,$GRj),$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (GRK), 0 } }, + & ifmt_ldsb, { 0x808c0 } + }, +/* nld$pack @($GRi,$GRj),$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (GRK), 0 } }, + & ifmt_ldsb, { 0x80900 } + }, +/* nldbf$pack @($GRi,$GRj),$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (FRINTK), 0 } }, + & ifmt_ldbf, { 0x80a00 } + }, +/* nldhf$pack @($GRi,$GRj),$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (FRINTK), 0 } }, + & ifmt_ldbf, { 0x80a40 } + }, +/* nldf$pack @($GRi,$GRj),$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (FRINTK), 0 } }, + & ifmt_ldbf, { 0x80a80 } + }, +/* ldd$pack @($GRi,$GRj),$GRdoublek */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (GRDOUBLEK), 0 } }, + & ifmt_ldd, { 0x80140 } + }, +/* lddf$pack @($GRi,$GRj),$FRdoublek */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (FRDOUBLEK), 0 } }, + & ifmt_lddf, { 0x802c0 } + }, +/* lddc$pack @($GRi,$GRj),$CPRdoublek */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (CPRDOUBLEK), 0 } }, + & ifmt_lddc, { 0x80380 } + }, +/* nldd$pack @($GRi,$GRj),$GRdoublek */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (GRDOUBLEK), 0 } }, + & ifmt_ldd, { 0x80940 } + }, +/* nlddf$pack @($GRi,$GRj),$FRdoublek */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (FRDOUBLEK), 0 } }, + & ifmt_lddf, { 0x80ac0 } + }, +/* ldq$pack @($GRi,$GRj),$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (GRK), 0 } }, + & ifmt_ldsb, { 0x80180 } + }, +/* ldqf$pack @($GRi,$GRj),$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (FRINTK), 0 } }, + & ifmt_ldbf, { 0x80300 } + }, +/* ldqc$pack @($GRi,$GRj),$CPRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (CPRK), 0 } }, + & ifmt_ldc, { 0x803c0 } + }, +/* nldq$pack @($GRi,$GRj),$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (GRK), 0 } }, + & ifmt_ldsb, { 0x80980 } + }, +/* nldqf$pack @($GRi,$GRj),$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (FRINTK), 0 } }, + & ifmt_ldbf, { 0x80b00 } + }, +/* ldsbu$pack @($GRi,$GRj),$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (GRK), 0 } }, + & ifmt_ldsb, { 0x80400 } + }, +/* ldubu$pack @($GRi,$GRj),$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (GRK), 0 } }, + & ifmt_ldsb, { 0x80440 } + }, +/* ldshu$pack @($GRi,$GRj),$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (GRK), 0 } }, + & ifmt_ldsb, { 0x80480 } + }, +/* lduhu$pack @($GRi,$GRj),$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (GRK), 0 } }, + & ifmt_ldsb, { 0x804c0 } + }, +/* ldu$pack @($GRi,$GRj),$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (GRK), 0 } }, + & ifmt_ldsb, { 0x80500 } + }, +/* nldsbu$pack @($GRi,$GRj),$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (GRK), 0 } }, + & ifmt_ldsb, { 0x80c00 } + }, +/* nldubu$pack @($GRi,$GRj),$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (GRK), 0 } }, + & ifmt_ldsb, { 0x80c40 } + }, +/* nldshu$pack @($GRi,$GRj),$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (GRK), 0 } }, + & ifmt_ldsb, { 0x80c80 } + }, +/* nlduhu$pack @($GRi,$GRj),$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (GRK), 0 } }, + & ifmt_ldsb, { 0x80cc0 } + }, +/* nldu$pack @($GRi,$GRj),$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (GRK), 0 } }, + & ifmt_ldsb, { 0x80d00 } + }, +/* ldbfu$pack @($GRi,$GRj),$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (FRINTK), 0 } }, + & ifmt_ldbf, { 0x80600 } + }, +/* ldhfu$pack @($GRi,$GRj),$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (FRINTK), 0 } }, + & ifmt_ldbf, { 0x80640 } + }, +/* ldfu$pack @($GRi,$GRj),$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (FRINTK), 0 } }, + & ifmt_ldbf, { 0x80680 } + }, +/* ldcu$pack @($GRi,$GRj),$CPRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (CPRK), 0 } }, + & ifmt_ldc, { 0x80740 } + }, +/* nldbfu$pack @($GRi,$GRj),$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (FRINTK), 0 } }, + & ifmt_ldbf, { 0x80e00 } + }, +/* nldhfu$pack @($GRi,$GRj),$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (FRINTK), 0 } }, + & ifmt_ldbf, { 0x80e40 } + }, +/* nldfu$pack @($GRi,$GRj),$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (FRINTK), 0 } }, + & ifmt_ldbf, { 0x80e80 } + }, +/* lddu$pack @($GRi,$GRj),$GRdoublek */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (GRDOUBLEK), 0 } }, + & ifmt_ldd, { 0x80540 } + }, +/* nlddu$pack @($GRi,$GRj),$GRdoublek */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (GRDOUBLEK), 0 } }, + & ifmt_ldd, { 0x80d40 } + }, +/* lddfu$pack @($GRi,$GRj),$FRdoublek */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (FRDOUBLEK), 0 } }, + & ifmt_lddf, { 0x806c0 } + }, +/* lddcu$pack @($GRi,$GRj),$CPRdoublek */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (CPRDOUBLEK), 0 } }, + & ifmt_lddc, { 0x80780 } + }, +/* nlddfu$pack @($GRi,$GRj),$FRdoublek */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (FRDOUBLEK), 0 } }, + & ifmt_lddf, { 0x80ec0 } + }, +/* ldqu$pack @($GRi,$GRj),$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (GRK), 0 } }, + & ifmt_ldsb, { 0x80580 } + }, +/* nldqu$pack @($GRi,$GRj),$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (GRK), 0 } }, + & ifmt_ldsb, { 0x80d80 } + }, +/* ldqfu$pack @($GRi,$GRj),$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (FRINTK), 0 } }, + & ifmt_ldbf, { 0x80700 } + }, +/* ldqcu$pack @($GRi,$GRj),$CPRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (CPRK), 0 } }, + & ifmt_ldc, { 0x807c0 } + }, +/* nldqfu$pack @($GRi,$GRj),$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (FRINTK), 0 } }, + & ifmt_ldbf, { 0x80f00 } + }, +/* ldsbi$pack @($GRi,$d12),$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (D12), ')', ',', OP (GRK), 0 } }, + & ifmt_ldsbi, { 0xc00000 } + }, +/* ldshi$pack @($GRi,$d12),$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (D12), ')', ',', OP (GRK), 0 } }, + & ifmt_ldsbi, { 0xc40000 } + }, +/* ldi$pack @($GRi,$d12),$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (D12), ')', ',', OP (GRK), 0 } }, + & ifmt_ldsbi, { 0xc80000 } + }, +/* ldubi$pack @($GRi,$d12),$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (D12), ')', ',', OP (GRK), 0 } }, + & ifmt_ldsbi, { 0xd40000 } + }, +/* lduhi$pack @($GRi,$d12),$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (D12), ')', ',', OP (GRK), 0 } }, + & ifmt_ldsbi, { 0xd80000 } + }, +/* ldbfi$pack @($GRi,$d12),$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (D12), ')', ',', OP (FRINTK), 0 } }, + & ifmt_ldbfi, { 0xe00000 } + }, +/* ldhfi$pack @($GRi,$d12),$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (D12), ')', ',', OP (FRINTK), 0 } }, + & ifmt_ldbfi, { 0xe40000 } + }, +/* ldfi$pack @($GRi,$d12),$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (D12), ')', ',', OP (FRINTK), 0 } }, + & ifmt_ldbfi, { 0xe80000 } + }, +/* nldsbi$pack @($GRi,$d12),$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (D12), ')', ',', OP (GRK), 0 } }, + & ifmt_ldsbi, { 0x1000000 } + }, +/* nldubi$pack @($GRi,$d12),$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (D12), ')', ',', OP (GRK), 0 } }, + & ifmt_ldsbi, { 0x1040000 } + }, +/* nldshi$pack @($GRi,$d12),$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (D12), ')', ',', OP (GRK), 0 } }, + & ifmt_ldsbi, { 0x1080000 } + }, +/* nlduhi$pack @($GRi,$d12),$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (D12), ')', ',', OP (GRK), 0 } }, + & ifmt_ldsbi, { 0x10c0000 } + }, +/* nldi$pack @($GRi,$d12),$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (D12), ')', ',', OP (GRK), 0 } }, + & ifmt_ldsbi, { 0x1100000 } + }, +/* nldbfi$pack @($GRi,$d12),$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (D12), ')', ',', OP (FRINTK), 0 } }, + & ifmt_ldbfi, { 0x1200000 } + }, +/* nldhfi$pack @($GRi,$d12),$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (D12), ')', ',', OP (FRINTK), 0 } }, + & ifmt_ldbfi, { 0x1240000 } + }, +/* nldfi$pack @($GRi,$d12),$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (D12), ')', ',', OP (FRINTK), 0 } }, + & ifmt_ldbfi, { 0x1280000 } + }, +/* lddi$pack @($GRi,$d12),$GRdoublek */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (D12), ')', ',', OP (GRDOUBLEK), 0 } }, + & ifmt_lddi, { 0xcc0000 } + }, +/* lddfi$pack @($GRi,$d12),$FRdoublek */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (D12), ')', ',', OP (FRDOUBLEK), 0 } }, + & ifmt_lddfi, { 0xec0000 } + }, +/* nlddi$pack @($GRi,$d12),$GRdoublek */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (D12), ')', ',', OP (GRDOUBLEK), 0 } }, + & ifmt_lddi, { 0x1140000 } + }, +/* nlddfi$pack @($GRi,$d12),$FRdoublek */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (D12), ')', ',', OP (FRDOUBLEK), 0 } }, + & ifmt_lddfi, { 0x12c0000 } + }, +/* ldqi$pack @($GRi,$d12),$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (D12), ')', ',', OP (GRK), 0 } }, + & ifmt_ldsbi, { 0xd00000 } + }, +/* ldqfi$pack @($GRi,$d12),$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (D12), ')', ',', OP (FRINTK), 0 } }, + & ifmt_ldbfi, { 0xf00000 } + }, +/* nldqi$pack @($GRi,$d12),$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (D12), ')', ',', OP (GRK), 0 } }, + & ifmt_ldsbi, { 0x1180000 } + }, +/* nldqfi$pack @($GRi,$d12),$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (D12), ')', ',', OP (FRINTK), 0 } }, + & ifmt_ldbfi, { 0x1300000 } + }, +/* stb$pack $GRk,@($GRi,$GRj) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', 0 } }, + & ifmt_ldsb, { 0xc0000 } + }, +/* sth$pack $GRk,@($GRi,$GRj) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', 0 } }, + & ifmt_ldsb, { 0xc0040 } + }, +/* st$pack $GRk,@($GRi,$GRj) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', 0 } }, + & ifmt_ldsb, { 0xc0080 } + }, +/* stbf$pack $FRintk,@($GRi,$GRj) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', 0 } }, + & ifmt_ldbf, { 0xc0200 } + }, +/* sthf$pack $FRintk,@($GRi,$GRj) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', 0 } }, + & ifmt_ldbf, { 0xc0240 } + }, +/* stf$pack $FRintk,@($GRi,$GRj) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', 0 } }, + & ifmt_ldbf, { 0xc0280 } + }, +/* stc$pack $CPRk,@($GRi,$GRj) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (CPRK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', 0 } }, + & ifmt_ldc, { 0xc0940 } + }, +/* rstb$pack $GRk,@($GRi,$GRj) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', 0 } }, + & ifmt_ldsb, { 0xc0800 } + }, +/* rsth$pack $GRk,@($GRi,$GRj) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', 0 } }, + & ifmt_ldsb, { 0xc0840 } + }, +/* rst$pack $GRk,@($GRi,$GRj) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', 0 } }, + & ifmt_ldsb, { 0xc0880 } + }, +/* rstbf$pack $FRintk,@($GRi,$GRj) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', 0 } }, + & ifmt_ldbf, { 0xc0a00 } + }, +/* rsthf$pack $FRintk,@($GRi,$GRj) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', 0 } }, + & ifmt_ldbf, { 0xc0a40 } + }, +/* rstf$pack $FRintk,@($GRi,$GRj) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', 0 } }, + & ifmt_ldbf, { 0xc0a80 } + }, +/* std$pack $GRk,@($GRi,$GRj) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', 0 } }, + & ifmt_ldsb, { 0xc00c0 } + }, +/* stdf$pack $FRk,@($GRi,$GRj) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', 0 } }, + & ifmt_stdf, { 0xc02c0 } + }, +/* stdc$pack $CPRk,@($GRi,$GRj) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (CPRK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', 0 } }, + & ifmt_ldc, { 0xc0980 } + }, +/* rstd$pack $GRk,@($GRi,$GRj) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', 0 } }, + & ifmt_ldsb, { 0xc08c0 } + }, +/* rstdf$pack $FRk,@($GRi,$GRj) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', 0 } }, + & ifmt_stdf, { 0xc0ac0 } + }, +/* stq$pack $GRk,@($GRi,$GRj) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', 0 } }, + & ifmt_ldsb, { 0xc0100 } + }, +/* stqf$pack $FRintk,@($GRi,$GRj) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', 0 } }, + & ifmt_ldbf, { 0xc0300 } + }, +/* stqc$pack $CPRk,@($GRi,$GRj) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (CPRK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', 0 } }, + & ifmt_ldc, { 0xc09c0 } + }, +/* rstq$pack $GRk,@($GRi,$GRj) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', 0 } }, + & ifmt_ldsb, { 0xc0900 } + }, +/* rstqf$pack $FRintk,@($GRi,$GRj) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', 0 } }, + & ifmt_ldbf, { 0xc0b00 } + }, +/* stbu$pack $GRk,@($GRi,$GRj) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', 0 } }, + & ifmt_ldsb, { 0xc0400 } + }, +/* sthu$pack $GRk,@($GRi,$GRj) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', 0 } }, + & ifmt_ldsb, { 0xc0440 } + }, +/* stu$pack $GRk,@($GRi,$GRj) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', 0 } }, + & ifmt_ldsb, { 0xc0480 } + }, +/* stbfu$pack $FRintk,@($GRi,$GRj) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', 0 } }, + & ifmt_ldbf, { 0xc0600 } + }, +/* sthfu$pack $FRintk,@($GRi,$GRj) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', 0 } }, + & ifmt_ldbf, { 0xc0640 } + }, +/* stfu$pack $FRintk,@($GRi,$GRj) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', 0 } }, + & ifmt_ldbf, { 0xc0680 } + }, +/* stcu$pack $CPRk,@($GRi,$GRj) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (CPRK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', 0 } }, + & ifmt_ldc, { 0xc0b40 } + }, +/* stdu$pack $GRk,@($GRi,$GRj) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', 0 } }, + & ifmt_ldsb, { 0xc04c0 } + }, +/* stdfu$pack $FRk,@($GRi,$GRj) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', 0 } }, + & ifmt_stdf, { 0xc06c0 } + }, +/* stdcu$pack $CPRk,@($GRi,$GRj) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (CPRK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', 0 } }, + & ifmt_ldc, { 0xc0b80 } + }, +/* stqu$pack $GRk,@($GRi,$GRj) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', 0 } }, + & ifmt_ldsb, { 0xc0500 } + }, +/* stqfu$pack $FRintk,@($GRi,$GRj) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', 0 } }, + & ifmt_ldbf, { 0xc0700 } + }, +/* stqcu$pack $CPRk,@($GRi,$GRj) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (CPRK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', 0 } }, + & ifmt_ldc, { 0xc0bc0 } + }, +/* cldsb$pack @($GRi,$GRj),$GRk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (GRK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cadd, { 0x1780000 } + }, +/* cldub$pack @($GRi,$GRj),$GRk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (GRK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cadd, { 0x1780040 } + }, +/* cldsh$pack @($GRi,$GRj),$GRk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (GRK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cadd, { 0x1780080 } + }, +/* clduh$pack @($GRi,$GRj),$GRk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (GRK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cadd, { 0x17800c0 } + }, +/* cld$pack @($GRi,$GRj),$GRk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (GRK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cadd, { 0x17c0000 } + }, +/* cldbf$pack @($GRi,$GRj),$FRintk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (FRINTK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cldbf, { 0x1800000 } + }, +/* cldhf$pack @($GRi,$GRj),$FRintk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (FRINTK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cldbf, { 0x1800040 } + }, +/* cldf$pack @($GRi,$GRj),$FRintk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (FRINTK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cldbf, { 0x1800080 } + }, +/* cldd$pack @($GRi,$GRj),$GRdoublek,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (GRDOUBLEK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_csmul, { 0x17c0040 } + }, +/* clddf$pack @($GRi,$GRj),$FRdoublek,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (FRDOUBLEK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_clddf, { 0x18000c0 } + }, +/* cldq$pack @($GRi,$GRj),$GRk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (GRK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cadd, { 0x17c0080 } + }, +/* cldsbu$pack @($GRi,$GRj),$GRk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (GRK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cadd, { 0x1840000 } + }, +/* cldubu$pack @($GRi,$GRj),$GRk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (GRK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cadd, { 0x1840040 } + }, +/* cldshu$pack @($GRi,$GRj),$GRk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (GRK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cadd, { 0x1840080 } + }, +/* clduhu$pack @($GRi,$GRj),$GRk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (GRK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cadd, { 0x18400c0 } + }, +/* cldu$pack @($GRi,$GRj),$GRk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (GRK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cadd, { 0x1880000 } + }, +/* cldbfu$pack @($GRi,$GRj),$FRintk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (FRINTK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cldbf, { 0x18c0000 } + }, +/* cldhfu$pack @($GRi,$GRj),$FRintk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (FRINTK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cldbf, { 0x18c0040 } + }, +/* cldfu$pack @($GRi,$GRj),$FRintk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (FRINTK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cldbf, { 0x18c0080 } + }, +/* clddu$pack @($GRi,$GRj),$GRdoublek,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (GRDOUBLEK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_csmul, { 0x1880040 } + }, +/* clddfu$pack @($GRi,$GRj),$FRdoublek,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (FRDOUBLEK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_clddf, { 0x18c00c0 } + }, +/* cldqu$pack @($GRi,$GRj),$GRk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (GRK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cadd, { 0x1880080 } + }, +/* cstb$pack $GRk,@($GRi,$GRj),$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cadd, { 0x1900000 } + }, +/* csth$pack $GRk,@($GRi,$GRj),$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cadd, { 0x1900040 } + }, +/* cst$pack $GRk,@($GRi,$GRj),$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cadd, { 0x1900080 } + }, +/* cstbf$pack $FRintk,@($GRi,$GRj),$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cldbf, { 0x1980000 } + }, +/* csthf$pack $FRintk,@($GRi,$GRj),$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cldbf, { 0x1980040 } + }, +/* cstf$pack $FRintk,@($GRi,$GRj),$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cldbf, { 0x1980080 } + }, +/* cstd$pack $GRk,@($GRi,$GRj),$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cadd, { 0x19000c0 } + }, +/* cstdf$pack $FRk,@($GRi,$GRj),$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cstdf, { 0x19800c0 } + }, +/* cstq$pack $GRk,@($GRi,$GRj),$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cadd, { 0x1940000 } + }, +/* cstbu$pack $GRk,@($GRi,$GRj),$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cadd, { 0x19c0000 } + }, +/* csthu$pack $GRk,@($GRi,$GRj),$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cadd, { 0x19c0040 } + }, +/* cstu$pack $GRk,@($GRi,$GRj),$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cadd, { 0x19c0080 } + }, +/* cstbfu$pack $FRintk,@($GRi,$GRj),$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cldbf, { 0x1a00000 } + }, +/* csthfu$pack $FRintk,@($GRi,$GRj),$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cldbf, { 0x1a00040 } + }, +/* cstfu$pack $FRintk,@($GRi,$GRj),$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cldbf, { 0x1a00080 } + }, +/* cstdu$pack $GRk,@($GRi,$GRj),$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cadd, { 0x19c00c0 } + }, +/* cstdfu$pack $FRk,@($GRi,$GRj),$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cstdf, { 0x1a000c0 } + }, +/* stbi$pack $GRk,@($GRi,$d12) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRK), ',', '@', '(', OP (GRI), ',', OP (D12), ')', 0 } }, + & ifmt_ldsbi, { 0x1400000 } + }, +/* sthi$pack $GRk,@($GRi,$d12) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRK), ',', '@', '(', OP (GRI), ',', OP (D12), ')', 0 } }, + & ifmt_ldsbi, { 0x1440000 } + }, +/* sti$pack $GRk,@($GRi,$d12) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRK), ',', '@', '(', OP (GRI), ',', OP (D12), ')', 0 } }, + & ifmt_ldsbi, { 0x1480000 } + }, +/* stbfi$pack $FRintk,@($GRi,$d12) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTK), ',', '@', '(', OP (GRI), ',', OP (D12), ')', 0 } }, + & ifmt_ldbfi, { 0x1380000 } + }, +/* sthfi$pack $FRintk,@($GRi,$d12) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTK), ',', '@', '(', OP (GRI), ',', OP (D12), ')', 0 } }, + & ifmt_ldbfi, { 0x13c0000 } + }, +/* stfi$pack $FRintk,@($GRi,$d12) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTK), ',', '@', '(', OP (GRI), ',', OP (D12), ')', 0 } }, + & ifmt_ldbfi, { 0x1540000 } + }, +/* stdi$pack $GRk,@($GRi,$d12) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRK), ',', '@', '(', OP (GRI), ',', OP (D12), ')', 0 } }, + & ifmt_ldsbi, { 0x14c0000 } + }, +/* stdfi$pack $FRk,@($GRi,$d12) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRK), ',', '@', '(', OP (GRI), ',', OP (D12), ')', 0 } }, + & ifmt_stdfi, { 0x1580000 } + }, +/* stqi$pack $GRk,@($GRi,$d12) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRK), ',', '@', '(', OP (GRI), ',', OP (D12), ')', 0 } }, + & ifmt_ldsbi, { 0x1500000 } + }, +/* stqfi$pack $FRintk,@($GRi,$d12) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTK), ',', '@', '(', OP (GRI), ',', OP (D12), ')', 0 } }, + & ifmt_ldbfi, { 0x15c0000 } + }, +/* swap$pack @($GRi,$GRj),$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (GRK), 0 } }, + & ifmt_ldsb, { 0xc0140 } + }, +/* swapi$pack @($GRi,$d12),$GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (D12), ')', ',', OP (GRK), 0 } }, + & ifmt_ldsbi, { 0x1340000 } + }, +/* cswap$pack @($GRi,$GRj),$GRk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (GRK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cadd, { 0x1940080 } + }, +/* movgf$pack $GRj,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRJ), ',', OP (FRINTK), 0 } }, + & ifmt_movgf, { 0xc0540 } + }, +/* movfg$pack $FRintk,$GRj */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTK), ',', OP (GRJ), 0 } }, + & ifmt_movgf, { 0xc0340 } + }, +/* movgfd$pack $GRj,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRJ), ',', OP (FRINTK), 0 } }, + & ifmt_movgf, { 0xc0580 } + }, +/* movfgd$pack $FRintk,$GRj */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTK), ',', OP (GRJ), 0 } }, + & ifmt_movgf, { 0xc0380 } + }, +/* movgfq$pack $GRj,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRJ), ',', OP (FRINTK), 0 } }, + & ifmt_movgf, { 0xc05c0 } + }, +/* movfgq$pack $FRintk,$GRj */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTK), ',', OP (GRJ), 0 } }, + & ifmt_movgf, { 0xc03c0 } + }, +/* cmovgf$pack $GRj,$FRintk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRJ), ',', OP (FRINTK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cmovgf, { 0x1a40000 } + }, +/* cmovfg$pack $FRintk,$GRj,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTK), ',', OP (GRJ), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cmovgf, { 0x1a40080 } + }, +/* cmovgfd$pack $GRj,$FRintk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRJ), ',', OP (FRINTK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cmovgf, { 0x1a40040 } + }, +/* cmovfgd$pack $FRintk,$GRj,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTK), ',', OP (GRJ), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cmovgf, { 0x1a400c0 } + }, +/* movgs$pack $GRj,$spr */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRJ), ',', OP (SPR), 0 } }, + & ifmt_movgs, { 0xc0180 } + }, +/* movsg$pack $spr,$GRj */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (SPR), ',', OP (GRJ), 0 } }, + & ifmt_movgs, { 0xc01c0 } + }, +/* bra$pack $hint_taken$label16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (HINT_TAKEN), OP (LABEL16), 0 } }, + & ifmt_bra, { 0x40180000 } + }, +/* bno$pack$hint_not_taken */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), OP (HINT_NOT_TAKEN), 0 } }, + & ifmt_bno, { 0x180000 } + }, +/* beq$pack $ICCi_2,$hint,$label16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (HINT), ',', OP (LABEL16), 0 } }, + & ifmt_beq, { 0x20180000 } + }, +/* bne$pack $ICCi_2,$hint,$label16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (HINT), ',', OP (LABEL16), 0 } }, + & ifmt_beq, { 0x60180000 } + }, +/* ble$pack $ICCi_2,$hint,$label16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (HINT), ',', OP (LABEL16), 0 } }, + & ifmt_beq, { 0x38180000 } + }, +/* bgt$pack $ICCi_2,$hint,$label16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (HINT), ',', OP (LABEL16), 0 } }, + & ifmt_beq, { 0x78180000 } + }, +/* blt$pack $ICCi_2,$hint,$label16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (HINT), ',', OP (LABEL16), 0 } }, + & ifmt_beq, { 0x18180000 } + }, +/* bge$pack $ICCi_2,$hint,$label16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (HINT), ',', OP (LABEL16), 0 } }, + & ifmt_beq, { 0x58180000 } + }, +/* bls$pack $ICCi_2,$hint,$label16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (HINT), ',', OP (LABEL16), 0 } }, + & ifmt_beq, { 0x28180000 } + }, +/* bhi$pack $ICCi_2,$hint,$label16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (HINT), ',', OP (LABEL16), 0 } }, + & ifmt_beq, { 0x68180000 } + }, +/* bc$pack $ICCi_2,$hint,$label16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (HINT), ',', OP (LABEL16), 0 } }, + & ifmt_beq, { 0x8180000 } + }, +/* bnc$pack $ICCi_2,$hint,$label16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (HINT), ',', OP (LABEL16), 0 } }, + & ifmt_beq, { 0x48180000 } + }, +/* bn$pack $ICCi_2,$hint,$label16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (HINT), ',', OP (LABEL16), 0 } }, + & ifmt_beq, { 0x30180000 } + }, +/* bp$pack $ICCi_2,$hint,$label16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (HINT), ',', OP (LABEL16), 0 } }, + & ifmt_beq, { 0x70180000 } + }, +/* bv$pack $ICCi_2,$hint,$label16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (HINT), ',', OP (LABEL16), 0 } }, + & ifmt_beq, { 0x10180000 } + }, +/* bnv$pack $ICCi_2,$hint,$label16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (HINT), ',', OP (LABEL16), 0 } }, + & ifmt_beq, { 0x50180000 } + }, +/* fbra$pack $hint_taken$label16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (HINT_TAKEN), OP (LABEL16), 0 } }, + & ifmt_fbra, { 0x781c0000 } + }, +/* fbno$pack$hint_not_taken */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), OP (HINT_NOT_TAKEN), 0 } }, + & ifmt_fbno, { 0x1c0000 } + }, +/* fbne$pack $FCCi_2,$hint,$label16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (HINT), ',', OP (LABEL16), 0 } }, + & ifmt_fbne, { 0x381c0000 } + }, +/* fbeq$pack $FCCi_2,$hint,$label16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (HINT), ',', OP (LABEL16), 0 } }, + & ifmt_fbne, { 0x401c0000 } + }, +/* fblg$pack $FCCi_2,$hint,$label16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (HINT), ',', OP (LABEL16), 0 } }, + & ifmt_fbne, { 0x301c0000 } + }, +/* fbue$pack $FCCi_2,$hint,$label16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (HINT), ',', OP (LABEL16), 0 } }, + & ifmt_fbne, { 0x481c0000 } + }, +/* fbul$pack $FCCi_2,$hint,$label16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (HINT), ',', OP (LABEL16), 0 } }, + & ifmt_fbne, { 0x281c0000 } + }, +/* fbge$pack $FCCi_2,$hint,$label16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (HINT), ',', OP (LABEL16), 0 } }, + & ifmt_fbne, { 0x501c0000 } + }, +/* fblt$pack $FCCi_2,$hint,$label16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (HINT), ',', OP (LABEL16), 0 } }, + & ifmt_fbne, { 0x201c0000 } + }, +/* fbuge$pack $FCCi_2,$hint,$label16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (HINT), ',', OP (LABEL16), 0 } }, + & ifmt_fbne, { 0x581c0000 } + }, +/* fbug$pack $FCCi_2,$hint,$label16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (HINT), ',', OP (LABEL16), 0 } }, + & ifmt_fbne, { 0x181c0000 } + }, +/* fble$pack $FCCi_2,$hint,$label16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (HINT), ',', OP (LABEL16), 0 } }, + & ifmt_fbne, { 0x601c0000 } + }, +/* fbgt$pack $FCCi_2,$hint,$label16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (HINT), ',', OP (LABEL16), 0 } }, + & ifmt_fbne, { 0x101c0000 } + }, +/* fbule$pack $FCCi_2,$hint,$label16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (HINT), ',', OP (LABEL16), 0 } }, + & ifmt_fbne, { 0x681c0000 } + }, +/* fbu$pack $FCCi_2,$hint,$label16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (HINT), ',', OP (LABEL16), 0 } }, + & ifmt_fbne, { 0x81c0000 } + }, +/* fbo$pack $FCCi_2,$hint,$label16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (HINT), ',', OP (LABEL16), 0 } }, + & ifmt_fbne, { 0x701c0000 } + }, +/* bctrlr$pack $ccond,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (CCOND), ',', OP (HINT), 0 } }, + & ifmt_bctrlr, { 0x382000 } + }, +/* bralr$pack$hint_taken */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), OP (HINT_TAKEN), 0 } }, + & ifmt_bralr, { 0x40384000 } + }, +/* bnolr$pack$hint_not_taken */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), OP (HINT_NOT_TAKEN), 0 } }, + & ifmt_bnolr, { 0x384000 } + }, +/* beqlr$pack $ICCi_2,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (HINT), 0 } }, + & ifmt_beqlr, { 0x20384000 } + }, +/* bnelr$pack $ICCi_2,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (HINT), 0 } }, + & ifmt_beqlr, { 0x60384000 } + }, +/* blelr$pack $ICCi_2,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (HINT), 0 } }, + & ifmt_beqlr, { 0x38384000 } + }, +/* bgtlr$pack $ICCi_2,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (HINT), 0 } }, + & ifmt_beqlr, { 0x78384000 } + }, +/* bltlr$pack $ICCi_2,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (HINT), 0 } }, + & ifmt_beqlr, { 0x18384000 } + }, +/* bgelr$pack $ICCi_2,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (HINT), 0 } }, + & ifmt_beqlr, { 0x58384000 } + }, +/* blslr$pack $ICCi_2,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (HINT), 0 } }, + & ifmt_beqlr, { 0x28384000 } + }, +/* bhilr$pack $ICCi_2,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (HINT), 0 } }, + & ifmt_beqlr, { 0x68384000 } + }, +/* bclr$pack $ICCi_2,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (HINT), 0 } }, + & ifmt_beqlr, { 0x8384000 } + }, +/* bnclr$pack $ICCi_2,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (HINT), 0 } }, + & ifmt_beqlr, { 0x48384000 } + }, +/* bnlr$pack $ICCi_2,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (HINT), 0 } }, + & ifmt_beqlr, { 0x30384000 } + }, +/* bplr$pack $ICCi_2,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (HINT), 0 } }, + & ifmt_beqlr, { 0x70384000 } + }, +/* bvlr$pack $ICCi_2,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (HINT), 0 } }, + & ifmt_beqlr, { 0x10384000 } + }, +/* bnvlr$pack $ICCi_2,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (HINT), 0 } }, + & ifmt_beqlr, { 0x50384000 } + }, +/* fbralr$pack$hint_taken */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), OP (HINT_TAKEN), 0 } }, + & ifmt_fbralr, { 0x7838c000 } + }, +/* fbnolr$pack$hint_not_taken */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), OP (HINT_NOT_TAKEN), 0 } }, + & ifmt_fbnolr, { 0x38c000 } + }, +/* fbeqlr$pack $FCCi_2,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (HINT), 0 } }, + & ifmt_fbeqlr, { 0x4038c000 } + }, +/* fbnelr$pack $FCCi_2,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (HINT), 0 } }, + & ifmt_fbeqlr, { 0x3838c000 } + }, +/* fblglr$pack $FCCi_2,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (HINT), 0 } }, + & ifmt_fbeqlr, { 0x3038c000 } + }, +/* fbuelr$pack $FCCi_2,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (HINT), 0 } }, + & ifmt_fbeqlr, { 0x4838c000 } + }, +/* fbullr$pack $FCCi_2,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (HINT), 0 } }, + & ifmt_fbeqlr, { 0x2838c000 } + }, +/* fbgelr$pack $FCCi_2,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (HINT), 0 } }, + & ifmt_fbeqlr, { 0x5038c000 } + }, +/* fbltlr$pack $FCCi_2,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (HINT), 0 } }, + & ifmt_fbeqlr, { 0x2038c000 } + }, +/* fbugelr$pack $FCCi_2,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (HINT), 0 } }, + & ifmt_fbeqlr, { 0x5838c000 } + }, +/* fbuglr$pack $FCCi_2,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (HINT), 0 } }, + & ifmt_fbeqlr, { 0x1838c000 } + }, +/* fblelr$pack $FCCi_2,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (HINT), 0 } }, + & ifmt_fbeqlr, { 0x6038c000 } + }, +/* fbgtlr$pack $FCCi_2,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (HINT), 0 } }, + & ifmt_fbeqlr, { 0x1038c000 } + }, +/* fbulelr$pack $FCCi_2,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (HINT), 0 } }, + & ifmt_fbeqlr, { 0x6838c000 } + }, +/* fbulr$pack $FCCi_2,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (HINT), 0 } }, + & ifmt_fbeqlr, { 0x838c000 } + }, +/* fbolr$pack $FCCi_2,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (HINT), 0 } }, + & ifmt_fbeqlr, { 0x7038c000 } + }, +/* bcralr$pack $ccond$hint_taken */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (CCOND), OP (HINT_TAKEN), 0 } }, + & ifmt_bcralr, { 0x40386000 } + }, +/* bcnolr$pack$hint_not_taken */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), OP (HINT_NOT_TAKEN), 0 } }, + & ifmt_bnolr, { 0x386000 } + }, +/* bceqlr$pack $ICCi_2,$ccond,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (CCOND), ',', OP (HINT), 0 } }, + & ifmt_bceqlr, { 0x20386000 } + }, +/* bcnelr$pack $ICCi_2,$ccond,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (CCOND), ',', OP (HINT), 0 } }, + & ifmt_bceqlr, { 0x60386000 } + }, +/* bclelr$pack $ICCi_2,$ccond,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (CCOND), ',', OP (HINT), 0 } }, + & ifmt_bceqlr, { 0x38386000 } + }, +/* bcgtlr$pack $ICCi_2,$ccond,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (CCOND), ',', OP (HINT), 0 } }, + & ifmt_bceqlr, { 0x78386000 } + }, +/* bcltlr$pack $ICCi_2,$ccond,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (CCOND), ',', OP (HINT), 0 } }, + & ifmt_bceqlr, { 0x18386000 } + }, +/* bcgelr$pack $ICCi_2,$ccond,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (CCOND), ',', OP (HINT), 0 } }, + & ifmt_bceqlr, { 0x58386000 } + }, +/* bclslr$pack $ICCi_2,$ccond,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (CCOND), ',', OP (HINT), 0 } }, + & ifmt_bceqlr, { 0x28386000 } + }, +/* bchilr$pack $ICCi_2,$ccond,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (CCOND), ',', OP (HINT), 0 } }, + & ifmt_bceqlr, { 0x68386000 } + }, +/* bcclr$pack $ICCi_2,$ccond,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (CCOND), ',', OP (HINT), 0 } }, + & ifmt_bceqlr, { 0x8386000 } + }, +/* bcnclr$pack $ICCi_2,$ccond,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (CCOND), ',', OP (HINT), 0 } }, + & ifmt_bceqlr, { 0x48386000 } + }, +/* bcnlr$pack $ICCi_2,$ccond,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (CCOND), ',', OP (HINT), 0 } }, + & ifmt_bceqlr, { 0x30386000 } + }, +/* bcplr$pack $ICCi_2,$ccond,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (CCOND), ',', OP (HINT), 0 } }, + & ifmt_bceqlr, { 0x70386000 } + }, +/* bcvlr$pack $ICCi_2,$ccond,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (CCOND), ',', OP (HINT), 0 } }, + & ifmt_bceqlr, { 0x10386000 } + }, +/* bcnvlr$pack $ICCi_2,$ccond,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (CCOND), ',', OP (HINT), 0 } }, + & ifmt_bceqlr, { 0x50386000 } + }, +/* fcbralr$pack $ccond$hint_taken */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (CCOND), OP (HINT_TAKEN), 0 } }, + & ifmt_fcbralr, { 0x7838e000 } + }, +/* fcbnolr$pack$hint_not_taken */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), OP (HINT_NOT_TAKEN), 0 } }, + & ifmt_fbnolr, { 0x38e000 } + }, +/* fcbeqlr$pack $FCCi_2,$ccond,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (CCOND), ',', OP (HINT), 0 } }, + & ifmt_fcbeqlr, { 0x4038e000 } + }, +/* fcbnelr$pack $FCCi_2,$ccond,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (CCOND), ',', OP (HINT), 0 } }, + & ifmt_fcbeqlr, { 0x3838e000 } + }, +/* fcblglr$pack $FCCi_2,$ccond,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (CCOND), ',', OP (HINT), 0 } }, + & ifmt_fcbeqlr, { 0x3038e000 } + }, +/* fcbuelr$pack $FCCi_2,$ccond,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (CCOND), ',', OP (HINT), 0 } }, + & ifmt_fcbeqlr, { 0x4838e000 } + }, +/* fcbullr$pack $FCCi_2,$ccond,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (CCOND), ',', OP (HINT), 0 } }, + & ifmt_fcbeqlr, { 0x2838e000 } + }, +/* fcbgelr$pack $FCCi_2,$ccond,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (CCOND), ',', OP (HINT), 0 } }, + & ifmt_fcbeqlr, { 0x5038e000 } + }, +/* fcbltlr$pack $FCCi_2,$ccond,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (CCOND), ',', OP (HINT), 0 } }, + & ifmt_fcbeqlr, { 0x2038e000 } + }, +/* fcbugelr$pack $FCCi_2,$ccond,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (CCOND), ',', OP (HINT), 0 } }, + & ifmt_fcbeqlr, { 0x5838e000 } + }, +/* fcbuglr$pack $FCCi_2,$ccond,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (CCOND), ',', OP (HINT), 0 } }, + & ifmt_fcbeqlr, { 0x1838e000 } + }, +/* fcblelr$pack $FCCi_2,$ccond,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (CCOND), ',', OP (HINT), 0 } }, + & ifmt_fcbeqlr, { 0x6038e000 } + }, +/* fcbgtlr$pack $FCCi_2,$ccond,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (CCOND), ',', OP (HINT), 0 } }, + & ifmt_fcbeqlr, { 0x1038e000 } + }, +/* fcbulelr$pack $FCCi_2,$ccond,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (CCOND), ',', OP (HINT), 0 } }, + & ifmt_fcbeqlr, { 0x6838e000 } + }, +/* fcbulr$pack $FCCi_2,$ccond,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (CCOND), ',', OP (HINT), 0 } }, + & ifmt_fcbeqlr, { 0x838e000 } + }, +/* fcbolr$pack $FCCi_2,$ccond,$hint */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (CCOND), ',', OP (HINT), 0 } }, + & ifmt_fcbeqlr, { 0x7038e000 } + }, +/* jmpl$pack @($GRi,$GRj) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', 0 } }, + & ifmt_jmpl, { 0x300000 } + }, +/* calll$pack @($GRi,$GRj) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', 0 } }, + & ifmt_calll, { 0x2300000 } + }, +/* jmpil$pack @($GRi,$s12) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (S12), ')', 0 } }, + & ifmt_jmpil, { 0x340000 } + }, +/* callil$pack @($GRi,$s12) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (S12), ')', 0 } }, + & ifmt_callil, { 0x2340000 } + }, +/* call$pack $label24 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (LABEL24), 0 } }, + & ifmt_call, { 0x3c0000 } + }, +/* rett$pack $debug */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (DEBUG), 0 } }, + & ifmt_rett, { 0x140000 } + }, +/* rei$pack $eir */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (EIR), 0 } }, + & ifmt_rei, { 0xdc0000 } + }, +/* tra$pack $GRi,$GRj */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), 0 } }, + & ifmt_tra, { 0x40100000 } + }, +/* tno$pack */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), 0 } }, + & ifmt_tno, { 0x100000 } + }, +/* teq$pack $ICCi_2,$GRi,$GRj */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (GRI), ',', OP (GRJ), 0 } }, + & ifmt_teq, { 0x20100000 } + }, +/* tne$pack $ICCi_2,$GRi,$GRj */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (GRI), ',', OP (GRJ), 0 } }, + & ifmt_teq, { 0x60100000 } + }, +/* tle$pack $ICCi_2,$GRi,$GRj */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (GRI), ',', OP (GRJ), 0 } }, + & ifmt_teq, { 0x38100000 } + }, +/* tgt$pack $ICCi_2,$GRi,$GRj */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (GRI), ',', OP (GRJ), 0 } }, + & ifmt_teq, { 0x78100000 } + }, +/* tlt$pack $ICCi_2,$GRi,$GRj */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (GRI), ',', OP (GRJ), 0 } }, + & ifmt_teq, { 0x18100000 } + }, +/* tge$pack $ICCi_2,$GRi,$GRj */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (GRI), ',', OP (GRJ), 0 } }, + & ifmt_teq, { 0x58100000 } + }, +/* tls$pack $ICCi_2,$GRi,$GRj */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (GRI), ',', OP (GRJ), 0 } }, + & ifmt_teq, { 0x28100000 } + }, +/* thi$pack $ICCi_2,$GRi,$GRj */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (GRI), ',', OP (GRJ), 0 } }, + & ifmt_teq, { 0x68100000 } + }, +/* tc$pack $ICCi_2,$GRi,$GRj */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (GRI), ',', OP (GRJ), 0 } }, + & ifmt_teq, { 0x8100000 } + }, +/* tnc$pack $ICCi_2,$GRi,$GRj */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (GRI), ',', OP (GRJ), 0 } }, + & ifmt_teq, { 0x48100000 } + }, +/* tn$pack $ICCi_2,$GRi,$GRj */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (GRI), ',', OP (GRJ), 0 } }, + & ifmt_teq, { 0x30100000 } + }, +/* tp$pack $ICCi_2,$GRi,$GRj */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (GRI), ',', OP (GRJ), 0 } }, + & ifmt_teq, { 0x70100000 } + }, +/* tv$pack $ICCi_2,$GRi,$GRj */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (GRI), ',', OP (GRJ), 0 } }, + & ifmt_teq, { 0x10100000 } + }, +/* tnv$pack $ICCi_2,$GRi,$GRj */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (GRI), ',', OP (GRJ), 0 } }, + & ifmt_teq, { 0x50100000 } + }, +/* ftra$pack $GRi,$GRj */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), 0 } }, + & ifmt_ftra, { 0x78100040 } + }, +/* ftno$pack */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), 0 } }, + & ifmt_ftno, { 0x100040 } + }, +/* ftne$pack $FCCi_2,$GRi,$GRj */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (GRI), ',', OP (GRJ), 0 } }, + & ifmt_ftne, { 0x38100040 } + }, +/* fteq$pack $FCCi_2,$GRi,$GRj */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (GRI), ',', OP (GRJ), 0 } }, + & ifmt_ftne, { 0x40100040 } + }, +/* ftlg$pack $FCCi_2,$GRi,$GRj */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (GRI), ',', OP (GRJ), 0 } }, + & ifmt_ftne, { 0x30100040 } + }, +/* ftue$pack $FCCi_2,$GRi,$GRj */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (GRI), ',', OP (GRJ), 0 } }, + & ifmt_ftne, { 0x48100040 } + }, +/* ftul$pack $FCCi_2,$GRi,$GRj */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (GRI), ',', OP (GRJ), 0 } }, + & ifmt_ftne, { 0x28100040 } + }, +/* ftge$pack $FCCi_2,$GRi,$GRj */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (GRI), ',', OP (GRJ), 0 } }, + & ifmt_ftne, { 0x50100040 } + }, +/* ftlt$pack $FCCi_2,$GRi,$GRj */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (GRI), ',', OP (GRJ), 0 } }, + & ifmt_ftne, { 0x20100040 } + }, +/* ftuge$pack $FCCi_2,$GRi,$GRj */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (GRI), ',', OP (GRJ), 0 } }, + & ifmt_ftne, { 0x58100040 } + }, +/* ftug$pack $FCCi_2,$GRi,$GRj */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (GRI), ',', OP (GRJ), 0 } }, + & ifmt_ftne, { 0x18100040 } + }, +/* ftle$pack $FCCi_2,$GRi,$GRj */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (GRI), ',', OP (GRJ), 0 } }, + & ifmt_ftne, { 0x60100040 } + }, +/* ftgt$pack $FCCi_2,$GRi,$GRj */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (GRI), ',', OP (GRJ), 0 } }, + & ifmt_ftne, { 0x10100040 } + }, +/* ftule$pack $FCCi_2,$GRi,$GRj */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (GRI), ',', OP (GRJ), 0 } }, + & ifmt_ftne, { 0x68100040 } + }, +/* ftu$pack $FCCi_2,$GRi,$GRj */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (GRI), ',', OP (GRJ), 0 } }, + & ifmt_ftne, { 0x8100040 } + }, +/* fto$pack $FCCi_2,$GRi,$GRj */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (GRI), ',', OP (GRJ), 0 } }, + & ifmt_ftne, { 0x70100040 } + }, +/* tira$pack $GRi,$s12 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (S12), 0 } }, + & ifmt_tira, { 0x40700000 } + }, +/* tino$pack */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), 0 } }, + & ifmt_tino, { 0x700000 } + }, +/* tieq$pack $ICCi_2,$GRi,$s12 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (GRI), ',', OP (S12), 0 } }, + & ifmt_tieq, { 0x20700000 } + }, +/* tine$pack $ICCi_2,$GRi,$s12 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (GRI), ',', OP (S12), 0 } }, + & ifmt_tieq, { 0x60700000 } + }, +/* tile$pack $ICCi_2,$GRi,$s12 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (GRI), ',', OP (S12), 0 } }, + & ifmt_tieq, { 0x38700000 } + }, +/* tigt$pack $ICCi_2,$GRi,$s12 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (GRI), ',', OP (S12), 0 } }, + & ifmt_tieq, { 0x78700000 } + }, +/* tilt$pack $ICCi_2,$GRi,$s12 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (GRI), ',', OP (S12), 0 } }, + & ifmt_tieq, { 0x18700000 } + }, +/* tige$pack $ICCi_2,$GRi,$s12 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (GRI), ',', OP (S12), 0 } }, + & ifmt_tieq, { 0x58700000 } + }, +/* tils$pack $ICCi_2,$GRi,$s12 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (GRI), ',', OP (S12), 0 } }, + & ifmt_tieq, { 0x28700000 } + }, +/* tihi$pack $ICCi_2,$GRi,$s12 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (GRI), ',', OP (S12), 0 } }, + & ifmt_tieq, { 0x68700000 } + }, +/* tic$pack $ICCi_2,$GRi,$s12 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (GRI), ',', OP (S12), 0 } }, + & ifmt_tieq, { 0x8700000 } + }, +/* tinc$pack $ICCi_2,$GRi,$s12 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (GRI), ',', OP (S12), 0 } }, + & ifmt_tieq, { 0x48700000 } + }, +/* tin$pack $ICCi_2,$GRi,$s12 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (GRI), ',', OP (S12), 0 } }, + & ifmt_tieq, { 0x30700000 } + }, +/* tip$pack $ICCi_2,$GRi,$s12 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (GRI), ',', OP (S12), 0 } }, + & ifmt_tieq, { 0x70700000 } + }, +/* tiv$pack $ICCi_2,$GRi,$s12 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (GRI), ',', OP (S12), 0 } }, + & ifmt_tieq, { 0x10700000 } + }, +/* tinv$pack $ICCi_2,$GRi,$s12 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_2), ',', OP (GRI), ',', OP (S12), 0 } }, + & ifmt_tieq, { 0x50700000 } + }, +/* ftira$pack $GRi,$s12 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (S12), 0 } }, + & ifmt_ftira, { 0x78740000 } + }, +/* ftino$pack */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), 0 } }, + & ifmt_ftino, { 0x740000 } + }, +/* ftine$pack $FCCi_2,$GRi,$s12 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (GRI), ',', OP (S12), 0 } }, + & ifmt_ftine, { 0x38740000 } + }, +/* ftieq$pack $FCCi_2,$GRi,$s12 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (GRI), ',', OP (S12), 0 } }, + & ifmt_ftine, { 0x40740000 } + }, +/* ftilg$pack $FCCi_2,$GRi,$s12 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (GRI), ',', OP (S12), 0 } }, + & ifmt_ftine, { 0x30740000 } + }, +/* ftiue$pack $FCCi_2,$GRi,$s12 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (GRI), ',', OP (S12), 0 } }, + & ifmt_ftine, { 0x48740000 } + }, +/* ftiul$pack $FCCi_2,$GRi,$s12 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (GRI), ',', OP (S12), 0 } }, + & ifmt_ftine, { 0x28740000 } + }, +/* ftige$pack $FCCi_2,$GRi,$s12 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (GRI), ',', OP (S12), 0 } }, + & ifmt_ftine, { 0x50740000 } + }, +/* ftilt$pack $FCCi_2,$GRi,$s12 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (GRI), ',', OP (S12), 0 } }, + & ifmt_ftine, { 0x20740000 } + }, +/* ftiuge$pack $FCCi_2,$GRi,$s12 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (GRI), ',', OP (S12), 0 } }, + & ifmt_ftine, { 0x58740000 } + }, +/* ftiug$pack $FCCi_2,$GRi,$s12 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (GRI), ',', OP (S12), 0 } }, + & ifmt_ftine, { 0x18740000 } + }, +/* ftile$pack $FCCi_2,$GRi,$s12 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (GRI), ',', OP (S12), 0 } }, + & ifmt_ftine, { 0x60740000 } + }, +/* ftigt$pack $FCCi_2,$GRi,$s12 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (GRI), ',', OP (S12), 0 } }, + & ifmt_ftine, { 0x10740000 } + }, +/* ftiule$pack $FCCi_2,$GRi,$s12 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (GRI), ',', OP (S12), 0 } }, + & ifmt_ftine, { 0x68740000 } + }, +/* ftiu$pack $FCCi_2,$GRi,$s12 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (GRI), ',', OP (S12), 0 } }, + & ifmt_ftine, { 0x8740000 } + }, +/* ftio$pack $FCCi_2,$GRi,$s12 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_2), ',', OP (GRI), ',', OP (S12), 0 } }, + & ifmt_ftine, { 0x70740000 } + }, +/* break$pack */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), 0 } }, + & ifmt_break, { 0x1000c0 } + }, +/* mtrap$pack */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), 0 } }, + & ifmt_break, { 0x100080 } + }, +/* andcr$pack $CRi,$CRj,$CRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (CRI), ',', OP (CRJ), ',', OP (CRK), 0 } }, + & ifmt_andcr, { 0x280200 } + }, +/* orcr$pack $CRi,$CRj,$CRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (CRI), ',', OP (CRJ), ',', OP (CRK), 0 } }, + & ifmt_andcr, { 0x280240 } + }, +/* xorcr$pack $CRi,$CRj,$CRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (CRI), ',', OP (CRJ), ',', OP (CRK), 0 } }, + & ifmt_andcr, { 0x280280 } + }, +/* nandcr$pack $CRi,$CRj,$CRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (CRI), ',', OP (CRJ), ',', OP (CRK), 0 } }, + & ifmt_andcr, { 0x280300 } + }, +/* norcr$pack $CRi,$CRj,$CRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (CRI), ',', OP (CRJ), ',', OP (CRK), 0 } }, + & ifmt_andcr, { 0x280340 } + }, +/* andncr$pack $CRi,$CRj,$CRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (CRI), ',', OP (CRJ), ',', OP (CRK), 0 } }, + & ifmt_andcr, { 0x280400 } + }, +/* orncr$pack $CRi,$CRj,$CRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (CRI), ',', OP (CRJ), ',', OP (CRK), 0 } }, + & ifmt_andcr, { 0x280440 } + }, +/* nandncr$pack $CRi,$CRj,$CRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (CRI), ',', OP (CRJ), ',', OP (CRK), 0 } }, + & ifmt_andcr, { 0x280500 } + }, +/* norncr$pack $CRi,$CRj,$CRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (CRI), ',', OP (CRJ), ',', OP (CRK), 0 } }, + & ifmt_andcr, { 0x280540 } + }, +/* notcr$pack $CRj,$CRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (CRJ), ',', OP (CRK), 0 } }, + & ifmt_notcr, { 0x2802c0 } + }, +/* ckra$pack $CRj_int */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (CRJ_INT), 0 } }, + & ifmt_ckra, { 0x40200000 } + }, +/* ckno$pack $CRj_int */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (CRJ_INT), 0 } }, + & ifmt_ckra, { 0x200000 } + }, +/* ckeq$pack $ICCi_3,$CRj_int */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_3), ',', OP (CRJ_INT), 0 } }, + & ifmt_ckeq, { 0x20200000 } + }, +/* ckne$pack $ICCi_3,$CRj_int */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_3), ',', OP (CRJ_INT), 0 } }, + & ifmt_ckeq, { 0x60200000 } + }, +/* ckle$pack $ICCi_3,$CRj_int */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_3), ',', OP (CRJ_INT), 0 } }, + & ifmt_ckeq, { 0x38200000 } + }, +/* ckgt$pack $ICCi_3,$CRj_int */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_3), ',', OP (CRJ_INT), 0 } }, + & ifmt_ckeq, { 0x78200000 } + }, +/* cklt$pack $ICCi_3,$CRj_int */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_3), ',', OP (CRJ_INT), 0 } }, + & ifmt_ckeq, { 0x18200000 } + }, +/* ckge$pack $ICCi_3,$CRj_int */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_3), ',', OP (CRJ_INT), 0 } }, + & ifmt_ckeq, { 0x58200000 } + }, +/* ckls$pack $ICCi_3,$CRj_int */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_3), ',', OP (CRJ_INT), 0 } }, + & ifmt_ckeq, { 0x28200000 } + }, +/* ckhi$pack $ICCi_3,$CRj_int */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_3), ',', OP (CRJ_INT), 0 } }, + & ifmt_ckeq, { 0x68200000 } + }, +/* ckc$pack $ICCi_3,$CRj_int */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_3), ',', OP (CRJ_INT), 0 } }, + & ifmt_ckeq, { 0x8200000 } + }, +/* cknc$pack $ICCi_3,$CRj_int */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_3), ',', OP (CRJ_INT), 0 } }, + & ifmt_ckeq, { 0x48200000 } + }, +/* ckn$pack $ICCi_3,$CRj_int */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_3), ',', OP (CRJ_INT), 0 } }, + & ifmt_ckeq, { 0x30200000 } + }, +/* ckp$pack $ICCi_3,$CRj_int */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_3), ',', OP (CRJ_INT), 0 } }, + & ifmt_ckeq, { 0x70200000 } + }, +/* ckv$pack $ICCi_3,$CRj_int */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_3), ',', OP (CRJ_INT), 0 } }, + & ifmt_ckeq, { 0x10200000 } + }, +/* cknv$pack $ICCi_3,$CRj_int */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_3), ',', OP (CRJ_INT), 0 } }, + & ifmt_ckeq, { 0x50200000 } + }, +/* fckra$pack $CRj_float */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (CRJ_FLOAT), 0 } }, + & ifmt_fckra, { 0x78240000 } + }, +/* fckno$pack $CRj_float */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (CRJ_FLOAT), 0 } }, + & ifmt_fckra, { 0x240000 } + }, +/* fckne$pack $FCCi_3,$CRj_float */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_3), ',', OP (CRJ_FLOAT), 0 } }, + & ifmt_fckra, { 0x38240000 } + }, +/* fckeq$pack $FCCi_3,$CRj_float */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_3), ',', OP (CRJ_FLOAT), 0 } }, + & ifmt_fckra, { 0x40240000 } + }, +/* fcklg$pack $FCCi_3,$CRj_float */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_3), ',', OP (CRJ_FLOAT), 0 } }, + & ifmt_fckra, { 0x30240000 } + }, +/* fckue$pack $FCCi_3,$CRj_float */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_3), ',', OP (CRJ_FLOAT), 0 } }, + & ifmt_fckra, { 0x48240000 } + }, +/* fckul$pack $FCCi_3,$CRj_float */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_3), ',', OP (CRJ_FLOAT), 0 } }, + & ifmt_fckra, { 0x28240000 } + }, +/* fckge$pack $FCCi_3,$CRj_float */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_3), ',', OP (CRJ_FLOAT), 0 } }, + & ifmt_fckra, { 0x50240000 } + }, +/* fcklt$pack $FCCi_3,$CRj_float */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_3), ',', OP (CRJ_FLOAT), 0 } }, + & ifmt_fckra, { 0x20240000 } + }, +/* fckuge$pack $FCCi_3,$CRj_float */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_3), ',', OP (CRJ_FLOAT), 0 } }, + & ifmt_fckra, { 0x58240000 } + }, +/* fckug$pack $FCCi_3,$CRj_float */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_3), ',', OP (CRJ_FLOAT), 0 } }, + & ifmt_fckra, { 0x18240000 } + }, +/* fckle$pack $FCCi_3,$CRj_float */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_3), ',', OP (CRJ_FLOAT), 0 } }, + & ifmt_fckra, { 0x60240000 } + }, +/* fckgt$pack $FCCi_3,$CRj_float */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_3), ',', OP (CRJ_FLOAT), 0 } }, + & ifmt_fckra, { 0x10240000 } + }, +/* fckule$pack $FCCi_3,$CRj_float */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_3), ',', OP (CRJ_FLOAT), 0 } }, + & ifmt_fckra, { 0x68240000 } + }, +/* fcku$pack $FCCi_3,$CRj_float */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_3), ',', OP (CRJ_FLOAT), 0 } }, + & ifmt_fckra, { 0x8240000 } + }, +/* fcko$pack $FCCi_3,$CRj_float */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_3), ',', OP (CRJ_FLOAT), 0 } }, + & ifmt_fckra, { 0x70240000 } + }, +/* cckra$pack $CRj_int,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (CRJ_INT), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cckra, { 0x41a80000 } + }, +/* cckno$pack $CRj_int,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (CRJ_INT), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cckra, { 0x1a80000 } + }, +/* cckeq$pack $ICCi_3,$CRj_int,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_3), ',', OP (CRJ_INT), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cckeq, { 0x21a80000 } + }, +/* cckne$pack $ICCi_3,$CRj_int,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_3), ',', OP (CRJ_INT), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cckeq, { 0x61a80000 } + }, +/* cckle$pack $ICCi_3,$CRj_int,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_3), ',', OP (CRJ_INT), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cckeq, { 0x39a80000 } + }, +/* cckgt$pack $ICCi_3,$CRj_int,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_3), ',', OP (CRJ_INT), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cckeq, { 0x79a80000 } + }, +/* ccklt$pack $ICCi_3,$CRj_int,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_3), ',', OP (CRJ_INT), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cckeq, { 0x19a80000 } + }, +/* cckge$pack $ICCi_3,$CRj_int,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_3), ',', OP (CRJ_INT), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cckeq, { 0x59a80000 } + }, +/* cckls$pack $ICCi_3,$CRj_int,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_3), ',', OP (CRJ_INT), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cckeq, { 0x29a80000 } + }, +/* cckhi$pack $ICCi_3,$CRj_int,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_3), ',', OP (CRJ_INT), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cckeq, { 0x69a80000 } + }, +/* cckc$pack $ICCi_3,$CRj_int,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_3), ',', OP (CRJ_INT), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cckeq, { 0x9a80000 } + }, +/* ccknc$pack $ICCi_3,$CRj_int,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_3), ',', OP (CRJ_INT), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cckeq, { 0x49a80000 } + }, +/* cckn$pack $ICCi_3,$CRj_int,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_3), ',', OP (CRJ_INT), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cckeq, { 0x31a80000 } + }, +/* cckp$pack $ICCi_3,$CRj_int,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_3), ',', OP (CRJ_INT), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cckeq, { 0x71a80000 } + }, +/* cckv$pack $ICCi_3,$CRj_int,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_3), ',', OP (CRJ_INT), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cckeq, { 0x11a80000 } + }, +/* ccknv$pack $ICCi_3,$CRj_int,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ICCI_3), ',', OP (CRJ_INT), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cckeq, { 0x51a80000 } + }, +/* cfckra$pack $CRj_float,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (CRJ_FLOAT), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cfckra, { 0x79a80040 } + }, +/* cfckno$pack $CRj_float,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (CRJ_FLOAT), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cfckra, { 0x1a80040 } + }, +/* cfckne$pack $FCCi_3,$CRj_float,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_3), ',', OP (CRJ_FLOAT), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cfckne, { 0x39a80040 } + }, +/* cfckeq$pack $FCCi_3,$CRj_float,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_3), ',', OP (CRJ_FLOAT), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cfckne, { 0x41a80040 } + }, +/* cfcklg$pack $FCCi_3,$CRj_float,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_3), ',', OP (CRJ_FLOAT), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cfckne, { 0x31a80040 } + }, +/* cfckue$pack $FCCi_3,$CRj_float,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_3), ',', OP (CRJ_FLOAT), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cfckne, { 0x49a80040 } + }, +/* cfckul$pack $FCCi_3,$CRj_float,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_3), ',', OP (CRJ_FLOAT), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cfckne, { 0x29a80040 } + }, +/* cfckge$pack $FCCi_3,$CRj_float,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_3), ',', OP (CRJ_FLOAT), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cfckne, { 0x51a80040 } + }, +/* cfcklt$pack $FCCi_3,$CRj_float,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_3), ',', OP (CRJ_FLOAT), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cfckne, { 0x21a80040 } + }, +/* cfckuge$pack $FCCi_3,$CRj_float,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_3), ',', OP (CRJ_FLOAT), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cfckne, { 0x59a80040 } + }, +/* cfckug$pack $FCCi_3,$CRj_float,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_3), ',', OP (CRJ_FLOAT), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cfckne, { 0x19a80040 } + }, +/* cfckle$pack $FCCi_3,$CRj_float,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_3), ',', OP (CRJ_FLOAT), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cfckne, { 0x61a80040 } + }, +/* cfckgt$pack $FCCi_3,$CRj_float,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_3), ',', OP (CRJ_FLOAT), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cfckne, { 0x11a80040 } + }, +/* cfckule$pack $FCCi_3,$CRj_float,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_3), ',', OP (CRJ_FLOAT), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cfckne, { 0x69a80040 } + }, +/* cfcku$pack $FCCi_3,$CRj_float,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_3), ',', OP (CRJ_FLOAT), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cfckne, { 0x9a80040 } + }, +/* cfcko$pack $FCCi_3,$CRj_float,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FCCI_3), ',', OP (CRJ_FLOAT), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cfckne, { 0x71a80040 } + }, +/* cjmpl$pack @($GRi,$GRj),$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cjmpl, { 0x1a80080 } + }, +/* ccalll$pack @($GRi,$GRj),$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_ccalll, { 0x3a80080 } + }, +/* ici$pack @($GRi,$GRj) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', 0 } }, + & ifmt_ici, { 0xc0e00 } + }, +/* dci$pack @($GRi,$GRj) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', 0 } }, + & ifmt_ici, { 0xc0f00 } + }, +/* icei$pack @($GRi,$GRj),$ae */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (AE), 0 } }, + & ifmt_icei, { 0xc0e40 } + }, +/* dcei$pack @($GRi,$GRj),$ae */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (AE), 0 } }, + & ifmt_icei, { 0xc0e80 } + }, +/* dcf$pack @($GRi,$GRj) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', 0 } }, + & ifmt_ici, { 0xc0f40 } + }, +/* dcef$pack @($GRi,$GRj),$ae */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', ',', OP (AE), 0 } }, + & ifmt_icei, { 0xc0ec0 } + }, +/* witlb$pack $GRk,@($GRi,$GRj) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', 0 } }, + & ifmt_ldsb, { 0xc0c80 } + }, +/* wdtlb$pack $GRk,@($GRi,$GRj) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRK), ',', '@', '(', OP (GRI), ',', OP (GRJ), ')', 0 } }, + & ifmt_ldsb, { 0xc0d80 } + }, +/* itlbi$pack @($GRi,$GRj) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', 0 } }, + & ifmt_ici, { 0xc0cc0 } + }, +/* dtlbi$pack @($GRi,$GRj) */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', '@', '(', OP (GRI), ',', OP (GRJ), ')', 0 } }, + & ifmt_ici, { 0xc0dc0 } + }, +/* icpl$pack $GRi,$GRj,$lock */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (LOCK), 0 } }, + & ifmt_icpl, { 0xc0c00 } + }, +/* dcpl$pack $GRi,$GRj,$lock */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), ',', OP (GRJ), ',', OP (LOCK), 0 } }, + & ifmt_icpl, { 0xc0d00 } + }, +/* icul$pack $GRi */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), 0 } }, + & ifmt_icul, { 0xc0c40 } + }, +/* dcul$pack $GRi */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRI), 0 } }, + & ifmt_icul, { 0xc0d40 } + }, +/* bar$pack */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), 0 } }, + & ifmt_bar, { 0xc0f80 } + }, +/* membar$pack */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), 0 } }, + & ifmt_bar, { 0xc0fc0 } + }, +/* cop1$pack $s6_1,$CPRi,$CPRj,$CPRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (S6_1), ',', OP (CPRI), ',', OP (CPRJ), ',', OP (CPRK), 0 } }, + & ifmt_cop1, { 0x1f80000 } + }, +/* cop2$pack $s6_1,$CPRi,$CPRj,$CPRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (S6_1), ',', OP (CPRI), ',', OP (CPRJ), ',', OP (CPRK), 0 } }, + & ifmt_cop1, { 0x1fc0000 } + }, +/* clrgr$pack $GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRK), 0 } }, + & ifmt_clrgr, { 0x280000 } + }, +/* clrfr$pack $FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRK), 0 } }, + & ifmt_clrfr, { 0x280080 } + }, +/* clrga$pack */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), 0 } }, + & ifmt_bar, { 0x280040 } + }, +/* clrfa$pack */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), 0 } }, + & ifmt_bar, { 0x2800c0 } + }, +/* commitgr$pack $GRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (GRK), 0 } }, + & ifmt_clrgr, { 0x280100 } + }, +/* commitfr$pack $FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRK), 0 } }, + & ifmt_clrfr, { 0x280180 } + }, +/* commitga$pack */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), 0 } }, + & ifmt_bar, { 0x280140 } + }, +/* commitfa$pack */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), 0 } }, + & ifmt_bar, { 0x2801c0 } + }, +/* fitos$pack $FRintj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTJ), ',', OP (FRK), 0 } }, + & ifmt_fitos, { 0x1e40000 } + }, +/* fstoi$pack $FRj,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRJ), ',', OP (FRINTK), 0 } }, + & ifmt_fstoi, { 0x1e40040 } + }, +/* fitod$pack $FRintj,$FRdoublek */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTJ), ',', OP (FRDOUBLEK), 0 } }, + & ifmt_fitod, { 0x1e80000 } + }, +/* fdtoi$pack $FRdoublej,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRDOUBLEJ), ',', OP (FRINTK), 0 } }, + & ifmt_fdtoi, { 0x1e80040 } + }, +/* fditos$pack $FRintj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTJ), ',', OP (FRK), 0 } }, + & ifmt_fitos, { 0x1e40400 } + }, +/* fdstoi$pack $FRj,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRJ), ',', OP (FRINTK), 0 } }, + & ifmt_fstoi, { 0x1e40440 } + }, +/* nfditos$pack $FRintj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTJ), ',', OP (FRK), 0 } }, + & ifmt_fitos, { 0x1e40c00 } + }, +/* nfdstoi$pack $FRj,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRJ), ',', OP (FRINTK), 0 } }, + & ifmt_fstoi, { 0x1e40c40 } + }, +/* cfitos$pack $FRintj,$FRk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTJ), ',', OP (FRK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cfitos, { 0x1ac0000 } + }, +/* cfstoi$pack $FRj,$FRintk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRJ), ',', OP (FRINTK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cfstoi, { 0x1ac0040 } + }, +/* nfitos$pack $FRintj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTJ), ',', OP (FRK), 0 } }, + & ifmt_fitos, { 0x1e40800 } + }, +/* nfstoi$pack $FRj,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRJ), ',', OP (FRINTK), 0 } }, + & ifmt_fstoi, { 0x1e40840 } + }, +/* fmovs$pack $FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fmovs, { 0x1e40080 } + }, +/* fmovd$pack $FRdoublej,$FRdoublek */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRDOUBLEJ), ',', OP (FRDOUBLEK), 0 } }, + & ifmt_fmovd, { 0x1e80080 } + }, +/* fdmovs$pack $FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fmovs, { 0x1e40480 } + }, +/* cfmovs$pack $FRj,$FRk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRJ), ',', OP (FRK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cfmovs, { 0x1b00000 } + }, +/* fnegs$pack $FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fmovs, { 0x1e400c0 } + }, +/* fnegd$pack $FRdoublej,$FRdoublek */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRDOUBLEJ), ',', OP (FRDOUBLEK), 0 } }, + & ifmt_fmovd, { 0x1e800c0 } + }, +/* fdnegs$pack $FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fmovs, { 0x1e404c0 } + }, +/* cfnegs$pack $FRj,$FRk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRJ), ',', OP (FRK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cfmovs, { 0x1b00040 } + }, +/* fabss$pack $FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fmovs, { 0x1e40100 } + }, +/* fabsd$pack $FRdoublej,$FRdoublek */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRDOUBLEJ), ',', OP (FRDOUBLEK), 0 } }, + & ifmt_fmovd, { 0x1e80100 } + }, +/* fdabss$pack $FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fmovs, { 0x1e40500 } + }, +/* cfabss$pack $FRj,$FRk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRJ), ',', OP (FRK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cfmovs, { 0x1b00080 } + }, +/* fsqrts$pack $FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fmovs, { 0x1e40140 } + }, +/* fdsqrts$pack $FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fmovs, { 0x1e40540 } + }, +/* nfdsqrts$pack $FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fmovs, { 0x1e40d40 } + }, +/* fsqrtd$pack $FRdoublej,$FRdoublek */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRDOUBLEJ), ',', OP (FRDOUBLEK), 0 } }, + & ifmt_fmovd, { 0x1e80140 } + }, +/* cfsqrts$pack $FRj,$FRk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRJ), ',', OP (FRK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cfmovs, { 0x1b80080 } + }, +/* nfsqrts$pack $FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fmovs, { 0x1e40940 } + }, +/* fadds$pack $FRi,$FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fadds, { 0x1e40180 } + }, +/* fsubs$pack $FRi,$FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fadds, { 0x1e401c0 } + }, +/* fmuls$pack $FRi,$FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fadds, { 0x1e40200 } + }, +/* fdivs$pack $FRi,$FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fadds, { 0x1e40240 } + }, +/* faddd$pack $FRdoublei,$FRdoublej,$FRdoublek */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRDOUBLEI), ',', OP (FRDOUBLEJ), ',', OP (FRDOUBLEK), 0 } }, + & ifmt_faddd, { 0x1e80180 } + }, +/* fsubd$pack $FRdoublei,$FRdoublej,$FRdoublek */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRDOUBLEI), ',', OP (FRDOUBLEJ), ',', OP (FRDOUBLEK), 0 } }, + & ifmt_faddd, { 0x1e801c0 } + }, +/* fmuld$pack $FRdoublei,$FRdoublej,$FRdoublek */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRDOUBLEI), ',', OP (FRDOUBLEJ), ',', OP (FRDOUBLEK), 0 } }, + & ifmt_faddd, { 0x1e80200 } + }, +/* fdivd$pack $FRdoublei,$FRdoublej,$FRdoublek */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRDOUBLEI), ',', OP (FRDOUBLEJ), ',', OP (FRDOUBLEK), 0 } }, + & ifmt_faddd, { 0x1e80240 } + }, +/* cfadds$pack $FRi,$FRj,$FRk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FRK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cfadds, { 0x1b40000 } + }, +/* cfsubs$pack $FRi,$FRj,$FRk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FRK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cfadds, { 0x1b40040 } + }, +/* cfmuls$pack $FRi,$FRj,$FRk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FRK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cfadds, { 0x1b80000 } + }, +/* cfdivs$pack $FRi,$FRj,$FRk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FRK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cfadds, { 0x1b80040 } + }, +/* nfadds$pack $FRi,$FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fadds, { 0x1e40980 } + }, +/* nfsubs$pack $FRi,$FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fadds, { 0x1e409c0 } + }, +/* nfmuls$pack $FRi,$FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fadds, { 0x1e40a00 } + }, +/* nfdivs$pack $FRi,$FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fadds, { 0x1e40a40 } + }, +/* fcmps$pack $FRi,$FRj,$FCCi_2 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FCCI_2), 0 } }, + & ifmt_fcmps, { 0x1e40280 } + }, +/* fcmpd$pack $FRdoublei,$FRdoublej,$FCCi_2 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRDOUBLEI), ',', OP (FRDOUBLEJ), ',', OP (FCCI_2), 0 } }, + & ifmt_fcmpd, { 0x1e80280 } + }, +/* cfcmps$pack $FRi,$FRj,$FCCi_2,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FCCI_2), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cfcmps, { 0x1b40080 } + }, +/* fdcmps$pack $FRi,$FRj,$FCCi_2 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FCCI_2), 0 } }, + & ifmt_fcmps, { 0x1e40680 } + }, +/* fmadds$pack $FRi,$FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fadds, { 0x1e402c0 } + }, +/* fmsubs$pack $FRi,$FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fadds, { 0x1e40300 } + }, +/* fmaddd$pack $FRdoublei,$FRdoublej,$FRdoublek */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRDOUBLEI), ',', OP (FRDOUBLEJ), ',', OP (FRDOUBLEK), 0 } }, + & ifmt_faddd, { 0x1e802c0 } + }, +/* fmsubd$pack $FRdoublei,$FRdoublej,$FRdoublek */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRDOUBLEI), ',', OP (FRDOUBLEJ), ',', OP (FRDOUBLEK), 0 } }, + & ifmt_faddd, { 0x1e80300 } + }, +/* fdmadds$pack $FRi,$FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fadds, { 0x1e406c0 } + }, +/* nfdmadds$pack $FRi,$FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fadds, { 0x1e40ec0 } + }, +/* cfmadds$pack $FRi,$FRj,$FRk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FRK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cfadds, { 0x1bc0000 } + }, +/* cfmsubs$pack $FRi,$FRj,$FRk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FRK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cfadds, { 0x1bc0040 } + }, +/* nfmadds$pack $FRi,$FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fadds, { 0x1e40ac0 } + }, +/* nfmsubs$pack $FRi,$FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fadds, { 0x1e40b00 } + }, +/* fmas$pack $FRi,$FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fadds, { 0x1e40380 } + }, +/* fmss$pack $FRi,$FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fadds, { 0x1e403c0 } + }, +/* fdmas$pack $FRi,$FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fadds, { 0x1e40700 } + }, +/* fdmss$pack $FRi,$FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fadds, { 0x1e40740 } + }, +/* nfdmas$pack $FRi,$FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fadds, { 0x1e40f00 } + }, +/* nfdmss$pack $FRi,$FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fadds, { 0x1e40f40 } + }, +/* cfmas$pack $FRi,$FRj,$FRk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FRK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cfadds, { 0x1bc0080 } + }, +/* cfmss$pack $FRi,$FRj,$FRk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FRK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cfadds, { 0x1bc00c0 } + }, +/* fmad$pack $FRi,$FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fadds, { 0x1e80380 } + }, +/* fmsd$pack $FRi,$FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fadds, { 0x1e803c0 } + }, +/* nfmas$pack $FRi,$FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fadds, { 0x1e40b80 } + }, +/* nfmss$pack $FRi,$FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fadds, { 0x1e40bc0 } + }, +/* fdadds$pack $FRi,$FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fadds, { 0x1e40580 } + }, +/* fdsubs$pack $FRi,$FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fadds, { 0x1e405c0 } + }, +/* fdmuls$pack $FRi,$FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fadds, { 0x1e40600 } + }, +/* fddivs$pack $FRi,$FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fadds, { 0x1e40640 } + }, +/* fdsads$pack $FRi,$FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fadds, { 0x1e40780 } + }, +/* fdmulcs$pack $FRi,$FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fadds, { 0x1e407c0 } + }, +/* nfdmulcs$pack $FRi,$FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fadds, { 0x1e40fc0 } + }, +/* nfdadds$pack $FRi,$FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fadds, { 0x1e40d80 } + }, +/* nfdsubs$pack $FRi,$FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fadds, { 0x1e40dc0 } + }, +/* nfdmuls$pack $FRi,$FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fadds, { 0x1e40e00 } + }, +/* nfddivs$pack $FRi,$FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fadds, { 0x1e40e40 } + }, +/* nfdsads$pack $FRi,$FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fadds, { 0x1e40f80 } + }, +/* nfdcmps$pack $FRi,$FRj,$FCCi_2 */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FCCI_2), 0 } }, + & ifmt_fcmps, { 0x1e40e80 } + }, +/* mhsetlos$pack $u12,$FRklo */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (U12), ',', OP (FRKLO), 0 } }, + & ifmt_mhsetlos, { 0x1e00800 } + }, +/* mhsethis$pack $u12,$FRkhi */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (U12), ',', OP (FRKHI), 0 } }, + & ifmt_mhsethis, { 0x1e00880 } + }, +/* mhdsets$pack $u12,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (U12), ',', OP (FRINTK), 0 } }, + & ifmt_mhdsets, { 0x1e00900 } + }, +/* mhsetloh$pack $s5,$FRklo */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (S5), ',', OP (FRKLO), 0 } }, + & ifmt_mhsetloh, { 0x1e00840 } + }, +/* mhsethih$pack $s5,$FRkhi */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (S5), ',', OP (FRKHI), 0 } }, + & ifmt_mhsethih, { 0x1e008c0 } + }, +/* mhdseth$pack $s5,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (S5), ',', OP (FRINTK), 0 } }, + & ifmt_mhdseth, { 0x1e00940 } + }, +/* mand$pack $FRinti,$FRintj,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (FRINTK), 0 } }, + & ifmt_mand, { 0x1ec0000 } + }, +/* mor$pack $FRinti,$FRintj,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (FRINTK), 0 } }, + & ifmt_mand, { 0x1ec0040 } + }, +/* mxor$pack $FRinti,$FRintj,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (FRINTK), 0 } }, + & ifmt_mand, { 0x1ec0080 } + }, +/* cmand$pack $FRinti,$FRintj,$FRintk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (FRINTK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cmand, { 0x1c00000 } + }, +/* cmor$pack $FRinti,$FRintj,$FRintk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (FRINTK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cmand, { 0x1c00040 } + }, +/* cmxor$pack $FRinti,$FRintj,$FRintk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (FRINTK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cmand, { 0x1c00080 } + }, +/* mnot$pack $FRintj,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTJ), ',', OP (FRINTK), 0 } }, + & ifmt_mnot, { 0x1ec00c0 } + }, +/* cmnot$pack $FRintj,$FRintk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTJ), ',', OP (FRINTK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cmnot, { 0x1c000c0 } + }, +/* mrotli$pack $FRinti,$u6,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (U6), ',', OP (FRINTK), 0 } }, + & ifmt_mrotli, { 0x1ec0100 } + }, +/* mrotri$pack $FRinti,$u6,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (U6), ',', OP (FRINTK), 0 } }, + & ifmt_mrotli, { 0x1ec0140 } + }, +/* mwcut$pack $FRinti,$FRintj,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (FRINTK), 0 } }, + & ifmt_mand, { 0x1ec0180 } + }, +/* mwcuti$pack $FRinti,$u6,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (U6), ',', OP (FRINTK), 0 } }, + & ifmt_mrotli, { 0x1ec01c0 } + }, +/* mcut$pack $ACC40Si,$FRintj,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ACC40SI), ',', OP (FRINTJ), ',', OP (FRINTK), 0 } }, + & ifmt_mcut, { 0x1ec0b00 } + }, +/* mcuti$pack $ACC40Si,$s6,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ACC40SI), ',', OP (S6), ',', OP (FRINTK), 0 } }, + & ifmt_mcuti, { 0x1ec0b80 } + }, +/* mcutss$pack $ACC40Si,$FRintj,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ACC40SI), ',', OP (FRINTJ), ',', OP (FRINTK), 0 } }, + & ifmt_mcut, { 0x1ec0b40 } + }, +/* mcutssi$pack $ACC40Si,$s6,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ACC40SI), ',', OP (S6), ',', OP (FRINTK), 0 } }, + & ifmt_mcuti, { 0x1ec0bc0 } + }, +/* mdcutssi$pack $ACC40Si,$s6,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ACC40SI), ',', OP (S6), ',', OP (FRINTK), 0 } }, + & ifmt_mcuti, { 0x1e00380 } + }, +/* maveh$pack $FRinti,$FRintj,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (FRINTK), 0 } }, + & ifmt_mand, { 0x1ec0200 } + }, +/* msllhi$pack $FRinti,$u6,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (U6), ',', OP (FRINTK), 0 } }, + & ifmt_mrotli, { 0x1ec0240 } + }, +/* msrlhi$pack $FRinti,$u6,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (U6), ',', OP (FRINTK), 0 } }, + & ifmt_mrotli, { 0x1ec0280 } + }, +/* msrahi$pack $FRinti,$u6,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (U6), ',', OP (FRINTK), 0 } }, + & ifmt_mrotli, { 0x1ec02c0 } + }, +/* mdrotli$pack $FRinti,$u6,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (U6), ',', OP (FRINTK), 0 } }, + & ifmt_mrotli, { 0x1e002c0 } + }, +/* mcplhi$pack $FRinti,$u6,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (U6), ',', OP (FRINTK), 0 } }, + & ifmt_mrotli, { 0x1e00300 } + }, +/* mcpli$pack $FRinti,$u6,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (U6), ',', OP (FRINTK), 0 } }, + & ifmt_mrotli, { 0x1e00340 } + }, +/* msaths$pack $FRinti,$FRintj,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (FRINTK), 0 } }, + & ifmt_mand, { 0x1ec0300 } + }, +/* mqsaths$pack $FRinti,$FRintj,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (FRINTK), 0 } }, + & ifmt_mand, { 0x1e003c0 } + }, +/* msathu$pack $FRinti,$FRintj,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (FRINTK), 0 } }, + & ifmt_mand, { 0x1ec0340 } + }, +/* mcmpsh$pack $FRinti,$FRintj,$FCCk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (FCCK), 0 } }, + & ifmt_mcmpsh, { 0x1ec0380 } + }, +/* mcmpuh$pack $FRinti,$FRintj,$FCCk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (FCCK), 0 } }, + & ifmt_mcmpsh, { 0x1ec03c0 } + }, +/* mabshs$pack $FRintj,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTJ), ',', OP (FRINTK), 0 } }, + & ifmt_mabshs, { 0x1e00280 } + }, +/* maddhss$pack $FRinti,$FRintj,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (FRINTK), 0 } }, + & ifmt_mand, { 0x1ec0400 } + }, +/* maddhus$pack $FRinti,$FRintj,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (FRINTK), 0 } }, + & ifmt_mand, { 0x1ec0440 } + }, +/* msubhss$pack $FRinti,$FRintj,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (FRINTK), 0 } }, + & ifmt_mand, { 0x1ec0480 } + }, +/* msubhus$pack $FRinti,$FRintj,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (FRINTK), 0 } }, + & ifmt_mand, { 0x1ec04c0 } + }, +/* cmaddhss$pack $FRinti,$FRintj,$FRintk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (FRINTK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cmand, { 0x1c40000 } + }, +/* cmaddhus$pack $FRinti,$FRintj,$FRintk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (FRINTK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cmand, { 0x1c40040 } + }, +/* cmsubhss$pack $FRinti,$FRintj,$FRintk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (FRINTK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cmand, { 0x1c40080 } + }, +/* cmsubhus$pack $FRinti,$FRintj,$FRintk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (FRINTK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cmand, { 0x1c400c0 } + }, +/* mqaddhss$pack $FRinti,$FRintj,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (FRINTK), 0 } }, + & ifmt_mand, { 0x1ec0600 } + }, +/* mqaddhus$pack $FRinti,$FRintj,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (FRINTK), 0 } }, + & ifmt_mand, { 0x1ec0640 } + }, +/* mqsubhss$pack $FRinti,$FRintj,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (FRINTK), 0 } }, + & ifmt_mand, { 0x1ec0680 } + }, +/* mqsubhus$pack $FRinti,$FRintj,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (FRINTK), 0 } }, + & ifmt_mand, { 0x1ec06c0 } + }, +/* cmqaddhss$pack $FRinti,$FRintj,$FRintk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (FRINTK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cmand, { 0x1cc0000 } + }, +/* cmqaddhus$pack $FRinti,$FRintj,$FRintk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (FRINTK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cmand, { 0x1cc0040 } + }, +/* cmqsubhss$pack $FRinti,$FRintj,$FRintk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (FRINTK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cmand, { 0x1cc0080 } + }, +/* cmqsubhus$pack $FRinti,$FRintj,$FRintk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (FRINTK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cmand, { 0x1cc00c0 } + }, +/* maddaccs$pack $ACC40Si,$ACC40Sk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ACC40SI), ',', OP (ACC40SK), 0 } }, + & ifmt_maddaccs, { 0x1e00100 } + }, +/* msubaccs$pack $ACC40Si,$ACC40Sk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ACC40SI), ',', OP (ACC40SK), 0 } }, + & ifmt_maddaccs, { 0x1e00140 } + }, +/* mdaddaccs$pack $ACC40Si,$ACC40Sk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ACC40SI), ',', OP (ACC40SK), 0 } }, + & ifmt_maddaccs, { 0x1e00180 } + }, +/* mdsubaccs$pack $ACC40Si,$ACC40Sk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ACC40SI), ',', OP (ACC40SK), 0 } }, + & ifmt_maddaccs, { 0x1e001c0 } + }, +/* masaccs$pack $ACC40Si,$ACC40Sk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ACC40SI), ',', OP (ACC40SK), 0 } }, + & ifmt_maddaccs, { 0x1e00200 } + }, +/* mdasaccs$pack $ACC40Si,$ACC40Sk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ACC40SI), ',', OP (ACC40SK), 0 } }, + & ifmt_maddaccs, { 0x1e00240 } + }, +/* mmulhs$pack $FRinti,$FRintj,$ACC40Sk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (ACC40SK), 0 } }, + & ifmt_mmulhs, { 0x1ec0500 } + }, +/* mmulhu$pack $FRinti,$FRintj,$ACC40Sk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (ACC40SK), 0 } }, + & ifmt_mmulhs, { 0x1ec0540 } + }, +/* mmulxhs$pack $FRinti,$FRintj,$ACC40Sk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (ACC40SK), 0 } }, + & ifmt_mmulhs, { 0x1ec0a00 } + }, +/* mmulxhu$pack $FRinti,$FRintj,$ACC40Sk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (ACC40SK), 0 } }, + & ifmt_mmulhs, { 0x1ec0a40 } + }, +/* cmmulhs$pack $FRinti,$FRintj,$ACC40Sk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (ACC40SK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cmmulhs, { 0x1c80000 } + }, +/* cmmulhu$pack $FRinti,$FRintj,$ACC40Sk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (ACC40SK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cmmulhs, { 0x1c80040 } + }, +/* mqmulhs$pack $FRinti,$FRintj,$ACC40Sk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (ACC40SK), 0 } }, + & ifmt_mmulhs, { 0x1ec0700 } + }, +/* mqmulhu$pack $FRinti,$FRintj,$ACC40Sk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (ACC40SK), 0 } }, + & ifmt_mmulhs, { 0x1ec0740 } + }, +/* mqmulxhs$pack $FRinti,$FRintj,$ACC40Sk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (ACC40SK), 0 } }, + & ifmt_mmulhs, { 0x1ec0a80 } + }, +/* mqmulxhu$pack $FRinti,$FRintj,$ACC40Sk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (ACC40SK), 0 } }, + & ifmt_mmulhs, { 0x1ec0ac0 } + }, +/* cmqmulhs$pack $FRinti,$FRintj,$ACC40Sk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (ACC40SK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cmmulhs, { 0x1d00000 } + }, +/* cmqmulhu$pack $FRinti,$FRintj,$ACC40Sk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (ACC40SK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cmmulhs, { 0x1d00040 } + }, +/* mmachs$pack $FRinti,$FRintj,$ACC40Sk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (ACC40SK), 0 } }, + & ifmt_mmulhs, { 0x1ec0580 } + }, +/* mmachu$pack $FRinti,$FRintj,$ACC40Uk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (ACC40UK), 0 } }, + & ifmt_mmachu, { 0x1ec05c0 } + }, +/* mmrdhs$pack $FRinti,$FRintj,$ACC40Sk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (ACC40SK), 0 } }, + & ifmt_mmulhs, { 0x1ec0c00 } + }, +/* mmrdhu$pack $FRinti,$FRintj,$ACC40Uk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (ACC40UK), 0 } }, + & ifmt_mmachu, { 0x1ec0c40 } + }, +/* cmmachs$pack $FRinti,$FRintj,$ACC40Sk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (ACC40SK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cmmulhs, { 0x1c80080 } + }, +/* cmmachu$pack $FRinti,$FRintj,$ACC40Uk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (ACC40UK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cmmachu, { 0x1c800c0 } + }, +/* mqmachs$pack $FRinti,$FRintj,$ACC40Sk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (ACC40SK), 0 } }, + & ifmt_mmulhs, { 0x1ec0780 } + }, +/* mqmachu$pack $FRinti,$FRintj,$ACC40Uk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (ACC40UK), 0 } }, + & ifmt_mmachu, { 0x1ec07c0 } + }, +/* cmqmachs$pack $FRinti,$FRintj,$ACC40Sk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (ACC40SK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cmmulhs, { 0x1d00080 } + }, +/* cmqmachu$pack $FRinti,$FRintj,$ACC40Uk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (ACC40UK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cmmachu, { 0x1d000c0 } + }, +/* mqxmachs$pack $FRinti,$FRintj,$ACC40Sk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (ACC40SK), 0 } }, + & ifmt_mmulhs, { 0x1e00000 } + }, +/* mqxmacxhs$pack $FRinti,$FRintj,$ACC40Sk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (ACC40SK), 0 } }, + & ifmt_mmulhs, { 0x1e00040 } + }, +/* mqmacxhs$pack $FRinti,$FRintj,$ACC40Sk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (ACC40SK), 0 } }, + & ifmt_mmulhs, { 0x1e00080 } + }, +/* mcpxrs$pack $FRinti,$FRintj,$ACC40Sk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (ACC40SK), 0 } }, + & ifmt_mmulhs, { 0x1ec0800 } + }, +/* mcpxru$pack $FRinti,$FRintj,$ACC40Sk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (ACC40SK), 0 } }, + & ifmt_mmulhs, { 0x1ec0840 } + }, +/* mcpxis$pack $FRinti,$FRintj,$ACC40Sk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (ACC40SK), 0 } }, + & ifmt_mmulhs, { 0x1ec0880 } + }, +/* mcpxiu$pack $FRinti,$FRintj,$ACC40Sk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (ACC40SK), 0 } }, + & ifmt_mmulhs, { 0x1ec08c0 } + }, +/* cmcpxrs$pack $FRinti,$FRintj,$ACC40Sk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (ACC40SK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cmmulhs, { 0x1d40000 } + }, +/* cmcpxru$pack $FRinti,$FRintj,$ACC40Sk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (ACC40SK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cmmulhs, { 0x1d40040 } + }, +/* cmcpxis$pack $FRinti,$FRintj,$ACC40Sk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (ACC40SK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cmmulhs, { 0x1d40080 } + }, +/* cmcpxiu$pack $FRinti,$FRintj,$ACC40Sk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (ACC40SK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cmmulhs, { 0x1d400c0 } + }, +/* mqcpxrs$pack $FRinti,$FRintj,$ACC40Sk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (ACC40SK), 0 } }, + & ifmt_mmulhs, { 0x1ec0900 } + }, +/* mqcpxru$pack $FRinti,$FRintj,$ACC40Sk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (ACC40SK), 0 } }, + & ifmt_mmulhs, { 0x1ec0940 } + }, +/* mqcpxis$pack $FRinti,$FRintj,$ACC40Sk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (ACC40SK), 0 } }, + & ifmt_mmulhs, { 0x1ec0980 } + }, +/* mqcpxiu$pack $FRinti,$FRintj,$ACC40Sk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (ACC40SK), 0 } }, + & ifmt_mmulhs, { 0x1ec09c0 } + }, +/* mexpdhw$pack $FRinti,$u6,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (U6), ',', OP (FRINTK), 0 } }, + & ifmt_mrotli, { 0x1ec0c80 } + }, +/* cmexpdhw$pack $FRinti,$u6,$FRintk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (U6), ',', OP (FRINTK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cmexpdhw, { 0x1d80080 } + }, +/* mexpdhd$pack $FRinti,$u6,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (U6), ',', OP (FRINTK), 0 } }, + & ifmt_mrotli, { 0x1ec0cc0 } + }, +/* cmexpdhd$pack $FRinti,$u6,$FRintk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (U6), ',', OP (FRINTK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cmexpdhw, { 0x1d800c0 } + }, +/* mpackh$pack $FRinti,$FRintj,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (FRINTK), 0 } }, + & ifmt_mand, { 0x1ec0d00 } + }, +/* mdpackh$pack $FRinti,$FRintj,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTJ), ',', OP (FRINTK), 0 } }, + & ifmt_mand, { 0x1ec0d80 } + }, +/* munpackh$pack $FRinti,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTK), 0 } }, + & ifmt_munpackh, { 0x1ec0d40 } + }, +/* mdunpackh$pack $FRinti,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (FRINTK), 0 } }, + & ifmt_munpackh, { 0x1ec0dc0 } + }, +/* mbtoh$pack $FRintj,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTJ), ',', OP (FRINTK), 0 } }, + & ifmt_mabshs, { 0x1ec0e00 } + }, +/* cmbtoh$pack $FRintj,$FRintk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTJ), ',', OP (FRINTK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cmbtoh, { 0x1dc0000 } + }, +/* mhtob$pack $FRintj,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTJ), ',', OP (FRINTK), 0 } }, + & ifmt_mabshs, { 0x1ec0e40 } + }, +/* cmhtob$pack $FRintj,$FRintk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTJ), ',', OP (FRINTK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cmbtoh, { 0x1dc0040 } + }, +/* mbtohe$pack $FRintj,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTJ), ',', OP (FRINTK), 0 } }, + & ifmt_mabshs, { 0x1ec0e80 } + }, +/* cmbtohe$pack $FRintj,$FRintk,$CCi,$cond */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTJ), ',', OP (FRINTK), ',', OP (CCI), ',', OP (COND), 0 } }, + & ifmt_cmbtoh, { 0x1dc0080 } + }, +/* mclracc$pack $ACC40Sk,$A */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ACC40SK), ',', OP (A), 0 } }, + & ifmt_mclracc, { 0x1ec0ec0 } + }, +/* mrdacc$pack $ACC40Si,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ACC40SI), ',', OP (FRINTK), 0 } }, + & ifmt_mrdacc, { 0x1ec0f00 } + }, +/* mrdaccg$pack $ACCGi,$FRintk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (ACCGI), ',', OP (FRINTK), 0 } }, + & ifmt_mrdaccg, { 0x1ec0f80 } + }, +/* mwtacc$pack $FRinti,$ACC40Sk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (ACC40SK), 0 } }, + & ifmt_mwtacc, { 0x1ec0f40 } + }, +/* mwtaccg$pack $FRinti,$ACCGk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRINTI), ',', OP (ACCGK), 0 } }, + & ifmt_mwtaccg, { 0x1ec0fc0 } + }, +/* mcop1$pack $FRi,$FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fadds, { 0x1f00000 } + }, +/* mcop2$pack $FRi,$FRj,$FRk */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), ' ', OP (FRI), ',', OP (FRJ), ',', OP (FRK), 0 } }, + & ifmt_fadds, { 0x1f40000 } + }, +/* fnop$pack */ + { + { 0, 0, 0, 0 }, + { { MNEM, OP (PACK), 0 } }, + & ifmt_fnop, { 0x1e40340 } + }, +}; + +#undef A +#undef OPERAND +#undef MNEM +#undef OP + +/* Formats for ALIAS macro-insns. */ + +#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE) +#define F(f) & frv_cgen_ifld_table[FRV_##f] +#else +#define F(f) & frv_cgen_ifld_table[FRV_/**/f] +#endif +static const CGEN_IFMT ifmt_nop = { + 32, 32, 0x7fffffff, { { F (F_PACK) }, { F (F_GRK) }, { F (F_OP) }, { F (F_GRI) }, { F (F_D12) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_mnop = { + 32, 32, 0x7fffffff, { { F (F_PACK) }, { F (F_ACC40SK) }, { F (F_OP) }, { F (F_A) }, { F (F_MISC_NULL_10) }, { F (F_OPE1) }, { F (F_FRJ_NULL) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_ret = { + 32, 32, 0x7fffffff, { { F (F_PACK) }, { F (F_INT_CC) }, { F (F_ICCI_2_NULL) }, { F (F_OP) }, { F (F_HINT) }, { F (F_OPE3) }, { F (F_CCOND_NULL) }, { F (F_S12_NULL) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_cmp = { + 32, 32, 0x7ffc03c0, { { F (F_PACK) }, { F (F_GRK) }, { F (F_OP) }, { F (F_GRI) }, { F (F_ICCI_1) }, { F (F_OPE2) }, { F (F_GRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_cmpi = { + 32, 32, 0x7ffc0000, { { F (F_PACK) }, { F (F_GRK) }, { F (F_OP) }, { F (F_GRI) }, { F (F_ICCI_1) }, { F (F_S10) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_ccmp = { + 32, 32, 0x7ffc00c0, { { F (F_PACK) }, { F (F_GRK) }, { F (F_OP) }, { F (F_GRI) }, { F (F_CCI) }, { F (F_COND) }, { F (F_OPE4) }, { F (F_GRJ) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_mov = { + 32, 32, 0x1fc0fff, { { F (F_PACK) }, { F (F_GRK) }, { F (F_OP) }, { F (F_GRI) }, { F (F_D12) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_cmov = { + 32, 32, 0x1fc00ff, { { F (F_PACK) }, { F (F_GRK) }, { F (F_OP) }, { F (F_GRI) }, { F (F_CCI) }, { F (F_COND) }, { F (F_OPE4) }, { F (F_GRJ) }, { 0 } } +}; + +#undef F + +/* Each non-simple macro entry points to an array of expansion possibilities. */ + +#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE) +#define A(a) (1 << CGEN_INSN_##a) +#else +#define A(a) (1 << CGEN_INSN_/**/a) +#endif +#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE) +#define OPERAND(op) FRV_OPERAND_##op +#else +#define OPERAND(op) FRV_OPERAND_/**/op +#endif +#define MNEM CGEN_SYNTAX_MNEMONIC /* syntax value for mnemonic */ +#define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field)) + +/* The macro instruction table. */ + +static const CGEN_IBASE frv_cgen_macro_insn_table[] = +{ +/* nop$pack */ + { + -1, "nop", "nop", 32, + { 0|A(ALIAS), { (1<macro_insn_table.init_entries = insns; + cd->macro_insn_table.entry_size = sizeof (CGEN_IBASE); + cd->macro_insn_table.num_init_entries = num_macros; + + oc = & frv_cgen_insn_opcode_table[0]; + insns = (CGEN_INSN *) cd->insn_table.init_entries; + for (i = 0; i < MAX_INSNS; ++i) + { + insns[i].opcode = &oc[i]; + frv_cgen_build_insn_regex (& insns[i]); + } + + cd->sizeof_fields = sizeof (CGEN_FIELDS); + cd->set_fields_bitsize = set_fields_bitsize; + + cd->asm_hash_p = asm_hash_insn_p; + cd->asm_hash = asm_hash_insn; + cd->asm_hash_size = CGEN_ASM_HASH_SIZE; + + cd->dis_hash_p = dis_hash_insn_p; + cd->dis_hash = dis_hash_insn; + cd->dis_hash_size = CGEN_DIS_HASH_SIZE; +} diff --git a/opcodes/frv-opc.h b/opcodes/frv-opc.h new file mode 100644 index 0000000..266031b --- /dev/null +++ b/opcodes/frv-opc.h @@ -0,0 +1,372 @@ +/* Instruction opcode header for frv. + +THIS FILE IS MACHINE GENERATED WITH CGEN. + +Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + +This file is part of the GNU Binutils and/or 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. + +*/ + +#ifndef FRV_OPC_H +#define FRV_OPC_H + +/* -- opc.h */ + +#undef CGEN_DIS_HASH_SIZE +#define CGEN_DIS_HASH_SIZE 128 +#undef CGEN_DIS_HASH +#define CGEN_DIS_HASH(buffer, value) (((value) >> 18) & 127) + +/* Vliw support. */ +#define FRV_VLIW_SIZE 4 /* fr500 has largest vliw size of 4. */ +typedef CGEN_ATTR_VALUE_TYPE VLIW_COMBO[FRV_VLIW_SIZE]; + +typedef struct +{ + int next_slot; + int constraint_violation; + unsigned long mach; + unsigned long elf_flags; + CGEN_ATTR_VALUE_TYPE *unit_mapping; + VLIW_COMBO *current_vliw; + CGEN_ATTR_VALUE_TYPE major[FRV_VLIW_SIZE]; +} FRV_VLIW; + +int frv_is_branch_major PARAMS ((CGEN_ATTR_VALUE_TYPE, unsigned long)); +int frv_is_float_major PARAMS ((CGEN_ATTR_VALUE_TYPE, unsigned long)); +int frv_is_media_major PARAMS ((CGEN_ATTR_VALUE_TYPE, unsigned long)); +int frv_is_branch_insn PARAMS ((const CGEN_INSN *)); +int frv_is_float_insn PARAMS ((const CGEN_INSN *)); +int frv_is_media_insn PARAMS ((const CGEN_INSN *)); +void frv_vliw_reset PARAMS ((FRV_VLIW *, unsigned long mach, unsigned long elf_flags)); +int frv_vliw_add_insn PARAMS ((FRV_VLIW *, const CGEN_INSN *)); +int spr_valid PARAMS ((long)); +/* -- */ +/* Enum declaration for frv instruction types. */ +typedef enum cgen_insn_type { + FRV_INSN_INVALID, FRV_INSN_ADD, FRV_INSN_SUB, FRV_INSN_AND + , FRV_INSN_OR, FRV_INSN_XOR, FRV_INSN_NOT, FRV_INSN_SDIV + , FRV_INSN_NSDIV, FRV_INSN_UDIV, FRV_INSN_NUDIV, FRV_INSN_SMUL + , FRV_INSN_UMUL, FRV_INSN_SLL, FRV_INSN_SRL, FRV_INSN_SRA + , FRV_INSN_SCAN, FRV_INSN_CADD, FRV_INSN_CSUB, FRV_INSN_CAND + , FRV_INSN_COR, FRV_INSN_CXOR, FRV_INSN_CNOT, FRV_INSN_CSMUL + , FRV_INSN_CSDIV, FRV_INSN_CUDIV, FRV_INSN_CSLL, FRV_INSN_CSRL + , FRV_INSN_CSRA, FRV_INSN_CSCAN, FRV_INSN_ADDCC, FRV_INSN_SUBCC + , FRV_INSN_ANDCC, FRV_INSN_ORCC, FRV_INSN_XORCC, FRV_INSN_SLLCC + , FRV_INSN_SRLCC, FRV_INSN_SRACC, FRV_INSN_SMULCC, FRV_INSN_UMULCC + , FRV_INSN_CADDCC, FRV_INSN_CSUBCC, FRV_INSN_CSMULCC, FRV_INSN_CANDCC + , FRV_INSN_CORCC, FRV_INSN_CXORCC, FRV_INSN_CSLLCC, FRV_INSN_CSRLCC + , FRV_INSN_CSRACC, FRV_INSN_ADDX, FRV_INSN_SUBX, FRV_INSN_ADDXCC + , FRV_INSN_SUBXCC, FRV_INSN_ADDI, FRV_INSN_SUBI, FRV_INSN_ANDI + , FRV_INSN_ORI, FRV_INSN_XORI, FRV_INSN_SDIVI, FRV_INSN_NSDIVI + , FRV_INSN_UDIVI, FRV_INSN_NUDIVI, FRV_INSN_SMULI, FRV_INSN_UMULI + , FRV_INSN_SLLI, FRV_INSN_SRLI, FRV_INSN_SRAI, FRV_INSN_SCANI + , FRV_INSN_ADDICC, FRV_INSN_SUBICC, FRV_INSN_ANDICC, FRV_INSN_ORICC + , FRV_INSN_XORICC, FRV_INSN_SMULICC, FRV_INSN_UMULICC, FRV_INSN_SLLICC + , FRV_INSN_SRLICC, FRV_INSN_SRAICC, FRV_INSN_ADDXI, FRV_INSN_SUBXI + , FRV_INSN_ADDXICC, FRV_INSN_SUBXICC, FRV_INSN_CMPB, FRV_INSN_CMPBA + , FRV_INSN_SETLO, FRV_INSN_SETHI, FRV_INSN_SETLOS, FRV_INSN_LDSB + , FRV_INSN_LDUB, FRV_INSN_LDSH, FRV_INSN_LDUH, FRV_INSN_LD + , FRV_INSN_LDBF, FRV_INSN_LDHF, FRV_INSN_LDF, FRV_INSN_LDC + , FRV_INSN_NLDSB, FRV_INSN_NLDUB, FRV_INSN_NLDSH, FRV_INSN_NLDUH + , FRV_INSN_NLD, FRV_INSN_NLDBF, FRV_INSN_NLDHF, FRV_INSN_NLDF + , FRV_INSN_LDD, FRV_INSN_LDDF, FRV_INSN_LDDC, FRV_INSN_NLDD + , FRV_INSN_NLDDF, FRV_INSN_LDQ, FRV_INSN_LDQF, FRV_INSN_LDQC + , FRV_INSN_NLDQ, FRV_INSN_NLDQF, FRV_INSN_LDSBU, FRV_INSN_LDUBU + , FRV_INSN_LDSHU, FRV_INSN_LDUHU, FRV_INSN_LDU, FRV_INSN_NLDSBU + , FRV_INSN_NLDUBU, FRV_INSN_NLDSHU, FRV_INSN_NLDUHU, FRV_INSN_NLDU + , FRV_INSN_LDBFU, FRV_INSN_LDHFU, FRV_INSN_LDFU, FRV_INSN_LDCU + , FRV_INSN_NLDBFU, FRV_INSN_NLDHFU, FRV_INSN_NLDFU, FRV_INSN_LDDU + , FRV_INSN_NLDDU, FRV_INSN_LDDFU, FRV_INSN_LDDCU, FRV_INSN_NLDDFU + , FRV_INSN_LDQU, FRV_INSN_NLDQU, FRV_INSN_LDQFU, FRV_INSN_LDQCU + , FRV_INSN_NLDQFU, FRV_INSN_LDSBI, FRV_INSN_LDSHI, FRV_INSN_LDI + , FRV_INSN_LDUBI, FRV_INSN_LDUHI, FRV_INSN_LDBFI, FRV_INSN_LDHFI + , FRV_INSN_LDFI, FRV_INSN_NLDSBI, FRV_INSN_NLDUBI, FRV_INSN_NLDSHI + , FRV_INSN_NLDUHI, FRV_INSN_NLDI, FRV_INSN_NLDBFI, FRV_INSN_NLDHFI + , FRV_INSN_NLDFI, FRV_INSN_LDDI, FRV_INSN_LDDFI, FRV_INSN_NLDDI + , FRV_INSN_NLDDFI, FRV_INSN_LDQI, FRV_INSN_LDQFI, FRV_INSN_NLDQI + , FRV_INSN_NLDQFI, FRV_INSN_STB, FRV_INSN_STH, FRV_INSN_ST + , FRV_INSN_STBF, FRV_INSN_STHF, FRV_INSN_STF, FRV_INSN_STC + , FRV_INSN_RSTB, FRV_INSN_RSTH, FRV_INSN_RST, FRV_INSN_RSTBF + , FRV_INSN_RSTHF, FRV_INSN_RSTF, FRV_INSN_STD, FRV_INSN_STDF + , FRV_INSN_STDC, FRV_INSN_RSTD, FRV_INSN_RSTDF, FRV_INSN_STQ + , FRV_INSN_STQF, FRV_INSN_STQC, FRV_INSN_RSTQ, FRV_INSN_RSTQF + , FRV_INSN_STBU, FRV_INSN_STHU, FRV_INSN_STU, FRV_INSN_STBFU + , FRV_INSN_STHFU, FRV_INSN_STFU, FRV_INSN_STCU, FRV_INSN_STDU + , FRV_INSN_STDFU, FRV_INSN_STDCU, FRV_INSN_STQU, FRV_INSN_STQFU + , FRV_INSN_STQCU, FRV_INSN_CLDSB, FRV_INSN_CLDUB, FRV_INSN_CLDSH + , FRV_INSN_CLDUH, FRV_INSN_CLD, FRV_INSN_CLDBF, FRV_INSN_CLDHF + , FRV_INSN_CLDF, FRV_INSN_CLDD, FRV_INSN_CLDDF, FRV_INSN_CLDQ + , FRV_INSN_CLDSBU, FRV_INSN_CLDUBU, FRV_INSN_CLDSHU, FRV_INSN_CLDUHU + , FRV_INSN_CLDU, FRV_INSN_CLDBFU, FRV_INSN_CLDHFU, FRV_INSN_CLDFU + , FRV_INSN_CLDDU, FRV_INSN_CLDDFU, FRV_INSN_CLDQU, FRV_INSN_CSTB + , FRV_INSN_CSTH, FRV_INSN_CST, FRV_INSN_CSTBF, FRV_INSN_CSTHF + , FRV_INSN_CSTF, FRV_INSN_CSTD, FRV_INSN_CSTDF, FRV_INSN_CSTQ + , FRV_INSN_CSTBU, FRV_INSN_CSTHU, FRV_INSN_CSTU, FRV_INSN_CSTBFU + , FRV_INSN_CSTHFU, FRV_INSN_CSTFU, FRV_INSN_CSTDU, FRV_INSN_CSTDFU + , FRV_INSN_STBI, FRV_INSN_STHI, FRV_INSN_STI, FRV_INSN_STBFI + , FRV_INSN_STHFI, FRV_INSN_STFI, FRV_INSN_STDI, FRV_INSN_STDFI + , FRV_INSN_STQI, FRV_INSN_STQFI, FRV_INSN_SWAP, FRV_INSN_SWAPI + , FRV_INSN_CSWAP, FRV_INSN_MOVGF, FRV_INSN_MOVFG, FRV_INSN_MOVGFD + , FRV_INSN_MOVFGD, FRV_INSN_MOVGFQ, FRV_INSN_MOVFGQ, FRV_INSN_CMOVGF + , FRV_INSN_CMOVFG, FRV_INSN_CMOVGFD, FRV_INSN_CMOVFGD, FRV_INSN_MOVGS + , FRV_INSN_MOVSG, FRV_INSN_BRA, FRV_INSN_BNO, FRV_INSN_BEQ + , FRV_INSN_BNE, FRV_INSN_BLE, FRV_INSN_BGT, FRV_INSN_BLT + , FRV_INSN_BGE, FRV_INSN_BLS, FRV_INSN_BHI, FRV_INSN_BC + , FRV_INSN_BNC, FRV_INSN_BN, FRV_INSN_BP, FRV_INSN_BV + , FRV_INSN_BNV, FRV_INSN_FBRA, FRV_INSN_FBNO, FRV_INSN_FBNE + , FRV_INSN_FBEQ, FRV_INSN_FBLG, FRV_INSN_FBUE, FRV_INSN_FBUL + , FRV_INSN_FBGE, FRV_INSN_FBLT, FRV_INSN_FBUGE, FRV_INSN_FBUG + , FRV_INSN_FBLE, FRV_INSN_FBGT, FRV_INSN_FBULE, FRV_INSN_FBU + , FRV_INSN_FBO, FRV_INSN_BCTRLR, FRV_INSN_BRALR, FRV_INSN_BNOLR + , FRV_INSN_BEQLR, FRV_INSN_BNELR, FRV_INSN_BLELR, FRV_INSN_BGTLR + , FRV_INSN_BLTLR, FRV_INSN_BGELR, FRV_INSN_BLSLR, FRV_INSN_BHILR + , FRV_INSN_BCLR, FRV_INSN_BNCLR, FRV_INSN_BNLR, FRV_INSN_BPLR + , FRV_INSN_BVLR, FRV_INSN_BNVLR, FRV_INSN_FBRALR, FRV_INSN_FBNOLR + , FRV_INSN_FBEQLR, FRV_INSN_FBNELR, FRV_INSN_FBLGLR, FRV_INSN_FBUELR + , FRV_INSN_FBULLR, FRV_INSN_FBGELR, FRV_INSN_FBLTLR, FRV_INSN_FBUGELR + , FRV_INSN_FBUGLR, FRV_INSN_FBLELR, FRV_INSN_FBGTLR, FRV_INSN_FBULELR + , FRV_INSN_FBULR, FRV_INSN_FBOLR, FRV_INSN_BCRALR, FRV_INSN_BCNOLR + , FRV_INSN_BCEQLR, FRV_INSN_BCNELR, FRV_INSN_BCLELR, FRV_INSN_BCGTLR + , FRV_INSN_BCLTLR, FRV_INSN_BCGELR, FRV_INSN_BCLSLR, FRV_INSN_BCHILR + , FRV_INSN_BCCLR, FRV_INSN_BCNCLR, FRV_INSN_BCNLR, FRV_INSN_BCPLR + , FRV_INSN_BCVLR, FRV_INSN_BCNVLR, FRV_INSN_FCBRALR, FRV_INSN_FCBNOLR + , FRV_INSN_FCBEQLR, FRV_INSN_FCBNELR, FRV_INSN_FCBLGLR, FRV_INSN_FCBUELR + , FRV_INSN_FCBULLR, FRV_INSN_FCBGELR, FRV_INSN_FCBLTLR, FRV_INSN_FCBUGELR + , FRV_INSN_FCBUGLR, FRV_INSN_FCBLELR, FRV_INSN_FCBGTLR, FRV_INSN_FCBULELR + , FRV_INSN_FCBULR, FRV_INSN_FCBOLR, FRV_INSN_JMPL, FRV_INSN_CALLL + , FRV_INSN_JMPIL, FRV_INSN_CALLIL, FRV_INSN_CALL, FRV_INSN_RETT + , FRV_INSN_REI, FRV_INSN_TRA, FRV_INSN_TNO, FRV_INSN_TEQ + , FRV_INSN_TNE, FRV_INSN_TLE, FRV_INSN_TGT, FRV_INSN_TLT + , FRV_INSN_TGE, FRV_INSN_TLS, FRV_INSN_THI, FRV_INSN_TC + , FRV_INSN_TNC, FRV_INSN_TN, FRV_INSN_TP, FRV_INSN_TV + , FRV_INSN_TNV, FRV_INSN_FTRA, FRV_INSN_FTNO, FRV_INSN_FTNE + , FRV_INSN_FTEQ, FRV_INSN_FTLG, FRV_INSN_FTUE, FRV_INSN_FTUL + , FRV_INSN_FTGE, FRV_INSN_FTLT, FRV_INSN_FTUGE, FRV_INSN_FTUG + , FRV_INSN_FTLE, FRV_INSN_FTGT, FRV_INSN_FTULE, FRV_INSN_FTU + , FRV_INSN_FTO, FRV_INSN_TIRA, FRV_INSN_TINO, FRV_INSN_TIEQ + , FRV_INSN_TINE, FRV_INSN_TILE, FRV_INSN_TIGT, FRV_INSN_TILT + , FRV_INSN_TIGE, FRV_INSN_TILS, FRV_INSN_TIHI, FRV_INSN_TIC + , FRV_INSN_TINC, FRV_INSN_TIN, FRV_INSN_TIP, FRV_INSN_TIV + , FRV_INSN_TINV, FRV_INSN_FTIRA, FRV_INSN_FTINO, FRV_INSN_FTINE + , FRV_INSN_FTIEQ, FRV_INSN_FTILG, FRV_INSN_FTIUE, FRV_INSN_FTIUL + , FRV_INSN_FTIGE, FRV_INSN_FTILT, FRV_INSN_FTIUGE, FRV_INSN_FTIUG + , FRV_INSN_FTILE, FRV_INSN_FTIGT, FRV_INSN_FTIULE, FRV_INSN_FTIU + , FRV_INSN_FTIO, FRV_INSN_BREAK, FRV_INSN_MTRAP, FRV_INSN_ANDCR + , FRV_INSN_ORCR, FRV_INSN_XORCR, FRV_INSN_NANDCR, FRV_INSN_NORCR + , FRV_INSN_ANDNCR, FRV_INSN_ORNCR, FRV_INSN_NANDNCR, FRV_INSN_NORNCR + , FRV_INSN_NOTCR, FRV_INSN_CKRA, FRV_INSN_CKNO, FRV_INSN_CKEQ + , FRV_INSN_CKNE, FRV_INSN_CKLE, FRV_INSN_CKGT, FRV_INSN_CKLT + , FRV_INSN_CKGE, FRV_INSN_CKLS, FRV_INSN_CKHI, FRV_INSN_CKC + , FRV_INSN_CKNC, FRV_INSN_CKN, FRV_INSN_CKP, FRV_INSN_CKV + , FRV_INSN_CKNV, FRV_INSN_FCKRA, FRV_INSN_FCKNO, FRV_INSN_FCKNE + , FRV_INSN_FCKEQ, FRV_INSN_FCKLG, FRV_INSN_FCKUE, FRV_INSN_FCKUL + , FRV_INSN_FCKGE, FRV_INSN_FCKLT, FRV_INSN_FCKUGE, FRV_INSN_FCKUG + , FRV_INSN_FCKLE, FRV_INSN_FCKGT, FRV_INSN_FCKULE, FRV_INSN_FCKU + , FRV_INSN_FCKO, FRV_INSN_CCKRA, FRV_INSN_CCKNO, FRV_INSN_CCKEQ + , FRV_INSN_CCKNE, FRV_INSN_CCKLE, FRV_INSN_CCKGT, FRV_INSN_CCKLT + , FRV_INSN_CCKGE, FRV_INSN_CCKLS, FRV_INSN_CCKHI, FRV_INSN_CCKC + , FRV_INSN_CCKNC, FRV_INSN_CCKN, FRV_INSN_CCKP, FRV_INSN_CCKV + , FRV_INSN_CCKNV, FRV_INSN_CFCKRA, FRV_INSN_CFCKNO, FRV_INSN_CFCKNE + , FRV_INSN_CFCKEQ, FRV_INSN_CFCKLG, FRV_INSN_CFCKUE, FRV_INSN_CFCKUL + , FRV_INSN_CFCKGE, FRV_INSN_CFCKLT, FRV_INSN_CFCKUGE, FRV_INSN_CFCKUG + , FRV_INSN_CFCKLE, FRV_INSN_CFCKGT, FRV_INSN_CFCKULE, FRV_INSN_CFCKU + , FRV_INSN_CFCKO, FRV_INSN_CJMPL, FRV_INSN_CCALLL, FRV_INSN_ICI + , FRV_INSN_DCI, FRV_INSN_ICEI, FRV_INSN_DCEI, FRV_INSN_DCF + , FRV_INSN_DCEF, FRV_INSN_WITLB, FRV_INSN_WDTLB, FRV_INSN_ITLBI + , FRV_INSN_DTLBI, FRV_INSN_ICPL, FRV_INSN_DCPL, FRV_INSN_ICUL + , FRV_INSN_DCUL, FRV_INSN_BAR, FRV_INSN_MEMBAR, FRV_INSN_COP1 + , FRV_INSN_COP2, FRV_INSN_CLRGR, FRV_INSN_CLRFR, FRV_INSN_CLRGA + , FRV_INSN_CLRFA, FRV_INSN_COMMITGR, FRV_INSN_COMMITFR, FRV_INSN_COMMITGA + , FRV_INSN_COMMITFA, FRV_INSN_FITOS, FRV_INSN_FSTOI, FRV_INSN_FITOD + , FRV_INSN_FDTOI, FRV_INSN_FDITOS, FRV_INSN_FDSTOI, FRV_INSN_NFDITOS + , FRV_INSN_NFDSTOI, FRV_INSN_CFITOS, FRV_INSN_CFSTOI, FRV_INSN_NFITOS + , FRV_INSN_NFSTOI, FRV_INSN_FMOVS, FRV_INSN_FMOVD, FRV_INSN_FDMOVS + , FRV_INSN_CFMOVS, FRV_INSN_FNEGS, FRV_INSN_FNEGD, FRV_INSN_FDNEGS + , FRV_INSN_CFNEGS, FRV_INSN_FABSS, FRV_INSN_FABSD, FRV_INSN_FDABSS + , FRV_INSN_CFABSS, FRV_INSN_FSQRTS, FRV_INSN_FDSQRTS, FRV_INSN_NFDSQRTS + , FRV_INSN_FSQRTD, FRV_INSN_CFSQRTS, FRV_INSN_NFSQRTS, FRV_INSN_FADDS + , FRV_INSN_FSUBS, FRV_INSN_FMULS, FRV_INSN_FDIVS, FRV_INSN_FADDD + , FRV_INSN_FSUBD, FRV_INSN_FMULD, FRV_INSN_FDIVD, FRV_INSN_CFADDS + , FRV_INSN_CFSUBS, FRV_INSN_CFMULS, FRV_INSN_CFDIVS, FRV_INSN_NFADDS + , FRV_INSN_NFSUBS, FRV_INSN_NFMULS, FRV_INSN_NFDIVS, FRV_INSN_FCMPS + , FRV_INSN_FCMPD, FRV_INSN_CFCMPS, FRV_INSN_FDCMPS, FRV_INSN_FMADDS + , FRV_INSN_FMSUBS, FRV_INSN_FMADDD, FRV_INSN_FMSUBD, FRV_INSN_FDMADDS + , FRV_INSN_NFDMADDS, FRV_INSN_CFMADDS, FRV_INSN_CFMSUBS, FRV_INSN_NFMADDS + , FRV_INSN_NFMSUBS, FRV_INSN_FMAS, FRV_INSN_FMSS, FRV_INSN_FDMAS + , FRV_INSN_FDMSS, FRV_INSN_NFDMAS, FRV_INSN_NFDMSS, FRV_INSN_CFMAS + , FRV_INSN_CFMSS, FRV_INSN_FMAD, FRV_INSN_FMSD, FRV_INSN_NFMAS + , FRV_INSN_NFMSS, FRV_INSN_FDADDS, FRV_INSN_FDSUBS, FRV_INSN_FDMULS + , FRV_INSN_FDDIVS, FRV_INSN_FDSADS, FRV_INSN_FDMULCS, FRV_INSN_NFDMULCS + , FRV_INSN_NFDADDS, FRV_INSN_NFDSUBS, FRV_INSN_NFDMULS, FRV_INSN_NFDDIVS + , FRV_INSN_NFDSADS, FRV_INSN_NFDCMPS, FRV_INSN_MHSETLOS, FRV_INSN_MHSETHIS + , FRV_INSN_MHDSETS, FRV_INSN_MHSETLOH, FRV_INSN_MHSETHIH, FRV_INSN_MHDSETH + , FRV_INSN_MAND, FRV_INSN_MOR, FRV_INSN_MXOR, FRV_INSN_CMAND + , FRV_INSN_CMOR, FRV_INSN_CMXOR, FRV_INSN_MNOT, FRV_INSN_CMNOT + , FRV_INSN_MROTLI, FRV_INSN_MROTRI, FRV_INSN_MWCUT, FRV_INSN_MWCUTI + , FRV_INSN_MCUT, FRV_INSN_MCUTI, FRV_INSN_MCUTSS, FRV_INSN_MCUTSSI + , FRV_INSN_MDCUTSSI, FRV_INSN_MAVEH, FRV_INSN_MSLLHI, FRV_INSN_MSRLHI + , FRV_INSN_MSRAHI, FRV_INSN_MDROTLI, FRV_INSN_MCPLHI, FRV_INSN_MCPLI + , FRV_INSN_MSATHS, FRV_INSN_MQSATHS, FRV_INSN_MSATHU, FRV_INSN_MCMPSH + , FRV_INSN_MCMPUH, FRV_INSN_MABSHS, FRV_INSN_MADDHSS, FRV_INSN_MADDHUS + , FRV_INSN_MSUBHSS, FRV_INSN_MSUBHUS, FRV_INSN_CMADDHSS, FRV_INSN_CMADDHUS + , FRV_INSN_CMSUBHSS, FRV_INSN_CMSUBHUS, FRV_INSN_MQADDHSS, FRV_INSN_MQADDHUS + , FRV_INSN_MQSUBHSS, FRV_INSN_MQSUBHUS, FRV_INSN_CMQADDHSS, FRV_INSN_CMQADDHUS + , FRV_INSN_CMQSUBHSS, FRV_INSN_CMQSUBHUS, FRV_INSN_MADDACCS, FRV_INSN_MSUBACCS + , FRV_INSN_MDADDACCS, FRV_INSN_MDSUBACCS, FRV_INSN_MASACCS, FRV_INSN_MDASACCS + , FRV_INSN_MMULHS, FRV_INSN_MMULHU, FRV_INSN_MMULXHS, FRV_INSN_MMULXHU + , FRV_INSN_CMMULHS, FRV_INSN_CMMULHU, FRV_INSN_MQMULHS, FRV_INSN_MQMULHU + , FRV_INSN_MQMULXHS, FRV_INSN_MQMULXHU, FRV_INSN_CMQMULHS, FRV_INSN_CMQMULHU + , FRV_INSN_MMACHS, FRV_INSN_MMACHU, FRV_INSN_MMRDHS, FRV_INSN_MMRDHU + , FRV_INSN_CMMACHS, FRV_INSN_CMMACHU, FRV_INSN_MQMACHS, FRV_INSN_MQMACHU + , FRV_INSN_CMQMACHS, FRV_INSN_CMQMACHU, FRV_INSN_MQXMACHS, FRV_INSN_MQXMACXHS + , FRV_INSN_MQMACXHS, FRV_INSN_MCPXRS, FRV_INSN_MCPXRU, FRV_INSN_MCPXIS + , FRV_INSN_MCPXIU, FRV_INSN_CMCPXRS, FRV_INSN_CMCPXRU, FRV_INSN_CMCPXIS + , FRV_INSN_CMCPXIU, FRV_INSN_MQCPXRS, FRV_INSN_MQCPXRU, FRV_INSN_MQCPXIS + , FRV_INSN_MQCPXIU, FRV_INSN_MEXPDHW, FRV_INSN_CMEXPDHW, FRV_INSN_MEXPDHD + , FRV_INSN_CMEXPDHD, FRV_INSN_MPACKH, FRV_INSN_MDPACKH, FRV_INSN_MUNPACKH + , FRV_INSN_MDUNPACKH, FRV_INSN_MBTOH, FRV_INSN_CMBTOH, FRV_INSN_MHTOB + , FRV_INSN_CMHTOB, FRV_INSN_MBTOHE, FRV_INSN_CMBTOHE, FRV_INSN_MCLRACC + , FRV_INSN_MRDACC, FRV_INSN_MRDACCG, FRV_INSN_MWTACC, FRV_INSN_MWTACCG + , FRV_INSN_MCOP1, FRV_INSN_MCOP2, FRV_INSN_FNOP +} CGEN_INSN_TYPE; + +/* Index of `invalid' insn place holder. */ +#define CGEN_INSN_INVALID FRV_INSN_INVALID + +/* Total number of insns in table. */ +#define MAX_INSNS ((int) FRV_INSN_FNOP + 1) + +/* This struct records data prior to insertion or after extraction. */ +struct cgen_fields +{ + int length; + long f_nil; + long f_anyof; + long f_pack; + long f_op; + long f_ope1; + long f_ope2; + long f_ope3; + long f_ope4; + long f_GRi; + long f_GRj; + long f_GRk; + long f_FRi; + long f_FRj; + long f_FRk; + long f_CPRi; + long f_CPRj; + long f_CPRk; + long f_ACCGi; + long f_ACCGk; + long f_ACC40Si; + long f_ACC40Ui; + long f_ACC40Sk; + long f_ACC40Uk; + long f_CRi; + long f_CRj; + long f_CRk; + long f_CCi; + long f_CRj_int; + long f_CRj_float; + long f_ICCi_1; + long f_ICCi_2; + long f_ICCi_3; + long f_FCCi_1; + long f_FCCi_2; + long f_FCCi_3; + long f_FCCk; + long f_eir; + long f_s10; + long f_s12; + long f_d12; + long f_u16; + long f_s16; + long f_s6; + long f_s6_1; + long f_u6; + long f_s5; + long f_u12_h; + long f_u12_l; + long f_u12; + long f_int_cc; + long f_flt_cc; + long f_cond; + long f_ccond; + long f_hint; + long f_LI; + long f_lock; + long f_debug; + long f_A; + long f_ae; + long f_spr_h; + long f_spr_l; + long f_spr; + long f_label16; + long f_labelH6; + long f_labelL18; + long f_label24; + long f_ICCi_1_null; + long f_ICCi_2_null; + long f_ICCi_3_null; + long f_FCCi_1_null; + long f_FCCi_2_null; + long f_FCCi_3_null; + long f_rs_null; + long f_GRi_null; + long f_GRj_null; + long f_GRk_null; + long f_FRi_null; + long f_FRj_null; + long f_ACCj_null; + long f_rd_null; + long f_cond_null; + long f_ccond_null; + long f_s12_null; + long f_label16_null; + long f_misc_null_1; + long f_misc_null_2; + long f_misc_null_3; + long f_misc_null_4; + long f_misc_null_5; + long f_misc_null_6; + long f_misc_null_7; + long f_misc_null_8; + long f_misc_null_9; + long f_misc_null_10; + long f_misc_null_11; + long f_LI_off; + long f_LI_on; +}; + +#define CGEN_INIT_PARSE(od) \ +{\ +} +#define CGEN_INIT_INSERT(od) \ +{\ +} +#define CGEN_INIT_EXTRACT(od) \ +{\ +} +#define CGEN_INIT_PRINT(od) \ +{\ +} + + +#endif /* FRV_OPC_H */ diff --git a/sim/mips/mdmx.c b/sim/mips/mdmx.c new file mode 100644 index 0000000..4955e82 --- /dev/null +++ b/sim/mips/mdmx.c @@ -0,0 +1,1476 @@ +/* Simulation code for the MIPS MDMX ASE. + Copyright (C) 2002 Free Software Foundation, Inc. + Contributed by Broadcom Corporation (SiByte). + +This file is part of 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 + +#include "sim-main.h" + +/* Within mdmx.c we refer to the sim_cpu directly. */ +#define CPU cpu +#define SD (CPU_STATE(CPU)) + +/* XXX FIXME: temporary hack while the impact of making unpredictable() + a "normal" (non-igen) function is evaluated. */ +#undef Unpredictable +#define Unpredictable() unpredictable_action (cpu, cia) + +/* MDMX Representations + + An 8-bit packed byte element (OB) is always unsigned. + The 24-bit accumulators are signed and are represented as 32-bit + signed values, which are reduced to 24-bit signed values prior to + Round and Clamp operations. + + A 16-bit packed halfword element (QH) is always signed. + The 48-bit accumulators are signed and are represented as 64-bit + signed values, which are reduced to 48-bit signed values prior to + Round and Clamp operations. + + The code below assumes a 2's-complement representation of signed + quantities. Care is required to clear extended sign bits when + repacking fields. + + The code (and the code for arithmetic shifts in mips.igen) also makes + the (not guaranteed portable) assumption that right shifts of signed + quantities in C do sign extension. */ + +typedef unsigned64 unsigned48; +#define MASK48 (UNSIGNED64 (0xffffffffffff)) + +typedef unsigned32 unsigned24; +#define MASK24 (UNSIGNED32 (0xffffff)) + +typedef enum { + mdmx_ob, /* OB (octal byte) */ + mdmx_qh /* QH (quad half-word) */ +} MX_fmt; + +typedef enum { + sel_elem, /* element select */ + sel_vect, /* vector select */ + sel_imm /* immediate select */ +} VT_select; + +#define OB_MAX ((unsigned8)0xFF) +#define QH_MIN ((signed16)0x8000) +#define QH_MAX ((signed16)0x7FFF) + +#define OB_CLAMP(x) ((unsigned8)((x) > OB_MAX ? OB_MAX : (x))) +#define QH_CLAMP(x) ((signed16)((x) < QH_MIN ? QH_MIN : \ + ((x) > QH_MAX ? QH_MAX : (x)))) + +#define MX_FMT(fmtsel) (((fmtsel) & 0x1) == 0 ? mdmx_ob : mdmx_qh) +#define MX_VT(fmtsel) (((fmtsel) & 0x10) == 0 ? sel_elem : \ + (((fmtsel) & 0x18) == 0x10 ? sel_vect : sel_imm)) + +#define QH_ELEM(v,fmtsel) \ + ((signed16)(((v) >> (((fmtsel) & 0xC) << 2)) & 0xFFFF)) +#define OB_ELEM(v,fmtsel) \ + ((unsigned8)(((v) >> (((fmtsel) & 0xE) << 2)) & 0xFF)) + + +typedef signed16 (*QH_FUNC)(signed16, signed16); +typedef unsigned8 (*OB_FUNC)(unsigned8, unsigned8); + +/* vectorized logical operators */ + +static signed16 +AndQH(signed16 ts, signed16 tt) +{ + return (signed16)((unsigned16)ts & (unsigned16)tt); +} + +static unsigned8 +AndOB(unsigned8 ts, unsigned8 tt) +{ + return ts & tt; +} + +static signed16 +NorQH(signed16 ts, signed16 tt) +{ + return (signed16)(((unsigned16)ts | (unsigned16)tt) ^ 0xFFFF); +} + +static unsigned8 +NorOB(unsigned8 ts, unsigned8 tt) +{ + return (ts | tt) ^ 0xFF; +} + +static signed16 +OrQH(signed16 ts, signed16 tt) +{ + return (signed16)((unsigned16)ts | (unsigned16)tt); +} + +static unsigned8 +OrOB(unsigned8 ts, unsigned8 tt) +{ + return ts | tt; +} + +static signed16 +XorQH(signed16 ts, signed16 tt) +{ + return (signed16)((unsigned16)ts ^ (unsigned16)tt); +} + +static unsigned8 +XorOB(unsigned8 ts, unsigned8 tt) +{ + return ts ^ tt; +} + +static signed16 +SLLQH(signed16 ts, signed16 tt) +{ + unsigned32 s = (unsigned32)tt & 0xF; + return (signed16)(((unsigned32)ts << s) & 0xFFFF); +} + +static unsigned8 +SLLOB(unsigned8 ts, unsigned8 tt) +{ + unsigned32 s = tt & 0x7; + return (ts << s) & 0xFF; +} + +static signed16 +SRLQH(signed16 ts, signed16 tt) +{ + unsigned32 s = (unsigned32)tt & 0xF; + return (signed16)((unsigned16)ts >> s); +} + +static unsigned8 +SRLOB(unsigned8 ts, unsigned8 tt) +{ + unsigned32 s = tt & 0x7; + return ts >> s; +} + + +/* Vectorized arithmetic operators. */ + +static signed16 +AddQH(signed16 ts, signed16 tt) +{ + signed32 t = (signed32)ts + (signed32)tt; + return QH_CLAMP(t); +} + +static unsigned8 +AddOB(unsigned8 ts, unsigned8 tt) +{ + unsigned32 t = (unsigned32)ts + (unsigned32)tt; + return OB_CLAMP(t); +} + +static signed16 +SubQH(signed16 ts, signed16 tt) +{ + signed32 t = (signed32)ts - (signed32)tt; + return QH_CLAMP(t); +} + +static unsigned8 +SubOB(unsigned8 ts, unsigned8 tt) +{ + signed32 t; + t = (signed32)ts - (signed32)tt; + if (t < 0) + t = 0; + return (unsigned8)t; +} + +static signed16 +MinQH(signed16 ts, signed16 tt) +{ + return (ts < tt ? ts : tt); +} + +static unsigned8 +MinOB(unsigned8 ts, unsigned8 tt) +{ + return (ts < tt ? ts : tt); +} + +static signed16 +MaxQH(signed16 ts, signed16 tt) +{ + return (ts > tt ? ts : tt); +} + +static unsigned8 +MaxOB(unsigned8 ts, unsigned8 tt) +{ + return (ts > tt ? ts : tt); +} + +static signed16 +MulQH(signed16 ts, signed16 tt) +{ + signed32 t = (signed32)ts * (signed32)tt; + return QH_CLAMP(t); +} + +static unsigned8 +MulOB(unsigned8 ts, unsigned8 tt) +{ + unsigned32 t = (unsigned32)ts * (unsigned32)tt; + return OB_CLAMP(t); +} + +/* "msgn" and "sra" are defined only for QH format. */ + +static signed16 +MsgnQH(signed16 ts, signed16 tt) +{ + signed16 t; + if (ts < 0) + t = (tt == QH_MIN ? QH_MAX : -tt); + else if (ts == 0) + t = 0; + else + t = tt; + return t; +} + +static signed16 +SRAQH(signed16 ts, signed16 tt) +{ + unsigned32 s = (unsigned32)tt & 0xF; + return (signed16)((signed32)ts >> s); +} + + +/* "pabsdiff" and "pavg" are defined only for OB format. */ + +static unsigned8 +AbsDiffOB(unsigned8 ts, unsigned8 tt) +{ + return (ts >= tt ? ts - tt : tt - ts); +} + +static unsigned8 +AvgOB(unsigned8 ts, unsigned8 tt) +{ + return ((unsigned32)ts + (unsigned32)tt + 1) >> 1; +} + + +/* Dispatch tables for operations that update a CPR. */ + +static const QH_FUNC qh_func[] = { + AndQH, NorQH, OrQH, XorQH, SLLQH, SRLQH, + AddQH, SubQH, MinQH, MaxQH, + MulQH, MsgnQH, SRAQH, NULL, NULL +}; + +static const OB_FUNC ob_func[] = { + AndOB, NorOB, OrOB, XorOB, SLLOB, SRLOB, + AddOB, SubOB, MinOB, MaxOB, + MulOB, NULL, NULL, AbsDiffOB, AvgOB +}; + +/* Auxiliary functions for CPR updates. */ + +/* Vector mapping for QH format. */ +static unsigned64 +qh_vector_op(unsigned64 v1, unsigned64 v2, QH_FUNC func) +{ + unsigned64 result = 0; + int i; + signed16 h, h1, h2; + + for (i = 0; i < 64; i += 16) + { + h1 = (signed16)(v1 & 0xFFFF); v1 >>= 16; + h2 = (signed16)(v2 & 0xFFFF); v2 >>= 16; + h = (*func)(h1, h2); + result |= ((unsigned64)((unsigned16)h) << i); + } + return result; +} + +static unsigned64 +qh_map_op(unsigned64 v1, signed16 h2, QH_FUNC func) +{ + unsigned64 result = 0; + int i; + signed16 h, h1; + + for (i = 0; i < 64; i += 16) + { + h1 = (signed16)(v1 & 0xFFFF); v1 >>= 16; + h = (*func)(h1, h2); + result |= ((unsigned64)((unsigned16)h) << i); + } + return result; +} + + +/* Vector operations for OB format. */ + +static unsigned64 +ob_vector_op(unsigned64 v1, unsigned64 v2, OB_FUNC func) +{ + unsigned64 result = 0; + int i; + unsigned8 b, b1, b2; + + for (i = 0; i < 64; i += 8) + { + b1 = v1 & 0xFF; v1 >>= 8; + b2 = v2 & 0xFF; v2 >>= 8; + b = (*func)(b1, b2); + result |= ((unsigned64)b << i); + } + return result; +} + +static unsigned64 +ob_map_op(unsigned64 v1, unsigned8 b2, OB_FUNC func) +{ + unsigned64 result = 0; + int i; + unsigned8 b, b1; + + for (i = 0; i < 64; i += 8) + { + b1 = v1 & 0xFF; v1 >>= 8; + b = (*func)(b1, b2); + result |= ((unsigned64)b << i); + } + return result; +} + + +/* Primary entry for operations that update CPRs. */ +unsigned64 +mdmx_cpr_op(sim_cpu *cpu, + address_word cia, + int op, + unsigned64 op1, + int vt, + MX_fmtsel fmtsel) +{ + unsigned64 op2; + unsigned64 result = 0; + + switch (MX_FMT (fmtsel)) + { + case mdmx_qh: + switch (MX_VT (fmtsel)) + { + case sel_elem: + op2 = ValueFPR(vt, fmt_mdmx); + result = qh_map_op(op1, QH_ELEM(op2, fmtsel), qh_func[op]); + break; + case sel_vect: + result = qh_vector_op(op1, ValueFPR(vt, fmt_mdmx), qh_func[op]); + break; + case sel_imm: + result = qh_map_op(op1, vt, qh_func[op]); + break; + } + break; + case mdmx_ob: + switch (MX_VT (fmtsel)) + { + case sel_elem: + op2 = ValueFPR(vt, fmt_mdmx); + result = ob_map_op(op1, OB_ELEM(op2, fmtsel), ob_func[op]); + break; + case sel_vect: + result = ob_vector_op(op1, ValueFPR(vt, fmt_mdmx), ob_func[op]); + break; + case sel_imm: + result = ob_map_op(op1, vt, ob_func[op]); + break; + } + break; + default: + Unpredictable (); + } + + return result; +} + + +/* Operations that update CCs */ + +static void +qh_vector_test(sim_cpu *cpu, unsigned64 v1, unsigned64 v2, int cond) +{ + int i; + signed16 h1, h2; + int boolean; + + for (i = 0; i < 4; i++) + { + h1 = (signed16)(v1 & 0xFFFF); v1 >>= 16; + h2 = (signed16)(v2 & 0xFFFF); v2 >>= 16; + boolean = ((cond & MX_C_EQ) && (h1 == h2)) || + ((cond & MX_C_LT) && (h1 < h2)); + SETFCC(i, boolean); + } +} + +static void +qh_map_test(sim_cpu *cpu, unsigned64 v1, signed16 h2, int cond) +{ + int i; + signed16 h1; + int boolean; + + for (i = 0; i < 4; i++) + { + h1 = (signed16)(v1 & 0xFFFF); v1 >>= 16; + boolean = ((cond & MX_C_EQ) && (h1 == h2)) || + ((cond & MX_C_LT) && (h1 < h2)); + SETFCC(i, boolean); + } +} + +static void +ob_vector_test(sim_cpu *cpu, unsigned64 v1, unsigned64 v2, int cond) +{ + int i; + unsigned8 b1, b2; + int boolean; + + for (i = 0; i < 8; i++) + { + b1 = v1 & 0xFF; v1 >>= 8; + b2 = v2 & 0xFF; v2 >>= 8; + boolean = ((cond & MX_C_EQ) && (b1 == b2)) || + ((cond & MX_C_LT) && (b1 < b2)); + SETFCC(i, boolean); + } +} + +static void +ob_map_test(sim_cpu *cpu, unsigned64 v1, unsigned8 b2, int cond) +{ + int i; + unsigned8 b1; + int boolean; + + for (i = 0; i < 8; i++) + { + b1 = (unsigned8)(v1 & 0xFF); v1 >>= 8; + boolean = ((cond & MX_C_EQ) && (b1 == b2)) || + ((cond & MX_C_LT) && (b1 < b2)); + SETFCC(i, boolean); + } +} + + +void +mdmx_cc_op(sim_cpu *cpu, + address_word cia, + int cond, + unsigned64 v1, + int vt, + MX_fmtsel fmtsel) +{ + unsigned64 op2; + + switch (MX_FMT (fmtsel)) + { + case mdmx_qh: + switch (MX_VT (fmtsel)) + { + case sel_elem: + op2 = ValueFPR(vt, fmt_mdmx); + qh_map_test(cpu, v1, QH_ELEM(op2, fmtsel), cond); + break; + case sel_vect: + qh_vector_test(cpu, v1, ValueFPR(vt, fmt_mdmx), cond); + break; + case sel_imm: + qh_map_test(cpu, v1, vt, cond); + break; + } + break; + case mdmx_ob: + switch (MX_VT (fmtsel)) + { + case sel_elem: + op2 = ValueFPR(vt, fmt_mdmx); + ob_map_test(cpu, v1, OB_ELEM(op2, fmtsel), cond); + break; + case sel_vect: + ob_vector_test(cpu, v1, ValueFPR(vt, fmt_mdmx), cond); + break; + case sel_imm: + ob_map_test(cpu, v1, vt, cond); + break; + } + break; + default: + Unpredictable (); + } +} + + +/* Pick operations. */ + +static unsigned64 +qh_vector_pick(sim_cpu *cpu, unsigned64 v1, unsigned64 v2, int tf) +{ + unsigned64 result = 0; + int i, s; + unsigned16 h; + + s = 0; + for (i = 0; i < 4; i++) + { + h = ((GETFCC(i) == tf) ? (v1 & 0xFFFF) : (v2 & 0xFFFF)); + v1 >>= 16; v2 >>= 16; + result |= ((unsigned64)h << s); + s += 16; + } + return result; +} + +static unsigned64 +qh_map_pick(sim_cpu *cpu, unsigned64 v1, signed16 h2, int tf) +{ + unsigned64 result = 0; + int i, s; + unsigned16 h; + + s = 0; + for (i = 0; i < 4; i++) + { + h = (GETFCC(i) == tf) ? (v1 & 0xFFFF) : (unsigned16)h2; + v1 >>= 16; + result |= ((unsigned64)h << s); + s += 16; + } + return result; +} + +static unsigned64 +ob_vector_pick(sim_cpu *cpu, unsigned64 v1, unsigned64 v2, int tf) +{ + unsigned64 result = 0; + int i, s; + unsigned8 b; + + s = 0; + for (i = 0; i < 8; i++) + { + b = (GETFCC(i) == tf) ? (v1 & 0xFF) : (v2 & 0xFF); + v1 >>= 8; v2 >>= 8; + result |= ((unsigned64)b << s); + s += 8; + } + return result; +} + +static unsigned64 +ob_map_pick(sim_cpu *cpu, unsigned64 v1, unsigned8 b2, int tf) +{ + unsigned64 result = 0; + int i, s; + unsigned8 b; + + s = 0; + for (i = 0; i < 8; i++) + { + b = (GETFCC(i) == tf) ? (v1 & 0xFF) : b2; + v1 >>= 8; + result |= ((unsigned64)b << s); + s += 8; + } + return result; +} + + +unsigned64 +mdmx_pick_op(sim_cpu *cpu, + address_word cia, + int tf, + unsigned64 v1, + int vt, + MX_fmtsel fmtsel) +{ + unsigned64 result = 0; + unsigned64 op2; + + switch (MX_FMT (fmtsel)) + { + case mdmx_qh: + switch (MX_VT (fmtsel)) + { + case sel_elem: + op2 = ValueFPR(vt, fmt_mdmx); + result = qh_map_pick(cpu, v1, QH_ELEM(op2, fmtsel), tf); + break; + case sel_vect: + result = qh_vector_pick(cpu, v1, ValueFPR(vt, fmt_mdmx), tf); + break; + case sel_imm: + result = qh_map_pick(cpu, v1, vt, tf); + break; + } + break; + case mdmx_ob: + switch (MX_VT (fmtsel)) + { + case sel_elem: + op2 = ValueFPR(vt, fmt_mdmx); + result = ob_map_pick(cpu, v1, OB_ELEM(op2, fmtsel), tf); + break; + case sel_vect: + result = ob_vector_pick(cpu, v1, ValueFPR(vt, fmt_mdmx), tf); + break; + case sel_imm: + result = ob_map_pick(cpu, v1, vt, tf); + break; + } + break; + default: + Unpredictable (); + } + return result; +} + + +/* Accumulators. */ + +typedef void (*QH_ACC)(signed48 *a, signed16 ts, signed16 tt); + +static void +AccAddAQH(signed48 *a, signed16 ts, signed16 tt) +{ + *a += (signed48)ts + (signed48)tt; +} + +static void +AccAddLQH(signed48 *a, signed16 ts, signed16 tt) +{ + *a = (signed48)ts + (signed48)tt; +} + +static void +AccMulAQH(signed48 *a, signed16 ts, signed16 tt) +{ + *a += (signed48)ts * (signed48)tt; +} + +static void +AccMulLQH(signed48 *a, signed16 ts, signed16 tt) +{ + *a = (signed48)ts * (signed48)tt; +} + +static void +SubMulAQH(signed48 *a, signed16 ts, signed16 tt) +{ + *a -= (signed48)ts * (signed48)tt; +} + +static void +SubMulLQH(signed48 *a, signed16 ts, signed16 tt) +{ + *a = -((signed48)ts * (signed48)tt); +} + +static void +AccSubAQH(signed48 *a, signed16 ts, signed16 tt) +{ + *a += (signed48)ts - (signed48)tt; +} + +static void +AccSubLQH(signed48 *a, signed16 ts, signed16 tt) +{ + *a = (signed48)ts - (signed48)tt; +} + + +typedef void (*OB_ACC)(signed24 *acc, unsigned8 ts, unsigned8 tt); + +static void +AccAddAOB(signed24 *a, unsigned8 ts, unsigned8 tt) +{ + *a += (signed24)ts + (signed24)tt; +} + +static void +AccAddLOB(signed24 *a, unsigned8 ts, unsigned8 tt) +{ + *a = (signed24)ts + (signed24)tt; +} + +static void +AccMulAOB(signed24 *a, unsigned8 ts, unsigned8 tt) +{ + *a += (signed24)ts * (signed24)tt; +} + +static void +AccMulLOB(signed24 *a, unsigned8 ts, unsigned8 tt) +{ + *a = (signed24)ts * (signed24)tt; +} + +static void +SubMulAOB(signed24 *a, unsigned8 ts, unsigned8 tt) +{ + *a -= (signed24)ts * (signed24)tt; +} + +static void +SubMulLOB(signed24 *a, unsigned8 ts, unsigned8 tt) +{ + *a = -((signed24)ts * (signed24)tt); +} + +static void +AccSubAOB(signed24 *a, unsigned8 ts, unsigned8 tt) +{ + *a += (signed24)ts - (signed24)tt; +} + +static void +AccSubLOB(signed24 *a, unsigned8 ts, unsigned8 tt) +{ + *a = (signed24)ts - (signed24)tt; +} + +static void +AccAbsDiffOB(signed24 *a, unsigned8 ts, unsigned8 tt) +{ + unsigned8 t = (ts >= tt ? ts - tt : tt - ts); + *a += (signed24)t; +} + + +/* Dispatch tables for operations that update a CPR. */ + +static const QH_ACC qh_acc[] = { + AccAddAQH, AccAddAQH, AccMulAQH, AccMulLQH, + SubMulAQH, SubMulLQH, AccSubAQH, AccSubLQH, + NULL +}; + +static const OB_ACC ob_acc[] = { + AccAddAOB, AccAddLOB, AccMulAOB, AccMulLOB, + SubMulAOB, SubMulLOB, AccSubAOB, AccSubLOB, + AccAbsDiffOB +}; + + +static void +qh_vector_acc(signed48 a[], unsigned64 v1, unsigned64 v2, QH_ACC acc) +{ + int i; + signed16 h1, h2; + + for (i = 0; i < 4; i++) + { + h1 = (signed16)(v1 & 0xFFFF); v1 >>= 16; + h2 = (signed16)(v2 & 0xFFFF); v2 >>= 16; + (*acc)(&a[i], h1, h2); + } +} + +static void +qh_map_acc(signed48 a[], unsigned64 v1, signed16 h2, QH_ACC acc) +{ + int i; + signed16 h1; + + for (i = 0; i < 4; i++) + { + h1 = (signed16)(v1 & 0xFFFF); v1 >>= 16; + (*acc)(&a[i], h1, h2); + } +} + +static void +ob_vector_acc(signed24 a[], unsigned64 v1, unsigned64 v2, OB_ACC acc) +{ + int i; + unsigned8 b1, b2; + + for (i = 0; i < 8; i++) + { + b1 = v1 & 0xFF; v1 >>= 8; + b2 = v2 & 0xFF; v2 >>= 8; + (*acc)(&a[i], b1, b2); + } +} + +static void +ob_map_acc(signed24 a[], unsigned64 v1, unsigned8 b2, OB_ACC acc) +{ + int i; + unsigned8 b1; + + for (i = 0; i < 8; i++) + { + b1 = v1 & 0xFF; v1 >>= 8; + (*acc)(&a[i], b1, b2); + } +} + + +/* Primary entry for operations that accumulate */ +void +mdmx_acc_op(sim_cpu *cpu, + address_word cia, + int op, + unsigned64 op1, + int vt, + MX_fmtsel fmtsel) +{ + unsigned64 op2; + + switch (MX_FMT (fmtsel)) + { + case mdmx_qh: + switch (MX_VT (fmtsel)) + { + case sel_elem: + op2 = ValueFPR(vt, fmt_mdmx); + qh_map_acc(ACC.qh, op1, QH_ELEM(op2, fmtsel), qh_acc[op]); + break; + case sel_vect: + qh_vector_acc(ACC.qh, op1, ValueFPR(vt, fmt_mdmx), qh_acc[op]); + break; + case sel_imm: + qh_map_acc(ACC.qh, op1, vt, qh_acc[op]); + break; + } + break; + case mdmx_ob: + switch (MX_VT (fmtsel)) + { + case sel_elem: + op2 = ValueFPR(vt, fmt_mdmx); + ob_map_acc(ACC.ob, op1, OB_ELEM(op2, fmtsel), ob_acc[op]); + break; + case sel_vect: + ob_vector_acc(ACC.ob, op1, ValueFPR(vt, fmt_mdmx), ob_acc[op]); + break; + case sel_imm: + ob_map_acc(ACC.ob, op1, vt, ob_acc[op]); + break; + } + break; + default: + Unpredictable (); + } +} + + +/* Reading and writing accumulator (no conversion). */ + +unsigned64 +mdmx_rac_op(sim_cpu *cpu, + address_word cia, + int op, + int fmt) +{ + unsigned64 result; + unsigned int shift; + int i; + + shift = op; /* L = 00, M = 01, H = 10. */ + result = 0; + + switch (fmt) + { + case MX_FMT_QH: + shift <<= 4; /* 16 bits per element. */ + for (i = 3; i >= 0; --i) + { + result <<= 16; + result |= ((ACC.qh[i] >> shift) & 0xFFFF); + } + break; + case MX_FMT_OB: + shift <<= 3; /* 8 bits per element. */ + for (i = 7; i >= 0; --i) + { + result <<= 8; + result |= ((ACC.ob[i] >> shift) & 0xFF); + } + break; + default: + Unpredictable (); + } + return result; +} + +void +mdmx_wacl(sim_cpu *cpu, + address_word cia, + int fmt, + unsigned64 vs, + unsigned64 vt) +{ + int i; + + switch (fmt) + { + case MX_FMT_QH: + for (i = 0; i < 4; i++) + { + signed32 s = (signed16)(vs & 0xFFFF); + ACC.qh[i] = ((signed48)s << 16) | (vt & 0xFFFF); + vs >>= 16; vt >>= 16; + } + break; + case MX_FMT_OB: + for (i = 0; i < 8; i++) + { + signed16 s = (signed8)(vs & 0xFF); + ACC.ob[i] = ((signed24)s << 8) | (vt & 0xFF); + vs >>= 8; vt >>= 8; + } + break; + default: + Unpredictable (); + } +} + +void +mdmx_wach(sim_cpu *cpu, + address_word cia, + int fmt, + unsigned64 vs) +{ + int i; + + switch (fmt) + { + case MX_FMT_QH: + for (i = 0; i < 4; i++) + { + signed32 s = (signed16)(vs & 0xFFFF); + ACC.qh[i] &= ~((signed48)0xFFFF << 32); + ACC.qh[i] |= ((signed48)s << 32); + vs >>= 16; + } + break; + case MX_FMT_OB: + for (i = 0; i < 8; i++) + { + ACC.ob[i] &= ~((signed24)0xFF << 16); + ACC.ob[i] |= ((signed24)(vs & 0xFF) << 16); + vs >>= 8; + } + break; + default: + Unpredictable (); + } +} + + +/* Reading and writing accumulator (rounding conversions). + Enumerating function guarantees s >= 0 for QH ops. */ + +typedef signed16 (*QH_ROUND)(signed48 a, signed16 s); + +#define QH_BIT(n) ((unsigned48)1 << (n)) +#define QH_ONES(n) (((unsigned48)1 << (n))-1) + +static signed16 +RNASQH(signed48 a, signed16 s) +{ + signed48 t; + signed16 result = 0; + + if (s > 48) + result = 0; + else + { + t = (a >> s); + if ((a & QH_BIT(47)) == 0) + { + if (s > 0 && ((a >> (s-1)) & 1) == 1) + t++; + if (t > QH_MAX) + t = QH_MAX; + } + else + { + if (s > 0 && ((a >> (s-1)) & 1) == 1) + { + if (s > 1 && ((unsigned48)a & QH_ONES(s-1)) != 0) + t++; + } + if (t < QH_MIN) + t = QH_MIN; + } + result = (signed16)t; + } + return result; +} + +static signed16 +RNAUQH(signed48 a, signed16 s) +{ + unsigned48 t; + signed16 result; + + if (s > 48) + result = 0; + else if (s == 48) + result = ((unsigned48)a & MASK48) >> 47; + else + { + t = ((unsigned48)a & MASK48) >> s; + if (s > 0 && ((a >> (s-1)) & 1) == 1) + t++; + if (t > 0xFFFF) + t = 0xFFFF; + result = (signed16)t; + } + return result; +} + +static signed16 +RNESQH(signed48 a, signed16 s) +{ + signed48 t; + signed16 result = 0; + + if (s > 47) + result = 0; + else + { + t = (a >> s); + if (s > 0 && ((a >> (s-1)) & 1) == 1) + { + if (s == 1 || (a & QH_ONES(s-1)) == 0) + t += t & 1; + else + t += 1; + } + if ((a & QH_BIT(47)) == 0) + { + if (t > QH_MAX) + t = QH_MAX; + } + else + { + if (t < QH_MIN) + t = QH_MIN; + } + result = (signed16)t; + } + return result; +} + +static signed16 +RNEUQH(signed48 a, signed16 s) +{ + unsigned48 t; + signed16 result; + + if (s > 48) + result = 0; + else if (s == 48) + result = ((unsigned48)a > QH_BIT(47) ? 1 : 0); + else + { + t = ((unsigned48)a & MASK48) >> s; + if (s > 0 && ((a >> (s-1)) & 1) == 1) + { + if (s > 1 && (a & QH_ONES(s-1)) != 0) + t++; + else + t += t & 1; + } + if (t > 0xFFFF) + t = 0xFFFF; + result = (signed16)t; + } + return result; +} + +static signed16 +RZSQH(signed48 a, signed16 s) +{ + signed48 t; + signed16 result = 0; + + if (s > 47) + result = 0; + else + { + t = (a >> s); + if ((a & QH_BIT(47)) == 0) + { + if (t > QH_MAX) + t = QH_MAX; + } + else + { + if (t < QH_MIN) + t = QH_MIN; + } + result = (signed16)t; + } + return result; +} + +static signed16 +RZUQH(signed48 a, signed16 s) +{ + unsigned48 t; + signed16 result = 0; + + if (s > 48) + result = 0; + else if (s == 48) + result = ((unsigned48)a > QH_BIT(47) ? 1 : 0); + else + { + t = ((unsigned48)a & MASK48) >> s; + if (t > 0xFFFF) + t = 0xFFFF; + result = (signed16)t; + } + return result; +} + + +typedef unsigned8 (*OB_ROUND)(signed24 a, unsigned8 s); + +#define OB_BIT(n) ((unsigned24)1 << (n)) +#define OB_ONES(n) (((unsigned24)1 << (n))-1) + +static unsigned8 +RNAUOB(signed24 a, unsigned8 s) +{ + unsigned8 result; + unsigned24 t; + + if (s > 24) + result = 0; + else if (s == 24) + result = ((unsigned24)a & MASK24) >> 23; + else + { + t = ((unsigned24)a & MASK24) >> s; + if (s > 0 && ((a >> (s-1)) & 1) == 1) + t ++; + result = OB_CLAMP(t); + } + return result; +} + +static unsigned8 +RNEUOB(signed24 a, unsigned8 s) +{ + unsigned8 result; + unsigned24 t; + + if (s > 24) + result = 0; + else if (s == 24) + result = (((unsigned24)a & MASK24) > OB_BIT(23) ? 1 : 0); + else + { + t = ((unsigned24)a & MASK24) >> s; + if (s > 0 && ((a >> (s-1)) & 1) == 1) + { + if (s > 1 && (a & OB_ONES(s-1)) != 0) + t++; + else + t += t & 1; + } + result = OB_CLAMP(t); + } + return result; +} + +static unsigned8 +RZUOB(signed24 a, unsigned8 s) +{ + unsigned8 result; + unsigned24 t; + + if (s >= 24) + result = 0; + else + { + t = ((unsigned24)a & MASK24) >> s; + result = OB_CLAMP(t); + } + return result; +} + + +static const QH_ROUND qh_round[] = { + RNASQH, RNAUQH, RNESQH, RNEUQH, RZSQH, RZUQH +}; + +static const OB_ROUND ob_round[] = { + NULL, RNAUOB, NULL, RNEUOB, NULL, RZUOB +}; + + +static unsigned64 +qh_vector_round(sim_cpu *cpu, address_word cia, unsigned64 v2, QH_ROUND round) +{ + unsigned64 result = 0; + int i, s; + signed16 h, h2; + + s = 0; + for (i = 0; i < 4; i++) + { + h2 = (signed16)(v2 & 0xFFFF); + if (h2 >= 0) + h = (*round)(ACC.qh[i], h2); + else + { + UnpredictableResult (); + h = 0xdead; + } + v2 >>= 16; + result |= ((unsigned64)((unsigned16)h) << s); + s += 16; + } + return result; +} + +static unsigned64 +qh_map_round(sim_cpu *cpu, address_word cia, signed16 h2, QH_ROUND round) +{ + unsigned64 result = 0; + int i, s; + signed16 h; + + s = 0; + for (i = 0; i < 4; i++) + { + if (h2 >= 0) + h = (*round)(ACC.qh[i], h2); + else + { + UnpredictableResult (); + h = 0xdead; + } + result |= ((unsigned64)((unsigned16)h) << s); + s += 16; + } + return result; +} + +static unsigned64 +ob_vector_round(sim_cpu *cpu, address_word cia, unsigned64 v2, OB_ROUND round) +{ + unsigned64 result = 0; + int i, s; + unsigned8 b, b2; + + s = 0; + for (i = 0; i < 8; i++) + { + b2 = v2 & 0xFF; v2 >>= 8; + b = (*round)(ACC.ob[i], b2); + result |= ((unsigned64)b << s); + s += 8; + } + return result; +} + +static unsigned64 +ob_map_round(sim_cpu *cpu, address_word cia, unsigned8 b2, OB_ROUND round) +{ + unsigned64 result = 0; + int i, s; + unsigned8 b; + + s = 0; + for (i = 0; i < 8; i++) + { + b = (*round)(ACC.ob[i], b2); + result |= ((unsigned64)b << s); + s += 8; + } + return result; +} + + +unsigned64 +mdmx_round_op(sim_cpu *cpu, + address_word cia, + int rm, + int vt, + MX_fmtsel fmtsel) +{ + unsigned64 op2; + unsigned64 result = 0; + + switch (MX_FMT (fmtsel)) + { + case mdmx_qh: + switch (MX_VT (fmtsel)) + { + case sel_elem: + op2 = ValueFPR(vt, fmt_mdmx); + result = qh_map_round(cpu, cia, QH_ELEM(op2, fmtsel), qh_round[rm]); + break; + case sel_vect: + op2 = ValueFPR(vt, fmt_mdmx); + result = qh_vector_round(cpu, cia, op2, qh_round[rm]); + break; + case sel_imm: + result = qh_map_round(cpu, cia, vt, qh_round[rm]); + break; + } + break; + case mdmx_ob: + switch (MX_VT (fmtsel)) + { + case sel_elem: + op2 = ValueFPR(vt, fmt_mdmx); + result = ob_map_round(cpu, cia, OB_ELEM(op2, fmtsel), ob_round[rm]); + break; + case sel_vect: + op2 = ValueFPR(vt, fmt_mdmx); + result = ob_vector_round(cpu, cia, op2, ob_round[rm]); + break; + case sel_imm: + result = ob_map_round(cpu, cia, vt, ob_round[rm]); + break; + } + break; + default: + Unpredictable (); + } + + return result; +} + + +/* Shuffle operation. */ + +typedef struct { + enum {vs, ss, vt} source; + unsigned int index; +} sh_map; + +static const sh_map ob_shuffle[][8] = { + /* MDMX 2.0 encodings (3-4, 6-7). */ + /* vr5400 encoding (5), otherwise. */ + { }, /* RSVD */ + {{vt,4}, {vs,4}, {vt,5}, {vs,5}, {vt,6}, {vs,6}, {vt,7}, {vs,7}}, /* RSVD */ + {{vt,0}, {vs,0}, {vt,1}, {vs,1}, {vt,2}, {vs,2}, {vt,3}, {vs,3}}, /* RSVD */ + {{vs,0}, {ss,0}, {vs,1}, {ss,1}, {vs,2}, {ss,2}, {vs,3}, {ss,3}}, /* upsl */ + {{vt,1}, {vt,3}, {vt,5}, {vt,7}, {vs,1}, {vs,3}, {vs,5}, {vs,7}}, /* pach */ + {{vt,0}, {vt,2}, {vt,4}, {vt,6}, {vs,0}, {vs,2}, {vs,4}, {vs,6}}, /* pacl */ + {{vt,4}, {vs,4}, {vt,5}, {vs,5}, {vt,6}, {vs,6}, {vt,7}, {vs,7}}, /* mixh */ + {{vt,0}, {vs,0}, {vt,1}, {vs,1}, {vt,2}, {vs,2}, {vt,3}, {vs,3}} /* mixl */ +}; + +static const sh_map qh_shuffle[][4] = { + {{vt,2}, {vs,2}, {vt,3}, {vs,3}}, /* mixh */ + {{vt,0}, {vs,0}, {vt,1}, {vs,1}}, /* mixl */ + {{vt,1}, {vt,3}, {vs,1}, {vs,3}}, /* pach */ + { }, /* RSVD */ + {{vt,1}, {vs,0}, {vt,3}, {vs,2}}, /* bfla */ + { }, /* RSVD */ + {{vt,2}, {vt,3}, {vs,2}, {vs,3}}, /* repa */ + {{vt,0}, {vt,1}, {vs,0}, {vs,1}} /* repb */ +}; + + +unsigned64 +mdmx_shuffle(sim_cpu *cpu, + address_word cia, + int shop, + unsigned64 op1, + unsigned64 op2) +{ + unsigned64 result = 0; + int i, s; + int op; + + if ((shop & 0x3) == 0x1) /* QH format. */ + { + op = shop >> 2; + s = 0; + for (i = 0; i < 4; i++) + { + unsigned64 v; + + switch (qh_shuffle[op][i].source) + { + case vs: + v = op1; + break; + case vt: + v = op2; + break; + default: + Unpredictable (); + v = 0; + } + result |= (((v >> 16*qh_shuffle[op][i].index) & 0xFFFF) << s); + s += 16; + } + } + else if ((shop & 0x1) == 0x0) /* OB format. */ + { + op = shop >> 1; + s = 0; + for (i = 0; i < 8; i++) + { + unsigned8 b; + unsigned int ishift = 8*ob_shuffle[op][i].index; + + switch (ob_shuffle[op][i].source) + { + case vs: + b = (op1 >> ishift) & 0xFF; + break; + case ss: + b = ((op1 >> ishift) & 0x80) ? 0xFF : 0; + break; + case vt: + b = (op2 >> ishift) & 0xFF; + break; + default: + Unpredictable (); + b = 0; + } + result |= ((unsigned64)b << s); + s += 8; + } + } + else + Unpredictable (); + + return result; +} -- cgit v1.1