summaryrefslogtreecommitdiffstats
path: root/binutils-2.17/gas/config/tc-mt.c
diff options
context:
space:
mode:
Diffstat (limited to 'binutils-2.17/gas/config/tc-mt.c')
-rw-r--r--binutils-2.17/gas/config/tc-mt.c538
1 files changed, 0 insertions, 538 deletions
diff --git a/binutils-2.17/gas/config/tc-mt.c b/binutils-2.17/gas/config/tc-mt.c
deleted file mode 100644
index f9a610e0..00000000
--- a/binutils-2.17/gas/config/tc-mt.c
+++ /dev/null
@@ -1,538 +0,0 @@
-/* tc-mt.c -- Assembler for the Morpho Technologies mt .
- Copyright (C) 2005 Free Software Foundation.
-
- This file is part of GAS, the GNU Assembler.
-
- GAS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- GAS is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GAS; see the file COPYING. If not, write to
- the Free Software Foundation, 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
-
-#include <stdio.h>
-#include "as.h"
-#include "dwarf2dbg.h"
-#include "subsegs.h"
-#include "symcat.h"
-#include "opcodes/mt-desc.h"
-#include "opcodes/mt-opc.h"
-#include "cgen.h"
-#include "elf/common.h"
-#include "elf/mt.h"
-#include "libbfd.h"
-
-/* Structure to hold all of the different components
- describing an individual instruction. */
-typedef struct
-{
- const CGEN_INSN * insn;
- const CGEN_INSN * orig_insn;
- CGEN_FIELDS fields;
-#if CGEN_INT_INSN_P
- CGEN_INSN_INT buffer [1];
-#define INSN_VALUE(buf) (*(buf))
-#else
- unsigned char buffer [CGEN_MAX_INSN_SIZE];
-#define INSN_VALUE(buf) (buf)
-#endif
- char * addr;
- fragS * frag;
- int num_fixups;
- fixS * fixups [GAS_CGEN_MAX_FIXUPS];
- int indices [MAX_OPERAND_INSTANCES];
-}
-mt_insn;
-
-
-const char comment_chars[] = ";";
-const char line_comment_chars[] = "#";
-const char line_separator_chars[] = "";
-const char EXP_CHARS[] = "eE";
-const char FLT_CHARS[] = "dD";
-
-/* The target specific pseudo-ops which we support. */
-const pseudo_typeS md_pseudo_table[] =
-{
- { "word", cons, 4 },
- { NULL, NULL, 0 }
-};
-
-
-
-static int no_scheduling_restrictions = 0;
-
-struct option md_longopts[] =
-{
-#define OPTION_NO_SCHED_REST (OPTION_MD_BASE)
- { "nosched", no_argument, NULL, OPTION_NO_SCHED_REST },
-#define OPTION_MARCH (OPTION_MD_BASE + 1)
- { "march", required_argument, NULL, OPTION_MARCH},
- { NULL, no_argument, NULL, 0 },
-};
-size_t md_longopts_size = sizeof (md_longopts);
-
-const char * md_shortopts = "";
-
-/* Mach selected from command line. */
-static int mt_mach = bfd_mach_ms1;
-static unsigned mt_mach_bitmask = 1 << MACH_MS1;
-
-/* Flags to set in the elf header */
-static flagword mt_flags = EF_MT_CPU_MRISC;
-
-/* The architecture to use. */
-enum mt_architectures
- {
- ms1_64_001,
- ms1_16_002,
- ms1_16_003,
- ms2
- };
-
-/* MT architecture we are using for this output file. */
-static enum mt_architectures mt_arch = ms1_16_002;
-
-int
-md_parse_option (int c ATTRIBUTE_UNUSED, char * arg)
-{
- switch (c)
- {
- case OPTION_MARCH:
- if (strcmp (arg, "ms1-64-001") == 0)
- {
- mt_flags = (mt_flags & ~EF_MT_CPU_MASK) | EF_MT_CPU_MRISC;
- mt_mach = bfd_mach_ms1;
- mt_mach_bitmask = 1 << MACH_MS1;
- mt_arch = ms1_64_001;
- }
- else if (strcmp (arg, "ms1-16-002") == 0)
- {
- mt_flags = (mt_flags & ~EF_MT_CPU_MASK) | EF_MT_CPU_MRISC;
- mt_mach = bfd_mach_ms1;
- mt_mach_bitmask = 1 << MACH_MS1;
- mt_arch = ms1_16_002;
- }
- else if (strcmp (arg, "ms1-16-003") == 0)
- {
- mt_flags = (mt_flags & ~EF_MT_CPU_MASK) | EF_MT_CPU_MRISC2;
- mt_mach = bfd_mach_mrisc2;
- mt_mach_bitmask = 1 << MACH_MS1_003;
- mt_arch = ms1_16_003;
- }
- else if (strcmp (arg, "ms2") == 0)
- {
- mt_flags = (mt_flags & ~EF_MT_CPU_MASK) | EF_MT_CPU_MS2;
- mt_mach = bfd_mach_mrisc2;
- mt_mach_bitmask = 1 << MACH_MS2;
- mt_arch = ms2;
- }
- case OPTION_NO_SCHED_REST:
- no_scheduling_restrictions = 1;
- break;
- default:
- return 0;
- }
-
- return 1;
-}
-
-
-void
-md_show_usage (FILE * stream)
-{
- fprintf (stream, _("MT specific command line options:\n"));
- fprintf (stream, _(" -march=ms1-64-001 allow ms1-64-001 instructions\n"));
- fprintf (stream, _(" -march=ms1-16-002 allow ms1-16-002 instructions (default)\n"));
- fprintf (stream, _(" -march=ms1-16-003 allow ms1-16-003 instructions\n"));
- fprintf (stream, _(" -march=ms2 allow ms2 instructions \n"));
- fprintf (stream, _(" -nosched disable scheduling restrictions\n"));
-}
-
-
-void
-md_begin (void)
-{
- /* Initialize the `cgen' interface. */
-
- /* Set the machine number and endian. */
- gas_cgen_cpu_desc = mt_cgen_cpu_open (CGEN_CPU_OPEN_MACHS, mt_mach_bitmask,
- CGEN_CPU_OPEN_ENDIAN,
- CGEN_ENDIAN_BIG,
- CGEN_CPU_OPEN_END);
- mt_cgen_init_asm (gas_cgen_cpu_desc);
-
- /* This is a callback from cgen to gas to parse operands. */
- cgen_set_parse_operand_fn (gas_cgen_cpu_desc, gas_cgen_parse_operand);
-
- /* Set the ELF flags if desired. */
- if (mt_flags)
- bfd_set_private_flags (stdoutput, mt_flags);
-
- /* Set the machine type. */
- bfd_default_set_arch_mach (stdoutput, bfd_arch_mt, mt_mach);
-}
-
-void
-md_assemble (char * str)
-{
- static long delayed_load_register = 0;
- static long prev_delayed_load_register = 0;
- static int last_insn_had_delay_slot = 0;
- static int last_insn_in_noncond_delay_slot = 0;
- static int last_insn_has_load_delay = 0;
- static int last_insn_was_memory_access = 0;
- static int last_insn_was_io_insn = 0;
- static int last_insn_was_arithmetic_or_logic = 0;
- static int last_insn_was_branch_insn = 0;
- static int last_insn_was_conditional_branch_insn = 0;
-
- mt_insn insn;
- char * errmsg;
-
- /* Initialize GAS's cgen interface for a new instruction. */
- gas_cgen_init_parse ();
-
- insn.insn = mt_cgen_assemble_insn
- (gas_cgen_cpu_desc, str, & insn.fields, insn.buffer, & errmsg);
-
- if (!insn.insn)
- {
- as_bad ("%s", errmsg);
- return;
- }
-
- /* Doesn't really matter what we pass for RELAX_P here. */
- gas_cgen_finish_insn (insn.insn, insn.buffer,
- CGEN_FIELDS_BITSIZE (& insn.fields), 1, NULL);
-
-
- /* Handle Scheduling Restrictions. */
- if (!no_scheduling_restrictions)
- {
- /* Detect consecutive Memory Accesses. */
- if (last_insn_was_memory_access
- && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_MEMORY_ACCESS)
- && mt_mach == ms1_64_001)
- as_warn (_("instruction %s may not follow another memory access instruction."),
- CGEN_INSN_NAME (insn.insn));
-
- /* Detect consecutive I/O Instructions. */
- else if (last_insn_was_io_insn
- && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_IO_INSN))
- as_warn (_("instruction %s may not follow another I/O instruction."),
- CGEN_INSN_NAME (insn.insn));
-
- /* Detect consecutive branch instructions. */
- else if (last_insn_was_branch_insn
- && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_BR_INSN))
- as_warn (_("%s may not occupy the delay slot of another branch insn."),
- CGEN_INSN_NAME (insn.insn));
-
- /* Detect data dependencies on delayed loads: memory and input insns. */
- if (last_insn_has_load_delay && delayed_load_register)
- {
- if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR1)
- && insn.fields.f_sr1 == delayed_load_register)
- as_warn (_("operand references R%ld of previous load."),
- insn.fields.f_sr1);
-
- if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR2)
- && insn.fields.f_sr2 == delayed_load_register)
- as_warn (_("operand references R%ld of previous load."),
- insn.fields.f_sr2);
- }
-
- /* Detect JAL/RETI hazard */
- if (mt_mach == ms2
- && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_JAL_HAZARD))
- {
- if ((CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR1)
- && insn.fields.f_sr1 == delayed_load_register)
- || (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR2)
- && insn.fields.f_sr2 == delayed_load_register))
- as_warn (_("operand references R%ld of previous instrutcion."),
- delayed_load_register);
- else if ((CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR1)
- && insn.fields.f_sr1 == prev_delayed_load_register)
- || (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR2)
- && insn.fields.f_sr2 == prev_delayed_load_register))
- as_warn (_("operand references R%ld of instructcion before previous."),
- prev_delayed_load_register);
- }
-
- /* Detect data dependency between conditional branch instruction
- and an immediately preceding arithmetic or logical instruction. */
- if (last_insn_was_arithmetic_or_logic
- && !last_insn_in_noncond_delay_slot
- && (delayed_load_register != 0)
- && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_BR_INSN)
- && mt_arch == ms1_64_001)
- {
- if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR1)
- && insn.fields.f_sr1 == delayed_load_register)
- as_warn (_("conditional branch or jal insn's operand references R%ld of previous arithmetic or logic insn."),
- insn.fields.f_sr1);
-
- if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR2)
- && insn.fields.f_sr2 == delayed_load_register)
- as_warn (_("conditional branch or jal insn's operand references R%ld of previous arithmetic or logic insn."),
- insn.fields.f_sr2);
- }
- }
-
- /* Keep track of details of this insn for processing next insn. */
- last_insn_in_noncond_delay_slot = last_insn_was_branch_insn
- && !last_insn_was_conditional_branch_insn;
-
- last_insn_had_delay_slot =
- CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_DELAY_SLOT);
-
- last_insn_has_load_delay =
- CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_LOAD_DELAY);
-
- last_insn_was_memory_access =
- CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_MEMORY_ACCESS);
-
- last_insn_was_io_insn =
- CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_IO_INSN);
-
- last_insn_was_arithmetic_or_logic =
- CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_AL_INSN);
-
- last_insn_was_branch_insn =
- CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_BR_INSN);
-
- last_insn_was_conditional_branch_insn =
- CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_BR_INSN)
- && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR2);
-
- prev_delayed_load_register = delayed_load_register;
-
- if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRDR))
- delayed_load_register = insn.fields.f_dr;
- else if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRDRRR))
- delayed_load_register = insn.fields.f_drrr;
- else /* Insns has no destination register. */
- delayed_load_register = 0;
-
- /* Generate dwarf2 line numbers. */
- dwarf2_emit_insn (4);
-}
-
-valueT
-md_section_align (segT segment, valueT size)
-{
- int align = bfd_get_section_alignment (stdoutput, segment);
-
- return ((size + (1 << align) - 1) & (-1 << align));
-}
-
-symbolS *
-md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
-{
- return NULL;
-}
-
-int
-md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
- segT segment ATTRIBUTE_UNUSED)
-{
- as_fatal (_("md_estimate_size_before_relax\n"));
- return 1;
-}
-
-/* *fragP has been relaxed to its final size, and now needs to have
- the bytes inside it modified to conform to the new size.
-
- Called after relaxation is finished.
- fragP->fr_type == rs_machine_dependent.
- fragP->fr_subtype is the subtype of what the address relaxed to. */
-
-void
-md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
- segT sec ATTRIBUTE_UNUSED,
- fragS * fragP ATTRIBUTE_UNUSED)
-{
-}
-
-
-/* Functions concerning relocs. */
-
-long
-md_pcrel_from_section (fixS *fixP, segT sec)
-{
- if (fixP->fx_addsy != (symbolS *) NULL
- && (!S_IS_DEFINED (fixP->fx_addsy)
- || S_GET_SEGMENT (fixP->fx_addsy) != sec))
- /* The symbol is undefined (or is defined but not in this section).
- Let the linker figure it out. */
- return 0;
-
- /* Return the address of the opcode - cgen adjusts for opcode size
- itself, to be consistent with the disassembler, which must do
- so. */
- return fixP->fx_where + fixP->fx_frag->fr_address;
-}
-
-
-/* Return the bfd reloc type for OPERAND of INSN at fixup FIXP.
- Returns BFD_RELOC_NONE if no reloc type can be found.
- *FIXP may be modified if desired. */
-
-bfd_reloc_code_real_type
-md_cgen_lookup_reloc (const CGEN_INSN * insn ATTRIBUTE_UNUSED,
- const CGEN_OPERAND * operand,
- fixS * fixP ATTRIBUTE_UNUSED)
-{
- bfd_reloc_code_real_type result;
-
- result = BFD_RELOC_NONE;
-
- switch (operand->type)
- {
- case MT_OPERAND_IMM16O:
- result = BFD_RELOC_16_PCREL;
- fixP->fx_pcrel = 1;
- /* fixP->fx_no_overflow = 1; */
- break;
- case MT_OPERAND_IMM16:
- case MT_OPERAND_IMM16Z:
- /* These may have been processed at parse time. */
- if (fixP->fx_cgen.opinfo != 0)
- result = fixP->fx_cgen.opinfo;
- fixP->fx_no_overflow = 1;
- break;
- case MT_OPERAND_LOOPSIZE:
- result = BFD_RELOC_MT_PCINSN8;
- fixP->fx_pcrel = 1;
- /* Adjust for the delay slot, which is not part of the loop */
- fixP->fx_offset -= 8;
- break;
- default:
- result = BFD_RELOC_NONE;
- break;
- }
-
- return result;
-}
-
-/* Write a value out to the object file, using the appropriate endianness. */
-
-void
-md_number_to_chars (char * buf, valueT val, int n)
-{
- number_to_chars_bigendian (buf, val, n);
-}
-
-/* Turn a string in input_line_pointer into a floating point constant of type
- type, and store the appropriate bytes in *litP. The number of LITTLENUMS
- emitted is stored in *sizeP . An error message is returned, or NULL on OK. */
-
-/* Equal to MAX_PRECISION in atof-ieee.c. */
-#define MAX_LITTLENUMS 6
-
-char *
-md_atof (type, litP, sizeP)
- char type;
- char * litP;
- int * sizeP;
-{
- int prec;
- LITTLENUM_TYPE words [MAX_LITTLENUMS];
- LITTLENUM_TYPE * wordP;
- char * t;
-
- switch (type)
- {
- case 'f':
- case 'F':
- case 's':
- case 'S':
- prec = 2;
- break;
-
- case 'd':
- case 'D':
- case 'r':
- case 'R':
- prec = 4;
- break;
-
- /* FIXME: Some targets allow other format chars for bigger sizes here. */
-
- default:
- * sizeP = 0;
- return _("Bad call to md_atof()");
- }
-
- t = atof_ieee (input_line_pointer, type, words);
- if (t)
- input_line_pointer = t;
- * sizeP = prec * sizeof (LITTLENUM_TYPE);
-
- /* This loops outputs the LITTLENUMs in REVERSE order;
- in accord with the mt endianness. */
- for (wordP = words; prec--;)
- {
- md_number_to_chars (litP, (valueT) (*wordP++), sizeof (LITTLENUM_TYPE));
- litP += sizeof (LITTLENUM_TYPE);
- }
-
- return 0;
-}
-
-/* See whether we need to force a relocation into the output file. */
-
-int
-mt_force_relocation (fixS * fixp ATTRIBUTE_UNUSED)
-{
- return 0;
-}
-
-void
-mt_apply_fix (fixS *fixP, valueT *valueP, segT seg)
-{
- if ((fixP->fx_pcrel != 0) && (fixP->fx_r_type == BFD_RELOC_32))
- fixP->fx_r_type = BFD_RELOC_32_PCREL;
-
- gas_cgen_md_apply_fix (fixP, valueP, seg);
-}
-
-bfd_boolean
-mt_fix_adjustable (fixS * fixP)
-{
- bfd_reloc_code_real_type reloc_type;
-
- if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
- {
- const CGEN_INSN *insn = NULL;
- int opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
- const CGEN_OPERAND *operand;
-
- operand = cgen_operand_lookup_by_num(gas_cgen_cpu_desc, opindex);
- reloc_type = md_cgen_lookup_reloc (insn, operand, fixP);
- }
- else
- reloc_type = fixP->fx_r_type;
-
- if (fixP->fx_addsy == NULL)
- return TRUE;
-
- /* Prevent all adjustments to global symbols. */
- if (S_IS_EXTERNAL (fixP->fx_addsy))
- return FALSE;
-
- if (S_IS_WEAK (fixP->fx_addsy))
- return FALSE;
-
- return 1;
-}