diff options
Diffstat (limited to 'gas/config/tc-xstormy16.c')
-rw-r--r-- | gas/config/tc-xstormy16.c | 653 |
1 files changed, 0 insertions, 653 deletions
diff --git a/gas/config/tc-xstormy16.c b/gas/config/tc-xstormy16.c deleted file mode 100644 index 446ac389c56..00000000000 --- a/gas/config/tc-xstormy16.c +++ /dev/null @@ -1,653 +0,0 @@ -/* tc-xstormy16.c -- Assembler for the Sanyo XSTORMY16. - Copyright (C) 2000, 2001, 2002 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 "subsegs.h" -#include "symcat.h" -#include "opcodes/xstormy16-desc.h" -#include "opcodes/xstormy16-opc.h" -#include "cgen.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]; -} -xstormy16_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"; - -#define O_fptr_symbol (O_max + 1) - -#define XSTORMY16_SHORTOPTS "" -const char * md_shortopts = XSTORMY16_SHORTOPTS; - -struct option md_longopts[] = -{ - {NULL, no_argument, NULL, 0} -}; -size_t md_longopts_size = sizeof (md_longopts); - -int -md_parse_option (c, arg) - int c ATTRIBUTE_UNUSED; - char * arg ATTRIBUTE_UNUSED; -{ - return 0; -} - -void -md_show_usage (stream) - FILE * stream; -{ - fprintf (stream, _(" XSTORMY16 specific command line options:\n")); -} - -/* The target specific pseudo-ops which we support. */ -const pseudo_typeS md_pseudo_table[] = -{ - { "word", cons, 4 }, - { NULL, NULL, 0 } -}; - - -void -md_begin () -{ - /* Initialize the `cgen' interface. */ - - /* Set the machine number and endian. */ - gas_cgen_cpu_desc = xstormy16_cgen_cpu_open (CGEN_CPU_OPEN_MACHS, 0, - CGEN_CPU_OPEN_ENDIAN, - CGEN_ENDIAN_LITTLE, - CGEN_CPU_OPEN_END); - xstormy16_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); -} - -void -md_assemble (str) - char * str; -{ - xstormy16_insn insn; - char * errmsg; - - /* Initialize GAS's cgen interface for a new instruction. */ - gas_cgen_init_parse (); - - insn.insn = xstormy16_cgen_assemble_insn - (gas_cgen_cpu_desc, str, & insn.fields, insn.buffer, & errmsg); - - if (!insn.insn) - { - as_bad (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), 0, NULL); -} - -void -md_operand (e) - expressionS * e; -{ - if (*input_line_pointer != '@') - return; - - if (strncmp (input_line_pointer+1, "fptr", 4) == 0) - { - input_line_pointer += 5; - SKIP_WHITESPACE (); - if (*input_line_pointer != '(') - { - as_bad ("Expected '('"); - goto err; - } - input_line_pointer++; - - expression (e); - - if (*input_line_pointer != ')') - { - as_bad ("Missing ')'"); - goto err; - } - input_line_pointer++; - - if (e->X_op != O_symbol) - as_bad ("Not a symbolic expression"); - else - e->X_op = O_fptr_symbol; - } - - return; - err: - ignore_rest_of_line (); -} - -/* Called while parsing data to create a fixup. - Create BFD_RELOC_XSTORMY16_FPTR16 relocations. */ - -void -xstormy16_cons_fix_new (f, where, nbytes, exp) - fragS *f; - int where; - int nbytes; - expressionS *exp; -{ - bfd_reloc_code_real_type code; - fixS *fix; - - if (exp->X_op == O_fptr_symbol) - { - if (nbytes != 2) - { - as_bad ("unsupported fptr fixup size %d", nbytes); - return; - } - exp->X_op = O_symbol; - code = BFD_RELOC_XSTORMY16_FPTR16; - } - else if (nbytes == 1) - code = BFD_RELOC_8; - else if (nbytes == 2) - code = BFD_RELOC_16; - else if (nbytes == 4) - code = BFD_RELOC_32; - else - { - as_bad ("unsupported fixup size %d", nbytes); - return; - } - - fix = fix_new_exp (f, where, nbytes, exp, 0, code); -} - -/* Called while parsing an instruction to create a fixup. - Create BFD_RELOC_XSTORMY16_FPTR16 relocations. */ - -fixS * -xstormy16_cgen_record_fixup_exp (frag, where, insn, length, operand, opinfo, exp) - fragS * frag; - int where; - const CGEN_INSN * insn; - int length; - const CGEN_OPERAND * operand; - int opinfo; - expressionS * exp; -{ - fixS *fixP; - operatorT op = exp->X_op; - - if (op == O_fptr_symbol) - exp->X_op = O_symbol; - - fixP = gas_cgen_record_fixup_exp (frag, where, insn, length, - operand, opinfo, exp); - - if (op == O_fptr_symbol) - { - if (operand->type != XSTORMY16_OPERAND_IMM16) - as_bad ("unsupported fptr fixup"); - else - { - fixP->fx_r_type = BFD_RELOC_XSTORMY16_FPTR16; - fixP->fx_where += 2; - } - } - - return fixP; -} - -valueT -md_section_align (segment, size) - segT segment; - valueT size; -{ - int align = bfd_get_section_alignment (stdoutput, segment); - return ((size + (1 << align) - 1) & (-1 << align)); -} - -symbolS * -md_undefined_symbol (name) - char * name ATTRIBUTE_UNUSED; -{ - return 0; -} - -/* Return an initial guess of the length by which a fragment must grow to - hold a branch to reach its destination. - Also updates fr_type/fr_subtype as necessary. - - Called just before doing relaxation. - Any symbol that is now undefined will not become defined. - The guess for fr_var is ACTUALLY the growth beyond fr_fix. - Whatever we do to grow fr_fix or fr_var contributes to our returned value. - Although it may not be explicit in the frag, pretend fr_var starts with a - 0 value. */ - -int -md_estimate_size_before_relax (fragP, segment) - fragS * fragP ATTRIBUTE_UNUSED; - segT segment ATTRIBUTE_UNUSED; -{ - /* No assembler relaxation is defined (or necessary) for this port. */ - abort (); -} - -/* *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 (abfd, sec, fragP) - bfd * abfd ATTRIBUTE_UNUSED; - segT sec ATTRIBUTE_UNUSED; - fragS * fragP ATTRIBUTE_UNUSED; -{ - /* No assembler relaxation is defined (or necessary) for this port. */ - abort (); -} - -/* Functions concerning relocs. */ - -/* The location from which a PC relative jump should be calculated, - given a PC relative reloc. */ - -long -md_pcrel_from_section (fixP, sec) - 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 fixP->fx_frag->fr_address + fixP->fx_where; -} - -/* 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 (insn, operand, fixP) - const CGEN_INSN * insn ATTRIBUTE_UNUSED; - const CGEN_OPERAND * operand; - fixS * fixP; -{ - switch (operand->type) - { - case XSTORMY16_OPERAND_IMM2: - case XSTORMY16_OPERAND_IMM3: - case XSTORMY16_OPERAND_IMM3B: - case XSTORMY16_OPERAND_IMM4: - case XSTORMY16_OPERAND_IMM12: - case XSTORMY16_OPERAND_HMEM8: - return BFD_RELOC_NONE; - - case XSTORMY16_OPERAND_IMM8: - case XSTORMY16_OPERAND_LMEM8: - return fixP->fx_pcrel ? BFD_RELOC_8_PCREL : BFD_RELOC_8; - - case XSTORMY16_OPERAND_IMM16: - fixP->fx_where += 2; - return fixP->fx_pcrel ? BFD_RELOC_16_PCREL : BFD_RELOC_16; - - case XSTORMY16_OPERAND_ABS24: - return BFD_RELOC_XSTORMY16_24; - - case XSTORMY16_OPERAND_REL8_2: - case XSTORMY16_OPERAND_REL8_4: - fixP->fx_pcrel = 1; - return BFD_RELOC_8_PCREL; - - case XSTORMY16_OPERAND_REL12: - fixP->fx_where += 2; - /* Fall through... */ - case XSTORMY16_OPERAND_REL12A: - fixP->fx_pcrel = 1; - return BFD_RELOC_XSTORMY16_REL_12; - - default : /* avoid -Wall warning */ - abort (); - } -} - -/* See whether we need to force a relocation into the output file. - This is used to force out switch and PC relative relocations when - relaxing. */ - -int -xstormy16_force_relocation (fix) - fixS * fix; -{ - switch (fix->fx_r_type) - { - case BFD_RELOC_XSTORMY16_FPTR16: - case BFD_RELOC_VTABLE_INHERIT: - case BFD_RELOC_VTABLE_ENTRY: - return 1; - - default: - return 0; - } -} - -/* Return true if a relocation against a symbol may be replaced with - a relocation against section+offset. */ - -boolean -xstormy16_fix_adjustable (fixP) - fixS * fixP; -{ - if (fixP->fx_addsy == NULL) - return 1; - - /* Prevent all adjustments to global symbols. */ - if (S_IS_EXTERN (fixP->fx_addsy)) - return 0; - - if (S_IS_WEAK (fixP->fx_addsy)) - return 0; - - /* We need the symbol name for the VTABLE entries. */ - if ( fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT - || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY) - return 0; - - return ! xstormy16_force_relocation (fixP); -} - -/* This is a copy of gas_cgen_md_apply_fix3, with some enhancements to - do various things that would not be valid for all ports. */ - -void -xstormy16_md_apply_fix3 (fixP, valueP, seg) - fixS * fixP; - valueT * valueP; - segT seg ATTRIBUTE_UNUSED; -{ - char *where = fixP->fx_frag->fr_literal + fixP->fx_where; - valueT value; - /* Canonical name, since used a lot. */ - CGEN_CPU_DESC cd = gas_cgen_cpu_desc; - - /* This port has pc-relative relocs and DIFF_EXPR_OK defined, so - it must deal with turning a BFD_RELOC_{8,16,32,64} into a - BFD_RELOC_*_PCREL for the case of - - .word something-. - */ - if (fixP->fx_pcrel) - switch (fixP->fx_r_type) - { - case BFD_RELOC_8: - fixP->fx_r_type = BFD_RELOC_8_PCREL; - break; - case BFD_RELOC_16: - fixP->fx_r_type = BFD_RELOC_16_PCREL; - break; - case BFD_RELOC_32: - fixP->fx_r_type = BFD_RELOC_32_PCREL; - break; - case BFD_RELOC_64: - fixP->fx_r_type = BFD_RELOC_64_PCREL; - break; - default: - break; - } - - /* FIXME FIXME FIXME: The value we are passed in *valuep includes - the symbol values. Since we are using BFD_ASSEMBLER, if we are - doing this relocation the code in write.c is going to call - bfd_install_relocation, which is also going to use the symbol - value. That means that if the reloc is fully resolved we want to - use *valuep since bfd_install_relocation is not being used. - However, if the reloc is not fully resolved we do not want to use - *valuep, and must use fx_offset instead. However, if the reloc - is PC relative, we do want to use *valuep since it includes the - result of md_pcrel_from. This is confusing. */ - - if (fixP->fx_addsy == (symbolS *) NULL) - { - value = *valueP; - fixP->fx_done = 1; - } - else if (fixP->fx_pcrel) - value = *valueP; - else - { - value = fixP->fx_offset; - if (fixP->fx_subsy != (symbolS *) NULL) - { - if (S_GET_SEGMENT (fixP->fx_subsy) == absolute_section) - value -= S_GET_VALUE (fixP->fx_subsy); - else - { - /* We don't actually support subtracting a symbol. */ - as_bad_where (fixP->fx_file, fixP->fx_line, - _("expression too complex")); - } - } - } - - if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED) - { - int opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED; - const CGEN_OPERAND *operand = cgen_operand_lookup_by_num (cd, opindex); - const char *errmsg; - bfd_reloc_code_real_type reloc_type; - CGEN_FIELDS *fields = alloca (CGEN_CPU_SIZEOF_FIELDS (cd)); - const CGEN_INSN *insn = fixP->fx_cgen.insn; - - /* If the reloc has been fully resolved finish the operand here. */ - /* FIXME: This duplicates the capabilities of code in BFD. */ - if (fixP->fx_done) - { - CGEN_CPU_SET_FIELDS_BITSIZE (cd) (fields, CGEN_INSN_BITSIZE (insn)); - CGEN_CPU_SET_VMA_OPERAND (cd) (cd, opindex, fields, (bfd_vma) value); - -#if CGEN_INT_INSN_P - { - CGEN_INSN_INT insn_value = - cgen_get_insn_value (cd, where, CGEN_INSN_BITSIZE (insn)); - - /* ??? 0 is passed for `pc'. */ - errmsg = CGEN_CPU_INSERT_OPERAND (cd) (cd, opindex, fields, - &insn_value, (bfd_vma) 0); - cgen_put_insn_value (cd, where, CGEN_INSN_BITSIZE (insn), - insn_value); - } -#else - /* ??? 0 is passed for `pc'. */ - errmsg = CGEN_CPU_INSERT_OPERAND (cd) (cd, opindex, fields, where, - (bfd_vma) 0); -#endif - if (errmsg) - as_bad_where (fixP->fx_file, fixP->fx_line, "%s", errmsg); - } - - if (fixP->fx_done) - return; - - /* The operand isn't fully resolved. Determine a BFD reloc value - based on the operand information and leave it to - bfd_install_relocation. Note that this doesn't work when - partial_inplace == false. */ - - reloc_type = md_cgen_lookup_reloc (insn, operand, fixP); - if (reloc_type != BFD_RELOC_NONE) - { - fixP->fx_r_type = reloc_type; - } - else - { - as_bad_where (fixP->fx_file, fixP->fx_line, - _("unresolved expression that must be resolved")); - fixP->fx_done = 1; - return; - } - } - else if (fixP->fx_done) - { - /* We're finished with this fixup. Install it because - bfd_install_relocation won't be called to do it. */ - switch (fixP->fx_r_type) - { - case BFD_RELOC_8: - md_number_to_chars (where, value, 1); - break; - case BFD_RELOC_16: - md_number_to_chars (where, value, 2); - break; - case BFD_RELOC_32: - md_number_to_chars (where, value, 4); - break; - case BFD_RELOC_64: - md_number_to_chars (where, value, 8); - break; - default: - as_bad_where (fixP->fx_file, fixP->fx_line, - _("internal error: can't install fix for reloc type %d (`%s')"), - fixP->fx_r_type, bfd_get_reloc_code_name (fixP->fx_r_type)); - break; - } - } - else - { - /* bfd_install_relocation will be called to finish things up. */ - } - - /* This is a RELA port. Thus, it does not need to store a - value if it is going to make a reloc. What's more, when - assembling a line like - - .byte global-0x7f00 - - we'll get a spurious error message if we try to stuff 0x7f00 into - the byte. */ - if (! fixP->fx_done) - *valueP = 0; - - /* Tuck `value' away for use by tc_gen_reloc. - See the comment describing fx_addnumber in write.h. - This field is misnamed (or misused :-). */ - fixP->fx_addnumber = value; -} - - -/* Write a value out to the object file, using the appropriate endianness. */ - -void -md_number_to_chars (buf, val, n) - char * buf; - valueT val; - int n; -{ - number_to_chars_littleendian (buf, val, n); -} - -/* Turn a string in input_line_pointer into a floating point constant of type - type, and store the appropriate bytes in *litP. The number of LITTLENUMS - emitted is stored in *sizeP . An error message is returned, or NULL on OK. -*/ - -/* 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': - prec = 2; - break; - - case 'd': - case 'D': - 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); - - *sizeP = prec * sizeof (LITTLENUM_TYPE); - /* This loops outputs the LITTLENUMs in REVERSE order; in accord with - the littleendianness of the processor. */ - for (wordP = words + prec - 1; prec--;) - { - md_number_to_chars (litP, (valueT) (*wordP--), sizeof (LITTLENUM_TYPE)); - litP += sizeof (LITTLENUM_TYPE); - } - - return 0; -} |