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