1 /* tc-xgate.c -- Assembler code for Freescale XGATE
2 Copyright (C) 2010-2015 Free Software Foundation, Inc.
3 Contributed by Sean Keys <skeys@ipdatasys.com>
5 This file is part of GAS, the GNU Assembler.
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to
19 the Free Software Foundation, 51 Franklin Street - Fifth Floor,
20 Boston, MA 02110-1301, USA. */
23 #include "safe-ctype.h"
25 #include "opcode/xgate.h"
26 #include "dwarf2dbg.h"
27 #include "elf/xgate.h"
29 const char comment_chars
[] = ";!";
30 const char line_comment_chars
[] = "#*";
31 const char line_separator_chars
[] = "";
32 const char EXP_CHARS
[] = "eE";
33 const char FLT_CHARS
[] = "dD";
35 /* Max opcodes per opcode handle. */
36 #define MAX_OPCODES 0x05
38 #define SIXTEENTH_BIT 0x8000
39 #define N_BITS_IN_WORD 16
40 #define MAX_NUM_OPERANDS 3
42 /* #define STATE_CONDITIONAL_BRANCH (1) */
43 #define STATE_PC_RELATIVE (2)
44 #define REGISTER_P(ptr) (ptr == 'r')
47 #define MAXREGISTER 07
48 #define MINREGISTER 00
50 #define OPTION_MMCU 'm'
52 /* This macro has no side-effects. */
53 #define ENCODE_RELAX(what,length) (((what) << 2) + (length))
55 /* Each unique opcode name has a handle. That handle may
56 contain pointers to opcodes with the same name but
57 different address modes. */
58 struct xgate_opcode_handle
62 struct xgate_opcode
*opc0
[MAX_OPCODES
];
65 /* XGATE's registers all are 16-bit general purpose.
66 They are numbered according to the specifications. */
67 typedef enum register_id
82 /* Operand Modifiers */
83 typedef enum op_modifiers
93 typedef struct s_operand
101 /* Forward declarations. */
102 static inline char *skip_whitespace (char *);
103 static void get_default_target (void);
104 static char *extract_word (char *, char *, int);
105 static struct xgate_opcode
*xgate_find_match (struct xgate_opcode_handle
*,
106 int, s_operand
[], unsigned int);
107 static int cmp_opcode (struct xgate_opcode
*, struct xgate_opcode
*);
108 static void xgate_print_table (void);
109 static unsigned int xgate_get_operands (char *, s_operand
[]);
110 static register_id
reg_name_search (char *);
111 static op_modifiers
xgate_determine_modifiers(char **);
112 static void xgate_scan_operands (struct xgate_opcode
*opcode
, s_operand
[]);
113 static unsigned int xgate_parse_operand (struct xgate_opcode
*, int *, int,
116 static struct hash_control
*xgate_hash
;
118 /* Previous opcode. */
119 static unsigned int prev
= 0;
121 static unsigned char fixup_required
= 0;
123 /* Used to enable clipping of 16 bit operands into 8 bit constraints. */
124 static unsigned char autoHiLo
= 0;
126 static char oper_check
;
127 static char flag_print_insn_syntax
= 0;
128 static char flag_print_opcodes
= 0;
130 static int current_architecture
;
131 static const char *default_cpu
;
133 /* ELF flags to set in the output file header. */
134 static int elf_flags
= E_XGATE_F64
;
136 /* This table describes how you change sizes for the various types of variable
137 size expressions. This version only supports two kinds. */
140 How far Forward this mode will reach.
141 How far Backward this mode will reach.
142 How many bytes this mode will add to the size of the frag.
143 Which mode to go to if the offset won't fit in this one. */
145 relax_typeS md_relax_table
[] =
147 {1, 1, 0, 0}, /* First entries aren't used. */
148 {1, 1, 0, 0}, /* For no good reason except. */
149 {1, 1, 0, 0}, /* that the VAX doesn't either. */
151 /* XGATE 9 and 10 bit pc rel todo complete and test */
152 /*{(511), (-512), 0, ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD)},
153 {(1023), (-1024), 0, ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD)}, */
157 /* This table describes all the machine specific pseudo-ops the assembler
158 has to support. The fields are: pseudo-op name without dot function to
159 call to execute this pseudo-op Integer arg to pass to the function. */
160 const pseudo_typeS md_pseudo_table
[] =
162 /* The following pseudo-ops are supported for MRI compatibility. */
166 const char *md_shortopts
= "m:";
168 struct option md_longopts
[] =
170 #define OPTION_PRINT_INSN_SYNTAX (OPTION_MD_BASE + 0)
171 { "print-insn-syntax", no_argument
, NULL
, OPTION_PRINT_INSN_SYNTAX
},
173 #define OPTION_PRINT_OPCODES (OPTION_MD_BASE + 1)
174 { "print-opcodes", no_argument
, NULL
, OPTION_PRINT_OPCODES
},
176 #define OPTION_GENERATE_EXAMPLE (OPTION_MD_BASE + 2)
177 { "generate-example", no_argument
, NULL
, OPTION_GENERATE_EXAMPLE
},
179 #define OPTION_MSHORT (OPTION_MD_BASE + 3)
180 { "mshort", no_argument
, NULL
, OPTION_MSHORT
},
182 #define OPTION_MLONG (OPTION_MD_BASE + 4)
183 { "mlong", no_argument
, NULL
, OPTION_MLONG
},
185 #define OPTION_MSHORT_DOUBLE (OPTION_MD_BASE + 5)
186 { "mshort-double", no_argument
, NULL
, OPTION_MSHORT_DOUBLE
},
188 #define OPTION_MLONG_DOUBLE (OPTION_MD_BASE + 6)
189 { "mlong-double", no_argument
, NULL
, OPTION_MLONG_DOUBLE
},
191 { NULL
, no_argument
, NULL
, 0 }
194 size_t md_longopts_size
= sizeof(md_longopts
);
197 md_atof (int type
, char *litP
, int *sizeP
)
199 return ieee_md_atof (type
, litP
, sizeP
, TRUE
);
203 md_parse_option (int c
, char *arg
)
208 if (strcasecmp (arg
, "v1") == 0)
209 current_architecture
= XGATE_V1
;
210 else if (strcasecmp (arg
, "v2") == 0)
211 current_architecture
= XGATE_V2
;
212 else if (strcasecmp (arg
, "v3") == 0)
213 current_architecture
= XGATE_V3
;
215 as_bad (_(" architecture variant invalid"));
218 case OPTION_PRINT_INSN_SYNTAX
:
219 flag_print_insn_syntax
= 1;
222 case OPTION_PRINT_OPCODES
:
223 flag_print_opcodes
= 1;
226 case OPTION_GENERATE_EXAMPLE
:
227 flag_print_opcodes
= 2;
231 elf_flags
&= ~E_XGATE_I32
;
235 elf_flags
|= E_XGATE_I32
;
238 case OPTION_MSHORT_DOUBLE
:
239 elf_flags
&= ~E_XGATE_F64
;
242 case OPTION_MLONG_DOUBLE
:
243 elf_flags
|= E_XGATE_F64
;
253 xgate_arch_format (void)
255 get_default_target ();
257 if (current_architecture
& cpuxgate
)
258 return "elf32-xgate";
264 get_default_target (void)
266 const bfd_target
*target
;
269 if (current_architecture
!= 0)
272 default_cpu
= "unknown";
273 target
= bfd_find_target (0, &abfd
);
275 if (target
&& target
->name
)
277 if (strcmp (target
->name
, "elf32-xgate") == 0)
279 current_architecture
= cpuxgate
;
280 default_cpu
= "XGATE V1";
284 as_bad (_("Default target `%s' is not supported."), target
->name
);
291 struct xgate_opcode
*xgate_opcode_ptr
= NULL
;
292 struct xgate_opcode
*xgate_op_table
= NULL
;
293 struct xgate_opcode_handle
*op_handles
= 0;
294 char *prev_op_name
= 0;
296 int number_of_op_handles
= 0;
299 /* Create a local copy of our opcode table
300 including an extra line for NULL termination. */
301 xgate_op_table
= (struct xgate_opcode
*)
302 xmalloc ((xgate_num_opcodes
) * sizeof (struct xgate_opcode
));
304 memset (xgate_op_table
, 0,
305 sizeof(struct xgate_opcode
) * (xgate_num_opcodes
));
307 for (xgate_opcode_ptr
= (struct xgate_opcode
*) xgate_opcodes
, i
= 0;
308 i
< xgate_num_opcodes
; i
++)
309 xgate_op_table
[i
] = xgate_opcode_ptr
[i
];
311 qsort (xgate_op_table
, xgate_num_opcodes
, sizeof(struct xgate_opcode
),
312 (int (*)(const void *, const void *)) cmp_opcode
);
314 /* Calculate number of handles since this will be
315 smaller than the raw number of opcodes in the table. */
317 for (xgate_opcode_ptr
= xgate_op_table
, i
= 0; i
< xgate_num_opcodes
;
318 xgate_opcode_ptr
++, i
++)
320 if (strcmp (prev_op_name
, xgate_opcode_ptr
->name
))
321 number_of_op_handles
++;
322 prev_op_name
= xgate_opcode_ptr
->name
;
325 op_handles
= (struct xgate_opcode_handle
*)
326 xmalloc (sizeof(struct xgate_opcode_handle
) * (number_of_op_handles
));
328 /* Insert unique opcode names into hash table, aliasing duplicates. */
329 xgate_hash
= hash_new ();
332 for (xgate_opcode_ptr
= xgate_op_table
, i
= 0, j
= 0; i
< xgate_num_opcodes
;
333 i
++, xgate_opcode_ptr
++)
335 if (!strcmp (prev_op_name
, xgate_opcode_ptr
->name
))
338 op_handles
[j
].opc0
[handle_enum
] = xgate_opcode_ptr
;
345 op_handles
[j
].name
= xgate_opcode_ptr
->name
;
346 op_handles
[j
].opc0
[0] = xgate_opcode_ptr
;
347 hash_insert (xgate_hash
, (char *) op_handles
[j
].name
,
348 (char *) &(op_handles
[j
]));
350 op_handles
[j
].number_of_modes
= handle_enum
;
351 prev_op_name
= op_handles
[j
].name
;
354 if (flag_print_opcodes
)
356 xgate_print_table ();
362 xgate_init_after_args (void)
367 md_show_usage (FILE * stream
)
369 get_default_target ();
373 Freescale XGATE co-processor options:\n\
374 -mshort use 16-bit int ABI (default)\n\
375 -mlong use 32-bit int ABI\n\
376 -mshort-double use 32-bit double ABI\n\
377 -mlong-double use 64-bit double ABI (default)\n\
378 --mxgate specify the processor variant[default %s]\n\
379 --print-insn-syntax print the syntax of instruction in case of error\n\
380 --print-opcodes print the list of instructions with syntax\n\
381 --generate-example generate an example of each instruction"),
385 enum bfd_architecture
388 get_default_target ();
389 return bfd_arch_xgate
;
399 xgate_print_syntax (char *name
)
403 for (i
= 0; i
< xgate_num_opcodes
; i
++)
405 if (!strcmp (xgate_opcodes
[i
].name
, name
))
407 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_IDR
))
408 printf ("\tFormat is %s\tRx, Rx, Rx+|-Rx|Rx\n",
409 xgate_opcodes
[i
].name
);
410 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_INH
))
411 printf ("\tFormat is %s\n", xgate_opcodes
[i
].name
);
412 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_TRI
))
413 printf ("\tFormat is %s\tRx, Rx, Rx\n", xgate_opcodes
[i
].name
);
414 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_DYA
))
415 printf ("\tFormat is %s\tRx, Rx\n", xgate_opcodes
[i
].name
);
416 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_IMM3
))
417 printf ("\tFormat is %s\t<3-bit value>\n", xgate_opcodes
[i
].name
);
418 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_IMM4
))
419 printf ("\tFormat is %s\t<4 -bit value>\n", xgate_opcodes
[i
].name
);
420 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_IMM8
))
421 printf ("\tFormat is %s\tRx, <8-bit value>\n",
422 xgate_opcodes
[i
].name
);
423 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_IMM16
))
424 printf ("\tFormat is %s\tRx, <16-bit value>\n",
425 xgate_opcodes
[i
].name
);
426 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_MON_R_C
))
427 printf ("\tFormat is %s\tRx, CCR\n", xgate_opcodes
[i
].name
);
428 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_MON_C_R
))
429 printf ("\tFormat is %s\tCCR, Rx\n", xgate_opcodes
[i
].name
);
430 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_MON_R_P
))
431 printf ("\tFormat is %s\tRx, PC\n", xgate_opcodes
[i
].name
);
432 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_IMM16mLDW
))
433 printf ("\tFormat is %s\tRx, <16-bit value>\n",
434 xgate_opcodes
[i
].name
);
440 xgate_print_table (void)
444 for (i
= 0; i
< xgate_num_opcodes
; i
++)
445 xgate_print_syntax (xgate_opcodes
[i
].name
);
451 xgate_listing_header (void)
453 if (current_architecture
& cpuxgate
)
456 return "ERROR MC9S12X GAS ";
460 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
465 /* GAS will call this function for each section at the end of the assembly,
466 to permit the CPU backend to adjust the alignment of a section. */
469 md_section_align (asection
* seg
, valueT addr
)
471 int align
= bfd_get_section_alignment (stdoutput
, seg
);
472 return ((addr
+ (1 << align
) - 1) & (-1 << align
));
476 md_assemble (char *input_line
)
478 struct xgate_opcode
*opcode
= 0;
479 struct xgate_opcode
*macro_opcode
= 0;
480 struct xgate_opcode_handle
*opcode_handle
= 0;
481 /* Caller expects it to be returned as it was passed. */
482 char *saved_input_line
= input_line
;
483 char op_name
[9] = { 0 };
484 unsigned int operandCount
= 0;
487 s_operand new_operands
[MAX_NUM_OPERANDS
];
490 oper_check
= 0; /* set error flags */
491 input_line
= extract_word (input_line
, op_name
, sizeof(op_name
));
493 /* Check to make sure we are not reading a bogus line. */
495 as_bad (_("opcode missing or not found on input line"));
497 if (!(opcode_handle
= (struct xgate_opcode_handle
*) hash_find (xgate_hash
,
500 as_bad (_("opcode %s not found in opcode hash table"), op_name
);
504 /* Parse operands so we can find the proper opcode bin. */
506 operandCount
= xgate_get_operands (input_line
, new_operands
);
508 opcode
= xgate_find_match (opcode_handle
, opcode_handle
->number_of_modes
,
509 new_operands
, operandCount
);
513 as_bad (_("matching operands to opcode "));
514 xgate_print_syntax (opcode_handle
->opc0
[0]->name
);
516 else if (opcode
->size
== 2)
518 /* Size is one word - assemble that native insn. */
519 xgate_scan_operands (opcode
, new_operands
);
523 /* Insn is a simplified instruction - expand it out. */
527 /* skip past our ';' separator. */
528 for (i
= strlen (opcode
->constraints
), p
= opcode
->constraints
; i
> 0;
537 input_line
= skip_whitespace (input_line
);
538 char *macro_inline
= input_line
;
540 /* Loop though the macro's opcode list and apply operands to
542 for (i
= 0; *p
&& i
< (opcode
->size
/ 2); i
++)
544 /* Loop though macro operand list. */
545 input_line
= macro_inline
; /* Rewind. */
546 p
= extract_word (p
, op_name
, 10);
548 if (!(opcode_handle
= (struct xgate_opcode_handle
*)
549 hash_find (xgate_hash
, op_name
)))
551 as_bad (_(": processing macro, real opcode handle"
552 " not found in hash"));
557 operandCount
= xgate_get_operands(input_line
, new_operands
);
558 macro_opcode
= xgate_find_match (opcode_handle
,
559 opcode_handle
->number_of_modes
, new_operands
,
561 xgate_scan_operands (macro_opcode
, new_operands
);
567 input_line
= saved_input_line
;
570 /* Force truly undefined symbols to their maximum size, and generally set up
571 the frag list to be relaxed. */
574 md_estimate_size_before_relax (fragS
*fragp
, asection
*seg
)
576 /* If symbol is undefined or located in a different section,
577 select the largest supported relocation. */
578 relax_substateT subtype
;
579 relax_substateT rlx_state
[] = { 0, 2 };
581 for (subtype
= 0; subtype
< ARRAY_SIZE (rlx_state
); subtype
+= 2)
583 if (fragp
->fr_subtype
== rlx_state
[subtype
]
584 && (!S_IS_DEFINED (fragp
->fr_symbol
)
585 || seg
!= S_GET_SEGMENT (fragp
->fr_symbol
)))
587 fragp
->fr_subtype
= rlx_state
[subtype
+ 1];
592 if (fragp
->fr_subtype
>= ARRAY_SIZE (md_relax_table
))
595 return md_relax_table
[fragp
->fr_subtype
].rlx_length
;
599 /* Relocation, relaxation and frag conversions. */
601 /* PC-relative offsets are relative to the start of the
602 next instruction. That is, the address of the offset, plus its
603 size, since the offset is always the last part of the insn. */
606 md_pcrel_from (fixS
* fixP
)
608 return fixP
->fx_size
+ fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
611 /* If while processing a fixup, a reloc really needs to be created
612 then it is done here. */
615 tc_gen_reloc (asection
* section ATTRIBUTE_UNUSED
, fixS
* fixp
)
619 reloc
= (arelent
*) xmalloc (sizeof(arelent
));
620 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof(asymbol
*));
621 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
622 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
624 if (fixp
->fx_r_type
== 0)
625 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_16
);
627 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
629 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
631 as_bad_where (fixp
->fx_file
, fixp
->fx_line
, _
632 ("Relocation %d is not supported by object file format."),
633 (int) fixp
->fx_r_type
);
637 /* Since we use Rel instead of Rela, encode the vtable entry to be
638 used in the relocation's section offset. */
639 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
640 reloc
->address
= fixp
->fx_offset
;
645 /* Patch the instruction with the resolved operand. Elf relocation
646 info will also be generated to take care of linker/loader fixups.
647 The XGATE addresses only 16-bit addresses.The BFD_RELOC_32 is necessary
648 for the support of --gstabs. */
651 md_apply_fix (fixS
* fixP
, valueT
* valP
, segT seg ATTRIBUTE_UNUSED
)
658 /* If the fixup is done mark it done so no further symbol resolution
660 if (fixP
->fx_addsy
== (symbolS
*) NULL
)
663 /* We don't actually support subtracting a symbol. */
664 if (fixP
->fx_subsy
!= (symbolS
*) NULL
)
665 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("Expression too complex."));
667 where
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
668 opcode
= bfd_getl16 (where
);
671 switch (fixP
->fx_r_type
)
673 case R_XGATE_PCREL_9
:
674 if (value
< -512 || value
> 511)
675 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
676 _("Value %ld too large for 9-bit PC-relative branch."),
678 result
= ldiv (value
, 2); /* from bytes to words */
681 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _
682 ("Value %ld not aligned by 2 for 9-bit"
683 " PC-relative branch."), value
);
684 /* Clip into 8-bit field.
685 FIXME I'm sure there is a more proper place for this. */
688 number_to_chars_bigendian (where
, (opcode
| value
), 2);
690 case R_XGATE_PCREL_10
:
691 if (value
< -1024 || value
> 1023)
692 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
693 _("Value %ld too large for 10-bit PC-relative branch."),
695 result
= ldiv (value
, 2); /* from bytes to words */
698 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _
699 ("Value %ld not aligned by 2 for 10-bit"
700 " PC-relative branch."), value
);
701 /* Clip into 9-bit field.
702 FIXME I'm sure there is a more proper place for this. */
705 number_to_chars_bigendian (where
, (opcode
| value
), 2);
707 case BFD_RELOC_XGATE_IMM8_HI
:
708 if (value
< -65537 || value
> 65535)
709 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
710 _("Value out of 16-bit range."));
713 bfd_putb16 ((bfd_vma
) value
| opcode
, (void *) where
);
715 case BFD_RELOC_XGATE_24
:
716 case BFD_RELOC_XGATE_IMM8_LO
:
717 if (value
< -65537 || value
> 65535)
718 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
719 _("Value out of 16-bit range."));
721 bfd_putb16 ((bfd_vma
) value
| opcode
, (void *) where
);
723 case BFD_RELOC_XGATE_IMM3
:
724 if (value
< 0 || value
> 7)
725 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
726 _("Value out of 3-bit range."));
727 value
<<= 8; /* make big endian */
728 number_to_chars_bigendian (where
, (opcode
| value
), 2);
730 case BFD_RELOC_XGATE_IMM4
:
731 if (value
< 0 || value
> 15)
732 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
733 _("Value out of 4-bit range."));
734 value
<<= 4; /* align the operand bits */
735 number_to_chars_bigendian (where
, (opcode
| value
), 2);
737 case BFD_RELOC_XGATE_IMM5
:
738 if (value
< 0 || value
> 31)
739 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
740 _("Value out of 5-bit range."));
741 value
<<= 5; /* align the operand bits */
742 number_to_chars_bigendian (where
, (opcode
| value
), 2);
745 ((bfd_byte
*) where
)[0] = (bfd_byte
) value
;
748 bfd_putb32 ((bfd_vma
) value
, (unsigned char *) where
);
751 bfd_putb16 ((bfd_vma
) value
, (unsigned char *) where
);
754 as_fatal (_("Line %d: unknown relocation type: 0x%x."), fixP
->fx_line
,
760 /* See whether we need to force a relocation into the output file. */
763 tc_xgate_force_relocation (fixS
* fixP
)
765 if (fixP
->fx_r_type
== BFD_RELOC_XGATE_RL_GROUP
)
767 return generic_force_reloc (fixP
);
770 /* Here we decide which fixups can be adjusted to make them relative
771 to the beginning of the section instead of the symbol. Basically
772 we need to make sure that the linker relaxation is done
773 correctly, so in some cases we force the original symbol to be
777 tc_xgate_fix_adjustable (fixS
* fixP
)
779 switch (fixP
->fx_r_type
)
781 /* For the linker relaxation to work correctly, these relocs
782 need to be on the symbol itself. */
784 case BFD_RELOC_XGATE_RL_JUMP
:
785 case BFD_RELOC_XGATE_RL_GROUP
:
786 case BFD_RELOC_VTABLE_INHERIT
:
787 case BFD_RELOC_VTABLE_ENTRY
:
796 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
,
797 asection
* sec ATTRIBUTE_UNUSED
,
798 fragS
* fragP ATTRIBUTE_UNUSED
)
800 as_bad (("md_convert_frag not implemented yet"));
804 /* Set the ELF specific flags. */
807 xgate_elf_final_processing (void)
809 elf_flags
|= EF_XGATE_MACH
;
810 elf_elfheader (stdoutput
)->e_flags
&= ~EF_XGATE_ABI
;
811 elf_elfheader (stdoutput
)->e_flags
|= elf_flags
;
815 skip_whitespace (char *s
)
817 while (*s
== ' ' || *s
== '\t' || *s
== '(' || *s
== ')')
823 /* Extract a word (continuous alpha-numeric chars) from the input line. */
826 extract_word (char *from
, char *to
, int limit
)
831 /* Drop leading whitespace. */
832 from
= skip_whitespace (from
);
834 /* Find the op code end. */
835 for (op_end
= from
; *op_end
!= 0 && is_part_of_name (*op_end
);)
837 to
[size
++] = *op_end
++;
838 if (size
+ 1 >= limit
)
846 xgate_new_instruction (int size
)
848 char *f
= frag_more (size
);
849 dwarf2_emit_insn (size
);
853 static unsigned short
854 xgate_apply_operand (unsigned short new_mask
,
855 unsigned short *availiable_mask_bits
,
857 unsigned char n_bits
)
859 unsigned short n_shifts
;
860 unsigned int n_drop_bits
;
862 /* Shift until you find an available operand bit "1" and record
863 the number of shifts. */
865 !(*availiable_mask_bits
& SIXTEENTH_BIT
) && n_shifts
< 16;
867 *availiable_mask_bits
<<= 1;
869 /* Shift for the number of bits your operand requires while bits
871 for (n_drop_bits
= n_bits
;
872 n_drop_bits
&& (*availiable_mask_bits
& SIXTEENTH_BIT
);
874 *availiable_mask_bits
<<= 1;
877 as_bad (_(":operand has too many bits"));
878 *availiable_mask_bits
>>= n_shifts
+ n_bits
;
879 if ((n_drop_bits
== 0) && (*availiable_mask_bits
== 0))
881 oper_check
= 1; /* flag operand check as good */
883 new_mask
<<= N_BITS_IN_WORD
- (n_shifts
+ n_bits
);
888 /* Parse ordinary expression. */
891 xgate_parse_exp (char *s
, expressionS
* op
)
893 input_line_pointer
= s
;
895 if (op
->X_op
== O_absent
)
896 as_bad (_("missing operand"));
897 return input_line_pointer
;
901 cmp_opcode (struct xgate_opcode
*op1
, struct xgate_opcode
*op2
)
903 return strcmp (op1
->name
, op2
->name
);
906 static struct xgate_opcode
*
907 xgate_find_match (struct xgate_opcode_handle
*opcode_handle
,
908 int numberOfModes
, s_operand oprs
[], unsigned int operandCount
)
912 if (numberOfModes
== 0)
913 return opcode_handle
->opc0
[0];
915 for (i
= 0; i
<= numberOfModes
; i
++)
917 switch (operandCount
)
920 if (!strcmp(opcode_handle
->opc0
[i
]->constraints
, XGATE_OP_INH
))
921 return opcode_handle
->opc0
[i
];
924 if (oprs
[0].reg
>= REG_R0
&& oprs
[0].reg
<= REG_R7
)
925 if (!strcmp(opcode_handle
->opc0
[i
]->constraints
, XGATE_OP_MON
))
926 return opcode_handle
->opc0
[i
];
927 if (!strcmp(opcode_handle
->opc0
[i
]->constraints
, XGATE_OP_DYA_MON
))
928 return opcode_handle
->opc0
[i
];
929 if (oprs
[0].reg
== REG_NONE
)
930 if (!strcmp(opcode_handle
->opc0
[i
]->constraints
, XGATE_OP_IMM3
))
931 return opcode_handle
->opc0
[i
];
934 if (oprs
[0].reg
>= REG_R0
&& oprs
[0].reg
<= REG_R7
)
936 if (oprs
[1].reg
>= REG_R0
&& oprs
[1].reg
<= REG_R7
)
937 if (!strcmp(opcode_handle
->opc0
[i
]->constraints
, XGATE_OP_DYA
))
938 return opcode_handle
->opc0
[i
];
939 if (oprs
[1].reg
== REG_CCR
)
940 if (!strcmp(opcode_handle
->opc0
[i
]->constraints
,
942 return opcode_handle
->opc0
[i
];
943 if (oprs
[1].reg
== REG_PC
)
944 if (!strcmp(opcode_handle
->opc0
[i
]->constraints
,
946 return opcode_handle
->opc0
[i
];
947 if (oprs
[1].reg
== REG_NONE
)
948 if (!strcmp(opcode_handle
->opc0
[i
]->constraints
, XGATE_OP_IMM16
)
949 || !strcmp(opcode_handle
->opc0
[i
]->constraints
, XGATE_OP_IMM8
)
950 || !strcmp(opcode_handle
->opc0
[i
]->constraints
, XGATE_OP_IMM4
)
951 || !strcmp(opcode_handle
->opc0
[i
]->constraints
,
953 || !strcmp(opcode_handle
->opc0
[i
]->constraints
,
955 || !strcmp(opcode_handle
->opc0
[i
]->constraints
,
957 || !strcmp(opcode_handle
->opc0
[i
]->constraints
,
959 || !strcmp(opcode_handle
->opc0
[i
]->constraints
,
961 return opcode_handle
->opc0
[i
];
963 if (oprs
[0].reg
== REG_CCR
)
964 if (!strcmp(opcode_handle
->opc0
[i
]->constraints
, XGATE_OP_MON_C_R
))
965 return opcode_handle
->opc0
[i
];
968 if (oprs
[0].reg
>= REG_R0
&& oprs
[0].reg
<= REG_R7
)
970 if (oprs
[1].reg
>= REG_R0
&& oprs
[1].reg
<= REG_R7
)
972 if (oprs
[2].reg
>= REG_R0
&& oprs
[2].reg
<= REG_R7
)
974 if (!strcmp(opcode_handle
->opc0
[i
]->constraints
,
976 || !strcmp(opcode_handle
->opc0
[i
]->constraints
,
978 return opcode_handle
->opc0
[i
];
981 if (oprs
[2].reg
== REG_NONE
)
982 if (!strcmp(opcode_handle
->opc0
[i
]->constraints
,
984 return opcode_handle
->opc0
[i
];
989 as_bad(_("unknown operand count"));
996 /* Because we are dealing with two different core that view the system
997 memory with different offsets, we must differentiate what core a
998 symbol belongs to, in order for the linker to cross-link. */
1001 xgate_frob_symbol (symbolS
*sym
)
1004 elf_symbol_type
*elfsym
;
1006 bfdsym
= symbol_get_bfdsym (sym
);
1007 elfsym
= elf_symbol_from (bfd_asymbol_bfd (bfdsym
), bfdsym
);
1011 /* Mark the symbol as being *from XGATE */
1012 elfsym
->internal_elf_sym
.st_target_internal
= 1;
1018 xgate_get_operands (char *line
, s_operand oprs
[])
1022 /* If there are no operands, then it must be inherent. */
1023 if (*line
== 0 || *line
== '\n' || *line
== '\r')
1026 for (num_operands
= 0; strlen (line
) && (num_operands
< MAX_NUM_OPERANDS
);
1029 line
= skip_whitespace (line
);
1033 oprs
[num_operands
].mod
= xgate_determine_modifiers (&line
);
1035 if ((oprs
[num_operands
].reg
= reg_name_search (line
)) == REG_NONE
)
1036 line
= xgate_parse_exp (line
, &oprs
[num_operands
].exp
);
1038 /* skip to next operand */
1049 if (num_operands
> MAX_NUM_OPERANDS
)
1051 return num_operands
;
1054 /* reg_name_search() finds the register number given its name.
1055 Returns the register number or REG_NONE on failure. */
1057 reg_name_search (char *name
)
1059 if (strncasecmp (name
, "r0", 2) == 0)
1061 if (strncasecmp (name
, "r1", 2) == 0)
1063 if (strncasecmp (name
, "r2", 2) == 0)
1065 if (strncasecmp (name
, "r3", 2) == 0)
1067 if (strncasecmp (name
, "r4", 2) == 0)
1069 if (strncasecmp (name
, "r5", 2) == 0)
1071 if (strncasecmp (name
, "r6", 2) == 0)
1073 if (strncasecmp (name
, "r7", 2) == 0)
1075 if (strncasecmp (name
, "pc", 2) == 0)
1077 if (strncasecmp (name
, "ccr", 3) == 0)
1082 /* Parse operand modifiers such as inc/dec/hi/low. */
1085 xgate_determine_modifiers(char **line
)
1087 char *local_line
= line
[0];
1089 if (strncasecmp (local_line
, "%hi", 3) == 0)
1092 return MOD_LOAD_HIGH
;
1094 if (strncasecmp (local_line
, "%lo", 3) == 0)
1097 return MOD_LOAD_LOW
;
1099 if (*(local_line
+ 2) == '+')
1101 if (strncasecmp (local_line
, "-r", 2) == 0)
1109 /* Parse instruction operands. */
1112 xgate_scan_operands (struct xgate_opcode
*opcode
, s_operand oprs
[])
1114 char *frag
= xgate_new_instruction (opcode
->size
);
1115 int where
= frag
- frag_now
->fr_literal
;
1116 char *op
= opcode
->constraints
;
1117 unsigned int bin
= (int) opcode
->bin_opcode
;
1118 unsigned short oper_mask
= 0;
1119 int operand_bit_length
= 0;
1120 unsigned int operand
= 0;
1121 char n_operand_bits
= 0;
1122 char first_operand_equals_second
= 0;
1126 /* Generate available operand bits mask. */
1127 for (i
= 0; (c
= opcode
->format
[i
]); i
++)
1129 if (ISDIGIT (c
) || (c
== 's'))
1141 /* Parse first operand. */
1146 first_operand_equals_second
= 1;
1149 operand
= xgate_parse_operand (opcode
, &operand_bit_length
, where
,
1152 bin
= xgate_apply_operand (operand
, &oper_mask
, bin
, operand_bit_length
);
1154 if(first_operand_equals_second
)
1155 bin
= xgate_apply_operand (operand
, &oper_mask
, bin
,
1156 operand_bit_length
);
1157 /* Parse second operand. */
1162 if (first_operand_equals_second
)
1164 bin
= xgate_apply_operand (operand
, &oper_mask
, bin
,
1165 operand_bit_length
);
1170 operand
= xgate_parse_operand (opcode
, &operand_bit_length
, where
,
1172 bin
= xgate_apply_operand (operand
, &oper_mask
, bin
,
1173 operand_bit_length
);
1177 /* Parse the third register. */
1182 operand
= xgate_parse_operand (opcode
, &operand_bit_length
, where
,
1184 bin
= xgate_apply_operand (operand
, &oper_mask
, bin
,
1185 operand_bit_length
);
1188 if (opcode
->size
== 2 && fixup_required
)
1190 bfd_putl16 (bin
, frag
);
1192 else if ( !strcmp (opcode
->constraints
, XGATE_OP_REL9
)
1193 || !strcmp (opcode
->constraints
, XGATE_OP_REL10
))
1195 /* Write our data to a frag for further processing. */
1196 bfd_putl16 (opcode
->bin_opcode
, frag
);
1200 /* Apply operand mask(s)to bin opcode and write the output. */
1201 /* Since we are done write this frag in xgate BE format. */
1202 number_to_chars_bigendian (frag
, bin
, opcode
->size
);
1209 xgate_parse_operand (struct xgate_opcode
*opcode
,
1215 char *op_constraint
= *op_con
;
1216 unsigned int op_mask
= 0;
1217 unsigned int pp_fix
= 0;
1218 unsigned short max_size
= 0;
1224 switch (*op_constraint
)
1226 case '+': /* Indexed register operand +/- or plain r. */
1227 /* Default to neither inc or dec. */
1231 if (operand
.reg
== REG_NONE
)
1232 as_bad (_(": expected register name r0-r7 ") );
1233 op_mask
= operand
.reg
;
1234 if(operand
.mod
== MOD_POSTINC
)
1236 if(operand
.mod
== MOD_PREDEC
)
1242 case 'r': /* Register operand. */
1243 if (operand
.reg
== REG_NONE
)
1244 as_bad (_(": expected register name r0-r7 "));
1248 op_mask
= operand
.reg
;
1251 case 'i': /* Immediate value or expression expected. */
1252 /* Advance the original format pointer. */
1255 if (ISDIGIT (*op_constraint
))
1256 *bit_width
= (int) *op_constraint
- '0';
1257 else if (*op_constraint
== 'a')
1259 else if (*op_constraint
== 'f')
1262 /* http://tigcc.ticalc.org/doc/gnuasm.html#SEC31 */
1263 if (operand
.exp
.X_op
== O_constant
)
1265 op_mask
= operand
.exp
.X_add_number
;
1266 if (((opcode
->name
[strlen (opcode
->name
) - 1] == 'l') && autoHiLo
)
1267 || operand
.mod
== MOD_LOAD_LOW
)
1269 else if (((opcode
->name
[strlen (opcode
->name
) - 1]) == 'h'
1270 && autoHiLo
) || operand
.mod
== MOD_LOAD_HIGH
)
1273 /* Make sure it fits. */
1274 for (i
= *bit_width
; i
; i
--)
1279 if (op_mask
> max_size
)
1280 as_bad (_(":operand value(%d) too big for constraint"), op_mask
);
1284 /* Should be BFD_RELOC_XGATE_IMM8_LO instead of BFD_RELOC_XGATE_24
1287 if (*op_constraint
== '8')
1289 if (((opcode
->name
[strlen (opcode
->name
) - 1] == 'l')
1290 && autoHiLo
) || operand
.mod
== MOD_LOAD_LOW
)
1291 fix_new_exp (frag_now
, where
, 2, &operand
.exp
, FALSE
,
1292 BFD_RELOC_XGATE_24
);
1293 else if (((opcode
->name
[strlen (opcode
->name
) - 1]) == 'h'
1294 && autoHiLo
) || operand
.mod
== MOD_LOAD_HIGH
)
1295 fix_new_exp (frag_now
, where
, 2, &operand
.exp
, FALSE
,
1296 BFD_RELOC_XGATE_IMM8_HI
);
1298 as_bad (_("you must use a hi/lo directive or 16-bit macro "
1299 "to load a 16-bit value."));
1301 else if (*op_constraint
== '5')
1302 fix_new_exp (frag_now
, where
, 2, &operand
.exp
, FALSE
,
1303 BFD_RELOC_XGATE_IMM5
);
1304 else if (*op_constraint
== '4')
1305 fix_new_exp (frag_now
, where
, 2, &operand
.exp
, FALSE
,
1306 BFD_RELOC_XGATE_IMM4
);
1307 else if (*op_constraint
== '3')
1308 fix_new_exp (frag_now
, where
, 2, &operand
.exp
, FALSE
,
1309 BFD_RELOC_XGATE_IMM3
);
1311 as_bad (_(":unknown relocation constraint size"));
1315 case 'c': /* CCR register expected. */
1317 if (operand
.reg
!= REG_CCR
)
1318 as_bad (_(": expected register name ccr "));
1321 case 'p': /* PC register expected. */
1323 if (operand
.reg
!= REG_PC
)
1324 as_bad (_(": expected register name pc "));
1327 case 'b': /* Branch expected. */
1331 if (operand
.exp
.X_op
!= O_register
)
1333 if (*op_constraint
== '9')
1334 fix_new_exp (frag_now
, where
, 2, &operand
.exp
, TRUE
,
1336 else if (*op_constraint
== 'a')
1337 fix_new_exp (frag_now
, where
, 2, &operand
.exp
, TRUE
,
1341 as_fatal (_("Operand `%x' not recognized in fixup8."),
1348 as_bad (_("unknown constraint `%c'"), *op_constraint
);