]> Git Repo - binutils.git/blob - gas/config/tc-xgate.c
gas/
[binutils.git] / gas / config / tc-xgate.c
1 /* tc-xgate.c -- Assembler code for Freescale XGATE
2    Copyright 2010, 2011, 2012
3    Free Software Foundation, Inc.
4    Contributed by Sean Keys <[email protected]>
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 3, or (at your option)
11    any later version.
12
13    GAS is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with GAS; see the file COPYING.  If not, write to
20    the Free Software Foundation, 51 Franklin Street - Fifth Floor,
21    Boston, MA 02110-1301, USA.  */
22
23 #include "as.h"
24 #include "safe-ctype.h"
25 #include "subsegs.h"
26 #include "opcode/xgate.h"
27 #include "dwarf2dbg.h"
28 #include "elf/xgate.h"
29
30 const char comment_chars[] = ";!";
31 const char line_comment_chars[] = "#*";
32 const char line_separator_chars[] = "";
33 const char EXP_CHARS[] = "eE";
34 const char FLT_CHARS[] = "dD";
35
36 #define SIXTEENTH_BIT   0x8000
37 #define N_BITS_IN_WORD  16
38
39 /* #define STATE_CONDITIONAL_BRANCH             (1) */
40 #define STATE_PC_RELATIVE       (2)
41 #define REGISTER_P(ptr)         (ptr == 'r')
42 #define INCREMENT               01
43 #define DECREMENT               02
44 #define MAXREGISTER             07
45 #define MINREGISTER             00
46
47 #define OPTION_MMCU 'm'
48
49 /* This macro has no side-effects.  */
50 #define ENCODE_RELAX(what,length) (((what) << 2) + (length))
51
52 /* Each unique opcode name has a handle.  That handle may
53    contain pointers to opcodes with the same name but
54    different address modes.  */
55 struct xgate_opcode_handle
56 {
57   int number_of_modes;
58   char *name;
59   struct xgate_opcode *opc0[MAX_OPCODES];
60 };
61
62 /*  LOCAL FUNCTIONS */
63 static char *
64 xgate_parse_exp (char *, expressionS *);
65 static inline char *
66 skip_whitespace (char *);
67 static void
68 get_default_target (void);
69 static char *
70 extract_word (char *, char *, int);
71 static char *
72 xgate_new_instruction (int size);
73 unsigned short
74 xgate_apply_operand (unsigned short, unsigned short *, unsigned short,
75     unsigned char);
76 void
77 xgate_operands (struct xgate_opcode *, char **);
78 static unsigned int
79 xgate_operand (struct xgate_opcode *, int *, int where, char **, char **);
80 static struct xgate_opcode *
81 xgate_find_match (struct xgate_opcode_handle *, int, unsigned int);
82 static int
83 cmp_opcode (struct xgate_opcode *, struct xgate_opcode *);
84 unsigned int
85 xgate_detect_format (char *);
86 void
87 xgate_print_syntax (char *);
88 void
89 xgate_print_table (void);
90
91 /* LOCAL DATA */
92 static struct hash_control *xgate_hash;
93
94 /* Previous opcode.  */
95 static unsigned int prev = 0;
96
97 static unsigned char fixup_required = 0;
98
99 /* Used to enable clipping of 16 bit operands into 8 bit constraints.  */
100 static unsigned char macroClipping = 0; 
101
102 static char oper_check;
103 static char flag_print_insn_syntax = 0;
104 static char flag_print_opcodes = 0;
105
106 static int current_architecture;
107 static const char *default_cpu;
108
109 /* ELF flags to set in the output file header.  */
110 static int elf_flags = E_XGATE_F64;
111
112 /* This table describes how you change sizes for the various types of variable
113    size expressions.  This version only supports two kinds.  */
114
115 /* The fields are:
116    How far Forward this mode will reach.
117    How far Backward this mode will reach.
118    How many bytes this mode will add to the size of the frag.
119    Which mode to go to if the offset won't fit in this one.  */
120
121 relax_typeS md_relax_table[] =
122 {
123   {1, 1, 0, 0},                 /* First entries aren't used.  */
124   {1, 1, 0, 0},                 /* For no good reason except.  */
125   {1, 1, 0, 0},                 /* that the VAX doesn't either.  */
126   {1, 1, 0, 0},
127   /* XGATE 9 and 10 bit pc rel todo complete and test */
128 /*{(511), (-512), 0, ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD)},
129   {(1023), (-1024), 0, ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD)}, */
130   {0, 0, 0, 0}
131 };
132
133 /* XGATE's registers all are 16-bit general purpose.  They are numbered according to the specifications.  */
134 typedef enum register_id
135 {
136   REG_NONE = -1,
137   REG_R0 = 0,
138   REG_R1 = 1,
139   REG_R2 = 2,
140   REG_R3 = 3,
141   REG_R4 = 4,
142   REG_R5 = 5,
143   REG_R6 = 6,
144   REG_R7 = 7,
145   REG_PC = 8,
146   REG_CCR = 9
147 } register_id;
148
149 /* This table describes all the machine specific pseudo-ops the assembler
150    has to support.  The fields are: pseudo-op name without dot function to
151    call to execute this pseudo-op Integer arg to pass to the function.  */
152 const pseudo_typeS md_pseudo_table[] =
153 {
154   /* The following pseudo-ops are supported for MRI compatibility.  */
155   {0, 0, 0}
156 };
157
158 const char *md_shortopts = "m:";
159
160 struct option md_longopts[] =
161 {
162 #define OPTION_PRINT_INSN_SYNTAX  (OPTION_MD_BASE + 0)
163   { "print-insn-syntax", no_argument, NULL, OPTION_PRINT_INSN_SYNTAX },
164
165 #define OPTION_PRINT_OPCODES  (OPTION_MD_BASE + 1)
166   { "print-opcodes", no_argument, NULL, OPTION_PRINT_OPCODES },
167
168 #define OPTION_GENERATE_EXAMPLE  (OPTION_MD_BASE + 2)
169   { "generate-example", no_argument, NULL, OPTION_GENERATE_EXAMPLE },
170
171 #define OPTION_MSHORT  (OPTION_MD_BASE + 3)
172   { "mshort", no_argument, NULL, OPTION_MSHORT },
173
174 #define OPTION_MLONG  (OPTION_MD_BASE + 4)
175   { "mlong", no_argument, NULL, OPTION_MLONG },
176
177 #define OPTION_MSHORT_DOUBLE  (OPTION_MD_BASE + 5)
178   { "mshort-double", no_argument, NULL, OPTION_MSHORT_DOUBLE },
179
180 #define OPTION_MLONG_DOUBLE  (OPTION_MD_BASE + 6)
181   { "mlong-double", no_argument, NULL, OPTION_MLONG_DOUBLE },
182
183   { NULL, no_argument, NULL, 0 }
184 };
185
186 size_t md_longopts_size = sizeof(md_longopts);
187
188 char *
189 md_atof (int type, char *litP, int *sizeP)
190 {
191   return ieee_md_atof (type, litP, sizeP, TRUE);
192 }
193
194 int
195 md_parse_option (int c, char *arg)
196 {
197   switch (c)
198     {
199     case OPTION_MMCU:
200       if (strcasecmp (arg, "v1") == 0)
201         current_architecture = XGATE_V1;
202       else if (strcasecmp (arg, "v2") == 0)
203         current_architecture = XGATE_V2;
204       else if (strcasecmp (arg, "v3") == 0)
205         current_architecture = XGATE_V3;
206       else
207         as_bad (_(" architecture variant invalid"));
208       break;
209
210     case OPTION_PRINT_INSN_SYNTAX:
211       flag_print_insn_syntax = 1;
212       break;
213
214     case OPTION_PRINT_OPCODES:
215       flag_print_opcodes = 1;
216       break;
217
218     case OPTION_GENERATE_EXAMPLE:
219       flag_print_opcodes = 2;
220       break;
221
222     case OPTION_MSHORT:
223       elf_flags &= ~E_XGATE_I32;
224       break;
225
226     case OPTION_MLONG:
227       elf_flags |= E_XGATE_I32;
228       break;
229
230     case OPTION_MSHORT_DOUBLE:
231       elf_flags &= ~E_XGATE_F64;
232       break;
233
234     case OPTION_MLONG_DOUBLE:
235       elf_flags |= E_XGATE_F64;
236       break;
237
238     default:
239       return 0;
240     }
241   return 1;
242 }
243
244 const char *
245 xgate_arch_format (void)
246 {
247   get_default_target ();
248
249   if (current_architecture & cpuxgate)
250     return "elf32-xgate";
251
252   return "error";
253 }
254
255 static void
256 get_default_target (void)
257 {
258   const bfd_target *target;
259   bfd abfd;
260
261   if (current_architecture != 0)
262     return;
263
264   default_cpu = "unknown";
265   target = bfd_find_target (0, &abfd);
266
267   if (target && target->name)
268     {
269       if (strcmp (target->name, "elf32-xgate") == 0)
270         {
271           current_architecture = cpuxgate;
272           default_cpu = "XGATE V1";
273           return;
274         }
275
276       as_bad (_("Default target `%s' is not supported."), target->name);
277     }
278 }
279
280 void
281 md_begin (void)
282 {
283   struct xgate_opcode *xgate_opcode_ptr = NULL;
284   struct xgate_opcode *xgate_op_table = NULL;
285   struct xgate_opcode_handle *op_handles = 0;
286   char *prev_op_name = 0;
287   int handle_enum = 0;
288   int number_of_op_handles = 0;
289   int i, j = 0;
290
291   /* Create a local copy of our opcode table
292      including an extra line for NULL termination.  */
293   xgate_op_table = (struct xgate_opcode *)
294     xmalloc ((xgate_num_opcodes) * sizeof (struct xgate_opcode));
295
296   memset (xgate_op_table, 0,
297           sizeof(struct xgate_opcode) * (xgate_num_opcodes));
298
299   for (xgate_opcode_ptr = (struct xgate_opcode*) xgate_opcodes, i = 0;
300       i < xgate_num_opcodes; i++)
301     xgate_op_table[i] = xgate_opcode_ptr[i];
302
303   qsort (xgate_op_table, xgate_num_opcodes, sizeof(struct xgate_opcode),
304          (int (*)(const void *, const void *)) cmp_opcode);
305
306   /* Calculate number of handles since this will be
307      smaller than the raw number of opcodes in the table.  */
308   prev_op_name = "";
309   for (xgate_opcode_ptr = xgate_op_table, i = 0;  i < xgate_num_opcodes;
310       xgate_opcode_ptr++, i++)
311     {
312       if (strcmp (prev_op_name, xgate_opcode_ptr->name))
313         number_of_op_handles++;
314       prev_op_name = xgate_opcode_ptr->name;
315     }
316
317   op_handles = (struct xgate_opcode_handle *)
318     xmalloc (sizeof(struct xgate_opcode_handle) * (number_of_op_handles));
319
320   /* Insert unique opcode names into hash table, aliasing duplicates.  */
321   xgate_hash = hash_new ();
322
323   prev_op_name = "";
324   for (xgate_opcode_ptr = xgate_op_table, i = 0, j = 0; i < xgate_num_opcodes;
325       i++, xgate_opcode_ptr++)
326     {
327       if (!strcmp (prev_op_name, xgate_opcode_ptr->name))
328         {
329           handle_enum++;
330           op_handles[j].opc0[handle_enum] = xgate_opcode_ptr;
331         }
332       else
333         {
334           handle_enum = 0;
335           if (i)
336             j++;
337           op_handles[j].name = xgate_opcode_ptr->name;
338           op_handles[j].opc0[0] = xgate_opcode_ptr;
339           hash_insert (xgate_hash, (char *) op_handles[j].name,
340               (char *) &(op_handles[j]));
341         }
342       op_handles[j].number_of_modes = handle_enum;
343       prev_op_name = op_handles[j].name;
344     }
345
346   if (flag_print_opcodes == 1)
347     xgate_print_table ();
348 }
349
350 void
351 xgate_init_after_args (void)
352 {
353 }
354
355 void
356 md_show_usage (FILE * stream)
357 {
358   get_default_target ();
359
360   fprintf (
361            stream,
362            _("\
363       Freescale XGATE co-processor options:\n                   \
364        -mshort                 use 16-bit int ABI (default)\n   \
365        -mlong                  use 32-bit int ABI\n             \
366        -mshort-double          use 32-bit double ABI\n                  \
367        -mlong-double           use 64-bit double ABI (default)\n\
368       --mxgate                 specify the processor variant[default %s]\n\
369       --print-insn-syntax     print the syntax of instruction in case of error\n\
370       --print-opcodes         print the list of instructions with syntax\n\
371       --generate-example      generate an example of each instruction"),
372            default_cpu);
373 }
374
375 enum bfd_architecture
376 xgate_arch (void)
377 {
378   get_default_target ();
379   return bfd_arch_xgate;
380 }
381
382 int
383 xgate_mach (void)
384 {
385   return 0;
386 }
387
388 void
389 xgate_print_syntax (char *name)
390 {
391   int i;
392
393   for (i = 0; i < xgate_num_opcodes; i++)
394     {
395       if (!strcmp (xgate_opcodes[i].name, name))
396         {
397           if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IDR))
398             printf ("\tFormat is %s\tRx, Rx, Rx+|-Rx|Rx\n",
399                     xgate_opcodes[i].name);
400           if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_INH))
401             printf ("\tFormat is %s\n", xgate_opcodes[i].name);
402           if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_TRI))
403             printf ("\tFormat is %s\tRx, Rx, Rx\n", xgate_opcodes[i].name);
404           if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_DYA))
405             printf ("\tFormat is %s\tRx, Rx\n", xgate_opcodes[i].name);
406           if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_DYA_MON)
407               || !strcmp (xgate_opcodes[i].constraints, XGATE_OP_MON))
408             printf ("\tFormat is %s\tRx\n", xgate_opcodes[i].name);
409           if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM3))
410             printf ("\tFormat is %s\t<3-bit value>\n", xgate_opcodes[i].name);
411           if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM4))
412             printf ("\tFormat is %s\t<4 -bit value>\n", xgate_opcodes[i].name);
413           if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM8))
414             printf ("\tFormat is %s\tRx, <8-bit value>\n",
415                     xgate_opcodes[i].name);
416           if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM16))
417             printf ("\tFormat is %s\tRx, <16-bit value>\n",
418                     xgate_opcodes[i].name);
419           if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_MON_R_C))
420             printf ("\tFormat is %s\tRx, CCR\n", xgate_opcodes[i].name);
421           if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_MON_C_R))
422             printf ("\tFormat is %s\tCCR, Rx\n", xgate_opcodes[i].name);
423           if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_MON_R_P))
424             printf ("\tFormat is %s\tRx, PC\n", xgate_opcodes[i].name);
425           if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM16mLDW))
426             printf ("\tFormat is %s\tRx, <16-bit value>\n",
427                     xgate_opcodes[i].name);
428         }
429     }
430 }
431
432 void
433 xgate_print_table (void)
434 {
435   int i;
436
437   for (i = 0; i < xgate_num_opcodes; i++)
438     xgate_print_syntax (xgate_opcodes[i].name);
439
440   return;
441 }
442
443 const char *
444 xgate_listing_header (void)
445 {
446   if (current_architecture & cpuxgate)
447     return "XGATE GAS ";
448
449   return "ERROR MC9S12X GAS ";
450 }
451
452 symbolS *
453 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
454 {
455   return 0;
456 }
457
458 /* GAS will call this function for each section at the end of the assembly,
459    to permit the CPU backend to adjust the alignment of a section.  */
460
461 valueT
462 md_section_align (asection * seg, valueT addr)
463 {
464   int align = bfd_get_section_alignment (stdoutput, seg);
465   return ((addr + (1 << align) - 1) & (-1 << align));
466 }
467
468 void
469 md_assemble (char *input_line)
470 {
471   struct xgate_opcode *opcode = 0;
472   struct xgate_opcode *macro_opcode = 0;
473   struct xgate_opcode_handle *opcode_handle = 0;
474   /* Caller expects it to be returned as it was passed.  */
475   char *saved_input_line = input_line;
476   char op_name[9] =  { 0 };
477   unsigned int sh_format = 0;
478   char *p = 0;
479
480   fixup_required = 0;
481   oper_check = 0; /* set error flags */
482   input_line = extract_word (input_line, op_name, sizeof(op_name));
483
484   /* Check to make sure we are not reading a bogus line.  */
485   if (!op_name[0])
486     as_bad (_("opcode missing or not found on input line"));
487
488   if (!(opcode_handle = (struct xgate_opcode_handle *) hash_find (xgate_hash,
489       op_name)))
490     {
491       as_bad (_("opcode %s not found in opcode hash table"), op_name);
492     }
493   else
494     {
495       /* Detect operand format so we can pull the proper opcode bin.  */
496       sh_format = xgate_detect_format (input_line);
497
498       opcode = xgate_find_match (opcode_handle, opcode_handle->number_of_modes,
499           sh_format);
500
501       if (!opcode)
502         {
503           as_bad (_("matching operands to opcode "));
504           xgate_print_syntax (opcode_handle->opc0[0]->name);
505         }
506       else if (opcode->size == 2)
507         {
508           /* Size is one word - assemble that native insn.  */
509           xgate_operands (opcode, &input_line);
510         }
511       else
512         {
513           /* Insn is a simplified instruction - expand it out.  */
514           macroClipping = 1;
515           unsigned int i;
516
517           /* skip past our ';' separator.  */
518           for (i = strlen (opcode->constraints), p = opcode->constraints; i > 0;
519               i--, p++)
520             {
521               if (*p == ';')
522                 {
523                   p++;
524                   break;
525                 }
526             }
527           input_line = skip_whitespace (input_line);
528           char *macro_inline = input_line;
529
530           /* Loop though the macro's opcode list and apply operands to each real opcode. */
531           for (i = 0; *p && i < (opcode->size / 2); i++)
532             {
533               /* Loop though macro operand list.  */
534               input_line = macro_inline; /* Rewind.  */
535               p = extract_word (p, op_name, 10);
536
537               if (!(opcode_handle = (struct xgate_opcode_handle *)
538                     hash_find (xgate_hash, op_name)))
539                 {
540                   as_bad (
541                       _(": processing macro, real opcode handle not found in hash"));
542                   break;
543                 }
544               else
545                 {
546                   sh_format = xgate_detect_format (input_line);
547                   macro_opcode = xgate_find_match (opcode_handle,
548                       opcode_handle->number_of_modes, sh_format);
549                   xgate_operands (macro_opcode, &input_line);
550                 }
551             }
552         }
553     }
554   macroClipping = 0;
555   input_line = saved_input_line;
556 }
557
558 /* Force truly undefined symbols to their maximum size, and generally set up
559    the frag list to be relaxed.  */
560
561 int
562 md_estimate_size_before_relax (fragS *fragp, asection *seg)
563 {
564   /* If symbol is undefined or located in a different section,
565      select the largest supported relocation.  */
566   relax_substateT subtype;
567   relax_substateT rlx_state[] =
568     { 0, 2 };
569
570   for (subtype = 0; subtype < ARRAY_SIZE (rlx_state); subtype += 2)
571     {
572       if (fragp->fr_subtype == rlx_state[subtype]
573           && (!S_IS_DEFINED (fragp->fr_symbol)
574               || seg != S_GET_SEGMENT (fragp->fr_symbol)))
575         {
576           fragp->fr_subtype = rlx_state[subtype + 1];
577           break;
578         }
579     }
580
581   if (fragp->fr_subtype >= ARRAY_SIZE (md_relax_table))
582     abort ();
583
584   return md_relax_table[fragp->fr_subtype].rlx_length;
585 }
586
587
588 /* Relocation, relaxation and frag conversions.  */
589
590 /* PC-relative offsets are relative to the start of the
591    next instruction.  That is, the address of the offset, plus its
592    size, since the offset is always the last part of the insn.  */
593
594 long
595 md_pcrel_from (fixS * fixP)
596 {
597   return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
598 }
599
600 /* If while processing a fixup, a reloc really needs to be created
601    then it is done here.  */
602
603 arelent *
604 tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
605 {
606   arelent * reloc;
607
608   reloc = (arelent *) xmalloc (sizeof(arelent));
609   reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof(asymbol *));
610   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
611   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
612
613   if (fixp->fx_r_type == 0)
614     {
615       reloc->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_16);
616     }
617   else
618     {
619       reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
620     }
621
622   if (reloc->howto == (reloc_howto_type *) NULL)
623     {
624       as_bad_where (fixp->fx_file, fixp->fx_line, _
625       ("Relocation %d is not supported by object file format."),
626           (int) fixp->fx_r_type);
627       return NULL;
628     }
629
630   /* Since we use Rel instead of Rela, encode the vtable entry to be
631      used in the relocation's section offset.  */
632   if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
633     reloc->address = fixp->fx_offset;
634   reloc->addend = 0;
635   return reloc;
636 }
637
638 /* Patch the instruction with the resolved operand.  Elf relocation
639    info will also be generated to take care of linker/loader fixups.
640    The XGATE addresses only 16-bit addresses.The BFD_RELOC_32 is necessary
641    for the support of --gstabs.  */
642
643 void
644 md_apply_fix (fixS * fixP, valueT * valP, segT seg ATTRIBUTE_UNUSED)
645 {
646   char *where;
647   long value = *valP;
648   int opcode = 0;
649   ldiv_t result;
650
651   /* If the fixup is done mark it done so no further symbol resolution will take place.  */
652   if (fixP->fx_addsy == (symbolS *) NULL)
653     {
654       fixP->fx_done = 1;
655     }
656
657   /* We don't actually support subtracting a symbol.  */
658   if (fixP->fx_subsy != (symbolS *) NULL)
659     as_bad_where (fixP->fx_file, fixP->fx_line, _("Expression too complex."));
660
661   where = fixP->fx_frag->fr_literal + fixP->fx_where;
662   opcode = bfd_getl16 (where);
663   int mask = 0;
664
665   switch (fixP->fx_r_type)
666     {
667     case R_XGATE_PCREL_9:
668       if (value < -512 || value > 511)
669         as_bad_where (fixP->fx_file, fixP->fx_line,
670                       _("Value %ld too large for 9-bit PC-relative branch."), value);
671       result = ldiv (value, 2); /* from bytes to words */
672       value = result.quot;
673       if (result.rem)
674         as_bad_where (fixP->fx_file, fixP->fx_line, _
675                       ("Value %ld not aligned by 2 for 9-bit PC-relative branch."), value);
676       mask = 0x1FF; /* Clip into 8-bit field FIXME I'm sure there is a more proper place for this */
677       value &= mask;
678       number_to_chars_bigendian (where, (opcode | value), 2);
679       break;
680     case R_XGATE_PCREL_10:
681       if (value < -1024 || value > 1023)
682         as_bad_where (fixP->fx_file, fixP->fx_line,
683                       _("Value %ld too large for 10-bit PC-relative branch."), value);
684       result = ldiv (value, 2); /* from bytes to words */
685       value = result.quot;
686       if (result.rem)
687         as_bad_where (fixP->fx_file, fixP->fx_line, _
688                       ("Value %ld not aligned by 2 for 10-bit PC-relative branch."), value);
689       mask = 0x3FF; /* Clip into 9-bit field FIXME I'm sure there is a more proper place for this */
690       value &= mask;
691       number_to_chars_bigendian (where, (opcode | value), 2);
692       break;
693     case BFD_RELOC_XGATE_IMM8_HI:
694       if (value < -65537 || value > 65535)
695         as_bad_where (fixP->fx_file, fixP->fx_line,
696                       _("Value out of 16-bit range."));
697       value >>= 8;
698       value &= 0x00ff;
699       bfd_putb16 ((bfd_vma) value | opcode, (void *) where);
700       break;
701     case BFD_RELOC_XGATE_24:
702     case BFD_RELOC_XGATE_IMM8_LO:
703       if (value < -65537 || value > 65535)
704         as_bad_where (fixP->fx_file, fixP->fx_line,
705                       _("Value out of 16-bit range."));
706       value &= 0x00ff;
707       bfd_putb16 ((bfd_vma) value | opcode, (void *) where);
708       break;
709     case BFD_RELOC_XGATE_IMM3:
710       if (value < 0 || value > 7)
711         as_bad_where (fixP->fx_file, fixP->fx_line,
712                       _("Value out of 3-bit range."));
713       value <<= 8; /* make big endian */
714       number_to_chars_bigendian (where, (opcode | value), 2);
715       break;
716     case BFD_RELOC_XGATE_IMM4:
717       if (value < 0 || value > 15)
718         as_bad_where (fixP->fx_file, fixP->fx_line,
719                       _("Value out of 4-bit range."));
720       value <<= 4; /* align the operand bits */
721       number_to_chars_bigendian (where, (opcode | value), 2);
722       break;
723     case BFD_RELOC_XGATE_IMM5:
724       if (value < 0 || value > 31)
725         as_bad_where (fixP->fx_file, fixP->fx_line,
726                       _("Value out of 5-bit range."));
727       value <<= 5; /* align the operand bits */
728       number_to_chars_bigendian (where, (opcode | value), 2);
729       break;
730     case BFD_RELOC_8:
731       ((bfd_byte *) where)[0] = (bfd_byte) value;
732       break;
733     case BFD_RELOC_32:
734       bfd_putb32 ((bfd_vma) value, (unsigned char *) where);
735       /* todo figure out how to make BFD_RELOC_16 the default */
736       break;
737     case BFD_RELOC_16:
738       bfd_putb16 ((bfd_vma) value, (unsigned char *) where);
739       break;
740     default:
741       as_fatal (_("Line %d: unknown relocation type: 0x%x."), fixP->fx_line,
742                 fixP->fx_r_type);
743       break;
744     }
745 }
746
747 /* See whether we need to force a relocation into the output file.  */
748
749 int
750 tc_xgate_force_relocation (fixS * fixP)
751 {
752   if (fixP->fx_r_type == BFD_RELOC_XGATE_RL_GROUP)
753     return 1;
754   return generic_force_reloc (fixP);
755 }
756
757 /* Here we decide which fixups can be adjusted to make them relative
758    to the beginning of the section instead of the symbol.  Basically
759    we need to make sure that the linker relaxation is done
760    correctly, so in some cases we force the original symbol to be
761    used.  */
762
763 int
764 tc_xgate_fix_adjustable (fixS * fixP)
765 {
766   switch (fixP->fx_r_type)
767     {
768       /* For the linker relaxation to work correctly, these relocs
769          need to be on the symbol itself.  */
770     case BFD_RELOC_16:
771     case BFD_RELOC_XGATE_RL_JUMP:
772     case BFD_RELOC_XGATE_RL_GROUP:
773     case BFD_RELOC_VTABLE_INHERIT:
774     case BFD_RELOC_VTABLE_ENTRY:
775     case BFD_RELOC_32:
776       return 0;
777     default:
778       return 1;
779     }
780 }
781
782 void
783 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
784                  asection * sec ATTRIBUTE_UNUSED,
785                  fragS * fragP ATTRIBUTE_UNUSED)
786 {
787   as_bad (("md_convert_frag not implemented yet"));
788   abort ();
789 }
790
791 /* Set the ELF specific flags.  */
792
793 void
794 xgate_elf_final_processing (void)
795 {
796   elf_flags |= EF_XGATE_MACH;
797   elf_elfheader (stdoutput)->e_flags &= ~EF_XGATE_ABI;
798   elf_elfheader (stdoutput)->e_flags |= elf_flags;
799 }
800
801 static inline char *
802 skip_whitespace (char *s)
803 {
804   while (*s == ' ' || *s == '\t' || *s == '(' || *s == ')')
805     s++;
806
807   return s;
808 }
809
810 /* Extract a word (continuous alpha-numeric chars) from the input line.  */
811
812 static char *
813 extract_word (char *from, char *to, int limit)
814 {
815   char *op_end;
816   int size = 0;
817
818   /* Drop leading whitespace.  */
819   from = skip_whitespace (from);
820   *to = 0;
821   /* Find the op code end.  */
822   for (op_end = from; *op_end != 0 && is_part_of_name (*op_end);)
823     {
824       to[size++] = *op_end++;
825       if (size + 1 >= limit)
826         break;
827     }
828   to[size] = 0;
829   return op_end;
830 }
831
832 static char *
833 xgate_new_instruction (int size)
834 {
835   char *f = frag_more (size);
836   dwarf2_emit_insn (size);
837   return f;
838 }
839
840 unsigned short
841 xgate_apply_operand (unsigned short new_mask,
842                      unsigned short *availiable_mask_bits,
843                      unsigned short mask,
844                      unsigned char n_bits)
845 {
846   unsigned short n_shifts;
847   unsigned int n_drop_bits;
848
849   /* Shift until you find an available operand bit "1" and record the number of shifts.  */
850   for (n_shifts = 0;
851        !(*availiable_mask_bits & SIXTEENTH_BIT) && n_shifts < 16;
852        n_shifts++)
853     *availiable_mask_bits <<= 1;
854
855   /* Shift for the number of bits your operand requires while bits are available.  */
856   for (n_drop_bits = n_bits;
857        n_drop_bits && (*availiable_mask_bits & SIXTEENTH_BIT);
858        --n_drop_bits)
859     *availiable_mask_bits <<= 1;
860
861   if (n_drop_bits)
862     as_bad (_(":operand has too many bits"));
863   *availiable_mask_bits >>= n_shifts + n_bits;
864   if ((n_drop_bits == 0) && (*availiable_mask_bits == 0))
865     {
866       oper_check = 1; /* flag operand check as good */
867     }
868   new_mask <<= N_BITS_IN_WORD - (n_shifts + n_bits);
869   mask |= new_mask;
870   return mask;
871 }
872
873 /* Parse ordinary expression.  */
874
875 static char *
876 xgate_parse_exp (char *s, expressionS * op)
877 {
878   input_line_pointer = s;
879   expression(op);
880   if (op->X_op == O_absent)
881     as_bad (_("missing operand"));
882   return input_line_pointer;
883 }
884
885 /* For testing.  Comment out to prevent defined but not used warning
886
887 static unsigned int
888 xgate_get_constant(char *str, int max)
889 {
890   expressionS ex;
891
892   str = skip_whitespace(str);
893   input_line_pointer = str;
894   expression (& ex);
895
896   if (ex.X_op != O_constant)
897     as_bad(_("constant value required"));
898
899   if (ex.X_add_number > max || ex.X_add_number < 0)
900     as_bad(_("number must be positive and less than %d"), max + 1);
901
902   return ex.X_add_number;
903 }
904 */
905
906 static int
907 cmp_opcode (struct xgate_opcode *op1, struct xgate_opcode *op2)
908 {
909   return strcmp (op1->name, op2->name);
910 }
911
912 /* Parse instruction operands.  */
913
914 void
915 xgate_operands (struct xgate_opcode *opcode, char **line)
916 {
917   char *frag = xgate_new_instruction (opcode->size);
918   int where = frag - frag_now->fr_literal;
919   char *op = opcode->constraints;
920   unsigned int bin = (int) opcode->bin_opcode;
921   char *str = *line;
922   unsigned short oper_mask = 0;
923   int operand_bit_length = 0;
924   unsigned int operand = 0;
925   char n_operand_bits = 0;
926   char first_operand_equals_second = 0;
927   int i = 0;
928   char c = 0;
929
930   /* Generate available operand bits mask.  */
931   for (i = 0; (c = opcode->format[i]); i++)
932     {
933       if (ISDIGIT (c) || (c == 's'))
934         {
935           oper_mask <<= 1;
936         }
937       else
938         {
939           oper_mask <<= 1;
940           oper_mask += 1;
941           n_operand_bits++;
942         }
943     }
944
945   /* Opcode has operands.  */
946   /* Parse first operand.  */
947   if (*op)
948     {
949       if (*op == '=')
950         {
951           first_operand_equals_second = 1;
952           ++op;
953         }
954       operand = xgate_operand (opcode, &operand_bit_length, where, &op, &str);
955       ++op;
956       bin = xgate_apply_operand (operand, &oper_mask, bin, operand_bit_length);
957       /* Parse second operand.  */
958       if (*op)
959         {
960           if (*op == ',')
961             ++op;
962           str = skip_whitespace (str);
963           if (*str++ != ',')
964             {
965               if (first_operand_equals_second)
966                 {
967                   bin = xgate_apply_operand (operand, &oper_mask, bin,
968                       operand_bit_length);
969                   ++op;
970                 }
971               else
972                 {
973                   as_bad (_("`,' required before second operand"));
974                 }
975             }
976           else
977             {
978               str = skip_whitespace (str);
979               operand = xgate_operand (opcode, &operand_bit_length, where, &op,
980                   &str);
981               bin = xgate_apply_operand (operand, &oper_mask, bin,
982                   operand_bit_length);
983               ++op;
984             }
985         }
986
987       /* Parse the third register.  */
988       if (*op)
989         {
990           if (*op == ',')
991             ++op;
992           str = skip_whitespace (str);
993           if (*str++ != ',')
994             as_bad (_("`,' required before third operand"));
995           str = skip_whitespace (str);
996           operand = xgate_operand (opcode, &operand_bit_length, where, &op,
997               &str);
998           bin = xgate_apply_operand (operand, &oper_mask, bin,
999               operand_bit_length);
1000         }
1001     }
1002   if (opcode->size == 2 && fixup_required)
1003     {
1004       bfd_putl16 (bin, frag);
1005     }
1006   else if ((opcode->sh_format & XG_PCREL))
1007     {
1008       /* Write our data to a frag for further processing.  */
1009       bfd_putl16 (opcode->bin_opcode, frag); 
1010     }
1011   else
1012     {
1013       /* Apply operand mask(s)to bin opcode and write the output.  */
1014       /* Since we are done write this frag in xgate BE format.  */
1015       number_to_chars_bigendian (frag, bin, opcode->size); 
1016     }
1017   prev = bin;
1018   *line = str;
1019   return;
1020 }
1021
1022 static unsigned int
1023 xgate_operand (struct xgate_opcode *opcode,
1024                int *bit_width,
1025                int where,
1026                char **op_con,
1027                char **line)
1028 {
1029   expressionS op_expr;
1030   fixS *fixp = 0;
1031   char *op_constraint = *op_con;
1032   unsigned int op_mask = 0;
1033   char *str = skip_whitespace (*line);
1034   char r_name[20] =
1035     { 0 };
1036   unsigned int pp_fix = 0;
1037   unsigned short max_size = 0;
1038   int i;
1039
1040   *bit_width = 0;
1041   /* Reset.  */
1042
1043   switch (*op_constraint)
1044     {
1045     case '+': /* Indexed register operand +/- or plain r.  */
1046       /* TODO should be able to combine with with case R.  */
1047
1048       /* Default to neither inc or dec.  */
1049       pp_fix = 0;
1050       *bit_width = 5;
1051       str = skip_whitespace (str);
1052       while (*str != ' ' && *str != '\t')
1053         {
1054           if (*str == '-')
1055             pp_fix = DECREMENT;
1056           else if (*str == '+')
1057             pp_fix = INCREMENT;
1058           else if (*str == 'r' || *str == 'R')
1059             {
1060               str = extract_word (str, r_name, sizeof(r_name));
1061               if (ISDIGIT (r_name[1]))
1062                 {
1063                   if (r_name[2] == '\0' && (r_name[1] - '0' < 8))
1064                     op_mask = r_name[1] - '0';
1065                   if (r_name[2] != '\0' && (r_name[1] - '0' > 7))
1066                     as_bad (_(": expected register name r0-r7 read %s"), r_name);
1067                   continue;
1068                 }
1069             }
1070           str++;
1071         }
1072       op_mask <<= 2;
1073       op_mask |= pp_fix;
1074       break;
1075
1076     case 'r': /* Register operand.  */
1077       if (*str == 'r' || *str == 'R')
1078         {
1079           *bit_width = 3;
1080           str = extract_word (str, r_name, sizeof(r_name));
1081           op_mask = 0xff;
1082           if (ISDIGIT (r_name[1]))
1083             {
1084               if (r_name[2] == '\0')
1085                 op_mask = r_name[1] - '0';
1086               else if (r_name[1] != '0' && ISDIGIT (r_name[2])
1087                        && r_name[3] == '\0')
1088                 op_mask = (r_name[1] - '0') * 10 + r_name[2] - '0';
1089               if (op_mask > MAXREGISTER)
1090                 as_bad (_(": expected register name r0-r7 read %s "), r_name);
1091             }
1092         }
1093       else
1094         {
1095           as_bad (_(": expected register name r0-r7 read %s "), r_name);
1096         }
1097       break;
1098
1099     case 'i': /* Immediate value or expression expected.  */
1100       /* Advance the original format pointer.  */
1101       (*op_con)++;
1102       op_constraint++;
1103       if (ISDIGIT (*op_constraint))
1104         {
1105           *bit_width = (int) *op_constraint - '0';
1106         }
1107       else if (*op_constraint == 'a')
1108         {
1109           *bit_width = 0x0A;
1110         }
1111       else if (*op_constraint == 'f')
1112         {
1113           *bit_width = 0x0F;
1114         }
1115       /* http://tigcc.ticalc.org/doc/gnuasm.html#SEC31 */
1116       if (*str == '#')
1117         str++;
1118       str = xgate_parse_exp (str, &op_expr);
1119       if (op_expr.X_op == O_constant)
1120         {
1121           if (!ISDIGIT (*op_constraint))
1122             as_bad (
1123                     _(":expected bit length with constraint type i(# immediate) read %c"),
1124                     *op_constraint);
1125           op_mask = op_expr.X_add_number;
1126           if ((opcode->name[strlen (opcode->name) - 1] == 'l') && macroClipping)
1127             {
1128               op_mask &= 0x00FF;
1129             }
1130           else if ((opcode->name[strlen (opcode->name) - 1]) == 'h'
1131                    && macroClipping)
1132             {
1133               op_mask >>= 8;
1134             }
1135
1136           /* Make sure it fits.  */
1137           for (i = *bit_width; i; i--)
1138             {
1139               max_size <<= 1;
1140               max_size += 1;
1141             }
1142           if (op_mask > max_size)
1143             as_bad (_(":operand value(%d) too big for constraint"), op_mask);
1144         }
1145       else
1146         {
1147           fixup_required = 1;
1148           if (*op_constraint == '8')
1149             {
1150               if ((opcode->name[strlen (opcode->name) - 1] == 'l')
1151                   && macroClipping)
1152                 {
1153                   fixp = fix_new_exp (frag_now, where, 2, &op_expr, FALSE,
1154                                       BFD_RELOC_XGATE_24);
1155                   /* Should be BFD_RELOC_XGATE_IMM8_LO TODO fix.  */
1156                   fixp->fx_pcrel_adjust = 0;
1157                 }
1158               if ((opcode->name[strlen (opcode->name) - 1]) == 'h'
1159                   && macroClipping)
1160                 {
1161                   fixp = fix_new_exp (frag_now, where, 2, &op_expr, FALSE,
1162                                       BFD_RELOC_XGATE_IMM8_HI);
1163                   fixp->fx_pcrel_adjust = 0;
1164                 }
1165               if (!fixp)
1166                 as_bad (_(":unknown relocation"));
1167             }
1168           else if (*op_constraint == '5')
1169             {
1170               fixp = fix_new_exp (frag_now, where, 2, &op_expr, FALSE,
1171                                   BFD_RELOC_XGATE_IMM5);
1172               fixp->fx_pcrel_adjust = 0;
1173             }
1174           else if (*op_constraint == '4')
1175             {
1176               fixp = fix_new_exp (frag_now, where, 2, &op_expr, FALSE,
1177                                   BFD_RELOC_XGATE_IMM4);
1178               fixp->fx_pcrel_adjust = 0;
1179             }
1180           else if (*op_constraint == '3')
1181             {
1182             fixp = fix_new_exp (frag_now, where, 2, &op_expr, FALSE,
1183                 BFD_RELOC_XGATE_IMM3);
1184             fixp->fx_pcrel_adjust = 0;
1185           }
1186         else
1187           {
1188             as_bad (_(":unknown relocation constraint size"));
1189           }
1190       }
1191     break;
1192
1193     case 'c': /* CCR register expected.  */
1194     if (*str == 'c' || *str == 'C')
1195       {
1196         *bit_width = 0;
1197         str = extract_word (str, r_name, sizeof(r_name));
1198         if (!(strcmp (r_name, "ccr") || strcmp (r_name, "CCR")))
1199           as_bad (_(": expected register name ccr read %s "), r_name);
1200       }
1201     else
1202       {
1203         as_bad (_(": expected character c or C  read %c"), *str);
1204       }
1205     break;
1206
1207     case 'p': /* PC register expected.  */
1208       if (*str == 'p' || *str == 'P')
1209         {
1210           *bit_width = 0;
1211           str = extract_word (str, r_name, sizeof(r_name));
1212           if (!(strcmp (r_name, "pc") || strcmp (r_name, "PC")))
1213             as_bad (_(": expected register name pc read %s "), r_name);
1214         }
1215       else
1216         {
1217           as_bad (_(": expected character p or P read %c "), *str);
1218         }
1219       break;
1220
1221     case 'b': /* Branch expected.  */
1222       str = xgate_parse_exp (str, &op_expr);
1223       (*op_con)++;
1224       op_constraint++;
1225       if (op_expr.X_op != O_register)
1226         {
1227           if (*op_constraint == '9')
1228             {
1229               /* mode == M68XG_OP_REL9 */
1230               fixp = fix_new_exp (frag_now, where, 2, &op_expr, TRUE,
1231                                   R_XGATE_PCREL_9);
1232               fixp->fx_pcrel_adjust = 1;
1233             }
1234           else if (*op_constraint == 'a')
1235             { /* mode == M68XG_OP_REL10 */
1236               fixp = fix_new_exp (frag_now, where, 2, &op_expr, TRUE,
1237                                   R_XGATE_PCREL_10);
1238               fixp->fx_pcrel_adjust = 1;
1239             }
1240         }
1241       else
1242         {
1243           as_fatal (_("Operand `%x' not recognized in fixup8."), op_expr.X_op);
1244         }
1245       break;
1246
1247     case '?':
1248       break;
1249
1250     default:
1251       as_bad (_("unknown constraint `%c'"), *op_constraint);
1252       break;
1253     }
1254   *line = str;
1255   return op_mask;
1256 }
1257
1258 unsigned int
1259 xgate_detect_format (char *line_in)
1260 {
1261   char num_operands = 0;
1262   char *str = skip_whitespace (line_in);
1263   int i = 0;
1264   int j = 0;
1265   char c = 0;
1266   unsigned int stripped_length = 0;
1267   char sh_format[10] =
1268     { 0 }; /* Shorthand format.  */
1269   char operands_stripped[3][20] =
1270     {
1271       { 0 }
1272     };
1273   /* Strings.  TODO maybe structure this.  */
1274   char *i_string =
1275     { "i" };
1276   char *r_string =
1277     { "r" };
1278   char *r_r_string =
1279     { "r,r" };
1280   char *r_r_r_string =
1281     { "r,r,r" };
1282   char *r_i_string =
1283     { "r,i" };
1284   char *r_c_string =
1285     { "r,c" };
1286   char *c_r_string =
1287     { "c,r" };
1288   char *r_p_string =
1289     { "r,p" };
1290   char *r_r_i_string =
1291     { "r,r,i" };
1292
1293   /* If the length is zero this is an inherent instruction.  */
1294   if (strlen (str) == 0)
1295     return XG_INH;
1296
1297   for (i = 0, j = 0, num_operands = 1; (c = TOLOWER (*str)) != 0; str++)
1298     {
1299       if (c == ' ' || c == '\t' || c == '(' || c == ')' || c == '-' || c == '+')
1300         continue;
1301
1302       if (c == ',')
1303         {
1304           j++;
1305           num_operands++;
1306           i = 0;
1307           continue;
1308         }
1309
1310       if (i > MAX_DETECT_CHARS)
1311         continue;
1312
1313       operands_stripped[j][i++] = c;
1314     }
1315
1316   /* Process our substrings to see what we have.  */
1317   for (i = 0, j = 0; num_operands > i; i++)
1318     {
1319       stripped_length = strlen (&operands_stripped[i][0]);
1320
1321       /* Add separator if we have more than one operand.  */
1322       if (i > 0)
1323         sh_format[j++] = ',';
1324
1325       /* Try to process by length first.  */
1326       if (stripped_length > 3)
1327         {
1328           sh_format[j++] = 'i';
1329         }
1330       else if (stripped_length == 1)
1331         {
1332           sh_format[j++] = 'i';
1333         }
1334       else if (stripped_length == 2)
1335         {
1336           if (operands_stripped[i][0]
1337               == 'r' && ISDIGIT (operands_stripped[i][1]))
1338             {
1339               sh_format[j++] = 'r';
1340             }
1341           else if (operands_stripped[i][0] == 'p'
1342               && operands_stripped[i][1] == 'c')
1343             {
1344               sh_format[j++] = 'p';
1345             }
1346           else
1347             {
1348               sh_format[j++] = 'i';
1349             }
1350         }
1351       else if (stripped_length == 3)
1352         {
1353           if (operands_stripped[i][0] == 'c'
1354               && (operands_stripped[i][1] == 'c'
1355                   && operands_stripped[i][2] == 'r'))
1356             {
1357               sh_format[j++] = 'c';
1358             }
1359           else if (operands_stripped[i][0] == '#')
1360             {
1361               sh_format[j++] = 'i';
1362             }
1363           else
1364             {
1365               sh_format[j++] = 'i';
1366             }
1367         }
1368       else /* default to immediate */
1369         {
1370           sh_format[j++] = 'i';
1371         }
1372     }
1373
1374   /* See if we have a match.  */
1375   if (!strcmp (i_string, sh_format) && num_operands == 1)
1376     return XG_I;
1377   if (!strcmp (r_i_string, sh_format) && num_operands == 2)
1378     return XG_R_I;
1379   if (!strcmp (r_r_r_string, sh_format) && num_operands == 3)
1380     return XG_R_R_R;
1381   if (!strcmp (r_r_string, sh_format) && num_operands == 2)
1382     return XG_R_R;
1383   if (!strcmp (r_string, sh_format) && num_operands == 1)
1384     return XG_R;
1385   if (!strcmp (r_c_string, sh_format) && num_operands == 2)
1386     return XG_R_C;
1387   if (!strcmp (c_r_string, sh_format) && num_operands == 2)
1388     return XG_C_R;
1389   if (!strcmp (r_p_string, sh_format) && num_operands == 2)
1390     return XG_R_P;
1391   if (!strcmp (r_r_i_string, sh_format) && num_operands == 3)
1392     return XG_R_R_I;
1393
1394   return 0;
1395 }
1396
1397 static struct xgate_opcode *
1398 xgate_find_match (struct xgate_opcode_handle *opcode_handle,
1399                   int numberOfModes,
1400                   unsigned int sh_format)
1401 {
1402   int i;
1403
1404   if (numberOfModes == 0)
1405     return opcode_handle->opc0[0];
1406
1407   for (i = 0; i <= numberOfModes; i++)
1408     if (opcode_handle->opc0[i]->sh_format & sh_format)
1409       return opcode_handle->opc0[i];
1410
1411   return NULL;
1412 }
This page took 0.105716 seconds and 4 git commands to generate.