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