Back to index

cell-binutils  2.17cvs20070401
tc-msp430.c
Go to the documentation of this file.
00001 /* tc-msp430.c -- Assembler code for the Texas Instruments MSP430
00002 
00003   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007
00004   Free Software Foundation, Inc.
00005   Contributed by Dmitry Diky <diwil@mail.ru>
00006 
00007   This file is part of GAS, the GNU Assembler.
00008 
00009   GAS is free software; you can redistribute it and/or modify
00010   it under the terms of the GNU General Public License as published by
00011   the Free Software Foundation; either version 2, or (at your option)
00012   any later version.
00013 
00014   GAS is distributed in the hope that it will be useful,
00015   but WITHOUT ANY WARRANTY; without even the implied warranty of
00016   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017   GNU General Public License for more details.
00018 
00019   You should have received a copy of the GNU General Public License
00020   along with GAS; see the file COPYING.  If not, write to
00021   the Free Software Foundation, 51 Franklin Street - Fifth Floor,
00022   Boston, MA 02110-1301, USA.  */
00023 
00024 #include <limits.h>
00025 
00026 #define PUSH_1X_WORKAROUND
00027 #include "as.h"
00028 #include "subsegs.h"
00029 #include "opcode/msp430.h"
00030 #include "safe-ctype.h"
00031 #include "dwarf2dbg.h"
00032 
00033 /*
00034    We will disable polymorphs by default because it is dangerous.
00035    The potential problem here is the following: assume we got the
00036    following code:
00037 
00038        jump .l1
00039        nop
00040        jump  subroutine     ; external symbol
00041       .l1:
00042        nop
00043        ret
00044    
00045    In case of assembly time relaxation we'll get:
00046        0: jmp .l1 <.text +0x08> (reloc deleted)
00047        2: nop
00048        4: br subroutine
00049     .l1:
00050        8: nop
00051        10: ret
00052 
00053    If the 'subroutine' wiys thin +-1024 bytes range then linker
00054    will produce
00055        0: jmp .text +0x08
00056        2: nop
00057        4: jmp subroutine
00058        .l1:
00059        6: nop
00060        8: ret ; 'jmp .text +0x08' will land here. WRONG!!!
00061 
00062 
00063    The workaround is the following:
00064    1. Declare global var enable_polymorphs which set to 1 via option -mP.
00065    2. Declare global var enable_relax     which set to 1 via option -mQ.
00066 
00067    If polymorphs are enabled, and relax isn't, treat all jumps as long jumps,
00068    do not delete any relocs and leave them for linker.
00069    
00070    If relax is enabled, relax at assembly time and kill relocs as necessary.
00071  */
00072 
00073 int msp430_enable_relax;
00074 int msp430_enable_polys;
00075 
00076 /* GCC uses the some condition codes which we'll
00077    implement as new polymorph instructions.
00078   
00079    COND       EXPL      SHORT JUMP LONG JUMP
00080    ===============================================
00081    eq  ==        jeq               jne +4; br lab
00082    ne  !=        jne               jeq +4; br lab
00083 
00084    ltn honours no-overflow flag
00085    ltn <         jn         jn +2;  jmp +4; br lab
00086 
00087    lt  <         jl         jge +4;       br lab 
00088    ltu <         jlo               lhs +4; br lab
00089    le  <= see below
00090    leu <= see below
00091 
00092    gt  >  see below
00093    gtu >  see below
00094    ge  >=        jge               jl +4; br lab
00095    geu >=        jhs               jlo +4; br lab
00096    ===============================================
00097 
00098    Therefore, new opcodes are (BranchEQ -> beq; and so on...)
00099    beq,bne,blt,bltn,bltu,bge,bgeu
00100    'u' means unsigned compares 
00101   
00102    Also, we add 'jump' instruction:
00103    jump       UNCOND -> jmp        br lab
00104 
00105    They will have fmt == 4, and insn_opnumb == number of instruction.  */
00106 
00107 struct rcodes_s 
00108 {
00109   char * name;
00110   int    index;      /* Corresponding insn_opnumb.  */
00111   int    sop; /* Opcode if jump length is short.  */
00112   long   lpos;       /* Label position.  */
00113   long   lop0;       /* Opcode 1 _word_ (16 bits).  */
00114   long   lop1;       /* Opcode second word.  */
00115   long   lop2;       /* Opcode third word.  */
00116 };
00117 
00118 #define MSP430_RLC(n,i,sop,o1) \
00119   {#n, i, sop, 2, (o1 + 2), 0x4010, 0}
00120 
00121 static struct rcodes_s msp430_rcodes[] = 
00122 {
00123   MSP430_RLC (beq,  0, 0x2400, 0x2000),
00124   MSP430_RLC (bne,  1, 0x2000, 0x2400),
00125   MSP430_RLC (blt,  2, 0x3800, 0x3400),
00126   MSP430_RLC (bltu, 3, 0x2800, 0x2c00),
00127   MSP430_RLC (bge,  4, 0x3400, 0x3800),
00128   MSP430_RLC (bgeu, 5, 0x2c00, 0x2800),
00129   {"bltn",          6, 0x3000, 3, 0x3000 + 1, 0x3c00 + 2,0x4010},
00130   {"jump",          7, 0x3c00, 1, 0x4010, 0, 0},
00131   {0,0,0,0,0,0,0}
00132 };
00133 #undef MSP430_RLC
00134 
00135 
00136 /* More difficult than above and they have format 5.
00137    
00138    COND       EXPL   SHORT                LONG
00139    =================================================================
00140    gt  >      jeq +2; jge label    jeq +6; jl  +4; br label
00141    gtu >      jeq +2; jhs label    jeq +6; jlo +4; br label
00142    leu <=     jeq label; jlo label jeq +2; jhs +4; br label
00143    le  <=     jeq label; jl  label jeq +2; jge +4; br label
00144    =================================================================  */
00145 
00146 struct hcodes_s 
00147 {
00148   char * name;       
00149   int    index;             /* Corresponding insn_opnumb.  */
00150   int    tlab;              /* Number of labels in short mode.  */
00151   int    op0;        /* Opcode for first word of short jump.  */
00152   int    op1;        /* Opcode for second word of short jump.  */
00153   int    lop0;              /* Opcodes for long jump mode.  */
00154   int    lop1;
00155   int    lop2;
00156 };
00157 
00158 static struct hcodes_s msp430_hcodes[] = 
00159 {
00160   {"bgt",  0, 1, 0x2401, 0x3400, 0x2403, 0x3802, 0x4010 },
00161   {"bgtu", 1, 1, 0x2401, 0x2c00, 0x2403, 0x2802, 0x4010 },
00162   {"bleu", 2, 2, 0x2400, 0x2800, 0x2401, 0x2c02, 0x4010 },
00163   {"ble",  3, 2, 0x2400, 0x3800, 0x2401, 0x3402, 0x4010 },
00164   {0,0,0,0,0,0,0,0}
00165 };
00166 
00167 const char comment_chars[] = ";";
00168 const char line_comment_chars[] = "#";
00169 const char line_separator_chars[] = "{";
00170 const char EXP_CHARS[] = "eE";
00171 const char FLT_CHARS[] = "dD";
00172 
00173 /* Handle  long expressions.  */
00174 extern LITTLENUM_TYPE generic_bignum[];
00175 
00176 static struct hash_control *msp430_hash;
00177 
00178 /* Relaxations.  */
00179 #define STATE_UNCOND_BRANCH 1      /* jump */
00180 #define STATE_NOOV_BRANCH   3      /* bltn */
00181 #define STATE_SIMPLE_BRANCH 2      /* bne, beq, etc... */
00182 #define STATE_EMUL_BRANCH   4
00183 
00184 #define CNRL  2
00185 #define CUBL  4
00186 #define CNOL  8
00187 #define CSBL  6
00188 #define CEBL  4
00189 
00190 /* Length.  */
00191 #define STATE_BITS10 1      /* wild guess. short jump */
00192 #define STATE_WORD   2      /* 2 bytes pc rel. addr. more */
00193 #define STATE_UNDEF  3      /* cannot handle this yet. convert to word mode */
00194 
00195 #define ENCODE_RELAX(what,length) (((what) << 2) + (length))
00196 #define RELAX_STATE(s)            ((s) & 3)
00197 #define RELAX_LEN(s)           ((s) >> 2)
00198 #define RELAX_NEXT(a,b)               ENCODE_RELAX (a, b + 1)
00199 
00200 relax_typeS md_relax_table[] =
00201 {
00202   /* Unused.  */
00203   {1, 1, 0, 0},
00204   {1, 1, 0, 0},
00205   {1, 1, 0, 0},
00206   {1, 1, 0, 0},
00207 
00208   /* Unconditional jump.  */
00209   {1, 1, 8, 5},
00210   {1024, -1024, CNRL, RELAX_NEXT (STATE_UNCOND_BRANCH, STATE_BITS10)},       /* state 10 bits displ */
00211   {0, 0, CUBL, RELAX_NEXT (STATE_UNCOND_BRANCH, STATE_WORD)},         /* state word */
00212   {1, 1, CUBL, 0},                                             /* state undef */
00213 
00214   /* Simple branches.  */
00215   {0, 0, 8, 9},
00216   {1024, -1024, CNRL, RELAX_NEXT (STATE_SIMPLE_BRANCH, STATE_BITS10)},       /* state 10 bits displ */
00217   {0, 0, CSBL, RELAX_NEXT (STATE_SIMPLE_BRANCH, STATE_WORD)},         /* state word */
00218   {1, 1, CSBL, 0},
00219 
00220   /* blt no overflow branch.  */
00221   {1, 1, 8, 13},
00222   {1024, -1024, CNRL, RELAX_NEXT (STATE_NOOV_BRANCH, STATE_BITS10)},  /* state 10 bits displ */
00223   {0, 0, CNOL, RELAX_NEXT (STATE_NOOV_BRANCH, STATE_WORD)},           /* state word */
00224   {1, 1, CNOL, 0},
00225 
00226   /* Emulated branches.  */
00227   {1, 1, 8, 17},
00228   {1020, -1020, CEBL, RELAX_NEXT (STATE_EMUL_BRANCH, STATE_BITS10)},  /* state 10 bits displ */
00229   {0, 0, CNOL, RELAX_NEXT (STATE_EMUL_BRANCH, STATE_WORD)},           /* state word */
00230   {1, 1, CNOL, 0}
00231 };
00232 
00233 
00234 #define MAX_OP_LEN   256
00235 
00236 struct mcu_type_s
00237 {
00238   char * name;
00239   int isa;
00240   int mach;
00241 };
00242 
00243 #define MSP430_ISA_11   11
00244 #define MSP430_ISA_110      110
00245 #define MSP430_ISA_12   12
00246 #define MSP430_ISA_13   13
00247 #define MSP430_ISA_14   14
00248 #define MSP430_ISA_15   15
00249 #define MSP430_ISA_16   16
00250 #define MSP430_ISA_21   21
00251 #define MSP430_ISA_31   31
00252 #define MSP430_ISA_32   32
00253 #define MSP430_ISA_33   33
00254 #define MSP430_ISA_41   41
00255 #define MSP430_ISA_42   42
00256 #define MSP430_ISA_43   43
00257 #define MSP430_ISA_44   44
00258 
00259 #define CHECK_RELOC_MSP430         ((imm_op || byte_op)?BFD_RELOC_MSP430_16_BYTE:BFD_RELOC_MSP430_16)
00260 #define CHECK_RELOC_MSP430_PCREL   ((imm_op || byte_op)?BFD_RELOC_MSP430_16_PCREL_BYTE:BFD_RELOC_MSP430_16_PCREL)
00261 
00262 static struct mcu_type_s mcu_types[] =
00263 {
00264   {"msp1",        MSP430_ISA_11, bfd_mach_msp11},
00265   {"msp2",        MSP430_ISA_14, bfd_mach_msp14},
00266   {"msp430x110",  MSP430_ISA_11, bfd_mach_msp11},
00267   {"msp430x112",  MSP430_ISA_11, bfd_mach_msp11},
00268   {"msp430x1101", MSP430_ISA_110, bfd_mach_msp110},
00269   {"msp430x1111", MSP430_ISA_110, bfd_mach_msp110},
00270   {"msp430x1121", MSP430_ISA_110, bfd_mach_msp110},
00271   {"msp430x1122", MSP430_ISA_11, bfd_mach_msp110},
00272   {"msp430x1132", MSP430_ISA_11, bfd_mach_msp110},
00273 
00274   {"msp430x122",  MSP430_ISA_12, bfd_mach_msp12},
00275   {"msp430x123",  MSP430_ISA_12, bfd_mach_msp12},
00276   {"msp430x1222", MSP430_ISA_12, bfd_mach_msp12},
00277   {"msp430x1232", MSP430_ISA_12, bfd_mach_msp12},
00278 
00279   {"msp430x133",  MSP430_ISA_13, bfd_mach_msp13},
00280   {"msp430x135",  MSP430_ISA_13, bfd_mach_msp13},
00281   {"msp430x1331", MSP430_ISA_13, bfd_mach_msp13},
00282   {"msp430x1351", MSP430_ISA_13, bfd_mach_msp13},
00283   {"msp430x147",  MSP430_ISA_14, bfd_mach_msp14},
00284   {"msp430x148",  MSP430_ISA_14, bfd_mach_msp14},
00285   {"msp430x149",  MSP430_ISA_14, bfd_mach_msp14},
00286 
00287   {"msp430x155",  MSP430_ISA_15, bfd_mach_msp15},
00288   {"msp430x156",  MSP430_ISA_15, bfd_mach_msp15},
00289   {"msp430x157",  MSP430_ISA_15, bfd_mach_msp15},
00290   {"msp430x167",  MSP430_ISA_16, bfd_mach_msp16},
00291   {"msp430x168",  MSP430_ISA_16, bfd_mach_msp16},
00292   {"msp430x169",  MSP430_ISA_16, bfd_mach_msp16},
00293   {"msp430x1610", MSP430_ISA_16, bfd_mach_msp16},
00294   {"msp430x1611", MSP430_ISA_16, bfd_mach_msp16},
00295   {"msp430x1612", MSP430_ISA_16, bfd_mach_msp16},
00296 
00297   {"msp430x2101", MSP430_ISA_21, bfd_mach_msp21},
00298   {"msp430x2111", MSP430_ISA_21, bfd_mach_msp21},
00299   {"msp430x2121", MSP430_ISA_21, bfd_mach_msp21},
00300   {"msp430x2131", MSP430_ISA_21, bfd_mach_msp21},
00301   
00302   {"msp430x311",  MSP430_ISA_31, bfd_mach_msp31},
00303   {"msp430x312",  MSP430_ISA_31, bfd_mach_msp31},
00304   {"msp430x313",  MSP430_ISA_31, bfd_mach_msp31},
00305   {"msp430x314",  MSP430_ISA_31, bfd_mach_msp31},
00306   {"msp430x315",  MSP430_ISA_31, bfd_mach_msp31},
00307   {"msp430x323",  MSP430_ISA_32, bfd_mach_msp32},
00308   {"msp430x325",  MSP430_ISA_32, bfd_mach_msp32},
00309   {"msp430x336",  MSP430_ISA_33, bfd_mach_msp33},
00310   {"msp430x337",  MSP430_ISA_33, bfd_mach_msp33},
00311 
00312   {"msp430x412",  MSP430_ISA_41, bfd_mach_msp41},
00313   {"msp430x413",  MSP430_ISA_41, bfd_mach_msp41},
00314   {"msp430x415",  MSP430_ISA_41, bfd_mach_msp41},
00315   {"msp430x417",  MSP430_ISA_41, bfd_mach_msp41},
00316 
00317   {"msp430xE423", MSP430_ISA_42, bfd_mach_msp42},
00318   {"msp430xE425", MSP430_ISA_42, bfd_mach_msp42},
00319   {"msp430xE427", MSP430_ISA_42, bfd_mach_msp42},
00320 
00321   {"msp430xW423", MSP430_ISA_42, bfd_mach_msp42},
00322   {"msp430xW425", MSP430_ISA_42, bfd_mach_msp42},
00323   {"msp430xW427", MSP430_ISA_42, bfd_mach_msp42},
00324 
00325   {"msp430xG437", MSP430_ISA_43, bfd_mach_msp43},
00326   {"msp430xG438", MSP430_ISA_43, bfd_mach_msp43},
00327   {"msp430xG439", MSP430_ISA_43, bfd_mach_msp43},
00328 
00329   {"msp430x435",  MSP430_ISA_43, bfd_mach_msp43},
00330   {"msp430x436",  MSP430_ISA_43, bfd_mach_msp43},
00331   {"msp430x437",  MSP430_ISA_43, bfd_mach_msp43},
00332   {"msp430x447",  MSP430_ISA_44, bfd_mach_msp44},
00333   {"msp430x448",  MSP430_ISA_44, bfd_mach_msp44},
00334   {"msp430x449",  MSP430_ISA_44, bfd_mach_msp44},
00335 
00336   {NULL, 0, 0}
00337 };
00338 
00339 
00340 static struct mcu_type_s default_mcu =
00341     { "msp430x11", MSP430_ISA_11, bfd_mach_msp11 };
00342 
00343 static struct mcu_type_s * msp430_mcu = & default_mcu;
00344 
00345 /* Profiling capability:
00346    It is a performance hit to use gcc's profiling approach for this tiny target.
00347    Even more -- jtag hardware facility does not perform any profiling functions.
00348    However we've got gdb's built-in simulator where we can do anything.
00349    Therefore my suggestion is:
00350 
00351    We define new section ".profiler" which holds all profiling information.
00352    We define new pseudo operation .profiler which will instruct assembler to
00353    add new profile entry to the object file. Profile should take place at the
00354    present address.
00355 
00356    Pseudo-op format:
00357 
00358       .profiler flags,function_to_profile [, cycle_corrector, extra]
00359 
00360    where 'flags' is a combination of the following chars:
00361            s - function Start
00362            x - function eXit
00363            i - function is in Init section
00364            f - function is in Fini section
00365            l - Library call
00366            c - libC standard call
00367            d - stack value Demand (saved at run-time in simulator)
00368            I - Interrupt service routine
00369            P - Prologue start
00370            p - Prologue end
00371            E - Epilogue start
00372            e - Epilogue end
00373            j - long Jump/ sjlj unwind
00374            a - an Arbitrary code fragment
00375            t - exTra parameter saved (constant value like frame size)
00376          '""' optional: "sil" == sil
00377 
00378       function_to_profile - function's address
00379       cycle_corrector     - a value which should be added to the cycle
00380                            counter, zero if omitted
00381       extra - some extra parameter, zero if omitted.
00382 
00383       For example:
00384       ------------------------------
00385        .global fxx
00386        .type fxx,@function
00387       fxx:
00388       .LFrameOffset_fxx=0x08
00389       .profiler "scdP", fxx ; function entry.
00390                             ; we also demand stack value to be displayed
00391        push r11
00392        push r10
00393        push r9
00394        push r8
00395       .profiler "cdp",fxx,0, .LFrameOffset_fxx   ; check stack value at this point
00396                                           ; (this is a prologue end)
00397                                           ; note, that spare var filled with the farme size
00398        mov r15,r8
00399        ....
00400       .profiler cdE,fxx            ; check stack
00401        pop r8
00402        pop r9
00403        pop r10
00404        pop r11
00405       .profiler xcde,fxx,3  ; exit adds 3 to the cycle counter
00406       ret                   ; cause 'ret' insn takes 3 cycles
00407       -------------------------------
00408 
00409       This profiling approach does not produce any overhead and
00410       absolutely harmless.
00411       So, even profiled code can be uploaded to the MCU.  */
00412 #define MSP430_PROFILER_FLAG_ENTRY 1      /* s */
00413 #define MSP430_PROFILER_FLAG_EXIT  2      /* x */
00414 #define MSP430_PROFILER_FLAG_INITSECT     4      /* i */
00415 #define MSP430_PROFILER_FLAG_FINISECT     8      /* f */
00416 #define MSP430_PROFILER_FLAG_LIBCALL      0x10   /* l */
00417 #define MSP430_PROFILER_FLAG_STDCALL      0x20   /* c */
00418 #define MSP430_PROFILER_FLAG_STACKDMD     0x40   /* d */
00419 #define MSP430_PROFILER_FLAG_ISR   0x80   /* I */
00420 #define MSP430_PROFILER_FLAG_PROLSTART    0x100  /* P */
00421 #define MSP430_PROFILER_FLAG_PROLEND      0x200  /* p */
00422 #define MSP430_PROFILER_FLAG_EPISTART     0x400  /* E */
00423 #define MSP430_PROFILER_FLAG_EPIEND       0x800  /* e */
00424 #define MSP430_PROFILER_FLAG_JUMP  0x1000 /* j */
00425 #define MSP430_PROFILER_FLAG_FRAGMENT     0x2000 /* a */
00426 #define MSP430_PROFILER_FLAG_EXTRA 0x4000 /* t */
00427 #define MSP430_PROFILER_FLAG_notyet       0x8000 /* ? */
00428 
00429 static int
00430 pow2value (int y)
00431 {
00432   int n = 0;
00433   unsigned int x;
00434 
00435   x = y;
00436 
00437   if (!x)
00438     return 1;
00439 
00440   for (; x; x = x >> 1)
00441     if (x & 1)
00442       n++;
00443 
00444   return n == 1;
00445 }
00446 
00447 /* Parse ordinary expression.  */
00448 
00449 static char *
00450 parse_exp (char * s, expressionS * op)
00451 {
00452   input_line_pointer = s;
00453   expression (op);
00454   if (op->X_op == O_absent)
00455     as_bad (_("missing operand"));
00456   return input_line_pointer;
00457 }
00458 
00459 
00460 /* Delete spaces from s: X ( r 1  2)  => X(r12).  */
00461 
00462 static void
00463 del_spaces (char * s)
00464 {
00465   while (*s)
00466     {
00467       if (ISSPACE (*s))
00468        {
00469          char *m = s + 1;
00470 
00471          while (ISSPACE (*m) && *m)
00472            m++;
00473          memmove (s, m, strlen (m) + 1);
00474        }
00475       else
00476        s++;
00477     }
00478 }
00479 
00480 static inline char *
00481 skip_space (char * s)
00482 {
00483   while (ISSPACE (*s))
00484     ++s;
00485   return s;
00486 }
00487 
00488 /* Extract one word from FROM and copy it to TO. Delimiters are ",;\n"  */
00489 
00490 static char *
00491 extract_operand (char * from, char * to, int limit)
00492 {
00493   int size = 0;
00494 
00495   /* Drop leading whitespace.  */
00496   from = skip_space (from);
00497 
00498   while (size < limit && *from)
00499     {
00500       *(to + size) = *from;
00501       if (*from == ',' || *from == ';' || *from == '\n')
00502        break;
00503       from++;
00504       size++;
00505     }
00506 
00507   *(to + size) = 0;
00508   del_spaces (to);
00509 
00510   from++;
00511 
00512   return from;
00513 }
00514 
00515 static void
00516 msp430_profiler (int dummy ATTRIBUTE_UNUSED)
00517 {
00518   char   buffer[1024];
00519   char   f[32];
00520   char * str = buffer;
00521   char * flags = f;
00522   int    p_flags = 0;
00523   char * halt;
00524   int    ops = 0;
00525   int    left;
00526   char * s;
00527   segT   seg;
00528   int    subseg;
00529   char * end = 0;
00530   expressionS exp;
00531   expressionS exp1;
00532 
00533   s = input_line_pointer;
00534   end = input_line_pointer;
00535 
00536   while (*end && *end != '\n')
00537     end++;
00538 
00539   while (*s && *s != '\n')
00540     {
00541       if (*s == ',')
00542        ops++;
00543       s++;
00544     }
00545 
00546   left = 3 - ops;
00547 
00548   if (ops < 1)
00549     {
00550       as_bad (_(".profiler pseudo requires at least two operands."));
00551       input_line_pointer = end;
00552       return;
00553     }
00554 
00555   input_line_pointer = extract_operand (input_line_pointer, flags, 32);
00556 
00557   while (*flags)
00558     {
00559       switch (*flags)
00560        {
00561        case '"':
00562          break;
00563        case 'a':
00564          p_flags |= MSP430_PROFILER_FLAG_FRAGMENT;
00565          break;
00566        case 'j':
00567          p_flags |= MSP430_PROFILER_FLAG_JUMP;
00568          break;
00569        case 'P':
00570          p_flags |= MSP430_PROFILER_FLAG_PROLSTART;
00571          break;
00572        case 'p':
00573          p_flags |= MSP430_PROFILER_FLAG_PROLEND;
00574          break;
00575        case 'E':
00576          p_flags |= MSP430_PROFILER_FLAG_EPISTART;
00577          break;
00578        case 'e':
00579          p_flags |= MSP430_PROFILER_FLAG_EPIEND;
00580          break;
00581        case 's':
00582          p_flags |= MSP430_PROFILER_FLAG_ENTRY;
00583          break;
00584        case 'x':
00585          p_flags |= MSP430_PROFILER_FLAG_EXIT;
00586          break;
00587        case 'i':
00588          p_flags |= MSP430_PROFILER_FLAG_INITSECT;
00589          break;
00590        case 'f':
00591          p_flags |= MSP430_PROFILER_FLAG_FINISECT;
00592          break;
00593        case 'l':
00594          p_flags |= MSP430_PROFILER_FLAG_LIBCALL;
00595          break;
00596        case 'c':
00597          p_flags |= MSP430_PROFILER_FLAG_STDCALL;
00598          break;
00599        case 'd':
00600          p_flags |= MSP430_PROFILER_FLAG_STACKDMD;
00601          break;
00602        case 'I':
00603          p_flags |= MSP430_PROFILER_FLAG_ISR;
00604          break;
00605        case 't':
00606          p_flags |= MSP430_PROFILER_FLAG_EXTRA;
00607          break;
00608        default:
00609          as_warn (_("unknown profiling flag - ignored."));
00610          break;
00611        }
00612       flags++;
00613     }
00614 
00615   if (p_flags
00616       && (   ! pow2value (p_flags & (  MSP430_PROFILER_FLAG_ENTRY
00617                                  | MSP430_PROFILER_FLAG_EXIT))
00618          || ! pow2value (p_flags & (  MSP430_PROFILER_FLAG_PROLSTART
00619                                  | MSP430_PROFILER_FLAG_PROLEND
00620                                  | MSP430_PROFILER_FLAG_EPISTART
00621                                  | MSP430_PROFILER_FLAG_EPIEND))
00622          || ! pow2value (p_flags & (  MSP430_PROFILER_FLAG_INITSECT
00623                                  | MSP430_PROFILER_FLAG_FINISECT))))
00624     {
00625       as_bad (_("ambigious flags combination - '.profiler' directive ignored."));
00626       input_line_pointer = end;
00627       return;
00628     }
00629 
00630   /* Generate temp symbol which denotes current location.  */
00631   if (now_seg == absolute_section) /* Paranoja ?  */
00632     {
00633       exp1.X_op = O_constant;
00634       exp1.X_add_number = abs_section_offset;
00635       as_warn (_("profiling in absolute section? Hm..."));
00636     }
00637   else
00638     {
00639       exp1.X_op = O_symbol;
00640       exp1.X_add_symbol = symbol_temp_new_now ();
00641       exp1.X_add_number = 0;
00642     }
00643 
00644   /* Generate a symbol which holds flags value.  */
00645   exp.X_op = O_constant;
00646   exp.X_add_number = p_flags;
00647 
00648   /* Save current section.  */
00649   seg = now_seg;
00650   subseg = now_subseg;
00651 
00652   /* Now go to .profiler section.  */
00653   obj_elf_change_section (".profiler", SHT_PROGBITS, 0, 0, 0, 0, 0);
00654 
00655   /* Save flags.  */
00656   emit_expr (& exp, 2);
00657 
00658   /* Save label value.  */
00659   emit_expr (& exp1, 2);
00660 
00661   while (ops--)
00662     {
00663       /* Now get profiling info.  */
00664       halt = extract_operand (input_line_pointer, str, 1024);
00665       /* Process like ".word xxx" directive.  */
00666       parse_exp (str, & exp);
00667       emit_expr (& exp, 2);
00668       input_line_pointer = halt;
00669     }
00670 
00671   /* Fill the rest with zeros.  */
00672   exp.X_op = O_constant;
00673   exp.X_add_number = 0;
00674   while (left--)
00675     emit_expr (& exp, 2);
00676 
00677   /* Return to current section.  */
00678   subseg_set (seg, subseg);
00679 }
00680 
00681 static char *
00682 extract_word (char * from, char * to, int limit)
00683 {
00684   char *op_start;
00685   char *op_end;
00686   int size = 0;
00687 
00688   /* Drop leading whitespace.  */
00689   from = skip_space (from);
00690   *to = 0;
00691 
00692   /* Find the op code end.  */
00693   for (op_start = op_end = from; *op_end != 0 && is_part_of_name (*op_end);)
00694     {
00695       to[size++] = *op_end++;
00696       if (size + 1 >= limit)
00697        break;
00698     }
00699 
00700   to[size] = 0;
00701   return op_end;
00702 }
00703 
00704 #define OPTION_MMCU 'm'
00705 #define OPTION_RELAX 'Q'
00706 #define OPTION_POLYMORPHS 'P'
00707 
00708 static void
00709 msp430_set_arch (int dummy ATTRIBUTE_UNUSED)
00710 {
00711   char *str = (char *) alloca (32);       /* 32 for good measure.  */
00712 
00713   input_line_pointer = extract_word (input_line_pointer, str, 32);
00714 
00715   md_parse_option (OPTION_MMCU, str);
00716   bfd_set_arch_mach (stdoutput, TARGET_ARCH, msp430_mcu->mach);
00717 }
00718 
00719 static void
00720 show_mcu_list (FILE * stream)
00721 {
00722   int i;
00723 
00724   fprintf (stream, _("Known MCU names:\n"));
00725 
00726   for (i = 0; mcu_types[i].name; i++)
00727     fprintf (stream, _("\t %s\n"), mcu_types[i].name);
00728 
00729   fprintf (stream, "\n");
00730 }
00731 
00732 int
00733 md_parse_option (int c, char * arg)
00734 {
00735   int i;
00736 
00737   switch (c)
00738     {
00739     case OPTION_MMCU:
00740       for (i = 0; mcu_types[i].name; ++i)
00741        if (strcmp (mcu_types[i].name, arg) == 0)
00742          break;
00743 
00744       if (!mcu_types[i].name)
00745        {
00746          show_mcu_list (stderr);
00747          as_fatal (_("unknown MCU: %s\n"), arg);
00748        }
00749 
00750       if (msp430_mcu == &default_mcu || msp430_mcu->mach == mcu_types[i].mach)
00751        msp430_mcu = &mcu_types[i];
00752       else
00753        as_fatal (_("redefinition of mcu type %s' to %s'"),
00754                 msp430_mcu->name, mcu_types[i].name);
00755       return 1;
00756       break;
00757       
00758     case OPTION_RELAX:
00759       msp430_enable_relax = 1; 
00760       return 1;
00761       break;
00762       
00763     case OPTION_POLYMORPHS:
00764       msp430_enable_polys = 1;
00765       return 1;
00766       break;
00767     }
00768 
00769   return 0;
00770 }
00771 
00772 
00773 const pseudo_typeS md_pseudo_table[] =
00774 {
00775   {"arch", msp430_set_arch, 0},
00776   {"profiler", msp430_profiler, 0},
00777   {NULL, NULL, 0}
00778 };
00779 
00780 const char *md_shortopts = "m:";
00781 
00782 struct option md_longopts[] =
00783 {
00784   {"mmcu", required_argument, NULL, OPTION_MMCU},
00785   {"mP", no_argument, NULL, OPTION_POLYMORPHS},
00786   {"mQ", no_argument, NULL, OPTION_RELAX},
00787   {NULL, no_argument, NULL, 0}
00788 };
00789 
00790 size_t md_longopts_size = sizeof (md_longopts);
00791 
00792 void
00793 md_show_usage (FILE * stream)
00794 {
00795   fprintf (stream,
00796           _("MSP430 options:\n"
00797             "  -mmcu=[msp430-name] select microcontroller type\n"
00798             "                  msp430x110  msp430x112\n"
00799             "                  msp430x1101 msp430x1111\n"
00800             "                  msp430x1121 msp430x1122 msp430x1132\n"
00801             "                  msp430x122  msp430x123\n"
00802             "                  msp430x1222 msp430x1232\n"
00803             "                  msp430x133  msp430x135\n"
00804             "                  msp430x1331 msp430x1351\n"
00805             "                  msp430x147  msp430x148  msp430x149\n"
00806             "                  msp430x155  msp430x156  msp430x157\n"
00807             "                  msp430x167  msp430x168  msp430x169\n"
00808             "                  msp430x1610 msp430x1611 msp430x1612\n"
00809             "                  msp430x311  msp430x312  msp430x313  msp430x314  msp430x315\n"
00810             "                  msp430x323  msp430x325\n"
00811             "                  msp430x336  msp430x337\n"
00812             "                  msp430x412  msp430x413  msp430x415  msp430x417\n"
00813             "                  msp430xE423 msp430xE425 msp430E427\n"
00814             "                  msp430xW423 msp430xW425 msp430W427\n"
00815             "                  msp430xG437 msp430xG438 msp430G439\n"
00816             "                  msp430x435  msp430x436  msp430x437\n"
00817             "                  msp430x447  msp430x448  msp430x449\n"));
00818   fprintf (stream,
00819           _("  -mQ - enable relaxation at assembly time. DANGEROUS!\n"
00820             "  -mP - enable polymorph instructions\n"));
00821 
00822   show_mcu_list (stream);
00823 }
00824 
00825 symbolS *
00826 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
00827 {
00828   return 0;
00829 }
00830 
00831 static char *
00832 extract_cmd (char * from, char * to, int limit)
00833 {
00834   int size = 0;
00835 
00836   while (*from && ! ISSPACE (*from) && *from != '.' && limit > size)
00837     {
00838       *(to + size) = *from;
00839       from++;
00840       size++;
00841     }
00842 
00843   *(to + size) = 0;
00844 
00845   return from;
00846 }
00847 
00848 /* Turn a string in input_line_pointer into a floating point constant
00849    of type TYPE, and store the appropriate bytes in *LITP.  The number
00850    of LITTLENUMS emitted is stored in *SIZEP.  An error message is
00851    returned, or NULL on OK.  */
00852 
00853 char *
00854 md_atof (int type, char * litP, int * sizeP)
00855 {
00856   int prec;
00857   LITTLENUM_TYPE words[4];
00858   LITTLENUM_TYPE *wordP;
00859   char *t;
00860 
00861   switch (type)
00862     {
00863     case 'f':
00864       prec = 2;
00865       break;
00866     case 'd':
00867       prec = 4;
00868       break;
00869     default:
00870       *sizeP = 0;
00871       return _("bad call to md_atof");
00872     }
00873 
00874   t = atof_ieee (input_line_pointer, type, words);
00875   if (t)
00876     input_line_pointer = t;
00877 
00878   *sizeP = prec * sizeof (LITTLENUM_TYPE);
00879 
00880   /* This loop outputs the LITTLENUMs in REVERSE order.  */
00881   for (wordP = words + prec - 1; prec--;)
00882     {
00883       md_number_to_chars (litP, (valueT) (*wordP--), sizeof (LITTLENUM_TYPE));
00884       litP += sizeof (LITTLENUM_TYPE);
00885     }
00886 
00887   return NULL;
00888 }
00889 
00890 void
00891 md_begin (void)
00892 {
00893   struct msp430_opcode_s * opcode;
00894   msp430_hash = hash_new ();
00895 
00896   for (opcode = msp430_opcodes; opcode->name; opcode++)
00897     hash_insert (msp430_hash, opcode->name, (char *) opcode);
00898 
00899   bfd_set_arch_mach (stdoutput, TARGET_ARCH, msp430_mcu->mach);
00900 }
00901 
00902 static int
00903 check_reg (char * t)
00904 {
00905   /* If this is a reg numb, str 't' must be a number from 0 - 15.  */
00906 
00907   if (strlen (t) > 2 && *(t + 2) != '+')
00908     return 1;
00909 
00910   while (*t)
00911     {
00912       if ((*t < '0' || *t > '9') && *t != '+')
00913        break;
00914       t++;
00915     }
00916 
00917   if (*t)
00918     return 1;
00919 
00920   return 0;
00921 }
00922 
00923 
00924 static int
00925 msp430_srcoperand (struct msp430_operand_s * op,
00926                  char * l, int bin, int * imm_op)
00927 {
00928   char *__tl = l;
00929 
00930   /* Check if an immediate #VALUE.  The hash sign should be only at the beginning!  */
00931   if (*l == '#')
00932     {
00933       char *h = l;
00934       int vshift = -1;
00935       int rval = 0;
00936 
00937       /* Check if there is:
00938         llo(x) - least significant 16 bits, x &= 0xffff
00939         lhi(x) - x = (x >> 16) & 0xffff,
00940         hlo(x) - x = (x >> 32) & 0xffff,
00941         hhi(x) - x = (x >> 48) & 0xffff
00942         The value _MUST_ be constant expression: #hlo(1231231231).  */
00943 
00944       *imm_op = 1;
00945 
00946       if (strncasecmp (h, "#llo(", 5) == 0)
00947        {
00948          vshift = 0;
00949          rval = 3;
00950        }
00951       else if (strncasecmp (h, "#lhi(", 5) == 0)
00952        {
00953          vshift = 1;
00954          rval = 3;
00955        }
00956       else if (strncasecmp (h, "#hlo(", 5) == 0)
00957        {
00958          vshift = 2;
00959          rval = 3;
00960        }
00961       else if (strncasecmp (h, "#hhi(", 5) == 0)
00962        {
00963          vshift = 3;
00964          rval = 3;
00965        }
00966       else if (strncasecmp (h, "#lo(", 4) == 0)
00967        {
00968          vshift = 0;
00969          rval = 2;
00970        }
00971       else if (strncasecmp (h, "#hi(", 4) == 0)
00972        {
00973          vshift = 1;
00974          rval = 2;
00975        }
00976 
00977       op->reg = 0;          /* Reg PC.  */
00978       op->am = 3;
00979       op->ol = 1;           /* Immediate  will follow an instruction.  */
00980       __tl = h + 1 + rval;
00981       op->mode = OP_EXP;
00982 
00983       parse_exp (__tl, &(op->exp));
00984       if (op->exp.X_op == O_constant)
00985        {
00986          int x = op->exp.X_add_number;
00987 
00988          if (vshift == 0)
00989            {
00990              x = x & 0xffff;
00991              op->exp.X_add_number = x;
00992            }
00993          else if (vshift == 1)
00994            {
00995              x = (x >> 16) & 0xffff;
00996              op->exp.X_add_number = x;
00997            }
00998          else if (vshift > 1)
00999            {
01000              if (x < 0)
01001               op->exp.X_add_number = -1;
01002              else
01003               op->exp.X_add_number = 0;   /* Nothing left.  */
01004              x = op->exp.X_add_number;
01005            }
01006 
01007          if (op->exp.X_add_number > 65535 || op->exp.X_add_number < -32768)
01008            {
01009              as_bad (_("value %d out of range. Use #lo() or #hi()"), x);
01010              return 1;
01011            }
01012 
01013          /* Now check constants.  */
01014          /* Substitute register mode with a constant generator if applicable.  */
01015 
01016          x = (short) x;     /* Extend sign.  */
01017 
01018          if (x == 0)
01019            {
01020              op->reg = 3;
01021              op->am = 0;
01022              op->ol = 0;
01023              op->mode = OP_REG;
01024            }
01025          else if (x == 1)
01026            {
01027              op->reg = 3;
01028              op->am = 1;
01029              op->ol = 0;
01030              op->mode = OP_REG;
01031            }
01032          else if (x == 2)
01033            {
01034              op->reg = 3;
01035              op->am = 2;
01036              op->ol = 0;
01037              op->mode = OP_REG;
01038            }
01039          else if (x == -1)
01040            {
01041              op->reg = 3;
01042              op->am = 3;
01043              op->ol = 0;
01044              op->mode = OP_REG;
01045            }
01046          else if (x == 4)
01047            {
01048 #ifdef PUSH_1X_WORKAROUND
01049              if (bin == 0x1200)
01050               {
01051                 /* Remove warning as confusing.
01052                    as_warn(_("Hardware push bug workaround")); */
01053               }
01054              else
01055 #endif
01056               {
01057                 op->reg = 2;
01058                 op->am = 2;
01059                 op->ol = 0;
01060                 op->mode = OP_REG;
01061               }
01062            }
01063          else if (x == 8)
01064            {
01065 #ifdef PUSH_1X_WORKAROUND
01066              if (bin == 0x1200)
01067               {
01068                 /* Remove warning as confusing.
01069                    as_warn(_("Hardware push bug workaround")); */
01070               }
01071              else
01072 #endif
01073               {
01074                 op->reg = 2;
01075                 op->am = 3;
01076                 op->ol = 0;
01077                 op->mode = OP_REG;
01078               }
01079            }
01080        }
01081       else if (op->exp.X_op == O_symbol)
01082        {
01083          op->mode = OP_EXP;
01084        }
01085       else if (op->exp.X_op == O_big)
01086        {
01087          short x;
01088          if (vshift != -1)
01089            {
01090              op->exp.X_op = O_constant;
01091              op->exp.X_add_number = 0xffff & generic_bignum[vshift];
01092              x = op->exp.X_add_number;
01093            }
01094          else
01095            {
01096              as_bad (_
01097                     ("unknown expression in operand %s. use #llo() #lhi() #hlo() #hhi() "),
01098                     l);
01099              return 1;
01100            }
01101 
01102          if (x == 0)
01103            {
01104              op->reg = 3;
01105              op->am = 0;
01106              op->ol = 0;
01107              op->mode = OP_REG;
01108            }
01109          else if (x == 1)
01110            {
01111              op->reg = 3;
01112              op->am = 1;
01113              op->ol = 0;
01114              op->mode = OP_REG;
01115            }
01116          else if (x == 2)
01117            {
01118              op->reg = 3;
01119              op->am = 2;
01120              op->ol = 0;
01121              op->mode = OP_REG;
01122            }
01123          else if (x == -1)
01124            {
01125              op->reg = 3;
01126              op->am = 3;
01127              op->ol = 0;
01128              op->mode = OP_REG;
01129            }
01130          else if (x == 4)
01131            {
01132              op->reg = 2;
01133              op->am = 2;
01134              op->ol = 0;
01135              op->mode = OP_REG;
01136            }
01137          else if (x == 8)
01138            {
01139              op->reg = 2;
01140              op->am = 3;
01141              op->ol = 0;
01142              op->mode = OP_REG;
01143            }
01144        }
01145       /* Redudant (yet) check.  */
01146       else if (op->exp.X_op == O_register)
01147        as_bad
01148          (_("Registers cannot be used within immediate expression [%s]"), l);
01149       else
01150        as_bad (_("unknown operand %s"), l);
01151 
01152       return 0;
01153     }
01154 
01155   /* Check if absolute &VALUE (assume that we can construct something like ((a&b)<<7 + 25).  */
01156   if (*l == '&')
01157     {
01158       char *h = l;
01159 
01160       op->reg = 2;          /* reg 2 in absolute addr mode.  */
01161       op->am = 1;           /* mode As == 01 bin.  */
01162       op->ol = 1;           /* Immediate value followed by instruction.  */
01163       __tl = h + 1;
01164       parse_exp (__tl, &(op->exp));
01165       op->mode = OP_EXP;
01166       if (op->exp.X_op == O_constant)
01167        {
01168          int x = op->exp.X_add_number;
01169 
01170          if (x > 65535 || x < -32768)
01171            {
01172              as_bad (_("value out of range: %d"), x);
01173              return 1;
01174            }
01175        }
01176       else if (op->exp.X_op == O_symbol)
01177        ;
01178       else
01179        {
01180          /* Redudant (yet) check.  */
01181          if (op->exp.X_op == O_register)
01182            as_bad
01183              (_("Registers cannot be used within absolute expression [%s]"), l);
01184          else
01185            as_bad (_("unknown expression in operand %s"), l);
01186          return 1;
01187        }
01188       return 0;
01189     }
01190 
01191   /* Check if indirect register mode @Rn / postincrement @Rn+.  */
01192   if (*l == '@')
01193     {
01194       char *t = l;
01195       char *m = strchr (l, '+');
01196 
01197       if (t != l)
01198        {
01199          as_bad (_("unknown addressing mode %s"), l);
01200          return 1;
01201        }
01202 
01203       t++;
01204       if (*t != 'r' && *t != 'R')
01205        {
01206          as_bad (_("unknown addressing mode %s"), l);
01207          return 1;
01208        }
01209 
01210       t++;    /* Points to the reg value.  */
01211 
01212       if (check_reg (t))
01213        {
01214          as_bad (_("Bad register name r%s"), t);
01215          return 1;
01216        }
01217 
01218       op->mode = OP_REG;
01219       op->am = m ? 3 : 2;
01220       op->ol = 0;
01221       if (m)
01222        *m = 0;                     /* strip '+' */
01223       op->reg = atoi (t);
01224       if (op->reg < 0 || op->reg > 15)
01225        {
01226          as_bad (_("MSP430 does not have %d registers"), op->reg);
01227          return 1;
01228        }
01229 
01230       return 0;
01231     }
01232 
01233   /* Check if register indexed X(Rn).  */
01234   do
01235     {
01236       char *h = strrchr (l, '(');
01237       char *m = strrchr (l, ')');
01238       char *t;
01239 
01240       *imm_op = 1;
01241 
01242       if (!h)
01243        break;
01244       if (!m)
01245        {
01246          as_bad (_("')' required"));
01247          return 1;
01248        }
01249 
01250       t = h;
01251       op->am = 1;
01252       op->ol = 1;
01253       /* Extract a register.  */
01254       t++;    /* Advance pointer.  */
01255 
01256       if (*t != 'r' && *t != 'R')
01257        {
01258          as_bad (_
01259                 ("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"),
01260                 l);
01261          return 1;
01262        }
01263       t++;
01264 
01265       op->reg = *t - '0';
01266       if (op->reg > 9 || op->reg < 0)
01267        {
01268          as_bad (_("unknown operator (r%s substituded as a register name"),
01269                 t);
01270          return 1;
01271        }
01272       t++;
01273       if (*t != ')')
01274        {
01275          op->reg = op->reg * 10;
01276          op->reg += *t - '0';
01277 
01278          if (op->reg > 15)
01279            {
01280              as_bad (_("unknown operator %s"), l);
01281              return 1;
01282            }
01283          if (op->reg == 2)
01284            {
01285              as_bad (_("r2 should not be used in indexed addressing mode"));
01286              return 1;
01287            }
01288 
01289          if (*(t + 1) != ')')
01290            {
01291              as_bad (_("unknown operator %s"), l);
01292              return 1;
01293            }
01294        }
01295 
01296       /* Extract constant.  */
01297       __tl = l;
01298       *h = 0;
01299       op->mode = OP_EXP;
01300       parse_exp (__tl, &(op->exp));
01301       if (op->exp.X_op == O_constant)
01302        {
01303          int x = op->exp.X_add_number;
01304 
01305          if (x > 65535 || x < -32768)
01306            {
01307              as_bad (_("value out of range: %d"), x);
01308              return 1;
01309            }
01310 
01311          if (x == 0)
01312            {
01313              op->mode = OP_REG;
01314              op->am = 2;
01315              op->ol = 0;
01316              return 0;
01317            }
01318        }
01319       else if (op->exp.X_op == O_symbol)
01320        ;
01321       else
01322        {
01323          /* Redudant (yet) check.  */
01324          if (op->exp.X_op == O_register)
01325            as_bad
01326              (_("Registers cannot be used as a prefix of indexed expression [%s]"), l);
01327          else
01328            as_bad (_("unknown expression in operand %s"), l);
01329          return 1;
01330        }
01331 
01332       return 0;
01333     }
01334   while (0);
01335 
01336   /* Register mode 'mov r1,r2'.  */
01337   do
01338     {
01339       char *t = l;
01340 
01341       /* Operand should be a register.  */
01342       if (*t == 'r' || *t == 'R')
01343        {
01344          int x = atoi (t + 1);
01345 
01346          if (check_reg (t + 1))
01347            break;
01348 
01349          if (x < 0 || x > 15)
01350            break;           /* Symbolic mode.  */
01351 
01352          op->mode = OP_REG;
01353          op->am = 0;
01354          op->ol = 0;
01355          op->reg = x;
01356          return 0;
01357        }
01358     }
01359   while (0);
01360 
01361   /* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'.  */
01362   do
01363     {
01364       op->mode = OP_EXP;
01365       op->reg = 0;          /* PC relative... be careful.  */
01366       op->am = 1;
01367       op->ol = 1;
01368       __tl = l;
01369       parse_exp (__tl, &(op->exp));
01370       return 0;
01371     }
01372   while (0);
01373 
01374   /* Unreachable.  */
01375   as_bad (_("unknown addressing mode for operand %s"), l);
01376   return 1;
01377 }
01378 
01379 
01380 static int
01381 msp430_dstoperand (struct msp430_operand_s * op, char * l, int bin)
01382 {
01383   int dummy;
01384   int ret = msp430_srcoperand (op, l, bin, & dummy);
01385 
01386   if (ret)
01387     return ret;
01388 
01389   if (op->am == 2)
01390     {
01391       char *__tl = "0";
01392 
01393       op->mode = OP_EXP;
01394       op->am = 1;
01395       op->ol = 1;
01396       parse_exp (__tl, &(op->exp));
01397 
01398       if (op->exp.X_op != O_constant || op->exp.X_add_number != 0)
01399        {
01400          as_bad (_("Internal bug. Try to use 0(r%d) instead of @r%d"),
01401                 op->reg, op->reg);
01402          return 1;
01403        }
01404       return 0;
01405     }
01406 
01407   if (op->am > 1)
01408     {
01409       as_bad (_
01410              ("this addressing mode is not applicable for destination operand"));
01411       return 1;
01412     }
01413   return 0;
01414 }
01415 
01416 
01417 /* Parse instruction operands.
01418    Return binary opcode.  */
01419 
01420 static unsigned int
01421 msp430_operands (struct msp430_opcode_s * opcode, char * line)
01422 {
01423   int bin = opcode->bin_opcode;    /* Opcode mask.  */
01424   int __is = 0;
01425   char l1[MAX_OP_LEN], l2[MAX_OP_LEN];
01426   char *frag;
01427   int where;
01428   struct msp430_operand_s op1, op2;
01429   int res = 0;
01430   static short ZEROS = 0;
01431   int byte_op, imm_op;
01432 
01433   /* Opcode is the one from opcodes table
01434      line contains something like
01435      [.w] @r2+, 5(R1)
01436      or
01437      .b @r2+, 5(R1).  */
01438 
01439   /* Check if byte or word operation.  */
01440   if (*line == '.' && TOLOWER (*(line + 1)) == 'b')
01441     {
01442       bin |= BYTE_OPERATION;
01443       byte_op = 1;
01444     }
01445   else
01446     byte_op = 0;
01447 
01448   /* skip .[bwBW].  */
01449   while (! ISSPACE (*line) && *line)
01450     line++;
01451 
01452   if (opcode->insn_opnumb && (!*line || *line == '\n'))
01453     {
01454       as_bad (_("instruction %s requires %d operand(s)"),
01455              opcode->name, opcode->insn_opnumb);
01456       return 0;
01457     }
01458 
01459   memset (l1, 0, sizeof (l1));
01460   memset (l2, 0, sizeof (l2));
01461   memset (&op1, 0, sizeof (op1));
01462   memset (&op2, 0, sizeof (op2));
01463 
01464   imm_op = 0;
01465 
01466   switch (opcode->fmt)
01467     {
01468     case 0:                 /* Emulated.  */
01469       switch (opcode->insn_opnumb)
01470        {
01471        case 0:
01472          /* Set/clear bits instructions.  */
01473          __is = 2;
01474          frag = frag_more (__is);
01475          bfd_putl16 ((bfd_vma) bin, frag);
01476          dwarf2_emit_insn (__is);
01477          break;
01478        case 1:
01479          /* Something which works with destination operand.  */
01480          line = extract_operand (line, l1, sizeof (l1));
01481          res = msp430_dstoperand (&op1, l1, opcode->bin_opcode);
01482          if (res)
01483            break;
01484 
01485          bin |= (op1.reg | (op1.am << 7));
01486          __is = 1 + op1.ol;
01487          frag = frag_more (2 * __is);
01488          where = frag - frag_now->fr_literal;
01489          bfd_putl16 ((bfd_vma) bin, frag);
01490          dwarf2_emit_insn (2 * __is);
01491 
01492          if (op1.mode == OP_EXP)
01493            {
01494              where += 2;
01495              bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
01496 
01497              if (op1.reg)
01498               fix_new_exp (frag_now, where, 2,
01499                           &(op1.exp), FALSE, CHECK_RELOC_MSP430);
01500              else
01501               fix_new_exp (frag_now, where, 2,
01502                           &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
01503            }
01504          break;
01505 
01506        case 2:
01507          {
01508            /* Shift instruction.  */
01509            line = extract_operand (line, l1, sizeof (l1));
01510            strncpy (l2, l1, sizeof (l2));
01511            l2[sizeof (l2) - 1] = '\0';
01512            res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op);
01513            res += msp430_dstoperand (&op2, l2, opcode->bin_opcode);
01514 
01515            if (res)
01516              break;  /* An error occurred.  All warnings were done before.  */
01517 
01518            bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
01519 
01520            __is = 1 + op1.ol + op2.ol;    /* insn size in words.  */
01521            frag = frag_more (2 * __is);
01522            where = frag - frag_now->fr_literal;
01523            bfd_putl16 ((bfd_vma) bin, frag);
01524            dwarf2_emit_insn (2 * __is);
01525            
01526            if (op1.mode == OP_EXP)
01527              {
01528               where += 2;   /* Advance 'where' as we do not know _where_.  */
01529               bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
01530 
01531               if (op1.reg || (op1.reg == 0 && op1.am == 3))    /* Not PC relative.  */
01532                 fix_new_exp (frag_now, where, 2,
01533                             &(op1.exp), FALSE, CHECK_RELOC_MSP430);
01534               else
01535                 fix_new_exp (frag_now, where, 2,
01536                             &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
01537              }
01538 
01539            if (op2.mode == OP_EXP)
01540              {
01541               imm_op = 0;
01542               bfd_putl16 ((bfd_vma) ZEROS, frag + 2 + ((__is == 3) ? 2 : 0));
01543 
01544               if (op2.reg)  /* Not PC relative.  */
01545                 fix_new_exp (frag_now, where + 2, 2,
01546                             &(op2.exp), FALSE, CHECK_RELOC_MSP430);
01547               else
01548                 fix_new_exp (frag_now, where + 2, 2,
01549                             &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
01550              }
01551            break;
01552          }
01553        case 3:
01554          /* Branch instruction => mov dst, r0.  */
01555          line = extract_operand (line, l1, sizeof (l1));
01556 
01557          res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op);
01558          if (res)
01559            break;
01560 
01561          byte_op = 0;
01562          imm_op = 0;
01563 
01564          bin |= ((op1.reg << 8) | (op1.am << 4));
01565          __is = 1 + op1.ol;
01566          frag = frag_more (2 * __is);
01567          where = frag - frag_now->fr_literal;
01568          bfd_putl16 ((bfd_vma) bin, frag);
01569          dwarf2_emit_insn (2 * __is);
01570 
01571          if (op1.mode == OP_EXP)
01572            {
01573              where += 2;
01574              bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
01575 
01576              if (op1.reg || (op1.reg == 0 && op1.am == 3))
01577               fix_new_exp (frag_now, where, 2,
01578                           &(op1.exp), FALSE, CHECK_RELOC_MSP430);
01579              else
01580               fix_new_exp (frag_now, where, 2,
01581                           &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
01582            }
01583          break;
01584        }
01585       break;
01586 
01587     case 1:                 /* Format 1, double operand.  */
01588       line = extract_operand (line, l1, sizeof (l1));
01589       line = extract_operand (line, l2, sizeof (l2));
01590       res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op);
01591       res += msp430_dstoperand (&op2, l2, opcode->bin_opcode);
01592 
01593       if (res)
01594        break;               /* Error occurred.  All warnings were done before.  */
01595 
01596       bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
01597 
01598       __is = 1 + op1.ol + op2.ol;  /* insn size in words.  */
01599       frag = frag_more (2 * __is);
01600       where = frag - frag_now->fr_literal;
01601       bfd_putl16 ((bfd_vma) bin, frag);
01602       dwarf2_emit_insn (2 * __is);
01603 
01604       if (op1.mode == OP_EXP)
01605        {
01606          where += 2;        /* Advance where as we do not know _where_.  */
01607          bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
01608 
01609          if (op1.reg || (op1.reg == 0 && op1.am == 3))  /* Not PC relative.  */
01610            fix_new_exp (frag_now, where, 2,
01611                       &(op1.exp), FALSE, CHECK_RELOC_MSP430);
01612          else
01613            fix_new_exp (frag_now, where, 2,
01614                       &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
01615        }
01616 
01617       if (op2.mode == OP_EXP)
01618        {
01619          imm_op = 0;
01620          bfd_putl16 ((bfd_vma) ZEROS, frag + 2 + ((__is == 3) ? 2 : 0));
01621 
01622          if (op2.reg)              /* Not PC relative.  */
01623            fix_new_exp (frag_now, where + 2, 2,
01624                       &(op2.exp), FALSE, CHECK_RELOC_MSP430);
01625          else
01626            fix_new_exp (frag_now, where + 2, 2,
01627                       &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
01628        }
01629       break;
01630 
01631     case 2:                 /* Single-operand mostly instr.  */
01632       if (opcode->insn_opnumb == 0)
01633        {
01634          /* reti instruction.  */
01635          frag = frag_more (2);
01636          bfd_putl16 ((bfd_vma) bin, frag);
01637          dwarf2_emit_insn (2);
01638          break;
01639        }
01640 
01641       line = extract_operand (line, l1, sizeof (l1));
01642       res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op);
01643       if (res)
01644        break;        /* Error in operand.  */
01645 
01646       bin |= op1.reg | (op1.am << 4);
01647       __is = 1 + op1.ol;
01648       frag = frag_more (2 * __is);
01649       where = frag - frag_now->fr_literal;
01650       bfd_putl16 ((bfd_vma) bin, frag);
01651       dwarf2_emit_insn (2 * __is);
01652 
01653       if (op1.mode == OP_EXP)
01654        {
01655          bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
01656 
01657          if (op1.reg || (op1.reg == 0 && op1.am == 3))  /* Not PC relative.  */
01658            fix_new_exp (frag_now, where + 2, 2,
01659                       &(op1.exp), FALSE, CHECK_RELOC_MSP430);
01660          else
01661            fix_new_exp (frag_now, where + 2, 2,
01662                       &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
01663        }
01664       break;
01665 
01666     case 3:                 /* Conditional jumps instructions.  */
01667       line = extract_operand (line, l1, sizeof (l1));
01668       /* l1 is a label.  */
01669       if (l1[0])
01670        {
01671          char *m = l1;
01672          expressionS exp;
01673 
01674          if (*m == '$')
01675            m++;
01676 
01677          parse_exp (m, &exp);
01678          frag = frag_more (2);     /* Instr size is 1 word.  */
01679 
01680          /* In order to handle something like:
01681 
01682             and #0x8000, r5
01683             tst r5
01684             jz   4     ;       skip next 4 bytes
01685             inv r5
01686             inc r5
01687             nop        ;       will jump here if r5 positive or zero
01688 
01689             jCOND      -n      ;assumes jump n bytes backward:
01690 
01691             mov r5,r6
01692             jmp -2
01693 
01694             is equal to:
01695             lab:
01696             mov r5,r6
01697             jmp lab
01698 
01699             jCOND      $n      ; jump from PC in either direction.  */
01700 
01701          if (exp.X_op == O_constant)
01702            {
01703              int x = exp.X_add_number;
01704 
01705              if (x & 1)
01706               {
01707                 as_warn (_("Even number required. Rounded to %d"), x + 1);
01708                 x++;
01709               }
01710 
01711              if ((*l1 == '$' && x > 0) || x < 0)
01712               x -= 2;
01713 
01714              x >>= 1;
01715 
01716              if (x > 512 || x < -511)
01717               {
01718                 as_bad (_("Wrong displacement  %d"), x << 1);
01719                 break;
01720               }
01721 
01722              bin |= x & 0x3ff;
01723              bfd_putl16 ((bfd_vma) bin, frag);
01724            }
01725          else if (exp.X_op == O_symbol && *l1 != '$')
01726            {
01727              where = frag - frag_now->fr_literal;
01728              fix_new_exp (frag_now, where, 2,
01729                         &exp, TRUE, BFD_RELOC_MSP430_10_PCREL);
01730 
01731              bfd_putl16 ((bfd_vma) bin, frag);
01732            }
01733          else if (*l1 == '$')
01734            {
01735              as_bad (_("instruction requires label sans '$'"));
01736            }
01737          else
01738            {
01739              as_bad (_
01740                     ("instruction requires label or value in range -511:512"));
01741            }
01742          dwarf2_emit_insn (2 * __is);
01743          break;
01744        }
01745       else
01746        {
01747          as_bad (_("instruction requires label"));
01748          break;
01749        }
01750       break;
01751 
01752     case 4:   /* Extended jumps.  */
01753       if (!msp430_enable_polys)
01754        {
01755          as_bad(_("polymorphs are not enabled. Use -mP option to enable."));
01756          break;
01757        }
01758        
01759       line = extract_operand (line, l1, sizeof (l1));
01760       if (l1[0])
01761        {
01762          char *m = l1;
01763          expressionS exp;
01764 
01765          /* Ignore absolute addressing. make it PC relative anyway.  */
01766          if (*m == '#' || *m == '$')
01767            m++;
01768 
01769          parse_exp (m, & exp);
01770          if (exp.X_op == O_symbol)
01771            {
01772              /* Relaxation required.  */
01773              struct rcodes_s rc = msp430_rcodes[opcode->insn_opnumb];
01774 
01775              /* The parameter to dwarf2_emit_insn is actually the offset to the start
01776                of the insn from the fix piece of instruction that was emitted.
01777                Since next fragments may have variable size we tie debug info
01778                 to the beginning of the instruction. */
01779              frag = frag_more (8);
01780              dwarf2_emit_insn (0);
01781              bfd_putl16 ((bfd_vma) rc.sop, frag);
01782              frag = frag_variant (rs_machine_dependent, 8, 2,
01783                                ENCODE_RELAX (rc.lpos, STATE_BITS10), /* Wild guess.  */
01784                                exp.X_add_symbol,
01785                                0,  /* Offset is zero if jump dist less than 1K.  */
01786                                (char *) frag);
01787              break;
01788            }
01789        }
01790 
01791       as_bad (_("instruction requires label"));
01792       break;
01793 
01794     case 5:   /* Emulated extended branches.  */
01795       if (!msp430_enable_polys)
01796        {
01797          as_bad(_("polymorphs are not enabled. Use -mP option to enable."));
01798          break;
01799        }
01800       line = extract_operand (line, l1, sizeof (l1));
01801       if (l1[0])
01802        {
01803          char * m = l1;
01804          expressionS exp;
01805 
01806          /* Ignore absolute addressing. make it PC relative anyway.  */
01807          if (*m == '#' || *m == '$')
01808            m++;
01809 
01810          parse_exp (m, & exp);
01811          if (exp.X_op == O_symbol)
01812            {
01813              /* Relaxation required.  */
01814              struct hcodes_s hc = msp430_hcodes[opcode->insn_opnumb];
01815 
01816              frag = frag_more (8);
01817              dwarf2_emit_insn (0);
01818              bfd_putl16 ((bfd_vma) hc.op0, frag);
01819              bfd_putl16 ((bfd_vma) hc.op1, frag+2);
01820 
01821              frag = frag_variant (rs_machine_dependent, 8, 2,
01822                                ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_BITS10), /* Wild guess.  */
01823                                exp.X_add_symbol,
01824                                0,  /* Offset is zero if jump dist less than 1K.  */
01825                                (char *) frag);
01826              break;
01827            }
01828        }
01829 
01830       as_bad (_("instruction requires label"));
01831       break;
01832 
01833     default:
01834       as_bad (_("Ilegal instruction or not implmented opcode."));
01835     }
01836 
01837   input_line_pointer = line;
01838   return 0;
01839 }
01840 
01841 void
01842 md_assemble (char * str)
01843 {
01844   struct msp430_opcode_s * opcode;
01845   char cmd[32];
01846   unsigned int i = 0;
01847 
01848   str = skip_space (str);   /* Skip leading spaces.  */
01849   str = extract_cmd (str, cmd, sizeof (cmd));
01850 
01851   while (cmd[i] && i < sizeof (cmd))
01852     {
01853       char a = TOLOWER (cmd[i]);
01854       cmd[i] = a;
01855       i++;
01856     }
01857 
01858   if (!cmd[0])
01859     {
01860       as_bad (_("can't find opcode "));
01861       return;
01862     }
01863 
01864   opcode = (struct msp430_opcode_s *) hash_find (msp430_hash, cmd);
01865 
01866   if (opcode == NULL)
01867     {
01868       as_bad (_("unknown opcode `%s'"), cmd);
01869       return;
01870     }
01871 
01872   {
01873     char *__t = input_line_pointer;
01874 
01875     msp430_operands (opcode, str);
01876     input_line_pointer = __t;
01877   }
01878 }
01879 
01880 /* GAS will call this function for each section at the end of the assembly,
01881    to permit the CPU backend to adjust the alignment of a section.  */
01882 
01883 valueT
01884 md_section_align (asection * seg, valueT addr)
01885 {
01886   int align = bfd_get_section_alignment (stdoutput, seg);
01887 
01888   return ((addr + (1 << align) - 1) & (-1 << align));
01889 }
01890 
01891 /* If you define this macro, it should return the offset between the
01892    address of a PC relative fixup and the position from which the PC
01893    relative adjustment should be made.  On many processors, the base
01894    of a PC relative instruction is the next instruction, so this
01895    macro would return the length of an instruction.  */
01896 
01897 long
01898 md_pcrel_from_section (fixS * fixp, segT sec)
01899 {
01900   if (fixp->fx_addsy != (symbolS *) NULL
01901       && (!S_IS_DEFINED (fixp->fx_addsy)
01902          || (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
01903     return 0;
01904 
01905   return fixp->fx_frag->fr_address + fixp->fx_where;
01906 }
01907 
01908 /* Replaces standard TC_FORCE_RELOCATION_LOCAL.
01909    Now it handles the situation when relocations
01910    have to be passed to linker. */
01911 int
01912 msp430_force_relocation_local(fixS *fixp)
01913 {
01914   if (msp430_enable_polys
01915         && !msp430_enable_relax)
01916     return 1;
01917   else
01918     return (!fixp->fx_pcrel
01919            || generic_force_reloc(fixp));
01920 }
01921 
01922 
01923 /* GAS will call this for each fixup.  It should store the correct
01924    value in the object file.  */
01925 void
01926 md_apply_fix (fixS * fixp, valueT * valuep, segT seg)
01927 {
01928   unsigned char * where;
01929   unsigned long insn;
01930   long value;
01931 
01932   if (fixp->fx_addsy == (symbolS *) NULL)
01933     {
01934       value = *valuep;
01935       fixp->fx_done = 1;
01936     }
01937   else if (fixp->fx_pcrel)
01938     {
01939       segT s = S_GET_SEGMENT (fixp->fx_addsy);
01940 
01941       if (fixp->fx_addsy && (s == seg || s == absolute_section))
01942        {
01943          /* FIXME: We can appear here only in case if we perform a pc
01944             relative jump to the label which is i) global, ii) locally
01945             defined or this is a jump to an absolute symbol.
01946             If this is an absolute symbol -- everything is OK.
01947             If this is a global label, we've got a symbol value defined
01948             twice:
01949                1. S_GET_VALUE (fixp->fx_addsy) will contain a symbol offset
01950                  from this section start
01951                2. *valuep will contain the real offset from jump insn to the
01952                  label
01953             So, the result of S_GET_VALUE (fixp->fx_addsy) + (* valuep);
01954             will be incorrect. Therefore remove s_get_value.  */
01955          value = /* S_GET_VALUE (fixp->fx_addsy) + */ * valuep;
01956          fixp->fx_done = 1;
01957        }
01958       else
01959        value = *valuep;
01960     }
01961   else
01962     {
01963       value = fixp->fx_offset;
01964 
01965       if (fixp->fx_subsy != (symbolS *) NULL)
01966        {
01967          if (S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
01968            {
01969              value -= S_GET_VALUE (fixp->fx_subsy);
01970              fixp->fx_done = 1;
01971            }
01972          else
01973            {
01974              /* We don't actually support subtracting a symbol.  */
01975              as_bad_where (fixp->fx_file, fixp->fx_line,
01976                          _("expression too complex"));
01977            }
01978        }
01979     }
01980 
01981   fixp->fx_no_overflow = 1;
01982 
01983   /* if polymorphs are enabled and relax disabled. 
01984      do not kill any relocs and pass them to linker. */
01985   if (msp430_enable_polys 
01986       && !msp430_enable_relax)
01987     {
01988       if (!fixp->fx_addsy || (fixp->fx_addsy 
01989          && S_GET_SEGMENT (fixp->fx_addsy) == absolute_section))
01990        fixp->fx_done = 1;   /* it is ok to kill 'abs' reloc */
01991       else
01992        fixp->fx_done = 0;
01993     }
01994 
01995   if (fixp->fx_done)
01996     {
01997       /* Fetch the instruction, insert the fully resolved operand
01998         value, and stuff the instruction back again.  */
01999 
02000       where = (unsigned char *) fixp->fx_frag->fr_literal + fixp->fx_where;
02001 
02002       insn = bfd_getl16 (where);
02003 
02004       switch (fixp->fx_r_type)
02005        {
02006        case BFD_RELOC_MSP430_10_PCREL:
02007          if (value & 1)
02008            as_bad_where (fixp->fx_file, fixp->fx_line,
02009                        _("odd address operand: %ld"), value);
02010 
02011          /* Jumps are in words.  */
02012          value >>= 1;
02013          --value;           /* Correct PC.  */
02014 
02015          if (value < -512 || value > 511)
02016            as_bad_where (fixp->fx_file, fixp->fx_line,
02017                        _("operand out of range: %ld"), value);
02018 
02019          value &= 0x3ff;    /* get rid of extended sign */
02020          bfd_putl16 ((bfd_vma) (value | insn), where);
02021          break;
02022 
02023        case BFD_RELOC_MSP430_RL_PCREL:
02024        case BFD_RELOC_MSP430_16_PCREL:
02025          if (value & 1)
02026            as_bad_where (fixp->fx_file, fixp->fx_line,
02027                        _("odd address operand: %ld"), value);
02028 
02029          /* Nothing to be corrected here.  */
02030          if (value < -32768 || value > 65536)
02031            as_bad_where (fixp->fx_file, fixp->fx_line,
02032                        _("operand out of range: %ld"), value);
02033 
02034          value &= 0xffff;   /* Get rid of extended sign.  */
02035          bfd_putl16 ((bfd_vma) value, where);
02036          break;
02037 
02038        case BFD_RELOC_MSP430_16_PCREL_BYTE:
02039          /* Nothing to be corrected here.  */
02040          if (value < -32768 || value > 65536)
02041            as_bad_where (fixp->fx_file, fixp->fx_line,
02042                        _("operand out of range: %ld"), value);
02043 
02044          value &= 0xffff;   /* Get rid of extended sign.  */
02045          bfd_putl16 ((bfd_vma) value, where);
02046          break;
02047 
02048        case BFD_RELOC_32:
02049          bfd_putl16 ((bfd_vma) value, where);
02050          break;
02051 
02052        case BFD_RELOC_MSP430_16:
02053        case BFD_RELOC_16:
02054        case BFD_RELOC_MSP430_16_BYTE:
02055          value &= 0xffff;
02056          bfd_putl16 ((bfd_vma) value, where);
02057          break;
02058 
02059        default:
02060          as_fatal (_("line %d: unknown relocation type: 0x%x"),
02061                   fixp->fx_line, fixp->fx_r_type);
02062          break;
02063        }
02064     }
02065   else
02066     {
02067       fixp->fx_addnumber = value;
02068     }
02069 }
02070 
02071 /* GAS will call this to generate a reloc, passing the resulting reloc
02072    to `bfd_install_relocation'.  This currently works poorly, as
02073    `bfd_install_relocation' often does the wrong thing, and instances of
02074    `tc_gen_reloc' have been written to work around the problems, which
02075    in turns makes it difficult to fix `bfd_install_relocation'.  */
02076 
02077 /* If while processing a fixup, a reloc really needs to be created
02078    then it is done here.  */
02079 
02080 arelent *
02081 tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
02082 {
02083   arelent * reloc;
02084 
02085   reloc = xmalloc (sizeof (arelent));
02086 
02087   reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
02088   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
02089 
02090   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
02091   reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
02092   if (reloc->howto == (reloc_howto_type *) NULL)
02093     {
02094       as_bad_where (fixp->fx_file, fixp->fx_line,
02095                   _("reloc %d not supported by object file format"),
02096                   (int) fixp->fx_r_type);
02097       return NULL;
02098     }
02099 
02100   if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
02101       || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
02102     reloc->address = fixp->fx_offset;
02103 
02104   reloc->addend = fixp->fx_offset;
02105 
02106   return reloc;
02107 }
02108 
02109 int
02110 md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
02111                             asection * segment_type ATTRIBUTE_UNUSED)
02112 {
02113   if (fragP->fr_symbol && S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
02114     {
02115       /* This is a jump -> pcrel mode. Nothing to do much here.
02116          Return value == 2.  */
02117       fragP->fr_subtype =
02118          ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_BITS10);
02119     }
02120   else if (fragP->fr_symbol)
02121     {
02122       /* Its got a segment, but its not ours.   Even if fr_symbol is in
02123         an absolute segment, we dont know a displacement until we link
02124         object files. So it will always be long. This also applies to
02125         labels in a subsegment of current. Liker may relax it to short
02126         jump later. Return value == 8.  */
02127       fragP->fr_subtype =
02128          ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_WORD);
02129     }
02130   else
02131     {
02132       /* We know the abs value. may be it is a jump to fixed address.
02133          Impossible in our case, cause all constants already handeled. */
02134       fragP->fr_subtype =
02135          ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_UNDEF);
02136     }
02137 
02138   return md_relax_table[fragP->fr_subtype].rlx_length;
02139 }
02140 
02141 void
02142 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
02143                asection * sec ATTRIBUTE_UNUSED,
02144                fragS * fragP)
02145 {
02146   char * where = 0;
02147   int rela = -1;
02148   int i;
02149   struct rcodes_s * cc = NULL;
02150   struct hcodes_s * hc = NULL;
02151 
02152   switch (fragP->fr_subtype)
02153     {
02154     case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_BITS10):
02155     case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_BITS10):
02156     case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_BITS10):
02157       /* We do not have to convert anything here.
02158          Just apply a fix.  */
02159       rela = BFD_RELOC_MSP430_10_PCREL;
02160       break;
02161 
02162     case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_WORD):
02163     case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_UNDEF):
02164       /* Convert uncond branch jmp lab -> br lab.  */
02165       cc = & msp430_rcodes[7];
02166       where = fragP->fr_literal + fragP->fr_fix;
02167       bfd_putl16 (cc->lop0, where);
02168       rela = BFD_RELOC_MSP430_RL_PCREL;
02169       fragP->fr_fix += 2;
02170       break;
02171 
02172     case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_WORD):
02173     case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_UNDEF):
02174       {
02175        /* Other simple branches.  */
02176        int insn = bfd_getl16 (fragP->fr_opcode);
02177 
02178        insn &= 0xffff;
02179        /* Find actual instruction.  */
02180        for (i = 0; i < 7 && !cc; i++)
02181          if (msp430_rcodes[i].sop == insn)
02182            cc = & msp430_rcodes[i];
02183        if (!cc || !cc->name)
02184          as_fatal (_("internal inconsistency problem in %s: insn %04lx"),
02185                   __FUNCTION__, (long) insn);
02186        where = fragP->fr_literal + fragP->fr_fix;
02187        bfd_putl16 (cc->lop0, where);
02188        bfd_putl16 (cc->lop1, where + 2);
02189        rela = BFD_RELOC_MSP430_RL_PCREL;
02190        fragP->fr_fix += 4;
02191       }
02192       break;
02193 
02194     case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_WORD):
02195     case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_UNDEF):
02196       cc = & msp430_rcodes[6];
02197       where = fragP->fr_literal + fragP->fr_fix;
02198       bfd_putl16 (cc->lop0, where);
02199       bfd_putl16 (cc->lop1, where + 2);
02200       bfd_putl16 (cc->lop2, where + 4);
02201       rela = BFD_RELOC_MSP430_RL_PCREL;
02202       fragP->fr_fix += 6;
02203       break;
02204 
02205     case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_BITS10):
02206       {
02207        int insn = bfd_getl16 (fragP->fr_opcode + 2);
02208 
02209        insn &= 0xffff;
02210        for (i = 0; i < 4 && !hc; i++)
02211          if (msp430_hcodes[i].op1 == insn)
02212            hc = &msp430_hcodes[i];
02213        if (!hc || !hc->name)
02214          as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
02215              __FUNCTION__, (long) insn);
02216        rela = BFD_RELOC_MSP430_10_PCREL;
02217        /* Apply a fix for a first label if necessary.
02218           another fix will be applied to the next word of insn anyway.  */
02219        if (hc->tlab == 2)
02220          fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
02221              fragP->fr_offset, TRUE, rela);
02222        fragP->fr_fix += 2;
02223       }
02224 
02225       break;
02226 
02227     case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_WORD):
02228     case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_UNDEF):
02229       {
02230        int insn = bfd_getl16 (fragP->fr_opcode + 2);
02231 
02232        insn &= 0xffff;
02233        for (i = 0; i < 4 && !hc; i++)
02234          if (msp430_hcodes[i].op1 == insn)
02235            hc = & msp430_hcodes[i];
02236        if (!hc || !hc->name)
02237          as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
02238              __FUNCTION__, (long) insn);
02239        rela = BFD_RELOC_MSP430_RL_PCREL;
02240        where = fragP->fr_literal + fragP->fr_fix;
02241        bfd_putl16 (hc->lop0, where);
02242        bfd_putl16 (hc->lop1, where + 2);
02243        bfd_putl16 (hc->lop2, where + 4);
02244        fragP->fr_fix += 6;
02245       }
02246       break;
02247 
02248     default:
02249       as_fatal (_("internal inconsistency problem in %s:  %lx"),
02250               __FUNCTION__, (long) fragP->fr_subtype);
02251       break;
02252     }
02253 
02254   /* Now apply fix.  */
02255   fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
02256           fragP->fr_offset, TRUE, rela);
02257   /* Just fixed 2 bytes.  */
02258   fragP->fr_fix += 2;
02259 }
02260 
02261 /* Relax fragment. Mostly stolen from hc11 and mcore
02262    which arches I think I know.  */
02263 
02264 long
02265 msp430_relax_frag (segT seg ATTRIBUTE_UNUSED, fragS * fragP,
02266                  long stretch ATTRIBUTE_UNUSED)
02267 {
02268   long growth;
02269   offsetT aim = 0;
02270   symbolS *symbolP;
02271   const relax_typeS *this_type;
02272   const relax_typeS *start_type;
02273   relax_substateT next_state;
02274   relax_substateT this_state;
02275   const relax_typeS *table = md_relax_table;
02276 
02277   /* Nothing to be done if the frag has already max size.  */
02278   if (RELAX_STATE (fragP->fr_subtype) == STATE_UNDEF
02279       || RELAX_STATE (fragP->fr_subtype) == STATE_WORD)
02280     return 0;
02281 
02282   if (RELAX_STATE (fragP->fr_subtype) == STATE_BITS10)
02283     {
02284       symbolP = fragP->fr_symbol;
02285       if (symbol_resolved_p (symbolP))
02286        as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
02287                 __FUNCTION__);
02288       /* We know the offset. calculate a distance.  */
02289       aim = S_GET_VALUE (symbolP) - fragP->fr_address - fragP->fr_fix;
02290     }
02291 
02292   if (!msp430_enable_relax)
02293     {
02294       /* Relaxation is not enabled. So, make all jump as long ones
02295          by setting 'aim' to quite high value. */
02296       aim = 0x7fff;
02297     }
02298   
02299   this_state = fragP->fr_subtype;
02300   start_type = this_type = table + this_state;
02301 
02302   if (aim < 0)
02303     {
02304       /* Look backwards.  */
02305       for (next_state = this_type->rlx_more; next_state;)
02306        if (aim >= this_type->rlx_backward || !this_type->rlx_backward)
02307          next_state = 0;
02308        else
02309          {
02310            /* Grow to next state.  */
02311            this_state = next_state;
02312            this_type = table + this_state;
02313            next_state = this_type->rlx_more;
02314          }
02315     }
02316   else
02317     {
02318       /* Look forwards.  */
02319       for (next_state = this_type->rlx_more; next_state;)
02320        if (aim <= this_type->rlx_forward || !this_type->rlx_forward)
02321          next_state = 0;
02322        else
02323          {
02324            /* Grow to next state.  */
02325            this_state = next_state;
02326            this_type = table + this_state;
02327            next_state = this_type->rlx_more;
02328          }
02329     }
02330 
02331   growth = this_type->rlx_length - start_type->rlx_length;
02332   if (growth != 0)
02333     fragP->fr_subtype = this_state;
02334   return growth;
02335 }