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