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>
6 This file is part of GAS, the GNU Assembler.
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)
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.
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. */
24 #include "safe-ctype.h"
26 #include "opcode/xgate.h"
27 #include "dwarf2dbg.h"
28 #include "elf/xgate.h"
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";
36 #define SIXTEENTH_BIT 0x8000
37 #define N_BITS_IN_WORD 16
38 #define MAX_NUM_OPERANDS 3
40 /* #define STATE_CONDITIONAL_BRANCH (1) */
41 #define STATE_PC_RELATIVE (2)
42 #define REGISTER_P(ptr) (ptr == 'r')
45 #define MAXREGISTER 07
46 #define MINREGISTER 00
48 #define OPTION_MMCU 'm'
50 /* This macro has no side-effects. */
51 #define ENCODE_RELAX(what,length) (((what) << 2) + (length))
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
60 struct xgate_opcode
*opc0
[MAX_OPCODES
];
63 /* XGATE's registers all are 16-bit general purpose.
64 They are numbered according to the specifications. */
65 typedef enum register_id
80 /* Operand Modifiers */
81 typedef enum op_modifiers
91 typedef struct s_operand
99 /* Forward declarations. */
100 static inline char *skip_whitespace (char *);
101 static void get_default_target (void);
102 static char *extract_word (char *, char *, int);
103 static struct xgate_opcode
*xgate_find_match (struct xgate_opcode_handle
*,
105 static int cmp_opcode (struct xgate_opcode
*, struct xgate_opcode
*);
106 static void xgate_print_table (void);
107 static unsigned int xgate_get_operands (char *, s_operand
[]);
108 static register_id
reg_name_search (char *);
109 static op_modifiers
xgate_determine_modifiers(char **);
110 static void xgate_scan_operands (struct xgate_opcode
*opcode
, s_operand
[]);
111 static unsigned int xgate_parse_operand (struct xgate_opcode
*, int *, int,
114 static struct hash_control
*xgate_hash
;
116 /* Previous opcode. */
117 static unsigned int prev
= 0;
119 static unsigned char fixup_required
= 0;
121 /* Used to enable clipping of 16 bit operands into 8 bit constraints. */
122 static unsigned char autoHiLo
= 0;
124 static char oper_check
;
125 static char flag_print_insn_syntax
= 0;
126 static char flag_print_opcodes
= 0;
128 static int current_architecture
;
129 static const char *default_cpu
;
131 /* ELF flags to set in the output file header. */
132 static int elf_flags
= E_XGATE_F64
;
134 /* This table describes how you change sizes for the various types of variable
135 size expressions. This version only supports two kinds. */
138 How far Forward this mode will reach.
139 How far Backward this mode will reach.
140 How many bytes this mode will add to the size of the frag.
141 Which mode to go to if the offset won't fit in this one. */
143 relax_typeS md_relax_table
[] =
145 {1, 1, 0, 0}, /* First entries aren't used. */
146 {1, 1, 0, 0}, /* For no good reason except. */
147 {1, 1, 0, 0}, /* that the VAX doesn't either. */
149 /* XGATE 9 and 10 bit pc rel todo complete and test */
150 /*{(511), (-512), 0, ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD)},
151 {(1023), (-1024), 0, ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD)}, */
155 /* This table describes all the machine specific pseudo-ops the assembler
156 has to support. The fields are: pseudo-op name without dot function to
157 call to execute this pseudo-op Integer arg to pass to the function. */
158 const pseudo_typeS md_pseudo_table
[] =
160 /* The following pseudo-ops are supported for MRI compatibility. */
164 const char *md_shortopts
= "m:";
166 struct option md_longopts
[] =
168 #define OPTION_PRINT_INSN_SYNTAX (OPTION_MD_BASE + 0)
169 { "print-insn-syntax", no_argument
, NULL
, OPTION_PRINT_INSN_SYNTAX
},
171 #define OPTION_PRINT_OPCODES (OPTION_MD_BASE + 1)
172 { "print-opcodes", no_argument
, NULL
, OPTION_PRINT_OPCODES
},
174 #define OPTION_GENERATE_EXAMPLE (OPTION_MD_BASE + 2)
175 { "generate-example", no_argument
, NULL
, OPTION_GENERATE_EXAMPLE
},
177 #define OPTION_MSHORT (OPTION_MD_BASE + 3)
178 { "mshort", no_argument
, NULL
, OPTION_MSHORT
},
180 #define OPTION_MLONG (OPTION_MD_BASE + 4)
181 { "mlong", no_argument
, NULL
, OPTION_MLONG
},
183 #define OPTION_MSHORT_DOUBLE (OPTION_MD_BASE + 5)
184 { "mshort-double", no_argument
, NULL
, OPTION_MSHORT_DOUBLE
},
186 #define OPTION_MLONG_DOUBLE (OPTION_MD_BASE + 6)
187 { "mlong-double", no_argument
, NULL
, OPTION_MLONG_DOUBLE
},
189 { NULL
, no_argument
, NULL
, 0 }
192 size_t md_longopts_size
= sizeof(md_longopts
);
195 md_atof (int type
, char *litP
, int *sizeP
)
197 return ieee_md_atof (type
, litP
, sizeP
, TRUE
);
201 md_parse_option (int c
, char *arg
)
206 if (strcasecmp (arg
, "v1") == 0)
207 current_architecture
= XGATE_V1
;
208 else if (strcasecmp (arg
, "v2") == 0)
209 current_architecture
= XGATE_V2
;
210 else if (strcasecmp (arg
, "v3") == 0)
211 current_architecture
= XGATE_V3
;
213 as_bad (_(" architecture variant invalid"));
216 case OPTION_PRINT_INSN_SYNTAX
:
217 flag_print_insn_syntax
= 1;
220 case OPTION_PRINT_OPCODES
:
221 flag_print_opcodes
= 1;
224 case OPTION_GENERATE_EXAMPLE
:
225 flag_print_opcodes
= 2;
229 elf_flags
&= ~E_XGATE_I32
;
233 elf_flags
|= E_XGATE_I32
;
236 case OPTION_MSHORT_DOUBLE
:
237 elf_flags
&= ~E_XGATE_F64
;
240 case OPTION_MLONG_DOUBLE
:
241 elf_flags
|= E_XGATE_F64
;
251 xgate_arch_format (void)
253 get_default_target ();
255 if (current_architecture
& cpuxgate
)
256 return "elf32-xgate";
262 get_default_target (void)
264 const bfd_target
*target
;
267 if (current_architecture
!= 0)
270 default_cpu
= "unknown";
271 target
= bfd_find_target (0, &abfd
);
273 if (target
&& target
->name
)
275 if (strcmp (target
->name
, "elf32-xgate") == 0)
277 current_architecture
= cpuxgate
;
278 default_cpu
= "XGATE V1";
282 as_bad (_("Default target `%s' is not supported."), target
->name
);
289 struct xgate_opcode
*xgate_opcode_ptr
= NULL
;
290 struct xgate_opcode
*xgate_op_table
= NULL
;
291 struct xgate_opcode_handle
*op_handles
= 0;
292 char *prev_op_name
= 0;
294 int number_of_op_handles
= 0;
297 /* Create a local copy of our opcode table
298 including an extra line for NULL termination. */
299 xgate_op_table
= (struct xgate_opcode
*)
300 xmalloc ((xgate_num_opcodes
) * sizeof (struct xgate_opcode
));
302 memset (xgate_op_table
, 0,
303 sizeof(struct xgate_opcode
) * (xgate_num_opcodes
));
305 for (xgate_opcode_ptr
= (struct xgate_opcode
*) xgate_opcodes
, i
= 0;
306 i
< xgate_num_opcodes
; i
++)
307 xgate_op_table
[i
] = xgate_opcode_ptr
[i
];
309 qsort (xgate_op_table
, xgate_num_opcodes
, sizeof(struct xgate_opcode
),
310 (int (*)(const void *, const void *)) cmp_opcode
);
312 /* Calculate number of handles since this will be
313 smaller than the raw number of opcodes in the table. */
315 for (xgate_opcode_ptr
= xgate_op_table
, i
= 0; i
< xgate_num_opcodes
;
316 xgate_opcode_ptr
++, i
++)
318 if (strcmp (prev_op_name
, xgate_opcode_ptr
->name
))
319 number_of_op_handles
++;
320 prev_op_name
= xgate_opcode_ptr
->name
;
323 op_handles
= (struct xgate_opcode_handle
*)
324 xmalloc (sizeof(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
== 1)
353 xgate_print_table ();
357 xgate_init_after_args (void)
362 md_show_usage (FILE * stream
)
364 get_default_target ();
368 Freescale XGATE co-processor options:\n\
369 -mshort use 16-bit int ABI (default)\n\
370 -mlong use 32-bit int ABI\n\
371 -mshort-double use 32-bit double ABI\n\
372 -mlong-double use 64-bit double ABI (default)\n\
373 --mxgate specify the processor variant[default %s]\n\
374 --print-insn-syntax print the syntax of instruction in case of error\n\
375 --print-opcodes print the list of instructions with syntax\n\
376 --generate-example generate an example of each instruction"),
380 enum bfd_architecture
383 get_default_target ();
384 return bfd_arch_xgate
;
394 xgate_print_syntax (char *name
)
398 for (i
= 0; i
< xgate_num_opcodes
; i
++)
400 if (!strcmp (xgate_opcodes
[i
].name
, name
))
402 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_IDR
))
403 printf ("\tFormat is %s\tRx, Rx, Rx+|-Rx|Rx\n",
404 xgate_opcodes
[i
].name
);
405 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_INH
))
406 printf ("\tFormat is %s\n", xgate_opcodes
[i
].name
);
407 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_TRI
))
408 printf ("\tFormat is %s\tRx, Rx, Rx\n", xgate_opcodes
[i
].name
);
409 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_DYA
))
410 printf ("\tFormat is %s\tRx, Rx\n", xgate_opcodes
[i
].name
);
411 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_IMM3
))
412 printf ("\tFormat is %s\t<3-bit value>\n", xgate_opcodes
[i
].name
);
413 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_IMM4
))
414 printf ("\tFormat is %s\t<4 -bit value>\n", xgate_opcodes
[i
].name
);
415 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_IMM8
))
416 printf ("\tFormat is %s\tRx, <8-bit value>\n",
417 xgate_opcodes
[i
].name
);
418 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_IMM16
))
419 printf ("\tFormat is %s\tRx, <16-bit value>\n",
420 xgate_opcodes
[i
].name
);
421 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_MON_R_C
))
422 printf ("\tFormat is %s\tRx, CCR\n", xgate_opcodes
[i
].name
);
423 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_MON_C_R
))
424 printf ("\tFormat is %s\tCCR, Rx\n", xgate_opcodes
[i
].name
);
425 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_MON_R_P
))
426 printf ("\tFormat is %s\tRx, PC\n", xgate_opcodes
[i
].name
);
427 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_IMM16mLDW
))
428 printf ("\tFormat is %s\tRx, <16-bit value>\n",
429 xgate_opcodes
[i
].name
);
435 xgate_print_table (void)
439 for (i
= 0; i
< xgate_num_opcodes
; i
++)
440 xgate_print_syntax (xgate_opcodes
[i
].name
);
446 xgate_listing_header (void)
448 if (current_architecture
& cpuxgate
)
451 return "ERROR MC9S12X GAS ";
455 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
460 /* GAS will call this function for each section at the end of the assembly,
461 to permit the CPU backend to adjust the alignment of a section. */
464 md_section_align (asection
* seg
, valueT addr
)
466 int align
= bfd_get_section_alignment (stdoutput
, seg
);
467 return ((addr
+ (1 << align
) - 1) & (-1 << align
));
471 md_assemble (char *input_line
)
473 struct xgate_opcode
*opcode
= 0;
474 struct xgate_opcode
*macro_opcode
= 0;
475 struct xgate_opcode_handle
*opcode_handle
= 0;
476 /* Caller expects it to be returned as it was passed. */
477 char *saved_input_line
= input_line
;
478 char op_name
[9] = { 0 };
479 unsigned int sh_format
= 0;
482 s_operand new_operands
[MAX_NUM_OPERANDS
];
485 oper_check
= 0; /* set error flags */
486 input_line
= extract_word (input_line
, op_name
, sizeof(op_name
));
488 /* Check to make sure we are not reading a bogus line. */
490 as_bad (_("opcode missing or not found on input line"));
492 if (!(opcode_handle
= (struct xgate_opcode_handle
*) hash_find (xgate_hash
,
495 as_bad (_("opcode %s not found in opcode hash table"), op_name
);
499 /* Parse operands so we can find the proper opcode bin. */
501 sh_format
= xgate_get_operands(input_line
, new_operands
);
503 opcode
= xgate_find_match (opcode_handle
, opcode_handle
->number_of_modes
,
508 as_bad (_("matching operands to opcode "));
509 xgate_print_syntax (opcode_handle
->opc0
[0]->name
);
511 else if (opcode
->size
== 2)
513 /* Size is one word - assemble that native insn. */
514 xgate_scan_operands (opcode
, new_operands
);
518 /* Insn is a simplified instruction - expand it out. */
522 /* skip past our ';' separator. */
523 for (i
= strlen (opcode
->constraints
), p
= opcode
->constraints
; i
> 0;
532 input_line
= skip_whitespace (input_line
);
533 char *macro_inline
= input_line
;
535 /* Loop though the macro's opcode list and apply operands to
537 for (i
= 0; *p
&& i
< (opcode
->size
/ 2); i
++)
539 /* Loop though macro operand list. */
540 input_line
= macro_inline
; /* Rewind. */
541 p
= extract_word (p
, op_name
, 10);
543 if (!(opcode_handle
= (struct xgate_opcode_handle
*)
544 hash_find (xgate_hash
, op_name
)))
546 as_bad (_(": processing macro, real opcode handle"
547 " not found in hash"));
552 sh_format
= xgate_get_operands(input_line
, new_operands
);
554 = xgate_find_match (opcode_handle
,
555 opcode_handle
->number_of_modes
,
557 xgate_scan_operands (macro_opcode
, new_operands
);
564 input_line
= saved_input_line
;
567 /* Force truly undefined symbols to their maximum size, and generally set up
568 the frag list to be relaxed. */
571 md_estimate_size_before_relax (fragS
*fragp
, asection
*seg
)
573 /* If symbol is undefined or located in a different section,
574 select the largest supported relocation. */
575 relax_substateT subtype
;
576 relax_substateT rlx_state
[] = { 0, 2 };
578 for (subtype
= 0; subtype
< ARRAY_SIZE (rlx_state
); subtype
+= 2)
580 if (fragp
->fr_subtype
== rlx_state
[subtype
]
581 && (!S_IS_DEFINED (fragp
->fr_symbol
)
582 || seg
!= S_GET_SEGMENT (fragp
->fr_symbol
)))
584 fragp
->fr_subtype
= rlx_state
[subtype
+ 1];
589 if (fragp
->fr_subtype
>= ARRAY_SIZE (md_relax_table
))
592 return md_relax_table
[fragp
->fr_subtype
].rlx_length
;
596 /* Relocation, relaxation and frag conversions. */
598 /* PC-relative offsets are relative to the start of the
599 next instruction. That is, the address of the offset, plus its
600 size, since the offset is always the last part of the insn. */
603 md_pcrel_from (fixS
* fixP
)
605 return fixP
->fx_size
+ fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
608 /* If while processing a fixup, a reloc really needs to be created
609 then it is done here. */
612 tc_gen_reloc (asection
* section ATTRIBUTE_UNUSED
, fixS
* fixp
)
616 reloc
= (arelent
*) xmalloc (sizeof(arelent
));
617 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof(asymbol
*));
618 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
619 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
621 if (fixp
->fx_r_type
== 0)
622 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_16
);
624 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
626 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
628 as_bad_where (fixp
->fx_file
, fixp
->fx_line
, _
629 ("Relocation %d is not supported by object file format."),
630 (int) fixp
->fx_r_type
);
634 /* Since we use Rel instead of Rela, encode the vtable entry to be
635 used in the relocation's section offset. */
636 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
637 reloc
->address
= fixp
->fx_offset
;
642 /* Patch the instruction with the resolved operand. Elf relocation
643 info will also be generated to take care of linker/loader fixups.
644 The XGATE addresses only 16-bit addresses.The BFD_RELOC_32 is necessary
645 for the support of --gstabs. */
648 md_apply_fix (fixS
* fixP
, valueT
* valP
, segT seg ATTRIBUTE_UNUSED
)
655 /* If the fixup is done mark it done so no further symbol resolution
657 if (fixP
->fx_addsy
== (symbolS
*) NULL
)
660 /* We don't actually support subtracting a symbol. */
661 if (fixP
->fx_subsy
!= (symbolS
*) NULL
)
662 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("Expression too complex."));
664 where
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
665 opcode
= bfd_getl16 (where
);
668 switch (fixP
->fx_r_type
)
670 case R_XGATE_PCREL_9
:
671 if (value
< -512 || value
> 511)
672 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
673 _("Value %ld too large for 9-bit PC-relative branch."),
675 result
= ldiv (value
, 2); /* from bytes to words */
678 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _
679 ("Value %ld not aligned by 2 for 9-bit"
680 " PC-relative branch."), value
);
681 /* Clip into 8-bit field.
682 FIXME I'm sure there is a more proper place for this. */
685 number_to_chars_bigendian (where
, (opcode
| value
), 2);
687 case R_XGATE_PCREL_10
:
688 if (value
< -1024 || value
> 1023)
689 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
690 _("Value %ld too large for 10-bit PC-relative branch."),
692 result
= ldiv (value
, 2); /* from bytes to words */
695 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _
696 ("Value %ld not aligned by 2 for 10-bit"
697 " PC-relative branch."), value
);
698 /* Clip into 9-bit field.
699 FIXME I'm sure there is a more proper place for this. */
702 number_to_chars_bigendian (where
, (opcode
| value
), 2);
704 case BFD_RELOC_XGATE_IMM8_HI
:
705 if (value
< -65537 || value
> 65535)
706 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
707 _("Value out of 16-bit range."));
710 bfd_putb16 ((bfd_vma
) value
| opcode
, (void *) where
);
712 case BFD_RELOC_XGATE_24
:
713 case BFD_RELOC_XGATE_IMM8_LO
:
714 if (value
< -65537 || value
> 65535)
715 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
716 _("Value out of 16-bit range."));
718 bfd_putb16 ((bfd_vma
) value
| opcode
, (void *) where
);
720 case BFD_RELOC_XGATE_IMM3
:
721 if (value
< 0 || value
> 7)
722 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
723 _("Value out of 3-bit range."));
724 value
<<= 8; /* make big endian */
725 number_to_chars_bigendian (where
, (opcode
| value
), 2);
727 case BFD_RELOC_XGATE_IMM4
:
728 if (value
< 0 || value
> 15)
729 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
730 _("Value out of 4-bit range."));
731 value
<<= 4; /* align the operand bits */
732 number_to_chars_bigendian (where
, (opcode
| value
), 2);
734 case BFD_RELOC_XGATE_IMM5
:
735 if (value
< 0 || value
> 31)
736 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
737 _("Value out of 5-bit range."));
738 value
<<= 5; /* align the operand bits */
739 number_to_chars_bigendian (where
, (opcode
| value
), 2);
742 ((bfd_byte
*) where
)[0] = (bfd_byte
) value
;
745 bfd_putb32 ((bfd_vma
) value
, (unsigned char *) where
);
748 bfd_putb16 ((bfd_vma
) value
, (unsigned char *) where
);
751 as_fatal (_("Line %d: unknown relocation type: 0x%x."), fixP
->fx_line
,
757 /* See whether we need to force a relocation into the output file. */
760 tc_xgate_force_relocation (fixS
* fixP
)
762 if (fixP
->fx_r_type
== BFD_RELOC_XGATE_RL_GROUP
)
764 return generic_force_reloc (fixP
);
767 /* Here we decide which fixups can be adjusted to make them relative
768 to the beginning of the section instead of the symbol. Basically
769 we need to make sure that the linker relaxation is done
770 correctly, so in some cases we force the original symbol to be
774 tc_xgate_fix_adjustable (fixS
* fixP
)
776 switch (fixP
->fx_r_type
)
778 /* For the linker relaxation to work correctly, these relocs
779 need to be on the symbol itself. */
781 case BFD_RELOC_XGATE_RL_JUMP
:
782 case BFD_RELOC_XGATE_RL_GROUP
:
783 case BFD_RELOC_VTABLE_INHERIT
:
784 case BFD_RELOC_VTABLE_ENTRY
:
793 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
,
794 asection
* sec ATTRIBUTE_UNUSED
,
795 fragS
* fragP ATTRIBUTE_UNUSED
)
797 as_bad (("md_convert_frag not implemented yet"));
801 /* Set the ELF specific flags. */
804 xgate_elf_final_processing (void)
806 elf_flags
|= EF_XGATE_MACH
;
807 elf_elfheader (stdoutput
)->e_flags
&= ~EF_XGATE_ABI
;
808 elf_elfheader (stdoutput
)->e_flags
|= elf_flags
;
812 skip_whitespace (char *s
)
814 while (*s
== ' ' || *s
== '\t' || *s
== '(' || *s
== ')')
820 /* Extract a word (continuous alpha-numeric chars) from the input line. */
823 extract_word (char *from
, char *to
, int limit
)
828 /* Drop leading whitespace. */
829 from
= skip_whitespace (from
);
831 /* Find the op code end. */
832 for (op_end
= from
; *op_end
!= 0 && is_part_of_name (*op_end
);)
834 to
[size
++] = *op_end
++;
835 if (size
+ 1 >= limit
)
843 xgate_new_instruction (int size
)
845 char *f
= frag_more (size
);
846 dwarf2_emit_insn (size
);
850 static unsigned short
851 xgate_apply_operand (unsigned short new_mask
,
852 unsigned short *availiable_mask_bits
,
854 unsigned char n_bits
)
856 unsigned short n_shifts
;
857 unsigned int n_drop_bits
;
859 /* Shift until you find an available operand bit "1" and record
860 the number of shifts. */
862 !(*availiable_mask_bits
& SIXTEENTH_BIT
) && n_shifts
< 16;
864 *availiable_mask_bits
<<= 1;
866 /* Shift for the number of bits your operand requires while bits
868 for (n_drop_bits
= n_bits
;
869 n_drop_bits
&& (*availiable_mask_bits
& SIXTEENTH_BIT
);
871 *availiable_mask_bits
<<= 1;
874 as_bad (_(":operand has too many bits"));
875 *availiable_mask_bits
>>= n_shifts
+ n_bits
;
876 if ((n_drop_bits
== 0) && (*availiable_mask_bits
== 0))
878 oper_check
= 1; /* flag operand check as good */
880 new_mask
<<= N_BITS_IN_WORD
- (n_shifts
+ n_bits
);
885 /* Parse ordinary expression. */
888 xgate_parse_exp (char *s
, expressionS
* op
)
890 input_line_pointer
= s
;
892 if (op
->X_op
== O_absent
)
893 as_bad (_("missing operand"));
894 return input_line_pointer
;
898 cmp_opcode (struct xgate_opcode
*op1
, struct xgate_opcode
*op2
)
900 return strcmp (op1
->name
, op2
->name
);
903 static struct xgate_opcode
*
904 xgate_find_match (struct xgate_opcode_handle
*opcode_handle
,
906 unsigned int sh_format
)
910 if (numberOfModes
== 0)
911 return opcode_handle
->opc0
[0];
913 for (i
= 0; i
<= numberOfModes
; i
++)
914 if (opcode_handle
->opc0
[i
]->sh_format
& sh_format
)
915 return opcode_handle
->opc0
[i
];
920 /* Because we are dealing with two different core that view the system
921 memory with different offsets, we must differentiate what core a
922 symbol belongs to, in order for the linker to cross-link. */
925 xgate_frob_symbol (symbolS
*sym
)
928 elf_symbol_type
*elfsym
;
930 bfdsym
= symbol_get_bfdsym (sym
);
931 elfsym
= elf_symbol_from (bfd_asymbol_bfd (bfdsym
), bfdsym
);
935 /* Mark the symbol as being *from XGATE */
936 elfsym
->internal_elf_sym
.st_target_internal
= 1;
942 xgate_get_operands (char *line
, s_operand oprs
[])
946 /* If there are no operands, then it must be inherent. */
947 if (*line
== 0 || *line
== '\n' || *line
== '\r')
950 for (num_operands
= 0; strlen (line
) && (num_operands
< MAX_NUM_OPERANDS
);
953 line
= skip_whitespace (line
);
957 oprs
[num_operands
].mod
= xgate_determine_modifiers (&line
);
959 if ((oprs
[num_operands
].reg
= reg_name_search (line
)) == REG_NONE
)
960 line
= xgate_parse_exp (line
, &oprs
[num_operands
].exp
);
962 /* skip to next operand */
974 if (num_operands
> MAX_NUM_OPERANDS
)
977 switch (num_operands
)
980 if (oprs
[0].reg
>= REG_R0
&& oprs
[0].reg
<= REG_R7
)
982 if (oprs
[0].reg
== REG_NONE
)
986 if (oprs
[0].reg
>= REG_R0
&& oprs
[0].reg
<= REG_R7
)
988 if (oprs
[1].reg
>= REG_R0
&& oprs
[1].reg
<= REG_R7
)
990 if (oprs
[1].reg
== REG_CCR
)
992 if (oprs
[1].reg
== REG_PC
)
994 if (oprs
[1].reg
== REG_NONE
)
997 if (oprs
[0].reg
== REG_CCR
)
1001 if (oprs
[0].reg
>= REG_R0
&& oprs
[0].reg
<= REG_R7
)
1003 if (oprs
[1].reg
>= REG_R0
&& oprs
[1].reg
<= REG_R7
)
1005 if (oprs
[2].reg
>= REG_R0
&& oprs
[2].reg
<= REG_R7
)
1007 if (oprs
[2].reg
>= REG_NONE
)
1013 as_bad (_("unknown operand format"));
1020 /* reg_name_search() finds the register number given its name.
1021 Returns the register number or REG_NONE on failure. */
1023 reg_name_search (char *name
)
1025 if (strncasecmp (name
, "r0", 2) == 0)
1027 if (strncasecmp (name
, "r1", 2) == 0)
1029 if (strncasecmp (name
, "r2", 2) == 0)
1031 if (strncasecmp (name
, "r3", 2) == 0)
1033 if (strncasecmp (name
, "r4", 2) == 0)
1035 if (strncasecmp (name
, "r5", 2) == 0)
1037 if (strncasecmp (name
, "r6", 2) == 0)
1039 if (strncasecmp (name
, "r7", 2) == 0)
1041 if (strncasecmp (name
, "pc", 2) == 0)
1043 if (strncasecmp (name
, "ccr", 3) == 0)
1048 /* Parse operand modifiers such as inc/dec/hi/low. */
1051 xgate_determine_modifiers(char **line
)
1053 char *local_line
= line
[0];
1055 if (strncasecmp (local_line
, "%hi", 3) == 0)
1058 return MOD_LOAD_HIGH
;
1060 if (strncasecmp (local_line
, "%lo", 3) == 0)
1063 return MOD_LOAD_LOW
;
1065 if (*(local_line
+ 2) == '+')
1067 if (strncasecmp (local_line
, "-r", 2) == 0)
1075 /* Parse instruction operands. */
1078 xgate_scan_operands (struct xgate_opcode
*opcode
, s_operand oprs
[])
1080 char *frag
= xgate_new_instruction (opcode
->size
);
1081 int where
= frag
- frag_now
->fr_literal
;
1082 char *op
= opcode
->constraints
;
1083 unsigned int bin
= (int) opcode
->bin_opcode
;
1084 unsigned short oper_mask
= 0;
1085 int operand_bit_length
= 0;
1086 unsigned int operand
= 0;
1087 char n_operand_bits
= 0;
1088 char first_operand_equals_second
= 0;
1092 /* Generate available operand bits mask. */
1093 for (i
= 0; (c
= opcode
->format
[i
]); i
++)
1095 if (ISDIGIT (c
) || (c
== 's'))
1107 /* Parse first operand. */
1112 first_operand_equals_second
= 1;
1115 operand
= xgate_parse_operand (opcode
, &operand_bit_length
, where
,
1118 bin
= xgate_apply_operand (operand
, &oper_mask
, bin
, operand_bit_length
);
1120 if(first_operand_equals_second
)
1121 bin
= xgate_apply_operand (operand
, &oper_mask
, bin
,
1122 operand_bit_length
);
1123 /* Parse second operand. */
1128 if (first_operand_equals_second
)
1130 bin
= xgate_apply_operand (operand
, &oper_mask
, bin
,
1131 operand_bit_length
);
1136 operand
= xgate_parse_operand (opcode
, &operand_bit_length
, where
,
1138 bin
= xgate_apply_operand (operand
, &oper_mask
, bin
,
1139 operand_bit_length
);
1143 /* Parse the third register. */
1148 operand
= xgate_parse_operand (opcode
, &operand_bit_length
, where
,
1150 bin
= xgate_apply_operand (operand
, &oper_mask
, bin
,
1151 operand_bit_length
);
1154 if (opcode
->size
== 2 && fixup_required
)
1156 bfd_putl16 (bin
, frag
);
1158 else if ((opcode
->sh_format
& XG_PCREL
))
1160 /* Write our data to a frag for further processing. */
1161 bfd_putl16 (opcode
->bin_opcode
, frag
);
1165 /* Apply operand mask(s)to bin opcode and write the output. */
1166 /* Since we are done write this frag in xgate BE format. */
1167 number_to_chars_bigendian (frag
, bin
, opcode
->size
);
1174 xgate_parse_operand (struct xgate_opcode
*opcode
,
1180 char *op_constraint
= *op_con
;
1181 unsigned int op_mask
= 0;
1182 unsigned int pp_fix
= 0;
1183 unsigned short max_size
= 0;
1189 switch (*op_constraint
)
1191 case '+': /* Indexed register operand +/- or plain r. */
1192 /* Default to neither inc or dec. */
1196 if (operand
.reg
== REG_NONE
)
1197 as_bad (_(": expected register name r0-r7 ") );
1198 op_mask
= operand
.reg
;
1199 if(operand
.mod
== MOD_POSTINC
)
1201 if(operand
.mod
== MOD_PREDEC
)
1207 case 'r': /* Register operand. */
1208 if (operand
.reg
== REG_NONE
)
1209 as_bad (_(": expected register name r0-r7 "));
1213 op_mask
= operand
.reg
;
1216 case 'i': /* Immediate value or expression expected. */
1217 /* Advance the original format pointer. */
1220 if (ISDIGIT (*op_constraint
))
1221 *bit_width
= (int) *op_constraint
- '0';
1222 else if (*op_constraint
== 'a')
1224 else if (*op_constraint
== 'f')
1227 /* http://tigcc.ticalc.org/doc/gnuasm.html#SEC31 */
1228 if (operand
.exp
.X_op
== O_constant
)
1230 op_mask
= operand
.exp
.X_add_number
;
1231 if (((opcode
->name
[strlen (opcode
->name
) - 1] == 'l') && autoHiLo
)
1232 || operand
.mod
== MOD_LOAD_LOW
)
1234 else if (((opcode
->name
[strlen (opcode
->name
) - 1]) == 'h'
1235 && autoHiLo
) || operand
.mod
== MOD_LOAD_HIGH
)
1238 /* Make sure it fits. */
1239 for (i
= *bit_width
; i
; i
--)
1244 if (op_mask
> max_size
)
1245 as_bad (_(":operand value(%d) too big for constraint"), op_mask
);
1249 /* Should be BFD_RELOC_XGATE_IMM8_LO instead of BFD_RELOC_XGATE_24
1252 if (*op_constraint
== '8')
1254 if (((opcode
->name
[strlen (opcode
->name
) - 1] == 'l')
1255 && autoHiLo
) || operand
.mod
== MOD_LOAD_LOW
)
1256 fix_new_exp (frag_now
, where
, 2, &operand
.exp
, FALSE
,
1257 BFD_RELOC_XGATE_24
);
1258 else if (((opcode
->name
[strlen (opcode
->name
) - 1]) == 'h'
1259 && autoHiLo
) || operand
.mod
== MOD_LOAD_HIGH
)
1260 fix_new_exp (frag_now
, where
, 2, &operand
.exp
, FALSE
,
1261 BFD_RELOC_XGATE_IMM8_HI
);
1263 as_bad (_("you must use a hi/lo directive or 16-bit macro "
1264 "to load a 16-bit value."));
1266 else if (*op_constraint
== '5')
1267 fix_new_exp (frag_now
, where
, 2, &operand
.exp
, FALSE
,
1268 BFD_RELOC_XGATE_IMM5
);
1269 else if (*op_constraint
== '4')
1270 fix_new_exp (frag_now
, where
, 2, &operand
.exp
, FALSE
,
1271 BFD_RELOC_XGATE_IMM4
);
1272 else if (*op_constraint
== '3')
1273 fix_new_exp (frag_now
, where
, 2, &operand
.exp
, FALSE
,
1274 BFD_RELOC_XGATE_IMM3
);
1276 as_bad (_(":unknown relocation constraint size"));
1280 case 'c': /* CCR register expected. */
1282 if (operand
.reg
!= REG_CCR
)
1283 as_bad (_(": expected register name ccr "));
1286 case 'p': /* PC register expected. */
1288 if (operand
.reg
!= REG_PC
)
1289 as_bad (_(": expected register name pc "));
1292 case 'b': /* Branch expected. */
1296 if (operand
.exp
.X_op
!= O_register
)
1298 if (*op_constraint
== '9')
1299 fix_new_exp (frag_now
, where
, 2, &operand
.exp
, TRUE
,
1301 else if (*op_constraint
== 'a')
1302 fix_new_exp (frag_now
, where
, 2, &operand
.exp
, TRUE
,
1306 as_fatal (_("Operand `%x' not recognized in fixup8."),
1313 as_bad (_("unknown constraint `%c'"), *op_constraint
);