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