Adjust gdb/doc/ChangeLog re "set/show remotebaud" renaming...
[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
f4b1f6a9
SK
352 if (flag_print_opcodes)
353 {
464e3686 354 xgate_print_table ();
f4b1f6a9
SK
355 exit (EXIT_SUCCESS);
356 }
f6c1a2d5
NC
357}
358
359void
360xgate_init_after_args (void)
361{
362}
363
364void
365md_show_usage (FILE * stream)
366{
367 get_default_target ();
368
234fa27c 369 fprintf (stream,
f6c1a2d5 370 _("\
234fa27c
AM
371Freescale XGATE co-processor options:\n\
372 -mshort use 16-bit int ABI (default)\n\
373 -mlong use 32-bit int ABI\n\
374 -mshort-double use 32-bit double ABI\n\
375 -mlong-double use 64-bit double ABI (default)\n\
376 --mxgate specify the processor variant[default %s]\n\
377 --print-insn-syntax print the syntax of instruction in case of error\n\
378 --print-opcodes print the list of instructions with syntax\n\
379 --generate-example generate an example of each instruction"),
f6c1a2d5
NC
380 default_cpu);
381}
382
383enum bfd_architecture
384xgate_arch (void)
385{
386 get_default_target ();
387 return bfd_arch_xgate;
388}
389
390int
391xgate_mach (void)
392{
393 return 0;
394}
395
234fa27c 396static void
f6c1a2d5
NC
397xgate_print_syntax (char *name)
398{
399 int i;
400
401 for (i = 0; i < xgate_num_opcodes; i++)
402 {
403 if (!strcmp (xgate_opcodes[i].name, name))
234fa27c
AM
404 {
405 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IDR))
406 printf ("\tFormat is %s\tRx, Rx, Rx+|-Rx|Rx\n",
f6c1a2d5 407 xgate_opcodes[i].name);
234fa27c
AM
408 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_INH))
409 printf ("\tFormat is %s\n", xgate_opcodes[i].name);
410 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_TRI))
411 printf ("\tFormat is %s\tRx, Rx, Rx\n", xgate_opcodes[i].name);
412 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_DYA))
413 printf ("\tFormat is %s\tRx, Rx\n", xgate_opcodes[i].name);
414 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM3))
415 printf ("\tFormat is %s\t<3-bit value>\n", xgate_opcodes[i].name);
416 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM4))
417 printf ("\tFormat is %s\t<4 -bit value>\n", xgate_opcodes[i].name);
418 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM8))
419 printf ("\tFormat is %s\tRx, <8-bit value>\n",
f6c1a2d5 420 xgate_opcodes[i].name);
234fa27c
AM
421 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM16))
422 printf ("\tFormat is %s\tRx, <16-bit value>\n",
f6c1a2d5 423 xgate_opcodes[i].name);
234fa27c
AM
424 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_MON_R_C))
425 printf ("\tFormat is %s\tRx, CCR\n", xgate_opcodes[i].name);
426 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_MON_C_R))
427 printf ("\tFormat is %s\tCCR, Rx\n", xgate_opcodes[i].name);
428 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_MON_R_P))
429 printf ("\tFormat is %s\tRx, PC\n", xgate_opcodes[i].name);
430 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM16mLDW))
431 printf ("\tFormat is %s\tRx, <16-bit value>\n",
f6c1a2d5 432 xgate_opcodes[i].name);
234fa27c 433 }
f6c1a2d5
NC
434 }
435}
436
234fa27c 437static void
f6c1a2d5
NC
438xgate_print_table (void)
439{
440 int i;
441
442 for (i = 0; i < xgate_num_opcodes; i++)
443 xgate_print_syntax (xgate_opcodes[i].name);
444
445 return;
446}
447
448const char *
449xgate_listing_header (void)
450{
451 if (current_architecture & cpuxgate)
452 return "XGATE GAS ";
453
454 return "ERROR MC9S12X GAS ";
455}
456
457symbolS *
458md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
459{
460 return 0;
461}
462
463/* GAS will call this function for each section at the end of the assembly,
464 to permit the CPU backend to adjust the alignment of a section. */
465
466valueT
467md_section_align (asection * seg, valueT addr)
468{
469 int align = bfd_get_section_alignment (stdoutput, seg);
470 return ((addr + (1 << align) - 1) & (-1 << align));
471}
472
473void
474md_assemble (char *input_line)
475{
476 struct xgate_opcode *opcode = 0;
477 struct xgate_opcode *macro_opcode = 0;
478 struct xgate_opcode_handle *opcode_handle = 0;
479 /* Caller expects it to be returned as it was passed. */
480 char *saved_input_line = input_line;
481 char op_name[9] = { 0 };
482 unsigned int sh_format = 0;
483 char *p = 0;
484
3879925e
SK
485 s_operand new_operands[MAX_NUM_OPERANDS];
486
f6c1a2d5
NC
487 fixup_required = 0;
488 oper_check = 0; /* set error flags */
489 input_line = extract_word (input_line, op_name, sizeof(op_name));
490
491 /* Check to make sure we are not reading a bogus line. */
492 if (!op_name[0])
493 as_bad (_("opcode missing or not found on input line"));
494
495 if (!(opcode_handle = (struct xgate_opcode_handle *) hash_find (xgate_hash,
234fa27c 496 op_name)))
f6c1a2d5
NC
497 {
498 as_bad (_("opcode %s not found in opcode hash table"), op_name);
499 }
500 else
501 {
3879925e
SK
502 /* Parse operands so we can find the proper opcode bin. */
503
504 sh_format = xgate_get_operands(input_line, new_operands);
f6c1a2d5
NC
505
506 opcode = xgate_find_match (opcode_handle, opcode_handle->number_of_modes,
234fa27c 507 sh_format);
f6c1a2d5
NC
508
509 if (!opcode)
234fa27c
AM
510 {
511 as_bad (_("matching operands to opcode "));
512 xgate_print_syntax (opcode_handle->opc0[0]->name);
513 }
f6c1a2d5 514 else if (opcode->size == 2)
234fa27c 515 {
f6c1a2d5 516 /* Size is one word - assemble that native insn. */
234fa27c
AM
517 xgate_scan_operands (opcode, new_operands);
518 }
f6c1a2d5 519 else
234fa27c 520 {
f6c1a2d5 521 /* Insn is a simplified instruction - expand it out. */
234fa27c
AM
522 autoHiLo = 1;
523 unsigned int i;
524
525 /* skip past our ';' separator. */
526 for (i = strlen (opcode->constraints), p = opcode->constraints; i > 0;
527 i--, p++)
528 {
529 if (*p == ';')
530 {
531 p++;
532 break;
533 }
534 }
535 input_line = skip_whitespace (input_line);
536 char *macro_inline = input_line;
537
538 /* Loop though the macro's opcode list and apply operands to
539 each real opcode. */
540 for (i = 0; *p && i < (opcode->size / 2); i++)
541 {
f6c1a2d5 542 /* Loop though macro operand list. */
234fa27c
AM
543 input_line = macro_inline; /* Rewind. */
544 p = extract_word (p, op_name, 10);
f6c1a2d5 545
234fa27c 546 if (!(opcode_handle = (struct xgate_opcode_handle *)
f6c1a2d5 547 hash_find (xgate_hash, op_name)))
234fa27c
AM
548 {
549 as_bad (_(": processing macro, real opcode handle"
550 " not found in hash"));
551 break;
552 }
553 else
554 {
555 sh_format = xgate_get_operands(input_line, new_operands);
556 macro_opcode
557 = xgate_find_match (opcode_handle,
558 opcode_handle->number_of_modes,
559 sh_format);
560 xgate_scan_operands (macro_opcode, new_operands);
561
562 }
563 }
564 }
f6c1a2d5 565 }
8d8ad4eb 566 autoHiLo = 0;
f6c1a2d5
NC
567 input_line = saved_input_line;
568}
569
570/* Force truly undefined symbols to their maximum size, and generally set up
571 the frag list to be relaxed. */
572
573int
574md_estimate_size_before_relax (fragS *fragp, asection *seg)
575{
576 /* If symbol is undefined or located in a different section,
577 select the largest supported relocation. */
578 relax_substateT subtype;
234fa27c 579 relax_substateT rlx_state[] = { 0, 2 };
f6c1a2d5
NC
580
581 for (subtype = 0; subtype < ARRAY_SIZE (rlx_state); subtype += 2)
582 {
583 if (fragp->fr_subtype == rlx_state[subtype]
234fa27c
AM
584 && (!S_IS_DEFINED (fragp->fr_symbol)
585 || seg != S_GET_SEGMENT (fragp->fr_symbol)))
586 {
587 fragp->fr_subtype = rlx_state[subtype + 1];
588 break;
589 }
f6c1a2d5
NC
590 }
591
592 if (fragp->fr_subtype >= ARRAY_SIZE (md_relax_table))
593 abort ();
594
595 return md_relax_table[fragp->fr_subtype].rlx_length;
596}
597
598
599/* Relocation, relaxation and frag conversions. */
600
601/* PC-relative offsets are relative to the start of the
602 next instruction. That is, the address of the offset, plus its
603 size, since the offset is always the last part of the insn. */
604
605long
606md_pcrel_from (fixS * fixP)
607{
608 return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
609}
610
611/* If while processing a fixup, a reloc really needs to be created
612 then it is done here. */
613
614arelent *
615tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
616{
617 arelent * reloc;
618
619 reloc = (arelent *) xmalloc (sizeof(arelent));
620 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof(asymbol *));
621 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
622 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
623
624 if (fixp->fx_r_type == 0)
234fa27c 625 reloc->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_16);
f6c1a2d5 626 else
234fa27c 627 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
f6c1a2d5
NC
628
629 if (reloc->howto == (reloc_howto_type *) NULL)
630 {
631 as_bad_where (fixp->fx_file, fixp->fx_line, _
234fa27c
AM
632 ("Relocation %d is not supported by object file format."),
633 (int) fixp->fx_r_type);
f6c1a2d5
NC
634 return NULL;
635 }
636
637 /* Since we use Rel instead of Rela, encode the vtable entry to be
638 used in the relocation's section offset. */
639 if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
640 reloc->address = fixp->fx_offset;
641 reloc->addend = 0;
642 return reloc;
643}
644
645/* Patch the instruction with the resolved operand. Elf relocation
646 info will also be generated to take care of linker/loader fixups.
647 The XGATE addresses only 16-bit addresses.The BFD_RELOC_32 is necessary
648 for the support of --gstabs. */
649
650void
651md_apply_fix (fixS * fixP, valueT * valP, segT seg ATTRIBUTE_UNUSED)
652{
653 char *where;
654 long value = *valP;
655 int opcode = 0;
656 ldiv_t result;
657
234fa27c
AM
658 /* If the fixup is done mark it done so no further symbol resolution
659 will take place. */
f6c1a2d5 660 if (fixP->fx_addsy == (symbolS *) NULL)
234fa27c 661 fixP->fx_done = 1;
f6c1a2d5
NC
662
663 /* We don't actually support subtracting a symbol. */
664 if (fixP->fx_subsy != (symbolS *) NULL)
665 as_bad_where (fixP->fx_file, fixP->fx_line, _("Expression too complex."));
666
667 where = fixP->fx_frag->fr_literal + fixP->fx_where;
668 opcode = bfd_getl16 (where);
669 int mask = 0;
670
671 switch (fixP->fx_r_type)
672 {
673 case R_XGATE_PCREL_9:
674 if (value < -512 || value > 511)
675 as_bad_where (fixP->fx_file, fixP->fx_line,
234fa27c
AM
676 _("Value %ld too large for 9-bit PC-relative branch."),
677 value);
f6c1a2d5
NC
678 result = ldiv (value, 2); /* from bytes to words */
679 value = result.quot;
680 if (result.rem)
681 as_bad_where (fixP->fx_file, fixP->fx_line, _
234fa27c
AM
682 ("Value %ld not aligned by 2 for 9-bit"
683 " PC-relative branch."), value);
684 /* Clip into 8-bit field.
685 FIXME I'm sure there is a more proper place for this. */
686 mask = 0x1FF;
f6c1a2d5
NC
687 value &= mask;
688 number_to_chars_bigendian (where, (opcode | value), 2);
689 break;
690 case R_XGATE_PCREL_10:
691 if (value < -1024 || value > 1023)
692 as_bad_where (fixP->fx_file, fixP->fx_line,
234fa27c
AM
693 _("Value %ld too large for 10-bit PC-relative branch."),
694 value);
f6c1a2d5
NC
695 result = ldiv (value, 2); /* from bytes to words */
696 value = result.quot;
697 if (result.rem)
698 as_bad_where (fixP->fx_file, fixP->fx_line, _
234fa27c
AM
699 ("Value %ld not aligned by 2 for 10-bit"
700 " PC-relative branch."), value);
701 /* Clip into 9-bit field.
702 FIXME I'm sure there is a more proper place for this. */
703 mask = 0x3FF;
f6c1a2d5
NC
704 value &= mask;
705 number_to_chars_bigendian (where, (opcode | value), 2);
706 break;
707 case BFD_RELOC_XGATE_IMM8_HI:
708 if (value < -65537 || value > 65535)
709 as_bad_where (fixP->fx_file, fixP->fx_line,
710 _("Value out of 16-bit range."));
711 value >>= 8;
712 value &= 0x00ff;
713 bfd_putb16 ((bfd_vma) value | opcode, (void *) where);
714 break;
715 case BFD_RELOC_XGATE_24:
716 case BFD_RELOC_XGATE_IMM8_LO:
717 if (value < -65537 || value > 65535)
718 as_bad_where (fixP->fx_file, fixP->fx_line,
719 _("Value out of 16-bit range."));
720 value &= 0x00ff;
721 bfd_putb16 ((bfd_vma) value | opcode, (void *) where);
722 break;
723 case BFD_RELOC_XGATE_IMM3:
724 if (value < 0 || value > 7)
725 as_bad_where (fixP->fx_file, fixP->fx_line,
726 _("Value out of 3-bit range."));
727 value <<= 8; /* make big endian */
728 number_to_chars_bigendian (where, (opcode | value), 2);
729 break;
730 case BFD_RELOC_XGATE_IMM4:
731 if (value < 0 || value > 15)
732 as_bad_where (fixP->fx_file, fixP->fx_line,
733 _("Value out of 4-bit range."));
734 value <<= 4; /* align the operand bits */
735 number_to_chars_bigendian (where, (opcode | value), 2);
736 break;
737 case BFD_RELOC_XGATE_IMM5:
738 if (value < 0 || value > 31)
739 as_bad_where (fixP->fx_file, fixP->fx_line,
740 _("Value out of 5-bit range."));
741 value <<= 5; /* align the operand bits */
742 number_to_chars_bigendian (where, (opcode | value), 2);
743 break;
744 case BFD_RELOC_8:
745 ((bfd_byte *) where)[0] = (bfd_byte) value;
746 break;
747 case BFD_RELOC_32:
748 bfd_putb32 ((bfd_vma) value, (unsigned char *) where);
f6c1a2d5
NC
749 break;
750 case BFD_RELOC_16:
751 bfd_putb16 ((bfd_vma) value, (unsigned char *) where);
752 break;
753 default:
754 as_fatal (_("Line %d: unknown relocation type: 0x%x."), fixP->fx_line,
755 fixP->fx_r_type);
756 break;
757 }
758}
759
760/* See whether we need to force a relocation into the output file. */
761
762int
763tc_xgate_force_relocation (fixS * fixP)
764{
765 if (fixP->fx_r_type == BFD_RELOC_XGATE_RL_GROUP)
766 return 1;
767 return generic_force_reloc (fixP);
768}
769
770/* Here we decide which fixups can be adjusted to make them relative
771 to the beginning of the section instead of the symbol. Basically
772 we need to make sure that the linker relaxation is done
773 correctly, so in some cases we force the original symbol to be
774 used. */
775
776int
777tc_xgate_fix_adjustable (fixS * fixP)
778{
779 switch (fixP->fx_r_type)
780 {
781 /* For the linker relaxation to work correctly, these relocs
782 need to be on the symbol itself. */
783 case BFD_RELOC_16:
784 case BFD_RELOC_XGATE_RL_JUMP:
785 case BFD_RELOC_XGATE_RL_GROUP:
786 case BFD_RELOC_VTABLE_INHERIT:
787 case BFD_RELOC_VTABLE_ENTRY:
788 case BFD_RELOC_32:
789 return 0;
790 default:
791 return 1;
792 }
793}
794
795void
796md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
797 asection * sec ATTRIBUTE_UNUSED,
798 fragS * fragP ATTRIBUTE_UNUSED)
799{
800 as_bad (("md_convert_frag not implemented yet"));
801 abort ();
802}
803
804/* Set the ELF specific flags. */
805
806void
807xgate_elf_final_processing (void)
808{
809 elf_flags |= EF_XGATE_MACH;
810 elf_elfheader (stdoutput)->e_flags &= ~EF_XGATE_ABI;
811 elf_elfheader (stdoutput)->e_flags |= elf_flags;
812}
813
814static inline char *
815skip_whitespace (char *s)
816{
817 while (*s == ' ' || *s == '\t' || *s == '(' || *s == ')')
818 s++;
819
820 return s;
821}
822
823/* Extract a word (continuous alpha-numeric chars) from the input line. */
824
825static char *
826extract_word (char *from, char *to, int limit)
827{
828 char *op_end;
829 int size = 0;
830
831 /* Drop leading whitespace. */
832 from = skip_whitespace (from);
833 *to = 0;
834 /* Find the op code end. */
835 for (op_end = from; *op_end != 0 && is_part_of_name (*op_end);)
836 {
837 to[size++] = *op_end++;
838 if (size + 1 >= limit)
234fa27c 839 break;
f6c1a2d5
NC
840 }
841 to[size] = 0;
842 return op_end;
843}
844
845static char *
846xgate_new_instruction (int size)
847{
848 char *f = frag_more (size);
849 dwarf2_emit_insn (size);
850 return f;
851}
852
234fa27c 853static unsigned short
f6c1a2d5
NC
854xgate_apply_operand (unsigned short new_mask,
855 unsigned short *availiable_mask_bits,
856 unsigned short mask,
857 unsigned char n_bits)
858{
859 unsigned short n_shifts;
860 unsigned int n_drop_bits;
861
234fa27c
AM
862 /* Shift until you find an available operand bit "1" and record
863 the number of shifts. */
f6c1a2d5
NC
864 for (n_shifts = 0;
865 !(*availiable_mask_bits & SIXTEENTH_BIT) && n_shifts < 16;
866 n_shifts++)
867 *availiable_mask_bits <<= 1;
868
234fa27c
AM
869 /* Shift for the number of bits your operand requires while bits
870 are available. */
f6c1a2d5
NC
871 for (n_drop_bits = n_bits;
872 n_drop_bits && (*availiable_mask_bits & SIXTEENTH_BIT);
873 --n_drop_bits)
874 *availiable_mask_bits <<= 1;
875
876 if (n_drop_bits)
877 as_bad (_(":operand has too many bits"));
878 *availiable_mask_bits >>= n_shifts + n_bits;
879 if ((n_drop_bits == 0) && (*availiable_mask_bits == 0))
880 {
881 oper_check = 1; /* flag operand check as good */
882 }
883 new_mask <<= N_BITS_IN_WORD - (n_shifts + n_bits);
884 mask |= new_mask;
885 return mask;
886}
887
888/* Parse ordinary expression. */
889
890static char *
891xgate_parse_exp (char *s, expressionS * op)
892{
893 input_line_pointer = s;
894 expression(op);
895 if (op->X_op == O_absent)
896 as_bad (_("missing operand"));
897 return input_line_pointer;
898}
899
3879925e
SK
900static int
901cmp_opcode (struct xgate_opcode *op1, struct xgate_opcode *op2)
902{
903 return strcmp (op1->name, op2->name);
904}
905
906static struct xgate_opcode *
907xgate_find_match (struct xgate_opcode_handle *opcode_handle,
908 int numberOfModes,
909 unsigned int sh_format)
910{
911 int i;
f6c1a2d5 912
3879925e
SK
913 if (numberOfModes == 0)
914 return opcode_handle->opc0[0];
915
916 for (i = 0; i <= numberOfModes; i++)
917 if (opcode_handle->opc0[i]->sh_format & sh_format)
918 return opcode_handle->opc0[i];
919
920 return NULL;
921}
922
923/* Because we are dealing with two different core that view the system
924 memory with different offsets, we must differentiate what core a
925 symbol belongs to, in order for the linker to cross-link. */
926
927int
928xgate_frob_symbol (symbolS *sym)
f6c1a2d5 929{
3879925e
SK
930 asymbol *bfdsym;
931 elf_symbol_type *elfsym;
f6c1a2d5 932
3879925e
SK
933 bfdsym = symbol_get_bfdsym (sym);
934 elfsym = elf_symbol_from (bfd_asymbol_bfd (bfdsym), bfdsym);
f6c1a2d5 935
3879925e 936 gas_assert(elfsym);
f6c1a2d5 937
3879925e
SK
938 /* Mark the symbol as being *from XGATE */
939 elfsym->internal_elf_sym.st_target_internal = 1;
f6c1a2d5 940
3879925e 941 return 0;
f6c1a2d5 942}
f6c1a2d5 943
234fa27c 944static unsigned int
3879925e 945xgate_get_operands (char *line, s_operand oprs[])
f6c1a2d5 946{
3879925e
SK
947 int num_operands;
948
949 /* If there are no operands, then it must be inherent. */
950 if (*line == 0 || *line == '\n' || *line == '\r')
951 return XG_INH;
952
953 for (num_operands = 0; strlen (line) && (num_operands < MAX_NUM_OPERANDS);
234fa27c 954 num_operands++)
3879925e
SK
955 {
956 line = skip_whitespace (line);
957 if (*line == '#')
234fa27c 958 line++;
3879925e 959
8d8ad4eb 960 oprs[num_operands].mod = xgate_determine_modifiers (&line);
3879925e
SK
961
962 if ((oprs[num_operands].reg = reg_name_search (line)) == REG_NONE)
234fa27c 963 line = xgate_parse_exp (line, &oprs[num_operands].exp);
3879925e
SK
964
965 /* skip to next operand */
966 while (*line != 0)
234fa27c
AM
967 {
968 if (*line == ',')
969 {
970 line++;
971 break;
972 }
973 line++;
974 }
3879925e
SK
975 }
976
977 if (num_operands > MAX_NUM_OPERANDS)
978 return 0;
979
980 switch (num_operands)
981 {
234fa27c
AM
982 case 1:
983 if (oprs[0].reg >= REG_R0 && oprs[0].reg <= REG_R7)
984 return XG_R;
985 if (oprs[0].reg == REG_NONE)
986 return XG_I;
987 break;
988 case 2:
989 if (oprs[0].reg >= REG_R0 && oprs[0].reg <= REG_R7)
990 {
991 if (oprs[1].reg >= REG_R0 && oprs[1].reg <= REG_R7)
992 return XG_R_R;
993 if (oprs[1].reg == REG_CCR)
994 return XG_R_C;
995 if (oprs[1].reg == REG_PC)
996 return XG_R_P;
997 if (oprs[1].reg == REG_NONE)
998 return XG_R_I;
999 }
1000 if (oprs[0].reg == REG_CCR)
1001 return XG_C_R;
1002 break;
1003 case 3:
1004 if (oprs[0].reg >= REG_R0 && oprs[0].reg <= REG_R7)
1005 {
1006 if (oprs[1].reg >= REG_R0 && oprs[1].reg <= REG_R7)
1007 {
1008 if (oprs[2].reg >= REG_R0 && oprs[2].reg <= REG_R7)
1009 return XG_R_R_R;
1010 if (oprs[2].reg >= REG_NONE)
1011 return XG_R_R_I;
1012 }
1013 }
1014 break;
1015 default:
1016 as_bad (_("unknown operand format"));
1017 break;
3879925e
SK
1018 }
1019
1020 return 0;
1021}
1022
1023/* reg_name_search() finds the register number given its name.
1024 Returns the register number or REG_NONE on failure. */
1025static register_id
1026reg_name_search (char *name)
1027{
1028 if (strncasecmp (name, "r0", 2) == 0)
1029 return REG_R0;
1030 if (strncasecmp (name, "r1", 2) == 0)
1031 return REG_R1;
1032 if (strncasecmp (name, "r2", 2) == 0)
1033 return REG_R2;
1034 if (strncasecmp (name, "r3", 2) == 0)
1035 return REG_R3;
1036 if (strncasecmp (name, "r4", 2) == 0)
1037 return REG_R4;
1038 if (strncasecmp (name, "r5", 2) == 0)
1039 return REG_R5;
1040 if (strncasecmp (name, "r6", 2) == 0)
1041 return REG_R6;
1042 if (strncasecmp (name, "r7", 2) == 0)
1043 return REG_R7;
1044 if (strncasecmp (name, "pc", 2) == 0)
1045 return REG_PC;
1046 if (strncasecmp (name, "ccr", 3) == 0)
1047 return REG_CCR;
1048 return REG_NONE;
1049}
1050
8d8ad4eb
SK
1051/* Parse operand modifiers such as inc/dec/hi/low. */
1052
234fa27c 1053static op_modifiers
8d8ad4eb 1054xgate_determine_modifiers(char **line)
3879925e
SK
1055{
1056 char *local_line = line[0];
1057
1058 if (strncasecmp (local_line, "%hi", 3) == 0)
1059 {
1060 *line += 3;
1061 return MOD_LOAD_HIGH;
1062 }
1063 if (strncasecmp (local_line, "%lo", 3) == 0)
1064 {
1065 *line += 3;
1066 return MOD_LOAD_LOW;
1067 }
3879925e 1068 if (*(local_line + 2) == '+')
234fa27c 1069 return MOD_POSTINC;
3879925e
SK
1070 if (strncasecmp (local_line, "-r", 2) == 0)
1071 {
1072 *line += 1;
1073 return MOD_PREDEC;
234fa27c 1074 }
3879925e 1075 return MOD_NONE;
f6c1a2d5
NC
1076}
1077
1078/* Parse instruction operands. */
1079
234fa27c 1080static void
3879925e 1081xgate_scan_operands (struct xgate_opcode *opcode, s_operand oprs[])
f6c1a2d5
NC
1082{
1083 char *frag = xgate_new_instruction (opcode->size);
1084 int where = frag - frag_now->fr_literal;
1085 char *op = opcode->constraints;
1086 unsigned int bin = (int) opcode->bin_opcode;
f6c1a2d5
NC
1087 unsigned short oper_mask = 0;
1088 int operand_bit_length = 0;
1089 unsigned int operand = 0;
1090 char n_operand_bits = 0;
1091 char first_operand_equals_second = 0;
1092 int i = 0;
1093 char c = 0;
1094
1095 /* Generate available operand bits mask. */
1096 for (i = 0; (c = opcode->format[i]); i++)
1097 {
1098 if (ISDIGIT (c) || (c == 's'))
234fa27c
AM
1099 {
1100 oper_mask <<= 1;
1101 }
f6c1a2d5 1102 else
234fa27c
AM
1103 {
1104 oper_mask <<= 1;
1105 oper_mask += 1;
1106 n_operand_bits++;
1107 }
f6c1a2d5
NC
1108 }
1109
f6c1a2d5
NC
1110 /* Parse first operand. */
1111 if (*op)
1112 {
1113 if (*op == '=')
234fa27c
AM
1114 {
1115 first_operand_equals_second = 1;
1116 ++op;
1117 }
1118 operand = xgate_parse_operand (opcode, &operand_bit_length, where,
1119 &op, oprs[0]);
f6c1a2d5
NC
1120 ++op;
1121 bin = xgate_apply_operand (operand, &oper_mask, bin, operand_bit_length);
3879925e
SK
1122
1123 if(first_operand_equals_second)
234fa27c
AM
1124 bin = xgate_apply_operand (operand, &oper_mask, bin,
1125 operand_bit_length);
f6c1a2d5
NC
1126 /* Parse second operand. */
1127 if (*op)
234fa27c
AM
1128 {
1129 if (*op == ',')
1130 ++op;
1131 if (first_operand_equals_second)
1132 {
1133 bin = xgate_apply_operand (operand, &oper_mask, bin,
1134 operand_bit_length);
1135 ++op;
1136 }
1137 else
1138 {
1139 operand = xgate_parse_operand (opcode, &operand_bit_length, where,
1140 &op, oprs[1]);
1141 bin = xgate_apply_operand (operand, &oper_mask, bin,
1142 operand_bit_length);
1143 ++op;
1144 }
1145 }
f6c1a2d5
NC
1146 /* Parse the third register. */
1147 if (*op)
234fa27c
AM
1148 {
1149 if (*op == ',')
1150 ++op;
1151 operand = xgate_parse_operand (opcode, &operand_bit_length, where,
1152 &op, oprs[2]);
1153 bin = xgate_apply_operand (operand, &oper_mask, bin,
1154 operand_bit_length);
1155 }
f6c1a2d5
NC
1156 }
1157 if (opcode->size == 2 && fixup_required)
1158 {
1159 bfd_putl16 (bin, frag);
1160 }
1161 else if ((opcode->sh_format & XG_PCREL))
1162 {
1163 /* Write our data to a frag for further processing. */
3879925e 1164 bfd_putl16 (opcode->bin_opcode, frag);
f6c1a2d5
NC
1165 }
1166 else
1167 {
1168 /* Apply operand mask(s)to bin opcode and write the output. */
1169 /* Since we are done write this frag in xgate BE format. */
3879925e 1170 number_to_chars_bigendian (frag, bin, opcode->size);
f6c1a2d5
NC
1171 }
1172 prev = bin;
f6c1a2d5
NC
1173 return;
1174}
1175
1176static unsigned int
3879925e 1177xgate_parse_operand (struct xgate_opcode *opcode,
234fa27c
AM
1178 int *bit_width,
1179 int where,
1180 char **op_con,
1181 s_operand operand)
f6c1a2d5 1182{
f6c1a2d5
NC
1183 char *op_constraint = *op_con;
1184 unsigned int op_mask = 0;
f6c1a2d5
NC
1185 unsigned int pp_fix = 0;
1186 unsigned short max_size = 0;
1187 int i;
1188
1189 *bit_width = 0;
1190 /* Reset. */
1191
1192 switch (*op_constraint)
1193 {
1194 case '+': /* Indexed register operand +/- or plain r. */
f6c1a2d5
NC
1195 /* Default to neither inc or dec. */
1196 pp_fix = 0;
1197 *bit_width = 5;
3879925e 1198
8d8ad4eb 1199 if (operand.reg == REG_NONE)
234fa27c 1200 as_bad (_(": expected register name r0-r7 ") );
8d8ad4eb
SK
1201 op_mask = operand.reg;
1202 if(operand.mod == MOD_POSTINC)
234fa27c 1203 pp_fix = INCREMENT;
8d8ad4eb 1204 if(operand.mod == MOD_PREDEC)
234fa27c 1205 pp_fix = DECREMENT;
f6c1a2d5
NC
1206 op_mask <<= 2;
1207 op_mask |= pp_fix;
1208 break;
1209
1210 case 'r': /* Register operand. */
234fa27c
AM
1211 if (operand.reg == REG_NONE)
1212 as_bad (_(": expected register name r0-r7 "));
3879925e 1213
234fa27c 1214 *bit_width = 3;
3879925e 1215
234fa27c 1216 op_mask = operand.reg;
f6c1a2d5
NC
1217 break;
1218
1219 case 'i': /* Immediate value or expression expected. */
1220 /* Advance the original format pointer. */
1221 (*op_con)++;
1222 op_constraint++;
1223 if (ISDIGIT (*op_constraint))
234fa27c 1224 *bit_width = (int) *op_constraint - '0';
f6c1a2d5 1225 else if (*op_constraint == 'a')
234fa27c 1226 *bit_width = 0x0A;
f6c1a2d5 1227 else if (*op_constraint == 'f')
234fa27c
AM
1228 *bit_width = 0x0F;
1229
f6c1a2d5 1230 /* http://tigcc.ticalc.org/doc/gnuasm.html#SEC31 */
8d8ad4eb 1231 if (operand.exp.X_op == O_constant)
234fa27c
AM
1232 {
1233 op_mask = operand.exp.X_add_number;
1234 if (((opcode->name[strlen (opcode->name) - 1] == 'l') && autoHiLo)
1235 || operand.mod == MOD_LOAD_LOW)
1236 op_mask &= 0x00FF;
1237 else if (((opcode->name[strlen (opcode->name) - 1]) == 'h'
1238 && autoHiLo) || operand.mod == MOD_LOAD_HIGH)
1239 op_mask >>= 8;
1240
1241 /* Make sure it fits. */
1242 for (i = *bit_width; i; i--)
1243 {
1244 max_size <<= 1;
1245 max_size += 1;
1246 }
1247 if (op_mask > max_size)
1248 as_bad (_(":operand value(%d) too big for constraint"), op_mask);
1249 }
f6c1a2d5 1250 else
234fa27c
AM
1251 {
1252 /* Should be BFD_RELOC_XGATE_IMM8_LO instead of BFD_RELOC_XGATE_24
1253 TODO fix. */
1254 fixup_required = 1;
1255 if (*op_constraint == '8')
1256 {
1257 if (((opcode->name[strlen (opcode->name) - 1] == 'l')
1258 && autoHiLo) || operand.mod == MOD_LOAD_LOW)
1259 fix_new_exp (frag_now, where, 2, &operand.exp, FALSE,
1260 BFD_RELOC_XGATE_24);
1261 else if (((opcode->name[strlen (opcode->name) - 1]) == 'h'
1262 && autoHiLo) || operand.mod == MOD_LOAD_HIGH )
1263 fix_new_exp (frag_now, where, 2, &operand.exp, FALSE,
1264 BFD_RELOC_XGATE_IMM8_HI);
1265 else
1266 as_bad (_("you must use a hi/lo directive or 16-bit macro "
1267 "to load a 16-bit value."));
1268 }
1269 else if (*op_constraint == '5')
1270 fix_new_exp (frag_now, where, 2, &operand.exp, FALSE,
1271 BFD_RELOC_XGATE_IMM5);
1272 else if (*op_constraint == '4')
1273 fix_new_exp (frag_now, where, 2, &operand.exp, FALSE,
1274 BFD_RELOC_XGATE_IMM4);
1275 else if (*op_constraint == '3')
1276 fix_new_exp (frag_now, where, 2, &operand.exp, FALSE,
1277 BFD_RELOC_XGATE_IMM3);
1278 else
1279 as_bad (_(":unknown relocation constraint size"));
1280 }
8d8ad4eb 1281 break;
f6c1a2d5
NC
1282
1283 case 'c': /* CCR register expected. */
3879925e 1284 *bit_width = 0;
8d8ad4eb 1285 if (operand.reg != REG_CCR)
234fa27c 1286 as_bad (_(": expected register name ccr "));
8d8ad4eb 1287 break;
f6c1a2d5
NC
1288
1289 case 'p': /* PC register expected. */
3879925e 1290 *bit_width = 0;
234fa27c
AM
1291 if (operand.reg != REG_PC)
1292 as_bad (_(": expected register name pc "));
f6c1a2d5
NC
1293 break;
1294
1295 case 'b': /* Branch expected. */
f6c1a2d5
NC
1296 (*op_con)++;
1297 op_constraint++;
f6c1a2d5 1298
8d8ad4eb 1299 if (operand.exp.X_op != O_register)
234fa27c
AM
1300 {
1301 if (*op_constraint == '9')
1302 fix_new_exp (frag_now, where, 2, &operand.exp, TRUE,
1303 R_XGATE_PCREL_9);
1304 else if (*op_constraint == 'a')
1305 fix_new_exp (frag_now, where, 2, &operand.exp, TRUE,
1306 R_XGATE_PCREL_10);
1307 }
3879925e 1308 else
234fa27c
AM
1309 as_fatal (_("Operand `%x' not recognized in fixup8."),
1310 operand.exp.X_op);
3879925e
SK
1311 break;
1312 case '?':
1313 break;
fe540416 1314
3879925e
SK
1315 default:
1316 as_bad (_("unknown constraint `%c'"), *op_constraint);
1317 break;
1318 }
1319 return op_mask;
fe540416 1320}
This page took 0.135034 seconds and 4 git commands to generate.