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