1 /* tc-msp430.c -- Assembler code for the Texas Instruments MSP430
2 
3   Copyright (C) 2002, 2003 Free Software Foundation, Inc.
4   Contributed by Dmitry Diky <diwil@mail.ru>
5 
6   This file is part of GAS, the GNU Assembler.
7 
8   GAS is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 2, or (at your option)
11   any later version.
12 
13   GAS is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17 
18   You should have received a copy of the GNU General Public License
19   along with GAS; see the file COPYING.  If not, write to
20   the Free Software Foundation, 59 Temple Place - Suite 330,
21   Boston, MA 02111-1307, USA.  */
22 
23 #include <stdio.h>
24 #include <string.h>
25 #include <stdlib.h>
26 #include <limits.h>
27 
28 #define PUSH_1X_WORKAROUND
29 #include "as.h"
30 #include "subsegs.h"
31 #include "opcode/msp430.h"
32 #include "safe-ctype.h"
33 
34 const char comment_chars[] = ";";
35 const char line_comment_chars[] = "#";
36 const char line_separator_chars[] = "";
37 const char EXP_CHARS[] = "eE";
38 const char FLT_CHARS[] = "dD";
39 
40 /* Handle  long expressions.  */
41 extern LITTLENUM_TYPE generic_bignum[];
42 
43 static struct hash_control *msp430_hash;
44 
45 static unsigned int msp430_operands
46   PARAMS ((struct msp430_opcode_s *, char *));
47 static int msp430_srcoperand
48   PARAMS ((struct msp430_operand_s *, char *, int, int *));
49 static int msp430_dstoperand
50   PARAMS ((struct msp430_operand_s *, char *, int));
51 static char *parse_exp
52   PARAMS ((char *, expressionS *));
53 static inline char *skip_space
54   PARAMS ((char *));
55 static int check_reg
56   PARAMS ((char *));
57 static void msp430_set_arch
58   PARAMS ((int));
59 static void show_mcu_list
60   PARAMS ((FILE *));
61 static void del_spaces
62   PARAMS ((char *));
63 
64 #define MAX_OP_LEN	256
65 
66 struct mcu_type_s
67 {
68   char *name;
69   int isa;
70   int mach;
71 };
72 
73 #define MSP430_ISA_11   11
74 #define MSP430_ISA_110	110
75 #define MSP430_ISA_12   12
76 #define MSP430_ISA_13   13
77 #define MSP430_ISA_14   14
78 #define MSP430_ISA_15   15
79 #define MSP430_ISA_16   16
80 #define MSP430_ISA_31   31
81 #define MSP430_ISA_32   32
82 #define MSP430_ISA_33   33
83 #define MSP430_ISA_41   41
84 #define MSP430_ISA_42   42
85 #define MSP430_ISA_43   43
86 #define MSP430_ISA_44   44
87 
88 #define CHECK_RELOC_MSP430 		((imm_op || byte_op)?BFD_RELOC_MSP430_16_BYTE:BFD_RELOC_MSP430_16)
89 #define CHECK_RELOC_MSP430_PCREL	((imm_op || byte_op)?BFD_RELOC_MSP430_16_PCREL_BYTE:BFD_RELOC_MSP430_16_PCREL)
90 
91 static struct mcu_type_s mcu_types[] =
92 {
93   {"msp1",       MSP430_ISA_11, bfd_mach_msp11},
94   {"msp2",       MSP430_ISA_14, bfd_mach_msp14},
95   {"msp430x110", MSP430_ISA_11, bfd_mach_msp11},
96   {"msp430x112", MSP430_ISA_11, bfd_mach_msp11},
97   {"msp430x1101",MSP430_ISA_110, bfd_mach_msp110},
98   {"msp430x1111",MSP430_ISA_110, bfd_mach_msp110},
99   {"msp430x1121",MSP430_ISA_110, bfd_mach_msp110},
100   {"msp430x1122",MSP430_ISA_11, bfd_mach_msp110},
101   {"msp430x1132",MSP430_ISA_11, bfd_mach_msp110},
102 
103   {"msp430x122", MSP430_ISA_12, bfd_mach_msp12},
104   {"msp430x123", MSP430_ISA_12, bfd_mach_msp12},
105   {"msp430x1222",MSP430_ISA_12, bfd_mach_msp12},
106   {"msp430x1232",MSP430_ISA_12, bfd_mach_msp12},
107 
108   {"msp430x133", MSP430_ISA_13, bfd_mach_msp13},
109   {"msp430x135", MSP430_ISA_13, bfd_mach_msp13},
110   {"msp430x1331",MSP430_ISA_13, bfd_mach_msp13},
111   {"msp430x1351",MSP430_ISA_13, bfd_mach_msp13},
112   {"msp430x147", MSP430_ISA_14, bfd_mach_msp14},
113   {"msp430x148", MSP430_ISA_14, bfd_mach_msp14},
114   {"msp430x149", MSP430_ISA_14, bfd_mach_msp14},
115 
116   {"msp430x155", MSP430_ISA_15, bfd_mach_msp15},
117   {"msp430x156", MSP430_ISA_15, bfd_mach_msp15},
118   {"msp430x157", MSP430_ISA_15, bfd_mach_msp15},
119   {"msp430x167", MSP430_ISA_16, bfd_mach_msp16},
120   {"msp430x168", MSP430_ISA_16, bfd_mach_msp16},
121   {"msp430x169", MSP430_ISA_16, bfd_mach_msp16},
122 
123   {"msp430x311", MSP430_ISA_31, bfd_mach_msp31},
124   {"msp430x312", MSP430_ISA_31, bfd_mach_msp31},
125   {"msp430x313", MSP430_ISA_31, bfd_mach_msp31},
126   {"msp430x314", MSP430_ISA_31, bfd_mach_msp31},
127   {"msp430x315", MSP430_ISA_31, bfd_mach_msp31},
128   {"msp430x323", MSP430_ISA_32, bfd_mach_msp32},
129   {"msp430x325", MSP430_ISA_32, bfd_mach_msp32},
130   {"msp430x336", MSP430_ISA_33, bfd_mach_msp33},
131   {"msp430x337", MSP430_ISA_33, bfd_mach_msp33},
132 
133   {"msp430x412", MSP430_ISA_41, bfd_mach_msp41},
134   {"msp430x413", MSP430_ISA_41, bfd_mach_msp41},
135 
136   {"msp430xE423", MSP430_ISA_42, bfd_mach_msp42},
137   {"msp430xE425", MSP430_ISA_42, bfd_mach_msp42},
138   {"msp430xE427", MSP430_ISA_42, bfd_mach_msp42},
139   {"msp430xW423", MSP430_ISA_42, bfd_mach_msp42},
140   {"msp430xW425", MSP430_ISA_42, bfd_mach_msp42},
141   {"msp430xW427", MSP430_ISA_42, bfd_mach_msp42},
142 
143   {"msp430x435", MSP430_ISA_43, bfd_mach_msp43},
144   {"msp430x436", MSP430_ISA_43, bfd_mach_msp43},
145   {"msp430x437", MSP430_ISA_43, bfd_mach_msp43},
146   {"msp430x447", MSP430_ISA_44, bfd_mach_msp44},
147   {"msp430x448", MSP430_ISA_44, bfd_mach_msp44},
148   {"msp430x449", MSP430_ISA_44, bfd_mach_msp44},
149 
150   {NULL, 0, 0}
151 };
152 
153 
154 static struct mcu_type_s default_mcu =
155     { "msp430x11", MSP430_ISA_11, bfd_mach_msp11 };
156 
157 static struct mcu_type_s *msp430_mcu = &default_mcu;
158 
159 const pseudo_typeS md_pseudo_table[] =
160 {
161   {"arch", msp430_set_arch, 0},
162   {NULL, NULL, 0}
163 };
164 
165 #define OPTION_MMCU 'm'
166 
167 const char *md_shortopts = "m:";
168 
169 struct option md_longopts[] =
170 {
171   {"mmcu", required_argument, NULL, OPTION_MMCU},
172   {NULL, no_argument, NULL, 0}
173 };
174 
175 size_t md_longopts_size = sizeof (md_longopts);
176 
177 static void
show_mcu_list(stream)178 show_mcu_list (stream)
179      FILE *stream;
180 {
181   int i;
182 
183   fprintf (stream, _("Known MCU names:\n"));
184 
185   for (i = 0; mcu_types[i].name; i++)
186     fprintf (stream, _("\t %s\n"), mcu_types[i].name);
187 
188   fprintf (stream, "\n");
189 }
190 
191 void
md_show_usage(stream)192 md_show_usage (stream)
193      FILE *stream;
194 {
195   fprintf (stream,
196 	   _("MSP430 options:\n"
197 	     "  -mmcu=[msp430-name] select microcontroller type\n"
198 	     "                  msp430x110  msp430x112\n"
199 	     "                  msp430x1101 msp430x1111\n"
200 	     "                  msp430x1121 msp430x1122 msp430x1132\n"
201 	     "                  msp430x122  msp430x123\n"
202 	     "                  msp430x1222 msp430x1232\n"
203 	     "                  msp430x133  msp430x135\n"
204 	     "                  msp430x1331 msp430x1351\n"
205 	     "                  msp430x147  msp430x148  msp430x149\n"
206 	     "                  msp430x155  msp430x156  msp430x157\n"
207 	     "                  msp430x167  msp430x168  msp430x169\n"
208 	     "                  msp430x311  msp430x312  msp430x313  msp430x314  msp430x315\n"
209 	     "                  msp430x323  msp430x325\n"
210 	     "                  msp430x336  msp430x337\n"
211 	     "                  msp430x412  msp430x413\n"
212 	     "                  msp430xE423 msp430xE425 msp430E427\n"
213 	     "                  msp430xW423 msp430xW425 msp430W427\n"
214 	     "                  msp430x435  msp430x436  msp430x437\n"
215 	     "                  msp430x447  msp430x448  msp430x449\n"));
216 
217   show_mcu_list (stream);
218 }
219 
220 static char *
extract_word(char * from,char * to,int limit)221 extract_word (char *from, char *to, int limit)
222 {
223   char *op_start;
224   char *op_end;
225   int size = 0;
226 
227   /* Drop leading whitespace.  */
228   from = skip_space (from);
229   *to = 0;
230 
231   /* Find the op code end.  */
232   for (op_start = op_end = from; *op_end != 0 && is_part_of_name (*op_end);)
233     {
234       to[size++] = *op_end++;
235       if (size + 1 >= limit)
236 	break;
237     }
238 
239   to[size] = 0;
240   return op_end;
241 }
242 
243 static void
msp430_set_arch(dummy)244 msp430_set_arch (dummy)
245      int dummy ATTRIBUTE_UNUSED;
246 {
247   char *str = (char *) alloca (32);	/* 32 for good measure.  */
248 
249   input_line_pointer = extract_word (input_line_pointer, str, 32);
250 
251   md_parse_option (OPTION_MMCU, str);
252   bfd_set_arch_mach (stdoutput, TARGET_ARCH, msp430_mcu->mach);
253 }
254 
255 int
md_parse_option(c,arg)256 md_parse_option (c, arg)
257      int c;
258      char *arg;
259 {
260   int i;
261 
262   switch (c)
263     {
264     case OPTION_MMCU:
265       for (i = 0; mcu_types[i].name; ++i)
266 	if (strcmp (mcu_types[i].name, arg) == 0)
267 	  break;
268 
269       if (!mcu_types[i].name)
270 	{
271 	  show_mcu_list (stderr);
272 	  as_fatal (_("unknown MCU: %s\n"), arg);
273 	}
274 
275       if (msp430_mcu == &default_mcu || msp430_mcu->mach == mcu_types[i].mach)
276 	msp430_mcu = &mcu_types[i];
277       else
278 	as_fatal (_("redefinition of mcu type %s' to %s'"),
279 		  msp430_mcu->name, mcu_types[i].name);
280       return 1;
281     }
282 
283   return 0;
284 }
285 
286 symbolS *
md_undefined_symbol(name)287 md_undefined_symbol (name)
288      char *name ATTRIBUTE_UNUSED;
289 {
290   return 0;
291 }
292 
293 static inline char *
skip_space(s)294 skip_space (s)
295      char *s;
296 {
297   while (ISSPACE (*s))
298     ++s;
299   return s;
300 }
301 
302 /* Delete spaces from s: X ( r 1  2)  => X(r12).  */
303 
304 static void
del_spaces(s)305 del_spaces (s)
306      char *s;
307 {
308   while (*s)
309     {
310       if (ISSPACE (*s))
311 	{
312 	  char *m = s + 1;
313 
314 	  while (ISSPACE (*m) && *m)
315 	    m++;
316 	  memmove (s, m, strlen (m) + 1);
317 	}
318       else
319 	s++;
320     }
321 }
322 
323 /* Extract one word from FROM and copy it to TO. Delimeters are ",;\n"  */
324 
325 static char *
extract_operand(char * from,char * to,int limit)326 extract_operand (char *from, char *to, int limit)
327 {
328   int size = 0;
329 
330   /* Drop leading whitespace.  */
331   from = skip_space (from);
332 
333   while (size < limit && *from)
334     {
335       *(to + size) = *from;
336       if (*from == ',' || *from == ';' || *from == '\n')
337 	break;
338       from++;
339       size++;
340     }
341 
342   *(to + size) = 0;
343   del_spaces (to);
344 
345   from++;
346 
347   return from;
348 }
349 
350 static char *
extract_cmd(char * from,char * to,int limit)351 extract_cmd (char *from, char *to, int limit)
352 {
353   int size = 0;
354 
355   while (*from && ! ISSPACE (*from) && *from != '.' && limit > size)
356     {
357       *(to + size) = *from;
358       from++;
359       size++;
360     }
361 
362   *(to + size) = 0;
363 
364   return from;
365 }
366 
367 /* Turn a string in input_line_pointer into a floating point constant
368    of type TYPE, and store the appropriate bytes in *LITP.  The number
369    of LITTLENUMS emitted is stored in *SIZEP.  An error message is
370    returned, or NULL on OK.  */
371 
372 char *
md_atof(type,litP,sizeP)373 md_atof (type, litP, sizeP)
374      int type;
375      char *litP;
376      int *sizeP;
377 {
378   int prec;
379   LITTLENUM_TYPE words[4];
380   LITTLENUM_TYPE *wordP;
381   char *t;
382 
383   switch (type)
384     {
385     case 'f':
386       prec = 2;
387       break;
388     case 'd':
389       prec = 4;
390       break;
391     default:
392       *sizeP = 0;
393       return _("bad call to md_atof");
394     }
395 
396   t = atof_ieee (input_line_pointer, type, words);
397   if (t)
398     input_line_pointer = t;
399 
400   *sizeP = prec * sizeof (LITTLENUM_TYPE);
401 
402   /* This loop outputs the LITTLENUMs in REVERSE order.  */
403   for (wordP = words + prec - 1; prec--;)
404     {
405       md_number_to_chars (litP, (valueT) (*wordP--), sizeof (LITTLENUM_TYPE));
406       litP += sizeof (LITTLENUM_TYPE);
407     }
408 
409   return NULL;
410 }
411 
412 void
md_convert_frag(abfd,sec,fragP)413 md_convert_frag (abfd, sec, fragP)
414      bfd *abfd ATTRIBUTE_UNUSED;
415      asection *sec ATTRIBUTE_UNUSED;
416      fragS *fragP ATTRIBUTE_UNUSED;
417 {
418   abort ();
419 }
420 
421 void
md_begin()422 md_begin ()
423 {
424   struct msp430_opcode_s *opcode;
425   msp430_hash = hash_new ();
426 
427   for (opcode = msp430_opcodes; opcode->name; opcode++)
428     hash_insert (msp430_hash, opcode->name, (char *) opcode);
429 
430   bfd_set_arch_mach (stdoutput, TARGET_ARCH, msp430_mcu->mach);
431 }
432 
433 void
md_assemble(str)434 md_assemble (str)
435      char *str;
436 {
437   struct msp430_opcode_s *opcode;
438   char cmd[32];
439   unsigned int i = 0;
440 
441   str = skip_space (str);	/* Skip leading spaces.  */
442   str = extract_cmd (str, cmd, sizeof (cmd));
443 
444   while (cmd[i] && i < sizeof (cmd))
445     {
446       char a = TOLOWER (cmd[i]);
447       cmd[i] = a;
448       i++;
449     }
450 
451   if (!cmd[0])
452     {
453       as_bad (_("can't find opcode "));
454       return;
455     }
456 
457   opcode = (struct msp430_opcode_s *) hash_find (msp430_hash, cmd);
458 
459   if (opcode == NULL)
460     {
461       as_bad (_("unknown opcode `%s'"), cmd);
462       return;
463     }
464 
465   {
466     char *__t = input_line_pointer;
467     msp430_operands (opcode, str);
468     input_line_pointer = __t;
469   }
470 }
471 
472 /* Parse instruction operands.
473    Return binary opcode.  */
474 
475 static unsigned int
msp430_operands(opcode,line)476 msp430_operands (opcode, line)
477      struct msp430_opcode_s *opcode;
478      char *line;
479 {
480   int bin = opcode->bin_opcode;	/* opcode mask.  */
481   int __is;
482   char l1[MAX_OP_LEN], l2[MAX_OP_LEN];
483   char *frag;
484   int where;
485   struct msp430_operand_s op1, op2;
486   int res = 0;
487   static short ZEROS = 0;
488   int byte_op, imm_op;
489 
490   /* opcode is the one from opcodes table
491      line contains something like
492      [.w] @r2+, 5(R1)
493      or
494      .b @r2+, 5(R1).  */
495 
496   /* Check if byte or word operation.  */
497   if (*line == '.' && TOLOWER (*(line + 1)) == 'b')
498     {
499       bin |= BYTE_OPERATION;
500       byte_op = 1;
501     }
502   else
503     byte_op = 0;
504 
505   /* skip .[bwBW].  */
506   while (! ISSPACE (*line) && *line)
507     line++;
508 
509   if (opcode->insn_opnumb && (!*line || *line == '\n'))
510     {
511       as_bad (_("instruction %s requires %d operand(s)"),
512 	      opcode->name, opcode->insn_opnumb);
513       return 0;
514     }
515 
516   memset (l1, 0, sizeof (l1));
517   memset (l2, 0, sizeof (l2));
518   memset (&op1, 0, sizeof (op1));
519   memset (&op2, 0, sizeof (op2));
520 
521   imm_op = 0;
522 
523   switch (opcode->fmt)
524     {
525     case 0:			/* Emulated.  */
526       switch (opcode->insn_opnumb)
527 	{
528 	case 0:
529 	  /* Set/clear bits instructions.  */
530 	  __is = 2;
531 	  frag = frag_more (__is);
532 	  bfd_putl16 ((bfd_vma) bin, frag);
533 	  break;
534 	case 1:
535 	  /* Something which works with destination operand.  */
536 	  line = extract_operand (line, l1, sizeof (l1));
537 	  res = msp430_dstoperand (&op1, l1, opcode->bin_opcode);
538 	  if (res)
539 	    break;
540 
541 	  bin |= (op1.reg | (op1.am << 7));
542 	  __is = 1 + op1.ol;
543 	  frag = frag_more (2 * __is);
544 	  where = frag - frag_now->fr_literal;
545 	  bfd_putl16 ((bfd_vma) bin, frag);
546 
547 	  if (op1.mode == OP_EXP)
548 	    {
549 	      where += 2;
550 	      bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
551 
552 	      if (op1.reg)
553 		fix_new_exp (frag_now, where, 2,
554 			     &(op1.exp), FALSE, CHECK_RELOC_MSP430);
555 	      else
556 		fix_new_exp (frag_now, where, 2,
557 			     &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
558 	    }
559 	  break;
560 
561 	case 2:
562 	  {
563 	    /* Shift instruction.  */
564 	    line = extract_operand (line, l1, sizeof (l1));
565 	    strncpy (l2, l1, sizeof (l2));
566 	    l2[sizeof (l2) - 1] = '\0';
567 	    res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op);
568 	    res += msp430_dstoperand (&op2, l2, opcode->bin_opcode);
569 
570 	    if (res)
571 	      break;	/* An error occurred.  All warnings were done before.  */
572 
573 	    bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
574 
575 	    __is = 1 + op1.ol + op2.ol;	/* insn size in words.  */
576 	    frag = frag_more (2 * __is);
577 	    where = frag - frag_now->fr_literal;
578 	    bfd_putl16 ((bfd_vma) bin, frag);
579 
580 	    if (op1.mode == OP_EXP)
581 	      {
582 		where += 2;	/* Advance 'where' as we do not know _where_.  */
583 		bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
584 
585 		if (op1.reg || (op1.reg == 0 && op1.am == 3))	/* Not PC relative.  */
586 		  fix_new_exp (frag_now, where, 2,
587 			       &(op1.exp), FALSE, CHECK_RELOC_MSP430);
588 		else
589 		  fix_new_exp (frag_now, where, 2,
590 			       &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
591 	      }
592 
593 	    if (op2.mode == OP_EXP)
594 	      {
595 		imm_op = 0;
596 		bfd_putl16 ((bfd_vma) ZEROS, frag + 2 + ((__is == 3) ? 2 : 0));
597 
598 		if (op2.reg)	/* Not PC relative.  */
599 		  fix_new_exp (frag_now, where + 2, 2,
600 			       &(op2.exp), FALSE, CHECK_RELOC_MSP430);
601 		else
602 		  fix_new_exp (frag_now, where + 2, 2,
603 			       &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
604 	      }
605 	    break;
606 	  }
607 	case 3:
608 	  /* Branch instruction => mov dst, r0.  */
609 	  line = extract_operand (line, l1, sizeof (l1));
610 
611 	  res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op);
612 	  if (res)
613 	    break;
614 
615 	  byte_op = 0;
616 	  imm_op = 0;
617 
618 	  bin |= ((op1.reg << 8) | (op1.am << 4));
619 	  __is = 1 + op1.ol;
620 	  frag = frag_more (2 * __is);
621 	  where = frag - frag_now->fr_literal;
622 	  bfd_putl16 ((bfd_vma) bin, frag);
623 
624 	  if (op1.mode == OP_EXP)
625 	    {
626 	      where += 2;
627 	      bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
628 
629 	      if (op1.reg || (op1.reg == 0 && op1.am == 3))
630 		fix_new_exp (frag_now, where, 2,
631 			     &(op1.exp), FALSE, CHECK_RELOC_MSP430);
632 	      else
633 		fix_new_exp (frag_now, where, 2,
634 			     &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
635 	    }
636 	  break;
637 	}
638       break;
639 
640     case 1:			/* Format 1, double operand.  */
641       line = extract_operand (line, l1, sizeof (l1));
642       line = extract_operand (line, l2, sizeof (l2));
643       res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op);
644       res += msp430_dstoperand (&op2, l2, opcode->bin_opcode);
645 
646       if (res)
647 	break;			/* Error occurred.  All warnings were done before.  */
648 
649       bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
650 
651       __is = 1 + op1.ol + op2.ol;	/* insn size in words.  */
652       frag = frag_more (2 * __is);
653       where = frag - frag_now->fr_literal;
654       bfd_putl16 ((bfd_vma) bin, frag);
655 
656       if (op1.mode == OP_EXP)
657 	{
658 	  where += 2;		/* Advance where as we do not know _where_.  */
659 	  bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
660 
661 	  if (op1.reg || (op1.reg == 0 && op1.am == 3))	/* Not PC relative.  */
662 	    fix_new_exp (frag_now, where, 2,
663 			 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
664 	  else
665 	    fix_new_exp (frag_now, where, 2,
666 			 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
667 	}
668 
669       if (op2.mode == OP_EXP)
670 	{
671 	  imm_op = 0;
672 	  bfd_putl16 ((bfd_vma) ZEROS, frag + 2 + ((__is == 3) ? 2 : 0));
673 
674 	  if (op2.reg)		/* Not PC relative.  */
675 	    fix_new_exp (frag_now, where + 2, 2,
676 			 &(op2.exp), FALSE, CHECK_RELOC_MSP430);
677 	  else
678 	    fix_new_exp (frag_now, where + 2, 2,
679 			 &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
680 	}
681       break;
682 
683     case 2:			/* Single-operand mostly instr.  */
684       if (opcode->insn_opnumb == 0)
685 	{
686 	  /* reti instruction.  */
687 	  frag = frag_more (2);
688 	  bfd_putl16 ((bfd_vma) bin, frag);
689 	  break;
690 	}
691 
692       line = extract_operand (line, l1, sizeof (l1));
693       res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op);
694       if (res)
695 	break;		/* Error in operand.  */
696 
697       bin |= op1.reg | (op1.am << 4);
698       __is = 1 + op1.ol;
699       frag = frag_more (2 * __is);
700       where = frag - frag_now->fr_literal;
701       bfd_putl16 ((bfd_vma) bin, frag);
702 
703       if (op1.mode == OP_EXP)
704 	{
705 	  bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
706 
707 	  if (op1.reg || (op1.reg == 0 && op1.am == 3))	/* Not PC relative.  */
708 	    fix_new_exp (frag_now, where + 2, 2,
709 			 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
710 	  else
711 	    fix_new_exp (frag_now, where + 2, 2,
712 			 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
713 	}
714       break;
715 
716     case 3:			/* Conditional jumps instructions.  */
717       line = extract_operand (line, l1, sizeof (l1));
718       /* l1 is a label.  */
719       if (l1[0])
720 	{
721 	  char *m = l1;
722 	  expressionS exp;
723 
724 	  if (*m == '$')
725 	    m++;
726 
727 	  parse_exp (m, &exp);
728 	  frag = frag_more (2);	/* Instr size is 1 word.  */
729 
730 	  /* In order to handle something like:
731 
732 	     and #0x8000, r5
733 	     tst r5
734 	     jz   4     ;       skip next 4 bytes
735 	     inv r5
736 	     inc r5
737 	     nop        ;       will jump here if r5 positive or zero
738 
739 	     jCOND      -n      ;assumes jump n bytes backward:
740 
741 	     mov r5,r6
742 	     jmp -2
743 
744 	     is equal to:
745 	     lab:
746 	     mov r5,r6
747 	     jmp lab
748 
749 	     jCOND      $n      ; jump from PC in either direction.  */
750 
751 	  if (exp.X_op == O_constant)
752 	    {
753 	      int x = exp.X_add_number;
754 
755 	      if (x & 1)
756 		{
757 		  as_warn (_("Even number required. Rounded to %d"), x + 1);
758 		  x++;
759 		}
760 
761 	      if ((*l1 == '$' && x > 0) || x < 0)
762 		x -= 2;
763 
764 	      x >>= 1;
765 
766 	      if (x > 512 || x < -511)
767 		{
768 		  as_bad (_("Wrong displacement  %d"), x << 1);
769 		  break;
770 		}
771 
772 	      bin |= x & 0x3ff;
773 	      bfd_putl16 ((bfd_vma) bin, frag);
774 	    }
775 	  else if (exp.X_op == O_symbol && *l1 != '$')
776 	    {
777 	      where = frag - frag_now->fr_literal;
778 	      fix_new_exp (frag_now, where, 2,
779 			   &exp, TRUE, BFD_RELOC_MSP430_10_PCREL);
780 
781 	      bfd_putl16 ((bfd_vma) bin, frag);
782 	    }
783 	  else if (*l1 == '$')
784 	    {
785 	      as_bad (_("instruction requires label sans '$'"));
786 	      break;
787 	    }
788 	  else
789 	    {
790 	      as_bad (_
791 		      ("instruction requires label or value in range -511:512"));
792 	      break;
793 	    }
794 	}
795       else
796 	{
797 	  as_bad (_("instruction requires label"));
798 	  break;
799 	}
800       break;
801 
802     default:
803       as_bad (_("Ilegal instruction or not implmented opcode."));
804     }
805 
806   input_line_pointer = line;
807   return 0;
808 }
809 
810 static int
msp430_dstoperand(op,l,bin)811 msp430_dstoperand (op, l, bin)
812      struct msp430_operand_s *op;
813      char *l;
814      int bin;
815 {
816   int dummy;
817   int ret = msp430_srcoperand (op, l, bin, &dummy);
818   if (ret)
819     return ret;
820 
821   if (op->am == 2)
822     {
823       char *__tl = "0";
824 
825       op->mode = OP_EXP;
826       op->am = 1;
827       op->ol = 1;
828       parse_exp (__tl, &(op->exp));
829       if (op->exp.X_op != O_constant || op->exp.X_add_number != 0)
830 	{
831 	  as_bad (_("Internal bug. Try to use 0(r%d) instead of @r%d"),
832 		  op->reg, op->reg);
833 	  return 1;
834 	}
835       return 0;
836     }
837 
838   if (op->am > 1)
839     {
840       as_bad (_
841 	      ("this addressing mode is not applicable for destination operand"));
842       return 1;
843     }
844   return 0;
845 }
846 
847 
848 static int
check_reg(t)849 check_reg (t)
850      char *t;
851 {
852   /* If this is a reg numb, str 't' must be a number from 0 - 15.  */
853 
854   if (strlen (t) > 2 && *(t + 2) != '+')
855     return 1;
856 
857   while (*t)
858     {
859       if ((*t < '0' || *t > '9') && *t != '+')
860 	break;
861       t++;
862     }
863 
864   if (*t)
865     return 1;
866 
867   return 0;
868 }
869 
870 
871 static int
msp430_srcoperand(op,l,bin,imm_op)872 msp430_srcoperand (op, l, bin, imm_op)
873      struct msp430_operand_s *op;
874      char *l;
875      int bin;
876      int *imm_op;
877 {
878   char *__tl = l;
879 
880   /* Check if an immediate #VALUE.  The hash sign should be only at the beginning!  */
881   if (*l == '#')
882     {
883       char *h = l;
884       int vshift = -1;
885       int rval = 0;
886 
887       /* Check if there is:
888 	 llo(x) - least significant 16 bits, x &= 0xffff
889 	 lhi(x) - x = (x >> 16) & 0xffff,
890 	 hlo(x) - x = (x >> 32) & 0xffff,
891 	 hhi(x) - x = (x >> 48) & 0xffff
892 	 The value _MUST_ be constant expression: #hlo(1231231231).  */
893 
894       *imm_op = 1;
895 
896       if (strncasecmp (h, "#llo(", 5) == 0)
897 	{
898 	  vshift = 0;
899 	  rval = 3;
900 	}
901       else if (strncasecmp (h, "#lhi(", 5) == 0)
902 	{
903 	  vshift = 1;
904 	  rval = 3;
905 	}
906       else if (strncasecmp (h, "#hlo(", 5) == 0)
907 	{
908 	  vshift = 2;
909 	  rval = 3;
910 	}
911       else if (strncasecmp (h, "#hhi(", 5) == 0)
912 	{
913 	  vshift = 3;
914 	  rval = 3;
915 	}
916       else if (strncasecmp (h, "#lo(", 4) == 0)
917 	{
918 	  vshift = 0;
919 	  rval = 2;
920 	}
921       else if (strncasecmp (h, "#hi(", 4) == 0)
922 	{
923 	  vshift = 1;
924 	  rval = 2;
925 	}
926 
927       op->reg = 0;		/* Reg PC.  */
928       op->am = 3;
929       op->ol = 1;		/* Immediate  will follow an instruction.  */
930       __tl = h + 1 + rval;
931       op->mode = OP_EXP;
932       parse_exp (__tl, &(op->exp));
933       if (op->exp.X_op == O_constant)
934 	{
935 	  int x = op->exp.X_add_number;
936 
937 	  if (vshift == 0)
938 	    {
939 	      x = x & 0xffff;
940 	      op->exp.X_add_number = x;
941 	    }
942 	  else if (vshift == 1)
943 	    {
944 	      x = (x >> 16) & 0xffff;
945 	      op->exp.X_add_number = x;
946 	    }
947 	  else if (vshift > 1)
948 	    {
949 	      if (x < 0)
950 		op->exp.X_add_number = -1;
951 	      else
952 		op->exp.X_add_number = 0;	/* Nothing left.  */
953 	      x = op->exp.X_add_number;
954 	    }
955 
956 	  if (op->exp.X_add_number > 65535 || op->exp.X_add_number < -32768)
957 	    {
958 	      as_bad (_("value %ld out of range. Use #lo() or #hi()"), x);
959 	      return 1;
960 	    }
961 
962 	  /* Now check constants.  */
963 	  /* Substitute register mode with a constant generator if applicable.  */
964 
965 	  x = (short) x;	/* Extend sign.  */
966 
967 	  if (x == 0)
968 	    {
969 	      op->reg = 3;
970 	      op->am = 0;
971 	      op->ol = 0;
972 	      op->mode = OP_REG;
973 	    }
974 	  else if (x == 1)
975 	    {
976 	      op->reg = 3;
977 	      op->am = 1;
978 	      op->ol = 0;
979 	      op->mode = OP_REG;
980 	    }
981 	  else if (x == 2)
982 	    {
983 	      op->reg = 3;
984 	      op->am = 2;
985 	      op->ol = 0;
986 	      op->mode = OP_REG;
987 	    }
988 	  else if (x == -1)
989 	    {
990 	      op->reg = 3;
991 	      op->am = 3;
992 	      op->ol = 0;
993 	      op->mode = OP_REG;
994 	    }
995 	  else if (x == 4)
996 	    {
997 #ifdef PUSH_1X_WORKAROUND
998 	      if (bin == 0x1200)
999 		{
1000 		  /* Remove warning as confusing.
1001 		     as_warn(_("Hardware push bug workaround")); */
1002 		}
1003 	      else
1004 #endif
1005 		{
1006 		  op->reg = 2;
1007 		  op->am = 2;
1008 		  op->ol = 0;
1009 		  op->mode = OP_REG;
1010 		}
1011 	    }
1012 	  else if (x == 8)
1013 	    {
1014 #ifdef PUSH_1X_WORKAROUND
1015 	      if (bin == 0x1200)
1016 		{
1017 		  /* Remove warning as confusing.
1018 		     as_warn(_("Hardware push bug workaround")); */
1019 		}
1020 	      else
1021 #endif
1022 		{
1023 		  op->reg = 2;
1024 		  op->am = 3;
1025 		  op->ol = 0;
1026 		  op->mode = OP_REG;
1027 		}
1028 	    }
1029 	}
1030       else if (op->exp.X_op == O_symbol)
1031 	{
1032 	  op->mode = OP_EXP;
1033 	}
1034       else if (op->exp.X_op == O_big)
1035 	{
1036 	  short x;
1037 	  if (vshift != -1)
1038 	    {
1039 	      op->exp.X_op = O_constant;
1040 	      op->exp.X_add_number = 0xffff & generic_bignum[vshift];
1041 	      x = op->exp.X_add_number;
1042 	    }
1043 	  else
1044 	    {
1045 	      as_bad (_
1046 		      ("unknown expression in operand %s. use #llo() #lhi() #hlo() #hhi() "),
1047 		      l);
1048 	      return 1;
1049 	    }
1050 
1051 	  if (x == 0)
1052 	    {
1053 	      op->reg = 3;
1054 	      op->am = 0;
1055 	      op->ol = 0;
1056 	      op->mode = OP_REG;
1057 	    }
1058 	  else if (x == 1)
1059 	    {
1060 	      op->reg = 3;
1061 	      op->am = 1;
1062 	      op->ol = 0;
1063 	      op->mode = OP_REG;
1064 	    }
1065 	  else if (x == 2)
1066 	    {
1067 	      op->reg = 3;
1068 	      op->am = 2;
1069 	      op->ol = 0;
1070 	      op->mode = OP_REG;
1071 	    }
1072 	  else if (x == -1)
1073 	    {
1074 	      op->reg = 3;
1075 	      op->am = 3;
1076 	      op->ol = 0;
1077 	      op->mode = OP_REG;
1078 	    }
1079 	  else if (x == 4)
1080 	    {
1081 	      op->reg = 2;
1082 	      op->am = 2;
1083 	      op->ol = 0;
1084 	      op->mode = OP_REG;
1085 	    }
1086 	  else if (x == 8)
1087 	    {
1088 	      op->reg = 2;
1089 	      op->am = 3;
1090 	      op->ol = 0;
1091 	      op->mode = OP_REG;
1092 	    }
1093 	}
1094       else
1095 	{
1096 	  as_bad (_("unknown operand %s"), l);
1097 	}
1098       return 0;
1099     }
1100 
1101   /* Check if absolute &VALUE (assume that we can construct something like ((a&b)<<7 + 25).  */
1102   if (*l == '&')
1103     {
1104       char *h = l;
1105 
1106       op->reg = 2;		/* reg 2 in absolute addr mode.  */
1107       op->am = 1;		/* mode As == 01 bin.  */
1108       op->ol = 1;		/* Immediate value followed by instruction.  */
1109       __tl = h + 1;
1110       parse_exp (__tl, &(op->exp));
1111       op->mode = OP_EXP;
1112       if (op->exp.X_op == O_constant)
1113 	{
1114 	  int x = op->exp.X_add_number;
1115 	  if (x > 65535 || x < -32768)
1116 	    {
1117 	      as_bad (_("value out of range: %d"), x);
1118 	      return 1;
1119 	    }
1120 	}
1121       else if (op->exp.X_op == O_symbol)
1122 	{
1123 	}
1124       else
1125 	{
1126 	  as_bad (_("unknown expression in operand %s"), l);
1127 	  return 1;
1128 	}
1129       return 0;
1130     }
1131 
1132   /* Check if indirect register mode @Rn / postincrement @Rn+.  */
1133   if (*l == '@')
1134     {
1135       char *t = l;
1136       char *m = strchr (l, '+');
1137 
1138       if (t != l)
1139 	{
1140 	  as_bad (_("unknown addressing mode %s"), l);
1141 	  return 1;
1142 	}
1143 
1144       t++;
1145       if (*t != 'r' && *t != 'R')
1146 	{
1147 	  as_bad (_("unknown addressing mode %s"), l);
1148 	  return 1;
1149 	}
1150 
1151       t++;	/* Points to the reg value.  */
1152 
1153       if (check_reg (t))
1154 	{
1155 	  as_bad (_("Bad register name r%s"), t);
1156 	  return 1;
1157 	}
1158 
1159       op->mode = OP_REG;
1160       op->am = m ? 3 : 2;
1161       op->ol = 0;
1162       if (m)
1163 	*m = 0;			/* strip '+' */
1164       op->reg = atoi (t);
1165       if (op->reg < 0 || op->reg > 15)
1166 	{
1167 	  as_bad (_("MSP430 does not have %d registers"), op->reg);
1168 	  return 1;
1169 	}
1170 
1171       return 0;
1172     }
1173 
1174   /* Check if register indexed X(Rn).  */
1175   do
1176     {
1177       char *h = strrchr (l, '(');
1178       char *m = strrchr (l, ')');
1179       char *t;
1180 
1181       *imm_op = 1;
1182 
1183       if (!h)
1184 	break;
1185       if (!m)
1186 	{
1187 	  as_bad (_("')' required"));
1188 	  return 1;
1189 	}
1190 
1191       t = h;
1192       op->am = 1;
1193       op->ol = 1;
1194       /* Extract a register.  */
1195       t++;	/* Advance pointer.  */
1196 
1197       if (*t != 'r' && *t != 'R')
1198 	{
1199 	  as_bad (_
1200 		  ("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"),
1201 		  l);
1202 	  return 1;
1203 	}
1204       t++;
1205 
1206       op->reg = *t - '0';
1207       if (op->reg > 9 || op->reg < 0)
1208 	{
1209 	  as_bad (_("unknown operator (r%s substituded as a register name"),
1210 		  t);
1211 	  return 1;
1212 	}
1213       t++;
1214       if (*t != ')')
1215 	{
1216 	  op->reg = op->reg * 10;
1217 	  op->reg += *t - '0';
1218 
1219 	  if (op->reg > 15)
1220 	    {
1221 	      as_bad (_("unknown operator %s"), l);
1222 	      return 1;
1223 	    }
1224 	  if (op->reg == 2)
1225 	    {
1226 	      as_bad (_("r2 should not be used in indexed addressing mode"));
1227 	      return 1;
1228 	    }
1229 
1230 	  if (*(t + 1) != ')')
1231 	    {
1232 	      as_bad (_("unknown operator %s"), l);
1233 	      return 1;
1234 	    }
1235 	}
1236 
1237       /* Extract constant.  */
1238       __tl = l;
1239       *h = 0;
1240       op->mode = OP_EXP;
1241       parse_exp (__tl, &(op->exp));
1242       if (op->exp.X_op == O_constant)
1243 	{
1244 	  int x = op->exp.X_add_number;
1245 
1246 	  if (x > 65535 || x < -32768)
1247 	    {
1248 	      as_bad (_("value out of range: %d"), x);
1249 	      return 1;
1250 	    }
1251 
1252 	  if (x == 0)
1253 	    {
1254 	      op->mode = OP_REG;
1255 	      op->am = 2;
1256 	      op->ol = 0;
1257 	      return 0;
1258 	    }
1259 	}
1260       else if (op->exp.X_op == O_symbol)
1261 	{
1262 	}
1263       else
1264 	{
1265 	  as_bad (_("unknown expression in operand %s"), l);
1266 	  return 1;
1267 	}
1268 
1269       return 0;
1270     }
1271   while (0);
1272 
1273   /* Register mode 'mov r1,r2'.  */
1274   do
1275     {
1276       char *t = l;
1277 
1278       /* Operand should be a register.  */
1279       if (*t == 'r' || *t == 'R')
1280 	{
1281 	  int x = atoi (t + 1);
1282 
1283 	  if (check_reg (t + 1))
1284 	    break;
1285 
1286 	  if (x < 0 || x > 15)
1287 	    break;		/* Symbolic mode.  */
1288 
1289 	  op->mode = OP_REG;
1290 	  op->am = 0;
1291 	  op->ol = 0;
1292 	  op->reg = x;
1293 	  return 0;
1294 	}
1295     }
1296   while (0);
1297 
1298   /* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'.  */
1299   do
1300     {
1301       char *t = l;
1302 
1303       __tl = l;
1304 
1305       while (*t)
1306 	{
1307 	  /* alpha/number    underline     dot for labels.  */
1308 	  if (! ISALNUM (*t) && *t != '_' && *t != '.')
1309 	    {
1310 	      as_bad (_("unknown operand %s"), l);
1311 	      return 1;
1312 	    }
1313 	  t++;
1314 	}
1315 
1316       op->mode = OP_EXP;
1317       op->reg = 0;		/* PC relative... be careful.  */
1318       op->am = 1;
1319       op->ol = 1;
1320       __tl = l;
1321       parse_exp (__tl, &(op->exp));
1322       return 0;
1323     }
1324   while (0);
1325 
1326   /* Unreachable.  */
1327   as_bad (_("unknown addressing mode for operand %s"), l);
1328   return 1;
1329 }
1330 
1331 
1332 /* GAS will call this function for each section at the end of the assembly,
1333    to permit the CPU backend to adjust the alignment of a section.  */
1334 
1335 valueT
md_section_align(seg,addr)1336 md_section_align (seg, addr)
1337      asection *seg;
1338      valueT addr;
1339 {
1340   int align = bfd_get_section_alignment (stdoutput, seg);
1341 
1342   return ((addr + (1 << align) - 1) & (-1 << align));
1343 }
1344 
1345 /* If you define this macro, it should return the offset between the
1346    address of a PC relative fixup and the position from which the PC
1347    relative adjustment should be made.  On many processors, the base
1348    of a PC relative instruction is the next instruction, so this
1349    macro would return the length of an instruction.  */
1350 
1351 long
md_pcrel_from_section(fixp,sec)1352 md_pcrel_from_section (fixp, sec)
1353      fixS *fixp;
1354      segT sec;
1355 {
1356   if (fixp->fx_addsy != (symbolS *) NULL
1357       && (!S_IS_DEFINED (fixp->fx_addsy)
1358 	  || (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
1359     return 0;
1360 
1361   return fixp->fx_frag->fr_address + fixp->fx_where;
1362 }
1363 
1364 /* GAS will call this for each fixup.  It should store the correct
1365    value in the object file.  */
1366 
1367 void
md_apply_fix3(fixp,valuep,seg)1368 md_apply_fix3 (fixp, valuep, seg)
1369      fixS *fixp;
1370      valueT *valuep;
1371      segT seg;
1372 {
1373   unsigned char *where;
1374   unsigned long insn;
1375   long value;
1376 
1377   if (fixp->fx_addsy == (symbolS *) NULL)
1378     {
1379       value = *valuep;
1380       fixp->fx_done = 1;
1381     }
1382   else if (fixp->fx_pcrel)
1383     {
1384       segT s = S_GET_SEGMENT (fixp->fx_addsy);
1385 
1386       if (fixp->fx_addsy && (s == seg || s == absolute_section))
1387 	{
1388 	  value = S_GET_VALUE (fixp->fx_addsy) + *valuep;
1389 	  fixp->fx_done = 1;
1390 	}
1391       else
1392 	value = *valuep;
1393     }
1394   else
1395     {
1396       value = fixp->fx_offset;
1397 
1398       if (fixp->fx_subsy != (symbolS *) NULL)
1399 	{
1400 	  if (S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
1401 	    {
1402 	      value -= S_GET_VALUE (fixp->fx_subsy);
1403 	      fixp->fx_done = 1;
1404 	    }
1405 	  else
1406 	    {
1407 	      /* We don't actually support subtracting a symbol.  */
1408 	      as_bad_where (fixp->fx_file, fixp->fx_line,
1409 			    _("expression too complex"));
1410 	    }
1411 	}
1412     }
1413 
1414   switch (fixp->fx_r_type)
1415     {
1416     default:
1417       fixp->fx_no_overflow = 1;
1418       break;
1419     case BFD_RELOC_MSP430_10_PCREL:
1420       break;
1421     }
1422 
1423   if (fixp->fx_done)
1424     {
1425       /* Fetch the instruction, insert the fully resolved operand
1426 	 value, and stuff the instruction back again.  */
1427 
1428       where = fixp->fx_frag->fr_literal + fixp->fx_where;
1429 
1430       insn = bfd_getl16 (where);
1431 
1432       switch (fixp->fx_r_type)
1433 	{
1434 	case BFD_RELOC_MSP430_10_PCREL:
1435 	  if (value & 1)
1436 	    as_bad_where (fixp->fx_file, fixp->fx_line,
1437 			  _("odd address operand: %ld"), value);
1438 
1439 	  /* Jumps are in words.  */
1440 	  value >>= 1;
1441 	  --value;		/* Correct PC.  */
1442 
1443 	  if (value < -512 || value > 511)
1444 	    as_bad_where (fixp->fx_file, fixp->fx_line,
1445 			  _("operand out of range: %ld"), value);
1446 
1447 	  value &= 0x3ff;	/* get rid of extended sign */
1448 	  bfd_putl16 ((bfd_vma) (value | insn), where);
1449 	  break;
1450 
1451 	case BFD_RELOC_MSP430_16_PCREL:
1452 	  if (value & 1)
1453 	    as_bad_where (fixp->fx_file, fixp->fx_line,
1454 			  _("odd address operand: %ld"), value);
1455 
1456 	  /* Nothing to be corrected here.  */
1457 	  if (value < -32768 || value > 65536)
1458 	    as_bad_where (fixp->fx_file, fixp->fx_line,
1459 			  _("operand out of range: %ld"), value);
1460 
1461 	  value &= 0xffff;	/* Get rid of extended sign.  */
1462 	  bfd_putl16 ((bfd_vma) value, where);
1463 	  break;
1464 
1465 	case BFD_RELOC_MSP430_16_PCREL_BYTE:
1466 	  /* Nothing to be corrected here.  */
1467 	  if (value < -32768 || value > 65536)
1468 	    as_bad_where (fixp->fx_file, fixp->fx_line,
1469 			  _("operand out of range: %ld"), value);
1470 
1471 	  value &= 0xffff;	/* Get rid of extended sign.  */
1472 	  bfd_putl16 ((bfd_vma) value, where);
1473 	  break;
1474 
1475 	case BFD_RELOC_32:
1476 	  bfd_putl16 ((bfd_vma) value, where);
1477 	  break;
1478 
1479 	case BFD_RELOC_MSP430_16:
1480 	case BFD_RELOC_16:
1481 	case BFD_RELOC_MSP430_16_BYTE:
1482 	  value &= 0xffff;
1483 	  bfd_putl16 ((bfd_vma) value, where);
1484 	  break;
1485 
1486 	default:
1487 	  as_fatal (_("line %d: unknown relocation type: 0x%x"),
1488 		    fixp->fx_line, fixp->fx_r_type);
1489 	  break;
1490 	}
1491     }
1492   else
1493     {
1494       fixp->fx_addnumber = value;
1495     }
1496 }
1497 
1498 /* A `BFD_ASSEMBLER' GAS will call this to generate a reloc.  GAS
1499    will pass the resulting reloc to `bfd_install_relocation'.  This
1500    currently works poorly, as `bfd_install_relocation' often does the
1501    wrong thing, and instances of `tc_gen_reloc' have been written to
1502    work around the problems, which in turns makes it difficult to fix
1503    `bfd_install_relocation'.  */
1504 
1505 /* If while processing a fixup, a reloc really needs to be created
1506    then it is done here.  */
1507 
1508 arelent *
tc_gen_reloc(seg,fixp)1509 tc_gen_reloc (seg, fixp)
1510      asection *seg ATTRIBUTE_UNUSED;
1511      fixS *fixp;
1512 {
1513   arelent *reloc;
1514 
1515   reloc = (arelent *) xmalloc (sizeof (arelent));
1516 
1517   reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
1518   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
1519 
1520   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1521   reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1522   if (reloc->howto == (reloc_howto_type *) NULL)
1523     {
1524       as_bad_where (fixp->fx_file, fixp->fx_line,
1525 		    _("reloc %d not supported by object file format"),
1526 		    (int) fixp->fx_r_type);
1527       return NULL;
1528     }
1529 
1530   if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
1531       || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
1532     reloc->address = fixp->fx_offset;
1533 
1534   reloc->addend = fixp->fx_offset;
1535 
1536   return reloc;
1537 }
1538 
1539 /* Parse ordinary expression.  */
1540 
1541 static char *
parse_exp(s,op)1542 parse_exp (s, op)
1543      char *s;
1544      expressionS *op;
1545 {
1546   input_line_pointer = s;
1547   expression (op);
1548   if (op->X_op == O_absent)
1549     as_bad (_("missing operand"));
1550   return input_line_pointer;
1551 }
1552 
1553 
1554 int
md_estimate_size_before_relax(fragp,seg)1555 md_estimate_size_before_relax (fragp, seg)
1556      fragS *fragp ATTRIBUTE_UNUSED;
1557      asection *seg ATTRIBUTE_UNUSED;
1558 {
1559   abort ();
1560   return 0;
1561 }
1562