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