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. They are numbered according to the specifications. */
64 typedef enum register_id
79 /* Operand Modifiers */
80 typedef enum op_modifiers
90 typedef struct s_operand
100 xgate_parse_exp (char *, expressionS
*);
102 skip_whitespace (char *);
104 get_default_target (void);
106 extract_word (char *, char *, int);
108 xgate_new_instruction (int size
);
110 xgate_apply_operand (unsigned short, unsigned short *, unsigned short,
112 static struct xgate_opcode
*
113 xgate_find_match (struct xgate_opcode_handle
*, int, unsigned int);
115 cmp_opcode (struct xgate_opcode
*, struct xgate_opcode
*);
117 xgate_print_syntax (char *);
119 xgate_print_table (void);
121 xgate_get_operands (char *, s_operand
[]);
123 reg_name_search (char *);
125 xgate_determine_hi_low(char **);
127 xgate_determine_increment(char **);
130 xgate_scan_operands (struct xgate_opcode
*opcode
, s_operand
[]);
133 xgate_parse_operand (struct xgate_opcode
*, int *, int where
, char **,
137 static struct hash_control
*xgate_hash
;
139 /* Previous opcode. */
140 static unsigned int prev
= 0;
142 static unsigned char fixup_required
= 0;
144 /* Used to enable clipping of 16 bit operands into 8 bit constraints. */
145 static unsigned char macroClipping
= 0;
147 static char oper_check
;
148 static char flag_print_insn_syntax
= 0;
149 static char flag_print_opcodes
= 0;
151 static int current_architecture
;
152 static const char *default_cpu
;
154 /* ELF flags to set in the output file header. */
155 static int elf_flags
= E_XGATE_F64
;
157 /* This table describes how you change sizes for the various types of variable
158 size expressions. This version only supports two kinds. */
161 How far Forward this mode will reach.
162 How far Backward this mode will reach.
163 How many bytes this mode will add to the size of the frag.
164 Which mode to go to if the offset won't fit in this one. */
166 relax_typeS md_relax_table
[] =
168 {1, 1, 0, 0}, /* First entries aren't used. */
169 {1, 1, 0, 0}, /* For no good reason except. */
170 {1, 1, 0, 0}, /* that the VAX doesn't either. */
172 /* XGATE 9 and 10 bit pc rel todo complete and test */
173 /*{(511), (-512), 0, ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD)},
174 {(1023), (-1024), 0, ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD)}, */
178 /* This table describes all the machine specific pseudo-ops the assembler
179 has to support. The fields are: pseudo-op name without dot function to
180 call to execute this pseudo-op Integer arg to pass to the function. */
181 const pseudo_typeS md_pseudo_table
[] =
183 /* The following pseudo-ops are supported for MRI compatibility. */
187 const char *md_shortopts
= "m:";
189 struct option md_longopts
[] =
191 #define OPTION_PRINT_INSN_SYNTAX (OPTION_MD_BASE + 0)
192 { "print-insn-syntax", no_argument
, NULL
, OPTION_PRINT_INSN_SYNTAX
},
194 #define OPTION_PRINT_OPCODES (OPTION_MD_BASE + 1)
195 { "print-opcodes", no_argument
, NULL
, OPTION_PRINT_OPCODES
},
197 #define OPTION_GENERATE_EXAMPLE (OPTION_MD_BASE + 2)
198 { "generate-example", no_argument
, NULL
, OPTION_GENERATE_EXAMPLE
},
200 #define OPTION_MSHORT (OPTION_MD_BASE + 3)
201 { "mshort", no_argument
, NULL
, OPTION_MSHORT
},
203 #define OPTION_MLONG (OPTION_MD_BASE + 4)
204 { "mlong", no_argument
, NULL
, OPTION_MLONG
},
206 #define OPTION_MSHORT_DOUBLE (OPTION_MD_BASE + 5)
207 { "mshort-double", no_argument
, NULL
, OPTION_MSHORT_DOUBLE
},
209 #define OPTION_MLONG_DOUBLE (OPTION_MD_BASE + 6)
210 { "mlong-double", no_argument
, NULL
, OPTION_MLONG_DOUBLE
},
212 { NULL
, no_argument
, NULL
, 0 }
215 size_t md_longopts_size
= sizeof(md_longopts
);
218 md_atof (int type
, char *litP
, int *sizeP
)
220 return ieee_md_atof (type
, litP
, sizeP
, TRUE
);
224 md_parse_option (int c
, char *arg
)
229 if (strcasecmp (arg
, "v1") == 0)
230 current_architecture
= XGATE_V1
;
231 else if (strcasecmp (arg
, "v2") == 0)
232 current_architecture
= XGATE_V2
;
233 else if (strcasecmp (arg
, "v3") == 0)
234 current_architecture
= XGATE_V3
;
236 as_bad (_(" architecture variant invalid"));
239 case OPTION_PRINT_INSN_SYNTAX
:
240 flag_print_insn_syntax
= 1;
243 case OPTION_PRINT_OPCODES
:
244 flag_print_opcodes
= 1;
247 case OPTION_GENERATE_EXAMPLE
:
248 flag_print_opcodes
= 2;
252 elf_flags
&= ~E_XGATE_I32
;
256 elf_flags
|= E_XGATE_I32
;
259 case OPTION_MSHORT_DOUBLE
:
260 elf_flags
&= ~E_XGATE_F64
;
263 case OPTION_MLONG_DOUBLE
:
264 elf_flags
|= E_XGATE_F64
;
274 xgate_arch_format (void)
276 get_default_target ();
278 if (current_architecture
& cpuxgate
)
279 return "elf32-xgate";
285 get_default_target (void)
287 const bfd_target
*target
;
290 if (current_architecture
!= 0)
293 default_cpu
= "unknown";
294 target
= bfd_find_target (0, &abfd
);
296 if (target
&& target
->name
)
298 if (strcmp (target
->name
, "elf32-xgate") == 0)
300 current_architecture
= cpuxgate
;
301 default_cpu
= "XGATE V1";
305 as_bad (_("Default target `%s' is not supported."), target
->name
);
312 struct xgate_opcode
*xgate_opcode_ptr
= NULL
;
313 struct xgate_opcode
*xgate_op_table
= NULL
;
314 struct xgate_opcode_handle
*op_handles
= 0;
315 char *prev_op_name
= 0;
317 int number_of_op_handles
= 0;
320 /* Create a local copy of our opcode table
321 including an extra line for NULL termination. */
322 xgate_op_table
= (struct xgate_opcode
*)
323 xmalloc ((xgate_num_opcodes
) * sizeof (struct xgate_opcode
));
325 memset (xgate_op_table
, 0,
326 sizeof(struct xgate_opcode
) * (xgate_num_opcodes
));
328 for (xgate_opcode_ptr
= (struct xgate_opcode
*) xgate_opcodes
, i
= 0;
329 i
< xgate_num_opcodes
; i
++)
330 xgate_op_table
[i
] = xgate_opcode_ptr
[i
];
332 qsort (xgate_op_table
, xgate_num_opcodes
, sizeof(struct xgate_opcode
),
333 (int (*)(const void *, const void *)) cmp_opcode
);
335 /* Calculate number of handles since this will be
336 smaller than the raw number of opcodes in the table. */
338 for (xgate_opcode_ptr
= xgate_op_table
, i
= 0; i
< xgate_num_opcodes
;
339 xgate_opcode_ptr
++, i
++)
341 if (strcmp (prev_op_name
, xgate_opcode_ptr
->name
))
342 number_of_op_handles
++;
343 prev_op_name
= xgate_opcode_ptr
->name
;
346 op_handles
= (struct xgate_opcode_handle
*)
347 xmalloc (sizeof(struct xgate_opcode_handle
) * (number_of_op_handles
));
349 /* Insert unique opcode names into hash table, aliasing duplicates. */
350 xgate_hash
= hash_new ();
353 for (xgate_opcode_ptr
= xgate_op_table
, i
= 0, j
= 0; i
< xgate_num_opcodes
;
354 i
++, xgate_opcode_ptr
++)
356 if (!strcmp (prev_op_name
, xgate_opcode_ptr
->name
))
359 op_handles
[j
].opc0
[handle_enum
] = xgate_opcode_ptr
;
366 op_handles
[j
].name
= xgate_opcode_ptr
->name
;
367 op_handles
[j
].opc0
[0] = xgate_opcode_ptr
;
368 hash_insert (xgate_hash
, (char *) op_handles
[j
].name
,
369 (char *) &(op_handles
[j
]));
371 op_handles
[j
].number_of_modes
= handle_enum
;
372 prev_op_name
= op_handles
[j
].name
;
375 if (flag_print_opcodes
== 1)
376 xgate_print_table ();
380 xgate_init_after_args (void)
385 md_show_usage (FILE * stream
)
387 get_default_target ();
392 Freescale XGATE co-processor options:\n \
393 -mshort use 16-bit int ABI (default)\n \
394 -mlong use 32-bit int ABI\n \
395 -mshort-double use 32-bit double ABI\n \
396 -mlong-double use 64-bit double ABI (default)\n\
397 --mxgate specify the processor variant[default %s]\n\
398 --print-insn-syntax print the syntax of instruction in case of error\n\
399 --print-opcodes print the list of instructions with syntax\n\
400 --generate-example generate an example of each instruction"),
404 enum bfd_architecture
407 get_default_target ();
408 return bfd_arch_xgate
;
418 xgate_print_syntax (char *name
)
422 for (i
= 0; i
< xgate_num_opcodes
; i
++)
424 if (!strcmp (xgate_opcodes
[i
].name
, name
))
426 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_IDR
))
427 printf ("\tFormat is %s\tRx, Rx, Rx+|-Rx|Rx\n",
428 xgate_opcodes
[i
].name
);
429 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_INH
))
430 printf ("\tFormat is %s\n", xgate_opcodes
[i
].name
);
431 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_TRI
))
432 printf ("\tFormat is %s\tRx, Rx, Rx\n", xgate_opcodes
[i
].name
);
433 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_DYA
))
434 printf ("\tFormat is %s\tRx, Rx\n", xgate_opcodes
[i
].name
);
435 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_IMM3
))
436 printf ("\tFormat is %s\t<3-bit value>\n", xgate_opcodes
[i
].name
);
437 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_IMM4
))
438 printf ("\tFormat is %s\t<4 -bit value>\n", xgate_opcodes
[i
].name
);
439 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_IMM8
))
440 printf ("\tFormat is %s\tRx, <8-bit value>\n",
441 xgate_opcodes
[i
].name
);
442 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_IMM16
))
443 printf ("\tFormat is %s\tRx, <16-bit value>\n",
444 xgate_opcodes
[i
].name
);
445 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_MON_R_C
))
446 printf ("\tFormat is %s\tRx, CCR\n", xgate_opcodes
[i
].name
);
447 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_MON_C_R
))
448 printf ("\tFormat is %s\tCCR, Rx\n", xgate_opcodes
[i
].name
);
449 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_MON_R_P
))
450 printf ("\tFormat is %s\tRx, PC\n", xgate_opcodes
[i
].name
);
451 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_IMM16mLDW
))
452 printf ("\tFormat is %s\tRx, <16-bit value>\n",
453 xgate_opcodes
[i
].name
);
459 xgate_print_table (void)
463 for (i
= 0; i
< xgate_num_opcodes
; i
++)
464 xgate_print_syntax (xgate_opcodes
[i
].name
);
470 xgate_listing_header (void)
472 if (current_architecture
& cpuxgate
)
475 return "ERROR MC9S12X GAS ";
479 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
484 /* GAS will call this function for each section at the end of the assembly,
485 to permit the CPU backend to adjust the alignment of a section. */
488 md_section_align (asection
* seg
, valueT addr
)
490 int align
= bfd_get_section_alignment (stdoutput
, seg
);
491 return ((addr
+ (1 << align
) - 1) & (-1 << align
));
495 md_assemble (char *input_line
)
497 struct xgate_opcode
*opcode
= 0;
498 struct xgate_opcode
*macro_opcode
= 0;
499 struct xgate_opcode_handle
*opcode_handle
= 0;
500 /* Caller expects it to be returned as it was passed. */
501 char *saved_input_line
= input_line
;
502 char op_name
[9] = { 0 };
503 unsigned int sh_format
= 0;
506 s_operand new_operands
[MAX_NUM_OPERANDS
];
509 oper_check
= 0; /* set error flags */
510 input_line
= extract_word (input_line
, op_name
, sizeof(op_name
));
512 /* Check to make sure we are not reading a bogus line. */
514 as_bad (_("opcode missing or not found on input line"));
516 if (!(opcode_handle
= (struct xgate_opcode_handle
*) hash_find (xgate_hash
,
519 as_bad (_("opcode %s not found in opcode hash table"), op_name
);
523 /* Parse operands so we can find the proper opcode bin. */
525 sh_format
= xgate_get_operands(input_line
, new_operands
);
527 opcode
= xgate_find_match (opcode_handle
, opcode_handle
->number_of_modes
,
532 as_bad (_("matching operands to opcode "));
533 xgate_print_syntax (opcode_handle
->opc0
[0]->name
);
535 else if (opcode
->size
== 2)
537 /* Size is one word - assemble that native insn. */
538 xgate_scan_operands (opcode
, new_operands
);
542 /* Insn is a simplified instruction - expand it out. */
546 /* skip past our ';' separator. */
547 for (i
= strlen (opcode
->constraints
), p
= opcode
->constraints
; i
> 0;
556 input_line
= skip_whitespace (input_line
);
557 char *macro_inline
= input_line
;
559 /* Loop though the macro's opcode list and apply operands to each real opcode. */
560 for (i
= 0; *p
&& i
< (opcode
->size
/ 2); i
++)
562 /* Loop though macro operand list. */
563 input_line
= macro_inline
; /* Rewind. */
564 p
= extract_word (p
, op_name
, 10);
566 if (!(opcode_handle
= (struct xgate_opcode_handle
*)
567 hash_find (xgate_hash
, op_name
)))
570 _(": processing macro, real opcode handle not found in hash"));
575 sh_format
= xgate_get_operands(input_line
, new_operands
);
576 macro_opcode
= xgate_find_match (opcode_handle
,
577 opcode_handle
->number_of_modes
, sh_format
);
578 xgate_scan_operands (macro_opcode
, new_operands
);
585 input_line
= saved_input_line
;
588 /* Force truly undefined symbols to their maximum size, and generally set up
589 the frag list to be relaxed. */
592 md_estimate_size_before_relax (fragS
*fragp
, asection
*seg
)
594 /* If symbol is undefined or located in a different section,
595 select the largest supported relocation. */
596 relax_substateT subtype
;
597 relax_substateT rlx_state
[] =
600 for (subtype
= 0; subtype
< ARRAY_SIZE (rlx_state
); subtype
+= 2)
602 if (fragp
->fr_subtype
== rlx_state
[subtype
]
603 && (!S_IS_DEFINED (fragp
->fr_symbol
)
604 || seg
!= S_GET_SEGMENT (fragp
->fr_symbol
)))
606 fragp
->fr_subtype
= rlx_state
[subtype
+ 1];
611 if (fragp
->fr_subtype
>= ARRAY_SIZE (md_relax_table
))
614 return md_relax_table
[fragp
->fr_subtype
].rlx_length
;
618 /* Relocation, relaxation and frag conversions. */
620 /* PC-relative offsets are relative to the start of the
621 next instruction. That is, the address of the offset, plus its
622 size, since the offset is always the last part of the insn. */
625 md_pcrel_from (fixS
* fixP
)
627 return fixP
->fx_size
+ fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
630 /* If while processing a fixup, a reloc really needs to be created
631 then it is done here. */
634 tc_gen_reloc (asection
* section ATTRIBUTE_UNUSED
, fixS
* fixp
)
638 reloc
= (arelent
*) xmalloc (sizeof(arelent
));
639 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof(asymbol
*));
640 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
641 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
643 if (fixp
->fx_r_type
== 0)
645 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_16
);
649 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
652 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
654 as_bad_where (fixp
->fx_file
, fixp
->fx_line
, _
655 ("Relocation %d is not supported by object file format."),
656 (int) fixp
->fx_r_type
);
660 /* Since we use Rel instead of Rela, encode the vtable entry to be
661 used in the relocation's section offset. */
662 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
663 reloc
->address
= fixp
->fx_offset
;
668 /* Patch the instruction with the resolved operand. Elf relocation
669 info will also be generated to take care of linker/loader fixups.
670 The XGATE addresses only 16-bit addresses.The BFD_RELOC_32 is necessary
671 for the support of --gstabs. */
674 md_apply_fix (fixS
* fixP
, valueT
* valP
, segT seg ATTRIBUTE_UNUSED
)
681 /* If the fixup is done mark it done so no further symbol resolution will take place. */
682 if (fixP
->fx_addsy
== (symbolS
*) NULL
)
687 /* We don't actually support subtracting a symbol. */
688 if (fixP
->fx_subsy
!= (symbolS
*) NULL
)
689 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("Expression too complex."));
691 where
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
692 opcode
= bfd_getl16 (where
);
695 switch (fixP
->fx_r_type
)
697 case R_XGATE_PCREL_9
:
698 if (value
< -512 || value
> 511)
699 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
700 _("Value %ld too large for 9-bit PC-relative branch."), value
);
701 result
= ldiv (value
, 2); /* from bytes to words */
704 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _
705 ("Value %ld not aligned by 2 for 9-bit PC-relative branch."), value
);
706 mask
= 0x1FF; /* Clip into 8-bit field FIXME I'm sure there is a more proper place for this */
708 number_to_chars_bigendian (where
, (opcode
| value
), 2);
710 case R_XGATE_PCREL_10
:
711 if (value
< -1024 || value
> 1023)
712 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
713 _("Value %ld too large for 10-bit PC-relative branch."), value
);
714 result
= ldiv (value
, 2); /* from bytes to words */
717 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _
718 ("Value %ld not aligned by 2 for 10-bit PC-relative branch."), value
);
719 mask
= 0x3FF; /* Clip into 9-bit field FIXME I'm sure there is a more proper place for this */
721 number_to_chars_bigendian (where
, (opcode
| value
), 2);
723 case BFD_RELOC_XGATE_IMM8_HI
:
724 if (value
< -65537 || value
> 65535)
725 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
726 _("Value out of 16-bit range."));
729 bfd_putb16 ((bfd_vma
) value
| opcode
, (void *) where
);
731 case BFD_RELOC_XGATE_24
:
732 case BFD_RELOC_XGATE_IMM8_LO
:
733 if (value
< -65537 || value
> 65535)
734 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
735 _("Value out of 16-bit range."));
737 bfd_putb16 ((bfd_vma
) value
| opcode
, (void *) where
);
739 case BFD_RELOC_XGATE_IMM3
:
740 if (value
< 0 || value
> 7)
741 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
742 _("Value out of 3-bit range."));
743 value
<<= 8; /* make big endian */
744 number_to_chars_bigendian (where
, (opcode
| value
), 2);
746 case BFD_RELOC_XGATE_IMM4
:
747 if (value
< 0 || value
> 15)
748 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
749 _("Value out of 4-bit range."));
750 value
<<= 4; /* align the operand bits */
751 number_to_chars_bigendian (where
, (opcode
| value
), 2);
753 case BFD_RELOC_XGATE_IMM5
:
754 if (value
< 0 || value
> 31)
755 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
756 _("Value out of 5-bit range."));
757 value
<<= 5; /* align the operand bits */
758 number_to_chars_bigendian (where
, (opcode
| value
), 2);
761 ((bfd_byte
*) where
)[0] = (bfd_byte
) value
;
764 bfd_putb32 ((bfd_vma
) value
, (unsigned char *) where
);
767 bfd_putb16 ((bfd_vma
) value
, (unsigned char *) where
);
770 as_fatal (_("Line %d: unknown relocation type: 0x%x."), fixP
->fx_line
,
776 /* See whether we need to force a relocation into the output file. */
779 tc_xgate_force_relocation (fixS
* fixP
)
781 if (fixP
->fx_r_type
== BFD_RELOC_XGATE_RL_GROUP
)
783 return generic_force_reloc (fixP
);
786 /* Here we decide which fixups can be adjusted to make them relative
787 to the beginning of the section instead of the symbol. Basically
788 we need to make sure that the linker relaxation is done
789 correctly, so in some cases we force the original symbol to be
793 tc_xgate_fix_adjustable (fixS
* fixP
)
795 switch (fixP
->fx_r_type
)
797 /* For the linker relaxation to work correctly, these relocs
798 need to be on the symbol itself. */
800 case BFD_RELOC_XGATE_RL_JUMP
:
801 case BFD_RELOC_XGATE_RL_GROUP
:
802 case BFD_RELOC_VTABLE_INHERIT
:
803 case BFD_RELOC_VTABLE_ENTRY
:
812 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
,
813 asection
* sec ATTRIBUTE_UNUSED
,
814 fragS
* fragP ATTRIBUTE_UNUSED
)
816 as_bad (("md_convert_frag not implemented yet"));
820 /* Set the ELF specific flags. */
823 xgate_elf_final_processing (void)
825 elf_flags
|= EF_XGATE_MACH
;
826 elf_elfheader (stdoutput
)->e_flags
&= ~EF_XGATE_ABI
;
827 elf_elfheader (stdoutput
)->e_flags
|= elf_flags
;
831 skip_whitespace (char *s
)
833 while (*s
== ' ' || *s
== '\t' || *s
== '(' || *s
== ')')
839 /* Extract a word (continuous alpha-numeric chars) from the input line. */
842 extract_word (char *from
, char *to
, int limit
)
847 /* Drop leading whitespace. */
848 from
= skip_whitespace (from
);
850 /* Find the op code end. */
851 for (op_end
= from
; *op_end
!= 0 && is_part_of_name (*op_end
);)
853 to
[size
++] = *op_end
++;
854 if (size
+ 1 >= limit
)
862 xgate_new_instruction (int size
)
864 char *f
= frag_more (size
);
865 dwarf2_emit_insn (size
);
870 xgate_apply_operand (unsigned short new_mask
,
871 unsigned short *availiable_mask_bits
,
873 unsigned char n_bits
)
875 unsigned short n_shifts
;
876 unsigned int n_drop_bits
;
878 /* Shift until you find an available operand bit "1" and record the number of shifts. */
880 !(*availiable_mask_bits
& SIXTEENTH_BIT
) && n_shifts
< 16;
882 *availiable_mask_bits
<<= 1;
884 /* Shift for the number of bits your operand requires while bits are available. */
885 for (n_drop_bits
= n_bits
;
886 n_drop_bits
&& (*availiable_mask_bits
& SIXTEENTH_BIT
);
888 *availiable_mask_bits
<<= 1;
891 as_bad (_(":operand has too many bits"));
892 *availiable_mask_bits
>>= n_shifts
+ n_bits
;
893 if ((n_drop_bits
== 0) && (*availiable_mask_bits
== 0))
895 oper_check
= 1; /* flag operand check as good */
897 new_mask
<<= N_BITS_IN_WORD
- (n_shifts
+ n_bits
);
902 /* Parse ordinary expression. */
905 xgate_parse_exp (char *s
, expressionS
* op
)
907 input_line_pointer
= s
;
909 if (op
->X_op
== O_absent
)
910 as_bad (_("missing operand"));
911 return input_line_pointer
;
915 cmp_opcode (struct xgate_opcode
*op1
, struct xgate_opcode
*op2
)
917 return strcmp (op1
->name
, op2
->name
);
920 static struct xgate_opcode
*
921 xgate_find_match (struct xgate_opcode_handle
*opcode_handle
,
923 unsigned int sh_format
)
927 if (numberOfModes
== 0)
928 return opcode_handle
->opc0
[0];
930 for (i
= 0; i
<= numberOfModes
; i
++)
931 if (opcode_handle
->opc0
[i
]->sh_format
& sh_format
)
932 return opcode_handle
->opc0
[i
];
937 /* Because we are dealing with two different core that view the system
938 memory with different offsets, we must differentiate what core a
939 symbol belongs to, in order for the linker to cross-link. */
942 xgate_frob_symbol (symbolS
*sym
)
945 elf_symbol_type
*elfsym
;
947 bfdsym
= symbol_get_bfdsym (sym
);
948 elfsym
= elf_symbol_from (bfd_asymbol_bfd (bfdsym
), bfdsym
);
952 /* Mark the symbol as being *from XGATE */
953 elfsym
->internal_elf_sym
.st_target_internal
= 1;
959 xgate_get_operands (char *line
, s_operand oprs
[])
963 /* If there are no operands, then it must be inherent. */
964 if (*line
== 0 || *line
== '\n' || *line
== '\r')
967 for (num_operands
= 0; strlen (line
) && (num_operands
< MAX_NUM_OPERANDS
);
970 line
= skip_whitespace (line
);
974 oprs
[num_operands
].mod
= xgate_determine_hi_low (&line
);
975 oprs
[num_operands
].mod
= xgate_determine_increment (&line
);
977 if ((oprs
[num_operands
].reg
= reg_name_search (line
)) == REG_NONE
)
978 line
= xgate_parse_exp (line
, &oprs
[num_operands
].exp
);
980 /* skip to next operand */
992 if (num_operands
> MAX_NUM_OPERANDS
)
995 switch (num_operands
)
998 if (oprs
[0].reg
>= REG_R0
&& oprs
[0].reg
<= REG_R7
)
1000 if (oprs
[0].reg
== REG_NONE
)
1004 if (oprs
[0].reg
>= REG_R0
&& oprs
[0].reg
<= REG_R7
)
1006 if (oprs
[1].reg
>= REG_R0
&& oprs
[1].reg
<= REG_R7
)
1008 if (oprs
[1].reg
== REG_CCR
)
1010 if (oprs
[1].reg
== REG_PC
)
1012 if (oprs
[1].reg
== REG_NONE
)
1015 if (oprs
[0].reg
== REG_CCR
)
1019 if (oprs
[0].reg
>= REG_R0
&& oprs
[0].reg
<= REG_R7
)
1021 if (oprs
[1].reg
>= REG_R0
&& oprs
[1].reg
<= REG_R7
)
1023 if (oprs
[2].reg
>= REG_R0
&& oprs
[2].reg
<= REG_R7
)
1025 if (oprs
[2].reg
>= REG_NONE
)
1031 as_bad (_("unknown operand format"));
1038 /* reg_name_search() finds the register number given its name.
1039 Returns the register number or REG_NONE on failure. */
1041 reg_name_search (char *name
)
1043 if (strncasecmp (name
, "r0", 2) == 0)
1045 if (strncasecmp (name
, "r1", 2) == 0)
1047 if (strncasecmp (name
, "r2", 2) == 0)
1049 if (strncasecmp (name
, "r3", 2) == 0)
1051 if (strncasecmp (name
, "r4", 2) == 0)
1053 if (strncasecmp (name
, "r5", 2) == 0)
1055 if (strncasecmp (name
, "r6", 2) == 0)
1057 if (strncasecmp (name
, "r7", 2) == 0)
1059 if (strncasecmp (name
, "pc", 2) == 0)
1061 if (strncasecmp (name
, "ccr", 3) == 0)
1067 xgate_determine_hi_low(char **line
)
1069 char *local_line
= line
[0];
1071 if (strncasecmp (local_line
, "%hi", 3) == 0)
1074 return MOD_LOAD_HIGH
;
1076 if (strncasecmp (local_line
, "%lo", 3) == 0)
1079 return MOD_LOAD_LOW
;
1085 xgate_determine_increment(char **line
)
1087 char *local_line
= line
[0];
1089 if (*(local_line
+ 2) == '+')
1091 if (strncasecmp (local_line
, "-r", 2) == 0)
1099 /* Parse instruction operands. */
1102 xgate_scan_operands (struct xgate_opcode
*opcode
, s_operand oprs
[])
1104 char *frag
= xgate_new_instruction (opcode
->size
);
1105 int where
= frag
- frag_now
->fr_literal
;
1106 char *op
= opcode
->constraints
;
1107 unsigned int bin
= (int) opcode
->bin_opcode
;
1108 unsigned short oper_mask
= 0;
1109 int operand_bit_length
= 0;
1110 unsigned int operand
= 0;
1111 char n_operand_bits
= 0;
1112 char first_operand_equals_second
= 0;
1116 /* Generate available operand bits mask. */
1117 for (i
= 0; (c
= opcode
->format
[i
]); i
++)
1119 if (ISDIGIT (c
) || (c
== 's'))
1131 /* Parse first operand. */
1136 first_operand_equals_second
= 1;
1139 operand
= xgate_parse_operand (opcode
, &operand_bit_length
, where
, &op
, oprs
[0]);
1141 bin
= xgate_apply_operand (operand
, &oper_mask
, bin
, operand_bit_length
);
1143 if(first_operand_equals_second
)
1144 bin
= xgate_apply_operand (operand
, &oper_mask
, bin
, operand_bit_length
);
1145 /* Parse second operand. */
1150 if (first_operand_equals_second
)
1152 bin
= xgate_apply_operand (operand
, &oper_mask
, bin
,
1153 operand_bit_length
);
1158 operand
= xgate_parse_operand (opcode
, &operand_bit_length
, where
,
1160 bin
= xgate_apply_operand (operand
, &oper_mask
, bin
,
1161 operand_bit_length
);
1165 /* Parse the third register. */
1170 operand
= xgate_parse_operand (opcode
, &operand_bit_length
, where
, &op
,
1172 bin
= xgate_apply_operand (operand
, &oper_mask
, bin
,
1173 operand_bit_length
);
1176 if (opcode
->size
== 2 && fixup_required
)
1178 bfd_putl16 (bin
, frag
);
1180 else if ((opcode
->sh_format
& XG_PCREL
))
1182 /* Write our data to a frag for further processing. */
1183 bfd_putl16 (opcode
->bin_opcode
, frag
);
1187 /* Apply operand mask(s)to bin opcode and write the output. */
1188 /* Since we are done write this frag in xgate BE format. */
1189 number_to_chars_bigendian (frag
, bin
, opcode
->size
);
1196 xgate_parse_operand (struct xgate_opcode
*opcode
,
1200 s_operand operand_two
)
1203 char *op_constraint
= *op_con
;
1204 unsigned int op_mask
= 0;
1205 unsigned int pp_fix
= 0;
1206 unsigned short max_size
= 0;
1212 switch (*op_constraint
)
1214 case '+': /* Indexed register operand +/- or plain r. */
1215 /* Default to neither inc or dec. */
1219 if (operand_two
.reg
== REG_NONE
)
1220 as_bad (_(": expected register name r0-r7 ") );
1221 op_mask
= operand_two
.reg
;
1222 if(operand_two
.mod
== MOD_POSTINC
)
1224 if(operand_two
.mod
== MOD_PREDEC
)
1230 case 'r': /* Register operand. */
1231 if (operand_two
.reg
== REG_NONE
)
1232 as_bad (_(": expected register name r0-r7 "));
1236 op_mask
= operand_two
.reg
;
1239 case 'i': /* Immediate value or expression expected. */
1240 /* Advance the original format pointer. */
1243 if (ISDIGIT (*op_constraint
))
1245 *bit_width
= (int) *op_constraint
- '0';
1247 else if (*op_constraint
== 'a')
1251 else if (*op_constraint
== 'f')
1255 /* http://tigcc.ticalc.org/doc/gnuasm.html#SEC31 */
1256 if (operand_two
.exp
.X_op
== O_constant
)
1258 op_mask
= operand_two
.exp
.X_add_number
;
1259 if ((opcode
->name
[strlen (opcode
->name
) - 1] == 'l') && macroClipping
)
1263 else if ((opcode
->name
[strlen (opcode
->name
) - 1]) == 'h'
1269 /* Make sure it fits. */
1270 for (i
= *bit_width
; i
; i
--)
1275 if (op_mask
> max_size
)
1276 as_bad (_(":operand value(%d) too big for constraint"), op_mask
);
1281 if (*op_constraint
== '8')
1283 if ((opcode
->name
[strlen (opcode
->name
) - 1] == 'l')
1286 fixp
= fix_new_exp (frag_now
, where
, 2, &operand_two
.exp
, FALSE
,
1287 BFD_RELOC_XGATE_24
);
1288 /* Should be BFD_RELOC_XGATE_IMM8_LO TODO fix. */
1289 fixp
->fx_pcrel_adjust
= 0;
1291 if ((opcode
->name
[strlen (opcode
->name
) - 1]) == 'h'
1294 fixp
= fix_new_exp (frag_now
, where
, 2, &operand_two
.exp
, FALSE
,
1295 BFD_RELOC_XGATE_IMM8_HI
);
1296 fixp
->fx_pcrel_adjust
= 0;
1299 as_bad (_(":unknown relocation"));
1301 else if (*op_constraint
== '5')
1303 fixp
= fix_new_exp (frag_now
, where
, 2, &operand_two
.exp
, FALSE
,
1304 BFD_RELOC_XGATE_IMM5
);
1305 fixp
->fx_pcrel_adjust
= 0;
1307 else if (*op_constraint
== '4')
1309 fixp
= fix_new_exp (frag_now
, where
, 2, &operand_two
.exp
, FALSE
,
1310 BFD_RELOC_XGATE_IMM4
);
1311 fixp
->fx_pcrel_adjust
= 0;
1313 else if (*op_constraint
== '3')
1315 fixp
= fix_new_exp (frag_now
, where
, 2, &operand_two
.exp
, FALSE
,
1316 BFD_RELOC_XGATE_IMM3
);
1317 fixp
->fx_pcrel_adjust
= 0;
1321 as_bad (_(":unknown relocation constraint size"));
1326 case 'c': /* CCR register expected. */
1328 if (operand_two
.reg
!= REG_CCR
)
1329 as_bad (_(": expected register name ccr "));
1332 case 'p': /* PC register expected. */
1334 if (operand_two
.reg
!= REG_PC
)
1335 as_bad (_(": expected register name pc "));
1338 case 'b': /* Branch expected. */
1342 if (operand_two
.exp
.X_op
!= O_register
)
1344 if (*op_constraint
== '9')
1346 fixp
= fix_new_exp (frag_now
, where
, 2, &operand_two
.exp
, TRUE
,
1348 fixp
->fx_pcrel_adjust
= 1;
1350 else if (*op_constraint
== 'a')
1352 fixp
= fix_new_exp (frag_now
, where
, 2, &operand_two
.exp
, TRUE
,
1354 fixp
->fx_pcrel_adjust
= 1;
1359 as_fatal (_("Operand `%x' not recognized in fixup8."), operand_two
.exp
.X_op
);
1366 as_bad (_("unknown constraint `%c'"), *op_constraint
);