* config/tc-a29k.h: Fix comment typos.
[external/binutils.git] / gas / config / tc-msp430.c
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
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
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 *
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
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
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 *
287 md_undefined_symbol (name)
288      char *name ATTRIBUTE_UNUSED;
289 {
290   return 0;
291 }
292
293 static inline char *
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
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 *
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 *
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 *
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
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
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
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
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
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
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
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
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
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
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   return;
1497 }
1498
1499 /* A `BFD_ASSEMBLER' GAS will call this to generate a reloc.  GAS
1500    will pass the resulting reloc to `bfd_install_relocation'.  This
1501    currently works poorly, as `bfd_install_relocation' often does the
1502    wrong thing, and instances of `tc_gen_reloc' have been written to
1503    work around the problems, which in turns makes it difficult to fix
1504    `bfd_install_relocation'.  */
1505
1506 /* If while processing a fixup, a reloc really needs to be created
1507    then it is done here.  */
1508
1509 arelent *
1510 tc_gen_reloc (seg, fixp)
1511      asection *seg ATTRIBUTE_UNUSED;
1512      fixS *fixp;
1513 {
1514   arelent *reloc;
1515
1516   reloc = (arelent *) xmalloc (sizeof (arelent));
1517
1518   reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
1519   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
1520
1521   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1522   reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1523   if (reloc->howto == (reloc_howto_type *) NULL)
1524     {
1525       as_bad_where (fixp->fx_file, fixp->fx_line,
1526                     _("reloc %d not supported by object file format"),
1527                     (int) fixp->fx_r_type);
1528       return NULL;
1529     }
1530
1531   if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
1532       || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
1533     reloc->address = fixp->fx_offset;
1534
1535   reloc->addend = fixp->fx_offset;
1536
1537   return reloc;
1538 }
1539
1540 /* Parse ordinary expression.  */
1541
1542 static char *
1543 parse_exp (s, op)
1544      char *s;
1545      expressionS *op;
1546 {
1547   input_line_pointer = s;
1548   expression (op);
1549   if (op->X_op == O_absent)
1550     as_bad (_("missing operand"));
1551   return input_line_pointer;
1552 }
1553
1554
1555 int
1556 md_estimate_size_before_relax (fragp, seg)
1557      fragS *fragp ATTRIBUTE_UNUSED;
1558      asection *seg ATTRIBUTE_UNUSED;
1559 {
1560   abort ();
1561   return 0;
1562 }