d7a2082092875a8a0ec0b164652d9a2a8d287d15
[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, 2003, 2004, 2005 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 2, 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, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
22
23 #include <stdio.h>
24 #include <string.h>
25 #include <stdlib.h>
26 #include <limits.h>
27
28 #define PUSH_1X_WORKAROUND
29 #include "as.h"
30 #include "subsegs.h"
31 #include "opcode/msp430.h"
32 #include "safe-ctype.h"
33
34 /* GCC uses the some condition codes which we'll
35 implement as new polymorph instructions.
36
37 COND EXPL SHORT JUMP LONG JUMP
38 ===============================================
39 eq == jeq jne +4; br lab
40 ne != jne jeq +4; br lab
41
42 ltn honours no-overflow flag
43 ltn < jn jn +2; jmp +4; br lab
44
45 lt < jl jge +4; br lab
46 ltu < jlo lhs +4; br lab
47 le <= see below
48 leu <= see below
49
50 gt > see below
51 gtu > see below
52 ge >= jge jl +4; br lab
53 geu >= jhs jlo +4; br lab
54 ===============================================
55
56 Therefore, new opcodes are (BranchEQ -> beq; and so on...)
57 beq,bne,blt,bltn,bltu,bge,bgeu
58 'u' means unsigned compares
59
60 Also, we add 'jump' instruction:
61 jump UNCOND -> jmp br lab
62
63 They will have fmt == 4, and insn_opnumb == number of instruction. */
64
65 struct rcodes_s
66 {
67 char * name;
68 int index; /* Corresponding insn_opnumb. */
69 int sop; /* Opcode if jump length is short. */
70 long lpos; /* Label position. */
71 long lop0; /* Opcode 1 _word_ (16 bits). */
72 long lop1; /* Opcode second word. */
73 long lop2; /* Opcode third word. */
74 };
75
76 #define MSP430_RLC(n,i,sop,o1) \
77 {#n, i, sop, 2, (o1 + 2), 0x4010, 0}
78
79 static struct rcodes_s msp430_rcodes[] =
80 {
81 MSP430_RLC (beq, 0, 0x2400, 0x2000),
82 MSP430_RLC (bne, 1, 0x2000, 0x2400),
83 MSP430_RLC (blt, 2, 0x3800, 0x3400),
84 MSP430_RLC (bltu, 3, 0x2800, 0x2c00),
85 MSP430_RLC (bge, 4, 0x3400, 0x3800),
86 MSP430_RLC (bgeu, 5, 0x2c00, 0x2800),
87 {"bltn", 6, 0x3000, 3, 0x3000 + 1, 0x3c00 + 2,0x4010},
88 {"jump", 7, 0x3c00, 1, 0x4010, 0, 0},
89 {0,0,0,0,0,0,0}
90 };
91 #undef MSP430_RLC
92
93
94 /* More difficult than above and they have format 5.
95
96 COND EXPL SHORT LONG
97 =================================================================
98 gt > jeq +2; jge label jeq +6; jl +4; br label
99 gtu > jeq +2; jhs label jeq +6; jlo +4; br label
100 leu <= jeq label; jlo label jeq +2; jhs +4; br label
101 le <= jeq label; jl label jeq +2; jge +4; br label
102 ================================================================= */
103
104 struct hcodes_s
105 {
106 char * name;
107 int index; /* Corresponding insn_opnumb. */
108 int tlab; /* Number of labels in short mode. */
109 int op0; /* Opcode for first word of short jump. */
110 int op1; /* Opcode for second word of short jump. */
111 int lop0; /* Opcodes for long jump mode. */
112 int lop1;
113 int lop2;
114 };
115
116 static struct hcodes_s msp430_hcodes[] =
117 {
118 {"bgt", 0, 1, 0x2401, 0x3400, 0x2403, 0x3802, 0x4010 },
119 {"bgtu", 1, 1, 0x2401, 0x2c00, 0x2403, 0x2802, 0x4010 },
120 {"bleu", 2, 2, 0x2400, 0x2800, 0x2401, 0x2c02, 0x4010 },
121 {"ble", 3, 2, 0x2400, 0x3800, 0x2401, 0x3402, 0x4010 },
122 {0,0,0,0,0,0,0,0}
123 };
124
125 const char comment_chars[] = ";";
126 const char line_comment_chars[] = "#";
127 const char line_separator_chars[] = "";
128 const char EXP_CHARS[] = "eE";
129 const char FLT_CHARS[] = "dD";
130
131 /* Handle long expressions. */
132 extern LITTLENUM_TYPE generic_bignum[];
133
134 static struct hash_control *msp430_hash;
135
136 /* Relaxations. */
137 #define STATE_UNCOND_BRANCH 1 /* jump */
138 #define STATE_NOOV_BRANCH 3 /* bltn */
139 #define STATE_SIMPLE_BRANCH 2 /* bne, beq, etc... */
140 #define STATE_EMUL_BRANCH 4
141
142 #define CNRL 2
143 #define CUBL 4
144 #define CNOL 8
145 #define CSBL 6
146 #define CEBL 4
147
148 /* Length. */
149 #define STATE_BITS10 1 /* wild guess. short jump */
150 #define STATE_WORD 2 /* 2 bytes pc rel. addr. more */
151 #define STATE_UNDEF 3 /* cannot handle this yet. convert to word mode */
152
153 #define ENCODE_RELAX(what,length) (((what) << 2) + (length))
154 #define RELAX_STATE(s) ((s) & 3)
155 #define RELAX_LEN(s) ((s) >> 2)
156 #define RELAX_NEXT(a,b) ENCODE_RELAX (a, b + 1)
157
158 relax_typeS md_relax_table[] =
159 {
160 /* Unused. */
161 {1, 1, 0, 0},
162 {1, 1, 0, 0},
163 {1, 1, 0, 0},
164 {1, 1, 0, 0},
165
166 /* Unconditional jump. */
167 {1, 1, 8, 5},
168 {1024, -1024, CNRL, RELAX_NEXT (STATE_UNCOND_BRANCH, STATE_BITS10)}, /* state 10 bits displ */
169 {0, 0, CUBL, RELAX_NEXT (STATE_UNCOND_BRANCH, STATE_WORD)}, /* state word */
170 {1, 1, CUBL, 0}, /* state undef */
171
172 /* Simple branches. */
173 {0, 0, 8, 9},
174 {1024, -1024, CNRL, RELAX_NEXT (STATE_SIMPLE_BRANCH, STATE_BITS10)}, /* state 10 bits displ */
175 {0, 0, CSBL, RELAX_NEXT (STATE_SIMPLE_BRANCH, STATE_WORD)}, /* state word */
176 {1, 1, CSBL, 0},
177
178 /* blt no overflow branch. */
179 {1, 1, 8, 13},
180 {1024, -1024, CNRL, RELAX_NEXT (STATE_NOOV_BRANCH, STATE_BITS10)}, /* state 10 bits displ */
181 {0, 0, CNOL, RELAX_NEXT (STATE_NOOV_BRANCH, STATE_WORD)}, /* state word */
182 {1, 1, CNOL, 0},
183
184 /* Emulated branches. */
185 {1, 1, 8, 17},
186 {1020, -1020, CEBL, RELAX_NEXT (STATE_EMUL_BRANCH, STATE_BITS10)}, /* state 10 bits displ */
187 {0, 0, CNOL, RELAX_NEXT (STATE_EMUL_BRANCH, STATE_WORD)}, /* state word */
188 {1, 1, CNOL, 0}
189 };
190
191
192 #define MAX_OP_LEN 256
193
194 struct mcu_type_s
195 {
196 char * name;
197 int isa;
198 int mach;
199 };
200
201 #define MSP430_ISA_11 11
202 #define MSP430_ISA_110 110
203 #define MSP430_ISA_12 12
204 #define MSP430_ISA_13 13
205 #define MSP430_ISA_14 14
206 #define MSP430_ISA_15 15
207 #define MSP430_ISA_16 16
208 #define MSP430_ISA_31 31
209 #define MSP430_ISA_32 32
210 #define MSP430_ISA_33 33
211 #define MSP430_ISA_41 41
212 #define MSP430_ISA_42 42
213 #define MSP430_ISA_43 43
214 #define MSP430_ISA_44 44
215
216 #define CHECK_RELOC_MSP430 ((imm_op || byte_op)?BFD_RELOC_MSP430_16_BYTE:BFD_RELOC_MSP430_16)
217 #define CHECK_RELOC_MSP430_PCREL ((imm_op || byte_op)?BFD_RELOC_MSP430_16_PCREL_BYTE:BFD_RELOC_MSP430_16_PCREL)
218
219 static struct mcu_type_s mcu_types[] =
220 {
221 {"msp1", MSP430_ISA_11, bfd_mach_msp11},
222 {"msp2", MSP430_ISA_14, bfd_mach_msp14},
223 {"msp430x110", MSP430_ISA_11, bfd_mach_msp11},
224 {"msp430x112", MSP430_ISA_11, bfd_mach_msp11},
225 {"msp430x1101", MSP430_ISA_110, bfd_mach_msp110},
226 {"msp430x1111", MSP430_ISA_110, bfd_mach_msp110},
227 {"msp430x1121", MSP430_ISA_110, bfd_mach_msp110},
228 {"msp430x1122", MSP430_ISA_11, bfd_mach_msp110},
229 {"msp430x1132", MSP430_ISA_11, bfd_mach_msp110},
230
231 {"msp430x122", MSP430_ISA_12, bfd_mach_msp12},
232 {"msp430x123", MSP430_ISA_12, bfd_mach_msp12},
233 {"msp430x1222", MSP430_ISA_12, bfd_mach_msp12},
234 {"msp430x1232", MSP430_ISA_12, bfd_mach_msp12},
235
236 {"msp430x133", MSP430_ISA_13, bfd_mach_msp13},
237 {"msp430x135", MSP430_ISA_13, bfd_mach_msp13},
238 {"msp430x1331", MSP430_ISA_13, bfd_mach_msp13},
239 {"msp430x1351", MSP430_ISA_13, bfd_mach_msp13},
240 {"msp430x147", MSP430_ISA_14, bfd_mach_msp14},
241 {"msp430x148", MSP430_ISA_14, bfd_mach_msp14},
242 {"msp430x149", MSP430_ISA_14, bfd_mach_msp14},
243
244 {"msp430x155", MSP430_ISA_15, bfd_mach_msp15},
245 {"msp430x156", MSP430_ISA_15, bfd_mach_msp15},
246 {"msp430x157", MSP430_ISA_15, bfd_mach_msp15},
247 {"msp430x167", MSP430_ISA_16, bfd_mach_msp16},
248 {"msp430x168", MSP430_ISA_16, bfd_mach_msp16},
249 {"msp430x169", MSP430_ISA_16, bfd_mach_msp16},
250 {"msp430x1610", MSP430_ISA_16, bfd_mach_msp16},
251 {"msp430x1611", MSP430_ISA_16, bfd_mach_msp16},
252 {"msp430x1612", MSP430_ISA_16, bfd_mach_msp16},
253
254 {"msp430x311", MSP430_ISA_31, bfd_mach_msp31},
255 {"msp430x312", MSP430_ISA_31, bfd_mach_msp31},
256 {"msp430x313", MSP430_ISA_31, bfd_mach_msp31},
257 {"msp430x314", MSP430_ISA_31, bfd_mach_msp31},
258 {"msp430x315", MSP430_ISA_31, bfd_mach_msp31},
259 {"msp430x323", MSP430_ISA_32, bfd_mach_msp32},
260 {"msp430x325", MSP430_ISA_32, bfd_mach_msp32},
261 {"msp430x336", MSP430_ISA_33, bfd_mach_msp33},
262 {"msp430x337", MSP430_ISA_33, bfd_mach_msp33},
263
264 {"msp430x412", MSP430_ISA_41, bfd_mach_msp41},
265 {"msp430x413", MSP430_ISA_41, bfd_mach_msp41},
266 {"msp430x415", MSP430_ISA_41, bfd_mach_msp41},
267 {"msp430x417", MSP430_ISA_41, bfd_mach_msp41},
268
269 {"msp430xE423", MSP430_ISA_42, bfd_mach_msp42},
270 {"msp430xE425", MSP430_ISA_42, bfd_mach_msp42},
271 {"msp430xE427", MSP430_ISA_42, bfd_mach_msp42},
272
273 {"msp430xW423", MSP430_ISA_42, bfd_mach_msp42},
274 {"msp430xW425", MSP430_ISA_42, bfd_mach_msp42},
275 {"msp430xW427", MSP430_ISA_42, bfd_mach_msp42},
276
277 {"msp430xG437", MSP430_ISA_43, bfd_mach_msp43},
278 {"msp430xG438", MSP430_ISA_43, bfd_mach_msp43},
279 {"msp430xG439", MSP430_ISA_43, bfd_mach_msp43},
280
281 {"msp430x435", MSP430_ISA_43, bfd_mach_msp43},
282 {"msp430x436", MSP430_ISA_43, bfd_mach_msp43},
283 {"msp430x437", MSP430_ISA_43, bfd_mach_msp43},
284 {"msp430x447", MSP430_ISA_44, bfd_mach_msp44},
285 {"msp430x448", MSP430_ISA_44, bfd_mach_msp44},
286 {"msp430x449", MSP430_ISA_44, bfd_mach_msp44},
287
288 {NULL, 0, 0}
289 };
290
291
292 static struct mcu_type_s default_mcu =
293 { "msp430x11", MSP430_ISA_11, bfd_mach_msp11 };
294
295 static struct mcu_type_s * msp430_mcu = & default_mcu;
296
297 /* Profiling capability:
298 It is a performance hit to use gcc's profiling approach for this tiny target.
299 Even more -- jtag hardware facility does not perform any profiling functions.
300 However we've got gdb's built-in simulator where we can do anything.
301 Therefore my suggestion is:
302
303 We define new section ".profiler" which holds all profiling information.
304 We define new pseudo operation .profiler which will instruct assembler to
305 add new profile entry to the object file. Profile should take place at the
306 present address.
307
308 Pseudo-op format:
309
310 .profiler flags,function_to_profile [, cycle_corrector, extra]
311
312 where 'flags' is a combination of the following chars:
313 s - function Start
314 x - function eXit
315 i - function is in Init section
316 f - function is in Fini section
317 l - Library call
318 c - libC standard call
319 d - stack value Demand (saved at run-time in simulator)
320 I - Interrupt service routine
321 P - Prologue start
322 p - Prologue end
323 E - Epilogue start
324 e - Epilogue end
325 j - long Jump/ sjlj unwind
326 a - an Arbitrary code fragment
327 t - exTra parameter saved (constant value like frame size)
328 '""' optional: "sil" == sil
329
330 function_to_profile - function's address
331 cycle_corrector - a value which should be added to the cycle
332 counter, zero if omitted
333 extra - some extra parameter, zero if omitted.
334
335 For example:
336 ------------------------------
337 .global fxx
338 .type fxx,@function
339 fxx:
340 .LFrameOffset_fxx=0x08
341 .profiler "scdP", fxx ; function entry.
342 ; we also demand stack value to be displayed
343 push r11
344 push r10
345 push r9
346 push r8
347 .profiler "cdp",fxx,0, .LFrameOffset_fxx ; check stack value at this point
348 ; (this is a prologue end)
349 ; note, that spare var filled with the farme size
350 mov r15,r8
351 ....
352 .profiler cdE,fxx ; check stack
353 pop r8
354 pop r9
355 pop r10
356 pop r11
357 .profiler xcde,fxx,3 ; exit adds 3 to the cycle counter
358 ret ; cause 'ret' insn takes 3 cycles
359 -------------------------------
360
361 This profiling approach does not produce any overhead and
362 absolutely harmless.
363 So, even profiled code can be uploaded to the MCU. */
364 #define MSP430_PROFILER_FLAG_ENTRY 1 /* s */
365 #define MSP430_PROFILER_FLAG_EXIT 2 /* x */
366 #define MSP430_PROFILER_FLAG_INITSECT 4 /* i */
367 #define MSP430_PROFILER_FLAG_FINISECT 8 /* f */
368 #define MSP430_PROFILER_FLAG_LIBCALL 0x10 /* l */
369 #define MSP430_PROFILER_FLAG_STDCALL 0x20 /* c */
370 #define MSP430_PROFILER_FLAG_STACKDMD 0x40 /* d */
371 #define MSP430_PROFILER_FLAG_ISR 0x80 /* I */
372 #define MSP430_PROFILER_FLAG_PROLSTART 0x100 /* P */
373 #define MSP430_PROFILER_FLAG_PROLEND 0x200 /* p */
374 #define MSP430_PROFILER_FLAG_EPISTART 0x400 /* E */
375 #define MSP430_PROFILER_FLAG_EPIEND 0x800 /* e */
376 #define MSP430_PROFILER_FLAG_JUMP 0x1000 /* j */
377 #define MSP430_PROFILER_FLAG_FRAGMENT 0x2000 /* a */
378 #define MSP430_PROFILER_FLAG_EXTRA 0x4000 /* t */
379 #define MSP430_PROFILER_FLAG_notyet 0x8000 /* ? */
380
381 static int
382 pow2value (int y)
383 {
384 int n = 0;
385 unsigned int x;
386
387 x = y;
388
389 if (!x)
390 return 1;
391
392 for (; x; x = x >> 1)
393 if (x & 1)
394 n++;
395
396 return n == 1;
397 }
398
399 /* Parse ordinary expression. */
400
401 static char *
402 parse_exp (char * s, expressionS * op)
403 {
404 input_line_pointer = s;
405 expression (op);
406 if (op->X_op == O_absent)
407 as_bad (_("missing operand"));
408 return input_line_pointer;
409 }
410
411
412 /* Delete spaces from s: X ( r 1 2) => X(r12). */
413
414 static void
415 del_spaces (char * s)
416 {
417 while (*s)
418 {
419 if (ISSPACE (*s))
420 {
421 char *m = s + 1;
422
423 while (ISSPACE (*m) && *m)
424 m++;
425 memmove (s, m, strlen (m) + 1);
426 }
427 else
428 s++;
429 }
430 }
431
432 static inline char *
433 skip_space (char * s)
434 {
435 while (ISSPACE (*s))
436 ++s;
437 return s;
438 }
439
440 /* Extract one word from FROM and copy it to TO. Delimeters are ",;\n" */
441
442 static char *
443 extract_operand (char * from, char * to, int limit)
444 {
445 int size = 0;
446
447 /* Drop leading whitespace. */
448 from = skip_space (from);
449
450 while (size < limit && *from)
451 {
452 *(to + size) = *from;
453 if (*from == ',' || *from == ';' || *from == '\n')
454 break;
455 from++;
456 size++;
457 }
458
459 *(to + size) = 0;
460 del_spaces (to);
461
462 from++;
463
464 return from;
465 }
466
467 static void
468 msp430_profiler (int dummy ATTRIBUTE_UNUSED)
469 {
470 char buffer[1024];
471 char f[32];
472 char * str = buffer;
473 char * flags = f;
474 int p_flags = 0;
475 char * halt;
476 int ops = 0;
477 int left;
478 char * s;
479 segT seg;
480 int subseg;
481 char * end = 0;
482 expressionS exp;
483 expressionS exp1;
484
485 s = input_line_pointer;
486 end = input_line_pointer;
487
488 while (*end && *end != '\n')
489 end++;
490
491 while (*s && *s != '\n')
492 {
493 if (*s == ',')
494 ops++;
495 s++;
496 }
497
498 left = 3 - ops;
499
500 if (ops < 1)
501 {
502 as_bad (_(".profiler pseudo requires at least two operands."));
503 input_line_pointer = end;
504 return;
505 }
506
507 input_line_pointer = extract_operand (input_line_pointer, flags, 32);
508
509 while (*flags)
510 {
511 switch (*flags)
512 {
513 case '"':
514 break;
515 case 'a':
516 p_flags |= MSP430_PROFILER_FLAG_FRAGMENT;
517 break;
518 case 'j':
519 p_flags |= MSP430_PROFILER_FLAG_JUMP;
520 break;
521 case 'P':
522 p_flags |= MSP430_PROFILER_FLAG_PROLSTART;
523 break;
524 case 'p':
525 p_flags |= MSP430_PROFILER_FLAG_PROLEND;
526 break;
527 case 'E':
528 p_flags |= MSP430_PROFILER_FLAG_EPISTART;
529 break;
530 case 'e':
531 p_flags |= MSP430_PROFILER_FLAG_EPIEND;
532 break;
533 case 's':
534 p_flags |= MSP430_PROFILER_FLAG_ENTRY;
535 break;
536 case 'x':
537 p_flags |= MSP430_PROFILER_FLAG_EXIT;
538 break;
539 case 'i':
540 p_flags |= MSP430_PROFILER_FLAG_INITSECT;
541 break;
542 case 'f':
543 p_flags |= MSP430_PROFILER_FLAG_FINISECT;
544 break;
545 case 'l':
546 p_flags |= MSP430_PROFILER_FLAG_LIBCALL;
547 break;
548 case 'c':
549 p_flags |= MSP430_PROFILER_FLAG_STDCALL;
550 break;
551 case 'd':
552 p_flags |= MSP430_PROFILER_FLAG_STACKDMD;
553 break;
554 case 'I':
555 p_flags |= MSP430_PROFILER_FLAG_ISR;
556 break;
557 case 't':
558 p_flags |= MSP430_PROFILER_FLAG_EXTRA;
559 break;
560 default:
561 as_warn (_("unknown profiling flag - ignored."));
562 break;
563 }
564 flags++;
565 }
566
567 if (p_flags
568 && ( ! pow2value (p_flags & ( MSP430_PROFILER_FLAG_ENTRY
569 | MSP430_PROFILER_FLAG_EXIT))
570 || ! pow2value (p_flags & ( MSP430_PROFILER_FLAG_PROLSTART
571 | MSP430_PROFILER_FLAG_PROLEND
572 | MSP430_PROFILER_FLAG_EPISTART
573 | MSP430_PROFILER_FLAG_EPIEND))
574 || ! pow2value (p_flags & ( MSP430_PROFILER_FLAG_INITSECT
575 | MSP430_PROFILER_FLAG_FINISECT))))
576 {
577 as_bad (_("ambigious flags combination - '.profiler' directive ignored."));
578 input_line_pointer = end;
579 return;
580 }
581
582 /* Generate temp symbol which denotes current location. */
583 if (now_seg == absolute_section) /* Paranoja ? */
584 {
585 exp1.X_op = O_constant;
586 exp1.X_add_number = abs_section_offset;
587 as_warn (_("profiling in absolute section? Hm..."));
588 }
589 else
590 {
591 exp1.X_op = O_symbol;
592 exp1.X_add_symbol = symbol_temp_new_now ();
593 exp1.X_add_number = 0;
594 }
595
596 /* Generate a symbol which holds flags value. */
597 exp.X_op = O_constant;
598 exp.X_add_number = p_flags;
599
600 /* Save current section. */
601 seg = now_seg;
602 subseg = now_subseg;
603
604 /* Now go to .profiler section. */
605 obj_elf_change_section (".profiler", SHT_PROGBITS, 0, 0, 0, 0, 0);
606
607 /* Save flags. */
608 emit_expr (& exp, 2);
609
610 /* Save label value. */
611 emit_expr (& exp1, 2);
612
613 while (ops--)
614 {
615 /* Now get profiling info. */
616 halt = extract_operand (input_line_pointer, str, 1024);
617 /* Process like ".word xxx" directive. */
618 parse_exp (str, & exp);
619 emit_expr (& exp, 2);
620 input_line_pointer = halt;
621 }
622
623 /* Fill the rest with zeros. */
624 exp.X_op = O_constant;
625 exp.X_add_number = 0;
626 while (left--)
627 emit_expr (& exp, 2);
628
629 /* Return to current section. */
630 subseg_set (seg, subseg);
631 }
632
633 static char *
634 extract_word (char * from, char * to, int limit)
635 {
636 char *op_start;
637 char *op_end;
638 int size = 0;
639
640 /* Drop leading whitespace. */
641 from = skip_space (from);
642 *to = 0;
643
644 /* Find the op code end. */
645 for (op_start = op_end = from; *op_end != 0 && is_part_of_name (*op_end);)
646 {
647 to[size++] = *op_end++;
648 if (size + 1 >= limit)
649 break;
650 }
651
652 to[size] = 0;
653 return op_end;
654 }
655
656 #define OPTION_MMCU 'm'
657
658 static void
659 msp430_set_arch (int dummy ATTRIBUTE_UNUSED)
660 {
661 char *str = (char *) alloca (32); /* 32 for good measure. */
662
663 input_line_pointer = extract_word (input_line_pointer, str, 32);
664
665 md_parse_option (OPTION_MMCU, str);
666 bfd_set_arch_mach (stdoutput, TARGET_ARCH, msp430_mcu->mach);
667 }
668
669 static void
670 show_mcu_list (FILE * stream)
671 {
672 int i;
673
674 fprintf (stream, _("Known MCU names:\n"));
675
676 for (i = 0; mcu_types[i].name; i++)
677 fprintf (stream, _("\t %s\n"), mcu_types[i].name);
678
679 fprintf (stream, "\n");
680 }
681
682 int
683 md_parse_option (int c, char * arg)
684 {
685 int i;
686
687 switch (c)
688 {
689 case OPTION_MMCU:
690 for (i = 0; mcu_types[i].name; ++i)
691 if (strcmp (mcu_types[i].name, arg) == 0)
692 break;
693
694 if (!mcu_types[i].name)
695 {
696 show_mcu_list (stderr);
697 as_fatal (_("unknown MCU: %s\n"), arg);
698 }
699
700 if (msp430_mcu == &default_mcu || msp430_mcu->mach == mcu_types[i].mach)
701 msp430_mcu = &mcu_types[i];
702 else
703 as_fatal (_("redefinition of mcu type %s' to %s'"),
704 msp430_mcu->name, mcu_types[i].name);
705 return 1;
706 }
707
708 return 0;
709 }
710
711
712 const pseudo_typeS md_pseudo_table[] =
713 {
714 {"arch", msp430_set_arch, 0},
715 {"profiler", msp430_profiler, 0},
716 {NULL, NULL, 0}
717 };
718
719 const char *md_shortopts = "m:";
720
721 struct option md_longopts[] =
722 {
723 {"mmcu", required_argument, NULL, OPTION_MMCU},
724 {NULL, no_argument, NULL, 0}
725 };
726
727 size_t md_longopts_size = sizeof (md_longopts);
728
729 void
730 md_show_usage (FILE * stream)
731 {
732 fprintf (stream,
733 _("MSP430 options:\n"
734 " -mmcu=[msp430-name] select microcontroller type\n"
735 " msp430x110 msp430x112\n"
736 " msp430x1101 msp430x1111\n"
737 " msp430x1121 msp430x1122 msp430x1132\n"
738 " msp430x122 msp430x123\n"
739 " msp430x1222 msp430x1232\n"
740 " msp430x133 msp430x135\n"
741 " msp430x1331 msp430x1351\n"
742 " msp430x147 msp430x148 msp430x149\n"
743 " msp430x155 msp430x156 msp430x157\n"
744 " msp430x167 msp430x168 msp430x169\n"
745 " msp430x1610 msp430x1611 msp430x1612\n"
746 " msp430x311 msp430x312 msp430x313 msp430x314 msp430x315\n"
747 " msp430x323 msp430x325\n"
748 " msp430x336 msp430x337\n"
749 " msp430x412 msp430x413 msp430x415 msp430x417\n"
750 " msp430xE423 msp430xE425 msp430E427\n"
751 " msp430xW423 msp430xW425 msp430W427\n"
752 " msp430xG437 msp430xG438 msp430G439\n"
753 " msp430x435 msp430x436 msp430x437\n"
754 " msp430x447 msp430x448 msp430x449\n"));
755
756 show_mcu_list (stream);
757 }
758
759 symbolS *
760 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
761 {
762 return 0;
763 }
764
765 static char *
766 extract_cmd (char * from, char * to, int limit)
767 {
768 int size = 0;
769
770 while (*from && ! ISSPACE (*from) && *from != '.' && limit > size)
771 {
772 *(to + size) = *from;
773 from++;
774 size++;
775 }
776
777 *(to + size) = 0;
778
779 return from;
780 }
781
782 /* Turn a string in input_line_pointer into a floating point constant
783 of type TYPE, and store the appropriate bytes in *LITP. The number
784 of LITTLENUMS emitted is stored in *SIZEP. An error message is
785 returned, or NULL on OK. */
786
787 char *
788 md_atof (int type, char * litP, int * sizeP)
789 {
790 int prec;
791 LITTLENUM_TYPE words[4];
792 LITTLENUM_TYPE *wordP;
793 char *t;
794
795 switch (type)
796 {
797 case 'f':
798 prec = 2;
799 break;
800 case 'd':
801 prec = 4;
802 break;
803 default:
804 *sizeP = 0;
805 return _("bad call to md_atof");
806 }
807
808 t = atof_ieee (input_line_pointer, type, words);
809 if (t)
810 input_line_pointer = t;
811
812 *sizeP = prec * sizeof (LITTLENUM_TYPE);
813
814 /* This loop outputs the LITTLENUMs in REVERSE order. */
815 for (wordP = words + prec - 1; prec--;)
816 {
817 md_number_to_chars (litP, (valueT) (*wordP--), sizeof (LITTLENUM_TYPE));
818 litP += sizeof (LITTLENUM_TYPE);
819 }
820
821 return NULL;
822 }
823
824 void
825 md_begin (void)
826 {
827 struct msp430_opcode_s * opcode;
828 msp430_hash = hash_new ();
829
830 for (opcode = msp430_opcodes; opcode->name; opcode++)
831 hash_insert (msp430_hash, opcode->name, (char *) opcode);
832
833 bfd_set_arch_mach (stdoutput, TARGET_ARCH, msp430_mcu->mach);
834 }
835
836 static int
837 check_reg (char * t)
838 {
839 /* If this is a reg numb, str 't' must be a number from 0 - 15. */
840
841 if (strlen (t) > 2 && *(t + 2) != '+')
842 return 1;
843
844 while (*t)
845 {
846 if ((*t < '0' || *t > '9') && *t != '+')
847 break;
848 t++;
849 }
850
851 if (*t)
852 return 1;
853
854 return 0;
855 }
856
857
858 static int
859 msp430_srcoperand (struct msp430_operand_s * op,
860 char * l, int bin, int * imm_op)
861 {
862 char *__tl = l;
863
864 /* Check if an immediate #VALUE. The hash sign should be only at the beginning! */
865 if (*l == '#')
866 {
867 char *h = l;
868 int vshift = -1;
869 int rval = 0;
870
871 /* Check if there is:
872 llo(x) - least significant 16 bits, x &= 0xffff
873 lhi(x) - x = (x >> 16) & 0xffff,
874 hlo(x) - x = (x >> 32) & 0xffff,
875 hhi(x) - x = (x >> 48) & 0xffff
876 The value _MUST_ be constant expression: #hlo(1231231231). */
877
878 *imm_op = 1;
879
880 if (strncasecmp (h, "#llo(", 5) == 0)
881 {
882 vshift = 0;
883 rval = 3;
884 }
885 else if (strncasecmp (h, "#lhi(", 5) == 0)
886 {
887 vshift = 1;
888 rval = 3;
889 }
890 else if (strncasecmp (h, "#hlo(", 5) == 0)
891 {
892 vshift = 2;
893 rval = 3;
894 }
895 else if (strncasecmp (h, "#hhi(", 5) == 0)
896 {
897 vshift = 3;
898 rval = 3;
899 }
900 else if (strncasecmp (h, "#lo(", 4) == 0)
901 {
902 vshift = 0;
903 rval = 2;
904 }
905 else if (strncasecmp (h, "#hi(", 4) == 0)
906 {
907 vshift = 1;
908 rval = 2;
909 }
910
911 op->reg = 0; /* Reg PC. */
912 op->am = 3;
913 op->ol = 1; /* Immediate will follow an instruction. */
914 __tl = h + 1 + rval;
915 op->mode = OP_EXP;
916
917 parse_exp (__tl, &(op->exp));
918 if (op->exp.X_op == O_constant)
919 {
920 int x = op->exp.X_add_number;
921
922 if (vshift == 0)
923 {
924 x = x & 0xffff;
925 op->exp.X_add_number = x;
926 }
927 else if (vshift == 1)
928 {
929 x = (x >> 16) & 0xffff;
930 op->exp.X_add_number = x;
931 }
932 else if (vshift > 1)
933 {
934 if (x < 0)
935 op->exp.X_add_number = -1;
936 else
937 op->exp.X_add_number = 0; /* Nothing left. */
938 x = op->exp.X_add_number;
939 }
940
941 if (op->exp.X_add_number > 65535 || op->exp.X_add_number < -32768)
942 {
943 as_bad (_("value %d out of range. Use #lo() or #hi()"), x);
944 return 1;
945 }
946
947 /* Now check constants. */
948 /* Substitute register mode with a constant generator if applicable. */
949
950 x = (short) x; /* Extend sign. */
951
952 if (x == 0)
953 {
954 op->reg = 3;
955 op->am = 0;
956 op->ol = 0;
957 op->mode = OP_REG;
958 }
959 else if (x == 1)
960 {
961 op->reg = 3;
962 op->am = 1;
963 op->ol = 0;
964 op->mode = OP_REG;
965 }
966 else if (x == 2)
967 {
968 op->reg = 3;
969 op->am = 2;
970 op->ol = 0;
971 op->mode = OP_REG;
972 }
973 else if (x == -1)
974 {
975 op->reg = 3;
976 op->am = 3;
977 op->ol = 0;
978 op->mode = OP_REG;
979 }
980 else if (x == 4)
981 {
982 #ifdef PUSH_1X_WORKAROUND
983 if (bin == 0x1200)
984 {
985 /* Remove warning as confusing.
986 as_warn(_("Hardware push bug workaround")); */
987 }
988 else
989 #endif
990 {
991 op->reg = 2;
992 op->am = 2;
993 op->ol = 0;
994 op->mode = OP_REG;
995 }
996 }
997 else if (x == 8)
998 {
999 #ifdef PUSH_1X_WORKAROUND
1000 if (bin == 0x1200)
1001 {
1002 /* Remove warning as confusing.
1003 as_warn(_("Hardware push bug workaround")); */
1004 }
1005 else
1006 #endif
1007 {
1008 op->reg = 2;
1009 op->am = 3;
1010 op->ol = 0;
1011 op->mode = OP_REG;
1012 }
1013 }
1014 }
1015 else if (op->exp.X_op == O_symbol)
1016 {
1017 op->mode = OP_EXP;
1018 }
1019 else if (op->exp.X_op == O_big)
1020 {
1021 short x;
1022 if (vshift != -1)
1023 {
1024 op->exp.X_op = O_constant;
1025 op->exp.X_add_number = 0xffff & generic_bignum[vshift];
1026 x = op->exp.X_add_number;
1027 }
1028 else
1029 {
1030 as_bad (_
1031 ("unknown expression in operand %s. use #llo() #lhi() #hlo() #hhi() "),
1032 l);
1033 return 1;
1034 }
1035
1036 if (x == 0)
1037 {
1038 op->reg = 3;
1039 op->am = 0;
1040 op->ol = 0;
1041 op->mode = OP_REG;
1042 }
1043 else if (x == 1)
1044 {
1045 op->reg = 3;
1046 op->am = 1;
1047 op->ol = 0;
1048 op->mode = OP_REG;
1049 }
1050 else if (x == 2)
1051 {
1052 op->reg = 3;
1053 op->am = 2;
1054 op->ol = 0;
1055 op->mode = OP_REG;
1056 }
1057 else if (x == -1)
1058 {
1059 op->reg = 3;
1060 op->am = 3;
1061 op->ol = 0;
1062 op->mode = OP_REG;
1063 }
1064 else if (x == 4)
1065 {
1066 op->reg = 2;
1067 op->am = 2;
1068 op->ol = 0;
1069 op->mode = OP_REG;
1070 }
1071 else if (x == 8)
1072 {
1073 op->reg = 2;
1074 op->am = 3;
1075 op->ol = 0;
1076 op->mode = OP_REG;
1077 }
1078 }
1079 /* Redudant (yet) check. */
1080 else if (op->exp.X_op == O_register)
1081 as_bad
1082 (_("Registers cannot be used within immediate expression [%s]"), l);
1083 else
1084 as_bad (_("unknown operand %s"), l);
1085
1086 return 0;
1087 }
1088
1089 /* Check if absolute &VALUE (assume that we can construct something like ((a&b)<<7 + 25). */
1090 if (*l == '&')
1091 {
1092 char *h = l;
1093
1094 op->reg = 2; /* reg 2 in absolute addr mode. */
1095 op->am = 1; /* mode As == 01 bin. */
1096 op->ol = 1; /* Immediate value followed by instruction. */
1097 __tl = h + 1;
1098 parse_exp (__tl, &(op->exp));
1099 op->mode = OP_EXP;
1100 if (op->exp.X_op == O_constant)
1101 {
1102 int x = op->exp.X_add_number;
1103
1104 if (x > 65535 || x < -32768)
1105 {
1106 as_bad (_("value out of range: %d"), x);
1107 return 1;
1108 }
1109 }
1110 else if (op->exp.X_op == O_symbol)
1111 ;
1112 else
1113 {
1114 /* Redudant (yet) check. */
1115 if (op->exp.X_op == O_register)
1116 as_bad
1117 (_("Registers cannot be used within absolute expression [%s]"), l);
1118 else
1119 as_bad (_("unknown expression in operand %s"), l);
1120 return 1;
1121 }
1122 return 0;
1123 }
1124
1125 /* Check if indirect register mode @Rn / postincrement @Rn+. */
1126 if (*l == '@')
1127 {
1128 char *t = l;
1129 char *m = strchr (l, '+');
1130
1131 if (t != l)
1132 {
1133 as_bad (_("unknown addressing mode %s"), l);
1134 return 1;
1135 }
1136
1137 t++;
1138 if (*t != 'r' && *t != 'R')
1139 {
1140 as_bad (_("unknown addressing mode %s"), l);
1141 return 1;
1142 }
1143
1144 t++; /* Points to the reg value. */
1145
1146 if (check_reg (t))
1147 {
1148 as_bad (_("Bad register name r%s"), t);
1149 return 1;
1150 }
1151
1152 op->mode = OP_REG;
1153 op->am = m ? 3 : 2;
1154 op->ol = 0;
1155 if (m)
1156 *m = 0; /* strip '+' */
1157 op->reg = atoi (t);
1158 if (op->reg < 0 || op->reg > 15)
1159 {
1160 as_bad (_("MSP430 does not have %d registers"), op->reg);
1161 return 1;
1162 }
1163
1164 return 0;
1165 }
1166
1167 /* Check if register indexed X(Rn). */
1168 do
1169 {
1170 char *h = strrchr (l, '(');
1171 char *m = strrchr (l, ')');
1172 char *t;
1173
1174 *imm_op = 1;
1175
1176 if (!h)
1177 break;
1178 if (!m)
1179 {
1180 as_bad (_("')' required"));
1181 return 1;
1182 }
1183
1184 t = h;
1185 op->am = 1;
1186 op->ol = 1;
1187 /* Extract a register. */
1188 t++; /* Advance pointer. */
1189
1190 if (*t != 'r' && *t != 'R')
1191 {
1192 as_bad (_
1193 ("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"),
1194 l);
1195 return 1;
1196 }
1197 t++;
1198
1199 op->reg = *t - '0';
1200 if (op->reg > 9 || op->reg < 0)
1201 {
1202 as_bad (_("unknown operator (r%s substituded as a register name"),
1203 t);
1204 return 1;
1205 }
1206 t++;
1207 if (*t != ')')
1208 {
1209 op->reg = op->reg * 10;
1210 op->reg += *t - '0';
1211
1212 if (op->reg > 15)
1213 {
1214 as_bad (_("unknown operator %s"), l);
1215 return 1;
1216 }
1217 if (op->reg == 2)
1218 {
1219 as_bad (_("r2 should not be used in indexed addressing mode"));
1220 return 1;
1221 }
1222
1223 if (*(t + 1) != ')')
1224 {
1225 as_bad (_("unknown operator %s"), l);
1226 return 1;
1227 }
1228 }
1229
1230 /* Extract constant. */
1231 __tl = l;
1232 *h = 0;
1233 op->mode = OP_EXP;
1234 parse_exp (__tl, &(op->exp));
1235 if (op->exp.X_op == O_constant)
1236 {
1237 int x = op->exp.X_add_number;
1238
1239 if (x > 65535 || x < -32768)
1240 {
1241 as_bad (_("value out of range: %d"), x);
1242 return 1;
1243 }
1244
1245 if (x == 0)
1246 {
1247 op->mode = OP_REG;
1248 op->am = 2;
1249 op->ol = 0;
1250 return 0;
1251 }
1252 }
1253 else if (op->exp.X_op == O_symbol)
1254 ;
1255 else
1256 {
1257 /* Redudant (yet) check. */
1258 if (op->exp.X_op == O_register)
1259 as_bad
1260 (_("Registers cannot be used as a prefix of indexed expression [%s]"), l);
1261 else
1262 as_bad (_("unknown expression in operand %s"), l);
1263 return 1;
1264 }
1265
1266 return 0;
1267 }
1268 while (0);
1269
1270 /* Register mode 'mov r1,r2'. */
1271 do
1272 {
1273 char *t = l;
1274
1275 /* Operand should be a register. */
1276 if (*t == 'r' || *t == 'R')
1277 {
1278 int x = atoi (t + 1);
1279
1280 if (check_reg (t + 1))
1281 break;
1282
1283 if (x < 0 || x > 15)
1284 break; /* Symbolic mode. */
1285
1286 op->mode = OP_REG;
1287 op->am = 0;
1288 op->ol = 0;
1289 op->reg = x;
1290 return 0;
1291 }
1292 }
1293 while (0);
1294
1295 /* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'. */
1296 do
1297 {
1298 #if 0 /* Allow expression in operand like 'a+123*(1|2)'. */
1299 char *t = l;
1300
1301 __tl = l;
1302
1303 while (*t)
1304 {
1305 /* alpha/number underline dot for labels. */
1306 if (! ISALNUM (*t) && *t != '_' && *t != '.')
1307 {
1308 as_bad (_("unknown operand %s"), l);
1309 return 1;
1310 }
1311 t++;
1312 }
1313 #endif
1314 op->mode = OP_EXP;
1315 op->reg = 0; /* PC relative... be careful. */
1316 op->am = 1;
1317 op->ol = 1;
1318 __tl = l;
1319 parse_exp (__tl, &(op->exp));
1320 return 0;
1321 }
1322 while (0);
1323
1324 /* Unreachable. */
1325 as_bad (_("unknown addressing mode for operand %s"), l);
1326 return 1;
1327 }
1328
1329
1330 static int
1331 msp430_dstoperand (struct msp430_operand_s * op, char * l, int bin)
1332 {
1333 int dummy;
1334 int ret = msp430_srcoperand (op, l, bin, & dummy);
1335
1336 if (ret)
1337 return ret;
1338
1339 if (op->am == 2)
1340 {
1341 char *__tl = "0";
1342
1343 op->mode = OP_EXP;
1344 op->am = 1;
1345 op->ol = 1;
1346 parse_exp (__tl, &(op->exp));
1347
1348 if (op->exp.X_op != O_constant || op->exp.X_add_number != 0)
1349 {
1350 as_bad (_("Internal bug. Try to use 0(r%d) instead of @r%d"),
1351 op->reg, op->reg);
1352 return 1;
1353 }
1354 return 0;
1355 }
1356
1357 if (op->am > 1)
1358 {
1359 as_bad (_
1360 ("this addressing mode is not applicable for destination operand"));
1361 return 1;
1362 }
1363 return 0;
1364 }
1365
1366
1367 /* Parse instruction operands.
1368 Return binary opcode. */
1369
1370 static unsigned int
1371 msp430_operands (struct msp430_opcode_s * opcode, char * line)
1372 {
1373 int bin = opcode->bin_opcode; /* Opcode mask. */
1374 int __is;
1375 char l1[MAX_OP_LEN], l2[MAX_OP_LEN];
1376 char *frag;
1377 int where;
1378 struct msp430_operand_s op1, op2;
1379 int res = 0;
1380 static short ZEROS = 0;
1381 int byte_op, imm_op;
1382
1383 /* Opcode is the one from opcodes table
1384 line contains something like
1385 [.w] @r2+, 5(R1)
1386 or
1387 .b @r2+, 5(R1). */
1388
1389 /* Check if byte or word operation. */
1390 if (*line == '.' && TOLOWER (*(line + 1)) == 'b')
1391 {
1392 bin |= BYTE_OPERATION;
1393 byte_op = 1;
1394 }
1395 else
1396 byte_op = 0;
1397
1398 /* skip .[bwBW]. */
1399 while (! ISSPACE (*line) && *line)
1400 line++;
1401
1402 if (opcode->insn_opnumb && (!*line || *line == '\n'))
1403 {
1404 as_bad (_("instruction %s requires %d operand(s)"),
1405 opcode->name, opcode->insn_opnumb);
1406 return 0;
1407 }
1408
1409 memset (l1, 0, sizeof (l1));
1410 memset (l2, 0, sizeof (l2));
1411 memset (&op1, 0, sizeof (op1));
1412 memset (&op2, 0, sizeof (op2));
1413
1414 imm_op = 0;
1415
1416 switch (opcode->fmt)
1417 {
1418 case 0: /* Emulated. */
1419 switch (opcode->insn_opnumb)
1420 {
1421 case 0:
1422 /* Set/clear bits instructions. */
1423 __is = 2;
1424 frag = frag_more (__is);
1425 bfd_putl16 ((bfd_vma) bin, frag);
1426 break;
1427 case 1:
1428 /* Something which works with destination operand. */
1429 line = extract_operand (line, l1, sizeof (l1));
1430 res = msp430_dstoperand (&op1, l1, opcode->bin_opcode);
1431 if (res)
1432 break;
1433
1434 bin |= (op1.reg | (op1.am << 7));
1435 __is = 1 + op1.ol;
1436 frag = frag_more (2 * __is);
1437 where = frag - frag_now->fr_literal;
1438 bfd_putl16 ((bfd_vma) bin, frag);
1439
1440 if (op1.mode == OP_EXP)
1441 {
1442 where += 2;
1443 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1444
1445 if (op1.reg)
1446 fix_new_exp (frag_now, where, 2,
1447 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
1448 else
1449 fix_new_exp (frag_now, where, 2,
1450 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
1451 }
1452 break;
1453
1454 case 2:
1455 {
1456 /* Shift instruction. */
1457 line = extract_operand (line, l1, sizeof (l1));
1458 strncpy (l2, l1, sizeof (l2));
1459 l2[sizeof (l2) - 1] = '\0';
1460 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op);
1461 res += msp430_dstoperand (&op2, l2, opcode->bin_opcode);
1462
1463 if (res)
1464 break; /* An error occurred. All warnings were done before. */
1465
1466 bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
1467
1468 __is = 1 + op1.ol + op2.ol; /* insn size in words. */
1469 frag = frag_more (2 * __is);
1470 where = frag - frag_now->fr_literal;
1471 bfd_putl16 ((bfd_vma) bin, frag);
1472
1473 if (op1.mode == OP_EXP)
1474 {
1475 where += 2; /* Advance 'where' as we do not know _where_. */
1476 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1477
1478 if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
1479 fix_new_exp (frag_now, where, 2,
1480 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
1481 else
1482 fix_new_exp (frag_now, where, 2,
1483 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
1484 }
1485
1486 if (op2.mode == OP_EXP)
1487 {
1488 imm_op = 0;
1489 bfd_putl16 ((bfd_vma) ZEROS, frag + 2 + ((__is == 3) ? 2 : 0));
1490
1491 if (op2.reg) /* Not PC relative. */
1492 fix_new_exp (frag_now, where + 2, 2,
1493 &(op2.exp), FALSE, CHECK_RELOC_MSP430);
1494 else
1495 fix_new_exp (frag_now, where + 2, 2,
1496 &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
1497 }
1498 break;
1499 }
1500 case 3:
1501 /* Branch instruction => mov dst, r0. */
1502 line = extract_operand (line, l1, sizeof (l1));
1503
1504 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op);
1505 if (res)
1506 break;
1507
1508 byte_op = 0;
1509 imm_op = 0;
1510
1511 bin |= ((op1.reg << 8) | (op1.am << 4));
1512 __is = 1 + op1.ol;
1513 frag = frag_more (2 * __is);
1514 where = frag - frag_now->fr_literal;
1515 bfd_putl16 ((bfd_vma) bin, frag);
1516
1517 if (op1.mode == OP_EXP)
1518 {
1519 where += 2;
1520 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1521
1522 if (op1.reg || (op1.reg == 0 && op1.am == 3))
1523 fix_new_exp (frag_now, where, 2,
1524 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
1525 else
1526 fix_new_exp (frag_now, where, 2,
1527 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
1528 }
1529 break;
1530 }
1531 break;
1532
1533 case 1: /* Format 1, double operand. */
1534 line = extract_operand (line, l1, sizeof (l1));
1535 line = extract_operand (line, l2, sizeof (l2));
1536 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op);
1537 res += msp430_dstoperand (&op2, l2, opcode->bin_opcode);
1538
1539 if (res)
1540 break; /* Error occurred. All warnings were done before. */
1541
1542 bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
1543
1544 __is = 1 + op1.ol + op2.ol; /* insn size in words. */
1545 frag = frag_more (2 * __is);
1546 where = frag - frag_now->fr_literal;
1547 bfd_putl16 ((bfd_vma) bin, frag);
1548
1549 if (op1.mode == OP_EXP)
1550 {
1551 where += 2; /* Advance where as we do not know _where_. */
1552 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1553
1554 if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
1555 fix_new_exp (frag_now, where, 2,
1556 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
1557 else
1558 fix_new_exp (frag_now, where, 2,
1559 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
1560 }
1561
1562 if (op2.mode == OP_EXP)
1563 {
1564 imm_op = 0;
1565 bfd_putl16 ((bfd_vma) ZEROS, frag + 2 + ((__is == 3) ? 2 : 0));
1566
1567 if (op2.reg) /* Not PC relative. */
1568 fix_new_exp (frag_now, where + 2, 2,
1569 &(op2.exp), FALSE, CHECK_RELOC_MSP430);
1570 else
1571 fix_new_exp (frag_now, where + 2, 2,
1572 &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
1573 }
1574 break;
1575
1576 case 2: /* Single-operand mostly instr. */
1577 if (opcode->insn_opnumb == 0)
1578 {
1579 /* reti instruction. */
1580 frag = frag_more (2);
1581 bfd_putl16 ((bfd_vma) bin, frag);
1582 break;
1583 }
1584
1585 line = extract_operand (line, l1, sizeof (l1));
1586 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op);
1587 if (res)
1588 break; /* Error in operand. */
1589
1590 bin |= op1.reg | (op1.am << 4);
1591 __is = 1 + op1.ol;
1592 frag = frag_more (2 * __is);
1593 where = frag - frag_now->fr_literal;
1594 bfd_putl16 ((bfd_vma) bin, frag);
1595
1596 if (op1.mode == OP_EXP)
1597 {
1598 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1599
1600 if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
1601 fix_new_exp (frag_now, where + 2, 2,
1602 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
1603 else
1604 fix_new_exp (frag_now, where + 2, 2,
1605 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
1606 }
1607 break;
1608
1609 case 3: /* Conditional jumps instructions. */
1610 line = extract_operand (line, l1, sizeof (l1));
1611 /* l1 is a label. */
1612 if (l1[0])
1613 {
1614 char *m = l1;
1615 expressionS exp;
1616
1617 if (*m == '$')
1618 m++;
1619
1620 parse_exp (m, &exp);
1621 frag = frag_more (2); /* Instr size is 1 word. */
1622
1623 /* In order to handle something like:
1624
1625 and #0x8000, r5
1626 tst r5
1627 jz 4 ; skip next 4 bytes
1628 inv r5
1629 inc r5
1630 nop ; will jump here if r5 positive or zero
1631
1632 jCOND -n ;assumes jump n bytes backward:
1633
1634 mov r5,r6
1635 jmp -2
1636
1637 is equal to:
1638 lab:
1639 mov r5,r6
1640 jmp lab
1641
1642 jCOND $n ; jump from PC in either direction. */
1643
1644 if (exp.X_op == O_constant)
1645 {
1646 int x = exp.X_add_number;
1647
1648 if (x & 1)
1649 {
1650 as_warn (_("Even number required. Rounded to %d"), x + 1);
1651 x++;
1652 }
1653
1654 if ((*l1 == '$' && x > 0) || x < 0)
1655 x -= 2;
1656
1657 x >>= 1;
1658
1659 if (x > 512 || x < -511)
1660 {
1661 as_bad (_("Wrong displacement %d"), x << 1);
1662 break;
1663 }
1664
1665 bin |= x & 0x3ff;
1666 bfd_putl16 ((bfd_vma) bin, frag);
1667 }
1668 else if (exp.X_op == O_symbol && *l1 != '$')
1669 {
1670 where = frag - frag_now->fr_literal;
1671 fix_new_exp (frag_now, where, 2,
1672 &exp, TRUE, BFD_RELOC_MSP430_10_PCREL);
1673
1674 bfd_putl16 ((bfd_vma) bin, frag);
1675 }
1676 else if (*l1 == '$')
1677 {
1678 as_bad (_("instruction requires label sans '$'"));
1679 break;
1680 }
1681 else
1682 {
1683 as_bad (_
1684 ("instruction requires label or value in range -511:512"));
1685 break;
1686 }
1687 }
1688 else
1689 {
1690 as_bad (_("instruction requires label"));
1691 break;
1692 }
1693 break;
1694
1695 case 4: /* Extended jumps. */
1696 line = extract_operand (line, l1, sizeof (l1));
1697 if (l1[0])
1698 {
1699 char *m = l1;
1700 expressionS exp;
1701
1702 /* Ignore absolute addressing. make it PC relative anyway. */
1703 if (*m == '#' || *m == '$')
1704 m++;
1705
1706 parse_exp (m, & exp);
1707 if (exp.X_op == O_symbol)
1708 {
1709 /* Relaxation required. */
1710 struct rcodes_s rc = msp430_rcodes[opcode->insn_opnumb];
1711
1712 frag = frag_more (8);
1713 bfd_putl16 ((bfd_vma) rc.sop, frag);
1714 frag = frag_variant (rs_machine_dependent, 8, 2,
1715 ENCODE_RELAX (rc.lpos, STATE_BITS10), /* Wild guess. */
1716 exp.X_add_symbol,
1717 0, /* Offset is zero if jump dist less than 1K. */
1718 (char *) frag);
1719 break;
1720 }
1721 }
1722
1723 as_bad (_("instruction requires label"));
1724 break;
1725
1726 case 5: /* Emulated extended branches. */
1727 line = extract_operand (line, l1, sizeof (l1));
1728 if (l1[0])
1729 {
1730 char * m = l1;
1731 expressionS exp;
1732
1733 /* Ignore absolute addressing. make it PC relative anyway. */
1734 if (*m == '#' || *m == '$')
1735 m++;
1736
1737 parse_exp (m, & exp);
1738 if (exp.X_op == O_symbol)
1739 {
1740 /* Relaxation required. */
1741 struct hcodes_s hc = msp430_hcodes[opcode->insn_opnumb];
1742
1743 frag = frag_more (8);
1744 bfd_putl16 ((bfd_vma) hc.op0, frag);
1745 bfd_putl16 ((bfd_vma) hc.op1, frag+2);
1746 frag = frag_variant (rs_machine_dependent, 8, 2,
1747 ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_BITS10), /* Wild guess. */
1748 exp.X_add_symbol,
1749 0, /* Offset is zero if jump dist less than 1K. */
1750 (char *) frag);
1751 break;
1752 }
1753 }
1754
1755 as_bad (_("instruction requires label"));
1756 break;
1757
1758 default:
1759 as_bad (_("Ilegal instruction or not implmented opcode."));
1760 }
1761
1762 input_line_pointer = line;
1763 return 0;
1764 }
1765
1766 void
1767 md_assemble (char * str)
1768 {
1769 struct msp430_opcode_s * opcode;
1770 char cmd[32];
1771 unsigned int i = 0;
1772
1773 str = skip_space (str); /* Skip leading spaces. */
1774 str = extract_cmd (str, cmd, sizeof (cmd));
1775
1776 while (cmd[i] && i < sizeof (cmd))
1777 {
1778 char a = TOLOWER (cmd[i]);
1779 cmd[i] = a;
1780 i++;
1781 }
1782
1783 if (!cmd[0])
1784 {
1785 as_bad (_("can't find opcode "));
1786 return;
1787 }
1788
1789 opcode = (struct msp430_opcode_s *) hash_find (msp430_hash, cmd);
1790
1791 if (opcode == NULL)
1792 {
1793 as_bad (_("unknown opcode `%s'"), cmd);
1794 return;
1795 }
1796
1797 {
1798 char *__t = input_line_pointer;
1799
1800 msp430_operands (opcode, str);
1801 input_line_pointer = __t;
1802 }
1803 }
1804
1805 /* GAS will call this function for each section at the end of the assembly,
1806 to permit the CPU backend to adjust the alignment of a section. */
1807
1808 valueT
1809 md_section_align (asection * seg, valueT addr)
1810 {
1811 int align = bfd_get_section_alignment (stdoutput, seg);
1812
1813 return ((addr + (1 << align) - 1) & (-1 << align));
1814 }
1815
1816 /* If you define this macro, it should return the offset between the
1817 address of a PC relative fixup and the position from which the PC
1818 relative adjustment should be made. On many processors, the base
1819 of a PC relative instruction is the next instruction, so this
1820 macro would return the length of an instruction. */
1821
1822 long
1823 md_pcrel_from_section (fixS * fixp, segT sec)
1824 {
1825 if (fixp->fx_addsy != (symbolS *) NULL
1826 && (!S_IS_DEFINED (fixp->fx_addsy)
1827 || (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
1828 return 0;
1829
1830 return fixp->fx_frag->fr_address + fixp->fx_where;
1831 }
1832
1833 /* GAS will call this for each fixup. It should store the correct
1834 value in the object file. */
1835
1836 void
1837 md_apply_fix3 (fixS * fixp, valueT * valuep, segT seg)
1838 {
1839 unsigned char * where;
1840 unsigned long insn;
1841 long value;
1842
1843 if (fixp->fx_addsy == (symbolS *) NULL)
1844 {
1845 value = *valuep;
1846 fixp->fx_done = 1;
1847 }
1848 else if (fixp->fx_pcrel)
1849 {
1850 segT s = S_GET_SEGMENT (fixp->fx_addsy);
1851
1852 if (fixp->fx_addsy && (s == seg || s == absolute_section))
1853 {
1854 /* FIXME: We can appear here only in case if we perform a pc
1855 relative jump to the label which is i) global, ii) locally
1856 defined or this is a jump to an absolute symbol.
1857 If this is an absolute symbol -- everything is OK.
1858 If this is a global label, we've got a symbol value defined
1859 twice:
1860 1. S_GET_VALUE (fixp->fx_addsy) will contain a symbol offset
1861 from this section start
1862 2. *valuep will contain the real offset from jump insn to the
1863 label
1864 So, the result of S_GET_VALUE (fixp->fx_addsy) + (* valuep);
1865 will be incorrect. Therefore remove s_get_value. */
1866 value = /* S_GET_VALUE (fixp->fx_addsy) + */ * valuep;
1867 fixp->fx_done = 1;
1868 }
1869 else
1870 value = *valuep;
1871 }
1872 else
1873 {
1874 value = fixp->fx_offset;
1875
1876 if (fixp->fx_subsy != (symbolS *) NULL)
1877 {
1878 if (S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
1879 {
1880 value -= S_GET_VALUE (fixp->fx_subsy);
1881 fixp->fx_done = 1;
1882 }
1883 else
1884 {
1885 /* We don't actually support subtracting a symbol. */
1886 as_bad_where (fixp->fx_file, fixp->fx_line,
1887 _("expression too complex"));
1888 }
1889 }
1890 }
1891
1892 switch (fixp->fx_r_type)
1893 {
1894 default:
1895 fixp->fx_no_overflow = 1;
1896 break;
1897 case BFD_RELOC_MSP430_10_PCREL:
1898 break;
1899 }
1900
1901 if (fixp->fx_done)
1902 {
1903 /* Fetch the instruction, insert the fully resolved operand
1904 value, and stuff the instruction back again. */
1905
1906 where = fixp->fx_frag->fr_literal + fixp->fx_where;
1907
1908 insn = bfd_getl16 (where);
1909
1910 switch (fixp->fx_r_type)
1911 {
1912 case BFD_RELOC_MSP430_10_PCREL:
1913 if (value & 1)
1914 as_bad_where (fixp->fx_file, fixp->fx_line,
1915 _("odd address operand: %ld"), value);
1916
1917 /* Jumps are in words. */
1918 value >>= 1;
1919 --value; /* Correct PC. */
1920
1921 if (value < -512 || value > 511)
1922 as_bad_where (fixp->fx_file, fixp->fx_line,
1923 _("operand out of range: %ld"), value);
1924
1925 value &= 0x3ff; /* get rid of extended sign */
1926 bfd_putl16 ((bfd_vma) (value | insn), where);
1927 break;
1928
1929 case BFD_RELOC_MSP430_RL_PCREL:
1930 case BFD_RELOC_MSP430_16_PCREL:
1931 if (value & 1)
1932 as_bad_where (fixp->fx_file, fixp->fx_line,
1933 _("odd address operand: %ld"), value);
1934
1935 /* Nothing to be corrected here. */
1936 if (value < -32768 || value > 65536)
1937 as_bad_where (fixp->fx_file, fixp->fx_line,
1938 _("operand out of range: %ld"), value);
1939
1940 value &= 0xffff; /* Get rid of extended sign. */
1941 bfd_putl16 ((bfd_vma) value, where);
1942 break;
1943
1944 case BFD_RELOC_MSP430_16_PCREL_BYTE:
1945 /* Nothing to be corrected here. */
1946 if (value < -32768 || value > 65536)
1947 as_bad_where (fixp->fx_file, fixp->fx_line,
1948 _("operand out of range: %ld"), value);
1949
1950 value &= 0xffff; /* Get rid of extended sign. */
1951 bfd_putl16 ((bfd_vma) value, where);
1952 break;
1953
1954 case BFD_RELOC_32:
1955 bfd_putl16 ((bfd_vma) value, where);
1956 break;
1957
1958 case BFD_RELOC_MSP430_16:
1959 case BFD_RELOC_16:
1960 case BFD_RELOC_MSP430_16_BYTE:
1961 value &= 0xffff;
1962 bfd_putl16 ((bfd_vma) value, where);
1963 break;
1964
1965 default:
1966 as_fatal (_("line %d: unknown relocation type: 0x%x"),
1967 fixp->fx_line, fixp->fx_r_type);
1968 break;
1969 }
1970 }
1971 else
1972 {
1973 fixp->fx_addnumber = value;
1974 }
1975 }
1976
1977 /* A `BFD_ASSEMBLER' GAS will call this to generate a reloc. GAS
1978 will pass the resulting reloc to `bfd_install_relocation'. This
1979 currently works poorly, as `bfd_install_relocation' often does the
1980 wrong thing, and instances of `tc_gen_reloc' have been written to
1981 work around the problems, which in turns makes it difficult to fix
1982 `bfd_install_relocation'. */
1983
1984 /* If while processing a fixup, a reloc really needs to be created
1985 then it is done here. */
1986
1987 arelent *
1988 tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
1989 {
1990 arelent * reloc;
1991
1992 reloc = xmalloc (sizeof (arelent));
1993
1994 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
1995 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
1996
1997 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1998 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1999 if (reloc->howto == (reloc_howto_type *) NULL)
2000 {
2001 as_bad_where (fixp->fx_file, fixp->fx_line,
2002 _("reloc %d not supported by object file format"),
2003 (int) fixp->fx_r_type);
2004 return NULL;
2005 }
2006
2007 if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
2008 || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
2009 reloc->address = fixp->fx_offset;
2010
2011 reloc->addend = fixp->fx_offset;
2012
2013 return reloc;
2014 }
2015
2016 int
2017 md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
2018 asection * segment_type ATTRIBUTE_UNUSED)
2019 {
2020 if (fragP->fr_symbol && S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
2021 {
2022 /* This is a jump -> pcrel mode. Nothing to do much here.
2023 Return value == 2. */
2024 fragP->fr_subtype =
2025 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_BITS10);
2026 }
2027 else if (fragP->fr_symbol)
2028 {
2029 /* Its got a segment, but its not ours. Even if fr_symbol is in
2030 an absolute segment, we dont know a displacement until we link
2031 object files. So it will always be long. This also applies to
2032 labels in a subsegment of current. Liker may relax it to short
2033 jump later. Return value == 8. */
2034 fragP->fr_subtype =
2035 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_WORD);
2036 }
2037 else
2038 {
2039 /* We know the abs value. may be it is a jump to fixed address.
2040 Impossible in our case, cause all constants already handeled. */
2041 fragP->fr_subtype =
2042 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_UNDEF);
2043 }
2044
2045 return md_relax_table[fragP->fr_subtype].rlx_length;
2046 }
2047
2048 void
2049 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
2050 asection * sec ATTRIBUTE_UNUSED,
2051 fragS * fragP)
2052 {
2053 char * where = 0;
2054 int rela = -1;
2055 int i;
2056 struct rcodes_s * cc = NULL;
2057 struct hcodes_s * hc = NULL;
2058
2059 switch (fragP->fr_subtype)
2060 {
2061 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_BITS10):
2062 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_BITS10):
2063 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_BITS10):
2064 /* We do not have to convert anything here.
2065 Just apply a fix. */
2066 rela = BFD_RELOC_MSP430_10_PCREL;
2067 break;
2068
2069 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_WORD):
2070 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_UNDEF):
2071 /* Convert uncond branch jmp lab -> br lab. */
2072 cc = & msp430_rcodes[7];
2073 where = fragP->fr_literal + fragP->fr_fix;
2074 bfd_putl16 (cc->lop0, where);
2075 rela = BFD_RELOC_MSP430_RL_PCREL;
2076 fragP->fr_fix += 2;
2077 break;
2078
2079 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_WORD):
2080 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_UNDEF):
2081 {
2082 /* Other simple branches. */
2083 int insn = bfd_getl16 (fragP->fr_opcode);
2084
2085 insn &= 0xffff;
2086 /* Find actual instruction. */
2087 for (i = 0; i < 7 && !cc; i++)
2088 if (msp430_rcodes[i].sop == insn)
2089 cc = & msp430_rcodes[i];
2090 if (!cc || !cc->name)
2091 as_fatal (_("internal inconsistency problem in %s: insn %04lx"),
2092 __FUNCTION__, (long) insn);
2093 where = fragP->fr_literal + fragP->fr_fix;
2094 bfd_putl16 (cc->lop0, where);
2095 bfd_putl16 (cc->lop1, where + 2);
2096 rela = BFD_RELOC_MSP430_RL_PCREL;
2097 fragP->fr_fix += 4;
2098 }
2099 break;
2100
2101 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_WORD):
2102 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_UNDEF):
2103 cc = & msp430_rcodes[6];
2104 where = fragP->fr_literal + fragP->fr_fix;
2105 bfd_putl16 (cc->lop0, where);
2106 bfd_putl16 (cc->lop1, where + 2);
2107 bfd_putl16 (cc->lop2, where + 4);
2108 rela = BFD_RELOC_MSP430_RL_PCREL;
2109 fragP->fr_fix += 6;
2110 break;
2111
2112 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_BITS10):
2113 {
2114 int insn = bfd_getl16 (fragP->fr_opcode + 2);
2115
2116 insn &= 0xffff;
2117 for (i = 0; i < 4 && !hc; i++)
2118 if (msp430_hcodes[i].op1 == insn)
2119 hc = &msp430_hcodes[i];
2120 if (!hc || !hc->name)
2121 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
2122 __FUNCTION__, (long) insn);
2123 rela = BFD_RELOC_MSP430_10_PCREL;
2124 /* Apply a fix for a first label if necessary.
2125 another fix will be applied to the next word of insn anyway. */
2126 if (hc->tlab == 2)
2127 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
2128 fragP->fr_offset, TRUE, rela);
2129 fragP->fr_fix += 2;
2130 }
2131
2132 break;
2133
2134 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_WORD):
2135 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_UNDEF):
2136 {
2137 int insn = bfd_getl16 (fragP->fr_opcode + 2);
2138
2139 insn &= 0xffff;
2140 for (i = 0; i < 4 && !hc; i++)
2141 if (msp430_hcodes[i].op1 == insn)
2142 hc = & msp430_hcodes[i];
2143 if (!hc || !hc->name)
2144 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
2145 __FUNCTION__, (long) insn);
2146 rela = BFD_RELOC_MSP430_RL_PCREL;
2147 where = fragP->fr_literal + fragP->fr_fix;
2148 bfd_putl16 (hc->lop0, where);
2149 bfd_putl16 (hc->lop1, where + 2);
2150 bfd_putl16 (hc->lop2, where + 4);
2151 fragP->fr_fix += 6;
2152 }
2153 break;
2154
2155 default:
2156 as_fatal (_("internal inconsistency problem in %s: %lx"),
2157 __FUNCTION__, (long) fragP->fr_subtype);
2158 break;
2159 }
2160
2161 /* Now apply fix. */
2162 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
2163 fragP->fr_offset, TRUE, rela);
2164 /* Just fixed 2 bytes. */
2165 fragP->fr_fix += 2;
2166 }
2167
2168 /* Relax fragment. Mostly stolen from hc11 and mcore
2169 which arches I think I know. */
2170
2171 long
2172 msp430_relax_frag (segT seg ATTRIBUTE_UNUSED, fragS * fragP,
2173 long stretch ATTRIBUTE_UNUSED)
2174 {
2175 long growth;
2176 offsetT aim = 0;
2177 symbolS *symbolP;
2178 const relax_typeS *this_type;
2179 const relax_typeS *start_type;
2180 relax_substateT next_state;
2181 relax_substateT this_state;
2182 const relax_typeS *table = md_relax_table;
2183
2184 /* Nothing to be done if the frag has already max size. */
2185 if (RELAX_STATE (fragP->fr_subtype) == STATE_UNDEF
2186 || RELAX_STATE (fragP->fr_subtype) == STATE_WORD)
2187 return 0;
2188
2189 if (RELAX_STATE (fragP->fr_subtype) == STATE_BITS10)
2190 {
2191 symbolP = fragP->fr_symbol;
2192 if (symbol_resolved_p (symbolP))
2193 as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
2194 __FUNCTION__);
2195 /* We know the offset. calculate a distance. */
2196 aim = S_GET_VALUE (symbolP) - fragP->fr_address - fragP->fr_fix;
2197 }
2198
2199 this_state = fragP->fr_subtype;
2200 start_type = this_type = table + this_state;
2201
2202 if (aim < 0)
2203 {
2204 /* Look backwards. */
2205 for (next_state = this_type->rlx_more; next_state;)
2206 if (aim >= this_type->rlx_backward)
2207 next_state = 0;
2208 else
2209 {
2210 /* Grow to next state. */
2211 this_state = next_state;
2212 this_type = table + this_state;
2213 next_state = this_type->rlx_more;
2214 }
2215 }
2216 else
2217 {
2218 /* Look forwards. */
2219 for (next_state = this_type->rlx_more; next_state;)
2220 if (aim <= this_type->rlx_forward)
2221 next_state = 0;
2222 else
2223 {
2224 /* Grow to next state. */
2225 this_state = next_state;
2226 this_type = table + this_state;
2227 next_state = this_type->rlx_more;
2228 }
2229 }
2230
2231 growth = this_type->rlx_length - start_type->rlx_length;
2232 if (growth != 0)
2233 fragP->fr_subtype = this_state;
2234 return growth;
2235 }
This page took 0.073479 seconds and 3 git commands to generate.