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