PR binutils/14567
[deliverable/binutils-gdb.git] / gas / config / tc-xgate.c
CommitLineData
f6c1a2d5
NC
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>
5
6 This file is part of GAS, the GNU Assembler.
7
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)
11 any later version.
12
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.
17
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. */
22
23#include "as.h"
24#include "safe-ctype.h"
25#include "subsegs.h"
26#include "opcode/xgate.h"
27#include "dwarf2dbg.h"
28#include "elf/xgate.h"
29
30const char comment_chars[] = ";!";
31const char line_comment_chars[] = "#*";
32const char line_separator_chars[] = "";
33const char EXP_CHARS[] = "eE";
34const char FLT_CHARS[] = "dD";
35
3879925e
SK
36#define SIXTEENTH_BIT 0x8000
37#define N_BITS_IN_WORD 16
38#define MAX_NUM_OPERANDS 3
f6c1a2d5
NC
39
40/* #define STATE_CONDITIONAL_BRANCH (1) */
41#define STATE_PC_RELATIVE (2)
42#define REGISTER_P(ptr) (ptr == 'r')
43#define INCREMENT 01
44#define DECREMENT 02
45#define MAXREGISTER 07
46#define MINREGISTER 00
47
48#define OPTION_MMCU 'm'
49
50/* This macro has no side-effects. */
51#define ENCODE_RELAX(what,length) (((what) << 2) + (length))
52
19f55fe4
SK
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. */
f6c1a2d5
NC
56struct xgate_opcode_handle
57{
58 int number_of_modes;
59 char *name;
60 struct xgate_opcode *opc0[MAX_OPCODES];
61};
62
3879925e
SK
63/* XGATE's registers all are 16-bit general purpose. They are numbered according to the specifications. */
64typedef enum register_id
65{
66 REG_NONE = -1,
67 REG_R0 = 0,
68 REG_R1 = 1,
69 REG_R2 = 2,
70 REG_R3 = 3,
71 REG_R4 = 4,
72 REG_R5 = 5,
73 REG_R6 = 6,
74 REG_R7 = 7,
75 REG_PC = 8,
76 REG_CCR = 9
77} register_id;
78
79/* Operand Modifiers */
80typedef enum op_modifiers
81{
82 MOD_NONE = -1,
83 MOD_POSTINC = 1,
84 MOD_PREDEC = 2,
85 MOD_CONSTANT = 3,
86 MOD_LOAD_HIGH = 4,
87 MOD_LOAD_LOW = 5
88}op_modifiers;
89
90typedef struct s_operand
91{
92 expressionS exp;
93 register_id reg;
94 op_modifiers mod;
95} s_operand;
96
97
f6c1a2d5
NC
98/* LOCAL FUNCTIONS */
99static char *
100xgate_parse_exp (char *, expressionS *);
101static inline char *
102skip_whitespace (char *);
103static void
104get_default_target (void);
105static char *
106extract_word (char *, char *, int);
107static char *
108xgate_new_instruction (int size);
109unsigned short
110xgate_apply_operand (unsigned short, unsigned short *, unsigned short,
111 unsigned char);
f6c1a2d5
NC
112static struct xgate_opcode *
113xgate_find_match (struct xgate_opcode_handle *, int, unsigned int);
114static int
115cmp_opcode (struct xgate_opcode *, struct xgate_opcode *);
f6c1a2d5
NC
116void
117xgate_print_syntax (char *);
118void
119xgate_print_table (void);
3879925e
SK
120unsigned int
121xgate_get_operands (char *, s_operand []);
122static register_id
123reg_name_search (char *);
124op_modifiers
8d8ad4eb 125xgate_determine_modifiers(char **);
3879925e
SK
126
127void
128xgate_scan_operands (struct xgate_opcode *opcode, s_operand []);
129
130static unsigned int
131xgate_parse_operand (struct xgate_opcode *, int *, int where, char **,
132 s_operand);
f6c1a2d5
NC
133
134/* LOCAL DATA */
135static struct hash_control *xgate_hash;
136
137/* Previous opcode. */
138static unsigned int prev = 0;
139
140static unsigned char fixup_required = 0;
141
142/* Used to enable clipping of 16 bit operands into 8 bit constraints. */
8d8ad4eb 143static unsigned char autoHiLo = 0;
f6c1a2d5
NC
144
145static char oper_check;
146static char flag_print_insn_syntax = 0;
147static char flag_print_opcodes = 0;
148
149static int current_architecture;
150static const char *default_cpu;
151
152/* ELF flags to set in the output file header. */
153static int elf_flags = E_XGATE_F64;
154
155/* This table describes how you change sizes for the various types of variable
156 size expressions. This version only supports two kinds. */
157
158/* The fields are:
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. */
163
164relax_typeS md_relax_table[] =
165{
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. */
169 {1, 1, 0, 0},
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)}, */
173 {0, 0, 0, 0}
174};
175
f6c1a2d5
NC
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. */
179const pseudo_typeS md_pseudo_table[] =
180{
181 /* The following pseudo-ops are supported for MRI compatibility. */
182 {0, 0, 0}
183};
184
185const char *md_shortopts = "m:";
186
187struct option md_longopts[] =
188{
189#define OPTION_PRINT_INSN_SYNTAX (OPTION_MD_BASE + 0)
190 { "print-insn-syntax", no_argument, NULL, OPTION_PRINT_INSN_SYNTAX },
191
192#define OPTION_PRINT_OPCODES (OPTION_MD_BASE + 1)
193 { "print-opcodes", no_argument, NULL, OPTION_PRINT_OPCODES },
194
195#define OPTION_GENERATE_EXAMPLE (OPTION_MD_BASE + 2)
196 { "generate-example", no_argument, NULL, OPTION_GENERATE_EXAMPLE },
197
198#define OPTION_MSHORT (OPTION_MD_BASE + 3)
199 { "mshort", no_argument, NULL, OPTION_MSHORT },
200
201#define OPTION_MLONG (OPTION_MD_BASE + 4)
202 { "mlong", no_argument, NULL, OPTION_MLONG },
203
204#define OPTION_MSHORT_DOUBLE (OPTION_MD_BASE + 5)
205 { "mshort-double", no_argument, NULL, OPTION_MSHORT_DOUBLE },
206
207#define OPTION_MLONG_DOUBLE (OPTION_MD_BASE + 6)
208 { "mlong-double", no_argument, NULL, OPTION_MLONG_DOUBLE },
209
210 { NULL, no_argument, NULL, 0 }
211};
212
213size_t md_longopts_size = sizeof(md_longopts);
214
215char *
216md_atof (int type, char *litP, int *sizeP)
217{
218 return ieee_md_atof (type, litP, sizeP, TRUE);
219}
220
221int
222md_parse_option (int c, char *arg)
223{
224 switch (c)
225 {
226 case OPTION_MMCU:
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;
233 else
234 as_bad (_(" architecture variant invalid"));
235 break;
236
237 case OPTION_PRINT_INSN_SYNTAX:
238 flag_print_insn_syntax = 1;
239 break;
240
241 case OPTION_PRINT_OPCODES:
242 flag_print_opcodes = 1;
243 break;
244
245 case OPTION_GENERATE_EXAMPLE:
246 flag_print_opcodes = 2;
247 break;
248
249 case OPTION_MSHORT:
250 elf_flags &= ~E_XGATE_I32;
251 break;
252
253 case OPTION_MLONG:
254 elf_flags |= E_XGATE_I32;
255 break;
256
257 case OPTION_MSHORT_DOUBLE:
258 elf_flags &= ~E_XGATE_F64;
259 break;
260
261 case OPTION_MLONG_DOUBLE:
262 elf_flags |= E_XGATE_F64;
263 break;
264
265 default:
266 return 0;
267 }
268 return 1;
269}
270
271const char *
272xgate_arch_format (void)
273{
274 get_default_target ();
275
276 if (current_architecture & cpuxgate)
277 return "elf32-xgate";
278
279 return "error";
280}
281
282static void
283get_default_target (void)
284{
285 const bfd_target *target;
286 bfd abfd;
287
288 if (current_architecture != 0)
289 return;
290
291 default_cpu = "unknown";
292 target = bfd_find_target (0, &abfd);
293
294 if (target && target->name)
295 {
296 if (strcmp (target->name, "elf32-xgate") == 0)
297 {
298 current_architecture = cpuxgate;
299 default_cpu = "XGATE V1";
300 return;
301 }
302
303 as_bad (_("Default target `%s' is not supported."), target->name);
304 }
305}
306
307void
308md_begin (void)
309{
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;
314 int handle_enum = 0;
19f55fe4 315 int number_of_op_handles = 0;
f6c1a2d5
NC
316 int i, j = 0;
317
318 /* Create a local copy of our opcode table
319 including an extra line for NULL termination. */
320 xgate_op_table = (struct xgate_opcode *)
19f55fe4 321 xmalloc ((xgate_num_opcodes) * sizeof (struct xgate_opcode));
f6c1a2d5
NC
322
323 memset (xgate_op_table, 0,
19f55fe4 324 sizeof(struct xgate_opcode) * (xgate_num_opcodes));
f6c1a2d5
NC
325
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];
329
330 qsort (xgate_op_table, xgate_num_opcodes, sizeof(struct xgate_opcode),
331 (int (*)(const void *, const void *)) cmp_opcode);
332
333 /* Calculate number of handles since this will be
334 smaller than the raw number of opcodes in the table. */
19f55fe4
SK
335 prev_op_name = "";
336 for (xgate_opcode_ptr = xgate_op_table, i = 0; i < xgate_num_opcodes;
337 xgate_opcode_ptr++, i++)
f6c1a2d5 338 {
19f55fe4
SK
339 if (strcmp (prev_op_name, xgate_opcode_ptr->name))
340 number_of_op_handles++;
f6c1a2d5
NC
341 prev_op_name = xgate_opcode_ptr->name;
342 }
343
344 op_handles = (struct xgate_opcode_handle *)
19f55fe4 345 xmalloc (sizeof(struct xgate_opcode_handle) * (number_of_op_handles));
f6c1a2d5 346
19f55fe4 347 /* Insert unique opcode names into hash table, aliasing duplicates. */
f6c1a2d5
NC
348 xgate_hash = hash_new ();
349
19f55fe4 350 prev_op_name = "";
f6c1a2d5 351 for (xgate_opcode_ptr = xgate_op_table, i = 0, j = 0; i < xgate_num_opcodes;
19f55fe4 352 i++, xgate_opcode_ptr++)
f6c1a2d5 353 {
19f55fe4
SK
354 if (!strcmp (prev_op_name, xgate_opcode_ptr->name))
355 {
356 handle_enum++;
357 op_handles[j].opc0[handle_enum] = xgate_opcode_ptr;
358 }
359 else
f6c1a2d5
NC
360 {
361 handle_enum = 0;
362 if (i)
19f55fe4 363 j++;
f6c1a2d5
NC
364 op_handles[j].name = xgate_opcode_ptr->name;
365 op_handles[j].opc0[0] = xgate_opcode_ptr;
19f55fe4
SK
366 hash_insert (xgate_hash, (char *) op_handles[j].name,
367 (char *) &(op_handles[j]));
f6c1a2d5
NC
368 }
369 op_handles[j].number_of_modes = handle_enum;
370 prev_op_name = op_handles[j].name;
371 }
372
f6c1a2d5
NC
373 if (flag_print_opcodes == 1)
374 xgate_print_table ();
375}
376
377void
378xgate_init_after_args (void)
379{
380}
381
382void
383md_show_usage (FILE * stream)
384{
385 get_default_target ();
386
387 fprintf (
388 stream,
389 _("\
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"),
399 default_cpu);
400}
401
402enum bfd_architecture
403xgate_arch (void)
404{
405 get_default_target ();
406 return bfd_arch_xgate;
407}
408
409int
410xgate_mach (void)
411{
412 return 0;
413}
414
415void
416xgate_print_syntax (char *name)
417{
418 int i;
419
420 for (i = 0; i < xgate_num_opcodes; i++)
421 {
422 if (!strcmp (xgate_opcodes[i].name, name))
423 {
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);
f6c1a2d5
NC
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);
452 }
453 }
454}
455
456void
457xgate_print_table (void)
458{
459 int i;
460
461 for (i = 0; i < xgate_num_opcodes; i++)
462 xgate_print_syntax (xgate_opcodes[i].name);
463
464 return;
465}
466
467const char *
468xgate_listing_header (void)
469{
470 if (current_architecture & cpuxgate)
471 return "XGATE GAS ";
472
473 return "ERROR MC9S12X GAS ";
474}
475
476symbolS *
477md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
478{
479 return 0;
480}
481
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. */
484
485valueT
486md_section_align (asection * seg, valueT addr)
487{
488 int align = bfd_get_section_alignment (stdoutput, seg);
489 return ((addr + (1 << align) - 1) & (-1 << align));
490}
491
492void
493md_assemble (char *input_line)
494{
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;
502 char *p = 0;
503
3879925e
SK
504 s_operand new_operands[MAX_NUM_OPERANDS];
505
f6c1a2d5
NC
506 fixup_required = 0;
507 oper_check = 0; /* set error flags */
508 input_line = extract_word (input_line, op_name, sizeof(op_name));
509
510 /* Check to make sure we are not reading a bogus line. */
511 if (!op_name[0])
512 as_bad (_("opcode missing or not found on input line"));
513
514 if (!(opcode_handle = (struct xgate_opcode_handle *) hash_find (xgate_hash,
515 op_name)))
516 {
517 as_bad (_("opcode %s not found in opcode hash table"), op_name);
518 }
519 else
520 {
3879925e
SK
521 /* Parse operands so we can find the proper opcode bin. */
522
523 sh_format = xgate_get_operands(input_line, new_operands);
f6c1a2d5
NC
524
525 opcode = xgate_find_match (opcode_handle, opcode_handle->number_of_modes,
526 sh_format);
527
528 if (!opcode)
529 {
530 as_bad (_("matching operands to opcode "));
531 xgate_print_syntax (opcode_handle->opc0[0]->name);
532 }
533 else if (opcode->size == 2)
534 {
535 /* Size is one word - assemble that native insn. */
3879925e 536 xgate_scan_operands (opcode, new_operands);
f6c1a2d5
NC
537 }
538 else
539 {
540 /* Insn is a simplified instruction - expand it out. */
8d8ad4eb 541 autoHiLo = 1;
f6c1a2d5
NC
542 unsigned int i;
543
544 /* skip past our ';' separator. */
545 for (i = strlen (opcode->constraints), p = opcode->constraints; i > 0;
546 i--, p++)
547 {
548 if (*p == ';')
549 {
550 p++;
551 break;
552 }
553 }
554 input_line = skip_whitespace (input_line);
555 char *macro_inline = input_line;
556
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++)
559 {
560 /* Loop though macro operand list. */
561 input_line = macro_inline; /* Rewind. */
562 p = extract_word (p, op_name, 10);
563
564 if (!(opcode_handle = (struct xgate_opcode_handle *)
565 hash_find (xgate_hash, op_name)))
566 {
567 as_bad (
568 _(": processing macro, real opcode handle not found in hash"));
569 break;
570 }
571 else
572 {
3879925e 573 sh_format = xgate_get_operands(input_line, new_operands);
f6c1a2d5
NC
574 macro_opcode = xgate_find_match (opcode_handle,
575 opcode_handle->number_of_modes, sh_format);
3879925e
SK
576 xgate_scan_operands (macro_opcode, new_operands);
577
f6c1a2d5
NC
578 }
579 }
580 }
581 }
8d8ad4eb 582 autoHiLo = 0;
f6c1a2d5
NC
583 input_line = saved_input_line;
584}
585
586/* Force truly undefined symbols to their maximum size, and generally set up
587 the frag list to be relaxed. */
588
589int
590md_estimate_size_before_relax (fragS *fragp, asection *seg)
591{
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[] =
596 { 0, 2 };
597
598 for (subtype = 0; subtype < ARRAY_SIZE (rlx_state); subtype += 2)
599 {
600 if (fragp->fr_subtype == rlx_state[subtype]
601 && (!S_IS_DEFINED (fragp->fr_symbol)
602 || seg != S_GET_SEGMENT (fragp->fr_symbol)))
603 {
604 fragp->fr_subtype = rlx_state[subtype + 1];
605 break;
606 }
607 }
608
609 if (fragp->fr_subtype >= ARRAY_SIZE (md_relax_table))
610 abort ();
611
612 return md_relax_table[fragp->fr_subtype].rlx_length;
613}
614
615
616/* Relocation, relaxation and frag conversions. */
617
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. */
621
622long
623md_pcrel_from (fixS * fixP)
624{
625 return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
626}
627
628/* If while processing a fixup, a reloc really needs to be created
629 then it is done here. */
630
631arelent *
632tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
633{
634 arelent * reloc;
635
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;
640
641 if (fixp->fx_r_type == 0)
642 {
643 reloc->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_16);
644 }
645 else
646 {
647 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
648 }
649
650 if (reloc->howto == (reloc_howto_type *) NULL)
651 {
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);
655 return NULL;
656 }
657
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;
662 reloc->addend = 0;
663 return reloc;
664}
665
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. */
670
671void
672md_apply_fix (fixS * fixP, valueT * valP, segT seg ATTRIBUTE_UNUSED)
673{
674 char *where;
675 long value = *valP;
676 int opcode = 0;
677 ldiv_t result;
678
679 /* If the fixup is done mark it done so no further symbol resolution will take place. */
680 if (fixP->fx_addsy == (symbolS *) NULL)
681 {
682 fixP->fx_done = 1;
683 }
684
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."));
688
689 where = fixP->fx_frag->fr_literal + fixP->fx_where;
690 opcode = bfd_getl16 (where);
691 int mask = 0;
692
693 switch (fixP->fx_r_type)
694 {
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 */
700 value = result.quot;
701 if (result.rem)
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 */
705 value &= mask;
706 number_to_chars_bigendian (where, (opcode | value), 2);
707 break;
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 */
713 value = result.quot;
714 if (result.rem)
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 */
718 value &= mask;
719 number_to_chars_bigendian (where, (opcode | value), 2);
720 break;
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."));
725 value >>= 8;
726 value &= 0x00ff;
727 bfd_putb16 ((bfd_vma) value | opcode, (void *) where);
728 break;
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."));
734 value &= 0x00ff;
735 bfd_putb16 ((bfd_vma) value | opcode, (void *) where);
736 break;
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);
743 break;
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);
750 break;
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);
757 break;
758 case BFD_RELOC_8:
759 ((bfd_byte *) where)[0] = (bfd_byte) value;
760 break;
761 case BFD_RELOC_32:
762 bfd_putb32 ((bfd_vma) value, (unsigned char *) where);
f6c1a2d5
NC
763 break;
764 case BFD_RELOC_16:
765 bfd_putb16 ((bfd_vma) value, (unsigned char *) where);
766 break;
767 default:
768 as_fatal (_("Line %d: unknown relocation type: 0x%x."), fixP->fx_line,
769 fixP->fx_r_type);
770 break;
771 }
772}
773
774/* See whether we need to force a relocation into the output file. */
775
776int
777tc_xgate_force_relocation (fixS * fixP)
778{
779 if (fixP->fx_r_type == BFD_RELOC_XGATE_RL_GROUP)
780 return 1;
781 return generic_force_reloc (fixP);
782}
783
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
788 used. */
789
790int
791tc_xgate_fix_adjustable (fixS * fixP)
792{
793 switch (fixP->fx_r_type)
794 {
795 /* For the linker relaxation to work correctly, these relocs
796 need to be on the symbol itself. */
797 case BFD_RELOC_16:
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:
802 case BFD_RELOC_32:
803 return 0;
804 default:
805 return 1;
806 }
807}
808
809void
810md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
811 asection * sec ATTRIBUTE_UNUSED,
812 fragS * fragP ATTRIBUTE_UNUSED)
813{
814 as_bad (("md_convert_frag not implemented yet"));
815 abort ();
816}
817
818/* Set the ELF specific flags. */
819
820void
821xgate_elf_final_processing (void)
822{
823 elf_flags |= EF_XGATE_MACH;
824 elf_elfheader (stdoutput)->e_flags &= ~EF_XGATE_ABI;
825 elf_elfheader (stdoutput)->e_flags |= elf_flags;
826}
827
828static inline char *
829skip_whitespace (char *s)
830{
831 while (*s == ' ' || *s == '\t' || *s == '(' || *s == ')')
832 s++;
833
834 return s;
835}
836
837/* Extract a word (continuous alpha-numeric chars) from the input line. */
838
839static char *
840extract_word (char *from, char *to, int limit)
841{
842 char *op_end;
843 int size = 0;
844
845 /* Drop leading whitespace. */
846 from = skip_whitespace (from);
847 *to = 0;
848 /* Find the op code end. */
849 for (op_end = from; *op_end != 0 && is_part_of_name (*op_end);)
850 {
851 to[size++] = *op_end++;
852 if (size + 1 >= limit)
853 break;
854 }
855 to[size] = 0;
856 return op_end;
857}
858
859static char *
860xgate_new_instruction (int size)
861{
862 char *f = frag_more (size);
863 dwarf2_emit_insn (size);
864 return f;
865}
866
867unsigned short
868xgate_apply_operand (unsigned short new_mask,
869 unsigned short *availiable_mask_bits,
870 unsigned short mask,
871 unsigned char n_bits)
872{
873 unsigned short n_shifts;
874 unsigned int n_drop_bits;
875
876 /* Shift until you find an available operand bit "1" and record the number of shifts. */
877 for (n_shifts = 0;
878 !(*availiable_mask_bits & SIXTEENTH_BIT) && n_shifts < 16;
879 n_shifts++)
880 *availiable_mask_bits <<= 1;
881
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);
885 --n_drop_bits)
886 *availiable_mask_bits <<= 1;
887
888 if (n_drop_bits)
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))
892 {
893 oper_check = 1; /* flag operand check as good */
894 }
895 new_mask <<= N_BITS_IN_WORD - (n_shifts + n_bits);
896 mask |= new_mask;
897 return mask;
898}
899
900/* Parse ordinary expression. */
901
902static char *
903xgate_parse_exp (char *s, expressionS * op)
904{
905 input_line_pointer = s;
906 expression(op);
907 if (op->X_op == O_absent)
908 as_bad (_("missing operand"));
909 return input_line_pointer;
910}
911
3879925e
SK
912static int
913cmp_opcode (struct xgate_opcode *op1, struct xgate_opcode *op2)
914{
915 return strcmp (op1->name, op2->name);
916}
917
918static struct xgate_opcode *
919xgate_find_match (struct xgate_opcode_handle *opcode_handle,
920 int numberOfModes,
921 unsigned int sh_format)
922{
923 int i;
f6c1a2d5 924
3879925e
SK
925 if (numberOfModes == 0)
926 return opcode_handle->opc0[0];
927
928 for (i = 0; i <= numberOfModes; i++)
929 if (opcode_handle->opc0[i]->sh_format & sh_format)
930 return opcode_handle->opc0[i];
931
932 return NULL;
933}
934
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. */
938
939int
940xgate_frob_symbol (symbolS *sym)
f6c1a2d5 941{
3879925e
SK
942 asymbol *bfdsym;
943 elf_symbol_type *elfsym;
f6c1a2d5 944
3879925e
SK
945 bfdsym = symbol_get_bfdsym (sym);
946 elfsym = elf_symbol_from (bfd_asymbol_bfd (bfdsym), bfdsym);
f6c1a2d5 947
3879925e 948 gas_assert(elfsym);
f6c1a2d5 949
3879925e
SK
950 /* Mark the symbol as being *from XGATE */
951 elfsym->internal_elf_sym.st_target_internal = 1;
f6c1a2d5 952
3879925e 953 return 0;
f6c1a2d5 954}
f6c1a2d5 955
3879925e
SK
956unsigned int
957xgate_get_operands (char *line, s_operand oprs[])
f6c1a2d5 958{
3879925e
SK
959 int num_operands;
960
961 /* If there are no operands, then it must be inherent. */
962 if (*line == 0 || *line == '\n' || *line == '\r')
963 return XG_INH;
964
965 for (num_operands = 0; strlen (line) && (num_operands < MAX_NUM_OPERANDS);
966 num_operands++)
967 {
968 line = skip_whitespace (line);
969 if (*line == '#')
970 line++;
971
8d8ad4eb 972 oprs[num_operands].mod = xgate_determine_modifiers (&line);
3879925e
SK
973
974 if ((oprs[num_operands].reg = reg_name_search (line)) == REG_NONE)
975 line = xgate_parse_exp (line, &oprs[num_operands].exp);
976
977 /* skip to next operand */
978 while (*line != 0)
979 {
980 if (*line == ',')
981 {
982 line++;
983 break;
984 }
985 line++;
986 }
987 }
988
989 if (num_operands > MAX_NUM_OPERANDS)
990 return 0;
991
992 switch (num_operands)
993 {
994 case 1:
995 if (oprs[0].reg >= REG_R0 && oprs[0].reg <= REG_R7)
996 return XG_R;
997 if (oprs[0].reg == REG_NONE)
998 return XG_I;
999 break;
1000 case 2:
1001 if (oprs[0].reg >= REG_R0 && oprs[0].reg <= REG_R7)
1002 {
1003 if (oprs[1].reg >= REG_R0 && oprs[1].reg <= REG_R7)
1004 return XG_R_R;
1005 if (oprs[1].reg == REG_CCR)
1006 return XG_R_C;
1007 if (oprs[1].reg == REG_PC)
1008 return XG_R_P;
1009 if (oprs[1].reg == REG_NONE)
1010 return XG_R_I;
1011 }
1012 if (oprs[0].reg == REG_CCR)
1013 return XG_C_R;
1014 break;
1015 case 3:
1016 if (oprs[0].reg >= REG_R0 && oprs[0].reg <= REG_R7)
1017 {
1018 if (oprs[1].reg >= REG_R0 && oprs[1].reg <= REG_R7)
1019 {
1020 if (oprs[2].reg >= REG_R0 && oprs[2].reg <= REG_R7)
1021 return XG_R_R_R;
1022 if (oprs[2].reg >= REG_NONE)
1023 return XG_R_R_I;
1024 }
1025 }
1026 break;
1027 default:
1028 as_bad (_("unknown operand format"));
1029 break;
1030 }
1031
1032 return 0;
1033}
1034
1035/* reg_name_search() finds the register number given its name.
1036 Returns the register number or REG_NONE on failure. */
1037static register_id
1038reg_name_search (char *name)
1039{
1040 if (strncasecmp (name, "r0", 2) == 0)
1041 return REG_R0;
1042 if (strncasecmp (name, "r1", 2) == 0)
1043 return REG_R1;
1044 if (strncasecmp (name, "r2", 2) == 0)
1045 return REG_R2;
1046 if (strncasecmp (name, "r3", 2) == 0)
1047 return REG_R3;
1048 if (strncasecmp (name, "r4", 2) == 0)
1049 return REG_R4;
1050 if (strncasecmp (name, "r5", 2) == 0)
1051 return REG_R5;
1052 if (strncasecmp (name, "r6", 2) == 0)
1053 return REG_R6;
1054 if (strncasecmp (name, "r7", 2) == 0)
1055 return REG_R7;
1056 if (strncasecmp (name, "pc", 2) == 0)
1057 return REG_PC;
1058 if (strncasecmp (name, "ccr", 3) == 0)
1059 return REG_CCR;
1060 return REG_NONE;
1061}
1062
8d8ad4eb
SK
1063/* Parse operand modifiers such as inc/dec/hi/low. */
1064
3879925e 1065op_modifiers
8d8ad4eb 1066xgate_determine_modifiers(char **line)
3879925e
SK
1067{
1068 char *local_line = line[0];
1069
1070 if (strncasecmp (local_line, "%hi", 3) == 0)
1071 {
1072 *line += 3;
1073 return MOD_LOAD_HIGH;
1074 }
1075 if (strncasecmp (local_line, "%lo", 3) == 0)
1076 {
1077 *line += 3;
1078 return MOD_LOAD_LOW;
1079 }
3879925e 1080 if (*(local_line + 2) == '+')
8d8ad4eb 1081 return MOD_POSTINC;
3879925e
SK
1082 if (strncasecmp (local_line, "-r", 2) == 0)
1083 {
1084 *line += 1;
1085 return MOD_PREDEC;
8d8ad4eb 1086 }
3879925e 1087 return MOD_NONE;
f6c1a2d5
NC
1088}
1089
1090/* Parse instruction operands. */
1091
1092void
3879925e 1093xgate_scan_operands (struct xgate_opcode *opcode, s_operand oprs[])
f6c1a2d5
NC
1094{
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;
f6c1a2d5
NC
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;
1104 int i = 0;
1105 char c = 0;
1106
1107 /* Generate available operand bits mask. */
1108 for (i = 0; (c = opcode->format[i]); i++)
1109 {
1110 if (ISDIGIT (c) || (c == 's'))
1111 {
1112 oper_mask <<= 1;
1113 }
1114 else
1115 {
1116 oper_mask <<= 1;
1117 oper_mask += 1;
1118 n_operand_bits++;
1119 }
1120 }
1121
f6c1a2d5
NC
1122 /* Parse first operand. */
1123 if (*op)
1124 {
1125 if (*op == '=')
1126 {
1127 first_operand_equals_second = 1;
1128 ++op;
1129 }
3879925e 1130 operand = xgate_parse_operand (opcode, &operand_bit_length, where, &op, oprs[0]);
f6c1a2d5
NC
1131 ++op;
1132 bin = xgate_apply_operand (operand, &oper_mask, bin, operand_bit_length);
3879925e
SK
1133
1134 if(first_operand_equals_second)
1135 bin = xgate_apply_operand (operand, &oper_mask, bin, operand_bit_length);
f6c1a2d5
NC
1136 /* Parse second operand. */
1137 if (*op)
1138 {
1139 if (*op == ',')
1140 ++op;
3879925e 1141 if (first_operand_equals_second)
f6c1a2d5 1142 {
3879925e
SK
1143 bin = xgate_apply_operand (operand, &oper_mask, bin,
1144 operand_bit_length);
1145 ++op;
f6c1a2d5
NC
1146 }
1147 else
1148 {
3879925e
SK
1149 operand = xgate_parse_operand (opcode, &operand_bit_length, where,
1150 &op, oprs[1]);
f6c1a2d5
NC
1151 bin = xgate_apply_operand (operand, &oper_mask, bin,
1152 operand_bit_length);
1153 ++op;
1154 }
1155 }
f6c1a2d5
NC
1156 /* Parse the third register. */
1157 if (*op)
1158 {
1159 if (*op == ',')
1160 ++op;
3879925e
SK
1161 operand = xgate_parse_operand (opcode, &operand_bit_length, where, &op,
1162 oprs[2]);
f6c1a2d5
NC
1163 bin = xgate_apply_operand (operand, &oper_mask, bin,
1164 operand_bit_length);
1165 }
1166 }
1167 if (opcode->size == 2 && fixup_required)
1168 {
1169 bfd_putl16 (bin, frag);
1170 }
1171 else if ((opcode->sh_format & XG_PCREL))
1172 {
1173 /* Write our data to a frag for further processing. */
3879925e 1174 bfd_putl16 (opcode->bin_opcode, frag);
f6c1a2d5
NC
1175 }
1176 else
1177 {
1178 /* Apply operand mask(s)to bin opcode and write the output. */
1179 /* Since we are done write this frag in xgate BE format. */
3879925e 1180 number_to_chars_bigendian (frag, bin, opcode->size);
f6c1a2d5
NC
1181 }
1182 prev = bin;
f6c1a2d5
NC
1183 return;
1184}
1185
1186static unsigned int
3879925e
SK
1187xgate_parse_operand (struct xgate_opcode *opcode,
1188 int *bit_width,
1189 int where,
1190 char **op_con,
8d8ad4eb 1191 s_operand operand)
f6c1a2d5 1192{
f6c1a2d5
NC
1193 char *op_constraint = *op_con;
1194 unsigned int op_mask = 0;
f6c1a2d5
NC
1195 unsigned int pp_fix = 0;
1196 unsigned short max_size = 0;
1197 int i;
1198
1199 *bit_width = 0;
1200 /* Reset. */
1201
1202 switch (*op_constraint)
1203 {
1204 case '+': /* Indexed register operand +/- or plain r. */
f6c1a2d5
NC
1205 /* Default to neither inc or dec. */
1206 pp_fix = 0;
1207 *bit_width = 5;
3879925e 1208
8d8ad4eb 1209 if (operand.reg == REG_NONE)
3879925e 1210 as_bad (_(": expected register name r0-r7 ") );
8d8ad4eb
SK
1211 op_mask = operand.reg;
1212 if(operand.mod == MOD_POSTINC)
3879925e 1213 pp_fix = INCREMENT;
8d8ad4eb 1214 if(operand.mod == MOD_PREDEC)
3879925e 1215 pp_fix = DECREMENT;
f6c1a2d5
NC
1216 op_mask <<= 2;
1217 op_mask |= pp_fix;
1218 break;
1219
1220 case 'r': /* Register operand. */
8d8ad4eb 1221 if (operand.reg == REG_NONE)
3879925e
SK
1222 as_bad (_(": expected register name r0-r7 "));
1223
1224 *bit_width = 3;
1225
8d8ad4eb 1226 op_mask = operand.reg;
f6c1a2d5
NC
1227 break;
1228
1229 case 'i': /* Immediate value or expression expected. */
1230 /* Advance the original format pointer. */
1231 (*op_con)++;
1232 op_constraint++;
1233 if (ISDIGIT (*op_constraint))
3879925e
SK
1234 {
1235 *bit_width = (int) *op_constraint - '0';
1236 }
f6c1a2d5 1237 else if (*op_constraint == 'a')
3879925e
SK
1238 {
1239 *bit_width = 0x0A;
1240 }
f6c1a2d5 1241 else if (*op_constraint == 'f')
3879925e
SK
1242 {
1243 *bit_width = 0x0F;
1244 }
f6c1a2d5 1245 /* http://tigcc.ticalc.org/doc/gnuasm.html#SEC31 */
8d8ad4eb 1246 if (operand.exp.X_op == O_constant)
3879925e 1247 {
8d8ad4eb
SK
1248 op_mask = operand.exp.X_add_number;
1249 if (((opcode->name[strlen (opcode->name) - 1] == 'l') && autoHiLo)
1250 || operand.mod == MOD_LOAD_LOW)
3879925e
SK
1251 {
1252 op_mask &= 0x00FF;
1253 }
8d8ad4eb
SK
1254 else if (((opcode->name[strlen (opcode->name) - 1]) == 'h'
1255 && autoHiLo) || operand.mod == MOD_LOAD_HIGH)
3879925e
SK
1256 {
1257 op_mask >>= 8;
1258 }
1259
1260 /* Make sure it fits. */
1261 for (i = *bit_width; i; i--)
1262 {
1263 max_size <<= 1;
1264 max_size += 1;
1265 }
1266 if (op_mask > max_size)
1267 as_bad (_(":operand value(%d) too big for constraint"), op_mask);
1268 }
f6c1a2d5 1269 else
3879925e 1270 {
8d8ad4eb
SK
1271 /* Should be BFD_RELOC_XGATE_IMM8_LO instead of BFD_RELOC_XGATE_24
1272 TODO fix. */
3879925e
SK
1273 fixup_required = 1;
1274 if (*op_constraint == '8')
1275 {
8d8ad4eb
SK
1276 if (((opcode->name[strlen (opcode->name) - 1] == 'l')
1277 && autoHiLo) || operand.mod == MOD_LOAD_LOW)
3879925e 1278 {
9798e45d
SK
1279 fix_new_exp (frag_now, where, 2, &operand.exp, FALSE,
1280 BFD_RELOC_XGATE_24);
3879925e 1281 }
8d8ad4eb
SK
1282 else if (((opcode->name[strlen (opcode->name) - 1]) == 'h'
1283 && autoHiLo) || operand.mod == MOD_LOAD_HIGH )
3879925e 1284 {
9798e45d
SK
1285 fix_new_exp (frag_now, where, 2, &operand.exp, FALSE,
1286 BFD_RELOC_XGATE_IMM8_HI);
3879925e 1287 }
8d8ad4eb
SK
1288 else
1289 {
1290 as_bad (_("you must use a hi/lo directive or 16-bit macro "
1291 "to load a 16-bit value."));
1292 break;
1293 }
3879925e
SK
1294 }
1295 else if (*op_constraint == '5')
1296 {
9798e45d
SK
1297 fix_new_exp (frag_now, where, 2, &operand.exp, FALSE,
1298 BFD_RELOC_XGATE_IMM5);
3879925e
SK
1299 }
1300 else if (*op_constraint == '4')
1301 {
9798e45d
SK
1302 fix_new_exp (frag_now, where, 2, &operand.exp, FALSE,
1303 BFD_RELOC_XGATE_IMM4);
3879925e
SK
1304 }
1305 else if (*op_constraint == '3')
1306 {
9798e45d
SK
1307 fix_new_exp (frag_now, where, 2, &operand.exp, FALSE,
1308 BFD_RELOC_XGATE_IMM3);
f6c1a2d5
NC
1309 }
1310 else
1311 {
1312 as_bad (_(":unknown relocation constraint size"));
1313 }
1314 }
8d8ad4eb 1315 break;
f6c1a2d5
NC
1316
1317 case 'c': /* CCR register expected. */
3879925e 1318 *bit_width = 0;
8d8ad4eb 1319 if (operand.reg != REG_CCR)
3879925e 1320 as_bad (_(": expected register name ccr "));
8d8ad4eb 1321 break;
f6c1a2d5
NC
1322
1323 case 'p': /* PC register expected. */
3879925e 1324 *bit_width = 0;
8d8ad4eb 1325 if (operand.reg != REG_PC)
3879925e 1326 as_bad (_(": expected register name pc "));
f6c1a2d5
NC
1327 break;
1328
1329 case 'b': /* Branch expected. */
f6c1a2d5
NC
1330 (*op_con)++;
1331 op_constraint++;
f6c1a2d5 1332
8d8ad4eb 1333 if (operand.exp.X_op != O_register)
f6c1a2d5 1334 {
3879925e 1335 if (*op_constraint == '9')
f6c1a2d5 1336 {
9798e45d
SK
1337 fix_new_exp (frag_now, where, 2, &operand.exp, TRUE,
1338 R_XGATE_PCREL_9);
f6c1a2d5 1339 }
3879925e 1340 else if (*op_constraint == 'a')
f6c1a2d5 1341 {
9798e45d
SK
1342 fix_new_exp (frag_now, where, 2, &operand.exp, TRUE,
1343 R_XGATE_PCREL_10);
f6c1a2d5
NC
1344 }
1345 }
3879925e 1346 else
f6c1a2d5 1347 {
8d8ad4eb 1348 as_fatal (_("Operand `%x' not recognized in fixup8."), operand.exp.X_op);
f6c1a2d5 1349 }
3879925e
SK
1350 break;
1351 case '?':
1352 break;
fe540416 1353
3879925e
SK
1354 default:
1355 as_bad (_("unknown constraint `%c'"), *op_constraint);
1356 break;
1357 }
1358 return op_mask;
fe540416 1359}
This page took 0.118239 seconds and 4 git commands to generate.