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