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 /* Max opcodes per opcode handle. */
37 #define MAX_OPCODES 0x05
39 #define SIXTEENTH_BIT 0x8000
40 #define N_BITS_IN_WORD 16
41 #define MAX_NUM_OPERANDS 3
43 /* #define STATE_CONDITIONAL_BRANCH (1) */
44 #define STATE_PC_RELATIVE (2)
45 #define REGISTER_P(ptr) (ptr == 'r')
48 #define MAXREGISTER 07
49 #define MINREGISTER 00
51 #define OPTION_MMCU 'm'
53 /* This macro has no side-effects. */
54 #define ENCODE_RELAX(what,length) (((what) << 2) + (length))
56 /* Each unique opcode name has a handle. That handle may
57 contain pointers to opcodes with the same name but
58 different address modes. */
59 struct xgate_opcode_handle
63 struct xgate_opcode
*opc0
[MAX_OPCODES
];
66 /* XGATE's registers all are 16-bit general purpose.
67 They are numbered according to the specifications. */
68 typedef enum register_id
83 /* Operand Modifiers */
84 typedef enum op_modifiers
94 typedef struct s_operand
102 /* Forward declarations. */
103 static inline char *skip_whitespace (char *);
104 static void get_default_target (void);
105 static char *extract_word (char *, char *, int);
106 static struct xgate_opcode
*xgate_find_match (struct xgate_opcode_handle
*,
107 int, s_operand
[], unsigned int);
108 static int cmp_opcode (struct xgate_opcode
*, struct xgate_opcode
*);
109 static void xgate_print_table (void);
110 static unsigned int xgate_get_operands (char *, s_operand
[]);
111 static register_id
reg_name_search (char *);
112 static op_modifiers
xgate_determine_modifiers(char **);
113 static void xgate_scan_operands (struct xgate_opcode
*opcode
, s_operand
[]);
114 static unsigned int xgate_parse_operand (struct xgate_opcode
*, int *, int,
117 static struct hash_control
*xgate_hash
;
119 /* Previous opcode. */
120 static unsigned int prev
= 0;
122 static unsigned char fixup_required
= 0;
124 /* Used to enable clipping of 16 bit operands into 8 bit constraints. */
125 static unsigned char autoHiLo
= 0;
127 static char oper_check
;
128 static char flag_print_insn_syntax
= 0;
129 static char flag_print_opcodes
= 0;
131 static int current_architecture
;
132 static const char *default_cpu
;
134 /* ELF flags to set in the output file header. */
135 static int elf_flags
= E_XGATE_F64
;
137 /* This table describes how you change sizes for the various types of variable
138 size expressions. This version only supports two kinds. */
141 How far Forward this mode will reach.
142 How far Backward this mode will reach.
143 How many bytes this mode will add to the size of the frag.
144 Which mode to go to if the offset won't fit in this one. */
146 relax_typeS md_relax_table
[] =
148 {1, 1, 0, 0}, /* First entries aren't used. */
149 {1, 1, 0, 0}, /* For no good reason except. */
150 {1, 1, 0, 0}, /* that the VAX doesn't either. */
152 /* XGATE 9 and 10 bit pc rel todo complete and test */
153 /*{(511), (-512), 0, ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD)},
154 {(1023), (-1024), 0, ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD)}, */
158 /* This table describes all the machine specific pseudo-ops the assembler
159 has to support. The fields are: pseudo-op name without dot function to
160 call to execute this pseudo-op Integer arg to pass to the function. */
161 const pseudo_typeS md_pseudo_table
[] =
163 /* The following pseudo-ops are supported for MRI compatibility. */
167 const char *md_shortopts
= "m:";
169 struct option md_longopts
[] =
171 #define OPTION_PRINT_INSN_SYNTAX (OPTION_MD_BASE + 0)
172 { "print-insn-syntax", no_argument
, NULL
, OPTION_PRINT_INSN_SYNTAX
},
174 #define OPTION_PRINT_OPCODES (OPTION_MD_BASE + 1)
175 { "print-opcodes", no_argument
, NULL
, OPTION_PRINT_OPCODES
},
177 #define OPTION_GENERATE_EXAMPLE (OPTION_MD_BASE + 2)
178 { "generate-example", no_argument
, NULL
, OPTION_GENERATE_EXAMPLE
},
180 #define OPTION_MSHORT (OPTION_MD_BASE + 3)
181 { "mshort", no_argument
, NULL
, OPTION_MSHORT
},
183 #define OPTION_MLONG (OPTION_MD_BASE + 4)
184 { "mlong", no_argument
, NULL
, OPTION_MLONG
},
186 #define OPTION_MSHORT_DOUBLE (OPTION_MD_BASE + 5)
187 { "mshort-double", no_argument
, NULL
, OPTION_MSHORT_DOUBLE
},
189 #define OPTION_MLONG_DOUBLE (OPTION_MD_BASE + 6)
190 { "mlong-double", no_argument
, NULL
, OPTION_MLONG_DOUBLE
},
192 { NULL
, no_argument
, NULL
, 0 }
195 size_t md_longopts_size
= sizeof(md_longopts
);
198 md_atof (int type
, char *litP
, int *sizeP
)
200 return ieee_md_atof (type
, litP
, sizeP
, TRUE
);
204 md_parse_option (int c
, char *arg
)
209 if (strcasecmp (arg
, "v1") == 0)
210 current_architecture
= XGATE_V1
;
211 else if (strcasecmp (arg
, "v2") == 0)
212 current_architecture
= XGATE_V2
;
213 else if (strcasecmp (arg
, "v3") == 0)
214 current_architecture
= XGATE_V3
;
216 as_bad (_(" architecture variant invalid"));
219 case OPTION_PRINT_INSN_SYNTAX
:
220 flag_print_insn_syntax
= 1;
223 case OPTION_PRINT_OPCODES
:
224 flag_print_opcodes
= 1;
227 case OPTION_GENERATE_EXAMPLE
:
228 flag_print_opcodes
= 2;
232 elf_flags
&= ~E_XGATE_I32
;
236 elf_flags
|= E_XGATE_I32
;
239 case OPTION_MSHORT_DOUBLE
:
240 elf_flags
&= ~E_XGATE_F64
;
243 case OPTION_MLONG_DOUBLE
:
244 elf_flags
|= E_XGATE_F64
;
254 xgate_arch_format (void)
256 get_default_target ();
258 if (current_architecture
& cpuxgate
)
259 return "elf32-xgate";
265 get_default_target (void)
267 const bfd_target
*target
;
270 if (current_architecture
!= 0)
273 default_cpu
= "unknown";
274 target
= bfd_find_target (0, &abfd
);
276 if (target
&& target
->name
)
278 if (strcmp (target
->name
, "elf32-xgate") == 0)
280 current_architecture
= cpuxgate
;
281 default_cpu
= "XGATE V1";
285 as_bad (_("Default target `%s' is not supported."), target
->name
);
292 struct xgate_opcode
*xgate_opcode_ptr
= NULL
;
293 struct xgate_opcode
*xgate_op_table
= NULL
;
294 struct xgate_opcode_handle
*op_handles
= 0;
295 char *prev_op_name
= 0;
297 int number_of_op_handles
= 0;
300 /* Create a local copy of our opcode table
301 including an extra line for NULL termination. */
302 xgate_op_table
= (struct xgate_opcode
*)
303 xmalloc ((xgate_num_opcodes
) * sizeof (struct xgate_opcode
));
305 memset (xgate_op_table
, 0,
306 sizeof(struct xgate_opcode
) * (xgate_num_opcodes
));
308 for (xgate_opcode_ptr
= (struct xgate_opcode
*) xgate_opcodes
, i
= 0;
309 i
< xgate_num_opcodes
; i
++)
310 xgate_op_table
[i
] = xgate_opcode_ptr
[i
];
312 qsort (xgate_op_table
, xgate_num_opcodes
, sizeof(struct xgate_opcode
),
313 (int (*)(const void *, const void *)) cmp_opcode
);
315 /* Calculate number of handles since this will be
316 smaller than the raw number of opcodes in the table. */
318 for (xgate_opcode_ptr
= xgate_op_table
, i
= 0; i
< xgate_num_opcodes
;
319 xgate_opcode_ptr
++, i
++)
321 if (strcmp (prev_op_name
, xgate_opcode_ptr
->name
))
322 number_of_op_handles
++;
323 prev_op_name
= xgate_opcode_ptr
->name
;
326 op_handles
= (struct xgate_opcode_handle
*)
327 xmalloc (sizeof(struct xgate_opcode_handle
) * (number_of_op_handles
));
329 /* Insert unique opcode names into hash table, aliasing duplicates. */
330 xgate_hash
= hash_new ();
333 for (xgate_opcode_ptr
= xgate_op_table
, i
= 0, j
= 0; i
< xgate_num_opcodes
;
334 i
++, xgate_opcode_ptr
++)
336 if (!strcmp (prev_op_name
, xgate_opcode_ptr
->name
))
339 op_handles
[j
].opc0
[handle_enum
] = xgate_opcode_ptr
;
346 op_handles
[j
].name
= xgate_opcode_ptr
->name
;
347 op_handles
[j
].opc0
[0] = xgate_opcode_ptr
;
348 hash_insert (xgate_hash
, (char *) op_handles
[j
].name
,
349 (char *) &(op_handles
[j
]));
351 op_handles
[j
].number_of_modes
= handle_enum
;
352 prev_op_name
= op_handles
[j
].name
;
355 if (flag_print_opcodes
)
357 xgate_print_table ();
363 xgate_init_after_args (void)
368 md_show_usage (FILE * stream
)
370 get_default_target ();
374 Freescale XGATE co-processor options:\n\
375 -mshort use 16-bit int ABI (default)\n\
376 -mlong use 32-bit int ABI\n\
377 -mshort-double use 32-bit double ABI\n\
378 -mlong-double use 64-bit double ABI (default)\n\
379 --mxgate specify the processor variant[default %s]\n\
380 --print-insn-syntax print the syntax of instruction in case of error\n\
381 --print-opcodes print the list of instructions with syntax\n\
382 --generate-example generate an example of each instruction"),
386 enum bfd_architecture
389 get_default_target ();
390 return bfd_arch_xgate
;
400 xgate_print_syntax (char *name
)
404 for (i
= 0; i
< xgate_num_opcodes
; i
++)
406 if (!strcmp (xgate_opcodes
[i
].name
, name
))
408 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_IDR
))
409 printf ("\tFormat is %s\tRx, Rx, Rx+|-Rx|Rx\n",
410 xgate_opcodes
[i
].name
);
411 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_INH
))
412 printf ("\tFormat is %s\n", xgate_opcodes
[i
].name
);
413 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_TRI
))
414 printf ("\tFormat is %s\tRx, Rx, Rx\n", xgate_opcodes
[i
].name
);
415 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_DYA
))
416 printf ("\tFormat is %s\tRx, Rx\n", xgate_opcodes
[i
].name
);
417 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_IMM3
))
418 printf ("\tFormat is %s\t<3-bit value>\n", xgate_opcodes
[i
].name
);
419 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_IMM4
))
420 printf ("\tFormat is %s\t<4 -bit value>\n", xgate_opcodes
[i
].name
);
421 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_IMM8
))
422 printf ("\tFormat is %s\tRx, <8-bit value>\n",
423 xgate_opcodes
[i
].name
);
424 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_IMM16
))
425 printf ("\tFormat is %s\tRx, <16-bit value>\n",
426 xgate_opcodes
[i
].name
);
427 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_MON_R_C
))
428 printf ("\tFormat is %s\tRx, CCR\n", xgate_opcodes
[i
].name
);
429 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_MON_C_R
))
430 printf ("\tFormat is %s\tCCR, Rx\n", xgate_opcodes
[i
].name
);
431 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_MON_R_P
))
432 printf ("\tFormat is %s\tRx, PC\n", xgate_opcodes
[i
].name
);
433 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_IMM16mLDW
))
434 printf ("\tFormat is %s\tRx, <16-bit value>\n",
435 xgate_opcodes
[i
].name
);
441 xgate_print_table (void)
445 for (i
= 0; i
< xgate_num_opcodes
; i
++)
446 xgate_print_syntax (xgate_opcodes
[i
].name
);
452 xgate_listing_header (void)
454 if (current_architecture
& cpuxgate
)
457 return "ERROR MC9S12X GAS ";
461 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
466 /* GAS will call this function for each section at the end of the assembly,
467 to permit the CPU backend to adjust the alignment of a section. */
470 md_section_align (asection
* seg
, valueT addr
)
472 int align
= bfd_get_section_alignment (stdoutput
, seg
);
473 return ((addr
+ (1 << align
) - 1) & (-1 << align
));
477 md_assemble (char *input_line
)
479 struct xgate_opcode
*opcode
= 0;
480 struct xgate_opcode
*macro_opcode
= 0;
481 struct xgate_opcode_handle
*opcode_handle
= 0;
482 /* Caller expects it to be returned as it was passed. */
483 char *saved_input_line
= input_line
;
484 char op_name
[9] = { 0 };
485 unsigned int operandCount
= 0;
488 s_operand new_operands
[MAX_NUM_OPERANDS
];
491 oper_check
= 0; /* set error flags */
492 input_line
= extract_word (input_line
, op_name
, sizeof(op_name
));
494 /* Check to make sure we are not reading a bogus line. */
496 as_bad (_("opcode missing or not found on input line"));
498 if (!(opcode_handle
= (struct xgate_opcode_handle
*) hash_find (xgate_hash
,
501 as_bad (_("opcode %s not found in opcode hash table"), op_name
);
505 /* Parse operands so we can find the proper opcode bin. */
507 operandCount
= xgate_get_operands (input_line
, new_operands
);
509 opcode
= xgate_find_match (opcode_handle
, opcode_handle
->number_of_modes
,
510 new_operands
, operandCount
);
514 as_bad (_("matching operands to opcode "));
515 xgate_print_syntax (opcode_handle
->opc0
[0]->name
);
517 else if (opcode
->size
== 2)
519 /* Size is one word - assemble that native insn. */
520 xgate_scan_operands (opcode
, new_operands
);
524 /* Insn is a simplified instruction - expand it out. */
528 /* skip past our ';' separator. */
529 for (i
= strlen (opcode
->constraints
), p
= opcode
->constraints
; i
> 0;
538 input_line
= skip_whitespace (input_line
);
539 char *macro_inline
= input_line
;
541 /* Loop though the macro's opcode list and apply operands to
543 for (i
= 0; *p
&& i
< (opcode
->size
/ 2); i
++)
545 /* Loop though macro operand list. */
546 input_line
= macro_inline
; /* Rewind. */
547 p
= extract_word (p
, op_name
, 10);
549 if (!(opcode_handle
= (struct xgate_opcode_handle
*)
550 hash_find (xgate_hash
, op_name
)))
552 as_bad (_(": processing macro, real opcode handle"
553 " not found in hash"));
558 operandCount
= xgate_get_operands(input_line
, new_operands
);
559 macro_opcode
= xgate_find_match (opcode_handle
,
560 opcode_handle
->number_of_modes
, new_operands
,
562 xgate_scan_operands (macro_opcode
, new_operands
);
568 input_line
= saved_input_line
;
571 /* Force truly undefined symbols to their maximum size, and generally set up
572 the frag list to be relaxed. */
575 md_estimate_size_before_relax (fragS
*fragp
, asection
*seg
)
577 /* If symbol is undefined or located in a different section,
578 select the largest supported relocation. */
579 relax_substateT subtype
;
580 relax_substateT rlx_state
[] = { 0, 2 };
582 for (subtype
= 0; subtype
< ARRAY_SIZE (rlx_state
); subtype
+= 2)
584 if (fragp
->fr_subtype
== rlx_state
[subtype
]
585 && (!S_IS_DEFINED (fragp
->fr_symbol
)
586 || seg
!= S_GET_SEGMENT (fragp
->fr_symbol
)))
588 fragp
->fr_subtype
= rlx_state
[subtype
+ 1];
593 if (fragp
->fr_subtype
>= ARRAY_SIZE (md_relax_table
))
596 return md_relax_table
[fragp
->fr_subtype
].rlx_length
;
600 /* Relocation, relaxation and frag conversions. */
602 /* PC-relative offsets are relative to the start of the
603 next instruction. That is, the address of the offset, plus its
604 size, since the offset is always the last part of the insn. */
607 md_pcrel_from (fixS
* fixP
)
609 return fixP
->fx_size
+ fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
612 /* If while processing a fixup, a reloc really needs to be created
613 then it is done here. */
616 tc_gen_reloc (asection
* section ATTRIBUTE_UNUSED
, fixS
* fixp
)
620 reloc
= (arelent
*) xmalloc (sizeof(arelent
));
621 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof(asymbol
*));
622 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
623 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
625 if (fixp
->fx_r_type
== 0)
626 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_16
);
628 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
630 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
632 as_bad_where (fixp
->fx_file
, fixp
->fx_line
, _
633 ("Relocation %d is not supported by object file format."),
634 (int) fixp
->fx_r_type
);
638 /* Since we use Rel instead of Rela, encode the vtable entry to be
639 used in the relocation's section offset. */
640 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
641 reloc
->address
= fixp
->fx_offset
;
646 /* Patch the instruction with the resolved operand. Elf relocation
647 info will also be generated to take care of linker/loader fixups.
648 The XGATE addresses only 16-bit addresses.The BFD_RELOC_32 is necessary
649 for the support of --gstabs. */
652 md_apply_fix (fixS
* fixP
, valueT
* valP
, segT seg ATTRIBUTE_UNUSED
)
659 /* If the fixup is done mark it done so no further symbol resolution
661 if (fixP
->fx_addsy
== (symbolS
*) NULL
)
664 /* We don't actually support subtracting a symbol. */
665 if (fixP
->fx_subsy
!= (symbolS
*) NULL
)
666 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("Expression too complex."));
668 where
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
669 opcode
= bfd_getl16 (where
);
672 switch (fixP
->fx_r_type
)
674 case R_XGATE_PCREL_9
:
675 if (value
< -512 || value
> 511)
676 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
677 _("Value %ld too large for 9-bit PC-relative branch."),
679 result
= ldiv (value
, 2); /* from bytes to words */
682 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _
683 ("Value %ld not aligned by 2 for 9-bit"
684 " PC-relative branch."), value
);
685 /* Clip into 8-bit field.
686 FIXME I'm sure there is a more proper place for this. */
689 number_to_chars_bigendian (where
, (opcode
| value
), 2);
691 case R_XGATE_PCREL_10
:
692 if (value
< -1024 || value
> 1023)
693 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
694 _("Value %ld too large for 10-bit PC-relative branch."),
696 result
= ldiv (value
, 2); /* from bytes to words */
699 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _
700 ("Value %ld not aligned by 2 for 10-bit"
701 " PC-relative branch."), value
);
702 /* Clip into 9-bit field.
703 FIXME I'm sure there is a more proper place for this. */
706 number_to_chars_bigendian (where
, (opcode
| value
), 2);
708 case BFD_RELOC_XGATE_IMM8_HI
:
709 if (value
< -65537 || value
> 65535)
710 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
711 _("Value out of 16-bit range."));
714 bfd_putb16 ((bfd_vma
) value
| opcode
, (void *) where
);
716 case BFD_RELOC_XGATE_24
:
717 case BFD_RELOC_XGATE_IMM8_LO
:
718 if (value
< -65537 || value
> 65535)
719 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
720 _("Value out of 16-bit range."));
722 bfd_putb16 ((bfd_vma
) value
| opcode
, (void *) where
);
724 case BFD_RELOC_XGATE_IMM3
:
725 if (value
< 0 || value
> 7)
726 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
727 _("Value out of 3-bit range."));
728 value
<<= 8; /* make big endian */
729 number_to_chars_bigendian (where
, (opcode
| value
), 2);
731 case BFD_RELOC_XGATE_IMM4
:
732 if (value
< 0 || value
> 15)
733 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
734 _("Value out of 4-bit range."));
735 value
<<= 4; /* align the operand bits */
736 number_to_chars_bigendian (where
, (opcode
| value
), 2);
738 case BFD_RELOC_XGATE_IMM5
:
739 if (value
< 0 || value
> 31)
740 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
741 _("Value out of 5-bit range."));
742 value
<<= 5; /* align the operand bits */
743 number_to_chars_bigendian (where
, (opcode
| value
), 2);
746 ((bfd_byte
*) where
)[0] = (bfd_byte
) value
;
749 bfd_putb32 ((bfd_vma
) value
, (unsigned char *) where
);
752 bfd_putb16 ((bfd_vma
) value
, (unsigned char *) where
);
755 as_fatal (_("Line %d: unknown relocation type: 0x%x."), fixP
->fx_line
,
761 /* See whether we need to force a relocation into the output file. */
764 tc_xgate_force_relocation (fixS
* fixP
)
766 if (fixP
->fx_r_type
== BFD_RELOC_XGATE_RL_GROUP
)
768 return generic_force_reloc (fixP
);
771 /* Here we decide which fixups can be adjusted to make them relative
772 to the beginning of the section instead of the symbol. Basically
773 we need to make sure that the linker relaxation is done
774 correctly, so in some cases we force the original symbol to be
778 tc_xgate_fix_adjustable (fixS
* fixP
)
780 switch (fixP
->fx_r_type
)
782 /* For the linker relaxation to work correctly, these relocs
783 need to be on the symbol itself. */
785 case BFD_RELOC_XGATE_RL_JUMP
:
786 case BFD_RELOC_XGATE_RL_GROUP
:
787 case BFD_RELOC_VTABLE_INHERIT
:
788 case BFD_RELOC_VTABLE_ENTRY
:
797 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
,
798 asection
* sec ATTRIBUTE_UNUSED
,
799 fragS
* fragP ATTRIBUTE_UNUSED
)
801 as_bad (("md_convert_frag not implemented yet"));
805 /* Set the ELF specific flags. */
808 xgate_elf_final_processing (void)
810 elf_flags
|= EF_XGATE_MACH
;
811 elf_elfheader (stdoutput
)->e_flags
&= ~EF_XGATE_ABI
;
812 elf_elfheader (stdoutput
)->e_flags
|= elf_flags
;
816 skip_whitespace (char *s
)
818 while (*s
== ' ' || *s
== '\t' || *s
== '(' || *s
== ')')
824 /* Extract a word (continuous alpha-numeric chars) from the input line. */
827 extract_word (char *from
, char *to
, int limit
)
832 /* Drop leading whitespace. */
833 from
= skip_whitespace (from
);
835 /* Find the op code end. */
836 for (op_end
= from
; *op_end
!= 0 && is_part_of_name (*op_end
);)
838 to
[size
++] = *op_end
++;
839 if (size
+ 1 >= limit
)
847 xgate_new_instruction (int size
)
849 char *f
= frag_more (size
);
850 dwarf2_emit_insn (size
);
854 static unsigned short
855 xgate_apply_operand (unsigned short new_mask
,
856 unsigned short *availiable_mask_bits
,
858 unsigned char n_bits
)
860 unsigned short n_shifts
;
861 unsigned int n_drop_bits
;
863 /* Shift until you find an available operand bit "1" and record
864 the number of shifts. */
866 !(*availiable_mask_bits
& SIXTEENTH_BIT
) && n_shifts
< 16;
868 *availiable_mask_bits
<<= 1;
870 /* Shift for the number of bits your operand requires while bits
872 for (n_drop_bits
= n_bits
;
873 n_drop_bits
&& (*availiable_mask_bits
& SIXTEENTH_BIT
);
875 *availiable_mask_bits
<<= 1;
878 as_bad (_(":operand has too many bits"));
879 *availiable_mask_bits
>>= n_shifts
+ n_bits
;
880 if ((n_drop_bits
== 0) && (*availiable_mask_bits
== 0))
882 oper_check
= 1; /* flag operand check as good */
884 new_mask
<<= N_BITS_IN_WORD
- (n_shifts
+ n_bits
);
889 /* Parse ordinary expression. */
892 xgate_parse_exp (char *s
, expressionS
* op
)
894 input_line_pointer
= s
;
896 if (op
->X_op
== O_absent
)
897 as_bad (_("missing operand"));
898 return input_line_pointer
;
902 cmp_opcode (struct xgate_opcode
*op1
, struct xgate_opcode
*op2
)
904 return strcmp (op1
->name
, op2
->name
);
907 static struct xgate_opcode
*
908 xgate_find_match (struct xgate_opcode_handle
*opcode_handle
,
909 int numberOfModes
, s_operand oprs
[], unsigned int operandCount
)
913 if (numberOfModes
== 0)
914 return opcode_handle
->opc0
[0];
916 for (i
= 0; i
<= numberOfModes
; i
++)
918 switch (operandCount
)
921 if (!strcmp(opcode_handle
->opc0
[i
]->constraints
, XGATE_OP_INH
))
922 return opcode_handle
->opc0
[i
];
925 if (oprs
[0].reg
>= REG_R0
&& oprs
[0].reg
<= REG_R7
)
926 if (!strcmp(opcode_handle
->opc0
[i
]->constraints
, XGATE_OP_MON
))
927 return opcode_handle
->opc0
[i
];
928 if (!strcmp(opcode_handle
->opc0
[i
]->constraints
, XGATE_OP_DYA_MON
))
929 return opcode_handle
->opc0
[i
];
930 if (oprs
[0].reg
== REG_NONE
)
931 if (!strcmp(opcode_handle
->opc0
[i
]->constraints
, XGATE_OP_IMM3
))
932 return opcode_handle
->opc0
[i
];
935 if (oprs
[0].reg
>= REG_R0
&& oprs
[0].reg
<= REG_R7
)
937 if (oprs
[1].reg
>= REG_R0
&& oprs
[1].reg
<= REG_R7
)
938 if (!strcmp(opcode_handle
->opc0
[i
]->constraints
, XGATE_OP_DYA
))
939 return opcode_handle
->opc0
[i
];
940 if (oprs
[1].reg
== REG_CCR
)
941 if (!strcmp(opcode_handle
->opc0
[i
]->constraints
,
943 return opcode_handle
->opc0
[i
];
944 if (oprs
[1].reg
== REG_PC
)
945 if (!strcmp(opcode_handle
->opc0
[i
]->constraints
,
947 return opcode_handle
->opc0
[i
];
948 if (oprs
[1].reg
== REG_NONE
)
949 if (!strcmp(opcode_handle
->opc0
[i
]->constraints
, XGATE_OP_IMM16
)
950 || !strcmp(opcode_handle
->opc0
[i
]->constraints
, XGATE_OP_IMM8
)
951 || !strcmp(opcode_handle
->opc0
[i
]->constraints
, XGATE_OP_IMM4
)
952 || !strcmp(opcode_handle
->opc0
[i
]->constraints
,
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 return opcode_handle
->opc0
[i
];
964 if (oprs
[0].reg
== REG_CCR
)
965 if (!strcmp(opcode_handle
->opc0
[i
]->constraints
, XGATE_OP_MON_C_R
))
966 return opcode_handle
->opc0
[i
];
969 if (oprs
[0].reg
>= REG_R0
&& oprs
[0].reg
<= REG_R7
)
971 if (oprs
[1].reg
>= REG_R0
&& oprs
[1].reg
<= REG_R7
)
973 if (oprs
[2].reg
>= REG_R0
&& oprs
[2].reg
<= REG_R7
)
975 if (!strcmp(opcode_handle
->opc0
[i
]->constraints
,
977 || !strcmp(opcode_handle
->opc0
[i
]->constraints
,
979 return opcode_handle
->opc0
[i
];
982 if (oprs
[2].reg
== REG_NONE
)
983 if (!strcmp(opcode_handle
->opc0
[i
]->constraints
,
985 return opcode_handle
->opc0
[i
];
990 as_bad(_("unknown operand count"));
997 /* Because we are dealing with two different core that view the system
998 memory with different offsets, we must differentiate what core a
999 symbol belongs to, in order for the linker to cross-link. */
1002 xgate_frob_symbol (symbolS
*sym
)
1005 elf_symbol_type
*elfsym
;
1007 bfdsym
= symbol_get_bfdsym (sym
);
1008 elfsym
= elf_symbol_from (bfd_asymbol_bfd (bfdsym
), bfdsym
);
1012 /* Mark the symbol as being *from XGATE */
1013 elfsym
->internal_elf_sym
.st_target_internal
= 1;
1019 xgate_get_operands (char *line
, s_operand oprs
[])
1023 /* If there are no operands, then it must be inherent. */
1024 if (*line
== 0 || *line
== '\n' || *line
== '\r')
1027 for (num_operands
= 0; strlen (line
) && (num_operands
< MAX_NUM_OPERANDS
);
1030 line
= skip_whitespace (line
);
1034 oprs
[num_operands
].mod
= xgate_determine_modifiers (&line
);
1036 if ((oprs
[num_operands
].reg
= reg_name_search (line
)) == REG_NONE
)
1037 line
= xgate_parse_exp (line
, &oprs
[num_operands
].exp
);
1039 /* skip to next operand */
1050 if (num_operands
> MAX_NUM_OPERANDS
)
1052 return num_operands
;
1055 /* reg_name_search() finds the register number given its name.
1056 Returns the register number or REG_NONE on failure. */
1058 reg_name_search (char *name
)
1060 if (strncasecmp (name
, "r0", 2) == 0)
1062 if (strncasecmp (name
, "r1", 2) == 0)
1064 if (strncasecmp (name
, "r2", 2) == 0)
1066 if (strncasecmp (name
, "r3", 2) == 0)
1068 if (strncasecmp (name
, "r4", 2) == 0)
1070 if (strncasecmp (name
, "r5", 2) == 0)
1072 if (strncasecmp (name
, "r6", 2) == 0)
1074 if (strncasecmp (name
, "r7", 2) == 0)
1076 if (strncasecmp (name
, "pc", 2) == 0)
1078 if (strncasecmp (name
, "ccr", 3) == 0)
1083 /* Parse operand modifiers such as inc/dec/hi/low. */
1086 xgate_determine_modifiers(char **line
)
1088 char *local_line
= line
[0];
1090 if (strncasecmp (local_line
, "%hi", 3) == 0)
1093 return MOD_LOAD_HIGH
;
1095 if (strncasecmp (local_line
, "%lo", 3) == 0)
1098 return MOD_LOAD_LOW
;
1100 if (*(local_line
+ 2) == '+')
1102 if (strncasecmp (local_line
, "-r", 2) == 0)
1110 /* Parse instruction operands. */
1113 xgate_scan_operands (struct xgate_opcode
*opcode
, s_operand oprs
[])
1115 char *frag
= xgate_new_instruction (opcode
->size
);
1116 int where
= frag
- frag_now
->fr_literal
;
1117 char *op
= opcode
->constraints
;
1118 unsigned int bin
= (int) opcode
->bin_opcode
;
1119 unsigned short oper_mask
= 0;
1120 int operand_bit_length
= 0;
1121 unsigned int operand
= 0;
1122 char n_operand_bits
= 0;
1123 char first_operand_equals_second
= 0;
1127 /* Generate available operand bits mask. */
1128 for (i
= 0; (c
= opcode
->format
[i
]); i
++)
1130 if (ISDIGIT (c
) || (c
== 's'))
1142 /* Parse first operand. */
1147 first_operand_equals_second
= 1;
1150 operand
= xgate_parse_operand (opcode
, &operand_bit_length
, where
,
1153 bin
= xgate_apply_operand (operand
, &oper_mask
, bin
, operand_bit_length
);
1155 if(first_operand_equals_second
)
1156 bin
= xgate_apply_operand (operand
, &oper_mask
, bin
,
1157 operand_bit_length
);
1158 /* Parse second operand. */
1163 if (first_operand_equals_second
)
1165 bin
= xgate_apply_operand (operand
, &oper_mask
, bin
,
1166 operand_bit_length
);
1171 operand
= xgate_parse_operand (opcode
, &operand_bit_length
, where
,
1173 bin
= xgate_apply_operand (operand
, &oper_mask
, bin
,
1174 operand_bit_length
);
1178 /* Parse the third register. */
1183 operand
= xgate_parse_operand (opcode
, &operand_bit_length
, where
,
1185 bin
= xgate_apply_operand (operand
, &oper_mask
, bin
,
1186 operand_bit_length
);
1189 if (opcode
->size
== 2 && fixup_required
)
1191 bfd_putl16 (bin
, frag
);
1193 else if ( !strcmp (opcode
->constraints
, XGATE_OP_REL9
)
1194 || !strcmp (opcode
->constraints
, XGATE_OP_REL10
))
1196 /* Write our data to a frag for further processing. */
1197 bfd_putl16 (opcode
->bin_opcode
, frag
);
1201 /* Apply operand mask(s)to bin opcode and write the output. */
1202 /* Since we are done write this frag in xgate BE format. */
1203 number_to_chars_bigendian (frag
, bin
, opcode
->size
);
1210 xgate_parse_operand (struct xgate_opcode
*opcode
,
1216 char *op_constraint
= *op_con
;
1217 unsigned int op_mask
= 0;
1218 unsigned int pp_fix
= 0;
1219 unsigned short max_size
= 0;
1225 switch (*op_constraint
)
1227 case '+': /* Indexed register operand +/- or plain r. */
1228 /* Default to neither inc or dec. */
1232 if (operand
.reg
== REG_NONE
)
1233 as_bad (_(": expected register name r0-r7 ") );
1234 op_mask
= operand
.reg
;
1235 if(operand
.mod
== MOD_POSTINC
)
1237 if(operand
.mod
== MOD_PREDEC
)
1243 case 'r': /* Register operand. */
1244 if (operand
.reg
== REG_NONE
)
1245 as_bad (_(": expected register name r0-r7 "));
1249 op_mask
= operand
.reg
;
1252 case 'i': /* Immediate value or expression expected. */
1253 /* Advance the original format pointer. */
1256 if (ISDIGIT (*op_constraint
))
1257 *bit_width
= (int) *op_constraint
- '0';
1258 else if (*op_constraint
== 'a')
1260 else if (*op_constraint
== 'f')
1263 /* http://tigcc.ticalc.org/doc/gnuasm.html#SEC31 */
1264 if (operand
.exp
.X_op
== O_constant
)
1266 op_mask
= operand
.exp
.X_add_number
;
1267 if (((opcode
->name
[strlen (opcode
->name
) - 1] == 'l') && autoHiLo
)
1268 || operand
.mod
== MOD_LOAD_LOW
)
1270 else if (((opcode
->name
[strlen (opcode
->name
) - 1]) == 'h'
1271 && autoHiLo
) || operand
.mod
== MOD_LOAD_HIGH
)
1274 /* Make sure it fits. */
1275 for (i
= *bit_width
; i
; i
--)
1280 if (op_mask
> max_size
)
1281 as_bad (_(":operand value(%d) too big for constraint"), op_mask
);
1285 /* Should be BFD_RELOC_XGATE_IMM8_LO instead of BFD_RELOC_XGATE_24
1288 if (*op_constraint
== '8')
1290 if (((opcode
->name
[strlen (opcode
->name
) - 1] == 'l')
1291 && autoHiLo
) || operand
.mod
== MOD_LOAD_LOW
)
1292 fix_new_exp (frag_now
, where
, 2, &operand
.exp
, FALSE
,
1293 BFD_RELOC_XGATE_24
);
1294 else if (((opcode
->name
[strlen (opcode
->name
) - 1]) == 'h'
1295 && autoHiLo
) || operand
.mod
== MOD_LOAD_HIGH
)
1296 fix_new_exp (frag_now
, where
, 2, &operand
.exp
, FALSE
,
1297 BFD_RELOC_XGATE_IMM8_HI
);
1299 as_bad (_("you must use a hi/lo directive or 16-bit macro "
1300 "to load a 16-bit value."));
1302 else if (*op_constraint
== '5')
1303 fix_new_exp (frag_now
, where
, 2, &operand
.exp
, FALSE
,
1304 BFD_RELOC_XGATE_IMM5
);
1305 else if (*op_constraint
== '4')
1306 fix_new_exp (frag_now
, where
, 2, &operand
.exp
, FALSE
,
1307 BFD_RELOC_XGATE_IMM4
);
1308 else if (*op_constraint
== '3')
1309 fix_new_exp (frag_now
, where
, 2, &operand
.exp
, FALSE
,
1310 BFD_RELOC_XGATE_IMM3
);
1312 as_bad (_(":unknown relocation constraint size"));
1316 case 'c': /* CCR register expected. */
1318 if (operand
.reg
!= REG_CCR
)
1319 as_bad (_(": expected register name ccr "));
1322 case 'p': /* PC register expected. */
1324 if (operand
.reg
!= REG_PC
)
1325 as_bad (_(": expected register name pc "));
1328 case 'b': /* Branch expected. */
1332 if (operand
.exp
.X_op
!= O_register
)
1334 if (*op_constraint
== '9')
1335 fix_new_exp (frag_now
, where
, 2, &operand
.exp
, TRUE
,
1337 else if (*op_constraint
== 'a')
1338 fix_new_exp (frag_now
, where
, 2, &operand
.exp
, TRUE
,
1342 as_fatal (_("Operand `%x' not recognized in fixup8."),
1349 as_bad (_("unknown constraint `%c'"), *op_constraint
);