2012-11-09 Nick Clifton <nickc@redhat.com>
[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
234fa27c
AM
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
234fa27c
AM
63/* XGATE's registers all are 16-bit general purpose.
64 They are numbered according to the specifications. */
3879925e
SK
65typedef enum register_id
66{
67 REG_NONE = -1,
68 REG_R0 = 0,
69 REG_R1 = 1,
70 REG_R2 = 2,
71 REG_R3 = 3,
72 REG_R4 = 4,
73 REG_R5 = 5,
74 REG_R6 = 6,
75 REG_R7 = 7,
76 REG_PC = 8,
77 REG_CCR = 9
78} register_id;
79
80/* Operand Modifiers */
81typedef enum op_modifiers
82{
83 MOD_NONE = -1,
84 MOD_POSTINC = 1,
85 MOD_PREDEC = 2,
86 MOD_CONSTANT = 3,
87 MOD_LOAD_HIGH = 4,
88 MOD_LOAD_LOW = 5
89}op_modifiers;
90
91typedef struct s_operand
92{
93 expressionS exp;
94 register_id reg;
95 op_modifiers mod;
96} s_operand;
97
98
234fa27c
AM
99/* Forward declarations. */
100static inline char *skip_whitespace (char *);
101static void get_default_target (void);
102static char *extract_word (char *, char *, int);
103static struct xgate_opcode *xgate_find_match (struct xgate_opcode_handle *,
104 int, unsigned int);
105static int cmp_opcode (struct xgate_opcode *, struct xgate_opcode *);
106static void xgate_print_table (void);
107static unsigned int xgate_get_operands (char *, s_operand []);
108static register_id reg_name_search (char *);
109static op_modifiers xgate_determine_modifiers(char **);
110static void xgate_scan_operands (struct xgate_opcode *opcode, s_operand []);
111static unsigned int xgate_parse_operand (struct xgate_opcode *, int *, int,
112 char **, s_operand);
f6c1a2d5 113
f6c1a2d5
NC
114static struct hash_control *xgate_hash;
115
116/* Previous opcode. */
117static unsigned int prev = 0;
118
119static unsigned char fixup_required = 0;
120
121/* Used to enable clipping of 16 bit operands into 8 bit constraints. */
234fa27c 122static unsigned char autoHiLo = 0;
f6c1a2d5
NC
123
124static char oper_check;
125static char flag_print_insn_syntax = 0;
126static char flag_print_opcodes = 0;
127
128static int current_architecture;
129static const char *default_cpu;
130
131/* ELF flags to set in the output file header. */
132static int elf_flags = E_XGATE_F64;
133
134/* This table describes how you change sizes for the various types of variable
135 size expressions. This version only supports two kinds. */
136
137/* The fields are:
138 How far Forward this mode will reach.
139 How far Backward this mode will reach.
140 How many bytes this mode will add to the size of the frag.
141 Which mode to go to if the offset won't fit in this one. */
142
143relax_typeS md_relax_table[] =
144{
145 {1, 1, 0, 0}, /* First entries aren't used. */
146 {1, 1, 0, 0}, /* For no good reason except. */
147 {1, 1, 0, 0}, /* that the VAX doesn't either. */
148 {1, 1, 0, 0},
149 /* XGATE 9 and 10 bit pc rel todo complete and test */
150/*{(511), (-512), 0, ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD)},
151 {(1023), (-1024), 0, ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD)}, */
152 {0, 0, 0, 0}
153};
154
f6c1a2d5
NC
155/* This table describes all the machine specific pseudo-ops the assembler
156 has to support. The fields are: pseudo-op name without dot function to
157 call to execute this pseudo-op Integer arg to pass to the function. */
158const pseudo_typeS md_pseudo_table[] =
159{
160 /* The following pseudo-ops are supported for MRI compatibility. */
161 {0, 0, 0}
162};
163
164const char *md_shortopts = "m:";
165
166struct option md_longopts[] =
167{
168#define OPTION_PRINT_INSN_SYNTAX (OPTION_MD_BASE + 0)
169 { "print-insn-syntax", no_argument, NULL, OPTION_PRINT_INSN_SYNTAX },
170
171#define OPTION_PRINT_OPCODES (OPTION_MD_BASE + 1)
172 { "print-opcodes", no_argument, NULL, OPTION_PRINT_OPCODES },
173
174#define OPTION_GENERATE_EXAMPLE (OPTION_MD_BASE + 2)
175 { "generate-example", no_argument, NULL, OPTION_GENERATE_EXAMPLE },
176
177#define OPTION_MSHORT (OPTION_MD_BASE + 3)
178 { "mshort", no_argument, NULL, OPTION_MSHORT },
179
180#define OPTION_MLONG (OPTION_MD_BASE + 4)
181 { "mlong", no_argument, NULL, OPTION_MLONG },
182
183#define OPTION_MSHORT_DOUBLE (OPTION_MD_BASE + 5)
184 { "mshort-double", no_argument, NULL, OPTION_MSHORT_DOUBLE },
185
186#define OPTION_MLONG_DOUBLE (OPTION_MD_BASE + 6)
187 { "mlong-double", no_argument, NULL, OPTION_MLONG_DOUBLE },
188
189 { NULL, no_argument, NULL, 0 }
190};
191
192size_t md_longopts_size = sizeof(md_longopts);
193
194char *
195md_atof (int type, char *litP, int *sizeP)
196{
197 return ieee_md_atof (type, litP, sizeP, TRUE);
198}
199
200int
201md_parse_option (int c, char *arg)
202{
203 switch (c)
204 {
205 case OPTION_MMCU:
206 if (strcasecmp (arg, "v1") == 0)
207 current_architecture = XGATE_V1;
208 else if (strcasecmp (arg, "v2") == 0)
209 current_architecture = XGATE_V2;
210 else if (strcasecmp (arg, "v3") == 0)
211 current_architecture = XGATE_V3;
212 else
213 as_bad (_(" architecture variant invalid"));
214 break;
215
216 case OPTION_PRINT_INSN_SYNTAX:
217 flag_print_insn_syntax = 1;
218 break;
219
220 case OPTION_PRINT_OPCODES:
221 flag_print_opcodes = 1;
222 break;
223
224 case OPTION_GENERATE_EXAMPLE:
225 flag_print_opcodes = 2;
226 break;
227
228 case OPTION_MSHORT:
229 elf_flags &= ~E_XGATE_I32;
230 break;
231
232 case OPTION_MLONG:
233 elf_flags |= E_XGATE_I32;
234 break;
235
236 case OPTION_MSHORT_DOUBLE:
237 elf_flags &= ~E_XGATE_F64;
238 break;
239
240 case OPTION_MLONG_DOUBLE:
241 elf_flags |= E_XGATE_F64;
242 break;
243
244 default:
245 return 0;
246 }
247 return 1;
248}
249
250const char *
251xgate_arch_format (void)
252{
253 get_default_target ();
254
255 if (current_architecture & cpuxgate)
256 return "elf32-xgate";
257
258 return "error";
259}
260
261static void
262get_default_target (void)
263{
264 const bfd_target *target;
265 bfd abfd;
266
267 if (current_architecture != 0)
268 return;
269
270 default_cpu = "unknown";
271 target = bfd_find_target (0, &abfd);
272
273 if (target && target->name)
274 {
275 if (strcmp (target->name, "elf32-xgate") == 0)
234fa27c
AM
276 {
277 current_architecture = cpuxgate;
278 default_cpu = "XGATE V1";
279 return;
280 }
f6c1a2d5
NC
281
282 as_bad (_("Default target `%s' is not supported."), target->name);
283 }
284}
285
286void
287md_begin (void)
288{
289 struct xgate_opcode *xgate_opcode_ptr = NULL;
290 struct xgate_opcode *xgate_op_table = NULL;
291 struct xgate_opcode_handle *op_handles = 0;
292 char *prev_op_name = 0;
293 int handle_enum = 0;
19f55fe4 294 int number_of_op_handles = 0;
f6c1a2d5
NC
295 int i, j = 0;
296
297 /* Create a local copy of our opcode table
298 including an extra line for NULL termination. */
299 xgate_op_table = (struct xgate_opcode *)
19f55fe4 300 xmalloc ((xgate_num_opcodes) * sizeof (struct xgate_opcode));
f6c1a2d5
NC
301
302 memset (xgate_op_table, 0,
19f55fe4 303 sizeof(struct xgate_opcode) * (xgate_num_opcodes));
f6c1a2d5
NC
304
305 for (xgate_opcode_ptr = (struct xgate_opcode*) xgate_opcodes, i = 0;
234fa27c 306 i < xgate_num_opcodes; i++)
f6c1a2d5
NC
307 xgate_op_table[i] = xgate_opcode_ptr[i];
308
309 qsort (xgate_op_table, xgate_num_opcodes, sizeof(struct xgate_opcode),
310 (int (*)(const void *, const void *)) cmp_opcode);
311
312 /* Calculate number of handles since this will be
313 smaller than the raw number of opcodes in the table. */
19f55fe4
SK
314 prev_op_name = "";
315 for (xgate_opcode_ptr = xgate_op_table, i = 0; i < xgate_num_opcodes;
234fa27c 316 xgate_opcode_ptr++, i++)
f6c1a2d5 317 {
19f55fe4 318 if (strcmp (prev_op_name, xgate_opcode_ptr->name))
234fa27c 319 number_of_op_handles++;
f6c1a2d5
NC
320 prev_op_name = xgate_opcode_ptr->name;
321 }
322
323 op_handles = (struct xgate_opcode_handle *)
19f55fe4 324 xmalloc (sizeof(struct xgate_opcode_handle) * (number_of_op_handles));
f6c1a2d5 325
19f55fe4 326 /* Insert unique opcode names into hash table, aliasing duplicates. */
f6c1a2d5
NC
327 xgate_hash = hash_new ();
328
19f55fe4 329 prev_op_name = "";
f6c1a2d5 330 for (xgate_opcode_ptr = xgate_op_table, i = 0, j = 0; i < xgate_num_opcodes;
234fa27c 331 i++, xgate_opcode_ptr++)
f6c1a2d5 332 {
19f55fe4 333 if (!strcmp (prev_op_name, xgate_opcode_ptr->name))
234fa27c
AM
334 {
335 handle_enum++;
336 op_handles[j].opc0[handle_enum] = xgate_opcode_ptr;
337 }
19f55fe4 338 else
234fa27c
AM
339 {
340 handle_enum = 0;
341 if (i)
342 j++;
343 op_handles[j].name = xgate_opcode_ptr->name;
344 op_handles[j].opc0[0] = xgate_opcode_ptr;
345 hash_insert (xgate_hash, (char *) op_handles[j].name,
346 (char *) &(op_handles[j]));
347 }
f6c1a2d5
NC
348 op_handles[j].number_of_modes = handle_enum;
349 prev_op_name = op_handles[j].name;
350 }
351
f6c1a2d5
NC
352 if (flag_print_opcodes == 1)
353 xgate_print_table ();
354}
355
356void
357xgate_init_after_args (void)
358{
359}
360
361void
362md_show_usage (FILE * stream)
363{
364 get_default_target ();
365
234fa27c 366 fprintf (stream,
f6c1a2d5 367 _("\
234fa27c
AM
368Freescale XGATE co-processor options:\n\
369 -mshort use 16-bit int ABI (default)\n\
370 -mlong use 32-bit int ABI\n\
371 -mshort-double use 32-bit double ABI\n\
372 -mlong-double use 64-bit double ABI (default)\n\
373 --mxgate specify the processor variant[default %s]\n\
374 --print-insn-syntax print the syntax of instruction in case of error\n\
375 --print-opcodes print the list of instructions with syntax\n\
376 --generate-example generate an example of each instruction"),
f6c1a2d5
NC
377 default_cpu);
378}
379
380enum bfd_architecture
381xgate_arch (void)
382{
383 get_default_target ();
384 return bfd_arch_xgate;
385}
386
387int
388xgate_mach (void)
389{
390 return 0;
391}
392
234fa27c 393static void
f6c1a2d5
NC
394xgate_print_syntax (char *name)
395{
396 int i;
397
398 for (i = 0; i < xgate_num_opcodes; i++)
399 {
400 if (!strcmp (xgate_opcodes[i].name, name))
234fa27c
AM
401 {
402 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IDR))
403 printf ("\tFormat is %s\tRx, Rx, Rx+|-Rx|Rx\n",
f6c1a2d5 404 xgate_opcodes[i].name);
234fa27c
AM
405 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_INH))
406 printf ("\tFormat is %s\n", xgate_opcodes[i].name);
407 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_TRI))
408 printf ("\tFormat is %s\tRx, Rx, Rx\n", xgate_opcodes[i].name);
409 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_DYA))
410 printf ("\tFormat is %s\tRx, Rx\n", xgate_opcodes[i].name);
411 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM3))
412 printf ("\tFormat is %s\t<3-bit value>\n", xgate_opcodes[i].name);
413 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM4))
414 printf ("\tFormat is %s\t<4 -bit value>\n", xgate_opcodes[i].name);
415 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM8))
416 printf ("\tFormat is %s\tRx, <8-bit value>\n",
f6c1a2d5 417 xgate_opcodes[i].name);
234fa27c
AM
418 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM16))
419 printf ("\tFormat is %s\tRx, <16-bit value>\n",
f6c1a2d5 420 xgate_opcodes[i].name);
234fa27c
AM
421 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_MON_R_C))
422 printf ("\tFormat is %s\tRx, CCR\n", xgate_opcodes[i].name);
423 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_MON_C_R))
424 printf ("\tFormat is %s\tCCR, Rx\n", xgate_opcodes[i].name);
425 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_MON_R_P))
426 printf ("\tFormat is %s\tRx, PC\n", xgate_opcodes[i].name);
427 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM16mLDW))
428 printf ("\tFormat is %s\tRx, <16-bit value>\n",
f6c1a2d5 429 xgate_opcodes[i].name);
234fa27c 430 }
f6c1a2d5
NC
431 }
432}
433
234fa27c 434static void
f6c1a2d5
NC
435xgate_print_table (void)
436{
437 int i;
438
439 for (i = 0; i < xgate_num_opcodes; i++)
440 xgate_print_syntax (xgate_opcodes[i].name);
441
442 return;
443}
444
445const char *
446xgate_listing_header (void)
447{
448 if (current_architecture & cpuxgate)
449 return "XGATE GAS ";
450
451 return "ERROR MC9S12X GAS ";
452}
453
454symbolS *
455md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
456{
457 return 0;
458}
459
460/* GAS will call this function for each section at the end of the assembly,
461 to permit the CPU backend to adjust the alignment of a section. */
462
463valueT
464md_section_align (asection * seg, valueT addr)
465{
466 int align = bfd_get_section_alignment (stdoutput, seg);
467 return ((addr + (1 << align) - 1) & (-1 << align));
468}
469
470void
471md_assemble (char *input_line)
472{
473 struct xgate_opcode *opcode = 0;
474 struct xgate_opcode *macro_opcode = 0;
475 struct xgate_opcode_handle *opcode_handle = 0;
476 /* Caller expects it to be returned as it was passed. */
477 char *saved_input_line = input_line;
478 char op_name[9] = { 0 };
479 unsigned int sh_format = 0;
480 char *p = 0;
481
3879925e
SK
482 s_operand new_operands[MAX_NUM_OPERANDS];
483
f6c1a2d5
NC
484 fixup_required = 0;
485 oper_check = 0; /* set error flags */
486 input_line = extract_word (input_line, op_name, sizeof(op_name));
487
488 /* Check to make sure we are not reading a bogus line. */
489 if (!op_name[0])
490 as_bad (_("opcode missing or not found on input line"));
491
492 if (!(opcode_handle = (struct xgate_opcode_handle *) hash_find (xgate_hash,
234fa27c 493 op_name)))
f6c1a2d5
NC
494 {
495 as_bad (_("opcode %s not found in opcode hash table"), op_name);
496 }
497 else
498 {
3879925e
SK
499 /* Parse operands so we can find the proper opcode bin. */
500
501 sh_format = xgate_get_operands(input_line, new_operands);
f6c1a2d5
NC
502
503 opcode = xgate_find_match (opcode_handle, opcode_handle->number_of_modes,
234fa27c 504 sh_format);
f6c1a2d5
NC
505
506 if (!opcode)
234fa27c
AM
507 {
508 as_bad (_("matching operands to opcode "));
509 xgate_print_syntax (opcode_handle->opc0[0]->name);
510 }
f6c1a2d5 511 else if (opcode->size == 2)
234fa27c 512 {
f6c1a2d5 513 /* Size is one word - assemble that native insn. */
234fa27c
AM
514 xgate_scan_operands (opcode, new_operands);
515 }
f6c1a2d5 516 else
234fa27c 517 {
f6c1a2d5 518 /* Insn is a simplified instruction - expand it out. */
234fa27c
AM
519 autoHiLo = 1;
520 unsigned int i;
521
522 /* skip past our ';' separator. */
523 for (i = strlen (opcode->constraints), p = opcode->constraints; i > 0;
524 i--, p++)
525 {
526 if (*p == ';')
527 {
528 p++;
529 break;
530 }
531 }
532 input_line = skip_whitespace (input_line);
533 char *macro_inline = input_line;
534
535 /* Loop though the macro's opcode list and apply operands to
536 each real opcode. */
537 for (i = 0; *p && i < (opcode->size / 2); i++)
538 {
f6c1a2d5 539 /* Loop though macro operand list. */
234fa27c
AM
540 input_line = macro_inline; /* Rewind. */
541 p = extract_word (p, op_name, 10);
f6c1a2d5 542
234fa27c 543 if (!(opcode_handle = (struct xgate_opcode_handle *)
f6c1a2d5 544 hash_find (xgate_hash, op_name)))
234fa27c
AM
545 {
546 as_bad (_(": processing macro, real opcode handle"
547 " not found in hash"));
548 break;
549 }
550 else
551 {
552 sh_format = xgate_get_operands(input_line, new_operands);
553 macro_opcode
554 = xgate_find_match (opcode_handle,
555 opcode_handle->number_of_modes,
556 sh_format);
557 xgate_scan_operands (macro_opcode, new_operands);
558
559 }
560 }
561 }
f6c1a2d5 562 }
8d8ad4eb 563 autoHiLo = 0;
f6c1a2d5
NC
564 input_line = saved_input_line;
565}
566
567/* Force truly undefined symbols to their maximum size, and generally set up
568 the frag list to be relaxed. */
569
570int
571md_estimate_size_before_relax (fragS *fragp, asection *seg)
572{
573 /* If symbol is undefined or located in a different section,
574 select the largest supported relocation. */
575 relax_substateT subtype;
234fa27c 576 relax_substateT rlx_state[] = { 0, 2 };
f6c1a2d5
NC
577
578 for (subtype = 0; subtype < ARRAY_SIZE (rlx_state); subtype += 2)
579 {
580 if (fragp->fr_subtype == rlx_state[subtype]
234fa27c
AM
581 && (!S_IS_DEFINED (fragp->fr_symbol)
582 || seg != S_GET_SEGMENT (fragp->fr_symbol)))
583 {
584 fragp->fr_subtype = rlx_state[subtype + 1];
585 break;
586 }
f6c1a2d5
NC
587 }
588
589 if (fragp->fr_subtype >= ARRAY_SIZE (md_relax_table))
590 abort ();
591
592 return md_relax_table[fragp->fr_subtype].rlx_length;
593}
594
595
596/* Relocation, relaxation and frag conversions. */
597
598/* PC-relative offsets are relative to the start of the
599 next instruction. That is, the address of the offset, plus its
600 size, since the offset is always the last part of the insn. */
601
602long
603md_pcrel_from (fixS * fixP)
604{
605 return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
606}
607
608/* If while processing a fixup, a reloc really needs to be created
609 then it is done here. */
610
611arelent *
612tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
613{
614 arelent * reloc;
615
616 reloc = (arelent *) xmalloc (sizeof(arelent));
617 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof(asymbol *));
618 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
619 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
620
621 if (fixp->fx_r_type == 0)
234fa27c 622 reloc->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_16);
f6c1a2d5 623 else
234fa27c 624 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
f6c1a2d5
NC
625
626 if (reloc->howto == (reloc_howto_type *) NULL)
627 {
628 as_bad_where (fixp->fx_file, fixp->fx_line, _
234fa27c
AM
629 ("Relocation %d is not supported by object file format."),
630 (int) fixp->fx_r_type);
f6c1a2d5
NC
631 return NULL;
632 }
633
634 /* Since we use Rel instead of Rela, encode the vtable entry to be
635 used in the relocation's section offset. */
636 if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
637 reloc->address = fixp->fx_offset;
638 reloc->addend = 0;
639 return reloc;
640}
641
642/* Patch the instruction with the resolved operand. Elf relocation
643 info will also be generated to take care of linker/loader fixups.
644 The XGATE addresses only 16-bit addresses.The BFD_RELOC_32 is necessary
645 for the support of --gstabs. */
646
647void
648md_apply_fix (fixS * fixP, valueT * valP, segT seg ATTRIBUTE_UNUSED)
649{
650 char *where;
651 long value = *valP;
652 int opcode = 0;
653 ldiv_t result;
654
234fa27c
AM
655 /* If the fixup is done mark it done so no further symbol resolution
656 will take place. */
f6c1a2d5 657 if (fixP->fx_addsy == (symbolS *) NULL)
234fa27c 658 fixP->fx_done = 1;
f6c1a2d5
NC
659
660 /* We don't actually support subtracting a symbol. */
661 if (fixP->fx_subsy != (symbolS *) NULL)
662 as_bad_where (fixP->fx_file, fixP->fx_line, _("Expression too complex."));
663
664 where = fixP->fx_frag->fr_literal + fixP->fx_where;
665 opcode = bfd_getl16 (where);
666 int mask = 0;
667
668 switch (fixP->fx_r_type)
669 {
670 case R_XGATE_PCREL_9:
671 if (value < -512 || value > 511)
672 as_bad_where (fixP->fx_file, fixP->fx_line,
234fa27c
AM
673 _("Value %ld too large for 9-bit PC-relative branch."),
674 value);
f6c1a2d5
NC
675 result = ldiv (value, 2); /* from bytes to words */
676 value = result.quot;
677 if (result.rem)
678 as_bad_where (fixP->fx_file, fixP->fx_line, _
234fa27c
AM
679 ("Value %ld not aligned by 2 for 9-bit"
680 " PC-relative branch."), value);
681 /* Clip into 8-bit field.
682 FIXME I'm sure there is a more proper place for this. */
683 mask = 0x1FF;
f6c1a2d5
NC
684 value &= mask;
685 number_to_chars_bigendian (where, (opcode | value), 2);
686 break;
687 case R_XGATE_PCREL_10:
688 if (value < -1024 || value > 1023)
689 as_bad_where (fixP->fx_file, fixP->fx_line,
234fa27c
AM
690 _("Value %ld too large for 10-bit PC-relative branch."),
691 value);
f6c1a2d5
NC
692 result = ldiv (value, 2); /* from bytes to words */
693 value = result.quot;
694 if (result.rem)
695 as_bad_where (fixP->fx_file, fixP->fx_line, _
234fa27c
AM
696 ("Value %ld not aligned by 2 for 10-bit"
697 " PC-relative branch."), value);
698 /* Clip into 9-bit field.
699 FIXME I'm sure there is a more proper place for this. */
700 mask = 0x3FF;
f6c1a2d5
NC
701 value &= mask;
702 number_to_chars_bigendian (where, (opcode | value), 2);
703 break;
704 case BFD_RELOC_XGATE_IMM8_HI:
705 if (value < -65537 || value > 65535)
706 as_bad_where (fixP->fx_file, fixP->fx_line,
707 _("Value out of 16-bit range."));
708 value >>= 8;
709 value &= 0x00ff;
710 bfd_putb16 ((bfd_vma) value | opcode, (void *) where);
711 break;
712 case BFD_RELOC_XGATE_24:
713 case BFD_RELOC_XGATE_IMM8_LO:
714 if (value < -65537 || value > 65535)
715 as_bad_where (fixP->fx_file, fixP->fx_line,
716 _("Value out of 16-bit range."));
717 value &= 0x00ff;
718 bfd_putb16 ((bfd_vma) value | opcode, (void *) where);
719 break;
720 case BFD_RELOC_XGATE_IMM3:
721 if (value < 0 || value > 7)
722 as_bad_where (fixP->fx_file, fixP->fx_line,
723 _("Value out of 3-bit range."));
724 value <<= 8; /* make big endian */
725 number_to_chars_bigendian (where, (opcode | value), 2);
726 break;
727 case BFD_RELOC_XGATE_IMM4:
728 if (value < 0 || value > 15)
729 as_bad_where (fixP->fx_file, fixP->fx_line,
730 _("Value out of 4-bit range."));
731 value <<= 4; /* align the operand bits */
732 number_to_chars_bigendian (where, (opcode | value), 2);
733 break;
734 case BFD_RELOC_XGATE_IMM5:
735 if (value < 0 || value > 31)
736 as_bad_where (fixP->fx_file, fixP->fx_line,
737 _("Value out of 5-bit range."));
738 value <<= 5; /* align the operand bits */
739 number_to_chars_bigendian (where, (opcode | value), 2);
740 break;
741 case BFD_RELOC_8:
742 ((bfd_byte *) where)[0] = (bfd_byte) value;
743 break;
744 case BFD_RELOC_32:
745 bfd_putb32 ((bfd_vma) value, (unsigned char *) where);
f6c1a2d5
NC
746 break;
747 case BFD_RELOC_16:
748 bfd_putb16 ((bfd_vma) value, (unsigned char *) where);
749 break;
750 default:
751 as_fatal (_("Line %d: unknown relocation type: 0x%x."), fixP->fx_line,
752 fixP->fx_r_type);
753 break;
754 }
755}
756
757/* See whether we need to force a relocation into the output file. */
758
759int
760tc_xgate_force_relocation (fixS * fixP)
761{
762 if (fixP->fx_r_type == BFD_RELOC_XGATE_RL_GROUP)
763 return 1;
764 return generic_force_reloc (fixP);
765}
766
767/* Here we decide which fixups can be adjusted to make them relative
768 to the beginning of the section instead of the symbol. Basically
769 we need to make sure that the linker relaxation is done
770 correctly, so in some cases we force the original symbol to be
771 used. */
772
773int
774tc_xgate_fix_adjustable (fixS * fixP)
775{
776 switch (fixP->fx_r_type)
777 {
778 /* For the linker relaxation to work correctly, these relocs
779 need to be on the symbol itself. */
780 case BFD_RELOC_16:
781 case BFD_RELOC_XGATE_RL_JUMP:
782 case BFD_RELOC_XGATE_RL_GROUP:
783 case BFD_RELOC_VTABLE_INHERIT:
784 case BFD_RELOC_VTABLE_ENTRY:
785 case BFD_RELOC_32:
786 return 0;
787 default:
788 return 1;
789 }
790}
791
792void
793md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
794 asection * sec ATTRIBUTE_UNUSED,
795 fragS * fragP ATTRIBUTE_UNUSED)
796{
797 as_bad (("md_convert_frag not implemented yet"));
798 abort ();
799}
800
801/* Set the ELF specific flags. */
802
803void
804xgate_elf_final_processing (void)
805{
806 elf_flags |= EF_XGATE_MACH;
807 elf_elfheader (stdoutput)->e_flags &= ~EF_XGATE_ABI;
808 elf_elfheader (stdoutput)->e_flags |= elf_flags;
809}
810
811static inline char *
812skip_whitespace (char *s)
813{
814 while (*s == ' ' || *s == '\t' || *s == '(' || *s == ')')
815 s++;
816
817 return s;
818}
819
820/* Extract a word (continuous alpha-numeric chars) from the input line. */
821
822static char *
823extract_word (char *from, char *to, int limit)
824{
825 char *op_end;
826 int size = 0;
827
828 /* Drop leading whitespace. */
829 from = skip_whitespace (from);
830 *to = 0;
831 /* Find the op code end. */
832 for (op_end = from; *op_end != 0 && is_part_of_name (*op_end);)
833 {
834 to[size++] = *op_end++;
835 if (size + 1 >= limit)
234fa27c 836 break;
f6c1a2d5
NC
837 }
838 to[size] = 0;
839 return op_end;
840}
841
842static char *
843xgate_new_instruction (int size)
844{
845 char *f = frag_more (size);
846 dwarf2_emit_insn (size);
847 return f;
848}
849
234fa27c 850static unsigned short
f6c1a2d5
NC
851xgate_apply_operand (unsigned short new_mask,
852 unsigned short *availiable_mask_bits,
853 unsigned short mask,
854 unsigned char n_bits)
855{
856 unsigned short n_shifts;
857 unsigned int n_drop_bits;
858
234fa27c
AM
859 /* Shift until you find an available operand bit "1" and record
860 the number of shifts. */
f6c1a2d5
NC
861 for (n_shifts = 0;
862 !(*availiable_mask_bits & SIXTEENTH_BIT) && n_shifts < 16;
863 n_shifts++)
864 *availiable_mask_bits <<= 1;
865
234fa27c
AM
866 /* Shift for the number of bits your operand requires while bits
867 are available. */
f6c1a2d5
NC
868 for (n_drop_bits = n_bits;
869 n_drop_bits && (*availiable_mask_bits & SIXTEENTH_BIT);
870 --n_drop_bits)
871 *availiable_mask_bits <<= 1;
872
873 if (n_drop_bits)
874 as_bad (_(":operand has too many bits"));
875 *availiable_mask_bits >>= n_shifts + n_bits;
876 if ((n_drop_bits == 0) && (*availiable_mask_bits == 0))
877 {
878 oper_check = 1; /* flag operand check as good */
879 }
880 new_mask <<= N_BITS_IN_WORD - (n_shifts + n_bits);
881 mask |= new_mask;
882 return mask;
883}
884
885/* Parse ordinary expression. */
886
887static char *
888xgate_parse_exp (char *s, expressionS * op)
889{
890 input_line_pointer = s;
891 expression(op);
892 if (op->X_op == O_absent)
893 as_bad (_("missing operand"));
894 return input_line_pointer;
895}
896
3879925e
SK
897static int
898cmp_opcode (struct xgate_opcode *op1, struct xgate_opcode *op2)
899{
900 return strcmp (op1->name, op2->name);
901}
902
903static struct xgate_opcode *
904xgate_find_match (struct xgate_opcode_handle *opcode_handle,
905 int numberOfModes,
906 unsigned int sh_format)
907{
908 int i;
f6c1a2d5 909
3879925e
SK
910 if (numberOfModes == 0)
911 return opcode_handle->opc0[0];
912
913 for (i = 0; i <= numberOfModes; i++)
914 if (opcode_handle->opc0[i]->sh_format & sh_format)
915 return opcode_handle->opc0[i];
916
917 return NULL;
918}
919
920/* Because we are dealing with two different core that view the system
921 memory with different offsets, we must differentiate what core a
922 symbol belongs to, in order for the linker to cross-link. */
923
924int
925xgate_frob_symbol (symbolS *sym)
f6c1a2d5 926{
3879925e
SK
927 asymbol *bfdsym;
928 elf_symbol_type *elfsym;
f6c1a2d5 929
3879925e
SK
930 bfdsym = symbol_get_bfdsym (sym);
931 elfsym = elf_symbol_from (bfd_asymbol_bfd (bfdsym), bfdsym);
f6c1a2d5 932
3879925e 933 gas_assert(elfsym);
f6c1a2d5 934
3879925e
SK
935 /* Mark the symbol as being *from XGATE */
936 elfsym->internal_elf_sym.st_target_internal = 1;
f6c1a2d5 937
3879925e 938 return 0;
f6c1a2d5 939}
f6c1a2d5 940
234fa27c 941static unsigned int
3879925e 942xgate_get_operands (char *line, s_operand oprs[])
f6c1a2d5 943{
3879925e
SK
944 int num_operands;
945
946 /* If there are no operands, then it must be inherent. */
947 if (*line == 0 || *line == '\n' || *line == '\r')
948 return XG_INH;
949
950 for (num_operands = 0; strlen (line) && (num_operands < MAX_NUM_OPERANDS);
234fa27c 951 num_operands++)
3879925e
SK
952 {
953 line = skip_whitespace (line);
954 if (*line == '#')
234fa27c 955 line++;
3879925e 956
8d8ad4eb 957 oprs[num_operands].mod = xgate_determine_modifiers (&line);
3879925e
SK
958
959 if ((oprs[num_operands].reg = reg_name_search (line)) == REG_NONE)
234fa27c 960 line = xgate_parse_exp (line, &oprs[num_operands].exp);
3879925e
SK
961
962 /* skip to next operand */
963 while (*line != 0)
234fa27c
AM
964 {
965 if (*line == ',')
966 {
967 line++;
968 break;
969 }
970 line++;
971 }
3879925e
SK
972 }
973
974 if (num_operands > MAX_NUM_OPERANDS)
975 return 0;
976
977 switch (num_operands)
978 {
234fa27c
AM
979 case 1:
980 if (oprs[0].reg >= REG_R0 && oprs[0].reg <= REG_R7)
981 return XG_R;
982 if (oprs[0].reg == REG_NONE)
983 return XG_I;
984 break;
985 case 2:
986 if (oprs[0].reg >= REG_R0 && oprs[0].reg <= REG_R7)
987 {
988 if (oprs[1].reg >= REG_R0 && oprs[1].reg <= REG_R7)
989 return XG_R_R;
990 if (oprs[1].reg == REG_CCR)
991 return XG_R_C;
992 if (oprs[1].reg == REG_PC)
993 return XG_R_P;
994 if (oprs[1].reg == REG_NONE)
995 return XG_R_I;
996 }
997 if (oprs[0].reg == REG_CCR)
998 return XG_C_R;
999 break;
1000 case 3:
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 {
1005 if (oprs[2].reg >= REG_R0 && oprs[2].reg <= REG_R7)
1006 return XG_R_R_R;
1007 if (oprs[2].reg >= REG_NONE)
1008 return XG_R_R_I;
1009 }
1010 }
1011 break;
1012 default:
1013 as_bad (_("unknown operand format"));
1014 break;
3879925e
SK
1015 }
1016
1017 return 0;
1018}
1019
1020/* reg_name_search() finds the register number given its name.
1021 Returns the register number or REG_NONE on failure. */
1022static register_id
1023reg_name_search (char *name)
1024{
1025 if (strncasecmp (name, "r0", 2) == 0)
1026 return REG_R0;
1027 if (strncasecmp (name, "r1", 2) == 0)
1028 return REG_R1;
1029 if (strncasecmp (name, "r2", 2) == 0)
1030 return REG_R2;
1031 if (strncasecmp (name, "r3", 2) == 0)
1032 return REG_R3;
1033 if (strncasecmp (name, "r4", 2) == 0)
1034 return REG_R4;
1035 if (strncasecmp (name, "r5", 2) == 0)
1036 return REG_R5;
1037 if (strncasecmp (name, "r6", 2) == 0)
1038 return REG_R6;
1039 if (strncasecmp (name, "r7", 2) == 0)
1040 return REG_R7;
1041 if (strncasecmp (name, "pc", 2) == 0)
1042 return REG_PC;
1043 if (strncasecmp (name, "ccr", 3) == 0)
1044 return REG_CCR;
1045 return REG_NONE;
1046}
1047
8d8ad4eb
SK
1048/* Parse operand modifiers such as inc/dec/hi/low. */
1049
234fa27c 1050static op_modifiers
8d8ad4eb 1051xgate_determine_modifiers(char **line)
3879925e
SK
1052{
1053 char *local_line = line[0];
1054
1055 if (strncasecmp (local_line, "%hi", 3) == 0)
1056 {
1057 *line += 3;
1058 return MOD_LOAD_HIGH;
1059 }
1060 if (strncasecmp (local_line, "%lo", 3) == 0)
1061 {
1062 *line += 3;
1063 return MOD_LOAD_LOW;
1064 }
3879925e 1065 if (*(local_line + 2) == '+')
234fa27c 1066 return MOD_POSTINC;
3879925e
SK
1067 if (strncasecmp (local_line, "-r", 2) == 0)
1068 {
1069 *line += 1;
1070 return MOD_PREDEC;
234fa27c 1071 }
3879925e 1072 return MOD_NONE;
f6c1a2d5
NC
1073}
1074
1075/* Parse instruction operands. */
1076
234fa27c 1077static void
3879925e 1078xgate_scan_operands (struct xgate_opcode *opcode, s_operand oprs[])
f6c1a2d5
NC
1079{
1080 char *frag = xgate_new_instruction (opcode->size);
1081 int where = frag - frag_now->fr_literal;
1082 char *op = opcode->constraints;
1083 unsigned int bin = (int) opcode->bin_opcode;
f6c1a2d5
NC
1084 unsigned short oper_mask = 0;
1085 int operand_bit_length = 0;
1086 unsigned int operand = 0;
1087 char n_operand_bits = 0;
1088 char first_operand_equals_second = 0;
1089 int i = 0;
1090 char c = 0;
1091
1092 /* Generate available operand bits mask. */
1093 for (i = 0; (c = opcode->format[i]); i++)
1094 {
1095 if (ISDIGIT (c) || (c == 's'))
234fa27c
AM
1096 {
1097 oper_mask <<= 1;
1098 }
f6c1a2d5 1099 else
234fa27c
AM
1100 {
1101 oper_mask <<= 1;
1102 oper_mask += 1;
1103 n_operand_bits++;
1104 }
f6c1a2d5
NC
1105 }
1106
f6c1a2d5
NC
1107 /* Parse first operand. */
1108 if (*op)
1109 {
1110 if (*op == '=')
234fa27c
AM
1111 {
1112 first_operand_equals_second = 1;
1113 ++op;
1114 }
1115 operand = xgate_parse_operand (opcode, &operand_bit_length, where,
1116 &op, oprs[0]);
f6c1a2d5
NC
1117 ++op;
1118 bin = xgate_apply_operand (operand, &oper_mask, bin, operand_bit_length);
3879925e
SK
1119
1120 if(first_operand_equals_second)
234fa27c
AM
1121 bin = xgate_apply_operand (operand, &oper_mask, bin,
1122 operand_bit_length);
f6c1a2d5
NC
1123 /* Parse second operand. */
1124 if (*op)
234fa27c
AM
1125 {
1126 if (*op == ',')
1127 ++op;
1128 if (first_operand_equals_second)
1129 {
1130 bin = xgate_apply_operand (operand, &oper_mask, bin,
1131 operand_bit_length);
1132 ++op;
1133 }
1134 else
1135 {
1136 operand = xgate_parse_operand (opcode, &operand_bit_length, where,
1137 &op, oprs[1]);
1138 bin = xgate_apply_operand (operand, &oper_mask, bin,
1139 operand_bit_length);
1140 ++op;
1141 }
1142 }
f6c1a2d5
NC
1143 /* Parse the third register. */
1144 if (*op)
234fa27c
AM
1145 {
1146 if (*op == ',')
1147 ++op;
1148 operand = xgate_parse_operand (opcode, &operand_bit_length, where,
1149 &op, oprs[2]);
1150 bin = xgate_apply_operand (operand, &oper_mask, bin,
1151 operand_bit_length);
1152 }
f6c1a2d5
NC
1153 }
1154 if (opcode->size == 2 && fixup_required)
1155 {
1156 bfd_putl16 (bin, frag);
1157 }
1158 else if ((opcode->sh_format & XG_PCREL))
1159 {
1160 /* Write our data to a frag for further processing. */
3879925e 1161 bfd_putl16 (opcode->bin_opcode, frag);
f6c1a2d5
NC
1162 }
1163 else
1164 {
1165 /* Apply operand mask(s)to bin opcode and write the output. */
1166 /* Since we are done write this frag in xgate BE format. */
3879925e 1167 number_to_chars_bigendian (frag, bin, opcode->size);
f6c1a2d5
NC
1168 }
1169 prev = bin;
f6c1a2d5
NC
1170 return;
1171}
1172
1173static unsigned int
3879925e 1174xgate_parse_operand (struct xgate_opcode *opcode,
234fa27c
AM
1175 int *bit_width,
1176 int where,
1177 char **op_con,
1178 s_operand operand)
f6c1a2d5 1179{
f6c1a2d5
NC
1180 char *op_constraint = *op_con;
1181 unsigned int op_mask = 0;
f6c1a2d5
NC
1182 unsigned int pp_fix = 0;
1183 unsigned short max_size = 0;
1184 int i;
1185
1186 *bit_width = 0;
1187 /* Reset. */
1188
1189 switch (*op_constraint)
1190 {
1191 case '+': /* Indexed register operand +/- or plain r. */
f6c1a2d5
NC
1192 /* Default to neither inc or dec. */
1193 pp_fix = 0;
1194 *bit_width = 5;
3879925e 1195
8d8ad4eb 1196 if (operand.reg == REG_NONE)
234fa27c 1197 as_bad (_(": expected register name r0-r7 ") );
8d8ad4eb
SK
1198 op_mask = operand.reg;
1199 if(operand.mod == MOD_POSTINC)
234fa27c 1200 pp_fix = INCREMENT;
8d8ad4eb 1201 if(operand.mod == MOD_PREDEC)
234fa27c 1202 pp_fix = DECREMENT;
f6c1a2d5
NC
1203 op_mask <<= 2;
1204 op_mask |= pp_fix;
1205 break;
1206
1207 case 'r': /* Register operand. */
234fa27c
AM
1208 if (operand.reg == REG_NONE)
1209 as_bad (_(": expected register name r0-r7 "));
3879925e 1210
234fa27c 1211 *bit_width = 3;
3879925e 1212
234fa27c 1213 op_mask = operand.reg;
f6c1a2d5
NC
1214 break;
1215
1216 case 'i': /* Immediate value or expression expected. */
1217 /* Advance the original format pointer. */
1218 (*op_con)++;
1219 op_constraint++;
1220 if (ISDIGIT (*op_constraint))
234fa27c 1221 *bit_width = (int) *op_constraint - '0';
f6c1a2d5 1222 else if (*op_constraint == 'a')
234fa27c 1223 *bit_width = 0x0A;
f6c1a2d5 1224 else if (*op_constraint == 'f')
234fa27c
AM
1225 *bit_width = 0x0F;
1226
f6c1a2d5 1227 /* http://tigcc.ticalc.org/doc/gnuasm.html#SEC31 */
8d8ad4eb 1228 if (operand.exp.X_op == O_constant)
234fa27c
AM
1229 {
1230 op_mask = operand.exp.X_add_number;
1231 if (((opcode->name[strlen (opcode->name) - 1] == 'l') && autoHiLo)
1232 || operand.mod == MOD_LOAD_LOW)
1233 op_mask &= 0x00FF;
1234 else if (((opcode->name[strlen (opcode->name) - 1]) == 'h'
1235 && autoHiLo) || operand.mod == MOD_LOAD_HIGH)
1236 op_mask >>= 8;
1237
1238 /* Make sure it fits. */
1239 for (i = *bit_width; i; i--)
1240 {
1241 max_size <<= 1;
1242 max_size += 1;
1243 }
1244 if (op_mask > max_size)
1245 as_bad (_(":operand value(%d) too big for constraint"), op_mask);
1246 }
f6c1a2d5 1247 else
234fa27c
AM
1248 {
1249 /* Should be BFD_RELOC_XGATE_IMM8_LO instead of BFD_RELOC_XGATE_24
1250 TODO fix. */
1251 fixup_required = 1;
1252 if (*op_constraint == '8')
1253 {
1254 if (((opcode->name[strlen (opcode->name) - 1] == 'l')
1255 && autoHiLo) || operand.mod == MOD_LOAD_LOW)
1256 fix_new_exp (frag_now, where, 2, &operand.exp, FALSE,
1257 BFD_RELOC_XGATE_24);
1258 else if (((opcode->name[strlen (opcode->name) - 1]) == 'h'
1259 && autoHiLo) || operand.mod == MOD_LOAD_HIGH )
1260 fix_new_exp (frag_now, where, 2, &operand.exp, FALSE,
1261 BFD_RELOC_XGATE_IMM8_HI);
1262 else
1263 as_bad (_("you must use a hi/lo directive or 16-bit macro "
1264 "to load a 16-bit value."));
1265 }
1266 else if (*op_constraint == '5')
1267 fix_new_exp (frag_now, where, 2, &operand.exp, FALSE,
1268 BFD_RELOC_XGATE_IMM5);
1269 else if (*op_constraint == '4')
1270 fix_new_exp (frag_now, where, 2, &operand.exp, FALSE,
1271 BFD_RELOC_XGATE_IMM4);
1272 else if (*op_constraint == '3')
1273 fix_new_exp (frag_now, where, 2, &operand.exp, FALSE,
1274 BFD_RELOC_XGATE_IMM3);
1275 else
1276 as_bad (_(":unknown relocation constraint size"));
1277 }
8d8ad4eb 1278 break;
f6c1a2d5
NC
1279
1280 case 'c': /* CCR register expected. */
3879925e 1281 *bit_width = 0;
8d8ad4eb 1282 if (operand.reg != REG_CCR)
234fa27c 1283 as_bad (_(": expected register name ccr "));
8d8ad4eb 1284 break;
f6c1a2d5
NC
1285
1286 case 'p': /* PC register expected. */
3879925e 1287 *bit_width = 0;
234fa27c
AM
1288 if (operand.reg != REG_PC)
1289 as_bad (_(": expected register name pc "));
f6c1a2d5
NC
1290 break;
1291
1292 case 'b': /* Branch expected. */
f6c1a2d5
NC
1293 (*op_con)++;
1294 op_constraint++;
f6c1a2d5 1295
8d8ad4eb 1296 if (operand.exp.X_op != O_register)
234fa27c
AM
1297 {
1298 if (*op_constraint == '9')
1299 fix_new_exp (frag_now, where, 2, &operand.exp, TRUE,
1300 R_XGATE_PCREL_9);
1301 else if (*op_constraint == 'a')
1302 fix_new_exp (frag_now, where, 2, &operand.exp, TRUE,
1303 R_XGATE_PCREL_10);
1304 }
3879925e 1305 else
234fa27c
AM
1306 as_fatal (_("Operand `%x' not recognized in fixup8."),
1307 operand.exp.X_op);
3879925e
SK
1308 break;
1309 case '?':
1310 break;
fe540416 1311
3879925e
SK
1312 default:
1313 as_bad (_("unknown constraint `%c'"), *op_constraint);
1314 break;
1315 }
1316 return op_mask;
fe540416 1317}
This page took 0.101189 seconds and 4 git commands to generate.