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