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_modifiers(char **);
128 xgate_scan_operands (struct xgate_opcode
*opcode
, s_operand
[]);
131 xgate_parse_operand (struct xgate_opcode
*, int *, int where
, char **,
135 static struct hash_control
*xgate_hash
;
137 /* Previous opcode. */
138 static unsigned int prev
= 0;
140 static unsigned char fixup_required
= 0;
142 /* Used to enable clipping of 16 bit operands into 8 bit constraints. */
143 static unsigned char autoHiLo
= 0;
145 static char oper_check
;
146 static char flag_print_insn_syntax
= 0;
147 static char flag_print_opcodes
= 0;
149 static int current_architecture
;
150 static const char *default_cpu
;
152 /* ELF flags to set in the output file header. */
153 static int elf_flags
= E_XGATE_F64
;
155 /* This table describes how you change sizes for the various types of variable
156 size expressions. This version only supports two kinds. */
159 How far Forward this mode will reach.
160 How far Backward this mode will reach.
161 How many bytes this mode will add to the size of the frag.
162 Which mode to go to if the offset won't fit in this one. */
164 relax_typeS md_relax_table
[] =
166 {1, 1, 0, 0}, /* First entries aren't used. */
167 {1, 1, 0, 0}, /* For no good reason except. */
168 {1, 1, 0, 0}, /* that the VAX doesn't either. */
170 /* XGATE 9 and 10 bit pc rel todo complete and test */
171 /*{(511), (-512), 0, ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD)},
172 {(1023), (-1024), 0, ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD)}, */
176 /* This table describes all the machine specific pseudo-ops the assembler
177 has to support. The fields are: pseudo-op name without dot function to
178 call to execute this pseudo-op Integer arg to pass to the function. */
179 const pseudo_typeS md_pseudo_table
[] =
181 /* The following pseudo-ops are supported for MRI compatibility. */
185 const char *md_shortopts
= "m:";
187 struct option md_longopts
[] =
189 #define OPTION_PRINT_INSN_SYNTAX (OPTION_MD_BASE + 0)
190 { "print-insn-syntax", no_argument
, NULL
, OPTION_PRINT_INSN_SYNTAX
},
192 #define OPTION_PRINT_OPCODES (OPTION_MD_BASE + 1)
193 { "print-opcodes", no_argument
, NULL
, OPTION_PRINT_OPCODES
},
195 #define OPTION_GENERATE_EXAMPLE (OPTION_MD_BASE + 2)
196 { "generate-example", no_argument
, NULL
, OPTION_GENERATE_EXAMPLE
},
198 #define OPTION_MSHORT (OPTION_MD_BASE + 3)
199 { "mshort", no_argument
, NULL
, OPTION_MSHORT
},
201 #define OPTION_MLONG (OPTION_MD_BASE + 4)
202 { "mlong", no_argument
, NULL
, OPTION_MLONG
},
204 #define OPTION_MSHORT_DOUBLE (OPTION_MD_BASE + 5)
205 { "mshort-double", no_argument
, NULL
, OPTION_MSHORT_DOUBLE
},
207 #define OPTION_MLONG_DOUBLE (OPTION_MD_BASE + 6)
208 { "mlong-double", no_argument
, NULL
, OPTION_MLONG_DOUBLE
},
210 { NULL
, no_argument
, NULL
, 0 }
213 size_t md_longopts_size
= sizeof(md_longopts
);
216 md_atof (int type
, char *litP
, int *sizeP
)
218 return ieee_md_atof (type
, litP
, sizeP
, TRUE
);
222 md_parse_option (int c
, char *arg
)
227 if (strcasecmp (arg
, "v1") == 0)
228 current_architecture
= XGATE_V1
;
229 else if (strcasecmp (arg
, "v2") == 0)
230 current_architecture
= XGATE_V2
;
231 else if (strcasecmp (arg
, "v3") == 0)
232 current_architecture
= XGATE_V3
;
234 as_bad (_(" architecture variant invalid"));
237 case OPTION_PRINT_INSN_SYNTAX
:
238 flag_print_insn_syntax
= 1;
241 case OPTION_PRINT_OPCODES
:
242 flag_print_opcodes
= 1;
245 case OPTION_GENERATE_EXAMPLE
:
246 flag_print_opcodes
= 2;
250 elf_flags
&= ~E_XGATE_I32
;
254 elf_flags
|= E_XGATE_I32
;
257 case OPTION_MSHORT_DOUBLE
:
258 elf_flags
&= ~E_XGATE_F64
;
261 case OPTION_MLONG_DOUBLE
:
262 elf_flags
|= E_XGATE_F64
;
272 xgate_arch_format (void)
274 get_default_target ();
276 if (current_architecture
& cpuxgate
)
277 return "elf32-xgate";
283 get_default_target (void)
285 const bfd_target
*target
;
288 if (current_architecture
!= 0)
291 default_cpu
= "unknown";
292 target
= bfd_find_target (0, &abfd
);
294 if (target
&& target
->name
)
296 if (strcmp (target
->name
, "elf32-xgate") == 0)
298 current_architecture
= cpuxgate
;
299 default_cpu
= "XGATE V1";
303 as_bad (_("Default target `%s' is not supported."), target
->name
);
310 struct xgate_opcode
*xgate_opcode_ptr
= NULL
;
311 struct xgate_opcode
*xgate_op_table
= NULL
;
312 struct xgate_opcode_handle
*op_handles
= 0;
313 char *prev_op_name
= 0;
315 int number_of_op_handles
= 0;
318 /* Create a local copy of our opcode table
319 including an extra line for NULL termination. */
320 xgate_op_table
= (struct xgate_opcode
*)
321 xmalloc ((xgate_num_opcodes
) * sizeof (struct xgate_opcode
));
323 memset (xgate_op_table
, 0,
324 sizeof(struct xgate_opcode
) * (xgate_num_opcodes
));
326 for (xgate_opcode_ptr
= (struct xgate_opcode
*) xgate_opcodes
, i
= 0;
327 i
< xgate_num_opcodes
; i
++)
328 xgate_op_table
[i
] = xgate_opcode_ptr
[i
];
330 qsort (xgate_op_table
, xgate_num_opcodes
, sizeof(struct xgate_opcode
),
331 (int (*)(const void *, const void *)) cmp_opcode
);
333 /* Calculate number of handles since this will be
334 smaller than the raw number of opcodes in the table. */
336 for (xgate_opcode_ptr
= xgate_op_table
, i
= 0; i
< xgate_num_opcodes
;
337 xgate_opcode_ptr
++, i
++)
339 if (strcmp (prev_op_name
, xgate_opcode_ptr
->name
))
340 number_of_op_handles
++;
341 prev_op_name
= xgate_opcode_ptr
->name
;
344 op_handles
= (struct xgate_opcode_handle
*)
345 xmalloc (sizeof(struct xgate_opcode_handle
) * (number_of_op_handles
));
347 /* Insert unique opcode names into hash table, aliasing duplicates. */
348 xgate_hash
= hash_new ();
351 for (xgate_opcode_ptr
= xgate_op_table
, i
= 0, j
= 0; i
< xgate_num_opcodes
;
352 i
++, xgate_opcode_ptr
++)
354 if (!strcmp (prev_op_name
, xgate_opcode_ptr
->name
))
357 op_handles
[j
].opc0
[handle_enum
] = xgate_opcode_ptr
;
364 op_handles
[j
].name
= xgate_opcode_ptr
->name
;
365 op_handles
[j
].opc0
[0] = xgate_opcode_ptr
;
366 hash_insert (xgate_hash
, (char *) op_handles
[j
].name
,
367 (char *) &(op_handles
[j
]));
369 op_handles
[j
].number_of_modes
= handle_enum
;
370 prev_op_name
= op_handles
[j
].name
;
373 if (flag_print_opcodes
== 1)
374 xgate_print_table ();
378 xgate_init_after_args (void)
383 md_show_usage (FILE * stream
)
385 get_default_target ();
390 Freescale XGATE co-processor options:\n \
391 -mshort use 16-bit int ABI (default)\n \
392 -mlong use 32-bit int ABI\n \
393 -mshort-double use 32-bit double ABI\n \
394 -mlong-double use 64-bit double ABI (default)\n\
395 --mxgate specify the processor variant[default %s]\n\
396 --print-insn-syntax print the syntax of instruction in case of error\n\
397 --print-opcodes print the list of instructions with syntax\n\
398 --generate-example generate an example of each instruction"),
402 enum bfd_architecture
405 get_default_target ();
406 return bfd_arch_xgate
;
416 xgate_print_syntax (char *name
)
420 for (i
= 0; i
< xgate_num_opcodes
; i
++)
422 if (!strcmp (xgate_opcodes
[i
].name
, name
))
424 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_IDR
))
425 printf ("\tFormat is %s\tRx, Rx, Rx+|-Rx|Rx\n",
426 xgate_opcodes
[i
].name
);
427 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_INH
))
428 printf ("\tFormat is %s\n", xgate_opcodes
[i
].name
);
429 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_TRI
))
430 printf ("\tFormat is %s\tRx, Rx, Rx\n", xgate_opcodes
[i
].name
);
431 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_DYA
))
432 printf ("\tFormat is %s\tRx, Rx\n", xgate_opcodes
[i
].name
);
433 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_IMM3
))
434 printf ("\tFormat is %s\t<3-bit value>\n", xgate_opcodes
[i
].name
);
435 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_IMM4
))
436 printf ("\tFormat is %s\t<4 -bit value>\n", xgate_opcodes
[i
].name
);
437 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_IMM8
))
438 printf ("\tFormat is %s\tRx, <8-bit value>\n",
439 xgate_opcodes
[i
].name
);
440 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_IMM16
))
441 printf ("\tFormat is %s\tRx, <16-bit value>\n",
442 xgate_opcodes
[i
].name
);
443 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_MON_R_C
))
444 printf ("\tFormat is %s\tRx, CCR\n", xgate_opcodes
[i
].name
);
445 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_MON_C_R
))
446 printf ("\tFormat is %s\tCCR, Rx\n", xgate_opcodes
[i
].name
);
447 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_MON_R_P
))
448 printf ("\tFormat is %s\tRx, PC\n", xgate_opcodes
[i
].name
);
449 if (!strcmp (xgate_opcodes
[i
].constraints
, XGATE_OP_IMM16mLDW
))
450 printf ("\tFormat is %s\tRx, <16-bit value>\n",
451 xgate_opcodes
[i
].name
);
457 xgate_print_table (void)
461 for (i
= 0; i
< xgate_num_opcodes
; i
++)
462 xgate_print_syntax (xgate_opcodes
[i
].name
);
468 xgate_listing_header (void)
470 if (current_architecture
& cpuxgate
)
473 return "ERROR MC9S12X GAS ";
477 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
482 /* GAS will call this function for each section at the end of the assembly,
483 to permit the CPU backend to adjust the alignment of a section. */
486 md_section_align (asection
* seg
, valueT addr
)
488 int align
= bfd_get_section_alignment (stdoutput
, seg
);
489 return ((addr
+ (1 << align
) - 1) & (-1 << align
));
493 md_assemble (char *input_line
)
495 struct xgate_opcode
*opcode
= 0;
496 struct xgate_opcode
*macro_opcode
= 0;
497 struct xgate_opcode_handle
*opcode_handle
= 0;
498 /* Caller expects it to be returned as it was passed. */
499 char *saved_input_line
= input_line
;
500 char op_name
[9] = { 0 };
501 unsigned int sh_format
= 0;
504 s_operand new_operands
[MAX_NUM_OPERANDS
];
507 oper_check
= 0; /* set error flags */
508 input_line
= extract_word (input_line
, op_name
, sizeof(op_name
));
510 /* Check to make sure we are not reading a bogus line. */
512 as_bad (_("opcode missing or not found on input line"));
514 if (!(opcode_handle
= (struct xgate_opcode_handle
*) hash_find (xgate_hash
,
517 as_bad (_("opcode %s not found in opcode hash table"), op_name
);
521 /* Parse operands so we can find the proper opcode bin. */
523 sh_format
= xgate_get_operands(input_line
, new_operands
);
525 opcode
= xgate_find_match (opcode_handle
, opcode_handle
->number_of_modes
,
530 as_bad (_("matching operands to opcode "));
531 xgate_print_syntax (opcode_handle
->opc0
[0]->name
);
533 else if (opcode
->size
== 2)
535 /* Size is one word - assemble that native insn. */
536 xgate_scan_operands (opcode
, new_operands
);
540 /* Insn is a simplified instruction - expand it out. */
544 /* skip past our ';' separator. */
545 for (i
= strlen (opcode
->constraints
), p
= opcode
->constraints
; i
> 0;
554 input_line
= skip_whitespace (input_line
);
555 char *macro_inline
= input_line
;
557 /* Loop though the macro's opcode list and apply operands to each real opcode. */
558 for (i
= 0; *p
&& i
< (opcode
->size
/ 2); i
++)
560 /* Loop though macro operand list. */
561 input_line
= macro_inline
; /* Rewind. */
562 p
= extract_word (p
, op_name
, 10);
564 if (!(opcode_handle
= (struct xgate_opcode_handle
*)
565 hash_find (xgate_hash
, op_name
)))
568 _(": processing macro, real opcode handle not found in hash"));
573 sh_format
= xgate_get_operands(input_line
, new_operands
);
574 macro_opcode
= xgate_find_match (opcode_handle
,
575 opcode_handle
->number_of_modes
, sh_format
);
576 xgate_scan_operands (macro_opcode
, new_operands
);
583 input_line
= saved_input_line
;
586 /* Force truly undefined symbols to their maximum size, and generally set up
587 the frag list to be relaxed. */
590 md_estimate_size_before_relax (fragS
*fragp
, asection
*seg
)
592 /* If symbol is undefined or located in a different section,
593 select the largest supported relocation. */
594 relax_substateT subtype
;
595 relax_substateT rlx_state
[] =
598 for (subtype
= 0; subtype
< ARRAY_SIZE (rlx_state
); subtype
+= 2)
600 if (fragp
->fr_subtype
== rlx_state
[subtype
]
601 && (!S_IS_DEFINED (fragp
->fr_symbol
)
602 || seg
!= S_GET_SEGMENT (fragp
->fr_symbol
)))
604 fragp
->fr_subtype
= rlx_state
[subtype
+ 1];
609 if (fragp
->fr_subtype
>= ARRAY_SIZE (md_relax_table
))
612 return md_relax_table
[fragp
->fr_subtype
].rlx_length
;
616 /* Relocation, relaxation and frag conversions. */
618 /* PC-relative offsets are relative to the start of the
619 next instruction. That is, the address of the offset, plus its
620 size, since the offset is always the last part of the insn. */
623 md_pcrel_from (fixS
* fixP
)
625 return fixP
->fx_size
+ fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
628 /* If while processing a fixup, a reloc really needs to be created
629 then it is done here. */
632 tc_gen_reloc (asection
* section ATTRIBUTE_UNUSED
, fixS
* fixp
)
636 reloc
= (arelent
*) xmalloc (sizeof(arelent
));
637 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof(asymbol
*));
638 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
639 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
641 if (fixp
->fx_r_type
== 0)
643 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_16
);
647 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
650 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
652 as_bad_where (fixp
->fx_file
, fixp
->fx_line
, _
653 ("Relocation %d is not supported by object file format."),
654 (int) fixp
->fx_r_type
);
658 /* Since we use Rel instead of Rela, encode the vtable entry to be
659 used in the relocation's section offset. */
660 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
661 reloc
->address
= fixp
->fx_offset
;
666 /* Patch the instruction with the resolved operand. Elf relocation
667 info will also be generated to take care of linker/loader fixups.
668 The XGATE addresses only 16-bit addresses.The BFD_RELOC_32 is necessary
669 for the support of --gstabs. */
672 md_apply_fix (fixS
* fixP
, valueT
* valP
, segT seg ATTRIBUTE_UNUSED
)
679 /* If the fixup is done mark it done so no further symbol resolution will take place. */
680 if (fixP
->fx_addsy
== (symbolS
*) NULL
)
685 /* We don't actually support subtracting a symbol. */
686 if (fixP
->fx_subsy
!= (symbolS
*) NULL
)
687 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("Expression too complex."));
689 where
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
690 opcode
= bfd_getl16 (where
);
693 switch (fixP
->fx_r_type
)
695 case R_XGATE_PCREL_9
:
696 if (value
< -512 || value
> 511)
697 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
698 _("Value %ld too large for 9-bit PC-relative branch."), value
);
699 result
= ldiv (value
, 2); /* from bytes to words */
702 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _
703 ("Value %ld not aligned by 2 for 9-bit PC-relative branch."), value
);
704 mask
= 0x1FF; /* Clip into 8-bit field FIXME I'm sure there is a more proper place for this */
706 number_to_chars_bigendian (where
, (opcode
| value
), 2);
708 case R_XGATE_PCREL_10
:
709 if (value
< -1024 || value
> 1023)
710 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
711 _("Value %ld too large for 10-bit PC-relative branch."), value
);
712 result
= ldiv (value
, 2); /* from bytes to words */
715 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _
716 ("Value %ld not aligned by 2 for 10-bit PC-relative branch."), value
);
717 mask
= 0x3FF; /* Clip into 9-bit field FIXME I'm sure there is a more proper place for this */
719 number_to_chars_bigendian (where
, (opcode
| value
), 2);
721 case BFD_RELOC_XGATE_IMM8_HI
:
722 if (value
< -65537 || value
> 65535)
723 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
724 _("Value out of 16-bit range."));
727 bfd_putb16 ((bfd_vma
) value
| opcode
, (void *) where
);
729 case BFD_RELOC_XGATE_24
:
730 case BFD_RELOC_XGATE_IMM8_LO
:
731 if (value
< -65537 || value
> 65535)
732 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
733 _("Value out of 16-bit range."));
735 bfd_putb16 ((bfd_vma
) value
| opcode
, (void *) where
);
737 case BFD_RELOC_XGATE_IMM3
:
738 if (value
< 0 || value
> 7)
739 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
740 _("Value out of 3-bit range."));
741 value
<<= 8; /* make big endian */
742 number_to_chars_bigendian (where
, (opcode
| value
), 2);
744 case BFD_RELOC_XGATE_IMM4
:
745 if (value
< 0 || value
> 15)
746 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
747 _("Value out of 4-bit range."));
748 value
<<= 4; /* align the operand bits */
749 number_to_chars_bigendian (where
, (opcode
| value
), 2);
751 case BFD_RELOC_XGATE_IMM5
:
752 if (value
< 0 || value
> 31)
753 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
754 _("Value out of 5-bit range."));
755 value
<<= 5; /* align the operand bits */
756 number_to_chars_bigendian (where
, (opcode
| value
), 2);
759 ((bfd_byte
*) where
)[0] = (bfd_byte
) value
;
762 bfd_putb32 ((bfd_vma
) value
, (unsigned char *) where
);
765 bfd_putb16 ((bfd_vma
) value
, (unsigned char *) where
);
768 as_fatal (_("Line %d: unknown relocation type: 0x%x."), fixP
->fx_line
,
774 /* See whether we need to force a relocation into the output file. */
777 tc_xgate_force_relocation (fixS
* fixP
)
779 if (fixP
->fx_r_type
== BFD_RELOC_XGATE_RL_GROUP
)
781 return generic_force_reloc (fixP
);
784 /* Here we decide which fixups can be adjusted to make them relative
785 to the beginning of the section instead of the symbol. Basically
786 we need to make sure that the linker relaxation is done
787 correctly, so in some cases we force the original symbol to be
791 tc_xgate_fix_adjustable (fixS
* fixP
)
793 switch (fixP
->fx_r_type
)
795 /* For the linker relaxation to work correctly, these relocs
796 need to be on the symbol itself. */
798 case BFD_RELOC_XGATE_RL_JUMP
:
799 case BFD_RELOC_XGATE_RL_GROUP
:
800 case BFD_RELOC_VTABLE_INHERIT
:
801 case BFD_RELOC_VTABLE_ENTRY
:
810 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
,
811 asection
* sec ATTRIBUTE_UNUSED
,
812 fragS
* fragP ATTRIBUTE_UNUSED
)
814 as_bad (("md_convert_frag not implemented yet"));
818 /* Set the ELF specific flags. */
821 xgate_elf_final_processing (void)
823 elf_flags
|= EF_XGATE_MACH
;
824 elf_elfheader (stdoutput
)->e_flags
&= ~EF_XGATE_ABI
;
825 elf_elfheader (stdoutput
)->e_flags
|= elf_flags
;
829 skip_whitespace (char *s
)
831 while (*s
== ' ' || *s
== '\t' || *s
== '(' || *s
== ')')
837 /* Extract a word (continuous alpha-numeric chars) from the input line. */
840 extract_word (char *from
, char *to
, int limit
)
845 /* Drop leading whitespace. */
846 from
= skip_whitespace (from
);
848 /* Find the op code end. */
849 for (op_end
= from
; *op_end
!= 0 && is_part_of_name (*op_end
);)
851 to
[size
++] = *op_end
++;
852 if (size
+ 1 >= limit
)
860 xgate_new_instruction (int size
)
862 char *f
= frag_more (size
);
863 dwarf2_emit_insn (size
);
868 xgate_apply_operand (unsigned short new_mask
,
869 unsigned short *availiable_mask_bits
,
871 unsigned char n_bits
)
873 unsigned short n_shifts
;
874 unsigned int n_drop_bits
;
876 /* Shift until you find an available operand bit "1" and record the number of shifts. */
878 !(*availiable_mask_bits
& SIXTEENTH_BIT
) && n_shifts
< 16;
880 *availiable_mask_bits
<<= 1;
882 /* Shift for the number of bits your operand requires while bits are available. */
883 for (n_drop_bits
= n_bits
;
884 n_drop_bits
&& (*availiable_mask_bits
& SIXTEENTH_BIT
);
886 *availiable_mask_bits
<<= 1;
889 as_bad (_(":operand has too many bits"));
890 *availiable_mask_bits
>>= n_shifts
+ n_bits
;
891 if ((n_drop_bits
== 0) && (*availiable_mask_bits
== 0))
893 oper_check
= 1; /* flag operand check as good */
895 new_mask
<<= N_BITS_IN_WORD
- (n_shifts
+ n_bits
);
900 /* Parse ordinary expression. */
903 xgate_parse_exp (char *s
, expressionS
* op
)
905 input_line_pointer
= s
;
907 if (op
->X_op
== O_absent
)
908 as_bad (_("missing operand"));
909 return input_line_pointer
;
913 cmp_opcode (struct xgate_opcode
*op1
, struct xgate_opcode
*op2
)
915 return strcmp (op1
->name
, op2
->name
);
918 static struct xgate_opcode
*
919 xgate_find_match (struct xgate_opcode_handle
*opcode_handle
,
921 unsigned int sh_format
)
925 if (numberOfModes
== 0)
926 return opcode_handle
->opc0
[0];
928 for (i
= 0; i
<= numberOfModes
; i
++)
929 if (opcode_handle
->opc0
[i
]->sh_format
& sh_format
)
930 return opcode_handle
->opc0
[i
];
935 /* Because we are dealing with two different core that view the system
936 memory with different offsets, we must differentiate what core a
937 symbol belongs to, in order for the linker to cross-link. */
940 xgate_frob_symbol (symbolS
*sym
)
943 elf_symbol_type
*elfsym
;
945 bfdsym
= symbol_get_bfdsym (sym
);
946 elfsym
= elf_symbol_from (bfd_asymbol_bfd (bfdsym
), bfdsym
);
950 /* Mark the symbol as being *from XGATE */
951 elfsym
->internal_elf_sym
.st_target_internal
= 1;
957 xgate_get_operands (char *line
, s_operand oprs
[])
961 /* If there are no operands, then it must be inherent. */
962 if (*line
== 0 || *line
== '\n' || *line
== '\r')
965 for (num_operands
= 0; strlen (line
) && (num_operands
< MAX_NUM_OPERANDS
);
968 line
= skip_whitespace (line
);
972 oprs
[num_operands
].mod
= xgate_determine_modifiers (&line
);
974 if ((oprs
[num_operands
].reg
= reg_name_search (line
)) == REG_NONE
)
975 line
= xgate_parse_exp (line
, &oprs
[num_operands
].exp
);
977 /* skip to next operand */
989 if (num_operands
> MAX_NUM_OPERANDS
)
992 switch (num_operands
)
995 if (oprs
[0].reg
>= REG_R0
&& oprs
[0].reg
<= REG_R7
)
997 if (oprs
[0].reg
== REG_NONE
)
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
[1].reg
== REG_CCR
)
1007 if (oprs
[1].reg
== REG_PC
)
1009 if (oprs
[1].reg
== REG_NONE
)
1012 if (oprs
[0].reg
== REG_CCR
)
1016 if (oprs
[0].reg
>= REG_R0
&& oprs
[0].reg
<= REG_R7
)
1018 if (oprs
[1].reg
>= REG_R0
&& oprs
[1].reg
<= REG_R7
)
1020 if (oprs
[2].reg
>= REG_R0
&& oprs
[2].reg
<= REG_R7
)
1022 if (oprs
[2].reg
>= REG_NONE
)
1028 as_bad (_("unknown operand format"));
1035 /* reg_name_search() finds the register number given its name.
1036 Returns the register number or REG_NONE on failure. */
1038 reg_name_search (char *name
)
1040 if (strncasecmp (name
, "r0", 2) == 0)
1042 if (strncasecmp (name
, "r1", 2) == 0)
1044 if (strncasecmp (name
, "r2", 2) == 0)
1046 if (strncasecmp (name
, "r3", 2) == 0)
1048 if (strncasecmp (name
, "r4", 2) == 0)
1050 if (strncasecmp (name
, "r5", 2) == 0)
1052 if (strncasecmp (name
, "r6", 2) == 0)
1054 if (strncasecmp (name
, "r7", 2) == 0)
1056 if (strncasecmp (name
, "pc", 2) == 0)
1058 if (strncasecmp (name
, "ccr", 3) == 0)
1063 /* Parse operand modifiers such as inc/dec/hi/low. */
1066 xgate_determine_modifiers(char **line
)
1068 char *local_line
= line
[0];
1070 if (strncasecmp (local_line
, "%hi", 3) == 0)
1073 return MOD_LOAD_HIGH
;
1075 if (strncasecmp (local_line
, "%lo", 3) == 0)
1078 return MOD_LOAD_LOW
;
1080 if (*(local_line
+ 2) == '+')
1082 if (strncasecmp (local_line
, "-r", 2) == 0)
1090 /* Parse instruction operands. */
1093 xgate_scan_operands (struct xgate_opcode
*opcode
, s_operand oprs
[])
1095 char *frag
= xgate_new_instruction (opcode
->size
);
1096 int where
= frag
- frag_now
->fr_literal
;
1097 char *op
= opcode
->constraints
;
1098 unsigned int bin
= (int) opcode
->bin_opcode
;
1099 unsigned short oper_mask
= 0;
1100 int operand_bit_length
= 0;
1101 unsigned int operand
= 0;
1102 char n_operand_bits
= 0;
1103 char first_operand_equals_second
= 0;
1107 /* Generate available operand bits mask. */
1108 for (i
= 0; (c
= opcode
->format
[i
]); i
++)
1110 if (ISDIGIT (c
) || (c
== 's'))
1122 /* Parse first operand. */
1127 first_operand_equals_second
= 1;
1130 operand
= xgate_parse_operand (opcode
, &operand_bit_length
, where
, &op
, oprs
[0]);
1132 bin
= xgate_apply_operand (operand
, &oper_mask
, bin
, operand_bit_length
);
1134 if(first_operand_equals_second
)
1135 bin
= xgate_apply_operand (operand
, &oper_mask
, bin
, operand_bit_length
);
1136 /* Parse second operand. */
1141 if (first_operand_equals_second
)
1143 bin
= xgate_apply_operand (operand
, &oper_mask
, bin
,
1144 operand_bit_length
);
1149 operand
= xgate_parse_operand (opcode
, &operand_bit_length
, where
,
1151 bin
= xgate_apply_operand (operand
, &oper_mask
, bin
,
1152 operand_bit_length
);
1156 /* Parse the third register. */
1161 operand
= xgate_parse_operand (opcode
, &operand_bit_length
, where
, &op
,
1163 bin
= xgate_apply_operand (operand
, &oper_mask
, bin
,
1164 operand_bit_length
);
1167 if (opcode
->size
== 2 && fixup_required
)
1169 bfd_putl16 (bin
, frag
);
1171 else if ((opcode
->sh_format
& XG_PCREL
))
1173 /* Write our data to a frag for further processing. */
1174 bfd_putl16 (opcode
->bin_opcode
, frag
);
1178 /* Apply operand mask(s)to bin opcode and write the output. */
1179 /* Since we are done write this frag in xgate BE format. */
1180 number_to_chars_bigendian (frag
, bin
, opcode
->size
);
1187 xgate_parse_operand (struct xgate_opcode
*opcode
,
1193 char *op_constraint
= *op_con
;
1194 unsigned int op_mask
= 0;
1195 unsigned int pp_fix
= 0;
1196 unsigned short max_size
= 0;
1202 switch (*op_constraint
)
1204 case '+': /* Indexed register operand +/- or plain r. */
1205 /* Default to neither inc or dec. */
1209 if (operand
.reg
== REG_NONE
)
1210 as_bad (_(": expected register name r0-r7 ") );
1211 op_mask
= operand
.reg
;
1212 if(operand
.mod
== MOD_POSTINC
)
1214 if(operand
.mod
== MOD_PREDEC
)
1220 case 'r': /* Register operand. */
1221 if (operand
.reg
== REG_NONE
)
1222 as_bad (_(": expected register name r0-r7 "));
1226 op_mask
= operand
.reg
;
1229 case 'i': /* Immediate value or expression expected. */
1230 /* Advance the original format pointer. */
1233 if (ISDIGIT (*op_constraint
))
1235 *bit_width
= (int) *op_constraint
- '0';
1237 else if (*op_constraint
== 'a')
1241 else if (*op_constraint
== 'f')
1245 /* http://tigcc.ticalc.org/doc/gnuasm.html#SEC31 */
1246 if (operand
.exp
.X_op
== O_constant
)
1248 op_mask
= operand
.exp
.X_add_number
;
1249 if (((opcode
->name
[strlen (opcode
->name
) - 1] == 'l') && autoHiLo
)
1250 || operand
.mod
== MOD_LOAD_LOW
)
1254 else if (((opcode
->name
[strlen (opcode
->name
) - 1]) == 'h'
1255 && autoHiLo
) || operand
.mod
== MOD_LOAD_HIGH
)
1260 /* Make sure it fits. */
1261 for (i
= *bit_width
; i
; i
--)
1266 if (op_mask
> max_size
)
1267 as_bad (_(":operand value(%d) too big for constraint"), op_mask
);
1271 /* Should be BFD_RELOC_XGATE_IMM8_LO instead of BFD_RELOC_XGATE_24
1274 if (*op_constraint
== '8')
1276 if (((opcode
->name
[strlen (opcode
->name
) - 1] == 'l')
1277 && autoHiLo
) || operand
.mod
== MOD_LOAD_LOW
)
1279 fix_new_exp (frag_now
, where
, 2, &operand
.exp
, FALSE
,
1280 BFD_RELOC_XGATE_24
);
1282 else if (((opcode
->name
[strlen (opcode
->name
) - 1]) == 'h'
1283 && autoHiLo
) || operand
.mod
== MOD_LOAD_HIGH
)
1285 fix_new_exp (frag_now
, where
, 2, &operand
.exp
, FALSE
,
1286 BFD_RELOC_XGATE_IMM8_HI
);
1290 as_bad (_("you must use a hi/lo directive or 16-bit macro "
1291 "to load a 16-bit value."));
1295 else if (*op_constraint
== '5')
1297 fix_new_exp (frag_now
, where
, 2, &operand
.exp
, FALSE
,
1298 BFD_RELOC_XGATE_IMM5
);
1300 else if (*op_constraint
== '4')
1302 fix_new_exp (frag_now
, where
, 2, &operand
.exp
, FALSE
,
1303 BFD_RELOC_XGATE_IMM4
);
1305 else if (*op_constraint
== '3')
1307 fix_new_exp (frag_now
, where
, 2, &operand
.exp
, FALSE
,
1308 BFD_RELOC_XGATE_IMM3
);
1312 as_bad (_(":unknown relocation constraint size"));
1317 case 'c': /* CCR register expected. */
1319 if (operand
.reg
!= REG_CCR
)
1320 as_bad (_(": expected register name ccr "));
1323 case 'p': /* PC register expected. */
1325 if (operand
.reg
!= REG_PC
)
1326 as_bad (_(": expected register name pc "));
1329 case 'b': /* Branch expected. */
1333 if (operand
.exp
.X_op
!= O_register
)
1335 if (*op_constraint
== '9')
1337 fix_new_exp (frag_now
, where
, 2, &operand
.exp
, TRUE
,
1340 else if (*op_constraint
== 'a')
1342 fix_new_exp (frag_now
, where
, 2, &operand
.exp
, TRUE
,
1348 as_fatal (_("Operand `%x' not recognized in fixup8."), operand
.exp
.X_op
);
1355 as_bad (_("unknown constraint `%c'"), *op_constraint
);