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