1 /* tc-xgate.c -- Assembler code for Freescale XGATE
2 Copyright (C) 2010-2019 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
, const 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 const 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
= XNEWVEC (struct xgate_opcode
, xgate_num_opcodes
);
303 memset (xgate_op_table
, 0,
304 sizeof (struct xgate_opcode
) * (xgate_num_opcodes
));
306 for (xgate_opcode_ptr
= (struct xgate_opcode
*) xgate_opcodes
, i
= 0;
307 i
< xgate_num_opcodes
; i
++)
308 xgate_op_table
[i
] = xgate_opcode_ptr
[i
];
310 qsort (xgate_op_table
, xgate_num_opcodes
, sizeof (struct xgate_opcode
),
311 (int (*)(const void *, const void *)) cmp_opcode
);
313 /* Calculate number of handles since this will be
314 smaller than the raw number of opcodes in the table. */
316 for (xgate_opcode_ptr
= xgate_op_table
, i
= 0; i
< xgate_num_opcodes
;
317 xgate_opcode_ptr
++, i
++)
319 if (strcmp (prev_op_name
, xgate_opcode_ptr
->name
))
320 number_of_op_handles
++;
321 prev_op_name
= xgate_opcode_ptr
->name
;
324 op_handles
= XNEWVEC (struct xgate_opcode_handle
, number_of_op_handles
);
326 /* Insert unique opcode names into hash table, aliasing duplicates. */
327 xgate_hash
= hash_new ();
330 for (xgate_opcode_ptr
= xgate_op_table
, i
= 0, j
= 0; i
< xgate_num_opcodes
;
331 i
++, xgate_opcode_ptr
++)
333 if (!strcmp (prev_op_name
, xgate_opcode_ptr
->name
))
336 op_handles
[j
].opc0
[handle_enum
] = xgate_opcode_ptr
;
343 op_handles
[j
].name
= xgate_opcode_ptr
->name
;
344 op_handles
[j
].opc0
[0] = xgate_opcode_ptr
;
345 hash_insert (xgate_hash
, (char *) op_handles
[j
].name
,
346 (char *) &(op_handles
[j
]));
348 op_handles
[j
].number_of_modes
= handle_enum
;
349 prev_op_name
= op_handles
[j
].name
;
352 if (flag_print_opcodes
)
354 xgate_print_table ();
360 xgate_init_after_args (void)
365 md_show_usage (FILE * stream
)
367 get_default_target ();
371 Freescale XGATE co-processor options:\n\
372 -mshort use 16-bit int ABI (default)\n\
373 -mlong use 32-bit int ABI\n\
374 -mshort-double use 32-bit double ABI\n\
375 -mlong-double use 64-bit double ABI (default)\n\
376 --mxgate specify the processor variant [default %s]\n\
377 --print-insn-syntax print the syntax of instruction in case of error\n\
378 --print-opcodes print the list of instructions with syntax\n\
379 --generate-example generate an example of each instruction"),
383 enum bfd_architecture
386 get_default_target ();
387 return bfd_arch_xgate
;
397 xgate_print_syntax (char *name
)
401 for (i
= 0; i
< xgate_num_opcodes
; i
++)
403 if (!strcmp (xgate_opcodes
[i
].name
, name
))
405 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_IDR
))
406 printf ("\tFormat is %s\tRx, Rx, Rx+|-Rx|Rx\n",
407 xgate_opcodes
[i
].name
);
408 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_INH
))
409 printf ("\tFormat is %s\n", xgate_opcodes
[i
].name
);
410 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_TRI
))
411 printf ("\tFormat is %s\tRx, Rx, Rx\n", xgate_opcodes
[i
].name
);
412 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_DYA
))
413 printf ("\tFormat is %s\tRx, Rx\n", xgate_opcodes
[i
].name
);
414 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_IMM3
))
415 printf ("\tFormat is %s\t<3-bit value>\n", xgate_opcodes
[i
].name
);
416 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_IMM4
))
417 printf ("\tFormat is %s\t<4 -bit value>\n", xgate_opcodes
[i
].name
);
418 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_IMM8
))
419 printf ("\tFormat is %s\tRx, <8-bit value>\n",
420 xgate_opcodes
[i
].name
);
421 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_IMM16
))
422 printf ("\tFormat is %s\tRx, <16-bit value>\n",
423 xgate_opcodes
[i
].name
);
424 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_MON_R_C
))
425 printf ("\tFormat is %s\tRx, CCR\n", xgate_opcodes
[i
].name
);
426 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_MON_C_R
))
427 printf ("\tFormat is %s\tCCR, Rx\n", xgate_opcodes
[i
].name
);
428 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_MON_R_P
))
429 printf ("\tFormat is %s\tRx, PC\n", xgate_opcodes
[i
].name
);
430 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_IMM16mLDW
))
431 printf ("\tFormat is %s\tRx, <16-bit value>\n",
432 xgate_opcodes
[i
].name
);
438 xgate_print_table (void)
442 for (i
= 0; i
< xgate_num_opcodes
; i
++)
443 xgate_print_syntax (xgate_opcodes
[i
].name
);
449 xgate_listing_header (void)
451 if (current_architecture
& cpuxgate
)
454 return "ERROR MC9S12X GAS ";
458 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
463 /* GAS will call this function for each section at the end of the assembly,
464 to permit the CPU backend to adjust the alignment of a section. */
467 md_section_align (asection
* seg
, valueT addr
)
469 int align
= bfd_get_section_alignment (stdoutput
, seg
);
470 return ((addr
+ (1 << align
) - 1) & -(1 << align
));
474 md_assemble (char *input_line
)
476 struct xgate_opcode
*opcode
= 0;
477 struct xgate_opcode
*macro_opcode
= 0;
478 struct xgate_opcode_handle
*opcode_handle
= 0;
479 /* Caller expects it to be returned as it was passed. */
480 char *saved_input_line
= input_line
;
481 char op_name
[9] = { 0 };
482 unsigned int operandCount
= 0;
485 s_operand new_operands
[MAX_NUM_OPERANDS
];
488 oper_check
= 0; /* set error flags */
489 input_line
= extract_word (input_line
, op_name
, sizeof (op_name
));
491 /* Check to make sure we are not reading a bogus line. */
493 as_bad (_("opcode missing or not found on input line"));
495 if (!(opcode_handle
= (struct xgate_opcode_handle
*) hash_find (xgate_hash
,
498 as_bad (_("opcode %s not found in opcode hash table"), op_name
);
502 /* Parse operands so we can find the proper opcode bin. */
504 operandCount
= xgate_get_operands (input_line
, new_operands
);
506 opcode
= xgate_find_match (opcode_handle
, opcode_handle
->number_of_modes
,
507 new_operands
, operandCount
);
511 as_bad (_("matching operands to opcode"));
512 xgate_print_syntax (opcode_handle
->opc0
[0]->name
);
514 else if (opcode
->size
== 2)
516 /* Size is one word - assemble that native insn. */
517 xgate_scan_operands (opcode
, new_operands
);
521 /* Insn is a simplified instruction - expand it out. */
525 /* skip past our ';' separator. */
526 for (i
= strlen (opcode
->constraints
), p
= opcode
->constraints
; i
> 0;
535 input_line
= skip_whitespace (input_line
);
536 char *macro_inline
= input_line
;
538 /* Loop though the macro's opcode list and apply operands to
540 for (i
= 0; *p
&& i
< (opcode
->size
/ 2); i
++)
542 /* Loop though macro operand list. */
543 input_line
= macro_inline
; /* Rewind. */
544 p
= extract_word (p
, op_name
, 10);
546 if (!(opcode_handle
= (struct xgate_opcode_handle
*)
547 hash_find (xgate_hash
, op_name
)))
549 as_bad (_(": processing macro, real opcode handle"
550 " not found in hash"));
555 operandCount
= xgate_get_operands (input_line
, new_operands
);
556 macro_opcode
= xgate_find_match (opcode_handle
,
557 opcode_handle
->number_of_modes
, new_operands
,
559 xgate_scan_operands (macro_opcode
, new_operands
);
565 input_line
= saved_input_line
;
568 /* Force truly undefined symbols to their maximum size, and generally set up
569 the frag list to be relaxed. */
572 md_estimate_size_before_relax (fragS
*fragp
, asection
*seg
)
574 /* If symbol is undefined or located in a different section,
575 select the largest supported relocation. */
576 relax_substateT subtype
;
577 relax_substateT rlx_state
[] = { 0, 2 };
579 for (subtype
= 0; subtype
< ARRAY_SIZE (rlx_state
); subtype
+= 2)
581 if (fragp
->fr_subtype
== rlx_state
[subtype
]
582 && (!S_IS_DEFINED (fragp
->fr_symbol
)
583 || seg
!= S_GET_SEGMENT (fragp
->fr_symbol
)))
585 fragp
->fr_subtype
= rlx_state
[subtype
+ 1];
590 if (fragp
->fr_subtype
>= ARRAY_SIZE (md_relax_table
))
593 return md_relax_table
[fragp
->fr_subtype
].rlx_length
;
597 /* Relocation, relaxation and frag conversions. */
599 /* PC-relative offsets are relative to the start of the
600 next instruction. That is, the address of the offset, plus its
601 size, since the offset is always the last part of the insn. */
604 md_pcrel_from (fixS
* fixP
)
606 return fixP
->fx_size
+ fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
609 /* If while processing a fixup, a reloc really needs to be created
610 then it is done here. */
613 tc_gen_reloc (asection
* section ATTRIBUTE_UNUSED
, fixS
* fixp
)
617 reloc
= XNEW (arelent
);
618 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
619 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
620 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
622 if (fixp
->fx_r_type
== 0)
623 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_16
);
625 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
627 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
629 as_bad_where (fixp
->fx_file
, fixp
->fx_line
, _
630 ("Relocation %d is not supported by object file format."),
631 (int) fixp
->fx_r_type
);
635 /* Since we use Rel instead of Rela, encode the vtable entry to be
636 used in the relocation's section offset. */
637 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
638 reloc
->address
= fixp
->fx_offset
;
643 /* Patch the instruction with the resolved operand. Elf relocation
644 info will also be generated to take care of linker/loader fixups.
645 The XGATE addresses only 16-bit addresses.The BFD_RELOC_32 is necessary
646 for the support of --gstabs. */
649 md_apply_fix (fixS
* fixP
, valueT
* valP
, segT seg ATTRIBUTE_UNUSED
)
656 /* If the fixup is done mark it done so no further symbol resolution
658 if (fixP
->fx_addsy
== (symbolS
*) NULL
)
661 /* We don't actually support subtracting a symbol. */
662 if (fixP
->fx_subsy
!= (symbolS
*) NULL
)
663 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("Expression too complex."));
665 where
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
666 opcode
= bfd_getl16 (where
);
669 switch (fixP
->fx_r_type
)
671 case R_XGATE_PCREL_9
:
672 if (value
< -512 || value
> 511)
673 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
674 _("Value %ld too large for 9-bit PC-relative branch."),
676 result
= ldiv (value
, 2); /* from bytes to words */
679 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _
680 ("Value %ld not aligned by 2 for 9-bit"
681 " PC-relative branch."), value
);
682 /* Clip into 8-bit field.
683 FIXME I'm sure there is a more proper place for this. */
686 number_to_chars_bigendian (where
, (opcode
| value
), 2);
688 case R_XGATE_PCREL_10
:
689 if (value
< -1024 || value
> 1023)
690 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
691 _("Value %ld too large for 10-bit PC-relative branch."),
693 result
= ldiv (value
, 2); /* from bytes to words */
696 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _
697 ("Value %ld not aligned by 2 for 10-bit"
698 " PC-relative branch."), value
);
699 /* Clip into 9-bit field.
700 FIXME I'm sure there is a more proper place for this. */
703 number_to_chars_bigendian (where
, (opcode
| value
), 2);
705 case BFD_RELOC_XGATE_IMM8_HI
:
706 if (value
< -65537 || value
> 65535)
707 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
708 _("Value out of 16-bit range."));
711 bfd_putb16 ((bfd_vma
) value
| opcode
, (void *) where
);
713 case BFD_RELOC_XGATE_24
:
714 case BFD_RELOC_XGATE_IMM8_LO
:
715 if (value
< -65537 || value
> 65535)
716 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
717 _("Value out of 16-bit range."));
719 bfd_putb16 ((bfd_vma
) value
| opcode
, (void *) where
);
721 case BFD_RELOC_XGATE_IMM3
:
722 if (value
< 0 || value
> 7)
723 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
724 _("Value out of 3-bit range."));
725 value
<<= 8; /* make big endian */
726 number_to_chars_bigendian (where
, (opcode
| value
), 2);
728 case BFD_RELOC_XGATE_IMM4
:
729 if (value
< 0 || value
> 15)
730 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
731 _("Value out of 4-bit range."));
732 value
<<= 4; /* align the operand bits */
733 number_to_chars_bigendian (where
, (opcode
| value
), 2);
735 case BFD_RELOC_XGATE_IMM5
:
736 if (value
< 0 || value
> 31)
737 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
738 _("Value out of 5-bit range."));
739 value
<<= 5; /* align the operand bits */
740 number_to_chars_bigendian (where
, (opcode
| value
), 2);
743 ((bfd_byte
*) where
)[0] = (bfd_byte
) value
;
746 bfd_putb32 ((bfd_vma
) value
, (unsigned char *) where
);
749 bfd_putb16 ((bfd_vma
) value
, (unsigned char *) where
);
752 as_fatal (_("Line %d: unknown relocation type: 0x%x."), fixP
->fx_line
,
758 /* See whether we need to force a relocation into the output file. */
761 tc_xgate_force_relocation (fixS
* fixP
)
763 if (fixP
->fx_r_type
== BFD_RELOC_XGATE_RL_GROUP
)
765 return generic_force_reloc (fixP
);
768 /* Here we decide which fixups can be adjusted to make them relative
769 to the beginning of the section instead of the symbol. Basically
770 we need to make sure that the linker relaxation is done
771 correctly, so in some cases we force the original symbol to be
775 tc_xgate_fix_adjustable (fixS
* fixP
)
777 switch (fixP
->fx_r_type
)
779 /* For the linker relaxation to work correctly, these relocs
780 need to be on the symbol itself. */
782 case BFD_RELOC_XGATE_RL_JUMP
:
783 case BFD_RELOC_XGATE_RL_GROUP
:
784 case BFD_RELOC_VTABLE_INHERIT
:
785 case BFD_RELOC_VTABLE_ENTRY
:
794 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
,
795 asection
* sec ATTRIBUTE_UNUSED
,
796 fragS
* fragP ATTRIBUTE_UNUSED
)
798 as_bad (("md_convert_frag not implemented yet"));
802 /* Set the ELF specific flags. */
805 xgate_elf_final_processing (void)
807 elf_flags
|= EF_XGATE_MACH
;
808 elf_elfheader (stdoutput
)->e_flags
&= ~EF_XGATE_ABI
;
809 elf_elfheader (stdoutput
)->e_flags
|= elf_flags
;
813 skip_whitespace (char *s
)
815 while (*s
== ' ' || *s
== '\t' || *s
== '(' || *s
== ')')
821 /* Extract a word (continuous alpha-numeric chars) from the input line. */
824 extract_word (char *from
, char *to
, int limit
)
829 /* Drop leading whitespace. */
830 from
= skip_whitespace (from
);
832 /* Find the op code end. */
833 for (op_end
= from
; *op_end
!= 0 && is_part_of_name (*op_end
);)
835 to
[size
++] = *op_end
++;
836 if (size
+ 1 >= limit
)
844 xgate_new_instruction (int size
)
846 char *f
= frag_more (size
);
847 dwarf2_emit_insn (size
);
851 static unsigned short
852 xgate_apply_operand (unsigned short new_mask
,
853 unsigned short *availiable_mask_bits
,
855 unsigned char n_bits
)
857 unsigned short n_shifts
;
858 unsigned int n_drop_bits
;
860 /* Shift until you find an available operand bit "1" and record
861 the number of shifts. */
863 !(*availiable_mask_bits
& SIXTEENTH_BIT
) && n_shifts
< 16;
865 *availiable_mask_bits
<<= 1;
867 /* Shift for the number of bits your operand requires while bits
869 for (n_drop_bits
= n_bits
;
870 n_drop_bits
&& (*availiable_mask_bits
& SIXTEENTH_BIT
);
872 *availiable_mask_bits
<<= 1;
875 as_bad (_(":operand has too many bits"));
876 *availiable_mask_bits
>>= n_shifts
+ n_bits
;
877 if ((n_drop_bits
== 0) && (*availiable_mask_bits
== 0))
879 oper_check
= 1; /* flag operand check as good */
881 new_mask
<<= N_BITS_IN_WORD
- (n_shifts
+ n_bits
);
886 /* Parse ordinary expression. */
889 xgate_parse_exp (char *s
, expressionS
* op
)
891 input_line_pointer
= s
;
894 if (op
->X_op
== O_absent
)
895 as_bad (_("missing operand"));
896 return input_line_pointer
;
900 cmp_opcode (struct xgate_opcode
*op1
, struct xgate_opcode
*op2
)
902 return strcmp (op1
->name
, op2
->name
);
905 static struct xgate_opcode
*
906 xgate_find_match (struct xgate_opcode_handle
*opcode_handle
,
907 int numberOfModes
, s_operand oprs
[], unsigned int operandCount
)
911 if (numberOfModes
== 0)
912 return opcode_handle
->opc0
[0];
914 for (i
= 0; i
<= numberOfModes
; i
++)
916 switch (operandCount
)
919 if (!strcmp (opcode_handle
->opc0
[i
]->constraints
, XGATE_OP_INH
))
920 return opcode_handle
->opc0
[i
];
923 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
];
930 if (oprs
[0].reg
== REG_NONE
)
931 if (!strcmp (opcode_handle
->opc0
[i
]->constraints
, XGATE_OP_IMM3
))
932 return opcode_handle
->opc0
[i
];
935 if (oprs
[0].reg
>= REG_R0
&& oprs
[0].reg
<= REG_R7
)
937 if (oprs
[1].reg
>= REG_R0
&& oprs
[1].reg
<= REG_R7
)
939 if (!strcmp (opcode_handle
->opc0
[i
]->constraints
, XGATE_OP_DYA
))
940 return opcode_handle
->opc0
[i
];
942 if (oprs
[1].reg
== REG_CCR
)
943 if (!strcmp (opcode_handle
->opc0
[i
]->constraints
,
945 return opcode_handle
->opc0
[i
];
946 if (oprs
[1].reg
== REG_PC
)
947 if (!strcmp (opcode_handle
->opc0
[i
]->constraints
,
949 return opcode_handle
->opc0
[i
];
950 if (oprs
[1].reg
== REG_NONE
)
951 if (!strcmp (opcode_handle
->opc0
[i
]->constraints
, XGATE_OP_IMM16
)
952 || !strcmp (opcode_handle
->opc0
[i
]->constraints
, XGATE_OP_IMM8
)
953 || !strcmp (opcode_handle
->opc0
[i
]->constraints
, XGATE_OP_IMM4
)
954 || !strcmp (opcode_handle
->opc0
[i
]->constraints
,
956 || !strcmp (opcode_handle
->opc0
[i
]->constraints
,
958 || !strcmp (opcode_handle
->opc0
[i
]->constraints
,
960 || !strcmp (opcode_handle
->opc0
[i
]->constraints
,
962 || !strcmp (opcode_handle
->opc0
[i
]->constraints
,
964 return opcode_handle
->opc0
[i
];
966 if (oprs
[0].reg
== REG_CCR
)
967 if (!strcmp (opcode_handle
->opc0
[i
]->constraints
, XGATE_OP_MON_C_R
))
968 return opcode_handle
->opc0
[i
];
971 if (oprs
[0].reg
>= REG_R0
&& oprs
[0].reg
<= REG_R7
)
973 if (oprs
[1].reg
>= REG_R0
&& oprs
[1].reg
<= REG_R7
)
975 if (oprs
[2].reg
>= REG_R0
&& oprs
[2].reg
<= REG_R7
)
977 if (!strcmp (opcode_handle
->opc0
[i
]->constraints
,
979 || !strcmp (opcode_handle
->opc0
[i
]->constraints
,
981 return opcode_handle
->opc0
[i
];
984 if (oprs
[2].reg
== REG_NONE
)
985 if (!strcmp (opcode_handle
->opc0
[i
]->constraints
,
987 return opcode_handle
->opc0
[i
];
992 as_bad (_("unknown operand count"));
999 /* Because we are dealing with two different core that view the system
1000 memory with different offsets, we must differentiate what core a
1001 symbol belongs to, in order for the linker to cross-link. */
1004 xgate_frob_symbol (symbolS
*sym
)
1007 elf_symbol_type
*elfsym
;
1009 bfdsym
= symbol_get_bfdsym (sym
);
1010 elfsym
= elf_symbol_from (bfd_asymbol_bfd (bfdsym
), bfdsym
);
1012 gas_assert (elfsym
);
1014 /* Mark the symbol as being *from XGATE */
1015 elfsym
->internal_elf_sym
.st_target_internal
= 1;
1021 xgate_get_operands (char *line
, s_operand oprs
[])
1025 /* If there are no operands, then it must be inherent. */
1026 if (*line
== 0 || *line
== '\n' || *line
== '\r')
1029 for (num_operands
= 0; strlen (line
) && (num_operands
< MAX_NUM_OPERANDS
);
1032 line
= skip_whitespace (line
);
1036 oprs
[num_operands
].mod
= xgate_determine_modifiers (&line
);
1038 if ((oprs
[num_operands
].reg
= reg_name_search (line
)) == REG_NONE
)
1039 line
= xgate_parse_exp (line
, &oprs
[num_operands
].exp
);
1041 /* skip to next operand */
1052 if (num_operands
> MAX_NUM_OPERANDS
)
1054 return num_operands
;
1057 /* reg_name_search() finds the register number given its name.
1058 Returns the register number or REG_NONE on failure. */
1061 reg_name_search (char *name
)
1063 if (strncasecmp (name
, "r0", 2) == 0)
1065 if (strncasecmp (name
, "r1", 2) == 0)
1067 if (strncasecmp (name
, "r2", 2) == 0)
1069 if (strncasecmp (name
, "r3", 2) == 0)
1071 if (strncasecmp (name
, "r4", 2) == 0)
1073 if (strncasecmp (name
, "r5", 2) == 0)
1075 if (strncasecmp (name
, "r6", 2) == 0)
1077 if (strncasecmp (name
, "r7", 2) == 0)
1079 if (strncasecmp (name
, "pc", 2) == 0)
1081 if (strncasecmp (name
, "ccr", 3) == 0)
1086 /* Parse operand modifiers such as inc/dec/hi/low. */
1089 xgate_determine_modifiers (char **line
)
1091 char *local_line
= line
[0];
1093 if (strncasecmp (local_line
, "%hi", 3) == 0)
1096 return MOD_LOAD_HIGH
;
1098 if (strncasecmp (local_line
, "%lo", 3) == 0)
1101 return MOD_LOAD_LOW
;
1103 if (*(local_line
+ 2) == '+')
1105 if (strncasecmp (local_line
, "-r", 2) == 0)
1113 /* Parse instruction operands. */
1116 xgate_scan_operands (struct xgate_opcode
*opcode
, s_operand oprs
[])
1118 char *frag
= xgate_new_instruction (opcode
->size
);
1119 int where
= frag
- frag_now
->fr_literal
;
1120 char *op
= opcode
->constraints
;
1121 unsigned int bin
= (int) opcode
->bin_opcode
;
1122 unsigned short oper_mask
= 0;
1123 int operand_bit_length
= 0;
1124 unsigned int operand
= 0;
1125 char n_operand_bits
= 0;
1126 char first_operand_equals_second
= 0;
1130 /* Generate available operand bits mask. */
1131 for (i
= 0; (c
= opcode
->format
[i
]); i
++)
1133 if (ISDIGIT (c
) || (c
== 's'))
1145 /* Parse first operand. */
1150 first_operand_equals_second
= 1;
1153 operand
= xgate_parse_operand (opcode
, &operand_bit_length
, where
,
1156 bin
= xgate_apply_operand (operand
, &oper_mask
, bin
, operand_bit_length
);
1158 if (first_operand_equals_second
)
1159 bin
= xgate_apply_operand (operand
, &oper_mask
, bin
,
1160 operand_bit_length
);
1161 /* Parse second operand. */
1166 if (first_operand_equals_second
)
1168 bin
= xgate_apply_operand (operand
, &oper_mask
, bin
,
1169 operand_bit_length
);
1174 operand
= xgate_parse_operand (opcode
, &operand_bit_length
, where
,
1176 bin
= xgate_apply_operand (operand
, &oper_mask
, bin
,
1177 operand_bit_length
);
1181 /* Parse the third register. */
1186 operand
= xgate_parse_operand (opcode
, &operand_bit_length
, where
,
1188 bin
= xgate_apply_operand (operand
, &oper_mask
, bin
,
1189 operand_bit_length
);
1192 if (opcode
->size
== 2 && fixup_required
)
1194 bfd_putl16 (bin
, frag
);
1196 else if ( !strcmp (opcode
->constraints
, XGATE_OP_REL9
)
1197 || !strcmp (opcode
->constraints
, XGATE_OP_REL10
))
1199 /* Write our data to a frag for further processing. */
1200 bfd_putl16 (opcode
->bin_opcode
, frag
);
1204 /* Apply operand mask(s)to bin opcode and write the output. */
1205 /* Since we are done write this frag in xgate BE format. */
1206 number_to_chars_bigendian (frag
, bin
, opcode
->size
);
1213 xgate_parse_operand (struct xgate_opcode
*opcode
,
1219 char *op_constraint
= *op_con
;
1220 unsigned int op_mask
= 0;
1221 unsigned int pp_fix
= 0;
1222 unsigned short max_size
= 0;
1228 switch (*op_constraint
)
1230 case '+': /* Indexed register operand +/- or plain r. */
1231 /* Default to neither inc or dec. */
1235 if (operand
.reg
== REG_NONE
)
1236 as_bad (_(": expected register name r0-r7 ") );
1237 op_mask
= operand
.reg
;
1238 if (operand
.mod
== MOD_POSTINC
)
1240 if (operand
.mod
== MOD_PREDEC
)
1246 case 'r': /* Register operand. */
1247 if (operand
.reg
== REG_NONE
)
1248 as_bad (_(": expected register name r0-r7 "));
1252 op_mask
= operand
.reg
;
1255 case 'i': /* Immediate value or expression expected. */
1256 /* Advance the original format pointer. */
1259 if (ISDIGIT (*op_constraint
))
1260 *bit_width
= (int) *op_constraint
- '0';
1261 else if (*op_constraint
== 'a')
1263 else if (*op_constraint
== 'f')
1266 /* http://tigcc.ticalc.org/doc/gnuasm.html#SEC31 */
1267 if (operand
.exp
.X_op
== O_constant
)
1269 op_mask
= operand
.exp
.X_add_number
;
1270 if (((opcode
->name
[strlen (opcode
->name
) - 1] == 'l') && autoHiLo
)
1271 || operand
.mod
== MOD_LOAD_LOW
)
1273 else if (((opcode
->name
[strlen (opcode
->name
) - 1]) == 'h'
1274 && autoHiLo
) || operand
.mod
== MOD_LOAD_HIGH
)
1277 /* Make sure it fits. */
1278 for (i
= *bit_width
; i
; i
--)
1283 if (op_mask
> max_size
)
1284 as_bad (_(":operand value(%d) too big for constraint"), op_mask
);
1288 /* Should be BFD_RELOC_XGATE_IMM8_LO instead of BFD_RELOC_XGATE_24
1291 if (*op_constraint
== '8')
1293 if (((opcode
->name
[strlen (opcode
->name
) - 1] == 'l')
1294 && autoHiLo
) || operand
.mod
== MOD_LOAD_LOW
)
1295 fix_new_exp (frag_now
, where
, 2, &operand
.exp
, FALSE
,
1296 BFD_RELOC_XGATE_24
);
1297 else if (((opcode
->name
[strlen (opcode
->name
) - 1]) == 'h'
1298 && autoHiLo
) || operand
.mod
== MOD_LOAD_HIGH
)
1299 fix_new_exp (frag_now
, where
, 2, &operand
.exp
, FALSE
,
1300 BFD_RELOC_XGATE_IMM8_HI
);
1302 as_bad (_("you must use a hi/lo directive or 16-bit macro "
1303 "to load a 16-bit value."));
1305 else if (*op_constraint
== '5')
1306 fix_new_exp (frag_now
, where
, 2, &operand
.exp
, FALSE
,
1307 BFD_RELOC_XGATE_IMM5
);
1308 else if (*op_constraint
== '4')
1309 fix_new_exp (frag_now
, where
, 2, &operand
.exp
, FALSE
,
1310 BFD_RELOC_XGATE_IMM4
);
1311 else if (*op_constraint
== '3')
1312 fix_new_exp (frag_now
, where
, 2, &operand
.exp
, FALSE
,
1313 BFD_RELOC_XGATE_IMM3
);
1315 as_bad (_(":unknown relocation constraint size"));
1319 case 'c': /* CCR register expected. */
1321 if (operand
.reg
!= REG_CCR
)
1322 as_bad (_(": expected register name ccr "));
1325 case 'p': /* PC register expected. */
1327 if (operand
.reg
!= REG_PC
)
1328 as_bad (_(": expected register name pc "));
1331 case 'b': /* Branch expected. */
1335 if (operand
.exp
.X_op
!= O_register
)
1337 if (*op_constraint
== '9')
1338 fix_new_exp (frag_now
, where
, 2, &operand
.exp
, TRUE
,
1340 else if (*op_constraint
== 'a')
1341 fix_new_exp (frag_now
, where
, 2, &operand
.exp
, TRUE
,
1345 as_fatal (_("Operand `%x' not recognized in fixup8."),
1352 as_bad (_("unknown constraint `%c'"), *op_constraint
);