Back to index

cell-binutils  2.17cvs20070401
tc-m32c.c
Go to the documentation of this file.
00001 /* tc-m32c.c -- Assembler for the Renesas M32C.
00002    Copyright (C) 2005, 2006 Free Software Foundation.
00003    Contributed by RedHat.
00004 
00005    This file is part of GAS, the GNU Assembler.
00006 
00007    GAS is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 2, or (at your option)
00010    any later version.
00011 
00012    GAS is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with GAS; see the file COPYING.  If not, write to
00019    the Free Software Foundation, 59 Temple Place - Suite 330,
00020    Boston, MA 02111-1307, USA.  */
00021 
00022 #include "as.h"
00023 #include "subsegs.h"     
00024 #include "symcat.h"
00025 #include "opcodes/m32c-desc.h"
00026 #include "opcodes/m32c-opc.h"
00027 #include "cgen.h"
00028 #include "elf/common.h"
00029 #include "elf/m32c.h"
00030 #include "libbfd.h"
00031 #include "safe-ctype.h"
00032 
00033 /* Structure to hold all of the different components
00034    describing an individual instruction.  */
00035 typedef struct
00036 {
00037   const CGEN_INSN *  insn;
00038   const CGEN_INSN *  orig_insn;
00039   CGEN_FIELDS        fields;
00040 #if CGEN_INT_INSN_P
00041   CGEN_INSN_INT         buffer [1];
00042 #define INSN_VALUE(buf) (*(buf))
00043 #else
00044   unsigned char         buffer [CGEN_MAX_INSN_SIZE];
00045 #define INSN_VALUE(buf) (buf)
00046 #endif
00047   char *             addr;
00048   fragS *            frag;
00049   int                   num_fixups;
00050   fixS *                fixups [GAS_CGEN_MAX_FIXUPS];
00051   int                   indices [MAX_OPERAND_INSTANCES];
00052 }
00053 m32c_insn;
00054 
00055 #define rl_for(_insn) (CGEN_ATTR_CGEN_INSN_RL_TYPE_VALUE (&((_insn).insn->base->attrs)))
00056 #define relaxable(_insn) (CGEN_ATTR_CGEN_INSN_RELAXABLE_VALUE (&((_insn).insn->base->attrs)))
00057 
00058 const char comment_chars[]        = ";";
00059 const char line_comment_chars[]   = "#";
00060 const char line_separator_chars[] = "|";
00061 const char EXP_CHARS[]            = "eE";
00062 const char FLT_CHARS[]            = "dD";
00063 
00064 #define M32C_SHORTOPTS ""
00065 const char * md_shortopts = M32C_SHORTOPTS;
00066 
00067 /* assembler options */
00068 #define OPTION_CPU_M16C            (OPTION_MD_BASE)
00069 #define OPTION_CPU_M32C        (OPTION_MD_BASE + 1)
00070 #define OPTION_LINKRELAX       (OPTION_MD_BASE + 2)
00071 
00072 struct option md_longopts[] =
00073 {
00074   { "m16c",       no_argument,           NULL, OPTION_CPU_M16C   },
00075   { "m32c",       no_argument,           NULL, OPTION_CPU_M32C   },
00076   { "relax",      no_argument,           NULL, OPTION_LINKRELAX   },
00077   {NULL, no_argument, NULL, 0}
00078 };
00079 size_t md_longopts_size = sizeof (md_longopts);
00080 
00081 /* Default machine */
00082 
00083 #define DEFAULT_MACHINE bfd_mach_m16c
00084 #define DEFAULT_FLAGS       EF_M32C_CPU_M16C
00085 
00086 static unsigned long m32c_mach = bfd_mach_m16c;
00087 static int cpu_mach = (1 << MACH_M16C);
00088 static int insn_size;
00089 static int m32c_relax = 0;
00090 
00091 /* Flags to set in the elf header */
00092 static flagword m32c_flags = DEFAULT_FLAGS;
00093 
00094 static char default_isa = 1 << (7 - ISA_M16C);
00095 static CGEN_BITSET m32c_isa = {1, & default_isa};
00096 
00097 static void
00098 set_isa (enum isa_attr isa_num)
00099 {
00100   cgen_bitset_set (& m32c_isa, isa_num);
00101 }
00102 
00103 static void s_bss (int);
00104 
00105 int
00106 md_parse_option (int c, char * arg ATTRIBUTE_UNUSED)
00107 {
00108   switch (c)
00109     {
00110     case OPTION_CPU_M16C:
00111       m32c_flags = (m32c_flags & ~EF_M32C_CPU_MASK) | EF_M32C_CPU_M16C;
00112       m32c_mach = bfd_mach_m16c;
00113       cpu_mach = (1 << MACH_M16C);
00114       set_isa (ISA_M16C);
00115       break;
00116 
00117     case OPTION_CPU_M32C:
00118       m32c_flags = (m32c_flags & ~EF_M32C_CPU_MASK) | EF_M32C_CPU_M32C;
00119       m32c_mach = bfd_mach_m32c;
00120       cpu_mach = (1 << MACH_M32C);
00121       set_isa (ISA_M32C);
00122       break;
00123 
00124     case OPTION_LINKRELAX:
00125       m32c_relax = 1;
00126       break;
00127 
00128     default:
00129       return 0;
00130     }
00131   return 1;
00132 }
00133 
00134 void
00135 md_show_usage (FILE * stream)
00136 {
00137   fprintf (stream, _(" M32C specific command line options:\n"));
00138 } 
00139 
00140 static void
00141 s_bss (int ignore ATTRIBUTE_UNUSED)
00142 {
00143   int temp;
00144 
00145   temp = get_absolute_expression ();
00146   subseg_set (bss_section, (subsegT) temp);
00147   demand_empty_rest_of_line ();
00148 }
00149 
00150 /* The target specific pseudo-ops which we support.  */
00151 const pseudo_typeS md_pseudo_table[] =
00152 {
00153   { "bss",    s_bss,               0},
00154   { "3byte",  cons,         3 },
00155   { "word",   cons,         4 },
00156   { NULL,     NULL,         0 }
00157 };
00158 
00159 
00160 void
00161 md_begin (void)
00162 {
00163   /* Initialize the `cgen' interface.  */
00164 
00165   /* Set the machine number and endian.  */
00166   gas_cgen_cpu_desc = m32c_cgen_cpu_open (CGEN_CPU_OPEN_MACHS, cpu_mach,
00167                                      CGEN_CPU_OPEN_ENDIAN,
00168                                      CGEN_ENDIAN_BIG,
00169                                      CGEN_CPU_OPEN_ISAS, & m32c_isa,
00170                                      CGEN_CPU_OPEN_END);
00171 
00172   m32c_cgen_init_asm (gas_cgen_cpu_desc);
00173 
00174   /* This is a callback from cgen to gas to parse operands.  */
00175   cgen_set_parse_operand_fn (gas_cgen_cpu_desc, gas_cgen_parse_operand);
00176 
00177   /* Set the ELF flags if desired. */
00178   if (m32c_flags)
00179     bfd_set_private_flags (stdoutput, m32c_flags);
00180 
00181   /* Set the machine type */
00182   bfd_default_set_arch_mach (stdoutput, bfd_arch_m32c, m32c_mach);
00183 
00184   insn_size = 0;
00185 }
00186 
00187 void
00188 m32c_md_end (void)
00189 {
00190   int i, n_nops;
00191 
00192   if (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE)
00193     {
00194       /* Pad with nops for objdump.  */
00195       n_nops = (32 - ((insn_size) % 32)) / 8;
00196       for (i = 1; i <= n_nops; i++)
00197        md_assemble ("nop");
00198     }
00199 }
00200 
00201 void
00202 m32c_start_line_hook (void)
00203 {
00204 #if 0 /* not necessary....handled in the .cpu file */
00205   char *s = input_line_pointer;
00206   char *sg;
00207 
00208   for (s = input_line_pointer ; s && s[0] != '\n'; s++)
00209     {
00210       if (s[0] == ':')
00211        {
00212          /* Remove :g suffix.  Squeeze out blanks.  */
00213          if (s[1] == 'g')
00214            {
00215              for (sg = s - 1; sg && sg >= input_line_pointer; sg--)
00216               {
00217                 sg[2] = sg[0];
00218               }
00219              sg[1] = ' ';
00220              sg[2] = ' ';
00221              input_line_pointer += 2;
00222            }
00223        }
00224     }
00225 #endif
00226 }
00227 
00228 /* Process [[indirect-operands]] in instruction str.  */
00229 
00230 static bfd_boolean
00231 m32c_indirect_operand (char *str)
00232 {
00233   char *new_str;
00234   char *s;
00235   char *ns;
00236   int ns_len;
00237   char *ns_end;
00238   enum indirect_type {none, relative, absolute} ;
00239   enum indirect_type indirection [3] = { none, none, none };
00240   int brace_n [3] = { 0, 0, 0 };
00241   int operand;
00242 
00243   s = str;
00244   operand = 1;
00245   for (s = str; *s; s++)
00246     {
00247       if (s[0] == ',')
00248        operand = 2;
00249       /* [abs] where abs is not a0 or a1  */
00250       if (s[1] == '[' && ! (s[2] == 'a' && (s[3] == '0' || s[3] == '1'))
00251          && (ISBLANK (s[0]) || s[0] == ','))
00252        indirection[operand] = absolute;
00253       if (s[0] == ']' && s[1] == ']')
00254        indirection[operand] = relative;
00255       if (s[0] == '[' && s[1] == '[')
00256        indirection[operand] = relative;
00257     }
00258    
00259   if (indirection[1] == none && indirection[2] == none)
00260     return FALSE;
00261   
00262   operand = 1;
00263   ns_len = strlen (str);
00264   new_str = (char*) xmalloc (ns_len);
00265   ns = new_str;
00266   ns_end = ns + ns_len;
00267  
00268   for (s = str; *s; s++)
00269     {
00270       if (s[0] == ',')
00271        operand = 2;
00272  
00273       if (s[0] == '[' && ! brace_n[operand])
00274        {
00275          brace_n[operand] += 1;
00276          /* Squeeze [[ to [ if this is an indirect operand.  */
00277          if (indirection[operand] != none)
00278            continue;
00279        }
00280  
00281       else if (s[0] == '[' && brace_n[operand])
00282        {
00283          brace_n[operand] += 1;
00284        }
00285       else if (s[0] == ']' && s[1] == ']' && indirection[operand] == relative)
00286        {
00287          s += 1;            /* skip one ].  */
00288          brace_n[operand] -= 2; /* allow for 2 [.  */
00289        }
00290       else if (s[0] == ']' && indirection[operand] == absolute)
00291        {
00292          brace_n[operand] -= 1;
00293          continue;          /* skip closing ].  */
00294        }
00295       else if (s[0] == ']')
00296        {
00297          brace_n[operand] -= 1;
00298        }
00299       *ns = s[0];
00300       ns += 1;
00301       if (ns >= ns_end)
00302        return FALSE;
00303       if (s[0] == 0)
00304        break;
00305     }
00306   *ns = '\0';
00307   for (operand = 1; operand <= 2; operand++)
00308     if (brace_n[operand])
00309       {
00310        fprintf (stderr, "Unmatched [[operand-%d]] %d\n", operand, brace_n[operand]);
00311       }
00312        
00313   if (indirection[1] != none && indirection[2] != none)
00314     md_assemble ("src-dest-indirect");
00315   else if (indirection[1] != none)
00316     md_assemble ("src-indirect");
00317   else if (indirection[2] != none)
00318     md_assemble ("dest-indirect");
00319 
00320   md_assemble (new_str);
00321   free (new_str);
00322   return TRUE;
00323 }
00324 
00325 void
00326 md_assemble (char * str)
00327 {
00328   static int last_insn_had_delay_slot = 0;
00329   m32c_insn insn;
00330   char *    errmsg;
00331   finished_insnS results;
00332   int rl_type;
00333 
00334   if (m32c_mach == bfd_mach_m32c && m32c_indirect_operand (str))
00335     return;
00336 
00337   /* Initialize GAS's cgen interface for a new instruction.  */
00338   gas_cgen_init_parse ();
00339 
00340   insn.insn = m32c_cgen_assemble_insn
00341     (gas_cgen_cpu_desc, str, & insn.fields, insn.buffer, & errmsg);
00342   
00343   if (!insn.insn)
00344     {
00345       as_bad ("%s", errmsg);
00346       return;
00347     }
00348 
00349   results.num_fixups = 0;
00350   /* Doesn't really matter what we pass for RELAX_P here.  */
00351   gas_cgen_finish_insn (insn.insn, insn.buffer,
00352                      CGEN_FIELDS_BITSIZE (& insn.fields), 1, &results);
00353 
00354   last_insn_had_delay_slot
00355     = CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_DELAY_SLOT);
00356   insn_size = CGEN_INSN_BITSIZE(insn.insn);
00357 
00358   rl_type = rl_for (insn);
00359 
00360   /* We have to mark all the jumps, because we need to adjust them
00361      when we delete bytes, but we only need to mark the displacements
00362      if they're symbolic - if they're not, we've already picked the
00363      shortest opcode by now.  The linker, however, will still have to
00364      check any operands to see if they're the displacement type, since
00365      we don't know (nor record) *which* operands are relaxable.  */
00366   if (m32c_relax
00367       && rl_type != RL_TYPE_NONE
00368       && (rl_type == RL_TYPE_JUMP || results.num_fixups)
00369       && !relaxable (insn))
00370     {
00371       int reloc = 0;
00372       int addend = results.num_fixups + 16 * insn_size/8;
00373 
00374       switch (rl_for (insn))
00375        {
00376        case RL_TYPE_JUMP:  reloc = BFD_RELOC_M32C_RL_JUMP;  break;
00377        case RL_TYPE_1ADDR: reloc = BFD_RELOC_M32C_RL_1ADDR; break;
00378        case RL_TYPE_2ADDR: reloc = BFD_RELOC_M32C_RL_2ADDR; break;
00379        }
00380       if (insn.insn->base->num == M32C_INSN_JMP16_S
00381          || insn.insn->base->num == M32C_INSN_JMP32_S)
00382        addend = 0x10;
00383 
00384       fix_new (results.frag,
00385               results.addr - results.frag->fr_literal,
00386               0, abs_section_sym, addend, 0,
00387               reloc);
00388     }
00389 }
00390 
00391 /* The syntax in the manual says constants begin with '#'.
00392    We just ignore it.  */
00393 
00394 void 
00395 md_operand (expressionS * exp)
00396 {
00397   /* In case of a syntax error, escape back to try next syntax combo. */
00398   if (exp->X_op == O_absent)
00399     gas_cgen_md_operand (exp);
00400 }
00401 
00402 valueT
00403 md_section_align (segT segment, valueT size)
00404 {
00405   int align = bfd_get_section_alignment (stdoutput, segment);
00406   return ((size + (1 << align) - 1) & (-1 << align));
00407 }
00408 
00409 symbolS *
00410 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
00411 {
00412   return 0;
00413 }
00414 
00415 const relax_typeS md_relax_table[] =
00416 {
00417   /* The fields are:
00418      1) most positive reach of this state,
00419      2) most negative reach of this state,
00420      3) how many bytes this mode will have in the variable part of the frag
00421      4) which index into the table to try if we can't fit into this one.  */
00422 
00423   /* 0 */ {     0,      0, 0,  0 }, /* unused */
00424   /* 1 */ {     0,      0, 0,  0 }, /* marker for "don't know yet" */
00425 
00426   /* 2 */ {   127,   -128, 2,  3 }, /* jcnd16_5.b */
00427   /* 3 */ { 32767, -32768, 5,  4 }, /* jcnd16_5.w */
00428   /* 4 */ {     0,      0, 6,  0 }, /* jcnd16_5.a */
00429 
00430   /* 5 */ {   127,   -128, 2,  6 }, /* jcnd16.b */
00431   /* 6 */ { 32767, -32768, 5,  7 }, /* jcnd16.w */
00432   /* 7 */ {     0,      0, 6,  0 }, /* jcnd16.a */
00433 
00434   /* 8 */ {     8,      1, 1,  9 }, /* jmp16.s */
00435   /* 9 */ {   127,   -128, 2, 10 }, /* jmp16.b */
00436  /* 10 */ { 32767, -32768, 3, 11 }, /* jmp16.w */
00437  /* 11 */ {     0,      0, 4,  0 }, /* jmp16.a */
00438 
00439  /* 12 */ {   127,   -128, 2, 13 }, /* jcnd32.b */
00440  /* 13 */ { 32767, -32768, 5, 14 }, /* jcnd32.w */
00441  /* 14 */ {     0,      0, 6,  0 }, /* jcnd32.a */
00442 
00443  /* 15 */ {     8,      1, 1, 16 }, /* jmp32.s */
00444  /* 16 */ {   127,   -128, 2, 17 }, /* jmp32.b */
00445  /* 17 */ { 32767, -32768, 3, 18 }, /* jmp32.w */
00446  /* 18 */ {     0,      0, 4,  0 }, /* jmp32.a */
00447 
00448  /* 19 */ { 32767, -32768, 3, 20 }, /* jsr16.w */
00449  /* 20 */ {     0,      0, 4,  0 }, /* jsr16.a */
00450  /* 21 */ { 32767, -32768, 3, 11 }, /* jsr32.w */
00451  /* 22 */ {     0,      0, 4,  0 }, /* jsr32.a */
00452 
00453  /* 23 */ {     0,      0, 3,  0 }, /* adjnz pc8 */
00454  /* 24 */ {     0,      0, 4,  0 }, /* adjnz disp8 pc8 */
00455  /* 25 */ {     0,      0, 5,  0 }, /* adjnz disp16 pc8 */
00456  /* 26 */ {     0,      0, 6,  0 }  /* adjnz disp24 pc8 */
00457 };
00458 
00459 enum {
00460   M32C_MACRO_JCND16_5_W,
00461   M32C_MACRO_JCND16_5_A,
00462   M32C_MACRO_JCND16_W,
00463   M32C_MACRO_JCND16_A,
00464   M32C_MACRO_JCND32_W,
00465   M32C_MACRO_JCND32_A,
00466   /* the digit is the array index of the pcrel byte */
00467   M32C_MACRO_ADJNZ_2,
00468   M32C_MACRO_ADJNZ_3,
00469   M32C_MACRO_ADJNZ_4,
00470   M32C_MACRO_ADJNZ_5,
00471 } M32C_Macros;
00472 
00473 static struct {
00474   int insn;
00475   int bytes;
00476   int insn_for_extern;
00477   int pcrel_aim_offset;
00478 } subtype_mappings[] = {
00479   /* 0 */ { 0, 0, 0, 0 },
00480   /* 1 */ { 0, 0, 0, 0 },
00481 
00482   /* 2 */ {  M32C_INSN_JCND16_5,    2, -M32C_MACRO_JCND16_5_A, 1 },
00483   /* 3 */ { -M32C_MACRO_JCND16_5_W, 5, -M32C_MACRO_JCND16_5_A, 4 },
00484   /* 4 */ { -M32C_MACRO_JCND16_5_A, 6, -M32C_MACRO_JCND16_5_A, 0 },
00485 
00486   /* 5 */ {  M32C_INSN_JCND16,      3, -M32C_MACRO_JCND16_A,   1 },
00487   /* 6 */ { -M32C_MACRO_JCND16_W,   6, -M32C_MACRO_JCND16_A,   4 },
00488   /* 7 */ { -M32C_MACRO_JCND16_A,   7, -M32C_MACRO_JCND16_A,   0 },
00489 
00490   /* 8 */ {  M32C_INSN_JMP16_S,     1, M32C_INSN_JMP16_A,     0 },
00491   /* 9 */ {  M32C_INSN_JMP16_B,     2, M32C_INSN_JMP16_A,     1 },
00492  /* 10 */ {  M32C_INSN_JMP16_W,     3, M32C_INSN_JMP16_A,     2 },
00493  /* 11 */ {  M32C_INSN_JMP16_A,     4, M32C_INSN_JMP16_A,     0 },
00494 
00495  /* 12 */ {  M32C_INSN_JCND32,      2, -M32C_MACRO_JCND32_A,   1 },
00496  /* 13 */ { -M32C_MACRO_JCND32_W,   5, -M32C_MACRO_JCND32_A,   4 },
00497  /* 14 */ { -M32C_MACRO_JCND32_A,   6, -M32C_MACRO_JCND32_A,   0 },
00498 
00499  /* 15 */ {  M32C_INSN_JMP32_S,     1, M32C_INSN_JMP32_A,     0 },
00500  /* 16 */ {  M32C_INSN_JMP32_B,     2, M32C_INSN_JMP32_A,     1 },
00501  /* 17 */ {  M32C_INSN_JMP32_W,     3, M32C_INSN_JMP32_A,     2 },
00502  /* 18 */ {  M32C_INSN_JMP32_A,     4, M32C_INSN_JMP32_A,     0 },
00503 
00504  /* 19 */ {  M32C_INSN_JSR16_W,     3, M32C_INSN_JSR16_A,     2 },
00505  /* 20 */ {  M32C_INSN_JSR16_A,     4, M32C_INSN_JSR16_A,     0 },
00506  /* 21 */ {  M32C_INSN_JSR32_W,     3, M32C_INSN_JSR32_A,     2 },
00507  /* 22 */ {  M32C_INSN_JSR32_A,     4, M32C_INSN_JSR32_A,     0 },
00508 
00509  /* 23 */ { -M32C_MACRO_ADJNZ_2,    3, -M32C_MACRO_ADJNZ_2,    0 },
00510  /* 24 */ { -M32C_MACRO_ADJNZ_3,    4, -M32C_MACRO_ADJNZ_3,    0 },
00511  /* 25 */ { -M32C_MACRO_ADJNZ_4,    5, -M32C_MACRO_ADJNZ_4,    0 },
00512  /* 26 */ { -M32C_MACRO_ADJNZ_5,    6, -M32C_MACRO_ADJNZ_5,    0 }
00513 };
00514 #define NUM_MAPPINGS (sizeof (subtype_mappings) / sizeof (subtype_mappings[0]))
00515 
00516 void
00517 m32c_prepare_relax_scan (fragS *fragP, offsetT *aim, relax_substateT this_state)
00518 {
00519   symbolS *symbolP = fragP->fr_symbol;
00520   if (symbolP && !S_IS_DEFINED (symbolP))
00521     *aim = 0;
00522   /* Adjust for m32c pcrel not being relative to the next opcode.  */
00523   *aim += subtype_mappings[this_state].pcrel_aim_offset;
00524 }
00525 
00526 static int
00527 insn_to_subtype (int inum, const CGEN_INSN *insn)
00528 {
00529   unsigned int i;
00530 
00531   if (insn
00532       && (strncmp (insn->base->mnemonic, "adjnz", 5) == 0
00533          || strncmp (insn->base->mnemonic, "sbjnz", 5) == 0))
00534     {
00535       i = 23 + insn->base->bitsize/8 - 3;
00536       /*printf("mapping %d used for %s\n", i, insn->base->mnemonic);*/
00537       return i;
00538     }
00539 
00540   for (i=0; i<NUM_MAPPINGS; i++)
00541     if (inum == subtype_mappings[i].insn)
00542       {
00543        /*printf("mapping %d used\n", i);*/
00544        return i;
00545       }
00546   abort ();
00547 }
00548 
00549 /* Return an initial guess of the length by which a fragment must grow to
00550    hold a branch to reach its destination.
00551    Also updates fr_type/fr_subtype as necessary.
00552 
00553    Called just before doing relaxation.
00554    Any symbol that is now undefined will not become defined.
00555    The guess for fr_var is ACTUALLY the growth beyond fr_fix.
00556    Whatever we do to grow fr_fix or fr_var contributes to our returned value.
00557    Although it may not be explicit in the frag, pretend fr_var starts with a
00558    0 value.  */
00559 
00560 int
00561 md_estimate_size_before_relax (fragS * fragP, segT segment ATTRIBUTE_UNUSED)
00562 {
00563   int where = fragP->fr_opcode - fragP->fr_literal;
00564 
00565   if (fragP->fr_subtype == 1)
00566     fragP->fr_subtype = insn_to_subtype (fragP->fr_cgen.insn->base->num, fragP->fr_cgen.insn);
00567 
00568   if (S_GET_SEGMENT (fragP->fr_symbol) != segment)
00569     {
00570       int new_insn;
00571 
00572       new_insn = subtype_mappings[fragP->fr_subtype].insn_for_extern;
00573       fragP->fr_subtype = insn_to_subtype (new_insn, 0);
00574     }
00575 
00576   if (fragP->fr_cgen.insn->base
00577       && fragP->fr_cgen.insn->base->num
00578          != subtype_mappings[fragP->fr_subtype].insn
00579       && subtype_mappings[fragP->fr_subtype].insn > 0)
00580     {
00581       int new_insn= subtype_mappings[fragP->fr_subtype].insn;
00582       if (new_insn >= 0)
00583        {
00584          fragP->fr_cgen.insn = (fragP->fr_cgen.insn
00585                              - fragP->fr_cgen.insn->base->num
00586                              + new_insn);
00587        }
00588     }
00589 
00590   return subtype_mappings[fragP->fr_subtype].bytes - (fragP->fr_fix - where);
00591 } 
00592 
00593 /* *fragP has been relaxed to its final size, and now needs to have
00594    the bytes inside it modified to conform to the new size.
00595 
00596    Called after relaxation is finished.
00597    fragP->fr_type == rs_machine_dependent.
00598    fragP->fr_subtype is the subtype of what the address relaxed to.  */
00599 
00600 static int
00601 target_address_for (fragS *frag)
00602 {
00603   int rv = frag->fr_offset;
00604   symbolS *sym = frag->fr_symbol;
00605 
00606   if (sym)
00607     rv += S_GET_VALUE (sym);
00608 
00609   /*printf("target_address_for returns %d\n", rv);*/
00610   return rv;
00611 }
00612 
00613 void
00614 md_convert_frag (bfd *   abfd ATTRIBUTE_UNUSED,
00615                segT    sec ATTRIBUTE_UNUSED,
00616                fragS * fragP ATTRIBUTE_UNUSED)
00617 {
00618   int addend;
00619   int operand;
00620   int new_insn;
00621   int where = fragP->fr_opcode - fragP->fr_literal;
00622   int rl_where = fragP->fr_opcode - fragP->fr_literal;
00623   unsigned char *op = (unsigned char *)fragP->fr_opcode;
00624   int op_base = 0;
00625   int op_op = 0;
00626   int rl_addend = 0;
00627 
00628   addend = target_address_for (fragP) - (fragP->fr_address + where);
00629   new_insn = subtype_mappings[fragP->fr_subtype].insn;
00630 
00631   fragP->fr_fix = where + subtype_mappings[fragP->fr_subtype].bytes;
00632 
00633   op_base = 0;
00634 
00635   switch (subtype_mappings[fragP->fr_subtype].insn)
00636     {
00637     case M32C_INSN_JCND16_5:
00638       op[1] = addend - 1;
00639       operand = M32C_OPERAND_LAB_8_8;
00640       op_op = 1;
00641       rl_addend = 0x21;
00642       break;
00643 
00644     case -M32C_MACRO_JCND16_5_W:
00645       op[0] ^= 0x04;
00646       op[1] = 4;
00647       op[2] = 0xf4;
00648       op[3] = addend - 3;
00649       op[4] = (addend - 3) >> 8;
00650       operand = M32C_OPERAND_LAB_8_16;
00651       where += 2;
00652       new_insn = M32C_INSN_JMP16_W;
00653       op_base = 2;
00654       op_op = 3;
00655       rl_addend = 0x51;
00656       break;
00657 
00658     case -M32C_MACRO_JCND16_5_A:
00659       op[0] ^= 0x04;
00660       op[1] = 5;
00661       op[2] = 0xfc;
00662       operand = M32C_OPERAND_LAB_8_24;
00663       where += 2;
00664       new_insn = M32C_INSN_JMP16_A;
00665       op_base = 2;
00666       op_op = 3;
00667       rl_addend = 0x61;
00668       break;
00669 
00670 
00671     case M32C_INSN_JCND16:
00672       op[2] = addend - 2;
00673       operand = M32C_OPERAND_LAB_16_8;
00674       op_base = 0;
00675       op_op = 2;
00676       rl_addend = 0x31;
00677       break;
00678 
00679     case -M32C_MACRO_JCND16_W:
00680       op[1] ^= 0x04;
00681       op[2] = 4;
00682       op[3] = 0xf4;
00683       op[4] = addend - 4;
00684       op[5] = (addend - 4) >> 8;
00685       operand = M32C_OPERAND_LAB_8_16;
00686       where += 3;
00687       new_insn = M32C_INSN_JMP16_W;
00688       op_base = 3;
00689       op_op = 4;
00690       rl_addend = 0x61;
00691       break;
00692 
00693     case -M32C_MACRO_JCND16_A:
00694       op[1] ^= 0x04;
00695       op[2] = 5;
00696       op[3] = 0xfc;
00697       operand = M32C_OPERAND_LAB_8_24;
00698       where += 3;
00699       new_insn = M32C_INSN_JMP16_A;
00700       op_base = 3;
00701       op_op = 4;
00702       rl_addend = 0x71;
00703       break;
00704 
00705     case M32C_INSN_JMP16_S:
00706       op[0] = 0x60 | ((addend-2) & 0x07);
00707       operand = M32C_OPERAND_LAB_5_3;
00708       op_base = 0;
00709       op_op = 0;
00710       rl_addend = 0x10;
00711       break;
00712 
00713     case M32C_INSN_JMP16_B:
00714       op[0] = 0xfe;
00715       op[1] = addend - 1;
00716       operand = M32C_OPERAND_LAB_8_8;
00717       op_base = 0;
00718       op_op = 1;
00719       rl_addend = 0x21;
00720       break;
00721 
00722     case M32C_INSN_JMP16_W:
00723       op[0] = 0xf4;
00724       op[1] = addend - 1;
00725       op[2] = (addend - 1) >> 8;
00726       operand = M32C_OPERAND_LAB_8_16;
00727       op_base = 0;
00728       op_op = 1;
00729       rl_addend = 0x31;
00730       break;
00731 
00732     case M32C_INSN_JMP16_A:
00733       op[0] = 0xfc;
00734       op[1] = 0;
00735       op[2] = 0;
00736       op[3] = 0;
00737       operand = M32C_OPERAND_LAB_8_24;
00738       op_base = 0;
00739       op_op = 1;
00740       rl_addend = 0x41;
00741       break;
00742 
00743     case M32C_INSN_JCND32:
00744       op[1] = addend - 1;
00745       operand = M32C_OPERAND_LAB_8_8;
00746       op_base = 0;
00747       op_op = 1;
00748       rl_addend = 0x21;
00749       break;
00750 
00751     case -M32C_MACRO_JCND32_W:
00752       op[0] ^= 0x40;
00753       op[1] = 4;
00754       op[2] = 0xce;
00755       op[3] = addend - 3;
00756       op[4] = (addend - 3) >> 8;
00757       operand = M32C_OPERAND_LAB_8_16;
00758       where += 2;
00759       new_insn = M32C_INSN_JMP32_W;
00760       op_base = 2;
00761       op_op = 3;
00762       rl_addend = 0x51;
00763       break;
00764 
00765     case -M32C_MACRO_JCND32_A:
00766       op[0] ^= 0x40;
00767       op[1] = 5;
00768       op[2] = 0xcc;
00769       operand = M32C_OPERAND_LAB_8_24;
00770       where += 2;
00771       new_insn = M32C_INSN_JMP32_A;
00772       op_base = 2;
00773       op_op = 3;
00774       rl_addend = 0x61;
00775       break;
00776 
00777 
00778 
00779     case M32C_INSN_JMP32_S:
00780       addend = ((addend-2) & 0x07);
00781       op[0] = 0x4a | (addend & 0x01) | ((addend << 3) & 0x30);
00782       operand = M32C_OPERAND_LAB32_JMP_S;
00783       op_base = 0;
00784       op_op = 0;
00785       rl_addend = 0x10;
00786       break;
00787 
00788     case M32C_INSN_JMP32_B:
00789       op[0] = 0xbb;
00790       op[1] = addend - 1;
00791       operand = M32C_OPERAND_LAB_8_8;
00792       op_base = 0;
00793       op_op = 1;
00794       rl_addend = 0x21;
00795       break;
00796 
00797     case M32C_INSN_JMP32_W:
00798       op[0] = 0xce;
00799       op[1] = addend - 1;
00800       op[2] = (addend - 1) >> 8;
00801       operand = M32C_OPERAND_LAB_8_16;
00802       op_base = 0;
00803       op_op = 1;
00804       rl_addend = 0x31;
00805       break;
00806 
00807     case M32C_INSN_JMP32_A:
00808       op[0] = 0xcc;
00809       op[1] = 0;
00810       op[2] = 0;
00811       op[3] = 0;
00812       operand = M32C_OPERAND_LAB_8_24;
00813       op_base = 0;
00814       op_op = 1;
00815       rl_addend = 0x41;
00816       break;
00817 
00818 
00819     case M32C_INSN_JSR16_W:
00820       op[0] = 0xf5;
00821       op[1] = addend - 1;
00822       op[2] = (addend - 1) >> 8;
00823       operand = M32C_OPERAND_LAB_8_16;
00824       op_base = 0;
00825       op_op = 1;
00826       rl_addend = 0x31;
00827       break;
00828 
00829     case M32C_INSN_JSR16_A:
00830       op[0] = 0xfd;
00831       op[1] = 0;
00832       op[2] = 0;
00833       op[3] = 0;
00834       operand = M32C_OPERAND_LAB_8_24;
00835       op_base = 0;
00836       op_op = 1;
00837       rl_addend = 0x41;
00838       break;
00839 
00840     case M32C_INSN_JSR32_W:
00841       op[0] = 0xcf;
00842       op[1] = addend - 1;
00843       op[2] = (addend - 1) >> 8;
00844       operand = M32C_OPERAND_LAB_8_16;
00845       op_base = 0;
00846       op_op = 1;
00847       rl_addend = 0x31;
00848       break;
00849 
00850     case M32C_INSN_JSR32_A:
00851       op[0] = 0xcd;
00852       op[1] = 0;
00853       op[2] = 0;
00854       op[3] = 0;
00855       operand = M32C_OPERAND_LAB_8_24;
00856       op_base = 0;
00857       op_op = 1;
00858       rl_addend = 0x41;
00859       break;
00860 
00861     case -M32C_MACRO_ADJNZ_2:
00862       rl_addend = 0x31;
00863       op[2] = addend;
00864       operand = M32C_OPERAND_LAB_16_8;
00865       break;
00866     case -M32C_MACRO_ADJNZ_3:
00867       rl_addend = 0x41;
00868       op[3] = addend;
00869       operand = M32C_OPERAND_LAB_24_8;
00870       break;
00871     case -M32C_MACRO_ADJNZ_4:
00872       rl_addend = 0x51;
00873       op[4] = addend;
00874       operand = M32C_OPERAND_LAB_32_8;
00875       break;
00876     case -M32C_MACRO_ADJNZ_5:
00877       rl_addend = 0x61;
00878       op[5] = addend;
00879       operand = M32C_OPERAND_LAB_40_8;
00880       break;
00881 
00882 
00883     default:
00884       printf("\nHey!  Need more opcode converters! missing: %d %s\n\n",
00885             fragP->fr_subtype,
00886             fragP->fr_cgen.insn->base->name);
00887       abort();
00888     }
00889 
00890   if (m32c_relax)
00891     {
00892       if (operand != M32C_OPERAND_LAB_8_24)
00893        fragP->fr_offset = (fragP->fr_address + where);
00894 
00895       fix_new (fragP,
00896               rl_where,
00897               0, abs_section_sym, rl_addend, 0,
00898               BFD_RELOC_M32C_RL_JUMP);
00899     }
00900 
00901   if (S_GET_SEGMENT (fragP->fr_symbol) != sec
00902       || operand == M32C_OPERAND_LAB_8_24
00903       || (m32c_relax && (operand != M32C_OPERAND_LAB_5_3
00904                       && operand != M32C_OPERAND_LAB32_JMP_S)))
00905     {
00906       fixS *fixP;
00907       assert (fragP->fr_cgen.insn != 0);
00908       fixP = gas_cgen_record_fixup (fragP,
00909                                 where,
00910                                 fragP->fr_cgen.insn,
00911                                 (fragP->fr_fix - where) * 8,
00912                                 cgen_operand_lookup_by_num (gas_cgen_cpu_desc,
00913                                                         operand),
00914                                 fragP->fr_cgen.opinfo,
00915                                 fragP->fr_symbol, fragP->fr_offset);
00916     }
00917 }
00918 
00919 /* Functions concerning relocs.  */
00920 
00921 /* The location from which a PC relative jump should be calculated,
00922    given a PC relative reloc.  */
00923 
00924 long
00925 md_pcrel_from_section (fixS * fixP, segT sec)
00926 {
00927   if (fixP->fx_addsy != (symbolS *) NULL
00928       && (! S_IS_DEFINED (fixP->fx_addsy)
00929          || S_GET_SEGMENT (fixP->fx_addsy) != sec))
00930     /* The symbol is undefined (or is defined but not in this section).
00931        Let the linker figure it out.  */
00932     return 0;
00933 
00934   return (fixP->fx_frag->fr_address + fixP->fx_where);
00935 }
00936 
00937 /* Return the bfd reloc type for OPERAND of INSN at fixup FIXP.
00938    Returns BFD_RELOC_NONE if no reloc type can be found.
00939    *FIXP may be modified if desired.  */
00940 
00941 bfd_reloc_code_real_type
00942 md_cgen_lookup_reloc (const CGEN_INSN *    insn ATTRIBUTE_UNUSED,
00943                     const CGEN_OPERAND * operand,
00944                     fixS *               fixP ATTRIBUTE_UNUSED)
00945 {
00946   static const struct op_reloc {
00947     /* A CGEN operand type that can be a relocatable expression.  */
00948     CGEN_OPERAND_TYPE operand;
00949 
00950     /* The appropriate BFD reloc type to use for that.  */
00951     bfd_reloc_code_real_type reloc;
00952 
00953     /* The offset from the start of the instruction to the field to be
00954        relocated, in bytes.  */
00955     int offset;
00956   } op_reloc_table[] = {
00957 
00958     /* PC-REL relocs for 8-bit fields.  */
00959     { M32C_OPERAND_LAB_8_8,    BFD_RELOC_8_PCREL, 1 },
00960     { M32C_OPERAND_LAB_16_8,   BFD_RELOC_8_PCREL, 2 },
00961     { M32C_OPERAND_LAB_24_8,   BFD_RELOC_8_PCREL, 3 },
00962     { M32C_OPERAND_LAB_32_8,   BFD_RELOC_8_PCREL, 4 },
00963     { M32C_OPERAND_LAB_40_8,   BFD_RELOC_8_PCREL, 5 },
00964 
00965     /* PC-REL relocs for 16-bit fields.  */
00966     { M32C_OPERAND_LAB_8_16,   BFD_RELOC_16_PCREL, 1 },
00967 
00968     /* Absolute relocs for 8-bit fields.  */
00969     { M32C_OPERAND_IMM_8_QI,   BFD_RELOC_8, 1 },
00970     { M32C_OPERAND_IMM_16_QI,  BFD_RELOC_8, 2 },
00971     { M32C_OPERAND_IMM_24_QI,  BFD_RELOC_8, 3 },
00972     { M32C_OPERAND_IMM_32_QI,  BFD_RELOC_8, 4 },
00973     { M32C_OPERAND_IMM_40_QI,  BFD_RELOC_8, 5 },
00974     { M32C_OPERAND_IMM_48_QI,  BFD_RELOC_8, 6 },
00975     { M32C_OPERAND_IMM_56_QI,  BFD_RELOC_8, 7 },
00976     { M32C_OPERAND_DSP_8_S8,   BFD_RELOC_8, 1 },
00977     { M32C_OPERAND_DSP_16_S8,  BFD_RELOC_8, 2 },
00978     { M32C_OPERAND_DSP_24_S8,  BFD_RELOC_8, 3 },
00979     { M32C_OPERAND_DSP_32_S8,  BFD_RELOC_8, 4 },
00980     { M32C_OPERAND_DSP_40_S8,  BFD_RELOC_8, 5 },
00981     { M32C_OPERAND_DSP_48_S8,  BFD_RELOC_8, 6 },
00982     { M32C_OPERAND_DSP_8_U8,   BFD_RELOC_8, 1 },
00983     { M32C_OPERAND_DSP_16_U8,  BFD_RELOC_8, 2 },
00984     { M32C_OPERAND_DSP_24_U8,  BFD_RELOC_8, 3 },
00985     { M32C_OPERAND_DSP_32_U8,  BFD_RELOC_8, 4 },
00986     { M32C_OPERAND_DSP_40_U8,  BFD_RELOC_8, 5 },
00987     { M32C_OPERAND_DSP_48_U8,  BFD_RELOC_8, 6 },
00988     { M32C_OPERAND_BITBASE32_16_S11_UNPREFIXED, BFD_RELOC_8, 2 },
00989     { M32C_OPERAND_BITBASE32_16_U11_UNPREFIXED, BFD_RELOC_8, 2 },
00990     { M32C_OPERAND_BITBASE32_24_S11_PREFIXED, BFD_RELOC_8, 3 },
00991     { M32C_OPERAND_BITBASE32_24_U11_PREFIXED, BFD_RELOC_8, 3 },
00992 
00993     /* Absolute relocs for 16-bit fields.  */
00994     { M32C_OPERAND_IMM_8_HI,   BFD_RELOC_16, 1 },
00995     { M32C_OPERAND_IMM_16_HI,  BFD_RELOC_16, 2 },
00996     { M32C_OPERAND_IMM_24_HI,  BFD_RELOC_16, 3 },
00997     { M32C_OPERAND_IMM_32_HI,  BFD_RELOC_16, 4 },
00998     { M32C_OPERAND_IMM_40_HI,  BFD_RELOC_16, 5 },
00999     { M32C_OPERAND_IMM_48_HI,  BFD_RELOC_16, 6 },
01000     { M32C_OPERAND_IMM_56_HI,  BFD_RELOC_16, 7 },
01001     { M32C_OPERAND_IMM_64_HI,  BFD_RELOC_16, 8 },
01002     { M32C_OPERAND_DSP_16_S16, BFD_RELOC_16, 2 },
01003     { M32C_OPERAND_DSP_24_S16, BFD_RELOC_16, 3 },
01004     { M32C_OPERAND_DSP_32_S16, BFD_RELOC_16, 4 },
01005     { M32C_OPERAND_DSP_40_S16, BFD_RELOC_16, 5 },
01006     { M32C_OPERAND_DSP_8_U16,  BFD_RELOC_16, 1 },
01007     { M32C_OPERAND_DSP_16_U16, BFD_RELOC_16, 2 },
01008     { M32C_OPERAND_DSP_24_U16, BFD_RELOC_16, 3 },
01009     { M32C_OPERAND_DSP_32_U16, BFD_RELOC_16, 4 },
01010     { M32C_OPERAND_DSP_40_U16, BFD_RELOC_16, 5 },
01011     { M32C_OPERAND_DSP_48_U16, BFD_RELOC_16, 6 },
01012     { M32C_OPERAND_BITBASE32_16_S19_UNPREFIXED, BFD_RELOC_16, 2 },
01013     { M32C_OPERAND_BITBASE32_16_U19_UNPREFIXED, BFD_RELOC_16, 2 },
01014     { M32C_OPERAND_BITBASE32_24_S19_PREFIXED, BFD_RELOC_16, 3 },
01015     { M32C_OPERAND_BITBASE32_24_U19_PREFIXED, BFD_RELOC_16, 3 },
01016 
01017     /* Absolute relocs for 24-bit fields.  */
01018     { M32C_OPERAND_LAB_8_24,   BFD_RELOC_24, 1 },
01019     { M32C_OPERAND_DSP_8_S24,  BFD_RELOC_24, 1 },
01020     { M32C_OPERAND_DSP_8_U24,  BFD_RELOC_24, 1 },
01021     { M32C_OPERAND_DSP_16_U24, BFD_RELOC_24, 2 },
01022     { M32C_OPERAND_DSP_24_U24, BFD_RELOC_24, 3 },
01023     { M32C_OPERAND_DSP_32_U24, BFD_RELOC_24, 4 },
01024     { M32C_OPERAND_DSP_40_U24, BFD_RELOC_24, 5 },
01025     { M32C_OPERAND_DSP_48_U24, BFD_RELOC_24, 6 },
01026     { M32C_OPERAND_DSP_16_U20, BFD_RELOC_24, 2 },
01027     { M32C_OPERAND_DSP_24_U20, BFD_RELOC_24, 3 },
01028     { M32C_OPERAND_DSP_32_U20, BFD_RELOC_24, 4 },
01029     { M32C_OPERAND_BITBASE32_16_U27_UNPREFIXED, BFD_RELOC_24, 2 },
01030     { M32C_OPERAND_BITBASE32_24_U27_PREFIXED, BFD_RELOC_24, 3 },
01031 
01032     /* Absolute relocs for 32-bit fields.  */
01033     { M32C_OPERAND_IMM_16_SI,  BFD_RELOC_32, 2 },
01034     { M32C_OPERAND_IMM_24_SI,  BFD_RELOC_32, 3 },
01035     { M32C_OPERAND_IMM_32_SI,  BFD_RELOC_32, 4 },
01036     { M32C_OPERAND_IMM_40_SI,  BFD_RELOC_32, 5 },
01037 
01038   };
01039 
01040   int i;
01041 
01042   for (i = ARRAY_SIZE (op_reloc_table); --i >= 0; )
01043     {
01044       const struct op_reloc *or = &op_reloc_table[i];
01045 
01046       if (or->operand == operand->type)
01047         {
01048           fixP->fx_where += or->offset;
01049           fixP->fx_size -= or->offset;
01050 
01051          if (fixP->fx_cgen.opinfo
01052              && fixP->fx_cgen.opinfo != BFD_RELOC_NONE)
01053            return fixP->fx_cgen.opinfo;
01054 
01055           return or->reloc;
01056         }
01057     }
01058 
01059   fprintf
01060     (stderr,
01061      "Error: tc-m32c.c:md_cgen_lookup_reloc Unimplemented relocation for operand %s\n",
01062      operand->name);
01063 
01064   return BFD_RELOC_NONE;
01065 }
01066 
01067 void
01068 m32c_cons_fix_new (fragS *  frag,
01069                  int        where,
01070                  int        size,
01071                  expressionS *exp)
01072 {
01073   bfd_reloc_code_real_type type;
01074 
01075   switch (size)
01076     {
01077     case 1:
01078       type = BFD_RELOC_8;
01079       break;
01080     case 2:
01081       type = BFD_RELOC_16;
01082       break;
01083     case 3:
01084       type = BFD_RELOC_24;
01085       break;
01086     case 4:
01087     default:
01088       type = BFD_RELOC_32;
01089       break;
01090     case 8:
01091       type = BFD_RELOC_64;
01092       break;
01093     }
01094 
01095   fix_new_exp (frag, where, (int) size, exp, 0, type);
01096 }
01097 
01098 void
01099 m32c_apply_fix (struct fix *f, valueT *t, segT s)
01100 {
01101   if (f->fx_r_type == BFD_RELOC_M32C_RL_JUMP
01102       || f->fx_r_type == BFD_RELOC_M32C_RL_1ADDR
01103       || f->fx_r_type == BFD_RELOC_M32C_RL_2ADDR)
01104     return;
01105   gas_cgen_md_apply_fix (f, t, s);
01106 }
01107 
01108 arelent *
01109 tc_gen_reloc (asection *sec, fixS *fx)
01110 {
01111   if (fx->fx_r_type == BFD_RELOC_M32C_RL_JUMP
01112       || fx->fx_r_type == BFD_RELOC_M32C_RL_1ADDR
01113       || fx->fx_r_type == BFD_RELOC_M32C_RL_2ADDR)
01114     {
01115       arelent * reloc;
01116  
01117       reloc = xmalloc (sizeof (* reloc));
01118  
01119       reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
01120       *reloc->sym_ptr_ptr = symbol_get_bfdsym (fx->fx_addsy);
01121       reloc->address = fx->fx_frag->fr_address + fx->fx_where;
01122       reloc->howto = bfd_reloc_type_lookup (stdoutput, fx->fx_r_type);
01123       reloc->addend = fx->fx_offset;
01124       return reloc;
01125 
01126     }
01127   return gas_cgen_tc_gen_reloc (sec, fx);
01128 }
01129 
01130 /* See whether we need to force a relocation into the output file.
01131    This is used to force out switch and PC relative relocations when
01132    relaxing.  */
01133 
01134 int
01135 m32c_force_relocation (fixS * fixp)
01136 {
01137   int reloc = fixp->fx_r_type;
01138 
01139   if (reloc > (int)BFD_RELOC_UNUSED)
01140     {
01141       reloc -= (int)BFD_RELOC_UNUSED;
01142       switch (reloc)
01143        {
01144        case M32C_OPERAND_DSP_32_S16:
01145        case M32C_OPERAND_DSP_32_U16:
01146        case M32C_OPERAND_IMM_32_HI:
01147        case M32C_OPERAND_DSP_16_S16:
01148        case M32C_OPERAND_DSP_16_U16:
01149        case M32C_OPERAND_IMM_16_HI:
01150        case M32C_OPERAND_DSP_24_S16:
01151        case M32C_OPERAND_DSP_24_U16:
01152        case M32C_OPERAND_IMM_24_HI:
01153          return 1;
01154 
01155         /* If we're doing linker relaxing, we need to keep all the
01156           pc-relative jumps in case we need to fix them due to
01157           deleted bytes between the jump and its destination.  */
01158        case M32C_OPERAND_LAB_8_8:
01159        case M32C_OPERAND_LAB_8_16:
01160        case M32C_OPERAND_LAB_8_24:
01161        case M32C_OPERAND_LAB_16_8:
01162        case M32C_OPERAND_LAB_24_8:
01163        case M32C_OPERAND_LAB_32_8:
01164        case M32C_OPERAND_LAB_40_8:
01165          if (m32c_relax)
01166            return 1;
01167        default:
01168          break;
01169        }
01170     }
01171   else
01172     {
01173       switch (fixp->fx_r_type)
01174        {
01175        case BFD_RELOC_16:
01176          return 1;
01177 
01178        case BFD_RELOC_M32C_RL_JUMP:
01179        case BFD_RELOC_M32C_RL_1ADDR:
01180        case BFD_RELOC_M32C_RL_2ADDR:
01181        case BFD_RELOC_8_PCREL:
01182        case BFD_RELOC_16_PCREL:
01183          if (m32c_relax)
01184            return 1;
01185        default:
01186          break;
01187        }
01188     }
01189 
01190   return generic_force_reloc (fixp);
01191 }
01192 
01193 /* Write a value out to the object file, using the appropriate endianness.  */
01194 
01195 void
01196 md_number_to_chars (char * buf, valueT val, int n)
01197 {
01198   number_to_chars_littleendian (buf, val, n);
01199 }
01200 
01201 /* Turn a string in input_line_pointer into a floating point constant of type
01202    type, and store the appropriate bytes in *litP.  The number of LITTLENUMS
01203    emitted is stored in *sizeP .  An error message is returned, or NULL on OK.  */
01204 
01205 /* Equal to MAX_PRECISION in atof-ieee.c.  */
01206 #define MAX_LITTLENUMS 6
01207 
01208 char *
01209 md_atof (int type, char * litP, int * sizeP)
01210 {
01211   int              i;
01212   int              prec;
01213   LITTLENUM_TYPE   words [MAX_LITTLENUMS];
01214   char *           t;
01215 
01216   switch (type)
01217     {
01218     case 'f':
01219     case 'F':
01220     case 's':
01221     case 'S':
01222       prec = 2;
01223       break;
01224 
01225     case 'd':
01226     case 'D':
01227     case 'r':
01228     case 'R':
01229       prec = 4;
01230       break;
01231 
01232    /* FIXME: Some targets allow other format chars for bigger sizes here.  */
01233 
01234     default:
01235       * sizeP = 0;
01236       return _("Bad call to md_atof()");
01237     }
01238 
01239   t = atof_ieee (input_line_pointer, type, words);
01240   if (t)
01241     input_line_pointer = t;
01242   * sizeP = prec * sizeof (LITTLENUM_TYPE);
01243 
01244   for (i = 0; i < prec; i++)
01245     {
01246       md_number_to_chars (litP, (valueT) words[i],
01247                        sizeof (LITTLENUM_TYPE));
01248       litP += sizeof (LITTLENUM_TYPE);
01249     }
01250      
01251   return 0;
01252 }
01253 
01254 bfd_boolean
01255 m32c_fix_adjustable (fixS * fixP)
01256 {
01257   int reloc;
01258   if (fixP->fx_addsy == NULL)
01259     return 1;
01260 
01261   /* We need the symbol name for the VTABLE entries.  */
01262   reloc = fixP->fx_r_type;
01263   if (reloc > (int)BFD_RELOC_UNUSED)
01264     {
01265       reloc -= (int)BFD_RELOC_UNUSED;
01266       switch (reloc)
01267        {
01268        case M32C_OPERAND_DSP_32_S16:
01269        case M32C_OPERAND_DSP_32_U16:
01270        case M32C_OPERAND_IMM_32_HI:
01271        case M32C_OPERAND_DSP_16_S16:
01272        case M32C_OPERAND_DSP_16_U16:
01273        case M32C_OPERAND_IMM_16_HI:
01274        case M32C_OPERAND_DSP_24_S16:
01275        case M32C_OPERAND_DSP_24_U16:
01276        case M32C_OPERAND_IMM_24_HI:
01277          return 0;
01278        }
01279     }
01280   else
01281     {
01282       if (fixP->fx_r_type == BFD_RELOC_16)
01283        return 0;
01284     }
01285 
01286   /* Do not adjust relocations involving symbols in merged sections.
01287 
01288      A reloc patching in the value of some symbol S plus some addend A
01289      can be produced in different ways:
01290 
01291      1) It might simply be a reference to the data at S + A.  Clearly,
01292         if linker merging shift that data around, the value patched in
01293         by the reloc needs to be adjusted accordingly.
01294 
01295      2) Or, it might be a reference to S, with A added in as a constant
01296        bias.  For example, given code like this:
01297 
01298          static int S[100];
01299 
01300          ... S[i - 8] ...
01301 
01302        it would be reasonable for the compiler to rearrange the array
01303        reference to something like:
01304 
01305          ... (S-8)[i] ...
01306 
01307        and emit assembly code that refers to S - (8 * sizeof (int)),
01308        so the subtraction is done entirely at compile-time.  In this
01309        case, the reloc's addend A would be -(8 * sizeof (int)), and
01310        shifting around code or data at S + A should not affect the
01311        reloc: the reloc isn't referring to that code or data at all.
01312 
01313      The linker has no way of knowing which case it has in hand.  So,
01314      to disambiguate, we have the linker always treat reloc addends as
01315      in case 2): they're constants that should be simply added to the
01316      symbol value, just like the reloc says.  And we express case 1)
01317      in different way: we have the compiler place a label at the real
01318      target, and reference that label with an addend of zero.  (The
01319      compiler is unlikely to reference code using a label plus an
01320      offset anyway, since it doesn't know the sizes of the
01321      instructions.)
01322 
01323      The simplification being done by gas/write.c:adjust_reloc_syms,
01324      however, turns the explicit-label usage into the label-plus-
01325      offset usage, re-introducing the ambiguity the compiler avoided.
01326      So we need to disable that simplification for symbols referring
01327      to merged data.
01328 
01329      This only affects object size a little bit.  */
01330   if (S_GET_SEGMENT (fixP->fx_addsy)->flags & SEC_MERGE)
01331     return 0;
01332 
01333   if (m32c_relax)
01334     return 0;
01335 
01336   return 1;
01337 }
01338 
01339 /* Worker function for m32c_is_colon_insn().  */
01340 static char restore_colon PARAMS ((int));
01341 
01342 static char
01343 restore_colon (int advance_i_l_p_by)
01344 {
01345   char c;
01346 
01347   /* Restore the colon, and advance input_line_pointer to
01348      the end of the new symbol.  */
01349   * input_line_pointer = ':';
01350   input_line_pointer += advance_i_l_p_by;
01351   c = * input_line_pointer;
01352   * input_line_pointer = 0;
01353 
01354   return c;
01355 }
01356 
01357 /* Determines if the symbol starting at START and ending in
01358    a colon that was at the location pointed to by INPUT_LINE_POINTER
01359    (but which has now been replaced bu a NUL) is in fact an
01360    :Z, :S, :Q, or :G suffix.
01361    If it is, then it restores the colon, advances INPUT_LINE_POINTER
01362    to the real end of the instruction/symbol, and returns the character
01363    that really terminated the symbol.  Otherwise it returns 0.  */
01364 char
01365 m32c_is_colon_insn (char *start ATTRIBUTE_UNUSED)
01366 {
01367   char * i_l_p = input_line_pointer;
01368 
01369   /* Check to see if the text following the colon is 'G' */
01370   if (TOLOWER (i_l_p[1]) == 'g' && (i_l_p[2] == ' ' || i_l_p[2] == '\t'))
01371     return restore_colon (2);
01372 
01373   /* Check to see if the text following the colon is 'Q' */
01374   if (TOLOWER (i_l_p[1]) == 'q' && (i_l_p[2] == ' ' || i_l_p[2] == '\t'))
01375     return restore_colon (2);
01376 
01377   /* Check to see if the text following the colon is 'S' */
01378   if (TOLOWER (i_l_p[1]) == 's' && (i_l_p[2] == ' ' || i_l_p[2] == '\t'))
01379     return restore_colon (2);
01380 
01381   /* Check to see if the text following the colon is 'Z' */
01382   if (TOLOWER (i_l_p[1]) == 'z' && (i_l_p[2] == ' ' || i_l_p[2] == '\t'))
01383     return restore_colon (2);
01384 
01385   return 0;
01386 }