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