Update copyright years
[external/binutils.git] / gas / config / tc-moxie.c
1 /* tc-moxie.c -- Assemble code for moxie
2    Copyright (C) 2009-2014 Free Software Foundation, Inc.
3
4    This file is part of GAS, the GNU Assembler.
5
6    GAS is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3, or (at your option)
9    any later version.
10
11    GAS is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with GAS; see the file COPYING.  If not, write to
18    the Free Software Foundation, 51 Franklin Street - Fifth Floor,
19    Boston, MA 02110-1301, USA.  */
20
21 /* Contributed by Anthony Green <green@moxielogic.com>.  */
22
23 #include "as.h"
24 #include "safe-ctype.h"
25 #include "opcode/moxie.h"
26 #include "elf/moxie.h"
27
28 extern const moxie_opc_info_t moxie_opc_info[128];
29
30 const char comment_chars[]        = "#";
31 const char line_separator_chars[] = ";";
32 const char line_comment_chars[]   = "#";
33
34 static int pending_reloc;
35 static struct hash_control *opcode_hash_control;
36
37 const pseudo_typeS md_pseudo_table[] =
38 {
39   {0, 0, 0}
40 };
41
42 const char FLT_CHARS[] = "rRsSfFdDxXpP";
43 const char EXP_CHARS[] = "eE";
44
45 static valueT md_chars_to_number (char * buf, int n);
46
47 /* Byte order.  */
48 extern int target_big_endian;
49 const char *moxie_target_format = DEFAULT_TARGET_FORMAT;
50
51 void
52 md_operand (expressionS *op __attribute__((unused)))
53 {
54   /* Empty for now. */
55 }
56
57 /* This function is called once, at assembler startup time.  It sets
58    up the hash table with all the opcodes in it, and also initializes
59    some aliases for compatibility with other assemblers.  */
60
61 void
62 md_begin (void)
63 {
64   int count;
65   const moxie_opc_info_t *opcode;
66   opcode_hash_control = hash_new ();
67
68   /* Insert names into hash table.  */
69   for (count = 0, opcode = moxie_form1_opc_info; count++ < 64; opcode++)
70     hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
71
72   for (count = 0, opcode = moxie_form2_opc_info; count++ < 4; opcode++)
73     hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
74
75   for (count = 0, opcode = moxie_form3_opc_info; count++ < 10; opcode++)
76     hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
77
78   bfd_set_arch_mach (stdoutput, TARGET_ARCH, 0);
79 }
80
81 /* Parse an expression and then restore the input line pointer.  */
82
83 static char *
84 parse_exp_save_ilp (char *s, expressionS *op)
85 {
86   char *save = input_line_pointer;
87
88   input_line_pointer = s;
89   expression (op);
90   s = input_line_pointer;
91   input_line_pointer = save;
92   return s;
93 }
94
95 static int
96 parse_register_operand (char **ptr)
97 {
98   int reg;
99   char *s = *ptr;
100
101   if (*s != '$')
102     {
103       as_bad (_("expecting register"));
104       ignore_rest_of_line ();
105       return -1;
106     }
107   if (s[1] == 'f' && s[2] == 'p')
108     {
109       *ptr += 3;
110       return 0;
111     }
112   if (s[1] == 's' && s[2] == 'p')
113     {
114       *ptr += 3;
115       return 1;
116     }
117   if (s[1] == 'r')
118     {
119       reg = s[2] - '0';
120       if ((reg < 0) || (reg > 9))
121         {
122           as_bad (_("illegal register number"));
123           ignore_rest_of_line ();
124           return -1;
125         }
126       if (reg == 1)
127         {
128           int r2 = s[3] - '0';
129           if ((r2 >= 0) && (r2 <= 3))
130             {
131               reg = 10 + r2;
132               *ptr += 1;
133             }
134         }
135     }
136   else
137     {
138       as_bad (_("illegal register number"));
139       ignore_rest_of_line ();
140       return -1;
141     }
142
143   *ptr += 3;
144
145   return reg + 2;
146 }
147
148 /* This is the guts of the machine-dependent assembler.  STR points to
149    a machine dependent instruction.  This function is supposed to emit
150    the frags/bytes it assembles to.  */
151
152 void
153 md_assemble (char *str)
154 {
155   char *op_start;
156   char *op_end;
157
158   moxie_opc_info_t *opcode;
159   char *p;
160   char pend;
161
162   unsigned short iword = 0;
163
164   int nlen = 0;
165
166   /* Drop leading whitespace.  */
167   while (*str == ' ')
168     str++;
169
170   /* Find the op code end.  */
171   op_start = str;
172   for (op_end = str;
173        *op_end && !is_end_of_line[*op_end & 0xff] && *op_end != ' ';
174        op_end++)
175     nlen++;
176
177   pend = *op_end;
178   *op_end = 0;
179
180   if (nlen == 0)
181     as_bad (_("can't find opcode "));
182   opcode = (moxie_opc_info_t *) hash_find (opcode_hash_control, op_start);
183   *op_end = pend;
184
185   if (opcode == NULL)
186     {
187       as_bad (_("unknown opcode %s"), op_start);
188       return;
189     }
190
191   p = frag_more (2);
192
193   switch (opcode->itype)
194     {
195     case MOXIE_F2_A8V:
196       iword = (1<<15) | (opcode->opcode << 12);
197       while (ISSPACE (*op_end))
198         op_end++;
199       {
200         expressionS arg;
201         int reg;
202         reg = parse_register_operand (&op_end);
203         iword += (reg << 8);
204         if (*op_end != ',')
205           as_warn (_("expecting comma delimited register operands"));
206         op_end++;
207         op_end = parse_exp_save_ilp (op_end, &arg);
208         fix_new_exp (frag_now,
209                      ((p + (target_big_endian ? 1 : 0)) - frag_now->fr_literal),
210                      1,
211                      &arg,
212                      0,
213                      BFD_RELOC_8);
214       }
215       break;
216     case MOXIE_F1_AB:
217       iword = opcode->opcode << 8;
218       while (ISSPACE (*op_end))
219         op_end++;
220       {
221         int dest, src;
222         dest = parse_register_operand (&op_end);
223         if (*op_end != ',')
224           as_warn (_("expecting comma delimited register operands"));
225         op_end++;
226         src  = parse_register_operand (&op_end);
227         iword += (dest << 4) + src;
228         while (ISSPACE (*op_end))
229           op_end++;
230         if (*op_end != 0)
231           as_warn (_("extra stuff on line ignored"));
232       }
233       break;
234     case MOXIE_F1_A4:
235       iword = opcode->opcode << 8;
236       while (ISSPACE (*op_end))
237         op_end++;
238       {
239         expressionS arg;
240         char *where;
241         int regnum;
242
243         regnum = parse_register_operand (&op_end);
244         while (ISSPACE (*op_end))
245           op_end++;
246
247         iword += (regnum << 4);
248
249         if (*op_end != ',')
250           {
251             as_bad (_("expecting comma delimited operands"));
252             ignore_rest_of_line ();
253             return;
254           }
255         op_end++;
256
257         op_end = parse_exp_save_ilp (op_end, &arg);
258         where = frag_more (4);
259         fix_new_exp (frag_now,
260                      (where - frag_now->fr_literal),
261                      4,
262                      &arg,
263                      0,
264                      BFD_RELOC_32);
265       }
266       break;
267     case MOXIE_F1_M:
268     case MOXIE_F1_4:
269       iword = opcode->opcode << 8;
270       while (ISSPACE (*op_end))
271         op_end++;
272       {
273         expressionS arg;
274         char *where;
275
276         op_end = parse_exp_save_ilp (op_end, &arg);
277         where = frag_more (4);
278         fix_new_exp (frag_now,
279                      (where - frag_now->fr_literal),
280                      4,
281                      &arg,
282                      0,
283                      BFD_RELOC_32);
284       }
285       break;
286     case MOXIE_F1_NARG:
287       iword = opcode->opcode << 8;
288       while (ISSPACE (*op_end))
289         op_end++;
290       if (*op_end != 0)
291         as_warn (_("extra stuff on line ignored"));
292       break;
293     case MOXIE_F1_A:
294       iword = opcode->opcode << 8;
295       while (ISSPACE (*op_end))
296         op_end++;
297       {
298         int reg;
299         reg = parse_register_operand (&op_end);
300         while (ISSPACE (*op_end))
301           op_end++;
302         if (*op_end != 0)
303           as_warn (_("extra stuff on line ignored"));
304         iword += (reg << 4);
305       }
306       break;
307     case MOXIE_F1_ABi:
308       iword = opcode->opcode << 8;
309       while (ISSPACE (*op_end))
310         op_end++;
311       {
312         int a, b;
313         a = parse_register_operand (&op_end);
314         if (*op_end != ',')
315           as_warn (_("expecting comma delimited register operands"));
316         op_end++;
317         if (*op_end != '(')
318           {
319             as_bad (_("expecting indirect register `($rA)'"));
320             ignore_rest_of_line ();
321             return;
322           }
323         op_end++;
324         b = parse_register_operand (&op_end);
325         if (*op_end != ')')
326           {
327             as_bad (_("missing closing parenthesis"));
328             ignore_rest_of_line ();
329             return;
330           }
331         op_end++;
332         iword += (a << 4) + b;
333         while (ISSPACE (*op_end))
334           op_end++;
335         if (*op_end != 0)
336           as_warn (_("extra stuff on line ignored"));
337       }
338       break;
339     case MOXIE_F1_AiB:
340       iword = opcode->opcode << 8;
341       while (ISSPACE (*op_end))
342         op_end++;
343       {
344         int a, b;
345         if (*op_end != '(')
346           {
347             as_bad (_("expecting indirect register `($rA)'"));
348             ignore_rest_of_line ();
349             return;
350           }
351         op_end++;
352         a = parse_register_operand (&op_end);
353         if (*op_end != ')')
354           {
355             as_bad (_("missing closing parenthesis"));
356             ignore_rest_of_line ();
357             return;
358           }
359         op_end++;
360         if (*op_end != ',')
361           as_warn (_("expecting comma delimited register operands"));
362         op_end++;
363         b = parse_register_operand (&op_end);
364         iword += (a << 4) + b;
365         while (ISSPACE (*op_end))
366           op_end++;
367         if (*op_end != 0)
368           as_warn (_("extra stuff on line ignored"));
369       }
370       break;
371     case MOXIE_F1_4A:
372       iword = opcode->opcode << 8;
373       while (ISSPACE (*op_end))
374         op_end++;
375       {
376         expressionS arg;
377         char *where;
378         int a;
379
380         op_end = parse_exp_save_ilp (op_end, &arg);
381         where = frag_more (4);
382         fix_new_exp (frag_now,
383                      (where - frag_now->fr_literal),
384                      4,
385                      &arg,
386                      0,
387                      BFD_RELOC_32);
388
389         if (*op_end != ',')
390           {
391             as_bad (_("expecting comma delimited operands"));
392             ignore_rest_of_line ();
393             return;
394           }
395         op_end++;
396
397         a = parse_register_operand (&op_end);
398         while (ISSPACE (*op_end))
399           op_end++;
400         if (*op_end != 0)
401           as_warn (_("extra stuff on line ignored"));
402
403         iword += (a << 4);
404       }
405       break;
406     case MOXIE_F1_ABi4:
407       iword = opcode->opcode << 8;
408       while (ISSPACE (*op_end))
409         op_end++;
410       {
411         expressionS arg;
412         char *offset;
413         int a, b;
414
415         a = parse_register_operand (&op_end);
416         while (ISSPACE (*op_end))
417           op_end++;
418
419         if (*op_end != ',')
420           {
421             as_bad (_("expecting comma delimited operands"));
422             ignore_rest_of_line ();
423             return;
424           }
425         op_end++;
426
427         op_end = parse_exp_save_ilp (op_end, &arg);
428         offset = frag_more (4);
429         fix_new_exp (frag_now,
430                      (offset - frag_now->fr_literal),
431                      4,
432                      &arg,
433                      0,
434                      BFD_RELOC_32);
435
436         if (*op_end != '(')
437           {
438             as_bad (_("expecting indirect register `($rX)'"));
439             ignore_rest_of_line ();
440             return;
441           }
442         op_end++;
443         b = parse_register_operand (&op_end);
444         if (*op_end != ')')
445           {
446             as_bad (_("missing closing parenthesis"));
447             ignore_rest_of_line ();
448             return;
449           }
450         op_end++;
451
452         while (ISSPACE (*op_end))
453           op_end++;
454         if (*op_end != 0)
455           as_warn (_("extra stuff on line ignored"));
456
457         iword += (a << 4) + b;
458       }
459       break;
460     case MOXIE_F1_AiB4:
461       iword = opcode->opcode << 8;
462       while (ISSPACE (*op_end))
463         op_end++;
464       {
465         expressionS arg;
466         char *offset;
467         int a, b;
468
469         op_end = parse_exp_save_ilp (op_end, &arg);
470         offset = frag_more (4);
471         fix_new_exp (frag_now,
472                      (offset - frag_now->fr_literal),
473                      4,
474                      &arg,
475                      0,
476                      BFD_RELOC_32);
477
478         if (*op_end != '(')
479           {
480             as_bad (_("expecting indirect register `($rX)'"));
481             ignore_rest_of_line ();
482             return;
483           }
484         op_end++;
485         a = parse_register_operand (&op_end);
486         if (*op_end != ')')
487           {
488             as_bad (_("missing closing parenthesis"));
489             ignore_rest_of_line ();
490             return;
491           }
492         op_end++;
493
494         if (*op_end != ',')
495           {
496             as_bad (_("expecting comma delimited operands"));
497             ignore_rest_of_line ();
498             return;
499           }
500         op_end++;
501
502         b = parse_register_operand (&op_end);
503         while (ISSPACE (*op_end))
504           op_end++;
505
506         while (ISSPACE (*op_end))
507           op_end++;
508         if (*op_end != 0)
509           as_warn (_("extra stuff on line ignored"));
510
511         iword += (a << 4) + b;
512       }
513       break;
514     case MOXIE_F2_NARG:
515       iword = opcode->opcode << 12;
516       while (ISSPACE (*op_end))
517         op_end++;
518       if (*op_end != 0)
519         as_warn (_("extra stuff on line ignored"));
520       break;
521     case MOXIE_F3_PCREL:
522       iword = (3<<14) | (opcode->opcode << 10);
523       while (ISSPACE (*op_end))
524         op_end++;
525       {
526         expressionS arg;
527
528         op_end = parse_exp_save_ilp (op_end, &arg);
529         fix_new_exp (frag_now,
530                      (p - frag_now->fr_literal),
531                      2,
532                      &arg,
533                      TRUE,
534                      BFD_RELOC_MOXIE_10_PCREL);
535       }
536       break;
537     default:
538       abort ();
539     }
540
541   md_number_to_chars (p, iword, 2);
542
543   while (ISSPACE (*op_end))
544     op_end++;
545
546   if (*op_end != 0)
547     as_warn (_("extra stuff on line ignored"));
548
549   if (pending_reloc)
550     as_bad (_("Something forgot to clean up\n"));
551 }
552
553 /* Turn a string in input_line_pointer into a floating point constant
554    of type type, and store the appropriate bytes in *LITP.  The number
555    of LITTLENUMS emitted is stored in *SIZEP .  An error message is
556    returned, or NULL on OK.  */
557
558 char *
559 md_atof (int type, char *litP, int *sizeP)
560 {
561   int prec;
562   LITTLENUM_TYPE words[4];
563   char *t;
564   int i;
565
566   switch (type)
567     {
568     case 'f':
569       prec = 2;
570       break;
571
572     case 'd':
573       prec = 4;
574       break;
575
576     default:
577       *sizeP = 0;
578       return _("bad call to md_atof");
579     }
580
581   t = atof_ieee (input_line_pointer, type, words);
582   if (t)
583     input_line_pointer = t;
584
585   *sizeP = prec * 2;
586
587   for (i = prec - 1; i >= 0; i--)
588     {
589       md_number_to_chars (litP, (valueT) words[i], 2);
590       litP += 2;
591     }
592
593   return NULL;
594 }
595
596 enum options
597 {
598   OPTION_EB = OPTION_MD_BASE,
599   OPTION_EL,
600 };
601
602 struct option md_longopts[] =
603 {
604   { "EB",          no_argument, NULL, OPTION_EB},
605   { "EL",          no_argument, NULL, OPTION_EL},
606   { NULL,          no_argument, NULL, 0}
607 };
608
609 size_t md_longopts_size = sizeof (md_longopts);
610 \f
611 const char *md_shortopts = "";
612
613 int
614 md_parse_option (int c ATTRIBUTE_UNUSED, char *arg ATTRIBUTE_UNUSED)
615 {
616   switch (c)
617     {
618     case OPTION_EB: 
619       target_big_endian = 1; 
620       moxie_target_format = "elf32-bigmoxie";
621       break;
622     case OPTION_EL: 
623       target_big_endian = 0;
624       moxie_target_format = "elf32-littlemoxie";
625       break;
626     default:        
627       return 0;
628     }
629
630   return 1;
631 }
632
633 void
634 md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
635 {
636   fprintf (stream, _("\
637   -EB                     assemble for a big endian system (default)\n\
638   -EL                     assemble for a little endian system\n"));
639 }
640
641 /* Apply a fixup to the object file.  */
642
643 void
644 md_apply_fix (fixS *fixP ATTRIBUTE_UNUSED, 
645               valueT * valP ATTRIBUTE_UNUSED, segT seg ATTRIBUTE_UNUSED)
646 {
647   char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
648   long val = *valP;
649   long newval;
650   long max, min;
651
652   max = min = 0;
653   switch (fixP->fx_r_type)
654     {
655     case BFD_RELOC_32:
656       if (target_big_endian)
657         {
658           buf[0] = val >> 24;
659           buf[1] = val >> 16;
660           buf[2] = val >> 8;
661           buf[3] = val >> 0;
662         }
663       else
664         {
665           buf[3] = val >> 24;
666           buf[2] = val >> 16;
667           buf[1] = val >> 8;
668           buf[0] = val >> 0;
669         }
670       buf += 4;
671       break;
672
673     case BFD_RELOC_16:
674       if (target_big_endian)
675         {
676           buf[0] = val >> 8;
677           buf[1] = val >> 0;
678         }
679       else
680         {
681           buf[1] = val >> 8;
682           buf[0] = val >> 0;
683         }
684       buf += 2;
685       break;
686
687     case BFD_RELOC_8:
688       *buf++ = val;
689       break;
690
691     case BFD_RELOC_MOXIE_10_PCREL:
692       if (!val)
693         break;
694       if (val < -1024 || val > 1022)
695         as_bad_where (fixP->fx_file, fixP->fx_line,
696                       _("pcrel too far BFD_RELOC_MOXIE_10"));
697       /* 11 bit offset even numbered, so we remove right bit.  */
698       val >>= 1;
699       newval = md_chars_to_number (buf, 2);
700       newval |= val & 0x03ff;
701       md_number_to_chars (buf, newval, 2);
702       break;
703
704     default:
705       abort ();
706     }
707
708   if (max != 0 && (val < min || val > max))
709     as_bad_where (fixP->fx_file, fixP->fx_line, _("offset out of range"));
710
711   if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
712     fixP->fx_done = 1;
713 }
714
715 /* Put number into target byte order.  */
716
717 void
718 md_number_to_chars (char * ptr, valueT use, int nbytes)
719 {
720   if (target_big_endian)
721     number_to_chars_bigendian (ptr, use, nbytes);
722   else
723     number_to_chars_littleendian (ptr, use, nbytes);
724 }
725
726 /* Convert from target byte order to host byte order.  */
727
728 static valueT
729 md_chars_to_number (char * buf, int n)
730 {
731   valueT result = 0;
732   unsigned char * where = (unsigned char *) buf;
733
734   if (target_big_endian)
735     {
736       while (n--)
737         {
738           result <<= 8;
739           result |= (*where++ & 255);
740         }
741     }
742   else
743     {
744       while (n--)
745         {
746           result <<= 8;
747           result |= (where[n] & 255);
748         }
749     }
750
751   return result;
752 }
753
754 /* Generate a machine-dependent relocation.  */
755 arelent *
756 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
757 {
758   arelent *relP;
759   bfd_reloc_code_real_type code;
760
761   switch (fixP->fx_r_type)
762     {
763     case BFD_RELOC_32:
764       code = fixP->fx_r_type;
765       break;
766     case BFD_RELOC_MOXIE_10_PCREL:
767       code = fixP->fx_r_type;
768       break;
769     default:
770       as_bad_where (fixP->fx_file, fixP->fx_line,
771                     _("Semantics error.  This type of operand can not be relocated, it must be an assembly-time constant"));
772       return 0;
773     }
774
775   relP = xmalloc (sizeof (arelent));
776   gas_assert (relP != 0);
777   relP->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
778   *relP->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
779   relP->address = fixP->fx_frag->fr_address + fixP->fx_where;
780
781   relP->addend = fixP->fx_offset;
782
783   /* This is the standard place for KLUDGEs to work around bugs in
784      bfd_install_relocation (first such note in the documentation
785      appears with binutils-2.8).
786
787      That function bfd_install_relocation does the wrong thing with
788      putting stuff into the addend of a reloc (it should stay out) for a
789      weak symbol.  The really bad thing is that it adds the
790      "segment-relative offset" of the symbol into the reloc.  In this
791      case, the reloc should instead be relative to the symbol with no
792      other offset than the assembly code shows; and since the symbol is
793      weak, any local definition should be ignored until link time (or
794      thereafter).
795      To wit:  weaksym+42  should be weaksym+42 in the reloc,
796      not weaksym+(offset_from_segment_of_local_weaksym_definition)
797
798      To "work around" this, we subtract the segment-relative offset of
799      "known" weak symbols.  This evens out the extra offset.
800
801      That happens for a.out but not for ELF, since for ELF,
802      bfd_install_relocation uses the "special function" field of the
803      howto, and does not execute the code that needs to be undone.  */
804
805   if (OUTPUT_FLAVOR == bfd_target_aout_flavour
806       && fixP->fx_addsy && S_IS_WEAK (fixP->fx_addsy)
807       && ! bfd_is_und_section (S_GET_SEGMENT (fixP->fx_addsy)))
808     {
809       relP->addend -= S_GET_VALUE (fixP->fx_addsy);
810     }
811
812   relP->howto = bfd_reloc_type_lookup (stdoutput, code);
813   if (! relP->howto)
814     {
815       const char *name;
816
817       name = S_GET_NAME (fixP->fx_addsy);
818       if (name == NULL)
819         name = _("<unknown>");
820       as_fatal (_("Cannot generate relocation type for symbol %s, code %s"),
821                 name, bfd_get_reloc_code_name (code));
822     }
823
824   return relP;
825 }
826
827 /* Decide from what point a pc-relative relocation is relative to,
828    relative to the pc-relative fixup.  Er, relatively speaking.  */
829 long
830 md_pcrel_from (fixS *fixP)
831 {
832   valueT addr = fixP->fx_where + fixP->fx_frag->fr_address;
833
834   switch (fixP->fx_r_type)
835     {
836     case BFD_RELOC_32:
837       return addr + 4;
838     case BFD_RELOC_MOXIE_10_PCREL:
839       /* Offset is from the end of the instruction.  */
840       return addr + 2;
841     default:
842       abort ();
843       return addr;
844     }
845 }