Home | History | Annotate | Line # | Download | only in config
tc-msp430.c revision 1.1.1.6
      1      1.1     skrll /* tc-msp430.c -- Assembler code for the Texas Instruments MSP430
      2      1.1     skrll 
      3  1.1.1.6  christos   Copyright (C) 2002-2018 Free Software Foundation, Inc.
      4      1.1     skrll   Contributed by Dmitry Diky <diwil (at) mail.ru>
      5      1.1     skrll 
      6      1.1     skrll   This file is part of GAS, the GNU Assembler.
      7      1.1     skrll 
      8      1.1     skrll   GAS is free software; you can redistribute it and/or modify
      9      1.1     skrll   it under the terms of the GNU General Public License as published by
     10      1.1     skrll   the Free Software Foundation; either version 3, or (at your option)
     11      1.1     skrll   any later version.
     12      1.1     skrll 
     13      1.1     skrll   GAS is distributed in the hope that it will be useful,
     14      1.1     skrll   but WITHOUT ANY WARRANTY; without even the implied warranty of
     15      1.1     skrll   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16      1.1     skrll   GNU General Public License for more details.
     17      1.1     skrll 
     18      1.1     skrll   You should have received a copy of the GNU General Public License
     19      1.1     skrll   along with GAS; see the file COPYING.  If not, write to
     20      1.1     skrll   the Free Software Foundation, 51 Franklin Street - Fifth Floor,
     21      1.1     skrll   Boston, MA 02110-1301, USA.  */
     22      1.1     skrll 
     23  1.1.1.3  christos #include "as.h"
     24      1.1     skrll #include <limits.h>
     25      1.1     skrll #include "subsegs.h"
     26      1.1     skrll #include "opcode/msp430.h"
     27      1.1     skrll #include "safe-ctype.h"
     28      1.1     skrll #include "dwarf2dbg.h"
     29  1.1.1.4  christos #include "elf/msp430.h"
     30  1.1.1.4  christos #include "libiberty.h"
     31      1.1     skrll 
     32      1.1     skrll /* We will disable polymorphs by default because it is dangerous.
     33      1.1     skrll    The potential problem here is the following: assume we got the
     34      1.1     skrll    following code:
     35      1.1     skrll 
     36      1.1     skrll 	jump .l1
     37      1.1     skrll 	nop
     38      1.1     skrll 	jump  subroutine	; external symbol
     39      1.1     skrll       .l1:
     40      1.1     skrll 	nop
     41      1.1     skrll 	ret
     42  1.1.1.4  christos 
     43      1.1     skrll    In case of assembly time relaxation we'll get:
     44      1.1     skrll 	0: jmp .l1 <.text +0x08> (reloc deleted)
     45      1.1     skrll 	2: nop
     46      1.1     skrll 	4: br subroutine
     47      1.1     skrll     .l1:
     48      1.1     skrll 	8: nop
     49      1.1     skrll 	10: ret
     50      1.1     skrll 
     51      1.1     skrll    If the 'subroutine' is within +-1024 bytes range then linker
     52      1.1     skrll    will produce:
     53      1.1     skrll 	0: jmp .text +0x08
     54      1.1     skrll 	2: nop
     55      1.1     skrll 	4: jmp subroutine
     56      1.1     skrll 	.l1:
     57      1.1     skrll 	6: nop
     58      1.1     skrll 	8: ret	; 'jmp .text +0x08' will land here. WRONG!!!
     59      1.1     skrll 
     60      1.1     skrll    The workaround is the following:
     61      1.1     skrll    1. Declare global var enable_polymorphs which set to 1 via option -mp.
     62      1.1     skrll    2. Declare global var enable_relax	which set to 1 via option -mQ.
     63      1.1     skrll 
     64      1.1     skrll    If polymorphs are enabled, and relax isn't, treat all jumps as long jumps,
     65      1.1     skrll    do not delete any relocs and leave them for linker.
     66  1.1.1.4  christos 
     67      1.1     skrll    If relax is enabled, relax at assembly time and kill relocs as necessary.  */
     68      1.1     skrll 
     69      1.1     skrll int msp430_enable_relax;
     70      1.1     skrll int msp430_enable_polys;
     71      1.1     skrll 
     72      1.1     skrll /* GCC uses the some condition codes which we'll
     73      1.1     skrll    implement as new polymorph instructions.
     74  1.1.1.4  christos 
     75      1.1     skrll    COND	EXPL	   SHORT JUMP	LONG JUMP
     76      1.1     skrll    ===============================================
     77      1.1     skrll    eq	==	   jeq 		jne +4; br lab
     78      1.1     skrll    ne	!=	   jne 		jeq +4; br lab
     79      1.1     skrll 
     80      1.1     skrll    ltn honours no-overflow flag
     81      1.1     skrll    ltn	<	   jn 		jn +2;  jmp +4; br lab
     82      1.1     skrll 
     83  1.1.1.4  christos    lt	<	   jl 		jge +4;	br lab
     84      1.1     skrll    ltu	<	   jlo 		lhs +4; br lab
     85      1.1     skrll    le	<= see below
     86      1.1     skrll    leu	<= see below
     87      1.1     skrll 
     88      1.1     skrll    gt	>  see below
     89      1.1     skrll    gtu	>  see below
     90      1.1     skrll    ge	>=	   jge 		jl +4; br lab
     91      1.1     skrll    geu	>=	   jhs 		jlo +4; br lab
     92      1.1     skrll    ===============================================
     93      1.1     skrll 
     94      1.1     skrll    Therefore, new opcodes are (BranchEQ -> beq; and so on...)
     95      1.1     skrll    beq,bne,blt,bltn,bltu,bge,bgeu
     96  1.1.1.4  christos    'u' means unsigned compares
     97  1.1.1.4  christos 
     98      1.1     skrll    Also, we add 'jump' instruction:
     99      1.1     skrll    jump	UNCOND	-> jmp		br lab
    100      1.1     skrll 
    101      1.1     skrll    They will have fmt == 4, and insn_opnumb == number of instruction.  */
    102      1.1     skrll 
    103  1.1.1.4  christos struct rcodes_s
    104      1.1     skrll {
    105  1.1.1.5  christos   const char * name;
    106      1.1     skrll   int    index;	/* Corresponding insn_opnumb.  */
    107      1.1     skrll   int    sop;	/* Opcode if jump length is short.  */
    108      1.1     skrll   long   lpos;	/* Label position.  */
    109      1.1     skrll   long   lop0;	/* Opcode 1 _word_ (16 bits).  */
    110      1.1     skrll   long   lop1;	/* Opcode second word.  */
    111      1.1     skrll   long   lop2;	/* Opcode third word.  */
    112      1.1     skrll };
    113      1.1     skrll 
    114      1.1     skrll #define MSP430_RLC(n,i,sop,o1) \
    115      1.1     skrll   {#n, i, sop, 2, (o1 + 2), 0x4010, 0}
    116      1.1     skrll 
    117  1.1.1.4  christos static struct rcodes_s msp430_rcodes[] =
    118      1.1     skrll {
    119      1.1     skrll   MSP430_RLC (beq,  0, 0x2400, 0x2000),
    120      1.1     skrll   MSP430_RLC (bne,  1, 0x2000, 0x2400),
    121      1.1     skrll   MSP430_RLC (blt,  2, 0x3800, 0x3400),
    122      1.1     skrll   MSP430_RLC (bltu, 3, 0x2800, 0x2c00),
    123      1.1     skrll   MSP430_RLC (bge,  4, 0x3400, 0x3800),
    124      1.1     skrll   MSP430_RLC (bgeu, 5, 0x2c00, 0x2800),
    125      1.1     skrll   {"bltn",          6, 0x3000, 3, 0x3000 + 1, 0x3c00 + 2,0x4010},
    126      1.1     skrll   {"jump",          7, 0x3c00, 1, 0x4010, 0, 0},
    127      1.1     skrll   {0,0,0,0,0,0,0}
    128      1.1     skrll };
    129      1.1     skrll 
    130  1.1.1.4  christos #undef  MSP430_RLC
    131  1.1.1.4  christos #define MSP430_RLC(n,i,sop,o1) \
    132  1.1.1.4  christos   {#n, i, sop, 2, (o1 + 2), 0x0030, 0}
    133  1.1.1.4  christos 
    134  1.1.1.4  christos static struct rcodes_s msp430x_rcodes[] =
    135  1.1.1.4  christos {
    136  1.1.1.4  christos   MSP430_RLC (beq,  0, 0x2400,    0x2000),
    137  1.1.1.4  christos   MSP430_RLC (bne,  1, 0x2000,    0x2400),
    138  1.1.1.4  christos   MSP430_RLC (blt,  2, 0x3800,    0x3400),
    139  1.1.1.4  christos   MSP430_RLC (bltu, 3, 0x2800,    0x2c00),
    140  1.1.1.4  christos   MSP430_RLC (bge,  4, 0x3400,    0x3800),
    141  1.1.1.4  christos   MSP430_RLC (bgeu, 5, 0x2c00,    0x2800),
    142  1.1.1.4  christos   {"bltn",          6, 0x3000, 3, 0x0030 + 1, 0x3c00 + 2, 0x3000},
    143  1.1.1.4  christos   {"jump",          7, 0x3c00, 1, 0x0030,     0,          0},
    144  1.1.1.4  christos   {0,0,0,0,0,0,0}
    145  1.1.1.4  christos };
    146  1.1.1.4  christos #undef MSP430_RLC
    147      1.1     skrll 
    148      1.1     skrll /* More difficult than above and they have format 5.
    149  1.1.1.4  christos 
    150      1.1     skrll    COND	EXPL	SHORT			LONG
    151      1.1     skrll    =================================================================
    152      1.1     skrll    gt	>	jeq +2; jge label	jeq +6; jl  +4; br label
    153      1.1     skrll    gtu	>	jeq +2; jhs label	jeq +6; jlo +4; br label
    154      1.1     skrll    leu	<=	jeq label; jlo label	jeq +2; jhs +4; br label
    155      1.1     skrll    le	<=	jeq label; jl  label	jeq +2; jge +4; br label
    156      1.1     skrll    =================================================================  */
    157      1.1     skrll 
    158  1.1.1.4  christos struct hcodes_s
    159      1.1     skrll {
    160  1.1.1.5  christos   const char * name;
    161      1.1     skrll   int    index;		/* Corresponding insn_opnumb.  */
    162      1.1     skrll   int    tlab;		/* Number of labels in short mode.  */
    163      1.1     skrll   int    op0;		/* Opcode for first word of short jump.  */
    164      1.1     skrll   int    op1;		/* Opcode for second word of short jump.  */
    165      1.1     skrll   int    lop0;		/* Opcodes for long jump mode.  */
    166      1.1     skrll   int    lop1;
    167      1.1     skrll   int    lop2;
    168      1.1     skrll };
    169      1.1     skrll 
    170  1.1.1.4  christos static struct hcodes_s msp430_hcodes[] =
    171      1.1     skrll {
    172      1.1     skrll   {"bgt",  0, 1, 0x2401, 0x3400, 0x2403, 0x3802, 0x4010 },
    173      1.1     skrll   {"bgtu", 1, 1, 0x2401, 0x2c00, 0x2403, 0x2802, 0x4010 },
    174      1.1     skrll   {"bleu", 2, 2, 0x2400, 0x2800, 0x2401, 0x2c02, 0x4010 },
    175      1.1     skrll   {"ble",  3, 2, 0x2400, 0x3800, 0x2401, 0x3402, 0x4010 },
    176      1.1     skrll   {0,0,0,0,0,0,0,0}
    177      1.1     skrll };
    178      1.1     skrll 
    179  1.1.1.4  christos static struct hcodes_s msp430x_hcodes[] =
    180  1.1.1.4  christos {
    181  1.1.1.4  christos   {"bgt",  0, 1, 0x2401, 0x3400, 0x2403, 0x3802, 0x0030 },
    182  1.1.1.4  christos   {"bgtu", 1, 1, 0x2401, 0x2c00, 0x2403, 0x2802, 0x0030 },
    183  1.1.1.4  christos   {"bleu", 2, 2, 0x2400, 0x2800, 0x2401, 0x2c02, 0x0030 },
    184  1.1.1.4  christos   {"ble",  3, 2, 0x2400, 0x3800, 0x2401, 0x3402, 0x0030 },
    185  1.1.1.4  christos   {0,0,0,0,0,0,0,0}
    186  1.1.1.4  christos };
    187  1.1.1.4  christos 
    188      1.1     skrll const char comment_chars[] = ";";
    189      1.1     skrll const char line_comment_chars[] = "#";
    190      1.1     skrll const char line_separator_chars[] = "{";
    191      1.1     skrll const char EXP_CHARS[] = "eE";
    192      1.1     skrll const char FLT_CHARS[] = "dD";
    193      1.1     skrll 
    194      1.1     skrll /* Handle  long expressions.  */
    195      1.1     skrll extern LITTLENUM_TYPE generic_bignum[];
    196      1.1     skrll 
    197      1.1     skrll static struct hash_control *msp430_hash;
    198      1.1     skrll 
    199      1.1     skrll /* Relaxations.  */
    200      1.1     skrll #define STATE_UNCOND_BRANCH	1	/* jump */
    201      1.1     skrll #define STATE_NOOV_BRANCH	3	/* bltn */
    202      1.1     skrll #define STATE_SIMPLE_BRANCH	2	/* bne, beq, etc... */
    203      1.1     skrll #define STATE_EMUL_BRANCH	4
    204      1.1     skrll 
    205      1.1     skrll #define CNRL	2
    206      1.1     skrll #define CUBL	4
    207      1.1     skrll #define CNOL	8
    208      1.1     skrll #define CSBL	6
    209      1.1     skrll #define CEBL	4
    210      1.1     skrll 
    211      1.1     skrll /* Length.  */
    212      1.1     skrll #define STATE_BITS10	1	/* wild guess. short jump */
    213      1.1     skrll #define STATE_WORD	2	/* 2 bytes pc rel. addr. more */
    214      1.1     skrll #define STATE_UNDEF	3	/* cannot handle this yet. convert to word mode */
    215      1.1     skrll 
    216      1.1     skrll #define ENCODE_RELAX(what,length) (((what) << 2) + (length))
    217      1.1     skrll #define RELAX_STATE(s)            ((s) & 3)
    218      1.1     skrll #define RELAX_LEN(s)	          ((s) >> 2)
    219      1.1     skrll #define RELAX_NEXT(a,b)	          ENCODE_RELAX (a, b + 1)
    220      1.1     skrll 
    221      1.1     skrll relax_typeS md_relax_table[] =
    222      1.1     skrll {
    223      1.1     skrll   /* Unused.  */
    224      1.1     skrll   {1, 1, 0, 0},
    225      1.1     skrll   {1, 1, 0, 0},
    226      1.1     skrll   {1, 1, 0, 0},
    227      1.1     skrll   {1, 1, 0, 0},
    228      1.1     skrll 
    229      1.1     skrll   /* Unconditional jump.  */
    230      1.1     skrll   {1, 1, 8, 5},
    231      1.1     skrll   {1024, -1024, CNRL, RELAX_NEXT (STATE_UNCOND_BRANCH, STATE_BITS10)},	/* state 10 bits displ */
    232      1.1     skrll   {0, 0, CUBL, RELAX_NEXT (STATE_UNCOND_BRANCH, STATE_WORD)},		/* state word */
    233      1.1     skrll   {1, 1, CUBL, 0},							/* state undef */
    234      1.1     skrll 
    235      1.1     skrll   /* Simple branches.  */
    236      1.1     skrll   {0, 0, 8, 9},
    237      1.1     skrll   {1024, -1024, CNRL, RELAX_NEXT (STATE_SIMPLE_BRANCH, STATE_BITS10)},	/* state 10 bits displ */
    238      1.1     skrll   {0, 0, CSBL, RELAX_NEXT (STATE_SIMPLE_BRANCH, STATE_WORD)},		/* state word */
    239      1.1     skrll   {1, 1, CSBL, 0},
    240      1.1     skrll 
    241      1.1     skrll   /* blt no overflow branch.  */
    242      1.1     skrll   {1, 1, 8, 13},
    243      1.1     skrll   {1024, -1024, CNRL, RELAX_NEXT (STATE_NOOV_BRANCH, STATE_BITS10)},	/* state 10 bits displ */
    244      1.1     skrll   {0, 0, CNOL, RELAX_NEXT (STATE_NOOV_BRANCH, STATE_WORD)},		/* state word */
    245      1.1     skrll   {1, 1, CNOL, 0},
    246      1.1     skrll 
    247      1.1     skrll   /* Emulated branches.  */
    248      1.1     skrll   {1, 1, 8, 17},
    249      1.1     skrll   {1020, -1020, CEBL, RELAX_NEXT (STATE_EMUL_BRANCH, STATE_BITS10)},	/* state 10 bits displ */
    250      1.1     skrll   {0, 0, CNOL, RELAX_NEXT (STATE_EMUL_BRANCH, STATE_WORD)},		/* state word */
    251      1.1     skrll   {1, 1, CNOL, 0}
    252      1.1     skrll };
    253      1.1     skrll 
    254      1.1     skrll 
    255  1.1.1.4  christos #define MAX_OP_LEN	4096
    256      1.1     skrll 
    257  1.1.1.4  christos typedef enum msp_isa
    258      1.1     skrll {
    259  1.1.1.4  christos   MSP_ISA_430,
    260  1.1.1.4  christos   MSP_ISA_430X,
    261  1.1.1.4  christos   MSP_ISA_430Xv2
    262  1.1.1.4  christos } msp_isa;
    263      1.1     skrll 
    264  1.1.1.4  christos static enum msp_isa selected_isa = MSP_ISA_430Xv2;
    265      1.1     skrll 
    266  1.1.1.4  christos static inline bfd_boolean
    267  1.1.1.4  christos target_is_430x (void)
    268  1.1.1.4  christos {
    269  1.1.1.4  christos   return selected_isa >= MSP_ISA_430X;
    270  1.1.1.4  christos }
    271      1.1     skrll 
    272  1.1.1.4  christos static inline bfd_boolean
    273  1.1.1.4  christos target_is_430xv2 (void)
    274  1.1.1.4  christos {
    275  1.1.1.4  christos   return selected_isa == MSP_ISA_430Xv2;
    276  1.1.1.4  christos }
    277      1.1     skrll 
    278  1.1.1.4  christos /* Generate an absolute 16-bit relocation.
    279  1.1.1.4  christos    For the 430X we generate a relocation without linker range checking
    280  1.1.1.4  christos     if the value is being used in an extended (ie 20-bit) instruction,
    281  1.1.1.4  christos     otherwise if have a shifted expression we use a HI reloc.
    282  1.1.1.4  christos    For the 430 we generate a relocation without assembler range checking
    283  1.1.1.4  christos     if we are handling an immediate value or a byte-width instruction.  */
    284  1.1.1.4  christos 
    285  1.1.1.4  christos #undef  CHECK_RELOC_MSP430
    286  1.1.1.4  christos #define CHECK_RELOC_MSP430(OP)				\
    287  1.1.1.4  christos   (target_is_430x ()					\
    288  1.1.1.4  christos   ? (extended_op					\
    289  1.1.1.4  christos      ? BFD_RELOC_16					\
    290  1.1.1.4  christos      : ((OP).vshift == 1)				\
    291  1.1.1.4  christos      ? BFD_RELOC_MSP430_ABS_HI16			\
    292  1.1.1.4  christos      : BFD_RELOC_MSP430X_ABS16)				\
    293  1.1.1.4  christos    : ((imm_op || byte_op)				\
    294  1.1.1.4  christos       ? BFD_RELOC_MSP430_16_BYTE : BFD_RELOC_MSP430_16))
    295  1.1.1.4  christos 
    296  1.1.1.4  christos /* Generate a 16-bit pc-relative relocation.
    297  1.1.1.6  christos    For the 430X we generate a relocation without linker range checking.
    298  1.1.1.4  christos    For the 430 we generate a relocation without assembler range checking
    299  1.1.1.4  christos    if we are handling an immediate value or a byte-width instruction.  */
    300  1.1.1.4  christos #undef  CHECK_RELOC_MSP430_PCREL
    301  1.1.1.4  christos #define CHECK_RELOC_MSP430_PCREL			     \
    302  1.1.1.4  christos   (target_is_430x ()					     \
    303  1.1.1.4  christos    ? BFD_RELOC_MSP430X_PCR16				     \
    304  1.1.1.4  christos    : (imm_op || byte_op)				     \
    305  1.1.1.4  christos    ? BFD_RELOC_MSP430_16_PCREL_BYTE : BFD_RELOC_MSP430_16_PCREL)
    306      1.1     skrll 
    307      1.1     skrll /* Profiling capability:
    308      1.1     skrll    It is a performance hit to use gcc's profiling approach for this tiny target.
    309      1.1     skrll    Even more -- jtag hardware facility does not perform any profiling functions.
    310      1.1     skrll    However we've got gdb's built-in simulator where we can do anything.
    311      1.1     skrll    Therefore my suggestion is:
    312      1.1     skrll 
    313      1.1     skrll    We define new section ".profiler" which holds all profiling information.
    314      1.1     skrll    We define new pseudo operation .profiler which will instruct assembler to
    315      1.1     skrll    add new profile entry to the object file. Profile should take place at the
    316      1.1     skrll    present address.
    317      1.1     skrll 
    318      1.1     skrll    Pseudo-op format:
    319      1.1     skrll 
    320      1.1     skrll       .profiler flags,function_to_profile [, cycle_corrector, extra]
    321      1.1     skrll 
    322      1.1     skrll    where 'flags' is a combination of the following chars:
    323      1.1     skrll 	    s - function Start
    324      1.1     skrll 	    x - function eXit
    325      1.1     skrll 	    i - function is in Init section
    326      1.1     skrll 	    f - function is in Fini section
    327      1.1     skrll 	    l - Library call
    328      1.1     skrll 	    c - libC standard call
    329      1.1     skrll 	    d - stack value Demand (saved at run-time in simulator)
    330      1.1     skrll 	    I - Interrupt service routine
    331      1.1     skrll 	    P - Prologue start
    332      1.1     skrll 	    p - Prologue end
    333      1.1     skrll 	    E - Epilogue start
    334      1.1     skrll 	    e - Epilogue end
    335      1.1     skrll 	    j - long Jump/ sjlj unwind
    336      1.1     skrll 	    a - an Arbitrary code fragment
    337      1.1     skrll 	    t - exTra parameter saved (constant value like frame size)
    338      1.1     skrll 	  '""' optional: "sil" == sil
    339      1.1     skrll 
    340      1.1     skrll       function_to_profile - function's address
    341      1.1     skrll       cycle_corrector     - a value which should be added to the cycle
    342      1.1     skrll 			      counter, zero if omitted
    343      1.1     skrll       extra - some extra parameter, zero if omitted.
    344      1.1     skrll 
    345      1.1     skrll       For example:
    346      1.1     skrll       ------------------------------
    347      1.1     skrll 	.global fxx
    348      1.1     skrll 	.type fxx,@function
    349      1.1     skrll       fxx:
    350      1.1     skrll       .LFrameOffset_fxx=0x08
    351      1.1     skrll       .profiler "scdP", fxx	; function entry.
    352      1.1     skrll 				; we also demand stack value to be displayed
    353      1.1     skrll 	push r11
    354      1.1     skrll 	push r10
    355      1.1     skrll 	push r9
    356      1.1     skrll 	push r8
    357      1.1     skrll       .profiler "cdp",fxx,0, .LFrameOffset_fxx	; check stack value at this point
    358      1.1     skrll 						; (this is a prologue end)
    359      1.1     skrll 						; note, that spare var filled with the frame size
    360      1.1     skrll 	mov r15,r8
    361      1.1     skrll 	....
    362      1.1     skrll       .profiler cdE,fxx		; check stack
    363      1.1     skrll 	pop r8
    364      1.1     skrll 	pop r9
    365      1.1     skrll 	pop r10
    366      1.1     skrll 	pop r11
    367      1.1     skrll       .profiler xcde,fxx,3	; exit adds 3 to the cycle counter
    368      1.1     skrll       ret			; cause 'ret' insn takes 3 cycles
    369      1.1     skrll       -------------------------------
    370      1.1     skrll 
    371      1.1     skrll       This profiling approach does not produce any overhead and
    372      1.1     skrll       absolutely harmless.
    373      1.1     skrll       So, even profiled code can be uploaded to the MCU.  */
    374      1.1     skrll #define MSP430_PROFILER_FLAG_ENTRY	1	/* s */
    375      1.1     skrll #define MSP430_PROFILER_FLAG_EXIT	2	/* x */
    376      1.1     skrll #define MSP430_PROFILER_FLAG_INITSECT	4	/* i */
    377      1.1     skrll #define MSP430_PROFILER_FLAG_FINISECT	8	/* f */
    378      1.1     skrll #define MSP430_PROFILER_FLAG_LIBCALL	0x10	/* l */
    379      1.1     skrll #define MSP430_PROFILER_FLAG_STDCALL	0x20	/* c */
    380      1.1     skrll #define MSP430_PROFILER_FLAG_STACKDMD	0x40	/* d */
    381      1.1     skrll #define MSP430_PROFILER_FLAG_ISR	0x80	/* I */
    382      1.1     skrll #define MSP430_PROFILER_FLAG_PROLSTART	0x100	/* P */
    383      1.1     skrll #define MSP430_PROFILER_FLAG_PROLEND	0x200	/* p */
    384      1.1     skrll #define MSP430_PROFILER_FLAG_EPISTART	0x400	/* E */
    385      1.1     skrll #define MSP430_PROFILER_FLAG_EPIEND	0x800	/* e */
    386      1.1     skrll #define MSP430_PROFILER_FLAG_JUMP	0x1000	/* j */
    387      1.1     skrll #define MSP430_PROFILER_FLAG_FRAGMENT	0x2000	/* a */
    388      1.1     skrll #define MSP430_PROFILER_FLAG_EXTRA	0x4000	/* t */
    389      1.1     skrll #define MSP430_PROFILER_FLAG_notyet	0x8000	/* ? */
    390      1.1     skrll 
    391      1.1     skrll static int
    392      1.1     skrll pow2value (int y)
    393      1.1     skrll {
    394      1.1     skrll   int n = 0;
    395      1.1     skrll   unsigned int x;
    396      1.1     skrll 
    397      1.1     skrll   x = y;
    398      1.1     skrll 
    399      1.1     skrll   if (!x)
    400      1.1     skrll     return 1;
    401      1.1     skrll 
    402      1.1     skrll   for (; x; x = x >> 1)
    403      1.1     skrll     if (x & 1)
    404      1.1     skrll       n++;
    405      1.1     skrll 
    406      1.1     skrll   return n == 1;
    407      1.1     skrll }
    408      1.1     skrll 
    409      1.1     skrll /* Parse ordinary expression.  */
    410      1.1     skrll 
    411      1.1     skrll static char *
    412      1.1     skrll parse_exp (char * s, expressionS * op)
    413      1.1     skrll {
    414      1.1     skrll   input_line_pointer = s;
    415      1.1     skrll   expression (op);
    416      1.1     skrll   if (op->X_op == O_absent)
    417      1.1     skrll     as_bad (_("missing operand"));
    418  1.1.1.6  christos   /* Our caller is likely to check that the entire expression was parsed.
    419  1.1.1.6  christos      If we have found a hex constant with an 'h' suffix, ilp will be left
    420  1.1.1.6  christos      pointing at the 'h', so skip it here.  */
    421  1.1.1.6  christos   if (input_line_pointer != NULL
    422  1.1.1.6  christos       && op->X_op == O_constant
    423  1.1.1.6  christos       && (*input_line_pointer == 'h' || *input_line_pointer == 'H'))
    424  1.1.1.6  christos     ++ input_line_pointer;
    425      1.1     skrll   return input_line_pointer;
    426      1.1     skrll }
    427      1.1     skrll 
    428      1.1     skrll 
    429      1.1     skrll /* Delete spaces from s: X ( r 1  2)  => X(r12).  */
    430      1.1     skrll 
    431      1.1     skrll static void
    432      1.1     skrll del_spaces (char * s)
    433      1.1     skrll {
    434      1.1     skrll   while (*s)
    435      1.1     skrll     {
    436      1.1     skrll       if (ISSPACE (*s))
    437      1.1     skrll 	{
    438      1.1     skrll 	  char *m = s + 1;
    439      1.1     skrll 
    440      1.1     skrll 	  while (ISSPACE (*m) && *m)
    441      1.1     skrll 	    m++;
    442      1.1     skrll 	  memmove (s, m, strlen (m) + 1);
    443      1.1     skrll 	}
    444      1.1     skrll       else
    445      1.1     skrll 	s++;
    446      1.1     skrll     }
    447      1.1     skrll }
    448      1.1     skrll 
    449      1.1     skrll static inline char *
    450      1.1     skrll skip_space (char * s)
    451      1.1     skrll {
    452      1.1     skrll   while (ISSPACE (*s))
    453      1.1     skrll     ++s;
    454      1.1     skrll   return s;
    455      1.1     skrll }
    456      1.1     skrll 
    457      1.1     skrll /* Extract one word from FROM and copy it to TO. Delimiters are ",;\n"  */
    458      1.1     skrll 
    459      1.1     skrll static char *
    460      1.1     skrll extract_operand (char * from, char * to, int limit)
    461      1.1     skrll {
    462      1.1     skrll   int size = 0;
    463      1.1     skrll 
    464      1.1     skrll   /* Drop leading whitespace.  */
    465      1.1     skrll   from = skip_space (from);
    466      1.1     skrll 
    467      1.1     skrll   while (size < limit && *from)
    468      1.1     skrll     {
    469      1.1     skrll       *(to + size) = *from;
    470      1.1     skrll       if (*from == ',' || *from == ';' || *from == '\n')
    471      1.1     skrll 	break;
    472      1.1     skrll       from++;
    473      1.1     skrll       size++;
    474      1.1     skrll     }
    475      1.1     skrll 
    476      1.1     skrll   *(to + size) = 0;
    477      1.1     skrll   del_spaces (to);
    478      1.1     skrll 
    479      1.1     skrll   from++;
    480      1.1     skrll 
    481      1.1     skrll   return from;
    482      1.1     skrll }
    483      1.1     skrll 
    484      1.1     skrll static void
    485      1.1     skrll msp430_profiler (int dummy ATTRIBUTE_UNUSED)
    486      1.1     skrll {
    487      1.1     skrll   char   buffer[1024];
    488      1.1     skrll   char   f[32];
    489      1.1     skrll   char * str = buffer;
    490      1.1     skrll   char * flags = f;
    491      1.1     skrll   int    p_flags = 0;
    492      1.1     skrll   char * halt;
    493      1.1     skrll   int    ops = 0;
    494      1.1     skrll   int    left;
    495      1.1     skrll   char * s;
    496      1.1     skrll   segT   seg;
    497      1.1     skrll   int    subseg;
    498      1.1     skrll   char * end = 0;
    499      1.1     skrll   expressionS exp;
    500      1.1     skrll   expressionS exp1;
    501      1.1     skrll 
    502      1.1     skrll   s = input_line_pointer;
    503      1.1     skrll   end = input_line_pointer;
    504      1.1     skrll 
    505      1.1     skrll   while (*end && *end != '\n')
    506      1.1     skrll     end++;
    507      1.1     skrll 
    508      1.1     skrll   while (*s && *s != '\n')
    509      1.1     skrll     {
    510      1.1     skrll       if (*s == ',')
    511      1.1     skrll 	ops++;
    512      1.1     skrll       s++;
    513      1.1     skrll     }
    514      1.1     skrll 
    515      1.1     skrll   left = 3 - ops;
    516      1.1     skrll 
    517      1.1     skrll   if (ops < 1)
    518      1.1     skrll     {
    519      1.1     skrll       as_bad (_(".profiler pseudo requires at least two operands."));
    520      1.1     skrll       input_line_pointer = end;
    521      1.1     skrll       return;
    522      1.1     skrll     }
    523      1.1     skrll 
    524      1.1     skrll   input_line_pointer = extract_operand (input_line_pointer, flags, 32);
    525      1.1     skrll 
    526      1.1     skrll   while (*flags)
    527      1.1     skrll     {
    528      1.1     skrll       switch (*flags)
    529      1.1     skrll 	{
    530      1.1     skrll 	case '"':
    531      1.1     skrll 	  break;
    532      1.1     skrll 	case 'a':
    533      1.1     skrll 	  p_flags |= MSP430_PROFILER_FLAG_FRAGMENT;
    534      1.1     skrll 	  break;
    535      1.1     skrll 	case 'j':
    536      1.1     skrll 	  p_flags |= MSP430_PROFILER_FLAG_JUMP;
    537      1.1     skrll 	  break;
    538      1.1     skrll 	case 'P':
    539      1.1     skrll 	  p_flags |= MSP430_PROFILER_FLAG_PROLSTART;
    540      1.1     skrll 	  break;
    541      1.1     skrll 	case 'p':
    542      1.1     skrll 	  p_flags |= MSP430_PROFILER_FLAG_PROLEND;
    543      1.1     skrll 	  break;
    544      1.1     skrll 	case 'E':
    545      1.1     skrll 	  p_flags |= MSP430_PROFILER_FLAG_EPISTART;
    546      1.1     skrll 	  break;
    547      1.1     skrll 	case 'e':
    548      1.1     skrll 	  p_flags |= MSP430_PROFILER_FLAG_EPIEND;
    549      1.1     skrll 	  break;
    550      1.1     skrll 	case 's':
    551      1.1     skrll 	  p_flags |= MSP430_PROFILER_FLAG_ENTRY;
    552      1.1     skrll 	  break;
    553      1.1     skrll 	case 'x':
    554      1.1     skrll 	  p_flags |= MSP430_PROFILER_FLAG_EXIT;
    555      1.1     skrll 	  break;
    556      1.1     skrll 	case 'i':
    557      1.1     skrll 	  p_flags |= MSP430_PROFILER_FLAG_INITSECT;
    558      1.1     skrll 	  break;
    559      1.1     skrll 	case 'f':
    560      1.1     skrll 	  p_flags |= MSP430_PROFILER_FLAG_FINISECT;
    561      1.1     skrll 	  break;
    562      1.1     skrll 	case 'l':
    563      1.1     skrll 	  p_flags |= MSP430_PROFILER_FLAG_LIBCALL;
    564      1.1     skrll 	  break;
    565      1.1     skrll 	case 'c':
    566      1.1     skrll 	  p_flags |= MSP430_PROFILER_FLAG_STDCALL;
    567      1.1     skrll 	  break;
    568      1.1     skrll 	case 'd':
    569      1.1     skrll 	  p_flags |= MSP430_PROFILER_FLAG_STACKDMD;
    570      1.1     skrll 	  break;
    571      1.1     skrll 	case 'I':
    572      1.1     skrll 	  p_flags |= MSP430_PROFILER_FLAG_ISR;
    573      1.1     skrll 	  break;
    574      1.1     skrll 	case 't':
    575      1.1     skrll 	  p_flags |= MSP430_PROFILER_FLAG_EXTRA;
    576      1.1     skrll 	  break;
    577      1.1     skrll 	default:
    578      1.1     skrll 	  as_warn (_("unknown profiling flag - ignored."));
    579      1.1     skrll 	  break;
    580      1.1     skrll 	}
    581      1.1     skrll       flags++;
    582      1.1     skrll     }
    583      1.1     skrll 
    584      1.1     skrll   if (p_flags
    585      1.1     skrll       && (   ! pow2value (p_flags & (  MSP430_PROFILER_FLAG_ENTRY
    586      1.1     skrll 				     | MSP430_PROFILER_FLAG_EXIT))
    587      1.1     skrll 	  || ! pow2value (p_flags & (  MSP430_PROFILER_FLAG_PROLSTART
    588      1.1     skrll 				     | MSP430_PROFILER_FLAG_PROLEND
    589      1.1     skrll 				     | MSP430_PROFILER_FLAG_EPISTART
    590      1.1     skrll 				     | MSP430_PROFILER_FLAG_EPIEND))
    591      1.1     skrll 	  || ! pow2value (p_flags & (  MSP430_PROFILER_FLAG_INITSECT
    592      1.1     skrll 				     | MSP430_PROFILER_FLAG_FINISECT))))
    593      1.1     skrll     {
    594      1.1     skrll       as_bad (_("ambiguous flags combination - '.profiler' directive ignored."));
    595      1.1     skrll       input_line_pointer = end;
    596      1.1     skrll       return;
    597      1.1     skrll     }
    598      1.1     skrll 
    599      1.1     skrll   /* Generate temp symbol which denotes current location.  */
    600      1.1     skrll   if (now_seg == absolute_section)	/* Paranoia ?  */
    601      1.1     skrll     {
    602      1.1     skrll       exp1.X_op = O_constant;
    603      1.1     skrll       exp1.X_add_number = abs_section_offset;
    604      1.1     skrll       as_warn (_("profiling in absolute section?"));
    605      1.1     skrll     }
    606      1.1     skrll   else
    607      1.1     skrll     {
    608      1.1     skrll       exp1.X_op = O_symbol;
    609      1.1     skrll       exp1.X_add_symbol = symbol_temp_new_now ();
    610      1.1     skrll       exp1.X_add_number = 0;
    611      1.1     skrll     }
    612      1.1     skrll 
    613      1.1     skrll   /* Generate a symbol which holds flags value.  */
    614      1.1     skrll   exp.X_op = O_constant;
    615      1.1     skrll   exp.X_add_number = p_flags;
    616      1.1     skrll 
    617      1.1     skrll   /* Save current section.  */
    618      1.1     skrll   seg = now_seg;
    619      1.1     skrll   subseg = now_subseg;
    620      1.1     skrll 
    621      1.1     skrll   /* Now go to .profiler section.  */
    622  1.1.1.6  christos   obj_elf_change_section (".profiler", SHT_PROGBITS, 0, 0, 0, 0, 0, 0);
    623      1.1     skrll 
    624      1.1     skrll   /* Save flags.  */
    625      1.1     skrll   emit_expr (& exp, 2);
    626      1.1     skrll 
    627      1.1     skrll   /* Save label value.  */
    628      1.1     skrll   emit_expr (& exp1, 2);
    629      1.1     skrll 
    630      1.1     skrll   while (ops--)
    631      1.1     skrll     {
    632      1.1     skrll       /* Now get profiling info.  */
    633      1.1     skrll       halt = extract_operand (input_line_pointer, str, 1024);
    634      1.1     skrll       /* Process like ".word xxx" directive.  */
    635  1.1.1.6  christos       (void) parse_exp (str, & exp);
    636      1.1     skrll       emit_expr (& exp, 2);
    637      1.1     skrll       input_line_pointer = halt;
    638      1.1     skrll     }
    639      1.1     skrll 
    640      1.1     skrll   /* Fill the rest with zeros.  */
    641      1.1     skrll   exp.X_op = O_constant;
    642      1.1     skrll   exp.X_add_number = 0;
    643      1.1     skrll   while (left--)
    644      1.1     skrll     emit_expr (& exp, 2);
    645      1.1     skrll 
    646      1.1     skrll   /* Return to current section.  */
    647      1.1     skrll   subseg_set (seg, subseg);
    648      1.1     skrll }
    649      1.1     skrll 
    650      1.1     skrll static char *
    651      1.1     skrll extract_word (char * from, char * to, int limit)
    652      1.1     skrll {
    653      1.1     skrll   char *op_end;
    654      1.1     skrll   int size = 0;
    655      1.1     skrll 
    656      1.1     skrll   /* Drop leading whitespace.  */
    657      1.1     skrll   from = skip_space (from);
    658      1.1     skrll   *to = 0;
    659      1.1     skrll 
    660      1.1     skrll   /* Find the op code end.  */
    661  1.1.1.2  christos   for (op_end = from; *op_end != 0 && is_part_of_name (*op_end);)
    662      1.1     skrll     {
    663      1.1     skrll       to[size++] = *op_end++;
    664      1.1     skrll       if (size + 1 >= limit)
    665      1.1     skrll 	break;
    666      1.1     skrll     }
    667      1.1     skrll 
    668      1.1     skrll   to[size] = 0;
    669      1.1     skrll   return op_end;
    670      1.1     skrll }
    671      1.1     skrll 
    672      1.1     skrll #define OPTION_MMCU 'm'
    673      1.1     skrll #define OPTION_RELAX 'Q'
    674      1.1     skrll #define OPTION_POLYMORPHS 'P'
    675  1.1.1.4  christos #define OPTION_LARGE 'l'
    676  1.1.1.4  christos static bfd_boolean large_model = FALSE;
    677  1.1.1.4  christos #define OPTION_NO_INTR_NOPS 'N'
    678  1.1.1.4  christos #define OPTION_INTR_NOPS 'n'
    679  1.1.1.4  christos static bfd_boolean gen_interrupt_nops = FALSE;
    680  1.1.1.4  christos #define OPTION_WARN_INTR_NOPS 'y'
    681  1.1.1.4  christos #define OPTION_NO_WARN_INTR_NOPS 'Y'
    682  1.1.1.4  christos static bfd_boolean warn_interrupt_nops = TRUE;
    683  1.1.1.4  christos #define OPTION_MCPU 'c'
    684  1.1.1.4  christos #define OPTION_MOVE_DATA 'd'
    685  1.1.1.4  christos static bfd_boolean move_data = FALSE;
    686  1.1.1.6  christos #define OPTION_DATA_REGION 'r'
    687  1.1.1.6  christos static bfd_boolean upper_data_region_in_use = FALSE;
    688  1.1.1.4  christos 
    689  1.1.1.4  christos enum
    690  1.1.1.4  christos {
    691  1.1.1.4  christos   OPTION_SILICON_ERRATA = OPTION_MD_BASE,
    692  1.1.1.4  christos   OPTION_SILICON_ERRATA_WARN,
    693  1.1.1.5  christos };
    694  1.1.1.4  christos 
    695  1.1.1.4  christos static unsigned int silicon_errata_fix = 0;
    696  1.1.1.4  christos static unsigned int silicon_errata_warn = 0;
    697  1.1.1.4  christos #define SILICON_ERRATA_CPU4 		(1 << 0)
    698  1.1.1.4  christos #define SILICON_ERRATA_CPU8		(1 << 1)
    699  1.1.1.4  christos #define SILICON_ERRATA_CPU11 		(1 << 2)
    700  1.1.1.4  christos #define SILICON_ERRATA_CPU12 		(1 << 3)
    701  1.1.1.4  christos #define SILICON_ERRATA_CPU13 		(1 << 4)
    702  1.1.1.4  christos #define SILICON_ERRATA_CPU19 		(1 << 5)
    703      1.1     skrll 
    704      1.1     skrll static void
    705  1.1.1.4  christos msp430_set_arch (int option)
    706      1.1     skrll {
    707  1.1.1.5  christos   char str[32];	/* 32 for good measure.  */
    708      1.1     skrll 
    709      1.1     skrll   input_line_pointer = extract_word (input_line_pointer, str, 32);
    710      1.1     skrll 
    711  1.1.1.4  christos   md_parse_option (option, str);
    712  1.1.1.4  christos   bfd_set_arch_mach (stdoutput, TARGET_ARCH,
    713  1.1.1.4  christos 		     target_is_430x () ? bfd_mach_msp430x : bfd_mach_msp11);
    714      1.1     skrll }
    715      1.1     skrll 
    716  1.1.1.4  christos /* This is a copy of the same data structure found in gcc/config/msp430/msp430.c
    717  1.1.1.4  christos    Keep these two structures in sync.
    718  1.1.1.6  christos    The data in this structure has been extracted from version 1.194 of the
    719  1.1.1.6  christos    devices.csv file released by TI in September 2016.  */
    720      1.1     skrll 
    721  1.1.1.4  christos struct msp430_mcu_data
    722  1.1.1.4  christos {
    723  1.1.1.4  christos   const char * name;
    724  1.1.1.4  christos   unsigned int revision; /* 0=> MSP430, 1=>MSP430X, 2=> MSP430Xv2.  */
    725  1.1.1.4  christos   unsigned int hwmpy;    /* 0=>none, 1=>16-bit, 2=>16-bit w/sign extend, 4=>32-bit, 8=> 32-bit (5xx).  */
    726      1.1     skrll }
    727  1.1.1.4  christos msp430_mcu_data [] =
    728  1.1.1.4  christos {
    729  1.1.1.4  christos   { "cc430f5123",2,8 },
    730  1.1.1.4  christos   { "cc430f5125",2,8 },
    731  1.1.1.4  christos   { "cc430f5133",2,8 },
    732  1.1.1.4  christos   { "cc430f5135",2,8 },
    733  1.1.1.4  christos   { "cc430f5137",2,8 },
    734  1.1.1.4  christos   { "cc430f5143",2,8 },
    735  1.1.1.4  christos   { "cc430f5145",2,8 },
    736  1.1.1.4  christos   { "cc430f5147",2,8 },
    737  1.1.1.4  christos   { "cc430f6125",2,8 },
    738  1.1.1.4  christos   { "cc430f6126",2,8 },
    739  1.1.1.4  christos   { "cc430f6127",2,8 },
    740  1.1.1.4  christos   { "cc430f6135",2,8 },
    741  1.1.1.4  christos   { "cc430f6137",2,8 },
    742  1.1.1.4  christos   { "cc430f6143",2,8 },
    743  1.1.1.4  christos   { "cc430f6145",2,8 },
    744  1.1.1.4  christos   { "cc430f6147",2,8 },
    745  1.1.1.4  christos   { "msp430afe221",0,2 },
    746  1.1.1.4  christos   { "msp430afe222",0,2 },
    747  1.1.1.4  christos   { "msp430afe223",0,2 },
    748  1.1.1.4  christos   { "msp430afe231",0,2 },
    749  1.1.1.4  christos   { "msp430afe232",0,2 },
    750  1.1.1.4  christos   { "msp430afe233",0,2 },
    751  1.1.1.4  christos   { "msp430afe251",0,2 },
    752  1.1.1.4  christos   { "msp430afe252",0,2 },
    753  1.1.1.4  christos   { "msp430afe253",0,2 },
    754  1.1.1.4  christos   { "msp430bt5190",2,8 },
    755  1.1.1.4  christos   { "msp430c091",0,0 },
    756  1.1.1.4  christos   { "msp430c092",0,0 },
    757  1.1.1.4  christos   { "msp430c111",0,0 },
    758  1.1.1.4  christos   { "msp430c1111",0,0 },
    759  1.1.1.4  christos   { "msp430c112",0,0 },
    760  1.1.1.4  christos   { "msp430c1121",0,0 },
    761  1.1.1.4  christos   { "msp430c1331",0,0 },
    762  1.1.1.4  christos   { "msp430c1351",0,0 },
    763  1.1.1.4  christos   { "msp430c311s",0,0 },
    764  1.1.1.4  christos   { "msp430c312",0,0 },
    765  1.1.1.4  christos   { "msp430c313",0,0 },
    766  1.1.1.4  christos   { "msp430c314",0,0 },
    767  1.1.1.4  christos   { "msp430c315",0,0 },
    768  1.1.1.4  christos   { "msp430c323",0,0 },
    769  1.1.1.4  christos   { "msp430c325",0,0 },
    770  1.1.1.4  christos   { "msp430c336",0,1 },
    771  1.1.1.4  christos   { "msp430c337",0,1 },
    772  1.1.1.4  christos   { "msp430c412",0,0 },
    773  1.1.1.4  christos   { "msp430c413",0,0 },
    774  1.1.1.4  christos   { "msp430cg4616",1,1 },
    775  1.1.1.4  christos   { "msp430cg4617",1,1 },
    776  1.1.1.4  christos   { "msp430cg4618",1,1 },
    777  1.1.1.4  christos   { "msp430cg4619",1,1 },
    778  1.1.1.4  christos   { "msp430e112",0,0 },
    779  1.1.1.4  christos   { "msp430e313",0,0 },
    780  1.1.1.4  christos   { "msp430e315",0,0 },
    781  1.1.1.4  christos   { "msp430e325",0,0 },
    782  1.1.1.4  christos   { "msp430e337",0,1 },
    783  1.1.1.4  christos   { "msp430f110",0,0 },
    784  1.1.1.4  christos   { "msp430f1101",0,0 },
    785  1.1.1.4  christos   { "msp430f1101a",0,0 },
    786  1.1.1.4  christos   { "msp430f1111",0,0 },
    787  1.1.1.4  christos   { "msp430f1111a",0,0 },
    788  1.1.1.4  christos   { "msp430f112",0,0 },
    789  1.1.1.4  christos   { "msp430f1121",0,0 },
    790  1.1.1.4  christos   { "msp430f1121a",0,0 },
    791  1.1.1.4  christos   { "msp430f1122",0,0 },
    792  1.1.1.4  christos   { "msp430f1132",0,0 },
    793  1.1.1.4  christos   { "msp430f122",0,0 },
    794  1.1.1.4  christos   { "msp430f1222",0,0 },
    795  1.1.1.4  christos   { "msp430f123",0,0 },
    796  1.1.1.4  christos   { "msp430f1232",0,0 },
    797  1.1.1.4  christos   { "msp430f133",0,0 },
    798  1.1.1.4  christos   { "msp430f135",0,0 },
    799  1.1.1.4  christos   { "msp430f147",0,1 },
    800  1.1.1.4  christos   { "msp430f1471",0,1 },
    801  1.1.1.4  christos   { "msp430f148",0,1 },
    802  1.1.1.4  christos   { "msp430f1481",0,1 },
    803  1.1.1.4  christos   { "msp430f149",0,1 },
    804  1.1.1.4  christos   { "msp430f1491",0,1 },
    805  1.1.1.4  christos   { "msp430f155",0,0 },
    806  1.1.1.4  christos   { "msp430f156",0,0 },
    807  1.1.1.4  christos   { "msp430f157",0,0 },
    808  1.1.1.4  christos   { "msp430f1610",0,1 },
    809  1.1.1.4  christos   { "msp430f1611",0,1 },
    810  1.1.1.4  christos   { "msp430f1612",0,1 },
    811  1.1.1.4  christos   { "msp430f167",0,1 },
    812  1.1.1.4  christos   { "msp430f168",0,1 },
    813  1.1.1.4  christos   { "msp430f169",0,1 },
    814  1.1.1.4  christos   { "msp430f2001",0,0 },
    815  1.1.1.4  christos   { "msp430f2002",0,0 },
    816  1.1.1.4  christos   { "msp430f2003",0,0 },
    817  1.1.1.4  christos   { "msp430f2011",0,0 },
    818  1.1.1.4  christos   { "msp430f2012",0,0 },
    819  1.1.1.4  christos   { "msp430f2013",0,0 },
    820  1.1.1.4  christos   { "msp430f2101",0,0 },
    821  1.1.1.4  christos   { "msp430f2111",0,0 },
    822  1.1.1.4  christos   { "msp430f2112",0,0 },
    823  1.1.1.4  christos   { "msp430f2121",0,0 },
    824  1.1.1.4  christos   { "msp430f2122",0,0 },
    825  1.1.1.4  christos   { "msp430f2131",0,0 },
    826  1.1.1.4  christos   { "msp430f2132",0,0 },
    827  1.1.1.4  christos   { "msp430f2232",0,0 },
    828  1.1.1.4  christos   { "msp430f2234",0,0 },
    829  1.1.1.4  christos   { "msp430f2252",0,0 },
    830  1.1.1.4  christos   { "msp430f2254",0,0 },
    831  1.1.1.4  christos   { "msp430f2272",0,0 },
    832  1.1.1.4  christos   { "msp430f2274",0,0 },
    833  1.1.1.4  christos   { "msp430f233",0,2 },
    834  1.1.1.4  christos   { "msp430f2330",0,2 },
    835  1.1.1.4  christos   { "msp430f235",0,2 },
    836  1.1.1.4  christos   { "msp430f2350",0,2 },
    837  1.1.1.4  christos   { "msp430f2370",0,2 },
    838  1.1.1.4  christos   { "msp430f2410",0,2 },
    839  1.1.1.4  christos   { "msp430f2416",1,2 },
    840  1.1.1.4  christos   { "msp430f2417",1,2 },
    841  1.1.1.4  christos   { "msp430f2418",1,2 },
    842  1.1.1.4  christos   { "msp430f2419",1,2 },
    843  1.1.1.4  christos   { "msp430f247",0,2 },
    844  1.1.1.4  christos   { "msp430f2471",0,2 },
    845  1.1.1.4  christos   { "msp430f248",0,2 },
    846  1.1.1.4  christos   { "msp430f2481",0,2 },
    847  1.1.1.4  christos   { "msp430f249",0,2 },
    848  1.1.1.4  christos   { "msp430f2491",0,2 },
    849  1.1.1.4  christos   { "msp430f2616",1,2 },
    850  1.1.1.4  christos   { "msp430f2617",1,2 },
    851  1.1.1.4  christos   { "msp430f2618",1,2 },
    852  1.1.1.4  christos   { "msp430f2619",1,2 },
    853  1.1.1.4  christos   { "msp430f412",0,0 },
    854  1.1.1.4  christos   { "msp430f413",0,0 },
    855  1.1.1.4  christos   { "msp430f4132",0,0 },
    856  1.1.1.4  christos   { "msp430f415",0,0 },
    857  1.1.1.4  christos   { "msp430f4152",0,0 },
    858  1.1.1.4  christos   { "msp430f417",0,0 },
    859  1.1.1.4  christos   { "msp430f423",0,1 },
    860  1.1.1.4  christos   { "msp430f423a",0,1 },
    861  1.1.1.4  christos   { "msp430f425",0,1 },
    862  1.1.1.4  christos   { "msp430f4250",0,0 },
    863  1.1.1.4  christos   { "msp430f425a",0,1 },
    864  1.1.1.4  christos   { "msp430f4260",0,0 },
    865  1.1.1.4  christos   { "msp430f427",0,1 },
    866  1.1.1.4  christos   { "msp430f4270",0,0 },
    867  1.1.1.4  christos   { "msp430f427a",0,1 },
    868  1.1.1.4  christos   { "msp430f435",0,0 },
    869  1.1.1.4  christos   { "msp430f4351",0,0 },
    870  1.1.1.4  christos   { "msp430f436",0,0 },
    871  1.1.1.4  christos   { "msp430f4361",0,0 },
    872  1.1.1.4  christos   { "msp430f437",0,0 },
    873  1.1.1.4  christos   { "msp430f4371",0,0 },
    874  1.1.1.4  christos   { "msp430f438",0,0 },
    875  1.1.1.4  christos   { "msp430f439",0,0 },
    876  1.1.1.4  christos   { "msp430f447",0,1 },
    877  1.1.1.4  christos   { "msp430f448",0,1 },
    878  1.1.1.4  christos   { "msp430f4481",0,1 },
    879  1.1.1.4  christos   { "msp430f449",0,1 },
    880  1.1.1.4  christos   { "msp430f4491",0,1 },
    881  1.1.1.4  christos   { "msp430f4616",1,1 },
    882  1.1.1.4  christos   { "msp430f46161",1,1 },
    883  1.1.1.4  christos   { "msp430f4617",1,1 },
    884  1.1.1.4  christos   { "msp430f46171",1,1 },
    885  1.1.1.4  christos   { "msp430f4618",1,1 },
    886  1.1.1.4  christos   { "msp430f46181",1,1 },
    887  1.1.1.4  christos   { "msp430f4619",1,1 },
    888  1.1.1.4  christos   { "msp430f46191",1,1 },
    889  1.1.1.4  christos   { "msp430f47126",1,4 },
    890  1.1.1.4  christos   { "msp430f47127",1,4 },
    891  1.1.1.4  christos   { "msp430f47163",1,4 },
    892  1.1.1.4  christos   { "msp430f47166",1,4 },
    893  1.1.1.4  christos   { "msp430f47167",1,4 },
    894  1.1.1.4  christos   { "msp430f47173",1,4 },
    895  1.1.1.4  christos   { "msp430f47176",1,4 },
    896  1.1.1.4  christos   { "msp430f47177",1,4 },
    897  1.1.1.4  christos   { "msp430f47183",1,4 },
    898  1.1.1.4  christos   { "msp430f47186",1,4 },
    899  1.1.1.4  christos   { "msp430f47187",1,4 },
    900  1.1.1.4  christos   { "msp430f47193",1,4 },
    901  1.1.1.4  christos   { "msp430f47196",1,4 },
    902  1.1.1.4  christos   { "msp430f47197",1,4 },
    903  1.1.1.4  christos   { "msp430f477",0,0 },
    904  1.1.1.4  christos   { "msp430f478",0,0 },
    905  1.1.1.4  christos   { "msp430f4783",0,4 },
    906  1.1.1.4  christos   { "msp430f4784",0,4 },
    907  1.1.1.4  christos   { "msp430f479",0,0 },
    908  1.1.1.4  christos   { "msp430f4793",0,4 },
    909  1.1.1.4  christos   { "msp430f4794",0,4 },
    910  1.1.1.4  christos   { "msp430f5131",2,8 },
    911  1.1.1.4  christos   { "msp430f5132",2,8 },
    912  1.1.1.4  christos   { "msp430f5151",2,8 },
    913  1.1.1.4  christos   { "msp430f5152",2,8 },
    914  1.1.1.4  christos   { "msp430f5171",2,8 },
    915  1.1.1.4  christos   { "msp430f5172",2,8 },
    916  1.1.1.4  christos   { "msp430f5212",2,8 },
    917  1.1.1.4  christos   { "msp430f5213",2,8 },
    918  1.1.1.4  christos   { "msp430f5214",2,8 },
    919  1.1.1.4  christos   { "msp430f5217",2,8 },
    920  1.1.1.4  christos   { "msp430f5218",2,8 },
    921  1.1.1.4  christos   { "msp430f5219",2,8 },
    922  1.1.1.4  christos   { "msp430f5222",2,8 },
    923  1.1.1.4  christos   { "msp430f5223",2,8 },
    924  1.1.1.4  christos   { "msp430f5224",2,8 },
    925  1.1.1.4  christos   { "msp430f5227",2,8 },
    926  1.1.1.4  christos   { "msp430f5228",2,8 },
    927  1.1.1.4  christos   { "msp430f5229",2,8 },
    928  1.1.1.4  christos   { "msp430f5232",2,8 },
    929  1.1.1.4  christos   { "msp430f5234",2,8 },
    930  1.1.1.4  christos   { "msp430f5237",2,8 },
    931  1.1.1.4  christos   { "msp430f5239",2,8 },
    932  1.1.1.4  christos   { "msp430f5242",2,8 },
    933  1.1.1.4  christos   { "msp430f5244",2,8 },
    934  1.1.1.4  christos   { "msp430f5247",2,8 },
    935  1.1.1.4  christos   { "msp430f5249",2,8 },
    936  1.1.1.4  christos   { "msp430f5252",2,8 },
    937  1.1.1.4  christos   { "msp430f5253",2,8 },
    938  1.1.1.4  christos   { "msp430f5254",2,8 },
    939  1.1.1.4  christos   { "msp430f5255",2,8 },
    940  1.1.1.4  christos   { "msp430f5256",2,8 },
    941  1.1.1.4  christos   { "msp430f5257",2,8 },
    942  1.1.1.4  christos   { "msp430f5258",2,8 },
    943  1.1.1.4  christos   { "msp430f5259",2,8 },
    944  1.1.1.4  christos   { "msp430f5304",2,8 },
    945  1.1.1.4  christos   { "msp430f5308",2,8 },
    946  1.1.1.4  christos   { "msp430f5309",2,8 },
    947  1.1.1.4  christos   { "msp430f5310",2,8 },
    948  1.1.1.4  christos   { "msp430f5324",2,8 },
    949  1.1.1.4  christos   { "msp430f5325",2,8 },
    950  1.1.1.4  christos   { "msp430f5326",2,8 },
    951  1.1.1.4  christos   { "msp430f5327",2,8 },
    952  1.1.1.4  christos   { "msp430f5328",2,8 },
    953  1.1.1.4  christos   { "msp430f5329",2,8 },
    954  1.1.1.4  christos   { "msp430f5333",2,8 },
    955  1.1.1.4  christos   { "msp430f5335",2,8 },
    956  1.1.1.4  christos   { "msp430f5336",2,8 },
    957  1.1.1.4  christos   { "msp430f5338",2,8 },
    958  1.1.1.4  christos   { "msp430f5340",2,8 },
    959  1.1.1.4  christos   { "msp430f5341",2,8 },
    960  1.1.1.4  christos   { "msp430f5342",2,8 },
    961  1.1.1.4  christos   { "msp430f5358",2,8 },
    962  1.1.1.4  christos   { "msp430f5359",2,8 },
    963  1.1.1.4  christos   { "msp430f5418",2,8 },
    964  1.1.1.4  christos   { "msp430f5418a",2,8 },
    965  1.1.1.4  christos   { "msp430f5419",2,8 },
    966  1.1.1.4  christos   { "msp430f5419a",2,8 },
    967  1.1.1.4  christos   { "msp430f5435",2,8 },
    968  1.1.1.4  christos   { "msp430f5435a",2,8 },
    969  1.1.1.4  christos   { "msp430f5436",2,8 },
    970  1.1.1.4  christos   { "msp430f5436a",2,8 },
    971  1.1.1.4  christos   { "msp430f5437",2,8 },
    972  1.1.1.4  christos   { "msp430f5437a",2,8 },
    973  1.1.1.4  christos   { "msp430f5438",2,8 },
    974  1.1.1.4  christos   { "msp430f5438a",2,8 },
    975  1.1.1.4  christos   { "msp430f5500",2,8 },
    976  1.1.1.4  christos   { "msp430f5501",2,8 },
    977  1.1.1.4  christos   { "msp430f5502",2,8 },
    978  1.1.1.4  christos   { "msp430f5503",2,8 },
    979  1.1.1.4  christos   { "msp430f5504",2,8 },
    980  1.1.1.4  christos   { "msp430f5505",2,8 },
    981  1.1.1.4  christos   { "msp430f5506",2,8 },
    982  1.1.1.4  christos   { "msp430f5507",2,8 },
    983  1.1.1.4  christos   { "msp430f5508",2,8 },
    984  1.1.1.4  christos   { "msp430f5509",2,8 },
    985  1.1.1.4  christos   { "msp430f5510",2,8 },
    986  1.1.1.4  christos   { "msp430f5513",2,8 },
    987  1.1.1.4  christos   { "msp430f5514",2,8 },
    988  1.1.1.4  christos   { "msp430f5515",2,8 },
    989  1.1.1.4  christos   { "msp430f5517",2,8 },
    990  1.1.1.4  christos   { "msp430f5519",2,8 },
    991  1.1.1.4  christos   { "msp430f5521",2,8 },
    992  1.1.1.4  christos   { "msp430f5522",2,8 },
    993  1.1.1.4  christos   { "msp430f5524",2,8 },
    994  1.1.1.4  christos   { "msp430f5525",2,8 },
    995  1.1.1.4  christos   { "msp430f5526",2,8 },
    996  1.1.1.4  christos   { "msp430f5527",2,8 },
    997  1.1.1.4  christos   { "msp430f5528",2,8 },
    998  1.1.1.4  christos   { "msp430f5529",2,8 },
    999  1.1.1.4  christos   { "msp430f5630",2,8 },
   1000  1.1.1.4  christos   { "msp430f5631",2,8 },
   1001  1.1.1.4  christos   { "msp430f5632",2,8 },
   1002  1.1.1.4  christos   { "msp430f5633",2,8 },
   1003  1.1.1.4  christos   { "msp430f5634",2,8 },
   1004  1.1.1.4  christos   { "msp430f5635",2,8 },
   1005  1.1.1.4  christos   { "msp430f5636",2,8 },
   1006  1.1.1.4  christos   { "msp430f5637",2,8 },
   1007  1.1.1.4  christos   { "msp430f5638",2,8 },
   1008  1.1.1.4  christos   { "msp430f5658",2,8 },
   1009  1.1.1.4  christos   { "msp430f5659",2,8 },
   1010  1.1.1.4  christos   { "msp430f5xx_6xxgeneric",2,8 },
   1011  1.1.1.4  christos   { "msp430f6433",2,8 },
   1012  1.1.1.4  christos   { "msp430f6435",2,8 },
   1013  1.1.1.4  christos   { "msp430f6436",2,8 },
   1014  1.1.1.4  christos   { "msp430f6438",2,8 },
   1015  1.1.1.4  christos   { "msp430f6458",2,8 },
   1016  1.1.1.4  christos   { "msp430f6459",2,8 },
   1017  1.1.1.4  christos   { "msp430f6630",2,8 },
   1018  1.1.1.4  christos   { "msp430f6631",2,8 },
   1019  1.1.1.4  christos   { "msp430f6632",2,8 },
   1020  1.1.1.4  christos   { "msp430f6633",2,8 },
   1021  1.1.1.4  christos   { "msp430f6634",2,8 },
   1022  1.1.1.4  christos   { "msp430f6635",2,8 },
   1023  1.1.1.4  christos   { "msp430f6636",2,8 },
   1024  1.1.1.4  christos   { "msp430f6637",2,8 },
   1025  1.1.1.4  christos   { "msp430f6638",2,8 },
   1026  1.1.1.4  christos   { "msp430f6658",2,8 },
   1027  1.1.1.4  christos   { "msp430f6659",2,8 },
   1028  1.1.1.4  christos   { "msp430f6720",2,8 },
   1029  1.1.1.4  christos   { "msp430f6720a",2,8 },
   1030  1.1.1.4  christos   { "msp430f6721",2,8 },
   1031  1.1.1.4  christos   { "msp430f6721a",2,8 },
   1032  1.1.1.4  christos   { "msp430f6723",2,8 },
   1033  1.1.1.4  christos   { "msp430f6723a",2,8 },
   1034  1.1.1.4  christos   { "msp430f6724",2,8 },
   1035  1.1.1.4  christos   { "msp430f6724a",2,8 },
   1036  1.1.1.4  christos   { "msp430f6725",2,8 },
   1037  1.1.1.4  christos   { "msp430f6725a",2,8 },
   1038  1.1.1.4  christos   { "msp430f6726",2,8 },
   1039  1.1.1.4  christos   { "msp430f6726a",2,8 },
   1040  1.1.1.4  christos   { "msp430f6730",2,8 },
   1041  1.1.1.4  christos   { "msp430f6730a",2,8 },
   1042  1.1.1.4  christos   { "msp430f6731",2,8 },
   1043  1.1.1.4  christos   { "msp430f6731a",2,8 },
   1044  1.1.1.4  christos   { "msp430f6733",2,8 },
   1045  1.1.1.4  christos   { "msp430f6733a",2,8 },
   1046  1.1.1.4  christos   { "msp430f6734",2,8 },
   1047  1.1.1.4  christos   { "msp430f6734a",2,8 },
   1048  1.1.1.4  christos   { "msp430f6735",2,8 },
   1049  1.1.1.4  christos   { "msp430f6735a",2,8 },
   1050  1.1.1.4  christos   { "msp430f6736",2,8 },
   1051  1.1.1.4  christos   { "msp430f6736a",2,8 },
   1052  1.1.1.4  christos   { "msp430f6745",2,8 },
   1053  1.1.1.4  christos   { "msp430f67451",2,8 },
   1054  1.1.1.4  christos   { "msp430f67451a",2,8 },
   1055  1.1.1.4  christos   { "msp430f6745a",2,8 },
   1056  1.1.1.4  christos   { "msp430f6746",2,8 },
   1057  1.1.1.4  christos   { "msp430f67461",2,8 },
   1058  1.1.1.4  christos   { "msp430f67461a",2,8 },
   1059  1.1.1.4  christos   { "msp430f6746a",2,8 },
   1060  1.1.1.4  christos   { "msp430f6747",2,8 },
   1061  1.1.1.4  christos   { "msp430f67471",2,8 },
   1062  1.1.1.4  christos   { "msp430f67471a",2,8 },
   1063  1.1.1.4  christos   { "msp430f6747a",2,8 },
   1064  1.1.1.4  christos   { "msp430f6748",2,8 },
   1065  1.1.1.4  christos   { "msp430f67481",2,8 },
   1066  1.1.1.4  christos   { "msp430f67481a",2,8 },
   1067  1.1.1.4  christos   { "msp430f6748a",2,8 },
   1068  1.1.1.4  christos   { "msp430f6749",2,8 },
   1069  1.1.1.4  christos   { "msp430f67491",2,8 },
   1070  1.1.1.4  christos   { "msp430f67491a",2,8 },
   1071  1.1.1.4  christos   { "msp430f6749a",2,8 },
   1072  1.1.1.4  christos   { "msp430f67621",2,8 },
   1073  1.1.1.4  christos   { "msp430f67621a",2,8 },
   1074  1.1.1.4  christos   { "msp430f67641",2,8 },
   1075  1.1.1.4  christos   { "msp430f67641a",2,8 },
   1076  1.1.1.4  christos   { "msp430f6765",2,8 },
   1077  1.1.1.4  christos   { "msp430f67651",2,8 },
   1078  1.1.1.4  christos   { "msp430f67651a",2,8 },
   1079  1.1.1.4  christos   { "msp430f6765a",2,8 },
   1080  1.1.1.4  christos   { "msp430f6766",2,8 },
   1081  1.1.1.4  christos   { "msp430f67661",2,8 },
   1082  1.1.1.4  christos   { "msp430f67661a",2,8 },
   1083  1.1.1.4  christos   { "msp430f6766a",2,8 },
   1084  1.1.1.4  christos   { "msp430f6767",2,8 },
   1085  1.1.1.4  christos   { "msp430f67671",2,8 },
   1086  1.1.1.4  christos   { "msp430f67671a",2,8 },
   1087  1.1.1.4  christos   { "msp430f6767a",2,8 },
   1088  1.1.1.4  christos   { "msp430f6768",2,8 },
   1089  1.1.1.4  christos   { "msp430f67681",2,8 },
   1090  1.1.1.4  christos   { "msp430f67681a",2,8 },
   1091  1.1.1.4  christos   { "msp430f6768a",2,8 },
   1092  1.1.1.4  christos   { "msp430f6769",2,8 },
   1093  1.1.1.4  christos   { "msp430f67691",2,8 },
   1094  1.1.1.4  christos   { "msp430f67691a",2,8 },
   1095  1.1.1.4  christos   { "msp430f6769a",2,8 },
   1096  1.1.1.4  christos   { "msp430f6775",2,8 },
   1097  1.1.1.4  christos   { "msp430f67751",2,8 },
   1098  1.1.1.4  christos   { "msp430f67751a",2,8 },
   1099  1.1.1.4  christos   { "msp430f6775a",2,8 },
   1100  1.1.1.4  christos   { "msp430f6776",2,8 },
   1101  1.1.1.4  christos   { "msp430f67761",2,8 },
   1102  1.1.1.4  christos   { "msp430f67761a",2,8 },
   1103  1.1.1.4  christos   { "msp430f6776a",2,8 },
   1104  1.1.1.4  christos   { "msp430f6777",2,8 },
   1105  1.1.1.4  christos   { "msp430f67771",2,8 },
   1106  1.1.1.4  christos   { "msp430f67771a",2,8 },
   1107  1.1.1.4  christos   { "msp430f6777a",2,8 },
   1108  1.1.1.4  christos   { "msp430f6778",2,8 },
   1109  1.1.1.4  christos   { "msp430f67781",2,8 },
   1110  1.1.1.4  christos   { "msp430f67781a",2,8 },
   1111  1.1.1.4  christos   { "msp430f6778a",2,8 },
   1112  1.1.1.4  christos   { "msp430f6779",2,8 },
   1113  1.1.1.4  christos   { "msp430f67791",2,8 },
   1114  1.1.1.4  christos   { "msp430f67791a",2,8 },
   1115  1.1.1.4  christos   { "msp430f6779a",2,8 },
   1116  1.1.1.4  christos   { "msp430fe423",0,0 },
   1117  1.1.1.4  christos   { "msp430fe4232",0,0 },
   1118  1.1.1.4  christos   { "msp430fe423a",0,0 },
   1119  1.1.1.4  christos   { "msp430fe4242",0,0 },
   1120  1.1.1.4  christos   { "msp430fe425",0,0 },
   1121  1.1.1.4  christos   { "msp430fe4252",0,0 },
   1122  1.1.1.4  christos   { "msp430fe425a",0,0 },
   1123  1.1.1.4  christos   { "msp430fe427",0,0 },
   1124  1.1.1.4  christos   { "msp430fe4272",0,0 },
   1125  1.1.1.4  christos   { "msp430fe427a",0,0 },
   1126  1.1.1.4  christos   { "msp430fg4250",0,0 },
   1127  1.1.1.4  christos   { "msp430fg4260",0,0 },
   1128  1.1.1.4  christos   { "msp430fg4270",0,0 },
   1129  1.1.1.4  christos   { "msp430fg437",0,0 },
   1130  1.1.1.4  christos   { "msp430fg438",0,0 },
   1131  1.1.1.4  christos   { "msp430fg439",0,0 },
   1132  1.1.1.4  christos   { "msp430fg4616",1,1 },
   1133  1.1.1.4  christos   { "msp430fg4617",1,1 },
   1134  1.1.1.4  christos   { "msp430fg4618",1,1 },
   1135  1.1.1.4  christos   { "msp430fg4619",1,1 },
   1136  1.1.1.4  christos   { "msp430fg477",0,0 },
   1137  1.1.1.4  christos   { "msp430fg478",0,0 },
   1138  1.1.1.4  christos   { "msp430fg479",0,0 },
   1139  1.1.1.4  christos   { "msp430fg6425",2,8 },
   1140  1.1.1.4  christos   { "msp430fg6426",2,8 },
   1141  1.1.1.4  christos   { "msp430fg6625",2,8 },
   1142  1.1.1.4  christos   { "msp430fg6626",2,8 },
   1143  1.1.1.4  christos   { "msp430fr2032",2,0 },
   1144  1.1.1.4  christos   { "msp430fr2033",2,0 },
   1145  1.1.1.6  christos   { "msp430fr2110",2,0 },
   1146  1.1.1.6  christos   { "msp430fr2111",2,0 },
   1147  1.1.1.5  christos   { "msp430fr2310",2,0 },
   1148  1.1.1.5  christos   { "msp430fr2311",2,0 },
   1149  1.1.1.4  christos   { "msp430fr2433",2,8 },
   1150  1.1.1.5  christos   { "msp430fr2532",2,8 },
   1151  1.1.1.5  christos   { "msp430fr2533",2,8 },
   1152  1.1.1.5  christos   { "msp430fr2632",2,8 },
   1153  1.1.1.5  christos   { "msp430fr2633",2,8 },
   1154  1.1.1.4  christos   { "msp430fr2xx_4xxgeneric",2,8 },
   1155  1.1.1.4  christos   { "msp430fr4131",2,0 },
   1156  1.1.1.4  christos   { "msp430fr4132",2,0 },
   1157  1.1.1.4  christos   { "msp430fr4133",2,0 },
   1158  1.1.1.4  christos   { "msp430fr5720",2,8 },
   1159  1.1.1.4  christos   { "msp430fr5721",2,8 },
   1160  1.1.1.4  christos   { "msp430fr5722",2,8 },
   1161  1.1.1.4  christos   { "msp430fr5723",2,8 },
   1162  1.1.1.4  christos   { "msp430fr5724",2,8 },
   1163  1.1.1.4  christos   { "msp430fr5725",2,8 },
   1164  1.1.1.4  christos   { "msp430fr5726",2,8 },
   1165  1.1.1.4  christos   { "msp430fr5727",2,8 },
   1166  1.1.1.4  christos   { "msp430fr5728",2,8 },
   1167  1.1.1.4  christos   { "msp430fr5729",2,8 },
   1168  1.1.1.4  christos   { "msp430fr5730",2,8 },
   1169  1.1.1.4  christos   { "msp430fr5731",2,8 },
   1170  1.1.1.4  christos   { "msp430fr5732",2,8 },
   1171  1.1.1.4  christos   { "msp430fr5733",2,8 },
   1172  1.1.1.4  christos   { "msp430fr5734",2,8 },
   1173  1.1.1.4  christos   { "msp430fr5735",2,8 },
   1174  1.1.1.4  christos   { "msp430fr5736",2,8 },
   1175  1.1.1.4  christos   { "msp430fr5737",2,8 },
   1176  1.1.1.4  christos   { "msp430fr5738",2,8 },
   1177  1.1.1.4  christos   { "msp430fr5739",2,8 },
   1178  1.1.1.4  christos   { "msp430fr57xxgeneric",2,8 },
   1179  1.1.1.4  christos   { "msp430fr5847",2,8 },
   1180  1.1.1.4  christos   { "msp430fr58471",2,8 },
   1181  1.1.1.4  christos   { "msp430fr5848",2,8 },
   1182  1.1.1.4  christos   { "msp430fr5849",2,8 },
   1183  1.1.1.4  christos   { "msp430fr5857",2,8 },
   1184  1.1.1.4  christos   { "msp430fr5858",2,8 },
   1185  1.1.1.4  christos   { "msp430fr5859",2,8 },
   1186  1.1.1.4  christos   { "msp430fr5867",2,8 },
   1187  1.1.1.4  christos   { "msp430fr58671",2,8 },
   1188  1.1.1.4  christos   { "msp430fr5868",2,8 },
   1189  1.1.1.4  christos   { "msp430fr5869",2,8 },
   1190  1.1.1.4  christos   { "msp430fr5870",2,8 },
   1191  1.1.1.4  christos   { "msp430fr5872",2,8 },
   1192  1.1.1.4  christos   { "msp430fr58721",2,8 },
   1193  1.1.1.4  christos   { "msp430fr5887",2,8 },
   1194  1.1.1.4  christos   { "msp430fr5888",2,8 },
   1195  1.1.1.4  christos   { "msp430fr5889",2,8 },
   1196  1.1.1.4  christos   { "msp430fr58891",2,8 },
   1197  1.1.1.4  christos   { "msp430fr5922",2,8 },
   1198  1.1.1.4  christos   { "msp430fr59221",2,8 },
   1199  1.1.1.4  christos   { "msp430fr5947",2,8 },
   1200  1.1.1.4  christos   { "msp430fr59471",2,8 },
   1201  1.1.1.4  christos   { "msp430fr5948",2,8 },
   1202  1.1.1.4  christos   { "msp430fr5949",2,8 },
   1203  1.1.1.4  christos   { "msp430fr5957",2,8 },
   1204  1.1.1.4  christos   { "msp430fr5958",2,8 },
   1205  1.1.1.4  christos   { "msp430fr5959",2,8 },
   1206  1.1.1.5  christos   { "msp430fr5962",2,8 },
   1207  1.1.1.5  christos   { "msp430fr5964",2,8 },
   1208  1.1.1.4  christos   { "msp430fr5967",2,8 },
   1209  1.1.1.4  christos   { "msp430fr5968",2,8 },
   1210  1.1.1.4  christos   { "msp430fr5969",2,8 },
   1211  1.1.1.4  christos   { "msp430fr59691",2,8 },
   1212  1.1.1.4  christos   { "msp430fr5970",2,8 },
   1213  1.1.1.4  christos   { "msp430fr5972",2,8 },
   1214  1.1.1.4  christos   { "msp430fr59721",2,8 },
   1215  1.1.1.4  christos   { "msp430fr5986",2,8 },
   1216  1.1.1.4  christos   { "msp430fr5987",2,8 },
   1217  1.1.1.4  christos   { "msp430fr5988",2,8 },
   1218  1.1.1.4  christos   { "msp430fr5989",2,8 },
   1219  1.1.1.4  christos   { "msp430fr59891",2,8 },
   1220  1.1.1.5  christos   { "msp430fr5992",2,8 },
   1221  1.1.1.5  christos   { "msp430fr5994",2,8 },
   1222  1.1.1.6  christos   { "msp430fr59941",2,8 },
   1223  1.1.1.4  christos   { "msp430fr5xx_6xxgeneric",2,8 },
   1224  1.1.1.4  christos   { "msp430fr6820",2,8 },
   1225  1.1.1.4  christos   { "msp430fr6822",2,8 },
   1226  1.1.1.4  christos   { "msp430fr68221",2,8 },
   1227  1.1.1.4  christos   { "msp430fr6870",2,8 },
   1228  1.1.1.4  christos   { "msp430fr6872",2,8 },
   1229  1.1.1.4  christos   { "msp430fr68721",2,8 },
   1230  1.1.1.4  christos   { "msp430fr6877",2,8 },
   1231  1.1.1.4  christos   { "msp430fr6879",2,8 },
   1232  1.1.1.4  christos   { "msp430fr68791",2,8 },
   1233  1.1.1.4  christos   { "msp430fr6887",2,8 },
   1234  1.1.1.4  christos   { "msp430fr6888",2,8 },
   1235  1.1.1.4  christos   { "msp430fr6889",2,8 },
   1236  1.1.1.4  christos   { "msp430fr68891",2,8 },
   1237  1.1.1.4  christos   { "msp430fr6920",2,8 },
   1238  1.1.1.4  christos   { "msp430fr6922",2,8 },
   1239  1.1.1.4  christos   { "msp430fr69221",2,8 },
   1240  1.1.1.4  christos   { "msp430fr6927",2,8 },
   1241  1.1.1.4  christos   { "msp430fr69271",2,8 },
   1242  1.1.1.4  christos   { "msp430fr6928",2,8 },
   1243  1.1.1.4  christos   { "msp430fr6970",2,8 },
   1244  1.1.1.4  christos   { "msp430fr6972",2,8 },
   1245  1.1.1.4  christos   { "msp430fr69721",2,8 },
   1246  1.1.1.4  christos   { "msp430fr6977",2,8 },
   1247  1.1.1.4  christos   { "msp430fr6979",2,8 },
   1248  1.1.1.4  christos   { "msp430fr69791",2,8 },
   1249  1.1.1.4  christos   { "msp430fr6987",2,8 },
   1250  1.1.1.4  christos   { "msp430fr6988",2,8 },
   1251  1.1.1.4  christos   { "msp430fr6989",2,8 },
   1252  1.1.1.4  christos   { "msp430fr69891",2,8 },
   1253  1.1.1.4  christos   { "msp430fw423",0,0 },
   1254  1.1.1.4  christos   { "msp430fw425",0,0 },
   1255  1.1.1.4  christos   { "msp430fw427",0,0 },
   1256  1.1.1.4  christos   { "msp430fw428",0,0 },
   1257  1.1.1.4  christos   { "msp430fw429",0,0 },
   1258  1.1.1.4  christos   { "msp430g2001",0,0 },
   1259  1.1.1.4  christos   { "msp430g2101",0,0 },
   1260  1.1.1.4  christos   { "msp430g2102",0,0 },
   1261  1.1.1.4  christos   { "msp430g2111",0,0 },
   1262  1.1.1.4  christos   { "msp430g2112",0,0 },
   1263  1.1.1.4  christos   { "msp430g2113",0,0 },
   1264  1.1.1.4  christos   { "msp430g2121",0,0 },
   1265  1.1.1.4  christos   { "msp430g2131",0,0 },
   1266  1.1.1.4  christos   { "msp430g2132",0,0 },
   1267  1.1.1.4  christos   { "msp430g2152",0,0 },
   1268  1.1.1.4  christos   { "msp430g2153",0,0 },
   1269  1.1.1.4  christos   { "msp430g2201",0,0 },
   1270  1.1.1.4  christos   { "msp430g2202",0,0 },
   1271  1.1.1.4  christos   { "msp430g2203",0,0 },
   1272  1.1.1.4  christos   { "msp430g2210",0,0 },
   1273  1.1.1.4  christos   { "msp430g2211",0,0 },
   1274  1.1.1.4  christos   { "msp430g2212",0,0 },
   1275  1.1.1.4  christos   { "msp430g2213",0,0 },
   1276  1.1.1.4  christos   { "msp430g2221",0,0 },
   1277  1.1.1.4  christos   { "msp430g2230",0,0 },
   1278  1.1.1.4  christos   { "msp430g2231",0,0 },
   1279  1.1.1.4  christos   { "msp430g2232",0,0 },
   1280  1.1.1.4  christos   { "msp430g2233",0,0 },
   1281  1.1.1.4  christos   { "msp430g2252",0,0 },
   1282  1.1.1.4  christos   { "msp430g2253",0,0 },
   1283  1.1.1.4  christos   { "msp430g2302",0,0 },
   1284  1.1.1.4  christos   { "msp430g2303",0,0 },
   1285  1.1.1.4  christos   { "msp430g2312",0,0 },
   1286  1.1.1.4  christos   { "msp430g2313",0,0 },
   1287  1.1.1.4  christos   { "msp430g2332",0,0 },
   1288  1.1.1.4  christos   { "msp430g2333",0,0 },
   1289  1.1.1.4  christos   { "msp430g2352",0,0 },
   1290  1.1.1.4  christos   { "msp430g2353",0,0 },
   1291  1.1.1.4  christos   { "msp430g2402",0,0 },
   1292  1.1.1.4  christos   { "msp430g2403",0,0 },
   1293  1.1.1.4  christos   { "msp430g2412",0,0 },
   1294  1.1.1.4  christos   { "msp430g2413",0,0 },
   1295  1.1.1.4  christos   { "msp430g2432",0,0 },
   1296  1.1.1.4  christos   { "msp430g2433",0,0 },
   1297  1.1.1.4  christos   { "msp430g2444",0,0 },
   1298  1.1.1.4  christos   { "msp430g2452",0,0 },
   1299  1.1.1.4  christos   { "msp430g2453",0,0 },
   1300  1.1.1.4  christos   { "msp430g2513",0,0 },
   1301  1.1.1.4  christos   { "msp430g2533",0,0 },
   1302  1.1.1.4  christos   { "msp430g2544",0,0 },
   1303  1.1.1.4  christos   { "msp430g2553",0,0 },
   1304  1.1.1.4  christos   { "msp430g2744",0,0 },
   1305  1.1.1.4  christos   { "msp430g2755",0,0 },
   1306  1.1.1.4  christos   { "msp430g2855",0,0 },
   1307  1.1.1.4  christos   { "msp430g2955",0,0 },
   1308  1.1.1.4  christos   { "msp430i2020",0,2 },
   1309  1.1.1.4  christos   { "msp430i2021",0,2 },
   1310  1.1.1.4  christos   { "msp430i2030",0,2 },
   1311  1.1.1.4  christos   { "msp430i2031",0,2 },
   1312  1.1.1.4  christos   { "msp430i2040",0,2 },
   1313  1.1.1.4  christos   { "msp430i2041",0,2 },
   1314  1.1.1.4  christos   { "msp430i2xxgeneric",0,2 },
   1315  1.1.1.4  christos   { "msp430l092",0,0 },
   1316  1.1.1.4  christos   { "msp430p112",0,0 },
   1317  1.1.1.4  christos   { "msp430p313",0,0 },
   1318  1.1.1.4  christos   { "msp430p315",0,0 },
   1319  1.1.1.4  christos   { "msp430p315s",0,0 },
   1320  1.1.1.4  christos   { "msp430p325",0,0 },
   1321  1.1.1.4  christos   { "msp430p337",0,1 },
   1322  1.1.1.4  christos   { "msp430sl5438a",2,8 },
   1323  1.1.1.4  christos   { "msp430tch5e",0,0 },
   1324  1.1.1.4  christos   { "msp430xgeneric",2,8 },
   1325  1.1.1.4  christos   { "rf430f5144",2,8 },
   1326  1.1.1.4  christos   { "rf430f5155",2,8 },
   1327  1.1.1.4  christos   { "rf430f5175",2,8 },
   1328  1.1.1.4  christos   { "rf430frl152h",0,0 },
   1329  1.1.1.4  christos   { "rf430frl152h_rom",0,0 },
   1330  1.1.1.4  christos   { "rf430frl153h",0,0 },
   1331  1.1.1.4  christos   { "rf430frl153h_rom",0,0 },
   1332  1.1.1.4  christos   { "rf430frl154h",0,0 },
   1333  1.1.1.4  christos   { "rf430frl154h_rom",0,0 }
   1334  1.1.1.4  christos };
   1335      1.1     skrll 
   1336      1.1     skrll int
   1337  1.1.1.5  christos md_parse_option (int c, const char * arg)
   1338      1.1     skrll {
   1339      1.1     skrll   switch (c)
   1340      1.1     skrll     {
   1341  1.1.1.4  christos     case OPTION_SILICON_ERRATA:
   1342  1.1.1.4  christos     case OPTION_SILICON_ERRATA_WARN:
   1343  1.1.1.4  christos       {
   1344  1.1.1.4  christos 	signed int i;
   1345  1.1.1.4  christos 	const struct
   1346  1.1.1.4  christos 	{
   1347  1.1.1.5  christos 	  const char *       name;
   1348  1.1.1.4  christos 	  unsigned int length;
   1349  1.1.1.4  christos 	  unsigned int bitfield;
   1350  1.1.1.4  christos 	} erratas[] =
   1351  1.1.1.4  christos 	{
   1352  1.1.1.4  christos 	  { STRING_COMMA_LEN ("cpu4"), SILICON_ERRATA_CPU4 },
   1353  1.1.1.4  christos 	  { STRING_COMMA_LEN ("cpu8"), SILICON_ERRATA_CPU8 },
   1354  1.1.1.4  christos 	  { STRING_COMMA_LEN ("cpu11"), SILICON_ERRATA_CPU11 },
   1355  1.1.1.4  christos 	  { STRING_COMMA_LEN ("cpu12"), SILICON_ERRATA_CPU12 },
   1356  1.1.1.4  christos 	  { STRING_COMMA_LEN ("cpu13"), SILICON_ERRATA_CPU13 },
   1357  1.1.1.4  christos 	  { STRING_COMMA_LEN ("cpu19"), SILICON_ERRATA_CPU19 },
   1358  1.1.1.4  christos 	};
   1359  1.1.1.4  christos 
   1360  1.1.1.4  christos 	do
   1361  1.1.1.4  christos 	  {
   1362  1.1.1.4  christos 	    for (i = ARRAY_SIZE (erratas); i--;)
   1363  1.1.1.4  christos 	      if (strncasecmp (arg, erratas[i].name, erratas[i].length) == 0)
   1364  1.1.1.4  christos 		{
   1365  1.1.1.4  christos 		  if (c == OPTION_SILICON_ERRATA)
   1366  1.1.1.4  christos 		    silicon_errata_fix |= erratas[i].bitfield;
   1367  1.1.1.4  christos 		  else
   1368  1.1.1.4  christos 		    silicon_errata_warn |= erratas[i].bitfield;
   1369  1.1.1.4  christos 		  arg += erratas[i].length;
   1370  1.1.1.4  christos 		  break;
   1371  1.1.1.4  christos 		}
   1372  1.1.1.4  christos 	    if (i < 0)
   1373  1.1.1.4  christos 	      {
   1374  1.1.1.4  christos 		as_warn (_("Unrecognised CPU errata name starting here: %s"), arg);
   1375  1.1.1.4  christos 		break;
   1376  1.1.1.4  christos 	      }
   1377  1.1.1.4  christos 	    if (*arg == 0)
   1378  1.1.1.4  christos 	      break;
   1379  1.1.1.4  christos 	    if (*arg != ',')
   1380  1.1.1.4  christos 	      as_warn (_("Expecting comma after CPU errata name, not: %s"), arg);
   1381  1.1.1.4  christos 	    else
   1382  1.1.1.4  christos 	      arg ++;
   1383  1.1.1.4  christos 	  }
   1384  1.1.1.4  christos 	while (*arg != 0);
   1385  1.1.1.4  christos       }
   1386  1.1.1.4  christos       return 1;
   1387  1.1.1.4  christos 
   1388      1.1     skrll     case OPTION_MMCU:
   1389  1.1.1.4  christos       if (arg == NULL)
   1390  1.1.1.4  christos 	as_fatal (_("MCU option requires a name\n"));
   1391      1.1     skrll 
   1392  1.1.1.4  christos       if (strcasecmp ("msp430", arg) == 0)
   1393  1.1.1.4  christos 	selected_isa = MSP_ISA_430;
   1394  1.1.1.4  christos       else if (strcasecmp ("msp430xv2", arg) == 0)
   1395  1.1.1.4  christos 	selected_isa = MSP_ISA_430Xv2;
   1396  1.1.1.4  christos       else if (strcasecmp ("msp430x", arg) == 0)
   1397  1.1.1.4  christos 	selected_isa = MSP_ISA_430X;
   1398  1.1.1.4  christos       else
   1399      1.1     skrll 	{
   1400  1.1.1.4  christos 	  int i;
   1401  1.1.1.4  christos 
   1402  1.1.1.4  christos 	  for (i = ARRAY_SIZE (msp430_mcu_data); i--;)
   1403  1.1.1.4  christos 	    if (strcasecmp (msp430_mcu_data[i].name, arg) == 0)
   1404  1.1.1.4  christos 	      {
   1405  1.1.1.4  christos 		switch (msp430_mcu_data[i].revision)
   1406  1.1.1.4  christos 		  {
   1407  1.1.1.4  christos 		  case 0: selected_isa = MSP_ISA_430; break;
   1408  1.1.1.4  christos 		  case 1: selected_isa = MSP_ISA_430X; break;
   1409  1.1.1.4  christos 		  case 2: selected_isa = MSP_ISA_430Xv2; break;
   1410  1.1.1.4  christos 		  }
   1411  1.1.1.4  christos 		break;
   1412  1.1.1.4  christos 	    }
   1413      1.1     skrll 	}
   1414  1.1.1.4  christos       /* It is not an error if we do not match the MCU name.  */
   1415  1.1.1.4  christos       return 1;
   1416      1.1     skrll 
   1417  1.1.1.4  christos     case OPTION_MCPU:
   1418  1.1.1.4  christos       if (strcmp (arg, "430") == 0
   1419  1.1.1.4  christos 	  || strcasecmp (arg, "msp430") == 0)
   1420  1.1.1.4  christos 	selected_isa = MSP_ISA_430;
   1421  1.1.1.4  christos       else if (strcasecmp (arg, "430x") == 0
   1422  1.1.1.4  christos 	       || strcasecmp (arg, "msp430x") == 0)
   1423  1.1.1.4  christos 	selected_isa = MSP_ISA_430X;
   1424  1.1.1.4  christos       else if (strcasecmp (arg, "430xv2") == 0
   1425  1.1.1.4  christos 	       || strcasecmp (arg, "msp430xv2") == 0)
   1426  1.1.1.4  christos 	selected_isa = MSP_ISA_430Xv2;
   1427      1.1     skrll       else
   1428  1.1.1.4  christos 	as_fatal (_("unrecognised argument to -mcpu option '%s'"), arg);
   1429      1.1     skrll       return 1;
   1430  1.1.1.4  christos 
   1431      1.1     skrll     case OPTION_RELAX:
   1432  1.1.1.4  christos       msp430_enable_relax = 1;
   1433      1.1     skrll       return 1;
   1434  1.1.1.4  christos 
   1435      1.1     skrll     case OPTION_POLYMORPHS:
   1436      1.1     skrll       msp430_enable_polys = 1;
   1437      1.1     skrll       return 1;
   1438  1.1.1.4  christos 
   1439  1.1.1.4  christos     case OPTION_LARGE:
   1440  1.1.1.4  christos       large_model = TRUE;
   1441  1.1.1.4  christos       return 1;
   1442  1.1.1.4  christos 
   1443  1.1.1.4  christos     case OPTION_NO_INTR_NOPS:
   1444  1.1.1.4  christos       gen_interrupt_nops = FALSE;
   1445  1.1.1.4  christos       return 1;
   1446  1.1.1.4  christos     case OPTION_INTR_NOPS:
   1447  1.1.1.4  christos       gen_interrupt_nops = TRUE;
   1448  1.1.1.4  christos       return 1;
   1449  1.1.1.4  christos 
   1450  1.1.1.4  christos     case OPTION_WARN_INTR_NOPS:
   1451  1.1.1.4  christos       warn_interrupt_nops = TRUE;
   1452  1.1.1.4  christos       return 1;
   1453  1.1.1.4  christos     case OPTION_NO_WARN_INTR_NOPS:
   1454  1.1.1.4  christos       warn_interrupt_nops = FALSE;
   1455  1.1.1.4  christos       return 1;
   1456  1.1.1.4  christos 
   1457  1.1.1.4  christos     case OPTION_MOVE_DATA:
   1458  1.1.1.4  christos       move_data = TRUE;
   1459  1.1.1.4  christos       return 1;
   1460  1.1.1.6  christos 
   1461  1.1.1.6  christos     case OPTION_DATA_REGION:
   1462  1.1.1.6  christos       if (strcmp (arg, "upper") == 0
   1463  1.1.1.6  christos 	  || strcmp (arg, "either") == 0)
   1464  1.1.1.6  christos 	upper_data_region_in_use = TRUE;
   1465  1.1.1.6  christos       return 1;
   1466      1.1     skrll     }
   1467      1.1     skrll 
   1468      1.1     skrll   return 0;
   1469      1.1     skrll }
   1470      1.1     skrll 
   1471  1.1.1.4  christos /* The intention here is to have the mere presence of these sections
   1472  1.1.1.4  christos    cause the object to have a reference to a well-known symbol.  This
   1473  1.1.1.4  christos    reference pulls in the bits of the runtime (crt0) that initialize
   1474  1.1.1.4  christos    these sections.  Thus, for example, the startup code to call
   1475  1.1.1.4  christos    memset() to initialize .bss will only be linked in when there is a
   1476  1.1.1.4  christos    non-empty .bss section.  Otherwise, the call would exist but have a
   1477  1.1.1.4  christos    zero length parameter, which is a waste of memory and cycles.
   1478  1.1.1.4  christos 
   1479  1.1.1.4  christos    The code which initializes these sections should have a global
   1480  1.1.1.4  christos    label for these symbols, and should be marked with KEEP() in the
   1481  1.1.1.4  christos    linker script.  */
   1482  1.1.1.4  christos 
   1483  1.1.1.4  christos static void
   1484  1.1.1.4  christos msp430_make_init_symbols (const char * name)
   1485  1.1.1.4  christos {
   1486  1.1.1.4  christos   if (strncmp (name, ".bss", 4) == 0
   1487  1.1.1.4  christos       || strncmp (name, ".gnu.linkonce.b.", 16) == 0)
   1488  1.1.1.4  christos     (void) symbol_find_or_make ("__crt0_init_bss");
   1489  1.1.1.4  christos 
   1490  1.1.1.4  christos   if (strncmp (name, ".data", 5) == 0
   1491  1.1.1.4  christos       || strncmp (name, ".gnu.linkonce.d.", 16) == 0)
   1492  1.1.1.4  christos     (void) symbol_find_or_make ("__crt0_movedata");
   1493  1.1.1.4  christos 
   1494  1.1.1.4  christos   /* Note - data assigned to the .either.data section may end up being
   1495  1.1.1.4  christos      placed in the .upper.data section if the .lower.data section is
   1496  1.1.1.6  christos      full.  Hence the need to define the crt0 symbol.
   1497  1.1.1.6  christos      The linker may create upper or either data sections, even when none exist
   1498  1.1.1.6  christos      at the moment, so use the value of the data-region flag to determine if
   1499  1.1.1.6  christos      the symbol is needed.  */
   1500  1.1.1.4  christos   if (strncmp (name, ".either.data", 12) == 0
   1501  1.1.1.6  christos       || strncmp (name, ".upper.data", 11) == 0
   1502  1.1.1.6  christos       || upper_data_region_in_use)
   1503  1.1.1.4  christos     (void) symbol_find_or_make ("__crt0_move_highdata");
   1504  1.1.1.4  christos 
   1505  1.1.1.4  christos   /* See note about .either.data above.  */
   1506  1.1.1.4  christos   if (strncmp (name, ".upper.bss", 10) == 0
   1507  1.1.1.6  christos       || strncmp (name, ".either.bss", 11) == 0
   1508  1.1.1.6  christos       || upper_data_region_in_use)
   1509  1.1.1.4  christos     (void) symbol_find_or_make ("__crt0_init_highbss");
   1510  1.1.1.4  christos }
   1511  1.1.1.4  christos 
   1512  1.1.1.4  christos static void
   1513  1.1.1.4  christos msp430_section (int arg)
   1514  1.1.1.4  christos {
   1515  1.1.1.4  christos   char * saved_ilp = input_line_pointer;
   1516  1.1.1.5  christos   const char * name = obj_elf_section_name ();
   1517  1.1.1.4  christos 
   1518  1.1.1.4  christos   msp430_make_init_symbols (name);
   1519  1.1.1.4  christos 
   1520  1.1.1.4  christos   input_line_pointer = saved_ilp;
   1521  1.1.1.4  christos   obj_elf_section (arg);
   1522  1.1.1.4  christos }
   1523  1.1.1.4  christos 
   1524  1.1.1.4  christos void
   1525  1.1.1.4  christos msp430_frob_section (asection *sec)
   1526  1.1.1.4  christos {
   1527  1.1.1.4  christos   const char *name = sec->name;
   1528  1.1.1.4  christos 
   1529  1.1.1.4  christos   if (sec->size == 0)
   1530  1.1.1.4  christos     return;
   1531  1.1.1.4  christos 
   1532  1.1.1.4  christos   msp430_make_init_symbols (name);
   1533  1.1.1.4  christos }
   1534  1.1.1.4  christos 
   1535  1.1.1.4  christos static void
   1536  1.1.1.4  christos msp430_lcomm (int ignore ATTRIBUTE_UNUSED)
   1537  1.1.1.4  christos {
   1538  1.1.1.4  christos   symbolS *symbolP = s_comm_internal (0, s_lcomm_internal);
   1539  1.1.1.4  christos 
   1540  1.1.1.4  christos   if (symbolP)
   1541  1.1.1.4  christos     symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
   1542  1.1.1.4  christos   (void) symbol_find_or_make ("__crt0_init_bss");
   1543  1.1.1.4  christos }
   1544  1.1.1.4  christos 
   1545  1.1.1.4  christos static void
   1546  1.1.1.4  christos msp430_comm (int needs_align)
   1547  1.1.1.4  christos {
   1548  1.1.1.4  christos   s_comm_internal (needs_align, elf_common_parse);
   1549  1.1.1.4  christos   (void) symbol_find_or_make ("__crt0_init_bss");
   1550  1.1.1.4  christos }
   1551  1.1.1.4  christos 
   1552  1.1.1.4  christos static void
   1553  1.1.1.4  christos msp430_refsym (int arg ATTRIBUTE_UNUSED)
   1554  1.1.1.4  christos {
   1555  1.1.1.4  christos   char sym_name[1024];
   1556  1.1.1.4  christos   input_line_pointer = extract_word (input_line_pointer, sym_name, 1024);
   1557  1.1.1.4  christos 
   1558  1.1.1.4  christos   (void) symbol_find_or_make (sym_name);
   1559  1.1.1.4  christos }
   1560      1.1     skrll 
   1561      1.1     skrll const pseudo_typeS md_pseudo_table[] =
   1562      1.1     skrll {
   1563  1.1.1.4  christos   {"arch", msp430_set_arch, OPTION_MMCU},
   1564  1.1.1.4  christos   {"cpu", msp430_set_arch, OPTION_MCPU},
   1565      1.1     skrll   {"profiler", msp430_profiler, 0},
   1566  1.1.1.4  christos   {"section", msp430_section, 0},
   1567  1.1.1.4  christos   {"section.s", msp430_section, 0},
   1568  1.1.1.4  christos   {"sect", msp430_section, 0},
   1569  1.1.1.4  christos   {"sect.s", msp430_section, 0},
   1570  1.1.1.4  christos   {"pushsection", msp430_section, 1},
   1571  1.1.1.4  christos   {"refsym", msp430_refsym, 0},
   1572  1.1.1.4  christos   {"comm", msp430_comm, 0},
   1573  1.1.1.4  christos   {"lcomm", msp430_lcomm, 0},
   1574      1.1     skrll   {NULL, NULL, 0}
   1575      1.1     skrll };
   1576      1.1     skrll 
   1577  1.1.1.4  christos const char *md_shortopts = "mm:,mP,mQ,ml,mN,mn,my,mY";
   1578      1.1     skrll 
   1579      1.1     skrll struct option md_longopts[] =
   1580      1.1     skrll {
   1581  1.1.1.4  christos   {"msilicon-errata", required_argument, NULL, OPTION_SILICON_ERRATA},
   1582  1.1.1.4  christos   {"msilicon-errata-warn", required_argument, NULL, OPTION_SILICON_ERRATA_WARN},
   1583      1.1     skrll   {"mmcu", required_argument, NULL, OPTION_MMCU},
   1584  1.1.1.4  christos   {"mcpu", required_argument, NULL, OPTION_MCPU},
   1585      1.1     skrll   {"mP", no_argument, NULL, OPTION_POLYMORPHS},
   1586      1.1     skrll   {"mQ", no_argument, NULL, OPTION_RELAX},
   1587  1.1.1.4  christos   {"ml", no_argument, NULL, OPTION_LARGE},
   1588  1.1.1.4  christos   {"mN", no_argument, NULL, OPTION_NO_INTR_NOPS},
   1589  1.1.1.4  christos   {"mn", no_argument, NULL, OPTION_INTR_NOPS},
   1590  1.1.1.4  christos   {"mY", no_argument, NULL, OPTION_NO_WARN_INTR_NOPS},
   1591  1.1.1.4  christos   {"my", no_argument, NULL, OPTION_WARN_INTR_NOPS},
   1592  1.1.1.4  christos   {"md", no_argument, NULL, OPTION_MOVE_DATA},
   1593  1.1.1.6  christos   {"mdata-region", required_argument, NULL, OPTION_DATA_REGION},
   1594      1.1     skrll   {NULL, no_argument, NULL, 0}
   1595      1.1     skrll };
   1596      1.1     skrll 
   1597      1.1     skrll size_t md_longopts_size = sizeof (md_longopts);
   1598      1.1     skrll 
   1599      1.1     skrll void
   1600      1.1     skrll md_show_usage (FILE * stream)
   1601      1.1     skrll {
   1602      1.1     skrll   fprintf (stream,
   1603      1.1     skrll 	   _("MSP430 options:\n"
   1604  1.1.1.4  christos 	     "  -mmcu=<msp430-name>     - select microcontroller type\n"
   1605  1.1.1.4  christos              "  -mcpu={430|430x|430xv2} - select microcontroller architecture\n"));
   1606  1.1.1.4  christos   fprintf (stream,
   1607  1.1.1.4  christos 	   _("  -msilicon-errata=<name>[,<name>...] - enable fixups for silicon errata\n"
   1608  1.1.1.4  christos 	     "  -msilicon-errata-warn=<name>[,<name>...] - warn when a fixup might be needed\n"
   1609  1.1.1.4  christos 	     "   supported errata names: cpu4, cpu8, cpu11, cpu12, cpu13, cpu19\n"));
   1610      1.1     skrll   fprintf (stream,
   1611      1.1     skrll 	   _("  -mQ - enable relaxation at assembly time. DANGEROUS!\n"
   1612      1.1     skrll 	     "  -mP - enable polymorph instructions\n"));
   1613  1.1.1.4  christos   fprintf (stream,
   1614  1.1.1.4  christos 	   _("  -ml - enable large code model\n"));
   1615  1.1.1.4  christos   fprintf (stream,
   1616  1.1.1.4  christos 	   _("  -mN - do not insert NOPs after changing interrupts (default)\n"));
   1617  1.1.1.4  christos   fprintf (stream,
   1618  1.1.1.4  christos 	   _("  -mn - insert a NOP after changing interrupts\n"));
   1619  1.1.1.4  christos   fprintf (stream,
   1620  1.1.1.4  christos 	   _("  -mY - do not warn about missing NOPs after changing interrupts\n"));
   1621  1.1.1.4  christos   fprintf (stream,
   1622  1.1.1.4  christos 	   _("  -my - warn about missing NOPs after changing interrupts (default)\n"));
   1623  1.1.1.4  christos   fprintf (stream,
   1624  1.1.1.4  christos 	   _("  -md - Force copying of data from ROM to RAM at startup\n"));
   1625  1.1.1.6  christos   fprintf (stream,
   1626  1.1.1.6  christos 	   _("  -mdata-region={none|lower|upper|either} - select region data will be\n"
   1627  1.1.1.6  christos 	     "    placed in.\n"));
   1628      1.1     skrll }
   1629      1.1     skrll 
   1630      1.1     skrll symbolS *
   1631      1.1     skrll md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
   1632      1.1     skrll {
   1633  1.1.1.4  christos   return NULL;
   1634      1.1     skrll }
   1635      1.1     skrll 
   1636      1.1     skrll static char *
   1637      1.1     skrll extract_cmd (char * from, char * to, int limit)
   1638      1.1     skrll {
   1639      1.1     skrll   int size = 0;
   1640      1.1     skrll 
   1641      1.1     skrll   while (*from && ! ISSPACE (*from) && *from != '.' && limit > size)
   1642      1.1     skrll     {
   1643      1.1     skrll       *(to + size) = *from;
   1644      1.1     skrll       from++;
   1645      1.1     skrll       size++;
   1646      1.1     skrll     }
   1647      1.1     skrll 
   1648      1.1     skrll   *(to + size) = 0;
   1649      1.1     skrll 
   1650      1.1     skrll   return from;
   1651      1.1     skrll }
   1652      1.1     skrll 
   1653  1.1.1.5  christos const char *
   1654      1.1     skrll md_atof (int type, char * litP, int * sizeP)
   1655      1.1     skrll {
   1656      1.1     skrll   return ieee_md_atof (type, litP, sizeP, FALSE);
   1657      1.1     skrll }
   1658      1.1     skrll 
   1659      1.1     skrll void
   1660      1.1     skrll md_begin (void)
   1661      1.1     skrll {
   1662      1.1     skrll   struct msp430_opcode_s * opcode;
   1663      1.1     skrll   msp430_hash = hash_new ();
   1664      1.1     skrll 
   1665      1.1     skrll   for (opcode = msp430_opcodes; opcode->name; opcode++)
   1666      1.1     skrll     hash_insert (msp430_hash, opcode->name, (char *) opcode);
   1667      1.1     skrll 
   1668  1.1.1.4  christos   bfd_set_arch_mach (stdoutput, TARGET_ARCH,
   1669  1.1.1.4  christos 		     target_is_430x () ? bfd_mach_msp430x : bfd_mach_msp11);
   1670  1.1.1.5  christos 
   1671  1.1.1.5  christos   /*  Set linkrelax here to avoid fixups in most sections.  */
   1672  1.1.1.5  christos   linkrelax = 1;
   1673      1.1     skrll }
   1674      1.1     skrll 
   1675  1.1.1.4  christos /* Returns the register number equivalent to the string T.
   1676  1.1.1.4  christos    Returns -1 if there is no such register.
   1677  1.1.1.4  christos    Skips a leading 'r' or 'R' character if there is one.
   1678  1.1.1.4  christos    Handles the register aliases PC and SP.  */
   1679  1.1.1.4  christos 
   1680  1.1.1.4  christos static signed int
   1681      1.1     skrll check_reg (char * t)
   1682      1.1     skrll {
   1683  1.1.1.4  christos   signed int val;
   1684      1.1     skrll 
   1685  1.1.1.4  christos   if (t == NULL)
   1686  1.1.1.4  christos     return -1;
   1687      1.1     skrll 
   1688  1.1.1.4  christos   if (*t == 'r' || *t == 'R')
   1689  1.1.1.4  christos     ++t;
   1690  1.1.1.4  christos 
   1691  1.1.1.4  christos   if (strncasecmp (t, "pc", 2) == 0)
   1692  1.1.1.4  christos     return 0;
   1693      1.1     skrll 
   1694  1.1.1.4  christos   if (strncasecmp (t, "sp", 2) == 0)
   1695      1.1     skrll     return 1;
   1696      1.1     skrll 
   1697  1.1.1.4  christos   if (strncasecmp (t, "sr", 2) == 0)
   1698  1.1.1.4  christos     return 2;
   1699  1.1.1.4  christos 
   1700  1.1.1.4  christos   if (*t == '0')
   1701  1.1.1.4  christos     return 0;
   1702  1.1.1.4  christos 
   1703  1.1.1.4  christos   val = atoi (t);
   1704      1.1     skrll 
   1705  1.1.1.4  christos   if (val < 1 || val > 15)
   1706  1.1.1.4  christos     return -1;
   1707  1.1.1.4  christos 
   1708  1.1.1.4  christos   return val;
   1709  1.1.1.4  christos }
   1710      1.1     skrll 
   1711      1.1     skrll static int
   1712      1.1     skrll msp430_srcoperand (struct msp430_operand_s * op,
   1713  1.1.1.4  christos 		   char * l,
   1714  1.1.1.4  christos 		   int bin,
   1715  1.1.1.4  christos 		   bfd_boolean * imm_op,
   1716  1.1.1.4  christos 		   bfd_boolean allow_20bit_values,
   1717  1.1.1.4  christos 		   bfd_boolean constants_allowed)
   1718      1.1     skrll {
   1719  1.1.1.6  christos   char * end;
   1720      1.1     skrll   char *__tl = l;
   1721      1.1     skrll 
   1722      1.1     skrll   /* Check if an immediate #VALUE.  The hash sign should be only at the beginning!  */
   1723      1.1     skrll   if (*l == '#')
   1724      1.1     skrll     {
   1725      1.1     skrll       char *h = l;
   1726      1.1     skrll       int vshift = -1;
   1727      1.1     skrll       int rval = 0;
   1728      1.1     skrll 
   1729      1.1     skrll       /* Check if there is:
   1730      1.1     skrll 	 llo(x) - least significant 16 bits, x &= 0xffff
   1731      1.1     skrll 	 lhi(x) - x = (x >> 16) & 0xffff,
   1732      1.1     skrll 	 hlo(x) - x = (x >> 32) & 0xffff,
   1733      1.1     skrll 	 hhi(x) - x = (x >> 48) & 0xffff
   1734      1.1     skrll 	 The value _MUST_ be constant expression: #hlo(1231231231).  */
   1735      1.1     skrll 
   1736  1.1.1.4  christos       *imm_op = TRUE;
   1737      1.1     skrll 
   1738      1.1     skrll       if (strncasecmp (h, "#llo(", 5) == 0)
   1739      1.1     skrll 	{
   1740      1.1     skrll 	  vshift = 0;
   1741      1.1     skrll 	  rval = 3;
   1742      1.1     skrll 	}
   1743      1.1     skrll       else if (strncasecmp (h, "#lhi(", 5) == 0)
   1744      1.1     skrll 	{
   1745      1.1     skrll 	  vshift = 1;
   1746      1.1     skrll 	  rval = 3;
   1747      1.1     skrll 	}
   1748      1.1     skrll       else if (strncasecmp (h, "#hlo(", 5) == 0)
   1749      1.1     skrll 	{
   1750      1.1     skrll 	  vshift = 2;
   1751      1.1     skrll 	  rval = 3;
   1752      1.1     skrll 	}
   1753      1.1     skrll       else if (strncasecmp (h, "#hhi(", 5) == 0)
   1754      1.1     skrll 	{
   1755      1.1     skrll 	  vshift = 3;
   1756      1.1     skrll 	  rval = 3;
   1757      1.1     skrll 	}
   1758      1.1     skrll       else if (strncasecmp (h, "#lo(", 4) == 0)
   1759      1.1     skrll 	{
   1760      1.1     skrll 	  vshift = 0;
   1761      1.1     skrll 	  rval = 2;
   1762      1.1     skrll 	}
   1763      1.1     skrll       else if (strncasecmp (h, "#hi(", 4) == 0)
   1764      1.1     skrll 	{
   1765      1.1     skrll 	  vshift = 1;
   1766      1.1     skrll 	  rval = 2;
   1767      1.1     skrll 	}
   1768      1.1     skrll 
   1769      1.1     skrll       op->reg = 0;		/* Reg PC.  */
   1770      1.1     skrll       op->am = 3;
   1771  1.1.1.4  christos       op->ol = 1;		/* Immediate will follow an instruction.  */
   1772      1.1     skrll       __tl = h + 1 + rval;
   1773      1.1     skrll       op->mode = OP_EXP;
   1774  1.1.1.4  christos       op->vshift = vshift;
   1775      1.1     skrll 
   1776  1.1.1.6  christos       end = parse_exp (__tl, &(op->exp));
   1777  1.1.1.6  christos       if (end != NULL && *end != 0 && *end != ')' )
   1778  1.1.1.6  christos 	{
   1779  1.1.1.6  christos 	  as_bad (_("extra characters '%s' at end of immediate expression '%s'"), end, l);
   1780  1.1.1.6  christos 	  return 1;
   1781  1.1.1.6  christos 	}
   1782      1.1     skrll       if (op->exp.X_op == O_constant)
   1783      1.1     skrll 	{
   1784      1.1     skrll 	  int x = op->exp.X_add_number;
   1785      1.1     skrll 
   1786      1.1     skrll 	  if (vshift == 0)
   1787      1.1     skrll 	    {
   1788      1.1     skrll 	      x = x & 0xffff;
   1789      1.1     skrll 	      op->exp.X_add_number = x;
   1790      1.1     skrll 	    }
   1791      1.1     skrll 	  else if (vshift == 1)
   1792      1.1     skrll 	    {
   1793      1.1     skrll 	      x = (x >> 16) & 0xffff;
   1794      1.1     skrll 	      op->exp.X_add_number = x;
   1795  1.1.1.4  christos 	      op->vshift = 0;
   1796      1.1     skrll 	    }
   1797      1.1     skrll 	  else if (vshift > 1)
   1798      1.1     skrll 	    {
   1799      1.1     skrll 	      if (x < 0)
   1800      1.1     skrll 		op->exp.X_add_number = -1;
   1801      1.1     skrll 	      else
   1802      1.1     skrll 		op->exp.X_add_number = 0;	/* Nothing left.  */
   1803      1.1     skrll 	      x = op->exp.X_add_number;
   1804  1.1.1.4  christos 	      op->vshift = 0;
   1805      1.1     skrll 	    }
   1806      1.1     skrll 
   1807  1.1.1.4  christos 	  if (allow_20bit_values)
   1808  1.1.1.4  christos 	    {
   1809  1.1.1.4  christos 	      if (op->exp.X_add_number > 0xfffff || op->exp.X_add_number < -524288)
   1810  1.1.1.4  christos 		{
   1811  1.1.1.4  christos 		  as_bad (_("value 0x%x out of extended range."), x);
   1812  1.1.1.4  christos 		  return 1;
   1813  1.1.1.4  christos 		}
   1814  1.1.1.4  christos 	    }
   1815  1.1.1.4  christos 	  else if (op->exp.X_add_number > 65535 || op->exp.X_add_number < -32768)
   1816      1.1     skrll 	    {
   1817      1.1     skrll 	      as_bad (_("value %d out of range. Use #lo() or #hi()"), x);
   1818      1.1     skrll 	      return 1;
   1819      1.1     skrll 	    }
   1820      1.1     skrll 
   1821      1.1     skrll 	  /* Now check constants.  */
   1822      1.1     skrll 	  /* Substitute register mode with a constant generator if applicable.  */
   1823      1.1     skrll 
   1824  1.1.1.4  christos 	  if (!allow_20bit_values)
   1825  1.1.1.4  christos 	    x = (short) x;	/* Extend sign.  */
   1826      1.1     skrll 
   1827  1.1.1.4  christos 	  if (! constants_allowed)
   1828  1.1.1.4  christos 	    ;
   1829  1.1.1.4  christos 	  else if (x == 0)
   1830      1.1     skrll 	    {
   1831      1.1     skrll 	      op->reg = 3;
   1832      1.1     skrll 	      op->am = 0;
   1833      1.1     skrll 	      op->ol = 0;
   1834      1.1     skrll 	      op->mode = OP_REG;
   1835      1.1     skrll 	    }
   1836      1.1     skrll 	  else if (x == 1)
   1837      1.1     skrll 	    {
   1838      1.1     skrll 	      op->reg = 3;
   1839      1.1     skrll 	      op->am = 1;
   1840      1.1     skrll 	      op->ol = 0;
   1841      1.1     skrll 	      op->mode = OP_REG;
   1842      1.1     skrll 	    }
   1843      1.1     skrll 	  else if (x == 2)
   1844      1.1     skrll 	    {
   1845      1.1     skrll 	      op->reg = 3;
   1846      1.1     skrll 	      op->am = 2;
   1847      1.1     skrll 	      op->ol = 0;
   1848      1.1     skrll 	      op->mode = OP_REG;
   1849      1.1     skrll 	    }
   1850      1.1     skrll 	  else if (x == -1)
   1851      1.1     skrll 	    {
   1852      1.1     skrll 	      op->reg = 3;
   1853      1.1     skrll 	      op->am = 3;
   1854      1.1     skrll 	      op->ol = 0;
   1855      1.1     skrll 	      op->mode = OP_REG;
   1856      1.1     skrll 	    }
   1857      1.1     skrll 	  else if (x == 4)
   1858      1.1     skrll 	    {
   1859  1.1.1.4  christos 	      if (bin == 0x1200 && ! target_is_430x ())
   1860      1.1     skrll 		{
   1861  1.1.1.4  christos 		  /* CPU4: The shorter form of PUSH #4 is not supported on MSP430.  */
   1862  1.1.1.4  christos 		  if (silicon_errata_warn & SILICON_ERRATA_CPU4)
   1863  1.1.1.4  christos 		    as_warn (_("cpu4: not converting PUSH #4 to shorter form"));
   1864  1.1.1.4  christos 		  /* No need to check silicon_errata_fixes - this fix is always implemented.  */
   1865      1.1     skrll 		}
   1866      1.1     skrll 	      else
   1867      1.1     skrll 		{
   1868      1.1     skrll 		  op->reg = 2;
   1869      1.1     skrll 		  op->am = 2;
   1870      1.1     skrll 		  op->ol = 0;
   1871      1.1     skrll 		  op->mode = OP_REG;
   1872      1.1     skrll 		}
   1873      1.1     skrll 	    }
   1874      1.1     skrll 	  else if (x == 8)
   1875      1.1     skrll 	    {
   1876  1.1.1.4  christos 	      if (bin == 0x1200 && ! target_is_430x ())
   1877      1.1     skrll 		{
   1878  1.1.1.4  christos 		  /* CPU4: The shorter form of PUSH #8 is not supported on MSP430.  */
   1879  1.1.1.4  christos 		  if (silicon_errata_warn & SILICON_ERRATA_CPU4)
   1880  1.1.1.4  christos 		    as_warn (_("cpu4: not converting PUSH #8 to shorter form"));
   1881      1.1     skrll 		}
   1882      1.1     skrll 	      else
   1883      1.1     skrll 		{
   1884      1.1     skrll 		  op->reg = 2;
   1885      1.1     skrll 		  op->am = 3;
   1886      1.1     skrll 		  op->ol = 0;
   1887      1.1     skrll 		  op->mode = OP_REG;
   1888      1.1     skrll 		}
   1889      1.1     skrll 	    }
   1890      1.1     skrll 	}
   1891      1.1     skrll       else if (op->exp.X_op == O_symbol)
   1892      1.1     skrll 	{
   1893  1.1.1.4  christos 	  if (vshift > 1)
   1894  1.1.1.4  christos 	    as_bad (_("error: unsupported #foo() directive used on symbol"));
   1895      1.1     skrll 	  op->mode = OP_EXP;
   1896      1.1     skrll 	}
   1897      1.1     skrll       else if (op->exp.X_op == O_big)
   1898      1.1     skrll 	{
   1899      1.1     skrll 	  short x;
   1900  1.1.1.4  christos 
   1901      1.1     skrll 	  if (vshift != -1)
   1902      1.1     skrll 	    {
   1903      1.1     skrll 	      op->exp.X_op = O_constant;
   1904      1.1     skrll 	      op->exp.X_add_number = 0xffff & generic_bignum[vshift];
   1905      1.1     skrll 	      x = op->exp.X_add_number;
   1906  1.1.1.4  christos 	      op->vshift = 0;
   1907      1.1     skrll 	    }
   1908      1.1     skrll 	  else
   1909      1.1     skrll 	    {
   1910      1.1     skrll 	      as_bad (_
   1911  1.1.1.6  christos 		      ("unknown expression in operand %s.  Use #llo(), #lhi(), #hlo() or #hhi()"),
   1912      1.1     skrll 		      l);
   1913      1.1     skrll 	      return 1;
   1914      1.1     skrll 	    }
   1915      1.1     skrll 
   1916      1.1     skrll 	  if (x == 0)
   1917      1.1     skrll 	    {
   1918      1.1     skrll 	      op->reg = 3;
   1919      1.1     skrll 	      op->am = 0;
   1920      1.1     skrll 	      op->ol = 0;
   1921      1.1     skrll 	      op->mode = OP_REG;
   1922      1.1     skrll 	    }
   1923      1.1     skrll 	  else if (x == 1)
   1924      1.1     skrll 	    {
   1925      1.1     skrll 	      op->reg = 3;
   1926      1.1     skrll 	      op->am = 1;
   1927      1.1     skrll 	      op->ol = 0;
   1928      1.1     skrll 	      op->mode = OP_REG;
   1929      1.1     skrll 	    }
   1930      1.1     skrll 	  else if (x == 2)
   1931      1.1     skrll 	    {
   1932      1.1     skrll 	      op->reg = 3;
   1933      1.1     skrll 	      op->am = 2;
   1934      1.1     skrll 	      op->ol = 0;
   1935      1.1     skrll 	      op->mode = OP_REG;
   1936      1.1     skrll 	    }
   1937      1.1     skrll 	  else if (x == -1)
   1938      1.1     skrll 	    {
   1939      1.1     skrll 	      op->reg = 3;
   1940      1.1     skrll 	      op->am = 3;
   1941      1.1     skrll 	      op->ol = 0;
   1942      1.1     skrll 	      op->mode = OP_REG;
   1943      1.1     skrll 	    }
   1944      1.1     skrll 	  else if (x == 4)
   1945      1.1     skrll 	    {
   1946      1.1     skrll 	      op->reg = 2;
   1947      1.1     skrll 	      op->am = 2;
   1948      1.1     skrll 	      op->ol = 0;
   1949      1.1     skrll 	      op->mode = OP_REG;
   1950      1.1     skrll 	    }
   1951      1.1     skrll 	  else if (x == 8)
   1952      1.1     skrll 	    {
   1953      1.1     skrll 	      op->reg = 2;
   1954      1.1     skrll 	      op->am = 3;
   1955      1.1     skrll 	      op->ol = 0;
   1956      1.1     skrll 	      op->mode = OP_REG;
   1957      1.1     skrll 	    }
   1958      1.1     skrll 	}
   1959      1.1     skrll       /* Redundant (yet) check.  */
   1960      1.1     skrll       else if (op->exp.X_op == O_register)
   1961      1.1     skrll 	as_bad
   1962      1.1     skrll 	  (_("Registers cannot be used within immediate expression [%s]"), l);
   1963      1.1     skrll       else
   1964      1.1     skrll 	as_bad (_("unknown operand %s"), l);
   1965      1.1     skrll 
   1966      1.1     skrll       return 0;
   1967      1.1     skrll     }
   1968      1.1     skrll 
   1969      1.1     skrll   /* Check if absolute &VALUE (assume that we can construct something like ((a&b)<<7 + 25).  */
   1970      1.1     skrll   if (*l == '&')
   1971      1.1     skrll     {
   1972      1.1     skrll       char *h = l;
   1973      1.1     skrll 
   1974      1.1     skrll       op->reg = 2;		/* reg 2 in absolute addr mode.  */
   1975      1.1     skrll       op->am = 1;		/* mode As == 01 bin.  */
   1976      1.1     skrll       op->ol = 1;		/* Immediate value followed by instruction.  */
   1977      1.1     skrll       __tl = h + 1;
   1978  1.1.1.6  christos       end = parse_exp (__tl, &(op->exp));
   1979  1.1.1.6  christos       if (end != NULL && *end != 0)
   1980  1.1.1.6  christos 	{
   1981  1.1.1.6  christos 	  as_bad (_("extra characters '%s' at the end of absolute operand '%s'"), end, l);
   1982  1.1.1.6  christos 	  return 1;
   1983  1.1.1.6  christos 	}
   1984      1.1     skrll       op->mode = OP_EXP;
   1985  1.1.1.4  christos       op->vshift = 0;
   1986      1.1     skrll       if (op->exp.X_op == O_constant)
   1987      1.1     skrll 	{
   1988      1.1     skrll 	  int x = op->exp.X_add_number;
   1989      1.1     skrll 
   1990  1.1.1.4  christos 	  if (allow_20bit_values)
   1991      1.1     skrll 	    {
   1992  1.1.1.4  christos 	      if (x > 0xfffff || x < -(0x7ffff))
   1993  1.1.1.4  christos 		{
   1994  1.1.1.4  christos 		  as_bad (_("value 0x%x out of extended range."), x);
   1995  1.1.1.4  christos 		  return 1;
   1996  1.1.1.4  christos 		}
   1997  1.1.1.4  christos 	    }
   1998  1.1.1.4  christos 	  else if (x > 65535 || x < -32768)
   1999  1.1.1.4  christos 	    {
   2000  1.1.1.4  christos 	      as_bad (_("value out of range: 0x%x"), x);
   2001      1.1     skrll 	      return 1;
   2002      1.1     skrll 	    }
   2003      1.1     skrll 	}
   2004      1.1     skrll       else if (op->exp.X_op == O_symbol)
   2005      1.1     skrll 	;
   2006      1.1     skrll       else
   2007      1.1     skrll 	{
   2008      1.1     skrll 	  /* Redundant (yet) check.  */
   2009      1.1     skrll 	  if (op->exp.X_op == O_register)
   2010      1.1     skrll 	    as_bad
   2011      1.1     skrll 	      (_("Registers cannot be used within absolute expression [%s]"), l);
   2012      1.1     skrll 	  else
   2013      1.1     skrll 	    as_bad (_("unknown expression in operand %s"), l);
   2014      1.1     skrll 	  return 1;
   2015      1.1     skrll 	}
   2016      1.1     skrll       return 0;
   2017      1.1     skrll     }
   2018      1.1     skrll 
   2019      1.1     skrll   /* Check if indirect register mode @Rn / postincrement @Rn+.  */
   2020      1.1     skrll   if (*l == '@')
   2021      1.1     skrll     {
   2022      1.1     skrll       char *t = l;
   2023      1.1     skrll       char *m = strchr (l, '+');
   2024      1.1     skrll 
   2025      1.1     skrll       if (t != l)
   2026      1.1     skrll 	{
   2027      1.1     skrll 	  as_bad (_("unknown addressing mode %s"), l);
   2028      1.1     skrll 	  return 1;
   2029      1.1     skrll 	}
   2030      1.1     skrll 
   2031      1.1     skrll       t++;
   2032      1.1     skrll 
   2033  1.1.1.4  christos       if ((op->reg = check_reg (t)) == -1)
   2034      1.1     skrll 	{
   2035  1.1.1.4  christos 	  as_bad (_("Bad register name %s"), t);
   2036      1.1     skrll 	  return 1;
   2037      1.1     skrll 	}
   2038      1.1     skrll 
   2039      1.1     skrll       op->mode = OP_REG;
   2040      1.1     skrll       op->am = m ? 3 : 2;
   2041      1.1     skrll       op->ol = 0;
   2042  1.1.1.4  christos 
   2043  1.1.1.4  christos       /* PC cannot be used in indirect addressing.  */
   2044  1.1.1.4  christos       if (target_is_430xv2 () && op->reg == 0)
   2045      1.1     skrll 	{
   2046  1.1.1.4  christos 	  as_bad (_("cannot use indirect addressing with the PC"));
   2047      1.1     skrll 	  return 1;
   2048      1.1     skrll 	}
   2049      1.1     skrll 
   2050      1.1     skrll       return 0;
   2051      1.1     skrll     }
   2052      1.1     skrll 
   2053      1.1     skrll   /* Check if register indexed X(Rn).  */
   2054      1.1     skrll   do
   2055      1.1     skrll     {
   2056      1.1     skrll       char *h = strrchr (l, '(');
   2057      1.1     skrll       char *m = strrchr (l, ')');
   2058      1.1     skrll       char *t;
   2059      1.1     skrll 
   2060  1.1.1.4  christos       *imm_op = TRUE;
   2061      1.1     skrll 
   2062      1.1     skrll       if (!h)
   2063      1.1     skrll 	break;
   2064      1.1     skrll       if (!m)
   2065      1.1     skrll 	{
   2066      1.1     skrll 	  as_bad (_("')' required"));
   2067      1.1     skrll 	  return 1;
   2068      1.1     skrll 	}
   2069      1.1     skrll 
   2070      1.1     skrll       t = h;
   2071      1.1     skrll       op->am = 1;
   2072      1.1     skrll       op->ol = 1;
   2073      1.1     skrll 
   2074  1.1.1.4  christos       /* Extract a register.  */
   2075  1.1.1.4  christos       if ((op->reg = check_reg (t + 1)) == -1)
   2076      1.1     skrll 	{
   2077      1.1     skrll 	  as_bad (_
   2078      1.1     skrll 		  ("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"),
   2079      1.1     skrll 		  l);
   2080      1.1     skrll 	  return 1;
   2081      1.1     skrll 	}
   2082      1.1     skrll 
   2083  1.1.1.4  christos       if (op->reg == 2)
   2084      1.1     skrll 	{
   2085  1.1.1.4  christos 	  as_bad (_("r2 should not be used in indexed addressing mode"));
   2086      1.1     skrll 	  return 1;
   2087      1.1     skrll 	}
   2088      1.1     skrll 
   2089      1.1     skrll       /* Extract constant.  */
   2090      1.1     skrll       __tl = l;
   2091      1.1     skrll       *h = 0;
   2092      1.1     skrll       op->mode = OP_EXP;
   2093  1.1.1.4  christos       op->vshift = 0;
   2094  1.1.1.6  christos       end = parse_exp (__tl, &(op->exp));
   2095  1.1.1.6  christos       if (end != NULL && *end != 0)
   2096  1.1.1.6  christos 	{
   2097  1.1.1.6  christos 	  as_bad (_("extra characters '%s' at end of operand '%s'"), end, l);
   2098  1.1.1.6  christos 	  return 1;
   2099  1.1.1.6  christos 	}
   2100      1.1     skrll       if (op->exp.X_op == O_constant)
   2101      1.1     skrll 	{
   2102      1.1     skrll 	  int x = op->exp.X_add_number;
   2103      1.1     skrll 
   2104  1.1.1.4  christos 	  if (allow_20bit_values)
   2105  1.1.1.4  christos 	    {
   2106  1.1.1.4  christos 	      if (x > 0xfffff || x < - (0x7ffff))
   2107  1.1.1.4  christos 		{
   2108  1.1.1.4  christos 		  as_bad (_("value 0x%x out of extended range."), x);
   2109  1.1.1.4  christos 		  return 1;
   2110  1.1.1.4  christos 		}
   2111  1.1.1.4  christos 	    }
   2112  1.1.1.4  christos 	  else if (x > 65535 || x < -32768)
   2113      1.1     skrll 	    {
   2114  1.1.1.4  christos 	      as_bad (_("value out of range: 0x%x"), x);
   2115      1.1     skrll 	      return 1;
   2116      1.1     skrll 	    }
   2117      1.1     skrll 
   2118      1.1     skrll 	  if (x == 0)
   2119      1.1     skrll 	    {
   2120      1.1     skrll 	      op->mode = OP_REG;
   2121      1.1     skrll 	      op->am = 2;
   2122      1.1     skrll 	      op->ol = 0;
   2123      1.1     skrll 	      return 0;
   2124      1.1     skrll 	    }
   2125  1.1.1.4  christos 
   2126  1.1.1.4  christos 	  if (op->reg == 1 && (x & 1))
   2127  1.1.1.4  christos 	    {
   2128  1.1.1.4  christos 	      if (silicon_errata_fix & SILICON_ERRATA_CPU8)
   2129  1.1.1.4  christos 		as_bad (_("CPU8: Stack pointer accessed with an odd offset"));
   2130  1.1.1.4  christos 	      else if (silicon_errata_warn & SILICON_ERRATA_CPU8)
   2131  1.1.1.4  christos 		as_warn (_("CPU8: Stack pointer accessed with an odd offset"));
   2132  1.1.1.4  christos 	    }
   2133      1.1     skrll 	}
   2134      1.1     skrll       else if (op->exp.X_op == O_symbol)
   2135      1.1     skrll 	;
   2136      1.1     skrll       else
   2137      1.1     skrll 	{
   2138      1.1     skrll 	  /* Redundant (yet) check.  */
   2139      1.1     skrll 	  if (op->exp.X_op == O_register)
   2140      1.1     skrll 	    as_bad
   2141      1.1     skrll 	      (_("Registers cannot be used as a prefix of indexed expression [%s]"), l);
   2142      1.1     skrll 	  else
   2143      1.1     skrll 	    as_bad (_("unknown expression in operand %s"), l);
   2144      1.1     skrll 	  return 1;
   2145      1.1     skrll 	}
   2146      1.1     skrll 
   2147      1.1     skrll       return 0;
   2148      1.1     skrll     }
   2149      1.1     skrll   while (0);
   2150      1.1     skrll 
   2151  1.1.1.4  christos   /* Possibly register mode 'mov r1,r2'.  */
   2152  1.1.1.4  christos   if ((op->reg = check_reg (l)) != -1)
   2153      1.1     skrll     {
   2154  1.1.1.4  christos       op->mode = OP_REG;
   2155  1.1.1.4  christos       op->am = 0;
   2156  1.1.1.4  christos       op->ol = 0;
   2157  1.1.1.4  christos       return 0;
   2158      1.1     skrll     }
   2159      1.1     skrll 
   2160      1.1     skrll   /* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'.  */
   2161  1.1.1.6  christos   op->mode = OP_EXP;
   2162  1.1.1.6  christos   op->reg = 0;		/* PC relative... be careful.  */
   2163  1.1.1.6  christos   /* An expression starting with a minus sign is a constant, not an address.  */
   2164  1.1.1.6  christos   op->am = (*l == '-' ? 3 : 1);
   2165  1.1.1.6  christos   op->ol = 1;
   2166  1.1.1.6  christos   op->vshift = 0;
   2167  1.1.1.6  christos   __tl = l;
   2168  1.1.1.6  christos   end = parse_exp (__tl, &(op->exp));
   2169  1.1.1.6  christos   if (end != NULL && * end != 0)
   2170      1.1     skrll     {
   2171  1.1.1.6  christos       as_bad (_("extra characters '%s' at end of operand '%s'"), end, l);
   2172  1.1.1.6  christos       return 1;
   2173      1.1     skrll     }
   2174  1.1.1.6  christos   return 0;
   2175      1.1     skrll }
   2176      1.1     skrll 
   2177      1.1     skrll 
   2178      1.1     skrll static int
   2179  1.1.1.4  christos msp430_dstoperand (struct msp430_operand_s * op,
   2180  1.1.1.4  christos 		   char * l,
   2181  1.1.1.4  christos 		   int bin,
   2182  1.1.1.4  christos 		   bfd_boolean allow_20bit_values,
   2183  1.1.1.4  christos 		   bfd_boolean constants_allowed)
   2184      1.1     skrll {
   2185      1.1     skrll   int dummy;
   2186  1.1.1.4  christos   int ret = msp430_srcoperand (op, l, bin, & dummy,
   2187  1.1.1.4  christos 			       allow_20bit_values,
   2188  1.1.1.4  christos 			       constants_allowed);
   2189      1.1     skrll 
   2190      1.1     skrll   if (ret)
   2191      1.1     skrll     return ret;
   2192      1.1     skrll 
   2193      1.1     skrll   if (op->am == 2)
   2194      1.1     skrll     {
   2195  1.1.1.5  christos       char *__tl = (char *) "0";
   2196      1.1     skrll 
   2197      1.1     skrll       op->mode = OP_EXP;
   2198      1.1     skrll       op->am = 1;
   2199      1.1     skrll       op->ol = 1;
   2200  1.1.1.4  christos       op->vshift = 0;
   2201  1.1.1.6  christos       (void) parse_exp (__tl, &(op->exp));
   2202      1.1     skrll 
   2203      1.1     skrll       if (op->exp.X_op != O_constant || op->exp.X_add_number != 0)
   2204      1.1     skrll 	{
   2205      1.1     skrll 	  as_bad (_("Internal bug. Try to use 0(r%d) instead of @r%d"),
   2206      1.1     skrll 		  op->reg, op->reg);
   2207      1.1     skrll 	  return 1;
   2208      1.1     skrll 	}
   2209      1.1     skrll       return 0;
   2210      1.1     skrll     }
   2211      1.1     skrll 
   2212      1.1     skrll   if (op->am > 1)
   2213      1.1     skrll     {
   2214      1.1     skrll       as_bad (_
   2215      1.1     skrll 	      ("this addressing mode is not applicable for destination operand"));
   2216      1.1     skrll       return 1;
   2217      1.1     skrll     }
   2218      1.1     skrll   return 0;
   2219      1.1     skrll }
   2220      1.1     skrll 
   2221  1.1.1.4  christos /* Attempt to encode a MOVA instruction with the given operands.
   2222  1.1.1.4  christos    Returns the length of the encoded instruction if successful
   2223  1.1.1.4  christos    or 0 upon failure.  If the encoding fails, an error message
   2224  1.1.1.4  christos    will be returned if a pointer is provided.  */
   2225      1.1     skrll 
   2226  1.1.1.4  christos static int
   2227  1.1.1.4  christos try_encode_mova (bfd_boolean imm_op,
   2228  1.1.1.4  christos 		 int bin,
   2229  1.1.1.4  christos 		 struct msp430_operand_s * op1,
   2230  1.1.1.4  christos 		 struct msp430_operand_s * op2,
   2231  1.1.1.4  christos 		 const char ** error_message_return)
   2232      1.1     skrll {
   2233  1.1.1.4  christos   short ZEROS = 0;
   2234      1.1     skrll   char *frag;
   2235      1.1     skrll   int where;
   2236      1.1     skrll 
   2237  1.1.1.4  christos   /* Only a restricted subset of the normal MSP430 addressing modes
   2238  1.1.1.4  christos      are supported here, so check for the ones that are allowed.  */
   2239  1.1.1.4  christos   if (imm_op)
   2240      1.1     skrll     {
   2241  1.1.1.4  christos       if (op1->mode == OP_EXP)
   2242      1.1     skrll 	{
   2243  1.1.1.4  christos 	  if (op2->mode != OP_REG)
   2244  1.1.1.4  christos 	    {
   2245  1.1.1.4  christos 	      if (error_message_return != NULL)
   2246  1.1.1.4  christos 		* error_message_return = _("expected register as second argument of %s");
   2247  1.1.1.4  christos 	      return 0;
   2248  1.1.1.4  christos 	    }
   2249      1.1     skrll 
   2250  1.1.1.4  christos 	  if (op1->am == 3)
   2251      1.1     skrll 	    {
   2252  1.1.1.4  christos 	      /* MOVA #imm20, Rdst.  */
   2253  1.1.1.4  christos 	      bin |= 0x80 | op2->reg;
   2254  1.1.1.4  christos 	      frag = frag_more (4);
   2255  1.1.1.4  christos 	      where = frag - frag_now->fr_literal;
   2256  1.1.1.4  christos 	      if (op1->exp.X_op == O_constant)
   2257  1.1.1.4  christos 		{
   2258  1.1.1.4  christos 		  bin |= ((op1->exp.X_add_number >> 16) & 0xf) << 8;
   2259  1.1.1.4  christos 		  bfd_putl16 ((bfd_vma) bin, frag);
   2260  1.1.1.4  christos 		  bfd_putl16 (op1->exp.X_add_number & 0xffff, frag + 2);
   2261  1.1.1.4  christos 		}
   2262  1.1.1.4  christos 	      else
   2263  1.1.1.4  christos 		{
   2264  1.1.1.4  christos 		  bfd_putl16 ((bfd_vma) bin, frag);
   2265  1.1.1.4  christos 		  fix_new_exp (frag_now, where, 4, &(op1->exp), FALSE,
   2266  1.1.1.4  christos 			       BFD_RELOC_MSP430X_ABS20_ADR_SRC);
   2267  1.1.1.4  christos 		  bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
   2268  1.1.1.4  christos 		}
   2269      1.1     skrll 
   2270  1.1.1.4  christos 	      return 4;
   2271  1.1.1.4  christos 	    }
   2272  1.1.1.4  christos 	  else if (op1->am == 1)
   2273  1.1.1.4  christos 	    {
   2274  1.1.1.4  christos 	      /* MOVA z16(Rsrc), Rdst.  */
   2275  1.1.1.4  christos 	      bin |= 0x30 | (op1->reg << 8) | op2->reg;
   2276  1.1.1.4  christos 	      frag = frag_more (4);
   2277  1.1.1.4  christos 	      where = frag - frag_now->fr_literal;
   2278  1.1.1.4  christos 	      bfd_putl16 ((bfd_vma) bin, frag);
   2279  1.1.1.4  christos 	      if (op1->exp.X_op == O_constant)
   2280  1.1.1.4  christos 		{
   2281  1.1.1.4  christos 		  if (op1->exp.X_add_number > 0xffff
   2282  1.1.1.4  christos 		      || op1->exp.X_add_number < -(0x7fff))
   2283  1.1.1.4  christos 		    {
   2284  1.1.1.4  christos 		      if (error_message_return != NULL)
   2285  1.1.1.4  christos 			* error_message_return = _("index value too big for %s");
   2286  1.1.1.4  christos 		      return 0;
   2287  1.1.1.4  christos 		    }
   2288  1.1.1.4  christos 		  bfd_putl16 (op1->exp.X_add_number & 0xffff, frag + 2);
   2289  1.1.1.4  christos 		}
   2290      1.1     skrll 	      else
   2291  1.1.1.4  christos 		{
   2292  1.1.1.4  christos 		  bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
   2293  1.1.1.4  christos 		  fix_new_exp (frag_now, where + 2, 2, &(op1->exp), FALSE,
   2294  1.1.1.4  christos 			       op1->reg == 0 ?
   2295  1.1.1.4  christos 			       BFD_RELOC_MSP430X_PCR16 :
   2296  1.1.1.4  christos 			       BFD_RELOC_MSP430X_ABS16);
   2297  1.1.1.4  christos 		}
   2298  1.1.1.4  christos 	      return 4;
   2299      1.1     skrll 	    }
   2300      1.1     skrll 
   2301  1.1.1.4  christos 	  if (error_message_return != NULL)
   2302  1.1.1.4  christos 	    * error_message_return = _("unexpected addressing mode for %s");
   2303  1.1.1.4  christos 	  return 0;
   2304  1.1.1.4  christos 	}
   2305  1.1.1.4  christos       else if (op1->am == 0)
   2306  1.1.1.4  christos 	{
   2307  1.1.1.4  christos 	  /* MOVA Rsrc, ... */
   2308  1.1.1.4  christos 	  if (op2->mode == OP_REG)
   2309  1.1.1.4  christos 	    {
   2310  1.1.1.4  christos 	      bin |= 0xc0 | (op1->reg << 8) | op2->reg;
   2311  1.1.1.4  christos 	      frag = frag_more (2);
   2312  1.1.1.4  christos 	      where = frag - frag_now->fr_literal;
   2313  1.1.1.4  christos 	      bfd_putl16 ((bfd_vma) bin, frag);
   2314  1.1.1.4  christos 	      return 2;
   2315  1.1.1.4  christos 	    }
   2316  1.1.1.4  christos 	  else if (op2->am == 1)
   2317  1.1.1.4  christos 	    {
   2318  1.1.1.4  christos 	      if (op2->reg == 2)
   2319  1.1.1.4  christos 		{
   2320  1.1.1.4  christos 		  /* MOVA Rsrc, &abs20.  */
   2321  1.1.1.4  christos 		  bin |= 0x60 | (op1->reg << 8);
   2322  1.1.1.4  christos 		  frag = frag_more (4);
   2323  1.1.1.4  christos 		  where = frag - frag_now->fr_literal;
   2324  1.1.1.4  christos 		  if (op2->exp.X_op == O_constant)
   2325  1.1.1.4  christos 		    {
   2326  1.1.1.4  christos 		      bin |= (op2->exp.X_add_number >> 16) & 0xf;
   2327  1.1.1.4  christos 		      bfd_putl16 ((bfd_vma) bin, frag);
   2328  1.1.1.4  christos 		      bfd_putl16 (op2->exp.X_add_number & 0xffff, frag + 2);
   2329  1.1.1.4  christos 		    }
   2330  1.1.1.4  christos 		  else
   2331  1.1.1.4  christos 		    {
   2332  1.1.1.4  christos 		      bfd_putl16 ((bfd_vma) bin, frag);
   2333  1.1.1.4  christos 		      bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
   2334  1.1.1.4  christos 		      fix_new_exp (frag_now, where, 4, &(op2->exp), FALSE,
   2335  1.1.1.4  christos 				   BFD_RELOC_MSP430X_ABS20_ADR_DST);
   2336  1.1.1.4  christos 		    }
   2337  1.1.1.4  christos 		  return 4;
   2338  1.1.1.4  christos 		}
   2339  1.1.1.4  christos 
   2340  1.1.1.4  christos 	      /* MOVA Rsrc, z16(Rdst).  */
   2341  1.1.1.4  christos 	      bin |= 0x70 | (op1->reg << 8) | op2->reg;
   2342  1.1.1.4  christos 	      frag = frag_more (4);
   2343  1.1.1.4  christos 	      where = frag - frag_now->fr_literal;
   2344  1.1.1.4  christos 	      bfd_putl16 ((bfd_vma) bin, frag);
   2345  1.1.1.4  christos 	      if (op2->exp.X_op == O_constant)
   2346  1.1.1.4  christos 		{
   2347  1.1.1.4  christos 		  if (op2->exp.X_add_number > 0xffff
   2348  1.1.1.4  christos 		      || op2->exp.X_add_number < -(0x7fff))
   2349  1.1.1.4  christos 		    {
   2350  1.1.1.4  christos 		      if (error_message_return != NULL)
   2351  1.1.1.4  christos 			* error_message_return = _("index value too big for %s");
   2352  1.1.1.4  christos 		      return 0;
   2353  1.1.1.4  christos 		    }
   2354  1.1.1.4  christos 		  bfd_putl16 (op2->exp.X_add_number & 0xffff, frag + 2);
   2355  1.1.1.4  christos 		}
   2356  1.1.1.4  christos 	      else
   2357  1.1.1.4  christos 		{
   2358  1.1.1.4  christos 		  bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
   2359  1.1.1.4  christos 		  fix_new_exp (frag_now, where + 2, 2, &(op2->exp), FALSE,
   2360  1.1.1.4  christos 			       op2->reg == 0 ?
   2361  1.1.1.4  christos 			       BFD_RELOC_MSP430X_PCR16 :
   2362  1.1.1.4  christos 			       BFD_RELOC_MSP430X_ABS16);
   2363  1.1.1.4  christos 		}
   2364  1.1.1.4  christos 	      return 4;
   2365  1.1.1.4  christos 	    }
   2366  1.1.1.4  christos 
   2367  1.1.1.4  christos 	  if (error_message_return != NULL)
   2368  1.1.1.4  christos 	    * error_message_return = _("unexpected addressing mode for %s");
   2369  1.1.1.4  christos 	  return 0;
   2370  1.1.1.4  christos 	}
   2371  1.1.1.4  christos     }
   2372  1.1.1.4  christos 
   2373  1.1.1.4  christos   /* imm_op == FALSE.  */
   2374  1.1.1.4  christos 
   2375  1.1.1.4  christos   if (op1->reg == 2 && op1->am == 1 && op1->mode == OP_EXP)
   2376  1.1.1.4  christos     {
   2377  1.1.1.4  christos       /* MOVA &abs20, Rdst.  */
   2378  1.1.1.4  christos       if (op2->mode != OP_REG)
   2379  1.1.1.4  christos 	{
   2380  1.1.1.4  christos 	  if (error_message_return != NULL)
   2381  1.1.1.4  christos 	    * error_message_return = _("expected register as second argument of %s");
   2382  1.1.1.4  christos 	  return 0;
   2383  1.1.1.4  christos 	}
   2384  1.1.1.4  christos 
   2385  1.1.1.4  christos       if (op2->reg == 2 || op2->reg == 3)
   2386  1.1.1.4  christos 	{
   2387  1.1.1.4  christos 	  if (error_message_return != NULL)
   2388  1.1.1.4  christos 	    * error_message_return = _("constant generator destination register found in %s");
   2389  1.1.1.4  christos 	  return 0;
   2390  1.1.1.4  christos 	}
   2391  1.1.1.4  christos 
   2392  1.1.1.4  christos       bin |= 0x20 | op2->reg;
   2393  1.1.1.4  christos       frag = frag_more (4);
   2394  1.1.1.4  christos       where = frag - frag_now->fr_literal;
   2395  1.1.1.4  christos       if (op1->exp.X_op == O_constant)
   2396  1.1.1.4  christos 	{
   2397  1.1.1.4  christos 	  bin |= ((op1->exp.X_add_number >> 16) & 0xf) << 8;
   2398  1.1.1.4  christos 	  bfd_putl16 ((bfd_vma) bin, frag);
   2399  1.1.1.4  christos 	  bfd_putl16 (op1->exp.X_add_number & 0xffff, frag + 2);
   2400  1.1.1.4  christos 	}
   2401  1.1.1.4  christos       else
   2402  1.1.1.4  christos 	{
   2403  1.1.1.4  christos 	  bfd_putl16 ((bfd_vma) bin, frag);
   2404  1.1.1.4  christos 	  bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
   2405  1.1.1.4  christos 	  fix_new_exp (frag_now, where, 4, &(op1->exp), FALSE,
   2406  1.1.1.4  christos 		       BFD_RELOC_MSP430X_ABS20_ADR_SRC);
   2407  1.1.1.4  christos 	}
   2408  1.1.1.4  christos       return 4;
   2409  1.1.1.4  christos     }
   2410  1.1.1.4  christos   else if (op1->mode == OP_REG)
   2411  1.1.1.4  christos     {
   2412  1.1.1.4  christos       if (op1->am == 3)
   2413  1.1.1.4  christos 	{
   2414  1.1.1.4  christos 	  /* MOVA @Rsrc+, Rdst.  */
   2415  1.1.1.4  christos 	  if (op2->mode != OP_REG)
   2416  1.1.1.4  christos 	    {
   2417  1.1.1.4  christos 	      if (error_message_return != NULL)
   2418  1.1.1.4  christos 		* error_message_return = _("expected register as second argument of %s");
   2419  1.1.1.4  christos 	      return 0;
   2420  1.1.1.4  christos 	    }
   2421  1.1.1.4  christos 
   2422  1.1.1.4  christos 	  if (op2->reg == 2 || op2->reg == 3)
   2423  1.1.1.4  christos 	    {
   2424  1.1.1.4  christos 	      if (error_message_return != NULL)
   2425  1.1.1.4  christos 		* error_message_return = _("constant generator destination register found in %s");
   2426  1.1.1.4  christos 	      return 0;
   2427  1.1.1.4  christos 	    }
   2428  1.1.1.4  christos 
   2429  1.1.1.4  christos 	  if (op1->reg == 2 || op1->reg == 3)
   2430  1.1.1.4  christos 	    {
   2431  1.1.1.4  christos 	      if (error_message_return != NULL)
   2432  1.1.1.4  christos 		* error_message_return = _("constant generator source register found in %s");
   2433  1.1.1.4  christos 	      return 0;
   2434  1.1.1.4  christos 	    }
   2435  1.1.1.4  christos 
   2436  1.1.1.4  christos 	  bin |= 0x10 | (op1->reg << 8) | op2->reg;
   2437  1.1.1.4  christos 	  frag = frag_more (2);
   2438  1.1.1.4  christos 	  where = frag - frag_now->fr_literal;
   2439  1.1.1.4  christos 	  bfd_putl16 ((bfd_vma) bin, frag);
   2440  1.1.1.4  christos 	  return 2;
   2441  1.1.1.4  christos 	}
   2442  1.1.1.4  christos       else if (op1->am == 2)
   2443  1.1.1.4  christos 	{
   2444  1.1.1.4  christos 	  /* MOVA @Rsrc,Rdst */
   2445  1.1.1.4  christos 	  if (op2->mode != OP_REG)
   2446  1.1.1.4  christos 	    {
   2447  1.1.1.4  christos 	      if (error_message_return != NULL)
   2448  1.1.1.4  christos 		* error_message_return = _("expected register as second argument of %s");
   2449  1.1.1.4  christos 	      return 0;
   2450  1.1.1.4  christos 	    }
   2451  1.1.1.4  christos 
   2452  1.1.1.4  christos 	  if (op2->reg == 2 || op2->reg == 3)
   2453  1.1.1.4  christos 	    {
   2454  1.1.1.4  christos 	      if (error_message_return != NULL)
   2455  1.1.1.4  christos 		* error_message_return = _("constant generator destination register found in %s");
   2456  1.1.1.4  christos 	      return 0;
   2457  1.1.1.4  christos 	    }
   2458  1.1.1.4  christos 
   2459  1.1.1.4  christos 	  if (op1->reg == 2 || op1->reg == 3)
   2460  1.1.1.4  christos 	    {
   2461  1.1.1.4  christos 	      if (error_message_return != NULL)
   2462  1.1.1.4  christos 		* error_message_return = _("constant generator source register found in %s");
   2463  1.1.1.4  christos 	      return 0;
   2464  1.1.1.4  christos 	    }
   2465  1.1.1.4  christos 
   2466  1.1.1.4  christos 	  bin |= (op1->reg << 8) | op2->reg;
   2467  1.1.1.4  christos 	  frag = frag_more (2);
   2468  1.1.1.4  christos 	  where = frag - frag_now->fr_literal;
   2469  1.1.1.4  christos 	  bfd_putl16 ((bfd_vma) bin, frag);
   2470  1.1.1.4  christos 	  return 2;
   2471  1.1.1.4  christos 	}
   2472  1.1.1.4  christos     }
   2473  1.1.1.4  christos 
   2474  1.1.1.4  christos   if (error_message_return != NULL)
   2475  1.1.1.4  christos     * error_message_return = _("unexpected addressing mode for %s");
   2476  1.1.1.4  christos 
   2477  1.1.1.4  christos   return 0;
   2478  1.1.1.4  christos }
   2479  1.1.1.4  christos 
   2480  1.1.1.4  christos #define NOP_CHECK_INTERRUPT  (1 << 0)
   2481  1.1.1.4  christos #define NOP_CHECK_CPU12      (1 << 1)
   2482  1.1.1.4  christos #define NOP_CHECK_CPU19      (1 << 2)
   2483  1.1.1.4  christos 
   2484  1.1.1.4  christos static signed int check_for_nop = 0;
   2485  1.1.1.4  christos 
   2486  1.1.1.4  christos #define is_opcode(NAME) (strcmp (opcode->name, NAME) == 0)
   2487  1.1.1.4  christos 
   2488  1.1.1.4  christos /* Parse instruction operands.
   2489  1.1.1.4  christos    Return binary opcode.  */
   2490  1.1.1.4  christos 
   2491  1.1.1.4  christos static unsigned int
   2492  1.1.1.4  christos msp430_operands (struct msp430_opcode_s * opcode, char * line)
   2493  1.1.1.4  christos {
   2494  1.1.1.4  christos   int bin = opcode->bin_opcode;	/* Opcode mask.  */
   2495  1.1.1.4  christos   int insn_length = 0;
   2496  1.1.1.4  christos   char l1[MAX_OP_LEN], l2[MAX_OP_LEN];
   2497  1.1.1.4  christos   char *frag;
   2498  1.1.1.6  christos   char *end;
   2499  1.1.1.4  christos   int where;
   2500  1.1.1.4  christos   struct msp430_operand_s op1, op2;
   2501  1.1.1.4  christos   int res = 0;
   2502  1.1.1.4  christos   static short ZEROS = 0;
   2503  1.1.1.4  christos   bfd_boolean byte_op, imm_op;
   2504  1.1.1.4  christos   int op_length = 0;
   2505  1.1.1.4  christos   int fmt;
   2506  1.1.1.4  christos   int extended = 0x1800;
   2507  1.1.1.4  christos   bfd_boolean extended_op = FALSE;
   2508  1.1.1.4  christos   bfd_boolean addr_op;
   2509  1.1.1.4  christos   const char * error_message;
   2510  1.1.1.4  christos   static signed int repeat_count = 0;
   2511  1.1.1.5  christos   static bfd_boolean prev_insn_is_nop = FALSE;
   2512  1.1.1.4  christos   bfd_boolean fix_emitted;
   2513  1.1.1.4  christos 
   2514  1.1.1.4  christos   /* Opcode is the one from opcodes table
   2515  1.1.1.4  christos      line contains something like
   2516  1.1.1.4  christos      [.w] @r2+, 5(R1)
   2517  1.1.1.4  christos      or
   2518  1.1.1.4  christos      .b @r2+, 5(R1).  */
   2519  1.1.1.4  christos 
   2520  1.1.1.4  christos   byte_op = FALSE;
   2521  1.1.1.4  christos   addr_op = FALSE;
   2522  1.1.1.4  christos   if (*line == '.')
   2523  1.1.1.4  christos     {
   2524  1.1.1.4  christos       bfd_boolean check = FALSE;
   2525  1.1.1.4  christos       ++ line;
   2526  1.1.1.4  christos 
   2527  1.1.1.4  christos       switch (TOLOWER (* line))
   2528  1.1.1.4  christos 	{
   2529  1.1.1.4  christos 	case 'b':
   2530  1.1.1.4  christos 	  /* Byte operation.  */
   2531  1.1.1.4  christos 	  bin |= BYTE_OPERATION;
   2532  1.1.1.4  christos 	  byte_op = TRUE;
   2533  1.1.1.4  christos 	  check = TRUE;
   2534  1.1.1.4  christos 	  break;
   2535  1.1.1.4  christos 
   2536  1.1.1.4  christos 	case 'a':
   2537  1.1.1.4  christos 	  /* "Address" ops work on 20-bit values.  */
   2538  1.1.1.4  christos 	  addr_op = TRUE;
   2539  1.1.1.4  christos 	  bin |= BYTE_OPERATION;
   2540  1.1.1.4  christos 	  check = TRUE;
   2541  1.1.1.4  christos 	  break;
   2542  1.1.1.4  christos 
   2543  1.1.1.4  christos 	case 'w':
   2544  1.1.1.4  christos 	  /* Word operation - this is the default.  */
   2545  1.1.1.4  christos 	  check = TRUE;
   2546  1.1.1.4  christos 	  break;
   2547  1.1.1.4  christos 
   2548  1.1.1.4  christos 	case 0:
   2549  1.1.1.4  christos 	case ' ':
   2550  1.1.1.4  christos 	case '\n':
   2551  1.1.1.4  christos 	case '\r':
   2552  1.1.1.4  christos 	  as_warn (_("no size modifier after period, .w assumed"));
   2553  1.1.1.4  christos 	  break;
   2554  1.1.1.4  christos 
   2555  1.1.1.4  christos 	default:
   2556  1.1.1.4  christos 	  as_bad (_("unrecognised instruction size modifier .%c"),
   2557  1.1.1.4  christos 		   * line);
   2558  1.1.1.4  christos 	  return 0;
   2559  1.1.1.4  christos 	}
   2560  1.1.1.4  christos 
   2561  1.1.1.4  christos       if (check)
   2562  1.1.1.4  christos 	{
   2563  1.1.1.4  christos 	  ++ line;
   2564  1.1.1.4  christos 
   2565  1.1.1.4  christos 	}
   2566  1.1.1.4  christos     }
   2567  1.1.1.4  christos 
   2568  1.1.1.4  christos   if (*line && ! ISSPACE (*line))
   2569  1.1.1.4  christos     {
   2570  1.1.1.4  christos       as_bad (_("junk found after instruction: %s.%s"),
   2571  1.1.1.4  christos 	      opcode->name, line);
   2572  1.1.1.4  christos       return 0;
   2573  1.1.1.4  christos     }
   2574  1.1.1.4  christos 
   2575  1.1.1.4  christos   /* Catch the case where the programmer has used a ".a" size modifier on an
   2576  1.1.1.4  christos      instruction that does not support it.  Look for an alternative extended
   2577  1.1.1.4  christos      instruction that has the same name without the period.  Eg: "add.a"
   2578  1.1.1.4  christos      becomes "adda".  Although this not an officially supported way of
   2579  1.1.1.6  christos      specifying instruction aliases other MSP430 assemblers allow it.  So we
   2580  1.1.1.4  christos      support it for compatibility purposes.  */
   2581  1.1.1.4  christos   if (addr_op && opcode->fmt >= 0)
   2582  1.1.1.4  christos     {
   2583  1.1.1.5  christos       const char * old_name = opcode->name;
   2584  1.1.1.4  christos       char real_name[32];
   2585  1.1.1.4  christos 
   2586  1.1.1.4  christos       sprintf (real_name, "%sa", old_name);
   2587  1.1.1.4  christos       opcode = hash_find (msp430_hash, real_name);
   2588  1.1.1.4  christos       if (opcode == NULL)
   2589  1.1.1.4  christos 	{
   2590  1.1.1.4  christos 	  as_bad (_("instruction %s.a does not exist"), old_name);
   2591  1.1.1.4  christos 	  return 0;
   2592  1.1.1.4  christos 	}
   2593  1.1.1.4  christos #if 0 /* Enable for debugging.  */
   2594  1.1.1.4  christos       as_warn ("treating %s.a as %s", old_name, real_name);
   2595  1.1.1.4  christos #endif
   2596  1.1.1.4  christos       addr_op = FALSE;
   2597  1.1.1.4  christos       bin = opcode->bin_opcode;
   2598  1.1.1.4  christos     }
   2599  1.1.1.4  christos 
   2600  1.1.1.4  christos   if (opcode->fmt != -1
   2601  1.1.1.4  christos       && opcode->insn_opnumb
   2602  1.1.1.4  christos       && (!*line || *line == '\n'))
   2603  1.1.1.4  christos     {
   2604  1.1.1.6  christos       as_bad (ngettext ("instruction %s requires %d operand",
   2605  1.1.1.6  christos 			"instruction %s requires %d operands",
   2606  1.1.1.6  christos 			opcode->insn_opnumb),
   2607  1.1.1.4  christos 	      opcode->name, opcode->insn_opnumb);
   2608  1.1.1.4  christos       return 0;
   2609  1.1.1.4  christos     }
   2610  1.1.1.4  christos 
   2611  1.1.1.4  christos   memset (l1, 0, sizeof (l1));
   2612  1.1.1.4  christos   memset (l2, 0, sizeof (l2));
   2613  1.1.1.4  christos   memset (&op1, 0, sizeof (op1));
   2614  1.1.1.4  christos   memset (&op2, 0, sizeof (op2));
   2615  1.1.1.4  christos 
   2616  1.1.1.4  christos   imm_op = FALSE;
   2617  1.1.1.4  christos 
   2618  1.1.1.4  christos   if ((fmt = opcode->fmt) < 0)
   2619  1.1.1.4  christos     {
   2620  1.1.1.4  christos       if (! target_is_430x ())
   2621  1.1.1.4  christos 	{
   2622  1.1.1.4  christos 	  as_bad (_("instruction %s requires MSP430X mcu"),
   2623  1.1.1.4  christos 		  opcode->name);
   2624  1.1.1.4  christos 	  return 0;
   2625  1.1.1.4  christos 	}
   2626  1.1.1.4  christos 
   2627  1.1.1.4  christos       fmt = (-fmt) - 1;
   2628  1.1.1.4  christos       extended_op = TRUE;
   2629  1.1.1.4  christos     }
   2630  1.1.1.4  christos 
   2631  1.1.1.4  christos   if (repeat_count)
   2632  1.1.1.4  christos     {
   2633  1.1.1.4  christos       /* If requested set the extended instruction repeat count.  */
   2634  1.1.1.4  christos       if (extended_op)
   2635  1.1.1.4  christos 	{
   2636  1.1.1.4  christos 	  if (repeat_count > 0)
   2637  1.1.1.4  christos 	    extended |= (repeat_count - 1);
   2638  1.1.1.4  christos 	  else
   2639  1.1.1.4  christos 	    extended |= (1 << 7) | (- repeat_count);
   2640  1.1.1.4  christos 	}
   2641  1.1.1.4  christos       else
   2642  1.1.1.4  christos 	as_bad (_("unable to repeat %s insn"), opcode->name);
   2643  1.1.1.4  christos 
   2644  1.1.1.4  christos       repeat_count = 0;
   2645  1.1.1.4  christos     }
   2646  1.1.1.4  christos 
   2647  1.1.1.4  christos   if (check_for_nop)
   2648  1.1.1.4  christos     {
   2649  1.1.1.4  christos       if (! is_opcode ("nop"))
   2650  1.1.1.4  christos 	{
   2651  1.1.1.4  christos 	  bfd_boolean doit = FALSE;
   2652  1.1.1.4  christos 
   2653  1.1.1.4  christos 	  do
   2654  1.1.1.4  christos 	    {
   2655  1.1.1.4  christos 	      switch (check_for_nop & - check_for_nop)
   2656  1.1.1.4  christos 		{
   2657  1.1.1.4  christos 		case NOP_CHECK_INTERRUPT:
   2658  1.1.1.4  christos 		  if (warn_interrupt_nops)
   2659  1.1.1.4  christos 		    {
   2660  1.1.1.4  christos 		      if (gen_interrupt_nops)
   2661  1.1.1.4  christos 			as_warn (_("NOP inserted between two instructions that change interrupt state"));
   2662  1.1.1.4  christos 		      else
   2663  1.1.1.4  christos 			as_warn (_("a NOP might be needed here because of successive changes in interrupt state"));
   2664  1.1.1.4  christos 		    }
   2665  1.1.1.4  christos 
   2666  1.1.1.4  christos 		  if (gen_interrupt_nops)
   2667  1.1.1.4  christos 		    /* Emit a NOP between interrupt enable/disable.
   2668  1.1.1.4  christos 		       See 1.3.4.1 of the MSP430x5xx User Guide.  */
   2669  1.1.1.4  christos 		    doit = TRUE;
   2670  1.1.1.4  christos 		  break;
   2671  1.1.1.4  christos 
   2672  1.1.1.4  christos 		case NOP_CHECK_CPU12:
   2673  1.1.1.4  christos 		  if (silicon_errata_warn & SILICON_ERRATA_CPU12)
   2674  1.1.1.6  christos 		    as_warn (_("CPU12: CMP/BIT with PC destination ignores next instruction"));
   2675  1.1.1.4  christos 
   2676  1.1.1.4  christos 		  if (silicon_errata_fix & SILICON_ERRATA_CPU12)
   2677  1.1.1.4  christos 		    doit = TRUE;
   2678  1.1.1.4  christos 		  break;
   2679  1.1.1.4  christos 
   2680  1.1.1.4  christos 		case NOP_CHECK_CPU19:
   2681  1.1.1.4  christos 		  if (silicon_errata_warn & SILICON_ERRATA_CPU19)
   2682  1.1.1.4  christos 		    as_warn (_("CPU19: Instruction setting CPUOFF must be followed by a NOP"));
   2683  1.1.1.4  christos 
   2684  1.1.1.4  christos 		  if (silicon_errata_fix & SILICON_ERRATA_CPU19)
   2685  1.1.1.4  christos 		    doit = TRUE;
   2686  1.1.1.4  christos 		  break;
   2687  1.1.1.4  christos 
   2688  1.1.1.4  christos 		default:
   2689  1.1.1.4  christos 		  as_bad (_("internal error: unknown nop check state"));
   2690  1.1.1.4  christos 		  break;
   2691  1.1.1.4  christos 		}
   2692  1.1.1.4  christos 	      check_for_nop &= ~ (check_for_nop & - check_for_nop);
   2693  1.1.1.4  christos 	    }
   2694  1.1.1.4  christos 	  while (check_for_nop);
   2695  1.1.1.4  christos 
   2696  1.1.1.4  christos 	  if (doit)
   2697  1.1.1.4  christos 	    {
   2698  1.1.1.4  christos 	      frag = frag_more (2);
   2699  1.1.1.4  christos 	      bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
   2700  1.1.1.4  christos 	      dwarf2_emit_insn (2);
   2701  1.1.1.4  christos 	    }
   2702  1.1.1.4  christos 	}
   2703  1.1.1.4  christos 
   2704  1.1.1.4  christos       check_for_nop = 0;
   2705  1.1.1.4  christos     }
   2706  1.1.1.4  christos 
   2707  1.1.1.4  christos   switch (fmt)
   2708  1.1.1.4  christos     {
   2709  1.1.1.4  christos     case 0:			/* Emulated.  */
   2710  1.1.1.4  christos       switch (opcode->insn_opnumb)
   2711  1.1.1.4  christos 	{
   2712  1.1.1.4  christos 	case 0:
   2713  1.1.1.5  christos 	  if (is_opcode ("eint"))
   2714  1.1.1.5  christos 	    {
   2715  1.1.1.5  christos 	      if (! prev_insn_is_nop)
   2716  1.1.1.5  christos 		{
   2717  1.1.1.5  christos 		  if (gen_interrupt_nops)
   2718  1.1.1.5  christos 		    {
   2719  1.1.1.5  christos 		      frag = frag_more (2);
   2720  1.1.1.5  christos 		      bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
   2721  1.1.1.5  christos 		      dwarf2_emit_insn (2);
   2722  1.1.1.5  christos 
   2723  1.1.1.5  christos 		      if (warn_interrupt_nops)
   2724  1.1.1.5  christos 			as_warn (_("inserting a NOP before EINT"));
   2725  1.1.1.5  christos 		    }
   2726  1.1.1.5  christos 		  else if (warn_interrupt_nops)
   2727  1.1.1.5  christos 		    as_warn (_("a NOP might be needed before the EINT"));
   2728  1.1.1.5  christos 		}
   2729  1.1.1.5  christos 	    }
   2730  1.1.1.5  christos 	  else if (is_opcode ("dint"))
   2731  1.1.1.4  christos 	    check_for_nop |= NOP_CHECK_INTERRUPT;
   2732  1.1.1.4  christos 
   2733  1.1.1.4  christos 	  /* Set/clear bits instructions.  */
   2734  1.1.1.4  christos 	  if (extended_op)
   2735  1.1.1.4  christos 	    {
   2736  1.1.1.4  christos 	      if (!addr_op)
   2737  1.1.1.4  christos 		extended |= BYTE_OPERATION;
   2738  1.1.1.4  christos 
   2739  1.1.1.4  christos 	      /* Emit the extension word.  */
   2740  1.1.1.4  christos 	      insn_length += 2;
   2741  1.1.1.4  christos 	      frag = frag_more (2);
   2742  1.1.1.4  christos 	      bfd_putl16 (extended, frag);
   2743  1.1.1.4  christos 	    }
   2744  1.1.1.4  christos 
   2745  1.1.1.4  christos 	  insn_length += 2;
   2746  1.1.1.4  christos 	  frag = frag_more (2);
   2747  1.1.1.4  christos 	  bfd_putl16 ((bfd_vma) bin, frag);
   2748  1.1.1.4  christos 	  dwarf2_emit_insn (insn_length);
   2749  1.1.1.4  christos 	  break;
   2750  1.1.1.4  christos 
   2751  1.1.1.4  christos 	case 1:
   2752  1.1.1.4  christos 	  /* Something which works with destination operand.  */
   2753  1.1.1.4  christos 	  line = extract_operand (line, l1, sizeof (l1));
   2754  1.1.1.4  christos 	  res = msp430_dstoperand (&op1, l1, opcode->bin_opcode, extended_op, TRUE);
   2755  1.1.1.4  christos 	  if (res)
   2756  1.1.1.4  christos 	    break;
   2757  1.1.1.4  christos 
   2758  1.1.1.4  christos 	  bin |= (op1.reg | (op1.am << 7));
   2759  1.1.1.4  christos 
   2760  1.1.1.4  christos 	  /* If the PC is the destination...  */
   2761  1.1.1.4  christos 	  if (op1.am == 0 && op1.reg == 0
   2762  1.1.1.4  christos 	      /* ... and the opcode alters the SR.  */
   2763  1.1.1.4  christos 	      && !(is_opcode ("bic") || is_opcode ("bis") || is_opcode ("mov")
   2764  1.1.1.4  christos 		   || is_opcode ("bicx") || is_opcode ("bisx") || is_opcode ("movx")))
   2765  1.1.1.4  christos 	    {
   2766  1.1.1.4  christos 	      if (silicon_errata_fix & SILICON_ERRATA_CPU11)
   2767  1.1.1.6  christos 		as_bad (_("CPU11: PC is destination of SR altering instruction"));
   2768  1.1.1.4  christos 	      else if (silicon_errata_warn & SILICON_ERRATA_CPU11)
   2769  1.1.1.6  christos 		as_warn (_("CPU11: PC is destination of SR altering instruction"));
   2770  1.1.1.4  christos 	    }
   2771  1.1.1.4  christos 
   2772  1.1.1.4  christos 	  /* If the status register is the destination...  */
   2773  1.1.1.4  christos 	  if (op1.am == 0 && op1.reg == 2
   2774  1.1.1.4  christos 	      /* ... and the opcode alters the SR.  */
   2775  1.1.1.4  christos 	      && (is_opcode ("adc") || is_opcode ("dec") || is_opcode ("decd")
   2776  1.1.1.4  christos 		  || is_opcode ("inc") || is_opcode ("incd") || is_opcode ("inv")
   2777  1.1.1.4  christos 		  || is_opcode ("sbc") || is_opcode ("sxt")
   2778  1.1.1.4  christos 		  || is_opcode ("adcx") || is_opcode ("decx") || is_opcode ("decdx")
   2779  1.1.1.4  christos 		  || is_opcode ("incx") || is_opcode ("incdx") || is_opcode ("invx")
   2780  1.1.1.4  christos 		  || is_opcode ("sbcx")
   2781  1.1.1.4  christos 		  ))
   2782  1.1.1.4  christos 	    {
   2783  1.1.1.4  christos 	      if (silicon_errata_fix & SILICON_ERRATA_CPU13)
   2784  1.1.1.6  christos 		as_bad (_("CPU13: SR is destination of SR altering instruction"));
   2785  1.1.1.4  christos 	      else if (silicon_errata_warn & SILICON_ERRATA_CPU13)
   2786  1.1.1.6  christos 		as_warn (_("CPU13: SR is destination of SR altering instruction"));
   2787  1.1.1.4  christos 	    }
   2788  1.1.1.4  christos 
   2789  1.1.1.4  christos 	  if (is_opcode ("clr") && bin == 0x4302 /* CLR R2*/)
   2790  1.1.1.4  christos 	    check_for_nop |= NOP_CHECK_INTERRUPT;
   2791  1.1.1.4  christos 
   2792  1.1.1.4  christos 	  /* Compute the entire instruction length, in bytes.  */
   2793  1.1.1.4  christos 	  op_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2);
   2794  1.1.1.4  christos 	  insn_length += op_length;
   2795  1.1.1.4  christos 	  frag = frag_more (op_length);
   2796  1.1.1.4  christos 	  where = frag - frag_now->fr_literal;
   2797  1.1.1.4  christos 
   2798  1.1.1.4  christos 	  if (extended_op)
   2799  1.1.1.4  christos 	    {
   2800  1.1.1.4  christos 	      if (!addr_op)
   2801  1.1.1.4  christos 		extended |= BYTE_OPERATION;
   2802  1.1.1.4  christos 
   2803  1.1.1.4  christos 	      if (op1.ol != 0 && ((extended & 0xf) != 0))
   2804  1.1.1.4  christos 		{
   2805  1.1.1.4  christos 		  as_bad (_("repeat instruction used with non-register mode instruction"));
   2806  1.1.1.4  christos 		  extended &= ~ 0xf;
   2807  1.1.1.4  christos 		}
   2808  1.1.1.4  christos 
   2809  1.1.1.4  christos 	      if (op1.mode == OP_EXP)
   2810  1.1.1.4  christos 		{
   2811  1.1.1.4  christos 		  if (op1.exp.X_op == O_constant)
   2812  1.1.1.4  christos 		    extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
   2813  1.1.1.4  christos 
   2814  1.1.1.4  christos 		  else if (op1.reg || op1.am == 3)	/* Not PC relative.  */
   2815  1.1.1.4  christos 		    fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
   2816  1.1.1.4  christos 				 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
   2817  1.1.1.4  christos 		  else
   2818  1.1.1.4  christos 		    fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
   2819  1.1.1.4  christos 				 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
   2820  1.1.1.4  christos 		}
   2821  1.1.1.4  christos 
   2822  1.1.1.4  christos 	      /* Emit the extension word.  */
   2823  1.1.1.4  christos 	      bfd_putl16 (extended, frag);
   2824  1.1.1.4  christos 	      frag += 2;
   2825  1.1.1.4  christos 	      where += 2;
   2826  1.1.1.4  christos 	    }
   2827  1.1.1.4  christos 
   2828  1.1.1.4  christos 	  bfd_putl16 ((bfd_vma) bin, frag);
   2829  1.1.1.4  christos 	  frag += 2;
   2830  1.1.1.4  christos 	  where += 2;
   2831  1.1.1.4  christos 
   2832  1.1.1.4  christos 	  if (op1.mode == OP_EXP)
   2833  1.1.1.4  christos 	    {
   2834  1.1.1.4  christos 	      if (op1.exp.X_op == O_constant)
   2835  1.1.1.4  christos 		{
   2836  1.1.1.4  christos 		  bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
   2837  1.1.1.4  christos 		}
   2838  1.1.1.4  christos 	      else
   2839  1.1.1.4  christos 		{
   2840  1.1.1.4  christos 		  bfd_putl16 ((bfd_vma) ZEROS, frag);
   2841  1.1.1.4  christos 
   2842  1.1.1.4  christos 		  if (!extended_op)
   2843  1.1.1.4  christos 		    {
   2844  1.1.1.4  christos 		      if (op1.reg)
   2845  1.1.1.4  christos 			fix_new_exp (frag_now, where, 2,
   2846  1.1.1.4  christos 				     &(op1.exp), FALSE, CHECK_RELOC_MSP430 (op1));
   2847  1.1.1.4  christos 		      else
   2848  1.1.1.4  christos 			fix_new_exp (frag_now, where, 2,
   2849  1.1.1.4  christos 				     &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
   2850  1.1.1.4  christos 		    }
   2851  1.1.1.4  christos 		}
   2852  1.1.1.4  christos 	    }
   2853  1.1.1.4  christos 
   2854  1.1.1.4  christos 	  dwarf2_emit_insn (insn_length);
   2855  1.1.1.4  christos 	  break;
   2856  1.1.1.4  christos 
   2857  1.1.1.4  christos 	case 2:
   2858  1.1.1.4  christos 	  /* Shift instruction.  */
   2859  1.1.1.4  christos 	  line = extract_operand (line, l1, sizeof (l1));
   2860  1.1.1.4  christos 	  strncpy (l2, l1, sizeof (l2));
   2861  1.1.1.4  christos 	  l2[sizeof (l2) - 1] = '\0';
   2862  1.1.1.4  christos 	  res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op, extended_op, TRUE);
   2863  1.1.1.4  christos 	  res += msp430_dstoperand (&op2, l2, opcode->bin_opcode, extended_op, TRUE);
   2864  1.1.1.4  christos 
   2865  1.1.1.4  christos 	  if (res)
   2866  1.1.1.4  christos 	    break;	/* An error occurred.  All warnings were done before.  */
   2867  1.1.1.4  christos 
   2868  1.1.1.4  christos 	  insn_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2) + (op2.ol * 2);
   2869  1.1.1.4  christos 	  frag = frag_more (insn_length);
   2870  1.1.1.4  christos 	  where = frag - frag_now->fr_literal;
   2871  1.1.1.4  christos 
   2872  1.1.1.4  christos 	  if (target_is_430xv2 ()
   2873  1.1.1.4  christos 	      && op1.mode == OP_REG
   2874  1.1.1.4  christos 	      && op1.reg == 0
   2875  1.1.1.4  christos 	      && (is_opcode ("rlax")
   2876  1.1.1.4  christos 		  || is_opcode ("rlcx")
   2877  1.1.1.4  christos 		  || is_opcode ("rla")
   2878  1.1.1.4  christos 		  || is_opcode ("rlc")))
   2879  1.1.1.4  christos 	    {
   2880  1.1.1.4  christos 	      as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
   2881  1.1.1.4  christos 	      break;
   2882  1.1.1.4  christos 	    }
   2883  1.1.1.4  christos 
   2884  1.1.1.4  christos 	  /* If the status register is the destination...  */
   2885  1.1.1.4  christos 	  if (op1.am == 0 && op1.reg == 2
   2886  1.1.1.4  christos 	      /* ... and the opcode alters the SR.  */
   2887  1.1.1.4  christos 	      && (is_opcode ("rla") || is_opcode ("rlc")
   2888  1.1.1.4  christos 		  || is_opcode ("rlax") || is_opcode ("rlcx")
   2889  1.1.1.4  christos 		  ))
   2890  1.1.1.4  christos 	    {
   2891  1.1.1.4  christos 	      if (silicon_errata_fix & SILICON_ERRATA_CPU13)
   2892  1.1.1.6  christos 		as_bad (_("CPU13: SR is destination of SR altering instruction"));
   2893  1.1.1.4  christos 	      else if (silicon_errata_warn & SILICON_ERRATA_CPU13)
   2894  1.1.1.6  christos 		as_warn (_("CPU13: SR is destination of SR altering instruction"));
   2895  1.1.1.4  christos 	    }
   2896  1.1.1.4  christos 
   2897  1.1.1.4  christos 	  if (extended_op)
   2898  1.1.1.4  christos 	    {
   2899  1.1.1.4  christos 	      if (!addr_op)
   2900  1.1.1.4  christos 		extended |= BYTE_OPERATION;
   2901  1.1.1.4  christos 
   2902  1.1.1.4  christos 	      if ((op1.ol != 0 || op2.ol != 0) && ((extended & 0xf) != 0))
   2903  1.1.1.4  christos 		{
   2904  1.1.1.4  christos 		  as_bad (_("repeat instruction used with non-register mode instruction"));
   2905  1.1.1.4  christos 		  extended &= ~ 0xf;
   2906  1.1.1.4  christos 		}
   2907  1.1.1.4  christos 
   2908  1.1.1.4  christos 	      if (op1.mode == OP_EXP)
   2909  1.1.1.4  christos 		{
   2910  1.1.1.4  christos 		  if (op1.exp.X_op == O_constant)
   2911  1.1.1.4  christos 		    extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
   2912  1.1.1.4  christos 
   2913  1.1.1.4  christos 		  else if (op1.reg || op1.am == 3)	/* Not PC relative.  */
   2914  1.1.1.4  christos 		    fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
   2915  1.1.1.4  christos 				 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
   2916  1.1.1.4  christos 		  else
   2917  1.1.1.4  christos 		    fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
   2918  1.1.1.4  christos 				 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
   2919  1.1.1.4  christos 		}
   2920  1.1.1.4  christos 
   2921  1.1.1.4  christos 	      if (op2.mode == OP_EXP)
   2922  1.1.1.4  christos 		{
   2923  1.1.1.4  christos 		  if (op2.exp.X_op == O_constant)
   2924  1.1.1.4  christos 		    extended |= (op2.exp.X_add_number >> 16) & 0xf;
   2925  1.1.1.4  christos 
   2926  1.1.1.4  christos 		  else if (op1.mode == OP_EXP)
   2927  1.1.1.4  christos 		    fix_new_exp (frag_now, where, 8, &(op2.exp), FALSE,
   2928  1.1.1.4  christos 				 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_ODST
   2929  1.1.1.4  christos 				 : BFD_RELOC_MSP430X_PCR20_EXT_ODST);
   2930  1.1.1.4  christos 		  else
   2931  1.1.1.4  christos 		    fix_new_exp (frag_now, where, 6, &(op2.exp), FALSE,
   2932  1.1.1.4  christos 				 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_DST
   2933  1.1.1.4  christos 				 : BFD_RELOC_MSP430X_PCR20_EXT_DST);
   2934  1.1.1.4  christos 		}
   2935  1.1.1.4  christos 
   2936  1.1.1.4  christos 	      /* Emit the extension word.  */
   2937  1.1.1.4  christos 	      bfd_putl16 (extended, frag);
   2938  1.1.1.4  christos 	      frag += 2;
   2939  1.1.1.4  christos 	      where += 2;
   2940  1.1.1.4  christos 	    }
   2941  1.1.1.4  christos 
   2942  1.1.1.4  christos 	  bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
   2943  1.1.1.4  christos 	  bfd_putl16 ((bfd_vma) bin, frag);
   2944  1.1.1.4  christos 	  frag += 2;
   2945  1.1.1.4  christos 	  where += 2;
   2946  1.1.1.4  christos 
   2947  1.1.1.4  christos 	  if (op1.mode == OP_EXP)
   2948  1.1.1.4  christos 	    {
   2949  1.1.1.4  christos 	      if (op1.exp.X_op == O_constant)
   2950  1.1.1.4  christos 		{
   2951  1.1.1.4  christos 		  bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
   2952  1.1.1.4  christos 		}
   2953  1.1.1.4  christos 	      else
   2954  1.1.1.4  christos 		{
   2955  1.1.1.4  christos 		  bfd_putl16 ((bfd_vma) ZEROS, frag);
   2956  1.1.1.4  christos 
   2957  1.1.1.4  christos 		  if (!extended_op)
   2958  1.1.1.4  christos 		    {
   2959  1.1.1.4  christos 		      if (op1.reg || op1.am == 3)	/* Not PC relative.  */
   2960  1.1.1.4  christos 			fix_new_exp (frag_now, where, 2,
   2961  1.1.1.4  christos 				     &(op1.exp), FALSE, CHECK_RELOC_MSP430 (op1));
   2962  1.1.1.4  christos 		      else
   2963  1.1.1.4  christos 			fix_new_exp (frag_now, where, 2,
   2964  1.1.1.4  christos 				     &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
   2965  1.1.1.4  christos 		    }
   2966  1.1.1.4  christos 		}
   2967  1.1.1.4  christos 	      frag += 2;
   2968  1.1.1.4  christos 	      where += 2;
   2969  1.1.1.4  christos 	    }
   2970  1.1.1.4  christos 
   2971  1.1.1.4  christos 	  if (op2.mode == OP_EXP)
   2972  1.1.1.4  christos 	    {
   2973  1.1.1.4  christos 	      if (op2.exp.X_op == O_constant)
   2974  1.1.1.4  christos 		{
   2975  1.1.1.4  christos 		  bfd_putl16 (op2.exp.X_add_number & 0xffff, frag);
   2976  1.1.1.4  christos 		}
   2977  1.1.1.4  christos 	      else
   2978  1.1.1.4  christos 		{
   2979  1.1.1.4  christos 		  bfd_putl16 ((bfd_vma) ZEROS, frag);
   2980  1.1.1.4  christos 
   2981  1.1.1.4  christos 		  if (!extended_op)
   2982  1.1.1.4  christos 		    {
   2983  1.1.1.4  christos 		      if (op2.reg)	/* Not PC relative.  */
   2984  1.1.1.4  christos 			fix_new_exp (frag_now, where, 2,
   2985  1.1.1.4  christos 				     &(op2.exp), FALSE, CHECK_RELOC_MSP430 (op2));
   2986  1.1.1.4  christos 		      else
   2987  1.1.1.4  christos 			fix_new_exp (frag_now, where, 2,
   2988  1.1.1.4  christos 				     &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
   2989  1.1.1.4  christos 		    }
   2990  1.1.1.4  christos 		}
   2991  1.1.1.4  christos 	    }
   2992  1.1.1.4  christos 
   2993  1.1.1.4  christos 	  dwarf2_emit_insn (insn_length);
   2994  1.1.1.4  christos 	  break;
   2995  1.1.1.4  christos 
   2996  1.1.1.4  christos 	case 3:
   2997  1.1.1.4  christos 	  /* Branch instruction => mov dst, r0.  */
   2998  1.1.1.4  christos 	  if (extended_op)
   2999  1.1.1.4  christos 	    {
   3000  1.1.1.4  christos 	      as_bad ("Internal error: state 0/3 not coded for extended instructions");
   3001  1.1.1.4  christos 	      break;
   3002  1.1.1.4  christos 	    }
   3003  1.1.1.4  christos 
   3004  1.1.1.4  christos 	  line = extract_operand (line, l1, sizeof (l1));
   3005  1.1.1.4  christos 	  res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op, extended_op, FALSE);
   3006  1.1.1.4  christos 	  if (res)
   3007  1.1.1.4  christos 	    break;
   3008  1.1.1.4  christos 
   3009  1.1.1.4  christos 	  byte_op = FALSE;
   3010  1.1.1.4  christos 	  imm_op = FALSE;
   3011  1.1.1.4  christos 	  bin |= ((op1.reg << 8) | (op1.am << 4));
   3012  1.1.1.4  christos 	  op_length = 2 + 2 * op1.ol;
   3013  1.1.1.4  christos 	  frag = frag_more (op_length);
   3014  1.1.1.4  christos 	  where = frag - frag_now->fr_literal;
   3015  1.1.1.4  christos 	  bfd_putl16 ((bfd_vma) bin, frag);
   3016  1.1.1.4  christos 
   3017  1.1.1.4  christos 	  if (op1.mode == OP_EXP)
   3018  1.1.1.4  christos 	    {
   3019  1.1.1.4  christos 	      if (op1.exp.X_op == O_constant)
   3020  1.1.1.4  christos 		{
   3021  1.1.1.4  christos 		  bfd_putl16 (op1.exp.X_add_number & 0xffff, frag + 2);
   3022  1.1.1.4  christos 		}
   3023  1.1.1.4  christos 	      else
   3024  1.1.1.4  christos 		{
   3025  1.1.1.4  christos 		  where += 2;
   3026  1.1.1.4  christos 
   3027  1.1.1.4  christos 		  bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
   3028  1.1.1.4  christos 
   3029  1.1.1.4  christos 		  if (op1.reg || op1.am == 3)
   3030  1.1.1.4  christos 		    fix_new_exp (frag_now, where, 2,
   3031  1.1.1.4  christos 				 &(op1.exp), FALSE, CHECK_RELOC_MSP430 (op1));
   3032  1.1.1.4  christos 		  else
   3033  1.1.1.4  christos 		    fix_new_exp (frag_now, where, 2,
   3034  1.1.1.4  christos 				 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
   3035  1.1.1.4  christos 		}
   3036  1.1.1.4  christos 	    }
   3037  1.1.1.4  christos 
   3038  1.1.1.4  christos 	  dwarf2_emit_insn (insn_length + op_length);
   3039  1.1.1.4  christos 	  break;
   3040  1.1.1.4  christos 
   3041  1.1.1.4  christos 	case 4:
   3042  1.1.1.4  christos 	  /* CALLA instructions.  */
   3043  1.1.1.4  christos 	  fix_emitted = FALSE;
   3044  1.1.1.4  christos 
   3045  1.1.1.4  christos 	  line = extract_operand (line, l1, sizeof (l1));
   3046  1.1.1.4  christos 	  imm_op = FALSE;
   3047  1.1.1.4  christos 
   3048  1.1.1.4  christos 	  res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op,
   3049  1.1.1.4  christos 				   extended_op, FALSE);
   3050  1.1.1.4  christos 	  if (res)
   3051  1.1.1.4  christos 	    break;
   3052  1.1.1.4  christos 
   3053  1.1.1.4  christos 	  byte_op = FALSE;
   3054  1.1.1.4  christos 
   3055  1.1.1.4  christos 	  op_length = 2 + 2 * op1.ol;
   3056  1.1.1.4  christos 	  frag = frag_more (op_length);
   3057  1.1.1.4  christos 	  where = frag - frag_now->fr_literal;
   3058  1.1.1.4  christos 
   3059  1.1.1.4  christos 	  if (imm_op)
   3060  1.1.1.4  christos 	    {
   3061  1.1.1.4  christos 	      if (op1.am == 3)
   3062  1.1.1.4  christos 		{
   3063  1.1.1.4  christos 		  bin |= 0xb0;
   3064  1.1.1.4  christos 
   3065  1.1.1.4  christos 		  fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
   3066  1.1.1.4  christos 			       BFD_RELOC_MSP430X_ABS20_ADR_DST);
   3067  1.1.1.4  christos 		  fix_emitted = TRUE;
   3068  1.1.1.4  christos 		}
   3069  1.1.1.4  christos 	      else if (op1.am == 1)
   3070  1.1.1.4  christos 		{
   3071  1.1.1.4  christos 		  if (op1.reg == 0)
   3072  1.1.1.4  christos 		    {
   3073  1.1.1.4  christos 		      bin |=  0x90;
   3074  1.1.1.4  christos 
   3075  1.1.1.4  christos 		      fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
   3076  1.1.1.4  christos 				   BFD_RELOC_MSP430X_PCR20_CALL);
   3077  1.1.1.4  christos 		      fix_emitted = TRUE;
   3078  1.1.1.4  christos 		    }
   3079  1.1.1.4  christos 		  else
   3080  1.1.1.4  christos 		    bin |=  0x50 | op1.reg;
   3081  1.1.1.4  christos 		}
   3082  1.1.1.4  christos 	      else if (op1.am == 0)
   3083  1.1.1.4  christos 		bin |= 0x40 | op1.reg;
   3084  1.1.1.4  christos 	    }
   3085  1.1.1.4  christos 	  else if (op1.am == 1)
   3086  1.1.1.4  christos 	    {
   3087  1.1.1.4  christos 	      bin |= 0x80;
   3088  1.1.1.4  christos 
   3089  1.1.1.4  christos 	      fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
   3090  1.1.1.4  christos 			   BFD_RELOC_MSP430X_ABS20_ADR_DST);
   3091  1.1.1.4  christos 	      fix_emitted = TRUE;
   3092  1.1.1.4  christos 	    }
   3093  1.1.1.4  christos 	  else if (op1.am == 2)
   3094  1.1.1.4  christos 	    bin |= 0x60 | op1.reg;
   3095  1.1.1.4  christos 	  else if (op1.am == 3)
   3096  1.1.1.4  christos 	    bin |= 0x70 | op1.reg;
   3097  1.1.1.4  christos 
   3098  1.1.1.4  christos 	  bfd_putl16 ((bfd_vma) bin, frag);
   3099  1.1.1.4  christos 
   3100  1.1.1.4  christos 	  if (op1.mode == OP_EXP)
   3101  1.1.1.4  christos 	    {
   3102  1.1.1.4  christos 	      if (op1.ol != 1)
   3103  1.1.1.4  christos 		{
   3104  1.1.1.4  christos 		  as_bad ("Internal error: unexpected CALLA instruction length: %d\n", op1.ol);
   3105  1.1.1.4  christos 		  break;
   3106  1.1.1.4  christos 		}
   3107  1.1.1.4  christos 
   3108  1.1.1.4  christos 	      bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
   3109  1.1.1.4  christos 
   3110  1.1.1.4  christos 	      if (! fix_emitted)
   3111  1.1.1.4  christos 		fix_new_exp (frag_now, where + 2, 2,
   3112  1.1.1.4  christos 			     &(op1.exp), FALSE, BFD_RELOC_16);
   3113  1.1.1.4  christos 	    }
   3114  1.1.1.4  christos 
   3115  1.1.1.4  christos 	  dwarf2_emit_insn (insn_length + op_length);
   3116  1.1.1.4  christos 	  break;
   3117  1.1.1.4  christos 
   3118  1.1.1.4  christos 	case 5:
   3119      1.1     skrll 	  {
   3120  1.1.1.4  christos 	    int n;
   3121  1.1.1.4  christos 	    int reg;
   3122  1.1.1.4  christos 
   3123  1.1.1.4  christos 	    /* [POP|PUSH]M[.A] #N, Rd */
   3124      1.1     skrll 	    line = extract_operand (line, l1, sizeof (l1));
   3125  1.1.1.4  christos 	    line = extract_operand (line, l2, sizeof (l2));
   3126      1.1     skrll 
   3127  1.1.1.4  christos 	    if (*l1 != '#')
   3128  1.1.1.4  christos 	      {
   3129  1.1.1.4  christos 		as_bad (_("expected #n as first argument of %s"), opcode->name);
   3130  1.1.1.4  christos 		break;
   3131  1.1.1.4  christos 	      }
   3132  1.1.1.6  christos 	    end = parse_exp (l1 + 1, &(op1.exp));
   3133  1.1.1.6  christos 	    if (end != NULL && *end != 0)
   3134  1.1.1.6  christos 	      {
   3135  1.1.1.6  christos 		as_bad (_("extra characters '%s' at end of constant expression '%s'"), end, l1);
   3136  1.1.1.6  christos 		break;
   3137  1.1.1.6  christos 	      }
   3138  1.1.1.4  christos 	    if (op1.exp.X_op != O_constant)
   3139  1.1.1.4  christos 	      {
   3140  1.1.1.6  christos 		as_bad (_("expected constant expression as first argument of %s"),
   3141  1.1.1.4  christos 			opcode->name);
   3142  1.1.1.4  christos 		break;
   3143  1.1.1.4  christos 	      }
   3144      1.1     skrll 
   3145  1.1.1.4  christos 	    if ((reg = check_reg (l2)) == -1)
   3146  1.1.1.4  christos 	      {
   3147  1.1.1.4  christos 		as_bad (_("expected register as second argument of %s"),
   3148  1.1.1.4  christos 			opcode->name);
   3149  1.1.1.4  christos 		break;
   3150  1.1.1.4  christos 	      }
   3151      1.1     skrll 
   3152  1.1.1.4  christos 	    op_length = 2;
   3153  1.1.1.4  christos 	    frag = frag_more (op_length);
   3154      1.1     skrll 	    where = frag - frag_now->fr_literal;
   3155  1.1.1.4  christos 	    bin = opcode->bin_opcode;
   3156  1.1.1.4  christos 	    if (! addr_op)
   3157  1.1.1.4  christos 	      bin |= 0x100;
   3158  1.1.1.4  christos 	    n = op1.exp.X_add_number;
   3159  1.1.1.4  christos 	    bin |= (n - 1) << 4;
   3160  1.1.1.4  christos 	    if (is_opcode ("pushm"))
   3161  1.1.1.4  christos 	      bin |= reg;
   3162  1.1.1.4  christos 	    else
   3163  1.1.1.4  christos 	      {
   3164  1.1.1.4  christos 		if (reg - n + 1 < 0)
   3165  1.1.1.4  christos 		  {
   3166  1.1.1.4  christos 		    as_bad (_("Too many registers popped"));
   3167  1.1.1.4  christos 		    break;
   3168  1.1.1.4  christos 		  }
   3169  1.1.1.4  christos 
   3170  1.1.1.4  christos 		/* CPU21 errata: cannot use POPM to restore the SR register.  */
   3171  1.1.1.4  christos 		if (target_is_430xv2 ()
   3172  1.1.1.4  christos 		    && (reg - n + 1 < 3)
   3173  1.1.1.4  christos 		    && reg >= 2
   3174  1.1.1.4  christos 		    && is_opcode ("popm"))
   3175  1.1.1.4  christos 		  {
   3176  1.1.1.4  christos 		    as_bad (_("Cannot use POPM to restore the SR register"));
   3177  1.1.1.4  christos 		    break;
   3178  1.1.1.4  christos 		  }
   3179  1.1.1.4  christos 
   3180  1.1.1.4  christos 		bin |= (reg - n + 1);
   3181  1.1.1.4  christos 	      }
   3182  1.1.1.4  christos 
   3183      1.1     skrll 	    bfd_putl16 ((bfd_vma) bin, frag);
   3184  1.1.1.4  christos 	    dwarf2_emit_insn (op_length);
   3185  1.1.1.4  christos 	    break;
   3186  1.1.1.4  christos 	  }
   3187  1.1.1.4  christos 
   3188  1.1.1.4  christos 	case 6:
   3189  1.1.1.4  christos 	  {
   3190  1.1.1.4  christos 	    int n;
   3191  1.1.1.4  christos 	    int reg;
   3192  1.1.1.4  christos 
   3193  1.1.1.4  christos 	    /* Bit rotation instructions. RRCM, RRAM, RRUM, RLAM.  */
   3194  1.1.1.4  christos 	    if (extended & 0xff)
   3195  1.1.1.4  christos 	      {
   3196  1.1.1.4  christos 		as_bad (_("repeat count cannot be used with %s"), opcode->name);
   3197  1.1.1.4  christos 		break;
   3198      1.1     skrll 	      }
   3199      1.1     skrll 
   3200  1.1.1.4  christos 	    line = extract_operand (line, l1, sizeof (l1));
   3201  1.1.1.4  christos 	    line = extract_operand (line, l2, sizeof (l2));
   3202  1.1.1.4  christos 
   3203  1.1.1.4  christos 	    if (*l1 != '#')
   3204  1.1.1.4  christos 	      {
   3205  1.1.1.4  christos 		as_bad (_("expected #n as first argument of %s"), opcode->name);
   3206  1.1.1.4  christos 		break;
   3207  1.1.1.4  christos 	      }
   3208  1.1.1.6  christos 	    end = parse_exp (l1 + 1, &(op1.exp));
   3209  1.1.1.6  christos 	    if (end != NULL && *end != 0)
   3210  1.1.1.6  christos 	      {
   3211  1.1.1.6  christos 		as_bad (_("extra characters '%s' at end of operand '%s'"), end, l1);
   3212  1.1.1.6  christos 		break;
   3213  1.1.1.6  christos 	      }
   3214  1.1.1.4  christos 	    if (op1.exp.X_op != O_constant)
   3215  1.1.1.4  christos 	      {
   3216  1.1.1.6  christos 		as_bad (_("expected constant expression as first argument of %s"),
   3217  1.1.1.4  christos 			opcode->name);
   3218  1.1.1.4  christos 		break;
   3219  1.1.1.4  christos 	      }
   3220  1.1.1.4  christos 	    n = op1.exp.X_add_number;
   3221  1.1.1.4  christos 	    if (n > 4 || n < 1)
   3222      1.1     skrll 	      {
   3223  1.1.1.4  christos 		as_bad (_("expected first argument of %s to be in the range 1-4"),
   3224  1.1.1.4  christos 			opcode->name);
   3225  1.1.1.4  christos 		break;
   3226  1.1.1.4  christos 	      }
   3227      1.1     skrll 
   3228  1.1.1.4  christos 	    if ((reg = check_reg (l2)) == -1)
   3229  1.1.1.4  christos 	      {
   3230  1.1.1.4  christos 		as_bad (_("expected register as second argument of %s"),
   3231  1.1.1.4  christos 			opcode->name);
   3232  1.1.1.4  christos 		break;
   3233  1.1.1.4  christos 	      }
   3234  1.1.1.4  christos 
   3235  1.1.1.4  christos 	    if (target_is_430xv2 () && reg == 0)
   3236  1.1.1.4  christos 	      {
   3237  1.1.1.4  christos 		as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
   3238  1.1.1.4  christos 		break;
   3239      1.1     skrll 	      }
   3240  1.1.1.4  christos 
   3241  1.1.1.4  christos 	    op_length = 2;
   3242  1.1.1.4  christos 	    frag = frag_more (op_length);
   3243  1.1.1.4  christos 	    where = frag - frag_now->fr_literal;
   3244  1.1.1.4  christos 
   3245  1.1.1.4  christos 	    bin = opcode->bin_opcode;
   3246  1.1.1.4  christos 	    if (! addr_op)
   3247  1.1.1.4  christos 	      bin |= 0x10;
   3248  1.1.1.4  christos 	    bin |= (n - 1) << 10;
   3249  1.1.1.4  christos 	    bin |= reg;
   3250  1.1.1.4  christos 
   3251  1.1.1.4  christos 	    bfd_putl16 ((bfd_vma) bin, frag);
   3252  1.1.1.4  christos 	    dwarf2_emit_insn (op_length);
   3253      1.1     skrll 	    break;
   3254      1.1     skrll 	  }
   3255      1.1     skrll 
   3256  1.1.1.4  christos 	case 8:
   3257  1.1.1.4  christos 	  {
   3258  1.1.1.4  christos 	    bfd_boolean need_reloc = FALSE;
   3259  1.1.1.4  christos 	    int n;
   3260  1.1.1.4  christos 	    int reg;
   3261  1.1.1.4  christos 
   3262  1.1.1.4  christos 	    /* ADDA, CMPA and SUBA address instructions.  */
   3263  1.1.1.4  christos 	    if (extended & 0xff)
   3264  1.1.1.4  christos 	      {
   3265  1.1.1.4  christos 		as_bad (_("repeat count cannot be used with %s"), opcode->name);
   3266  1.1.1.4  christos 		break;
   3267  1.1.1.4  christos 	      }
   3268  1.1.1.4  christos 
   3269  1.1.1.4  christos 	    line = extract_operand (line, l1, sizeof (l1));
   3270  1.1.1.4  christos 	    line = extract_operand (line, l2, sizeof (l2));
   3271  1.1.1.4  christos 
   3272  1.1.1.4  christos 	    bin = opcode->bin_opcode;
   3273  1.1.1.4  christos 
   3274  1.1.1.4  christos 	    if (*l1 == '#')
   3275  1.1.1.4  christos 	      {
   3276  1.1.1.6  christos 		end = parse_exp (l1 + 1, &(op1.exp));
   3277  1.1.1.6  christos 		if (end != NULL && *end != 0)
   3278  1.1.1.6  christos 		  {
   3279  1.1.1.6  christos 		    as_bad (_("extra characters '%s' at end of operand '%s'"), end, l1);
   3280  1.1.1.6  christos 		    break;
   3281  1.1.1.6  christos 		  }
   3282  1.1.1.4  christos 
   3283  1.1.1.4  christos 		if (op1.exp.X_op == O_constant)
   3284  1.1.1.4  christos 		  {
   3285  1.1.1.4  christos 		    n = op1.exp.X_add_number;
   3286  1.1.1.4  christos 		    if (n > 0xfffff || n < - (0x7ffff))
   3287  1.1.1.4  christos 		      {
   3288  1.1.1.4  christos 			as_bad (_("expected value of first argument of %s to fit into 20-bits"),
   3289  1.1.1.4  christos 				opcode->name);
   3290  1.1.1.4  christos 			break;
   3291  1.1.1.4  christos 		      }
   3292  1.1.1.4  christos 
   3293  1.1.1.4  christos 		    bin |= ((n >> 16) & 0xf) << 8;
   3294  1.1.1.4  christos 		  }
   3295  1.1.1.4  christos 		else
   3296  1.1.1.4  christos 		  {
   3297  1.1.1.4  christos 		    n = 0;
   3298  1.1.1.4  christos 		    need_reloc = TRUE;
   3299  1.1.1.4  christos 		  }
   3300  1.1.1.4  christos 
   3301  1.1.1.4  christos 		op_length = 4;
   3302  1.1.1.4  christos 	      }
   3303  1.1.1.4  christos 	    else
   3304  1.1.1.4  christos 	      {
   3305  1.1.1.4  christos 		if ((n = check_reg (l1)) == -1)
   3306  1.1.1.4  christos 		  {
   3307  1.1.1.4  christos 		    as_bad (_("expected register name or constant as first argument of %s"),
   3308  1.1.1.4  christos 			    opcode->name);
   3309  1.1.1.4  christos 		    break;
   3310  1.1.1.4  christos 		  }
   3311  1.1.1.4  christos 
   3312  1.1.1.4  christos 		bin |= (n << 8) | (1 << 6);
   3313  1.1.1.4  christos 		op_length = 2;
   3314  1.1.1.4  christos 	      }
   3315  1.1.1.4  christos 
   3316  1.1.1.4  christos 	    if ((reg = check_reg (l2)) == -1)
   3317  1.1.1.4  christos 	      {
   3318  1.1.1.4  christos 		as_bad (_("expected register as second argument of %s"),
   3319  1.1.1.4  christos 			opcode->name);
   3320  1.1.1.4  christos 		break;
   3321  1.1.1.4  christos 	      }
   3322  1.1.1.4  christos 
   3323  1.1.1.4  christos 	    frag = frag_more (op_length);
   3324  1.1.1.4  christos 	    where = frag - frag_now->fr_literal;
   3325  1.1.1.4  christos 	    bin |= reg;
   3326  1.1.1.4  christos 	    if (need_reloc)
   3327  1.1.1.4  christos 	      fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
   3328  1.1.1.4  christos 			   BFD_RELOC_MSP430X_ABS20_ADR_SRC);
   3329  1.1.1.4  christos 
   3330  1.1.1.4  christos 	    bfd_putl16 ((bfd_vma) bin, frag);
   3331  1.1.1.4  christos 	    if (op_length == 4)
   3332  1.1.1.4  christos 	      bfd_putl16 ((bfd_vma) (n & 0xffff), frag + 2);
   3333  1.1.1.4  christos 	    dwarf2_emit_insn (op_length);
   3334      1.1     skrll 	    break;
   3335  1.1.1.4  christos 	  }
   3336  1.1.1.4  christos 
   3337  1.1.1.4  christos 	case 9: /* MOVA, BRA, RETA.  */
   3338  1.1.1.4  christos 	  imm_op = FALSE;
   3339  1.1.1.4  christos 	  bin = opcode->bin_opcode;
   3340  1.1.1.4  christos 
   3341  1.1.1.4  christos 	  if (is_opcode ("reta"))
   3342  1.1.1.4  christos 	    {
   3343  1.1.1.4  christos 	      /* The RETA instruction does not take any arguments.
   3344  1.1.1.4  christos 		 The implicit first argument is @SP+.
   3345  1.1.1.4  christos 		 The implicit second argument is PC.  */
   3346  1.1.1.4  christos 	      op1.mode = OP_REG;
   3347  1.1.1.4  christos 	      op1.am = 3;
   3348  1.1.1.4  christos 	      op1.reg = 1;
   3349  1.1.1.4  christos 
   3350  1.1.1.4  christos 	      op2.mode = OP_REG;
   3351  1.1.1.4  christos 	      op2.reg = 0;
   3352  1.1.1.4  christos 	    }
   3353  1.1.1.4  christos 	  else
   3354  1.1.1.4  christos 	    {
   3355  1.1.1.4  christos 	      line = extract_operand (line, l1, sizeof (l1));
   3356  1.1.1.4  christos 	      res = msp430_srcoperand (&op1, l1, opcode->bin_opcode,
   3357  1.1.1.4  christos 				       &imm_op, extended_op, FALSE);
   3358  1.1.1.4  christos 
   3359  1.1.1.4  christos 	      if (is_opcode ("bra"))
   3360  1.1.1.4  christos 		{
   3361  1.1.1.4  christos 		  /* This is the BRA synthetic instruction.
   3362  1.1.1.4  christos 		     The second argument is always PC.  */
   3363  1.1.1.4  christos 		  op2.mode = OP_REG;
   3364  1.1.1.4  christos 		  op2.reg = 0;
   3365  1.1.1.4  christos 		}
   3366  1.1.1.4  christos 	      else
   3367  1.1.1.4  christos 		{
   3368  1.1.1.4  christos 		  line = extract_operand (line, l2, sizeof (l2));
   3369  1.1.1.4  christos 		  res += msp430_dstoperand (&op2, l2, opcode->bin_opcode,
   3370  1.1.1.4  christos 					    extended_op, TRUE);
   3371  1.1.1.4  christos 		}
   3372  1.1.1.4  christos 
   3373  1.1.1.4  christos 	      if (res)
   3374  1.1.1.4  christos 		break;	/* Error occurred.  All warnings were done before.  */
   3375  1.1.1.4  christos 	    }
   3376      1.1     skrll 
   3377  1.1.1.4  christos 	  /* Only a restricted subset of the normal MSP430 addressing modes
   3378  1.1.1.4  christos 	     are supported here, so check for the ones that are allowed.  */
   3379  1.1.1.4  christos 	  if ((op_length = try_encode_mova (imm_op, bin, & op1, & op2,
   3380  1.1.1.4  christos 					    & error_message)) == 0)
   3381  1.1.1.4  christos 	    {
   3382  1.1.1.4  christos 	      as_bad (error_message, opcode->name);
   3383  1.1.1.4  christos 	      break;
   3384  1.1.1.4  christos 	    }
   3385  1.1.1.4  christos 	  dwarf2_emit_insn (op_length);
   3386  1.1.1.4  christos 	  break;
   3387      1.1     skrll 
   3388  1.1.1.4  christos 	case 10: /* RPT */
   3389  1.1.1.4  christos 	  line = extract_operand (line, l1, sizeof l1);
   3390  1.1.1.4  christos 	  /* The RPT instruction only accepted immediates and registers.  */
   3391  1.1.1.4  christos 	  if (*l1 == '#')
   3392  1.1.1.4  christos 	    {
   3393  1.1.1.6  christos 	      end = parse_exp (l1 + 1, &(op1.exp));
   3394  1.1.1.6  christos 	      if (end != NULL && *end != 0)
   3395  1.1.1.6  christos 		{
   3396  1.1.1.6  christos 		  as_bad (_("extra characters '%s' at end of operand '%s'"), end, l1);
   3397  1.1.1.6  christos 		  break;
   3398  1.1.1.6  christos 		}
   3399  1.1.1.4  christos 	      if (op1.exp.X_op != O_constant)
   3400  1.1.1.4  christos 		{
   3401  1.1.1.4  christos 		  as_bad (_("expected constant value as argument to RPT"));
   3402  1.1.1.4  christos 		  break;
   3403  1.1.1.4  christos 		}
   3404  1.1.1.4  christos 	      if (op1.exp.X_add_number < 1
   3405  1.1.1.4  christos 		  || op1.exp.X_add_number > (1 << 4))
   3406  1.1.1.4  christos 		{
   3407  1.1.1.4  christos 		  as_bad (_("expected constant in the range 2..16"));
   3408  1.1.1.4  christos 		  break;
   3409  1.1.1.4  christos 		}
   3410      1.1     skrll 
   3411  1.1.1.4  christos 	      /* We silently accept and ignore a repeat count of 1.  */
   3412  1.1.1.4  christos 	      if (op1.exp.X_add_number > 1)
   3413  1.1.1.4  christos 		repeat_count = op1.exp.X_add_number;
   3414  1.1.1.4  christos 	    }
   3415  1.1.1.4  christos 	  else
   3416      1.1     skrll 	    {
   3417  1.1.1.4  christos 	      int reg;
   3418      1.1     skrll 
   3419  1.1.1.4  christos 	      if ((reg = check_reg (l1)) != -1)
   3420  1.1.1.4  christos 		{
   3421  1.1.1.4  christos 		  if (reg == 0)
   3422  1.1.1.4  christos 		    as_warn (_("PC used as an argument to RPT"));
   3423  1.1.1.4  christos 		  else
   3424  1.1.1.4  christos 		    repeat_count = - reg;
   3425  1.1.1.4  christos 		}
   3426      1.1     skrll 	      else
   3427  1.1.1.4  christos 		{
   3428  1.1.1.4  christos 		  as_bad (_("expected constant or register name as argument to RPT insn"));
   3429  1.1.1.4  christos 		  break;
   3430  1.1.1.4  christos 		}
   3431      1.1     skrll 	    }
   3432      1.1     skrll 	  break;
   3433  1.1.1.4  christos 
   3434  1.1.1.4  christos 	default:
   3435  1.1.1.6  christos 	  as_bad (_("Illegal emulated instruction"));
   3436  1.1.1.4  christos 	  break;
   3437      1.1     skrll 	}
   3438      1.1     skrll       break;
   3439      1.1     skrll 
   3440      1.1     skrll     case 1:			/* Format 1, double operand.  */
   3441      1.1     skrll       line = extract_operand (line, l1, sizeof (l1));
   3442      1.1     skrll       line = extract_operand (line, l2, sizeof (l2));
   3443  1.1.1.4  christos       res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op, extended_op, TRUE);
   3444  1.1.1.4  christos       res += msp430_dstoperand (&op2, l2, opcode->bin_opcode, extended_op, TRUE);
   3445      1.1     skrll 
   3446      1.1     skrll       if (res)
   3447      1.1     skrll 	break;			/* Error occurred.  All warnings were done before.  */
   3448      1.1     skrll 
   3449  1.1.1.4  christos       if (extended_op
   3450  1.1.1.4  christos 	  && is_opcode ("movx")
   3451  1.1.1.4  christos 	  && addr_op
   3452  1.1.1.4  christos 	  && msp430_enable_relax)
   3453  1.1.1.4  christos 	{
   3454  1.1.1.4  christos 	  /* This is the MOVX.A instruction.  See if we can convert
   3455  1.1.1.4  christos 	     it into the MOVA instruction instead.  This saves 2 bytes.  */
   3456  1.1.1.4  christos 	  if ((op_length = try_encode_mova (imm_op, 0x0000, & op1, & op2,
   3457  1.1.1.4  christos 					    NULL)) != 0)
   3458  1.1.1.4  christos 	    {
   3459  1.1.1.4  christos 	      dwarf2_emit_insn (op_length);
   3460  1.1.1.4  christos 	      break;
   3461  1.1.1.4  christos 	    }
   3462  1.1.1.4  christos 	}
   3463  1.1.1.4  christos 
   3464      1.1     skrll       bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
   3465      1.1     skrll 
   3466  1.1.1.4  christos       /* If the PC is the destination...  */
   3467  1.1.1.4  christos       if (op2.am == 0 && op2.reg == 0
   3468  1.1.1.4  christos 	  /* ... and the opcode alters the SR.  */
   3469  1.1.1.4  christos 	  && !(is_opcode ("bic") || is_opcode ("bis") || is_opcode ("mov")
   3470  1.1.1.4  christos 	       || is_opcode ("bicx") || is_opcode ("bisx") || is_opcode ("movx")))
   3471  1.1.1.4  christos 	{
   3472  1.1.1.4  christos 	  if (silicon_errata_fix & SILICON_ERRATA_CPU11)
   3473  1.1.1.6  christos 	    as_bad (_("CPU11: PC is destination of SR altering instruction"));
   3474  1.1.1.4  christos 	  else if (silicon_errata_warn & SILICON_ERRATA_CPU11)
   3475  1.1.1.6  christos 	    as_warn (_("CPU11: PC is destination of SR altering instruction"));
   3476  1.1.1.4  christos 	}
   3477  1.1.1.4  christos 
   3478  1.1.1.4  christos       /* If the status register is the destination...  */
   3479  1.1.1.4  christos       if (op2.am == 0 && op2.reg == 2
   3480  1.1.1.4  christos 	  /* ... and the opcode alters the SR.  */
   3481  1.1.1.4  christos 	  && (is_opcode ("add") || is_opcode ("addc") || is_opcode ("and")
   3482  1.1.1.4  christos 	      || is_opcode ("dadd") || is_opcode ("sub") || is_opcode ("subc")
   3483  1.1.1.4  christos 	      || is_opcode ("xor")
   3484  1.1.1.4  christos 	      || is_opcode ("addx") || is_opcode ("addcx") || is_opcode ("andx")
   3485  1.1.1.4  christos 	      || is_opcode ("daddx") || is_opcode ("subx") || is_opcode ("subcx")
   3486  1.1.1.4  christos 	      || is_opcode ("xorx")
   3487  1.1.1.4  christos 	      ))
   3488  1.1.1.4  christos 	{
   3489  1.1.1.4  christos 	  if (silicon_errata_fix & SILICON_ERRATA_CPU13)
   3490  1.1.1.6  christos 	    as_bad (_("CPU13: SR is destination of SR altering instruction"));
   3491  1.1.1.4  christos 	  else if (silicon_errata_warn & SILICON_ERRATA_CPU13)
   3492  1.1.1.6  christos 	    as_warn (_("CPU13: SR is destination of SR altering instruction"));
   3493  1.1.1.4  christos 	}
   3494  1.1.1.4  christos 
   3495  1.1.1.4  christos       if (   (is_opcode ("bic") && bin == 0xc232)
   3496  1.1.1.4  christos 	  || (is_opcode ("bis") && bin == 0xd232)
   3497  1.1.1.4  christos 	  || (is_opcode ("mov") && op2.mode == OP_REG && op2.reg == 2))
   3498  1.1.1.4  christos 	{
   3499  1.1.1.4  christos 	  /* Avoid false checks when a constant value is being put into the SR.  */
   3500  1.1.1.4  christos 	  if (op1.mode == OP_EXP
   3501  1.1.1.4  christos 	      && op1.exp.X_op == O_constant
   3502  1.1.1.4  christos 	      && (op1.exp.X_add_number & 0x8) != 0x8)
   3503  1.1.1.4  christos 	    ;
   3504  1.1.1.4  christos 	  else
   3505  1.1.1.4  christos 	    check_for_nop |= NOP_CHECK_INTERRUPT;
   3506  1.1.1.4  christos 	}
   3507  1.1.1.4  christos 
   3508  1.1.1.4  christos       if (((is_opcode ("bis") && bin == 0xd032)
   3509  1.1.1.4  christos 	   || (is_opcode ("mov") && bin == 0x4032)
   3510  1.1.1.4  christos 	   || (is_opcode ("xor") && bin == 0xe032))
   3511  1.1.1.4  christos 	  && op1.mode == OP_EXP
   3512  1.1.1.4  christos 	  && op1.exp.X_op == O_constant
   3513  1.1.1.4  christos 	  && (op1.exp.X_add_number & 0x10) == 0x10)
   3514  1.1.1.4  christos 	check_for_nop |= NOP_CHECK_CPU19;
   3515  1.1.1.4  christos 
   3516  1.1.1.4  christos       /* Compute the entire length of the instruction in bytes.  */
   3517  1.1.1.4  christos       op_length = (extended_op ? 2 : 0)	/* The extension word.  */
   3518  1.1.1.4  christos 	+ 2 			/* The opcode */
   3519  1.1.1.4  christos 	+ (2 * op1.ol)		/* The first operand. */
   3520  1.1.1.4  christos 	+ (2 * op2.ol);		/* The second operand.  */
   3521  1.1.1.4  christos 
   3522  1.1.1.4  christos       insn_length += op_length;
   3523  1.1.1.4  christos       frag = frag_more (op_length);
   3524      1.1     skrll       where = frag - frag_now->fr_literal;
   3525  1.1.1.4  christos 
   3526  1.1.1.4  christos       if (extended_op)
   3527  1.1.1.4  christos 	{
   3528  1.1.1.4  christos 	  if (!addr_op)
   3529  1.1.1.4  christos 	    extended |= BYTE_OPERATION;
   3530  1.1.1.4  christos 
   3531  1.1.1.4  christos 	  if ((op1.ol != 0 || op2.ol != 0) && ((extended & 0xf) != 0))
   3532  1.1.1.4  christos 	    {
   3533  1.1.1.4  christos 	      as_bad (_("repeat instruction used with non-register mode instruction"));
   3534  1.1.1.4  christos 	      extended &= ~ 0xf;
   3535  1.1.1.4  christos 	    }
   3536  1.1.1.4  christos 
   3537  1.1.1.4  christos 	  /* If necessary, emit a reloc to update the extension word.  */
   3538  1.1.1.4  christos 	  if (op1.mode == OP_EXP)
   3539  1.1.1.4  christos 	    {
   3540  1.1.1.4  christos 	      if (op1.exp.X_op == O_constant)
   3541  1.1.1.4  christos 		extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
   3542  1.1.1.4  christos 
   3543  1.1.1.4  christos 	      else  if (op1.reg || op1.am == 3)	/* Not PC relative.  */
   3544  1.1.1.4  christos 		fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
   3545  1.1.1.4  christos 			     BFD_RELOC_MSP430X_ABS20_EXT_SRC);
   3546  1.1.1.4  christos 	      else
   3547  1.1.1.4  christos 		fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
   3548  1.1.1.4  christos 			     BFD_RELOC_MSP430X_PCR20_EXT_SRC);
   3549  1.1.1.4  christos 	    }
   3550  1.1.1.4  christos 
   3551  1.1.1.4  christos 	  if (op2.mode == OP_EXP)
   3552  1.1.1.4  christos 	    {
   3553  1.1.1.4  christos 	      if (op2.exp.X_op == O_constant)
   3554  1.1.1.4  christos 		extended |= (op2.exp.X_add_number >> 16) & 0xf;
   3555  1.1.1.4  christos 
   3556  1.1.1.4  christos 	      else if (op1.mode == OP_EXP)
   3557  1.1.1.4  christos 		fix_new_exp (frag_now, where, 8, &(op2.exp), FALSE,
   3558  1.1.1.4  christos 			     op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_ODST
   3559  1.1.1.4  christos 			     : BFD_RELOC_MSP430X_PCR20_EXT_ODST);
   3560  1.1.1.4  christos 
   3561  1.1.1.4  christos 	      else
   3562  1.1.1.4  christos 		fix_new_exp (frag_now, where, 6, &(op2.exp), FALSE,
   3563  1.1.1.4  christos 			     op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_DST
   3564  1.1.1.4  christos 			     : BFD_RELOC_MSP430X_PCR20_EXT_DST);
   3565  1.1.1.4  christos 	    }
   3566  1.1.1.4  christos 
   3567  1.1.1.4  christos 	  /* Emit the extension word.  */
   3568  1.1.1.4  christos 	  bfd_putl16 (extended, frag);
   3569  1.1.1.4  christos 	  where += 2;
   3570  1.1.1.4  christos 	  frag += 2;
   3571  1.1.1.4  christos 	}
   3572  1.1.1.4  christos 
   3573      1.1     skrll       bfd_putl16 ((bfd_vma) bin, frag);
   3574  1.1.1.4  christos       where += 2;
   3575  1.1.1.4  christos       frag += 2;
   3576      1.1     skrll 
   3577      1.1     skrll       if (op1.mode == OP_EXP)
   3578      1.1     skrll 	{
   3579  1.1.1.4  christos 	  if (op1.exp.X_op == O_constant)
   3580  1.1.1.4  christos 	    {
   3581  1.1.1.4  christos 	      bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
   3582  1.1.1.4  christos 	    }
   3583      1.1     skrll 	  else
   3584  1.1.1.4  christos 	    {
   3585  1.1.1.4  christos 	      bfd_putl16 ((bfd_vma) ZEROS, frag);
   3586  1.1.1.4  christos 
   3587  1.1.1.4  christos 	      if (!extended_op)
   3588  1.1.1.4  christos 		{
   3589  1.1.1.4  christos 		  if (op1.reg || op1.am == 3)	/* Not PC relative.  */
   3590  1.1.1.4  christos 		    fix_new_exp (frag_now, where, 2,
   3591  1.1.1.4  christos 				 &(op1.exp), FALSE, CHECK_RELOC_MSP430 (op1));
   3592  1.1.1.4  christos 		  else
   3593  1.1.1.4  christos 		    fix_new_exp (frag_now, where, 2,
   3594  1.1.1.4  christos 				 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
   3595  1.1.1.4  christos 		}
   3596  1.1.1.4  christos 	    }
   3597  1.1.1.4  christos 
   3598  1.1.1.4  christos 	  where += 2;
   3599  1.1.1.4  christos 	  frag += 2;
   3600      1.1     skrll 	}
   3601      1.1     skrll 
   3602      1.1     skrll       if (op2.mode == OP_EXP)
   3603      1.1     skrll 	{
   3604  1.1.1.4  christos 	  if (op2.exp.X_op == O_constant)
   3605  1.1.1.4  christos 	    {
   3606  1.1.1.4  christos 	      bfd_putl16 (op2.exp.X_add_number & 0xffff, frag);
   3607  1.1.1.4  christos 	    }
   3608      1.1     skrll 	  else
   3609  1.1.1.4  christos 	    {
   3610  1.1.1.4  christos 	      bfd_putl16 ((bfd_vma) ZEROS, frag);
   3611  1.1.1.4  christos 
   3612  1.1.1.4  christos 	      if (!extended_op)
   3613  1.1.1.4  christos 		{
   3614  1.1.1.4  christos 		  if (op2.reg)		/* Not PC relative.  */
   3615  1.1.1.4  christos 		    fix_new_exp (frag_now, where, 2,
   3616  1.1.1.4  christos 				 &(op2.exp), FALSE, CHECK_RELOC_MSP430 (op2));
   3617  1.1.1.4  christos 		  else
   3618  1.1.1.4  christos 		    fix_new_exp (frag_now, where, 2,
   3619  1.1.1.4  christos 				 &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
   3620  1.1.1.4  christos 		}
   3621  1.1.1.4  christos 	    }
   3622      1.1     skrll 	}
   3623  1.1.1.4  christos 
   3624  1.1.1.4  christos       dwarf2_emit_insn (insn_length);
   3625  1.1.1.4  christos 
   3626  1.1.1.4  christos       /* If the PC is the destination...  */
   3627  1.1.1.4  christos       if (op2.am == 0 && op2.reg == 0
   3628  1.1.1.4  christos 	  /* ... but the opcode does not alter the destination.  */
   3629  1.1.1.4  christos 	  && (is_opcode ("cmp") || is_opcode ("bit") || is_opcode ("cmpx")))
   3630  1.1.1.4  christos 	check_for_nop |= NOP_CHECK_CPU12;
   3631      1.1     skrll       break;
   3632      1.1     skrll 
   3633      1.1     skrll     case 2:			/* Single-operand mostly instr.  */
   3634      1.1     skrll       if (opcode->insn_opnumb == 0)
   3635      1.1     skrll 	{
   3636      1.1     skrll 	  /* reti instruction.  */
   3637  1.1.1.4  christos 	  insn_length += 2;
   3638      1.1     skrll 	  frag = frag_more (2);
   3639      1.1     skrll 	  bfd_putl16 ((bfd_vma) bin, frag);
   3640  1.1.1.4  christos 	  dwarf2_emit_insn (insn_length);
   3641      1.1     skrll 	  break;
   3642      1.1     skrll 	}
   3643      1.1     skrll 
   3644      1.1     skrll       line = extract_operand (line, l1, sizeof (l1));
   3645  1.1.1.4  christos       res = msp430_srcoperand (&op1, l1, opcode->bin_opcode,
   3646  1.1.1.4  christos 			       &imm_op, extended_op, TRUE);
   3647      1.1     skrll       if (res)
   3648      1.1     skrll 	break;		/* Error in operand.  */
   3649      1.1     skrll 
   3650  1.1.1.4  christos       if (target_is_430xv2 ()
   3651  1.1.1.4  christos 	  && op1.mode == OP_REG
   3652  1.1.1.4  christos 	  && op1.reg == 0
   3653  1.1.1.4  christos 	  && (is_opcode ("rrax")
   3654  1.1.1.4  christos 	      || is_opcode ("rrcx")
   3655  1.1.1.4  christos 	      || is_opcode ("rra")
   3656  1.1.1.4  christos 	      || is_opcode ("rrc")))
   3657  1.1.1.4  christos 	{
   3658  1.1.1.4  christos 	  as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
   3659  1.1.1.4  christos 	  break;
   3660  1.1.1.4  christos 	}
   3661  1.1.1.4  christos 
   3662  1.1.1.4  christos       /* If the status register is the destination...  */
   3663  1.1.1.4  christos       if (op1.am == 0 && op1.reg == 2
   3664  1.1.1.4  christos 	  /* ... and the opcode alters the SR.  */
   3665  1.1.1.4  christos 	  && (is_opcode ("rra") || is_opcode ("rrc") || is_opcode ("sxt")))
   3666  1.1.1.4  christos 	{
   3667  1.1.1.4  christos 	  if (silicon_errata_fix & SILICON_ERRATA_CPU13)
   3668  1.1.1.6  christos 	    as_bad (_("CPU13: SR is destination of SR altering instruction"));
   3669  1.1.1.4  christos 	  else if (silicon_errata_warn & SILICON_ERRATA_CPU13)
   3670  1.1.1.6  christos 	    as_warn (_("CPU13: SR is destination of SR altering instruction"));
   3671  1.1.1.4  christos 	}
   3672  1.1.1.4  christos 
   3673  1.1.1.4  christos       insn_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2);
   3674  1.1.1.4  christos       frag = frag_more (insn_length);
   3675      1.1     skrll       where = frag - frag_now->fr_literal;
   3676  1.1.1.4  christos 
   3677  1.1.1.4  christos       if (extended_op)
   3678  1.1.1.4  christos 	{
   3679  1.1.1.4  christos 	  if (is_opcode ("swpbx") || is_opcode ("sxtx"))
   3680  1.1.1.4  christos 	    {
   3681  1.1.1.4  christos 	      /* These two instructions use a special
   3682  1.1.1.4  christos 		 encoding of the A/L and B/W bits.  */
   3683  1.1.1.4  christos 	      bin &= ~ BYTE_OPERATION;
   3684  1.1.1.4  christos 
   3685  1.1.1.4  christos 	      if (byte_op)
   3686  1.1.1.4  christos 		{
   3687  1.1.1.4  christos 		  as_bad (_("%s instruction does not accept a .b suffix"),
   3688  1.1.1.4  christos 			  opcode->name);
   3689  1.1.1.4  christos 		  break;
   3690  1.1.1.4  christos 		}
   3691  1.1.1.4  christos 	      else if (! addr_op)
   3692  1.1.1.4  christos 		extended |= BYTE_OPERATION;
   3693  1.1.1.4  christos 	    }
   3694  1.1.1.4  christos 	  else if (! addr_op)
   3695  1.1.1.4  christos 	    extended |= BYTE_OPERATION;
   3696  1.1.1.4  christos 
   3697  1.1.1.5  christos 	  if (is_opcode ("rrux"))
   3698  1.1.1.5  christos 	    extended |= IGNORE_CARRY_BIT;
   3699  1.1.1.5  christos 
   3700  1.1.1.4  christos 	  if (op1.ol != 0 && ((extended & 0xf) != 0))
   3701  1.1.1.4  christos 	    {
   3702  1.1.1.4  christos 	      as_bad (_("repeat instruction used with non-register mode instruction"));
   3703  1.1.1.4  christos 	      extended &= ~ 0xf;
   3704  1.1.1.4  christos 	    }
   3705  1.1.1.4  christos 
   3706  1.1.1.4  christos 	  if (op1.mode == OP_EXP)
   3707  1.1.1.4  christos 	    {
   3708  1.1.1.4  christos 	      if (op1.exp.X_op == O_constant)
   3709  1.1.1.4  christos 		extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
   3710  1.1.1.4  christos 
   3711  1.1.1.4  christos 	      else if (op1.reg || op1.am == 3)	/* Not PC relative.  */
   3712  1.1.1.4  christos 		fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
   3713  1.1.1.4  christos 			     BFD_RELOC_MSP430X_ABS20_EXT_SRC);
   3714  1.1.1.4  christos 	      else
   3715  1.1.1.4  christos 		fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
   3716  1.1.1.4  christos 			     BFD_RELOC_MSP430X_PCR20_EXT_SRC);
   3717  1.1.1.4  christos 	    }
   3718  1.1.1.4  christos 
   3719  1.1.1.4  christos 	  /* Emit the extension word.  */
   3720  1.1.1.4  christos 	  bfd_putl16 (extended, frag);
   3721  1.1.1.4  christos 	  frag += 2;
   3722  1.1.1.4  christos 	  where += 2;
   3723  1.1.1.4  christos 	}
   3724  1.1.1.4  christos 
   3725  1.1.1.4  christos       bin |= op1.reg | (op1.am << 4);
   3726      1.1     skrll       bfd_putl16 ((bfd_vma) bin, frag);
   3727  1.1.1.4  christos       frag += 2;
   3728  1.1.1.4  christos       where += 2;
   3729      1.1     skrll 
   3730      1.1     skrll       if (op1.mode == OP_EXP)
   3731      1.1     skrll 	{
   3732  1.1.1.4  christos 	  if (op1.exp.X_op == O_constant)
   3733  1.1.1.4  christos 	    {
   3734  1.1.1.4  christos 	      bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
   3735  1.1.1.4  christos 	    }
   3736      1.1     skrll 	  else
   3737  1.1.1.4  christos 	    {
   3738  1.1.1.4  christos 	      bfd_putl16 ((bfd_vma) ZEROS, frag);
   3739  1.1.1.4  christos 
   3740  1.1.1.4  christos 	      if (!extended_op)
   3741  1.1.1.4  christos 		{
   3742  1.1.1.4  christos 		  if (op1.reg || op1.am == 3)	/* Not PC relative.  */
   3743  1.1.1.4  christos 		    fix_new_exp (frag_now, where, 2,
   3744  1.1.1.4  christos 				 &(op1.exp), FALSE, CHECK_RELOC_MSP430 (op1));
   3745  1.1.1.4  christos 		  else
   3746  1.1.1.4  christos 		    fix_new_exp (frag_now, where, 2,
   3747  1.1.1.4  christos 				 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
   3748  1.1.1.4  christos 		}
   3749  1.1.1.4  christos 	    }
   3750      1.1     skrll 	}
   3751  1.1.1.4  christos 
   3752  1.1.1.4  christos       dwarf2_emit_insn (insn_length);
   3753      1.1     skrll       break;
   3754      1.1     skrll 
   3755      1.1     skrll     case 3:			/* Conditional jumps instructions.  */
   3756      1.1     skrll       line = extract_operand (line, l1, sizeof (l1));
   3757      1.1     skrll       /* l1 is a label.  */
   3758      1.1     skrll       if (l1[0])
   3759      1.1     skrll 	{
   3760      1.1     skrll 	  char *m = l1;
   3761      1.1     skrll 	  expressionS exp;
   3762      1.1     skrll 
   3763      1.1     skrll 	  if (*m == '$')
   3764      1.1     skrll 	    m++;
   3765      1.1     skrll 
   3766  1.1.1.6  christos 	  end = parse_exp (m, &exp);
   3767  1.1.1.6  christos 	  if (end != NULL && *end != 0)
   3768  1.1.1.6  christos 	    {
   3769  1.1.1.6  christos 	      as_bad (_("extra characters '%s' at end of operand '%s'"), end, l1);
   3770  1.1.1.6  christos 	      break;
   3771  1.1.1.6  christos 	    }
   3772      1.1     skrll 
   3773      1.1     skrll 	  /* In order to handle something like:
   3774      1.1     skrll 
   3775      1.1     skrll 	     and #0x8000, r5
   3776      1.1     skrll 	     tst r5
   3777      1.1     skrll 	     jz   4     ;       skip next 4 bytes
   3778      1.1     skrll 	     inv r5
   3779      1.1     skrll 	     inc r5
   3780      1.1     skrll 	     nop        ;       will jump here if r5 positive or zero
   3781      1.1     skrll 
   3782      1.1     skrll 	     jCOND      -n      ;assumes jump n bytes backward:
   3783      1.1     skrll 
   3784      1.1     skrll 	     mov r5,r6
   3785      1.1     skrll 	     jmp -2
   3786      1.1     skrll 
   3787      1.1     skrll 	     is equal to:
   3788      1.1     skrll 	     lab:
   3789      1.1     skrll 	     mov r5,r6
   3790      1.1     skrll 	     jmp lab
   3791      1.1     skrll 
   3792      1.1     skrll 	     jCOND      $n      ; jump from PC in either direction.  */
   3793      1.1     skrll 
   3794      1.1     skrll 	  if (exp.X_op == O_constant)
   3795      1.1     skrll 	    {
   3796      1.1     skrll 	      int x = exp.X_add_number;
   3797      1.1     skrll 
   3798      1.1     skrll 	      if (x & 1)
   3799      1.1     skrll 		{
   3800      1.1     skrll 		  as_warn (_("Even number required. Rounded to %d"), x + 1);
   3801      1.1     skrll 		  x++;
   3802      1.1     skrll 		}
   3803      1.1     skrll 
   3804      1.1     skrll 	      if ((*l1 == '$' && x > 0) || x < 0)
   3805      1.1     skrll 		x -= 2;
   3806      1.1     skrll 
   3807      1.1     skrll 	      x >>= 1;
   3808      1.1     skrll 
   3809      1.1     skrll 	      if (x > 512 || x < -511)
   3810      1.1     skrll 		{
   3811  1.1.1.6  christos 		  as_bad (_("Wrong displacement %d"), x << 1);
   3812      1.1     skrll 		  break;
   3813      1.1     skrll 		}
   3814      1.1     skrll 
   3815  1.1.1.4  christos 	      insn_length += 2;
   3816  1.1.1.4  christos 	      frag = frag_more (2);	/* Instr size is 1 word.  */
   3817  1.1.1.4  christos 
   3818      1.1     skrll 	      bin |= x & 0x3ff;
   3819      1.1     skrll 	      bfd_putl16 ((bfd_vma) bin, frag);
   3820      1.1     skrll 	    }
   3821      1.1     skrll 	  else if (exp.X_op == O_symbol && *l1 != '$')
   3822      1.1     skrll 	    {
   3823  1.1.1.4  christos 	      insn_length += 2;
   3824  1.1.1.4  christos 	      frag = frag_more (2);	/* Instr size is 1 word.  */
   3825      1.1     skrll 	      where = frag - frag_now->fr_literal;
   3826      1.1     skrll 	      fix_new_exp (frag_now, where, 2,
   3827      1.1     skrll 			   &exp, TRUE, BFD_RELOC_MSP430_10_PCREL);
   3828      1.1     skrll 
   3829      1.1     skrll 	      bfd_putl16 ((bfd_vma) bin, frag);
   3830      1.1     skrll 	    }
   3831      1.1     skrll 	  else if (*l1 == '$')
   3832      1.1     skrll 	    {
   3833      1.1     skrll 	      as_bad (_("instruction requires label sans '$'"));
   3834      1.1     skrll 	    }
   3835      1.1     skrll 	  else
   3836  1.1.1.4  christos 	    as_bad (_
   3837  1.1.1.4  christos 		    ("instruction requires label or value in range -511:512"));
   3838  1.1.1.4  christos 	  dwarf2_emit_insn (insn_length);
   3839      1.1     skrll 	  break;
   3840      1.1     skrll 	}
   3841      1.1     skrll       else
   3842      1.1     skrll 	{
   3843      1.1     skrll 	  as_bad (_("instruction requires label"));
   3844      1.1     skrll 	  break;
   3845      1.1     skrll 	}
   3846      1.1     skrll       break;
   3847      1.1     skrll 
   3848      1.1     skrll     case 4:	/* Extended jumps.  */
   3849      1.1     skrll       if (!msp430_enable_polys)
   3850      1.1     skrll 	{
   3851  1.1.1.2  christos 	  as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
   3852      1.1     skrll 	  break;
   3853      1.1     skrll 	}
   3854  1.1.1.4  christos 
   3855      1.1     skrll       line = extract_operand (line, l1, sizeof (l1));
   3856      1.1     skrll       if (l1[0])
   3857      1.1     skrll 	{
   3858      1.1     skrll 	  char *m = l1;
   3859      1.1     skrll 	  expressionS exp;
   3860      1.1     skrll 
   3861      1.1     skrll 	  /* Ignore absolute addressing. make it PC relative anyway.  */
   3862      1.1     skrll 	  if (*m == '#' || *m == '$')
   3863      1.1     skrll 	    m++;
   3864      1.1     skrll 
   3865  1.1.1.6  christos 	  end = parse_exp (m, & exp);
   3866  1.1.1.6  christos 	  if (end != NULL && *end != 0)
   3867  1.1.1.6  christos 	    {
   3868  1.1.1.6  christos 	      as_bad (_("extra characters '%s' at end of operand '%s'"), end, l1);
   3869  1.1.1.6  christos 	      break;
   3870  1.1.1.6  christos 	    }
   3871      1.1     skrll 	  if (exp.X_op == O_symbol)
   3872      1.1     skrll 	    {
   3873      1.1     skrll 	      /* Relaxation required.  */
   3874      1.1     skrll 	      struct rcodes_s rc = msp430_rcodes[opcode->insn_opnumb];
   3875      1.1     skrll 
   3876  1.1.1.4  christos 	      if (target_is_430x ())
   3877  1.1.1.4  christos 		rc = msp430x_rcodes[opcode->insn_opnumb];
   3878  1.1.1.4  christos 
   3879  1.1.1.4  christos 	      /* The parameter to dwarf2_emit_insn is actually the offset to
   3880  1.1.1.4  christos 		 the start of the insn from the fix piece of instruction that
   3881  1.1.1.4  christos 		 was emitted.  Since next fragments may have variable size we
   3882  1.1.1.4  christos 		 tie debug info to the beginning of the instruction.  */
   3883  1.1.1.4  christos 	      insn_length += 8;
   3884      1.1     skrll 	      frag = frag_more (8);
   3885      1.1     skrll 	      dwarf2_emit_insn (0);
   3886      1.1     skrll 	      bfd_putl16 ((bfd_vma) rc.sop, frag);
   3887      1.1     skrll 	      frag = frag_variant (rs_machine_dependent, 8, 2,
   3888  1.1.1.4  christos 				    /* Wild guess.  */
   3889  1.1.1.4  christos 				   ENCODE_RELAX (rc.lpos, STATE_BITS10),
   3890      1.1     skrll 				   exp.X_add_symbol,
   3891      1.1     skrll 				   0,	/* Offset is zero if jump dist less than 1K.  */
   3892      1.1     skrll 				   (char *) frag);
   3893      1.1     skrll 	      break;
   3894      1.1     skrll 	    }
   3895      1.1     skrll 	}
   3896      1.1     skrll 
   3897      1.1     skrll       as_bad (_("instruction requires label"));
   3898      1.1     skrll       break;
   3899      1.1     skrll 
   3900      1.1     skrll     case 5:	/* Emulated extended branches.  */
   3901      1.1     skrll       if (!msp430_enable_polys)
   3902      1.1     skrll 	{
   3903  1.1.1.2  christos 	  as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
   3904      1.1     skrll 	  break;
   3905      1.1     skrll 	}
   3906      1.1     skrll       line = extract_operand (line, l1, sizeof (l1));
   3907      1.1     skrll       if (l1[0])
   3908      1.1     skrll 	{
   3909      1.1     skrll 	  char * m = l1;
   3910      1.1     skrll 	  expressionS exp;
   3911      1.1     skrll 
   3912      1.1     skrll 	  /* Ignore absolute addressing. make it PC relative anyway.  */
   3913      1.1     skrll 	  if (*m == '#' || *m == '$')
   3914      1.1     skrll 	    m++;
   3915      1.1     skrll 
   3916  1.1.1.6  christos 	  end = parse_exp (m, & exp);
   3917  1.1.1.6  christos 	  if (end != NULL && *end != 0)
   3918  1.1.1.6  christos 	    {
   3919  1.1.1.6  christos 	      as_bad (_("extra characters '%s' at end of operand '%s'"), end, l1);
   3920  1.1.1.6  christos 	      break;
   3921  1.1.1.6  christos 	    }
   3922      1.1     skrll 	  if (exp.X_op == O_symbol)
   3923      1.1     skrll 	    {
   3924      1.1     skrll 	      /* Relaxation required.  */
   3925      1.1     skrll 	      struct hcodes_s hc = msp430_hcodes[opcode->insn_opnumb];
   3926      1.1     skrll 
   3927  1.1.1.4  christos 	      if (target_is_430x ())
   3928  1.1.1.4  christos 		hc = msp430x_hcodes[opcode->insn_opnumb];
   3929  1.1.1.4  christos 
   3930  1.1.1.4  christos 	      insn_length += 8;
   3931      1.1     skrll 	      frag = frag_more (8);
   3932      1.1     skrll 	      dwarf2_emit_insn (0);
   3933      1.1     skrll 	      bfd_putl16 ((bfd_vma) hc.op0, frag);
   3934      1.1     skrll 	      bfd_putl16 ((bfd_vma) hc.op1, frag+2);
   3935      1.1     skrll 
   3936      1.1     skrll 	      frag = frag_variant (rs_machine_dependent, 8, 2,
   3937      1.1     skrll 				   ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_BITS10), /* Wild guess.  */
   3938      1.1     skrll 				   exp.X_add_symbol,
   3939      1.1     skrll 				   0,	/* Offset is zero if jump dist less than 1K.  */
   3940      1.1     skrll 				   (char *) frag);
   3941      1.1     skrll 	      break;
   3942      1.1     skrll 	    }
   3943      1.1     skrll 	}
   3944      1.1     skrll 
   3945      1.1     skrll       as_bad (_("instruction requires label"));
   3946      1.1     skrll       break;
   3947      1.1     skrll 
   3948      1.1     skrll     default:
   3949      1.1     skrll       as_bad (_("Illegal instruction or not implemented opcode."));
   3950      1.1     skrll     }
   3951      1.1     skrll 
   3952  1.1.1.5  christos   if (is_opcode ("nop"))
   3953  1.1.1.5  christos     prev_insn_is_nop = TRUE;
   3954  1.1.1.5  christos   else
   3955  1.1.1.5  christos     prev_insn_is_nop = FALSE;
   3956  1.1.1.5  christos 
   3957      1.1     skrll   input_line_pointer = line;
   3958      1.1     skrll   return 0;
   3959      1.1     skrll }
   3960      1.1     skrll 
   3961      1.1     skrll void
   3962      1.1     skrll md_assemble (char * str)
   3963      1.1     skrll {
   3964      1.1     skrll   struct msp430_opcode_s * opcode;
   3965      1.1     skrll   char cmd[32];
   3966      1.1     skrll   unsigned int i = 0;
   3967      1.1     skrll 
   3968      1.1     skrll   str = skip_space (str);	/* Skip leading spaces.  */
   3969  1.1.1.4  christos   str = extract_cmd (str, cmd, sizeof (cmd) - 1);
   3970      1.1     skrll 
   3971  1.1.1.4  christos   while (cmd[i])
   3972      1.1     skrll     {
   3973      1.1     skrll       char a = TOLOWER (cmd[i]);
   3974      1.1     skrll       cmd[i] = a;
   3975      1.1     skrll       i++;
   3976      1.1     skrll     }
   3977      1.1     skrll 
   3978      1.1     skrll   if (!cmd[0])
   3979      1.1     skrll     {
   3980  1.1.1.6  christos       as_bad (_("can't find opcode"));
   3981      1.1     skrll       return;
   3982      1.1     skrll     }
   3983      1.1     skrll 
   3984      1.1     skrll   opcode = (struct msp430_opcode_s *) hash_find (msp430_hash, cmd);
   3985      1.1     skrll 
   3986      1.1     skrll   if (opcode == NULL)
   3987      1.1     skrll     {
   3988      1.1     skrll       as_bad (_("unknown opcode `%s'"), cmd);
   3989      1.1     skrll       return;
   3990      1.1     skrll     }
   3991      1.1     skrll 
   3992      1.1     skrll   {
   3993      1.1     skrll     char *__t = input_line_pointer;
   3994      1.1     skrll 
   3995      1.1     skrll     msp430_operands (opcode, str);
   3996      1.1     skrll     input_line_pointer = __t;
   3997      1.1     skrll   }
   3998      1.1     skrll }
   3999      1.1     skrll 
   4000      1.1     skrll /* GAS will call this function for each section at the end of the assembly,
   4001      1.1     skrll    to permit the CPU backend to adjust the alignment of a section.  */
   4002      1.1     skrll 
   4003      1.1     skrll valueT
   4004      1.1     skrll md_section_align (asection * seg, valueT addr)
   4005      1.1     skrll {
   4006      1.1     skrll   int align = bfd_get_section_alignment (stdoutput, seg);
   4007      1.1     skrll 
   4008  1.1.1.4  christos   return ((addr + (1 << align) - 1) & -(1 << align));
   4009      1.1     skrll }
   4010      1.1     skrll 
   4011      1.1     skrll /* If you define this macro, it should return the offset between the
   4012      1.1     skrll    address of a PC relative fixup and the position from which the PC
   4013      1.1     skrll    relative adjustment should be made.  On many processors, the base
   4014      1.1     skrll    of a PC relative instruction is the next instruction, so this
   4015      1.1     skrll    macro would return the length of an instruction.  */
   4016      1.1     skrll 
   4017      1.1     skrll long
   4018      1.1     skrll md_pcrel_from_section (fixS * fixp, segT sec)
   4019      1.1     skrll {
   4020      1.1     skrll   if (fixp->fx_addsy != (symbolS *) NULL
   4021      1.1     skrll       && (!S_IS_DEFINED (fixp->fx_addsy)
   4022      1.1     skrll 	  || (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
   4023      1.1     skrll     return 0;
   4024      1.1     skrll 
   4025      1.1     skrll   return fixp->fx_frag->fr_address + fixp->fx_where;
   4026      1.1     skrll }
   4027      1.1     skrll 
   4028  1.1.1.6  christos /* Addition to the standard TC_FORCE_RELOCATION_LOCAL.
   4029      1.1     skrll    Now it handles the situation when relocations
   4030  1.1.1.4  christos    have to be passed to linker.  */
   4031      1.1     skrll int
   4032  1.1.1.4  christos msp430_force_relocation_local (fixS *fixp)
   4033      1.1     skrll {
   4034  1.1.1.4  christos   if (fixp->fx_r_type == BFD_RELOC_MSP430_10_PCREL)
   4035  1.1.1.4  christos     return 1;
   4036  1.1.1.4  christos   if (fixp->fx_pcrel)
   4037  1.1.1.4  christos     return 1;
   4038      1.1     skrll   if (msp430_enable_polys
   4039      1.1     skrll         && !msp430_enable_relax)
   4040      1.1     skrll     return 1;
   4041  1.1.1.4  christos 
   4042  1.1.1.6  christos   return 0;
   4043      1.1     skrll }
   4044      1.1     skrll 
   4045      1.1     skrll 
   4046      1.1     skrll /* GAS will call this for each fixup.  It should store the correct
   4047      1.1     skrll    value in the object file.  */
   4048      1.1     skrll void
   4049      1.1     skrll md_apply_fix (fixS * fixp, valueT * valuep, segT seg)
   4050      1.1     skrll {
   4051      1.1     skrll   unsigned char * where;
   4052      1.1     skrll   unsigned long insn;
   4053      1.1     skrll   long value;
   4054      1.1     skrll 
   4055      1.1     skrll   if (fixp->fx_addsy == (symbolS *) NULL)
   4056      1.1     skrll     {
   4057      1.1     skrll       value = *valuep;
   4058      1.1     skrll       fixp->fx_done = 1;
   4059      1.1     skrll     }
   4060      1.1     skrll   else if (fixp->fx_pcrel)
   4061      1.1     skrll     {
   4062      1.1     skrll       segT s = S_GET_SEGMENT (fixp->fx_addsy);
   4063      1.1     skrll 
   4064      1.1     skrll       if (fixp->fx_addsy && (s == seg || s == absolute_section))
   4065      1.1     skrll 	{
   4066      1.1     skrll 	  /* FIXME: We can appear here only in case if we perform a pc
   4067      1.1     skrll 	     relative jump to the label which is i) global, ii) locally
   4068      1.1     skrll 	     defined or this is a jump to an absolute symbol.
   4069      1.1     skrll 	     If this is an absolute symbol -- everything is OK.
   4070      1.1     skrll 	     If this is a global label, we've got a symbol value defined
   4071      1.1     skrll 	     twice:
   4072      1.1     skrll                1. S_GET_VALUE (fixp->fx_addsy) will contain a symbol offset
   4073      1.1     skrll 	          from this section start
   4074      1.1     skrll                2. *valuep will contain the real offset from jump insn to the
   4075      1.1     skrll 	          label
   4076      1.1     skrll 	     So, the result of S_GET_VALUE (fixp->fx_addsy) + (* valuep);
   4077      1.1     skrll 	     will be incorrect. Therefore remove s_get_value.  */
   4078      1.1     skrll 	  value = /* S_GET_VALUE (fixp->fx_addsy) + */ * valuep;
   4079      1.1     skrll 	  fixp->fx_done = 1;
   4080      1.1     skrll 	}
   4081      1.1     skrll       else
   4082      1.1     skrll 	value = *valuep;
   4083      1.1     skrll     }
   4084      1.1     skrll   else
   4085      1.1     skrll     {
   4086      1.1     skrll       value = fixp->fx_offset;
   4087      1.1     skrll 
   4088      1.1     skrll       if (fixp->fx_subsy != (symbolS *) NULL)
   4089      1.1     skrll 	{
   4090      1.1     skrll 	  if (S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
   4091      1.1     skrll 	    {
   4092      1.1     skrll 	      value -= S_GET_VALUE (fixp->fx_subsy);
   4093      1.1     skrll 	      fixp->fx_done = 1;
   4094      1.1     skrll 	    }
   4095      1.1     skrll 	}
   4096      1.1     skrll     }
   4097      1.1     skrll 
   4098      1.1     skrll   fixp->fx_no_overflow = 1;
   4099      1.1     skrll 
   4100  1.1.1.4  christos   /* If polymorphs are enabled and relax disabled.
   4101  1.1.1.4  christos      do not kill any relocs and pass them to linker.  */
   4102  1.1.1.4  christos   if (msp430_enable_polys
   4103      1.1     skrll       && !msp430_enable_relax)
   4104      1.1     skrll     {
   4105  1.1.1.4  christos       if (!fixp->fx_addsy
   4106  1.1.1.4  christos 	  || S_GET_SEGMENT (fixp->fx_addsy) == absolute_section)
   4107      1.1     skrll 	fixp->fx_done = 1;	/* It is ok to kill 'abs' reloc.  */
   4108      1.1     skrll       else
   4109      1.1     skrll       	fixp->fx_done = 0;
   4110      1.1     skrll     }
   4111      1.1     skrll 
   4112      1.1     skrll   if (fixp->fx_done)
   4113      1.1     skrll     {
   4114      1.1     skrll       /* Fetch the instruction, insert the fully resolved operand
   4115      1.1     skrll 	 value, and stuff the instruction back again.  */
   4116      1.1     skrll       where = (unsigned char *) fixp->fx_frag->fr_literal + fixp->fx_where;
   4117      1.1     skrll 
   4118      1.1     skrll       insn = bfd_getl16 (where);
   4119      1.1     skrll 
   4120      1.1     skrll       switch (fixp->fx_r_type)
   4121      1.1     skrll 	{
   4122      1.1     skrll 	case BFD_RELOC_MSP430_10_PCREL:
   4123      1.1     skrll 	  if (value & 1)
   4124      1.1     skrll 	    as_bad_where (fixp->fx_file, fixp->fx_line,
   4125      1.1     skrll 			  _("odd address operand: %ld"), value);
   4126      1.1     skrll 
   4127      1.1     skrll 	  /* Jumps are in words.  */
   4128      1.1     skrll 	  value >>= 1;
   4129      1.1     skrll 	  --value;		/* Correct PC.  */
   4130      1.1     skrll 
   4131      1.1     skrll 	  if (value < -512 || value > 511)
   4132      1.1     skrll 	    as_bad_where (fixp->fx_file, fixp->fx_line,
   4133      1.1     skrll 			  _("operand out of range: %ld"), value);
   4134      1.1     skrll 
   4135      1.1     skrll 	  value &= 0x3ff;	/* get rid of extended sign */
   4136      1.1     skrll 	  bfd_putl16 ((bfd_vma) (value | insn), where);
   4137      1.1     skrll 	  break;
   4138      1.1     skrll 
   4139  1.1.1.4  christos 	case BFD_RELOC_MSP430X_PCR16:
   4140      1.1     skrll 	case BFD_RELOC_MSP430_RL_PCREL:
   4141      1.1     skrll 	case BFD_RELOC_MSP430_16_PCREL:
   4142      1.1     skrll 	  if (value & 1)
   4143      1.1     skrll 	    as_bad_where (fixp->fx_file, fixp->fx_line,
   4144      1.1     skrll 			  _("odd address operand: %ld"), value);
   4145  1.1.1.4  christos 	  /* Fall through.  */
   4146      1.1     skrll 
   4147  1.1.1.4  christos 	case BFD_RELOC_MSP430_16_PCREL_BYTE:
   4148      1.1     skrll 	  /* Nothing to be corrected here.  */
   4149      1.1     skrll 	  if (value < -32768 || value > 65536)
   4150      1.1     skrll 	    as_bad_where (fixp->fx_file, fixp->fx_line,
   4151      1.1     skrll 			  _("operand out of range: %ld"), value);
   4152  1.1.1.4  christos 	  /* Fall through.  */
   4153      1.1     skrll 
   4154  1.1.1.4  christos 	case BFD_RELOC_MSP430X_ABS16:
   4155  1.1.1.4  christos 	case BFD_RELOC_MSP430_16:
   4156  1.1.1.4  christos 	case BFD_RELOC_16:
   4157  1.1.1.4  christos 	case BFD_RELOC_MSP430_16_BYTE:
   4158      1.1     skrll 	  value &= 0xffff;	/* Get rid of extended sign.  */
   4159      1.1     skrll 	  bfd_putl16 ((bfd_vma) value, where);
   4160      1.1     skrll 	  break;
   4161      1.1     skrll 
   4162  1.1.1.4  christos 	case BFD_RELOC_MSP430_ABS_HI16:
   4163  1.1.1.4  christos 	  value >>= 16;
   4164      1.1     skrll 	  value &= 0xffff;	/* Get rid of extended sign.  */
   4165      1.1     skrll 	  bfd_putl16 ((bfd_vma) value, where);
   4166      1.1     skrll 	  break;
   4167      1.1     skrll 
   4168      1.1     skrll 	case BFD_RELOC_32:
   4169      1.1     skrll 	  bfd_putl16 ((bfd_vma) value, where);
   4170      1.1     skrll 	  break;
   4171      1.1     skrll 
   4172  1.1.1.4  christos 	case BFD_RELOC_MSP430_ABS8:
   4173  1.1.1.4  christos 	case BFD_RELOC_8:
   4174  1.1.1.4  christos 	  bfd_put_8 (NULL, (bfd_vma) value, where);
   4175  1.1.1.4  christos 	  break;
   4176  1.1.1.4  christos 
   4177  1.1.1.4  christos 	case BFD_RELOC_MSP430X_ABS20_EXT_SRC:
   4178  1.1.1.4  christos 	case BFD_RELOC_MSP430X_PCR20_EXT_SRC:
   4179  1.1.1.4  christos 	  bfd_putl16 ((bfd_vma) (value & 0xffff), where + 4);
   4180  1.1.1.4  christos 	  value >>= 16;
   4181  1.1.1.4  christos 	  bfd_putl16 ((bfd_vma) (((value & 0xf) << 7) | insn), where);
   4182  1.1.1.4  christos 	  break;
   4183  1.1.1.4  christos 
   4184  1.1.1.4  christos 	case BFD_RELOC_MSP430X_ABS20_ADR_SRC:
   4185  1.1.1.4  christos 	  bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
   4186  1.1.1.4  christos 	  value >>= 16;
   4187  1.1.1.4  christos 	  bfd_putl16 ((bfd_vma) (((value & 0xf) << 8) | insn), where);
   4188  1.1.1.4  christos 	  break;
   4189  1.1.1.4  christos 
   4190  1.1.1.4  christos 	case BFD_RELOC_MSP430X_ABS20_EXT_ODST:
   4191  1.1.1.4  christos 	  bfd_putl16 ((bfd_vma) (value & 0xffff), where + 6);
   4192  1.1.1.4  christos 	  value >>= 16;
   4193  1.1.1.4  christos 	  bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
   4194  1.1.1.4  christos 	  break;
   4195  1.1.1.4  christos 
   4196  1.1.1.4  christos 	case BFD_RELOC_MSP430X_PCR20_CALL:
   4197  1.1.1.4  christos 	  bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
   4198  1.1.1.4  christos 	  value >>= 16;
   4199  1.1.1.4  christos 	  bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
   4200  1.1.1.4  christos 	  break;
   4201  1.1.1.4  christos 
   4202  1.1.1.4  christos 	case BFD_RELOC_MSP430X_ABS20_EXT_DST:
   4203  1.1.1.4  christos 	case BFD_RELOC_MSP430X_PCR20_EXT_DST:
   4204  1.1.1.4  christos 	  bfd_putl16 ((bfd_vma) (value & 0xffff), where + 4);
   4205  1.1.1.4  christos 	  value >>= 16;
   4206  1.1.1.4  christos 	  bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
   4207  1.1.1.4  christos 	  break;
   4208  1.1.1.4  christos 
   4209  1.1.1.4  christos 	case BFD_RELOC_MSP430X_PCR20_EXT_ODST:
   4210  1.1.1.4  christos 	  bfd_putl16 ((bfd_vma) (value & 0xffff), where + 6);
   4211  1.1.1.4  christos 	  value >>= 16;
   4212  1.1.1.4  christos 	  bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
   4213  1.1.1.4  christos 	  break;
   4214  1.1.1.4  christos 
   4215  1.1.1.4  christos 	case BFD_RELOC_MSP430X_ABS20_ADR_DST:
   4216  1.1.1.4  christos 	  bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
   4217  1.1.1.4  christos 	  value >>= 16;
   4218  1.1.1.4  christos 	  bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
   4219      1.1     skrll 	  break;
   4220      1.1     skrll 
   4221      1.1     skrll 	default:
   4222      1.1     skrll 	  as_fatal (_("line %d: unknown relocation type: 0x%x"),
   4223      1.1     skrll 		    fixp->fx_line, fixp->fx_r_type);
   4224      1.1     skrll 	  break;
   4225      1.1     skrll 	}
   4226      1.1     skrll     }
   4227      1.1     skrll   else
   4228      1.1     skrll     {
   4229      1.1     skrll       fixp->fx_addnumber = value;
   4230      1.1     skrll     }
   4231      1.1     skrll }
   4232      1.1     skrll 
   4233  1.1.1.4  christos static bfd_boolean
   4234  1.1.1.4  christos S_IS_GAS_LOCAL (symbolS * s)
   4235  1.1.1.4  christos {
   4236  1.1.1.4  christos   const char * name;
   4237  1.1.1.4  christos   unsigned int len;
   4238  1.1.1.4  christos 
   4239  1.1.1.4  christos   if (s == NULL)
   4240  1.1.1.4  christos     return FALSE;
   4241  1.1.1.4  christos   name = S_GET_NAME (s);
   4242  1.1.1.4  christos   len = strlen (name) - 1;
   4243  1.1.1.4  christos 
   4244  1.1.1.4  christos   return name[len] == 1 || name[len] == 2;
   4245  1.1.1.4  christos }
   4246  1.1.1.4  christos 
   4247      1.1     skrll /* GAS will call this to generate a reloc, passing the resulting reloc
   4248      1.1     skrll    to `bfd_install_relocation'.  This currently works poorly, as
   4249      1.1     skrll    `bfd_install_relocation' often does the wrong thing, and instances of
   4250      1.1     skrll    `tc_gen_reloc' have been written to work around the problems, which
   4251      1.1     skrll    in turns makes it difficult to fix `bfd_install_relocation'.  */
   4252      1.1     skrll 
   4253      1.1     skrll /* If while processing a fixup, a reloc really needs to be created
   4254      1.1     skrll    then it is done here.  */
   4255      1.1     skrll 
   4256  1.1.1.4  christos arelent **
   4257      1.1     skrll tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
   4258      1.1     skrll {
   4259  1.1.1.4  christos   static arelent * no_relocs = NULL;
   4260  1.1.1.4  christos   static arelent * relocs[MAX_RELOC_EXPANSION + 1];
   4261  1.1.1.4  christos   arelent *reloc;
   4262      1.1     skrll 
   4263  1.1.1.5  christos   reloc = XNEW (arelent);
   4264      1.1     skrll   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
   4265      1.1     skrll   reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
   4266  1.1.1.4  christos 
   4267      1.1     skrll   if (reloc->howto == (reloc_howto_type *) NULL)
   4268      1.1     skrll     {
   4269      1.1     skrll       as_bad_where (fixp->fx_file, fixp->fx_line,
   4270      1.1     skrll 		    _("reloc %d not supported by object file format"),
   4271      1.1     skrll 		    (int) fixp->fx_r_type);
   4272  1.1.1.4  christos       free (reloc);
   4273  1.1.1.4  christos       return & no_relocs;
   4274  1.1.1.4  christos     }
   4275  1.1.1.4  christos 
   4276  1.1.1.4  christos   relocs[0] = reloc;
   4277  1.1.1.4  christos   relocs[1] = NULL;
   4278  1.1.1.4  christos 
   4279  1.1.1.4  christos   if (fixp->fx_subsy
   4280  1.1.1.4  christos       && S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
   4281  1.1.1.4  christos     {
   4282  1.1.1.4  christos       fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy);
   4283  1.1.1.4  christos       fixp->fx_subsy = NULL;
   4284  1.1.1.4  christos     }
   4285  1.1.1.4  christos 
   4286  1.1.1.4  christos   if (fixp->fx_addsy && fixp->fx_subsy)
   4287  1.1.1.4  christos     {
   4288  1.1.1.4  christos       asection *asec, *ssec;
   4289  1.1.1.4  christos 
   4290  1.1.1.4  christos       asec = S_GET_SEGMENT (fixp->fx_addsy);
   4291  1.1.1.4  christos       ssec = S_GET_SEGMENT (fixp->fx_subsy);
   4292  1.1.1.4  christos 
   4293  1.1.1.4  christos       /* If we have a difference between two different, non-absolute symbols
   4294  1.1.1.4  christos 	 we must generate two relocs (one for each symbol) and allow the
   4295  1.1.1.4  christos 	 linker to resolve them - relaxation may change the distances between
   4296  1.1.1.4  christos 	 symbols, even local symbols defined in the same section.
   4297  1.1.1.4  christos 
   4298  1.1.1.4  christos 	 Unfortunately we cannot do this with assembler generated local labels
   4299  1.1.1.4  christos 	 because there can be multiple incarnations of the same label, with
   4300  1.1.1.4  christos 	 exactly the same name, in any given section and the linker will have
   4301  1.1.1.4  christos 	 no way to identify the correct one.  Instead we just have to hope
   4302  1.1.1.6  christos 	 that no relaxation will occur between the local label and the other
   4303  1.1.1.4  christos 	 symbol in the expression.
   4304  1.1.1.4  christos 
   4305  1.1.1.4  christos 	 Similarly we have to compute differences between symbols in the .eh_frame
   4306  1.1.1.4  christos 	 section as the linker is not smart enough to apply relocations there
   4307  1.1.1.4  christos 	 before attempting to process it.  */
   4308  1.1.1.4  christos       if ((ssec != absolute_section || asec != absolute_section)
   4309  1.1.1.4  christos 	  && (fixp->fx_addsy != fixp->fx_subsy)
   4310  1.1.1.4  christos 	  && strcmp (ssec->name, ".eh_frame") != 0
   4311  1.1.1.4  christos 	  && ! S_IS_GAS_LOCAL (fixp->fx_addsy)
   4312  1.1.1.4  christos 	  && ! S_IS_GAS_LOCAL (fixp->fx_subsy))
   4313  1.1.1.4  christos 	{
   4314  1.1.1.5  christos 	  arelent * reloc2 = XNEW (arelent);
   4315  1.1.1.4  christos 
   4316  1.1.1.4  christos 	  relocs[0] = reloc2;
   4317  1.1.1.4  christos 	  relocs[1] = reloc;
   4318  1.1.1.4  christos 
   4319  1.1.1.4  christos 	  reloc2->address = reloc->address;
   4320  1.1.1.4  christos 	  reloc2->howto = bfd_reloc_type_lookup (stdoutput,
   4321  1.1.1.4  christos 						 BFD_RELOC_MSP430_SYM_DIFF);
   4322  1.1.1.4  christos 	  reloc2->addend = - S_GET_VALUE (fixp->fx_subsy);
   4323  1.1.1.4  christos 
   4324  1.1.1.4  christos 	  if (ssec == absolute_section)
   4325  1.1.1.4  christos 	    reloc2->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
   4326  1.1.1.4  christos 	  else
   4327  1.1.1.4  christos 	    {
   4328  1.1.1.5  christos 	      reloc2->sym_ptr_ptr = XNEW (asymbol *);
   4329  1.1.1.4  christos 	      *reloc2->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy);
   4330  1.1.1.4  christos 	    }
   4331  1.1.1.4  christos 
   4332  1.1.1.4  christos 	  reloc->addend = fixp->fx_offset;
   4333  1.1.1.4  christos 	  if (asec == absolute_section)
   4334  1.1.1.4  christos 	    {
   4335  1.1.1.4  christos 	      reloc->addend += S_GET_VALUE (fixp->fx_addsy);
   4336  1.1.1.4  christos 	      reloc->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
   4337  1.1.1.4  christos 	    }
   4338  1.1.1.4  christos 	  else
   4339  1.1.1.4  christos 	    {
   4340  1.1.1.5  christos 	      reloc->sym_ptr_ptr = XNEW (asymbol *);
   4341  1.1.1.4  christos 	      *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
   4342  1.1.1.4  christos 	    }
   4343  1.1.1.4  christos 
   4344  1.1.1.4  christos 	  fixp->fx_pcrel = 0;
   4345  1.1.1.4  christos 	  fixp->fx_done = 1;
   4346  1.1.1.4  christos 	  return relocs;
   4347  1.1.1.4  christos 	}
   4348  1.1.1.4  christos       else
   4349  1.1.1.4  christos 	{
   4350  1.1.1.4  christos 	  char *fixpos = fixp->fx_where + fixp->fx_frag->fr_literal;
   4351  1.1.1.4  christos 
   4352  1.1.1.4  christos 	  reloc->addend = (S_GET_VALUE (fixp->fx_addsy)
   4353  1.1.1.4  christos 			   - S_GET_VALUE (fixp->fx_subsy) + fixp->fx_offset);
   4354  1.1.1.4  christos 
   4355  1.1.1.4  christos 	  switch (fixp->fx_r_type)
   4356  1.1.1.4  christos 	    {
   4357  1.1.1.4  christos 	    case BFD_RELOC_8:
   4358  1.1.1.4  christos 	      md_number_to_chars (fixpos, reloc->addend, 1);
   4359  1.1.1.4  christos 	      break;
   4360  1.1.1.4  christos 
   4361  1.1.1.4  christos 	    case BFD_RELOC_16:
   4362  1.1.1.4  christos 	      md_number_to_chars (fixpos, reloc->addend, 2);
   4363  1.1.1.4  christos 	      break;
   4364  1.1.1.4  christos 
   4365  1.1.1.4  christos 	    case BFD_RELOC_24:
   4366  1.1.1.4  christos 	      md_number_to_chars (fixpos, reloc->addend, 3);
   4367  1.1.1.4  christos 	      break;
   4368  1.1.1.4  christos 
   4369  1.1.1.4  christos 	    case BFD_RELOC_32:
   4370  1.1.1.4  christos 	      md_number_to_chars (fixpos, reloc->addend, 4);
   4371  1.1.1.4  christos 	      break;
   4372  1.1.1.4  christos 
   4373  1.1.1.4  christos 	    default:
   4374  1.1.1.4  christos 	      reloc->sym_ptr_ptr
   4375  1.1.1.4  christos 		= (asymbol **) bfd_abs_section_ptr->symbol_ptr_ptr;
   4376  1.1.1.4  christos 	      return relocs;
   4377  1.1.1.4  christos 	    }
   4378  1.1.1.4  christos 
   4379  1.1.1.4  christos 	  free (reloc);
   4380  1.1.1.4  christos 	  return & no_relocs;
   4381  1.1.1.4  christos 	}
   4382      1.1     skrll     }
   4383  1.1.1.4  christos   else
   4384  1.1.1.4  christos     {
   4385  1.1.1.4  christos #if 0
   4386  1.1.1.4  christos       if (fixp->fx_r_type == BFD_RELOC_MSP430X_ABS16
   4387  1.1.1.4  christos 	  && S_GET_SEGMENT (fixp->fx_addsy) == absolute_section)
   4388  1.1.1.4  christos 	{
   4389  1.1.1.4  christos 	  bfd_vma amount = S_GET_VALUE (fixp->fx_addsy);
   4390  1.1.1.4  christos 	  char *fixpos = fixp->fx_where + fixp->fx_frag->fr_literal;
   4391      1.1     skrll 
   4392  1.1.1.4  christos 	  md_number_to_chars (fixpos, amount, 2);
   4393  1.1.1.4  christos 	  free (reloc);
   4394  1.1.1.4  christos 	  return & no_relocs;
   4395  1.1.1.4  christos 	}
   4396  1.1.1.4  christos #endif
   4397  1.1.1.5  christos       reloc->sym_ptr_ptr = XNEW (asymbol *);
   4398  1.1.1.4  christos       *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
   4399  1.1.1.4  christos       reloc->addend = fixp->fx_offset;
   4400      1.1     skrll 
   4401  1.1.1.4  christos       if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
   4402  1.1.1.4  christos 	  || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
   4403  1.1.1.4  christos 	reloc->address = fixp->fx_offset;
   4404  1.1.1.4  christos     }
   4405      1.1     skrll 
   4406  1.1.1.4  christos   return relocs;
   4407      1.1     skrll }
   4408      1.1     skrll 
   4409      1.1     skrll int
   4410      1.1     skrll md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
   4411      1.1     skrll 			       asection * segment_type ATTRIBUTE_UNUSED)
   4412      1.1     skrll {
   4413      1.1     skrll   if (fragP->fr_symbol && S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
   4414      1.1     skrll     {
   4415      1.1     skrll       /* This is a jump -> pcrel mode. Nothing to do much here.
   4416      1.1     skrll          Return value == 2.  */
   4417      1.1     skrll       fragP->fr_subtype =
   4418      1.1     skrll 	  ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_BITS10);
   4419      1.1     skrll     }
   4420      1.1     skrll   else if (fragP->fr_symbol)
   4421      1.1     skrll     {
   4422  1.1.1.6  christos       /* It's got a segment, but it's not ours.   Even if fr_symbol is in
   4423      1.1     skrll 	 an absolute segment, we don't know a displacement until we link
   4424      1.1     skrll 	 object files. So it will always be long. This also applies to
   4425      1.1     skrll 	 labels in a subsegment of current. Liker may relax it to short
   4426      1.1     skrll 	 jump later. Return value == 8.  */
   4427      1.1     skrll       fragP->fr_subtype =
   4428      1.1     skrll 	  ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_WORD);
   4429      1.1     skrll     }
   4430      1.1     skrll   else
   4431      1.1     skrll     {
   4432      1.1     skrll       /* We know the abs value. may be it is a jump to fixed address.
   4433      1.1     skrll          Impossible in our case, cause all constants already handled. */
   4434      1.1     skrll       fragP->fr_subtype =
   4435      1.1     skrll 	  ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_UNDEF);
   4436      1.1     skrll     }
   4437      1.1     skrll 
   4438      1.1     skrll   return md_relax_table[fragP->fr_subtype].rlx_length;
   4439      1.1     skrll }
   4440      1.1     skrll 
   4441      1.1     skrll void
   4442      1.1     skrll md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
   4443      1.1     skrll 		 asection * sec ATTRIBUTE_UNUSED,
   4444      1.1     skrll 		 fragS * fragP)
   4445      1.1     skrll {
   4446      1.1     skrll   char * where = 0;
   4447      1.1     skrll   int rela = -1;
   4448      1.1     skrll   int i;
   4449      1.1     skrll   struct rcodes_s * cc = NULL;
   4450      1.1     skrll   struct hcodes_s * hc = NULL;
   4451      1.1     skrll 
   4452      1.1     skrll   switch (fragP->fr_subtype)
   4453      1.1     skrll     {
   4454      1.1     skrll     case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_BITS10):
   4455      1.1     skrll     case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_BITS10):
   4456      1.1     skrll     case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_BITS10):
   4457      1.1     skrll       /* We do not have to convert anything here.
   4458      1.1     skrll          Just apply a fix.  */
   4459      1.1     skrll       rela = BFD_RELOC_MSP430_10_PCREL;
   4460      1.1     skrll       break;
   4461      1.1     skrll 
   4462      1.1     skrll     case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_WORD):
   4463      1.1     skrll     case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_UNDEF):
   4464      1.1     skrll       /* Convert uncond branch jmp lab -> br lab.  */
   4465  1.1.1.4  christos       if (target_is_430x ())
   4466  1.1.1.4  christos 	cc = msp430x_rcodes + 7;
   4467  1.1.1.4  christos       else
   4468  1.1.1.4  christos 	cc = msp430_rcodes + 7;
   4469      1.1     skrll       where = fragP->fr_literal + fragP->fr_fix;
   4470      1.1     skrll       bfd_putl16 (cc->lop0, where);
   4471      1.1     skrll       rela = BFD_RELOC_MSP430_RL_PCREL;
   4472      1.1     skrll       fragP->fr_fix += 2;
   4473      1.1     skrll       break;
   4474      1.1     skrll 
   4475      1.1     skrll     case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_WORD):
   4476      1.1     skrll     case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_UNDEF):
   4477      1.1     skrll       {
   4478      1.1     skrll 	/* Other simple branches.  */
   4479      1.1     skrll 	int insn = bfd_getl16 (fragP->fr_opcode);
   4480      1.1     skrll 
   4481      1.1     skrll 	insn &= 0xffff;
   4482      1.1     skrll 	/* Find actual instruction.  */
   4483  1.1.1.4  christos 	if (target_is_430x ())
   4484  1.1.1.4  christos 	  {
   4485  1.1.1.4  christos 	    for (i = 0; i < 7 && !cc; i++)
   4486  1.1.1.4  christos 	      if (msp430x_rcodes[i].sop == insn)
   4487  1.1.1.4  christos 		cc = msp430x_rcodes + i;
   4488  1.1.1.4  christos 	  }
   4489  1.1.1.4  christos 	else
   4490  1.1.1.4  christos 	  {
   4491  1.1.1.4  christos 	    for (i = 0; i < 7 && !cc; i++)
   4492  1.1.1.4  christos 	      if (msp430_rcodes[i].sop == insn)
   4493  1.1.1.4  christos 		cc = & msp430_rcodes[i];
   4494  1.1.1.4  christos 	  }
   4495  1.1.1.4  christos 
   4496      1.1     skrll 	if (!cc || !cc->name)
   4497      1.1     skrll 	  as_fatal (_("internal inconsistency problem in %s: insn %04lx"),
   4498      1.1     skrll 		    __FUNCTION__, (long) insn);
   4499      1.1     skrll 	where = fragP->fr_literal + fragP->fr_fix;
   4500      1.1     skrll 	bfd_putl16 (cc->lop0, where);
   4501      1.1     skrll 	bfd_putl16 (cc->lop1, where + 2);
   4502      1.1     skrll 	rela = BFD_RELOC_MSP430_RL_PCREL;
   4503      1.1     skrll 	fragP->fr_fix += 4;
   4504      1.1     skrll       }
   4505      1.1     skrll       break;
   4506      1.1     skrll 
   4507      1.1     skrll     case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_WORD):
   4508      1.1     skrll     case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_UNDEF):
   4509  1.1.1.4  christos       if (target_is_430x ())
   4510  1.1.1.4  christos 	cc = msp430x_rcodes + 6;
   4511  1.1.1.4  christos       else
   4512  1.1.1.4  christos 	cc = msp430_rcodes + 6;
   4513      1.1     skrll       where = fragP->fr_literal + fragP->fr_fix;
   4514      1.1     skrll       bfd_putl16 (cc->lop0, where);
   4515      1.1     skrll       bfd_putl16 (cc->lop1, where + 2);
   4516      1.1     skrll       bfd_putl16 (cc->lop2, where + 4);
   4517      1.1     skrll       rela = BFD_RELOC_MSP430_RL_PCREL;
   4518      1.1     skrll       fragP->fr_fix += 6;
   4519      1.1     skrll       break;
   4520      1.1     skrll 
   4521      1.1     skrll     case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_BITS10):
   4522      1.1     skrll       {
   4523      1.1     skrll 	int insn = bfd_getl16 (fragP->fr_opcode + 2);
   4524      1.1     skrll 
   4525      1.1     skrll 	insn &= 0xffff;
   4526  1.1.1.4  christos 	if (target_is_430x ())
   4527  1.1.1.4  christos 	  {
   4528  1.1.1.4  christos 	    for (i = 0; i < 4 && !hc; i++)
   4529  1.1.1.4  christos 	      if (msp430x_hcodes[i].op1 == insn)
   4530  1.1.1.4  christos 		hc = msp430x_hcodes + i;
   4531  1.1.1.4  christos 	  }
   4532  1.1.1.4  christos 	else
   4533  1.1.1.4  christos 	  {
   4534  1.1.1.4  christos 	    for (i = 0; i < 4 && !hc; i++)
   4535  1.1.1.4  christos 	      if (msp430_hcodes[i].op1 == insn)
   4536  1.1.1.4  christos 		hc = &msp430_hcodes[i];
   4537  1.1.1.4  christos 	  }
   4538      1.1     skrll 	if (!hc || !hc->name)
   4539      1.1     skrll 	  as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
   4540      1.1     skrll 	      __FUNCTION__, (long) insn);
   4541      1.1     skrll 	rela = BFD_RELOC_MSP430_10_PCREL;
   4542      1.1     skrll 	/* Apply a fix for a first label if necessary.
   4543      1.1     skrll 	   another fix will be applied to the next word of insn anyway.  */
   4544      1.1     skrll 	if (hc->tlab == 2)
   4545      1.1     skrll 	  fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
   4546  1.1.1.4  christos 		   fragP->fr_offset, TRUE, rela);
   4547      1.1     skrll 	fragP->fr_fix += 2;
   4548      1.1     skrll       }
   4549      1.1     skrll 
   4550      1.1     skrll       break;
   4551      1.1     skrll 
   4552      1.1     skrll     case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_WORD):
   4553      1.1     skrll     case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_UNDEF):
   4554      1.1     skrll       {
   4555      1.1     skrll 	int insn = bfd_getl16 (fragP->fr_opcode + 2);
   4556      1.1     skrll 
   4557      1.1     skrll 	insn &= 0xffff;
   4558  1.1.1.4  christos 	if (target_is_430x ())
   4559  1.1.1.4  christos 	  {
   4560  1.1.1.4  christos 	    for (i = 0; i < 4 && !hc; i++)
   4561  1.1.1.4  christos 	      if (msp430x_hcodes[i].op1 == insn)
   4562  1.1.1.4  christos 		hc = msp430x_hcodes + i;
   4563  1.1.1.4  christos 	  }
   4564  1.1.1.4  christos 	else
   4565  1.1.1.4  christos 	  {
   4566  1.1.1.4  christos 	    for (i = 0; i < 4 && !hc; i++)
   4567  1.1.1.4  christos 	      if (msp430_hcodes[i].op1 == insn)
   4568  1.1.1.4  christos 		hc = & msp430_hcodes[i];
   4569  1.1.1.4  christos 	  }
   4570      1.1     skrll 	if (!hc || !hc->name)
   4571      1.1     skrll 	  as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
   4572      1.1     skrll 	      __FUNCTION__, (long) insn);
   4573      1.1     skrll 	rela = BFD_RELOC_MSP430_RL_PCREL;
   4574      1.1     skrll 	where = fragP->fr_literal + fragP->fr_fix;
   4575      1.1     skrll 	bfd_putl16 (hc->lop0, where);
   4576      1.1     skrll 	bfd_putl16 (hc->lop1, where + 2);
   4577      1.1     skrll 	bfd_putl16 (hc->lop2, where + 4);
   4578      1.1     skrll 	fragP->fr_fix += 6;
   4579      1.1     skrll       }
   4580      1.1     skrll       break;
   4581      1.1     skrll 
   4582      1.1     skrll     default:
   4583  1.1.1.6  christos       as_fatal (_("internal inconsistency problem in %s: %lx"),
   4584      1.1     skrll 		__FUNCTION__, (long) fragP->fr_subtype);
   4585      1.1     skrll       break;
   4586      1.1     skrll     }
   4587      1.1     skrll 
   4588      1.1     skrll   /* Now apply fix.  */
   4589      1.1     skrll   fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
   4590      1.1     skrll 	   fragP->fr_offset, TRUE, rela);
   4591      1.1     skrll   /* Just fixed 2 bytes.  */
   4592      1.1     skrll   fragP->fr_fix += 2;
   4593      1.1     skrll }
   4594      1.1     skrll 
   4595      1.1     skrll /* Relax fragment. Mostly stolen from hc11 and mcore
   4596      1.1     skrll    which arches I think I know.  */
   4597      1.1     skrll 
   4598      1.1     skrll long
   4599      1.1     skrll msp430_relax_frag (segT seg ATTRIBUTE_UNUSED, fragS * fragP,
   4600      1.1     skrll 		   long stretch ATTRIBUTE_UNUSED)
   4601      1.1     skrll {
   4602      1.1     skrll   long growth;
   4603      1.1     skrll   offsetT aim = 0;
   4604      1.1     skrll   symbolS *symbolP;
   4605      1.1     skrll   const relax_typeS *this_type;
   4606      1.1     skrll   const relax_typeS *start_type;
   4607      1.1     skrll   relax_substateT next_state;
   4608      1.1     skrll   relax_substateT this_state;
   4609      1.1     skrll   const relax_typeS *table = md_relax_table;
   4610      1.1     skrll 
   4611      1.1     skrll   /* Nothing to be done if the frag has already max size.  */
   4612      1.1     skrll   if (RELAX_STATE (fragP->fr_subtype) == STATE_UNDEF
   4613      1.1     skrll       || RELAX_STATE (fragP->fr_subtype) == STATE_WORD)
   4614      1.1     skrll     return 0;
   4615      1.1     skrll 
   4616      1.1     skrll   if (RELAX_STATE (fragP->fr_subtype) == STATE_BITS10)
   4617      1.1     skrll     {
   4618      1.1     skrll       symbolP = fragP->fr_symbol;
   4619      1.1     skrll       if (symbol_resolved_p (symbolP))
   4620      1.1     skrll 	as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
   4621      1.1     skrll 		  __FUNCTION__);
   4622      1.1     skrll       /* We know the offset. calculate a distance.  */
   4623      1.1     skrll       aim = S_GET_VALUE (symbolP) - fragP->fr_address - fragP->fr_fix;
   4624      1.1     skrll     }
   4625      1.1     skrll 
   4626      1.1     skrll   if (!msp430_enable_relax)
   4627      1.1     skrll     {
   4628      1.1     skrll       /* Relaxation is not enabled. So, make all jump as long ones
   4629  1.1.1.4  christos          by setting 'aim' to quite high value.  */
   4630      1.1     skrll       aim = 0x7fff;
   4631      1.1     skrll     }
   4632  1.1.1.4  christos 
   4633      1.1     skrll   this_state = fragP->fr_subtype;
   4634      1.1     skrll   start_type = this_type = table + this_state;
   4635      1.1     skrll 
   4636      1.1     skrll   if (aim < 0)
   4637      1.1     skrll     {
   4638      1.1     skrll       /* Look backwards.  */
   4639      1.1     skrll       for (next_state = this_type->rlx_more; next_state;)
   4640      1.1     skrll 	if (aim >= this_type->rlx_backward || !this_type->rlx_backward)
   4641      1.1     skrll 	  next_state = 0;
   4642      1.1     skrll 	else
   4643      1.1     skrll 	  {
   4644      1.1     skrll 	    /* Grow to next state.  */
   4645      1.1     skrll 	    this_state = next_state;
   4646      1.1     skrll 	    this_type = table + this_state;
   4647      1.1     skrll 	    next_state = this_type->rlx_more;
   4648      1.1     skrll 	  }
   4649      1.1     skrll     }
   4650      1.1     skrll   else
   4651      1.1     skrll     {
   4652      1.1     skrll       /* Look forwards.  */
   4653      1.1     skrll       for (next_state = this_type->rlx_more; next_state;)
   4654      1.1     skrll 	if (aim <= this_type->rlx_forward || !this_type->rlx_forward)
   4655      1.1     skrll 	  next_state = 0;
   4656      1.1     skrll 	else
   4657      1.1     skrll 	  {
   4658      1.1     skrll 	    /* Grow to next state.  */
   4659      1.1     skrll 	    this_state = next_state;
   4660      1.1     skrll 	    this_type = table + this_state;
   4661      1.1     skrll 	    next_state = this_type->rlx_more;
   4662      1.1     skrll 	  }
   4663      1.1     skrll     }
   4664      1.1     skrll 
   4665      1.1     skrll   growth = this_type->rlx_length - start_type->rlx_length;
   4666      1.1     skrll   if (growth != 0)
   4667      1.1     skrll     fragP->fr_subtype = this_state;
   4668      1.1     skrll   return growth;
   4669      1.1     skrll }
   4670  1.1.1.4  christos 
   4671  1.1.1.4  christos /* Return FALSE if the fixup in fixp should be left alone and not
   4672  1.1.1.4  christos    adjusted.   We return FALSE here so that linker relaxation will
   4673  1.1.1.4  christos    work.  */
   4674  1.1.1.4  christos 
   4675  1.1.1.4  christos bfd_boolean
   4676  1.1.1.4  christos msp430_fix_adjustable (struct fix *fixp ATTRIBUTE_UNUSED)
   4677  1.1.1.4  christos {
   4678  1.1.1.4  christos   /* If the symbol is in a non-code section then it should be OK.  */
   4679  1.1.1.4  christos   if (fixp->fx_addsy
   4680  1.1.1.4  christos       && ((S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_CODE) == 0))
   4681  1.1.1.4  christos     return TRUE;
   4682  1.1.1.4  christos 
   4683  1.1.1.4  christos   return FALSE;
   4684  1.1.1.4  christos }
   4685  1.1.1.4  christos 
   4686  1.1.1.4  christos /* Set the contents of the .MSP430.attributes section.  */
   4687  1.1.1.4  christos 
   4688  1.1.1.4  christos void
   4689  1.1.1.4  christos msp430_md_end (void)
   4690  1.1.1.4  christos {
   4691  1.1.1.4  christos   if (check_for_nop)
   4692  1.1.1.4  christos     as_warn ("assembly finished without a possibly needed NOP instruction");
   4693  1.1.1.4  christos 
   4694  1.1.1.4  christos   bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_ISA,
   4695  1.1.1.4  christos 			     target_is_430x () ? 2 : 1);
   4696  1.1.1.4  christos 
   4697  1.1.1.4  christos   bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_Code_Model,
   4698  1.1.1.4  christos 			     large_model ? 2 : 1);
   4699  1.1.1.4  christos 
   4700  1.1.1.4  christos   bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_Data_Model,
   4701  1.1.1.4  christos 			     large_model ? 2 : 1);
   4702  1.1.1.4  christos }
   4703  1.1.1.4  christos 
   4704  1.1.1.4  christos /* Returns FALSE if there is a msp430 specific reason why the
   4705  1.1.1.4  christos    subtraction of two same-section symbols cannot be computed by
   4706  1.1.1.4  christos    the assembler.  */
   4707  1.1.1.4  christos 
   4708  1.1.1.4  christos bfd_boolean
   4709  1.1.1.4  christos msp430_allow_local_subtract (expressionS * left,
   4710  1.1.1.4  christos 			     expressionS * right,
   4711  1.1.1.4  christos 			     segT section)
   4712  1.1.1.4  christos {
   4713  1.1.1.4  christos   /* If the symbols are not in a code section then they are OK.  */
   4714  1.1.1.4  christos   if ((section->flags & SEC_CODE) == 0)
   4715  1.1.1.4  christos     return TRUE;
   4716  1.1.1.4  christos 
   4717  1.1.1.4  christos   if (S_IS_GAS_LOCAL (left->X_add_symbol) || S_IS_GAS_LOCAL (right->X_add_symbol))
   4718  1.1.1.4  christos     return TRUE;
   4719  1.1.1.4  christos 
   4720  1.1.1.4  christos   if (left->X_add_symbol == right->X_add_symbol)
   4721  1.1.1.4  christos     return TRUE;
   4722  1.1.1.4  christos 
   4723  1.1.1.4  christos   /* We have to assume that there may be instructions between the
   4724  1.1.1.4  christos      two symbols and that relaxation may increase the distance between
   4725  1.1.1.4  christos      them.  */
   4726  1.1.1.4  christos   return FALSE;
   4727  1.1.1.4  christos }
   4728