* archures.c: Add some more MSP430 machine numbers.
[deliverable/binutils-gdb.git] / gas / config / tc-msp430.c
CommitLineData
2469cfa2
NC
1/* tc-msp430.c -- Assembler code for the Texas Instruments MSP430
2
13761a11 3 Copyright (C) 2002-2013 Free Software Foundation, Inc.
2469cfa2
NC
4 Contributed by Dmitry Diky <diwil@mail.ru>
5
6 This file is part of GAS, the GNU Assembler.
7
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
ec2655a6 10 the Free Software Foundation; either version 3, or (at your option)
2469cfa2
NC
11 any later version.
12
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GAS; see the file COPYING. If not, write to
4b4da160
NC
20 the Free Software Foundation, 51 Franklin Street - Fifth Floor,
21 Boston, MA 02110-1301, USA. */
2469cfa2 22
df7b86aa 23#include "as.h"
2469cfa2 24#include <limits.h>
2469cfa2 25#define PUSH_1X_WORKAROUND
2469cfa2
NC
26#include "subsegs.h"
27#include "opcode/msp430.h"
28#include "safe-ctype.h"
2a9a06c1 29#include "dwarf2dbg.h"
13761a11 30#include "elf/msp430.h"
2469cfa2 31
79cf5950 32/* We will disable polymorphs by default because it is dangerous.
708587a4 33 The potential problem here is the following: assume we got the
77592908
DD
34 following code:
35
36 jump .l1
37 nop
38 jump subroutine ; external symbol
39 .l1:
40 nop
41 ret
13761a11 42
77592908
DD
43 In case of assembly time relaxation we'll get:
44 0: jmp .l1 <.text +0x08> (reloc deleted)
45 2: nop
46 4: br subroutine
47 .l1:
48 8: nop
49 10: ret
50
79cf5950
NC
51 If the 'subroutine' is within +-1024 bytes range then linker
52 will produce:
77592908
DD
53 0: jmp .text +0x08
54 2: nop
55 4: jmp subroutine
56 .l1:
57 6: nop
58 8: ret ; 'jmp .text +0x08' will land here. WRONG!!!
59
77592908 60 The workaround is the following:
79cf5950 61 1. Declare global var enable_polymorphs which set to 1 via option -mp.
77592908
DD
62 2. Declare global var enable_relax which set to 1 via option -mQ.
63
64 If polymorphs are enabled, and relax isn't, treat all jumps as long jumps,
65 do not delete any relocs and leave them for linker.
13761a11 66
79cf5950 67 If relax is enabled, relax at assembly time and kill relocs as necessary. */
77592908
DD
68
69int msp430_enable_relax;
70int msp430_enable_polys;
71
13761a11
NC
72/* Set linkrelax here to avoid fixups in most sections. */
73int linkrelax = 1;
74
f5c7edf4
AM
75/* GCC uses the some condition codes which we'll
76 implement as new polymorph instructions.
13761a11 77
f5c7edf4
AM
78 COND EXPL SHORT JUMP LONG JUMP
79 ===============================================
80 eq == jeq jne +4; br lab
81 ne != jne jeq +4; br lab
82
83 ltn honours no-overflow flag
84 ltn < jn jn +2; jmp +4; br lab
85
13761a11 86 lt < jl jge +4; br lab
f5c7edf4
AM
87 ltu < jlo lhs +4; br lab
88 le <= see below
89 leu <= see below
90
91 gt > see below
92 gtu > see below
93 ge >= jge jl +4; br lab
94 geu >= jhs jlo +4; br lab
95 ===============================================
96
97 Therefore, new opcodes are (BranchEQ -> beq; and so on...)
98 beq,bne,blt,bltn,bltu,bge,bgeu
13761a11
NC
99 'u' means unsigned compares
100
f5c7edf4
AM
101 Also, we add 'jump' instruction:
102 jump UNCOND -> jmp br lab
103
104 They will have fmt == 4, and insn_opnumb == number of instruction. */
105
13761a11 106struct rcodes_s
f5c7edf4
AM
107{
108 char * name;
109 int index; /* Corresponding insn_opnumb. */
110 int sop; /* Opcode if jump length is short. */
111 long lpos; /* Label position. */
112 long lop0; /* Opcode 1 _word_ (16 bits). */
113 long lop1; /* Opcode second word. */
114 long lop2; /* Opcode third word. */
115};
116
117#define MSP430_RLC(n,i,sop,o1) \
118 {#n, i, sop, 2, (o1 + 2), 0x4010, 0}
119
13761a11 120static struct rcodes_s msp430_rcodes[] =
f5c7edf4
AM
121{
122 MSP430_RLC (beq, 0, 0x2400, 0x2000),
123 MSP430_RLC (bne, 1, 0x2000, 0x2400),
124 MSP430_RLC (blt, 2, 0x3800, 0x3400),
125 MSP430_RLC (bltu, 3, 0x2800, 0x2c00),
126 MSP430_RLC (bge, 4, 0x3400, 0x3800),
127 MSP430_RLC (bgeu, 5, 0x2c00, 0x2800),
128 {"bltn", 6, 0x3000, 3, 0x3000 + 1, 0x3c00 + 2,0x4010},
129 {"jump", 7, 0x3c00, 1, 0x4010, 0, 0},
130 {0,0,0,0,0,0,0}
131};
f5c7edf4 132
13761a11
NC
133#undef MSP430_RLC
134#define MSP430_RLC(n,i,sop,o1) \
135 {#n, i, sop, 2, (o1 + 2), 0x0030, 0}
136
137static struct rcodes_s msp430x_rcodes[] =
138{
139 MSP430_RLC (beq, 0, 0x2400, 0x2000),
140 MSP430_RLC (bne, 1, 0x2000, 0x2400),
141 MSP430_RLC (blt, 2, 0x3800, 0x3400),
142 MSP430_RLC (bltu, 3, 0x2800, 0x2c00),
143 MSP430_RLC (bge, 4, 0x3400, 0x3800),
144 MSP430_RLC (bgeu, 5, 0x2c00, 0x2800),
145 {"bltn", 6, 0x3000, 3, 0x0030 + 1, 0x3c00 + 2, 0x3000},
146 {"jump", 7, 0x3c00, 1, 0x0030, 0, 0},
147 {0,0,0,0,0,0,0}
148};
149#undef MSP430_RLC
f5c7edf4
AM
150
151/* More difficult than above and they have format 5.
13761a11 152
f5c7edf4
AM
153 COND EXPL SHORT LONG
154 =================================================================
155 gt > jeq +2; jge label jeq +6; jl +4; br label
156 gtu > jeq +2; jhs label jeq +6; jlo +4; br label
157 leu <= jeq label; jlo label jeq +2; jhs +4; br label
158 le <= jeq label; jl label jeq +2; jge +4; br label
159 ================================================================= */
160
13761a11 161struct hcodes_s
f5c7edf4 162{
13761a11 163 char * name;
f5c7edf4
AM
164 int index; /* Corresponding insn_opnumb. */
165 int tlab; /* Number of labels in short mode. */
166 int op0; /* Opcode for first word of short jump. */
167 int op1; /* Opcode for second word of short jump. */
168 int lop0; /* Opcodes for long jump mode. */
169 int lop1;
170 int lop2;
171};
172
13761a11 173static struct hcodes_s msp430_hcodes[] =
f5c7edf4
AM
174{
175 {"bgt", 0, 1, 0x2401, 0x3400, 0x2403, 0x3802, 0x4010 },
176 {"bgtu", 1, 1, 0x2401, 0x2c00, 0x2403, 0x2802, 0x4010 },
177 {"bleu", 2, 2, 0x2400, 0x2800, 0x2401, 0x2c02, 0x4010 },
178 {"ble", 3, 2, 0x2400, 0x3800, 0x2401, 0x3402, 0x4010 },
179 {0,0,0,0,0,0,0,0}
180};
181
13761a11
NC
182static struct hcodes_s msp430x_hcodes[] =
183{
184 {"bgt", 0, 1, 0x2401, 0x3400, 0x2403, 0x3802, 0x0030 },
185 {"bgtu", 1, 1, 0x2401, 0x2c00, 0x2403, 0x2802, 0x0030 },
186 {"bleu", 2, 2, 0x2400, 0x2800, 0x2401, 0x2c02, 0x0030 },
187 {"ble", 3, 2, 0x2400, 0x3800, 0x2401, 0x3402, 0x0030 },
188 {0,0,0,0,0,0,0,0}
189};
190
2469cfa2
NC
191const char comment_chars[] = ";";
192const char line_comment_chars[] = "#";
870074dd 193const char line_separator_chars[] = "{";
2469cfa2
NC
194const char EXP_CHARS[] = "eE";
195const char FLT_CHARS[] = "dD";
196
197/* Handle long expressions. */
198extern LITTLENUM_TYPE generic_bignum[];
199
200static struct hash_control *msp430_hash;
201
b18c562e
NC
202/* Relaxations. */
203#define STATE_UNCOND_BRANCH 1 /* jump */
204#define STATE_NOOV_BRANCH 3 /* bltn */
205#define STATE_SIMPLE_BRANCH 2 /* bne, beq, etc... */
206#define STATE_EMUL_BRANCH 4
207
208#define CNRL 2
209#define CUBL 4
210#define CNOL 8
211#define CSBL 6
212#define CEBL 4
213
214/* Length. */
215#define STATE_BITS10 1 /* wild guess. short jump */
216#define STATE_WORD 2 /* 2 bytes pc rel. addr. more */
217#define STATE_UNDEF 3 /* cannot handle this yet. convert to word mode */
218
219#define ENCODE_RELAX(what,length) (((what) << 2) + (length))
220#define RELAX_STATE(s) ((s) & 3)
221#define RELAX_LEN(s) ((s) >> 2)
222#define RELAX_NEXT(a,b) ENCODE_RELAX (a, b + 1)
223
224relax_typeS md_relax_table[] =
225{
226 /* Unused. */
227 {1, 1, 0, 0},
228 {1, 1, 0, 0},
229 {1, 1, 0, 0},
230 {1, 1, 0, 0},
231
232 /* Unconditional jump. */
233 {1, 1, 8, 5},
234 {1024, -1024, CNRL, RELAX_NEXT (STATE_UNCOND_BRANCH, STATE_BITS10)}, /* state 10 bits displ */
235 {0, 0, CUBL, RELAX_NEXT (STATE_UNCOND_BRANCH, STATE_WORD)}, /* state word */
236 {1, 1, CUBL, 0}, /* state undef */
237
238 /* Simple branches. */
239 {0, 0, 8, 9},
240 {1024, -1024, CNRL, RELAX_NEXT (STATE_SIMPLE_BRANCH, STATE_BITS10)}, /* state 10 bits displ */
241 {0, 0, CSBL, RELAX_NEXT (STATE_SIMPLE_BRANCH, STATE_WORD)}, /* state word */
242 {1, 1, CSBL, 0},
243
244 /* blt no overflow branch. */
245 {1, 1, 8, 13},
246 {1024, -1024, CNRL, RELAX_NEXT (STATE_NOOV_BRANCH, STATE_BITS10)}, /* state 10 bits displ */
247 {0, 0, CNOL, RELAX_NEXT (STATE_NOOV_BRANCH, STATE_WORD)}, /* state word */
248 {1, 1, CNOL, 0},
249
250 /* Emulated branches. */
251 {1, 1, 8, 17},
252 {1020, -1020, CEBL, RELAX_NEXT (STATE_EMUL_BRANCH, STATE_BITS10)}, /* state 10 bits displ */
253 {0, 0, CNOL, RELAX_NEXT (STATE_EMUL_BRANCH, STATE_WORD)}, /* state word */
254 {1, 1, CNOL, 0}
255};
256
2469cfa2 257
8cd5b113 258#define MAX_OP_LEN 256
2469cfa2
NC
259
260struct mcu_type_s
261{
b18c562e 262 char * name;
2469cfa2
NC
263 int isa;
264 int mach;
265};
266
267#define MSP430_ISA_11 11
3b260895 268#define MSP430_ISA_110 110
2469cfa2
NC
269#define MSP430_ISA_12 12
270#define MSP430_ISA_13 13
271#define MSP430_ISA_14 14
3b260895
NC
272#define MSP430_ISA_15 15
273#define MSP430_ISA_16 16
13761a11 274#define MSP430_ISA_20 20
44c86e8c 275#define MSP430_ISA_21 21
13761a11
NC
276#define MSP430_ISA_22 22
277#define MSP430_ISA_23 23
278#define MSP430_ISA_24 24
279#define MSP430_ISA_26 26
2469cfa2
NC
280#define MSP430_ISA_31 31
281#define MSP430_ISA_32 32
282#define MSP430_ISA_33 33
3b260895
NC
283#define MSP430_ISA_41 41
284#define MSP430_ISA_42 42
2469cfa2
NC
285#define MSP430_ISA_43 43
286#define MSP430_ISA_44 44
13761a11
NC
287#define MSP430X_ISA 45
288#define MSP430_ISA_46 46
289#define MSP430_ISA_47 47
290#define MSP430_ISA_54 54
291
292/* Generate a 16-bit relocation.
293 For the 430X we generate a relocation without linkwer range checking
294 if the value is being used in an extended (ie 20-bit) instruction.
295 For the 430 we generate a relocation without assembler range checking
296 if we are handling an immediate value or a byte-width instruction. */
297#undef CHECK_RELOC_MSP430
298#define CHECK_RELOC_MSP430 \
299 (msp430_mcu->isa == MSP430X_ISA \
300 ? (extended_op ? BFD_RELOC_16 : BFD_RELOC_MSP430X_ABS16) \
301 : ((imm_op || byte_op) \
302 ? BFD_RELOC_MSP430_16_BYTE : BFD_RELOC_MSP430_16))
303
304/* Generate a 16-bit pc-relative relocation.
305 For the 430X we generate a relocation without linkwer range checking.
306 For the 430 we generate a relocation without assembler range checking
307 if we are handling an immediate value or a byte-width instruction. */
308#undef CHECK_RELOC_MSP430_PCREL
309#define CHECK_RELOC_MSP430_PCREL \
310 (msp430_mcu->isa == MSP430X_ISA \
311 ? BFD_RELOC_MSP430X_PCR16 \
312 : (imm_op || byte_op) \
313 ? BFD_RELOC_MSP430_16_PCREL_BYTE : BFD_RELOC_MSP430_16_PCREL)
2469cfa2
NC
314
315static struct mcu_type_s mcu_types[] =
316{
b18c562e
NC
317 {"msp1", MSP430_ISA_11, bfd_mach_msp11},
318 {"msp2", MSP430_ISA_14, bfd_mach_msp14},
13761a11
NC
319 {"msp3", MSP430_ISA_20, bfd_mach_msp20},
320 {"msp4", MSP430_ISA_24, bfd_mach_msp24},
321 {"msp5", MSP430_ISA_31, bfd_mach_msp31},
322 {"msp6", MSP430_ISA_42, bfd_mach_msp42},
323
b18c562e
NC
324 {"msp430x110", MSP430_ISA_11, bfd_mach_msp11},
325 {"msp430x112", MSP430_ISA_11, bfd_mach_msp11},
326 {"msp430x1101", MSP430_ISA_110, bfd_mach_msp110},
327 {"msp430x1111", MSP430_ISA_110, bfd_mach_msp110},
328 {"msp430x1121", MSP430_ISA_110, bfd_mach_msp110},
329 {"msp430x1122", MSP430_ISA_11, bfd_mach_msp110},
330 {"msp430x1132", MSP430_ISA_11, bfd_mach_msp110},
331
332 {"msp430x122", MSP430_ISA_12, bfd_mach_msp12},
333 {"msp430x123", MSP430_ISA_12, bfd_mach_msp12},
334 {"msp430x1222", MSP430_ISA_12, bfd_mach_msp12},
335 {"msp430x1232", MSP430_ISA_12, bfd_mach_msp12},
336
337 {"msp430x133", MSP430_ISA_13, bfd_mach_msp13},
338 {"msp430x135", MSP430_ISA_13, bfd_mach_msp13},
339 {"msp430x1331", MSP430_ISA_13, bfd_mach_msp13},
340 {"msp430x1351", MSP430_ISA_13, bfd_mach_msp13},
341 {"msp430x147", MSP430_ISA_14, bfd_mach_msp14},
342 {"msp430x148", MSP430_ISA_14, bfd_mach_msp14},
343 {"msp430x149", MSP430_ISA_14, bfd_mach_msp14},
13761a11
NC
344 {"msp430x1471", MSP430_ISA_14, bfd_mach_msp14},
345 {"msp430x1481", MSP430_ISA_14, bfd_mach_msp14},
346 {"msp430x1491", MSP430_ISA_14, bfd_mach_msp14},
b18c562e
NC
347
348 {"msp430x155", MSP430_ISA_15, bfd_mach_msp15},
349 {"msp430x156", MSP430_ISA_15, bfd_mach_msp15},
350 {"msp430x157", MSP430_ISA_15, bfd_mach_msp15},
351 {"msp430x167", MSP430_ISA_16, bfd_mach_msp16},
352 {"msp430x168", MSP430_ISA_16, bfd_mach_msp16},
353 {"msp430x169", MSP430_ISA_16, bfd_mach_msp16},
c05e9f04
NC
354 {"msp430x1610", MSP430_ISA_16, bfd_mach_msp16},
355 {"msp430x1611", MSP430_ISA_16, bfd_mach_msp16},
356 {"msp430x1612", MSP430_ISA_16, bfd_mach_msp16},
3b260895 357
13761a11
NC
358 {"msp430x2001", MSP430_ISA_20, bfd_mach_msp20},
359 {"msp430x2011", MSP430_ISA_20, bfd_mach_msp20},
360 {"msp430x2002", MSP430_ISA_20, bfd_mach_msp20},
361 {"msp430x2012", MSP430_ISA_20, bfd_mach_msp20},
362 {"msp430x2003", MSP430_ISA_20, bfd_mach_msp20},
363 {"msp430x2013", MSP430_ISA_20, bfd_mach_msp20 },
364
44c86e8c
NC
365 {"msp430x2101", MSP430_ISA_21, bfd_mach_msp21},
366 {"msp430x2111", MSP430_ISA_21, bfd_mach_msp21},
13761a11 367 {"msp430x2112", MSP430_ISA_21, bfd_mach_msp21},
44c86e8c
NC
368 {"msp430x2121", MSP430_ISA_21, bfd_mach_msp21},
369 {"msp430x2131", MSP430_ISA_21, bfd_mach_msp21},
13761a11
NC
370 {"msp430x2132", MSP430_ISA_21, bfd_mach_msp21},
371
372 {"msp430x2232", MSP430_ISA_22, bfd_mach_msp22},
373 {"msp430x2234", MSP430_ISA_22, bfd_mach_msp22},
374 {"msp430x2252", MSP430_ISA_22, bfd_mach_msp22},
375 {"msp430x2254", MSP430_ISA_22, bfd_mach_msp22},
376 {"msp430x2272", MSP430_ISA_22, bfd_mach_msp22},
377 {"msp430x2274", MSP430_ISA_22, bfd_mach_msp22},
378
379 {"msp430x233", MSP430_ISA_23, bfd_mach_msp23},
380 {"msp430x235", MSP430_ISA_23, bfd_mach_msp23},
381 {"msp430x2330", MSP430_ISA_23, bfd_mach_msp23},
382 {"msp430x2350", MSP430_ISA_23, bfd_mach_msp23},
383 {"msp430x2370", MSP430_ISA_23, bfd_mach_msp23},
384
385 {"msp430x247", MSP430_ISA_24, bfd_mach_msp24},
386 {"msp430x2471", MSP430_ISA_24, bfd_mach_msp24},
387 {"msp430x248", MSP430_ISA_24, bfd_mach_msp24},
388 {"msp430x2481", MSP430_ISA_24, bfd_mach_msp24},
389 {"msp430x249", MSP430_ISA_24, bfd_mach_msp24},
390 {"msp430x2491", MSP430_ISA_24, bfd_mach_msp24},
391 {"msp430x2410", MSP430_ISA_24, bfd_mach_msp24},
392 {"msp430x2416", MSP430_ISA_24, bfd_mach_msp24},
393 {"msp430x2417", MSP430_ISA_24, bfd_mach_msp24},
394 {"msp430x2418", MSP430_ISA_24, bfd_mach_msp24},
395 {"msp430x2419", MSP430_ISA_24, bfd_mach_msp24},
396
397 {"msp430x2616", MSP430_ISA_26, bfd_mach_msp26},
398 {"msp430x2617", MSP430_ISA_26, bfd_mach_msp26},
399 {"msp430x2618", MSP430_ISA_26, bfd_mach_msp26},
400 {"msp430x2619", MSP430_ISA_26, bfd_mach_msp26},
401
b18c562e
NC
402 {"msp430x311", MSP430_ISA_31, bfd_mach_msp31},
403 {"msp430x312", MSP430_ISA_31, bfd_mach_msp31},
404 {"msp430x313", MSP430_ISA_31, bfd_mach_msp31},
405 {"msp430x314", MSP430_ISA_31, bfd_mach_msp31},
406 {"msp430x315", MSP430_ISA_31, bfd_mach_msp31},
407 {"msp430x323", MSP430_ISA_32, bfd_mach_msp32},
408 {"msp430x325", MSP430_ISA_32, bfd_mach_msp32},
409 {"msp430x336", MSP430_ISA_33, bfd_mach_msp33},
410 {"msp430x337", MSP430_ISA_33, bfd_mach_msp33},
411
412 {"msp430x412", MSP430_ISA_41, bfd_mach_msp41},
413 {"msp430x413", MSP430_ISA_41, bfd_mach_msp41},
414 {"msp430x415", MSP430_ISA_41, bfd_mach_msp41},
415 {"msp430x417", MSP430_ISA_41, bfd_mach_msp41},
3b260895 416
13761a11
NC
417 {"msp430x423", MSP430_ISA_42, bfd_mach_msp42},
418 {"msp430x425", MSP430_ISA_42, bfd_mach_msp42},
419 {"msp430x427", MSP430_ISA_42, bfd_mach_msp42},
420 {"msp430x4250", MSP430_ISA_42, bfd_mach_msp42},
421 {"msp430x4260", MSP430_ISA_42, bfd_mach_msp42},
422 {"msp430x4270", MSP430_ISA_42, bfd_mach_msp42},
423 {"msp430xG4250",MSP430_ISA_42, bfd_mach_msp42},
424 {"msp430xG4260",MSP430_ISA_42, bfd_mach_msp42},
425 {"msp430xG4270",MSP430_ISA_42, bfd_mach_msp42},
426
3b260895 427 {"msp430xE423", MSP430_ISA_42, bfd_mach_msp42},
13761a11
NC
428 {"msp430xE4232",MSP430_ISA_42, bfd_mach_msp42},
429 {"msp430xE4242",MSP430_ISA_42, bfd_mach_msp42},
430 {"msp430xE4252",MSP430_ISA_42, bfd_mach_msp42},
3b260895
NC
431 {"msp430xE425", MSP430_ISA_42, bfd_mach_msp42},
432 {"msp430xE427", MSP430_ISA_42, bfd_mach_msp42},
13761a11 433 {"msp430xE4272",MSP430_ISA_42, bfd_mach_msp42},
c05e9f04 434
3b260895
NC
435 {"msp430xW423", MSP430_ISA_42, bfd_mach_msp42},
436 {"msp430xW425", MSP430_ISA_42, bfd_mach_msp42},
437 {"msp430xW427", MSP430_ISA_42, bfd_mach_msp42},
438
c05e9f04
NC
439 {"msp430xG437", MSP430_ISA_43, bfd_mach_msp43},
440 {"msp430xG438", MSP430_ISA_43, bfd_mach_msp43},
441 {"msp430xG439", MSP430_ISA_43, bfd_mach_msp43},
442
b18c562e 443 {"msp430x435", MSP430_ISA_43, bfd_mach_msp43},
13761a11 444 {"msp430x4351", MSP430_ISA_43, bfd_mach_msp43},
b18c562e 445 {"msp430x436", MSP430_ISA_43, bfd_mach_msp43},
13761a11 446 {"msp430x4361", MSP430_ISA_43, bfd_mach_msp43},
b18c562e 447 {"msp430x437", MSP430_ISA_43, bfd_mach_msp43},
13761a11
NC
448 {"msp430x4371", MSP430_ISA_43, bfd_mach_msp43},
449
b18c562e
NC
450 {"msp430x447", MSP430_ISA_44, bfd_mach_msp44},
451 {"msp430x448", MSP430_ISA_44, bfd_mach_msp44},
452 {"msp430x449", MSP430_ISA_44, bfd_mach_msp44},
2469cfa2 453
13761a11
NC
454 {"msp430xG4616",MSP430_ISA_46, bfd_mach_msp46},
455 {"msp430xG4617",MSP430_ISA_46, bfd_mach_msp46},
456 {"msp430xG4618",MSP430_ISA_46, bfd_mach_msp46},
457 {"msp430xG4619",MSP430_ISA_46, bfd_mach_msp46},
458
459 {"msp430x4783", MSP430_ISA_47, bfd_mach_msp47},
460 {"msp430x4784", MSP430_ISA_47, bfd_mach_msp47},
461 {"msp430x4793", MSP430_ISA_47, bfd_mach_msp47},
462 {"msp430x4794", MSP430_ISA_47, bfd_mach_msp47},
463 {"msp430x47166",MSP430_ISA_47, bfd_mach_msp47},
464 {"msp430x47176",MSP430_ISA_47, bfd_mach_msp47},
465 {"msp430x47186",MSP430_ISA_47, bfd_mach_msp47},
466 {"msp430x47196",MSP430_ISA_47, bfd_mach_msp47},
467 {"msp430x47167",MSP430_ISA_47, bfd_mach_msp47},
468 {"msp430x47177",MSP430_ISA_47, bfd_mach_msp47},
469 {"msp430x47187",MSP430_ISA_47, bfd_mach_msp47},
470 {"msp430x47197",MSP430_ISA_47, bfd_mach_msp47},
471
472 {"msp430x5418", MSP430_ISA_54, bfd_mach_msp54},
473 {"msp430x5419", MSP430_ISA_54, bfd_mach_msp54},
474 {"msp430x5435", MSP430_ISA_54, bfd_mach_msp54},
475 {"msp430x5436", MSP430_ISA_54, bfd_mach_msp54},
476 {"msp430x5437", MSP430_ISA_54, bfd_mach_msp54},
477 {"msp430x5438", MSP430_ISA_54, bfd_mach_msp54},
478
479 {"msp430X", MSP430X_ISA, bfd_mach_msp430x},
480
2469cfa2
NC
481 {NULL, 0, 0}
482};
483
484
485static struct mcu_type_s default_mcu =
486 { "msp430x11", MSP430_ISA_11, bfd_mach_msp11 };
487
b18c562e
NC
488static struct mcu_type_s * msp430_mcu = & default_mcu;
489
490/* Profiling capability:
491 It is a performance hit to use gcc's profiling approach for this tiny target.
492 Even more -- jtag hardware facility does not perform any profiling functions.
493 However we've got gdb's built-in simulator where we can do anything.
494 Therefore my suggestion is:
495
496 We define new section ".profiler" which holds all profiling information.
497 We define new pseudo operation .profiler which will instruct assembler to
498 add new profile entry to the object file. Profile should take place at the
499 present address.
500
501 Pseudo-op format:
502
503 .profiler flags,function_to_profile [, cycle_corrector, extra]
504
505 where 'flags' is a combination of the following chars:
506 s - function Start
507 x - function eXit
508 i - function is in Init section
509 f - function is in Fini section
510 l - Library call
511 c - libC standard call
512 d - stack value Demand (saved at run-time in simulator)
513 I - Interrupt service routine
514 P - Prologue start
515 p - Prologue end
516 E - Epilogue start
517 e - Epilogue end
518 j - long Jump/ sjlj unwind
519 a - an Arbitrary code fragment
520 t - exTra parameter saved (constant value like frame size)
521 '""' optional: "sil" == sil
522
523 function_to_profile - function's address
524 cycle_corrector - a value which should be added to the cycle
525 counter, zero if omitted
526 extra - some extra parameter, zero if omitted.
527
528 For example:
529 ------------------------------
530 .global fxx
531 .type fxx,@function
532 fxx:
533 .LFrameOffset_fxx=0x08
534 .profiler "scdP", fxx ; function entry.
535 ; we also demand stack value to be displayed
536 push r11
537 push r10
538 push r9
539 push r8
540 .profiler "cdp",fxx,0, .LFrameOffset_fxx ; check stack value at this point
541 ; (this is a prologue end)
79cf5950 542 ; note, that spare var filled with the frame size
b18c562e
NC
543 mov r15,r8
544 ....
545 .profiler cdE,fxx ; check stack
546 pop r8
547 pop r9
548 pop r10
549 pop r11
550 .profiler xcde,fxx,3 ; exit adds 3 to the cycle counter
551 ret ; cause 'ret' insn takes 3 cycles
552 -------------------------------
553
554 This profiling approach does not produce any overhead and
555 absolutely harmless.
556 So, even profiled code can be uploaded to the MCU. */
557#define MSP430_PROFILER_FLAG_ENTRY 1 /* s */
558#define MSP430_PROFILER_FLAG_EXIT 2 /* x */
559#define MSP430_PROFILER_FLAG_INITSECT 4 /* i */
560#define MSP430_PROFILER_FLAG_FINISECT 8 /* f */
561#define MSP430_PROFILER_FLAG_LIBCALL 0x10 /* l */
562#define MSP430_PROFILER_FLAG_STDCALL 0x20 /* c */
563#define MSP430_PROFILER_FLAG_STACKDMD 0x40 /* d */
564#define MSP430_PROFILER_FLAG_ISR 0x80 /* I */
565#define MSP430_PROFILER_FLAG_PROLSTART 0x100 /* P */
566#define MSP430_PROFILER_FLAG_PROLEND 0x200 /* p */
567#define MSP430_PROFILER_FLAG_EPISTART 0x400 /* E */
568#define MSP430_PROFILER_FLAG_EPIEND 0x800 /* e */
569#define MSP430_PROFILER_FLAG_JUMP 0x1000 /* j */
570#define MSP430_PROFILER_FLAG_FRAGMENT 0x2000 /* a */
571#define MSP430_PROFILER_FLAG_EXTRA 0x4000 /* t */
572#define MSP430_PROFILER_FLAG_notyet 0x8000 /* ? */
2469cfa2 573
b18c562e
NC
574static int
575pow2value (int y)
2469cfa2 576{
b18c562e
NC
577 int n = 0;
578 unsigned int x;
2469cfa2 579
b18c562e 580 x = y;
2469cfa2 581
b18c562e
NC
582 if (!x)
583 return 1;
2469cfa2 584
b18c562e
NC
585 for (; x; x = x >> 1)
586 if (x & 1)
587 n++;
588
589 return n == 1;
590}
591
592/* Parse ordinary expression. */
593
594static char *
595parse_exp (char * s, expressionS * op)
2469cfa2 596{
b18c562e
NC
597 input_line_pointer = s;
598 expression (op);
599 if (op->X_op == O_absent)
600 as_bad (_("missing operand"));
601 return input_line_pointer;
602}
2469cfa2 603
b18c562e
NC
604
605/* Delete spaces from s: X ( r 1 2) => X(r12). */
2469cfa2
NC
606
607static void
b18c562e 608del_spaces (char * s)
2469cfa2 609{
b18c562e
NC
610 while (*s)
611 {
612 if (ISSPACE (*s))
613 {
614 char *m = s + 1;
2469cfa2 615
b18c562e
NC
616 while (ISSPACE (*m) && *m)
617 m++;
618 memmove (s, m, strlen (m) + 1);
619 }
620 else
621 s++;
622 }
623}
2469cfa2 624
b18c562e
NC
625static inline char *
626skip_space (char * s)
627{
628 while (ISSPACE (*s))
629 ++s;
630 return s;
631}
2469cfa2 632
708587a4 633/* Extract one word from FROM and copy it to TO. Delimiters are ",;\n" */
b18c562e
NC
634
635static char *
636extract_operand (char * from, char * to, int limit)
637{
638 int size = 0;
639
640 /* Drop leading whitespace. */
641 from = skip_space (from);
642
643 while (size < limit && *from)
644 {
645 *(to + size) = *from;
646 if (*from == ',' || *from == ';' || *from == '\n')
647 break;
648 from++;
649 size++;
650 }
651
652 *(to + size) = 0;
653 del_spaces (to);
654
655 from++;
656
657 return from;
2469cfa2
NC
658}
659
b18c562e
NC
660static void
661msp430_profiler (int dummy ATTRIBUTE_UNUSED)
2469cfa2 662{
b18c562e
NC
663 char buffer[1024];
664 char f[32];
665 char * str = buffer;
666 char * flags = f;
667 int p_flags = 0;
668 char * halt;
669 int ops = 0;
670 int left;
671 char * s;
672 segT seg;
673 int subseg;
674 char * end = 0;
675 expressionS exp;
676 expressionS exp1;
677
678 s = input_line_pointer;
679 end = input_line_pointer;
680
681 while (*end && *end != '\n')
682 end++;
683
684 while (*s && *s != '\n')
685 {
686 if (*s == ',')
687 ops++;
688 s++;
689 }
2469cfa2 690
b18c562e
NC
691 left = 3 - ops;
692
693 if (ops < 1)
694 {
695 as_bad (_(".profiler pseudo requires at least two operands."));
696 input_line_pointer = end;
697 return;
698 }
699
700 input_line_pointer = extract_operand (input_line_pointer, flags, 32);
701
702 while (*flags)
703 {
704 switch (*flags)
705 {
706 case '"':
707 break;
708 case 'a':
709 p_flags |= MSP430_PROFILER_FLAG_FRAGMENT;
710 break;
711 case 'j':
712 p_flags |= MSP430_PROFILER_FLAG_JUMP;
713 break;
714 case 'P':
715 p_flags |= MSP430_PROFILER_FLAG_PROLSTART;
716 break;
717 case 'p':
718 p_flags |= MSP430_PROFILER_FLAG_PROLEND;
719 break;
720 case 'E':
721 p_flags |= MSP430_PROFILER_FLAG_EPISTART;
722 break;
723 case 'e':
724 p_flags |= MSP430_PROFILER_FLAG_EPIEND;
725 break;
726 case 's':
727 p_flags |= MSP430_PROFILER_FLAG_ENTRY;
728 break;
729 case 'x':
730 p_flags |= MSP430_PROFILER_FLAG_EXIT;
731 break;
732 case 'i':
733 p_flags |= MSP430_PROFILER_FLAG_INITSECT;
734 break;
735 case 'f':
736 p_flags |= MSP430_PROFILER_FLAG_FINISECT;
737 break;
738 case 'l':
739 p_flags |= MSP430_PROFILER_FLAG_LIBCALL;
740 break;
741 case 'c':
742 p_flags |= MSP430_PROFILER_FLAG_STDCALL;
743 break;
744 case 'd':
745 p_flags |= MSP430_PROFILER_FLAG_STACKDMD;
746 break;
747 case 'I':
748 p_flags |= MSP430_PROFILER_FLAG_ISR;
749 break;
750 case 't':
751 p_flags |= MSP430_PROFILER_FLAG_EXTRA;
752 break;
753 default:
754 as_warn (_("unknown profiling flag - ignored."));
755 break;
756 }
757 flags++;
758 }
759
760 if (p_flags
761 && ( ! pow2value (p_flags & ( MSP430_PROFILER_FLAG_ENTRY
762 | MSP430_PROFILER_FLAG_EXIT))
763 || ! pow2value (p_flags & ( MSP430_PROFILER_FLAG_PROLSTART
764 | MSP430_PROFILER_FLAG_PROLEND
765 | MSP430_PROFILER_FLAG_EPISTART
766 | MSP430_PROFILER_FLAG_EPIEND))
767 || ! pow2value (p_flags & ( MSP430_PROFILER_FLAG_INITSECT
768 | MSP430_PROFILER_FLAG_FINISECT))))
769 {
79cf5950 770 as_bad (_("ambiguous flags combination - '.profiler' directive ignored."));
b18c562e
NC
771 input_line_pointer = end;
772 return;
773 }
774
775 /* Generate temp symbol which denotes current location. */
79cf5950 776 if (now_seg == absolute_section) /* Paranoia ? */
b18c562e
NC
777 {
778 exp1.X_op = O_constant;
779 exp1.X_add_number = abs_section_offset;
79cf5950 780 as_warn (_("profiling in absolute section?"));
b18c562e
NC
781 }
782 else
783 {
784 exp1.X_op = O_symbol;
785 exp1.X_add_symbol = symbol_temp_new_now ();
786 exp1.X_add_number = 0;
787 }
788
789 /* Generate a symbol which holds flags value. */
790 exp.X_op = O_constant;
791 exp.X_add_number = p_flags;
792
793 /* Save current section. */
794 seg = now_seg;
795 subseg = now_subseg;
796
797 /* Now go to .profiler section. */
798 obj_elf_change_section (".profiler", SHT_PROGBITS, 0, 0, 0, 0, 0);
799
800 /* Save flags. */
801 emit_expr (& exp, 2);
802
803 /* Save label value. */
804 emit_expr (& exp1, 2);
805
806 while (ops--)
807 {
808 /* Now get profiling info. */
809 halt = extract_operand (input_line_pointer, str, 1024);
810 /* Process like ".word xxx" directive. */
811 parse_exp (str, & exp);
812 emit_expr (& exp, 2);
813 input_line_pointer = halt;
814 }
815
816 /* Fill the rest with zeros. */
817 exp.X_op = O_constant;
818 exp.X_add_number = 0;
819 while (left--)
820 emit_expr (& exp, 2);
821
822 /* Return to current section. */
823 subseg_set (seg, subseg);
2469cfa2
NC
824}
825
826static char *
b18c562e 827extract_word (char * from, char * to, int limit)
2469cfa2 828{
2469cfa2
NC
829 char *op_end;
830 int size = 0;
831
832 /* Drop leading whitespace. */
833 from = skip_space (from);
834 *to = 0;
835
836 /* Find the op code end. */
87975d2a 837 for (op_end = from; *op_end != 0 && is_part_of_name (*op_end);)
2469cfa2
NC
838 {
839 to[size++] = *op_end++;
840 if (size + 1 >= limit)
841 break;
842 }
843
844 to[size] = 0;
845 return op_end;
846}
847
b18c562e 848#define OPTION_MMCU 'm'
77592908
DD
849#define OPTION_RELAX 'Q'
850#define OPTION_POLYMORPHS 'P'
13761a11
NC
851#define OPTION_LARGE 'l'
852static bfd_boolean large_model = FALSE;
853#define OPTION_NO_INTR_NOPS 'N'
854static bfd_boolean gen_interrupt_nops = TRUE;
b18c562e 855
2469cfa2 856static void
b18c562e 857msp430_set_arch (int dummy ATTRIBUTE_UNUSED)
2469cfa2
NC
858{
859 char *str = (char *) alloca (32); /* 32 for good measure. */
860
861 input_line_pointer = extract_word (input_line_pointer, str, 32);
862
863 md_parse_option (OPTION_MMCU, str);
864 bfd_set_arch_mach (stdoutput, TARGET_ARCH, msp430_mcu->mach);
865}
866
b18c562e
NC
867static void
868show_mcu_list (FILE * stream)
869{
870 int i;
871
872 fprintf (stream, _("Known MCU names:\n"));
873
874 for (i = 0; mcu_types[i].name; i++)
13761a11
NC
875 {
876 fprintf (stream, "%13.13s", mcu_types[i].name);
877 if ((i % 6) == 5)
878 fprintf (stream, "\n");
879 }
b18c562e
NC
880
881 fprintf (stream, "\n");
882}
883
2469cfa2 884int
b18c562e 885md_parse_option (int c, char * arg)
2469cfa2
NC
886{
887 int i;
888
889 switch (c)
890 {
891 case OPTION_MMCU:
892 for (i = 0; mcu_types[i].name; ++i)
893 if (strcmp (mcu_types[i].name, arg) == 0)
894 break;
895
896 if (!mcu_types[i].name)
897 {
898 show_mcu_list (stderr);
899 as_fatal (_("unknown MCU: %s\n"), arg);
900 }
901
902 if (msp430_mcu == &default_mcu || msp430_mcu->mach == mcu_types[i].mach)
903 msp430_mcu = &mcu_types[i];
13761a11
NC
904 else if (msp430_mcu->mach == bfd_mach_msp430x)
905 /* Allow switching to a lesser architecture. */
906 msp430_mcu = mcu_types + i;
2469cfa2
NC
907 else
908 as_fatal (_("redefinition of mcu type %s' to %s'"),
909 msp430_mcu->name, mcu_types[i].name);
910 return 1;
13761a11 911
77592908 912 case OPTION_RELAX:
13761a11 913 msp430_enable_relax = 1;
77592908 914 return 1;
13761a11 915
77592908
DD
916 case OPTION_POLYMORPHS:
917 msp430_enable_polys = 1;
918 return 1;
13761a11
NC
919
920 case OPTION_LARGE:
921 large_model = TRUE;
922 return 1;
923
924 case OPTION_NO_INTR_NOPS:
925 gen_interrupt_nops = FALSE;
926 return 1;
2469cfa2
NC
927 }
928
929 return 0;
930}
931
2469cfa2 932
b18c562e 933const pseudo_typeS md_pseudo_table[] =
2469cfa2 934{
b18c562e
NC
935 {"arch", msp430_set_arch, 0},
936 {"profiler", msp430_profiler, 0},
937 {NULL, NULL, 0}
938};
2469cfa2 939
b18c562e 940const char *md_shortopts = "m:";
2469cfa2 941
b18c562e 942struct option md_longopts[] =
2469cfa2 943{
b18c562e 944 {"mmcu", required_argument, NULL, OPTION_MMCU},
77592908
DD
945 {"mP", no_argument, NULL, OPTION_POLYMORPHS},
946 {"mQ", no_argument, NULL, OPTION_RELAX},
13761a11
NC
947 {"ml", no_argument, NULL, OPTION_LARGE},
948 {"mN", no_argument, NULL, OPTION_NO_INTR_NOPS},
b18c562e
NC
949 {NULL, no_argument, NULL, 0}
950};
2469cfa2 951
b18c562e 952size_t md_longopts_size = sizeof (md_longopts);
2469cfa2 953
b18c562e
NC
954void
955md_show_usage (FILE * stream)
2469cfa2 956{
b18c562e
NC
957 fprintf (stream,
958 _("MSP430 options:\n"
13761a11 959 " -mmcu=<msp430-name> select microcontroller type\n"));
77592908
DD
960 fprintf (stream,
961 _(" -mQ - enable relaxation at assembly time. DANGEROUS!\n"
962 " -mP - enable polymorph instructions\n"));
13761a11
NC
963 fprintf (stream,
964 _(" -ml - enable large code model\n"));
965 fprintf (stream,
966 _(" -mN - disable generation of NOP after changing interrupts\n"));
2469cfa2 967
b18c562e
NC
968 show_mcu_list (stream);
969}
2469cfa2 970
b18c562e
NC
971symbolS *
972md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
973{
13761a11 974 return NULL;
2469cfa2
NC
975}
976
977static char *
b18c562e 978extract_cmd (char * from, char * to, int limit)
2469cfa2
NC
979{
980 int size = 0;
981
982 while (*from && ! ISSPACE (*from) && *from != '.' && limit > size)
983 {
984 *(to + size) = *from;
985 from++;
986 size++;
987 }
988
989 *(to + size) = 0;
990
991 return from;
992}
993
2469cfa2 994char *
b18c562e 995md_atof (int type, char * litP, int * sizeP)
2469cfa2 996{
499ac353 997 return ieee_md_atof (type, litP, sizeP, FALSE);
2469cfa2
NC
998}
999
1000void
b18c562e 1001md_begin (void)
2469cfa2 1002{
b18c562e 1003 struct msp430_opcode_s * opcode;
2469cfa2
NC
1004 msp430_hash = hash_new ();
1005
1006 for (opcode = msp430_opcodes; opcode->name; opcode++)
1007 hash_insert (msp430_hash, opcode->name, (char *) opcode);
1008
1009 bfd_set_arch_mach (stdoutput, TARGET_ARCH, msp430_mcu->mach);
1010}
1011
13761a11
NC
1012/* Returns the register number equivalent to the string T.
1013 Returns -1 if there is no such register.
1014 Skips a leading 'r' or 'R' character if there is one.
1015 Handles the register aliases PC and SP. */
1016
1017static signed int
b18c562e 1018check_reg (char * t)
2469cfa2 1019{
13761a11 1020 signed int val;
2469cfa2 1021
13761a11
NC
1022 if (t == NULL)
1023 return -1;
2469cfa2 1024
13761a11
NC
1025 if (*t == 'r' || *t == 'R')
1026 ++t;
1027
1028 if (strncasecmp (t, "pc", 2) == 0)
1029 return 0;
2469cfa2 1030
13761a11 1031 if (strncasecmp (t, "sp", 2) == 0)
b18c562e 1032 return 1;
2469cfa2 1033
13761a11
NC
1034 if (strncasecmp (t, "sr", 2) == 0)
1035 return 2;
1036
1037 if (*t == '0')
1038 return 0;
2469cfa2 1039
13761a11
NC
1040 val = atoi (t);
1041
1042 if (val < 1 || val > 15)
1043 return -1;
1044
1045 return val;
1046}
2469cfa2 1047
b18c562e
NC
1048static int
1049msp430_srcoperand (struct msp430_operand_s * op,
13761a11
NC
1050 char * l,
1051 int bin,
1052 int * imm_op,
1053 bfd_boolean allow_20bit_values,
1054 bfd_boolean constants_allowed)
2469cfa2 1055{
b18c562e 1056 char *__tl = l;
2469cfa2 1057
b18c562e
NC
1058 /* Check if an immediate #VALUE. The hash sign should be only at the beginning! */
1059 if (*l == '#')
2469cfa2 1060 {
b18c562e
NC
1061 char *h = l;
1062 int vshift = -1;
1063 int rval = 0;
2469cfa2 1064
b18c562e
NC
1065 /* Check if there is:
1066 llo(x) - least significant 16 bits, x &= 0xffff
1067 lhi(x) - x = (x >> 16) & 0xffff,
1068 hlo(x) - x = (x >> 32) & 0xffff,
1069 hhi(x) - x = (x >> 48) & 0xffff
1070 The value _MUST_ be constant expression: #hlo(1231231231). */
2469cfa2 1071
b18c562e 1072 *imm_op = 1;
2469cfa2 1073
b18c562e
NC
1074 if (strncasecmp (h, "#llo(", 5) == 0)
1075 {
1076 vshift = 0;
1077 rval = 3;
1078 }
1079 else if (strncasecmp (h, "#lhi(", 5) == 0)
1080 {
1081 vshift = 1;
1082 rval = 3;
1083 }
1084 else if (strncasecmp (h, "#hlo(", 5) == 0)
1085 {
1086 vshift = 2;
1087 rval = 3;
1088 }
1089 else if (strncasecmp (h, "#hhi(", 5) == 0)
1090 {
1091 vshift = 3;
1092 rval = 3;
1093 }
1094 else if (strncasecmp (h, "#lo(", 4) == 0)
1095 {
1096 vshift = 0;
1097 rval = 2;
1098 }
1099 else if (strncasecmp (h, "#hi(", 4) == 0)
1100 {
1101 vshift = 1;
1102 rval = 2;
1103 }
2469cfa2 1104
b18c562e
NC
1105 op->reg = 0; /* Reg PC. */
1106 op->am = 3;
1107 op->ol = 1; /* Immediate will follow an instruction. */
1108 __tl = h + 1 + rval;
1109 op->mode = OP_EXP;
2469cfa2 1110
b18c562e
NC
1111 parse_exp (__tl, &(op->exp));
1112 if (op->exp.X_op == O_constant)
2469cfa2 1113 {
b18c562e 1114 int x = op->exp.X_add_number;
2469cfa2 1115
b18c562e 1116 if (vshift == 0)
2469cfa2 1117 {
b18c562e
NC
1118 x = x & 0xffff;
1119 op->exp.X_add_number = x;
1120 }
1121 else if (vshift == 1)
1122 {
1123 x = (x >> 16) & 0xffff;
1124 op->exp.X_add_number = x;
1125 }
1126 else if (vshift > 1)
1127 {
1128 if (x < 0)
1129 op->exp.X_add_number = -1;
2469cfa2 1130 else
b18c562e
NC
1131 op->exp.X_add_number = 0; /* Nothing left. */
1132 x = op->exp.X_add_number;
2469cfa2 1133 }
2469cfa2 1134
13761a11
NC
1135 if (allow_20bit_values)
1136 {
1137 if (op->exp.X_add_number > 0xfffff || op->exp.X_add_number < - (0x7ffff))
1138 {
1139 as_bad (_("value 0x%x out of extended range."), x);
1140 return 1;
1141 }
1142 }
1143 else if (op->exp.X_add_number > 65535 || op->exp.X_add_number < -32768)
b18c562e
NC
1144 {
1145 as_bad (_("value %d out of range. Use #lo() or #hi()"), x);
1146 return 1;
1147 }
2469cfa2 1148
b18c562e
NC
1149 /* Now check constants. */
1150 /* Substitute register mode with a constant generator if applicable. */
2469cfa2 1151
13761a11
NC
1152 if (!allow_20bit_values)
1153 x = (short) x; /* Extend sign. */
2469cfa2 1154
13761a11
NC
1155 if (! constants_allowed)
1156 ;
1157 else if (x == 0)
2469cfa2 1158 {
b18c562e
NC
1159 op->reg = 3;
1160 op->am = 0;
1161 op->ol = 0;
1162 op->mode = OP_REG;
1163 }
1164 else if (x == 1)
1165 {
1166 op->reg = 3;
1167 op->am = 1;
1168 op->ol = 0;
1169 op->mode = OP_REG;
1170 }
1171 else if (x == 2)
1172 {
1173 op->reg = 3;
1174 op->am = 2;
1175 op->ol = 0;
1176 op->mode = OP_REG;
1177 }
1178 else if (x == -1)
1179 {
1180 op->reg = 3;
1181 op->am = 3;
1182 op->ol = 0;
1183 op->mode = OP_REG;
1184 }
1185 else if (x == 4)
1186 {
1187#ifdef PUSH_1X_WORKAROUND
1188 if (bin == 0x1200)
1189 {
1190 /* Remove warning as confusing.
20203fb9 1191 as_warn (_("Hardware push bug workaround")); */
b18c562e
NC
1192 }
1193 else
1194#endif
1195 {
1196 op->reg = 2;
1197 op->am = 2;
1198 op->ol = 0;
1199 op->mode = OP_REG;
1200 }
1201 }
1202 else if (x == 8)
1203 {
1204#ifdef PUSH_1X_WORKAROUND
1205 if (bin == 0x1200)
1206 {
1207 /* Remove warning as confusing.
20203fb9 1208 as_warn (_("Hardware push bug workaround")); */
b18c562e
NC
1209 }
1210 else
1211#endif
1212 {
1213 op->reg = 2;
1214 op->am = 3;
1215 op->ol = 0;
1216 op->mode = OP_REG;
1217 }
2469cfa2 1218 }
2469cfa2 1219 }
b18c562e
NC
1220 else if (op->exp.X_op == O_symbol)
1221 {
1222 op->mode = OP_EXP;
1223 }
1224 else if (op->exp.X_op == O_big)
1225 {
1226 short x;
1227 if (vshift != -1)
1228 {
1229 op->exp.X_op = O_constant;
1230 op->exp.X_add_number = 0xffff & generic_bignum[vshift];
1231 x = op->exp.X_add_number;
1232 }
1233 else
1234 {
1235 as_bad (_
1236 ("unknown expression in operand %s. use #llo() #lhi() #hlo() #hhi() "),
1237 l);
1238 return 1;
1239 }
2469cfa2 1240
b18c562e
NC
1241 if (x == 0)
1242 {
1243 op->reg = 3;
1244 op->am = 0;
1245 op->ol = 0;
1246 op->mode = OP_REG;
1247 }
1248 else if (x == 1)
1249 {
1250 op->reg = 3;
1251 op->am = 1;
1252 op->ol = 0;
1253 op->mode = OP_REG;
1254 }
1255 else if (x == 2)
1256 {
1257 op->reg = 3;
1258 op->am = 2;
1259 op->ol = 0;
1260 op->mode = OP_REG;
1261 }
1262 else if (x == -1)
1263 {
1264 op->reg = 3;
1265 op->am = 3;
1266 op->ol = 0;
1267 op->mode = OP_REG;
1268 }
1269 else if (x == 4)
1270 {
1271 op->reg = 2;
1272 op->am = 2;
1273 op->ol = 0;
1274 op->mode = OP_REG;
1275 }
1276 else if (x == 8)
1277 {
1278 op->reg = 2;
1279 op->am = 3;
1280 op->ol = 0;
1281 op->mode = OP_REG;
1282 }
1283 }
79cf5950 1284 /* Redundant (yet) check. */
b18c562e
NC
1285 else if (op->exp.X_op == O_register)
1286 as_bad
1287 (_("Registers cannot be used within immediate expression [%s]"), l);
1288 else
1289 as_bad (_("unknown operand %s"), l);
2469cfa2 1290
b18c562e
NC
1291 return 0;
1292 }
2469cfa2 1293
b18c562e
NC
1294 /* Check if absolute &VALUE (assume that we can construct something like ((a&b)<<7 + 25). */
1295 if (*l == '&')
1296 {
1297 char *h = l;
2469cfa2 1298
b18c562e
NC
1299 op->reg = 2; /* reg 2 in absolute addr mode. */
1300 op->am = 1; /* mode As == 01 bin. */
1301 op->ol = 1; /* Immediate value followed by instruction. */
1302 __tl = h + 1;
1303 parse_exp (__tl, &(op->exp));
1304 op->mode = OP_EXP;
1305 if (op->exp.X_op == O_constant)
2469cfa2 1306 {
b18c562e 1307 int x = op->exp.X_add_number;
2469cfa2 1308
13761a11
NC
1309 if (allow_20bit_values)
1310 {
1311 if (x > 0xfffff || x < -(0x7ffff))
1312 {
1313 as_bad (_("value 0x%x out of extended range."), x);
1314 return 1;
1315 }
1316 }
1317 else if (x > 65535 || x < -32768)
b18c562e 1318 {
13761a11 1319 as_bad (_("value out of range: 0x%x"), x);
b18c562e
NC
1320 return 1;
1321 }
2469cfa2 1322 }
b18c562e
NC
1323 else if (op->exp.X_op == O_symbol)
1324 ;
1325 else
2469cfa2 1326 {
79cf5950 1327 /* Redundant (yet) check. */
b18c562e
NC
1328 if (op->exp.X_op == O_register)
1329 as_bad
1330 (_("Registers cannot be used within absolute expression [%s]"), l);
2469cfa2 1331 else
b18c562e
NC
1332 as_bad (_("unknown expression in operand %s"), l);
1333 return 1;
2469cfa2 1334 }
b18c562e
NC
1335 return 0;
1336 }
2469cfa2 1337
b18c562e
NC
1338 /* Check if indirect register mode @Rn / postincrement @Rn+. */
1339 if (*l == '@')
1340 {
1341 char *t = l;
1342 char *m = strchr (l, '+');
1343
1344 if (t != l)
2469cfa2 1345 {
b18c562e
NC
1346 as_bad (_("unknown addressing mode %s"), l);
1347 return 1;
2469cfa2
NC
1348 }
1349
b18c562e 1350 t++;
2469cfa2 1351
13761a11 1352 if ((op->reg = check_reg (t)) == -1)
2469cfa2 1353 {
13761a11 1354 as_bad (_("Bad register name %s"), t);
b18c562e 1355 return 1;
2469cfa2 1356 }
2469cfa2 1357
b18c562e
NC
1358 op->mode = OP_REG;
1359 op->am = m ? 3 : 2;
1360 op->ol = 0;
2469cfa2 1361
b18c562e
NC
1362 return 0;
1363 }
2469cfa2 1364
b18c562e
NC
1365 /* Check if register indexed X(Rn). */
1366 do
1367 {
1368 char *h = strrchr (l, '(');
1369 char *m = strrchr (l, ')');
1370 char *t;
2469cfa2 1371
b18c562e 1372 *imm_op = 1;
2469cfa2 1373
b18c562e
NC
1374 if (!h)
1375 break;
1376 if (!m)
1377 {
1378 as_bad (_("')' required"));
1379 return 1;
1380 }
2469cfa2 1381
b18c562e
NC
1382 t = h;
1383 op->am = 1;
1384 op->ol = 1;
2469cfa2 1385
13761a11
NC
1386 /* Extract a register. */
1387 if ((op->reg = check_reg (t + 1)) == -1)
b18c562e
NC
1388 {
1389 as_bad (_
1390 ("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"),
1391 l);
1392 return 1;
1393 }
2469cfa2 1394
13761a11 1395 if (op->reg == 2)
b18c562e 1396 {
13761a11 1397 as_bad (_("r2 should not be used in indexed addressing mode"));
b18c562e
NC
1398 return 1;
1399 }
b18c562e
NC
1400
1401 /* Extract constant. */
1402 __tl = l;
1403 *h = 0;
1404 op->mode = OP_EXP;
1405 parse_exp (__tl, &(op->exp));
1406 if (op->exp.X_op == O_constant)
1407 {
1408 int x = op->exp.X_add_number;
1409
13761a11
NC
1410 if (allow_20bit_values)
1411 {
1412 if (x > 0xfffff || x < - (0x7ffff))
1413 {
1414 as_bad (_("value 0x%x out of extended range."), x);
1415 return 1;
1416 }
1417 }
1418 else if (x > 65535 || x < -32768)
2469cfa2 1419 {
13761a11 1420 as_bad (_("value out of range: 0x%x"), x);
b18c562e 1421 return 1;
2469cfa2 1422 }
b18c562e
NC
1423
1424 if (x == 0)
2469cfa2 1425 {
b18c562e
NC
1426 op->mode = OP_REG;
1427 op->am = 2;
1428 op->ol = 0;
1429 return 0;
2469cfa2
NC
1430 }
1431 }
b18c562e
NC
1432 else if (op->exp.X_op == O_symbol)
1433 ;
2469cfa2
NC
1434 else
1435 {
79cf5950 1436 /* Redundant (yet) check. */
b18c562e
NC
1437 if (op->exp.X_op == O_register)
1438 as_bad
1439 (_("Registers cannot be used as a prefix of indexed expression [%s]"), l);
1440 else
1441 as_bad (_("unknown expression in operand %s"), l);
1442 return 1;
2469cfa2 1443 }
2469cfa2 1444
b18c562e 1445 return 0;
2469cfa2 1446 }
b18c562e 1447 while (0);
2469cfa2 1448
13761a11
NC
1449 /* Possibly register mode 'mov r1,r2'. */
1450 if ((op->reg = check_reg (l)) != -1)
b18c562e 1451 {
13761a11
NC
1452 op->mode = OP_REG;
1453 op->am = 0;
1454 op->ol = 0;
1455 return 0;
b18c562e 1456 }
b18c562e
NC
1457
1458 /* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'. */
1459 do
1460 {
b18c562e
NC
1461 op->mode = OP_EXP;
1462 op->reg = 0; /* PC relative... be careful. */
13761a11
NC
1463 /* An expression starting with a minus sign is a constant, not an address. */
1464 op->am = (*l == '-' ? 3 : 1);
b18c562e
NC
1465 op->ol = 1;
1466 __tl = l;
1467 parse_exp (__tl, &(op->exp));
1468 return 0;
1469 }
1470 while (0);
1471
1472 /* Unreachable. */
1473 as_bad (_("unknown addressing mode for operand %s"), l);
1474 return 1;
2469cfa2
NC
1475}
1476
b18c562e 1477
2469cfa2 1478static int
13761a11
NC
1479msp430_dstoperand (struct msp430_operand_s * op,
1480 char * l,
1481 int bin,
1482 bfd_boolean allow_20bit_values,
1483 bfd_boolean constants_allowed)
2469cfa2
NC
1484{
1485 int dummy;
13761a11
NC
1486 int ret = msp430_srcoperand (op, l, bin, & dummy,
1487 allow_20bit_values,
1488 constants_allowed);
b18c562e 1489
2469cfa2
NC
1490 if (ret)
1491 return ret;
1492
1493 if (op->am == 2)
1494 {
1495 char *__tl = "0";
1496
1497 op->mode = OP_EXP;
1498 op->am = 1;
1499 op->ol = 1;
1500 parse_exp (__tl, &(op->exp));
b18c562e 1501
2469cfa2
NC
1502 if (op->exp.X_op != O_constant || op->exp.X_add_number != 0)
1503 {
1504 as_bad (_("Internal bug. Try to use 0(r%d) instead of @r%d"),
1505 op->reg, op->reg);
1506 return 1;
1507 }
1508 return 0;
1509 }
1510
1511 if (op->am > 1)
1512 {
1513 as_bad (_
1514 ("this addressing mode is not applicable for destination operand"));
1515 return 1;
1516 }
1517 return 0;
1518}
1519
1520
13761a11
NC
1521/* Attempt to encode a MOVA instruction with the given operands.
1522 Returns the length of the encoded instruction if successful
1523 or 0 upon failure. If the encoding fails, an error message
1524 will be returned if a pointer is provided. */
1525
1526static int
1527try_encode_mova (bfd_boolean imm_op,
1528 int bin,
1529 struct msp430_operand_s * op1,
1530 struct msp430_operand_s * op2,
1531 const char ** error_message_return)
1532{
1533 short ZEROS = 0;
1534 char *frag;
1535 int where;
1536
1537 /* Only a restricted subset of the normal MSP430 addressing modes
1538 are supported here, so check for the ones that are allowed. */
1539 if (imm_op)
1540 {
1541 if (op1->mode == OP_EXP)
1542 {
1543 if (op2->mode != OP_REG)
1544 {
1545 if (error_message_return != NULL)
1546 * error_message_return = _("expected register as second argument of %s");
1547 return 0;
1548 }
1549
1550 if (op1->am == 3)
1551 {
1552 /* MOVA #imm20, Rdst. */
1553 bin |= 0x80 | op2->reg;
1554 frag = frag_more (4);
1555 where = frag - frag_now->fr_literal;
1556 if (op1->exp.X_op == O_constant)
1557 {
1558 bin |= ((op1->exp.X_add_number >> 16) & 0xf) << 8;
1559 bfd_putl16 ((bfd_vma) bin, frag);
1560 bfd_putl16 (op1->exp.X_add_number & 0xffff, frag + 2);
1561 }
1562 else
1563 {
1564 bfd_putl16 ((bfd_vma) bin, frag);
1565 fix_new_exp (frag_now, where, 4, &(op1->exp), FALSE,
1566 BFD_RELOC_MSP430X_ABS20_ADR_SRC);
1567 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1568 }
1569
1570 return 4;
1571 }
1572 else if (op1->am == 1)
1573 {
1574 /* MOVA z16(Rsrc), Rdst. */
1575 bin |= 0x30 | (op1->reg << 8) | op2->reg;
1576 frag = frag_more (4);
1577 where = frag - frag_now->fr_literal;
1578 bfd_putl16 ((bfd_vma) bin, frag);
1579 if (op1->exp.X_op == O_constant)
1580 {
1581 if (op1->exp.X_add_number > 0xffff
1582 || op1->exp.X_add_number < -(0x7fff))
1583 {
1584 if (error_message_return != NULL)
1585 * error_message_return = _("index value too big for %s");
1586 return 0;
1587 }
1588 bfd_putl16 (op1->exp.X_add_number & 0xffff, frag + 2);
1589 }
1590 else
1591 {
1592 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1593 fix_new_exp (frag_now, where + 2, 2, &(op1->exp), FALSE,
1594 op1->reg == 0 ?
1595 BFD_RELOC_MSP430X_PCR16 :
1596 BFD_RELOC_MSP430X_ABS16);
1597 }
1598 return 4;
1599 }
1600
1601 if (error_message_return != NULL)
1602 * error_message_return = _("unexpected addressing mode for %s");
1603 return 0;
1604 }
1605 else if (op1->am == 0)
1606 {
1607 /* MOVA Rsrc, ... */
1608 if (op2->mode == OP_REG)
1609 {
1610 bin |= 0xc0 | (op1->reg << 8) | op2->reg;
1611 frag = frag_more (2);
1612 where = frag - frag_now->fr_literal;
1613 bfd_putl16 ((bfd_vma) bin, frag);
1614 return 2;
1615 }
1616 else if (op2->am == 1)
1617 {
1618 if (op2->reg == 2)
1619 {
1620 /* MOVA Rsrc, &abs20. */
1621 bin |= 0x60 | (op1->reg << 8);
1622 frag = frag_more (4);
1623 where = frag - frag_now->fr_literal;
1624 if (op2->exp.X_op == O_constant)
1625 {
1626 bin |= (op2->exp.X_add_number >> 16) & 0xf;
1627 bfd_putl16 ((bfd_vma) bin, frag);
1628 bfd_putl16 (op2->exp.X_add_number & 0xffff, frag + 2);
1629 }
1630 else
1631 {
1632 bfd_putl16 ((bfd_vma) bin, frag);
1633 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1634 fix_new_exp (frag_now, where, 4, &(op2->exp), FALSE,
1635 BFD_RELOC_MSP430X_ABS20_ADR_DST);
1636 }
1637 return 4;
1638 }
1639
1640 /* MOVA Rsrc, z16(Rdst). */
1641 bin |= 0x70 | (op1->reg << 8) | op2->reg;
1642 frag = frag_more (4);
1643 where = frag - frag_now->fr_literal;
1644 bfd_putl16 ((bfd_vma) bin, frag);
1645 if (op2->exp.X_op == O_constant)
1646 {
1647 if (op2->exp.X_add_number > 0xffff
1648 || op2->exp.X_add_number < -(0x7fff))
1649 {
1650 if (error_message_return != NULL)
1651 * error_message_return = _("index value too big for %s");
1652 return 0;
1653 }
1654 bfd_putl16 (op2->exp.X_add_number & 0xffff, frag + 2);
1655 }
1656 else
1657 {
1658 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1659 fix_new_exp (frag_now, where + 2, 2, &(op2->exp), FALSE,
1660 op2->reg == 0 ?
1661 BFD_RELOC_MSP430X_PCR16 :
1662 BFD_RELOC_MSP430X_ABS16);
1663 }
1664 return 4;
1665 }
1666
1667 if (error_message_return != NULL)
1668 * error_message_return = _("unexpected addressing mode for %s");
1669 return 0;
1670 }
1671 }
1672
1673 /* imm_op == FALSE. */
1674
1675 if (op1->reg == 2 && op1->am == 1 && op1->mode == OP_EXP)
1676 {
1677 /* MOVA &abs20, Rdst. */
1678 if (op2->mode != OP_REG)
1679 {
1680 if (error_message_return != NULL)
1681 * error_message_return = _("expected register as second argument of %s");
1682 return 0;
1683 }
1684
1685 if (op2->reg == 2 || op2->reg == 3)
1686 {
1687 if (error_message_return != NULL)
1688 * error_message_return = _("constant generator destination register found in %s");
1689 return 0;
1690 }
1691
1692 bin |= 0x20 | op2->reg;
1693 frag = frag_more (4);
1694 where = frag - frag_now->fr_literal;
1695 if (op1->exp.X_op == O_constant)
1696 {
1697 bin |= ((op1->exp.X_add_number >> 16) & 0xf) << 8;
1698 bfd_putl16 ((bfd_vma) bin, frag);
1699 bfd_putl16 (op1->exp.X_add_number & 0xffff, frag + 2);
1700 }
1701 else
1702 {
1703 bfd_putl16 ((bfd_vma) bin, frag);
1704 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1705 fix_new_exp (frag_now, where, 4, &(op1->exp), FALSE,
1706 BFD_RELOC_MSP430X_ABS20_ADR_SRC);
1707 }
1708 return 4;
1709 }
1710 else if (op1->mode == OP_REG)
1711 {
1712 if (op1->am == 3)
1713 {
1714 /* MOVA @Rsrc+, Rdst. */
1715 if (op2->mode != OP_REG)
1716 {
1717 if (error_message_return != NULL)
1718 * error_message_return = _("expected register as second argument of %s");
1719 return 0;
1720 }
1721
1722 if (op2->reg == 2 || op2->reg == 3)
1723 {
1724 if (error_message_return != NULL)
1725 * error_message_return = _("constant generator destination register found in %s");
1726 return 0;
1727 }
1728
1729 if (op1->reg == 2 || op1->reg == 3)
1730 {
1731 if (error_message_return != NULL)
1732 * error_message_return = _("constant generator source register found in %s");
1733 return 0;
1734 }
1735
1736 bin |= 0x10 | (op1->reg << 8) | op2->reg;
1737 frag = frag_more (2);
1738 where = frag - frag_now->fr_literal;
1739 bfd_putl16 ((bfd_vma) bin, frag);
1740 return 2;
1741 }
1742 else if (op1->am == 2)
1743 {
1744 /* MOVA @Rsrc,Rdst */
1745 if (op2->mode != OP_REG)
1746 {
1747 if (error_message_return != NULL)
1748 * error_message_return = _("expected register as second argument of %s");
1749 return 0;
1750 }
1751
1752 if (op2->reg == 2 || op2->reg == 3)
1753 {
1754 if (error_message_return != NULL)
1755 * error_message_return = _("constant generator destination register found in %s");
1756 return 0;
1757 }
1758
1759 if (op1->reg == 2 || op1->reg == 3)
1760 {
1761 if (error_message_return != NULL)
1762 * error_message_return = _("constant generator source register found in %s");
1763 return 0;
1764 }
1765
1766 bin |= (op1->reg << 8) | op2->reg;
1767 frag = frag_more (2);
1768 where = frag - frag_now->fr_literal;
1769 bfd_putl16 ((bfd_vma) bin, frag);
1770 return 2;
1771 }
1772 }
1773
1774 if (error_message_return != NULL)
1775 * error_message_return = _("unexpected addressing mode for %s");
1776
1777 return 0;
1778}
1779
b18c562e
NC
1780/* Parse instruction operands.
1781 Return binary opcode. */
1782
1783static unsigned int
1784msp430_operands (struct msp430_opcode_s * opcode, char * line)
2469cfa2 1785{
b18c562e 1786 int bin = opcode->bin_opcode; /* Opcode mask. */
13761a11 1787 int insn_length = 0;
b18c562e
NC
1788 char l1[MAX_OP_LEN], l2[MAX_OP_LEN];
1789 char *frag;
1790 int where;
1791 struct msp430_operand_s op1, op2;
1792 int res = 0;
1793 static short ZEROS = 0;
1794 int byte_op, imm_op;
13761a11
NC
1795 int op_length = 0;
1796 int fmt;
1797 int extended = 0x1800;
1798 bfd_boolean extended_op = FALSE;
1799 bfd_boolean addr_op;
1800 const char * error_message;
1801 static signed int repeat_count = 0;
1802 bfd_boolean fix_emitted;
2469cfa2 1803
b18c562e
NC
1804 /* Opcode is the one from opcodes table
1805 line contains something like
1806 [.w] @r2+, 5(R1)
1807 or
1808 .b @r2+, 5(R1). */
2469cfa2 1809
b18c562e
NC
1810 /* Check if byte or word operation. */
1811 if (*line == '.' && TOLOWER (*(line + 1)) == 'b')
2469cfa2 1812 {
b18c562e
NC
1813 bin |= BYTE_OPERATION;
1814 byte_op = 1;
2469cfa2 1815 }
b18c562e
NC
1816 else
1817 byte_op = 0;
2469cfa2 1818
13761a11
NC
1819 /* "Address" ops work on 20-bit values. */
1820 if (*line == '.' && TOLOWER (*(line + 1)) == 'a')
1821 {
1822 addr_op = TRUE;
1823 bin |= BYTE_OPERATION;
1824 }
1825 else
1826 addr_op = FALSE;
1827
1828 /* skip .[aAbwBW]. */
b18c562e
NC
1829 while (! ISSPACE (*line) && *line)
1830 line++;
2469cfa2 1831
13761a11
NC
1832 if (opcode->fmt != -1
1833 && opcode->insn_opnumb
1834 && (!*line || *line == '\n'))
2469cfa2 1835 {
b18c562e
NC
1836 as_bad (_("instruction %s requires %d operand(s)"),
1837 opcode->name, opcode->insn_opnumb);
1838 return 0;
1839 }
2469cfa2 1840
b18c562e
NC
1841 memset (l1, 0, sizeof (l1));
1842 memset (l2, 0, sizeof (l2));
1843 memset (&op1, 0, sizeof (op1));
1844 memset (&op2, 0, sizeof (op2));
2469cfa2 1845
b18c562e 1846 imm_op = 0;
2469cfa2 1847
13761a11
NC
1848 if ((fmt = opcode->fmt) < 0)
1849 {
1850 if (msp430_mcu->isa != MSP430X_ISA)
1851 {
1852 as_bad (_("instruction %s requires MSP430X mcu"),
1853 opcode->name);
1854 return 0;
1855 }
1856
1857 fmt = (-fmt) - 1;
1858 extended_op = TRUE;
1859 }
1860
1861 if (repeat_count)
1862 {
1863 /* If requested set the extended instruction repeat count. */
1864 if (extended_op)
1865 {
1866 if (repeat_count > 0)
1867 extended |= (repeat_count - 1);
1868 else
1869 extended |= (1 << 7) | (- repeat_count);
1870 }
1871 else
1872 as_bad (_("unable to repeat %s insn"), opcode->name);
1873
1874 repeat_count = 0;
1875 }
1876
1877 switch (fmt)
b18c562e
NC
1878 {
1879 case 0: /* Emulated. */
1880 switch (opcode->insn_opnumb)
2469cfa2 1881 {
b18c562e
NC
1882 case 0:
1883 /* Set/clear bits instructions. */
13761a11
NC
1884 if (extended_op)
1885 {
1886 if (!addr_op)
1887 extended |= BYTE_OPERATION;
1888
1889 /* Emit the extension word. */
1890 insn_length += 2;
1891 frag = frag_more (insn_length);
1892 bfd_putl16 (extended, frag);
1893 }
1894 insn_length += 2;
1895 frag = frag_more (insn_length);
b18c562e 1896 bfd_putl16 ((bfd_vma) bin, frag);
13761a11
NC
1897
1898 if (gen_interrupt_nops
1899 && msp430_mcu->isa == MSP430_ISA_54
1900 && (strcmp (opcode->name, "eint") == 0
1901 || strcmp (opcode->name, "dint") == 0))
1902 {
1903 /* Emit a NOP following interrupt enable/disable.
1904 See 1.3.4.1 of the MSP430x5xx User Guide. */
1905 insn_length += 2;
1906 frag = frag_more (2);
1907 bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
1908 }
1909
1910 dwarf2_emit_insn (insn_length);
b18c562e 1911 break;
13761a11 1912
b18c562e
NC
1913 case 1:
1914 /* Something which works with destination operand. */
1915 line = extract_operand (line, l1, sizeof (l1));
13761a11 1916 res = msp430_dstoperand (&op1, l1, opcode->bin_opcode, extended_op, TRUE);
b18c562e
NC
1917 if (res)
1918 break;
2469cfa2 1919
13761a11
NC
1920 /* Compute the entire instruction length, in bytes. */
1921 insn_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2);
1922 frag = frag_more (insn_length);
b18c562e 1923 where = frag - frag_now->fr_literal;
2469cfa2 1924
13761a11 1925 if (extended_op)
2469cfa2 1926 {
13761a11
NC
1927 if (!addr_op)
1928 extended |= BYTE_OPERATION;
1929
1930 if (op1.ol != 0 && ((extended & 0xf) != 0))
1931 {
1932 as_bad (_("repeat instruction used with non-register mode instruction"));
1933 extended &= ~ 0xf;
1934 }
b18c562e 1935
13761a11
NC
1936 if (op1.mode == OP_EXP)
1937 {
1938 if (op1.exp.X_op == O_constant)
1939 extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
1940
1941 else if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
1942 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
1943 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
1944 else
1945 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
1946 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
1947 }
1948
1949 /* Emit the extension word. */
1950 bfd_putl16 (extended, frag);
1951 frag += 2;
1952 where += 2;
1953 }
1954
1955 bin |= (op1.reg | (op1.am << 7));
1956 bfd_putl16 ((bfd_vma) bin, frag);
1957 frag += 2;
1958 where += 2;
1959
1960 if (op1.mode == OP_EXP)
1961 {
1962 if (op1.exp.X_op == O_constant)
1963 {
1964 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
1965 }
2469cfa2 1966 else
13761a11
NC
1967 {
1968 bfd_putl16 ((bfd_vma) ZEROS, frag);
1969
1970 if (!extended_op)
1971 {
1972 if (op1.reg)
1973 fix_new_exp (frag_now, where, 2,
1974 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
1975 else
1976 fix_new_exp (frag_now, where, 2,
1977 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
1978 }
1979 }
1980 }
1981
1982 if (gen_interrupt_nops
1983 && msp430_mcu->isa == MSP430_ISA_54
1984 && strcmp (opcode->name, "clr") == 0
1985 && bin == 0x4302 /* CLR R2*/)
1986 {
1987 /* Emit a NOP following interrupt enable/disable.
1988 See 1.3.4.1 of the MSP430x5xx User Guide. */
1989 insn_length += 2;
1990 frag = frag_more (2);
1991 bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
2469cfa2 1992 }
13761a11
NC
1993
1994 dwarf2_emit_insn (insn_length);
b18c562e 1995 break;
2469cfa2 1996
b18c562e 1997 case 2:
13761a11
NC
1998 /* Shift instruction. */
1999 line = extract_operand (line, l1, sizeof (l1));
2000 strncpy (l2, l1, sizeof (l2));
2001 l2[sizeof (l2) - 1] = '\0';
2002 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op, extended_op, TRUE);
2003 res += msp430_dstoperand (&op2, l2, opcode->bin_opcode, extended_op, TRUE);
2004
2005 if (res)
2006 break; /* An error occurred. All warnings were done before. */
2007
2008 insn_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2) + (op2.ol * 2);
2009 frag = frag_more (insn_length);
2010 where = frag - frag_now->fr_literal;
2011
2012 if (extended_op)
2013 {
2014 if (!addr_op)
2015 extended |= BYTE_OPERATION;
2016
2017 if ((op1.ol != 0 || op2.ol != 0) && ((extended & 0xf) != 0))
2018 {
2019 as_bad (_("repeat instruction used with non-register mode instruction"));
2020 extended &= ~ 0xf;
2021 }
2022
2023 if (op1.mode == OP_EXP)
2024 {
2025 if (op1.exp.X_op == O_constant)
2026 extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
2027
2028 else if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
2029 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
2030 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
2031 else
2032 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
2033 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
2034 }
2035
2036 if (op2.mode == OP_EXP)
2037 {
2038 if (op2.exp.X_op == O_constant)
2039 extended |= (op2.exp.X_add_number >> 16) & 0xf;
2040
2041 else if (op1.mode == OP_EXP)
2042 fix_new_exp (frag_now, where, 8, &(op2.exp), FALSE,
2043 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_ODST
2044 : BFD_RELOC_MSP430X_PCR20_EXT_ODST);
2045 else
2046 fix_new_exp (frag_now, where, 6, &(op2.exp), FALSE,
2047 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_DST
2048 : BFD_RELOC_MSP430X_PCR20_EXT_DST);
2049 }
2050
2051 /* Emit the extension word. */
2052 bfd_putl16 (extended, frag);
2053 frag += 2;
2054 where += 2;
2055 }
2056
2057 bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
2058 bfd_putl16 ((bfd_vma) bin, frag);
2059 frag += 2;
2060 where += 2;
2061
2062 if (op1.mode == OP_EXP)
2063 {
2064 if (op1.exp.X_op == O_constant)
2065 {
2066 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
2067 }
2068 else
2069 {
2070 bfd_putl16 ((bfd_vma) ZEROS, frag);
2071
2072 if (!extended_op)
2073 {
2074 if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
2075 fix_new_exp (frag_now, where, 2,
2076 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
2077 else
2078 fix_new_exp (frag_now, where, 2,
2079 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2080 }
2081 }
2082 frag += 2;
2083 where += 2;
2084 }
2085
2086 if (op2.mode == OP_EXP)
2087 {
2088 if (op2.exp.X_op == O_constant)
2089 {
2090 bfd_putl16 (op2.exp.X_add_number & 0xffff, frag);
2091 }
2092 else
2093 {
2094 bfd_putl16 ((bfd_vma) ZEROS, frag);
2095
2096 if (!extended_op)
2097 {
2098 if (op2.reg) /* Not PC relative. */
2099 fix_new_exp (frag_now, where, 2,
2100 &(op2.exp), FALSE, CHECK_RELOC_MSP430);
2101 else
2102 fix_new_exp (frag_now, where, 2,
2103 &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2104 }
2105 }
2106 }
2107
2108 dwarf2_emit_insn (insn_length);
2109 break;
2110
2111 case 3:
2112 /* Branch instruction => mov dst, r0. */
2113 if (extended_op)
2114 {
2115 as_bad ("Internal error: state 0/3 not coded for extended instructions");
2116 return 0;
2117 }
2118
2119 line = extract_operand (line, l1, sizeof (l1));
2120 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op, extended_op, FALSE);
2121 if (res)
2122 break;
2123
2124 byte_op = 0;
2125 imm_op = 0;
2126 bin |= ((op1.reg << 8) | (op1.am << 4));
2127 op_length = 2 + 2 * op1.ol;
2128 frag = frag_more (op_length);
2129 where = frag - frag_now->fr_literal;
2130 bfd_putl16 ((bfd_vma) bin, frag);
2131
2132 if (op1.mode == OP_EXP)
2133 {
2134 if (op1.exp.X_op == O_constant)
2135 {
2136 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag + 2);
2137 }
2138 else
2139 {
2140 where += 2;
2141
2142 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2143
2144 if (op1.reg || (op1.reg == 0 && op1.am == 3))
2145 fix_new_exp (frag_now, where, 2,
2146 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
2147 else
2148 fix_new_exp (frag_now, where, 2,
2149 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2150 }
2151 }
2152
2153 dwarf2_emit_insn (insn_length + op_length);
2154 break;
2155
2156 case 4:
2157 /* CALLA instructions. */
2158 fix_emitted = FALSE;
2159
2160 line = extract_operand (line, l1, sizeof (l1));
2161 imm_op = 0;
2162
2163 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op,
2164 extended_op, FALSE);
2165 if (res)
2166 break;
2167
2168 byte_op = 0;
2169
2170 op_length = 2 + 2 * op1.ol;
2171 frag = frag_more (op_length);
2172 where = frag - frag_now->fr_literal;
2173
2174 if (imm_op)
2175 {
2176 if (op1.am == 3)
2177 {
2178 bin |= 0xb0;
2179
2180 fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
2181 BFD_RELOC_MSP430X_ABS20_ADR_DST);
2182 fix_emitted = TRUE;
2183 }
2184 else if (op1.am == 1)
2185 {
2186 if (op1.reg == 0)
2187 {
2188 bin |= 0x90;
2189
2190 fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
2191 BFD_RELOC_MSP430X_PCR20_CALL);
2192 fix_emitted = TRUE;
2193 }
2194 else
2195 bin |= 0x50 | op1.reg;
2196 }
2197 else if (op1.am == 0)
2198 bin |= 0x40 | op1.reg;
2199 }
2200 else if (op1.am == 1)
2201 {
2202 bin |= 0x80;
2203
2204 fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
2205 BFD_RELOC_MSP430X_ABS20_ADR_DST);
2206 fix_emitted = TRUE;
2207 }
2208 else if (op1.am == 2)
2209 bin |= 0x60 | op1.reg;
2210 else if (op1.am == 3)
2211 bin |= 0x70 | op1.reg;
2212
2213 bfd_putl16 ((bfd_vma) bin, frag);
2214
2215 if (op1.mode == OP_EXP)
2216 {
2217 if (op1.ol != 1)
2218 {
2219 as_bad ("Internal error: unexpected CALLA instruction length: %d\n", op1.ol);
2220 return 0;
2221 }
2222
2223 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2224
2225 if (! fix_emitted)
2226 fix_new_exp (frag_now, where + 2, 2,
2227 &(op1.exp), FALSE, BFD_RELOC_16);
2228 }
2229
2230 dwarf2_emit_insn (insn_length + op_length);
2231 break;
2232
2233 case 5:
b18c562e 2234 {
13761a11
NC
2235 int n;
2236 int reg;
2237
2238 /* [POP|PUSH]M[.A] #N, Rd */
b18c562e 2239 line = extract_operand (line, l1, sizeof (l1));
13761a11 2240 line = extract_operand (line, l2, sizeof (l2));
2469cfa2 2241
13761a11
NC
2242 if (*l1 != '#')
2243 {
2244 as_bad (_("expected #n as first argument of POPM"));
2245 return 0;
2246 }
2247 parse_exp (l1 + 1, &(op1.exp));
2248 if (op1.exp.X_op != O_constant)
2249 {
2250 as_bad (_("expected constant expression for first argument of %s"),
2251 opcode->name);
2252 return 0;
2253 }
2469cfa2 2254
13761a11
NC
2255 if ((reg = check_reg (l2)) == -1)
2256 {
2257 as_bad (_("expected register as second argument of %s"),
2258 opcode->name);
2259 return 0;
2260 }
2469cfa2 2261
13761a11
NC
2262 op_length = 2;
2263 frag = frag_more (op_length);
b18c562e 2264 where = frag - frag_now->fr_literal;
13761a11
NC
2265 bin = opcode->bin_opcode;
2266 if (! addr_op)
2267 bin |= 0x100;
2268 n = op1.exp.X_add_number;
2269 bin |= (n - 1) << 4;
2270 if (strcmp (opcode->name, "pushm") == 0)
2271 bin |= reg;
2272 else
2273 {
2274 if (reg - n + 1 < 0)
2275 {
2276 as_bad (_("Too many registers popped"));
2277 return 0;
2278 }
2279 bin |= (reg - n + 1);
2280 }
2281
b18c562e 2282 bfd_putl16 ((bfd_vma) bin, frag);
13761a11
NC
2283 dwarf2_emit_insn (op_length);
2284 break;
2285 }
2286
2287 case 6:
2288 {
2289 int n;
2290 int reg;
2291
2292 /* Bit rotation instructions. RRCM, RRAM, RRUM, RLAM. */
2293 if (extended & 0xff)
2294 {
2295 as_bad (_("repeat count cannot be used with %s"), opcode->name);
2296 return 0;
2297 }
2298
2299 line = extract_operand (line, l1, sizeof (l1));
2300 line = extract_operand (line, l2, sizeof (l2));
2301
2302 if (*l1 != '#')
2303 {
2304 as_bad (_("expected #n as first argument of %s"), opcode->name);
2305 return 0;
2306 }
2307 parse_exp (l1 + 1, &(op1.exp));
2308 if (op1.exp.X_op != O_constant)
2309 {
2310 as_bad (_("expected constant expression for first argument of %s"),
2311 opcode->name);
2312 return 0;
2313 }
2314 n = op1.exp.X_add_number;
2315 if (n > 4 || n < 1)
b18c562e 2316 {
13761a11
NC
2317 as_bad (_("expected first argument of %s to be in the range 1-4"),
2318 opcode->name);
2319 return 0;
2320 }
b18c562e 2321
13761a11
NC
2322 if ((reg = check_reg (l2)) == -1)
2323 {
2324 as_bad (_("expected register as second argument of %s"),
2325 opcode->name);
2326 return 0;
b18c562e
NC
2327 }
2328
13761a11
NC
2329 op_length = 2;
2330 frag = frag_more (op_length);
2331 where = frag - frag_now->fr_literal;
2332
2333 bin = opcode->bin_opcode;
2334 if (! addr_op)
2335 bin |= 0x10;
2336 bin |= (n - 1) << 10;
2337 bin |= reg;
2338
2339 bfd_putl16 ((bfd_vma) bin, frag);
2340 dwarf2_emit_insn (op_length);
2341 break;
2342 }
2343
2344 case 7:
2345 {
2346 int reg;
2347
2348 /* RRUX: Synthetic unsigned right shift of a register by one bit. */
2349 if (extended & 0xff)
b18c562e 2350 {
13761a11
NC
2351 as_bad (_("repeat count cannot be used with %s"), opcode->name);
2352 return 0;
2353 }
b18c562e 2354
13761a11
NC
2355 line = extract_operand (line, l1, sizeof (l1));
2356 if ((reg = check_reg (l1)) == -1)
2357 {
2358 as_bad (_("expected register as argument of %s"),
2359 opcode->name);
2360 return 0;
2361 }
2362
2363 if (byte_op)
2364 {
2365 /* Tricky - there is no single instruction that will do this.
2366 Encode as: RRA.B rN { BIC.B #0x80, rN */
2367 op_length = 6;
2368 frag = frag_more (op_length);
2369 where = frag - frag_now->fr_literal;
2370 bin = 0x1140 | reg;
2371 bfd_putl16 ((bfd_vma) bin, frag);
2372 dwarf2_emit_insn (2);
2373 bin = 0xc070 | reg;
2374 bfd_putl16 ((bfd_vma) bin, frag + 2);
2375 bin = 0x0080;
2376 bfd_putl16 ((bfd_vma) bin, frag + 4);
2377 dwarf2_emit_insn (4);
2378 }
2379 else
2380 {
2381 /* Encode as RRUM[.A] rN. */
2382 bin = opcode->bin_opcode;
2383 if (! addr_op)
2384 bin |= 0x10;
2385 bin |= reg;
2386 op_length = 2;
2387 frag = frag_more (op_length);
2388 where = frag - frag_now->fr_literal;
2389 bfd_putl16 ((bfd_vma) bin, frag);
2390 dwarf2_emit_insn (op_length);
b18c562e
NC
2391 }
2392 break;
2393 }
b18c562e 2394
13761a11
NC
2395 case 8:
2396 {
2397 bfd_boolean need_reloc = FALSE;
2398 int n;
2399 int reg;
2400
2401 /* ADDA, CMPA and SUBA address instructions. */
2402 if (extended & 0xff)
2403 {
2404 as_bad (_("repeat count cannot be used with %s"), opcode->name);
2405 return 0;
2406 }
2407
2408 line = extract_operand (line, l1, sizeof (l1));
2409 line = extract_operand (line, l2, sizeof (l2));
2410
2411 bin = opcode->bin_opcode;
2412
2413 if (*l1 == '#')
2414 {
2415 parse_exp (l1 + 1, &(op1.exp));
2416
2417 if (op1.exp.X_op == O_constant)
2418 {
2419 n = op1.exp.X_add_number;
2420 if (n > 0xfffff || n < - (0x7ffff))
2421 {
2422 as_bad (_("expected value of first argument of %s to fit into 20-bits"),
2423 opcode->name);
2424 return 0;
2425 }
2426
2427 bin |= ((n >> 16) & 0xf) << 8;
2428 }
2429 else
2430 {
2431 n = 0;
2432 need_reloc = TRUE;
2433 }
2434
2435 op_length = 4;
2436 }
2437 else
2438 {
2439 if ((n = check_reg (l1)) == -1)
2440 {
2441 as_bad (_("expected register name or constant as first argument of %s"),
2442 opcode->name);
2443 return 0;
2444 }
2445
2446 bin |= (n << 8) | (1 << 6);
2447 op_length = 2;
2448 }
2449
2450 if ((reg = check_reg (l2)) == -1)
2451 {
2452 as_bad (_("expected register as second argument of %s"),
2453 opcode->name);
2454 return 0;
2455 }
2456
2457 frag = frag_more (op_length);
2458 where = frag - frag_now->fr_literal;
2459 bin |= reg;
2460 if (need_reloc)
2461 fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
2462 BFD_RELOC_MSP430X_ABS20_ADR_SRC);
2463
2464 bfd_putl16 ((bfd_vma) bin, frag);
2465 if (op_length == 4)
2466 bfd_putl16 ((bfd_vma) (n & 0xffff), frag + 2);
2467 dwarf2_emit_insn (op_length);
b18c562e 2468 break;
13761a11 2469 }
b18c562e 2470
13761a11 2471 case 9: /* MOVA, BRA, RETA. */
b18c562e 2472 imm_op = 0;
13761a11 2473 bin = opcode->bin_opcode;
b18c562e 2474
13761a11
NC
2475 if (strcmp (opcode->name, "reta") == 0)
2476 {
2477 /* The RETA instruction does not take any arguments.
2478 The implicit first argument is @SP+.
2479 The implicit second argument is PC. */
2480 op1.mode = OP_REG;
2481 op1.am = 3;
2482 op1.reg = 1;
2483
2484 op2.mode = OP_REG;
2485 op2.reg = 0;
2486 }
2487 else
2488 {
2489 line = extract_operand (line, l1, sizeof (l1));
2490 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode,
2491 &imm_op, extended_op, FALSE);
b18c562e 2492
13761a11
NC
2493 if (strcmp (opcode->name, "bra") == 0)
2494 {
2495 /* This is the BRA synthetic instruction.
2496 The second argument is always PC. */
2497 op2.mode = OP_REG;
2498 op2.reg = 0;
2499 }
2500 else
2501 {
2502 line = extract_operand (line, l2, sizeof (l2));
2503 res += msp430_dstoperand (&op2, l2, opcode->bin_opcode,
2504 extended_op, TRUE);
2505 }
2506
2507 if (res)
2508 break; /* Error occurred. All warnings were done before. */
2509 }
2510
2511 /* Only a restricted subset of the normal MSP430 addressing modes
2512 are supported here, so check for the ones that are allowed. */
2513 if ((op_length = try_encode_mova (imm_op, bin, & op1, & op2,
2514 & error_message)) == 0)
2469cfa2 2515 {
13761a11
NC
2516 as_bad (error_message, opcode->name);
2517 return 0;
2518 }
2519 dwarf2_emit_insn (op_length);
2520 break;
2521
2522 case 10: /* RPT */
2523 line = extract_operand (line, l1, sizeof l1);
2524 /* The RPT instruction only accepted immediates and registers. */
2525 if (*l1 == '#')
2526 {
2527 parse_exp (l1 + 1, &(op1.exp));
2528 if (op1.exp.X_op != O_constant)
2529 {
2530 as_bad (_("expected constant value as argument to RPT"));
2531 return 0;
2532 }
2533 if (op1.exp.X_add_number < 1
2534 || op1.exp.X_add_number > (1 << 4))
2535 {
2536 as_bad (_("expected constant in the range 2..16"));
2537 return 0;
2538 }
2539
2540 /* We silently accept and ignore a repeat count of 1. */
2541 if (op1.exp.X_add_number > 1)
2542 repeat_count = op1.exp.X_add_number;
2543 }
2544 else
2545 {
2546 int reg;
b18c562e 2547
13761a11
NC
2548 if ((reg = check_reg (l1)) != -1)
2549 {
2550 if (reg == 0)
2551 as_warn (_("PC used as an argument to RPT"));
2552 else
2553 repeat_count = - reg;
2554 }
2469cfa2 2555 else
13761a11
NC
2556 {
2557 as_bad (_("expected constant or register name as argument to RPT insn"));
2558 return 0;
2559 }
2469cfa2 2560 }
b18c562e 2561 break;
13761a11
NC
2562
2563 default:
2564 as_bad (_("Illegal emulated instruction "));
2565 break;
2469cfa2 2566 }
b18c562e 2567 break;
2469cfa2 2568
b18c562e
NC
2569 case 1: /* Format 1, double operand. */
2570 line = extract_operand (line, l1, sizeof (l1));
2571 line = extract_operand (line, l2, sizeof (l2));
13761a11
NC
2572 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op, extended_op, TRUE);
2573 res += msp430_dstoperand (&op2, l2, opcode->bin_opcode, extended_op, TRUE);
2469cfa2 2574
b18c562e
NC
2575 if (res)
2576 break; /* Error occurred. All warnings were done before. */
2469cfa2 2577
13761a11
NC
2578 if (extended_op
2579 && strcmp (opcode->name, "movx") == 0
2580 && addr_op
2581 && msp430_enable_relax)
2582 {
2583 /* This is the MOVX.A instruction. See if we can convert
2584 it into the MOVA instruction instead. This saves 2 bytes. */
2585 if ((op_length = try_encode_mova (imm_op, 0x0000, & op1, & op2,
2586 NULL)) != 0)
2587 {
2588 dwarf2_emit_insn (op_length);
2589 break;
2590 }
2591 }
2592
2593 /* Compute the entire length of the instruction in bytes. */
2594 insn_length =
2595 (extended_op ? 2 : 0) /* The extension word. */
2596 + 2 /* The opcode */
2597 + (2 * op1.ol) /* The first operand. */
2598 + (2 * op2.ol); /* The second operand. */
b18c562e 2599
13761a11 2600 frag = frag_more (insn_length);
b18c562e 2601 where = frag - frag_now->fr_literal;
13761a11
NC
2602
2603 if (extended_op)
2604 {
2605 if (!addr_op)
2606 extended |= BYTE_OPERATION;
2607
2608 if ((op1.ol != 0 || op2.ol != 0) && ((extended & 0xf) != 0))
2609 {
2610 as_bad (_("repeat instruction used with non-register mode instruction"));
2611 extended &= ~ 0xf;
2612 }
2613
2614 /* If necessary, emit a reloc to update the extension word. */
2615 if (op1.mode == OP_EXP)
2616 {
2617 if (op1.exp.X_op == O_constant)
2618 extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
2619
2620 else if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
2621 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
2622 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
2623 else
2624 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
2625 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
2626 }
2627
2628 if (op2.mode == OP_EXP)
2629 {
2630 if (op2.exp.X_op == O_constant)
2631 extended |= (op2.exp.X_add_number >> 16) & 0xf;
2632
2633 else if (op1.mode == OP_EXP)
2634 fix_new_exp (frag_now, where, 8, &(op2.exp), FALSE,
2635 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_ODST
2636 : BFD_RELOC_MSP430X_PCR20_EXT_ODST);
2637
2638 else
2639 fix_new_exp (frag_now, where, 6, &(op2.exp), FALSE,
2640 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_DST
2641 : BFD_RELOC_MSP430X_PCR20_EXT_DST);
2642 }
2643
2644 /* Emit the extension word. */
2645 bfd_putl16 (extended, frag);
2646 where += 2;
2647 frag += 2;
2648 }
2649
2650 bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
b18c562e 2651 bfd_putl16 ((bfd_vma) bin, frag);
13761a11
NC
2652 where += 2;
2653 frag += 2;
b18c562e
NC
2654
2655 if (op1.mode == OP_EXP)
2469cfa2 2656 {
13761a11
NC
2657 if (op1.exp.X_op == O_constant)
2658 {
2659 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
2660 }
b18c562e 2661 else
13761a11
NC
2662 {
2663 bfd_putl16 ((bfd_vma) ZEROS, frag);
2664
2665 if (!extended_op)
2666 {
2667 if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
2668 fix_new_exp (frag_now, where, 2,
2669 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
2670 else
2671 fix_new_exp (frag_now, where, 2,
2672 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2673 }
2674 }
2675
2676 where += 2;
2677 frag += 2;
2469cfa2 2678 }
b18c562e
NC
2679
2680 if (op2.mode == OP_EXP)
2469cfa2 2681 {
13761a11
NC
2682 if (op2.exp.X_op == O_constant)
2683 {
2684 bfd_putl16 (op2.exp.X_add_number & 0xffff, frag);
2685 }
b18c562e 2686 else
13761a11
NC
2687 {
2688 bfd_putl16 ((bfd_vma) ZEROS, frag);
2689
2690 if (!extended_op)
2691 {
2692 if (op2.reg) /* Not PC relative. */
2693 fix_new_exp (frag_now, where, 2,
2694 &(op2.exp), FALSE, CHECK_RELOC_MSP430);
2695 else
2696 fix_new_exp (frag_now, where, 2,
2697 &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2698 }
2699 }
2700 }
2701
2702 if (gen_interrupt_nops
2703 && msp430_mcu->isa == MSP430_ISA_54
2704 && ( (strcmp (opcode->name, "bic") == 0 && bin == 0xc232)
2705 || (strcmp (opcode->name, "bis") == 0 && bin == 0xd232)
2706 || (strcmp (opcode->name, "mov") == 0 && op2.mode == OP_REG && op2.reg == 2)))
2707 {
2708 /* Emit a NOP following interrupt enable/disable.
2709 See 1.3.4.1 of the MSP430x5xx User Guide. */
2710 insn_length += 2;
2711 frag = frag_more (2);
2712 bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
2469cfa2 2713 }
13761a11
NC
2714
2715 dwarf2_emit_insn (insn_length);
b18c562e
NC
2716 break;
2717
2718 case 2: /* Single-operand mostly instr. */
2719 if (opcode->insn_opnumb == 0)
2469cfa2 2720 {
b18c562e 2721 /* reti instruction. */
13761a11 2722 insn_length += 2;
b18c562e
NC
2723 frag = frag_more (2);
2724 bfd_putl16 ((bfd_vma) bin, frag);
13761a11 2725 dwarf2_emit_insn (insn_length);
b18c562e 2726 break;
2469cfa2 2727 }
2469cfa2 2728
b18c562e 2729 line = extract_operand (line, l1, sizeof (l1));
13761a11
NC
2730 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode,
2731 &imm_op, extended_op, TRUE);
b18c562e
NC
2732 if (res)
2733 break; /* Error in operand. */
2469cfa2 2734
13761a11
NC
2735 insn_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2);
2736 frag = frag_more (insn_length);
b18c562e 2737 where = frag - frag_now->fr_literal;
13761a11
NC
2738
2739 if (extended_op)
2740 {
2741 if (strcmp (opcode->name, "swpbx") == 0
2742 || strcmp (opcode->name, "sxtx") == 0)
2743 {
2744 /* These two instructions use a special
2745 encoding of the A/L and B/W bits. */
2746 bin &= ~ BYTE_OPERATION;
2747
2748 if (byte_op)
2749 {
2750 as_bad (_("%s instruction does not accept a .b suffix"),
2751 opcode->name);
2752 return 0;
2753 }
2754 else if (! addr_op)
2755 extended |= BYTE_OPERATION;
2756 }
2757 else if (! addr_op)
2758 extended |= BYTE_OPERATION;
2759
2760 if (op1.ol != 0 && ((extended & 0xf) != 0))
2761 {
2762 as_bad (_("repeat instruction used with non-register mode instruction"));
2763 extended &= ~ 0xf;
2764 }
2765
2766 if (op1.mode == OP_EXP)
2767 {
2768 if (op1.exp.X_op == O_constant)
2769 extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
2770
2771 else if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
2772 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
2773 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
2774 else
2775 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
2776 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
2777 }
2778
2779 /* Emit the extension word. */
2780 bfd_putl16 (extended, frag);
2781 frag += 2;
2782 where += 2;
2783 }
2784
2785 bin |= op1.reg | (op1.am << 4);
b18c562e 2786 bfd_putl16 ((bfd_vma) bin, frag);
13761a11
NC
2787 frag += 2;
2788 where += 2;
b18c562e
NC
2789
2790 if (op1.mode == OP_EXP)
2469cfa2 2791 {
13761a11
NC
2792 if (op1.exp.X_op == O_constant)
2793 {
2794 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
2795 }
b18c562e 2796 else
13761a11
NC
2797 {
2798 bfd_putl16 ((bfd_vma) ZEROS, frag);
2799
2800 if (!extended_op)
2801 {
2802 if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
2803 fix_new_exp (frag_now, where, 2,
2804 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
2805 else
2806 fix_new_exp (frag_now, where, 2,
2807 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2808 }
2809 }
2469cfa2 2810 }
13761a11
NC
2811
2812 dwarf2_emit_insn (insn_length);
b18c562e 2813 break;
2469cfa2 2814
b18c562e
NC
2815 case 3: /* Conditional jumps instructions. */
2816 line = extract_operand (line, l1, sizeof (l1));
2817 /* l1 is a label. */
2818 if (l1[0])
2469cfa2 2819 {
b18c562e
NC
2820 char *m = l1;
2821 expressionS exp;
2469cfa2 2822
b18c562e
NC
2823 if (*m == '$')
2824 m++;
2469cfa2 2825
b18c562e 2826 parse_exp (m, &exp);
2469cfa2 2827
b18c562e 2828 /* In order to handle something like:
2469cfa2 2829
b18c562e
NC
2830 and #0x8000, r5
2831 tst r5
2832 jz 4 ; skip next 4 bytes
2833 inv r5
2834 inc r5
2835 nop ; will jump here if r5 positive or zero
2469cfa2 2836
b18c562e 2837 jCOND -n ;assumes jump n bytes backward:
2469cfa2 2838
b18c562e
NC
2839 mov r5,r6
2840 jmp -2
2469cfa2 2841
b18c562e
NC
2842 is equal to:
2843 lab:
2844 mov r5,r6
2845 jmp lab
2846
2847 jCOND $n ; jump from PC in either direction. */
2469cfa2 2848
b18c562e
NC
2849 if (exp.X_op == O_constant)
2850 {
2851 int x = exp.X_add_number;
2469cfa2 2852
b18c562e
NC
2853 if (x & 1)
2854 {
2855 as_warn (_("Even number required. Rounded to %d"), x + 1);
2856 x++;
2857 }
2469cfa2 2858
b18c562e
NC
2859 if ((*l1 == '$' && x > 0) || x < 0)
2860 x -= 2;
2469cfa2 2861
b18c562e
NC
2862 x >>= 1;
2863
2864 if (x > 512 || x < -511)
2865 {
2866 as_bad (_("Wrong displacement %d"), x << 1);
2867 break;
2868 }
2869
13761a11
NC
2870 insn_length += 2;
2871 frag = frag_more (2); /* Instr size is 1 word. */
2872
b18c562e
NC
2873 bin |= x & 0x3ff;
2874 bfd_putl16 ((bfd_vma) bin, frag);
2875 }
2876 else if (exp.X_op == O_symbol && *l1 != '$')
2469cfa2 2877 {
13761a11
NC
2878 insn_length += 2;
2879 frag = frag_more (2); /* Instr size is 1 word. */
b18c562e
NC
2880 where = frag - frag_now->fr_literal;
2881 fix_new_exp (frag_now, where, 2,
2882 &exp, TRUE, BFD_RELOC_MSP430_10_PCREL);
2883
2884 bfd_putl16 ((bfd_vma) bin, frag);
2469cfa2 2885 }
b18c562e 2886 else if (*l1 == '$')
2469cfa2 2887 {
b18c562e 2888 as_bad (_("instruction requires label sans '$'"));
2469cfa2 2889 }
b18c562e 2890 else
13761a11
NC
2891 as_bad (_
2892 ("instruction requires label or value in range -511:512"));
2893 dwarf2_emit_insn (insn_length);
2a9a06c1 2894 break;
2469cfa2 2895 }
b18c562e
NC
2896 else
2897 {
2898 as_bad (_("instruction requires label"));
2899 break;
2900 }
2901 break;
2469cfa2 2902
b18c562e 2903 case 4: /* Extended jumps. */
77592908
DD
2904 if (!msp430_enable_polys)
2905 {
20203fb9 2906 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
77592908
DD
2907 break;
2908 }
13761a11 2909
b18c562e
NC
2910 line = extract_operand (line, l1, sizeof (l1));
2911 if (l1[0])
2469cfa2 2912 {
b18c562e
NC
2913 char *m = l1;
2914 expressionS exp;
2469cfa2 2915
b18c562e
NC
2916 /* Ignore absolute addressing. make it PC relative anyway. */
2917 if (*m == '#' || *m == '$')
2918 m++;
2469cfa2 2919
b18c562e
NC
2920 parse_exp (m, & exp);
2921 if (exp.X_op == O_symbol)
2469cfa2 2922 {
b18c562e
NC
2923 /* Relaxation required. */
2924 struct rcodes_s rc = msp430_rcodes[opcode->insn_opnumb];
2925
13761a11
NC
2926 if (msp430_mcu->isa == MSP430X_ISA)
2927 rc = msp430x_rcodes[opcode->insn_opnumb];
2928
2929 /* The parameter to dwarf2_emit_insn is actually the offset to
2930 the start of the insn from the fix piece of instruction that
2931 was emitted. Since next fragments may have variable size we
2932 tie debug info to the beginning of the instruction. */
2933 insn_length += 8;
3e470ab5 2934 frag = frag_more (8);
2a9a06c1 2935 dwarf2_emit_insn (0);
3e470ab5
DD
2936 bfd_putl16 ((bfd_vma) rc.sop, frag);
2937 frag = frag_variant (rs_machine_dependent, 8, 2,
13761a11
NC
2938 /* Wild guess. */
2939 ENCODE_RELAX (rc.lpos, STATE_BITS10),
b18c562e
NC
2940 exp.X_add_symbol,
2941 0, /* Offset is zero if jump dist less than 1K. */
2942 (char *) frag);
2943 break;
2469cfa2
NC
2944 }
2945 }
b18c562e
NC
2946
2947 as_bad (_("instruction requires label"));
2948 break;
2949
2950 case 5: /* Emulated extended branches. */
77592908
DD
2951 if (!msp430_enable_polys)
2952 {
20203fb9 2953 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
77592908
DD
2954 break;
2955 }
b18c562e
NC
2956 line = extract_operand (line, l1, sizeof (l1));
2957 if (l1[0])
2469cfa2 2958 {
b18c562e
NC
2959 char * m = l1;
2960 expressionS exp;
2961
2962 /* Ignore absolute addressing. make it PC relative anyway. */
2963 if (*m == '#' || *m == '$')
2964 m++;
2965
2966 parse_exp (m, & exp);
2967 if (exp.X_op == O_symbol)
2968 {
2969 /* Relaxation required. */
2970 struct hcodes_s hc = msp430_hcodes[opcode->insn_opnumb];
2971
13761a11
NC
2972 if (msp430_mcu->isa == MSP430X_ISA)
2973 hc = msp430x_hcodes[opcode->insn_opnumb];
2974
2975 insn_length += 8;
3e470ab5 2976 frag = frag_more (8);
2a9a06c1 2977 dwarf2_emit_insn (0);
3e470ab5
DD
2978 bfd_putl16 ((bfd_vma) hc.op0, frag);
2979 bfd_putl16 ((bfd_vma) hc.op1, frag+2);
2980
2981 frag = frag_variant (rs_machine_dependent, 8, 2,
b18c562e
NC
2982 ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_BITS10), /* Wild guess. */
2983 exp.X_add_symbol,
2984 0, /* Offset is zero if jump dist less than 1K. */
2985 (char *) frag);
2986 break;
2987 }
2469cfa2
NC
2988 }
2989
b18c562e
NC
2990 as_bad (_("instruction requires label"));
2991 break;
2469cfa2 2992
b18c562e 2993 default:
79cf5950 2994 as_bad (_("Illegal instruction or not implemented opcode."));
b18c562e 2995 }
2469cfa2 2996
b18c562e
NC
2997 input_line_pointer = line;
2998 return 0;
2999}
2469cfa2 3000
b18c562e
NC
3001void
3002md_assemble (char * str)
3003{
3004 struct msp430_opcode_s * opcode;
3005 char cmd[32];
3006 unsigned int i = 0;
2469cfa2 3007
b18c562e
NC
3008 str = skip_space (str); /* Skip leading spaces. */
3009 str = extract_cmd (str, cmd, sizeof (cmd));
2469cfa2 3010
b18c562e
NC
3011 while (cmd[i] && i < sizeof (cmd))
3012 {
3013 char a = TOLOWER (cmd[i]);
3014 cmd[i] = a;
3015 i++;
2469cfa2 3016 }
2469cfa2 3017
b18c562e 3018 if (!cmd[0])
2469cfa2 3019 {
b18c562e
NC
3020 as_bad (_("can't find opcode "));
3021 return;
3022 }
2469cfa2 3023
b18c562e 3024 opcode = (struct msp430_opcode_s *) hash_find (msp430_hash, cmd);
2469cfa2 3025
b18c562e
NC
3026 if (opcode == NULL)
3027 {
3028 as_bad (_("unknown opcode `%s'"), cmd);
3029 return;
2469cfa2 3030 }
2469cfa2 3031
b18c562e
NC
3032 {
3033 char *__t = input_line_pointer;
2469cfa2 3034
b18c562e
NC
3035 msp430_operands (opcode, str);
3036 input_line_pointer = __t;
3037 }
3038}
2469cfa2
NC
3039
3040/* GAS will call this function for each section at the end of the assembly,
3041 to permit the CPU backend to adjust the alignment of a section. */
3042
3043valueT
b18c562e 3044md_section_align (asection * seg, valueT addr)
2469cfa2
NC
3045{
3046 int align = bfd_get_section_alignment (stdoutput, seg);
3047
3048 return ((addr + (1 << align) - 1) & (-1 << align));
3049}
3050
3051/* If you define this macro, it should return the offset between the
3052 address of a PC relative fixup and the position from which the PC
3053 relative adjustment should be made. On many processors, the base
3054 of a PC relative instruction is the next instruction, so this
3055 macro would return the length of an instruction. */
3056
3057long
b18c562e 3058md_pcrel_from_section (fixS * fixp, segT sec)
2469cfa2
NC
3059{
3060 if (fixp->fx_addsy != (symbolS *) NULL
3061 && (!S_IS_DEFINED (fixp->fx_addsy)
3062 || (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
3063 return 0;
3064
3065 return fixp->fx_frag->fr_address + fixp->fx_where;
3066}
3067
77592908
DD
3068/* Replaces standard TC_FORCE_RELOCATION_LOCAL.
3069 Now it handles the situation when relocations
13761a11 3070 have to be passed to linker. */
77592908 3071int
13761a11 3072msp430_force_relocation_local (fixS *fixp)
77592908 3073{
13761a11
NC
3074 if (fixp->fx_r_type == BFD_RELOC_MSP430_10_PCREL)
3075 return 1;
3076
3077 if (fixp->fx_pcrel)
3078 return 1;
3079
77592908
DD
3080 if (msp430_enable_polys
3081 && !msp430_enable_relax)
3082 return 1;
13761a11
NC
3083
3084 return (!fixp->fx_pcrel
3085 || generic_force_reloc (fixp));
77592908
DD
3086}
3087
3088
2469cfa2
NC
3089/* GAS will call this for each fixup. It should store the correct
3090 value in the object file. */
2469cfa2 3091void
55cf6793 3092md_apply_fix (fixS * fixp, valueT * valuep, segT seg)
2469cfa2 3093{
b18c562e 3094 unsigned char * where;
2469cfa2
NC
3095 unsigned long insn;
3096 long value;
3097
3098 if (fixp->fx_addsy == (symbolS *) NULL)
3099 {
3100 value = *valuep;
3101 fixp->fx_done = 1;
3102 }
3103 else if (fixp->fx_pcrel)
3104 {
3105 segT s = S_GET_SEGMENT (fixp->fx_addsy);
3106
3107 if (fixp->fx_addsy && (s == seg || s == absolute_section))
3108 {
18af0b39
NC
3109 /* FIXME: We can appear here only in case if we perform a pc
3110 relative jump to the label which is i) global, ii) locally
3111 defined or this is a jump to an absolute symbol.
3112 If this is an absolute symbol -- everything is OK.
3113 If this is a global label, we've got a symbol value defined
3114 twice:
3115 1. S_GET_VALUE (fixp->fx_addsy) will contain a symbol offset
3116 from this section start
3117 2. *valuep will contain the real offset from jump insn to the
3118 label
3119 So, the result of S_GET_VALUE (fixp->fx_addsy) + (* valuep);
3120 will be incorrect. Therefore remove s_get_value. */
3121 value = /* S_GET_VALUE (fixp->fx_addsy) + */ * valuep;
2469cfa2
NC
3122 fixp->fx_done = 1;
3123 }
3124 else
3125 value = *valuep;
3126 }
3127 else
3128 {
3129 value = fixp->fx_offset;
3130
3131 if (fixp->fx_subsy != (symbolS *) NULL)
3132 {
3133 if (S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
3134 {
3135 value -= S_GET_VALUE (fixp->fx_subsy);
3136 fixp->fx_done = 1;
3137 }
2469cfa2
NC
3138 }
3139 }
3140
77592908
DD
3141 fixp->fx_no_overflow = 1;
3142
13761a11
NC
3143 /* If polymorphs are enabled and relax disabled.
3144 do not kill any relocs and pass them to linker. */
3145 if (msp430_enable_polys
77592908 3146 && !msp430_enable_relax)
2469cfa2 3147 {
13761a11 3148 if (!fixp->fx_addsy || (fixp->fx_addsy
77592908 3149 && S_GET_SEGMENT (fixp->fx_addsy) == absolute_section))
79cf5950 3150 fixp->fx_done = 1; /* It is ok to kill 'abs' reloc. */
77592908
DD
3151 else
3152 fixp->fx_done = 0;
2469cfa2
NC
3153 }
3154
3155 if (fixp->fx_done)
3156 {
3157 /* Fetch the instruction, insert the fully resolved operand
8cd5b113 3158 value, and stuff the instruction back again. */
2132e3a3 3159 where = (unsigned char *) fixp->fx_frag->fr_literal + fixp->fx_where;
2469cfa2
NC
3160
3161 insn = bfd_getl16 (where);
3162
3163 switch (fixp->fx_r_type)
3164 {
3165 case BFD_RELOC_MSP430_10_PCREL:
3166 if (value & 1)
3167 as_bad_where (fixp->fx_file, fixp->fx_line,
3168 _("odd address operand: %ld"), value);
3169
3170 /* Jumps are in words. */
3171 value >>= 1;
3172 --value; /* Correct PC. */
3173
3174 if (value < -512 || value > 511)
3175 as_bad_where (fixp->fx_file, fixp->fx_line,
3176 _("operand out of range: %ld"), value);
3177
3178 value &= 0x3ff; /* get rid of extended sign */
3179 bfd_putl16 ((bfd_vma) (value | insn), where);
3180 break;
3181
13761a11 3182 case BFD_RELOC_MSP430X_PCR16:
b18c562e 3183 case BFD_RELOC_MSP430_RL_PCREL:
2469cfa2
NC
3184 case BFD_RELOC_MSP430_16_PCREL:
3185 if (value & 1)
3186 as_bad_where (fixp->fx_file, fixp->fx_line,
3187 _("odd address operand: %ld"), value);
13761a11 3188 /* Fall through. */
2469cfa2
NC
3189
3190 case BFD_RELOC_MSP430_16_PCREL_BYTE:
3191 /* Nothing to be corrected here. */
3192 if (value < -32768 || value > 65536)
3193 as_bad_where (fixp->fx_file, fixp->fx_line,
3194 _("operand out of range: %ld"), value);
13761a11 3195 /* Fall through. */
2469cfa2 3196
13761a11
NC
3197 case BFD_RELOC_MSP430X_ABS16:
3198 case BFD_RELOC_MSP430_16:
3199 case BFD_RELOC_16:
3200 case BFD_RELOC_MSP430_16_BYTE:
2469cfa2
NC
3201 value &= 0xffff; /* Get rid of extended sign. */
3202 bfd_putl16 ((bfd_vma) value, where);
3203 break;
3204
3205 case BFD_RELOC_32:
3206 bfd_putl16 ((bfd_vma) value, where);
3207 break;
3208
13761a11
NC
3209 case BFD_RELOC_MSP430_ABS8:
3210 case BFD_RELOC_8:
3211 bfd_put_8 (NULL, (bfd_vma) value, where);
3212 break;
3213
3214 case BFD_RELOC_MSP430X_ABS20_EXT_SRC:
3215 case BFD_RELOC_MSP430X_PCR20_EXT_SRC:
3216 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 4);
3217 value >>= 16;
3218 bfd_putl16 ((bfd_vma) (((value & 0xf) << 7) | insn), where);
3219 break;
3220
3221 case BFD_RELOC_MSP430X_ABS20_ADR_SRC:
3222 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
3223 value >>= 16;
3224 bfd_putl16 ((bfd_vma) (((value & 0xf) << 8) | insn), where);
3225 break;
3226
3227 case BFD_RELOC_MSP430X_ABS20_EXT_ODST:
3228 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 6);
3229 value >>= 16;
3230 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
3231 break;
3232
3233 case BFD_RELOC_MSP430X_PCR20_CALL:
3234 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
3235 value >>= 16;
3236 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
3237 break;
3238
3239 case BFD_RELOC_MSP430X_ABS20_EXT_DST:
3240 case BFD_RELOC_MSP430X_PCR20_EXT_DST:
3241 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 4);
3242 value >>= 16;
3243 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
3244 break;
3245
3246 case BFD_RELOC_MSP430X_PCR20_EXT_ODST:
3247 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 6);
3248 value >>= 16;
3249 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
3250 break;
3251
3252 case BFD_RELOC_MSP430X_ABS20_ADR_DST:
3253 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
3254 value >>= 16;
3255 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
2469cfa2
NC
3256 break;
3257
3258 default:
3259 as_fatal (_("line %d: unknown relocation type: 0x%x"),
3260 fixp->fx_line, fixp->fx_r_type);
3261 break;
3262 }
3263 }
3264 else
3265 {
3266 fixp->fx_addnumber = value;
3267 }
2469cfa2
NC
3268}
3269
13761a11
NC
3270static bfd_boolean
3271S_IS_GAS_LOCAL (symbolS * s)
3272{
3273 const char * name;
3274 unsigned int len;
3275
3276 if (s == NULL)
3277 return FALSE;
3278 name = S_GET_NAME (s);
3279 len = strlen (name) - 1;
3280
3281 return name[len] == 1 || name[len] == 2;
3282}
3283
7be1c489
AM
3284/* GAS will call this to generate a reloc, passing the resulting reloc
3285 to `bfd_install_relocation'. This currently works poorly, as
3286 `bfd_install_relocation' often does the wrong thing, and instances of
3287 `tc_gen_reloc' have been written to work around the problems, which
3288 in turns makes it difficult to fix `bfd_install_relocation'. */
2469cfa2
NC
3289
3290/* If while processing a fixup, a reloc really needs to be created
3291 then it is done here. */
3292
13761a11 3293arelent **
b18c562e 3294tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
2469cfa2 3295{
13761a11
NC
3296 static arelent * no_relocs = NULL;
3297 static arelent * relocs[MAX_RELOC_EXPANSION + 1];
3298 arelent *reloc;
2469cfa2 3299
b18c562e 3300 reloc = xmalloc (sizeof (arelent));
2469cfa2
NC
3301 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
3302 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
13761a11 3303
2469cfa2
NC
3304 if (reloc->howto == (reloc_howto_type *) NULL)
3305 {
3306 as_bad_where (fixp->fx_file, fixp->fx_line,
3307 _("reloc %d not supported by object file format"),
3308 (int) fixp->fx_r_type);
13761a11
NC
3309 free (reloc);
3310 return & no_relocs;
3311 }
3312
3313 relocs[0] = reloc;
3314 relocs[1] = NULL;
3315
3316 if (fixp->fx_subsy
3317 && S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
3318 {
3319 fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy);
3320 fixp->fx_subsy = NULL;
2469cfa2
NC
3321 }
3322
13761a11
NC
3323 if (fixp->fx_addsy && fixp->fx_subsy)
3324 {
3325 asection *asec, *ssec;
3326
3327 asec = S_GET_SEGMENT (fixp->fx_addsy);
3328 ssec = S_GET_SEGMENT (fixp->fx_subsy);
3329
3330 /* If we have a difference between two different, non-absolute symbols
3331 we must generate two relocs (one for each symbol) and allow the
3332 linker to resolve them - relaxation may change the distances between
3333 symbols, even local symbols defined in the same section.
3334
3335 Unfortunately we cannot do this with assembler generated local labels
3336 because there can be multiple incarnations of the same label, with
3337 exactly the same name, in any given section and the linker will have
3338 no way to identify the correct one. Instead we just have to hope
3339 that no relaxtion will occur between the local label and the other
3340 symbol in the expression.
3341
3342 Similarly we have to compute differences between symbols in the .eh_frame
3343 section as the linker is not smart enough to apply relocations there
3344 before attempting to process it. */
3345 if ((ssec != absolute_section || asec != absolute_section)
3346 && (fixp->fx_addsy != fixp->fx_subsy)
3347 && strcmp (ssec->name, ".eh_frame") != 0
3348 && ! S_IS_GAS_LOCAL (fixp->fx_addsy)
3349 && ! S_IS_GAS_LOCAL (fixp->fx_subsy))
3350 {
3351 arelent * reloc2 = xmalloc (sizeof * reloc);
2469cfa2 3352
13761a11
NC
3353 relocs[0] = reloc2;
3354 relocs[1] = reloc;
2469cfa2 3355
13761a11
NC
3356 reloc2->address = reloc->address;
3357 reloc2->howto = bfd_reloc_type_lookup (stdoutput,
3358 BFD_RELOC_MSP430_SYM_DIFF);
3359 reloc2->addend = - S_GET_VALUE (fixp->fx_subsy);
3360
3361 if (ssec == absolute_section)
3362 reloc2->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
3363 else
3364 {
3365 reloc2->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
3366 *reloc2->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy);
3367 }
3368
3369 reloc->addend = fixp->fx_offset;
3370 if (asec == absolute_section)
3371 {
3372 reloc->addend += S_GET_VALUE (fixp->fx_addsy);
3373 reloc->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
3374 }
3375 else
3376 {
3377 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
3378 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
3379 }
3380
3381 fixp->fx_pcrel = 0;
3382 fixp->fx_done = 1;
3383 return relocs;
3384 }
3385 else
3386 {
3387 char *fixpos = fixp->fx_where + fixp->fx_frag->fr_literal;
3388
3389 reloc->addend = (S_GET_VALUE (fixp->fx_addsy)
3390 - S_GET_VALUE (fixp->fx_subsy) + fixp->fx_offset);
3391
3392 switch (fixp->fx_r_type)
3393 {
3394 case BFD_RELOC_8:
3395 md_number_to_chars (fixpos, reloc->addend, 1);
3396 break;
3397
3398 case BFD_RELOC_16:
3399 md_number_to_chars (fixpos, reloc->addend, 2);
3400 break;
3401
3402 case BFD_RELOC_24:
3403 md_number_to_chars (fixpos, reloc->addend, 3);
3404 break;
3405
3406 case BFD_RELOC_32:
3407 md_number_to_chars (fixpos, reloc->addend, 4);
3408 break;
3409
3410 default:
3411 reloc->sym_ptr_ptr
3412 = (asymbol **) bfd_abs_section_ptr->symbol_ptr_ptr;
3413 return relocs;
3414 }
3415
3416 free (reloc);
3417 return & no_relocs;
3418 }
3419 }
3420 else
3421 {
3422#if 0
3423 if (fixp->fx_r_type == BFD_RELOC_MSP430X_ABS16
3424 && S_GET_SEGMENT (fixp->fx_addsy) == absolute_section)
3425 {
3426 bfd_vma amount = S_GET_VALUE (fixp->fx_addsy);
3427 char *fixpos = fixp->fx_where + fixp->fx_frag->fr_literal;
3428
3429 md_number_to_chars (fixpos, amount, 2);
3430 free (reloc);
3431 return & no_relocs;
3432 }
3433#endif
3434 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
3435 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
3436 reloc->addend = fixp->fx_offset;
3437
3438 if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
3439 || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
3440 reloc->address = fixp->fx_offset;
3441 }
3442
3443 return relocs;
2469cfa2
NC
3444}
3445
b18c562e
NC
3446int
3447md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
3448 asection * segment_type ATTRIBUTE_UNUSED)
3449{
3450 if (fragP->fr_symbol && S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
3451 {
3452 /* This is a jump -> pcrel mode. Nothing to do much here.
3453 Return value == 2. */
3454 fragP->fr_subtype =
3455 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_BITS10);
3456 }
3457 else if (fragP->fr_symbol)
3458 {
3459 /* Its got a segment, but its not ours. Even if fr_symbol is in
79cf5950 3460 an absolute segment, we don't know a displacement until we link
b18c562e
NC
3461 object files. So it will always be long. This also applies to
3462 labels in a subsegment of current. Liker may relax it to short
3463 jump later. Return value == 8. */
3464 fragP->fr_subtype =
3465 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_WORD);
3466 }
3467 else
3468 {
3469 /* We know the abs value. may be it is a jump to fixed address.
79cf5950 3470 Impossible in our case, cause all constants already handled. */
b18c562e
NC
3471 fragP->fr_subtype =
3472 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_UNDEF);
3473 }
2469cfa2 3474
b18c562e
NC
3475 return md_relax_table[fragP->fr_subtype].rlx_length;
3476}
3477
3478void
3479md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
3480 asection * sec ATTRIBUTE_UNUSED,
3481 fragS * fragP)
2469cfa2 3482{
b18c562e
NC
3483 char * where = 0;
3484 int rela = -1;
3485 int i;
3486 struct rcodes_s * cc = NULL;
3487 struct hcodes_s * hc = NULL;
3488
3489 switch (fragP->fr_subtype)
3490 {
3491 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_BITS10):
3492 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_BITS10):
3493 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_BITS10):
3494 /* We do not have to convert anything here.
3495 Just apply a fix. */
3496 rela = BFD_RELOC_MSP430_10_PCREL;
3497 break;
3498
3499 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_WORD):
3500 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_UNDEF):
3501 /* Convert uncond branch jmp lab -> br lab. */
3502 cc = & msp430_rcodes[7];
13761a11
NC
3503 if (msp430_mcu->isa == MSP430X_ISA)
3504 cc = msp430x_rcodes + 7;
b18c562e
NC
3505 where = fragP->fr_literal + fragP->fr_fix;
3506 bfd_putl16 (cc->lop0, where);
3507 rela = BFD_RELOC_MSP430_RL_PCREL;
3508 fragP->fr_fix += 2;
3509 break;
3510
3511 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_WORD):
3512 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_UNDEF):
3513 {
3514 /* Other simple branches. */
3515 int insn = bfd_getl16 (fragP->fr_opcode);
3516
3517 insn &= 0xffff;
3518 /* Find actual instruction. */
13761a11
NC
3519 if (msp430_mcu->isa == MSP430X_ISA)
3520 {
3521 for (i = 0; i < 7 && !cc; i++)
3522 if (msp430x_rcodes[i].sop == insn)
3523 cc = msp430x_rcodes + i;
3524 }
3525 else
3526 {
3527 for (i = 0; i < 7 && !cc; i++)
3528 if (msp430_rcodes[i].sop == insn)
3529 cc = & msp430_rcodes[i];
3530 }
3531
b18c562e
NC
3532 if (!cc || !cc->name)
3533 as_fatal (_("internal inconsistency problem in %s: insn %04lx"),
3534 __FUNCTION__, (long) insn);
3535 where = fragP->fr_literal + fragP->fr_fix;
3536 bfd_putl16 (cc->lop0, where);
3537 bfd_putl16 (cc->lop1, where + 2);
3538 rela = BFD_RELOC_MSP430_RL_PCREL;
3539 fragP->fr_fix += 4;
3540 }
3541 break;
3542
3543 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_WORD):
3544 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_UNDEF):
3545 cc = & msp430_rcodes[6];
13761a11
NC
3546
3547 if (msp430_mcu->isa == MSP430X_ISA)
3548 cc = msp430x_rcodes + 6;
3549
b18c562e
NC
3550 where = fragP->fr_literal + fragP->fr_fix;
3551 bfd_putl16 (cc->lop0, where);
3552 bfd_putl16 (cc->lop1, where + 2);
3553 bfd_putl16 (cc->lop2, where + 4);
3554 rela = BFD_RELOC_MSP430_RL_PCREL;
3555 fragP->fr_fix += 6;
3556 break;
3557
3558 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_BITS10):
3559 {
3560 int insn = bfd_getl16 (fragP->fr_opcode + 2);
3561
3562 insn &= 0xffff;
13761a11
NC
3563 if (msp430_mcu->isa == MSP430X_ISA)
3564 {
3565 for (i = 0; i < 4 && !hc; i++)
3566 if (msp430x_hcodes[i].op1 == insn)
3567 hc = msp430x_hcodes + i;
3568 }
3569 else
3570 {
3571 for (i = 0; i < 4 && !hc; i++)
3572 if (msp430_hcodes[i].op1 == insn)
3573 hc = &msp430_hcodes[i];
3574 }
3575
b18c562e
NC
3576 if (!hc || !hc->name)
3577 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
3578 __FUNCTION__, (long) insn);
3579 rela = BFD_RELOC_MSP430_10_PCREL;
3580 /* Apply a fix for a first label if necessary.
3581 another fix will be applied to the next word of insn anyway. */
3582 if (hc->tlab == 2)
3583 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
13761a11 3584 fragP->fr_offset, TRUE, rela);
b18c562e
NC
3585 fragP->fr_fix += 2;
3586 }
3587
3588 break;
3589
3590 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_WORD):
3591 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_UNDEF):
3592 {
3593 int insn = bfd_getl16 (fragP->fr_opcode + 2);
3594
3595 insn &= 0xffff;
13761a11
NC
3596 if (msp430_mcu->isa == MSP430X_ISA)
3597 {
3598 for (i = 0; i < 4 && !hc; i++)
3599 if (msp430x_hcodes[i].op1 == insn)
3600 hc = msp430x_hcodes + i;
3601 }
3602 else
3603 {
3604 for (i = 0; i < 4 && !hc; i++)
3605 if (msp430_hcodes[i].op1 == insn)
3606 hc = & msp430_hcodes[i];
3607 }
b18c562e
NC
3608 if (!hc || !hc->name)
3609 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
3610 __FUNCTION__, (long) insn);
3611 rela = BFD_RELOC_MSP430_RL_PCREL;
3612 where = fragP->fr_literal + fragP->fr_fix;
3613 bfd_putl16 (hc->lop0, where);
3614 bfd_putl16 (hc->lop1, where + 2);
3615 bfd_putl16 (hc->lop2, where + 4);
3616 fragP->fr_fix += 6;
3617 }
3618 break;
3619
3620 default:
3621 as_fatal (_("internal inconsistency problem in %s: %lx"),
3622 __FUNCTION__, (long) fragP->fr_subtype);
3623 break;
3624 }
3625
3626 /* Now apply fix. */
3627 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
3628 fragP->fr_offset, TRUE, rela);
3629 /* Just fixed 2 bytes. */
3630 fragP->fr_fix += 2;
2469cfa2
NC
3631}
3632
b18c562e
NC
3633/* Relax fragment. Mostly stolen from hc11 and mcore
3634 which arches I think I know. */
2469cfa2 3635
b18c562e
NC
3636long
3637msp430_relax_frag (segT seg ATTRIBUTE_UNUSED, fragS * fragP,
3638 long stretch ATTRIBUTE_UNUSED)
2469cfa2 3639{
b18c562e
NC
3640 long growth;
3641 offsetT aim = 0;
3642 symbolS *symbolP;
3643 const relax_typeS *this_type;
3644 const relax_typeS *start_type;
3645 relax_substateT next_state;
3646 relax_substateT this_state;
3647 const relax_typeS *table = md_relax_table;
3648
3649 /* Nothing to be done if the frag has already max size. */
3650 if (RELAX_STATE (fragP->fr_subtype) == STATE_UNDEF
3651 || RELAX_STATE (fragP->fr_subtype) == STATE_WORD)
3652 return 0;
3653
3654 if (RELAX_STATE (fragP->fr_subtype) == STATE_BITS10)
3655 {
3656 symbolP = fragP->fr_symbol;
3657 if (symbol_resolved_p (symbolP))
3658 as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
3659 __FUNCTION__);
3660 /* We know the offset. calculate a distance. */
3661 aim = S_GET_VALUE (symbolP) - fragP->fr_address - fragP->fr_fix;
3662 }
3663
77592908
DD
3664 if (!msp430_enable_relax)
3665 {
3666 /* Relaxation is not enabled. So, make all jump as long ones
13761a11 3667 by setting 'aim' to quite high value. */
77592908
DD
3668 aim = 0x7fff;
3669 }
13761a11 3670
b18c562e
NC
3671 this_state = fragP->fr_subtype;
3672 start_type = this_type = table + this_state;
3673
3674 if (aim < 0)
3675 {
3676 /* Look backwards. */
3677 for (next_state = this_type->rlx_more; next_state;)
3e470ab5 3678 if (aim >= this_type->rlx_backward || !this_type->rlx_backward)
b18c562e
NC
3679 next_state = 0;
3680 else
3681 {
3682 /* Grow to next state. */
3683 this_state = next_state;
3684 this_type = table + this_state;
3685 next_state = this_type->rlx_more;
3686 }
3687 }
3688 else
3689 {
3690 /* Look forwards. */
3691 for (next_state = this_type->rlx_more; next_state;)
3e470ab5 3692 if (aim <= this_type->rlx_forward || !this_type->rlx_forward)
b18c562e
NC
3693 next_state = 0;
3694 else
3695 {
3696 /* Grow to next state. */
3697 this_state = next_state;
3698 this_type = table + this_state;
3699 next_state = this_type->rlx_more;
3700 }
3701 }
3702
3703 growth = this_type->rlx_length - start_type->rlx_length;
3704 if (growth != 0)
3705 fragP->fr_subtype = this_state;
3706 return growth;
2469cfa2 3707}
13761a11
NC
3708
3709/* Return FALSE if the fixup in fixp should be left alone and not
3710 adjusted. We return FALSE here so that linker relaxation will
3711 work. */
3712
3713bfd_boolean
3714msp430_fix_adjustable (struct fix *fixp ATTRIBUTE_UNUSED)
3715{
3716 /* If the symbol is in a non-code section then it should be OK. */
3717 if (fixp->fx_addsy
3718 && ((S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_CODE) == 0))
3719 return TRUE;
3720
3721 return FALSE;
3722}
3723
3724/* Set the contents of the .MSP430.attributes section. */
3725
3726void
3727msp430_md_end (void)
3728{
3729 bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_ISA,
3730 msp430_mcu->isa == MSP430X_ISA ? 2 : 1);
3731
3732 bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_Code_Model,
3733 large_model ? 2 : 1);
3734
3735 bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_Data_Model,
3736 large_model ? 2 : 1);
3737}
3738
3739/* Returns FALSE if there is a msp430 specific reason why the
3740 subtraction of two same-section symbols cannot be computed by
3741 the assembler. */
3742
3743bfd_boolean
3744msp430_allow_local_subtract (expressionS * left,
3745 expressionS * right,
3746 segT section)
3747{
3748 /* If the symbols are not in a code section then they are OK. */
3749 if ((section->flags & SEC_CODE) == 0)
3750 return TRUE;
3751
3752 if (S_IS_GAS_LOCAL (left->X_add_symbol) || S_IS_GAS_LOCAL (right->X_add_symbol))
3753 return TRUE;
3754
3755 if (left->X_add_symbol == right->X_add_symbol)
3756 return TRUE;
3757
3758 /* We have to assume that there may be instructions between the
3759 two symbols and that relaxation may increase the distance between
3760 them. */
3761 return FALSE;
3762}
This page took 0.668904 seconds and 4 git commands to generate.