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